(self["webpackChunkbrowser_extension"] = self["webpackChunkbrowser_extension"] || []).push([[645,59,89],{

/***/ 23458:
/***/ ((__unused_webpack_module, exports) => {

"use strict";
var __webpack_unused_export__;
/**
* @file Compatibility tables data for AGTree
*
* This file is auto-generated from YAML files in the "compatibility-tables" directory.
* It is optimized for better runtime usage and storage efficiency.
*
* We use "shared" section to share the same values between different map keys
* to reduce the storage usage.
*/


__webpack_unused_export__ = ({ value: true });

var modifiersCompatibilityTableData = {
	shared: [
		{
			shared: [
				{
					name: "all",
					aliases: null,
					description: "$all modifier is made of $document, $popup, and all content-type modifiers combined.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#all-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: true,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "all",
					aliases: null,
					description: "The `all` option is equivalent to specifying all network-based types\n+ `popup`, `document`, `inline-font` and `inline-script`.",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#all",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"256": 0,
				"512": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "app",
					aliases: null,
					description: "The `$app` modifier lets you narrow the rule coverage down to a specific application or a list of applications.\nThe modifier's behavior and syntax perfectly match the corresponding basic rules `$app` modifier.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#app-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: "pipe_separated_apps"
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0
			}
		},
		{
			shared: [
				{
					name: "badfilter",
					aliases: null,
					description: "The rules with the `$badfilter` modifier disable other basic rules to which they refer. It means that\nthe text of the disabled rule should match the text of the `$badfilter` rule (without the `$badfilter` modifier).",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#badfilter-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "badfilter",
					aliases: null,
					description: "The rules with the `$badfilter` modifier disable other basic rules to which they refer. It means that\nthe text of the disabled rule should match the text of the `$badfilter` rule (without the `$badfilter` modifier).",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#badfilter",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"256": 0,
				"512": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "cname",
					aliases: null,
					description: "When used in an exception filter,\nit will bypass blocking CNAME uncloaked requests for the current (specified) document.",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#cname",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: true,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1024": 0,
				"2048": 0,
				"4096": 0,
				"8192": 0
			}
		},
		{
			shared: [
				{
					name: "content",
					aliases: null,
					description: "Disables HTML filtering and `$replace` rules on the pages that match the rule.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#content-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: true,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0
			}
		},
		{
			shared: [
				{
					name: "cookie",
					aliases: null,
					description: "The `$cookie` modifier completely changes rule behavior.\nInstead of blocking a request, this modifier makes us suppress or modify the Cookie and Set-Cookie headers.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#cookie-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: true,
					valueFormat: "^([^;=\\s]*?)((?:;(maxAge=\\d+;?)?|(sameSite=(lax|none|strict);?)?){1,3})(?<!;)$"
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "csp",
					aliases: null,
					description: "This modifier completely changes the rule behavior.\nIf it is applied to a rule, it will not block the matching request.\nThe response headers are going to be modified instead.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#csp-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"domain",
						"important",
						"subdocument",
						"badfilter"
					],
					inverseConflicts: true,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: true,
					valueFormat: "csp_value"
				},
				{
					name: "csp",
					aliases: null,
					description: "This modifier completely changes the rule behavior.\nIf it is applied to a rule, it will not block the matching request.\nThe response headers are going to be modified instead.",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#csp",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"1p",
						"3p",
						"domain",
						"badfilter"
					],
					inverseConflicts: true,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: true,
					valueFormat: "csp_value"
				},
				{
					name: "csp",
					aliases: null,
					description: "This modifier completely changes the rule behavior.\nIf it is applied to a rule, it will not block the matching request.\nThe response headers are going to be modified instead.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293-How-to-write-filters#content-security-policies",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"domain",
						"subdocument"
					],
					inverseConflicts: true,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: true,
					valueFormat: "csp_value"
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "denyallow",
					aliases: null,
					description: "The `$denyallow` modifier allows to avoid creating additional rules\nwhen it is needed to disable a certain rule for specific domains.\n`$denyallow` matches only target domains and not referrer domains.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#denyallow-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"to"
					],
					inverseConflicts: false,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: "pipe_separated_denyallow_domains"
				},
				{
					name: "denyallow",
					aliases: null,
					description: "The `$denyallow` modifier allows to avoid creating additional rules\nwhen it is needed to disable a certain rule for specific domains.\n`$denyallow` matches only target domains and not referrer domains.",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#denyallow",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"to"
					],
					inverseConflicts: false,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: "pipe_separated_denyallow_domains"
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"256": 0,
				"512": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "document",
					aliases: null,
					description: "The rule corresponds to the main frame document requests,\ni.e. HTML documents that are loaded in the browser tab.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#document-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "document",
					aliases: null,
					description: "The rule corresponds to the main frame document requests,\ni.e. HTML documents that are loaded in the browser tab.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#document-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "document",
					aliases: null,
					description: "The rule corresponds to the main frame document requests,\ni.e. HTML documents that are loaded in the browser tab.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#document-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "document",
					aliases: null,
					description: "The rule corresponds to the main frame document requests,\ni.e. HTML documents that are loaded in the browser tab.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#document-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "document",
					aliases: [
						"doc"
					],
					description: "The rule corresponds to the main frame document requests,\ni.e. HTML documents that are loaded in the browser tab.",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#document",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "document",
					aliases: null,
					description: "The rule corresponds to the main frame document requests,\ni.e. HTML documents that are loaded in the browser tab.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293-How-to-write-filters#allowlist",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 1,
				"16": 1,
				"32": 1,
				"64": 1,
				"256": 2,
				"512": 3,
				"1024": 4,
				"2048": 4,
				"4096": 4,
				"8192": 4,
				"16384": 5,
				"32768": 5,
				"65536": 5,
				"131072": 5
			}
		},
		{
			shared: [
				{
					name: "domain",
					aliases: [
						"from"
					],
					description: "The `$domain` modifier limits the rule application area to a list of domains and their subdomains.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#domain-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: "pipe_separated_domains"
				},
				{
					name: "domain",
					aliases: [
						"from"
					],
					description: "The `$domain` modifier limits the rule application area to a list of domains and their subdomains.",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#from",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: "pipe_separated_domains"
				},
				{
					name: "domain",
					aliases: null,
					description: "The `$domain` modifier limits the rule application area to a list of domains and their subdomains.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293-How-to-write-filters#domain-restrictions",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: "pipe_separated_domains"
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"128": 0,
				"256": 0,
				"512": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "elemhide",
					aliases: [
						"ehide"
					],
					description: "Disables any cosmetic rules on the pages matching the rule.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#elemhide-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: true,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "elemhide",
					aliases: [
						"ehide"
					],
					description: "Disables any cosmetic rules on the pages matching the rule.",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#elemhide-1",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: true,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "elemhide",
					aliases: [
						"ehide"
					],
					description: "Disables any cosmetic rules on the pages matching the rule.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293-How-to-write-filters#type-options",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: true,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"128": 0,
				"256": 0,
				"512": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "empty",
					aliases: null,
					description: "This modifier is deprecated in favor of the $redirect modifier.\nRules with `$empty` are still supported and being converted into `$redirect=nooptext` now\nbut the support shall be removed in the future.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#empty-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: true,
					deprecationMessage: "Rules with `$empty` are still supported and being converted into `$redirect=nooptext` now\nbut the support shall be removed in the future.",
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "empty",
					aliases: null,
					description: "This modifier is deprecated in favor of the $redirect modifier.\nRules with `$empty` are still supported and being converted into `$redirect=nooptext` now\nbut the support shall be removed in the future.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#empty-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: true,
					deprecationMessage: "Rules with `$empty` are still supported and being converted into `$redirect=nooptext` now\nbut the support shall be removed in the future.",
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "empty",
					aliases: null,
					description: "This modifier is deprecated in favor of the $redirect modifier.\nRules with `$empty` are supported and being converted into `$redirect=nooptext`.",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#empty",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 1,
				"16": 1,
				"32": 1,
				"64": 1,
				"1024": 2,
				"2048": 2,
				"4096": 2,
				"8192": 2
			}
		},
		{
			shared: [
				{
					name: "extension",
					aliases: null,
					description: "Disables all userscripts on the pages matching this rule.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#extension-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"domain",
						"specifichide",
						"generichide",
						"elemhide",
						"genericblock",
						"urlblock",
						"jsinject",
						"content",
						"xmlhttprequest",
						"badfilter"
					],
					inverseConflicts: true,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: true,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0
			}
		},
		{
			shared: [
				{
					name: "first-party",
					aliases: [
						"1p",
						"~third-party"
					],
					description: "A restriction of first-party requests. Equal to `~third-party`.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#third-party-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "first-party",
					aliases: [
						"1p",
						"~third-party"
					],
					description: "A restriction of first-party requests. Equal to `~third-party`.",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#1p",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"128": 0,
				"256": 0,
				"512": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "font",
					aliases: null,
					description: "The rule corresponds to requests for fonts, e.g. `.woff` filename extension.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#font-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "font",
					aliases: null,
					description: "The rule corresponds to requests for fonts, e.g. `.woff` filename extension.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293#options",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "font",
					aliases: null,
					description: "The rule corresponds to requests for fonts, e.g. `.woff` filename extension.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293#options",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"128": 0,
				"256": 0,
				"512": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "genericblock",
					aliases: null,
					description: "Disables generic basic rules on pages that correspond to exception rule.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#genericblock-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"domain",
						"specifichide",
						"generichide",
						"elemhide",
						"extension",
						"jsinject",
						"content",
						"badfilter"
					],
					inverseConflicts: true,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: true,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "genericblock",
					aliases: null,
					description: "Disables generic basic rules on pages that correspond to exception rule.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#genericblock-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"domain",
						"specifichide",
						"generichide",
						"elemhide",
						"jsinject",
						"badfilter"
					],
					inverseConflicts: true,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: true,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "genericblock",
					aliases: null,
					description: "Disables generic basic rules on pages that correspond to exception rule.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#genericblock-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"domain",
						"specifichide",
						"generichide",
						"elemhide",
						"jsinject",
						"badfilter"
					],
					inverseConflicts: true,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: true,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "genericblock",
					aliases: null,
					description: "Disables generic basic rules on pages that correspond to exception rule.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#genericblock-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"domain",
						"specifichide",
						"generichide",
						"elemhide",
						"jsinject",
						"badfilter"
					],
					inverseConflicts: true,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: true,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "genericblock",
					aliases: null,
					description: "Disables generic basic rules on pages that correspond to exception rule.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293-How-to-write-filters#type-options",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: true,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 1,
				"16": 1,
				"32": 1,
				"64": 1,
				"256": 2,
				"512": 3,
				"16384": 4,
				"32768": 4,
				"65536": 4,
				"131072": 4
			}
		},
		{
			shared: [
				{
					name: "generichide",
					aliases: [
						"ghide"
					],
					description: "Disables all generic cosmetic rules.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#generichide-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"domain",
						"genericblock",
						"urlblock",
						"extension",
						"jsinject",
						"content",
						"xmlhttprequest",
						"badfilter"
					],
					inverseConflicts: true,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: true,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "generichide",
					aliases: [
						"ghide"
					],
					description: "Disables all generic cosmetic rules.",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#generichide",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"domain",
						"badfilter"
					],
					inverseConflicts: true,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: true,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "generichide",
					aliases: null,
					description: "Disables all generic cosmetic rules.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293-How-to-write-filters#type-options",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"domain"
					],
					inverseConflicts: true,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: true,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"128": 0,
				"256": 0,
				"512": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "header",
					aliases: null,
					description: "The `$header` modifier allows matching the HTTP response\nhaving a specific header with (optionally) a specific value.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#header-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: true,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: "(?xi)\n  ^\n    # header name\n    [\\w-]+\n    (\n      :\n      # header value: string or regexp\n      (\\w+|\\/.+\\/)\n    )?"
				},
				{
					name: "header",
					aliases: null,
					description: "The `$header` modifier allows matching the HTTP response\nhaving a specific header with (optionally) a specific value.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#header-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: true,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: "(?xi)\n  ^\n    # header name\n    [\\w-]+\n    (\n      :\n      # header value: string or regexp\n      (\\w+|\\/.+\\/)\n    )?"
				},
				{
					name: "header",
					aliases: null,
					description: "The `$header` modifier allows matching the HTTP response\nhaving a specific header with (optionally) a specific value.",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#header",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: true,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: "(?xi)\n  ^\n    # header name\n    [\\w-]+\n    (\n      :\n      # header value: string or regexp\n      (\\w+|\\/.+\\/)\n    )?"
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 1,
				"16": 1,
				"32": 1,
				"64": 1,
				"1024": 2,
				"2048": 2,
				"4096": 2,
				"8192": 2
			}
		},
		{
			shared: [
				{
					name: "hls",
					aliases: null,
					description: "The `$hls` rules modify the response of a matching request.\nThey are intended as a convenient way to remove segments from HLS playlists (RFC 8216).",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#hls-modifier",
					versionAdded: "CoreLibs 1.10",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"domain",
						"third-party",
						"app",
						"important",
						"match-case",
						"xmlhttprequest"
					],
					inverseConflicts: true,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: true,
					valueFormat: "(?xi)\n  (\n    # string pattern\n    \\w+\n    # or regexp pattern\n    |\n    # TODO: improve regexp pattern to invalidate unescaped `/`, `$`, and `,`\n    \\/.+\\/\n      # options\n      ([ti]*)?\n  )"
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0
			}
		},
		{
			shared: [
				{
					name: "image",
					aliases: null,
					description: "The rule corresponds to images requests.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#image-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "image",
					aliases: null,
					description: "The rule corresponds to images requests.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293#options",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "image",
					aliases: null,
					description: "The rule corresponds to images requests.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293#options",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"128": 0,
				"256": 0,
				"512": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "important",
					aliases: null,
					description: "The `$important` modifier applied to a rule increases its priority\nover any other rule without `$important` modifier. Even over basic exception rules.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#important-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "important",
					aliases: null,
					description: "The `$important` modifier applied to a rule increases its priority\nover any other rule without `$important` modifier. Even over basic exception rules.",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#important",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"128": 0,
				"256": 0,
				"512": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "inline-font",
					aliases: null,
					description: "The `$inline-font` modifier is a sort of a shortcut for $csp modifier with specific value.\nE.g. `||example.org^$inline-font` is converting into:\n```adblock\n||example.org^$csp=font-src 'self' 'unsafe-eval' http: https: data: blob: mediastream: filesystem:\n```",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#inline-font-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "inline-font",
					aliases: null,
					description: "The `$inline-font` modifier is a sort of a shortcut for $csp modifier with specific value.\nE.g. `||example.org^$inline-font` is converting into:\n```adblock\n||example.org^$csp=font-src 'self' 'unsafe-eval' http: https: data: blob: mediastream: filesystem:\n```",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#inline-font-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "inline-font",
					aliases: null,
					description: "The `$inline-font` modifier is a sort of a shortcut for $csp modifier with specific value.\nE.g. `||example.org^$inline-font` is converting into:\n```adblock\n||example.org^$csp=font-src 'self' 'unsafe-eval' http: https: data: blob: mediastream: filesystem:\n```",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#inline-font",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 1,
				"16": 1,
				"32": 1,
				"64": 1,
				"1024": 2,
				"2048": 2,
				"4096": 2,
				"8192": 2
			}
		},
		{
			shared: [
				{
					name: "inline-script",
					aliases: null,
					description: "The `$inline-script` modifier is a sort of a shortcut for $csp modifier with specific value.\nE.g. `||example.org^$inline-script` is converting into:\n```adblock\n||example.org^$csp=script-src 'self' 'unsafe-eval' http: https: data: blob: mediastream: filesystem:\n```",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#inline-script-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "inline-script",
					aliases: null,
					description: "The `$inline-script` modifier is a sort of a shortcut for $csp modifier with specific value.\nE.g. `||example.org^$inline-script` is converting into:\n```adblock\n||example.org^$csp=script-src 'self' 'unsafe-eval' http: https: data: blob: mediastream: filesystem:\n```",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#inline-script-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "inline-script",
					aliases: null,
					description: "The `$inline-script` modifier is a sort of a shortcut for $csp modifier with specific value.\nE.g. `||example.org^$inline-script` is converting into:\n```adblock\n||example.org^$csp=script-src 'self' 'unsafe-eval' http: https: data: blob: mediastream: filesystem:\n```",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#inline-script",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 1,
				"16": 1,
				"32": 1,
				"64": 1,
				"1024": 2,
				"2048": 2,
				"4096": 2,
				"8192": 2
			}
		},
		{
			shared: [
				{
					name: "jsinject",
					aliases: null,
					description: "Forbids adding of javascript code to the page.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#jsinject-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"domain",
						"specifichide",
						"generichide",
						"elemhide",
						"genericblock",
						"urlblock",
						"extension",
						"content",
						"xmlhttprequest",
						"badfilter"
					],
					inverseConflicts: true,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: true,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "jsinject",
					aliases: null,
					description: "Forbids adding of javascript code to the page.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#jsinject-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"domain",
						"specifichide",
						"generichide",
						"elemhide",
						"genericblock",
						"urlblock",
						"xmlhttprequest",
						"badfilter"
					],
					inverseConflicts: true,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: true,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "jsinject",
					aliases: null,
					description: "Forbids adding of javascript code to the page.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#jsinject-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"domain",
						"specifichide",
						"generichide",
						"elemhide",
						"genericblock",
						"urlblock",
						"xmlhttprequest",
						"badfilter"
					],
					inverseConflicts: true,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: true,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "jsinject",
					aliases: null,
					description: "Forbids adding of javascript code to the page.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#jsinject-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"domain",
						"specifichide",
						"generichide",
						"elemhide",
						"genericblock",
						"urlblock",
						"xmlhttprequest",
						"badfilter"
					],
					inverseConflicts: true,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: true,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 1,
				"16": 1,
				"32": 1,
				"64": 1,
				"256": 2,
				"512": 3
			}
		},
		{
			shared: [
				{
					name: "jsonprune",
					aliases: null,
					description: "The `$jsonprune` rules modify the response to a matching request\nby removing JSON items that match a modified JSONPath expression.\nThey do not modify responses which are not valid JSON documents.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#jsonprune-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: true,
					valueFormat: "(?xi)\n  ^\n    # the expression always starts with a dollar sign (for root)\n    # which should be escaped\n    \\\\\n    \\$\n    \\.?\n    # TODO: improve the expression to invalidate unescaped `$` and `,`\n    .+\n  $"
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0
			}
		},
		{
			shared: [
				{
					name: "match-case",
					aliases: null,
					description: "This modifier defines a rule which applies only to addresses that match the case.\nDefault rules are case-insensitive.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#match-case-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "match-case",
					aliases: null,
					description: "This modifier defines a rule which applies only to addresses that match the case.\nDefault rules are case-insensitive.",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#match-case",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "match-case",
					aliases: null,
					description: "This modifier defines a rule which applies only to addresses that match the case.\nDefault rules are case-insensitive.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293-How-to-write-filters#type-options",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"128": 0,
				"256": 0,
				"512": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "media",
					aliases: null,
					description: "A restriction of third-party and own requests.\nA third-party request is a request from a different domain.\nFor example, a request to `example.org` from `domain.com` is a third-party request.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#media-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "media",
					aliases: null,
					description: "A restriction of third-party and own requests.\nA third-party request is a request from a different domain.\nFor example, a request to `example.org` from `domain.com` is a third-party request.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293#options",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "media",
					aliases: null,
					description: "A restriction of third-party and own requests.\nA third-party request is a request from a different domain.\nFor example, a request to `example.org` from `domain.com` is a third-party request.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293#options",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"128": 0,
				"256": 0,
				"512": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "method",
					aliases: null,
					description: "This modifier limits the rule scope to requests that use the specified set of HTTP methods.\nNegated methods are allowed.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#method-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: "pipe_separated_methods"
				},
				{
					name: "method",
					aliases: null,
					description: "This modifier limits the rule scope to requests that use the specified set of HTTP methods.\nNegated methods are allowed.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#method-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: "pipe_separated_methods"
				},
				{
					name: "method",
					aliases: null,
					description: "This modifier limits the rule scope to requests that use the specified set of HTTP methods.\nNegated methods are allowed.",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#method",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: "pipe_separated_methods"
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 1,
				"16": 1,
				"32": 1,
				"64": 1,
				"1024": 2,
				"2048": 2,
				"4096": 2,
				"8192": 2
			}
		},
		{
			shared: [
				{
					name: "mp4",
					aliases: null,
					description: "As a response to blocked request AdGuard returns a short video placeholder.\nRules with `$mp4` are still supported and being converted into `$redirect=noopmp4-1s` now\nbut the support shall be removed in the future.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#mp4-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: true,
					deprecationMessage: "Rules with `$mp4` are still supported and being converted into `$redirect=noopmp4-1s` now\nbut the support shall be removed in the future.",
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "mp4",
					aliases: null,
					description: "As a response to blocked request AdGuard returns a short video placeholder.\nRules with `$mp4` are still supported and being converted into `$redirect=noopmp4-1s` now\nbut the support shall be removed in the future.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#mp4-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: true,
					deprecationMessage: "Rules with `$mp4` are still supported and being converted into `$redirect=noopmp4-1s` now\nbut the support shall be removed in the future.",
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "mp4",
					aliases: null,
					description: "As a response to blocked request a short video placeholder is returned.\nRules with `$mp4` are supported and being converted into `$redirect=noopmp4-1s`.",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#mp4",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 1,
				"16": 1,
				"32": 1,
				"64": 1,
				"1024": 2,
				"2048": 2,
				"4096": 2,
				"8192": 2
			}
		},
		{
			shared: [
				{
					name: "network",
					aliases: null,
					description: "This is basically a Firewall-kind of rules allowing to fully block\nor unblock access to a specified remote address.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#network-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"app",
						"important"
					],
					inverseConflicts: true,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0
			}
		},
		{
			shared: [
				{
					name: "_",
					aliases: null,
					description: "The noop modifier does nothing and can be used solely to increase rules' readability.\nIt consists of a sequence of underscore characters (_) of any length\nand can appear in a rule as many times as needed.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#noop-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "_",
					aliases: null,
					description: "The noop modifier does nothing and can be used solely to increase rules' readability.\nIt consists of a sequence of underscore characters (_) of any length\nand can appear in a rule as many times as needed.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#noop-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "_",
					aliases: null,
					description: "The noop modifier does nothing and can be used solely to increase rules' readability.\nIt consists of a sequence of underscore characters (_) of any length\nand can appear in a rule as many times as needed.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#noop-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "_",
					aliases: null,
					description: "The noop modifier does nothing and can be used solely to increase rules' readability.\nIt consists of a sequence of underscore characters (_) of any length\nand can appear in a rule as many times as needed.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#noop-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "_",
					aliases: null,
					description: "The noop modifier does nothing and can be used solely to increase rules' readability.\nIt consists of a sequence of underscore characters (_) of any length\nand can appear in a rule as many times as needed.",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#_-aka-noop",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 1,
				"16": 1,
				"32": 1,
				"64": 1,
				"256": 2,
				"512": 3,
				"1024": 4,
				"2048": 4,
				"4096": 4,
				"8192": 4
			}
		},
		{
			shared: [
				{
					name: "object-subrequest",
					aliases: null,
					description: "The `$object-subrequest` modifier is removed and is no longer supported.\nRules with it are considered as invalid.\nThe rule corresponds to requests by browser plugins (it is usually Flash).",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#object-subrequest-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: true,
					removalMessage: "The `$object-subrequest` modifier is removed and is no longer supported.\nRules with it are considered as invalid.",
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"128": 0,
				"256": 0,
				"512": 0
			}
		},
		{
			shared: [
				{
					name: "object",
					aliases: null,
					description: "The rule corresponds to browser plugins resources, e.g. Java or Flash",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#object-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "object",
					aliases: null,
					description: "The rule corresponds to browser plugins resources, e.g. Java or Flash.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293-How-to-write-filters#type-options",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "object",
					aliases: null,
					description: "The rule corresponds to browser plugins resources, e.g. Java or Flash.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293-How-to-write-filters#type-options",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"128": 0,
				"256": 0,
				"512": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "other",
					aliases: null,
					description: "The rule applies to requests for which the type has not been determined\nor does not match the types listed above.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#other-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "other",
					aliases: null,
					description: "The rule applies to requests for which the type has not been determined\nor does not match the types listed above.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293-How-to-write-filters#type-options",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "other",
					aliases: null,
					description: "The rule applies to requests for which the type has not been determined\nor does not match the types listed above.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293-How-to-write-filters#type-options",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"128": 0,
				"256": 0,
				"512": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "permissions",
					aliases: null,
					description: "For the requests matching a `$permissions` rule, ad blocker strengthens response's feature policy\nby adding additional feature policy equal to the `$permissions` modifier contents.\n`$permissions` rules are applied independently from any other rule type.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#permissions-modifier",
					versionAdded: "CoreLibs 1.11",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"domain",
						"important",
						"subdocument"
					],
					inverseConflicts: true,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: true,
					valueFormat: "permissions_value"
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0
			}
		},
		{
			shared: [
				{
					name: "ping",
					aliases: null,
					description: "The rule corresponds to requests caused by either navigator.sendBeacon() or the ping attribute on links.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#ping-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "ping",
					aliases: null,
					description: "The rule corresponds to requests caused by either navigator.sendBeacon() or the ping attribute on links.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293-How-to-write-filters#type-options",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "ping",
					aliases: null,
					description: "The rule corresponds to requests caused by either navigator.sendBeacon() or the ping attribute on links.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293-How-to-write-filters#type-options",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"128": 0,
				"256": 0,
				"512": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "popunder",
					aliases: null,
					description: "To block \"popunders\" windows/tabs where the original page redirects to an advertisement\nand the desired content loads in the newly created one.\nTo be used in the same manner as the popup filter option, except that it will block popunders.",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#popunder",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: true,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1024": 0,
				"2048": 0,
				"4096": 0,
				"8192": 0
			}
		},
		{
			shared: [
				{
					name: "popup",
					aliases: null,
					description: "Pages opened in a new tab or window.\nNote: Filters will not block pop-ups by default, only if the `$popup`  type option is specified.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#popup-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "popup",
					aliases: null,
					description: "Pages opened in a new tab or window.\nNote: Filters will not block pop-ups by default, only if the `$popup`  type option is specified.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293-How-to-write-filters#type-options",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "popup",
					aliases: null,
					description: "Pages opened in a new tab or window.\nNote: Filters will not block pop-ups by default, only if the `$popup`  type option is specified.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293-How-to-write-filters#type-options",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"128": 0,
				"256": 0,
				"512": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "redirect-rule",
					aliases: null,
					description: "This is basically an alias to `$redirect`\nsince it has the same \"redirection\" values and the logic is almost similar.\nThe difference is that `$redirect-rule` is applied only in the case\nwhen the target request is blocked by a different basic rule.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#redirect-rule-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"domain",
						"to",
						"third-party",
						"popup",
						"match-case",
						"header",
						"first-party",
						"document",
						"image",
						"stylesheet",
						"script",
						"object",
						"font",
						"media",
						"subdocument",
						"ping",
						"xmlhttprequest",
						"websocket",
						"other",
						"webrtc",
						"important",
						"badfilter",
						"app"
					],
					inverseConflicts: true,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: true,
					valueFormat: "(?x)\n  ^(\n    1x1-transparent\\.gif|\n    2x2-transparent\\.png|\n    3x2-transparent\\.png|\n    32x32-transparent\\.png|\n    noopframe|\n    noopcss|\n    noopjs|\n    noopjson|\n    nooptext|\n    empty|\n    noopvmap-1\\.0|\n    noopvast-2\\.0|\n    noopvast-3\\.0|\n    noopvast-4\\.0|\n    noopmp3-0\\.1s|\n    noopmp4-1s|\n    amazon-apstag|\n    ati-smarttag|\n    didomi-loader|\n    fingerprintjs2|\n    fingerprintjs3|\n    gemius|\n    google-analytics-ga|\n    google-analytics|\n    google-ima3|\n    googlesyndication-adsbygoogle|\n    googletagservices-gpt|\n    matomo|\n    metrika-yandex-tag|\n    metrika-yandex-watch|\n    naver-wcslog|\n    noeval|\n    pardot-1\\.0|\n    prebid-ads|\n    prebid|\n    prevent-bab|\n    prevent-bab2|\n    prevent-fab-3\\.2\\.0|\n    prevent-popads-net|\n    scorecardresearch-beacon|\n    set-popads-dummy|\n    click2load\\.html|\n  )?$"
				},
				{
					name: "redirect-rule",
					aliases: null,
					description: "This is basically an alias to `$redirect`\nsince it has the same \"redirection\" values and the logic is almost similar.\nThe difference is that `$redirect-rule` is applied only in the case\nwhen the target request is blocked by a different basic rule.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#redirect-rule-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"domain",
						"to",
						"third-party",
						"popup",
						"match-case",
						"header",
						"first-party",
						"document",
						"image",
						"stylesheet",
						"script",
						"object",
						"font",
						"media",
						"subdocument",
						"ping",
						"xmlhttprequest",
						"websocket",
						"other",
						"webrtc",
						"important",
						"badfilter"
					],
					inverseConflicts: true,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: true,
					valueFormat: "(?x)\n  ^(\n    1x1-transparent\\.gif|\n    2x2-transparent\\.png|\n    3x2-transparent\\.png|\n    32x32-transparent\\.png|\n    noopframe|\n    noopcss|\n    noopjs|\n    noopjson|\n    nooptext|\n    empty|\n    noopvmap-1\\.0|\n    noopvast-2\\.0|\n    noopvast-3\\.0|\n    noopvast-4\\.0|\n    noopmp3-0\\.1s|\n    noopmp4-1s|\n    amazon-apstag|\n    ati-smarttag|\n    didomi-loader|\n    fingerprintjs2|\n    fingerprintjs3|\n    gemius|\n    google-analytics-ga|\n    google-analytics|\n    google-ima3|\n    googlesyndication-adsbygoogle|\n    googletagservices-gpt|\n    matomo|\n    metrika-yandex-tag|\n    metrika-yandex-watch|\n    naver-wcslog|\n    noeval|\n    pardot-1\\.0|\n    prebid-ads|\n    prebid|\n    prevent-bab|\n    prevent-bab2|\n    prevent-fab-3\\.2\\.0|\n    prevent-popads-net|\n    scorecardresearch-beacon|\n    set-popads-dummy|\n    click2load\\.html|\n  )?$"
				},
				{
					name: "redirect-rule",
					aliases: null,
					description: "This is basically an alias to `$redirect`\nsince it has the same \"redirection\" values and the logic is almost similar.\nThe difference is that `$redirect-rule` is applied only in the case\nwhen the target request is blocked by a different basic rule.",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#redirect-rule",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"domain",
						"to",
						"third-party",
						"popup",
						"match-case",
						"header",
						"first-party",
						"document",
						"image",
						"stylesheet",
						"script",
						"object",
						"font",
						"media",
						"subdocument",
						"ping",
						"xmlhttprequest",
						"websocket",
						"other",
						"webrtc",
						"important",
						"badfilter"
					],
					inverseConflicts: true,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: "(?x)\n  ^(\n    1x1\\.gif|\n    2x2\\.png|\n    3x2\\.png|\n    32x32\\.png|\n    noop\\.css|\n    noop\\.html|\n    noopframe|\n    noop\\.js|\n    noop\\.txt|\n    noop-0\\.1s\\.mp3|\n    noop-0\\.5s\\.mp3|\n    noop-1s\\.mp4|\n    none|\n    click2load\\.html|\n    addthis_widget\\.js|\n    amazon_ads\\.js|\n    amazon_apstag\\.js|\n    monkeybroker\\.js|\n    doubleclick_instream_ad_status|\n    google-analytics_ga\\.js|\n    google-analytics_analytics\\.js|\n    google-analytics_inpage_linkid\\.js|\n    google-analytics_cx_api\\.js|\n    google-ima\\.js|\n    googletagservices_gpt\\.js|\n    googletagmanager_gtm\\.js|\n    googlesyndication_adsbygoogle\\.js|\n    scorecardresearch_beacon\\.js|\n    outbrain-widget\\.js|\n    hd-main\\.js\n  )\n  (:[0-9]+)?$"
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 1,
				"16": 1,
				"32": 1,
				"64": 1,
				"1024": 2,
				"2048": 2,
				"4096": 2,
				"8192": 2
			}
		},
		{
			shared: [
				{
					name: "redirect",
					aliases: null,
					description: "Used to redirect web requests to a local \"resource\".",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#redirect-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: true,
					valueFormat: "(?x)\n  ^(\n    1x1-transparent\\.gif|\n    2x2-transparent\\.png|\n    3x2-transparent\\.png|\n    32x32-transparent\\.png|\n    noopframe|\n    noopcss|\n    noopjs|\n    noopjson|\n    nooptext|\n    empty|\n    noopvmap-1\\.0|\n    noopvast-2\\.0|\n    noopvast-3\\.0|\n    noopvast-4\\.0|\n    noopmp3-0\\.1s|\n    noopmp4-1s|\n    amazon-apstag|\n    ati-smarttag|\n    didomi-loader|\n    fingerprintjs2|\n    fingerprintjs3|\n    gemius|\n    google-analytics-ga|\n    google-analytics|\n    googletagmanager-gtm|\n    google-ima3|\n    googlesyndication-adsbygoogle|\n    googletagservices-gpt|\n    matomo|\n    metrika-yandex-tag|\n    metrika-yandex-watch|\n    naver-wcslog|\n    noeval|\n    pardot-1\\.0|\n    prebid-ads|\n    prebid|\n    prevent-bab|\n    prevent-bab2|\n    prevent-fab-3\\.2\\.0|\n    prevent-popads-net|\n    scorecardresearch-beacon|\n    set-popads-dummy|\n    click2load\\.html\n  )?$"
				},
				{
					name: "redirect",
					aliases: null,
					description: "Used to redirect web requests to a local \"resource\".",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#redirect-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: true,
					valueFormat: "(?x)\n  ^(\n    1x1-transparent\\.gif|\n    2x2-transparent\\.png|\n    3x2-transparent\\.png|\n    32x32-transparent\\.png|\n    noopframe|\n    noopcss|\n    noopjs|\n    noopjson|\n    nooptext|\n    empty|\n    noopvmap-1\\.0|\n    noopvast-2\\.0|\n    noopvast-3\\.0|\n    noopvast-4\\.0|\n    noopmp3-0\\.1s|\n    noopmp4-1s|\n    amazon-apstag|\n    ati-smarttag|\n    didomi-loader|\n    fingerprintjs2|\n    fingerprintjs3|\n    gemius|\n    google-analytics-ga|\n    google-analytics|\n    googletagmanager-gtm|\n    google-ima3|\n    googlesyndication-adsbygoogle|\n    googletagservices-gpt|\n    matomo|\n    metrika-yandex-tag|\n    metrika-yandex-watch|\n    naver-wcslog|\n    noeval|\n    pardot-1\\.0|\n    prebid-ads|\n    prebid|\n    prevent-bab|\n    prevent-bab2|\n    prevent-fab-3\\.2\\.0|\n    prevent-popads-net|\n    scorecardresearch-beacon|\n    set-popads-dummy|\n    click2load\\.html\n  )?$"
				},
				{
					name: "redirect",
					aliases: null,
					description: "Used to redirect web requests to a local \"resource\".",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#redirect",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: true,
					valueFormat: "(?x)\n  ^(\n    1x1\\.gif|\n    2x2\\.png|\n    3x2\\.png|\n    32x32\\.png|\n    noop\\.css|\n    noop\\.html|\n    noopframe|\n    noop\\.js|\n    noop\\.txt|\n    noop-0\\.1s\\.mp3|\n    noop-0\\.5s\\.mp3|\n    noop-1s\\.mp4|\n    none|\n    click2load\\.html|\n    addthis_widget\\.js|\n    amazon_ads\\.js|\n    amazon_apstag\\.js|\n    monkeybroker\\.js|\n    doubleclick_instream_ad_status|\n    google-analytics_ga\\.js|\n    google-analytics_analytics\\.js|\n    google-analytics_inpage_linkid\\.js|\n    google-analytics_cx_api\\.js|\n    google-ima\\.js|\n    googletagservices_gpt\\.js|\n    googletagmanager_gtm\\.js|\n    googlesyndication_adsbygoogle\\.js|\n    scorecardresearch_beacon\\.js|\n    outbrain-widget\\.js|\n    hd-main\\.js\n  )\n  (:[0-9]+)?$"
				},
				{
					name: "rewrite",
					aliases: null,
					description: "The `rewrite=` option allows the rewriting of URLs (or redirecting requests) to an internal\nresource in order to deactivate it without causing an error. Indicate the internal resource\nby name and prefix `abp-resource:` in order to be recognized. For example\n`$rewrite=abp-resource:blank-js` sends an empty JavaScript.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293#rewrite",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: "(?x)\n  # ABP resources always starts with the `abp-resource:` prefix\n  ^abp-resource:\n  # Possible resource names\n  (\n    blank-text|\n    blank-css|\n    blank-js|\n    blank-html|\n    blank-mp3|\n    1x1-transparent-gif|\n    2x2-transparent-png|\n    3x2-transparent-png|\n    32x32-transparent-png\n  )$"
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 1,
				"16": 1,
				"32": 1,
				"64": 1,
				"1024": 2,
				"2048": 2,
				"4096": 2,
				"8192": 2,
				"16384": 3,
				"32768": 3,
				"65536": 3,
				"131072": 3
			}
		},
		{
			shared: [
				{
					name: "referrerpolicy",
					aliases: null,
					description: "This modifier allows overriding of a page's referrer policy.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#referrerpolicy-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"document",
						"subdocument"
					],
					inverseConflicts: true,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: true,
					valueFormat: "referrerpolicy_value"
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0
			}
		},
		{
			shared: [
				{
					name: "removeheader",
					aliases: null,
					description: "Rules with the `$removeheader` modifier are intended to remove headers from HTTP requests and responses.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#removeheader-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"domain",
						"third-party",
						"first-party",
						"app",
						"important",
						"match-case",
						"document",
						"image",
						"stylesheet",
						"script",
						"object",
						"font",
						"media",
						"subdocument",
						"ping",
						"xmlhttpreqeust",
						"websocket",
						"other",
						"webrtc"
					],
					inverseConflicts: true,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: true,
					valueFormat: "(?xi)\n  ^\n    # Value may start with \"request:\"\n    (request:)?\n\n    # Forbidden header names\n    (?!\n      (\n        access-control-allow-origin|\n        access-control-allow-credentials|\n        access-control-allow-headers|\n        access-control-allow-methods|\n        access-control-expose-headers|\n        access-control-max-age|\n        access-control-request-headers|\n        access-control-request-method|\n        origin|\n        timing-allow-origin|\n        allow|\n        cross-origin-embedder-policy|\n        cross-origin-opener-policy|\n        cross-origin-resource-policy|\n        content-security-policy|\n        content-security-policy-report-only|\n        expect-ct|\n        feature-policy|\n        origin-isolation|\n        strict-transport-security|\n        upgrade-insecure-requests|\n        x-content-type-options|\n        x-download-options|\n        x-frame-options|\n        x-permitted-cross-domain-policies|\n        x-powered-by|\n        x-xss-protection|\n        public-key-pins|\n        public-key-pins-report-only|\n        sec-websocket-key|\n        sec-websocket-extensions|\n        sec-websocket-accept|\n        sec-websocket-protocol|\n        sec-websocket-version|\n        p3p|\n        sec-fetch-mode|\n        sec-fetch-dest|\n        sec-fetch-site|\n        sec-fetch-user|\n        referrer-policy|\n        content-type|\n        content-length|\n        accept|\n        accept-encoding|\n        host|\n        connection|\n        transfer-encoding|\n        upgrade\n      )\n    $)\n\n    # Any other header name is allowed, if it matches the following regex\n    [A-z0-9-]+\n  $"
				},
				{
					name: "removeheader",
					aliases: null,
					description: "Rules with the `$removeheader` modifier are intended to remove headers from HTTP requests and responses.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#removeheader-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"domain",
						"third-party",
						"first-party",
						"app",
						"important",
						"match-case",
						"document",
						"image",
						"stylesheet",
						"script",
						"object",
						"font",
						"media",
						"subdocument",
						"ping",
						"xmlhttpreqeust",
						"websocket",
						"other",
						"webrtc"
					],
					inverseConflicts: true,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: true,
					valueFormat: "(?xi)\n  ^\n    # Value may start with \"request:\"\n    (request:)?\n\n    # Forbidden header names\n    (?!\n      (\n        access-control-allow-origin|\n        access-control-allow-credentials|\n        access-control-allow-headers|\n        access-control-allow-methods|\n        access-control-expose-headers|\n        access-control-max-age|\n        access-control-request-headers|\n        access-control-request-method|\n        origin|\n        timing-allow-origin|\n        allow|\n        cross-origin-embedder-policy|\n        cross-origin-opener-policy|\n        cross-origin-resource-policy|\n        content-security-policy|\n        content-security-policy-report-only|\n        expect-ct|\n        feature-policy|\n        origin-isolation|\n        strict-transport-security|\n        upgrade-insecure-requests|\n        x-content-type-options|\n        x-download-options|\n        x-frame-options|\n        x-permitted-cross-domain-policies|\n        x-powered-by|\n        x-xss-protection|\n        public-key-pins|\n        public-key-pins-report-only|\n        sec-websocket-key|\n        sec-websocket-extensions|\n        sec-websocket-accept|\n        sec-websocket-protocol|\n        sec-websocket-version|\n        p3p|\n        sec-fetch-mode|\n        sec-fetch-dest|\n        sec-fetch-site|\n        sec-fetch-user|\n        referrer-policy|\n        content-type|\n        content-length|\n        accept|\n        accept-encoding|\n        host|\n        connection|\n        transfer-encoding|\n        upgrade\n      )\n    $)\n\n    # Any other header name is allowed, if it matches the following regex\n    [A-z0-9-]+\n  $"
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 1,
				"16": 1,
				"32": 1,
				"64": 1
			}
		},
		{
			shared: [
				{
					name: "removeparam",
					aliases: null,
					description: "Rules with the `$removeparam` modifier are intended to strip query parameters from requests' URLs.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#removeparam-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: true,
					valueFormat: "(?xi)\n  (\n    # string pattern\n    \\w+\n    # or regexp pattern\n    |\n    \\/.+\\/\n      # flags\n      ([gimuy]+)?\n  )"
				},
				{
					name: "removeparam",
					aliases: null,
					description: "Rules with the `$removeparam` modifier are intended to strip query parameters from requests' URLs.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#removeparam-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: true,
					valueFormat: "(?xi)\n  (\n    # string pattern\n    \\w+\n    # or regexp pattern\n    |\n    \\/.+\\/\n      # flags\n      ([gimuy]+)?\n  )"
				},
				{
					name: "removeparam",
					aliases: null,
					description: "Rules with the `$removeparam` modifier are intended to strip query parameters from requests' URLs.",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#removeparam",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: "(?xi)\n  (\n    # string pattern\n    \\w+\n    # or regexp pattern\n    |\n    \\/.+\\/\n      # flags\n      ([gimuy]+)?\n  )"
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 1,
				"16": 1,
				"32": 1,
				"64": 1,
				"1024": 2,
				"2048": 2,
				"4096": 2,
				"8192": 2
			}
		},
		{
			shared: [
				{
					name: "replace",
					aliases: null,
					description: "This modifier completely changes the rule behavior.\nIf it is applied, the rule will not block the request. The response is going to be modified instead.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#replace-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"app",
						"domain",
						"document",
						"subdocument",
						"script",
						"stylesheet",
						"other",
						"xmlhttprequest",
						"first-party",
						"third-party",
						"important",
						"badfilter"
					],
					inverseConflicts: true,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: "(?xi)\n  ^\n    \\/\n      # the regexp to match by\n      (.+)\n    # separator\n    \\/\n      # replacement\n      (.+)?\n    \\/\n      # flags\n      ([gimuy]*)?\n  $"
				},
				{
					name: "replace",
					aliases: null,
					description: "This modifier completely changes the rule behavior.\nIf it is applied, the rule will not block the request. The response is going to be modified instead.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#replace-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"app",
						"domain",
						"document",
						"subdocument",
						"script",
						"stylesheet",
						"other",
						"xmlhttprequest",
						"first-party",
						"third-party",
						"important",
						"badfilter"
					],
					inverseConflicts: true,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: "(?xi)\n  ^\n    \\/\n      # the regexp to match by\n      (.+)\n    # separator\n    \\/\n      # replacement\n      (.+)?\n    \\/\n      # flags\n      ([gimuy]*)?\n  $"
				},
				{
					name: "replace",
					aliases: null,
					description: "This modifier completely changes the rule behavior.\nIf it is applied, the rule will not block the request. The response is going to be modified instead.",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#replace",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"app",
						"domain",
						"document",
						"subdocument",
						"script",
						"stylesheet",
						"other",
						"xmlhttprequest",
						"first-party",
						"third-party",
						"important",
						"badfilter"
					],
					inverseConflicts: true,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: "(?xi)\n  ^\n    \\/\n      # the regexp to match by\n      (.+)\n    # separator\n    \\/\n      # replacement\n      (.+)?\n    \\/\n      # flags\n      ([gimuy]*)?\n  $"
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"64": 1,
				"8192": 2
			}
		},
		{
			shared: [
				{
					name: "script",
					aliases: null,
					description: "The rule corresponds to script requests, e.g. javascript, vbscript.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#script-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "script",
					aliases: null,
					description: "The rule corresponds to script requests, e.g. javascript, vbscript.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293#options",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "script",
					aliases: null,
					description: "The rule corresponds to script requests, e.g. javascript, vbscript.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293-How-to-write-filters#type-options",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"128": 0,
				"256": 0,
				"512": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "specifichide",
					aliases: [
						"shide"
					],
					description: "Disables all specific element hiding and CSS rules, but not general ones.\nHas an opposite effect to `$generichide`.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#specifichide-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"domain",
						"genericblock",
						"urlblock",
						"extension",
						"jsinject",
						"content",
						"xmlhttprequest",
						"badfilter"
					],
					inverseConflicts: true,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: true,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "specifichide",
					aliases: [
						"shide"
					],
					description: "Disables all specific element hiding and CSS rules, but not general ones.\nHas an opposite effect to `$generichide`.",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#specifichide",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"domain",
						"badfilter"
					],
					inverseConflicts: true,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: true,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"128": 0,
				"256": 0,
				"512": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "stealth",
					aliases: null,
					description: "Disables the Stealth Mode module for all corresponding pages and requests.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#stealth-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: true,
					valueOptional: true,
					valueFormat: "pipe_separated_stealth_options"
				},
				{
					name: "stealth",
					aliases: null,
					description: "Disables the Stealth Mode module for all corresponding pages and requests.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#stealth-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: true,
					valueOptional: true,
					valueFormat: "pipe_separated_stealth_options"
				},
				{
					name: "stealth",
					aliases: null,
					description: "Disables the Stealth Mode module for all corresponding pages and requests.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#stealth-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: true,
					valueOptional: true,
					valueFormat: "pipe_separated_stealth_options"
				},
				{
					name: "stealth",
					aliases: null,
					description: "Disables the Stealth Mode module for all corresponding pages and requests.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#stealth-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: true,
					valueOptional: true,
					valueFormat: "pipe_separated_stealth_options"
				},
				{
					name: "stealth",
					aliases: null,
					description: "Disables the Stealth Mode module for all corresponding pages and requests.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#stealth-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: true,
					valueOptional: true,
					valueFormat: "pipe_separated_stealth_options"
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 1,
				"16": 2,
				"32": 3,
				"64": 4
			}
		},
		{
			shared: [
				{
					name: "strict1p",
					aliases: null,
					description: "This new `strict1p` option can check for strict partyness.\nFor example, a network request qualifies as 1st-party if both the context and the request share the same hostname.",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#strict1p",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1024": 0,
				"2048": 0,
				"4096": 0,
				"8192": 0
			}
		},
		{
			shared: [
				{
					name: "strict3p",
					aliases: null,
					description: "This new `strict3p` option can check for strict partyness.\nFor example, a network request qualifies as 3rd-party if the context and the request hostnames are different.",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#strict3p",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1024": 0,
				"2048": 0,
				"4096": 0,
				"8192": 0
			}
		},
		{
			shared: [
				{
					name: "stylesheet",
					aliases: null,
					description: "The rule corresponds to CSS files requests.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#stylesheet-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "stylesheet",
					aliases: [
						"css"
					],
					description: "The rule corresponds to CSS files requests.",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#css",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "stylesheet",
					aliases: null,
					description: "The rule corresponds to CSS files requests.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293-How-to-write-filters#type-options",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"128": 0,
				"256": 0,
				"512": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "subdocument",
					aliases: null,
					description: "The rule corresponds to requests for built-in pages — HTML tags frame and iframe.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#subdocument-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "subdocument",
					aliases: [
						"frame"
					],
					description: "The rule corresponds to requests for built-in pages — HTML tags frame and iframe.",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#frame",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "subdocument",
					aliases: null,
					description: "The rule corresponds to requests for built-in pages — HTML tags frame and iframe.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293-How-to-write-filters#type-options",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"128": 0,
				"256": 0,
				"512": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "third-party",
					aliases: [
						"3p"
					],
					description: "A restriction of third-party and own requests.\nA third-party request is a request from a different domain.\nFor example, a request to `example.org` from `domain.com` is a third-party request.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#third-party-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "3p",
					aliases: [
						"third-party"
					],
					description: "A restriction of third-party and own requests.\nA third-party request is a request from a different domain.\nFor example, a request to `example.org` from `domain.com` is a third-party request.",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#3p",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "third-party",
					aliases: null,
					description: "A restriction of third-party and own requests.\nA third-party request is a request from a different domain.\nFor example, a request to `example.org` from `domain.com` is a third-party request.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293#party-requests",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"128": 0,
				"256": 0,
				"512": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "to",
					aliases: null,
					description: "`$to` limits the rule scope to requests made to the specified domains and their subdomains.\nTo add multiple domains to one rule, use the `|` character as a separator.",
					docs: "https://adguard.com/kb/general/ad-filtering/create-own-filters/#to-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"denyallow"
					],
					inverseConflicts: false,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: "pipe_separated_domains"
				},
				{
					name: "to",
					aliases: null,
					description: "`$to` limits the rule scope to requests made to the specified domains and their subdomains.\nTo add multiple domains to one rule, use the `|` character as a separator.",
					docs: "https://adguard.com/kb/general/ad-filtering/create-own-filters/#to-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"denyallow"
					],
					inverseConflicts: false,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: "pipe_separated_domains"
				},
				{
					name: "to",
					aliases: null,
					description: "The main motivation of this option is\nto give static network filtering engine an equivalent of DNR's `requestDomains` and `excludedRequestDomains`.",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#to",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"denyallow"
					],
					inverseConflicts: false,
					assignable: true,
					negatable: false,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: "pipe_separated_domains"
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 1,
				"16": 1,
				"32": 1,
				"64": 1,
				"1024": 2,
				"2048": 2,
				"4096": 2,
				"8192": 2
			}
		},
		{
			shared: [
				{
					name: "urlblock",
					aliases: null,
					description: "Disables blocking of all requests sent from the pages matching the rule.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#urlblock-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: [
						"domain",
						"specifichide",
						"generichide",
						"elemhide",
						"extension",
						"jsinject",
						"content",
						"badfilter"
					],
					inverseConflicts: true,
					assignable: false,
					negatable: false,
					blockOnly: false,
					exceptionOnly: true,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"128": 0,
				"256": 0,
				"512": 0
			}
		},
		{
			shared: [
				{
					name: "webrtc",
					aliases: null,
					description: "The rule applies only to WebRTC connections.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#webrtc-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: true,
					removalMessage: "This modifier is removed and is no longer supported.\nRules with it are considered as invalid. If you need to suppress WebRTC, consider using\nthe [nowebrtc scriptlet](https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#nowebrtc).",
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "webrtc",
					aliases: null,
					description: "The rule applies only to WebRTC connections.",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: true,
					removalMessage: "This modifier is removed and is no longer supported.\nIf you need to suppress WebRTC, consider using\nthe [nowebrtc scriptlet](https://github.com/gorhill/uBlock/wiki/Resources-Library#nowebrtcjs-).",
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "webrtc",
					aliases: null,
					description: "The rule applies only to WebRTC connections.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293-How-to-write-filters#type-options",
					versionAdded: "1.13.3",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"128": 0,
				"256": 0,
				"512": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "websocket",
					aliases: null,
					description: "The rule applies only to WebSocket connections.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#websocket-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "websocket",
					aliases: null,
					description: "The rule applies only to WebSocket connections.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#websocket-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "websocket",
					aliases: null,
					description: "The rule applies only to WebSocket connections.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#websocket-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "websocket",
					aliases: null,
					description: "The rule applies only to WebSocket connections.",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#websocket-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "websocket",
					aliases: null,
					description: "The rule applies only to WebSocket connections.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293-How-to-write-filters#type-options",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "websocket",
					aliases: null,
					description: "The rule applies only to WebSocket connections.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293-How-to-write-filters#type-options",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 1,
				"16": 1,
				"32": 1,
				"64": 1,
				"256": 2,
				"512": 3,
				"1024": 4,
				"2048": 4,
				"4096": 4,
				"8192": 4,
				"16384": 5,
				"32768": 5,
				"65536": 5,
				"131072": 5
			}
		},
		{
			shared: [
				{
					name: "xmlhttprequest",
					aliases: [
						"xhr"
					],
					description: "The rule applies only to ajax requests (requests sent via javascript object XMLHttpRequest).",
					docs: "https://adguard.app/kb/general/ad-filtering/create-own-filters/#xmlhttprequest-modifier",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "xhr",
					aliases: [
						"xmlhttprequest"
					],
					description: "The rule applies only to ajax requests (requests sent via javascript object XMLHttpRequest).",
					docs: "https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#xhr",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				},
				{
					name: "xmlhttprequest",
					aliases: null,
					description: "The rule applies only to ajax requests (requests sent via javascript object XMLHttpRequest).",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293-How-to-write-filters#type-options",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					conflicts: null,
					inverseConflicts: false,
					assignable: false,
					negatable: true,
					blockOnly: false,
					exceptionOnly: false,
					valueOptional: false,
					valueFormat: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"128": 0,
				"256": 0,
				"512": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		}
	],
	map: {
		all: 0,
		app: 1,
		badfilter: 2,
		cname: 3,
		content: 4,
		cookie: 5,
		csp: 6,
		denyallow: 7,
		document: 8,
		doc: 8,
		domain: 9,
		from: 9,
		elemhide: 10,
		ehide: 10,
		empty: 11,
		extension: 12,
		"first-party": 13,
		"1p": 13,
		"~third-party": 13,
		font: 14,
		genericblock: 15,
		generichide: 16,
		ghide: 16,
		header: 17,
		hls: 18,
		image: 19,
		important: 20,
		"inline-font": 21,
		"inline-script": 22,
		jsinject: 23,
		jsonprune: 24,
		"match-case": 25,
		media: 26,
		method: 27,
		mp4: 28,
		network: 29,
		_: 30,
		"object-subrequest": 31,
		object: 32,
		other: 33,
		permissions: 34,
		ping: 35,
		popunder: 36,
		popup: 37,
		"redirect-rule": 38,
		redirect: 39,
		rewrite: 39,
		referrerpolicy: 40,
		removeheader: 41,
		removeparam: 42,
		replace: 43,
		script: 44,
		specifichide: 45,
		shide: 45,
		stealth: 46,
		strict1p: 47,
		strict3p: 48,
		stylesheet: 49,
		css: 49,
		subdocument: 50,
		frame: 50,
		"third-party": 51,
		"3p": 51,
		to: 52,
		urlblock: 53,
		webrtc: 54,
		websocket: 55,
		xmlhttprequest: 56,
		xhr: 56
	}
};
var redirectsCompatibilityTableData = {
	shared: [
		{
			shared: [
				{
					name: "1x1-transparent.gif",
					aliases: [
						"1x1.gif",
						"1x1-transparent-gif"
					],
					description: "Redirects to a 1x1 transparent GIF.",
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-redirects.md#1x1-transparent.gif",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				},
				{
					name: "1x1.gif",
					aliases: null,
					description: "Redirects to a 1x1 transparent GIF.",
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#available-empty-redirect-resources",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"image"
					]
				},
				{
					name: "1x1-transparent-gif",
					aliases: null,
					description: "Redirects to a 1x1 transparent GIF.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293#rewrite",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "2x2-transparent.png",
					aliases: [
						"2x2.png",
						"2x2-transparent-png"
					],
					description: "Redirects to a 2x2 transparent PNG.",
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-redirects.md#2x2-transparent.png",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				},
				{
					name: "2x2.png",
					aliases: null,
					description: "Redirects to a 2x2 transparent PNG.",
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#available-empty-redirect-resources",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"image"
					]
				},
				{
					name: "2x2-transparent-png",
					aliases: null,
					description: "Redirects to a 2x2 transparent PNG.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293#rewrite",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "32x32-transparent.png",
					aliases: [
						"32x32.png",
						"32x32-transparent-png"
					],
					description: "Redirects to a 32x32 transparent PNG.",
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-redirects.md#32x32-transparent.png",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				},
				{
					name: "32x32.png",
					aliases: null,
					description: "Redirects to a 32x32 transparent PNG.",
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#available-empty-redirect-resources",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"image"
					]
				},
				{
					name: "32x32-transparent-png",
					aliases: null,
					description: "Redirects to a 32x32 transparent PNG.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293#rewrite",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "3x2-transparent.png",
					aliases: [
						"3x2.png",
						"3x2-transparent-png"
					],
					description: "Redirects to a 3x2 transparent PNG.",
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-redirects.md#3x2-transparent.png",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				},
				{
					name: "3x2.png",
					aliases: null,
					description: "Redirects to a 3x2 transparent PNG.",
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#available-empty-redirect-resources",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"image"
					]
				},
				{
					name: "3x2-transparent-png",
					aliases: null,
					description: "Redirects to a 3x2 transparent PNG.",
					docs: "https://help.adblockplus.org/hc/en-us/articles/360062733293#rewrite",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "amazon-apstag",
					aliases: [
						"ubo-amazon_apstag.js",
						"amazon_apstag.js"
					],
					description: "Mocks Amazon's apstag.js",
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-redirects.md#amazon-apstag",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				},
				{
					name: "amazon_apstag.js",
					aliases: null,
					description: "Mocks Amazon's apstag.js",
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#amazon_apstagjs-",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"script"
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "amazon_ads.js",
					aliases: null,
					description: null,
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"script"
					]
				}
			],
			map: {
				"1024": 0,
				"2048": 0,
				"4096": 0,
				"8192": 0
			}
		},
		{
			shared: [
				{
					name: "ampproject_v0.js",
					aliases: null,
					description: null,
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"script"
					]
				}
			],
			map: {
				"1024": 0,
				"2048": 0,
				"4096": 0,
				"8192": 0
			}
		},
		{
			shared: [
				{
					name: "ati-smarttag",
					aliases: null,
					description: null,
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "chartbeat.js",
					aliases: null,
					description: null,
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"script"
					]
				}
			],
			map: {
				"1024": 0,
				"2048": 0,
				"4096": 0,
				"8192": 0
			}
		},
		{
			shared: [
				{
					name: "click2load.html",
					aliases: [
						"click2load.html",
						"ubo-click2load.html"
					],
					description: "Redirects resource and replaces supposed content by decoy frame with button for original content recovering.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: true,
					resourceTypes: [
					]
				},
				{
					name: "click2load.html",
					aliases: null,
					description: "Redirects resource and replaces supposed content by decoy frame with button for original content recovering.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: true,
					resourceTypes: [
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "didomi-loader",
					aliases: null,
					description: "Mocks Didomi's CMP loader script.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "empty",
					aliases: null,
					description: "Redirects to an empty file.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				},
				{
					name: "empty",
					aliases: null,
					description: "Redirects to an empty file.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "fingerprintjs2",
					aliases: [
						"fingerprint2.js"
					],
					description: "Mocks FingerprintJS2 script.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				},
				{
					name: "fingerprint2.js",
					aliases: null,
					description: "Mocks FingerprintJS2 script.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"script"
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "fingerprintjs3",
					aliases: [
						"fingerprint3.js"
					],
					description: "Mocks FingerprintJS v3.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				},
				{
					name: "fingerprint3.js",
					aliases: null,
					description: "Mocks FingerprintJS v3.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"script"
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "gemius",
					aliases: null,
					description: "Mocks Gemius Analytics.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "google-analytics-ga",
					aliases: [
						"ubo-google-analytics_ga.js",
						"google-analytics_ga.js"
					],
					description: "Mocks old Google Analytics API.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				},
				{
					name: "google-analytics_ga.js",
					aliases: null,
					description: "Mocks old Google Analytics API.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"script"
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "google-analytics",
					aliases: [
						"ubo-google-analytics_analytics.js",
						"google-analytics_analytics.js",
						"googletagmanager-gtm",
						"ubo-googletagmanager_gtm.js",
						"googletagmanager_gtm.js"
					],
					description: "Mocks Google's Analytics and Tag Manager APIs.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				},
				{
					name: "google-analytics_analytics.js",
					aliases: null,
					description: "Mocks Google's Analytics and Tag Manager APIs.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"script"
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "google-analytics_cx_api.js",
					aliases: null,
					description: null,
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"script"
					]
				}
			],
			map: {
				"1024": 0,
				"2048": 0,
				"4096": 0,
				"8192": 0
			}
		},
		{
			shared: [
				{
					name: "google-analytics_inpage_linkid.js",
					aliases: null,
					description: null,
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"script"
					]
				}
			],
			map: {
				"1024": 0,
				"2048": 0,
				"4096": 0,
				"8192": 0
			}
		},
		{
			shared: [
				{
					name: "google-ima3",
					aliases: [
						"ubo-google-ima.js",
						"google-ima.js"
					],
					description: "Mocks the IMA SDK of Google.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				},
				{
					name: "google-ima.js",
					aliases: null,
					description: "Mocks the IMA SDK of Google.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"script"
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "googlesyndication-adsbygoogle",
					aliases: [
						"ubo-googlesyndication_adsbygoogle.js",
						"ubo-googlesyndication.com/adsbygoogle.js",
						"googlesyndication_adsbygoogle.js"
					],
					description: "Mocks Google AdSense API.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				},
				{
					name: "googlesyndication_adsbygoogle.js",
					aliases: [
						"googlesyndication.com/adsbygoogle.js"
					],
					description: "Mocks Google AdSense API.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"script"
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "googletagservices-gpt",
					aliases: [
						"ubo-googletagservices_gpt.js",
						"googletagservices_gpt.js"
					],
					description: "Mocks Google Publisher Tag API.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				},
				{
					name: "googletagservices_gpt.js",
					aliases: null,
					description: "Mocks Google Publisher Tag API.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"script"
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "hd-main.js",
					aliases: null,
					description: null,
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"script"
					]
				}
			],
			map: {
				"1024": 0,
				"2048": 0,
				"4096": 0,
				"8192": 0
			}
		},
		{
			shared: [
				{
					name: "matomo",
					aliases: null,
					description: "Mocks the piwik.js file of Matomo (formerly Piwik).",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "metrika-yandex-tag",
					aliases: null,
					description: "Mocks Yandex Metrika API.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "metrika-yandex-watch",
					aliases: null,
					description: "Mocks the old Yandex Metrika API.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "naver-wcslog",
					aliases: null,
					description: "Mocks wcslog.js of Naver Analytics.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "no-protected-audience",
					aliases: null,
					description: "Prevents using the Protected Audience API.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "no-topics",
					aliases: null,
					description: "Prevents using the Topics API.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "noeval",
					aliases: [
						"noeval.js",
						"silent-noeval.js",
						"ubo-noeval.js",
						"ubo-silent-noeval.js",
						"ubo-noeval",
						"ubo-silent-noeval"
					],
					description: "Prevents page to use eval.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				},
				{
					name: "noeval.js",
					aliases: null,
					description: "Prevents page to use eval.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"script"
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "noop-0.5s.mp3",
					aliases: null,
					description: "Redirects to an empty MP3 file with a duration of 0.5 seconds.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"media"
					]
				}
			],
			map: {
				"1024": 0,
				"2048": 0,
				"4096": 0,
				"8192": 0
			}
		},
		{
			shared: [
				{
					name: "noopcss",
					aliases: [
						"noop.css",
						"blank-css"
					],
					description: "Redirects to an empty CSS file.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				},
				{
					name: "noop.css",
					aliases: null,
					description: "Redirects to an empty CSS file.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"stylesheet"
					]
				},
				{
					name: "blank-css",
					aliases: null,
					description: "Redirects to an empty CSS file.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "noopframe",
					aliases: [
						"noop.html",
						"blank-html"
					],
					description: "Redirects to an empty HTML file.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				},
				{
					name: "noop.html",
					aliases: null,
					description: "Redirects to an empty HTML file.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"sub_frame"
					]
				},
				{
					name: "blank-html",
					aliases: null,
					description: "Redirects to an empty HTML file.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "noopjs",
					aliases: [
						"noop.js",
						"blank-js"
					],
					description: "Redirects to an empty JavaScript file.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				},
				{
					name: "noop.js",
					aliases: null,
					description: "Redirects to an empty JavaScript file.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"script"
					]
				},
				{
					name: "blank-js",
					aliases: null,
					description: "Redirects to an empty JavaScript file.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "noopjson",
					aliases: [
						"noop.json"
					],
					description: "Redirects to an empty JSON file.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				},
				{
					name: "noop.json",
					aliases: null,
					description: "Redirects to an empty JSON file.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "noopmp3-0.1s",
					aliases: [
						"noop-0.1s.mp3",
						"blank-mp3"
					],
					description: "Redirects to an empty MP3 file with a duration of 0.1 seconds.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				},
				{
					name: "noop-0.1s.mp3",
					aliases: null,
					description: "Redirects to an empty MP3 file with a duration of 0.1 seconds.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"media"
					]
				},
				{
					name: "blank-mp3",
					aliases: null,
					description: "Redirects to an empty MP3 file with a duration of 0.1 seconds.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "noopmp4-1s",
					aliases: [
						"noop-1s.mp4",
						"blank-mp4"
					],
					description: "Redirects to an empty MP4 file with a duration of 1 second.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				},
				{
					name: "noop-1s.mp4",
					aliases: null,
					description: "Redirects to an empty MP4 file with a duration of 1 second.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"media"
					]
				},
				{
					name: "blank-mp4",
					aliases: null,
					description: "Redirects to an empty MP4 file with a duration of 1 second.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "nooptext",
					aliases: [
						"noop.txt",
						"blank-text"
					],
					description: "Redirects to an empty text file.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				},
				{
					name: "noop.txt",
					aliases: null,
					description: "Redirects to an empty text file.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"image",
						"media",
						"sub_frame",
						"stylesheet",
						"script",
						"xmlhttprequest",
						"other"
					]
				},
				{
					name: "blank-text",
					aliases: null,
					description: "Redirects to an empty text file.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "noopvast-2.0",
					aliases: null,
					description: "Redirects to an empty VAST 2.0 XML file.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "noopvast-3.0",
					aliases: null,
					description: "Redirects to an empty VAST 3.0 XML file.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "noopvast-4.0",
					aliases: null,
					description: "Redirects to an empty VAST 4.0 XML file.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "noopvmap-1.0",
					aliases: [
						"noop-vmap1.0.xml"
					],
					description: "Redirects to an empty VMAP 1.0 XML file.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				},
				{
					name: "noop-vmap1.0.xml",
					aliases: null,
					description: "Redirects to an empty VMAP 1.0 XML file.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"media"
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "nowebrtc",
					aliases: [
						"nowebrtc.js",
						"ubo-nowebrtc.js",
						"ubo-nowebrtc"
					],
					description: "Disables WebRTC by overriding `RTCPeerConnection`.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				},
				{
					name: "nowebrtc.js",
					aliases: null,
					description: "Disables WebRTC by overriding `RTCPeerConnection`.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"other"
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "outbrain-widget.js",
					aliases: null,
					description: null,
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"script"
					]
				}
			],
			map: {
				"1024": 0,
				"2048": 0,
				"4096": 0,
				"8192": 0
			}
		},
		{
			shared: [
				{
					name: "pardot-1.0",
					aliases: null,
					description: "Mocks the pd.js file of Salesforce.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "prebid-ads",
					aliases: [
						"prebid-ads.js"
					],
					description: "Mocks prebid-ads.js script.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				},
				{
					name: "prebid-ads.js",
					aliases: null,
					description: "Mocks prebid-ads.js script.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"script"
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "prebid",
					aliases: null,
					description: "Mocks the prebid.js header bidding suit.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "prevent-bab",
					aliases: [
						"nobab.js"
					],
					description: "Prevents BlockAdblock script from detecting an ad blocker.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				},
				{
					name: "nobab.js",
					aliases: null,
					description: "Prevents BlockAdblock script from detecting an ad blocker.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"script"
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "prevent-bab2",
					aliases: [
						"nobab2.js"
					],
					description: "Prevents BlockAdblock script from detecting an ad blocker.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				},
				{
					name: "nobab2.js",
					aliases: null,
					description: "Prevents BlockAdblock script from detecting an ad blocker.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"script"
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "prevent-fab-3.2.0",
					aliases: [
						"nofab.js"
					],
					description: "Mocks FAB script v3.2.0.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				},
				{
					name: "nofab.js",
					aliases: [
						"fuckadblock.js-3.2.0",
						"fuckadblock.js-3.2.0.js"
					],
					description: "Mocks FAB script v3.2.0.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"script"
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "prevent-popads-net",
					aliases: [
						"popads.js"
					],
					description: "Aborts on property write (PopAds, popns), throws reference error with random id.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				},
				{
					name: "popads.js",
					aliases: null,
					description: "Aborts on property write (PopAds, popns), throws reference error with random id.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"script"
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "scorecardresearch-beacon",
					aliases: [
						"scorecardresearch_beacon.js"
					],
					description: "Mocks Scorecard Research API.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				},
				{
					name: "scorecardresearch_beacon.js",
					aliases: null,
					description: "Mocks Scorecard Research API.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"script"
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "set-popads-dummy",
					aliases: [
						"popads-dummy.js"
					],
					description: "Sets static properties PopAds and popns.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
					]
				},
				{
					name: "popads-dummy.js",
					aliases: null,
					description: "Sets static properties PopAds and popns.",
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					isBlocking: false,
					resourceTypes: [
						"script"
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		}
	],
	map: {
		"1x1-transparent.gif": 0,
		"1x1.gif": 0,
		"1x1-transparent-gif": 0,
		"2x2-transparent.png": 1,
		"2x2.png": 1,
		"2x2-transparent-png": 1,
		"32x32-transparent.png": 2,
		"32x32.png": 2,
		"32x32-transparent-png": 2,
		"3x2-transparent.png": 3,
		"3x2.png": 3,
		"3x2-transparent-png": 3,
		"amazon-apstag": 4,
		"ubo-amazon_apstag.js": 4,
		"amazon_apstag.js": 4,
		"amazon_ads.js": 5,
		"ampproject_v0.js": 6,
		"ati-smarttag": 7,
		"chartbeat.js": 8,
		"click2load.html": 9,
		"ubo-click2load.html": 9,
		"didomi-loader": 10,
		empty: 11,
		fingerprintjs2: 12,
		"fingerprint2.js": 12,
		fingerprintjs3: 13,
		"fingerprint3.js": 13,
		gemius: 14,
		"google-analytics-ga": 15,
		"ubo-google-analytics_ga.js": 15,
		"google-analytics_ga.js": 15,
		"google-analytics": 16,
		"ubo-google-analytics_analytics.js": 16,
		"google-analytics_analytics.js": 16,
		"googletagmanager-gtm": 16,
		"ubo-googletagmanager_gtm.js": 16,
		"googletagmanager_gtm.js": 16,
		"google-analytics_cx_api.js": 17,
		"google-analytics_inpage_linkid.js": 18,
		"google-ima3": 19,
		"ubo-google-ima.js": 19,
		"google-ima.js": 19,
		"googlesyndication-adsbygoogle": 20,
		"ubo-googlesyndication_adsbygoogle.js": 20,
		"ubo-googlesyndication.com/adsbygoogle.js": 20,
		"googlesyndication_adsbygoogle.js": 20,
		"googlesyndication.com/adsbygoogle.js": 20,
		"googletagservices-gpt": 21,
		"ubo-googletagservices_gpt.js": 21,
		"googletagservices_gpt.js": 21,
		"hd-main.js": 22,
		matomo: 23,
		"metrika-yandex-tag": 24,
		"metrika-yandex-watch": 25,
		"naver-wcslog": 26,
		"no-protected-audience": 27,
		"no-topics": 28,
		noeval: 29,
		"noeval.js": 29,
		"silent-noeval.js": 29,
		"ubo-noeval.js": 29,
		"ubo-silent-noeval.js": 29,
		"ubo-noeval": 29,
		"ubo-silent-noeval": 29,
		"noop-0.5s.mp3": 30,
		noopcss: 31,
		"noop.css": 31,
		"blank-css": 31,
		noopframe: 32,
		"noop.html": 32,
		"blank-html": 32,
		noopjs: 33,
		"noop.js": 33,
		"blank-js": 33,
		noopjson: 34,
		"noop.json": 34,
		"noopmp3-0.1s": 35,
		"noop-0.1s.mp3": 35,
		"blank-mp3": 35,
		"noopmp4-1s": 36,
		"noop-1s.mp4": 36,
		"blank-mp4": 36,
		nooptext: 37,
		"noop.txt": 37,
		"blank-text": 37,
		"noopvast-2.0": 38,
		"noopvast-3.0": 39,
		"noopvast-4.0": 40,
		"noopvmap-1.0": 41,
		"noop-vmap1.0.xml": 41,
		nowebrtc: 42,
		"nowebrtc.js": 42,
		"ubo-nowebrtc.js": 42,
		"ubo-nowebrtc": 42,
		"outbrain-widget.js": 43,
		"pardot-1.0": 44,
		"prebid-ads": 45,
		"prebid-ads.js": 45,
		prebid: 46,
		"prevent-bab": 47,
		"nobab.js": 47,
		"prevent-bab2": 48,
		"nobab2.js": 48,
		"prevent-fab-3.2.0": 49,
		"nofab.js": 49,
		"fuckadblock.js-3.2.0": 49,
		"fuckadblock.js-3.2.0.js": 49,
		"prevent-popads-net": 50,
		"popads.js": 50,
		"scorecardresearch-beacon": 51,
		"scorecardresearch_beacon.js": 51,
		"set-popads-dummy": 52,
		"popads-dummy.js": 52
	}
};
var scriptletsCompatibilityTableData = {
	shared: [
		{
			shared: [
				{
					name: "abort-current-inline-script",
					aliases: [
						"abort-current-script.js",
						"ubo-abort-current-script.js",
						"acs.js",
						"ubo-acs.js",
						"ubo-abort-current-script",
						"ubo-acs",
						"abort-current-inline-script.js",
						"ubo-abort-current-inline-script.js",
						"acis.js",
						"ubo-acis.js",
						"ubo-abort-current-inline-script",
						"ubo-acis",
						"abp-abort-current-inline-script"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#abort-current-inline-script",
					versionAdded: "1.0.4",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "property",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "search",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "abort-current-script.js",
					aliases: [
						"acs.js",
						"abort-current-inline-script.js",
						"acis.js"
					],
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#abort-current-scriptjs-",
					versionAdded: "1.37.0",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "property",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "search",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "abort-current-inline-script",
					aliases: null,
					description: null,
					docs: "https://help.adblockplus.org/hc/en-us/articles/1500002338501-Snippet-filters-tutorial#snippets-ref",
					versionAdded: "3.4.3",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "api",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "search",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "abort-on-property-read",
					aliases: [
						"abort-on-property-read.js",
						"ubo-abort-on-property-read.js",
						"aopr.js",
						"ubo-aopr.js",
						"ubo-abort-on-property-read",
						"ubo-aopr",
						"abp-abort-on-property-read"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#abort-on-property-read",
					versionAdded: "1.0.4",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "property",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "abort-on-property-read.js",
					aliases: [
						"aopr.js"
					],
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#abort-on-property-readjs-",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "property",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "abort-on-property-read",
					aliases: null,
					description: null,
					docs: "https://help.adblockplus.org/hc/en-us/articles/1500002338501-Snippet-filters-tutorial#snippets-ref",
					versionAdded: "3.4.1",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "property",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "setConfigurable",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "abort-on-property-write",
					aliases: [
						"abort-on-property-write.js",
						"ubo-abort-on-property-write.js",
						"aopw.js",
						"ubo-aopw.js",
						"ubo-abort-on-property-write",
						"ubo-aopw",
						"abp-abort-on-property-write"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#abort-on-property-write",
					versionAdded: "1.0.4",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "property",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "abort-on-property-write.js",
					aliases: [
						"aopw.js"
					],
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#abort-on-property-writejs-",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "property",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "abort-on-property-write",
					aliases: null,
					description: null,
					docs: "https://help.adblockplus.org/hc/en-us/articles/1500002338501-Snippet-filters-tutorial#snippets-ref",
					versionAdded: "3.4.3",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "property",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "setConfigurable",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "abort-on-stack-trace",
					aliases: [
						"abort-on-stack-trace.js",
						"ubo-abort-on-stack-trace.js",
						"aost.js",
						"ubo-aost.js",
						"ubo-abort-on-stack-trace",
						"ubo-aost",
						"abp-abort-on-stack-trace"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#abort-on-stack-trace",
					versionAdded: "1.5.0",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "property",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "stack",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "abort-on-stack-trace.js",
					aliases: [
						"aost.js"
					],
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#abort-on-stack-tracejs-",
					versionAdded: "1.29.3rc9",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "property",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "stack",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "adjust-setInterval",
					aliases: [
						"nano-setInterval-booster.js",
						"ubo-nano-setInterval-booster.js",
						"nano-sib.js",
						"ubo-nano-sib.js",
						"adjust-setInterval.js",
						"ubo-adjust-setInterval.js",
						"ubo-nano-setInterval-booster",
						"ubo-nano-sib",
						"ubo-adjust-setInterval"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#adjust-setInterval",
					versionAdded: "1.0.4",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "matchCallback",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "matchDelay",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "boost",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "adjust-setInterval.js",
					aliases: [
						"nano-setInterval-booster.js",
						"nano-sib.js"
					],
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#adjust-setIntervaljs-",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "matchCallback",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "matchDelay",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "boost",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "adjust-setTimeout",
					aliases: [
						"adjust-setTimeout.js",
						"ubo-adjust-setTimeout.js",
						"nano-setTimeout-booster.js",
						"ubo-nano-setTimeout-booster.js",
						"nano-stb.js",
						"ubo-nano-stb.js",
						"ubo-adjust-setTimeout",
						"ubo-nano-setTimeout-booster",
						"ubo-nano-stb"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#adjust-setTimeout",
					versionAdded: "1.0.4",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "matchCallback",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "matchDelay",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "boost",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "adjust-setTimeout.js",
					aliases: [
						"nano-setTimeout-booster.js",
						"nano-stb.js"
					],
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#adjust-setTimeoutjs-",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "matchCallback",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "matchDelay",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "boost",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "amazon-apstag",
					aliases: [
						"ubo-amazon_apstag.js",
						"amazon_apstag.js"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#amazon-apstag",
					versionAdded: "1.10.25",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "call-nothrow",
					aliases: [
						"call-nothrow.js",
						"ubo-call-nothrow.js",
						"ubo-call-nothrow"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#call-nothrow",
					versionAdded: "1.10.1",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "functionName",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "call-nothrow.js",
					aliases: null,
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#call-nothrowjs-",
					versionAdded: "1.48.1b0",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "functionName",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "close-window",
					aliases: [
						"window-close-if.js",
						"ubo-window-close-if.js",
						"ubo-window-close-if",
						"close-window.js",
						"ubo-close-window.js",
						"ubo-close-window"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#close-window",
					versionAdded: "1.5.0",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "path",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "close-window.js",
					aliases: [
						"window-close-if.js"
					],
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#close-windowjs-",
					versionAdded: "1.39.3b10",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "path",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "debug-current-inline-script",
					aliases: null,
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#debug-current-inline-script",
					versionAdded: "1.0.4",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "property",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "search",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "debug-on-property-read",
					aliases: null,
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#debug-on-property-read",
					versionAdded: "1.0.4",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "property",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "debug-on-property-write",
					aliases: null,
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#debug-on-property-write",
					versionAdded: "1.0.4",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "property",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "didomi-loader",
					aliases: null,
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#didomi-loader",
					versionAdded: "1.10.25",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "dir-string",
					aliases: null,
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#dir-string",
					versionAdded: "1.0.4",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "times",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "disable-newtab-links",
					aliases: [
						"disable-newtab-links.js",
						"ubo-disable-newtab-links.js",
						"ubo-disable-newtab-links"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#disable-newtab-links",
					versionAdded: "1.0.4",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null
				},
				{
					name: "disable-newtab-links.js",
					aliases: null,
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#disable-newtab-linksjs-",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "evaldata-prune",
					aliases: [
						"evaldata-prune.js",
						"ubo-evaldata-prune.js",
						"ubo-evaldata-prune"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#evaldata-prune",
					versionAdded: "1.9.37",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "propsToRemove",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "obligatoryProps",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "stack",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "evaldata-prune.js",
					aliases: null,
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#evaldata-prunejs-",
					versionAdded: "1.49.3rc15",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "propsToRemove",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "obligatoryProps",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "stack",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "fingerprintjs2",
					aliases: [
						"ubo-fingerprint2.js",
						"fingerprint2.js"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#fingerprintjs2",
					versionAdded: "1.10.25",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "fingerprintjs3",
					aliases: [
						"ubo-fingerprint3.js",
						"fingerprint3.js"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#fingerprintjs3",
					versionAdded: "1.10.25",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "gemius",
					aliases: null,
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#gemius",
					versionAdded: "1.10.25",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "google-analytics-ga",
					aliases: [
						"ubo-google-analytics_ga.js",
						"google-analytics_ga.js"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#google-analytics-ga",
					versionAdded: "1.10.25",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "google-analytics",
					aliases: [
						"ubo-google-analytics_analytics.js",
						"google-analytics_analytics.js",
						"googletagmanager-gtm",
						"ubo-googletagmanager_gtm.js",
						"googletagmanager_gtm.js"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#google-analytics",
					versionAdded: "1.10.25",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "google-ima3",
					aliases: [
						"ubo-google-ima.js",
						"google-ima.js"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#google-ima3",
					versionAdded: "1.10.25",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "googlesyndication-adsbygoogle",
					aliases: [
						"ubo-googlesyndication_adsbygoogle.js",
						"googlesyndication_adsbygoogle.js"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#googlesyndication-adsbygoogle",
					versionAdded: "1.10.25",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "googletagservices-gpt",
					aliases: [
						"ubo-googletagservices_gpt.js",
						"googletagservices_gpt.js"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#googletagservices-gpt",
					versionAdded: "1.10.25",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "hide-in-shadow-dom",
					aliases: null,
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#hide-in-shadow-dom",
					versionAdded: "1.3.0",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "selector",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "baseSelector",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "href-sanitizer",
					aliases: [
						"href-sanitizer.js",
						"ubo-href-sanitizer.js",
						"ubo-href-sanitizer"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#href-sanitizer",
					versionAdded: "1.10.25",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "selector",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "attribute",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "href-sanitizer.js",
					aliases: null,
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#href-sanitizerjs-",
					versionAdded: "1.47.5b4",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "selector",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "attribute",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "inject-css-in-shadow-dom",
					aliases: null,
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#inject-css-in-shadow-dom",
					versionAdded: "1.8.2",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "cssRule",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "hostSelector",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "json-prune-fetch-response",
					aliases: [
						"json-prune-fetch-response.js",
						"ubo-json-prune-fetch-response.js",
						"ubo-json-prune-fetch-response"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#json-prune-fetch-response",
					versionAdded: "1.10.25",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "propsToRemove",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "obligatoryProps",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "propsToMatch",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "stack",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "json-prune-fetch-response.js",
					aliases: null,
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#json-prune-fetch-responsejs-",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "propsToRemove",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "obligatoryProps",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "propsToMatch",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "stack",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "json-prune-xhr-response",
					aliases: [
						"json-prune-xhr-response.js",
						"ubo-json-prune-xhr-response.js",
						"ubo-json-prune-xhr-response"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#json-prune-xhr-response",
					versionAdded: "1.10.25",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "propsToRemove",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "obligatoryProps",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "propsToMatch",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "stack",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "json-prune-xhr-response.js",
					aliases: null,
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#json-prune-xhr-responsejs-",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "propsToRemove",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "obligatoryProps",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "propsToMatch",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "stack",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "json-prune",
					aliases: [
						"json-prune.js",
						"ubo-json-prune.js",
						"ubo-json-prune",
						"abp-json-prune"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#json-prune",
					versionAdded: "1.1.0",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "propsToRemove",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "obligatoryProps",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "stack",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "json-prune.js",
					aliases: null,
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#json-prunejs-",
					versionAdded: "1.23.0",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "propsToRemove",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "obligatoryProps",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "stack",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "json-prune",
					aliases: null,
					description: null,
					docs: "https://help.adblockplus.org/hc/en-us/articles/1500002338501-Snippet-filters-tutorial#snippets-ref",
					versionAdded: "3.9.0",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "rawPrunePaths",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "rawNeedlePaths",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "log-addEventListener",
					aliases: [
						"addEventListener-logger.js",
						"ubo-addEventListener-logger.js",
						"aell.js",
						"ubo-aell.js",
						"ubo-addEventListener-logger",
						"ubo-aell"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#log-addEventListener",
					versionAdded: "1.0.4",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "log-eval",
					aliases: null,
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#log-eval",
					versionAdded: "1.0.4",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "log-on-stack-trace",
					aliases: null,
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#log-on-stack-trace",
					versionAdded: "1.5.0",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "property",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "log",
					aliases: [
						"abp-log"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#log",
					versionAdded: "1.0.4",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "arguments",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "m3u-prune",
					aliases: [
						"m3u-prune.js",
						"ubo-m3u-prune.js",
						"ubo-m3u-prune"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#m3u-prune",
					versionAdded: "1.9.1",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "propsToRemove",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "urlToMatch",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "m3u-prune.js",
					aliases: null,
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#m3u-prunejs-",
					versionAdded: "1.44.5b6",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "propsToRemove",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "urlToMatch",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "matomo",
					aliases: null,
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#matomo",
					versionAdded: "1.10.25",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "metrika-yandex-tag",
					aliases: null,
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#metrika-yandex-tag",
					versionAdded: "1.10.25",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "metrika-yandex-watch",
					aliases: null,
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#metrika-yandex-watch",
					versionAdded: "1.10.25",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "naver-wcslog",
					aliases: null,
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#naver-wcslog",
					versionAdded: "1.10.25",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "no-protected-audience",
					aliases: null,
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#no-protected-audience",
					versionAdded: "1.10.25",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "no-topics",
					aliases: null,
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#no-topics",
					versionAdded: "1.6.18",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "noeval",
					aliases: [
						"noeval.js",
						"silent-noeval.js",
						"ubo-noeval.js",
						"ubo-silent-noeval.js",
						"ubo-noeval",
						"ubo-silent-noeval"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#noeval",
					versionAdded: "1.0.4",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "nowebrtc",
					aliases: [
						"nowebrtc.js",
						"ubo-nowebrtc.js",
						"ubo-nowebrtc"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#nowebrtc",
					versionAdded: "1.0.4",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null
				},
				{
					name: "nowebrtc.js",
					aliases: null,
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#nowebrtcjs-",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "pardot-1.0",
					aliases: null,
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#pardot-1.0",
					versionAdded: "1.10.25",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "prebid",
					aliases: null,
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#prebid",
					versionAdded: "1.10.25",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "prevent-addEventListener",
					aliases: [
						"addEventListener-defuser.js",
						"ubo-addEventListener-defuser.js",
						"aeld.js",
						"ubo-aeld.js",
						"ubo-addEventListener-defuser",
						"ubo-aeld",
						"abp-prevent-listener"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#prevent-addEventListener",
					versionAdded: "1.0.4",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "typeSearch",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "listenerSearch",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "addEventListener-defuser.js",
					aliases: [
						"aeld.js",
						"prevent-addEventListener.js"
					],
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#addEventListener-defuserjs-",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "typeSearch",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "listenerSearch",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "prevent-listener",
					aliases: null,
					description: null,
					docs: "https://help.adblockplus.org/hc/en-us/articles/1500002338501-Snippet-filters-tutorial#snippets-ref",
					versionAdded: "3.11.2",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "type",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "handler",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "selector",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "prevent-adfly",
					aliases: [
						"adfly-defuser.js",
						"ubo-adfly-defuser.js",
						"ubo-adfly-defuser"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#prevent-adfly",
					versionAdded: "1.0.4",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "prevent-bab",
					aliases: null,
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#prevent-bab",
					versionAdded: "1.0.4",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "prevent-element-src-loading",
					aliases: null,
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#prevent-element-src-loading",
					versionAdded: "1.6.2",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "tagName",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "match",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "prevent-eval-if",
					aliases: [
						"noeval-if.js",
						"ubo-noeval-if.js",
						"ubo-noeval-if"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#prevent-eval-if",
					versionAdded: "1.0.4",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "search",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "noeval-if.js",
					aliases: [
						"prevent-eval-if.js"
					],
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#noeval-ifjs-",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "search",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "prevent-fab-3.2.0",
					aliases: [
						"nofab.js",
						"ubo-nofab.js",
						"fuckadblock.js-3.2.0",
						"ubo-fuckadblock.js-3.2.0",
						"ubo-nofab"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#prevent-fab-3.2.0",
					versionAdded: "1.0.4",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "prevent-fetch",
					aliases: [
						"prevent-fetch.js",
						"no-fetch-if.js",
						"ubo-no-fetch-if.js",
						"ubo-no-fetch-if"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#prevent-fetch",
					versionAdded: "1.3.18",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "propsToMatch",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "responseBody",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "responseType",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "prevent-fetch.js",
					aliases: [
						"no-fetch-if.js"
					],
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#prevent-fetchjs-",
					versionAdded: "1.31.3b9",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "propsToMatch",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "responseBody",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "responseType",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "prevent-popads-net",
					aliases: [
						"popads.net.js",
						"ubo-popads.net.js",
						"ubo-popads.net"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#prevent-popads-net",
					versionAdded: "1.0.4",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "prevent-refresh",
					aliases: [
						"prevent-refresh.js",
						"refresh-defuser.js",
						"refresh-defuser",
						"ubo-prevent-refresh.js",
						"ubo-prevent-refresh",
						"ubo-refresh-defuser.js",
						"ubo-refresh-defuser"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#prevent-refresh",
					versionAdded: "1.6.2",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "delay",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "prevent-refresh.js",
					aliases: [
						"refresh-defuser.js"
					],
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#prevent-refreshjs-",
					versionAdded: "1.38.7b3",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "delay",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "prevent-requestAnimationFrame",
					aliases: [
						"no-requestAnimationFrame-if.js",
						"ubo-no-requestAnimationFrame-if.js",
						"norafif.js",
						"ubo-norafif.js",
						"ubo-no-requestAnimationFrame-if",
						"ubo-norafif"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#prevent-requestAnimationFrame",
					versionAdded: "1.1.15",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "search",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "no-requestAnimationFrame-if.js",
					aliases: [
						"norafif.js",
						"prevent-requestAnimationFrame.js"
					],
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#no-requestAnimationFrame-ifjs-",
					versionAdded: "1.27.0",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "search",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "prevent-setInterval",
					aliases: [
						"no-setInterval-if.js",
						"ubo-no-setInterval-if.js",
						"setInterval-defuser.js",
						"ubo-setInterval-defuser.js",
						"nosiif.js",
						"ubo-nosiif.js",
						"sid.js",
						"ubo-sid.js",
						"ubo-no-setInterval-if",
						"ubo-setInterval-defuser",
						"ubo-nosiif",
						"ubo-sid"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#prevent-setInterval",
					versionAdded: "1.0.4",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "matchCallback",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "matchDelay",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "no-setInterval-if.js",
					aliases: [
						"nosiif.js",
						"prevent-setInterval.js",
						"setInterval-defuser.js"
					],
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#no-setInterval-ifjs-",
					versionAdded: "1.23.0",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "matchCallback",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "matchDelay",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "prevent-setTimeout",
					aliases: [
						"no-setTimeout-if.js",
						"ubo-no-setTimeout-if.js",
						"nostif.js",
						"ubo-nostif.js",
						"ubo-no-setTimeout-if",
						"ubo-nostif",
						"setTimeout-defuser.js",
						"ubo-setTimeout-defuser.js",
						"ubo-setTimeout-defuser",
						"std.js",
						"ubo-std.js",
						"ubo-std"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#prevent-setTimeout",
					versionAdded: "1.0.4",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "matchCallback",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "matchDelay",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "no-setTimeout-if.js",
					aliases: [
						"nostif.js",
						"prevent-setTimeout.js",
						"setTimeout-defuser.js"
					],
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#no-setTimeout-ifjs-",
					versionAdded: "1.23.0",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "matchCallback",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "matchDelay",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "prevent-window-open",
					aliases: [
						"window.open-defuser.js",
						"ubo-window.open-defuser.js",
						"ubo-window.open-defuser",
						"nowoif.js",
						"ubo-nowoif.js",
						"ubo-nowoif",
						"no-window-open-if.js",
						"ubo-no-window-open-if.js",
						"ubo-no-window-open-if"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#prevent-window-open",
					versionAdded: "1.0.4",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "match",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "delay",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "replacement",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "no-window-open-if.js",
					aliases: [
						"nowoif.js",
						"prevent-window-open.js",
						"window.open-defuser.js"
					],
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#no-window-open-ifjs-",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "match",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "delay",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "replacement",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "prevent-xhr",
					aliases: [
						"no-xhr-if.js",
						"ubo-no-xhr-if.js",
						"ubo-no-xhr-if"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#prevent-xhr",
					versionAdded: "1.5.0",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "propsToMatch",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "randomize",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "no-xhr-if.js",
					aliases: [
						"prevent-xhr.js"
					],
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#no-xhr-ifjs-",
					versionAdded: "1.38.0",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "propsToMatch",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "randomize",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "remove-attr",
					aliases: [
						"remove-attr.js",
						"ubo-remove-attr.js",
						"ra.js",
						"ubo-ra.js",
						"ubo-remove-attr",
						"ubo-ra"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#remove-attr",
					versionAdded: "1.0.4",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "attrs",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "selector",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "applying",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "remove-attr.js",
					aliases: [
						"ra.js",
						"ra",
						"remove-attr"
					],
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#remove-attrjs-",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "attrs",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "selector",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "applying",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "remove-class",
					aliases: [
						"remove-class.js",
						"ubo-remove-class.js",
						"rc.js",
						"ubo-rc.js",
						"ubo-remove-class",
						"ubo-rc"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#remove-class",
					versionAdded: "1.1.1",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "classes",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "selector",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "applying",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "remove-class.js",
					aliases: [
						"rc.js",
						"rc",
						"remove-class"
					],
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#remove-classjs-",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "classes",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "selector",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "applying",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "remove-cookie",
					aliases: [
						"cookie-remover.js",
						"ubo-cookie-remover.js",
						"ubo-cookie-remover",
						"remove-cookie.js",
						"ubo-remove-cookie.js",
						"ubo-remove-cookie",
						"abp-cookie-remover"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#remove-cookie",
					versionAdded: "1.0.4",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "match",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "remove-cookie.js",
					aliases: [
						"cookie-remover.js"
					],
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#remove-cookiejs-",
					versionAdded: "1.28.0",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "match",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "cookie-remover",
					aliases: null,
					description: null,
					docs: "https://help.adblockplus.org/hc/en-us/articles/1500002338501-Snippet-filters-tutorial#snippets-ref",
					versionAdded: "3.11.2",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "cookie",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "autoRemoveCookie",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "remove-in-shadow-dom",
					aliases: null,
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#remove-in-shadow-dom",
					versionAdded: "1.3.14",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "selector",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "baseSelector",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "remove-node-text",
					aliases: [
						"remove-node-text.js",
						"ubo-remove-node-text.js",
						"rmnt.js",
						"ubo-rmnt.js",
						"ubo-remove-node-text",
						"ubo-rmnt"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#remove-node-text",
					versionAdded: "1.9.37",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "nodeName",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "textMatch",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "remove-node-text.js",
					aliases: [
						"rmnt.js"
					],
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#remove-node-textjs-",
					versionAdded: "1.49.3rc15",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "nodeName",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "textMatch",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "scorecardresearch-beacon",
					aliases: [
						"ubo-scorecardresearch_beacon.js",
						"scorecardresearch_beacon.js"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#scorecardresearch-beacon",
					versionAdded: "1.10.25",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "set-attr",
					aliases: [
						"set-attr.js",
						"ubo-set-attr.js",
						"ubo-set-attr"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#set-attr",
					versionAdded: "1.5.0",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "selector",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "attr",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "value",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "set-attr.js",
					aliases: null,
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#set-attrjs-",
					versionAdded: "1.50.1b16",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "selector",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "attr",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "value",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "set-constant",
					aliases: [
						"set-constant.js",
						"ubo-set-constant.js",
						"set.js",
						"ubo-set.js",
						"ubo-set-constant",
						"ubo-set"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#set-constant",
					versionAdded: "1.0.4",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "property",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "value",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "stack",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "valueWrapper",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "setProxyTrap",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "set-constant.js",
					aliases: [
						"set.js"
					],
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#set-constantjs-",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "chain",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "rawValue",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "runAt",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "override-property-read",
					aliases: null,
					description: null,
					docs: "https://help.adblockplus.org/hc/en-us/articles/1500002338501-Snippet-filters-tutorial#snippets-ref",
					versionAdded: "3.9.4",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "property",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "value",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "setConfigurable",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1,
				"16384": 2,
				"32768": 2,
				"65536": 2,
				"131072": 2
			}
		},
		{
			shared: [
				{
					name: "set-cookie-reload",
					aliases: [
						"set-cookie-reload.js",
						"ubo-set-cookie-reload.js",
						"ubo-set-cookie-reload"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#set-cookie-reload",
					versionAdded: "1.3.14",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "name",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "value",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "path",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "domain",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "set-cookie-reload.js",
					aliases: null,
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#set-cookie-reloadjs-",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "name",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "value",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "path",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "domain",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "set-cookie",
					aliases: [
						"set-cookie.js",
						"ubo-set-cookie.js",
						"ubo-set-cookie"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#set-cookie",
					versionAdded: "1.2.3",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "name",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "value",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "path",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "set-cookie.js",
					aliases: null,
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#set-cookiejs-",
					versionAdded: "1.50.1b0",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "name",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "value",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "path",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "set-local-storage-item",
					aliases: [
						"set-local-storage-item.js",
						"ubo-set-local-storage-item.js",
						"ubo-set-local-storage-item"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#set-local-storage-item",
					versionAdded: "1.4.3",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "key",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "value",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "set-local-storage-item.js",
					aliases: null,
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#set-local-storage-itemjs-",
					versionAdded: "1.50.1b4",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "key",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "value",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "set-popads-dummy",
					aliases: [
						"popads-dummy.js",
						"ubo-popads-dummy.js",
						"ubo-popads-dummy"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#set-popads-dummy",
					versionAdded: "1.0.4",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "set-session-storage-item",
					aliases: [
						"set-session-storage-item.js",
						"ubo-set-session-storage-item.js",
						"ubo-set-session-storage-item"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#set-session-storage-item",
					versionAdded: "1.4.3",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "key",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "value",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "set-session-storage-item.js",
					aliases: null,
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#set-session-storage-itemjs-",
					versionAdded: "1.50.1b4",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "key",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "value",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "spoof-css",
					aliases: [
						"spoof-css.js",
						"ubo-spoof-css.js",
						"ubo-spoof-css"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#spoof-css",
					versionAdded: "1.10.1",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "selectors",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "cssPropertyName",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "cssPropertyValue",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "spoof-css.js",
					aliases: null,
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#spoof-cssjs-",
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "selectors",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "cssPropertyName",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "cssPropertyValue",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "arguments",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		},
		{
			shared: [
				{
					name: "trusted-click-element",
					aliases: null,
					description: null,
					docs: null,
					versionAdded: "1.7.3",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "selectors",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "extraMatch",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "delay",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "trusted-create-element",
					aliases: null,
					description: null,
					docs: null,
					versionAdded: "1.10.1",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "parentSelector",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "tagName",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "attributePairs",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "textContent",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "cleanupDelayMs",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "trusted-dispatch-event",
					aliases: null,
					description: null,
					docs: null,
					versionAdded: null,
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "event",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "target",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "trusted-prune-inbound-object",
					aliases: null,
					description: null,
					docs: null,
					versionAdded: "1.9.91",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "functionName",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "propsToRemove",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "obligatoryProps",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "stack",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "trusted-replace-fetch-response",
					aliases: null,
					description: null,
					docs: null,
					versionAdded: "1.7.3",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "pattern",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "replacement",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "propsToMatch",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "trusted-replace-node-text",
					aliases: null,
					description: null,
					docs: null,
					versionAdded: "1.9.37",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "nodeName",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "textMatch",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "pattern",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "replacement",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "trusted-replace-xhr-response",
					aliases: null,
					description: null,
					docs: null,
					versionAdded: "1.7.3",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "pattern",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "replacement",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "propsToMatch",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "trusted-set-attr",
					aliases: null,
					description: null,
					docs: null,
					versionAdded: "1.10.1",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "selector",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "attr",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "value",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "trusted-set-constant",
					aliases: null,
					description: null,
					docs: null,
					versionAdded: "1.8.2",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "property",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "value",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "stack",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "trusted-set-cookie-reload",
					aliases: null,
					description: null,
					docs: null,
					versionAdded: "1.7.10",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "name",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "value",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "offsetExpiresSec",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "path",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "domain",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "trusted-set-cookie",
					aliases: null,
					description: null,
					docs: null,
					versionAdded: "1.7.3",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "name",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "value",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "offsetExpiresSec",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "path",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "domain",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "trusted-set-local-storage-item",
					aliases: null,
					description: null,
					docs: null,
					versionAdded: "1.7.3",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "key",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "value",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "trusted-suppress-native-method",
					aliases: null,
					description: null,
					docs: null,
					versionAdded: "1.10.25",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "methodPath",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "signatureStr",
							required: true,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "how",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "stack",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0
			}
		},
		{
			shared: [
				{
					name: "xml-prune",
					aliases: [
						"xml-prune.js",
						"ubo-xml-prune.js",
						"ubo-xml-prune"
					],
					description: null,
					docs: "https://github.com/AdguardTeam/Scriptlets/blob/master/wiki/about-scriptlets.md#xml-prune",
					versionAdded: "1.7.3",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "propsToMatch",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "optionalProp",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "urlToMatch",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				},
				{
					name: "xml-prune.js",
					aliases: null,
					description: null,
					docs: "https://github.com/gorhill/uBlock/wiki/Resources-Library#xml-prunejs-",
					versionAdded: "1.49.3rc6",
					versionRemoved: null,
					deprecated: false,
					deprecationMessage: null,
					removed: false,
					removalMessage: null,
					parameters: [
						{
							name: "propsToMatch",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "optionalProp",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						},
						{
							name: "urlToMatch",
							required: false,
							description: null,
							pattern: null,
							"default": null,
							debug: false
						}
					]
				}
			],
			map: {
				"1": 0,
				"2": 0,
				"4": 0,
				"8": 0,
				"16": 0,
				"32": 0,
				"64": 0,
				"1024": 1,
				"2048": 1,
				"4096": 1,
				"8192": 1
			}
		}
	],
	map: {
		"abort-current-inline-script": 0,
		"abort-current-script.js": 0,
		"ubo-abort-current-script.js": 0,
		"acs.js": 0,
		"ubo-acs.js": 0,
		"ubo-abort-current-script": 0,
		"ubo-acs": 0,
		"abort-current-inline-script.js": 0,
		"ubo-abort-current-inline-script.js": 0,
		"acis.js": 0,
		"ubo-acis.js": 0,
		"ubo-abort-current-inline-script": 0,
		"ubo-acis": 0,
		"abp-abort-current-inline-script": 0,
		"abort-on-property-read": 1,
		"abort-on-property-read.js": 1,
		"ubo-abort-on-property-read.js": 1,
		"aopr.js": 1,
		"ubo-aopr.js": 1,
		"ubo-abort-on-property-read": 1,
		"ubo-aopr": 1,
		"abp-abort-on-property-read": 1,
		"abort-on-property-write": 2,
		"abort-on-property-write.js": 2,
		"ubo-abort-on-property-write.js": 2,
		"aopw.js": 2,
		"ubo-aopw.js": 2,
		"ubo-abort-on-property-write": 2,
		"ubo-aopw": 2,
		"abp-abort-on-property-write": 2,
		"abort-on-stack-trace": 3,
		"abort-on-stack-trace.js": 3,
		"ubo-abort-on-stack-trace.js": 3,
		"aost.js": 3,
		"ubo-aost.js": 3,
		"ubo-abort-on-stack-trace": 3,
		"ubo-aost": 3,
		"abp-abort-on-stack-trace": 3,
		"adjust-setInterval": 4,
		"nano-setInterval-booster.js": 4,
		"ubo-nano-setInterval-booster.js": 4,
		"nano-sib.js": 4,
		"ubo-nano-sib.js": 4,
		"adjust-setInterval.js": 4,
		"ubo-adjust-setInterval.js": 4,
		"ubo-nano-setInterval-booster": 4,
		"ubo-nano-sib": 4,
		"ubo-adjust-setInterval": 4,
		"adjust-setTimeout": 5,
		"adjust-setTimeout.js": 5,
		"ubo-adjust-setTimeout.js": 5,
		"nano-setTimeout-booster.js": 5,
		"ubo-nano-setTimeout-booster.js": 5,
		"nano-stb.js": 5,
		"ubo-nano-stb.js": 5,
		"ubo-adjust-setTimeout": 5,
		"ubo-nano-setTimeout-booster": 5,
		"ubo-nano-stb": 5,
		"amazon-apstag": 6,
		"ubo-amazon_apstag.js": 6,
		"amazon_apstag.js": 6,
		"call-nothrow": 7,
		"call-nothrow.js": 7,
		"ubo-call-nothrow.js": 7,
		"ubo-call-nothrow": 7,
		"close-window": 8,
		"window-close-if.js": 8,
		"ubo-window-close-if.js": 8,
		"ubo-window-close-if": 8,
		"close-window.js": 8,
		"ubo-close-window.js": 8,
		"ubo-close-window": 8,
		"debug-current-inline-script": 9,
		"debug-on-property-read": 10,
		"debug-on-property-write": 11,
		"didomi-loader": 12,
		"dir-string": 13,
		"disable-newtab-links": 14,
		"disable-newtab-links.js": 14,
		"ubo-disable-newtab-links.js": 14,
		"ubo-disable-newtab-links": 14,
		"evaldata-prune": 15,
		"evaldata-prune.js": 15,
		"ubo-evaldata-prune.js": 15,
		"ubo-evaldata-prune": 15,
		fingerprintjs2: 16,
		"ubo-fingerprint2.js": 16,
		"fingerprint2.js": 16,
		fingerprintjs3: 17,
		"ubo-fingerprint3.js": 17,
		"fingerprint3.js": 17,
		gemius: 18,
		"google-analytics-ga": 19,
		"ubo-google-analytics_ga.js": 19,
		"google-analytics_ga.js": 19,
		"google-analytics": 20,
		"ubo-google-analytics_analytics.js": 20,
		"google-analytics_analytics.js": 20,
		"googletagmanager-gtm": 20,
		"ubo-googletagmanager_gtm.js": 20,
		"googletagmanager_gtm.js": 20,
		"google-ima3": 21,
		"ubo-google-ima.js": 21,
		"google-ima.js": 21,
		"googlesyndication-adsbygoogle": 22,
		"ubo-googlesyndication_adsbygoogle.js": 22,
		"googlesyndication_adsbygoogle.js": 22,
		"googletagservices-gpt": 23,
		"ubo-googletagservices_gpt.js": 23,
		"googletagservices_gpt.js": 23,
		"hide-in-shadow-dom": 24,
		"href-sanitizer": 25,
		"href-sanitizer.js": 25,
		"ubo-href-sanitizer.js": 25,
		"ubo-href-sanitizer": 25,
		"inject-css-in-shadow-dom": 26,
		"json-prune-fetch-response": 27,
		"json-prune-fetch-response.js": 27,
		"ubo-json-prune-fetch-response.js": 27,
		"ubo-json-prune-fetch-response": 27,
		"json-prune-xhr-response": 28,
		"json-prune-xhr-response.js": 28,
		"ubo-json-prune-xhr-response.js": 28,
		"ubo-json-prune-xhr-response": 28,
		"json-prune": 29,
		"json-prune.js": 29,
		"ubo-json-prune.js": 29,
		"ubo-json-prune": 29,
		"abp-json-prune": 29,
		"log-addEventListener": 30,
		"addEventListener-logger.js": 30,
		"ubo-addEventListener-logger.js": 30,
		"aell.js": 30,
		"ubo-aell.js": 30,
		"ubo-addEventListener-logger": 30,
		"ubo-aell": 30,
		"log-eval": 31,
		"log-on-stack-trace": 32,
		log: 33,
		"abp-log": 33,
		"m3u-prune": 34,
		"m3u-prune.js": 34,
		"ubo-m3u-prune.js": 34,
		"ubo-m3u-prune": 34,
		matomo: 35,
		"metrika-yandex-tag": 36,
		"metrika-yandex-watch": 37,
		"naver-wcslog": 38,
		"no-protected-audience": 39,
		"no-topics": 40,
		noeval: 41,
		"noeval.js": 41,
		"silent-noeval.js": 41,
		"ubo-noeval.js": 41,
		"ubo-silent-noeval.js": 41,
		"ubo-noeval": 41,
		"ubo-silent-noeval": 41,
		nowebrtc: 42,
		"nowebrtc.js": 42,
		"ubo-nowebrtc.js": 42,
		"ubo-nowebrtc": 42,
		"pardot-1.0": 43,
		prebid: 44,
		"prevent-addEventListener": 45,
		"addEventListener-defuser.js": 45,
		"ubo-addEventListener-defuser.js": 45,
		"aeld.js": 45,
		"ubo-aeld.js": 45,
		"ubo-addEventListener-defuser": 45,
		"ubo-aeld": 45,
		"abp-prevent-listener": 45,
		"prevent-addEventListener.js": 45,
		"prevent-listener": 45,
		"prevent-adfly": 46,
		"adfly-defuser.js": 46,
		"ubo-adfly-defuser.js": 46,
		"ubo-adfly-defuser": 46,
		"prevent-bab": 47,
		"prevent-element-src-loading": 48,
		"prevent-eval-if": 49,
		"noeval-if.js": 49,
		"ubo-noeval-if.js": 49,
		"ubo-noeval-if": 49,
		"prevent-eval-if.js": 49,
		"prevent-fab-3.2.0": 50,
		"nofab.js": 50,
		"ubo-nofab.js": 50,
		"fuckadblock.js-3.2.0": 50,
		"ubo-fuckadblock.js-3.2.0": 50,
		"ubo-nofab": 50,
		"prevent-fetch": 51,
		"prevent-fetch.js": 51,
		"no-fetch-if.js": 51,
		"ubo-no-fetch-if.js": 51,
		"ubo-no-fetch-if": 51,
		"prevent-popads-net": 52,
		"popads.net.js": 52,
		"ubo-popads.net.js": 52,
		"ubo-popads.net": 52,
		"prevent-refresh": 53,
		"prevent-refresh.js": 53,
		"refresh-defuser.js": 53,
		"refresh-defuser": 53,
		"ubo-prevent-refresh.js": 53,
		"ubo-prevent-refresh": 53,
		"ubo-refresh-defuser.js": 53,
		"ubo-refresh-defuser": 53,
		"prevent-requestAnimationFrame": 54,
		"no-requestAnimationFrame-if.js": 54,
		"ubo-no-requestAnimationFrame-if.js": 54,
		"norafif.js": 54,
		"ubo-norafif.js": 54,
		"ubo-no-requestAnimationFrame-if": 54,
		"ubo-norafif": 54,
		"prevent-requestAnimationFrame.js": 54,
		"prevent-setInterval": 55,
		"no-setInterval-if.js": 55,
		"ubo-no-setInterval-if.js": 55,
		"setInterval-defuser.js": 55,
		"ubo-setInterval-defuser.js": 55,
		"nosiif.js": 55,
		"ubo-nosiif.js": 55,
		"sid.js": 55,
		"ubo-sid.js": 55,
		"ubo-no-setInterval-if": 55,
		"ubo-setInterval-defuser": 55,
		"ubo-nosiif": 55,
		"ubo-sid": 55,
		"prevent-setInterval.js": 55,
		"prevent-setTimeout": 56,
		"no-setTimeout-if.js": 56,
		"ubo-no-setTimeout-if.js": 56,
		"nostif.js": 56,
		"ubo-nostif.js": 56,
		"ubo-no-setTimeout-if": 56,
		"ubo-nostif": 56,
		"setTimeout-defuser.js": 56,
		"ubo-setTimeout-defuser.js": 56,
		"ubo-setTimeout-defuser": 56,
		"std.js": 56,
		"ubo-std.js": 56,
		"ubo-std": 56,
		"prevent-setTimeout.js": 56,
		"prevent-window-open": 57,
		"window.open-defuser.js": 57,
		"ubo-window.open-defuser.js": 57,
		"ubo-window.open-defuser": 57,
		"nowoif.js": 57,
		"ubo-nowoif.js": 57,
		"ubo-nowoif": 57,
		"no-window-open-if.js": 57,
		"ubo-no-window-open-if.js": 57,
		"ubo-no-window-open-if": 57,
		"prevent-window-open.js": 57,
		"prevent-xhr": 58,
		"no-xhr-if.js": 58,
		"ubo-no-xhr-if.js": 58,
		"ubo-no-xhr-if": 58,
		"prevent-xhr.js": 58,
		"remove-attr": 59,
		"remove-attr.js": 59,
		"ubo-remove-attr.js": 59,
		"ra.js": 59,
		"ubo-ra.js": 59,
		"ubo-remove-attr": 59,
		"ubo-ra": 59,
		ra: 59,
		"remove-class": 60,
		"remove-class.js": 60,
		"ubo-remove-class.js": 60,
		"rc.js": 60,
		"ubo-rc.js": 60,
		"ubo-remove-class": 60,
		"ubo-rc": 60,
		rc: 60,
		"remove-cookie": 61,
		"cookie-remover.js": 61,
		"ubo-cookie-remover.js": 61,
		"ubo-cookie-remover": 61,
		"remove-cookie.js": 61,
		"ubo-remove-cookie.js": 61,
		"ubo-remove-cookie": 61,
		"abp-cookie-remover": 61,
		"cookie-remover": 61,
		"remove-in-shadow-dom": 62,
		"remove-node-text": 63,
		"remove-node-text.js": 63,
		"ubo-remove-node-text.js": 63,
		"rmnt.js": 63,
		"ubo-rmnt.js": 63,
		"ubo-remove-node-text": 63,
		"ubo-rmnt": 63,
		"scorecardresearch-beacon": 64,
		"ubo-scorecardresearch_beacon.js": 64,
		"scorecardresearch_beacon.js": 64,
		"set-attr": 65,
		"set-attr.js": 65,
		"ubo-set-attr.js": 65,
		"ubo-set-attr": 65,
		"set-constant": 66,
		"set-constant.js": 66,
		"ubo-set-constant.js": 66,
		"set.js": 66,
		"ubo-set.js": 66,
		"ubo-set-constant": 66,
		"ubo-set": 66,
		"override-property-read": 66,
		"set-cookie-reload": 67,
		"set-cookie-reload.js": 67,
		"ubo-set-cookie-reload.js": 67,
		"ubo-set-cookie-reload": 67,
		"set-cookie": 68,
		"set-cookie.js": 68,
		"ubo-set-cookie.js": 68,
		"ubo-set-cookie": 68,
		"set-local-storage-item": 69,
		"set-local-storage-item.js": 69,
		"ubo-set-local-storage-item.js": 69,
		"ubo-set-local-storage-item": 69,
		"set-popads-dummy": 70,
		"popads-dummy.js": 70,
		"ubo-popads-dummy.js": 70,
		"ubo-popads-dummy": 70,
		"set-session-storage-item": 71,
		"set-session-storage-item.js": 71,
		"ubo-set-session-storage-item.js": 71,
		"ubo-set-session-storage-item": 71,
		"spoof-css": 72,
		"spoof-css.js": 72,
		"ubo-spoof-css.js": 72,
		"ubo-spoof-css": 72,
		"trusted-click-element": 73,
		"trusted-create-element": 74,
		"trusted-dispatch-event": 75,
		"trusted-prune-inbound-object": 76,
		"trusted-replace-fetch-response": 77,
		"trusted-replace-node-text": 78,
		"trusted-replace-xhr-response": 79,
		"trusted-set-attr": 80,
		"trusted-set-constant": 81,
		"trusted-set-cookie-reload": 82,
		"trusted-set-cookie": 83,
		"trusted-set-local-storage-item": 84,
		"trusted-suppress-native-method": 85,
		"xml-prune": 86,
		"xml-prune.js": 86,
		"ubo-xml-prune.js": 86,
		"ubo-xml-prune": 86
	}
};
var compatibilityTableData = {
	modifiersCompatibilityTableData: modifiersCompatibilityTableData,
	redirectsCompatibilityTableData: redirectsCompatibilityTableData,
	scriptletsCompatibilityTableData: scriptletsCompatibilityTableData
};

__webpack_unused_export__ = compatibilityTableData;
exports.aB = modifiersCompatibilityTableData;
exports.HL = redirectsCompatibilityTableData;
exports.Rp = scriptletsCompatibilityTableData;


/***/ }),

/***/ 37302:
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";

// EXPORTS
__webpack_require__.d(__webpack_exports__, {
  "bm": () => (/* binding */ BufferRuleList),
  "LD": () => (/* binding */ CSP_HEADER_NAME),
  "cC": () => (/* binding */ CompatibilityTypes),
  "cT": () => (/* binding */ CosmeticResult),
  "D4": () => (/* binding */ Engine),
  "HV": () => (/* binding */ FilterListPreprocessor),
  "Ig": () => (/* reexport */ NETWORK_RULE_OPTIONS),
  "nC": () => (/* binding */ NetworkRule),
  "SJ": () => (/* binding */ NetworkRuleOption),
  "lN": () => (/* reexport */ OPTIONS_DELIMITER),
  "oF": () => (/* binding */ PERMISSIONS_POLICY_HEADER_NAME),
  "cf": () => (/* binding */ Request),
  "xd": () => (/* reexport */ RequestType),
  "Nr": () => (/* binding */ RuleFactory),
  "qc": () => (/* binding */ RuleStorage),
  "AG": () => (/* binding */ STEALTH_MODE_FILTER_ID),
  "SimpleRegex": () => (/* reexport */ simple_regex_dfa6ed82.S),
  "Mn": () => (/* binding */ StealthOptionName),
  "kz": () => (/* binding */ createAllowlistRuleList),
  "g3": () => (/* binding */ filterListChunksValidator),
  "Ff": () => (/* binding */ filterListSourceMapValidator),
  "k$": () => (/* binding */ preprocessedFilterListValidator),
  "Dg": () => (/* binding */ setConfiguration)
});

// UNUSED EXPORTS: CookieModifier, CosmeticEngine, CosmeticOption, CosmeticRule, DnsEngine, DnsResult, HTTPMethod, HostRule, IndexedRule, IndexedStorageRule, LIST_ID_MAX_VALUE, MatchingResult, NetworkEngine, NetworkRuleGroupOptions, PREPROCESSOR_AGTREE_OPTIONS, RULE_INDEX_NONE, RemoveHeaderModifier, RemoveParamModifier, ReplaceModifier, RuleSyntaxUtils, TSURLFILTER_VERSION, cleanUrlParamByRegExp, config, countEnabledBits, fastHash, filterListConversionMapValidator, findNextLineBreakIndex, getBitCount, getFilterBinaryName, getFilterConversionMapName, getFilterName, getFilterSourceMapName, getIdFromFilterName, getRelativeUrl, getRuleSourceIndex, getRuleSourceText, hasSpaces, hasUnquotedSubstring, indexOfAny, isCompatibleWith, isHttpOrWsRequest, isString, logger, replaceAll, setLogger, splitByDelimiterWithEscapeCharacter, startsAtIndexWith, stringArraysEquals, stringArraysHaveIntersection, unescapeChar

// EXTERNAL MODULE: ./node_modules/.pnpm/@adguard+tsurlfilter@3.1.0-alpha.7_@adguard+re2-wasm@1.2.0/node_modules/@adguard/tsurlfilter/dist/es/simple-regex-dfa6ed82.js
var simple_regex_dfa6ed82 = __webpack_require__(8549);
// EXTERNAL MODULE: ./node_modules/.pnpm/@adguard+agtree@2.1.2/node_modules/@adguard/agtree/dist/agtree.mjs + 3 modules
var agtree = __webpack_require__(94287);
// EXTERNAL MODULE: ./node_modules/.pnpm/tldts@5.6.45/node_modules/tldts/dist/es6/index.js + 2 modules
var es6 = __webpack_require__(85258);
// EXTERNAL MODULE: ./node_modules/.pnpm/@adguard+scriptlets@1.12.1/node_modules/@adguard/scriptlets/dist/umd/scriptlets.umd.js
var scriptlets_umd = __webpack_require__(97730);
var scriptlets_umd_default = /*#__PURE__*/__webpack_require__.n(scriptlets_umd);
// EXTERNAL MODULE: ./node_modules/.pnpm/@adguard+css-tokenizer@1.1.1/node_modules/@adguard/css-tokenizer/dist/csstokenizer.mjs
var csstokenizer = __webpack_require__(97094);
;// CONCATENATED MODULE: ./node_modules/.pnpm/@adguard+tsurlfilter@3.1.0-alpha.7_@adguard+re2-wasm@1.2.0/node_modules/@adguard/tsurlfilter/dist/es/network-rule-options.js
var NETWORK_RULE_OPTIONS = {
    THIRD_PARTY: 'third-party',
    FIRST_PARTY: 'first-party',
    MATCH_CASE: 'match-case',
    IMPORTANT: 'important',
    DOMAIN: 'domain',
    DENYALLOW: 'denyallow',
    ELEMHIDE: 'elemhide',
    GENERICHIDE: 'generichide',
    SPECIFICHIDE: 'specifichide',
    GENERICBLOCK: 'genericblock',
    JSINJECT: 'jsinject',
    URLBLOCK: 'urlblock',
    CONTENT: 'content',
    DOCUMENT: 'document',
    DOC: 'doc',
    STEALTH: 'stealth',
    POPUP: 'popup',
    EMPTY: 'empty',
    MP4: 'mp4',
    SCRIPT: 'script',
    STYLESHEET: 'stylesheet',
    SUBDOCUMENT: 'subdocument',
    OBJECT: 'object',
    IMAGE: 'image',
    XMLHTTPREQUEST: 'xmlhttprequest',
    MEDIA: 'media',
    FONT: 'font',
    WEBSOCKET: 'websocket',
    OTHER: 'other',
    PING: 'ping',
    BADFILTER: 'badfilter',
    CSP: 'csp',
    REPLACE: 'replace',
    COOKIE: 'cookie',
    REDIRECT: 'redirect',
    REDIRECTRULE: 'redirect-rule',
    REMOVEPARAM: 'removeparam',
    REMOVEHEADER: 'removeheader',
    JSONPRUNE: 'jsonprune',
    HLS: 'hls',
    REFERRERPOLICY: 'referrerpolicy',
    APP: 'app',
    NETWORK: 'network',
    EXTENSION: 'extension',
    NOOP: '_',
    CLIENT: 'client',
    DNSREWRITE: 'dnsrewrite',
    DNSTYPE: 'dnstype',
    CTAG: 'ctag',
    HEADER: 'header',
    METHOD: 'method',
    TO: 'to',
    PERMISSIONS: 'permissions',
    ALL: 'all',
};
var OPTIONS_DELIMITER = '$';
var MASK_ALLOWLIST = '@@';
var NOT_MARK = '~';
var ESCAPE_CHARACTER = '\\';



;// CONCATENATED MODULE: ./node_modules/.pnpm/@adguard+tsurlfilter@3.1.0-alpha.7_@adguard+re2-wasm@1.2.0/node_modules/@adguard/tsurlfilter/dist/es/request-type.js
/**
 * RequestType is the request types enumeration.
 * Important: the enumeration is marked as const to avoid side effects when
 * importing it into an extension.
 */
var RequestType = {
    /** No value is set. Syntax sugar to simplify code. */
    NotSet: 0,
    /** main frame */
    Document: 1,
    /** (iframe) $subdocument */
    SubDocument: 2,
    /** (javascript, etc) $script */
    Script: 4,
    /** (css) $stylesheet */
    Stylesheet: 8,
    /** (flash, etc) $object */
    Object: 16,
    /** (any image) $image */
    Image: 32,
    /** (ajax/fetch) $xmlhttprequest */
    XmlHttpRequest: 64,
    /** (video/music) $media */
    Media: 128,
    /** (any custom font) $font */
    Font: 256,
    /** (a websocket connection) $websocket */
    WebSocket: 512,
    /** (navigator.sendBeacon()) $ping */
    Ping: 1024,
    /** csp_report */
    CspReport: 2048,
    /** any other request type */
    Other: 4096, // 1 << 12
};



// EXTERNAL MODULE: ./node_modules/.pnpm/is-cidr@4.0.2/node_modules/is-cidr/index.js
var is_cidr = __webpack_require__(69918);
var is_cidr_default = /*#__PURE__*/__webpack_require__.n(is_cidr);
// EXTERNAL MODULE: ./node_modules/.pnpm/is-ip@3.1.0/node_modules/is-ip/index.js
var is_ip = __webpack_require__(13997);
var is_ip_default = /*#__PURE__*/__webpack_require__.n(is_ip);
// EXTERNAL MODULE: ./node_modules/.pnpm/cidr-tools@6.4.1/node_modules/cidr-tools/index.js + 3 modules
var cidr_tools = __webpack_require__(21289);
// EXTERNAL MODULE: ./node_modules/.pnpm/zod@3.21.4/node_modules/zod/lib/index.mjs
var lib = __webpack_require__(44945);
;// CONCATENATED MODULE: ./node_modules/.pnpm/@adguard+tsurlfilter@3.1.0-alpha.7_@adguard+re2-wasm@1.2.0/node_modules/@adguard/tsurlfilter/dist/es/index.js















var version = "3.1.0-alpha.7";

var TSURLFILTER_VERSION = (/* unused pure expression or super */ null && (version));
/**
 * Compatibility types are used to configure engine for better support of different libraries
 * For example:
 *  extension doesn't support $app modifier. So if we set in configuration CompatibilityTypes.Extension,
 *  engine would ignore rules with $app modifier
 */
var CompatibilityTypes;
(function (CompatibilityTypes) {
    CompatibilityTypes[CompatibilityTypes["Extension"] = 1] = "Extension";
    CompatibilityTypes[CompatibilityTypes["CoreLibs"] = 2] = "CoreLibs";
    CompatibilityTypes[CompatibilityTypes["Dns"] = 4] = "Dns";
})(CompatibilityTypes || (CompatibilityTypes = {}));
/**
 * Application configuration class
 */
var Configuration = /** @class */ (function () {
    function Configuration(inputConfig) {
        this.defaultConfig = {
            engine: null,
            version: null,
            verbose: false,
            compatibility: null,
        };
        /**
         * {'extension'|'corelibs'} engine application type
         */
        this.engine = null;
        /**
         * {string} version
         */
        this.version = null;
        /**
         * {boolean} verbose flag
         */
        this.verbose = false;
        /**
         * compatibility flag
         */
        this.compatibility = CompatibilityTypes.Extension;
        var config = (0,simple_regex_dfa6ed82._)((0,simple_regex_dfa6ed82._)({}, this.defaultConfig), inputConfig);
        this.engine = config.engine;
        this.version = config.version;
        this.verbose = config.verbose;
        this.compatibility = config.compatibility;
    }
    return Configuration;
}());
// eslint-disable-next-line import/no-mutable-exports
var config = new Configuration();
/**
 * Checks config is compatible with input level
 * @param compatibilityLevel
 * @private
 */
function isCompatibleWith(compatibilityLevel) {
    if (config.compatibility === null) {
        return false;
    }
    return (config.compatibility & compatibilityLevel) === compatibilityLevel;
}
var setConfiguration = function (outerConfig) {
    config = new Configuration(outerConfig);
};

/**
 * Export logger implementation
 */
var logger = console;
/**
 * Set logger implementation
 *
 * @param loggerImpl
 */
function setLogger(loggerImpl) {
    logger = loggerImpl;
}

/**
 * Pipe separator
 */
var PIPE_SEPARATOR$1 = '|';
/**
 * This is a helper class that is used specifically to work
 * with domains restrictions.
 *
 * There are two options how you can add a domain restriction:
 * * `$domain` modifier: https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#domain-modifier
 * * domains list for the cosmetic rules
 *
 * The only difference between them is that in one case we use `|` as a separator,
 * and in the other case - `,`.
 *
 * Examples:
 * * `||example.org^$domain=example.com|~sub.example.com` -- network rule
 * * `example.com,~sub.example.com##banner` -- cosmetic rule
 */
var DomainModifier = /** @class */ (function () {
    /**
     * Parses the `domains` string and initializes the object.
     *
     * @param domains Domain list string or AGTree DomainList node.
     * @param separator Separator — `,` or `|`.
     *
     * @throws An error if the domains string is empty or invalid
     */
    function DomainModifier(domains, separator) {
        var processed;
        if ((0,simple_regex_dfa6ed82.i)(domains)) {
            var node = agtree/* DomainListParser.parse */.Wf.parse(domains.trim(), (0,simple_regex_dfa6ed82._)((0,simple_regex_dfa6ed82._)({}, agtree/* defaultParserOptions */.Xm), { isLocIncluded: false }), 0, separator);
            if (node.children.length === 0) {
                throw new SyntaxError('At least one domain must be specified');
            }
            processed = DomainModifier.processDomainList(node);
        }
        else {
            // domain list node stores the separator
            if (separator !== domains.separator) {
                throw new SyntaxError('Separator mismatch');
            }
            processed = DomainModifier.processDomainList(domains);
        }
        // Unescape separator character in domains
        processed.permittedDomains = processed.permittedDomains.map(function (domain) { return (0,simple_regex_dfa6ed82.u)(domain, separator); });
        processed.restrictedDomains = processed.restrictedDomains.map(function (domain) { return (0,simple_regex_dfa6ed82.u)(domain, separator); });
        this.restrictedDomains = processed.restrictedDomains.length > 0 ? processed.restrictedDomains : null;
        this.permittedDomains = processed.permittedDomains.length > 0 ? processed.permittedDomains : null;
    }
    /**
     * Processes domain list node, which means extracting permitted and restricted
     * domains from it.
     *
     * @param domainListNode Domain list node to process
     * @returns Processed domain list (permitted and restricted domains) ({@link ProcessedDomainList})
     */
    DomainModifier.processDomainList = function (domainListNode) {
        var result = {
            permittedDomains: [],
            restrictedDomains: [],
        };
        var domains = domainListNode.children;
        for (var _i = 0, domains_1 = domains; _i < domains_1.length; _i++) {
            var _a = domains_1[_i], exception = _a.exception, domain = _a.value;
            var domainLowerCased = domain.toLowerCase();
            if (!simple_regex_dfa6ed82.S.isRegexPattern(domain) && domain.includes(simple_regex_dfa6ed82.W) && !domain.endsWith(simple_regex_dfa6ed82.W)) {
                throw new SyntaxError("Wildcards are only supported for top-level domains: \"".concat(domain, "\""));
            }
            if (exception) {
                result.restrictedDomains.push(domainLowerCased);
            }
            else {
                result.permittedDomains.push(domainLowerCased);
            }
        }
        return result;
    };
    /**
     * Checks if the filtering rule is allowed on this domain.
     *
     * @param domain Domain to check.
     *
     * @returns True if the filtering rule is allowed on this domain.
     */
    DomainModifier.prototype.matchDomain = function (domain) {
        if (this.hasRestrictedDomains()) {
            if (DomainModifier.isDomainOrSubdomainOfAny(domain, this.restrictedDomains)) {
                // Domain or host is restricted
                // i.e. $domain=~example.org
                return false;
            }
        }
        if (this.hasPermittedDomains()) {
            if (!DomainModifier.isDomainOrSubdomainOfAny(domain, this.permittedDomains)) {
                // Domain is not among permitted
                // i.e. $domain=example.org and we're checking example.com
                return false;
            }
        }
        return true;
    };
    /**
     * Checks if rule has permitted domains
     */
    DomainModifier.prototype.hasPermittedDomains = function () {
        return !!this.permittedDomains && this.permittedDomains.length > 0;
    };
    /**
     * Checks if rule has restricted domains
     */
    DomainModifier.prototype.hasRestrictedDomains = function () {
        return !!this.restrictedDomains && this.restrictedDomains.length > 0;
    };
    /**
     * Gets list of permitted domains.
     */
    DomainModifier.prototype.getPermittedDomains = function () {
        return this.permittedDomains;
    };
    /**
     * Gets list of restricted domains.
     */
    DomainModifier.prototype.getRestrictedDomains = function () {
        return this.restrictedDomains;
    };
    /**
     * isDomainOrSubdomainOfAny checks if `domain` is the same or a subdomain
     * of any of `domains`.
     *
     * @param domain - domain to check
     * @param domains - domains list to check against
     *
     * @returns true if `domain` is the same or a subdomain of any of `domains`
     */
    DomainModifier.isDomainOrSubdomainOfAny = function (domain, domains) {
        for (var i = 0; i < domains.length; i += 1) {
            var d = domains[i];
            if (DomainModifier.isWildcardDomain(d)) {
                if (DomainModifier.matchAsWildcard(d, domain)) {
                    return true;
                }
            }
            if (domain === d || (domain.endsWith(d) && domain.endsWith(".".concat(d)))) {
                return true;
            }
            if (simple_regex_dfa6ed82.S.isRegexPattern(d)) {
                try {
                    /**
                     * Regular expressions are cached internally by the browser
                     * (for instance, they're stored in the CompilationCache in V8/Chromium),
                     * so calling the constructor here should not be a problem.
                     *
                     * TODO use SimpleRegex.patternFromString(d) after it is refactored to not add 'g' flag
                     */
                    var domainPattern = new RegExp(d.slice(1, -1));
                    if (domainPattern.test(domain)) {
                        return true;
                    }
                }
                catch (_a) {
                    logger.error("Invalid regular expression as domain pattern: \"".concat(d, "\""));
                }
                continue;
            }
        }
        return false;
    };
    /**
     * Checks if domain ends with wildcard
     *
     * @param domain domain string to check
     *
     * @returns true if domain ends with wildcard
     */
    DomainModifier.isWildcardDomain = function (domain) {
        return domain.endsWith('.*');
    };
    /**
     * Checks if domain string does not ends with wildcard and is not regex pattern
     *
     * @param domain domain string to check
     *
     * @returns true if given domain is a wildcard or regexp pattern
     */
    DomainModifier.isWildcardOrRegexDomain = function (domain) {
        return DomainModifier.isWildcardDomain(domain) || simple_regex_dfa6ed82.S.isRegexPattern(domain);
    };
    /**
     * Checks if wildcard matches domain
     *
     * @param wildcard
     * @param domainNameToCheck
     *
     * @returns true if wildcard matches domain
     */
    DomainModifier.matchAsWildcard = function (wildcard, domainNameToCheck) {
        var wildcardedDomainToCheck = DomainModifier.genTldWildcard(domainNameToCheck);
        if (wildcardedDomainToCheck) {
            return wildcardedDomainToCheck === wildcard
                || (wildcardedDomainToCheck.endsWith(wildcard) && wildcardedDomainToCheck.endsWith(".".concat(wildcard)));
        }
        return false;
    };
    /**
     * Generates from domain tld wildcard e.g. google.com -> google.* ; youtube.co.uk -> youtube.*
     *
     * @param domainName
     *
     * @returns string is empty if tld for provided domain name doesn't exists
     */
    DomainModifier.genTldWildcard = function (domainName) {
        // To match eTld like "com.ru" we use allowPrivateDomains wildcard
        // https://github.com/AdguardTeam/AdguardBrowserExtension/issues/2650
        var tld = (0,es6/* getPublicSuffix */.cH)(domainName, { allowPrivateDomains: true });
        if (tld) {
            // lastIndexOf() is needed not to match the domain, e.g. 'www.chrono24.ch'.
            // https://github.com/AdguardTeam/AdguardBrowserExtension/issues/2312.
            return "".concat(domainName.slice(0, domainName.lastIndexOf(".".concat(tld))), ".*");
        }
        return '';
    };
    return DomainModifier;
}());

/**
 * CosmeticLookupTable lets quickly lookup cosmetic rules for the specified hostname.
 * It is primarily used by the {@see CosmeticEngine}.
 */
var CosmeticLookupTable = /** @class */ (function () {
    /**
     * Creates a new instance
     *
     * @param storage rules storage. We store "rule indexes" in the lookup table which
     * can be used to retrieve the full rules from the storage.
     */
    function CosmeticLookupTable(storage) {
        var _this = this;
        /**
         * Checks if a scriptlet is allowlisted for a request. It looks up the scriptlet
         * by content in the allowlist map and evaluates two conditions:
         * 1. If there's a generic allowlist rule applicable to all sites.
         * 2. If there's a specific allowlist rule that matches the request.
         *
         * @param content Content of the scriptlet. Empty string '' searches for scriptlets allowlisted globally.
         * @param request Request details to match against allowlist rules.
         * @returns True if allowlisted by a matching rule or a generic rule. False otherwise.
         */
        this.isScriptletAllowlisted = function (content, request) {
            // check for rules with that content
            var allowlistScriptletRulesIndexes = _this.allowlist.get(content);
            if (allowlistScriptletRulesIndexes) {
                var rules = allowlistScriptletRulesIndexes
                    .map(function (i) {
                    return _this.ruleStorage.retrieveRule(i);
                })
                    .filter(function (r) { return r; });
                // here we check if there is at least one generic allowlist rule
                var hasAllowlistGenericScriptlet = rules.some(function (r) {
                    return r.isGeneric();
                });
                if (hasAllowlistGenericScriptlet) {
                    return true;
                }
                // here we check if there is at least one allowlist rule that matches the request
                var hasRuleMatchingRequest = rules.some(function (r) { return r.match(request); });
                if (hasRuleMatchingRequest) {
                    return true;
                }
            }
            return false;
        };
        this.byHostname = new Map();
        this.seqScanRules = [];
        this.genericRules = [];
        this.allowlist = new Map();
        this.ruleStorage = storage;
    }
    /**
     * Adds rule to the allowlist map
     * @param key Can be used any string, but here we use ruleContent, scriptlet content, or scriptlet name.
     * @param storageIdx Index of the rule.
     */
    CosmeticLookupTable.prototype.addAllowlistRule = function (key, storageIdx) {
        var existingRules = this.allowlist.get(key);
        if (!existingRules) {
            this.allowlist.set(key, [storageIdx]);
            return;
        }
        existingRules.push(storageIdx);
    };
    /**
     * Adds rule to the appropriate collection
     * @param rule
     * @param storageIdx
     */
    CosmeticLookupTable.prototype.addRule = function (rule, storageIdx) {
        if (rule.isAllowlist()) {
            if (rule.isScriptlet) {
                // Store scriptlet rules by name to enable the possibility of allowlisting them.
                // See https://github.com/AdguardTeam/Scriptlets/issues/377 for more details.
                if (rule.scriptletParams.name !== undefined
                    && rule.scriptletParams.args.length === 0) {
                    this.addAllowlistRule(rule.scriptletParams.name, storageIdx);
                }
                // Use normalized scriptlet content for better matching.
                // For example, //scriptlet('log', 'arg') can be matched by //scriptlet("log", "arg").
                this.addAllowlistRule(rule.scriptletParams.toString(), storageIdx);
            }
            else {
                // Store all other rules by their content.
                this.addAllowlistRule(rule.getContent(), storageIdx);
            }
            return;
        }
        if (rule.isGeneric()) {
            this.genericRules.push(rule);
            return;
        }
        var permittedDomains = rule.getPermittedDomains();
        if (permittedDomains) {
            if (permittedDomains.some(DomainModifier.isWildcardOrRegexDomain)) {
                this.seqScanRules.push(rule);
                return;
            }
            for (var _i = 0, permittedDomains_1 = permittedDomains; _i < permittedDomains_1.length; _i++) {
                var domain = permittedDomains_1[_i];
                var tldResult = (0,es6/* parse */.Qc)(domain);
                // tldResult.domain equals to eTLD domain,
                // e.g. sub.example.uk.org would result in example.uk.org
                var parsedDomain = tldResult.domain || domain;
                var key = (0,simple_regex_dfa6ed82.f)(parsedDomain);
                var rules = this.byHostname.get(key) || [];
                rules.push(storageIdx);
                this.byHostname.set(key, rules);
            }
        }
    };
    /**
     * Finds rules by hostname
     * @param request
     */
    CosmeticLookupTable.prototype.findByHostname = function (request) {
        var result = [];
        var subdomains = request.subdomains;
        var _loop_1 = function (i) {
            var subdomain = subdomains[i];
            var rulesIndexes = this_1.byHostname.get((0,simple_regex_dfa6ed82.f)(subdomain));
            if (rulesIndexes) {
                // Filtering out duplicates
                rulesIndexes = rulesIndexes.filter(function (v, index) { return rulesIndexes.indexOf(v) === index; });
                for (var j = 0; j < rulesIndexes.length; j += 1) {
                    var rule = this_1.ruleStorage.retrieveRule(rulesIndexes[j]);
                    if (rule && !rule.isAllowlist() && rule.match(request)) {
                        result.push(rule);
                    }
                }
            }
        };
        var this_1 = this;
        // Iterate over all sub-domains
        for (var i = 0; i < subdomains.length; i += 1) {
            _loop_1(i);
        }
        result.push.apply(result, this.seqScanRules.filter(function (r) { return !r.isAllowlist() && r.match(request); }));
        return result;
    };
    /**
     * Checks if the rule is disabled on the specified hostname.
     * @param request
     * @param rule
     */
    CosmeticLookupTable.prototype.isAllowlisted = function (request, rule) {
        if (rule.isScriptlet) {
            // Empty string '' is a special case for scriptlet when the allowlist scriptlet has no name
            // e.g. #@%#//scriptlet(); example.org#@%#//scriptlet();
            var EMPTY_SCRIPTLET_NAME = '';
            if (this.isScriptletAllowlisted(EMPTY_SCRIPTLET_NAME, request)) {
                return true;
            }
            // If scriptlet allowlisted by name
            // e.g. #@%#//scriptlet('set-cookie'); example.org#@%#//scriptlet('set-cookie');
            if (rule.scriptletParams.name !== undefined
                && this.isScriptletAllowlisted(rule.scriptletParams.name, request)) {
                return true;
            }
            // If scriptlet allowlisted with args, using normalized scriptlet content for better matching
            // on different quote types (see https://github.com/AdguardTeam/AdguardBrowserExtension/issues/2947)
            // e.g. #@%#//scriptlet("set-cookie", "arg1"); example.org#@%#//scriptlet('set-cookie', 'arg1');
            if (rule.scriptletParams.name !== undefined
                && rule.scriptletParams.args.length > 0
                && this.isScriptletAllowlisted(rule.scriptletParams.toString(), request)) {
                return true;
            }
        }
        var rulesIndexes = this.allowlist.get(rule.getContent());
        if (!rulesIndexes) {
            return false;
        }
        for (var j = 0; j < rulesIndexes.length; j += 1) {
            var r = this.ruleStorage.retrieveRule(rulesIndexes[j]);
            if (r && r.match(request)) {
                return true;
            }
        }
        return false;
    };
    return CosmeticLookupTable;
}());

/* eslint-disable max-classes-per-file */
/**
 * Default rule index for source mapping.
 *
 * It is -1, similar to `Array.indexOf()` return value when element is not found.
 */
var RULE_INDEX_NONE = -1;
/**
 * Rule with index
 */
// TODO: Consider remove this because rule already has an index field
var IndexedRule = /** @class */ (function () {
    /**
     * Constructor
     *
     * @param rule
     * @param index
     */
    function IndexedRule(rule, index) {
        this.rule = rule;
        this.index = index;
    }
    return IndexedRule;
}());
/**
 * Rule with storage index
 */
var IndexedStorageRule = /** @class */ (function () {
    /**
     * Constructor
     *
     * @param rule
     * @param index
     */
    function IndexedStorageRule(rule, index) {
        this.rule = rule;
        this.index = index;
    }
    return IndexedStorageRule;
}());

/**
 * Splits url into parts
 *
 * @param url
 */
function splitUrl(url) {
    var strippedUrl = url;
    var hash = '';
    var hashIndex = url.indexOf('#');
    if (hashIndex >= 0) {
        hash = url.slice(hashIndex);
        strippedUrl = url.slice(0, hashIndex);
    }
    var query = '';
    var queryIndex = url.indexOf('?');
    if (queryIndex >= 0) {
        query = strippedUrl.slice(queryIndex + 1);
        strippedUrl = strippedUrl.slice(0, queryIndex);
    }
    return {
        path: strippedUrl,
        query: query,
        hash: hash,
    };
}
/**
 * Normalizes url query parameters
 *
 * @param query
 */
function normalizeQuery(query) {
    // Cleanup empty params (p0=0&=2&=3)
    var result = query
        .split('&')
        .filter(function (x) { return x && !x.startsWith('='); })
        .join('&');
    // If we've collapsed the URL to the point where there's an '&' against the '?'
    // then we need to get rid of that.
    while (result.charAt(0) === '&') {
        result = result.slice(1);
    }
    return result;
}
/**
 * Removes query params from url by regexp
 *
 * @param url
 * @param regExp
 * @param invert remove every parameter in url except the ones matched regexp
 */
function cleanUrlParamByRegExp(url, regExp, invert) {
    if (invert === void 0) { invert = false; }
    var searchIndex = url.indexOf('?');
    // If no params, nothing to modify
    if (searchIndex === -1) {
        return url;
    }
    var split = splitUrl(url);
    var modifiedQuery;
    if (invert) {
        modifiedQuery = split.query
            .split('&')
            .filter(function (x) { return x; })
            .filter(function (x) { return x && x.match(regExp); })
            .join('&');
    }
    else {
        modifiedQuery = split.query
            .split('&')
            .filter(function (x) {
            var test = x.includes('=') ? x : "".concat(x, "=");
            return !test.match(regExp);
        })
            .join('&');
    }
    // Do not normalize if regexp is not applied
    if (modifiedQuery === split.query) {
        return url;
    }
    modifiedQuery = normalizeQuery(modifiedQuery);
    var result = split.path;
    if (modifiedQuery) {
        result += "?".concat(modifiedQuery);
    }
    return result + split.hash;
}
/**
 * Extract relative part from hierarchical structured URL
 * @param url
 */
var getRelativeUrl = function (url) {
    var i = url.indexOf('/', url.indexOf('://') + 3);
    return i !== -1 ? url.slice(i) : null;
};
/**
 * Checks if url is http or websocket.
 *
 * @param url Request url.
 * @returns True if url starts with http{s?} or ws.
 */
function isHttpOrWsRequest(url) {
    return !!url && (url.startsWith('http') || url.startsWith('ws'));
}

/**
 * Rule pattern class
 *
 * This class parses rule pattern text to simple fields.
 */
var Pattern = /** @class */ (function () {
    /**
     * Constructor
     * @param pattern
     * @param matchcase
     */
    function Pattern(pattern, matchcase) {
        if (matchcase === void 0) { matchcase = false; }
        this.pattern = pattern;
        this.shortcut = simple_regex_dfa6ed82.S.extractShortcut(this.pattern);
        this.matchcase = matchcase;
    }
    /**
     * Checks if this rule pattern matches the specified request.
     *
     * @param request - request to check
     * @param shortcutMatched if true, it means that the request already matches
     * this pattern's shortcut and we don't need to match it again.
     * @returns true if pattern matches
     */
    Pattern.prototype.matchPattern = function (request, shortcutMatched) {
        this.prepare();
        if (this.patternShortcut) {
            return shortcutMatched || this.matchShortcut(request.urlLowercase);
        }
        if (this.hostname) {
            // If we have a `||example.org^` rule, it's easier to match
            // against the request's hostname only without matching
            // a regular expression.
            return request.hostname === this.hostname
                || ( // First light check without new string memory allocation
                request.hostname.endsWith(this.hostname)
                    // Strict check
                    && request.hostname.endsWith(".".concat(this.hostname)));
        }
        // If the regular expression is invalid, just return false right away.
        if (this.regexInvalid || !this.regex) {
            return false;
        }
        // This is needed for DNS filtering only, not used in browser blocking.
        if (this.shouldMatchHostname(request)) {
            return this.regex.test(request.hostname);
        }
        return this.regex.test(request.url);
    };
    /**
     * Checks if this rule pattern matches the specified relative path string.
     * This method is used in cosmetic rules to implement the $path modifier matching logic.
     *
     * @param path - path to check
     * @returns true if pattern matches
     */
    Pattern.prototype.matchPathPattern = function (path) {
        this.prepare();
        if (this.hostname) {
            return false;
        }
        var pathIsEmptyString = this.pattern === '';
        // No-value $path should match root URL
        if (pathIsEmptyString && path === '/') {
            return true;
        }
        if (!pathIsEmptyString && this.patternShortcut) {
            return this.matchShortcut(path);
        }
        // If the regular expression is invalid, just return false right away.
        if (this.regexInvalid || !this.regex) {
            return false;
        }
        return this.regex.test(path);
    };
    /**
     * matchShortcut simply checks if shortcut is a substring of the URL.
     * @param request - request to check.
     */
    Pattern.prototype.matchShortcut = function (str) {
        return str.indexOf(this.shortcut) >= 0;
    };
    /**
     * Prepares this pattern
     */
    Pattern.prototype.prepare = function () {
        if (this.prepared) {
            return;
        }
        this.prepared = true;
        // If shortcut and pattern are the same, we don't need to actually compile
        // a regex and can simply use matchShortcut instead,
        // except for the $match-case modifier
        if (this.pattern === this.shortcut && !this.matchcase) {
            this.patternShortcut = true;
            return;
        }
        // Rules like `/example/*` are rather often in the real-life filters,
        // we might want to process them.
        if (this.pattern.startsWith(this.shortcut)
            && this.pattern.length === this.shortcut.length + 1
            && this.pattern.endsWith('*')) {
            this.patternShortcut = true;
            return;
        }
        if (this.pattern.startsWith(simple_regex_dfa6ed82.S.MASK_START_URL)
            && this.pattern.endsWith(simple_regex_dfa6ed82.S.MASK_SEPARATOR)
            && this.pattern.indexOf('*') < 0
            && this.pattern.indexOf('/') < 0) {
            this.hostname = this.pattern.slice(2, this.pattern.length - 1);
            return;
        }
        this.compileRegex();
    };
    /**
     * Compiles this pattern regex
     */
    Pattern.prototype.compileRegex = function () {
        var regexText = simple_regex_dfa6ed82.S.patternToRegexp(this.pattern);
        try {
            var flags = 'i';
            if (this.matchcase) {
                flags = '';
            }
            this.regex = new RegExp(regexText, flags);
        }
        catch (e) {
            this.regexInvalid = true;
        }
    };
    /**
     * Checks if we should match hostnames and not the URL
     * this is important for the cases when we use urlfilter for DNS-level blocking
     * Note, that even though we may work on a DNS-level, we should still sometimes match full URL instead
     *
     * @param request
     */
    Pattern.prototype.shouldMatchHostname = function (request) {
        if (!request.isHostnameRequest) {
            return false;
        }
        return !this.isPatternDomainSpecific();
    };
    /**
     * In case pattern starts with the following it targets some specific domain
     */
    Pattern.prototype.isPatternDomainSpecific = function () {
        if (this.patternDomainSpecific === undefined) {
            this.patternDomainSpecific = this.pattern.startsWith(simple_regex_dfa6ed82.S.MASK_START_URL)
                || this.pattern.startsWith('http://')
                || this.pattern.startsWith('https:/')
                || this.pattern.startsWith('://');
        }
        return this.patternDomainSpecific;
    };
    return Pattern;
}());

/**
 * @file Known CSS / Extended CSS elements
 */
/**
 * Supported Extended CSS pseudo-classes.
 *
 * These pseudo-classes are not supported by browsers natively, so we need Extended CSS library to support them.
 *
 * Please keep this list sorted alphabetically.
 */
var SUPPORTED_EXT_CSS_PSEUDO_CLASSES = new Set([
    /**
     * Pseudo-classes :is(), and :not() may use native implementation
     * so they are not listed here
     * https://github.com/AdguardTeam/ExtendedCss#extended-css-is
     * https://github.com/AdguardTeam/ExtendedCss#extended-css-not
     */
    /**
     * :has() should also be conditionally considered as extended and should not be in this list
     * https://github.com/AdguardTeam/ExtendedCss#extended-css-has
     * but there is a bug with content blocker in safari
     * https://bugs.webkit.org/show_bug.cgi?id=248868
     *
     * TODO: remove 'has' later
     */
    '-abp-contains',
    '-abp-has',
    'contains',
    'has',
    'has-text',
    'if',
    'if-not',
    'matches-attr',
    'matches-css',
    'matches-css-after',
    'matches-css-before',
    'matches-property',
    'nth-ancestor',
    'remove',
    'upward',
    'xpath',
]);
/**
 * Supported native CSS pseudo-classes.
 *
 * These pseudo-classes are supported by browsers natively, so we don't need Extended CSS library to support them.
 *
 * The problem with pseudo-classes is that any unknown pseudo-class makes browser ignore the whole CSS rule,
 * which contains a lot more selectors. So, if CSS selector contains a pseudo-class, we should try to validate it.
 * One more problem with pseudo-classes is that they are actively used in uBlock, hence it may mess AG styles.
 *
 * Please keep this list sorted alphabetically.
 */
var SUPPORTED_CSS_PSEUDO_CLASSES = new Set([
    'active',
    'checked',
    'disabled',
    'empty',
    'enabled',
    'first-child',
    'first-of-type',
    'focus',
    'has',
    'hover',
    'in-range',
    'invalid',
    'is',
    'lang',
    'last-child',
    'last-of-type',
    'link',
    'not',
    'nth-child',
    'nth-last-child',
    'nth-last-of-type',
    'nth-of-type',
    'only-child',
    'only-of-type',
    'optional',
    'out-of-range',
    'read-only',
    'read-write',
    'required',
    'root',
    'target',
    'valid',
    'visited',
    'where', // https://developer.mozilla.org/en-US/docs/Web/CSS/:where
]);
/**
 * Every Extended CSS pseudo-class should start with this prefix.
 *
 * @see {@link https://github.com/AdguardTeam/ExtendedCss#-backward-compatible-syntax}
 */
var EXT_CSS_ATTRIBUTE_SELECTOR_PREFIX = '-ext-';
/**
 * Supported legacy Extended CSS attribute selectors.
 *
 * Attribute selector way is deprecated and will be removed completely in the future,
 * we replaced it with Extended CSS pseudo-classes. For example, instead of
 * `[-ext-has="a[href]"]` you should use `:has(a[href])`.
 *
 * Please keep this list sorted alphabetically.
 */
var SUPPORTED_EXT_CSS_ATTRIBUTE_SELECTORS = new Set([
    "".concat(EXT_CSS_ATTRIBUTE_SELECTOR_PREFIX, "has"),
    "".concat(EXT_CSS_ATTRIBUTE_SELECTOR_PREFIX, "contains"),
    "".concat(EXT_CSS_ATTRIBUTE_SELECTOR_PREFIX, "has-text"),
    "".concat(EXT_CSS_ATTRIBUTE_SELECTOR_PREFIX, "matches-css"),
    "".concat(EXT_CSS_ATTRIBUTE_SELECTOR_PREFIX, "matches-css-before"),
    "".concat(EXT_CSS_ATTRIBUTE_SELECTOR_PREFIX, "matches-css-after"),
]);
/**
 * Known CSS functions that aren't allowed in CSS injection rules, because they
 * able to load external resources. Please, keep this list sorted.
 */
var FORBIDDEN_CSS_FUNCTIONS = new Set([
    // https://developer.mozilla.org/en-US/docs/Web/CSS/cross-fade
    '-webkit-cross-fade',
    'cross-fade',
    // https://developer.mozilla.org/en-US/docs/Web/CSS/image
    'image',
    // https://developer.mozilla.org/en-US/docs/Web/CSS/image-set
    '-webkit-image-set',
    'image-set',
    // https://developer.mozilla.org/en-US/docs/Web/CSS/url
    'url',
]);

/**
 * Checks if error has message.
 *
 * @param error Error object.
 * @returns If param is error.
 */
function isErrorWithMessage(error) {
    return (typeof error === 'object'
        && error !== null
        && 'message' in error
        && typeof error.message === 'string');
}
/**
 * Converts error to the error with message.
 *
 * @param maybeError Possible error.
 * @returns Error with message.
 */
function toErrorWithMessage(maybeError) {
    if (isErrorWithMessage(maybeError)) {
        return maybeError;
    }
    try {
        return new Error(JSON.stringify(maybeError));
    }
    catch (_a) {
        // fallback in case there's an error stringifying the maybeError
        // like with circular references for example.
        return new Error(String(maybeError));
    }
}
/**
 * Converts error object to error with message. This method might be helpful to handle thrown errors.
 *
 * @param error Error object.
 *
 * @returns Message of the error.
 */
function getErrorMessage(error) {
    return toErrorWithMessage(error).message;
}

/**
 * @file Selector list validator.
 */
/**
 * Does a basic validation of a selector list.
 * Checks for unsupported pseudo-classes and attribute selectors,
 * and determines if the selector is an Extended CSS selector.
 *
 * @param selectorList Selector list to validate.
 * @returns Validation result, see {@link CssValidationResult}.
 * @note This is a basic validation for the most necessary things, it does not guarantee that the CSS is completely
 * valid.
 */
var validateSelectorList = function (selectorList) {
    var result = {
        isValid: true,
        isExtendedCss: false,
    };
    try {
        var prevIsDoubleColon_1 = false;
        var prevToken_1;
        var prevNonWhitespaceToken_1;
        (0,csstokenizer/* tokenizeExtended */.lL)(selectorList, function (token, start, end) {
            if ((token === csstokenizer/* TokenType.Function */.iv.Function || token === csstokenizer/* TokenType.Ident */.iv.Ident)
                && prevToken_1 === csstokenizer/* TokenType.Colon */.iv.Colon
                && !prevIsDoubleColon_1) {
                // whitespace is NOT allowed between the ':' and the pseudo-class name, like ': active('
                var name_1 = selectorList.slice(start, 
                // function tokens look like 'func(', so we need to remove the last character
                token === csstokenizer/* TokenType.Function */.iv.Function ? end - 1 : end);
                // function name may contain escaped characters, like '\75' instead of 'u', so we need to decode it
                var decodedName = (0,csstokenizer/* decodeIdent */.pV)(name_1);
                if (SUPPORTED_EXT_CSS_PSEUDO_CLASSES.has(decodedName)) {
                    result.isExtendedCss = true;
                }
                else if (!SUPPORTED_CSS_PSEUDO_CLASSES.has(decodedName)) {
                    throw new Error("Unsupported pseudo-class: ':".concat(decodedName, "'"));
                }
            }
            else if (token === csstokenizer/* TokenType.Ident */.iv.Ident && prevNonWhitespaceToken_1 === csstokenizer/* TokenType.OpenSquareBracket */.iv.OpenSquareBracket) {
                // whitespace is allowed between the '[' and the attribute name, like '[ attr]'
                var attributeName = selectorList.slice(start, end);
                if (attributeName.startsWith(EXT_CSS_ATTRIBUTE_SELECTOR_PREFIX)) {
                    result.isExtendedCss = true;
                    if (!SUPPORTED_EXT_CSS_ATTRIBUTE_SELECTORS.has(attributeName)) {
                        throw new Error("Unsupported Extended CSS attribute selector: '".concat(attributeName, "'"));
                    }
                }
            }
            else if (token === csstokenizer/* TokenType.OpenCurlyBracket */.iv.OpenCurlyBracket || token === csstokenizer/* TokenType.CloseCurlyBracket */.iv.CloseCurlyBracket) {
                throw new Error('Curly brackets are not allowed in selector lists');
            }
            else if (token === csstokenizer/* TokenType.Comment */.iv.Comment) {
                throw new Error('Comments are not allowed in selector lists');
            }
            // memorize tokens, we need them later
            if (token === csstokenizer/* TokenType.Colon */.iv.Colon) {
                prevIsDoubleColon_1 = prevToken_1 === csstokenizer/* TokenType.Colon */.iv.Colon;
            }
            prevToken_1 = token;
            if (token !== csstokenizer/* TokenType.Whitespace */.iv.Whitespace) {
                prevNonWhitespaceToken_1 = token;
            }
        });
    }
    catch (error) {
        result.isValid = false;
        result.errorMessage = getErrorMessage(error);
    }
    return result;
};

/**
 * @file Declaration list validator.
 */
var REMOVE_PROPERTY = 'remove';
var REMOVE_LENGTH = REMOVE_PROPERTY.length;
/**
 * Check if function name is forbidden. If so, throws an error.
 *
 * @param functionName Function name to check.
 * @throws Error if function name is forbidden.
 */
var checkFunctionName = function (functionName) {
    // function name may contain escaped characters, like '\75' instead of 'u', so we need to decode it
    var decodedFunctionName = (0,csstokenizer/* decodeIdent */.pV)(functionName);
    if (FORBIDDEN_CSS_FUNCTIONS.has(decodedFunctionName)) {
        throw new Error("Using '".concat(decodedFunctionName, "()' is not allowed"));
    }
};
/**
 * Does a basic validation of a declaration list.
 * Checks for unsafe resource loading and determines if the declaration list is an Extended CSS declaration list.
 *
 * @param declarationList Declaration list to validate.
 * @returns Validation result, see {@link CssValidationResult}.
 * @note This is a basic validation for the most necessary things, it does not guarantee that the CSS is completely
 * valid.
 */
var validateDeclarationList = function (declarationList) {
    var result = {
        isValid: true,
        isExtendedCss: false,
    };
    try {
        (0,csstokenizer/* tokenizeExtended */.lL)(declarationList, function (token, start, end) {
            switch (token) {
                // Special case: according to CSS specs, sometimes url() is handled as a separate token type
                case csstokenizer/* TokenType.Url */.iv.Url:
                case csstokenizer/* TokenType.BadUrl */.iv.BadUrl:
                    throw new Error("Using 'url()' is not allowed");
                case csstokenizer/* TokenType.Function */.iv.Function:
                    // we need -1 to exclude closing bracket, because function tokens look like 'func('
                    checkFunctionName(declarationList.slice(start, end - 1));
                    break;
                case csstokenizer/* TokenType.Ident */.iv.Ident:
                    // do a fast check before getting the substring
                    if (end - start === REMOVE_LENGTH) {
                        // TODO: Improve this check, and check the whole `remove: true` sequence.
                        // Please note that the `remove : true` case also valid.
                        if ((0,csstokenizer/* decodeIdent */.pV)(declarationList.slice(start, end)) === REMOVE_PROPERTY) {
                            result.isExtendedCss = true;
                        }
                    }
                    break;
                case csstokenizer/* TokenType.Comment */.iv.Comment:
                    throw new Error('Comments are not allowed in declaration lists');
                default:
                    break;
            }
        });
    }
    catch (error) {
        result.isValid = false;
        result.errorMessage = getErrorMessage(error);
    }
    return result;
};

/* eslint-disable max-classes-per-file */
var ScriptletParams = /** @class */ (function () {
    function ScriptletParams(name, args) {
        this.props = null;
        if (typeof name !== 'undefined') {
            this.props = {
                name: name,
                args: args || [],
            };
        }
    }
    Object.defineProperty(ScriptletParams.prototype, "name", {
        get: function () {
            var _a;
            return (_a = this.props) === null || _a === void 0 ? void 0 : _a.name;
        },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(ScriptletParams.prototype, "args", {
        get: function () {
            var _a, _b;
            return (_b = (_a = this.props) === null || _a === void 0 ? void 0 : _a.args) !== null && _b !== void 0 ? _b : [];
        },
        enumerable: false,
        configurable: true
    });
    ScriptletParams.prototype.toString = function () {
        var result = [];
        result.push(agtree/* ADG_SCRIPTLET_MASK */.wh);
        result.push('(');
        if (this.name) {
            result.push(agtree/* QuoteUtils.setStringQuoteType */.tC.setStringQuoteType(this.name, agtree/* QuoteType.Single */.Q_.Single));
        }
        if (this.args.length) {
            result.push(', ');
            result.push(this.args.map(function (arg) { return agtree/* QuoteUtils.setStringQuoteType */.tC.setStringQuoteType(arg, agtree/* QuoteType.Single */.Q_.Single); }).join(', '));
        }
        result.push(')');
        return result.join(simple_regex_dfa6ed82.E);
    };
    return ScriptletParams;
}());
/**
 * Implements a basic cosmetic rule.
 *
 * Cosmetic rules syntax are almost similar and looks like this:
 * ```
 * rule = [domains] "marker" content
 * domains = [domain0, domain1[, ...[, domainN]]]
 * ```
 *
 * The rule type is defined by the `marker` value, you can find the list of them
 * in the {@see CosmeticRuleMarker} enumeration.
 *
 * What matters, though, is what's in the `content` part of it.
 *
 * Examples:
 * * `example.org##.banner` -- element hiding rule
 * * `example.org#$#.banner { display: block; }` -- CSS rule
 * * `example.org#%#window.x=1;` -- JS rule
 * * `example.org#%#//scriptlet('scriptlet-name')` -- Scriptlet rule
 * * `example.org$$div[id="test"]` -- HTML filtering rule
 */
var CosmeticRule = /** @class */ (function () {
    /**
     * Creates an instance of the {@link CosmeticRule}.
     * It parses the rule and extracts the permitted/restricted domains,
     * and also the cosmetic rule's content.
     *
     * Depending on the rule type, the content might be transformed in
     * one of the helper classes, or kept as string when it's appropriate.
     *
     * @param inputRule Original rule text.
     * @param filterListId ID of the filter list this rule belongs to.
     * @param ruleIndex line start index in the source filter list; it will be used to find the original rule text
     * in the filtering log when a rule is applied. Default value is {@link RULE_INDEX_NONE} which means that
     * the rule does not have source index.
     *
     * @throws error if it fails to parse the rule.
     */
    function CosmeticRule(node, filterListId, ruleIndex) {
        if (ruleIndex === void 0) { ruleIndex = RULE_INDEX_NONE; }
        var _a, _b, _c;
        this.allowlist = false;
        this.extendedCss = false;
        /**
         * $domain modifier pattern. It is only set if $domain modifier is specified for this rule.
         */
        this.domainModifier = null;
        /**
         * Js script to execute
         */
        this.script = undefined;
        /**
         * Object with script code ready to execute and debug, domain values
         * @private
         */
        this.scriptData = null;
        /**
         * Object with scriptlet function and params
         * @private
         */
        this.scriptletData = null;
        /**
         * If the rule contains scriptlet content
         */
        this.isScriptlet = false;
        this.ruleIndex = ruleIndex;
        this.filterListId = filterListId;
        this.allowlist = agtree/* CosmeticRuleSeparatorUtils.isException */.T9.isException(node.separator.value);
        this.type = node.type;
        this.isScriptlet = node.type === agtree/* CosmeticRuleType.ScriptletInjectionRule */.Az.ScriptletInjectionRule;
        this.content = agtree/* CosmeticRuleParser.generateBody */.c3.generateBody(node);
        // Store the scriptlet parameters. They will be used later, when we initialize the scriptlet,
        // but at this point we need to store them in order to avoid double parsing
        if (node.type === agtree/* CosmeticRuleType.ScriptletInjectionRule */.Az.ScriptletInjectionRule) {
            // Transform complex node into a simple array of strings
            var params = (_b = (_a = node.body.children[0]) === null || _a === void 0 ? void 0 : _a.children.map(function (param) { return (param === null ? simple_regex_dfa6ed82.E : agtree/* QuoteUtils.removeQuotesAndUnescape */.tC.removeQuotesAndUnescape(param.value)); })) !== null && _b !== void 0 ? _b : [];
            this.scriptletParams = new ScriptletParams((_c = params[0]) !== null && _c !== void 0 ? _c : '', params.slice(1));
        }
        else {
            this.scriptletParams = new ScriptletParams();
        }
        var validationResult = CosmeticRule.validate(node);
        // We should throw an error if the validation failed for any reason
        if (!validationResult.isValid) {
            throw new SyntaxError(validationResult.errorMessage);
        }
        // Check if the rule is ExtendedCss
        var isExtendedCssSeparator = agtree/* CosmeticRuleSeparatorUtils.isExtendedCssMarker */.T9.isExtendedCssMarker(node.separator.value);
        this.extendedCss = isExtendedCssSeparator || validationResult.isExtendedCss;
        // Process cosmetic rule modifiers
        var processedModifiers = CosmeticRule.processModifiers(node);
        if (processedModifiers) {
            if (processedModifiers.domainModifier) {
                this.domainModifier = processedModifiers.domainModifier;
            }
            if (processedModifiers.pathModifier) {
                this.pathModifier = processedModifiers.pathModifier;
            }
            if (processedModifiers.urlModifier) {
                this.urlModifier = processedModifiers.urlModifier;
            }
        }
        // Process domain list, if at least one domain is specified
        var domainListNode = node.domains;
        if (CosmeticRule.isAnyDomainSpecified(domainListNode)) {
            this.domainModifier = new DomainModifier(domainListNode, agtree/* COMMA_DOMAIN_LIST_SEPARATOR */.Hm);
        }
    }
    CosmeticRule.prototype.getIndex = function () {
        return this.ruleIndex;
    };
    CosmeticRule.prototype.getFilterListId = function () {
        return this.filterListId;
    };
    /**
     * Returns the rule content.
     */
    CosmeticRule.prototype.getContent = function () {
        return this.content;
    };
    /**
     * Cosmetic rule type (always present)
     */
    CosmeticRule.prototype.getType = function () {
        return this.type;
    };
    /**
     * Allowlist means that this rule is meant to disable other rules.
     * For instance, https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#elemhide-exceptions
     */
    CosmeticRule.prototype.isAllowlist = function () {
        return this.allowlist;
    };
    /**
     * Returns script ready to execute or null
     * Rebuilds scriptlet script if debug or domain params change
     * @param options script options
     * @returns script code or null
     */
    CosmeticRule.prototype.getScript = function (options) {
        var _a, _b;
        if (options === void 0) { options = {}; }
        var _c = options.debug, debug = _c === void 0 ? false : _c, frameUrl = options.frameUrl;
        var scriptData = this.scriptData;
        if (scriptData && !this.isScriptlet) {
            return scriptData.code;
        }
        if (scriptData && scriptData.debug === debug) {
            if (frameUrl) {
                if (frameUrl === scriptData.frameUrl) {
                    return scriptData.code;
                }
            }
            else {
                return scriptData.code;
            }
        }
        this.initScript(options);
        return (_b = (_a = this.scriptData) === null || _a === void 0 ? void 0 : _a.code) !== null && _b !== void 0 ? _b : null;
    };
    /**
     * Gets list of permitted domains.
     */
    CosmeticRule.prototype.getPermittedDomains = function () {
        if (this.domainModifier) {
            return this.domainModifier.getPermittedDomains();
        }
        return null;
    };
    /**
     * Gets list of restricted domains.
     */
    CosmeticRule.prototype.getRestrictedDomains = function () {
        if (this.domainModifier) {
            return this.domainModifier.getRestrictedDomains();
        }
        return null;
    };
    /**
     * Returns true if the rule is considered "generic"
     * "generic" means that the rule is not restricted to a limited set of domains
     * Please note that it might be forbidden on some domains, though.
     *
     * @return {boolean}
     */
    CosmeticRule.prototype.isGeneric = function () {
        var _a;
        return !((_a = this.domainModifier) === null || _a === void 0 ? void 0 : _a.hasPermittedDomains());
    };
    CosmeticRule.prototype.isExtendedCss = function () {
        return this.extendedCss;
    };
    /**
     * Processes cosmetic rule modifiers, e.g. `$path`.
     *
     * @param ruleNode Cosmetic rule node to process
     * @returns Processed modifiers ({@link ProcessedModifiers}) or `null` if there are no modifiers
     * @see {@link https://adguard.com/kb/general/ad-filtering/create-own-filters/#modifiers-for-non-basic-type-of-rules}
     */
    CosmeticRule.processModifiers = function (ruleNode) {
        var _a;
        // Do nothing if there are no modifiers in the rule node
        if (!ruleNode.modifiers) {
            return null;
        }
        var result = {};
        // We don't allow duplicate modifiers, so we collect them in a set
        var usedModifiers = new Set();
        // Destructure the modifiers array just for convenience
        var modifierNodes = ruleNode.modifiers.children;
        // AGTree parser tolerates this case: [$]example.com##.foo
        // However, we should throw an error here if the modifier list is empty
        // (if the modifier list isn't specified at all, then ruleNode.modifiers
        // will be undefined, so we won't get here)
        if (modifierNodes.length < 1) {
            throw new SyntaxError('Modifiers list cannot be be empty');
        }
        for (var _i = 0, modifierNodes_1 = modifierNodes; _i < modifierNodes_1.length; _i++) {
            var modifierNode = modifierNodes_1[_i];
            var modifierName = modifierNode.name.value;
            // Check if the modifier is already used
            if (usedModifiers.has(modifierName)) {
                throw new Error("Duplicated modifier: '".concat(modifierName, "'"));
            }
            // Mark the modifier as used by adding it to the set
            usedModifiers.add(modifierName);
            var modifierValue = ((_a = modifierNode.value) === null || _a === void 0 ? void 0 : _a.value) || simple_regex_dfa6ed82.E;
            // Every modifier should have a value at the moment, so for simplicity we throw an error here if the
            // modifier value is not present.
            // TODO: Improve this when we decide to add modifiers without values
            if (modifierValue.length < 1 && modifierName !== "path" /* CosmeticRuleModifier.Path */) {
                throw new SyntaxError("'$".concat(modifierName, "' modifier should have a value"));
            }
            // Process the modifier based on its name
            switch (modifierName) {
                case "domain" /* CosmeticRuleModifier.Domain */:
                    if (ruleNode.domains.children.length > 0) {
                        throw new SyntaxError("'$".concat(modifierName, "' modifier is not allowed in a domain-specific rule"));
                    }
                    result.domainModifier = new DomainModifier(modifierValue, agtree/* PIPE_MODIFIER_SEPARATOR */.mC);
                    break;
                case "path" /* CosmeticRuleModifier.Path */:
                    result.pathModifier = new Pattern(simple_regex_dfa6ed82.S.isRegexPattern(modifierValue)
                        // eslint-disable-next-line max-len
                        ? simple_regex_dfa6ed82.S.unescapeRegexSpecials(modifierValue, simple_regex_dfa6ed82.S.reModifierPatternEscapedSpecialCharacters)
                        : modifierValue);
                    break;
                case "url" /* CosmeticRuleModifier.Url */:
                    if (ruleNode.domains.children.length > 0) {
                        throw new SyntaxError("'$".concat(modifierName, "' modifier is not allowed in a domain-specific rule"));
                    }
                    result.urlModifier = new Pattern(simple_regex_dfa6ed82.S.isRegexPattern(modifierValue)
                        // eslint-disable-next-line max-len
                        ? simple_regex_dfa6ed82.S.unescapeRegexSpecials(modifierValue, simple_regex_dfa6ed82.S.reModifierPatternEscapedSpecialCharacters)
                        : modifierValue);
                    break;
                // Don't allow unknown modifiers
                default:
                    throw new SyntaxError("'$".concat(modifierName, "' modifier is not supported"));
            }
        }
        // $url modifier can't be used with other modifiers
        // TODO: Extend / change this check if we decide to add more such modifiers
        if (result.urlModifier && usedModifiers.size > 1) {
            throw new SyntaxError("'$".concat("url" /* CosmeticRuleModifier.Url */, "' modifier cannot be used with other modifiers"));
        }
        return result;
    };
    /**
     * Validates cosmetic rule node.
     *
     * @param ruleNode Cosmetic rule node to validate
     * @returns Validation result ({@link ValidationResult})
     */
    CosmeticRule.validate = function (ruleNode) {
        var _a, _b, _c, _d;
        var result = {
            isValid: true,
            isExtendedCss: false,
        };
        var scriptletName;
        var selectorListValidationResult;
        var ruleType = ruleNode.type;
        try {
            // Common validation: every cosmetic rule has a domain list
            if ((_a = ruleNode.domains) === null || _a === void 0 ? void 0 : _a.children.length) {
                // Iterate over the domain list and check every domain
                for (var _i = 0, _e = ruleNode.domains.children; _i < _e.length; _i++) {
                    var domain = _e[_i].value;
                    if (!agtree/* DomainUtils.isValidDomainOrHostname */.QM.isValidDomainOrHostname(domain)) {
                        throw new Error("'".concat(domain, "' is not a valid domain name"));
                    }
                }
            }
            // Type-specific validation
            switch (ruleType) {
                case agtree/* CosmeticRuleType.ElementHidingRule */.Az.ElementHidingRule:
                    selectorListValidationResult = validateSelectorList(ruleNode.body.selectorList.value);
                    if (!selectorListValidationResult.isValid) {
                        throw new Error(selectorListValidationResult.errorMessage);
                    }
                    // Detect ExtendedCss and unsupported pseudo-classes
                    result.isExtendedCss = selectorListValidationResult.isExtendedCss;
                    break;
                case agtree/* CosmeticRuleType.CssInjectionRule */.Az.CssInjectionRule:
                    selectorListValidationResult = validateSelectorList(ruleNode.body.selectorList.value);
                    if (!selectorListValidationResult.isValid) {
                        throw new Error(selectorListValidationResult.errorMessage);
                    }
                    // Detect ExtendedCss and unsupported pseudo-classes
                    result.isExtendedCss = selectorListValidationResult.isExtendedCss;
                    // AGTree won't allow the following rule:
                    // `#$#selector { remove: true; padding: 0; }`
                    // because it mixes removal and non-removal declarations.
                    if (ruleNode.body.declarationList) {
                        // eslint-disable-next-line max-len
                        var declarationListValidationResult = validateDeclarationList(ruleNode.body.declarationList.value);
                        if (!declarationListValidationResult.isValid) {
                            throw new Error(declarationListValidationResult.errorMessage);
                        }
                        // If the selector list is not ExtendedCss, then we should set this flag based on the
                        // declaration list validation result
                        if (!result.isExtendedCss) {
                            result.isExtendedCss = declarationListValidationResult.isExtendedCss;
                        }
                    }
                    break;
                case agtree/* CosmeticRuleType.ScriptletInjectionRule */.Az.ScriptletInjectionRule:
                    // Scriptlet name is the first child of the parameter list
                    // eslint-disable-next-line max-len
                    scriptletName = agtree/* QuoteUtils.removeQuotes */.tC.removeQuotes((_d = (_c = (_b = ruleNode.body.children[0]) === null || _b === void 0 ? void 0 : _b.children[0]) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : simple_regex_dfa6ed82.E);
                    // Special case: scriptlet name is empty, e.g. '#%#//scriptlet()'
                    if (scriptletName.length === 0) {
                        break;
                    }
                    // Check if the scriptlet name is valid
                    if (!scriptlets_umd_default().isValidScriptletName(scriptletName)) {
                        throw new Error("'".concat(scriptletName, "' is not a known scriptlet name"));
                    }
                    break;
                case agtree/* CosmeticRuleType.HtmlFilteringRule */.Az.HtmlFilteringRule:
                    // TODO: Validate HTML filtering rules
                    break;
                case agtree/* CosmeticRuleType.JsInjectionRule */.Az.JsInjectionRule:
                    // TODO: Validate JS injection rules
                    break;
                default:
                    break;
            }
        }
        catch (error) {
            result.isValid = false;
            result.errorMessage = getErrorMessage(error);
        }
        return result;
    };
    /**
     * Checks if the domain list contains any domains, but returns `false` if only
     * the wildcard domain is specified.
     *
     * @param domainListNode Domain list node to check
     * @returns `true` if the domain list contains any domains, `false` otherwise
     */
    CosmeticRule.isAnyDomainSpecified = function (domainListNode) {
        if (domainListNode.children.length > 0) {
            // Skip wildcard domain list (*)
            return !(domainListNode.children.length === 1 && domainListNode.children[0].value === simple_regex_dfa6ed82.W);
        }
        return false;
    };
    /**
     * Match returns true if this rule can be used on the specified request.
     *
     * @param request - request to check
     */
    CosmeticRule.prototype.match = function (request) {
        if (!this.domainModifier
            && !this.pathModifier
            && !this.urlModifier) {
            return true;
        }
        if (this.urlModifier) {
            return this.urlModifier.matchPattern(request, false);
        }
        if (this.domainModifier) {
            if (!this.domainModifier.matchDomain(request.hostname)) {
                return false;
            }
        }
        if (this.pathModifier) {
            var path = getRelativeUrl(request.urlLowercase);
            if (path) {
                return this.pathModifier.matchPathPattern(path);
            }
            return false;
        }
        return true;
    };
    /**
     * Returns the scriptlet's data consisting of the scriptlet function and its arguments.
     * This method is supposed to be used in the manifest V3 extension.
     */
    CosmeticRule.prototype.getScriptletData = function () {
        if (this.scriptletData) {
            return this.scriptletData;
        }
        this.initScript();
        return this.scriptletData;
    };
    /**
     * Updates this.scriptData and this.scriptletData when it is necessary in a lazy way.
     *
     * @param options
     */
    CosmeticRule.prototype.initScript = function (options) {
        var _a, _b;
        if (options === void 0) { options = {}; }
        var _c = options.debug, debug = _c === void 0 ? false : _c, frameUrl = options.frameUrl;
        var ruleContent = this.getContent();
        if (!this.isScriptlet) {
            this.scriptData = {
                code: ruleContent,
            };
            return;
        }
        // A scriptlet without a name can only be an allowlist scriptlet
        // https://github.com/AdguardTeam/Scriptlets/issues/377
        // or it is considered invalid if the scriptlet was invalid.
        // This does not require finding scriptData and scriptletData.
        if (!((_a = this.scriptletParams) === null || _a === void 0 ? void 0 : _a.name)) {
            return;
        }
        var params = {
            args: this.scriptletParams.args,
            engine: config.engine || simple_regex_dfa6ed82.E,
            name: this.scriptletParams.name,
            verbose: debug,
            domainName: frameUrl,
            version: config.version || simple_regex_dfa6ed82.E,
        };
        this.scriptData = {
            code: (_b = scriptlets_umd_default().invoke(params)) !== null && _b !== void 0 ? _b : null,
            debug: debug,
            frameUrl: frameUrl,
        };
        this.scriptletData = {
            func: scriptlets_umd_default().getScriptletFunction(params.name),
            params: params,
        };
    };
    return CosmeticRule;
}());

/**
 * This class stores found cosmetic css rules content in the appropriate collections
 * It is primarily used by the {@see CosmeticResult}
 */
var CosmeticStylesResult = /** @class */ (function () {
    /**
     * Constructor
     */
    function CosmeticStylesResult() {
        this.generic = [];
        this.specific = [];
        this.genericExtCss = [];
        this.specificExtCss = [];
    }
    /**
     * Appends rule to the appropriate collection
     * @param rule
     */
    CosmeticStylesResult.prototype.append = function (rule) {
        if (rule.isGeneric()) {
            if (rule.isExtendedCss()) {
                this.genericExtCss.push(rule);
            }
            else {
                this.generic.push(rule);
            }
        }
        else if (rule.isExtendedCss()) {
            this.specificExtCss.push(rule);
        }
        else {
            this.specific.push(rule);
        }
    };
    return CosmeticStylesResult;
}());

/**
 * This class stores found script rules content in the appropriate collections
 * It is primarily used by the {@see CosmeticResult}
 */
var CosmeticScriptsResult = /** @class */ (function () {
    /**
     * Constructor
     */
    function CosmeticScriptsResult() {
        this.generic = [];
        this.specific = [];
    }
    /**
     * Appends rule to appropriate collection
     * @param rule
     */
    CosmeticScriptsResult.prototype.append = function (rule) {
        if (rule.isGeneric()) {
            this.generic.push(rule);
        }
        else {
            this.specific.push(rule);
        }
    };
    /**
     * Returns rules collected
     */
    CosmeticScriptsResult.prototype.getRules = function () {
        return (0,simple_regex_dfa6ed82.a)((0,simple_regex_dfa6ed82.a)([], this.generic, true), this.specific, true);
    };
    return CosmeticScriptsResult;
}());

/**
 * This class stores found cosmetic html rules content in the appropriate collections
 * It is primarily used by the {@see CosmeticResult}
 */
var CosmeticHtmlResult = /** @class */ (function () {
    /**
     * Constructor
     */
    function CosmeticHtmlResult() {
        this.generic = [];
        this.specific = [];
    }
    /**
     * Appends rule to the appropriate collection
     * @param rule
     */
    CosmeticHtmlResult.prototype.append = function (rule) {
        if (rule.isGeneric()) {
            this.generic.push(rule);
        }
        else {
            this.specific.push(rule);
        }
    };
    /**
     * Returns rules collected
     */
    CosmeticHtmlResult.prototype.getRules = function () {
        return (0,simple_regex_dfa6ed82.a)((0,simple_regex_dfa6ed82.a)([], this.generic, true), this.specific, true);
    };
    return CosmeticHtmlResult;
}());

/**
 * Cosmetic result is the representation of rules
 * It is primarily used by the {@see CosmeticEngine}
 */
var CosmeticResult = /** @class */ (function () {
    /**
     * Constructor
     */
    function CosmeticResult() {
        this.elementHiding = new CosmeticStylesResult();
        this.CSS = new CosmeticStylesResult();
        this.JS = new CosmeticScriptsResult();
        this.Html = new CosmeticHtmlResult();
    }
    /**
     * Script rules
     */
    CosmeticResult.prototype.getScriptRules = function () {
        return this.JS.getRules();
    };
    return CosmeticResult;
}());

/**
 * CosmeticOption is the enumeration of various content script options.
 * Depending on the set of enabled flags the content script will contain different set of settings.
 */
var CosmeticOption;
(function (CosmeticOption) {
    /**
     * if generic elemhide and CSS rules are enabled
     * Could be disabled by a $generichide rule and $elemhide rule.
     */
    CosmeticOption[CosmeticOption["CosmeticOptionGenericCSS"] = 2] = "CosmeticOptionGenericCSS";
    /**
     * if specific elemhide and CSS rules are enabled
     * Could be disabled by a $specifichide rule and $elemhide rule.
     */
    CosmeticOption[CosmeticOption["CosmeticOptionSpecificCSS"] = 4] = "CosmeticOptionSpecificCSS";
    /**
     * if JS rules and scriptlets are enabled
     * Could be disabled by a $jsinject rule.
     */
    CosmeticOption[CosmeticOption["CosmeticOptionJS"] = 8] = "CosmeticOptionJS";
    /**
     * if Html filtering rules are enabled
     * Could be disabled by a $content rule.
     */
    CosmeticOption[CosmeticOption["CosmeticOptionHtml"] = 16] = "CosmeticOptionHtml";
    /**
     * TODO: Add support for these flags
     * They are useful when content script is injected into an iframe
     * In this case we can check what flags were applied to the top-level frame
     */
    CosmeticOption[CosmeticOption["CosmeticOptionSourceGenericCSS"] = 32] = "CosmeticOptionSourceGenericCSS";
    CosmeticOption[CosmeticOption["CosmeticOptionSourceCSS"] = 64] = "CosmeticOptionSourceCSS";
    CosmeticOption[CosmeticOption["CosmeticOptionSourceJS"] = 128] = "CosmeticOptionSourceJS";
    /**
     * everything is enabled
     */
    CosmeticOption[CosmeticOption["CosmeticOptionAll"] = 30] = "CosmeticOptionAll";
    /**
     * everything is disabled
     */
    CosmeticOption[CosmeticOption["CosmeticOptionNone"] = 0] = "CosmeticOptionNone";
})(CosmeticOption || (CosmeticOption = {}));

/**
 * Scanner types enum
 */
var ScannerType;
(function (ScannerType) {
    /**
     * Scanning for network rules
     */
    ScannerType[ScannerType["NetworkRules"] = 0] = "NetworkRules";
    /**
     * Scanning for cosmetic rules
     */
    ScannerType[ScannerType["CosmeticRules"] = 2] = "CosmeticRules";
    /**
     * Scanning for host rules
     */
    ScannerType[ScannerType["HostRules"] = 4] = "HostRules";
    /**
     * All
     */
    ScannerType[ScannerType["All"] = 6] = "All";
})(ScannerType || (ScannerType = {}));

/**
 * CosmeticEngine combines all the cosmetic rules and allows to quickly
 * find all rules matching this or that hostname
 * It is primarily used by the {@see Engine}
 */
var CosmeticEngine = /** @class */ (function () {
    /**
     * Builds instance of cosmetic engine
     *
     * @param ruleStorage
     * @param skipStorageScan create an instance without storage scanning
     */
    function CosmeticEngine(ruleStorage, skipStorageScan) {
        if (skipStorageScan === void 0) { skipStorageScan = false; }
        this.ruleStorage = ruleStorage;
        this.rulesCount = 0;
        this.elementHidingLookupTable = new CosmeticLookupTable(ruleStorage);
        this.cssLookupTable = new CosmeticLookupTable(ruleStorage);
        this.jsLookupTable = new CosmeticLookupTable(ruleStorage);
        this.htmlLookupTable = new CosmeticLookupTable(ruleStorage);
        if (skipStorageScan) {
            return;
        }
        var scanner = this.ruleStorage.createRuleStorageScanner(ScannerType.CosmeticRules);
        while (scanner.scan()) {
            var indexedRule = scanner.getRule();
            if (indexedRule
                && indexedRule.rule instanceof CosmeticRule) {
                this.addRule(indexedRule.rule, indexedRule.index);
            }
        }
    }
    /**
     * Adds rules into appropriate tables
     * @param rule
     * @param storageIdx
     */
    CosmeticEngine.prototype.addRule = function (rule, storageIdx) {
        switch (rule.getType()) {
            case agtree/* CosmeticRuleType.ElementHidingRule */.Az.ElementHidingRule: {
                this.elementHidingLookupTable.addRule(rule, storageIdx);
                break;
            }
            case agtree/* CosmeticRuleType.CssInjectionRule */.Az.CssInjectionRule: {
                this.cssLookupTable.addRule(rule, storageIdx);
                break;
            }
            case agtree/* CosmeticRuleType.ScriptletInjectionRule */.Az.ScriptletInjectionRule: {
                this.jsLookupTable.addRule(rule, storageIdx);
                break;
            }
            case agtree/* CosmeticRuleType.JsInjectionRule */.Az.JsInjectionRule: {
                this.jsLookupTable.addRule(rule, storageIdx);
                break;
            }
            case agtree/* CosmeticRuleType.HtmlFilteringRule */.Az.HtmlFilteringRule: {
                this.htmlLookupTable.addRule(rule, storageIdx);
                break;
            }
        }
        this.rulesCount += 1;
    };
    /**
     * Checks if bitwise mask matches option
     * @param option
     * @param targetOption
     */
    CosmeticEngine.matchOption = function (option, targetOption) {
        return (option & targetOption) === targetOption;
    };
    /**
     * Prepares cosmetic result by request
     *
     * @param request - request to match
     * @param option mask of enabled cosmetic types
     * @return CosmeticResult
     */
    CosmeticEngine.prototype.match = function (request, option) {
        var includeGeneric = CosmeticEngine.matchOption(option, CosmeticOption.CosmeticOptionGenericCSS);
        var includeSpecific = CosmeticEngine.matchOption(option, CosmeticOption.CosmeticOptionSpecificCSS);
        var includeJs = CosmeticEngine.matchOption(option, CosmeticOption.CosmeticOptionJS);
        var includeHtml = CosmeticEngine.matchOption(option, CosmeticOption.CosmeticOptionHtml);
        var cosmeticResult = new CosmeticResult();
        if (includeGeneric) {
            CosmeticEngine.appendGenericRules(cosmeticResult.elementHiding, this.elementHidingLookupTable, request);
            CosmeticEngine.appendGenericRules(cosmeticResult.CSS, this.cssLookupTable, request);
        }
        if (includeSpecific) {
            CosmeticEngine.appendSpecificRules(cosmeticResult.elementHiding, this.elementHidingLookupTable, request);
            CosmeticEngine.appendSpecificRules(cosmeticResult.CSS, this.cssLookupTable, request);
        }
        if (includeJs) {
            CosmeticEngine.appendGenericRules(cosmeticResult.JS, this.jsLookupTable, request);
            CosmeticEngine.appendSpecificRules(cosmeticResult.JS, this.jsLookupTable, request);
        }
        if (includeHtml) {
            if (includeGeneric) {
                CosmeticEngine.appendGenericRules(cosmeticResult.Html, this.htmlLookupTable, request);
            }
            CosmeticEngine.appendSpecificRules(cosmeticResult.Html, this.htmlLookupTable, request);
        }
        return cosmeticResult;
    };
    /**
     * Selects generic rules and appends rules content to cosmetic result
     * @param cosmeticResult
     * @param lookupTable
     * @param request
     */
    CosmeticEngine.appendGenericRules = function (cosmeticResult, lookupTable, request) {
        for (var _i = 0, _a = lookupTable.genericRules; _i < _a.length; _i++) {
            var genericRule = _a[_i];
            if (!lookupTable.isAllowlisted(request, genericRule)
                && genericRule.match(request)) {
                cosmeticResult.append(genericRule, request);
            }
        }
    };
    /**
     * Selects specific rules and appends rules content to cosmetic result
     * @param cosmeticResult
     * @param lookupTable
     * @param request
     */
    CosmeticEngine.appendSpecificRules = function (cosmeticResult, lookupTable, request) {
        var hostnameRules = lookupTable.findByHostname(request);
        if (hostnameRules.length > 0) {
            for (var _i = 0, hostnameRules_1 = hostnameRules; _i < hostnameRules_1.length; _i++) {
                var rule = hostnameRules_1[_i];
                if (!lookupTable.isAllowlisted(request, rule)) {
                    cosmeticResult.append(rule, request);
                }
            }
        }
    };
    return CosmeticEngine;
}());

/**
 * Replace modifier class
 */
var ReplaceModifier = /** @class */ (function () {
    /**
     * Constructor
     *
     * @param value
     */
    function ReplaceModifier(value) {
        var parsed = ReplaceModifier.parseReplaceOption(value);
        this.replaceOption = parsed.optionText;
        this.replaceApply = parsed.apply;
    }
    /**
     *
     * @param option
     */
    ReplaceModifier.parseReplaceOption = function (option) {
        if (!option) {
            return {
                apply: function (x) { return x; },
                optionText: '',
            };
        }
        var parts = (0,simple_regex_dfa6ed82.s)(option, '/', '\\', true);
        var modifiers = (parts[2] || '');
        if (modifiers.indexOf('g') < 0) {
            modifiers += 'g';
        }
        var pattern = new RegExp(parts[0], modifiers);
        // unescape replacement alias
        var replacement = parts[1].replace(/\\\$/g, '$');
        replacement = simple_regex_dfa6ed82.S.unescapeSpecials(replacement);
        var apply = function (input) { return input.replace(pattern, replacement); };
        return {
            apply: apply,
            optionText: option,
        };
    };
    /**
     * Replace content
     */
    ReplaceModifier.prototype.getValue = function () {
        return this.replaceOption;
    };
    /**
     * Replace apply function
     */
    ReplaceModifier.prototype.getApplyFunc = function () {
        return this.replaceApply;
    };
    return ReplaceModifier;
}());

var CSP_HEADER_NAME = 'Content-Security-Policy';
/**
 * Csp modifier class
 */
var CspModifier = /** @class */ (function () {
    /**
     * Constructor
     *
     * @param value
     * @param isAllowlist
     */
    function CspModifier(value, isAllowlist) {
        this.cspDirective = value;
        this.isAllowlist = isAllowlist;
        this.validateCspDirective();
    }
    /**
     * Csp directive
     */
    CspModifier.prototype.getValue = function () {
        return this.cspDirective;
    };
    /**
     * Validates CSP rule
     */
    CspModifier.prototype.validateCspDirective = function () {
        /**
         * https://github.com/AdguardTeam/AdguardBrowserExtension/issues/685
         * CSP directive may be empty in case of allowlist rule,
         * it means to disable all $csp rules matching the allowlist rule
         */
        if (!this.isAllowlist && !this.cspDirective) {
            throw new Error('Invalid $CSP rule: CSP directive must not be empty');
        }
        if (this.cspDirective) {
            /**
             * https://github.com/AdguardTeam/AdguardBrowserExtension/issues/685#issue-228287090
             * Forbids report-to and report-uri directives
             */
            var cspDirective = this.cspDirective.toLowerCase();
            if (cspDirective.indexOf('report-') >= 0) {
                throw new Error("Forbidden CSP directive: ".concat(cspDirective));
            }
        }
    };
    return CspModifier;
}());

/**
 * Cookie modifier class
 *
 * Learn more about it here:
 * https://github.com/AdguardTeam/AdguardBrowserExtension/issues/961
 */
var CookieModifier = /** @class */ (function () {
    /**
     * Constructor
     *
     * @param value
     */
    function CookieModifier(value) {
        // Save the source text of the option modifier
        this.optionValue = value || '';
        this.regex = null;
        this.cookieName = null;
        this.sameSite = null;
        this.maxAge = null;
        // Parse cookie name/regex
        var parts = this.optionValue.split(/;/);
        if (parts.length < 1) {
            throw new Error("Cannot parse ".concat(this.optionValue));
        }
        var cookieName = parts[0];
        if (cookieName.startsWith('/') && cookieName.endsWith('/')) {
            var pattern = cookieName.substring(1, cookieName.length - 1);
            // Save regex to be used further for matching cookies
            this.regex = new RegExp(pattern);
        }
        else {
            // Match by cookie name
            this.cookieName = cookieName;
        }
        // Parse other cookie options
        if (parts.length > 1) {
            for (var i = 1; i < parts.length; i += 1) {
                var nameValue = parts[i].split('=');
                var optionName = nameValue[0];
                var optionValue = nameValue[1];
                if (optionName === CookieModifier.MAX_AGE) {
                    this.maxAge = parseInt(optionValue, 10);
                }
                else if (optionName === CookieModifier.SAME_SITE) {
                    this.sameSite = optionValue;
                }
                else {
                    throw new Error("Unknown $cookie option: ".concat(optionName));
                }
            }
        }
    }
    /**
     * Modifier value
     */
    CookieModifier.prototype.getValue = function () {
        return this.optionValue;
    };
    /**
     * First cookie name
     */
    CookieModifier.prototype.getCookieName = function () {
        return this.cookieName;
    };
    /**
     * Max age cookie value
     */
    CookieModifier.prototype.getMaxAge = function () {
        return this.maxAge;
    };
    /**
     * Same site cookie value
     */
    CookieModifier.prototype.getSameSite = function () {
        return this.sameSite;
    };
    /**
     * Checks if cookie with the specified name matches this option
     *
     * @param {string} name Cookie name
     * @return {boolean} true if it does
     */
    CookieModifier.prototype.matches = function (name) {
        if (!name) {
            return false;
        }
        if (this.regex) {
            return this.regex.test(name);
        }
        if (this.cookieName) {
            return this.cookieName === name;
        }
        // Empty regex and cookieName means that we must match all cookies
        return true;
    };
    /**
     * Checks if cookie rule has an empty $cookie option
     *
     * @return {boolean} True if $cookie option is empty
     */
    CookieModifier.prototype.isEmpty = function () {
        return !this.regex && !this.cookieName;
    };
    /**
     * Cookie name maxAge
     */
    CookieModifier.MAX_AGE = 'maxAge';
    /**
     * Cookie name sameSite
     */
    CookieModifier.SAME_SITE = 'sameSite';
    /**
     * Checks if the given modifier is an instance of CookieModifier.
     *
     * @param m The modifier to check.
     * @returns True if the modifier is an instance of CookieModifier, false otherwise.
     */
    CookieModifier.isCookieModifier = function (m) {
        return m instanceof CookieModifier;
    };
    return CookieModifier;
}());

var _a;
/**
 * Array of all stealth options available, even those which are not supported by browser extension.
 */
var UniversalStealthOption;
(function (UniversalStealthOption) {
    UniversalStealthOption["HideSearchQueries"] = "searchqueries";
    UniversalStealthOption["DoNotTrack"] = "donottrack";
    UniversalStealthOption["ThirdPartyCookies"] = "3p-cookie";
    UniversalStealthOption["FirstPartyCookies"] = "1p-cookie";
    UniversalStealthOption["ThirdPartyCache"] = "3p-cache";
    UniversalStealthOption["ThirdPartyAuth"] = "3p-auth";
    UniversalStealthOption["WebRTC"] = "webrtc";
    UniversalStealthOption["Push"] = "push";
    UniversalStealthOption["Location"] = "location";
    UniversalStealthOption["Flash"] = "flash";
    UniversalStealthOption["Java"] = "java";
    UniversalStealthOption["HideReferrer"] = "referrer";
    UniversalStealthOption["UserAgent"] = "useragent";
    UniversalStealthOption["IP"] = "ip";
    UniversalStealthOption["XClientData"] = "xclientdata";
    UniversalStealthOption["DPI"] = "dpi";
})(UniversalStealthOption || (UniversalStealthOption = {}));
/**
 * List of stealth options, supported by browser extension, which can be disabled by $stealth modifier.
 *
 * Following stealth options are initialized on the engine start
 * and can't be disabled via $stealth modifier:
 * - `Block trackers` and `Remove tracking parameters`, as they are applied by a specific
 *   rule lists, initialized on app start;
 * - `Disabling WebRTC`, as it is not being applied on per-request basis.
 */
var StealthOptionName;
(function (StealthOptionName) {
    StealthOptionName["HideSearchQueries"] = "searchqueries";
    StealthOptionName["DoNotTrack"] = "donottrack";
    StealthOptionName["HideReferrer"] = "referrer";
    StealthOptionName["XClientData"] = "xclientdata";
    StealthOptionName["FirstPartyCookies"] = "1p-cookie";
    StealthOptionName["ThirdPartyCookies"] = "3p-cookie";
})(StealthOptionName || (StealthOptionName = {}));
var StealthModifierOptions = new Set(Object.values(StealthOptionName));
var UniversalStealthOptions = new Set(Object.values(UniversalStealthOption));
var StealthOption = (_a = {
        NotSet: 0
    },
    _a[StealthOptionName.HideSearchQueries] = 1,
    _a[StealthOptionName.DoNotTrack] = 1 << 1,
    _a[StealthOptionName.HideReferrer] = 1 << 2,
    _a[StealthOptionName.XClientData] = 1 << 3,
    _a[StealthOptionName.FirstPartyCookies] = 1 << 4,
    _a[StealthOptionName.ThirdPartyCookies] = 1 << 5,
    _a);
/**
 * Id to create stealth mode rule lists with,
 * e.g cookie rules for `Self-destructing third-party/first-party cookies` options.
 * It is also used to identify such rules when disabling on per-rule basis.
 */
var STEALTH_MODE_FILTER_ID = -1;
/**
 * Stealth modifier class.
 * Rules with $stealth modifier will disable specified stealth options for matched requests.
 *
 * Learn more about it here:
 * https://adguard.com/kb/general/ad-filtering/create-own-filters/#stealth-modifier
 */
var StealthModifier = /** @class */ (function () {
    /**
     * Parses the options string and creates a new stealth modifier instance.
     *
     * @param optionsStr options string
     *
     * @throws SyntaxError on inverted stealth options, which are not supported
     */
    function StealthModifier(optionsStr) {
        this.PIPE_SEPARATOR = '|';
        this.options = StealthOption.NotSet;
        if (optionsStr.trim().length === 0) {
            return;
        }
        // This prevents parsing invalid syntax as rule without supported options
        if (optionsStr.includes(',')) {
            throw new SyntaxError("Invalid separator of stealth options used: \"".concat(optionsStr, "\""));
        }
        var tokens = optionsStr.split(this.PIPE_SEPARATOR);
        for (var i = 0; i < tokens.length; i += 1) {
            var optionName = tokens[i].trim();
            if (optionName === '') {
                continue;
            }
            if (optionName.startsWith('~')) {
                throw new SyntaxError("Inverted $stealth modifier values are not allowed: \"".concat(optionsStr, "\""));
            }
            if (!StealthModifier.isValidStealthOption(optionName)) {
                throw new SyntaxError("Invalid $stealth option in modifier value: \"".concat(optionsStr, "\""));
            }
            // Skip options which are not supported by browser extension
            if (!StealthModifier.isSupportedStealthOption(optionName)) {
                continue;
            }
            var option = StealthOption[optionName];
            if (this.options & option) {
                logger.debug("Duplicate $stealth modifier value \"".concat(optionName, "\" in \"").concat(optionsStr, "\""));
            }
            this.options |= option;
        }
        if (this.options === StealthOption.NotSet) {
            // eslint-disable-next-line max-len
            var msg = "$stealth modifier does not contain any options supported by browser extension: \"".concat(optionsStr, "\"");
            logger.debug(msg);
        }
    }
    /**
     * Checks if this stealth modifier has values.
     *
     * @returns True if this stealth modifier has at least one value
     */
    StealthModifier.prototype.hasValues = function () {
        return this.options !== StealthOption.NotSet;
    };
    /**
     * Checks if this stealth modifier is disabling the given stealth option.
     *
     * @param optionName - Stealth option name
     * @returns True if this stealth modifier is disabling the given stealth option
     */
    StealthModifier.prototype.hasStealthOption = function (optionName) {
        var option = StealthOption[optionName];
        return !!(option && this.options & option);
    };
    /**
     * Checks if the given string is a valid $stealth option, supported by browser extension.
     *
     * @param option - Option name
     * @returns True if the given string is a valid $stealth option
     */
    StealthModifier.isSupportedStealthOption = function (option) { return StealthModifierOptions.has(option); };
    /**
     * Checks if the given string is a valid $stealth option.
     * @param option
     * @returns
     */
    StealthModifier.isValidStealthOption = function (option) { return UniversalStealthOptions.has(option); };
    return StealthModifier;
}());

/**
 * Redirect modifier class
 */
var RedirectModifier = /** @class */ (function () {
    /**
     * Constructor
     *
     * @param value
     * @param ruleText
     * @param isAllowlist
     * @param isRedirectingOnlyBlocked is redirect-rule modifier
     */
    function RedirectModifier(value, isAllowlist, isRedirectingOnlyBlocked) {
        if (isRedirectingOnlyBlocked === void 0) { isRedirectingOnlyBlocked = false; }
        /**
         * Is redirecting only blocked requests
         * See $redirect-rule options
         */
        this.isRedirectingOnlyBlocked = false;
        RedirectModifier.validate(value, isAllowlist);
        this.redirectTitle = value;
        this.isRedirectingOnlyBlocked = isRedirectingOnlyBlocked;
    }
    /**
     * Redirect title
     */
    RedirectModifier.prototype.getValue = function () {
        return this.redirectTitle;
    };
    /**
     * Validates redirect rule
     *
     * @param ruleText
     * @param redirectTitle
     * @param isAllowlist
     */
    RedirectModifier.validate = function (redirectTitle, isAllowlist) {
        if (isAllowlist && !redirectTitle) {
            return;
        }
        if (!redirectTitle) {
            throw new SyntaxError('Invalid $redirect rule, redirect value must not be empty');
        }
        var redirects = (scriptlets_umd_default()).redirects;
        if (!redirects.isRedirectResourceCompatibleWithAdg(redirectTitle)) {
            throw new SyntaxError('$redirect modifier is invalid');
        }
    };
    return RedirectModifier;
}());

/**
 * Query parameters filtering modifier class
 * Works with '$removeparam' modifier
 */
var RemoveParamModifier = /** @class */ (function () {
    /**
     * Constructor
     *
     * @param value
     */
    function RemoveParamModifier(value) {
        /**
         * Is modifier valid for MV3 or not
         */
        this.mv3Valid = true;
        this.value = value;
        var rawValue = value;
        // TODO: Seems like negation not using in valueRegExp
        if (value.startsWith('~')) {
            rawValue = value.substring(1);
            this.mv3Valid = false;
        }
        if (rawValue.startsWith('/')) {
            this.valueRegExp = simple_regex_dfa6ed82.S.patternFromString(rawValue);
            this.mv3Valid = false;
        }
        else {
            if (rawValue.includes('|')) {
                throw new Error('Unsupported option in $removeparam: multiple values are not allowed');
            }
            this.valueRegExp = new RegExp("((^|&)(".concat(simple_regex_dfa6ed82.S.escapeRegexSpecials(rawValue), ")=[^&#]*)"), 'g');
        }
    }
    /**
     * Modifier value
     */
    RemoveParamModifier.prototype.getValue = function () {
        return this.value;
    };
    /**
     * Is modifier valid for MV3 or not
     */
    RemoveParamModifier.prototype.getMV3Validity = function () {
        return this.mv3Valid;
    };
    /**
     * Removes query parameters from url
     *
     * @param url
     */
    RemoveParamModifier.prototype.removeParameters = function (url) {
        var sepIndex = url.indexOf('?');
        if (sepIndex < 0) {
            return url;
        }
        if (!this.value) {
            return url.substring(0, sepIndex);
        }
        if (sepIndex === url.length - 1) {
            return url;
        }
        if (this.value.startsWith('~')) {
            return cleanUrlParamByRegExp(url, this.valueRegExp, true);
        }
        return cleanUrlParamByRegExp(url, this.valueRegExp);
    };
    /**
     * Checks if the given modifier is an instance of RemoveParamModifier.
     *
     * @param m The modifier to check.
     * @returns True if the modifier is an instance of RemoveParamModifier, false otherwise.
     */
    RemoveParamModifier.isRemoveParamModifier = function (m) {
        return m instanceof RemoveParamModifier;
    };
    return RemoveParamModifier;
}());

/**
 * Headers filtering modifier class.
 * Rules with $removeheader modifier are intended to remove headers from HTTP requests and responses.
 */
var RemoveHeaderModifier = /** @class */ (function () {
    /**
     * Constructor
     *
     * @param value
     * @param isAllowlist
     */
    function RemoveHeaderModifier(value, isAllowlist) {
        this.value = value.toLowerCase();
        if (!isAllowlist && !this.value) {
            throw new SyntaxError('Invalid $removeheader rule, removeheader value must not be empty');
        }
        this.isRequestModifier = this.value.startsWith(RemoveHeaderModifier.REQUEST_PREFIX);
        var headerName = this.isRequestModifier
            ? this.value.substring(RemoveHeaderModifier.REQUEST_PREFIX.length)
            : this.value;
        // Values with ":" are not supported in MV3 declarative rules, e.g. "$removeheader=dnt:1"
        this.valid = RemoveHeaderModifier.isAllowedHeader(headerName) && !headerName.includes(':');
        this.applicableHeaderName = this.valid ? headerName : null;
    }
    /**
     * Modifier value
     */
    RemoveHeaderModifier.prototype.getValue = function () {
        return this.value;
    };
    Object.defineProperty(RemoveHeaderModifier.prototype, "isValid", {
        /**
         * Modifier validity
         */
        get: function () {
            return this.valid;
        },
        enumerable: false,
        configurable: true
    });
    /**
     * Returns effective header name to be removed
     *
     * @param isRequestHeaders
     */
    RemoveHeaderModifier.prototype.getApplicableHeaderName = function (isRequestHeaders) {
        if (!this.applicableHeaderName) {
            return null;
        }
        if (isRequestHeaders !== this.isRequestModifier) {
            return null;
        }
        return this.applicableHeaderName;
    };
    /**
     * Some headers are forbidden to remove
     *
     * @param headerName
     */
    RemoveHeaderModifier.isAllowedHeader = function (headerName) {
        return !this.FORBIDDEN_HEADERS.includes(headerName);
    };
    /**
     * List of forbidden headers
     */
    RemoveHeaderModifier.FORBIDDEN_HEADERS = [
        'access-control-allow-origin',
        'access-control-allow-credentials',
        'access-control-allow-headers',
        'access-control-allow-methods',
        'access-control-expose-headers',
        'access-control-max-age',
        'access-control-request-headers',
        'access-control-request-method',
        'origin',
        'timing-allow-origin',
        'allow',
        'cross-origin-embedder-policy',
        'cross-origin-opener-policy',
        'cross-origin-resource-policy',
        'content-security-policy',
        'content-security-policy-report-only',
        'expect-ct',
        'feature-policy',
        'origin-isolation',
        'strict-transport-security',
        'upgrade-insecure-requests',
        'x-content-type-options',
        'x-download-options',
        'x-frame-options',
        'x-permitted-cross-domain-policies',
        'x-powered-by',
        'x-xss-protection',
        'public-key-pins',
        'public-key-pins-report-only',
        'sec-websocket-key',
        'sec-websocket-extensions',
        'sec-websocket-accept',
        'sec-websocket-protocol',
        'sec-websocket-version',
        'p3p',
        'sec-fetch-mode',
        'sec-fetch-dest',
        'sec-fetch-site',
        'sec-fetch-user',
        'referrer-policy',
        'content-type',
        'content-length',
        'accept',
        'accept-encoding',
        'host',
        'connection',
        'transfer-encoding',
        'upgrade',
    ];
    /**
     * Request prefix
     */
    RemoveHeaderModifier.REQUEST_PREFIX = 'request:';
    /**
     * Checks if the given modifier is an instance of RemoveHeaderModifier.
     *
     * @param m The modifier to check.
     * @returns True if the modifier is an instance of RemoveHeaderModifier, false otherwise.
     */
    RemoveHeaderModifier.isRemoveHeaderModifier = function (m) {
        return m instanceof RemoveHeaderModifier;
    };
    return RemoveHeaderModifier;
}());

/**
 * This is a helper class that is used specifically to work with app restrictions.
 *
 * https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#app
 *
 * Examples:
 * ||baddomain.com^$app=org.example.app
 * ||baddomain.com^$app=org.example.app1|org.example.app2
 */
var AppModifier = /** @class */ (function () {
    /**
     * Parses the `apps` string
     *
     * @param apps - apps string
     *
     * @throws an error if the app string is empty or invalid
     */
    function AppModifier(apps) {
        if (!apps) {
            throw new SyntaxError('$app modifier cannot be empty');
        }
        var permittedApps = [];
        var restrictedApps = [];
        var parts = apps.split(simple_regex_dfa6ed82.b);
        for (var i = 0; i < parts.length; i += 1) {
            var app = parts[i];
            var restricted = false;
            if (app.startsWith('~')) {
                restricted = true;
                app = app.substring(1).trim();
            }
            if (app === '') {
                throw new SyntaxError("Empty app specified in \"".concat(apps, "\""));
            }
            if (restricted) {
                restrictedApps.push(app);
            }
            else {
                permittedApps.push(app);
            }
        }
        this.restrictedApps = restrictedApps.length > 0 ? restrictedApps : null;
        this.permittedApps = permittedApps.length > 0 ? permittedApps : null;
    }
    return AppModifier;
}());

var HTTPMethod;
(function (HTTPMethod) {
    HTTPMethod["GET"] = "GET";
    HTTPMethod["POST"] = "POST";
    HTTPMethod["PUT"] = "PUT";
    HTTPMethod["DELETE"] = "DELETE";
    HTTPMethod["PATCH"] = "PATCH";
    HTTPMethod["HEAD"] = "HEAD";
    HTTPMethod["OPTIONS"] = "OPTIONS";
    HTTPMethod["CONNECT"] = "CONNECT";
    HTTPMethod["TRACE"] = "TRACE";
})(HTTPMethod || (HTTPMethod = {}));
/**
 * Method modifier class.
 * Rules with $method modifier will be applied only to requests with specified methods.
 *
 * Learn more about it here:
 * https://adguard.com/kb/general/ad-filtering/create-own-filters/#method-modifier
 */
var MethodModifier = /** @class */ (function () {
    /**
     * Constructor
     *
     * @param value
     */
    function MethodModifier(methodsStr) {
        if (methodsStr === '') {
            throw new SyntaxError('$method modifier value cannot be empty');
        }
        var permittedMethods = [];
        var restrictedMethods = [];
        var parts = methodsStr.toUpperCase().split(MethodModifier.PIPE_SEPARATOR);
        for (var i = 0; i < parts.length; i += 1) {
            var method = parts[i].trim();
            var restricted = false;
            if (method.startsWith('~')) {
                restricted = true;
                method = method.substring(1);
            }
            if (!MethodModifier.isHTTPMethod(method)) {
                throw new SyntaxError("Invalid $method modifier value: ".concat(method));
            }
            if (restricted) {
                restrictedMethods.push(method);
            }
            else {
                permittedMethods.push(method);
            }
        }
        if (restrictedMethods.length > 0 && permittedMethods.length > 0) {
            throw new SyntaxError("Negated values cannot be mixed with non-negated values: ".concat(methodsStr));
        }
        this.restrictedValues = restrictedMethods.length > 0 ? restrictedMethods : null;
        this.permittedValues = permittedMethods.length > 0 ? permittedMethods : null;
    }
    /**
     * Request methods separator
     */
    MethodModifier.PIPE_SEPARATOR = '|';
    MethodModifier.isHTTPMethod = function (value) { return value in HTTPMethod; };
    return MethodModifier;
}());

/**
 * Header modifier class.
 * The $header modifier allows matching the HTTP response
 * by a specific header with (optionally) a specific value.
 *
 * Learn more about it here:
 * https://adguard.com/kb/general/ad-filtering/create-own-filters/#header-modifier
 */
var HeaderModifier = /** @class */ (function () {
    /**
     * Constructor
     * @param headerStr Header modifier value.
     */
    function HeaderModifier(headerStr) {
        /**
         * Colon separator.
         */
        this.COLON_SEPARATOR = ':';
        /**
         * Forward slash regexp marker.
         */
        this.FORWARD_SLASH = '/';
        if (headerStr === '') {
            throw new SyntaxError('$header modifier value cannot be empty');
        }
        var separatorIndex = headerStr.indexOf(this.COLON_SEPARATOR);
        if (separatorIndex === -1) {
            this.header = headerStr;
            this.value = null;
            return;
        }
        this.header = headerStr.slice(0, separatorIndex);
        var rawValue = headerStr.slice(separatorIndex + 1);
        if (rawValue === '') {
            throw new SyntaxError("Invalid $header modifier value: \"".concat(headerStr, "\""));
        }
        if (rawValue.startsWith(this.FORWARD_SLASH) && rawValue.endsWith(this.FORWARD_SLASH)) {
            this.value = new RegExp(rawValue.slice(1, -1));
        }
        else {
            this.value = rawValue;
        }
    }
    /**
     * Returns header modifier value
     * @returns header modifier value
     */
    HeaderModifier.prototype.getHeaderModifierValue = function () {
        return {
            header: this.header,
            value: this.value,
        };
    };
    return HeaderModifier;
}());

/**
 * To modifier class.
 * Rules with $to modifier are limited to requests made to the specified domains and their subdomains.
 *
 * Learn more about it here:
 * https://adguard.com/kb/general/ad-filtering/create-own-filters/#to-modifier
 */
var ToModifier = /** @class */ (function () {
    /**
     * Constructor
     */
    function ToModifier(domainsStr) {
        if (!domainsStr) {
            throw new SyntaxError('$to modifier value cannot be empty');
        }
        var permittedDomains = [];
        var restrictedDomains = [];
        var parts = domainsStr.toLowerCase().split(ToModifier.PIPE_SEPARATOR);
        for (var i = 0; i < parts.length; i += 1) {
            var domain = parts[i].trim();
            var restricted = false;
            if (domain.startsWith('~')) {
                restricted = true;
                domain = domain.substring(1);
            }
            if (domain === '') {
                throw new SyntaxError("Empty domain specified in \"".concat(domainsStr, "\""));
            }
            if (restricted) {
                restrictedDomains.push(domain);
            }
            else {
                permittedDomains.push(domain);
            }
        }
        this.restrictedValues = restrictedDomains.length > 0 ? restrictedDomains : null;
        this.permittedValues = permittedDomains.length > 0 ? permittedDomains : null;
    }
    /**
     * Domains separator
     */
    ToModifier.PIPE_SEPARATOR = '|';
    return ToModifier;
}());

var PERMISSIONS_POLICY_HEADER_NAME = 'Permissions-Policy';
var COMMA_SEPARATOR = ',';
var PIPE_SEPARATOR = '|';
/**
 * Permissions modifier class.
 * Allows setting permission policies, effectively blocking specific page functionality.
 *
 * Learn more about it here:
 * https://adguard.com/kb/general/ad-filtering/create-own-filters/#permissions-modifier
 */
var PermissionsModifier = /** @class */ (function () {
    /**
     * Constructor
     * @param permissionPolicyStr
     * @param isAllowlist
     */
    function PermissionsModifier(permissionPolicyStr, isAllowlist) {
        this.permissionPolicyDirective = permissionPolicyStr
            .replace(PermissionsModifier.RE_SEPARATOR_REPLACE, COMMA_SEPARATOR);
        PermissionsModifier.validatePermissionPolicyDirective(this.permissionPolicyDirective, isAllowlist);
    }
    /**
     * Returns permission policy allowlist string
     * @returns permission policy allowlist string
     */
    PermissionsModifier.prototype.getValue = function () {
        return this.permissionPolicyDirective;
    };
    /**
     * Validates permission policy directive
     * @throws SyntaxError on invalid permission policy directive
     */
    PermissionsModifier.validatePermissionPolicyDirective = function (directive, isAllowlist) {
        /**
         * $permissions modifier value may be empty only in case of allowlist rule,
         * it means to disable all $permissions rules matching the rule pattern.
        */
        if (!isAllowlist && !directive) {
            throw new SyntaxError('Invalid $permissions rule: permissions directive must not be empty');
        }
    };
    /**
     * Regular expression to apply correct separators.
     * It replaces escaped commas and pipe separators with commas.
     */
    PermissionsModifier.RE_SEPARATOR_REPLACE = new RegExp("(\\\\".concat(COMMA_SEPARATOR, "|\\").concat(PIPE_SEPARATOR, ")"), 'g');
    return PermissionsModifier;
}());

/**
 * This is the base class representing double values modifiers
 */
var BaseValuesModifier = /** @class */ (function () {
    /**
     * Parses the values string
     *
     * @param values - values string
     *
     * @throws an error if the string is empty or invalid
     */
    function BaseValuesModifier(values) {
        if (!values) {
            throw new SyntaxError('Modifier cannot be empty');
        }
        this.value = values;
        var permittedValues = [];
        var restrictedValues = [];
        var parts = values.split(simple_regex_dfa6ed82.b);
        for (var i = 0; i < parts.length; i += 1) {
            var app = parts[i];
            var restricted = false;
            if (app.startsWith('~')) {
                restricted = true;
                app = app.substring(1).trim();
            }
            if (app === '') {
                throw new SyntaxError("Empty values specified in \"".concat(values, "\""));
            }
            if (restricted) {
                restrictedValues.push(app);
            }
            else {
                permittedValues.push(app);
            }
        }
        this.restricted = restrictedValues.length > 0 ? restrictedValues : null;
        this.permitted = permittedValues.length > 0 ? permittedValues : null;
    }
    BaseValuesModifier.prototype.getPermitted = function () {
        return this.permitted;
    };
    BaseValuesModifier.prototype.getRestricted = function () {
        return this.restricted;
    };
    BaseValuesModifier.prototype.getValue = function () {
        return this.value;
    };
    BaseValuesModifier.prototype.match = function (value) {
        if (!this.restricted && !this.permitted) {
            return true;
        }
        if (this.restricted && this.restricted.includes(value)) {
            return false;
        }
        if (this.permitted) {
            return this.permitted.includes(value);
        }
        return true;
    };
    return BaseValuesModifier;
}());

/**
 * Netmasks class
 */
var NetmasksCollection = /** @class */ (function () {
    function NetmasksCollection() {
        this.ipv4Masks = [];
        this.ipv6Masks = [];
    }
    /**
     * Returns true if any of the containing masks contains provided value
     *
     * @param value
     */
    NetmasksCollection.prototype.contains = function (value) {
        if (is_ip_default().v4(value)) {
            return this.ipv4Masks.some(function (x) { return (0,cidr_tools/* contains */.r3)(x, value); });
        }
        return this.ipv6Masks.some(function (x) { return (0,cidr_tools/* contains */.r3)(x, value); });
    };
    return NetmasksCollection;
}());
/**
 * The client modifier allows specifying clients this rule will be working for.
 * It accepts client names (not ClientIDs), IP addresses, or CIDR ranges.
 */
var ClientModifier = /** @class */ (function (_super) {
    (0,simple_regex_dfa6ed82.c)(ClientModifier, _super);
    /**
     * Constructor
     *
     * @param value
     */
    function ClientModifier(value) {
        var _this = _super.call(this, value) || this;
        var permitted = _this.getPermitted();
        if (permitted) {
            _this.permitted = ClientModifier.stripValues(permitted);
            _this.permittedNetmasks = ClientModifier.parseNetmasks(_this.permitted);
        }
        var restricted = _this.getRestricted();
        if (restricted) {
            _this.restricted = ClientModifier.stripValues(restricted);
            _this.restrictedNetmasks = ClientModifier.parseNetmasks(_this.restricted);
        }
        return _this;
    }
    /**
     * Unquotes and unescapes string
     *
     * @param values
     */
    ClientModifier.stripValues = function (values) {
        return values.map(function (v) {
            if ((v.startsWith('"') && v.endsWith('"'))
                || (v.startsWith('\'') && v.endsWith('\''))) {
                // eslint-disable-next-line no-param-reassign
                v = v.substr(1, v.length - 2);
            }
            return v.replace(/\\/ig, '');
        });
    };
    /**
     * Checks if this modifier matches provided params
     *
     * @param clientName
     * @param clientIP
     */
    ClientModifier.prototype.matchAny = function (clientName, clientIP) {
        if (this.restricted) {
            if (clientName && this.restricted.includes(clientName)) {
                return false;
            }
            if (clientIP && this.restricted.includes(clientIP)) {
                return false;
            }
            return true;
        }
        if (this.restrictedNetmasks) {
            if (clientIP && this.restrictedNetmasks.contains(clientIP)) {
                return false;
            }
            return true;
        }
        if (this.permitted) {
            if (clientName && this.permitted.includes(clientName)) {
                return true;
            }
            if (clientIP && this.permitted.includes(clientIP)) {
                return true;
            }
        }
        if (this.permittedNetmasks) {
            if (clientIP && this.permittedNetmasks.contains(clientIP)) {
                return true;
            }
        }
        return false;
    };
    /**
     * Parses netmasks from client's strings
     *
     * @param values
     */
    ClientModifier.parseNetmasks = function (values) {
        var result = new NetmasksCollection();
        values.forEach(function (x) {
            var cidrVersion = is_cidr_default()(x);
            if (cidrVersion === 4) {
                result.ipv4Masks.push(x);
            }
            else if (cidrVersion === 6) {
                result.ipv6Masks.push(x);
            }
        });
        return result;
    };
    return ClientModifier;
}(BaseValuesModifier));

/**
 * The dnsrewrite response modifier allows replacing the content of the response
 * to the DNS request for the matching hosts.
 *
 * TODO: This modifier is not yet implemented
 * https://github.com/AdguardTeam/AdGuardHome/wiki/Hosts-Blocklists#dnsrewrite
 */
var DnsRewriteModifier = /** @class */ (function () {
    /**
     * Constructor
     *
     * @param value
     */
    function DnsRewriteModifier(value) {
        this.value = value;
    }
    /**
     * Modifier value
     */
    DnsRewriteModifier.prototype.getValue = function () {
        return this.value;
    };
    return DnsRewriteModifier;
}());

/**
 * The dnstype modifier allows specifying DNS request type on which this rule will be triggered.
 */
var DnsTypeModifier = /** @class */ (function (_super) {
    (0,simple_regex_dfa6ed82.c)(DnsTypeModifier, _super);
    /**
     * Constructor
     *
     * @param value
     */
    function DnsTypeModifier(value) {
        var _this = _super.call(this, value) || this;
        if (_this.permitted) {
            _this.restricted = null;
        }
        return _this;
    }
    return DnsTypeModifier;
}(BaseValuesModifier));

/**
 * The ctag modifier allows to block domains only for specific types of DNS client tags.
 */
var CtagModifier = /** @class */ (function (_super) {
    (0,simple_regex_dfa6ed82.c)(CtagModifier, _super);
    /**
     * Constructor
     *
     * @param value
     */
    function CtagModifier(value) {
        var _this = _super.call(this, value) || this;
        _this.validate();
        return _this;
    }
    /**
     * Validates tag values
     */
    CtagModifier.prototype.validate = function () {
        if (!this.getValue()) {
            throw new Error('Invalid rule: Ctag modifier must not be empty');
        }
        var tags = this.permitted ? this.permitted : this.restricted;
        if (tags && tags.some(function (x) { return !CtagModifier.ALLOWED_TAGS.includes(x); })) {
            throw new Error('Invalid rule: Invalid ctag modifier');
        }
    };
    /**
     * The list of allowed tags
     */
    CtagModifier.ALLOWED_TAGS = [
        // By device type:
        'device_audio',
        'device_camera',
        'device_gameconsole',
        'device_laptop',
        'device_nas',
        'device_pc',
        'device_phone',
        'device_printer',
        'device_securityalarm',
        'device_tablet',
        'device_tv',
        'device_other',
        // By operating system:
        'os_android',
        'os_ios',
        'os_linux',
        'os_macos',
        'os_windows',
        'os_other',
        // By user group:
        'user_admin',
        'user_regular',
        'user_child',
    ];
    return CtagModifier;
}(BaseValuesModifier));

/**
 * Counts the number of bits in the number and returns it
 *
 * @param a number to count bits
 *
 * @returns The number of bits in the number.
 */
function getBitCount(a) {
    var count = 0;
    var n = a;
    while (n > 0) {
        count += n & 1;
        n >>= 1;
    }
    return count;
}
/**
 * Count the number of bits enabled in a number based on a bit mask
 *
 * @param base Base number to check
 * @param mask Mask to check
 *
 * @returns The number of bits enabled in the base number based on the mask
 *
 * @example
 * countEnabledBits(0b100, 0b110); // 1
 * countEnabledBits(0b111, 0b000); // 0
 */
function countEnabledBits(base, mask) {
    // Get the common bits between the base and the mask
    var common = base & mask;
    // Count the number of bits enabled in the common bits
    return getBitCount(common);
}

// eslint-disable-next-line max-classes-per-file
/**
 * NetworkRuleOption is the enumeration of various rule options.
 * In order to save memory, we store some options as a flag.
 * https://adguard.com/kb/general/ad-filtering/create-own-filters/#basic-rule-modifiers
 */
var NetworkRuleOption;
(function (NetworkRuleOption) {
    /** No value is set. Syntax sugar to simplify code. */
    NetworkRuleOption[NetworkRuleOption["NotSet"] = 0] = "NotSet";
    /** $third-party modifier */
    NetworkRuleOption[NetworkRuleOption["ThirdParty"] = 1] = "ThirdParty";
    /** $match-case modifier */
    NetworkRuleOption[NetworkRuleOption["MatchCase"] = 2] = "MatchCase";
    /** $important modifier */
    NetworkRuleOption[NetworkRuleOption["Important"] = 4] = "Important";
    // Allowlist rules modifiers
    // Each of them can disable part of the functionality
    /** $elemhide modifier */
    NetworkRuleOption[NetworkRuleOption["Elemhide"] = 8] = "Elemhide";
    /** $generichide modifier */
    NetworkRuleOption[NetworkRuleOption["Generichide"] = 16] = "Generichide";
    /** $specifichide modifier */
    NetworkRuleOption[NetworkRuleOption["Specifichide"] = 32] = "Specifichide";
    /** $genericblock modifier */
    NetworkRuleOption[NetworkRuleOption["Genericblock"] = 64] = "Genericblock";
    /** $jsinject modifier */
    NetworkRuleOption[NetworkRuleOption["Jsinject"] = 128] = "Jsinject";
    /** $urlblock modifier */
    NetworkRuleOption[NetworkRuleOption["Urlblock"] = 256] = "Urlblock";
    /** $content modifier */
    NetworkRuleOption[NetworkRuleOption["Content"] = 512] = "Content";
    /** $extension modifier */
    NetworkRuleOption[NetworkRuleOption["Extension"] = 1024] = "Extension";
    /** $stealth modifier */
    NetworkRuleOption[NetworkRuleOption["Stealth"] = 2048] = "Stealth";
    // Other modifiers
    /** $popup modifier */
    NetworkRuleOption[NetworkRuleOption["Popup"] = 4096] = "Popup";
    /** $csp modifier */
    NetworkRuleOption[NetworkRuleOption["Csp"] = 8192] = "Csp";
    /** $replace modifier */
    NetworkRuleOption[NetworkRuleOption["Replace"] = 16384] = "Replace";
    /** $cookie modifier */
    NetworkRuleOption[NetworkRuleOption["Cookie"] = 32768] = "Cookie";
    /** $redirect modifier */
    NetworkRuleOption[NetworkRuleOption["Redirect"] = 65536] = "Redirect";
    /** $badfilter modifier */
    NetworkRuleOption[NetworkRuleOption["Badfilter"] = 131072] = "Badfilter";
    /** $removeparam modifier */
    NetworkRuleOption[NetworkRuleOption["RemoveParam"] = 262144] = "RemoveParam";
    /** $removeheader modifier */
    NetworkRuleOption[NetworkRuleOption["RemoveHeader"] = 524288] = "RemoveHeader";
    /** $jsonprune modifier */
    NetworkRuleOption[NetworkRuleOption["JsonPrune"] = 1048576] = "JsonPrune";
    /** $hls modifier */
    NetworkRuleOption[NetworkRuleOption["Hls"] = 2097152] = "Hls";
    // Compatibility dependent
    /** $network modifier */
    NetworkRuleOption[NetworkRuleOption["Network"] = 4194304] = "Network";
    /** dns modifiers */
    NetworkRuleOption[NetworkRuleOption["Client"] = 8388608] = "Client";
    NetworkRuleOption[NetworkRuleOption["DnsRewrite"] = 16777216] = "DnsRewrite";
    NetworkRuleOption[NetworkRuleOption["DnsType"] = 33554432] = "DnsType";
    NetworkRuleOption[NetworkRuleOption["Ctag"] = 67108864] = "Ctag";
    /* $method modifier */
    NetworkRuleOption[NetworkRuleOption["Method"] = 134217728] = "Method";
    /* $to modifier */
    NetworkRuleOption[NetworkRuleOption["To"] = 268435456] = "To";
    /* $permissions modifier */
    NetworkRuleOption[NetworkRuleOption["Permissions"] = 536870912] = "Permissions";
    /* $header modifier */
    NetworkRuleOption[NetworkRuleOption["Header"] = 1073741824] = "Header";
})(NetworkRuleOption || (NetworkRuleOption = {}));
/**
 * NetworkRuleOptions is the enumeration of various rule options groups
 * needed for validation.
 */
var NetworkRuleGroupOptions;
(function (NetworkRuleGroupOptions) {
    /** Allowlist-only modifiers */
    NetworkRuleGroupOptions[NetworkRuleGroupOptions["AllowlistOnly"] = 4088] = "AllowlistOnly";
    /** Options supported by host-level network rules * */
    NetworkRuleGroupOptions[NetworkRuleGroupOptions["OptionHostLevelRules"] = 125960196] = "OptionHostLevelRules";
    /**
     * Cosmetic option modifiers
     */
    NetworkRuleGroupOptions[NetworkRuleGroupOptions["CosmeticOption"] = 696] = "CosmeticOption";
    /**
     * Removeparam compatible modifiers
     *
     * $removeparam rules are compatible only with content type modifiers ($subdocument, $script, $stylesheet, etc)
     * except $document (using by default) and this list of modifiers:
     */
    NetworkRuleGroupOptions[NetworkRuleGroupOptions["RemoveParamCompatibleOptions"] = 393223] = "RemoveParamCompatibleOptions";
    /**
     * Removeheader compatible modifiers
     *
     * $removeheader rules are compatible only with content type modifiers ($subdocument, $script, $stylesheet, etc)
     * except $document (using by default) and this list of modifiers:
     */
    NetworkRuleGroupOptions[NetworkRuleGroupOptions["RemoveHeaderCompatibleOptions"] = 1074397191] = "RemoveHeaderCompatibleOptions";
    /**
     * Permissions compatible modifiers
     *
     * $permissions is compatible with the limited list of modifiers: $domain, $important, and $subdocument
     */
    NetworkRuleGroupOptions[NetworkRuleGroupOptions["PermissionsCompatibleOptions"] = 537001988] = "PermissionsCompatibleOptions";
    /**
     * Header compatible modifiers
     *
     * $header is compatible with the limited list of modifiers: $csp and $removeheader (on response headers).
     */
    NetworkRuleGroupOptions[NetworkRuleGroupOptions["HeaderCompatibleOptions"] = 1074405380] = "HeaderCompatibleOptions";
})(NetworkRuleGroupOptions || (NetworkRuleGroupOptions = {}));
/**
 * Basic network filtering rule.
 * https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#basic-rules
 */
var NetworkRule = /** @class */ (function () {
    /**
     * Creates an instance of the {@link NetworkRule}.
     * It parses this rule and extracts the rule pattern (see {@link SimpleRegex}),
     * and rule modifiers.
     *
     * @param inputRule Original rule text.
     * @param filterListId ID of the filter list this rule belongs to.
     * @param ruleIndex line start index in the source filter list; it will be used to find the original rule text
     * in the filtering log when a rule is applied. Default value is {@link RULE_INDEX_NONE} which means that
     * the rule does not have source index.
     *
     * @throws error if it fails to parse the rule.
     */
    function NetworkRule(node, filterListId, ruleIndex) {
        if (ruleIndex === void 0) { ruleIndex = RULE_INDEX_NONE; }
        var _a, _b;
        /**
         * Domains in denyallow modifier providing exceptions for permitted domains
         * https://github.com/AdguardTeam/CoreLibs/issues/1304
         */
        this.denyAllowDomains = null;
        /**
         * Flag with all enabled rule options.
         */
        this.enabledOptions = NetworkRuleOption.NotSet;
        /**
         * Flag with all disabled rule options.
         */
        this.disabledOptions = NetworkRuleOption.NotSet;
        /**
         * Flag with all permitted request types.
         */
        this.permittedRequestTypes = RequestType.NotSet;
        /**
         * Flag with all restricted request types.
         */
        this.restrictedRequestTypes = RequestType.NotSet;
        /**
         * Rule Advanced modifier
         */
        this.advancedModifier = null;
        /**
         * Rule Domain modifier
         */
        this.domainModifier = null;
        /**
         * Rule App modifier
         */
        this.appModifier = null;
        /**
         * Rule Method modifier
         */
        this.methodModifier = null;
        /**
         * Rule header modifier
         */
        this.headerModifier = null;
        /**
         * Rule To modifier
         */
        this.toModifier = null;
        /**
         * Rule Stealth modifier
         */
        this.stealthModifier = null;
        /**
         * Options used by the rule, regardless of whether they are enabled or disabled.
         */
        this.usedOptionNames = new Set();
        /**
         * Rule priority, which is needed when the engine has to choose between
         * several rules matching the query. This value is calculated based on
         * the rule modifiers enabled or disabled and rounded up
         * to the smallest integer greater than or equal to the calculated weight
         * in the {@link calculatePriorityWeight}.
         *
         * @see https://adguard.com/kb/general/ad-filtering/create-own-filters/#priority-category-1
         */
        this.priorityWeight = 1;
        this.ruleIndex = ruleIndex;
        // TODO: Remove this completely
        this.ruleText = agtree/* RuleParser.generate */.sR.generate(node);
        this.filterListId = filterListId;
        this.allowlist = node.exception;
        var pattern = node.pattern.value;
        if (pattern && (0,simple_regex_dfa6ed82.h)(pattern)) {
            throw new SyntaxError('Rule has spaces, seems to be an host rule');
        }
        if ((_b = (_a = node.modifiers) === null || _a === void 0 ? void 0 : _a.children) === null || _b === void 0 ? void 0 : _b.length) {
            this.loadOptions(node.modifiers);
        }
        if (NetworkRule.isTooGeneral(node)) {
            throw new SyntaxError("Rule is too general: ".concat(agtree/* RuleParser.generate */.sR.generate(node)));
        }
        this.calculatePriorityWeight();
        this.pattern = new Pattern(pattern, this.isOptionEnabled(NetworkRuleOption.MatchCase));
    }
    // TODO: Remove .getText() completely
    NetworkRule.prototype.getText = function () {
        return this.ruleText;
    };
    NetworkRule.prototype.getIndex = function () {
        return this.ruleIndex;
    };
    /**
     * Returns the identifier of the filter from which the rule was received.
     *
     * @returns Identifier of the filter from which the rule was received.
     */
    NetworkRule.prototype.getFilterListId = function () {
        return this.filterListId;
    };
    /**
     * Returns all options that are used in the rule, regardless of whether they are
     * enabled or disabled.
     *
     * @return Set of option names
     */
    NetworkRule.prototype.getUsedOptionNames = function () {
        return this.usedOptionNames;
    };
    /**
     * Each rule has its own priority, which is necessary when several rules
     * match the request and the filtering system needs to select one of them.
     * Priority is measured as a positive integer.
     * In the case of a conflict between two rules with the same priority value,
     * it is not specified which one of them will be chosen.
     *
     * @returns Rule priority.
     */
    NetworkRule.prototype.getPriorityWeight = function () {
        return this.priorityWeight;
    };
    /**
     * Returns rule pattern,
     * which currently is used only in the rule validator module
     */
    NetworkRule.prototype.getPattern = function () {
        return this.pattern.pattern;
    };
    /**
     * Returns `true` if the rule is "allowlist", e.g. if it disables other
     * rules when the pattern matches the request.
     */
    NetworkRule.prototype.isAllowlist = function () {
        return this.allowlist;
    };
    /**
     * Checks if the rule is a document-level allowlist rule with $urlblock or
     * $genericblock or $content.
     * This means that the rule is supposed to disable or modify blocking
     * of the page subrequests.
     * For instance, `@@||example.org^$urlblock` unblocks all sub-requests.
     */
    NetworkRule.prototype.isDocumentLevelAllowlistRule = function () {
        if (!this.isAllowlist()) {
            return false;
        }
        return this.isOptionEnabled(NetworkRuleOption.Urlblock)
            || this.isOptionEnabled(NetworkRuleOption.Genericblock)
            || this.isOptionEnabled(NetworkRuleOption.Content);
    };
    /**
     * Checks if the rule completely disables filtering.
     */
    NetworkRule.prototype.isFilteringDisabled = function () {
        if (!this.isAllowlist()) {
            return false;
        }
        return this.isOptionEnabled(NetworkRuleOption.Elemhide)
            && this.isOptionEnabled(NetworkRuleOption.Content)
            && this.isOptionEnabled(NetworkRuleOption.Urlblock)
            && this.isOptionEnabled(NetworkRuleOption.Jsinject);
    };
    /**
     * The longest part of pattern without any special characters.
     * It is used to improve the matching performance.
     */
    NetworkRule.prototype.getShortcut = function () {
        return this.pattern.shortcut;
    };
    /**
     * Gets list of permitted domains.
     * See https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#domain-modifier
     */
    NetworkRule.prototype.getPermittedDomains = function () {
        if (this.domainModifier) {
            return this.domainModifier.getPermittedDomains();
        }
        return null;
    };
    /**
     * Gets list of restricted domains.
     * See https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#domain-modifier
     */
    NetworkRule.prototype.getRestrictedDomains = function () {
        if (this.domainModifier) {
            return this.domainModifier.getRestrictedDomains();
        }
        return null;
    };
    /**
     * Gets list of denyAllow domains.
     * See https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#denyallow-modifier
     */
    NetworkRule.prototype.getDenyAllowDomains = function () {
        return this.denyAllowDomains;
    };
    /**
     * Get list of permitted $to domains.
     * See https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#to-modifier
     */
    NetworkRule.prototype.getPermittedToDomains = function () {
        if (this.toModifier) {
            return this.toModifier.permittedValues;
        }
        return null;
    };
    /**
     * Get list of restricted $to domains.
     * See https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#to-modifier
     */
    NetworkRule.prototype.getRestrictedToDomains = function () {
        if (this.toModifier) {
            return this.toModifier.restrictedValues;
        }
        return null;
    };
    /**
     * Gets list of permitted domains.
     * See https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#app
     */
    NetworkRule.prototype.getPermittedApps = function () {
        if (this.appModifier) {
            return this.appModifier.permittedApps;
        }
        return null;
    };
    /**
     * Gets list of restricted domains.
     * See https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#app
     */
    NetworkRule.prototype.getRestrictedApps = function () {
        if (this.appModifier) {
            return this.appModifier.restrictedApps;
        }
        return null;
    };
    /**
     * Gets list of permitted methods.
     * See https://kb.adguard.com/general/how-to-create-your-own-ad-filters#method-modifier
     */
    NetworkRule.prototype.getRestrictedMethods = function () {
        if (this.methodModifier) {
            return this.methodModifier.restrictedValues;
        }
        return null;
    };
    /**
     * Gets list of restricted methods.
     * See https://kb.adguard.com/general/how-to-create-your-own-ad-filters#method-modifier
     */
    NetworkRule.prototype.getPermittedMethods = function () {
        if (this.methodModifier) {
            return this.methodModifier.permittedValues;
        }
        return null;
    };
    /**
     * Flag with all permitted request types.
     * The value {@link RequestType.NotSet} here means "all request types are allowed".
     */
    NetworkRule.prototype.getPermittedRequestTypes = function () {
        return this.permittedRequestTypes;
    };
    /**
     * Flag with all restricted request types.
     * The value {@link RequestType.NotSet} here means "no type of request is restricted".
     */
    NetworkRule.prototype.getRestrictedRequestTypes = function () {
        return this.restrictedRequestTypes;
    };
    /**
     * Advanced modifier
     */
    NetworkRule.prototype.getAdvancedModifier = function () {
        return this.advancedModifier;
    };
    /**
     * Stealth modifier
     */
    NetworkRule.prototype.getStealthModifier = function () {
        return this.stealthModifier;
    };
    /**
     * Advanced modifier value
     */
    NetworkRule.prototype.getAdvancedModifierValue = function () {
        return this.advancedModifier && this.advancedModifier.getValue();
    };
    /**
     * Retrieves the header modifier value.
     */
    NetworkRule.prototype.getHeaderModifierValue = function () {
        if (!this.headerModifier) {
            return null;
        }
        return this.headerModifier.getHeaderModifierValue();
    };
    /**
     * isRegexRule returns true if rule's pattern is a regular expression.
     * https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#regexp-support
     */
    NetworkRule.prototype.isRegexRule = function () {
        return (this.getPattern().startsWith(simple_regex_dfa6ed82.S.MASK_REGEX_RULE)
            && this.getPattern().endsWith(simple_regex_dfa6ed82.S.MASK_REGEX_RULE));
    };
    /**
     * Checks if this filtering rule matches the specified request.
     * @param request - request to check.
     * @param useShortcut - the flag to use this rule shortcut
     *
     * In case we use Trie in lookup table, we don't need to use shortcut cause we already check if request's url
     * includes full rule shortcut.
     */
    NetworkRule.prototype.match = function (request, useShortcut) {
        if (useShortcut === void 0) { useShortcut = true; }
        // Regex rules should not be tested by shortcut
        if (useShortcut && !this.matchShortcut(request)) {
            return false;
        }
        if (this.isOptionEnabled(NetworkRuleOption.Method) && !this.matchMethod(request.method)) {
            return false;
        }
        if (this.isOptionEnabled(NetworkRuleOption.ThirdParty) && !request.thirdParty) {
            return false;
        }
        if (this.isOptionDisabled(NetworkRuleOption.ThirdParty) && request.thirdParty) {
            return false;
        }
        if (!this.matchRequestType(request.requestType)) {
            return false;
        }
        if (!this.matchDomainModifier(request)) {
            return false;
        }
        if (this.isOptionEnabled(NetworkRuleOption.RemoveParam)
            || this.isOptionEnabled(NetworkRuleOption.Permissions)) {
            if (!this.matchRequestTypeExplicit(request.requestType)) {
                return false;
            }
        }
        if (!this.matchDenyAllowDomains(request.hostname)) {
            return false;
        }
        if (this.isOptionEnabled(NetworkRuleOption.To) && !this.matchToModifier(request.hostname)) {
            return false;
        }
        if (!this.matchDnsType(request.dnsType)) {
            return false;
        }
        if (!this.matchClientTags(request.clientTags)) {
            return false;
        }
        if (!this.matchClient(request.clientName, request.clientIP)) {
            return false;
        }
        return this.pattern.matchPattern(request, true);
    };
    /**
     * matchShortcut simply checks if shortcut is a substring of the URL.
     * @param request - request to check.
     */
    NetworkRule.prototype.matchShortcut = function (request) {
        return request.urlLowercase.indexOf(this.getShortcut()) >= 0;
    };
    /**
     * Check if request matches domain modifier by request referrer (general case) or by request target
     *
     * In some cases the $domain modifier can match not only the referrer domain, but also the target domain.
     * This happens when the following is true (1 AND ((2 AND 3) OR 4):
     *
     * 1) The request has $document request type (not subdocument)
     * 2) The rule's pattern doesn't match any particular domain(s)
     * 3) The rule's pattern doesn't contain regular expressions
     * 4) The $domain modifier contains only excluded domains (e.g., $domain=~example.org|~example.com)
     *
     * When all these conditions are met, the domain modifier will match both the referrer domain and the target domain.
     * https://github.com/AdguardTeam/tsurlfilter/issues/45
     * @param request
     */
    NetworkRule.prototype.matchDomainModifier = function (request) {
        if (!this.domainModifier) {
            return true;
        }
        var domainModifier = this.domainModifier;
        var isDocumentType = request.requestType === RequestType.Document;
        var hasOnlyExcludedDomains = !domainModifier.hasPermittedDomains()
            && domainModifier.hasRestrictedDomains();
        var patternIsRegex = this.isRegexRule();
        var patternIsDomainSpecific = this.pattern.isPatternDomainSpecific();
        var matchesTargetByPatternCondition = !patternIsRegex && !patternIsDomainSpecific;
        if (isDocumentType && (hasOnlyExcludedDomains || matchesTargetByPatternCondition)) {
            // check if matches source hostname if exists or if matches target hostname
            return (request.sourceHostname && domainModifier.matchDomain(request.sourceHostname))
                || domainModifier.matchDomain(request.hostname);
        }
        return domainModifier.matchDomain(request.sourceHostname || '');
    };
    /**
     * checks if the filtering rule is allowed on this domain.
     * @param domain
     */
    NetworkRule.prototype.matchDenyAllowDomains = function (domain) {
        if (!this.denyAllowDomains) {
            return true;
        }
        if (this.denyAllowDomains.length > 0) {
            if (DomainModifier.isDomainOrSubdomainOfAny(domain, this.denyAllowDomains)) {
                return false;
            }
        }
        return true;
    };
    /**
     * Checks if the request domain matches the specified conditions.
     *
     * @param domain The request's domain.
     * @return true if the request domain matches the permitted domains and does not match the restricted domains.
     */
    NetworkRule.prototype.matchToModifier = function (domain) {
        if (!this.toModifier) {
            return true;
        }
        /**
         * The request's domain must be either explicitly permitted or not be included
         * in the list of restricted domains for the rule to apply.
         */
        var permittedDomains = this.getPermittedToDomains();
        var restrictedDomains = this.getRestrictedToDomains();
        var matches = false;
        if (permittedDomains) {
            matches = DomainModifier.isDomainOrSubdomainOfAny(domain, permittedDomains);
        }
        if (restrictedDomains) {
            matches = !DomainModifier.isDomainOrSubdomainOfAny(domain, restrictedDomains);
        }
        return matches;
    };
    /**
     * Return TRUE if this rule matches with the tags associated with a client
     *
     * @param clientTags
     */
    NetworkRule.prototype.matchClientTags = function (clientTags) {
        var advancedModifier = this.getAdvancedModifier();
        if (!advancedModifier || !(advancedModifier instanceof CtagModifier)) {
            return true;
        }
        if (!clientTags) {
            return false;
        }
        var cTagsModifier = advancedModifier;
        return clientTags.every(function (x) { return cTagsModifier.match(x); });
    };
    /**
     * returns TRUE if the rule matches with the specified client
     *
     * @param clientName
     * @param clientIP
     */
    NetworkRule.prototype.matchClient = function (clientName, clientIP) {
        var advancedModifier = this.getAdvancedModifier();
        if (!advancedModifier || !(advancedModifier instanceof ClientModifier)) {
            return true;
        }
        if (!clientName && !clientIP) {
            return false;
        }
        var modifier = advancedModifier;
        return modifier.matchAny(clientName, clientIP);
    };
    /**
     * Return TRUE if this rule matches with the request dnstype
     *
     * @param dnstype
     */
    NetworkRule.prototype.matchDnsType = function (dnstype) {
        var advancedModifier = this.getAdvancedModifier();
        if (!advancedModifier || !(advancedModifier instanceof DnsTypeModifier)) {
            return true;
        }
        if (!dnstype) {
            return false;
        }
        var modifier = advancedModifier;
        return modifier.match(dnstype);
    };
    /**
     * Checks if rule has permitted apps
     */
    NetworkRule.prototype.hasPermittedApps = function () {
        if (!this.appModifier) {
            return false;
        }
        return this.appModifier.permittedApps !== null && this.appModifier.permittedApps.length > 0;
    };
    /**
     * matchRequestType checks if the request's type matches the rule properties
     * @param requestType - request type to check.
     */
    NetworkRule.prototype.matchRequestType = function (requestType) {
        if (this.permittedRequestTypes !== RequestType.NotSet) {
            if ((this.permittedRequestTypes & requestType) !== requestType) {
                return false;
            }
        }
        if (this.restrictedRequestTypes !== RequestType.NotSet) {
            if ((this.restrictedRequestTypes & requestType) === requestType) {
                return false;
            }
        }
        return true;
    };
    /**
     * In case of $removeparam, $permissions modifier,
     * we only allow it to target other content types if the rule has an explicit content-type modifier.
     */
    NetworkRule.prototype.matchRequestTypeExplicit = function (requestType) {
        if (this.permittedRequestTypes === RequestType.NotSet
            && this.restrictedRequestTypes === RequestType.NotSet
            && requestType !== RequestType.Document
            && requestType !== RequestType.SubDocument) {
            return false;
        }
        return this.matchRequestType(requestType);
    };
    /**
     * Checks if request's method matches with the rule
     *
     * @param method request's method
     * @returns true, if rule must be applied to the request
     */
    NetworkRule.prototype.matchMethod = function (method) {
        if (!method || !MethodModifier.isHTTPMethod(method)) {
            return false;
        }
        /**
         * Request's method must be either explicitly
         * permitted or not be included in list of restricted methods
         * for the rule to apply
         */
        var permittedMethods = this.getPermittedMethods();
        if (permittedMethods === null || permittedMethods === void 0 ? void 0 : permittedMethods.includes(method)) {
            return true;
        }
        var restrictedMethods = this.getRestrictedMethods();
        return !!restrictedMethods && !restrictedMethods.includes(method);
    };
    /**
     * Checks if request's response headers matches with
     * the rule's $header modifier value
     *
     * @param responseHeadersItems request's response headers
     * @returns true, if rule must be applied to the request
     */
    NetworkRule.prototype.matchResponseHeaders = function (responseHeadersItems) {
        if (!responseHeadersItems || responseHeadersItems.length === 0) {
            return false;
        }
        var ruleData = this.getHeaderModifierValue();
        if (!ruleData) {
            return false;
        }
        var ruleHeaderName = ruleData.header, ruleHeaderValue = ruleData.value;
        return responseHeadersItems.some(function (responseHeadersItem) {
            var responseHeaderName = responseHeadersItem.name, responseHeaderValue = responseHeadersItem.value;
            // Header name matching is case-insensitive
            if (ruleHeaderName.toLowerCase() !== responseHeaderName.toLowerCase()) {
                return false;
            }
            if (ruleHeaderValue === null) {
                return true;
            }
            // Unlike header name, header value matching is case-sensitive
            if (typeof ruleHeaderValue === 'string') {
                return ruleHeaderValue === responseHeaderValue;
            }
            if (responseHeaderValue && ruleHeaderValue instanceof RegExp) {
                return ruleHeaderValue.test(responseHeaderValue);
            }
            return false;
        });
    };
    /**
     * Checks if a network rule is too general.
     */
    NetworkRule.isTooGeneral = function (node) {
        var _a, _b;
        return !((_b = (_a = node.modifiers) === null || _a === void 0 ? void 0 : _a.children) === null || _b === void 0 ? void 0 : _b.length) && node.pattern.value.length < 4;
    };
    /**
     * Parses the options string and saves them.
     * More on the rule modifiers:
     * https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#basic-rules-modifiers
     *
     * @param options - Modifier list node.
     *
     * @throws an error if there is an unsupported modifier
     */
    NetworkRule.prototype.loadOptions = function (options) {
        for (var _i = 0, _a = options.children; _i < _a.length; _i++) {
            var option = _a[_i];
            var value = simple_regex_dfa6ed82.E;
            if (option.value && option.value.value) {
                value = option.value.value;
            }
            this.loadOption(option.name.value, value, option.exception);
            this.usedOptionNames.add(option.name.value);
        }
        this.validateOptions();
    };
    /**
     * Returns true if rule contains (enabled or disabled) specified option.
     * Please note, that options have three state: enabled, disabled, undefined.
     *
     * @param option - rule option to check.
     */
    NetworkRule.prototype.hasOption = function (option) {
        return this.isOptionEnabled(option) || this.isOptionDisabled(option);
    };
    /**
     * Returns true if rule has at least one cosmetic option enabled.
     */
    NetworkRule.prototype.hasCosmeticOption = function () {
        return (this.enabledOptions & NetworkRuleGroupOptions.CosmeticOption) !== 0;
    };
    /**
     * Returns true if the specified option is enabled.
     * Please note, that options have three state: enabled, disabled, undefined.
     *
     * @param option - rule option to check.
     */
    NetworkRule.prototype.isOptionEnabled = function (option) {
        return (this.enabledOptions & option) === option;
    };
    /**
     * Returns true if one and only option is enabled
     *
     * @param option
     */
    NetworkRule.prototype.isSingleOptionEnabled = function (option) {
        return this.enabledOptions === option;
    };
    /**
     * Returns true if the specified option is disabled.
     * Please note, that options have three state: enabled, disabled, undefined.
     *
     * @param option - rule option to check.
     */
    NetworkRule.prototype.isOptionDisabled = function (option) {
        return (this.disabledOptions & option) === option;
    };
    /**
     * Checks if the rule has higher priority that the specified rule
     * allowlist + $important > $important > redirect > allowlist > basic rules
     */
    NetworkRule.prototype.isHigherPriority = function (r) {
        return this.priorityWeight > r.priorityWeight;
    };
    /**
     * Returns true if the rule is considered "generic"
     * "generic" means that the rule is not restricted to a limited set of domains
     * Please note that it might be forbidden on some domains, though.
     *
     * @return {boolean}
     */
    NetworkRule.prototype.isGeneric = function () {
        var _a;
        return !((_a = this.domainModifier) === null || _a === void 0 ? void 0 : _a.hasPermittedDomains());
    };
    /**
     * Returns true if this rule negates the specified rule
     * Only makes sense when this rule has a `badfilter` modifier
     */
    NetworkRule.prototype.negatesBadfilter = function (specifiedRule) {
        if (!this.isOptionEnabled(NetworkRuleOption.Badfilter)) {
            return false;
        }
        if (this.allowlist !== specifiedRule.allowlist) {
            return false;
        }
        if (this.pattern.pattern !== specifiedRule.pattern.pattern) {
            return false;
        }
        if (this.permittedRequestTypes !== specifiedRule.permittedRequestTypes) {
            return false;
        }
        if (this.restrictedRequestTypes !== specifiedRule.restrictedRequestTypes) {
            return false;
        }
        if ((this.enabledOptions ^ NetworkRuleOption.Badfilter) !== specifiedRule.enabledOptions) {
            return false;
        }
        if (this.disabledOptions !== specifiedRule.disabledOptions) {
            return false;
        }
        if (!(0,simple_regex_dfa6ed82.d)(this.getRestrictedDomains(), specifiedRule.getRestrictedDomains())) {
            return false;
        }
        if (!(0,simple_regex_dfa6ed82.e)(this.getPermittedDomains(), specifiedRule.getPermittedDomains())) {
            return false;
        }
        return true;
    };
    /**
     * Checks if this rule can be used for hosts-level blocking
     */
    NetworkRule.prototype.isHostLevelNetworkRule = function () {
        var _a, _b;
        if (((_a = this.domainModifier) === null || _a === void 0 ? void 0 : _a.hasPermittedDomains()) || ((_b = this.domainModifier) === null || _b === void 0 ? void 0 : _b.hasRestrictedDomains())) {
            return false;
        }
        if (this.permittedRequestTypes !== 0 && this.restrictedRequestTypes !== 0) {
            return false;
        }
        if (this.disabledOptions !== NetworkRuleOption.NotSet) {
            return false;
        }
        if (this.enabledOptions !== NetworkRuleOption.NotSet) {
            return ((this.enabledOptions
                & NetworkRuleGroupOptions.OptionHostLevelRules)
                | (this.enabledOptions
                    ^ NetworkRuleGroupOptions.OptionHostLevelRules)) === NetworkRuleGroupOptions.OptionHostLevelRules;
        }
        return true;
    };
    /**
     * Enables or disables the specified option.
     *
     * @param option - option to enable or disable.
     * @param enabled - true to enable, false to disable.
     * @param skipRestrictions - skip options allowlist/blacklist restrictions
     *
     * @throws an error if the option we're trying to enable cannot be.
     * For instance, you cannot enable $elemhide for blacklist rules.
     */
    NetworkRule.prototype.setOptionEnabled = function (option, enabled, skipRestrictions) {
        if (skipRestrictions === void 0) { skipRestrictions = false; }
        if (!skipRestrictions) {
            if (!this.allowlist && (option & NetworkRuleGroupOptions.AllowlistOnly) === option) {
                throw new SyntaxError("Modifier ".concat(NetworkRuleOption[option], " cannot be used in blacklist rule"));
            }
        }
        if (enabled) {
            this.enabledOptions |= option;
        }
        else {
            this.disabledOptions |= option;
        }
    };
    /**
     * Permits or forbids the specified request type.
     * "Permits" means that the rule will match **only** the types that are permitted.
     * "Restricts" means that the rule will match **all but restricted**.
     *
     * @param requestType - request type.
     * @param permitted - true if it's permitted (whic)
     */
    NetworkRule.prototype.setRequestType = function (requestType, permitted) {
        if (permitted) {
            this.permittedRequestTypes |= requestType;
        }
        else {
            this.restrictedRequestTypes |= requestType;
        }
    };
    /**
     * Sets and validates exceptionally allowed domains presented in $denyallow modifier
     *
     * @param optionValue
     */
    NetworkRule.prototype.setDenyAllowDomains = function (optionValue) {
        var domainModifier = new DomainModifier(optionValue, PIPE_SEPARATOR$1);
        if (domainModifier.restrictedDomains && domainModifier.restrictedDomains.length > 0) {
            throw new SyntaxError('Invalid modifier: $denyallow domains cannot be negated');
        }
        if (domainModifier.permittedDomains) {
            if (domainModifier.permittedDomains.some(DomainModifier.isWildcardOrRegexDomain)) {
                throw new SyntaxError('Invalid modifier: $denyallow does not support wildcards and regex domains');
            }
        }
        this.denyAllowDomains = domainModifier.permittedDomains;
    };
    /**
     * Loads the specified modifier:
     * https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#basic-rules-modifiers
     *
     * @param optionName - modifier name.
     * @param optionValue - modifier value.
     * @param exception - true if the modifier is negated.
     *
     * @throws an error if there is an unsupported modifier
     */
    NetworkRule.prototype.loadOption = function (optionName, optionValue, exception) {
        var _this = this;
        if (exception === void 0) { exception = false; }
        var OPTIONS = NetworkRule.OPTIONS, NEGATABLE_OPTIONS = NetworkRule.NEGATABLE_OPTIONS;
        if (optionName.startsWith(OPTIONS.NOOP)) {
            /**
             * A noop modifier does nothing and can be used to increase some rules readability.
             * It consists of the sequence of underscore characters (_) of any length
             * and can appear in a rule as many times as it's needed.
             */
            if (!optionName.split(OPTIONS.NOOP).some(function (s) { return !!s; })) {
                return;
            }
        }
        // TODO: Speed up this by creating a map from names to bit mask positions
        if (exception && !NEGATABLE_OPTIONS.has(optionName)) {
            throw new SyntaxError("Invalid modifier: '".concat(optionName, "' cannot be negated"));
        }
        switch (optionName) {
            // General options
            // $first-party, $~first-party
            case OPTIONS.FIRST_PARTY:
                this.setOptionEnabled(NetworkRuleOption.ThirdParty, exception);
                break;
            // $third-party, $~third-party
            case OPTIONS.THIRD_PARTY:
                this.setOptionEnabled(NetworkRuleOption.ThirdParty, !exception);
                break;
            // $match-case, $~match-case
            case OPTIONS.MATCH_CASE:
                this.setOptionEnabled(NetworkRuleOption.MatchCase, !exception);
                break;
            // $important
            case OPTIONS.IMPORTANT:
                this.setOptionEnabled(NetworkRuleOption.Important, true);
                break;
            // $domain
            case OPTIONS.DOMAIN:
                this.domainModifier = new DomainModifier(optionValue, PIPE_SEPARATOR$1);
                break;
            // $denyallow
            case OPTIONS.DENYALLOW:
                this.setDenyAllowDomains(optionValue);
                break;
            // $method modifier
            case OPTIONS.METHOD: {
                this.setOptionEnabled(NetworkRuleOption.Method, true);
                this.methodModifier = new MethodModifier(optionValue);
                break;
            }
            // $header modifier
            case OPTIONS.HEADER:
                this.setOptionEnabled(NetworkRuleOption.Header, true);
                this.headerModifier = new HeaderModifier(optionValue);
                break;
            // $to modifier
            case OPTIONS.TO: {
                this.setOptionEnabled(NetworkRuleOption.To, true);
                this.toModifier = new ToModifier(optionValue);
                break;
            }
            // Document-level allowlist rules
            // $elemhide
            case OPTIONS.ELEMHIDE:
                this.setOptionEnabled(NetworkRuleOption.Elemhide, true);
                this.setRequestType(RequestType.Document, true);
                this.setRequestType(RequestType.SubDocument, true);
                break;
            // $generichide
            case OPTIONS.GENERICHIDE:
                this.setOptionEnabled(NetworkRuleOption.Generichide, true);
                this.setRequestType(RequestType.Document, true);
                this.setRequestType(RequestType.SubDocument, true);
                break;
            // $specifichide
            case OPTIONS.SPECIFICHIDE:
                this.setOptionEnabled(NetworkRuleOption.Specifichide, true);
                this.setRequestType(RequestType.Document, true);
                this.setRequestType(RequestType.SubDocument, true);
                break;
            // $genericblock
            case OPTIONS.GENERICBLOCK:
                this.setOptionEnabled(NetworkRuleOption.Genericblock, true);
                this.setRequestType(RequestType.Document, true);
                this.setRequestType(RequestType.SubDocument, true);
                break;
            // $jsinject
            case OPTIONS.JSINJECT:
                this.setOptionEnabled(NetworkRuleOption.Jsinject, true);
                this.setRequestType(RequestType.Document, true);
                this.setRequestType(RequestType.SubDocument, true);
                break;
            // $urlblock
            case OPTIONS.URLBLOCK:
                this.setOptionEnabled(NetworkRuleOption.Urlblock, true);
                this.setRequestType(RequestType.Document, true);
                this.setRequestType(RequestType.SubDocument, true);
                break;
            // $content
            case OPTIONS.CONTENT:
                this.setOptionEnabled(NetworkRuleOption.Content, true);
                this.setRequestType(RequestType.Document, true);
                this.setRequestType(RequestType.SubDocument, true);
                break;
            // $document, $doc / $~document, $~doc
            case OPTIONS.DOCUMENT:
            case OPTIONS.DOC:
                if (exception) {
                    this.setRequestType(RequestType.Document, false);
                    break;
                }
                this.setRequestType(RequestType.Document, true);
                // In the case of allowlist rules $document implicitly includes
                // all these modifiers: `$content`, `$elemhide`, `$jsinject`,
                // `$urlblock`.
                if (this.isAllowlist()) {
                    this.setOptionEnabled(NetworkRuleOption.Elemhide, true, true);
                    this.setOptionEnabled(NetworkRuleOption.Jsinject, true, true);
                    this.setOptionEnabled(NetworkRuleOption.Urlblock, true, true);
                    this.setOptionEnabled(NetworkRuleOption.Content, true, true);
                }
                break;
            // $stealth
            case OPTIONS.STEALTH:
                this.setOptionEnabled(NetworkRuleOption.Stealth, true);
                this.stealthModifier = new StealthModifier(optionValue);
                break;
            // $popup
            case OPTIONS.POPUP:
                this.setOptionEnabled(NetworkRuleOption.Popup, true);
                break;
            // Content type options
            // $script, $~script
            case OPTIONS.SCRIPT:
                this.setRequestType(RequestType.Script, !exception);
                break;
            // $stylesheet, $~stylesheet
            case OPTIONS.STYLESHEET:
                this.setRequestType(RequestType.Stylesheet, !exception);
                break;
            // $subdocument, $~subdocument
            case OPTIONS.SUBDOCUMENT:
                this.setRequestType(RequestType.SubDocument, !exception);
                break;
            // $object, $~object
            case OPTIONS.OBJECT:
                this.setRequestType(RequestType.Object, !exception);
                break;
            // $image, $~image
            case OPTIONS.IMAGE:
                this.setRequestType(RequestType.Image, !exception);
                break;
            // $xmlhttprequest, $~xmlhttprequest
            case OPTIONS.XMLHTTPREQUEST:
                this.setRequestType(RequestType.XmlHttpRequest, !exception);
                break;
            // $media, $~media
            case OPTIONS.MEDIA:
                this.setRequestType(RequestType.Media, !exception);
                break;
            // $font, $~font
            case OPTIONS.FONT:
                this.setRequestType(RequestType.Font, !exception);
                break;
            // $websocket, $~websocket
            case OPTIONS.WEBSOCKET:
                this.setRequestType(RequestType.WebSocket, !exception);
                break;
            // $other, $~other
            case OPTIONS.OTHER:
                this.setRequestType(RequestType.Other, !exception);
                break;
            // $ping, $~ping
            case OPTIONS.PING:
                this.setRequestType(RequestType.Ping, !exception);
                break;
            // Special modifiers
            // $badfilter
            case OPTIONS.BADFILTER:
                this.setOptionEnabled(NetworkRuleOption.Badfilter, true);
                break;
            // $csp
            case OPTIONS.CSP:
                this.setOptionEnabled(NetworkRuleOption.Csp, true);
                this.advancedModifier = new CspModifier(optionValue, this.isAllowlist());
                break;
            // $replace
            case OPTIONS.REPLACE:
                this.setOptionEnabled(NetworkRuleOption.Replace, true);
                this.advancedModifier = new ReplaceModifier(optionValue);
                break;
            // $cookie
            case OPTIONS.COOKIE:
                this.setOptionEnabled(NetworkRuleOption.Cookie, true);
                this.advancedModifier = new CookieModifier(optionValue);
                break;
            // $redirect
            case OPTIONS.REDIRECT:
                this.setOptionEnabled(NetworkRuleOption.Redirect, true);
                this.advancedModifier = new RedirectModifier(optionValue, this.isAllowlist());
                break;
            // $redirect-rule
            case OPTIONS.REDIRECTRULE:
                this.setOptionEnabled(NetworkRuleOption.Redirect, true);
                this.advancedModifier = new RedirectModifier(optionValue, this.isAllowlist(), true);
                break;
            // $removeparam
            case OPTIONS.REMOVEPARAM:
                this.setOptionEnabled(NetworkRuleOption.RemoveParam, true);
                this.advancedModifier = new RemoveParamModifier(optionValue);
                break;
            // $removeheader
            case OPTIONS.REMOVEHEADER:
                this.setOptionEnabled(NetworkRuleOption.RemoveHeader, true);
                this.advancedModifier = new RemoveHeaderModifier(optionValue, this.isAllowlist());
                break;
            // $permissions
            case OPTIONS.PERMISSIONS:
                this.setOptionEnabled(NetworkRuleOption.Permissions, true);
                this.advancedModifier = new PermissionsModifier(optionValue, this.isAllowlist());
                break;
            // $jsonprune
            // simple validation of jsonprune rules for compiler
            // https://github.com/AdguardTeam/FiltersCompiler/issues/168
            case OPTIONS.JSONPRUNE:
                if (isCompatibleWith(CompatibilityTypes.Extension)) {
                    throw new SyntaxError('Extension does not support $jsonprune modifier yet');
                }
                this.setOptionEnabled(NetworkRuleOption.JsonPrune, true);
                // TODO: should be properly implemented later
                // https://github.com/AdguardTeam/tsurlfilter/issues/71
                break;
            // $hls
            // simple validation of hls rules for compiler
            // https://github.com/AdguardTeam/FiltersCompiler/issues/169
            case OPTIONS.HLS:
                if (isCompatibleWith(CompatibilityTypes.Extension)) {
                    throw new SyntaxError('Extension does not support $hls modifier yet');
                }
                this.setOptionEnabled(NetworkRuleOption.Hls, true);
                // TODO: should be properly implemented later
                // https://github.com/AdguardTeam/tsurlfilter/issues/72
                break;
            // $referrerpolicy
            // simple validation of referrerpolicy rules for compiler
            // https://github.com/AdguardTeam/FiltersCompiler/issues/191
            case OPTIONS.REFERRERPOLICY:
                if (isCompatibleWith(CompatibilityTypes.Extension)) {
                    throw new SyntaxError('Extension does not support $referrerpolicy modifier');
                }
                // do nothing as $referrerpolicy is supported by CoreLibs-based apps only.
                // it is needed for proper rule conversion performed by FiltersCompiler
                // so rules with $referrerpolicy modifier is not marked as invalid
                break;
            // Dns modifiers
            // $client
            case OPTIONS.CLIENT:
                if (isCompatibleWith(CompatibilityTypes.Extension)) {
                    throw new SyntaxError('Extension doesn\'t support $client modifier');
                }
                this.setOptionEnabled(NetworkRuleOption.Client, true);
                this.advancedModifier = new ClientModifier(optionValue);
                break;
            // $dnsrewrite
            case OPTIONS.DNSREWRITE:
                if (isCompatibleWith(CompatibilityTypes.Extension)) {
                    throw new SyntaxError('Extension doesn\'t support $dnsrewrite modifier');
                }
                this.setOptionEnabled(NetworkRuleOption.DnsRewrite, true);
                this.advancedModifier = new DnsRewriteModifier(optionValue);
                break;
            // $dnstype
            case OPTIONS.DNSTYPE:
                if (isCompatibleWith(CompatibilityTypes.Extension)) {
                    throw new SyntaxError('Extension doesn\'t support $dnstype modifier');
                }
                this.setOptionEnabled(NetworkRuleOption.DnsType, true);
                this.advancedModifier = new DnsTypeModifier(optionValue);
                break;
            // $ctag
            case OPTIONS.CTAG:
                if (isCompatibleWith(CompatibilityTypes.Extension)) {
                    throw new SyntaxError('Extension doesn\'t support $ctag modifier');
                }
                this.setOptionEnabled(NetworkRuleOption.Ctag, true);
                this.advancedModifier = new CtagModifier(optionValue);
                break;
            // $app
            case OPTIONS.APP:
                if (isCompatibleWith(CompatibilityTypes.Extension)) {
                    throw new SyntaxError('Extension doesn\'t support $app modifier');
                }
                this.appModifier = new AppModifier(optionValue);
                break;
            // $network
            case OPTIONS.NETWORK:
                if (isCompatibleWith(CompatibilityTypes.Extension)) {
                    throw new SyntaxError('Extension doesn\'t support $network modifier');
                }
                this.setOptionEnabled(NetworkRuleOption.Network, true);
                break;
            // $extension, $~extension
            case OPTIONS.EXTENSION:
                if (isCompatibleWith(CompatibilityTypes.Extension)) {
                    throw new SyntaxError('Extension doesn\'t support $extension modifier');
                }
                this.setOptionEnabled(NetworkRuleOption.Extension, !exception);
                break;
            // $all
            case OPTIONS.ALL:
                if (this.isAllowlist()) {
                    throw new SyntaxError('Rule with $all modifier can not be allowlist rule');
                }
                // Set all request types
                Object.values(RequestType).forEach(function (type) {
                    _this.setRequestType(type, true);
                });
                this.setOptionEnabled(NetworkRuleOption.Popup, true);
                break;
            // $empty and $mp4
            // Deprecated in favor of $redirect
            case OPTIONS.EMPTY:
            case OPTIONS.MP4:
                // Do nothing.
                break;
            default: {
                // clear empty values
                var modifierView = [optionName, optionValue]
                    .filter(function (i) { return i; })
                    .join('=');
                throw new SyntaxError("Unknown modifier: ".concat(modifierView));
            }
        }
    };
    /**
     * To calculate priority, we've categorized modifiers into different groups.
     * These groups are ranked based on their priority, from lowest to highest.
     * A modifier that significantly narrows the scope of a rule adds more
     * weight to its total priority. Conversely, if a rule applies to a broader
     * range of requests, its priority decreases.
     *
     * It's worth noting that there are cases where a single-parameter modifier
     * has a higher priority than multi-parameter ones. For instance, in
     * the case of `$domain=example.com|example.org`, a rule that includes two
     * domains has a slightly broader effective area than a rule with one
     * specified domain, therefore its priority is lower.
     *
     * The base priority weight of any rule is 1. If the calculated priority
     * is a floating-point number, it will be **rounded up** to the smallest
     * integer greater than or equal to the calculated weight.
     *
     * @see {@link NetworkRule.PermittedRequestTypeWeight}
     * @see {@link NetworkRule.PermittedDomainWeight}
     * @see {@link NetworkRule.SpecificExceptionsWeight}
     * @see {@link NetworkRule.AllowlistRuleWeight}
     * @see {@link NetworkRule.RedirectRuleWeight}
     * @see {@link NetworkRule.ImportantRuleWeight}
     *
     * @see {@link https://adguard.com/kb/general/ad-filtering/create-own-filters/#priority-counting}
     */
    NetworkRule.prototype.calculatePriorityWeight = function () {
        var _a, _b;
        // Base modifiers, category 1.
        this.priorityWeight += countEnabledBits(this.enabledOptions, NetworkRule.CATEGORY_1_OPTIONS_MASK);
        this.priorityWeight += countEnabledBits(this.disabledOptions, NetworkRule.CATEGORY_1_OPTIONS_MASK);
        /**
         * When dealing with a negated domain, app, method, or content-type,
         * we add a point for the existence of the modifier itself, regardless
         * of the quantity of negated domains or content-types. This is because
         * the rule's scope is already infinitely broad. Put simply,
         * by prohibiting multiple domains, content-types, methods or apps,
         * the scope of the rule becomes only minimally smaller.
         */
        if (this.denyAllowDomains && this.denyAllowDomains.length > 0) {
            this.priorityWeight += 1;
        }
        var domainModifier = this.domainModifier;
        if (domainModifier === null || domainModifier === void 0 ? void 0 : domainModifier.hasRestrictedDomains()) {
            this.priorityWeight += 1;
        }
        if (((_a = this.methodModifier) === null || _a === void 0 ? void 0 : _a.restrictedValues) && this.methodModifier.restrictedValues.length > 0) {
            this.priorityWeight += 1;
        }
        if (this.restrictedRequestTypes !== RequestType.NotSet) {
            this.priorityWeight += 1;
        }
        // $to modifier is basically a replacement for a regular expression
        // See https://github.com/AdguardTeam/KnowledgeBase/pull/196#discussion_r1221401215
        if (this.toModifier) {
            this.priorityWeight += 1;
        }
        /**
         * Category 2: permitted request types, methods, headers, $popup.
         * Specified content-types add `50 + 50 / number_of_content_types`,
         * for example: `||example.com^$image,script` will add
         * `50 + 50 / 2 = 50 + 25 = 75` to the total weight of the rule.
         * The `$popup` also belongs to this category, because it implicitly
         * adds the modifier `$document`.
         * Similarly, specific exceptions add `$document,subdocument`.
         *
         * Learn more about it here:
         * https://adguard.com/kb/general/ad-filtering/create-own-filters/#priority-category-2
         */
        if (this.permittedRequestTypes !== RequestType.NotSet) {
            var numberOfPermittedRequestTypes = getBitCount(this.permittedRequestTypes);
            // More permitted request types mean less priority weight.
            var relativeWeight = NetworkRule.CategoryTwoWeight / numberOfPermittedRequestTypes;
            this.priorityWeight += NetworkRule.CategoryTwoWeight + relativeWeight;
        }
        if (((_b = this.methodModifier) === null || _b === void 0 ? void 0 : _b.permittedValues) && this.methodModifier.permittedValues.length > 0) {
            // More permitted request methods mean less priority weight.
            var relativeWeight = NetworkRule.CategoryTwoWeight / this.methodModifier.permittedValues.length;
            this.priorityWeight += NetworkRule.CategoryTwoWeight + relativeWeight;
        }
        if (this.headerModifier) {
            // $header modifier in the rule adds 50
            this.priorityWeight += NetworkRule.CategoryTwoWeight;
        }
        /**
         * Category 3: permitted domains.
         * Specified domains through `$domain` and specified applications
         * through `$app` add `100 + 100 / number_domains (or number_applications)`,
         * for example:
         * `||example.com^$domain=example.com|example.org|example.net`
         * will add `100 + 100 / 3 = 134.3 = 134` or
         * `||example.com^$app=org.example.app1|org.example.app2`
         * will add `100 + 100 / 2 = 151`.
         */
        if (domainModifier === null || domainModifier === void 0 ? void 0 : domainModifier.hasPermittedDomains()) {
            // More permitted domains mean less priority weight.
            var relativeWeight = NetworkRule.CategoryThreeWeight / domainModifier.getPermittedDomains().length;
            this.priorityWeight += NetworkRule.CategoryThreeWeight + relativeWeight;
        }
        // Category 4: redirect rules.
        if (this.isOptionEnabled(NetworkRuleOption.Redirect)) {
            this.priorityWeight += NetworkRule.CategoryFourWeight;
        }
        // Category 5: specific exceptions.
        this.priorityWeight += NetworkRule.CategoryFiveWeight * countEnabledBits(this.enabledOptions, NetworkRule.SPECIFIC_EXCLUSIONS_MASK);
        // Category 6: allowlist rules.
        if (this.isAllowlist()) {
            this.priorityWeight += NetworkRule.CategorySixWeight;
        }
        // Category 7: important rules.
        if (this.isOptionEnabled(NetworkRuleOption.Important)) {
            this.priorityWeight += NetworkRule.CategorySevenWeight;
        }
        // Round up to avoid overlap between different categories of rules.
        this.priorityWeight = Math.ceil(this.priorityWeight);
    };
    /**
     * Validates rule options
     */
    NetworkRule.prototype.validateOptions = function () {
        if (this.advancedModifier instanceof RemoveParamModifier) {
            this.validateRemoveParamRule();
        }
        else if (this.advancedModifier instanceof RemoveHeaderModifier) {
            this.validateRemoveHeaderRule();
        }
        else if (this.advancedModifier instanceof PermissionsModifier) {
            this.validatePermissionsRule();
        }
        else if (this.headerModifier instanceof HeaderModifier) {
            this.validateHeaderRule();
        }
        else if (this.toModifier !== null) {
            this.validateToRule();
        }
        else if (this.denyAllowDomains !== null) {
            this.validateDenyallowRule();
        }
    };
    /**
     * $header rules are not compatible with any other
     * modifiers except for $important, $csp, $removeheader, $badfilter.
     * The rules with any other modifiers are considered invalid and will be discarded.
     */
    NetworkRule.prototype.validateHeaderRule = function () {
        if ((this.enabledOptions | NetworkRuleGroupOptions.HeaderCompatibleOptions)
            !== NetworkRuleGroupOptions.HeaderCompatibleOptions) {
            throw new SyntaxError('$header rules are not compatible with some other modifiers');
        }
        if (this.advancedModifier && this.isOptionEnabled(NetworkRuleOption.RemoveHeader)) {
            var removeHeaderValue = this.getAdvancedModifierValue();
            if (!removeHeaderValue || removeHeaderValue.includes('request:')) {
                var message = '$header rules are only compatible with response headers removal of $removeheader.';
                throw new SyntaxError(message);
            }
        }
    };
    /**
     * $permissions rules are not compatible with any other
     * modifiers except $domain, $important, and $subdocument.
     * The rules with any other modifiers are considered invalid and will be discarded.
     */
    NetworkRule.prototype.validatePermissionsRule = function () {
        if ((this.enabledOptions | NetworkRuleGroupOptions.PermissionsCompatibleOptions)
            !== NetworkRuleGroupOptions.PermissionsCompatibleOptions) {
            throw new SyntaxError('$permissions rules are not compatible with some other modifiers');
        }
    };
    /**
     * $removeparam rules are not compatible with any other modifiers except $domain,
     * $third-party, $app, $important, $match-case and permitted content type modifiers ($script, $stylesheet, etc).
     * The rules with any other modifiers are considered invalid and will be discarded.
     */
    NetworkRule.prototype.validateRemoveParamRule = function () {
        if ((this.enabledOptions | NetworkRuleGroupOptions.RemoveParamCompatibleOptions)
            !== NetworkRuleGroupOptions.RemoveParamCompatibleOptions) {
            throw new SyntaxError('$removeparam rules are not compatible with some other modifiers');
        }
    };
    /**
     * $removeheader rules are not compatible with any other modifiers except $domain,
     * $third-party, $app, $important, $match-case and permitted content type modifiers ($script, $stylesheet, etc).
     * The rules with any other modifiers are considered invalid and will be discarded.
     */
    NetworkRule.prototype.validateRemoveHeaderRule = function () {
        if ((this.enabledOptions | NetworkRuleGroupOptions.RemoveHeaderCompatibleOptions)
            !== NetworkRuleGroupOptions.RemoveHeaderCompatibleOptions) {
            throw new SyntaxError('$removeheader rules are not compatible with some other modifiers');
        }
        if (this.headerModifier && this.isOptionEnabled(NetworkRuleOption.Header)) {
            var removeHeaderValue = this.getAdvancedModifierValue();
            if (!removeHeaderValue || removeHeaderValue.includes('request:')) {
                var message = 'Request headers removal of $removeheaders is not compatible with $header rules.';
                throw new SyntaxError(message);
            }
        }
    };
    /**
     * $to rules are not compatible $denyallow - these rules considered invalid
     * and will be discarded.
     */
    NetworkRule.prototype.validateToRule = function () {
        if (this.denyAllowDomains) {
            throw new SyntaxError('modifier $to is not compatible with $denyallow modifier');
        }
    };
    /**
     * $denyallow rules are not compatible $to - these rules considered invalid
     * and will be discarded.
     */
    NetworkRule.prototype.validateDenyallowRule = function () {
        if (this.toModifier) {
            throw new SyntaxError('modifier $to is not compatible with $denyallow modifier');
        }
    };
    /**
     * Rules with base modifiers, from category 1, each of them adds 1
     * to the weight of the rule.
     *
     * @see https://adguard.com/kb/general/ad-filtering/create-own-filters/#priority-category-1
     */
    NetworkRule.CATEGORY_1_OPTIONS_MASK = NetworkRuleOption.ThirdParty
        | NetworkRuleOption.MatchCase
        | NetworkRuleOption.DnsRewrite;
    /**
     * The priority weight used in {@link calculatePriorityWeight} for rules
     * with permitted request types and methods.
     * The value 50 is chosen in order to cover (with a margin) all possible
     * combinations and variations of rules from categories with a lower
     * priority (each of them adds 1 to the rule priority).
     *
     * @see https://adguard.com/kb/general/ad-filtering/create-own-filters/#priority-category-2
     */
    NetworkRule.CategoryTwoWeight = 50;
    /**
     * The priority weight used in {@link calculatePriorityWeight} for rules
     * with allowed domains.
     * The value 100 is chosen to cover all possible combinations and variations
     * of rules from categories with a lower priority, for example a rule with
     * one allowed query type will get priority 100 (50 + 50/1), but for allowed
     * domains with any number of domains we will get at least 101 (for 100
     * domains: 100 + 100/100; for 200 100 + 100/200; or even for 10000:
     * 100 + 100/10000) because the resulting weight is rounded up.
     *
     * @see https://adguard.com/kb/general/ad-filtering/create-own-filters/#priority-category-3
     */
    NetworkRule.CategoryThreeWeight = 100;
    /**
     * The priority weight used in {@link calculatePriorityWeight}
     * for $redirect rules.
     *
     * @see https://adguard.com/kb/general/ad-filtering/create-own-filters/#priority-category-6
     */
    NetworkRule.CategoryFourWeight = Math.pow(10, 3);
    /**
     * The priority weight used in {@link calculatePriorityWeight} for rules
     * with specific exceptions.
     *
     * @see https://adguard.com/kb/general/ad-filtering/create-own-filters/#priority-category-4
     */
    NetworkRule.CategoryFiveWeight = Math.pow(10, 4);
    /**
     * Rules with specific exclusions, from category 4, each of them adds
     * {@link SpecificExceptionsWeight} to the weight of the rule.
     *
     * @see https://adguard.com/kb/general/ad-filtering/create-own-filters/#priority-category-4
     */
    NetworkRule.SPECIFIC_EXCLUSIONS_MASK = NetworkRuleOption.Elemhide
        | NetworkRuleOption.Generichide
        | NetworkRuleOption.Specifichide
        | NetworkRuleOption.Content
        | NetworkRuleOption.Urlblock
        | NetworkRuleOption.Genericblock
        | NetworkRuleOption.Jsinject
        | NetworkRuleOption.Extension;
    /**
     * The priority weight used in {@link calculatePriorityWeight} for rules
     * with allowlist mark '@@'.
     *
     * @see https://adguard.com/kb/general/ad-filtering/create-own-filters/#priority-category-5
     */
    NetworkRule.CategorySixWeight = Math.pow(10, 5);
    /**
     * The priority weight used in {@link calculatePriorityWeight}
     * for $important rules.
     *
     * @see https://adguard.com/kb/general/ad-filtering/create-own-filters/#priority-category-7
     */
    NetworkRule.CategorySevenWeight = Math.pow(10, 6);
    /**
     * Separates the rule pattern from the list of modifiers.
     *
     * ```
     * rule = ["@@"] pattern [ "$" modifiers ]
     * modifiers = [modifier0, modifier1[, ...[, modifierN]]]
     * ```
     */
    NetworkRule.OPTIONS_DELIMITER = OPTIONS_DELIMITER;
    /**
     * A marker that is used in rules of exception.
     * To turn off filtering for a request, start your rule with this marker.
     */
    NetworkRule.MASK_ALLOWLIST = MASK_ALLOWLIST;
    /**
     * Mark that negates options
     */
    NetworkRule.NOT_MARK = NOT_MARK;
    /**
     * Rule options
     */
    NetworkRule.OPTIONS = NETWORK_RULE_OPTIONS;
    /**
     * Rule options that can be negated
     */
    NetworkRule.NEGATABLE_OPTIONS = new Set([
        // General options
        NetworkRule.OPTIONS.FIRST_PARTY,
        NetworkRule.OPTIONS.THIRD_PARTY,
        NetworkRule.OPTIONS.MATCH_CASE,
        NetworkRule.OPTIONS.DOCUMENT,
        NetworkRule.OPTIONS.DOC,
        // Content type options
        NetworkRule.OPTIONS.SCRIPT,
        NetworkRule.OPTIONS.STYLESHEET,
        NetworkRule.OPTIONS.SUBDOCUMENT,
        NetworkRule.OPTIONS.OBJECT,
        NetworkRule.OPTIONS.IMAGE,
        NetworkRule.OPTIONS.XMLHTTPREQUEST,
        NetworkRule.OPTIONS.MEDIA,
        NetworkRule.OPTIONS.FONT,
        NetworkRule.OPTIONS.WEBSOCKET,
        NetworkRule.OPTIONS.OTHER,
        NetworkRule.OPTIONS.PING,
        // Dns modifiers
        NetworkRule.OPTIONS.EXTENSION,
    ]);
    /**
     * Advanced option modifier names.
     */
    NetworkRule.ADVANCED_OPTIONS = new Set([
        NetworkRule.OPTIONS.CSP,
        NetworkRule.OPTIONS.REPLACE,
        NetworkRule.OPTIONS.COOKIE,
        NetworkRule.OPTIONS.REDIRECT,
        NetworkRule.OPTIONS.REDIRECTRULE,
        NetworkRule.OPTIONS.REMOVEPARAM,
        NetworkRule.OPTIONS.REMOVEHEADER,
        NetworkRule.OPTIONS.PERMISSIONS,
        NetworkRule.OPTIONS.CLIENT,
        NetworkRule.OPTIONS.DNSREWRITE,
        NetworkRule.OPTIONS.DNSTYPE,
        NetworkRule.OPTIONS.CTAG,
    ]);
    return NetworkRule;
}());

/**
 * MatchingResult contains all the rules matching a web request, and provides methods
 * that define how a web request should be processed
 */
var MatchingResult = /** @class */ (function () {
    /**
     * Creates an instance of the MatchingResult struct and fills it with the rules.
     *
     * @param rules A list of network rules that match the request.
     * @param sourceRule A rule that matches the document that is a source
     * of the request, i.e. document-level exclusions.
     */
    function MatchingResult(rules, sourceRule) {
        var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
        this.basicRule = null;
        this.documentRule = null;
        this.cspRules = null;
        this.cookieRules = null;
        this.replaceRules = null;
        this.removeParamRules = null;
        this.removeHeaderRules = null;
        this.redirectRules = null;
        this.stealthRules = null;
        this.permissionsRules = null;
        this.headerRules = null;
        this.popupRule = null;
        this.cosmeticExceptionRule = null;
        // eslint-disable-next-line no-param-reassign
        rules = MatchingResult.removeBadfilterRules(rules);
        if (sourceRule) {
            this.documentRule = sourceRule;
        }
        // Second - check if blocking rules (generic or all of them) are allowed
        // generic blocking rules are allowed by default
        var genericAllowed = true;
        // basic blocking rules are allowed by default
        var basicAllowed = true;
        if (this.documentRule) {
            if (this.documentRule.isOptionEnabled(NetworkRuleOption.Urlblock)) {
                basicAllowed = false;
            }
            else if (this.documentRule.isOptionEnabled(NetworkRuleOption.Genericblock)) {
                genericAllowed = false;
            }
        }
        // Iterate through the list of rules and fill the MatchingResult
        for (var _i = 0, rules_1 = rules; _i < rules_1.length; _i++) {
            var rule = rules_1[_i];
            if (rule.hasCosmeticOption()) {
                if (!this.cosmeticExceptionRule || rule.isHigherPriority(this.cosmeticExceptionRule)) {
                    this.cosmeticExceptionRule = rule;
                }
                /**
                 * Some rules include both cosmetic options and network modifiers,
                 * and affect both network and cosmetic engines matching.
                 *
                 * Such rules should also compete for `basicRule` slot down below,
                 * e.g `@@||example.org$document` and `@@||nhk.or.jp^$content`.
                 *
                 * Cosmetic options rules that don't contain such modifiers should only affect cosmetic engine.
                 */
                if (!rule.isOptionEnabled(NetworkRuleOption.Urlblock)
                    && !rule.isOptionEnabled(NetworkRuleOption.Genericblock)
                    && !rule.isOptionEnabled(NetworkRuleOption.Content)) {
                    continue;
                }
            }
            if (rule.isOptionEnabled(NetworkRuleOption.Cookie)) {
                ((_a = this.cookieRules) !== null && _a !== void 0 ? _a : (this.cookieRules = [])).push(rule);
                continue;
            }
            if (rule.isOptionEnabled(NetworkRuleOption.Replace)) {
                ((_b = this.replaceRules) !== null && _b !== void 0 ? _b : (this.replaceRules = [])).push(rule);
                continue;
            }
            if (rule.isOptionEnabled(NetworkRuleOption.RemoveParam)) {
                ((_c = this.removeParamRules) !== null && _c !== void 0 ? _c : (this.removeParamRules = [])).push(rule);
                continue;
            }
            if (rule.isOptionEnabled(NetworkRuleOption.RemoveHeader)) {
                ((_d = this.removeHeaderRules) !== null && _d !== void 0 ? _d : (this.removeHeaderRules = [])).push(rule);
                continue;
            }
            if (rule.isOptionEnabled(NetworkRuleOption.Redirect)) {
                ((_e = this.redirectRules) !== null && _e !== void 0 ? _e : (this.redirectRules = [])).push(rule);
                continue;
            }
            if (rule.isOptionEnabled(NetworkRuleOption.Csp)) {
                ((_f = this.cspRules) !== null && _f !== void 0 ? _f : (this.cspRules = [])).push(rule);
                continue;
            }
            if (rule.isOptionEnabled(NetworkRuleOption.Stealth)) {
                ((_g = this.stealthRules) !== null && _g !== void 0 ? _g : (this.stealthRules = [])).push(rule);
                continue;
            }
            if (rule.isOptionEnabled(NetworkRuleOption.Permissions)) {
                ((_h = this.permissionsRules) !== null && _h !== void 0 ? _h : (this.permissionsRules = [])).push(rule);
                continue;
            }
            if (rule.isOptionEnabled(NetworkRuleOption.Header)) {
                ((_j = this.headerRules) !== null && _j !== void 0 ? _j : (this.headerRules = [])).push(rule);
                continue;
            }
            if (rule.isOptionEnabled(NetworkRuleOption.Popup)
                // This check needed to split $all rules from $popup rules
                && (rule.getPermittedRequestTypes() & RequestType.Document) !== RequestType.Document) {
                this.popupRule = rule;
                continue;
            }
            // Check blocking rules against $genericblock / $urlblock
            if (!rule.isAllowlist() && ((_k = this.documentRule) === null || _k === void 0 ? void 0 : _k.isHigherPriority(rule))) {
                if (!basicAllowed) {
                    continue;
                }
                if (!genericAllowed && rule.isGeneric()) {
                    continue;
                }
            }
            if (!this.basicRule || rule.isHigherPriority(this.basicRule)) {
                this.basicRule = rule;
            }
        }
    }
    /**
     * Returns popup rule
     */
    MatchingResult.prototype.getPopupRule = function () {
        return this.popupRule;
    };
    /**
     * GetBasicResult returns a rule that should be applied to the web request.
     * Possible outcomes are:
     * returns nil -- allow the request.
     * returns an allowlist rule -- allow the request.
     * returns a blocking rule -- block the request.
     * returns a redirect rule -- redirect the request.
     *
     * @return {NetworkRule | null} basic result rule
     */
    MatchingResult.prototype.getBasicResult = function () {
        var basic = this.basicRule;
        // e.g. @@||example.com^$generichide
        if (this.cosmeticExceptionRule && (!basic || this.cosmeticExceptionRule.isHigherPriority(basic))) {
            return this.cosmeticExceptionRule;
        }
        if (!basic) {
            // Only document-level frame rule would be returned as a basic result,
            // cause only those rules could block or modify page sub-requests.
            // Other frame rules (generichide, elemhide etc) will be used in getCosmeticOption function.
            if (this.documentRule && this.documentRule.isDocumentLevelAllowlistRule()) {
                basic = this.documentRule;
            }
        }
        // https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#replace-modifier
        // https://adguard.com/kb/general/ad-filtering/create-own-filters/#priority-category-extra
        // $replace rules have a higher priority than other basic rules (including exception rules).
        // So if a request corresponds to two different rules one of which has the $replace modifier,
        // this rule will be applied.
        if (this.replaceRules) {
            var isReplaceOrContent = (basic === null || basic === void 0 ? void 0 : basic.isOptionEnabled(NetworkRuleOption.Replace))
                || (basic === null || basic === void 0 ? void 0 : basic.isOptionEnabled(NetworkRuleOption.Content));
            // If basic rule is an exception with $replace or $content modifier,
            // then basic rule will disable $replace rules.
            if ((basic === null || basic === void 0 ? void 0 : basic.isAllowlist()) && isReplaceOrContent) {
                return basic;
            }
            // Otherwise null is returned to allow the request, because we need
            // to get response first to then apply the $replace rules to
            // the response.
            return null;
        }
        // Redirect rules have a high priority
        // https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#redirect-modifier
        // https://adguard.com/kb/general/ad-filtering/create-own-filters/#priority-category-6
        var redirectRule = this.getRedirectRule();
        if (redirectRule && (!basic || !basic.isHigherPriority(redirectRule))) {
            return redirectRule;
        }
        if (!basic) {
            return this.popupRule;
        }
        return basic;
    };
    /**
     * Returns a single stealth rule, that is corresponding to the given option.
     * If no option is given, returns a rule that disables stealth completely if any.
     *
     * @param stealthOption stealth option name
     * @returns stealth rule or null
     */
    MatchingResult.prototype.getStealthRule = function (stealthOption) {
        var _a;
        if (!this.stealthRules) {
            return null;
        }
        return (_a = this.stealthRules.find(function (r) {
            var stealthModifier = r.getStealthModifier();
            if (!stealthModifier) {
                logger.debug("Stealth rule without stealth modifier: ".concat(r));
                return false;
            }
            if (stealthOption) {
                return stealthModifier.hasStealthOption(stealthOption);
            }
            // $stealth rules without values are globally disabling stealth mode
            return !stealthModifier.hasValues();
        })) !== null && _a !== void 0 ? _a : null;
    };
    /**
     * Returns a single rule with $header modifier,
     * that should be applied to the web request, if any.
     *
     * Function is intended to be called on onHeadersReceived event as an alternative to getBasicResult,
     * it returns only a blocking or allowlist rule without modifiers which could modify the request.
     * Request modifying rules with $header modifier are handled in a corresponding service.
     *
     * TODO: filterAdvancedModifierRules may not be optimal for sorting rules with $header modifier,
     * as $header is not an advanced modifier.
     *
     * @param responseHeaders response headers
     * @returns header result rule or null
     */
    MatchingResult.prototype.getResponseHeadersResult = function (responseHeaders) {
        if (!responseHeaders || responseHeaders.length === 0) {
            return null;
        }
        var _a = this, basicRule = _a.basicRule, documentRule = _a.documentRule;
        var headerRules = this.headerRules;
        if (!headerRules) {
            return null;
        }
        if (!basicRule) {
            if (documentRule && documentRule.isDocumentLevelAllowlistRule()) {
                return null;
            }
        }
        else if (basicRule.isAllowlist()) {
            return null;
        }
        headerRules = headerRules.filter(function (rule) { return rule.matchResponseHeaders(responseHeaders); });
        // Handle allowlist rules with $header modifier,
        // filtering out blocking rules which are allowlisted
        var rules = MatchingResult.filterAdvancedModifierRules(headerRules, function (bRule) { return (function (aRule) {
            var _a, _b;
            var bHeaderData = bRule.getHeaderModifierValue();
            var aHeaderData = aRule.getHeaderModifierValue();
            return (bHeaderData === null || bHeaderData === void 0 ? void 0 : bHeaderData.header) === (aHeaderData === null || aHeaderData === void 0 ? void 0 : aHeaderData.header)
                && ((_a = bHeaderData === null || bHeaderData === void 0 ? void 0 : bHeaderData.value) === null || _a === void 0 ? void 0 : _a.toString()) === ((_b = aHeaderData === null || aHeaderData === void 0 ? void 0 : aHeaderData.value) === null || _b === void 0 ? void 0 : _b.toString());
        }); });
        return MatchingResult.getHighestPriorityRule(rules);
    };
    /**
     * Returns a bit-flag with the list of cosmetic options
     *
     * @return {CosmeticOption} mask
     */
    MatchingResult.prototype.getCosmeticOption = function () {
        var _a = this, basicRule = _a.basicRule, documentRule = _a.documentRule, cosmeticExceptionRule = _a.cosmeticExceptionRule;
        var rule = cosmeticExceptionRule || basicRule;
        // We choose a non-empty rule and the one of the two with the higher
        // priority in order to accurately calculate cosmetic options.
        if ((!rule && documentRule) || (rule && (documentRule === null || documentRule === void 0 ? void 0 : documentRule.isHigherPriority(rule)))) {
            rule = documentRule;
        }
        if (!rule || !rule.isAllowlist()) {
            return CosmeticOption.CosmeticOptionAll;
        }
        var option = CosmeticOption.CosmeticOptionAll;
        if (rule.isOptionEnabled(NetworkRuleOption.Elemhide)) {
            option ^= CosmeticOption.CosmeticOptionGenericCSS;
            option ^= CosmeticOption.CosmeticOptionSpecificCSS;
        }
        if (rule.isOptionEnabled(NetworkRuleOption.Generichide)) {
            option ^= CosmeticOption.CosmeticOptionGenericCSS;
        }
        if (rule.isOptionEnabled(NetworkRuleOption.Specifichide)) {
            option ^= CosmeticOption.CosmeticOptionSpecificCSS;
        }
        if (rule.isOptionEnabled(NetworkRuleOption.Jsinject)) {
            option ^= CosmeticOption.CosmeticOptionJS;
        }
        if (rule.isOptionEnabled(NetworkRuleOption.Content)) {
            option ^= CosmeticOption.CosmeticOptionHtml;
        }
        return option;
    };
    /**
     * Return an array of replace rules
     */
    MatchingResult.prototype.getReplaceRules = function () {
        if (!this.replaceRules) {
            return [];
        }
        // TODO: Look up for allowlist $content rule
        return MatchingResult.filterAdvancedModifierRules(this.replaceRules, function (rule) { return (function (x) { return x.getAdvancedModifierValue() === rule.getAdvancedModifierValue(); }); });
    };
    /**
     * Filters array of rules according to allowlist rules contained.
     * Empty advanced modifier allowlists everything.
     *
     * @param rules
     * @param allowlistPredicate allowlist criteria
     * This function result will be called for testing if rule `x` allowlists rule `r`
     */
    MatchingResult.filterAdvancedModifierRules = function (rules, allowlistPredicate) {
        var _this = this;
        var blockingRules = [];
        var allowlistRules = [];
        for (var _i = 0, rules_2 = rules; _i < rules_2.length; _i++) {
            var rule = rules_2[_i];
            if (rule.isAllowlist()) {
                allowlistRules.push(rule);
            }
            else {
                blockingRules.push(rule);
            }
        }
        if (blockingRules.length === 0) {
            return [];
        }
        if (allowlistRules.length === 0) {
            return blockingRules;
        }
        if (allowlistRules.length > 0) {
            var allowlistRuleWithEmptyOption_1 = allowlistRules
                .find(function (allowlistRule) { return allowlistRule.getAdvancedModifierValue() === ''; });
            var result_1 = [];
            blockingRules.forEach(function (blockRule) {
                if (allowlistRuleWithEmptyOption_1
                    && !blockRule.isHigherPriority(allowlistRuleWithEmptyOption_1)) {
                    result_1.push(allowlistRuleWithEmptyOption_1);
                    return;
                }
                var allowlistingRule = allowlistRules.find(function (a) {
                    return !blockRule.isHigherPriority(a) && allowlistPredicate.call(_this, blockRule)(a);
                });
                if (allowlistingRule) {
                    result_1.push(allowlistingRule);
                }
                else {
                    result_1.push(blockRule);
                }
            });
            return result_1.filter(function (item, pos) { return result_1.indexOf(item) === pos; });
        }
        return blockingRules;
    };
    /**
     * Returns an array of csp rules
     */
    MatchingResult.prototype.getCspRules = function () {
        if (!this.cspRules) {
            return [];
        }
        var blockingRules = [];
        var allowlistedRulesByDirective = new Map();
        for (var _i = 0, _a = this.cspRules; _i < _a.length; _i++) {
            var rule = _a[_i];
            if (rule.isAllowlist()) {
                if (!rule.getAdvancedModifierValue()) { // Global allowlist rule
                    return [rule];
                }
                MatchingResult.putWithPriority(rule, undefined, allowlistedRulesByDirective);
            }
            else {
                blockingRules.push(rule);
            }
        }
        var rulesByDirective = new Map();
        // Collect allowlist and blocking CSP rules in one array
        blockingRules.forEach(function (rule) {
            if (rule.getAdvancedModifierValue()) {
                var allowlistRule = allowlistedRulesByDirective.get(rule.getAdvancedModifierValue());
                MatchingResult.putWithPriority(rule, allowlistRule, rulesByDirective);
            }
        });
        return Array.from(rulesByDirective.values());
    };
    /**
     * Checks if a network rule is sub document rule.
     *
     * @param rule Rule to check.
     * @returns `true` if the rule is sub document rule.
     */
    MatchingResult.isSubDocumentRule = function (rule) {
        return (rule.getPermittedRequestTypes() & RequestType.SubDocument) === RequestType.SubDocument;
    };
    /**
     * Returns an array of permission policy rules
     */
    MatchingResult.prototype.getPermissionsPolicyRules = function () {
        if (!this.permissionsRules) {
            return [];
        }
        var allowlistRules = [];
        var blockingRules = [];
        var globalAllowlistRule = null;
        var globalSubDocAllowlistRule = null;
        for (var i = 0; i < this.permissionsRules.length; i += 1) {
            var rule = this.permissionsRules[i];
            if (rule.isAllowlist()) {
                // Global allowlist rule, where $permissions modifier doesn't have a value
                if (!rule.getAdvancedModifierValue()) {
                    if (MatchingResult.isSubDocumentRule(rule)) {
                        if (!globalSubDocAllowlistRule) {
                            // e.g. @@||example.com^$subdocument,permissions
                            globalSubDocAllowlistRule = rule;
                        }
                    }
                    else if (!globalAllowlistRule) {
                        // e.g. @@||example.com^$permissions
                        globalAllowlistRule = rule;
                    }
                }
                else {
                    allowlistRules.push(rule);
                }
            }
            else {
                blockingRules.push(rule);
            }
        }
        if (globalAllowlistRule) {
            return [globalAllowlistRule];
        }
        var result = new Set();
        blockingRules.forEach(function (rule) {
            if (MatchingResult.isSubDocumentRule(rule) && globalSubDocAllowlistRule) {
                result.add(globalSubDocAllowlistRule);
                return;
            }
            var allowlistRule = allowlistRules.find(function (a) { return !rule.isHigherPriority(a) && rule.getAdvancedModifierValue() === a.getAdvancedModifierValue()
                && MatchingResult.isSubDocumentRule(a) === MatchingResult.isSubDocumentRule(rule); });
            if (allowlistRule) {
                result.add(allowlistRule);
            }
            else {
                result.add(rule);
            }
        });
        return Array.from(result);
    };
    /**
     * Returns a redirect rule or null if redirect rules are empty.
     * $redirect-rule is only returned if there's a blocking rule also matching
     * this request.
     */
    MatchingResult.prototype.getRedirectRule = function () {
        if (!this.redirectRules) {
            return null;
        }
        // Apply allowlist $redirect rules.
        var result = MatchingResult.filterAdvancedModifierRules(this.redirectRules, function (rule) { return (function (x) { return x.getAdvancedModifierValue() === rule.getAdvancedModifierValue(); }); });
        // Filters only not allowlist rules.
        result = result.filter(function (r) { return !r.isAllowlist(); });
        // Splits $redirect and $redirect-rule into separate arrays.
        var conditionalRedirectRules = [];
        var allWeatherRedirectRules = [];
        result.forEach(function (rule) {
            var redirectModifier = rule.getAdvancedModifier();
            if (redirectModifier.isRedirectingOnlyBlocked) {
                conditionalRedirectRules.push(rule);
            }
            else {
                allWeatherRedirectRules.push(rule);
            }
        });
        if (allWeatherRedirectRules.length > 0) {
            return MatchingResult.getHighestPriorityRule(allWeatherRedirectRules);
        }
        if (conditionalRedirectRules.length > 0 && this.basicRule && !this.basicRule.isAllowlist()) {
            return MatchingResult.getHighestPriorityRule(conditionalRedirectRules);
        }
        return null;
    };
    /**
     * Returns an array of cookie rules
     */
    MatchingResult.prototype.getCookieRules = function () {
        var _this = this;
        if (!this.cookieRules) {
            return [];
        }
        var basic = this.getBasicResult();
        if ((basic === null || basic === void 0 ? void 0 : basic.isAllowlist()) && basic.isOptionEnabled(NetworkRuleOption.Urlblock)) {
            return [];
        }
        var allowlistPredicate = function (rule) { return (function (allowlistRule) {
            var allowlistRuleCookieModifier = allowlistRule.getAdvancedModifier();
            var ruleCookieModifier = rule.getAdvancedModifier();
            if (allowlistRule.getAdvancedModifierValue() === rule.getAdvancedModifierValue()) {
                return true;
            }
            // Matches by cookie name
            if (allowlistRuleCookieModifier.matches(ruleCookieModifier.getCookieName())) {
                return true;
            }
            return false;
        }); };
        var filtered = MatchingResult.filterAdvancedModifierRules(this.cookieRules, allowlistPredicate);
        // Cookie rule may also be disabled by a stealth rule with corresponding `1p-cookie` or `3p-cookie` value
        // If corresponding $stealth rule is found, such cookie rule does not get into resulting array
        filtered = filtered.filter(function (cookieRule) {
            if (cookieRule.getFilterListId() !== STEALTH_MODE_FILTER_ID) {
                return true;
            }
            if (cookieRule.isOptionEnabled(NetworkRuleOption.ThirdParty)) {
                return !_this.getStealthRule(StealthOptionName.ThirdPartyCookies);
            }
            return !_this.getStealthRule(StealthOptionName.FirstPartyCookies);
        });
        return filtered.concat((0,simple_regex_dfa6ed82.a)([], this.cookieRules.filter(function (r) { return r.isAllowlist(); }), true));
    };
    /**
     * Returns an array of removeparam rules
     */
    MatchingResult.prototype.getRemoveParamRules = function () {
        if (!this.removeParamRules) {
            return [];
        }
        return MatchingResult.filterAdvancedModifierRules(this.removeParamRules, 
        // eslint-disable-next-line arrow-body-style
        function (rule) { return (function (x) {
            return x.isHigherPriority(rule) && x.getAdvancedModifierValue() === rule.getAdvancedModifierValue();
        }); });
    };
    /**
     * Returns an array of removeheader rules
     */
    MatchingResult.prototype.getRemoveHeaderRules = function () {
        if (!this.removeHeaderRules) {
            return [];
        }
        if (this.basicRule
            && this.basicRule.isAllowlist()
            && this.basicRule.isOptionEnabled(NetworkRuleOption.Urlblock)) {
            return [];
        }
        return MatchingResult.filterAdvancedModifierRules(this.removeHeaderRules, function (rule) { return (function (x) { return x.getAdvancedModifierValue() === rule.getAdvancedModifierValue(); }); });
    };
    /**
     * Decides which rule should be put into the given map.
     * Compares priorities of the two given rules with the equal CSP directive and the rule that may already in the map.
     *
     * @param rule CSP rule (not null)
     * @param allowlistRule CSP allowlist rule (may be null)
     * @param map Rules mapped by csp directive
     */
    // eslint-disable-next-line max-len
    MatchingResult.putWithPriority = function (rule, allowlistRule, map) {
        var cspDirective = rule.getAdvancedModifierValue();
        var currentRule = cspDirective ? map.get(cspDirective) : null;
        var newRule = rule;
        if (currentRule && !rule.isHigherPriority(currentRule)) {
            newRule = currentRule;
        }
        if (allowlistRule && allowlistRule.isHigherPriority(newRule)) {
            newRule = allowlistRule;
        }
        map.set(cspDirective, newRule);
    };
    /**
     * Looks if there are any matching $badfilter rules and removes
     * matching bad filters from the array (see the $badfilter description for more info)
     *
     * @param rules to filter
     * @return filtered rules
     */
    MatchingResult.removeBadfilterRules = function (rules) {
        var badfilterRules = [];
        for (var _i = 0, rules_3 = rules; _i < rules_3.length; _i++) {
            var rule = rules_3[_i];
            if (rule.isOptionEnabled(NetworkRuleOption.Badfilter)) {
                badfilterRules.push(rule);
            }
        }
        if (badfilterRules.length > 0) {
            return rules.filter(function (rule) {
                if (rule.isOptionEnabled(NetworkRuleOption.Badfilter)) {
                    return false;
                }
                var isRuleNegated = badfilterRules.some(function (badfilter) { return badfilter.negatesBadfilter(rule); });
                return !isRuleNegated;
            });
        }
        return rules;
    };
    /**
     * Returns the highest priority rule from the given array.
     *
     * @param rules array of network rules
     * @returns hightest priority rule or null if the array is empty
     */
    MatchingResult.getHighestPriorityRule = function (rules) {
        if (rules.length === 0) {
            return null;
        }
        return rules.sort(function (a, b) { return (b.isHigherPriority(a) ? 1 : -1); })[0];
    };
    return MatchingResult;
}());

/**
 * Prefix tree implementation
 */
var TrieNode = /** @class */ (function () {
    /**
     * Creates an instance of a TrieNode with the specified char code.
     *
     * @param code
     */
    function TrieNode(code) {
        this.code = code;
    }
    /**
     * Attaches data to this TrieNode.
     *
     * @param data
     */
    TrieNode.prototype.attach = function (data) {
        if (!this.data) {
            this.data = [];
        }
        this.data.push(data);
    };
    /**
     * Adds the specified string to the Trie and attaches data to it.
     *
     * @param str string to add.
     * @param data data to attach to the leaf node.
     */
    TrieNode.prototype.add = function (str, data) {
        // eslint-disable-next-line @typescript-eslint/no-this-alias
        var root = this;
        for (var i = 0; i < str.length; i += 1) {
            var c = str.charCodeAt(i);
            var next = root.getChild(c);
            if (!next) {
                next = root.addChild(c);
            }
            root = next;
        }
        root.attach(data);
    };
    /**
     * Traverses this TrieNode and it's children using the specified search string.
     * This method collects all the data that's attached on the way and returns as
     * a result.
     *
     * @param str string to check.
     * @param start index in str where to start traversing from.
     */
    TrieNode.prototype.traverse = function (str, start) {
        var result = [];
        // eslint-disable-next-line @typescript-eslint/no-this-alias
        var current = this;
        for (var i = start; i < str.length; i += 1) {
            var c = str.charCodeAt(i);
            var next = current.getChild(c);
            if (!next) {
                break;
            }
            if (next.data) {
                result.push.apply(result, next.data);
            }
            current = next;
        }
        return result;
    };
    /**
     * Traverses this TrieNode and it's children using the specified search string and all substrings.
     *
     * @param str string to check
     * @param len max length to check
     */
    TrieNode.prototype.traverseAll = function (str, len) {
        var data = [];
        for (var i = 0; i <= len; i += 1) {
            var result = this.traverse(str, i);
            if (result) {
                data.push.apply(data, result);
            }
        }
        return data;
    };
    /**
     * Returns a child node with the specified character code or
     * undefined if not found.
     *
     * @param code character code
     * @returns child node or undefined.
     */
    TrieNode.prototype.getChild = function (code) {
        var children = this.children;
        if (!children) {
            return undefined;
        }
        if (children instanceof TrieNode) {
            if (children.code === code) {
                return children;
            }
            return undefined;
        }
        return children.get(code);
    };
    /**
     * Adds a new child node with the specified character code.
     *
     * @param code character code.
     * @returns the newly created TrieNode.
     */
    TrieNode.prototype.addChild = function (code) {
        var node = new TrieNode(code);
        if (!this.children) {
            this.children = node;
        }
        else if (this.children instanceof TrieNode) {
            var oldNode = this.children;
            this.children = new Map();
            this.children.set(oldNode.code, oldNode);
            this.children.set(code, node);
        }
        else {
            this.children.set(code, node);
        }
        return node;
    };
    return TrieNode;
}());

/**
 * Look up table with underlying prefix tree
 */
var TrieLookupTable = /** @class */ (function () {
    /**
     * Creates a new instance of the TrieLookupTable.
     *
     * @param storage rules storage. We store "rule indexes" in the lookup table which
     * can be used to retrieve the full rules from the storage.
     */
    function TrieLookupTable(storage) {
        /**
         * Count of rules added to this lookup table.
         */
        this.rulesCount = 0;
        this.ruleStorage = storage;
        this.trie = new TrieNode(0);
    }
    /**
     * Finds all matching rules from the shortcuts lookup table
     *
     * @param request to check
     * @return array of matching rules
     */
    TrieLookupTable.prototype.matchAll = function (request) {
        var rulesIndexes = this.traverse(request);
        return this.matchRules(request, rulesIndexes);
    };
    /**
     * Tries to add the rule to the lookup table.
     * returns true if it was added
     *
     * @param rule to add
     * @param storageIdx index
     * @return {boolean} true if the rule been added
     */
    TrieLookupTable.prototype.addRule = function (rule, storageIdx) {
        var shortcut = rule.getShortcut();
        if (!shortcut || TrieLookupTable.isAnyURLShortcut(shortcut)
            || shortcut.length < simple_regex_dfa6ed82.S.MIN_SHORTCUT_LENGTH) {
            return false;
        }
        this.trie.add(shortcut, storageIdx);
        this.rulesCount += 1;
        return true;
    };
    /**
     * @return total rules count
     */
    TrieLookupTable.prototype.getRulesCount = function () {
        return this.rulesCount;
    };
    /**
     * For specified request finds matching rules from rules indexes array
     *
     * @param request
     * @param rulesIndexes
     */
    TrieLookupTable.prototype.matchRules = function (request, rulesIndexes) {
        if (!rulesIndexes) {
            return [];
        }
        var result = [];
        for (var j = 0; j < rulesIndexes.length; j += 1) {
            var idx = rulesIndexes[j];
            var rule = this.ruleStorage.retrieveNetworkRule(idx);
            if (rule && rule.match(request, false)) {
                result.push(rule);
            }
        }
        return result;
    };
    /**
     * Traverses trie
     *
     * @param request
     */
    TrieLookupTable.prototype.traverse = function (request) {
        return this.trie.traverseAll(request.urlLowercase, request.urlLowercase.length);
    };
    /**
     * Checks if the rule potentially matches too many URLs.
     * We'd better use another type of lookup table for this kind of rules.
     *
     * @param shortcut to check
     * @return check result
     */
    TrieLookupTable.isAnyURLShortcut = function (shortcut) {
        // The numbers are basically ("PROTO://".length + 1)
        if (shortcut.length < 6 && shortcut.indexOf('ws:') === 0) {
            return true;
        }
        if (shortcut.length < 7 && shortcut.indexOf('|ws') === 0) {
            return true;
        }
        if (shortcut.length < 9 && shortcut.indexOf('http') === 0) {
            return true;
        }
        return !!(shortcut.length < 10 && shortcut.indexOf('|http') === 0);
    };
    return TrieLookupTable;
}());

/**
 * Domain lookup table. Key is the domain name hash.
 */
var DomainsLookupTable = /** @class */ (function () {
    /**
     * Creates a new instance
     *
     * @param storage rules storage. We store "rule indexes" in the lookup table which
     * can be used to retrieve the full rules from the storage.
     */
    function DomainsLookupTable(storage) {
        /**
         * Count of rules added to this lookup table.
         */
        this.rulesCount = 0;
        /**
         * Domain lookup table. Key is the domain name hash.
         */
        this.domainsLookupTable = new Map();
        this.ruleStorage = storage;
    }
    /**
     * addRule implements the ILookupTable interface for DomainsLookupTable.
     * @param rule
     * @param storageIdx
     */
    DomainsLookupTable.prototype.addRule = function (rule, storageIdx) {
        var _this = this;
        var permittedDomains = rule.getPermittedDomains();
        if (!permittedDomains || permittedDomains.length === 0) {
            return false;
        }
        if (permittedDomains.some(DomainModifier.isWildcardOrRegexDomain)) {
            return false;
        }
        permittedDomains.forEach(function (domain) {
            var hash = (0,simple_regex_dfa6ed82.f)(domain);
            // Add the rule to the lookup table
            var rulesIndexes = _this.domainsLookupTable.get(hash);
            if (!rulesIndexes) {
                rulesIndexes = [];
            }
            rulesIndexes.push(storageIdx);
            _this.domainsLookupTable.set(hash, rulesIndexes);
        });
        this.rulesCount += 1;
        return true;
    };
    /**
     * Implements the ILookupTable interface method.
     */
    DomainsLookupTable.prototype.getRulesCount = function () {
        return this.rulesCount;
    };
    /**
     * Implements the ILookupTable interface method.
     * @param request
     */
    DomainsLookupTable.prototype.matchAll = function (request) {
        var result = [];
        if (!request.sourceHostname) {
            return result;
        }
        var domains = request.subdomains;
        if (request.hostname !== request.sourceHostname) {
            domains.push.apply(domains, request.sourceSubdomains);
        }
        for (var i = 0; i < domains.length; i += 1) {
            var hash = (0,simple_regex_dfa6ed82.f)(domains[i]);
            var rulesIndexes = this.domainsLookupTable.get(hash);
            if (rulesIndexes) {
                for (var j = 0; j < rulesIndexes.length; j += 1) {
                    var rule = this.ruleStorage.retrieveNetworkRule(rulesIndexes[j]);
                    if (rule && rule.match(request)) {
                        result.push(rule);
                    }
                }
            }
        }
        return result;
    };
    return DomainsLookupTable;
}());

/**
 * Hostname lookup table.
 * For specific kind of rules like '||hostname^' and '||hostname/path' more simple algorithm with hashes is faster.
 */
var HostnameLookupTable = /** @class */ (function () {
    /**
     * Creates a new instance
     *
     * @param storage rules storage. We store "rule indexes" in the lookup table which
     * can be used to retrieve the full rules from the storage.
     */
    function HostnameLookupTable(storage) {
        /**
         * Count of rules added to this lookup table.
         */
        this.rulesCount = 0;
        /**
         * Domain lookup table. Key is the domain name hash.
         */
        this.hostnameLookupTable = new Map();
        this.ruleStorage = storage;
    }
    /**
     * addRule implements the ILookupTable interface for DomainsLookupTable.
     * @param rule
     * @param storageIdx
     */
    HostnameLookupTable.prototype.addRule = function (rule, storageIdx) {
        var pattern = rule.getPattern();
        var hostname = '';
        // Pattern: '||example.org^'
        if (pattern.startsWith(simple_regex_dfa6ed82.S.MASK_START_URL) && pattern.endsWith(simple_regex_dfa6ed82.S.MASK_SEPARATOR)) {
            hostname = pattern.slice(simple_regex_dfa6ed82.S.MASK_START_URL.length, pattern.length - simple_regex_dfa6ed82.S.MASK_SEPARATOR.length);
        }
        // Pattern: '||example.org/path'
        if (pattern.startsWith(simple_regex_dfa6ed82.S.MASK_START_URL) && pattern.indexOf(simple_regex_dfa6ed82.S.MASK_BACKSLASH) !== -1) {
            var end = pattern.indexOf(simple_regex_dfa6ed82.S.MASK_BACKSLASH);
            hostname = pattern.slice(simple_regex_dfa6ed82.S.MASK_START_URL.length, end);
        }
        if (!HostnameLookupTable.isValidHostname(hostname)) {
            return false;
        }
        var hash = (0,simple_regex_dfa6ed82.f)(hostname);
        var rulesIndexes = this.hostnameLookupTable.get(hash);
        if (!rulesIndexes) {
            rulesIndexes = new Array();
            this.hostnameLookupTable.set(hash, rulesIndexes);
        }
        rulesIndexes.push(storageIdx);
        this.rulesCount += 1;
        return true;
    };
    /**
     * Implements the ILookupTable interface method.
     */
    HostnameLookupTable.prototype.getRulesCount = function () {
        return this.rulesCount;
    };
    /**
     * Implements the ILookupTable interface method.
     * @param request
     */
    HostnameLookupTable.prototype.matchAll = function (request) {
        var result = [];
        var domains = request.subdomains;
        for (var i = 0; i < domains.length; i += 1) {
            var hash = (0,simple_regex_dfa6ed82.f)(domains[i]);
            var rulesIndexes = this.hostnameLookupTable.get(hash);
            if (rulesIndexes) {
                for (var j = 0; j < rulesIndexes.length; j += 1) {
                    var rule = this.ruleStorage.retrieveNetworkRule(rulesIndexes[j]);
                    if (rule && rule.match(request)) {
                        result.push(rule);
                    }
                }
            }
        }
        return result;
    };
    /**
     * Checks if this hostname string is valid
     *
     * @param hostname
     */
    HostnameLookupTable.isValidHostname = function (hostname) {
        if (!hostname) {
            return false;
        }
        if (hostname.indexOf(simple_regex_dfa6ed82.S.MASK_ANY_CHARACTER) !== -1) {
            return false;
        }
        if (hostname.indexOf('.') < 0 || hostname.endsWith('.')) {
            return false;
        }
        return true;
    };
    return HostnameLookupTable;
}());

/**
 * Sequence scan lookup table of rules for which we could not find a shortcut
 * and could not place it to the shortcuts lookup table.
 * In common case of rule there is always a way to just check a rule.match().
 */
var SeqScanLookupTable = /** @class */ (function () {
    function SeqScanLookupTable() {
        /**
         * Count of rules added to this lookup table.
         */
        this.rulesCount = 0;
        /**
         * Rules for which we could not find a shortcut and could not place it to the shortcuts lookup table.
         */
        this.rules = [];
    }
    /**
     * addRule implements the ILookupTable interface for SeqScanLookupTable.
     * @param rule
     */
    SeqScanLookupTable.prototype.addRule = function (rule) {
        if (!this.rules.includes(rule)) {
            this.rules.push(rule);
            this.rulesCount += 1;
            return true;
        }
        return false;
    };
    /**
     * Implements the ILookupTable interface method.
     */
    SeqScanLookupTable.prototype.getRulesCount = function () {
        return this.rulesCount;
    };
    /**
     * Implements the ILookupTable interface method.
     * @param request
     */
    SeqScanLookupTable.prototype.matchAll = function (request) {
        var result = [];
        for (var i = 0; i < this.rules.length; i += 1) {
            var r = this.rules[i];
            if (r.match(request)) {
                result.push(r);
            }
        }
        return result;
    };
    return SeqScanLookupTable;
}());

/**
 * NetworkEngine is the engine that supports quick search over network rules
 */
var NetworkEngine = /** @class */ (function () {
    /**
     * Builds an instance of the network engine
     *
     * @param storage an object for a rules storage.
     * @param skipStorageScan create an instance without storage scanning.
     */
    function NetworkEngine(storage, skipStorageScan) {
        if (skipStorageScan === void 0) { skipStorageScan = false; }
        this.ruleStorage = storage;
        this.rulesCount = 0;
        this.domainsLookupTable = new DomainsLookupTable(storage);
        this.hostnameLookupTable = new HostnameLookupTable(storage);
        this.shortcutsLookupTable = new TrieLookupTable(storage);
        this.seqScanLookupTable = new SeqScanLookupTable();
        if (skipStorageScan) {
            return;
        }
        var scanner = this.ruleStorage.createRuleStorageScanner(ScannerType.NetworkRules);
        while (scanner.scan()) {
            var indexedRule = scanner.getRule();
            if (indexedRule
                && indexedRule.rule instanceof NetworkRule) {
                this.addRule(indexedRule.rule, indexedRule.index);
            }
        }
    }
    /**
     * Match searches over all filtering rules loaded to the engine
     * It returns rule if a match was found alongside the matching rule
     *
     * @param request to check
     * @return rule matching request or null
     */
    NetworkEngine.prototype.match = function (request) {
        var networkRules = this.matchAll(request);
        if (networkRules.length === 0) {
            return null;
        }
        var result = new MatchingResult(networkRules, null);
        return result.getBasicResult();
    };
    /**
     * Finds all rules matching the specified request regardless of the rule types
     * It will find both allowlist and blacklist rules
     *
     * @param request to check
     * @return array of matching rules
     */
    NetworkEngine.prototype.matchAll = function (request) {
        // First check by shortcuts
        var result = this.hostnameLookupTable.matchAll(request);
        result.push.apply(result, (this.shortcutsLookupTable.matchAll(request)));
        result.push.apply(result, (this.domainsLookupTable.matchAll(request)));
        result.push.apply(result, (this.seqScanLookupTable.matchAll(request)));
        return result;
    };
    /**
     * Adds rule to the network engine
     *
     * @param rule
     * @param storageIdx
     */
    NetworkEngine.prototype.addRule = function (rule, storageIdx) {
        if (!this.hostnameLookupTable.addRule(rule, storageIdx)) {
            if (!this.shortcutsLookupTable.addRule(rule, storageIdx)) {
                if (!this.domainsLookupTable.addRule(rule, storageIdx)) {
                    this.seqScanLookupTable.addRule(rule, storageIdx);
                }
            }
        }
        this.rulesCount += 1;
    };
    return NetworkEngine;
}());

/**
 * Implements a host rule.
 *
 * HostRule is a structure for simple host-level rules (i.e. /etc/hosts syntax).
 * http://man7.org/linux/man-pages/man5/hosts.5.html
 * It also supports "just domain" syntax. In this case, the IP will be set to 0.0.0.0.
 *
 * Rules syntax looks like this:
 * ```
 * IP_address canonical_hostname [aliases...]
 * ```
 *
 * Examples:
 * * `192.168.1.13 bar.mydomain.org bar` -- ipv4
 * * `ff02::1 ip6-allnodes` -- ipv6
 * * `::1 localhost ip6-localhost ip6-loopback` -- ipv6 aliases
 * * `example.org` -- "just domain" syntax
 */
var HostRule = /** @class */ (function () {
    /**
     * Constructor
     *
     * Parses the rule and creates a new HostRule instance
     *
     * @param inputRule - original rule text.
     * @param filterListId - ID of the filter list this rule belongs to.
     *
     * @throws error if it fails to parse the rule.
     */
    function HostRule(node, filterListId, ruleIndex) {
        if (ruleIndex === void 0) { ruleIndex = RULE_INDEX_NONE; }
        this.hostnames = [];
        this.ip = '';
        this.invalid = false;
        this.ruleIndex = ruleIndex;
        this.filterListId = filterListId;
        this.ip = node.ip.value;
        if (node.hostnames.children.length === 0) {
            this.invalid = true;
            return;
        }
        this.hostnames = node.hostnames.children.map(function (hostname) { return hostname.value; });
    }
    /**
     * Match returns true if this rule can be used on the specified hostname.
     *
     * @param hostname - hostname to check
     */
    HostRule.prototype.match = function (hostname) {
        return this.hostnames.includes(hostname);
    };
    /**
     * Returns list id
     */
    HostRule.prototype.getFilterListId = function () {
        return this.filterListId;
    };
    /**
     * Returns rule index
     */
    HostRule.prototype.getIndex = function () {
        return this.ruleIndex;
    };
    /**
     * Returns ip address
     */
    HostRule.prototype.getIp = function () {
        return this.ip;
    };
    /**
     * Returns hostnames
     */
    HostRule.prototype.getHostnames = function () {
        return this.hostnames;
    };
    /**
     * Is invalid rule
     */
    HostRule.prototype.isInvalid = function () {
        return this.invalid;
    };
    return HostRule;
}());

/**
 * Request represents a web request with all it's necessary properties
 */
var Request = /** @class */ (function () {
    /**
     * Creates an instance of a Request
     *
     * @param url - request URL
     * @param sourceUrl - source URL
     * @param requestType - request type
     * @param method - request method
     *
     * @throws
     */
    function Request(url, sourceUrl, requestType, method) {
        /**
         * the request is for a given Hostname, and not for a URL, and we don't really know what protocol it is.
         * This can be true for DNS requests, or for HTTP CONNECT, or SNI matching.
         */
        this.isHostnameRequest = false;
        if (typeof url !== 'string' || !isHttpOrWsRequest(url)) {
            throw new TypeError("Invalid request url: ".concat(url));
        }
        this.url = url;
        this.requestType = requestType;
        this.method = method;
        this.urlLowercase = Request.compactUrl(url).toLowerCase();
        this.sourceUrl = Request.compactUrl(sourceUrl);
        var tldResult = (0,es6/* parse */.Qc)(url);
        this.hostname = tldResult.hostname;
        this.domain = tldResult.domain;
        this.subdomains = Request.getSubdomains(tldResult);
        var sourceTldResult;
        if (sourceUrl) {
            sourceTldResult = (0,es6/* parse */.Qc)(sourceUrl);
            this.sourceHostname = sourceTldResult.hostname;
            this.sourceDomain = sourceTldResult.domain;
            this.sourceSubdomains = Request.getSubdomains(sourceTldResult);
        }
        else {
            this.sourceHostname = null;
            this.sourceDomain = null;
            this.sourceSubdomains = [];
        }
        if (this.sourceDomain) {
            this.thirdParty = this.domain !== this.sourceDomain;
        }
        else if (sourceTldResult && sourceTldResult.isIp) {
            this.thirdParty = this.hostname !== this.sourceHostname;
        }
        else {
            this.thirdParty = null;
        }
    }
    /**
     * We cut the url in performance purposes
     * @param url
     */
    Request.compactUrl = function (url) {
        var compacted = url;
        if (compacted && compacted.length > Request.MAX_URL_MATCH_LENGTH) {
            compacted = compacted.substring(0, Request.MAX_URL_MATCH_LENGTH);
        }
        return compacted;
    };
    /**
    * Splits subdomains and returns all subdomains (including the hostname itself)
    *
    * @param tldResult
    * @returns array of subdomains
    */
    Request.getSubdomains = function (tldResult) {
        var domain = tldResult.domain, hostname = tldResult.hostname, subdomain = tldResult.subdomain, publicSuffix = tldResult.publicSuffix;
        var subdomainsResult = [];
        if (!domain) {
            if (hostname) {
                subdomainsResult.push(hostname);
                return subdomainsResult;
            }
            return [];
        }
        if (publicSuffix) {
            subdomainsResult.push(publicSuffix);
            // Extract subdomains from complex suffixes
            // https://github.com/AdguardTeam/AdguardBrowserExtension/issues/2037
            // https://github.com/AdguardTeam/tsurlfilter/issues/57
            for (var i = 0; i < publicSuffix.length; i += 1) {
                if (publicSuffix[i] === '.') {
                    subdomainsResult.push(publicSuffix.slice(i + 1));
                }
            }
        }
        subdomainsResult.push(domain);
        if (!subdomain) {
            return subdomainsResult;
        }
        var parts = subdomain.split('.');
        var incrementDomain = domain;
        for (var i = parts.length - 1; i >= 0; i -= 1) {
            incrementDomain = "".concat(parts[i], ".").concat(incrementDomain);
            subdomainsResult.push(incrementDomain);
        }
        return subdomainsResult;
    };
    /**
     * Max url length for matching
     * Some urls are really long and slow down matching, so we cut them to this length.
     */
    Request.MAX_URL_MATCH_LENGTH = 2000;
    return Request;
}());

/**
 * DnsResult contains a network rule and host rules matching request
 */
var DnsResult = /** @class */ (function () {
    function DnsResult() {
        /**
         * BasicRule - a network rule matching the request.
         */
        this.basicRule = null;
        /**
         * Host rules
         */
        this.hostRules = [];
    }
    return DnsResult;
}());

/**
 * DNSEngine combines host rules and network rules and is supposed to quickly find
 * matching rules for hostnames.
 * First, it looks over network rules and returns first rule found.
 * Then, if nothing found, it looks up the host rules.
 */
var DnsEngine = /** @class */ (function () {
    /**
     * Builds an instance of dns engine
     *
     * @param storage
     */
    function DnsEngine(storage) {
        this.ruleStorage = storage;
        this.rulesCount = 0;
        this.lookupTable = new Map();
        this.networkEngine = new NetworkEngine(storage, true);
        var scanner = this.ruleStorage.createRuleStorageScanner(ScannerType.HostRules);
        while (scanner.scan()) {
            var indexedRule = scanner.getRule();
            if (indexedRule) {
                if (indexedRule.rule instanceof HostRule) {
                    this.addRule(indexedRule.rule, indexedRule.index);
                }
                else if (indexedRule.rule instanceof NetworkRule
                    && indexedRule.rule.isHostLevelNetworkRule()) {
                    this.networkEngine.addRule(indexedRule.rule, indexedRule.index);
                }
            }
        }
    }
    /**
     * Match searches over all filtering and host rules loaded to the engine
     *
     * @param hostname to check
     * @return dns result object
     */
    DnsEngine.prototype.match = function (hostname) {
        var result = new DnsResult();
        if (!hostname) {
            return result;
        }
        var url = "http://".concat(hostname, "/");
        var request = new Request(url, url, RequestType.Document);
        request.isHostnameRequest = true;
        var networkRule = this.networkEngine.match(request);
        if (networkRule) {
            // Network rules always have higher priority
            result.basicRule = networkRule;
            return result;
        }
        var hash = (0,simple_regex_dfa6ed82.f)(hostname);
        var rulesIndexes = this.lookupTable.get(hash);
        if (rulesIndexes) {
            for (var j = 0; j < rulesIndexes.length; j += 1) {
                var rule = this.ruleStorage.retrieveHostRule(rulesIndexes[j]);
                if (rule && rule.match(hostname)) {
                    result.hostRules.push(rule);
                }
            }
        }
        return result;
    };
    /**
     * Adds rule to engine
     *
     * @param rule
     * @param storageIdx
     */
    DnsEngine.prototype.addRule = function (rule, storageIdx) {
        var _this = this;
        rule.getHostnames().forEach(function (hostname) {
            var hash = (0,simple_regex_dfa6ed82.f)(hostname);
            // Add the rule to the lookup table
            var rulesIndexes = _this.lookupTable.get(hash);
            if (!rulesIndexes) {
                rulesIndexes = [];
            }
            rulesIndexes.push(storageIdx);
            _this.lookupTable.set(hash, rulesIndexes);
        });
        this.rulesCount += 1;
    };
    return DnsEngine;
}());

var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof __webpack_require__.g !== 'undefined' ? __webpack_require__.g : typeof self !== 'undefined' ? self : {};

var lru = {exports: {}};

(function (module, exports) {
	!function(g,c){c(exports);}(commonjsGlobal,function(g){const c=Symbol("newer"),e=Symbol("older");class n{constructor(a,b){typeof a!=="number"&&(b=a,a=0),this.size=0,this.limit=a,this.oldest=this.newest=void 0,this._keymap=new Map(),b&&(this.assign(b),a<1&&(this.limit=this.size));}_markEntryAsUsed(a){if(a===this.newest)return;a[c]&&(a===this.oldest&&(this.oldest=a[c]),a[c][e]=a[e]),a[e]&&(a[e][c]=a[c]),a[c]=void 0,a[e]=this.newest,this.newest&&(this.newest[c]=a),this.newest=a;}assign(a){let b,d=this.limit||Number.MAX_VALUE;this._keymap.clear();let m=a[Symbol.iterator]();for(let h=m.next();!h.done;h=m.next()){let f=new l(h.value[0],h.value[1]);this._keymap.set(f.key,f),b?(b[c]=f,f[e]=b):this.oldest=f,b=f;if(d--==0)throw new Error("overflow")}this.newest=b,this.size=this._keymap.size;}get(a){var b=this._keymap.get(a);return b?(this._markEntryAsUsed(b),b.value):void 0}set(a,b){var d=this._keymap.get(a);return d?(d.value=b,this._markEntryAsUsed(d),this):(this._keymap.set(a,d=new l(a,b)),this.newest?(this.newest[c]=d,d[e]=this.newest):this.oldest=d,this.newest=d,++this.size,this.size>this.limit&&this.shift(),this)}shift(){var a=this.oldest;if(a)return this.oldest[c]?(this.oldest=this.oldest[c],this.oldest[e]=void 0):(this.oldest=void 0,this.newest=void 0),a[c]=a[e]=void 0,this._keymap.delete(a.key),--this.size,[a.key,a.value]}find(a){let b=this._keymap.get(a);return b?b.value:void 0}has(a){return this._keymap.has(a)}delete(a){var b=this._keymap.get(a);return b?(this._keymap.delete(b.key),b[c]&&b[e]?(b[e][c]=b[c],b[c][e]=b[e]):b[c]?(b[c][e]=void 0,this.oldest=b[c]):b[e]?(b[e][c]=void 0,this.newest=b[e]):this.oldest=this.newest=void 0,this.size--,b.value):void 0}clear(){this.oldest=this.newest=void 0,this.size=0,this._keymap.clear();}keys(){return new j(this.oldest)}values(){return new k(this.oldest)}entries(){return this}[Symbol.iterator](){return new i(this.oldest)}forEach(a,b){typeof b!=="object"&&(b=this);let d=this.oldest;for(;d;)a.call(b,d.value,d.key,this),d=d[c];}toJSON(){for(var a=new Array(this.size),b=0,d=this.oldest;d;)a[b++]={key:d.key,value:d.value},d=d[c];return a}toString(){for(var a="",b=this.oldest;b;)a+=String(b.key)+":"+b.value,b=b[c],b&&(a+=" < ");return a}}g.LRUMap=n;function l(a,b){this.key=a,this.value=b,this[c]=void 0,this[e]=void 0;}function i(a){this.entry=a;}i.prototype[Symbol.iterator]=function(){return this},i.prototype.next=function(){let a=this.entry;return a?(this.entry=a[c],{done:!1,value:[a.key,a.value]}):{done:!0,value:void 0}};function j(a){this.entry=a;}j.prototype[Symbol.iterator]=function(){return this},j.prototype.next=function(){let a=this.entry;return a?(this.entry=a[c],{done:!1,value:a.key}):{done:!0,value:void 0}};function k(a){this.entry=a;}k.prototype[Symbol.iterator]=function(){return this},k.prototype.next=function(){let a=this.entry;return a?(this.entry=a[c],{done:!1,value:a.value}):{done:!0,value:void 0}};});
	
} (lru, lru.exports));

/**
 * Engine represents the filtering engine with all the loaded rules
 */
var Engine = /** @class */ (function () {
    /**
     * Creates an instance of an Engine
     * Parses the filtering rules and creates a filtering engine of them
     *
     * @param ruleStorage storage
     * @param skipStorageScan create an instance without storage scanning
     * @throws
     */
    function Engine(ruleStorage, skipStorageScan) {
        if (skipStorageScan === void 0) { skipStorageScan = false; }
        this.ruleStorage = ruleStorage;
        this.networkEngine = new NetworkEngine(ruleStorage, skipStorageScan);
        this.cosmeticEngine = new CosmeticEngine(ruleStorage, skipStorageScan);
        this.resultCache = new lru.exports.LRUMap(Engine.REQUEST_CACHE_SIZE);
    }
    /**
     * Loads rules to engine
     */
    Engine.prototype.loadRules = function () {
        var scanner = this.ruleStorage.createRuleStorageScanner(ScannerType.NetworkRules | ScannerType.CosmeticRules);
        while (scanner.scan()) {
            this.addRule(scanner.getRule());
        }
    };
    /**
     * Async loads rules to engine
     *
     * @param chunkSize size of rules chunk to load at a time
     */
    Engine.prototype.loadRulesAsync = function (chunkSize) {
        return (0,simple_regex_dfa6ed82.g)(this, void 0, void 0, function () {
            var scanner, counter;
            return (0,simple_regex_dfa6ed82.j)(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        scanner = this.ruleStorage.createRuleStorageScanner(ScannerType.NetworkRules | ScannerType.CosmeticRules);
                        counter = 0;
                        _a.label = 1;
                    case 1:
                        if (!scanner.scan()) return [3 /*break*/, 4];
                        counter += 1;
                        if (!(counter >= chunkSize)) return [3 /*break*/, 3];
                        counter = 0;
                        /**
                         * In some cases UI thread becomes blocked while adding rules to engine,
                         * that't why we create filter rules using chunks of the specified length
                         * Rules creation is rather slow operation so we should
                         * use setTimeout calls to give UI thread some time.
                         */
                        return [4 /*yield*/, new Promise(function (resolve) { return setTimeout(resolve, 1); })];
                    case 2:
                        /**
                         * In some cases UI thread becomes blocked while adding rules to engine,
                         * that't why we create filter rules using chunks of the specified length
                         * Rules creation is rather slow operation so we should
                         * use setTimeout calls to give UI thread some time.
                         */
                        _a.sent();
                        _a.label = 3;
                    case 3:
                        this.addRule(scanner.getRule());
                        return [3 /*break*/, 1];
                    case 4: return [2 /*return*/];
                }
            });
        });
    };
    /**
     * Matches the specified request against the filtering engine and returns the matching result.
     *
     * @param request - request to check
     * @param frameRule - source document rule or null
     * @return matching result
     */
    Engine.prototype.matchRequest = function (request, frameRule) {
        if (frameRule === void 0) { frameRule = null; }
        var cacheKey = "".concat(request.url, "#").concat(request.sourceHostname, "#").concat(request.requestType);
        if (request.method) {
            cacheKey += "#".concat(request.method);
        }
        /**
         * Add frame url text to the key to avoid caching,
         * because allowlist rules are not stored in the engine
         * AG-12694
         */
        if (frameRule) {
            cacheKey += "#".concat(frameRule.getIndex());
        }
        var res = this.resultCache.get(cacheKey);
        if (res) {
            return res;
        }
        var networkRules = this.networkEngine.matchAll(request);
        var result = new MatchingResult(networkRules, frameRule);
        this.resultCache.set(cacheKey, result);
        return result;
    };
    /**
     * Matches current frame and returns document-level allowlist rule if found.
     *
     * @param frameUrl
     */
    Engine.prototype.matchFrame = function (frameUrl) {
        var sourceRequest = new Request(frameUrl, '', RequestType.Document);
        var sourceRules = this.networkEngine.matchAll(sourceRequest);
        sourceRules = MatchingResult.removeBadfilterRules(sourceRules);
        var result = null;
        sourceRules.forEach(function (r) {
            if (r.isDocumentLevelAllowlistRule()) {
                if (!result || r.isHigherPriority(result)) {
                    result = r;
                }
            }
        });
        return result;
    };
    /**
     * Gets cosmetic result for the specified hostname and cosmetic options
     *
     * @param request host to check
     * @param option mask of enabled cosmetic types
     * @return cosmetic result
     */
    Engine.prototype.getCosmeticResult = function (request, option) {
        return this.cosmeticEngine.match(request, option);
    };
    /**
     * Gets rules count
     */
    Engine.prototype.getRulesCount = function () {
        return this.networkEngine.rulesCount + this.cosmeticEngine.rulesCount;
    };
    /**
     * Adds rules to engines
     *
     * @param indexedRule
     */
    Engine.prototype.addRule = function (indexedRule) {
        if (indexedRule) {
            if (indexedRule.rule instanceof NetworkRule) {
                this.networkEngine.addRule(indexedRule.rule, indexedRule.index);
            }
            else if (indexedRule.rule instanceof CosmeticRule) {
                this.cosmeticEngine.addRule(indexedRule.rule, indexedRule.index);
            }
        }
    };
    /**
     * Request's cache size
     * Used as both source rules and others limit.
     * The value is based on benchmark runs.
     */
    Engine.REQUEST_CACHE_SIZE = 500;
    return Engine;
}());

/**
 * Source map.
 *
 * @note Since serialized rule nodes are not store original rule text, we need this source map between the
 * serialized filter list and the raw filter list.
 */
var filterListSourceMapValidator = lib.z.record(
/**
 * Rule start index in the converted list's byte buffer.
 */
lib.z.string(), 
/**
 * Rule start index in the raw converted list.
 */
lib.z.number());

/**
 * Helper function to get the rule source text from the source string by its line start index.
 *
 * @param lineStartIndex Rule start index.
 * @param source Raw filter list source.
 * @returns Rule string or null if the rule couldn't be found.
 */
var getRuleSourceText = function (lineStartIndex, source) {
    // note: checking for LF is enough, because we transform source before storing it, and it's always LF
    var lineEndIndex = findNextLineBreakIndex(source, lineStartIndex)[0];
    // If the line end index is not found, we assume that the rule is the last line in the source.
    if (lineEndIndex === -1) {
        lineEndIndex = source.length;
    }
    // If the rule start index is equal to or greater than the rule end index, we return null,
    // and the rule is considered not found.
    if (lineStartIndex >= lineEndIndex) {
        return null;
    }
    var ruleSourceText = source.slice(lineStartIndex, lineEndIndex);
    // WARNING!
    // Potential memory leak mitigation for substring operation due to V8 optimizations:
    // When extracting a substring with rule.slice(), there's a concern in some JS environments
    // that the resulting substring might retain a hidden reference to the entire original 'rule' string.
    // This could prevent the garbage collector (GC) from freeing the memory allocated for filter rules.
    // This hidden reference occurs because the substring might not create a new string but rather
    // a view into the original, keeping it in memory longer than necessary.
    // And we receive a memory leak here because we store parsed tags from first N lines of the filter rules
    // which have references to the original large string with filter rules.
    // To ensure that the original large string can be garbage collected, and only the necessary
    // substring is retained, we explicitly force a copy of the substring via split and join,
    // thereby breaking the direct reference to the original string and allowing the GC to free the memory
    // for filter rules when they are no longer in use.
    return ruleSourceText.split('').join('');
};
/**
 * Helper function to get the rule source index (line start index in the source) from the source map by the rule index.
 *
 * @param ruleIdx Rule index.
 * @param sourceMap Source map.
 * @returns Rule source index or RULE_INDEX_NONE (-1).
 * @note Similar to `Array.prototype.indexOf`, we return -1 if the rule index is not found.
 */
var getRuleSourceIndex = function (ruleIdx, sourceMap) {
    var _a;
    return (_a = sourceMap[ruleIdx]) !== null && _a !== void 0 ? _a : RULE_INDEX_NONE;
};

/**
 * BufferReader is a class responsible for reading content from serialized rules.
 */
var BufferReader = /** @class */ (function () {
    /**
     * Constructor of a BufferReader.
     *
     * @param buffer - Uint8Array that contains a UTF-8 encoded string.
     */
    function BufferReader(buffer) {
        /**
         * Current position of the reader.
         */
        this.currentIndex = 0;
        this.buffer = buffer;
        this.currentIndex = this.buffer.currentOffset;
    }
    /**
     * Reads the next line in the buffer
     *
     * @return text or null on end
     */
    BufferReader.prototype.readNext = function () {
        // If the next byte is 0, it means that there's nothing to read.
        if (this.buffer.peekUint8() === 0) {
            return null;
        }
        var ruleNode;
        agtree/* RuleParser.deserialize */.sR.deserialize(this.buffer, ruleNode = {});
        this.currentIndex = this.buffer.currentOffset;
        if (ruleNode.category) {
            return ruleNode;
        }
        return null;
    };
    /**
     * Returns the current position of this reader or -1 if there's nothing to
     * read.
     *
     * @returns - The current position or -1 if there's nothing to read.
     */
    BufferReader.prototype.getCurrentPos = function () {
        return this.currentIndex;
    };
    /** @inheritdoc */
    BufferReader.prototype.getDataLength = function () {
        return this.buffer.capacity;
    };
    return BufferReader;
}());

/**
 * List identifier max value.
 * We use "number" type for storage indexes, so we have some limits for list
 * identifiers.
 * We use line number for rule index, so if we save 11 ranks for rules, then we
 * have 6 ranks left for list ids. Check RuleStorageScanner class for more info.
 */
var LIST_ID_MAX_VALUE = Math.pow(10, 6);

/**
 * Helper function to create an allowlist rule node for a given domain.
 *
 * @param domain Domain to create an allowlist rule for.
 * @returns Allowlist rule node or null.
 */
var createAllowlistRuleNode = function (domain) {
    var domainToUse = domain.startsWith('www.') ? domain.substring(4) : domain;
    if (!domainToUse) {
        return null;
    }
    var pattern;
    // Special case: Wildcard TLD + N domain
    if (domainToUse.startsWith('*.')) {
        pattern = "".concat(simple_regex_dfa6ed82.S.MASK_START_URL).concat(domainToUse.slice(2));
    }
    else {
        // In other cases we use regexp to match domain and it`s 'www' subdomain strictly.
        var regexp = '';
        // transform allowlist domain special characters
        for (var i = 0; i < domainToUse.length; i += 1) {
            var char = domainToUse[i];
            // transform wildcard to regexp equivalent
            if (char === '*') {
                regexp += '.*';
                // escape domain separator
            }
            else if (char === '.') {
                regexp += String.raw(templateObject_1 || (templateObject_1 = (0,simple_regex_dfa6ed82.l)(["."], ["\\."])));
            }
            else {
                regexp += char;
            }
        }
        pattern = String.raw(templateObject_2 || (templateObject_2 = (0,simple_regex_dfa6ed82.l)(["///(www.)?", "/"], ["///(www\\.)?", "/"])), regexp);
    }
    var node = {
        category: agtree/* RuleCategory.Network */.WV.Network,
        type: agtree/* NetworkRuleType.NetworkRule */.bS.NetworkRule,
        syntax: agtree/* AdblockSyntax.Common */.qJ.Common,
        exception: true,
        pattern: {
            type: 'Value',
            value: pattern,
        },
        modifiers: {
            type: 'ModifierList',
            children: [
                {
                    type: 'Modifier',
                    name: {
                        type: 'Value',
                        value: 'document',
                    },
                },
                {
                    type: 'Modifier',
                    name: {
                        type: 'Value',
                        value: 'important',
                    },
                },
            ],
        },
    };
    return node;
};
var templateObject_1, templateObject_2;

/**
 * Rule builder class
 */
var RuleFactory = /** @class */ (function () {
    function RuleFactory() {
    }
    /**
     * Creates rule of suitable class from text string
     * It returns null if the line is empty or if it is a comment
     *
     * TODO: Pack `ignore*` parameters and `silent` into one object with flags.
     *
     * @param inputRule rule string
     * @param filterListId list id
     * @param ruleIndex line start index in the source filter list; it will be used to find the original rule text
     * in the filtering log when a rule is applied. Default value is {@link RULE_INDEX_NONE} which means that
     * the rule does not have source index
     * @param ignoreNetwork do not create network rules
     * @param ignoreCosmetic do not create cosmetic rules
     * @param ignoreHost do not create host rules
     * @param silent Log the error for `true`, otherwise throw an exception on
     * a rule creation
     *
     * @throws Error when `silent` flag is passed as false on rule creation error.
     *
     * @return IRule object or null
     */
    RuleFactory.createRule = function (node, filterListId, ruleIndex, ignoreNetwork, ignoreCosmetic, ignoreHost, silent) {
        if (ruleIndex === void 0) { ruleIndex = RULE_INDEX_NONE; }
        if (ignoreNetwork === void 0) { ignoreNetwork = false; }
        if (ignoreCosmetic === void 0) { ignoreCosmetic = false; }
        if (ignoreHost === void 0) { ignoreHost = true; }
        if (silent === void 0) { silent = true; }
        try {
            switch (node.category) {
                case agtree/* RuleCategory.Invalid */.WV.Invalid:
                case agtree/* RuleCategory.Empty */.WV.Empty:
                case agtree/* RuleCategory.Comment */.WV.Comment:
                    return null;
                case agtree/* RuleCategory.Cosmetic */.WV.Cosmetic:
                    if (ignoreCosmetic) {
                        return null;
                    }
                    return new CosmeticRule(node, filterListId, ruleIndex);
                case agtree/* RuleCategory.Network */.WV.Network:
                    if (node.type === agtree/* NetworkRuleType.HostRule */.bS.HostRule) {
                        if (ignoreHost) {
                            return null;
                        }
                        return new HostRule(node, filterListId, ruleIndex);
                    }
                    if (ignoreNetwork) {
                        return null;
                    }
                    return new NetworkRule(node, filterListId, ruleIndex);
                default:
                    // should not happen in normal operation
                    return null;
            }
        }
        catch (e) {
            var ruleText = agtree/* RuleParser.generate */.sR.generate(node);
            var msg = "\"".concat(getErrorMessage(e), "\" in the rule: \"").concat(ruleText, "\"");
            if (silent) {
                logger.info("Error: ".concat(msg));
            }
            else {
                throw new Error(msg);
            }
        }
        return null;
    };
    /**
     * Creates allowlist rule for domain.
     *
     * @param domain Domain name.
     * @returns Allowlist rule or null.
     */
    RuleFactory.createAllowlistRule = function (domain, filterListId, ruleIndex) {
        if (ruleIndex === void 0) { ruleIndex = RULE_INDEX_NONE; }
        var node = createAllowlistRuleNode(domain);
        if (!node) {
            return null;
        }
        return new NetworkRule(node, filterListId, ruleIndex);
    };
    return RuleFactory;
}());

/**
 * Rule scanner provides the functionality for reading rules from a filter list.
 */
// TODO: Change string filter list to byte buffer.
var RuleScanner = /** @class */ (function () {
    /**
     * Constructor of a RuleScanner object.
     *
     * @param reader - Source of the filtering rules
     * @param listId - Filter list ID
     * @param configuration - Scanner configuration object
     */
    function RuleScanner(reader, listId, configuration) {
        /**
         * Current rule.
         */
        this.currentRule = null;
        /**
         * Index of the beginning of the current rule (basically, a line number).
         */
        this.currentRuleIndex = 0;
        this.reader = reader;
        this.listId = listId;
        this.ignoreCosmetic = !!configuration.ignoreCosmetic
            || ((configuration.scannerType & ScannerType.CosmeticRules) !== ScannerType.CosmeticRules);
        this.ignoreNetwork = (configuration.scannerType & ScannerType.NetworkRules) !== ScannerType.NetworkRules;
        this.ignoreHost = (configuration.scannerType & ScannerType.HostRules) !== ScannerType.HostRules;
        this.ignoreJS = !!configuration.ignoreJS;
        this.ignoreUnsafe = !!configuration.ignoreUnsafe;
    }
    /**
     * Scan advances the RuleScanner to the next rule, which will then be
     * available through the getRule() method.
     *
     * @return - False when the scan stops, either by reaching the end of the
     * input or an error. If there's a rule available, returns true.
     */
    RuleScanner.prototype.scan = function () {
        var lineIndex = this.reader.getCurrentPos();
        var line = this.readNext();
        while (line) {
            if (!this.isIgnored(line)) {
                var rule = RuleFactory.createRule(line, this.listId, lineIndex, this.ignoreNetwork, this.ignoreCosmetic, this.ignoreHost);
                this.currentRule = rule;
                this.currentRuleIndex = lineIndex;
                return true;
            }
            lineIndex = this.reader.getCurrentPos();
            line = this.readNext();
        }
        return false;
    };
    /**
     * @return - The most recent rule generated by a call to scan(), and the
     * index of this rule's text.
     */
    RuleScanner.prototype.getRule = function () {
        if (this.currentRule) {
            return new IndexedRule(this.currentRule, this.currentRuleIndex);
        }
        return null;
    };
    /**
     * Get filter list id.
     *
     * @returns List id.
     */
    RuleScanner.prototype.getListId = function () {
        return this.listId;
    };
    /**
     * Get the length of the data read by the scanner.
     *
     * @returns Data length.
     */
    RuleScanner.prototype.getDataLength = function () {
        return this.reader.getDataLength();
    };
    /**
     * Reads the next line and returns it.
     *
     * @return - Next line string or null.
     */
    RuleScanner.prototype.readNext = function () {
        return this.reader.readNext();
    };
    /**
     * Checks if the rule should be ignored by this scanner.
     *
     * @param rule - Rule to check.
     * @return - True if the rule should be ignored.
     */
    RuleScanner.prototype.isIgnored = function (rule) {
        var _a, _b;
        if (!this.ignoreCosmetic && !this.ignoreJS && !this.ignoreUnsafe) {
            return false;
        }
        if (rule.category === agtree/* RuleCategory.Cosmetic */.WV.Cosmetic) {
            if (this.ignoreCosmetic) {
                return true;
            }
            // Ignore JS type rules.
            // TODO: in the future we may allow CSS rules and Scriptlets (except
            // for "trusted" scriptlets).
            if (this.ignoreJS
                && (rule.type === agtree/* CosmeticRuleType.JsInjectionRule */.Az.JsInjectionRule
                    || rule.type === agtree/* CosmeticRuleType.ScriptletInjectionRule */.Az.ScriptletInjectionRule)) {
                return true;
            }
        }
        if (this.ignoreUnsafe) {
            if (rule.category === agtree/* RuleCategory.Network */.WV.Network && rule.type === agtree/* NetworkRuleType.NetworkRule */.bS.NetworkRule) {
                if ((_b = (_a = rule.modifiers) === null || _a === void 0 ? void 0 : _a.children) === null || _b === void 0 ? void 0 : _b.some(function (modifier) { return NetworkRule.ADVANCED_OPTIONS.has(modifier.name.value); })) {
                    return true;
                }
            }
        }
        return false;
    };
    return RuleScanner;
}());

/**
 * BufferRuleList represents a string-based rule list. It keeps the original
 * rule list as a byte array with UTF-8 encoded characters. This approach
 * allows saving on the memory used by tsurlfilter compared to StringRuleList.
 */
var BufferRuleList = /** @class */ (function () {
    /**
     * Constructor of BufferRuleList.
     *
     * @param listId - List identifier.
     * @param inputRules - String with filtering rules (one per line).
     * @param ignoreCosmetic - (Optional) True to ignore cosmetic rules.
     * @param ignoreJS - (Optional) True to ignore JS rules.
     * @param ignoreUnsafe - (Optional) True to ignore unsafe rules.
     * @param sourceMap - (Optional) Source map for the filter list.
     */
    function BufferRuleList(listId, inputRules, ignoreCosmetic, ignoreJS, ignoreUnsafe, sourceMap) {
        if (listId >= LIST_ID_MAX_VALUE) {
            throw new Error("Invalid list identifier, it must be less than ".concat(LIST_ID_MAX_VALUE));
        }
        this.id = listId;
        this.rulesBuffer = new agtree/* InputByteBuffer */.tL(inputRules);
        this.ignoreCosmetic = !!ignoreCosmetic;
        this.ignoreJS = !!ignoreJS;
        this.ignoreUnsafe = !!ignoreUnsafe;
        this.sourceMap = sourceMap !== null && sourceMap !== void 0 ? sourceMap : {};
    }
    /**
     * Close does nothing as here's nothing to close in the BufferRuleList.
     */
    // eslint-disable-next-line class-methods-use-this
    BufferRuleList.prototype.close = function () {
        // Empty
    };
    /**
     * @return - The rule list identifier
     */
    BufferRuleList.prototype.getId = function () {
        return this.id;
    };
    /**
     * Creates a new rules scanner that reads the list contents.
     *
     * @return - Scanner object.
     */
    BufferRuleList.prototype.newScanner = function (scannerType) {
        var reader = new BufferReader(this.rulesBuffer.createCopyWithOffset(0));
        return new RuleScanner(reader, this.id, {
            scannerType: scannerType,
            ignoreCosmetic: this.ignoreCosmetic,
            ignoreJS: this.ignoreJS,
            ignoreUnsafe: this.ignoreUnsafe,
        });
    };
    /**
     * Retrieves a rule node by its index.
     *
     * If there's no rule by that index or the rule is invalid, it will return
     * null.
     *
     * @param ruleIdx Rule index.
     * @return Rule node or `null`.
     */
    BufferRuleList.prototype.retrieveRuleNode = function (ruleIdx) {
        try {
            var ruleNode = {};
            var copy = this.rulesBuffer.createCopyWithOffset(ruleIdx);
            agtree/* RuleParser.deserialize */.sR.deserialize(copy, ruleNode);
            return ruleNode;
        }
        catch (e) {
            // fall through
        }
        return null;
    };
    /**
     * @inheritdoc
     */
    BufferRuleList.prototype.retrieveRuleSourceIndex = function (ruleIdx) {
        return getRuleSourceIndex(ruleIdx, this.sourceMap);
    };
    /**
     * Text decoder that is used to read strings from the internal buffer of
     * UTF-8 encoded characters.
     */
    BufferRuleList.decoder = new TextDecoder('utf-8');
    return BufferRuleList;
}());

/**
 * AGTree parser options for the preprocessor.
 */
var PREPROCESSOR_AGTREE_OPTIONS = (0,simple_regex_dfa6ed82._)((0,simple_regex_dfa6ed82._)({}, agtree/* defaultParserOptions */.Xm), { includeRaws: false, isLocIncluded: false, ignoreComments: false, 
    // TODO: Add support for host rules + in the converter
    parseHostRules: false });
/**
 * Utility class for pre-processing filter lists before they are used by the AdGuard filtering engine.
 *
 * Concept:
 *
 * Right after a filter list is downloaded, we iterate over its rules and do the following:
 *   1. Parse rule text to AST (Abstract Syntax Tree) (if possible).
 *   2. Convert rule node to AdGuard format (if possible / needed).
 *
 * During this conversion, we also produce two maps:
 *    - Source map:     For performance reasons, we don't store the original rule text in the AST.
 *                      We store AST in a binary serialized format.
 *                      This source map is used to map the rule start index from the serialized filter list to
 *                      its start index in the raw filter list (converted filter list). This is needed to show
 *                      the exact applied rule in the filtering log. This rule text maybe a converted rule,
 *                      but in this case, we can get its original rule text from the conversion map
 *                      (for filtering engine, only the converted filter list is needed).
 *    - Conversion map: Maps the converted rule text to its original rule text. This is needed to show the
 *                      original rule text in the filtering log if a converted rule is applied.
 */
var FilterListPreprocessor = /** @class */ (function () {
    function FilterListPreprocessor() {
    }
    /**
     * Processes the raw filter list and converts it to the AdGuard format.
     *
     * @param filterList Raw filter list to convert.
     * @param parseHosts If true, the preprocessor will parse host rules.
     * @returns A {@link PreprocessedFilterList} object which contains the converted filter list,
     * the mapping between the original and converted rules, and the source map.
     */
    FilterListPreprocessor.preprocess = function (filterList, parseHosts) {
        if (parseHosts === void 0) { parseHosts = false; }
        var filterListLength = filterList.length;
        var sourceMap = {};
        var conversionMap = {};
        var rawFilterList = [];
        var convertedFilterList = new agtree/* OutputByteBuffer */.Yh();
        var firstLineBreakData = (0,simple_regex_dfa6ed82.k)(filterList);
        var inputOffset = 0;
        var outputOffset = 0;
        var previousLineBreak = firstLineBreakData[1] > 0
            ? filterList.slice(firstLineBreakData[0], firstLineBreakData[0] + firstLineBreakData[1])
            : simple_regex_dfa6ed82.L;
        while (inputOffset < filterListLength) {
            var _a = (0,simple_regex_dfa6ed82.k)(filterList, inputOffset), lineBreakIndex = _a[0], lineBreakLength = _a[1];
            var ruleText = filterList.slice(inputOffset, lineBreakIndex);
            var lineBreak = filterList.slice(lineBreakIndex, lineBreakIndex + lineBreakLength);
            // parse and convert can throw an error, so we need to catch them
            try {
                var ruleNode = agtree/* RuleParser.parse */.sR.parse(ruleText, (0,simple_regex_dfa6ed82._)((0,simple_regex_dfa6ed82._)({}, PREPROCESSOR_AGTREE_OPTIONS), { parseHostRules: parseHosts }));
                if (ruleNode.category === agtree/* RuleCategory.Empty */.WV.Empty || ruleNode.category === agtree/* RuleCategory.Comment */.WV.Comment) {
                    // Add empty lines and comments as is to the converted filter list,
                    // but not to the output byte buffer / source map.
                    rawFilterList.push(ruleText);
                    rawFilterList.push(lineBreak);
                    outputOffset += ruleText.length + lineBreakLength;
                    inputOffset = lineBreakIndex + lineBreakLength;
                    previousLineBreak = lineBreak;
                    continue;
                }
                var conversionResult = agtree/* RuleConverter.convertToAdg */.cR.convertToAdg(ruleNode);
                if (conversionResult.isConverted) {
                    // Maybe the rule is the last line without a line break in the input filter list
                    // but we need to convert it to multiple rules.
                    // In this case, we should use the last used line break before the conversion.
                    var convertedRulesLineBreak = lineBreakLength > 0 ? lineBreak : previousLineBreak;
                    var numberOfConvertedRules = conversionResult.result.length;
                    // Note: 1 rule can be converted to multiple rules
                    for (var i = 0; i < conversionResult.result.length; i += 1) {
                        var convertedRuleNode = conversionResult.result[i];
                        // In this case we should generate the rule text from the AST, because its converted,
                        // i.e. it's not the same as the original rule text.
                        var convertedRuleText = agtree/* RuleParser.generate */.sR.generate(convertedRuleNode);
                        rawFilterList.push(convertedRuleText);
                        rawFilterList.push(i === numberOfConvertedRules - 1 ? lineBreak : convertedRulesLineBreak);
                        var bufferOffset = convertedFilterList.currentOffset;
                        // Store the converted rules and the mapping between the original and converted rules
                        conversionMap[outputOffset] = ruleText;
                        sourceMap[bufferOffset] = outputOffset;
                        agtree/* RuleParser.serialize */.sR.serialize(convertedRuleNode, convertedFilterList);
                        outputOffset += convertedRuleText.length + (i === numberOfConvertedRules - 1
                            ? lineBreakLength
                            : convertedRulesLineBreak.length);
                    }
                }
                else {
                    // If the rule is not converted, we should store the original rule text in the raw filter list.
                    rawFilterList.push(ruleText);
                    rawFilterList.push(lineBreak);
                    var bufferOffset = convertedFilterList.currentOffset;
                    // Store the converted rules and the mapping between the original and converted rules
                    sourceMap[bufferOffset] = outputOffset;
                    agtree/* RuleParser.serialize */.sR.serialize(ruleNode, convertedFilterList);
                    outputOffset += ruleText.length + lineBreakLength;
                }
            }
            catch (error) {
                logger.error("Failed to process rule: '".concat(ruleText, "' due to ").concat(getErrorMessage(error)));
                // Add invalid rules as is to the converted filter list,
                // but not to the output byte buffer / source map.
                rawFilterList.push(ruleText);
                rawFilterList.push(lineBreak);
                outputOffset += ruleText.length + lineBreakLength;
            }
            // Move to the next line
            inputOffset = lineBreakIndex + lineBreakLength;
            previousLineBreak = lineBreak;
        }
        return {
            // TODO: Remove any type cast
            filterList: convertedFilterList.chunks,
            rawFilterList: rawFilterList.join(simple_regex_dfa6ed82.E),
            conversionMap: conversionMap,
            sourceMap: sourceMap,
        };
    };
    /**
     * Gets the original filter list text from the preprocessed filter list.
     *
     * @param preprocessedFilterList Preprocessed filter list.
     * @returns Original filter list text.
     */
    FilterListPreprocessor.getOriginalFilterListText = function (preprocessedFilterList) {
        var _a;
        var rawFilterList = preprocessedFilterList.rawFilterList, conversionMap = preprocessedFilterList.conversionMap;
        var length = rawFilterList.length;
        var result = [];
        var offset = 0;
        var prevLineStart = -1;
        var lineBreakIndex = -1;
        var lineBreakLength = 0;
        while (offset < length) {
            _a = (0,simple_regex_dfa6ed82.k)(rawFilterList, offset), lineBreakIndex = _a[0], lineBreakLength = _a[1];
            var lineBreak = rawFilterList.slice(lineBreakIndex, lineBreakIndex + lineBreakLength);
            var originalRule = conversionMap[offset];
            // One rule can be converted to multiple rules - in this case we should put the original rule text only once
            // If there is such a case, these rules follow one after the other
            if (!(originalRule && originalRule === conversionMap[prevLineStart])) {
                result.push(originalRule !== null && originalRule !== void 0 ? originalRule : rawFilterList.slice(offset, lineBreakIndex));
                result.push(lineBreak);
            }
            prevLineStart = offset;
            offset = lineBreakIndex + lineBreakLength;
        }
        // Add an empty rule if final new line is present
        if (lineBreakLength > 0) {
            result.push(simple_regex_dfa6ed82.E);
        }
        return result.join(simple_regex_dfa6ed82.E);
    };
    /**
     * Gets the original rules from the preprocessed filter list.
     *
     * @param preprocessedFilterList Preprocessed filter list.
     * @returns Array of original rules.
     */
    FilterListPreprocessor.getOriginalRules = function (preprocessedFilterList) {
        var _a;
        var rawFilterList = preprocessedFilterList.rawFilterList, conversionMap = preprocessedFilterList.conversionMap;
        var length = rawFilterList.length;
        var result = [];
        var offset = 0;
        var prevLineStart = -1;
        var lineBreakIndex = -1;
        var lineBreakLength = 0;
        while (offset < length) {
            _a = (0,simple_regex_dfa6ed82.k)(rawFilterList, offset), lineBreakIndex = _a[0], lineBreakLength = _a[1];
            var originalRule = conversionMap[offset];
            // One rule can be converted to multiple rules - in this case we should put the original rule text only once
            // If there is such a case, these rules follow one after the other
            if (!(originalRule && originalRule === conversionMap[prevLineStart])) {
                result.push(originalRule !== null && originalRule !== void 0 ? originalRule : rawFilterList.slice(offset, lineBreakIndex));
            }
            prevLineStart = offset;
            offset = lineBreakIndex + lineBreakLength;
        }
        // Add an empty rule if final new line is present
        if (lineBreakLength > 0) {
            result.push(simple_regex_dfa6ed82.E);
        }
        return result;
    };
    return FilterListPreprocessor;
}());

/**
 * Validator for filter list conversion map.
 *
 * @note This is only needed to show the original rule text in the filtering log if a converted rule is applied.
 */
var filterListConversionMapValidator = lib.z.record(
/**
 * Converted rule line start offset.
 */
lib.z.string(), 
/**
 * Original rule text.
 */
lib.z.string());
/**
 * Validator for filter list chunks.
 */
var filterListChunksValidator = lib.z.array(lib.z["instanceof"](Uint8Array));
/**
 * Validator for preprocessed filter list.
 */
var preprocessedFilterListValidator = lib.z.object({
    /**
     * Raw processed filter list.
     */
    rawFilterList: lib.z.string(),
    /**
     * Processed filter list, but in a serialized form.
     */
    filterList: filterListChunksValidator,
    /**
     * Map of converted rules to original rules.
     */
    conversionMap: filterListConversionMapValidator,
    /**
     * Source map.
     */
    sourceMap: filterListSourceMapValidator,
});

/**
 * RuleStorageScanner scans multiple RuleScanner instances.
 * The storage index is built from the rule position in the list
 * + cumulative offset value of filter lists.
 */
var RuleStorageScanner = /** @class */ (function () {
    /**
     * Constructor
     *
     * @param scanners
     */
    function RuleStorageScanner(scanners) {
        /**
         * Current scanner
         */
        this.currentScanner = null;
        /**
         * Index of the current scanner
         */
        this.currentScannerIdx = -1;
        /**
         * Rule position in the concatenated filter lists data
         */
        this.storageOffset = 0;
        this.scanners = scanners;
        this.listOffsetEntriesCursor = 0;
        this.listOffsetKeys = new Int32Array(scanners.length);
        this.listOffsetValues = new Uint32Array(scanners.length);
    }
    /**
     * Scan advances the RuleStorageScanner to the next rule, which will then be available
     * through the Rule method. It returns false when the scan stops, either by
     * reaching the end of the input or an error.
     *
     * @return true if there is some result
     */
    RuleStorageScanner.prototype.scan = function () {
        var scannersLength = this.scanners.length;
        if (scannersLength === 0) {
            return false;
        }
        if (!this.currentScanner) {
            this.currentScannerIdx = 0;
            this.currentScanner = this.scanners[this.currentScannerIdx];
            this.setListOffset(this.currentScanner.getListId(), this.storageOffset);
        }
        while (this.currentScannerIdx < scannersLength) {
            if (this.currentScanner.scan()) {
                return true;
            }
            // Accumulate the length of the current scanner before moving to the next one
            this.storageOffset += this.currentScanner.getDataLength();
            // Move to the next scanner
            this.currentScannerIdx += 1;
            // Check if there's a next scanner
            if (this.currentScannerIdx < this.scanners.length) {
                this.currentScanner = this.scanners[this.currentScannerIdx];
                this.setListOffset(this.currentScanner.getListId(), this.storageOffset);
            }
        }
        return false;
    };
    /**
     * Rule returns the most recent rule generated by a call to Scan, and the index of this rule.
     * See ruleListIdxToStorageIdx for more information on what this index is.
     */
    RuleStorageScanner.prototype.getRule = function () {
        if (!this.currentScanner) {
            return null;
        }
        var rule = this.currentScanner.getRule();
        if (!rule) {
            return null;
        }
        var offset = this.getListOffset(rule.rule.getFilterListId());
        var index = offset + rule.index;
        return new IndexedStorageRule(rule.rule, index);
    };
    /**
     * Match storage index with range of filter list offset
     * and return list id and local filter list position.
     *
     * @param storageIdx rule position in concatenated filter lists data
     * @returns tuple of list id and local filter list position
     */
    RuleStorageScanner.prototype.getIds = function (storageIdx) {
        var listOffsetEntriesLength = this.listOffsetKeys.length;
        if (listOffsetEntriesLength === 1) {
            return [this.listOffsetKeys[0], storageIdx - this.listOffsetValues[0]];
        }
        for (var i = 0; i < listOffsetEntriesLength - 1; i += 1) {
            var offset = this.listOffsetValues[i];
            var nextOffset = this.listOffsetValues[i + 1];
            if (storageIdx >= offset && storageIdx < nextOffset) {
                return [this.listOffsetKeys[i], storageIdx - offset];
            }
        }
        return [
            this.listOffsetKeys[listOffsetEntriesLength - 1],
            storageIdx - this.listOffsetValues[listOffsetEntriesLength - 1],
        ];
    };
    /**
     * Push listID and offset to the {@link listOffsetEntries}.
     *
     * @param listId Filter list id.
     * @param offset Filter list offset position in the storage.
     */
    RuleStorageScanner.prototype.setListOffset = function (listId, offset) {
        this.listOffsetKeys[this.listOffsetEntriesCursor] = listId;
        this.listOffsetValues[this.listOffsetEntriesCursor] = offset;
        this.listOffsetEntriesCursor += 1;
    };
    /**
     * Get filter list offset by list id.
     *
     * @param listId Filter list id.
     * @returns offset position in the storage.
     * @throws Error if listId is not found.
     */
    RuleStorageScanner.prototype.getListOffset = function (listId) {
        var idx = this.listOffsetKeys.indexOf(listId);
        if (idx !== -1) {
            return this.listOffsetValues[idx];
        }
        throw new Error("listId ".concat(listId, " not found in the storage"));
    };
    return RuleStorageScanner;
}());

/**
 * RuleStorage is an abstraction that combines several rule lists
 * It can be scanned using RuleStorageScanner, and also it allows
 * retrieving rules by its index

 * The idea is to keep rules in a serialized format (even original format in the case of FileRuleList)
 * and create them in a lazy manner only when we really need them. When the filtering engine is
 * being initialized, we need to scan the rule lists once in order to fill up the lookup tables.
 * We use rule indexes as a unique rule identifier instead of the rule itself.
 * The rule is created (see RetrieveRule) only when there's a chance that it's needed.

 * Rule index is an int64 value that actually consists of two int32 values:
 * One is the rule list identifier, and the second is the index of the rule inside of that list.
*/
var RuleStorage = /** @class */ (function () {
    /**
     * Constructor
     *
     * @param lists rule lists array
     *
     * @throws on duplicate lists
     */
    function RuleStorage(lists) {
        var _this = this;
        this.lists = lists;
        this.listsMap = new Map();
        this.cache = new Map();
        this.lists.forEach(function (list) {
            var filterListId = list.getId();
            if (_this.listsMap.get(filterListId)) {
                throw new Error("Duplicate list ID: ".concat(filterListId));
            }
            _this.listsMap.set(filterListId, list);
        });
    }
    /**
     * Creates a new instance of RuleStorageScanner.
     * It can be used to read and parse all the storage contents.
     *
     * @return scanner instance
     */
    RuleStorage.prototype.createRuleStorageScanner = function (scannerType) {
        var scanners = this.lists.map(function (list) { return list.newScanner(scannerType); });
        this.scanner = new RuleStorageScanner(scanners);
        return this.scanner;
    };
    /**
     * Looks for the filtering rule in this storage
     *
     * @param storageIdx the lookup index that you can get from the rule storage scanner
     * @param ignoreHost rules could be retrieved as host rules
     */
    RuleStorage.prototype.retrieveRule = function (storageIdx, ignoreHost) {
        if (ignoreHost === void 0) { ignoreHost = true; }
        var rule = this.cache.get(storageIdx);
        if (rule) {
            return rule;
        }
        var _a = this.scanner.getIds(storageIdx), listId = _a[0], ruleId = _a[1];
        var list = this.listsMap.get(listId);
        if (!list) {
            logger.warn("Failed to retrieve list ".concat(listId, ", should not happen in normal operation"));
            return null;
        }
        var ruleNode = list.retrieveRuleNode(ruleId);
        if (!ruleNode) {
            logger.warn("Failed to retrieve rule ".concat(ruleId, ", should not happen in normal operation"));
            return null;
        }
        var result = RuleFactory.createRule(ruleNode, listId, ruleId, false, false, ignoreHost);
        if (result) {
            this.cache.set(storageIdx, result);
        }
        return result;
    };
    /**
     * RetrieveNetworkRule is a helper method that retrieves a network rule from the storage
     *
     * @param storageIdx
     * @return the rule or nil in any other case (not found or error)
     */
    RuleStorage.prototype.retrieveNetworkRule = function (storageIdx) {
        var rule = this.retrieveRule(storageIdx);
        if (!rule) {
            return null;
        }
        if (rule instanceof NetworkRule) {
            return rule;
        }
        return null;
    };
    /**
     * RetrieveHostRule is a helper method that retrieves a host rule from the storage
     *
     * @param storageIdx
     * @return the rule or nil in any other case (not found or error)
     */
    RuleStorage.prototype.retrieveHostRule = function (storageIdx) {
        var rule = this.retrieveRule(storageIdx, false);
        if (!rule) {
            return null;
        }
        if (rule instanceof HostRule) {
            return rule;
        }
        return null;
    };
    /**
     * Returns the size of the cache.
     */
    RuleStorage.prototype.getCacheSize = function () {
        return this.cache.size;
    };
    return RuleStorage;
}());

var FILTER_PREFIX = 'filter_';
/**
 * Generates a text file name for a given filter ID.
 *
 * @param filterId - The ID of the filter.
 * @returns The generated file name in the format `filter_{filterId}.txt`.
 */
var getFilterName = function (filterId) {
    return "".concat(FILTER_PREFIX).concat(filterId, ".txt");
};
/**
 * Generates a binary file name for a given filter ID.
 *
 * @param filterId - The ID of the filter.
 * @returns The generated file name in the format `filter_{filterId}.bin`.
 */
var getFilterBinaryName = function (filterId) {
    return "".concat(FILTER_PREFIX).concat(filterId, ".bin");
};
/**
 * Generates a conversion map file name for a given filter ID.
 *
 * @param filterId - The ID of the filter.
 * @returns The generated file name in the format `filter_{filterId}_conversion_map.json`.
 */
var getFilterConversionMapName = function (filterId) {
    return "".concat(FILTER_PREFIX).concat(filterId, "_conversion_map.json");
};
/**
 * Generates a source map file name for a given filter ID.
 *
 * @param filterId - The ID of the filter.
 * @returns The generated file name in the format `filter_{filterId}_source_map.json`.
 */
var getFilterSourceMapName = function (filterId) {
    return "".concat(FILTER_PREFIX).concat(filterId, "_source_map.json");
};
/**
 * Extracts the filter ID from a given filter name.
 *
 * @param filterName - The filter name in the format `filter_{filterId}.txt`.
 * @returns The extracted filter ID, or null if the filter name does not match the expected format.
 */
var getIdFromFilterName = function (filterName) {
    var match = filterName.match(new RegExp("".concat(FILTER_PREFIX, "(\\d+)\\.txt")));
    if (!match) {
        return null;
    }
    return parseInt(match[1], 10);
};

/**
 * Creates a list of allowlist rules for a given list ID and domains.
 *
 * @param listId List ID.
 * @param domains List of domains to create allowlist rules for.
 * @returns BufferRuleList instance.
 */
var createAllowlistRuleList = function (listId, domains) {
    var buffer = new agtree/* OutputByteBuffer */.Yh();
    domains.forEach(function (domain) {
        var rule = createAllowlistRuleNode(domain);
        if (rule) {
            agtree/* RuleParser.serialize */.sR.serialize(rule, buffer);
        }
    });
    // TODO (David): Remove any cast
    return new BufferRuleList(listId, buffer.chunks);
};

/**
 * Module with miscellaneous syntax utils exposed in API
 */
var RuleSyntaxUtils = /** @class */ (function () {
    function RuleSyntaxUtils() {
    }
    /**
     * Checks if rule can be matched by domain
     *
     * @param node Rule node
     * @param domain Domain to check
     */
    RuleSyntaxUtils.isRuleForDomain = function (node, domain) {
        var rule = RuleFactory.createRule(node, this.DUMMY_FILTER_ID);
        if (!rule) {
            return false;
        }
        var permittedDomains = rule.getPermittedDomains();
        return !!permittedDomains
            && DomainModifier.isDomainOrSubdomainOfAny(domain, permittedDomains);
    };
    /**
     * Checks if rule can be matched by URL
     *
     * @param node Rule node
     * @param url URL to check
     */
    RuleSyntaxUtils.isRuleForUrl = function (node, url) {
        var domain = (0,es6/* getHostname */.Fo)(url);
        if (!domain) {
            return false;
        }
        return this.isRuleForDomain(node, domain);
    };
    RuleSyntaxUtils.DUMMY_FILTER_ID = 0;
    return RuleSyntaxUtils;
}());




/***/ }),

/***/ 8549:
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "E": () => (/* binding */ EMPTY_STRING),
/* harmony export */   "L": () => (/* binding */ LF),
/* harmony export */   "S": () => (/* binding */ SimpleRegex),
/* harmony export */   "W": () => (/* binding */ WILDCARD),
/* harmony export */   "_": () => (/* binding */ __assign),
/* harmony export */   "a": () => (/* binding */ __spreadArray),
/* harmony export */   "b": () => (/* binding */ SEPARATOR),
/* harmony export */   "c": () => (/* binding */ __extends),
/* harmony export */   "d": () => (/* binding */ stringArraysEquals),
/* harmony export */   "e": () => (/* binding */ stringArraysHaveIntersection),
/* harmony export */   "f": () => (/* binding */ fastHash),
/* harmony export */   "g": () => (/* binding */ __awaiter),
/* harmony export */   "h": () => (/* binding */ hasSpaces),
/* harmony export */   "i": () => (/* binding */ isString),
/* harmony export */   "j": () => (/* binding */ __generator),
/* harmony export */   "k": () => (/* binding */ findNextLineBreakIndex),
/* harmony export */   "l": () => (/* binding */ __makeTemplateObject),
/* harmony export */   "s": () => (/* binding */ splitByDelimiterWithEscapeCharacter),
/* harmony export */   "u": () => (/* binding */ unescapeChar)
/* harmony export */ });
/* unused harmony exports m, n, o, r */
var extendStatics = function(d, b) {
    extendStatics = Object.setPrototypeOf ||
        ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
        function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
    return extendStatics(d, b);
};
function __extends(d, b) {
    if (typeof b !== "function" && b !== null)
        throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
    extendStatics(d, b);
    function __() { this.constructor = d; }
    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
}
var __assign = function() {
    __assign = Object.assign || function __assign(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
function __awaiter(thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
}
function __generator(thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (_) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
}
function __spreadArray(to, from, pack) {
    if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
        if (ar || !(i in from)) {
            if (!ar) ar = Array.prototype.slice.call(from, 0, i);
            ar[i] = from[i];
        }
    }
    return to.concat(ar || Array.prototype.slice.call(from));
}
function __makeTemplateObject(cooked, raw) {
    if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; }
    return cooked;
}

var ErrorStatusCodes;
(function (ErrorStatusCodes) {
    ErrorStatusCodes[ErrorStatusCodes["ComplexRegex"] = 1001] = "ComplexRegex";
    ErrorStatusCodes[ErrorStatusCodes["RuleLimit"] = 1002] = "RuleLimit";
    ErrorStatusCodes[ErrorStatusCodes["RegexpRuleLimit"] = 1003] = "RegexpRuleLimit";
    ErrorStatusCodes[ErrorStatusCodes["RemoveparamRegexpIsNotSupported"] = 1004] = "RemoveparamRegexpIsNotSupported";
    ErrorStatusCodes[ErrorStatusCodes["RemoveparamInversionIsNotSupported"] = 1005] = "RemoveparamInversionIsNotSupported";
})(ErrorStatusCodes || (ErrorStatusCodes = {}));
var EMPTY_STRING = '';
var SEPARATOR = '|';
var SPACE = ' ';
var WILDCARD = '*';
var LF = '\n';
var CR = '\r';
var FF = '\f';

/**
 * Splits the string by the delimiter, ignoring escaped delimiters
 * and without tokenizing.
 * Works for plain strings that don't include string representation of
 * complex entities, e.g $replace modifier values.
 *
 * @param string - string to split
 * @param delimiter - delimiter
 * @param escapeCharacter - escape character
 * @param preserveEmptyTokens - if true, preserve empty parts
 * @param shouldUnescape - if true, unescape characters
 * @return array of string parts
 */
function splitByDelimiterWithEscapeCharacter(string, delimiter, escapeCharacter, preserveEmptyTokens, shouldUnescape) {
    if (shouldUnescape === void 0) { shouldUnescape = true; }
    if (!string) {
        return [];
    }
    if (string.startsWith(delimiter)) {
        // eslint-disable-next-line no-param-reassign
        string = string.substring(1);
    }
    var words = [];
    if (!string.includes(escapeCharacter)) {
        words = string.split(delimiter);
        if (!preserveEmptyTokens) {
            words = words.filter(function (word) { return !!word; });
        }
        return words;
    }
    var chars = [];
    var makeWord = function () {
        var word = chars.join('');
        words.push(word);
        chars = [];
    };
    for (var i = 0; i < string.length; i += 1) {
        var char = string.charAt(i);
        var isLastChar = i === (string.length - 1);
        if (char === delimiter) {
            var isEscapedChar = i > 0 && string[i - 1] === escapeCharacter;
            if (isEscapedChar) {
                if (shouldUnescape) {
                    chars.splice(chars.length - 1, 1);
                }
                chars.push(char);
            }
            else {
                makeWord();
            }
            if (isLastChar) {
                makeWord();
            }
        }
        else if (isLastChar) {
            chars.push(char);
            makeWord();
        }
        else {
            chars.push(char);
        }
    }
    if (!preserveEmptyTokens) {
        words = words.filter(function (word) { return !!word; });
    }
    return words;
}
/**
 * Checks if the specified string starts with a substr at the specified index.
 *
 * @param str - String to check
 * @param startIndex - Index to start checking from
 * @param substr - Substring to check
 * @return boolean true if it does start
 */
function startsAtIndexWith(str, startIndex, substr) {
    if (str.length - startIndex < substr.length) {
        return false;
    }
    for (var i = 0; i < substr.length; i += 1) {
        if (str.charAt(startIndex + i) !== substr.charAt(i)) {
            return false;
        }
    }
    return true;
}
/**
 * Checks if str has unquoted substr
 *
 * @param str
 * @param substr
 */
function hasUnquotedSubstring(str, substr) {
    var quotes = ['"', "'", '/'];
    if (!str.includes(substr)) {
        return false;
    }
    // eslint-disable-next-line @typescript-eslint/no-use-before-define
    if (indexOfAny(str, quotes) === -1) {
        return true;
    }
    var stack = [];
    for (var i = 0; i < str.length; i += 1) {
        var cursor = str[i];
        if (stack.length === 0) {
            if (startsAtIndexWith(str, i, substr)) {
                return true;
            }
        }
        if (quotes.indexOf(cursor) >= 0
            && (i === 0 || str[i - 1] !== '\\')) {
            var last = stack.pop();
            if (!last) {
                stack.push(cursor);
            }
            else if (last !== cursor) {
                stack.push(last);
                stack.push(cursor);
            }
        }
    }
    return false;
}
/**
 * djb2 hash algorithm
 *
 * NOTE: This version uses some bit operands to exclude overflow MAX_SAFE_INTEGER
 * (and moreover, exclude overflow 2^32).
 *
 * @see {@link https://gist.github.com/eplawless/52813b1d8ad9af510d85?permalink_comment_id=3367765#gistcomment-3367765}
 *
 * @param str string to get hash
 * @return {number} hash
 */
function fastHash(str) {
    if (str.length === 0) {
        return 0;
    }
    var hash = 5381;
    for (var i = 0; i < str.length; i += 1) {
        hash = hash * 33 ^ str.charCodeAt(i);
    }
    return hash >>> 0;
}
/**
 * Look for any symbol from "chars" array starting at "start" index or from the start of the string
 *
 * @param str   String to search
 * @param chars Chars to search for
 * @param start Start index (optional, inclusive)
 * @return int Index of the element found or -1 if not
 */
function indexOfAny(str, chars, start) {
    if (start === void 0) { start = 0; }
    if (str.length <= start) {
        return -1;
    }
    for (var i = start; i < str.length; i += 1) {
        var c = str.charAt(i);
        if (chars.indexOf(c) > -1) {
            return i;
        }
    }
    return -1;
}
/**
 * Replaces all occurences of find with replace in str
 *
 * @param str
 * @param find
 * @param replace
 */
function replaceAll(str, find, replace) {
    if (!str) {
        return str;
    }
    return str.split(find).join(replace);
}
/**
 * Checks if arrays are equal
 *
 * @param left array
 * @param right array
 * @return {boolean} true on equality
 */
function stringArraysEquals(left, right) {
    if (!left || !right) {
        return !left && !right;
    }
    if (left.length !== right.length) {
        return false;
    }
    for (var i = 0; i < left.length; i += 1) {
        if (left[i] !== right[i]) {
            return false;
        }
    }
    return true;
}
/**
 * Checks if arrays have an intersection
 *
 * @param left array
 * @param right array
 * @return {boolean} true on equality
 */
function stringArraysHaveIntersection(left, right) {
    if (!left || !right) {
        return true;
    }
    for (var i = 0; i < left.length; i += 1) {
        if (right.includes(left[i])) {
            return true;
        }
    }
    return false;
}
/**
 * Checks if string contains spaces
 *
 * @param str String to check
 * @returns `true` if string contains spaces, `false` otherwise
 */
function hasSpaces(str) {
    return str.includes(SPACE);
}
/**
 * Check if the given value is a string
 *
 * @param value Value to check
 * @returns `true` if value is a string, `false` otherwise
 */
function isString(value) {
    return typeof value === 'string';
}
/**
 * Unescapes the specified character in the string
 *
 * @param str String to escape
 * @param char Character to escape
 * @returns The string with the specified character unescaped
 */
function unescapeChar(str, char) {
    return str.replace("\\".concat(char), char);
}
/**
 * Finds the next line break index in the string starting from the specified index.
 * Supports LF, CR, FF and CRLF line breaks.
 *
 * @param str String to search in.
 * @param startIndex  Start index. Default is 0.
 * @returns A tuple with the line break index and the line break length.
 * If the line break is not found, returns the string length and 0.
 */
function findNextLineBreakIndex(str, startIndex) {
    if (startIndex === void 0) { startIndex = 0; }
    var length = str.length;
    var offset = startIndex;
    while (offset < length) {
        var char = str[offset];
        if (char === LF || char === FF) {
            return [offset, 1];
        }
        if (char === CR) {
            return str[offset + 1] === LF ? [offset, 2] : [offset, 1];
        }
        offset += 1;
    }
    return [length, 0];
}

// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/regexp
// should be escaped . * + ? ^ $ { } ( ) | [ ] / \
// except of * | ^
var specialCharacters = ['.', '+', '?', '$', '{', '}', '(', ')', '[', ']', '/', '\\'];
var reSpecialCharacters = new RegExp("[".concat(specialCharacters.join('\\'), "]"), 'g');
var reSpecialCharactersFull = /[.*+?^${}()|[\]\\]/g;
var reEscapedSpecialCharactersFull = /\\[.*+?^${}()|[\]\\]/g;
var protocolMarker = String.raw(templateObject_1 || (templateObject_1 = __makeTemplateObject(["://"], [":\\/\\/"])));
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#using_special_characters_in_strings
var escapeSequence = {
    n: '\n',
    r: '\r',
    t: '\t',
    b: '\b',
    f: '\f',
    v: '\v',
};
/**
 * Class with static helper methods for working with basic filtering rules patterns.
 * https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#basic-rules
 */
var SimpleRegex = /** @class */ (function () {
    function SimpleRegex() {
    }
    /**
     * Extracts the shortcut from the rule's pattern.
     * Shortcut is the longest substring of the pattern that does not contain
     * any special characters.
     *
     * Please note, that the shortcut is always lower-case!
     *
     * @param pattern - network rule's pattern.
     * @returns the shortcut or the empty string if we could not extract any.
     */
    SimpleRegex.extractShortcut = function (pattern) {
        if (pattern.startsWith(this.MASK_REGEX_RULE) && pattern.endsWith(this.MASK_REGEX_RULE)) {
            return this.extractRegexpShortcut(pattern);
        }
        return this.extractBasicShortcut(pattern);
    };
    /**
     * Searches for the longest substring of the pattern that
     * does not contain any special characters: *,^,|.
     *
     * @param pattern - network rule's pattern.
     * @returns the shortcut or the empty string
     */
    SimpleRegex.extractBasicShortcut = function (pattern) {
        var longest = '';
        var parts = pattern.split(this.rePatternSpecialCharacters);
        for (var _i = 0, parts_1 = parts; _i < parts_1.length; _i++) {
            var part = parts_1[_i];
            if (part.length > longest.length) {
                longest = part;
            }
        }
        return (longest || '').toLowerCase();
    };
    /**
     * Searches for a shortcut inside of a regexp pattern.
     * Shortcut in this case is a longest string with no REGEX special characters.
     * Also, we discard complicated regexps right away.
     *
     * @param pattern - network rule's pattern (regexp).
     * @returns the shortcut or the empty string
     */
    SimpleRegex.extractRegexpShortcut = function (pattern) {
        var reText = pattern.substring(this.MASK_REGEX_RULE.length, pattern.length - this.MASK_REGEX_RULE.length);
        if (reText.length === 0) {
            // The rule is too short, doing nothing
            return '';
        }
        if (reText.indexOf('?') >= 0) {
            // Do not mess with complex expressions which use lookahead
            // And with those using ? special character
            // https://github.com/AdguardTeam/AdguardBrowserExtension/issues/978
            return '';
        }
        // Remove protocol part to avoid useless shortcuts like "http"
        var protocolIndex = reText.indexOf(protocolMarker);
        if (protocolIndex > -1) {
            reText = reText.substring(protocolIndex + protocolMarker.length);
        }
        var currentLongest = '';
        var token = '';
        for (var i = 0; i < reText.length; i += 1) {
            var char = reText[i];
            if (char === '\\') {
                // Don't break token on escapes
                continue;
            }
            if (SimpleRegex.isValidRegexpShortcutChar(reText, i)) {
                token += char;
                if (i !== reText.length - 1) {
                    continue;
                }
            }
            if (token.length > currentLongest.length) {
                currentLongest = token;
            }
            token = '';
        }
        return currentLongest.toLowerCase();
    };
    /**
     * patternToRegexp is a helper method for creating regular expressions from the simple
     * wildcard-based syntax which is used in basic filters:
     * https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#basic-rules
     *
     * @param pattern - basic rule pattern
     * @returns regular expression
     */
    SimpleRegex.patternToRegexp = function (pattern) {
        if (pattern === this.MASK_START_URL
            || pattern === this.MASK_PIPE
            || pattern === this.MASK_ANY_CHARACTER
            || pattern === '') {
            return this.REGEX_ANY_CHARACTER;
        }
        if (pattern.startsWith(this.MASK_REGEX_RULE) && pattern.endsWith(this.MASK_REGEX_RULE)) {
            // This is a regex rule, just remove the regex markers
            return pattern.substring(this.MASK_REGEX_RULE.length, pattern.length - this.MASK_REGEX_RULE.length);
        }
        // Escape special characters except of * | ^
        var regex = pattern.replace(reSpecialCharacters, '\\$&');
        // Now escape "|" characters but avoid escaping them in the special places
        if (regex.startsWith(this.MASK_START_URL)) {
            regex = regex.substring(0, this.MASK_START_URL.length)
                + replaceAll(regex.substring(this.MASK_START_URL.length, regex.length - this.MASK_PIPE.length), this.MASK_PIPE, "\\".concat(this.MASK_PIPE))
                + regex.substring(regex.length - this.MASK_PIPE.length);
        }
        else {
            regex = regex.substring(0, this.MASK_PIPE.length)
                + replaceAll(regex.substring(this.MASK_PIPE.length, regex.length - this.MASK_PIPE.length), this.MASK_PIPE, "\\".concat(this.MASK_PIPE))
                + regex.substring(regex.length - this.MASK_PIPE.length);
        }
        // Replace special URL masks
        regex = replaceAll(regex, this.MASK_ANY_CHARACTER, this.REGEX_ANY_CHARACTER);
        regex = replaceAll(regex, this.MASK_SEPARATOR, this.REGEX_SEPARATOR);
        // Replace start URL and pipes
        if (regex.startsWith(this.MASK_START_URL)) {
            regex = this.REGEX_START_URL + regex.substring(this.MASK_START_URL.length);
        }
        else if (regex.startsWith(this.MASK_PIPE)) {
            regex = this.REGEX_START_STRING + regex.substring(this.MASK_PIPE.length);
        }
        if (regex.endsWith(this.MASK_PIPE)) {
            regex = regex.substring(0, regex.length - this.MASK_PIPE.length) + this.REGEX_END_STRING;
        }
        return regex;
    };
    /**
     * Creates RegExp object from string in '/reg_exp/gi' format
     *
     * @param str
     */
    SimpleRegex.patternFromString = function (str) {
        var parts = splitByDelimiterWithEscapeCharacter(str, '/', '\\', true);
        var modifiers = (parts[1] || '');
        if (modifiers.indexOf('g') < 0) {
            modifiers += 'g';
        }
        return new RegExp(parts[0], modifiers);
    };
    /**
     * Escapes characters with special meaning inside a regular expression.
     *
     * @param str
     * @param searchPattern - Pattern for detecting special characters. Optional.
     */
    SimpleRegex.escapeRegexSpecials = function (str, searchPattern) {
        if (searchPattern === void 0) { searchPattern = reSpecialCharactersFull; }
        return str.replace(searchPattern, '\\$&');
    };
    /**
     * Unescapes characters with special meaning inside a regular expression.
     *
     * @param str
     * @param searchPattern - Pattern for detecting special characters. Optional.
     */
    SimpleRegex.unescapeRegexSpecials = function (str, searchPattern) {
        if (searchPattern === void 0) { searchPattern = reEscapedSpecialCharactersFull; }
        return str.replace(searchPattern, function (match) { return match.substring(1); });
    };
    /**
     * Check if pattern is Regex
     */
    SimpleRegex.isRegexPattern = function (str) {
        return str.startsWith('/') && str.endsWith('/');
    };
    /**
     * Unescapes special characters in a string
     * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Grammar_and_types#using_special_characters_in_strings
     */
    SimpleRegex.unescapeSpecials = function (str) {
        var keys = Object.keys(escapeSequence).join('|');
        var regex = new RegExp("\\\\(".concat(keys, ")"), 'g');
        return str.replace(regex, function (match, group) {
            return escapeSequence[group];
        });
    };
    /**
     * Matching the beginning of an address. With this character you don't
     * have to specify a particular protocol and subdomain in address mask.
     * It means, || stands for http://*., https://*., ws://*., wss://*. at once.
     */
    SimpleRegex.MASK_START_URL = '||';
    /**
     * REGEX_START_URL corresponds to MASK_START_URL
     */
    SimpleRegex.REGEX_START_URL = '^(http|https|ws|wss)://([a-z0-9-_.]+\\.)?';
    /**
     * A pointer to the beginning or the end of address. The value depends on the
     * character placement in the mask. For example, a rule swf| corresponds
     * to http://example.com/annoyingflash.swf , but not to http://example.com/swf/index.html.
     * |http://example.org corresponds to http://example.org,
     * but not to http://domain.com?url=http://example.org.
     */
    SimpleRegex.MASK_PIPE = '|';
    /**
     * REGEX_END_STRING corresponds to MASK_PIPE if it is in the end of a pattern.
     */
    SimpleRegex.REGEX_END_STRING = '$';
    /**
     * REGEX_START_STRING corresponds to MASK_PIPE if it is in the beginning of a pattern.
     */
    SimpleRegex.REGEX_START_STRING = '^';
    /**
     * Separator character mark. Separator character is any character,
     * but a letter, a digit, or one of the following: _ - .
     */
    SimpleRegex.MASK_SEPARATOR = '^';
    /**
     * REGEX_SEPARATOR corresponds to MASK_SEPARATOR
     */
    SimpleRegex.REGEX_SEPARATOR = '([^ a-zA-Z0-9.%_-]|$)';
    /**
     * This is a wildcard character. It is used to represent "any set of characters".
     * This can also be an empty string or a string of any length.
     */
    SimpleRegex.MASK_ANY_CHARACTER = '*';
    /**
     * Path separator
     */
    SimpleRegex.MASK_BACKSLASH = '/';
    /**
     * REGEX_ANY_CHARACTER corresponds to MASK_ANY_CHARACTER.
     */
    SimpleRegex.REGEX_ANY_CHARACTER = '.*';
    /**
     * Enclose regex in two backslashes to mark a regex rule:
     * https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#regular-expressions-support
     */
    SimpleRegex.MASK_REGEX_RULE = '/';
    /**
     *  Regex for matching special characters in modifier regex pattern
     */
    SimpleRegex.reModifierPatternSpecialCharacters = /[[\],\\]/g;
    /**
      *  Regex for matching escaped special characters in modifier regex pattern
      */
    SimpleRegex.reModifierPatternEscapedSpecialCharacters = /\\[[\],\\]/g;
    /**
     * If string starts with exclamation mark "!" we consider it as comment
     */
    SimpleRegex.MASK_COMMENT = '!';
    /**
     * Min length of rule shortcut
     * This value has been picked as a result of performance experiments
     */
    SimpleRegex.MIN_SHORTCUT_LENGTH = 3;
    /**
     * Min length of generic rule shortcut
     */
    SimpleRegex.MIN_GENERIC_RULE_LENGTH = 4;
    /** Regex with basic matching pattern special characters */
    SimpleRegex.rePatternSpecialCharacters = new RegExp('[*^|]');
    /**
     * Checks if char is valid for regexp shortcut – is alphanumeric or escaped period or forward slash
     *
     * @param str string
     * @param i index of char
     * @returns  true if char is valid for regexp shortcut
     */
    SimpleRegex.isValidRegexpShortcutChar = function (str, i) {
        var charCode = str.charCodeAt(i);
        if (SimpleRegex.isAlphaNumericChar(charCode)) {
            return true;
        }
        // Escaped period or escaped forward slash are allowed in regexp shortcut
        if (i > 0 && str[i - 1] === '\\') {
            if (charCode === 46 || charCode === 47) {
                return true;
            }
        }
        return false;
    };
    /**
     * Checks if char is alpha-numeric
     * @param charCode - char code
     * @returns true if char is alpha-numeric
     */
    SimpleRegex.isAlphaNumericChar = function (charCode) {
        return (charCode > 47 && charCode < 58) // numeric (0-9)
            || (charCode > 64 && charCode < 91) // upper alpha (A-Z)
            || (charCode > 96 && charCode < 123); // lower alpha (a-z)
    };
    return SimpleRegex;
}());
var templateObject_1;




/***/ }),

/***/ 92243:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";


const ipRegex = __webpack_require__(64185);

const defaultOpts = {exact: false};

const v4str = `${ipRegex.v4().source}\\/(3[0-2]|[12]?[0-9])`;
const v6str = `${ipRegex.v6().source}\\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])`;

// can not precompile the non-exact regexes because global flag makes the regex object stateful
// which would require the user to reset .lastIndex on subsequent calls
const v4exact = new RegExp(`^${v4str}$`);
const v6exact = new RegExp(`^${v6str}$`);
const v46exact = new RegExp(`(?:^${v4str}$)|(?:^${v6str}$)`);

module.exports = ({exact} = defaultOpts) => exact ? v46exact : new RegExp(`(?:${v4str})|(?:${v6str})`, "g");
module.exports.v4 = ({exact} = defaultOpts) => exact ? v4exact : new RegExp(v4str, "g");
module.exports.v6 = ({exact} = defaultOpts) => exact ? v6exact : new RegExp(v6str, "g");


/***/ }),

/***/ 94332:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";


/**
 * Module dependenices
 */

const clone = __webpack_require__(59072);
const typeOf = __webpack_require__(73378);
const isPlainObject = __webpack_require__(24019);

function cloneDeep(val, instanceClone) {
  switch (typeOf(val)) {
    case 'object':
      return cloneObjectDeep(val, instanceClone);
    case 'array':
      return cloneArrayDeep(val, instanceClone);
    default: {
      return clone(val);
    }
  }
}

function cloneObjectDeep(val, instanceClone) {
  if (typeof instanceClone === 'function') {
    return instanceClone(val);
  }
  if (instanceClone || isPlainObject(val)) {
    const res = new val.constructor();
    for (let key in val) {
      res[key] = cloneDeep(val[key], instanceClone);
    }
    return res;
  }
  return val;
}

function cloneArrayDeep(val, instanceClone) {
  const res = new val.constructor(val.length);
  for (let i = 0; i < val.length; i++) {
    res[i] = cloneDeep(val[i], instanceClone);
  }
  return res;
}

/**
 * Expose `cloneDeep`
 */

module.exports = cloneDeep;


/***/ }),

/***/ 64185:
/***/ ((module) => {

"use strict";


const word = '[a-fA-F\\d:]';
const b = options => options && options.includeBoundaries ?
	`(?:(?<=\\s|^)(?=${word})|(?<=${word})(?=\\s|$))` :
	'';

const v4 = '(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}';

const v6seg = '[a-fA-F\\d]{1,4}';
const v6 = `
(?:
(?:${v6seg}:){7}(?:${v6seg}|:)|                                    // 1:2:3:4:5:6:7::  1:2:3:4:5:6:7:8
(?:${v6seg}:){6}(?:${v4}|:${v6seg}|:)|                             // 1:2:3:4:5:6::    1:2:3:4:5:6::8   1:2:3:4:5:6::8  1:2:3:4:5:6::1.2.3.4
(?:${v6seg}:){5}(?::${v4}|(?::${v6seg}){1,2}|:)|                   // 1:2:3:4:5::      1:2:3:4:5::7:8   1:2:3:4:5::8    1:2:3:4:5::7:1.2.3.4
(?:${v6seg}:){4}(?:(?::${v6seg}){0,1}:${v4}|(?::${v6seg}){1,3}|:)| // 1:2:3:4::        1:2:3:4::6:7:8   1:2:3:4::8      1:2:3:4::6:7:1.2.3.4
(?:${v6seg}:){3}(?:(?::${v6seg}){0,2}:${v4}|(?::${v6seg}){1,4}|:)| // 1:2:3::          1:2:3::5:6:7:8   1:2:3::8        1:2:3::5:6:7:1.2.3.4
(?:${v6seg}:){2}(?:(?::${v6seg}){0,3}:${v4}|(?::${v6seg}){1,5}|:)| // 1:2::            1:2::4:5:6:7:8   1:2::8          1:2::4:5:6:7:1.2.3.4
(?:${v6seg}:){1}(?:(?::${v6seg}){0,4}:${v4}|(?::${v6seg}){1,6}|:)| // 1::              1::3:4:5:6:7:8   1::8            1::3:4:5:6:7:1.2.3.4
(?::(?:(?::${v6seg}){0,5}:${v4}|(?::${v6seg}){1,7}|:))             // ::2:3:4:5:6:7:8  ::2:3:4:5:6:7:8  ::8             ::1.2.3.4
)(?:%[0-9a-zA-Z]{1,})?                                             // %eth0            %1
`.replace(/\s*\/\/.*$/gm, '').replace(/\n/g, '').trim();

// Pre-compile only the exact regexes because adding a global flag make regexes stateful
const v46Exact = new RegExp(`(?:^${v4}$)|(?:^${v6}$)`);
const v4exact = new RegExp(`^${v4}$`);
const v6exact = new RegExp(`^${v6}$`);

const ip = options => options && options.exact ?
	v46Exact :
	new RegExp(`(?:${b(options)}${v4}${b(options)})|(?:${b(options)}${v6}${b(options)})`, 'g');

ip.v4 = options => options && options.exact ? v4exact : new RegExp(`${b(options)}${v4}${b(options)}`, 'g');
ip.v6 = options => options && options.exact ? v6exact : new RegExp(`${b(options)}${v6}${b(options)}`, 'g');

module.exports = ip;


/***/ }),

/***/ 69918:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

const {v4, v6} = __webpack_require__(92243);

const re4 = v4({exact: true});
const re6 = v6({exact: true});

module.exports = str => re4.test(str) ? 4 : (re6.test(str) ? 6 : 0);
module.exports.v4 = str => re4.test(str);
module.exports.v6 = str => re6.test(str);


/***/ }),

/***/ 13997:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

const ipRegex = __webpack_require__(64185);

const isIp = string => ipRegex({exact: true}).test(string);
isIp.v4 = string => ipRegex.v4({exact: true}).test(string);
isIp.v6 = string => ipRegex.v6({exact: true}).test(string);
isIp.version = string => isIp(string) ? (isIp.v4(string) ? 4 : 6) : undefined;

module.exports = isIp;


/***/ }),

/***/ 24019:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";
/*!
 * is-plain-object <https://github.com/jonschlinkert/is-plain-object>
 *
 * Copyright (c) 2014-2017, Jon Schlinkert.
 * Released under the MIT License.
 */



var isObject = __webpack_require__(97053);

function isObjectObject(o) {
  return isObject(o) === true
    && Object.prototype.toString.call(o) === '[object Object]';
}

module.exports = function isPlainObject(o) {
  var ctor,prot;

  if (isObjectObject(o) === false) return false;

  // If has modified constructor
  ctor = o.constructor;
  if (typeof ctor !== 'function') return false;

  // If has modified prototype
  prot = ctor.prototype;
  if (isObjectObject(prot) === false) return false;

  // If constructor does not have an Object-specific method
  if (prot.hasOwnProperty('isPrototypeOf') === false) {
    return false;
  }

  // Most likely a plain Object
  return true;
};


/***/ }),

/***/ 97053:
/***/ ((module) => {

"use strict";
/*!
 * isobject <https://github.com/jonschlinkert/isobject>
 *
 * Copyright (c) 2014-2017, Jon Schlinkert.
 * Released under the MIT License.
 */



module.exports = function isObject(val) {
  return val != null && typeof val === 'object' && Array.isArray(val) === false;
};


/***/ }),

/***/ 23176:
/***/ (function(module) {

(function (global, factory) {
	 true ? module.exports = factory() :
	0;
}(this, (function () { 'use strict';

	function createCommonjsModule(fn, module) {
		return module = { exports: {} }, fn(module, module.exports), module.exports;
	}

	var _global = createCommonjsModule(function (module) {
	// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
	var global = module.exports = typeof window != 'undefined' && window.Math == Math
	  ? window : typeof self != 'undefined' && self.Math == Math ? self
	  // eslint-disable-next-line no-new-func
	  : Function('return this')();
	if (typeof __g == 'number') { __g = global; } // eslint-disable-line no-undef
	});

	var _core = createCommonjsModule(function (module) {
	var core = module.exports = { version: '2.6.5' };
	if (typeof __e == 'number') { __e = core; } // eslint-disable-line no-undef
	});
	var _core_1 = _core.version;

	var _isObject = function (it) {
	  return typeof it === 'object' ? it !== null : typeof it === 'function';
	};

	var _anObject = function (it) {
	  if (!_isObject(it)) { throw TypeError(it + ' is not an object!'); }
	  return it;
	};

	var _fails = function (exec) {
	  try {
	    return !!exec();
	  } catch (e) {
	    return true;
	  }
	};

	// Thank's IE8 for his funny defineProperty
	var _descriptors = !_fails(function () {
	  return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7;
	});

	var document = _global.document;
	// typeof document.createElement is 'object' in old IE
	var is = _isObject(document) && _isObject(document.createElement);
	var _domCreate = function (it) {
	  return is ? document.createElement(it) : {};
	};

	var _ie8DomDefine = !_descriptors && !_fails(function () {
	  return Object.defineProperty(_domCreate('div'), 'a', { get: function () { return 7; } }).a != 7;
	});

	// 7.1.1 ToPrimitive(input [, PreferredType])

	// instead of the ES6 spec version, we didn't implement @@toPrimitive case
	// and the second argument - flag - preferred type is a string
	var _toPrimitive = function (it, S) {
	  if (!_isObject(it)) { return it; }
	  var fn, val;
	  if (S && typeof (fn = it.toString) == 'function' && !_isObject(val = fn.call(it))) { return val; }
	  if (typeof (fn = it.valueOf) == 'function' && !_isObject(val = fn.call(it))) { return val; }
	  if (!S && typeof (fn = it.toString) == 'function' && !_isObject(val = fn.call(it))) { return val; }
	  throw TypeError("Can't convert object to primitive value");
	};

	var dP = Object.defineProperty;

	var f = _descriptors ? Object.defineProperty : function defineProperty(O, P, Attributes) {
	  _anObject(O);
	  P = _toPrimitive(P, true);
	  _anObject(Attributes);
	  if (_ie8DomDefine) { try {
	    return dP(O, P, Attributes);
	  } catch (e) { /* empty */ } }
	  if ('get' in Attributes || 'set' in Attributes) { throw TypeError('Accessors not supported!'); }
	  if ('value' in Attributes) { O[P] = Attributes.value; }
	  return O;
	};

	var _objectDp = {
		f: f
	};

	var _propertyDesc = function (bitmap, value) {
	  return {
	    enumerable: !(bitmap & 1),
	    configurable: !(bitmap & 2),
	    writable: !(bitmap & 4),
	    value: value
	  };
	};

	var _hide = _descriptors ? function (object, key, value) {
	  return _objectDp.f(object, key, _propertyDesc(1, value));
	} : function (object, key, value) {
	  object[key] = value;
	  return object;
	};

	var hasOwnProperty = {}.hasOwnProperty;
	var _has = function (it, key) {
	  return hasOwnProperty.call(it, key);
	};

	var id = 0;
	var px = Math.random();
	var _uid = function (key) {
	  return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36));
	};

	var _library = false;

	var _shared = createCommonjsModule(function (module) {
	var SHARED = '__core-js_shared__';
	var store = _global[SHARED] || (_global[SHARED] = {});

	(module.exports = function (key, value) {
	  return store[key] || (store[key] = value !== undefined ? value : {});
	})('versions', []).push({
	  version: _core.version,
	  mode: _library ? 'pure' : 'global',
	  copyright: '© 2019 Denis Pushkarev (zloirock.ru)'
	});
	});

	var _functionToString = _shared('native-function-to-string', Function.toString);

	var _redefine = createCommonjsModule(function (module) {
	var SRC = _uid('src');

	var TO_STRING = 'toString';
	var TPL = ('' + _functionToString).split(TO_STRING);

	_core.inspectSource = function (it) {
	  return _functionToString.call(it);
	};

	(module.exports = function (O, key, val, safe) {
	  var isFunction = typeof val == 'function';
	  if (isFunction) { _has(val, 'name') || _hide(val, 'name', key); }
	  if (O[key] === val) { return; }
	  if (isFunction) { _has(val, SRC) || _hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key))); }
	  if (O === _global) {
	    O[key] = val;
	  } else if (!safe) {
	    delete O[key];
	    _hide(O, key, val);
	  } else if (O[key]) {
	    O[key] = val;
	  } else {
	    _hide(O, key, val);
	  }
	// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative
	})(Function.prototype, TO_STRING, function toString() {
	  return typeof this == 'function' && this[SRC] || _functionToString.call(this);
	});
	});

	var _aFunction = function (it) {
	  if (typeof it != 'function') { throw TypeError(it + ' is not a function!'); }
	  return it;
	};

	// optional / simple context binding

	var _ctx = function (fn, that, length) {
	  _aFunction(fn);
	  if (that === undefined) { return fn; }
	  switch (length) {
	    case 1: return function (a) {
	      return fn.call(that, a);
	    };
	    case 2: return function (a, b) {
	      return fn.call(that, a, b);
	    };
	    case 3: return function (a, b, c) {
	      return fn.call(that, a, b, c);
	    };
	  }
	  return function (/* ...args */) {
	    return fn.apply(that, arguments);
	  };
	};

	var PROTOTYPE = 'prototype';

	var $export = function (type, name, source) {
	  var IS_FORCED = type & $export.F;
	  var IS_GLOBAL = type & $export.G;
	  var IS_STATIC = type & $export.S;
	  var IS_PROTO = type & $export.P;
	  var IS_BIND = type & $export.B;
	  var target = IS_GLOBAL ? _global : IS_STATIC ? _global[name] || (_global[name] = {}) : (_global[name] || {})[PROTOTYPE];
	  var exports = IS_GLOBAL ? _core : _core[name] || (_core[name] = {});
	  var expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {});
	  var key, own, out, exp;
	  if (IS_GLOBAL) { source = name; }
	  for (key in source) {
	    // contains in native
	    own = !IS_FORCED && target && target[key] !== undefined;
	    // export native or passed
	    out = (own ? target : source)[key];
	    // bind timers to global for call from export context
	    exp = IS_BIND && own ? _ctx(out, _global) : IS_PROTO && typeof out == 'function' ? _ctx(Function.call, out) : out;
	    // extend global
	    if (target) { _redefine(target, key, out, type & $export.U); }
	    // export
	    if (exports[key] != out) { _hide(exports, key, exp); }
	    if (IS_PROTO && expProto[key] != out) { expProto[key] = out; }
	  }
	};
	_global.core = _core;
	// type bitmap
	$export.F = 1;   // forced
	$export.G = 2;   // global
	$export.S = 4;   // static
	$export.P = 8;   // proto
	$export.B = 16;  // bind
	$export.W = 32;  // wrap
	$export.U = 64;  // safe
	$export.R = 128; // real proto method for `library`
	var _export = $export;

	// 7.1.4 ToInteger
	var ceil = Math.ceil;
	var floor = Math.floor;
	var _toInteger = function (it) {
	  return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it);
	};

	// 7.2.1 RequireObjectCoercible(argument)
	var _defined = function (it) {
	  if (it == undefined) { throw TypeError("Can't call method on  " + it); }
	  return it;
	};

	// true  -> String#at
	// false -> String#codePointAt
	var _stringAt = function (TO_STRING) {
	  return function (that, pos) {
	    var s = String(_defined(that));
	    var i = _toInteger(pos);
	    var l = s.length;
	    var a, b;
	    if (i < 0 || i >= l) { return TO_STRING ? '' : undefined; }
	    a = s.charCodeAt(i);
	    return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff
	      ? TO_STRING ? s.charAt(i) : a
	      : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000;
	  };
	};

	var $at = _stringAt(false);
	_export(_export.P, 'String', {
	  // 21.1.3.3 String.prototype.codePointAt(pos)
	  codePointAt: function codePointAt(pos) {
	    return $at(this, pos);
	  }
	});

	var codePointAt = _core.String.codePointAt;

	var max = Math.max;
	var min = Math.min;
	var _toAbsoluteIndex = function (index, length) {
	  index = _toInteger(index);
	  return index < 0 ? max(index + length, 0) : min(index, length);
	};

	var fromCharCode = String.fromCharCode;
	var $fromCodePoint = String.fromCodePoint;

	// length should be 1, old FF problem
	_export(_export.S + _export.F * (!!$fromCodePoint && $fromCodePoint.length != 1), 'String', {
	  // 21.1.2.2 String.fromCodePoint(...codePoints)
	  fromCodePoint: function fromCodePoint(x) {
	    var arguments$1 = arguments;
	 // eslint-disable-line no-unused-vars
	    var res = [];
	    var aLen = arguments.length;
	    var i = 0;
	    var code;
	    while (aLen > i) {
	      code = +arguments$1[i++];
	      if (_toAbsoluteIndex(code, 0x10ffff) !== code) { throw RangeError(code + ' is not a valid code point'); }
	      res.push(code < 0x10000
	        ? fromCharCode(code)
	        : fromCharCode(((code -= 0x10000) >> 10) + 0xd800, code % 0x400 + 0xdc00)
	      );
	    } return res.join('');
	  }
	});

	var fromCodePoint = _core.String.fromCodePoint;

	// This is a generated file. Do not edit.
	var Space_Separator = /[\u1680\u2000-\u200A\u202F\u205F\u3000]/;
	var ID_Start = /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/;
	var ID_Continue = /[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/;

	var unicode = {
		Space_Separator: Space_Separator,
		ID_Start: ID_Start,
		ID_Continue: ID_Continue
	};

	var util = {
	    isSpaceSeparator: function isSpaceSeparator (c) {
	        return typeof c === 'string' && unicode.Space_Separator.test(c)
	    },

	    isIdStartChar: function isIdStartChar (c) {
	        return typeof c === 'string' && (
	            (c >= 'a' && c <= 'z') ||
	        (c >= 'A' && c <= 'Z') ||
	        (c === '$') || (c === '_') ||
	        unicode.ID_Start.test(c)
	        )
	    },

	    isIdContinueChar: function isIdContinueChar (c) {
	        return typeof c === 'string' && (
	            (c >= 'a' && c <= 'z') ||
	        (c >= 'A' && c <= 'Z') ||
	        (c >= '0' && c <= '9') ||
	        (c === '$') || (c === '_') ||
	        (c === '\u200C') || (c === '\u200D') ||
	        unicode.ID_Continue.test(c)
	        )
	    },

	    isDigit: function isDigit (c) {
	        return typeof c === 'string' && /[0-9]/.test(c)
	    },

	    isHexDigit: function isHexDigit (c) {
	        return typeof c === 'string' && /[0-9A-Fa-f]/.test(c)
	    },
	};

	var source;
	var parseState;
	var stack;
	var pos;
	var line;
	var column;
	var token;
	var key;
	var root;

	var parse = function parse (text, reviver) {
	    source = String(text);
	    parseState = 'start';
	    stack = [];
	    pos = 0;
	    line = 1;
	    column = 0;
	    token = undefined;
	    key = undefined;
	    root = undefined;

	    do {
	        token = lex();

	        // This code is unreachable.
	        // if (!parseStates[parseState]) {
	        //     throw invalidParseState()
	        // }

	        parseStates[parseState]();
	    } while (token.type !== 'eof')

	    if (typeof reviver === 'function') {
	        return internalize({'': root}, '', reviver)
	    }

	    return root
	};

	function internalize (holder, name, reviver) {
	    var value = holder[name];
	    if (value != null && typeof value === 'object') {
	        if (Array.isArray(value)) {
	            for (var i = 0; i < value.length; i++) {
	                var key = String(i);
	                var replacement = internalize(value, key, reviver);
	                if (replacement === undefined) {
	                    delete value[key];
	                } else {
	                    Object.defineProperty(value, key, {
	                        value: replacement,
	                        writable: true,
	                        enumerable: true,
	                        configurable: true,
	                    });
	                }
	            }
	        } else {
	            for (var key$1 in value) {
	                var replacement$1 = internalize(value, key$1, reviver);
	                if (replacement$1 === undefined) {
	                    delete value[key$1];
	                } else {
	                    Object.defineProperty(value, key$1, {
	                        value: replacement$1,
	                        writable: true,
	                        enumerable: true,
	                        configurable: true,
	                    });
	                }
	            }
	        }
	    }

	    return reviver.call(holder, name, value)
	}

	var lexState;
	var buffer;
	var doubleQuote;
	var sign;
	var c;

	function lex () {
	    lexState = 'default';
	    buffer = '';
	    doubleQuote = false;
	    sign = 1;

	    for (;;) {
	        c = peek();

	        // This code is unreachable.
	        // if (!lexStates[lexState]) {
	        //     throw invalidLexState(lexState)
	        // }

	        var token = lexStates[lexState]();
	        if (token) {
	            return token
	        }
	    }
	}

	function peek () {
	    if (source[pos]) {
	        return String.fromCodePoint(source.codePointAt(pos))
	    }
	}

	function read () {
	    var c = peek();

	    if (c === '\n') {
	        line++;
	        column = 0;
	    } else if (c) {
	        column += c.length;
	    } else {
	        column++;
	    }

	    if (c) {
	        pos += c.length;
	    }

	    return c
	}

	var lexStates = {
	    default: function default$1 () {
	        switch (c) {
	        case '\t':
	        case '\v':
	        case '\f':
	        case ' ':
	        case '\u00A0':
	        case '\uFEFF':
	        case '\n':
	        case '\r':
	        case '\u2028':
	        case '\u2029':
	            read();
	            return

	        case '/':
	            read();
	            lexState = 'comment';
	            return

	        case undefined:
	            read();
	            return newToken('eof')
	        }

	        if (util.isSpaceSeparator(c)) {
	            read();
	            return
	        }

	        // This code is unreachable.
	        // if (!lexStates[parseState]) {
	        //     throw invalidLexState(parseState)
	        // }

	        return lexStates[parseState]()
	    },

	    comment: function comment () {
	        switch (c) {
	        case '*':
	            read();
	            lexState = 'multiLineComment';
	            return

	        case '/':
	            read();
	            lexState = 'singleLineComment';
	            return
	        }

	        throw invalidChar(read())
	    },

	    multiLineComment: function multiLineComment () {
	        switch (c) {
	        case '*':
	            read();
	            lexState = 'multiLineCommentAsterisk';
	            return

	        case undefined:
	            throw invalidChar(read())
	        }

	        read();
	    },

	    multiLineCommentAsterisk: function multiLineCommentAsterisk () {
	        switch (c) {
	        case '*':
	            read();
	            return

	        case '/':
	            read();
	            lexState = 'default';
	            return

	        case undefined:
	            throw invalidChar(read())
	        }

	        read();
	        lexState = 'multiLineComment';
	    },

	    singleLineComment: function singleLineComment () {
	        switch (c) {
	        case '\n':
	        case '\r':
	        case '\u2028':
	        case '\u2029':
	            read();
	            lexState = 'default';
	            return

	        case undefined:
	            read();
	            return newToken('eof')
	        }

	        read();
	    },

	    value: function value () {
	        switch (c) {
	        case '{':
	        case '[':
	            return newToken('punctuator', read())

	        case 'n':
	            read();
	            literal('ull');
	            return newToken('null', null)

	        case 't':
	            read();
	            literal('rue');
	            return newToken('boolean', true)

	        case 'f':
	            read();
	            literal('alse');
	            return newToken('boolean', false)

	        case '-':
	        case '+':
	            if (read() === '-') {
	                sign = -1;
	            }

	            lexState = 'sign';
	            return

	        case '.':
	            buffer = read();
	            lexState = 'decimalPointLeading';
	            return

	        case '0':
	            buffer = read();
	            lexState = 'zero';
	            return

	        case '1':
	        case '2':
	        case '3':
	        case '4':
	        case '5':
	        case '6':
	        case '7':
	        case '8':
	        case '9':
	            buffer = read();
	            lexState = 'decimalInteger';
	            return

	        case 'I':
	            read();
	            literal('nfinity');
	            return newToken('numeric', Infinity)

	        case 'N':
	            read();
	            literal('aN');
	            return newToken('numeric', NaN)

	        case '"':
	        case "'":
	            doubleQuote = (read() === '"');
	            buffer = '';
	            lexState = 'string';
	            return
	        }

	        throw invalidChar(read())
	    },

	    identifierNameStartEscape: function identifierNameStartEscape () {
	        if (c !== 'u') {
	            throw invalidChar(read())
	        }

	        read();
	        var u = unicodeEscape();
	        switch (u) {
	        case '$':
	        case '_':
	            break

	        default:
	            if (!util.isIdStartChar(u)) {
	                throw invalidIdentifier()
	            }

	            break
	        }

	        buffer += u;
	        lexState = 'identifierName';
	    },

	    identifierName: function identifierName () {
	        switch (c) {
	        case '$':
	        case '_':
	        case '\u200C':
	        case '\u200D':
	            buffer += read();
	            return

	        case '\\':
	            read();
	            lexState = 'identifierNameEscape';
	            return
	        }

	        if (util.isIdContinueChar(c)) {
	            buffer += read();
	            return
	        }

	        return newToken('identifier', buffer)
	    },

	    identifierNameEscape: function identifierNameEscape () {
	        if (c !== 'u') {
	            throw invalidChar(read())
	        }

	        read();
	        var u = unicodeEscape();
	        switch (u) {
	        case '$':
	        case '_':
	        case '\u200C':
	        case '\u200D':
	            break

	        default:
	            if (!util.isIdContinueChar(u)) {
	                throw invalidIdentifier()
	            }

	            break
	        }

	        buffer += u;
	        lexState = 'identifierName';
	    },

	    sign: function sign$1 () {
	        switch (c) {
	        case '.':
	            buffer = read();
	            lexState = 'decimalPointLeading';
	            return

	        case '0':
	            buffer = read();
	            lexState = 'zero';
	            return

	        case '1':
	        case '2':
	        case '3':
	        case '4':
	        case '5':
	        case '6':
	        case '7':
	        case '8':
	        case '9':
	            buffer = read();
	            lexState = 'decimalInteger';
	            return

	        case 'I':
	            read();
	            literal('nfinity');
	            return newToken('numeric', sign * Infinity)

	        case 'N':
	            read();
	            literal('aN');
	            return newToken('numeric', NaN)
	        }

	        throw invalidChar(read())
	    },

	    zero: function zero () {
	        switch (c) {
	        case '.':
	            buffer += read();
	            lexState = 'decimalPoint';
	            return

	        case 'e':
	        case 'E':
	            buffer += read();
	            lexState = 'decimalExponent';
	            return

	        case 'x':
	        case 'X':
	            buffer += read();
	            lexState = 'hexadecimal';
	            return
	        }

	        return newToken('numeric', sign * 0)
	    },

	    decimalInteger: function decimalInteger () {
	        switch (c) {
	        case '.':
	            buffer += read();
	            lexState = 'decimalPoint';
	            return

	        case 'e':
	        case 'E':
	            buffer += read();
	            lexState = 'decimalExponent';
	            return
	        }

	        if (util.isDigit(c)) {
	            buffer += read();
	            return
	        }

	        return newToken('numeric', sign * Number(buffer))
	    },

	    decimalPointLeading: function decimalPointLeading () {
	        if (util.isDigit(c)) {
	            buffer += read();
	            lexState = 'decimalFraction';
	            return
	        }

	        throw invalidChar(read())
	    },

	    decimalPoint: function decimalPoint () {
	        switch (c) {
	        case 'e':
	        case 'E':
	            buffer += read();
	            lexState = 'decimalExponent';
	            return
	        }

	        if (util.isDigit(c)) {
	            buffer += read();
	            lexState = 'decimalFraction';
	            return
	        }

	        return newToken('numeric', sign * Number(buffer))
	    },

	    decimalFraction: function decimalFraction () {
	        switch (c) {
	        case 'e':
	        case 'E':
	            buffer += read();
	            lexState = 'decimalExponent';
	            return
	        }

	        if (util.isDigit(c)) {
	            buffer += read();
	            return
	        }

	        return newToken('numeric', sign * Number(buffer))
	    },

	    decimalExponent: function decimalExponent () {
	        switch (c) {
	        case '+':
	        case '-':
	            buffer += read();
	            lexState = 'decimalExponentSign';
	            return
	        }

	        if (util.isDigit(c)) {
	            buffer += read();
	            lexState = 'decimalExponentInteger';
	            return
	        }

	        throw invalidChar(read())
	    },

	    decimalExponentSign: function decimalExponentSign () {
	        if (util.isDigit(c)) {
	            buffer += read();
	            lexState = 'decimalExponentInteger';
	            return
	        }

	        throw invalidChar(read())
	    },

	    decimalExponentInteger: function decimalExponentInteger () {
	        if (util.isDigit(c)) {
	            buffer += read();
	            return
	        }

	        return newToken('numeric', sign * Number(buffer))
	    },

	    hexadecimal: function hexadecimal () {
	        if (util.isHexDigit(c)) {
	            buffer += read();
	            lexState = 'hexadecimalInteger';
	            return
	        }

	        throw invalidChar(read())
	    },

	    hexadecimalInteger: function hexadecimalInteger () {
	        if (util.isHexDigit(c)) {
	            buffer += read();
	            return
	        }

	        return newToken('numeric', sign * Number(buffer))
	    },

	    string: function string () {
	        switch (c) {
	        case '\\':
	            read();
	            buffer += escape();
	            return

	        case '"':
	            if (doubleQuote) {
	                read();
	                return newToken('string', buffer)
	            }

	            buffer += read();
	            return

	        case "'":
	            if (!doubleQuote) {
	                read();
	                return newToken('string', buffer)
	            }

	            buffer += read();
	            return

	        case '\n':
	        case '\r':
	            throw invalidChar(read())

	        case '\u2028':
	        case '\u2029':
	            separatorChar(c);
	            break

	        case undefined:
	            throw invalidChar(read())
	        }

	        buffer += read();
	    },

	    start: function start () {
	        switch (c) {
	        case '{':
	        case '[':
	            return newToken('punctuator', read())

	        // This code is unreachable since the default lexState handles eof.
	        // case undefined:
	        //     return newToken('eof')
	        }

	        lexState = 'value';
	    },

	    beforePropertyName: function beforePropertyName () {
	        switch (c) {
	        case '$':
	        case '_':
	            buffer = read();
	            lexState = 'identifierName';
	            return

	        case '\\':
	            read();
	            lexState = 'identifierNameStartEscape';
	            return

	        case '}':
	            return newToken('punctuator', read())

	        case '"':
	        case "'":
	            doubleQuote = (read() === '"');
	            lexState = 'string';
	            return
	        }

	        if (util.isIdStartChar(c)) {
	            buffer += read();
	            lexState = 'identifierName';
	            return
	        }

	        throw invalidChar(read())
	    },

	    afterPropertyName: function afterPropertyName () {
	        if (c === ':') {
	            return newToken('punctuator', read())
	        }

	        throw invalidChar(read())
	    },

	    beforePropertyValue: function beforePropertyValue () {
	        lexState = 'value';
	    },

	    afterPropertyValue: function afterPropertyValue () {
	        switch (c) {
	        case ',':
	        case '}':
	            return newToken('punctuator', read())
	        }

	        throw invalidChar(read())
	    },

	    beforeArrayValue: function beforeArrayValue () {
	        if (c === ']') {
	            return newToken('punctuator', read())
	        }

	        lexState = 'value';
	    },

	    afterArrayValue: function afterArrayValue () {
	        switch (c) {
	        case ',':
	        case ']':
	            return newToken('punctuator', read())
	        }

	        throw invalidChar(read())
	    },

	    end: function end () {
	        // This code is unreachable since it's handled by the default lexState.
	        // if (c === undefined) {
	        //     read()
	        //     return newToken('eof')
	        // }

	        throw invalidChar(read())
	    },
	};

	function newToken (type, value) {
	    return {
	        type: type,
	        value: value,
	        line: line,
	        column: column,
	    }
	}

	function literal (s) {
	    for (var i = 0, list = s; i < list.length; i += 1) {
	        var c = list[i];

	        var p = peek();

	        if (p !== c) {
	            throw invalidChar(read())
	        }

	        read();
	    }
	}

	function escape () {
	    var c = peek();
	    switch (c) {
	    case 'b':
	        read();
	        return '\b'

	    case 'f':
	        read();
	        return '\f'

	    case 'n':
	        read();
	        return '\n'

	    case 'r':
	        read();
	        return '\r'

	    case 't':
	        read();
	        return '\t'

	    case 'v':
	        read();
	        return '\v'

	    case '0':
	        read();
	        if (util.isDigit(peek())) {
	            throw invalidChar(read())
	        }

	        return '\0'

	    case 'x':
	        read();
	        return hexEscape()

	    case 'u':
	        read();
	        return unicodeEscape()

	    case '\n':
	    case '\u2028':
	    case '\u2029':
	        read();
	        return ''

	    case '\r':
	        read();
	        if (peek() === '\n') {
	            read();
	        }

	        return ''

	    case '1':
	    case '2':
	    case '3':
	    case '4':
	    case '5':
	    case '6':
	    case '7':
	    case '8':
	    case '9':
	        throw invalidChar(read())

	    case undefined:
	        throw invalidChar(read())
	    }

	    return read()
	}

	function hexEscape () {
	    var buffer = '';
	    var c = peek();

	    if (!util.isHexDigit(c)) {
	        throw invalidChar(read())
	    }

	    buffer += read();

	    c = peek();
	    if (!util.isHexDigit(c)) {
	        throw invalidChar(read())
	    }

	    buffer += read();

	    return String.fromCodePoint(parseInt(buffer, 16))
	}

	function unicodeEscape () {
	    var buffer = '';
	    var count = 4;

	    while (count-- > 0) {
	        var c = peek();
	        if (!util.isHexDigit(c)) {
	            throw invalidChar(read())
	        }

	        buffer += read();
	    }

	    return String.fromCodePoint(parseInt(buffer, 16))
	}

	var parseStates = {
	    start: function start () {
	        if (token.type === 'eof') {
	            throw invalidEOF()
	        }

	        push();
	    },

	    beforePropertyName: function beforePropertyName () {
	        switch (token.type) {
	        case 'identifier':
	        case 'string':
	            key = token.value;
	            parseState = 'afterPropertyName';
	            return

	        case 'punctuator':
	            // This code is unreachable since it's handled by the lexState.
	            // if (token.value !== '}') {
	            //     throw invalidToken()
	            // }

	            pop();
	            return

	        case 'eof':
	            throw invalidEOF()
	        }

	        // This code is unreachable since it's handled by the lexState.
	        // throw invalidToken()
	    },

	    afterPropertyName: function afterPropertyName () {
	        // This code is unreachable since it's handled by the lexState.
	        // if (token.type !== 'punctuator' || token.value !== ':') {
	        //     throw invalidToken()
	        // }

	        if (token.type === 'eof') {
	            throw invalidEOF()
	        }

	        parseState = 'beforePropertyValue';
	    },

	    beforePropertyValue: function beforePropertyValue () {
	        if (token.type === 'eof') {
	            throw invalidEOF()
	        }

	        push();
	    },

	    beforeArrayValue: function beforeArrayValue () {
	        if (token.type === 'eof') {
	            throw invalidEOF()
	        }

	        if (token.type === 'punctuator' && token.value === ']') {
	            pop();
	            return
	        }

	        push();
	    },

	    afterPropertyValue: function afterPropertyValue () {
	        // This code is unreachable since it's handled by the lexState.
	        // if (token.type !== 'punctuator') {
	        //     throw invalidToken()
	        // }

	        if (token.type === 'eof') {
	            throw invalidEOF()
	        }

	        switch (token.value) {
	        case ',':
	            parseState = 'beforePropertyName';
	            return

	        case '}':
	            pop();
	        }

	        // This code is unreachable since it's handled by the lexState.
	        // throw invalidToken()
	    },

	    afterArrayValue: function afterArrayValue () {
	        // This code is unreachable since it's handled by the lexState.
	        // if (token.type !== 'punctuator') {
	        //     throw invalidToken()
	        // }

	        if (token.type === 'eof') {
	            throw invalidEOF()
	        }

	        switch (token.value) {
	        case ',':
	            parseState = 'beforeArrayValue';
	            return

	        case ']':
	            pop();
	        }

	        // This code is unreachable since it's handled by the lexState.
	        // throw invalidToken()
	    },

	    end: function end () {
	        // This code is unreachable since it's handled by the lexState.
	        // if (token.type !== 'eof') {
	        //     throw invalidToken()
	        // }
	    },
	};

	function push () {
	    var value;

	    switch (token.type) {
	    case 'punctuator':
	        switch (token.value) {
	        case '{':
	            value = {};
	            break

	        case '[':
	            value = [];
	            break
	        }

	        break

	    case 'null':
	    case 'boolean':
	    case 'numeric':
	    case 'string':
	        value = token.value;
	        break

	    // This code is unreachable.
	    // default:
	    //     throw invalidToken()
	    }

	    if (root === undefined) {
	        root = value;
	    } else {
	        var parent = stack[stack.length - 1];
	        if (Array.isArray(parent)) {
	            parent.push(value);
	        } else {
	            Object.defineProperty(parent, key, {
	                value: value,
	                writable: true,
	                enumerable: true,
	                configurable: true,
	            });
	        }
	    }

	    if (value !== null && typeof value === 'object') {
	        stack.push(value);

	        if (Array.isArray(value)) {
	            parseState = 'beforeArrayValue';
	        } else {
	            parseState = 'beforePropertyName';
	        }
	    } else {
	        var current = stack[stack.length - 1];
	        if (current == null) {
	            parseState = 'end';
	        } else if (Array.isArray(current)) {
	            parseState = 'afterArrayValue';
	        } else {
	            parseState = 'afterPropertyValue';
	        }
	    }
	}

	function pop () {
	    stack.pop();

	    var current = stack[stack.length - 1];
	    if (current == null) {
	        parseState = 'end';
	    } else if (Array.isArray(current)) {
	        parseState = 'afterArrayValue';
	    } else {
	        parseState = 'afterPropertyValue';
	    }
	}

	// This code is unreachable.
	// function invalidParseState () {
	//     return new Error(`JSON5: invalid parse state '${parseState}'`)
	// }

	// This code is unreachable.
	// function invalidLexState (state) {
	//     return new Error(`JSON5: invalid lex state '${state}'`)
	// }

	function invalidChar (c) {
	    if (c === undefined) {
	        return syntaxError(("JSON5: invalid end of input at " + line + ":" + column))
	    }

	    return syntaxError(("JSON5: invalid character '" + (formatChar(c)) + "' at " + line + ":" + column))
	}

	function invalidEOF () {
	    return syntaxError(("JSON5: invalid end of input at " + line + ":" + column))
	}

	// This code is unreachable.
	// function invalidToken () {
	//     if (token.type === 'eof') {
	//         return syntaxError(`JSON5: invalid end of input at ${line}:${column}`)
	//     }

	//     const c = String.fromCodePoint(token.value.codePointAt(0))
	//     return syntaxError(`JSON5: invalid character '${formatChar(c)}' at ${line}:${column}`)
	// }

	function invalidIdentifier () {
	    column -= 5;
	    return syntaxError(("JSON5: invalid identifier character at " + line + ":" + column))
	}

	function separatorChar (c) {
	    console.warn(("JSON5: '" + (formatChar(c)) + "' in strings is not valid ECMAScript; consider escaping"));
	}

	function formatChar (c) {
	    var replacements = {
	        "'": "\\'",
	        '"': '\\"',
	        '\\': '\\\\',
	        '\b': '\\b',
	        '\f': '\\f',
	        '\n': '\\n',
	        '\r': '\\r',
	        '\t': '\\t',
	        '\v': '\\v',
	        '\0': '\\0',
	        '\u2028': '\\u2028',
	        '\u2029': '\\u2029',
	    };

	    if (replacements[c]) {
	        return replacements[c]
	    }

	    if (c < ' ') {
	        var hexString = c.charCodeAt(0).toString(16);
	        return '\\x' + ('00' + hexString).substring(hexString.length)
	    }

	    return c
	}

	function syntaxError (message) {
	    var err = new SyntaxError(message);
	    err.lineNumber = line;
	    err.columnNumber = column;
	    return err
	}

	var stringify = function stringify (value, replacer, space) {
	    var stack = [];
	    var indent = '';
	    var propertyList;
	    var replacerFunc;
	    var gap = '';
	    var quote;

	    if (
	        replacer != null &&
	        typeof replacer === 'object' &&
	        !Array.isArray(replacer)
	    ) {
	        space = replacer.space;
	        quote = replacer.quote;
	        replacer = replacer.replacer;
	    }

	    if (typeof replacer === 'function') {
	        replacerFunc = replacer;
	    } else if (Array.isArray(replacer)) {
	        propertyList = [];
	        for (var i = 0, list = replacer; i < list.length; i += 1) {
	            var v = list[i];

	            var item = (void 0);

	            if (typeof v === 'string') {
	                item = v;
	            } else if (
	                typeof v === 'number' ||
	                v instanceof String ||
	                v instanceof Number
	            ) {
	                item = String(v);
	            }

	            if (item !== undefined && propertyList.indexOf(item) < 0) {
	                propertyList.push(item);
	            }
	        }
	    }

	    if (space instanceof Number) {
	        space = Number(space);
	    } else if (space instanceof String) {
	        space = String(space);
	    }

	    if (typeof space === 'number') {
	        if (space > 0) {
	            space = Math.min(10, Math.floor(space));
	            gap = '          '.substr(0, space);
	        }
	    } else if (typeof space === 'string') {
	        gap = space.substr(0, 10);
	    }

	    return serializeProperty('', {'': value})

	    function serializeProperty (key, holder) {
	        var value = holder[key];
	        if (value != null) {
	            if (typeof value.toJSON5 === 'function') {
	                value = value.toJSON5(key);
	            } else if (typeof value.toJSON === 'function') {
	                value = value.toJSON(key);
	            }
	        }

	        if (replacerFunc) {
	            value = replacerFunc.call(holder, key, value);
	        }

	        if (value instanceof Number) {
	            value = Number(value);
	        } else if (value instanceof String) {
	            value = String(value);
	        } else if (value instanceof Boolean) {
	            value = value.valueOf();
	        }

	        switch (value) {
	        case null: return 'null'
	        case true: return 'true'
	        case false: return 'false'
	        }

	        if (typeof value === 'string') {
	            return quoteString(value, false)
	        }

	        if (typeof value === 'number') {
	            return String(value)
	        }

	        if (typeof value === 'object') {
	            return Array.isArray(value) ? serializeArray(value) : serializeObject(value)
	        }

	        return undefined
	    }

	    function quoteString (value) {
	        var quotes = {
	            "'": 0.1,
	            '"': 0.2,
	        };

	        var replacements = {
	            "'": "\\'",
	            '"': '\\"',
	            '\\': '\\\\',
	            '\b': '\\b',
	            '\f': '\\f',
	            '\n': '\\n',
	            '\r': '\\r',
	            '\t': '\\t',
	            '\v': '\\v',
	            '\0': '\\0',
	            '\u2028': '\\u2028',
	            '\u2029': '\\u2029',
	        };

	        var product = '';

	        for (var i = 0; i < value.length; i++) {
	            var c = value[i];
	            switch (c) {
	            case "'":
	            case '"':
	                quotes[c]++;
	                product += c;
	                continue

	            case '\0':
	                if (util.isDigit(value[i + 1])) {
	                    product += '\\x00';
	                    continue
	                }
	            }

	            if (replacements[c]) {
	                product += replacements[c];
	                continue
	            }

	            if (c < ' ') {
	                var hexString = c.charCodeAt(0).toString(16);
	                product += '\\x' + ('00' + hexString).substring(hexString.length);
	                continue
	            }

	            product += c;
	        }

	        var quoteChar = quote || Object.keys(quotes).reduce(function (a, b) { return (quotes[a] < quotes[b]) ? a : b; });

	        product = product.replace(new RegExp(quoteChar, 'g'), replacements[quoteChar]);

	        return quoteChar + product + quoteChar
	    }

	    function serializeObject (value) {
	        if (stack.indexOf(value) >= 0) {
	            throw TypeError('Converting circular structure to JSON5')
	        }

	        stack.push(value);

	        var stepback = indent;
	        indent = indent + gap;

	        var keys = propertyList || Object.keys(value);
	        var partial = [];
	        for (var i = 0, list = keys; i < list.length; i += 1) {
	            var key = list[i];

	            var propertyString = serializeProperty(key, value);
	            if (propertyString !== undefined) {
	                var member = serializeKey(key) + ':';
	                if (gap !== '') {
	                    member += ' ';
	                }
	                member += propertyString;
	                partial.push(member);
	            }
	        }

	        var final;
	        if (partial.length === 0) {
	            final = '{}';
	        } else {
	            var properties;
	            if (gap === '') {
	                properties = partial.join(',');
	                final = '{' + properties + '}';
	            } else {
	                var separator = ',\n' + indent;
	                properties = partial.join(separator);
	                final = '{\n' + indent + properties + ',\n' + stepback + '}';
	            }
	        }

	        stack.pop();
	        indent = stepback;
	        return final
	    }

	    function serializeKey (key) {
	        if (key.length === 0) {
	            return quoteString(key, true)
	        }

	        var firstChar = String.fromCodePoint(key.codePointAt(0));
	        if (!util.isIdStartChar(firstChar)) {
	            return quoteString(key, true)
	        }

	        for (var i = firstChar.length; i < key.length; i++) {
	            if (!util.isIdContinueChar(String.fromCodePoint(key.codePointAt(i)))) {
	                return quoteString(key, true)
	            }
	        }

	        return key
	    }

	    function serializeArray (value) {
	        if (stack.indexOf(value) >= 0) {
	            throw TypeError('Converting circular structure to JSON5')
	        }

	        stack.push(value);

	        var stepback = indent;
	        indent = indent + gap;

	        var partial = [];
	        for (var i = 0; i < value.length; i++) {
	            var propertyString = serializeProperty(String(i), value);
	            partial.push((propertyString !== undefined) ? propertyString : 'null');
	        }

	        var final;
	        if (partial.length === 0) {
	            final = '[]';
	        } else {
	            if (gap === '') {
	                var properties = partial.join(',');
	                final = '[' + properties + ']';
	            } else {
	                var separator = ',\n' + indent;
	                var properties$1 = partial.join(separator);
	                final = '[\n' + indent + properties$1 + ',\n' + stepback + ']';
	            }
	        }

	        stack.pop();
	        indent = stepback;
	        return final
	    }
	};

	var JSON5 = {
	    parse: parse,
	    stringify: stringify,
	};

	var lib = JSON5;

	var es5 = lib;

	return es5;

})));


/***/ }),

/***/ 73378:
/***/ ((module) => {

var toString = Object.prototype.toString;

module.exports = function kindOf(val) {
  if (val === void 0) return 'undefined';
  if (val === null) return 'null';

  var type = typeof val;
  if (type === 'boolean') return 'boolean';
  if (type === 'string') return 'string';
  if (type === 'number') return 'number';
  if (type === 'symbol') return 'symbol';
  if (type === 'function') {
    return isGeneratorFn(val) ? 'generatorfunction' : 'function';
  }

  if (isArray(val)) return 'array';
  if (isBuffer(val)) return 'buffer';
  if (isArguments(val)) return 'arguments';
  if (isDate(val)) return 'date';
  if (isError(val)) return 'error';
  if (isRegexp(val)) return 'regexp';

  switch (ctorName(val)) {
    case 'Symbol': return 'symbol';
    case 'Promise': return 'promise';

    // Set, Map, WeakSet, WeakMap
    case 'WeakMap': return 'weakmap';
    case 'WeakSet': return 'weakset';
    case 'Map': return 'map';
    case 'Set': return 'set';

    // 8-bit typed arrays
    case 'Int8Array': return 'int8array';
    case 'Uint8Array': return 'uint8array';
    case 'Uint8ClampedArray': return 'uint8clampedarray';

    // 16-bit typed arrays
    case 'Int16Array': return 'int16array';
    case 'Uint16Array': return 'uint16array';

    // 32-bit typed arrays
    case 'Int32Array': return 'int32array';
    case 'Uint32Array': return 'uint32array';
    case 'Float32Array': return 'float32array';
    case 'Float64Array': return 'float64array';
  }

  if (isGeneratorObj(val)) {
    return 'generator';
  }

  // Non-plain objects
  type = toString.call(val);
  switch (type) {
    case '[object Object]': return 'object';
    // iterators
    case '[object Map Iterator]': return 'mapiterator';
    case '[object Set Iterator]': return 'setiterator';
    case '[object String Iterator]': return 'stringiterator';
    case '[object Array Iterator]': return 'arrayiterator';
  }

  // other
  return type.slice(8, -1).toLowerCase().replace(/\s/g, '');
};

function ctorName(val) {
  return typeof val.constructor === 'function' ? val.constructor.name : null;
}

function isArray(val) {
  if (Array.isArray) return Array.isArray(val);
  return val instanceof Array;
}

function isError(val) {
  return val instanceof Error || (typeof val.message === 'string' && val.constructor && typeof val.constructor.stackTraceLimit === 'number');
}

function isDate(val) {
  if (val instanceof Date) return true;
  return typeof val.toDateString === 'function'
    && typeof val.getDate === 'function'
    && typeof val.setDate === 'function';
}

function isRegexp(val) {
  if (val instanceof RegExp) return true;
  return typeof val.flags === 'string'
    && typeof val.ignoreCase === 'boolean'
    && typeof val.multiline === 'boolean'
    && typeof val.global === 'boolean';
}

function isGeneratorFn(name, val) {
  return ctorName(name) === 'GeneratorFunction';
}

function isGeneratorObj(val) {
  return typeof val.throw === 'function'
    && typeof val.return === 'function'
    && typeof val.next === 'function';
}

function isArguments(val) {
  try {
    if (typeof val.length === 'number' && typeof val.callee === 'function') {
      return true;
    }
  } catch (err) {
    if (err.message.indexOf('callee') !== -1) {
      return true;
    }
  }
  return false;
}

/**
 * If you need to support Safari 5-7 (8-10 yr-old browser),
 * take a look at https://github.com/feross/is-buffer
 */

function isBuffer(val) {
  if (val.constructor && typeof val.constructor.isBuffer === 'function') {
    return val.constructor.isBuffer(val);
  }
  return false;
}


/***/ }),

/***/ 61583:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

const debug = __webpack_require__(58584)
const { MAX_LENGTH, MAX_SAFE_INTEGER } = __webpack_require__(99596)
const { safeRe: re, t } = __webpack_require__(70845)

const parseOptions = __webpack_require__(92904)
const { compareIdentifiers } = __webpack_require__(88540)
class SemVer {
  constructor (version, options) {
    options = parseOptions(options)

    if (version instanceof SemVer) {
      if (version.loose === !!options.loose &&
          version.includePrerelease === !!options.includePrerelease) {
        return version
      } else {
        version = version.version
      }
    } else if (typeof version !== 'string') {
      throw new TypeError(`Invalid version. Must be a string. Got type "${typeof version}".`)
    }

    if (version.length > MAX_LENGTH) {
      throw new TypeError(
        `version is longer than ${MAX_LENGTH} characters`
      )
    }

    debug('SemVer', version, options)
    this.options = options
    this.loose = !!options.loose
    // this isn't actually relevant for versions, but keep it so that we
    // don't run into trouble passing this.options around.
    this.includePrerelease = !!options.includePrerelease

    const m = version.trim().match(options.loose ? re[t.LOOSE] : re[t.FULL])

    if (!m) {
      throw new TypeError(`Invalid Version: ${version}`)
    }

    this.raw = version

    // these are actually numbers
    this.major = +m[1]
    this.minor = +m[2]
    this.patch = +m[3]

    if (this.major > MAX_SAFE_INTEGER || this.major < 0) {
      throw new TypeError('Invalid major version')
    }

    if (this.minor > MAX_SAFE_INTEGER || this.minor < 0) {
      throw new TypeError('Invalid minor version')
    }

    if (this.patch > MAX_SAFE_INTEGER || this.patch < 0) {
      throw new TypeError('Invalid patch version')
    }

    // numberify any prerelease numeric ids
    if (!m[4]) {
      this.prerelease = []
    } else {
      this.prerelease = m[4].split('.').map((id) => {
        if (/^[0-9]+$/.test(id)) {
          const num = +id
          if (num >= 0 && num < MAX_SAFE_INTEGER) {
            return num
          }
        }
        return id
      })
    }

    this.build = m[5] ? m[5].split('.') : []
    this.format()
  }

  format () {
    this.version = `${this.major}.${this.minor}.${this.patch}`
    if (this.prerelease.length) {
      this.version += `-${this.prerelease.join('.')}`
    }
    return this.version
  }

  toString () {
    return this.version
  }

  compare (other) {
    debug('SemVer.compare', this.version, this.options, other)
    if (!(other instanceof SemVer)) {
      if (typeof other === 'string' && other === this.version) {
        return 0
      }
      other = new SemVer(other, this.options)
    }

    if (other.version === this.version) {
      return 0
    }

    return this.compareMain(other) || this.comparePre(other)
  }

  compareMain (other) {
    if (!(other instanceof SemVer)) {
      other = new SemVer(other, this.options)
    }

    return (
      compareIdentifiers(this.major, other.major) ||
      compareIdentifiers(this.minor, other.minor) ||
      compareIdentifiers(this.patch, other.patch)
    )
  }

  comparePre (other) {
    if (!(other instanceof SemVer)) {
      other = new SemVer(other, this.options)
    }

    // NOT having a prerelease is > having one
    if (this.prerelease.length && !other.prerelease.length) {
      return -1
    } else if (!this.prerelease.length && other.prerelease.length) {
      return 1
    } else if (!this.prerelease.length && !other.prerelease.length) {
      return 0
    }

    let i = 0
    do {
      const a = this.prerelease[i]
      const b = other.prerelease[i]
      debug('prerelease compare', i, a, b)
      if (a === undefined && b === undefined) {
        return 0
      } else if (b === undefined) {
        return 1
      } else if (a === undefined) {
        return -1
      } else if (a === b) {
        continue
      } else {
        return compareIdentifiers(a, b)
      }
    } while (++i)
  }

  compareBuild (other) {
    if (!(other instanceof SemVer)) {
      other = new SemVer(other, this.options)
    }

    let i = 0
    do {
      const a = this.build[i]
      const b = other.build[i]
      debug('build compare', i, a, b)
      if (a === undefined && b === undefined) {
        return 0
      } else if (b === undefined) {
        return 1
      } else if (a === undefined) {
        return -1
      } else if (a === b) {
        continue
      } else {
        return compareIdentifiers(a, b)
      }
    } while (++i)
  }

  // preminor will bump the version up to the next minor release, and immediately
  // down to pre-release. premajor and prepatch work the same way.
  inc (release, identifier, identifierBase) {
    switch (release) {
      case 'premajor':
        this.prerelease.length = 0
        this.patch = 0
        this.minor = 0
        this.major++
        this.inc('pre', identifier, identifierBase)
        break
      case 'preminor':
        this.prerelease.length = 0
        this.patch = 0
        this.minor++
        this.inc('pre', identifier, identifierBase)
        break
      case 'prepatch':
        // If this is already a prerelease, it will bump to the next version
        // drop any prereleases that might already exist, since they are not
        // relevant at this point.
        this.prerelease.length = 0
        this.inc('patch', identifier, identifierBase)
        this.inc('pre', identifier, identifierBase)
        break
      // If the input is a non-prerelease version, this acts the same as
      // prepatch.
      case 'prerelease':
        if (this.prerelease.length === 0) {
          this.inc('patch', identifier, identifierBase)
        }
        this.inc('pre', identifier, identifierBase)
        break

      case 'major':
        // If this is a pre-major version, bump up to the same major version.
        // Otherwise increment major.
        // 1.0.0-5 bumps to 1.0.0
        // 1.1.0 bumps to 2.0.0
        if (
          this.minor !== 0 ||
          this.patch !== 0 ||
          this.prerelease.length === 0
        ) {
          this.major++
        }
        this.minor = 0
        this.patch = 0
        this.prerelease = []
        break
      case 'minor':
        // If this is a pre-minor version, bump up to the same minor version.
        // Otherwise increment minor.
        // 1.2.0-5 bumps to 1.2.0
        // 1.2.1 bumps to 1.3.0
        if (this.patch !== 0 || this.prerelease.length === 0) {
          this.minor++
        }
        this.patch = 0
        this.prerelease = []
        break
      case 'patch':
        // If this is not a pre-release version, it will increment the patch.
        // If it is a pre-release it will bump up to the same patch version.
        // 1.2.0-5 patches to 1.2.0
        // 1.2.0 patches to 1.2.1
        if (this.prerelease.length === 0) {
          this.patch++
        }
        this.prerelease = []
        break
      // This probably shouldn't be used publicly.
      // 1.0.0 'pre' would become 1.0.0-0 which is the wrong direction.
      case 'pre': {
        const base = Number(identifierBase) ? 1 : 0

        if (!identifier && identifierBase === false) {
          throw new Error('invalid increment argument: identifier is empty')
        }

        if (this.prerelease.length === 0) {
          this.prerelease = [base]
        } else {
          let i = this.prerelease.length
          while (--i >= 0) {
            if (typeof this.prerelease[i] === 'number') {
              this.prerelease[i]++
              i = -2
            }
          }
          if (i === -1) {
            // didn't increment anything
            if (identifier === this.prerelease.join('.') && identifierBase === false) {
              throw new Error('invalid increment argument: identifier already exists')
            }
            this.prerelease.push(base)
          }
        }
        if (identifier) {
          // 1.2.0-beta.1 bumps to 1.2.0-beta.2,
          // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0
          let prerelease = [identifier, base]
          if (identifierBase === false) {
            prerelease = [identifier]
          }
          if (compareIdentifiers(this.prerelease[0], identifier) === 0) {
            if (isNaN(this.prerelease[1])) {
              this.prerelease = prerelease
            }
          } else {
            this.prerelease = prerelease
          }
        }
        break
      }
      default:
        throw new Error(`invalid increment argument: ${release}`)
    }
    this.raw = this.format()
    if (this.build.length) {
      this.raw += `+${this.build.join('.')}`
    }
    return this
  }
}

module.exports = SemVer


/***/ }),

/***/ 81950:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

const SemVer = __webpack_require__(61583)
const parse = __webpack_require__(84195)
const { safeRe: re, t } = __webpack_require__(70845)

const coerce = (version, options) => {
  if (version instanceof SemVer) {
    return version
  }

  if (typeof version === 'number') {
    version = String(version)
  }

  if (typeof version !== 'string') {
    return null
  }

  options = options || {}

  let match = null
  if (!options.rtl) {
    match = version.match(options.includePrerelease ? re[t.COERCEFULL] : re[t.COERCE])
  } else {
    // Find the right-most coercible string that does not share
    // a terminus with a more left-ward coercible string.
    // Eg, '1.2.3.4' wants to coerce '2.3.4', not '3.4' or '4'
    // With includePrerelease option set, '1.2.3.4-rc' wants to coerce '2.3.4-rc', not '2.3.4'
    //
    // Walk through the string checking with a /g regexp
    // Manually set the index so as to pick up overlapping matches.
    // Stop when we get a match that ends at the string end, since no
    // coercible string can be more right-ward without the same terminus.
    const coerceRtlRegex = options.includePrerelease ? re[t.COERCERTLFULL] : re[t.COERCERTL]
    let next
    while ((next = coerceRtlRegex.exec(version)) &&
        (!match || match.index + match[0].length !== version.length)
    ) {
      if (!match ||
            next.index + next[0].length !== match.index + match[0].length) {
        match = next
      }
      coerceRtlRegex.lastIndex = next.index + next[1].length + next[2].length
    }
    // leave it in a clean state
    coerceRtlRegex.lastIndex = -1
  }

  if (match === null) {
    return null
  }

  const major = match[2]
  const minor = match[3] || '0'
  const patch = match[4] || '0'
  const prerelease = options.includePrerelease && match[5] ? `-${match[5]}` : ''
  const build = options.includePrerelease && match[6] ? `+${match[6]}` : ''

  return parse(`${major}.${minor}.${patch}${prerelease}${build}`, options)
}
module.exports = coerce


/***/ }),

/***/ 84195:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

const SemVer = __webpack_require__(61583)
const parse = (version, options, throwErrors = false) => {
  if (version instanceof SemVer) {
    return version
  }
  try {
    return new SemVer(version, options)
  } catch (er) {
    if (!throwErrors) {
      return null
    }
    throw er
  }
}

module.exports = parse


/***/ }),

/***/ 57848:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

const parse = __webpack_require__(84195)
const valid = (version, options) => {
  const v = parse(version, options)
  return v ? v.version : null
}
module.exports = valid


/***/ }),

/***/ 99596:
/***/ ((module) => {

// Note: this is the semver.org version of the spec that it implements
// Not necessarily the package version of this code.
const SEMVER_SPEC_VERSION = '2.0.0'

const MAX_LENGTH = 256
const MAX_SAFE_INTEGER = Number.MAX_SAFE_INTEGER ||
/* istanbul ignore next */ 9007199254740991

// Max safe segment length for coercion.
const MAX_SAFE_COMPONENT_LENGTH = 16

// Max safe length for a build identifier. The max length minus 6 characters for
// the shortest version with a build 0.0.0+BUILD.
const MAX_SAFE_BUILD_LENGTH = MAX_LENGTH - 6

const RELEASE_TYPES = [
  'major',
  'premajor',
  'minor',
  'preminor',
  'patch',
  'prepatch',
  'prerelease',
]

module.exports = {
  MAX_LENGTH,
  MAX_SAFE_COMPONENT_LENGTH,
  MAX_SAFE_BUILD_LENGTH,
  MAX_SAFE_INTEGER,
  RELEASE_TYPES,
  SEMVER_SPEC_VERSION,
  FLAG_INCLUDE_PRERELEASE: 0b001,
  FLAG_LOOSE: 0b010,
}


/***/ }),

/***/ 58584:
/***/ ((module) => {

const debug = (
  typeof process === 'object' &&
  process.env &&
  process.env.NODE_DEBUG &&
  /\bsemver\b/i.test(process.env.NODE_DEBUG)
) ? (...args) => console.error('SEMVER', ...args)
  : () => {}

module.exports = debug


/***/ }),

/***/ 88540:
/***/ ((module) => {

const numeric = /^[0-9]+$/
const compareIdentifiers = (a, b) => {
  const anum = numeric.test(a)
  const bnum = numeric.test(b)

  if (anum && bnum) {
    a = +a
    b = +b
  }

  return a === b ? 0
    : (anum && !bnum) ? -1
    : (bnum && !anum) ? 1
    : a < b ? -1
    : 1
}

const rcompareIdentifiers = (a, b) => compareIdentifiers(b, a)

module.exports = {
  compareIdentifiers,
  rcompareIdentifiers,
}


/***/ }),

/***/ 92904:
/***/ ((module) => {

// parse out just the options we care about
const looseOption = Object.freeze({ loose: true })
const emptyOpts = Object.freeze({ })
const parseOptions = options => {
  if (!options) {
    return emptyOpts
  }

  if (typeof options !== 'object') {
    return looseOption
  }

  return options
}
module.exports = parseOptions


/***/ }),

/***/ 70845:
/***/ ((module, exports, __webpack_require__) => {

const {
  MAX_SAFE_COMPONENT_LENGTH,
  MAX_SAFE_BUILD_LENGTH,
  MAX_LENGTH,
} = __webpack_require__(99596)
const debug = __webpack_require__(58584)
exports = module.exports = {}

// The actual regexps go on exports.re
const re = exports.re = []
const safeRe = exports.safeRe = []
const src = exports.src = []
const t = exports.t = {}
let R = 0

const LETTERDASHNUMBER = '[a-zA-Z0-9-]'

// Replace some greedy regex tokens to prevent regex dos issues. These regex are
// used internally via the safeRe object since all inputs in this library get
// normalized first to trim and collapse all extra whitespace. The original
// regexes are exported for userland consumption and lower level usage. A
// future breaking change could export the safer regex only with a note that
// all input should have extra whitespace removed.
const safeRegexReplacements = [
  ['\\s', 1],
  ['\\d', MAX_LENGTH],
  [LETTERDASHNUMBER, MAX_SAFE_BUILD_LENGTH],
]

const makeSafeRegex = (value) => {
  for (const [token, max] of safeRegexReplacements) {
    value = value
      .split(`${token}*`).join(`${token}{0,${max}}`)
      .split(`${token}+`).join(`${token}{1,${max}}`)
  }
  return value
}

const createToken = (name, value, isGlobal) => {
  const safe = makeSafeRegex(value)
  const index = R++
  debug(name, index, value)
  t[name] = index
  src[index] = value
  re[index] = new RegExp(value, isGlobal ? 'g' : undefined)
  safeRe[index] = new RegExp(safe, isGlobal ? 'g' : undefined)
}

// The following Regular Expressions can be used for tokenizing,
// validating, and parsing SemVer version strings.

// ## Numeric Identifier
// A single `0`, or a non-zero digit followed by zero or more digits.

createToken('NUMERICIDENTIFIER', '0|[1-9]\\d*')
createToken('NUMERICIDENTIFIERLOOSE', '\\d+')

// ## Non-numeric Identifier
// Zero or more digits, followed by a letter or hyphen, and then zero or
// more letters, digits, or hyphens.

createToken('NONNUMERICIDENTIFIER', `\\d*[a-zA-Z-]${LETTERDASHNUMBER}*`)

// ## Main Version
// Three dot-separated numeric identifiers.

createToken('MAINVERSION', `(${src[t.NUMERICIDENTIFIER]})\\.` +
                   `(${src[t.NUMERICIDENTIFIER]})\\.` +
                   `(${src[t.NUMERICIDENTIFIER]})`)

createToken('MAINVERSIONLOOSE', `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` +
                        `(${src[t.NUMERICIDENTIFIERLOOSE]})\\.` +
                        `(${src[t.NUMERICIDENTIFIERLOOSE]})`)

// ## Pre-release Version Identifier
// A numeric identifier, or a non-numeric identifier.

createToken('PRERELEASEIDENTIFIER', `(?:${src[t.NUMERICIDENTIFIER]
}|${src[t.NONNUMERICIDENTIFIER]})`)

createToken('PRERELEASEIDENTIFIERLOOSE', `(?:${src[t.NUMERICIDENTIFIERLOOSE]
}|${src[t.NONNUMERICIDENTIFIER]})`)

// ## Pre-release Version
// Hyphen, followed by one or more dot-separated pre-release version
// identifiers.

createToken('PRERELEASE', `(?:-(${src[t.PRERELEASEIDENTIFIER]
}(?:\\.${src[t.PRERELEASEIDENTIFIER]})*))`)

createToken('PRERELEASELOOSE', `(?:-?(${src[t.PRERELEASEIDENTIFIERLOOSE]
}(?:\\.${src[t.PRERELEASEIDENTIFIERLOOSE]})*))`)

// ## Build Metadata Identifier
// Any combination of digits, letters, or hyphens.

createToken('BUILDIDENTIFIER', `${LETTERDASHNUMBER}+`)

// ## Build Metadata
// Plus sign, followed by one or more period-separated build metadata
// identifiers.

createToken('BUILD', `(?:\\+(${src[t.BUILDIDENTIFIER]
}(?:\\.${src[t.BUILDIDENTIFIER]})*))`)

// ## Full Version String
// A main version, followed optionally by a pre-release version and
// build metadata.

// Note that the only major, minor, patch, and pre-release sections of
// the version string are capturing groups.  The build metadata is not a
// capturing group, because it should not ever be used in version
// comparison.

createToken('FULLPLAIN', `v?${src[t.MAINVERSION]
}${src[t.PRERELEASE]}?${
  src[t.BUILD]}?`)

createToken('FULL', `^${src[t.FULLPLAIN]}$`)

// like full, but allows v1.2.3 and =1.2.3, which people do sometimes.
// also, 1.0.0alpha1 (prerelease without the hyphen) which is pretty
// common in the npm registry.
createToken('LOOSEPLAIN', `[v=\\s]*${src[t.MAINVERSIONLOOSE]
}${src[t.PRERELEASELOOSE]}?${
  src[t.BUILD]}?`)

createToken('LOOSE', `^${src[t.LOOSEPLAIN]}$`)

createToken('GTLT', '((?:<|>)?=?)')

// Something like "2.*" or "1.2.x".
// Note that "x.x" is a valid xRange identifer, meaning "any version"
// Only the first item is strictly required.
createToken('XRANGEIDENTIFIERLOOSE', `${src[t.NUMERICIDENTIFIERLOOSE]}|x|X|\\*`)
createToken('XRANGEIDENTIFIER', `${src[t.NUMERICIDENTIFIER]}|x|X|\\*`)

createToken('XRANGEPLAIN', `[v=\\s]*(${src[t.XRANGEIDENTIFIER]})` +
                   `(?:\\.(${src[t.XRANGEIDENTIFIER]})` +
                   `(?:\\.(${src[t.XRANGEIDENTIFIER]})` +
                   `(?:${src[t.PRERELEASE]})?${
                     src[t.BUILD]}?` +
                   `)?)?`)

createToken('XRANGEPLAINLOOSE', `[v=\\s]*(${src[t.XRANGEIDENTIFIERLOOSE]})` +
                        `(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` +
                        `(?:\\.(${src[t.XRANGEIDENTIFIERLOOSE]})` +
                        `(?:${src[t.PRERELEASELOOSE]})?${
                          src[t.BUILD]}?` +
                        `)?)?`)

createToken('XRANGE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAIN]}$`)
createToken('XRANGELOOSE', `^${src[t.GTLT]}\\s*${src[t.XRANGEPLAINLOOSE]}$`)

// Coercion.
// Extract anything that could conceivably be a part of a valid semver
createToken('COERCEPLAIN', `${'(^|[^\\d])' +
              '(\\d{1,'}${MAX_SAFE_COMPONENT_LENGTH}})` +
              `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?` +
              `(?:\\.(\\d{1,${MAX_SAFE_COMPONENT_LENGTH}}))?`)
createToken('COERCE', `${src[t.COERCEPLAIN]}(?:$|[^\\d])`)
createToken('COERCEFULL', src[t.COERCEPLAIN] +
              `(?:${src[t.PRERELEASE]})?` +
              `(?:${src[t.BUILD]})?` +
              `(?:$|[^\\d])`)
createToken('COERCERTL', src[t.COERCE], true)
createToken('COERCERTLFULL', src[t.COERCEFULL], true)

// Tilde ranges.
// Meaning is "reasonably at or greater than"
createToken('LONETILDE', '(?:~>?)')

createToken('TILDETRIM', `(\\s*)${src[t.LONETILDE]}\\s+`, true)
exports.tildeTrimReplace = '$1~'

createToken('TILDE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAIN]}$`)
createToken('TILDELOOSE', `^${src[t.LONETILDE]}${src[t.XRANGEPLAINLOOSE]}$`)

// Caret ranges.
// Meaning is "at least and backwards compatible with"
createToken('LONECARET', '(?:\\^)')

createToken('CARETTRIM', `(\\s*)${src[t.LONECARET]}\\s+`, true)
exports.caretTrimReplace = '$1^'

createToken('CARET', `^${src[t.LONECARET]}${src[t.XRANGEPLAIN]}$`)
createToken('CARETLOOSE', `^${src[t.LONECARET]}${src[t.XRANGEPLAINLOOSE]}$`)

// A simple gt/lt/eq thing, or just "" to indicate "any version"
createToken('COMPARATORLOOSE', `^${src[t.GTLT]}\\s*(${src[t.LOOSEPLAIN]})$|^$`)
createToken('COMPARATOR', `^${src[t.GTLT]}\\s*(${src[t.FULLPLAIN]})$|^$`)

// An expression to strip any whitespace between the gtlt and the thing
// it modifies, so that `> 1.2.3` ==> `>1.2.3`
createToken('COMPARATORTRIM', `(\\s*)${src[t.GTLT]
}\\s*(${src[t.LOOSEPLAIN]}|${src[t.XRANGEPLAIN]})`, true)
exports.comparatorTrimReplace = '$1$2$3'

// Something like `1.2.3 - 1.2.4`
// Note that these all use the loose form, because they'll be
// checked against either the strict or loose comparator form
// later.
createToken('HYPHENRANGE', `^\\s*(${src[t.XRANGEPLAIN]})` +
                   `\\s+-\\s+` +
                   `(${src[t.XRANGEPLAIN]})` +
                   `\\s*$`)

createToken('HYPHENRANGELOOSE', `^\\s*(${src[t.XRANGEPLAINLOOSE]})` +
                        `\\s+-\\s+` +
                        `(${src[t.XRANGEPLAINLOOSE]})` +
                        `\\s*$`)

// Star ranges basically just allow anything at all.
createToken('STAR', '(<|>)?=?\\s*\\*')
// >=0.0.0 is like a star
createToken('GTE0', '^\\s*>=\\s*0\\.0\\.0\\s*$')
createToken('GTE0PRE', '^\\s*>=\\s*0\\.0\\.0-0\\s*$')


/***/ }),

/***/ 59072:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";
/*!
 * shallow-clone <https://github.com/jonschlinkert/shallow-clone>
 *
 * Copyright (c) 2015-present, Jon Schlinkert.
 * Released under the MIT License.
 */



const valueOf = Symbol.prototype.valueOf;
const typeOf = __webpack_require__(73378);

function clone(val, deep) {
  switch (typeOf(val)) {
    case 'array':
      return val.slice();
    case 'object':
      return Object.assign({}, val);
    case 'date':
      return new val.constructor(Number(val));
    case 'map':
      return new Map(val);
    case 'set':
      return new Set(val);
    case 'buffer':
      return cloneBuffer(val);
    case 'symbol':
      return cloneSymbol(val);
    case 'arraybuffer':
      return cloneArrayBuffer(val);
    case 'float32array':
    case 'float64array':
    case 'int16array':
    case 'int32array':
    case 'int8array':
    case 'uint16array':
    case 'uint32array':
    case 'uint8clampedarray':
    case 'uint8array':
      return cloneTypedArray(val);
    case 'regexp':
      return cloneRegExp(val);
    case 'error':
      return Object.create(val);
    default: {
      return val;
    }
  }
}

function cloneRegExp(val) {
  const flags = val.flags !== void 0 ? val.flags : (/\w+$/.exec(val) || void 0);
  const re = new val.constructor(val.source, flags);
  re.lastIndex = val.lastIndex;
  return re;
}

function cloneArrayBuffer(val) {
  const res = new val.constructor(val.byteLength);
  new Uint8Array(res).set(new Uint8Array(val));
  return res;
}

function cloneTypedArray(val, deep) {
  return new val.constructor(val.buffer, val.byteOffset, val.length);
}

function cloneBuffer(val) {
  const len = val.length;
  const buf = Buffer.allocUnsafe ? Buffer.allocUnsafe(len) : Buffer.from(len);
  val.copy(buf);
  return buf;
}

function cloneSymbol(val) {
  return valueOf ? Object(valueOf.call(val)) : {};
}

/**
 * Expose `clone`
 */

module.exports = clone;


/***/ }),

/***/ 92046:
/***/ ((module, exports, __webpack_require__) => {

var __WEBPACK_AMD_DEFINE_RESULT__;/* global window, exports, define */

!function() {
    'use strict'

    var re = {
        not_string: /[^s]/,
        not_bool: /[^t]/,
        not_type: /[^T]/,
        not_primitive: /[^v]/,
        number: /[diefg]/,
        numeric_arg: /[bcdiefguxX]/,
        json: /[j]/,
        not_json: /[^j]/,
        text: /^[^\x25]+/,
        modulo: /^\x25{2}/,
        placeholder: /^\x25(?:([1-9]\d*)\$|\(([^)]+)\))?(\+)?(0|'[^$])?(-)?(\d+)?(?:\.(\d+))?([b-gijostTuvxX])/,
        key: /^([a-z_][a-z_\d]*)/i,
        key_access: /^\.([a-z_][a-z_\d]*)/i,
        index_access: /^\[(\d+)\]/,
        sign: /^[+-]/
    }

    function sprintf(key) {
        // `arguments` is not an array, but should be fine for this call
        return sprintf_format(sprintf_parse(key), arguments)
    }

    function vsprintf(fmt, argv) {
        return sprintf.apply(null, [fmt].concat(argv || []))
    }

    function sprintf_format(parse_tree, argv) {
        var cursor = 1, tree_length = parse_tree.length, arg, output = '', i, k, ph, pad, pad_character, pad_length, is_positive, sign
        for (i = 0; i < tree_length; i++) {
            if (typeof parse_tree[i] === 'string') {
                output += parse_tree[i]
            }
            else if (typeof parse_tree[i] === 'object') {
                ph = parse_tree[i] // convenience purposes only
                if (ph.keys) { // keyword argument
                    arg = argv[cursor]
                    for (k = 0; k < ph.keys.length; k++) {
                        if (arg == undefined) {
                            throw new Error(sprintf('[sprintf] Cannot access property "%s" of undefined value "%s"', ph.keys[k], ph.keys[k-1]))
                        }
                        arg = arg[ph.keys[k]]
                    }
                }
                else if (ph.param_no) { // positional argument (explicit)
                    arg = argv[ph.param_no]
                }
                else { // positional argument (implicit)
                    arg = argv[cursor++]
                }

                if (re.not_type.test(ph.type) && re.not_primitive.test(ph.type) && arg instanceof Function) {
                    arg = arg()
                }

                if (re.numeric_arg.test(ph.type) && (typeof arg !== 'number' && isNaN(arg))) {
                    throw new TypeError(sprintf('[sprintf] expecting number but found %T', arg))
                }

                if (re.number.test(ph.type)) {
                    is_positive = arg >= 0
                }

                switch (ph.type) {
                    case 'b':
                        arg = parseInt(arg, 10).toString(2)
                        break
                    case 'c':
                        arg = String.fromCharCode(parseInt(arg, 10))
                        break
                    case 'd':
                    case 'i':
                        arg = parseInt(arg, 10)
                        break
                    case 'j':
                        arg = JSON.stringify(arg, null, ph.width ? parseInt(ph.width) : 0)
                        break
                    case 'e':
                        arg = ph.precision ? parseFloat(arg).toExponential(ph.precision) : parseFloat(arg).toExponential()
                        break
                    case 'f':
                        arg = ph.precision ? parseFloat(arg).toFixed(ph.precision) : parseFloat(arg)
                        break
                    case 'g':
                        arg = ph.precision ? String(Number(arg.toPrecision(ph.precision))) : parseFloat(arg)
                        break
                    case 'o':
                        arg = (parseInt(arg, 10) >>> 0).toString(8)
                        break
                    case 's':
                        arg = String(arg)
                        arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
                        break
                    case 't':
                        arg = String(!!arg)
                        arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
                        break
                    case 'T':
                        arg = Object.prototype.toString.call(arg).slice(8, -1).toLowerCase()
                        arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
                        break
                    case 'u':
                        arg = parseInt(arg, 10) >>> 0
                        break
                    case 'v':
                        arg = arg.valueOf()
                        arg = (ph.precision ? arg.substring(0, ph.precision) : arg)
                        break
                    case 'x':
                        arg = (parseInt(arg, 10) >>> 0).toString(16)
                        break
                    case 'X':
                        arg = (parseInt(arg, 10) >>> 0).toString(16).toUpperCase()
                        break
                }
                if (re.json.test(ph.type)) {
                    output += arg
                }
                else {
                    if (re.number.test(ph.type) && (!is_positive || ph.sign)) {
                        sign = is_positive ? '+' : '-'
                        arg = arg.toString().replace(re.sign, '')
                    }
                    else {
                        sign = ''
                    }
                    pad_character = ph.pad_char ? ph.pad_char === '0' ? '0' : ph.pad_char.charAt(1) : ' '
                    pad_length = ph.width - (sign + arg).length
                    pad = ph.width ? (pad_length > 0 ? pad_character.repeat(pad_length) : '') : ''
                    output += ph.align ? sign + arg + pad : (pad_character === '0' ? sign + pad + arg : pad + sign + arg)
                }
            }
        }
        return output
    }

    var sprintf_cache = Object.create(null)

    function sprintf_parse(fmt) {
        if (sprintf_cache[fmt]) {
            return sprintf_cache[fmt]
        }

        var _fmt = fmt, match, parse_tree = [], arg_names = 0
        while (_fmt) {
            if ((match = re.text.exec(_fmt)) !== null) {
                parse_tree.push(match[0])
            }
            else if ((match = re.modulo.exec(_fmt)) !== null) {
                parse_tree.push('%')
            }
            else if ((match = re.placeholder.exec(_fmt)) !== null) {
                if (match[2]) {
                    arg_names |= 1
                    var field_list = [], replacement_field = match[2], field_match = []
                    if ((field_match = re.key.exec(replacement_field)) !== null) {
                        field_list.push(field_match[1])
                        while ((replacement_field = replacement_field.substring(field_match[0].length)) !== '') {
                            if ((field_match = re.key_access.exec(replacement_field)) !== null) {
                                field_list.push(field_match[1])
                            }
                            else if ((field_match = re.index_access.exec(replacement_field)) !== null) {
                                field_list.push(field_match[1])
                            }
                            else {
                                throw new SyntaxError('[sprintf] failed to parse named argument key')
                            }
                        }
                    }
                    else {
                        throw new SyntaxError('[sprintf] failed to parse named argument key')
                    }
                    match[2] = field_list
                }
                else {
                    arg_names |= 2
                }
                if (arg_names === 3) {
                    throw new Error('[sprintf] mixing positional and named placeholders is not (yet) supported')
                }

                parse_tree.push(
                    {
                        placeholder: match[0],
                        param_no:    match[1],
                        keys:        match[2],
                        sign:        match[3],
                        pad_char:    match[4],
                        align:       match[5],
                        width:       match[6],
                        precision:   match[7],
                        type:        match[8]
                    }
                )
            }
            else {
                throw new SyntaxError('[sprintf] unexpected placeholder')
            }
            _fmt = _fmt.substring(match[0].length)
        }
        return sprintf_cache[fmt] = parse_tree
    }

    /**
     * export to either browser or node.js
     */
    /* eslint-disable quote-props */
    if (true) {
        exports.sprintf = sprintf
        exports.vsprintf = vsprintf
    }
    if (typeof window !== 'undefined') {
        window['sprintf'] = sprintf
        window['vsprintf'] = vsprintf

        if (true) {
            !(__WEBPACK_AMD_DEFINE_RESULT__ = (function() {
                return {
                    'sprintf': sprintf,
                    'vsprintf': vsprintf
                }
            }).call(exports, __webpack_require__, exports, module),
		__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__))
        }
    }
    /* eslint-enable quote-props */
}(); // eslint-disable-line


/***/ }),

/***/ 86730:
/***/ ((module) => {

"use strict";


const defaultAlphabetIndexMap = [];

function isNumberCode(code) {
  return code >= 48/* '0' */ && code <= 57/* '9' */;
}

function naturalCompare(a, b, opts) {
  if (typeof a !== 'string') {
    throw new TypeError(`The first argument must be a string. Received type '${typeof a}'`);
  }
  if (typeof b !== 'string') {
    throw new TypeError(`The second argument must be a string. Received type '${typeof b}'`);
  }

  const lengthA = a.length;
  const lengthB = b.length;
  let indexA = 0;
  let indexB = 0;
  let alphabetIndexMap = defaultAlphabetIndexMap;
  let firstDifferenceInLeadingZeros = 0;

  if (opts) {
    if (opts.caseInsensitive) {
      a = a.toLowerCase();
      b = b.toLowerCase();
    }

    if (opts.alphabet) {
      alphabetIndexMap = buildAlphabetIndexMap(opts.alphabet);
    }
  }

  while (indexA < lengthA && indexB < lengthB) {
    let charCodeA = a.charCodeAt(indexA);
    let charCodeB = b.charCodeAt(indexB);

    if (isNumberCode(charCodeA)) {
      if (!isNumberCode(charCodeB)) {
        return charCodeA - charCodeB;
      }

      let numStartA = indexA;
      let numStartB = indexB;

      while (charCodeA === 48/* '0' */ && ++numStartA < lengthA) {
        charCodeA = a.charCodeAt(numStartA);
      }
      while (charCodeB === 48/* '0' */ && ++numStartB < lengthB) {
        charCodeB = b.charCodeAt(numStartB);
      }

      if (numStartA !== numStartB && firstDifferenceInLeadingZeros === 0) {
        firstDifferenceInLeadingZeros = numStartA - numStartB;
      }

      let numEndA = numStartA;
      let numEndB = numStartB;

      while (numEndA < lengthA && isNumberCode(a.charCodeAt(numEndA))) {
        ++numEndA;
      }
      while (numEndB < lengthB && isNumberCode(b.charCodeAt(numEndB))) {
        ++numEndB;
      }

      let difference = numEndA - numStartA - numEndB + numStartB; // numA length - numB length
      if (difference !== 0) {
        return difference;
      }

      while (numStartA < numEndA) {
        difference = a.charCodeAt(numStartA++) - b.charCodeAt(numStartB++);
        if (difference !== 0) {
          return difference;
        }
      }

      indexA = numEndA;
      indexB = numEndB;
      continue;
    }

    if (charCodeA !== charCodeB) {
      if (
        charCodeA < alphabetIndexMap.length &&
        charCodeB < alphabetIndexMap.length &&
        alphabetIndexMap[charCodeA] !== -1 &&
        alphabetIndexMap[charCodeB] !== -1
      ) {
        return alphabetIndexMap[charCodeA] - alphabetIndexMap[charCodeB];
      }

      return charCodeA - charCodeB;
    }

    ++indexA;
    ++indexB;
  }

  if (indexA < lengthA) { // `b` is a substring of `a`
    return 1;
  }

  if (indexB < lengthB) { // `a` is a substring of `b`
    return -1;
  }

  return firstDifferenceInLeadingZeros;
}

const alphabetIndexMapCache = {};

function buildAlphabetIndexMap(alphabet) {
  const existingMap = alphabetIndexMapCache[alphabet];
  if (existingMap !== undefined) {
    return existingMap;
  }

  const indexMap = [];
  const maxCharCode = alphabet.split('').reduce((maxCode, char) => {
    return Math.max(maxCode, char.charCodeAt(0));
  }, 0);

  for (let i = 0; i <= maxCharCode; i++) {
    indexMap.push(-1);
  }

  for (let i = 0; i < alphabet.length; i++) {
    indexMap[alphabet.charCodeAt(i)] = i;
  }

  alphabetIndexMapCache[alphabet] = indexMap;

  return indexMap;
}

module.exports = naturalCompare;


/***/ }),

/***/ 58782:
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";

// EXPORTS
__webpack_require__.d(__webpack_exports__, {
  "m5": () => (/* reexport */ fast_path),
  "e4": () => (/* reexport */ getEmptyResult),
  "kL": () => (/* reexport */ parseImpl),
  "a7": () => (/* reexport */ resetResult)
});

// UNUSED EXPORTS: setDefaults

;// CONCATENATED MODULE: ./node_modules/.pnpm/tldts-core@5.7.112/node_modules/tldts-core/dist/es6/src/domain.js
/**
 * Check if `vhost` is a valid suffix of `hostname` (top-domain)
 *
 * It means that `vhost` needs to be a suffix of `hostname` and we then need to
 * make sure that: either they are equal, or the character preceding `vhost` in
 * `hostname` is a '.' (it should not be a partial label).
 *
 * * hostname = 'not.evil.com' and vhost = 'vil.com'      => not ok
 * * hostname = 'not.evil.com' and vhost = 'evil.com'     => ok
 * * hostname = 'not.evil.com' and vhost = 'not.evil.com' => ok
 */
function shareSameDomainSuffix(hostname, vhost) {
    if (hostname.endsWith(vhost)) {
        return (hostname.length === vhost.length ||
            hostname[hostname.length - vhost.length - 1] === '.');
    }
    return false;
}
/**
 * Given a hostname and its public suffix, extract the general domain.
 */
function extractDomainWithSuffix(hostname, publicSuffix) {
    // Locate the index of the last '.' in the part of the `hostname` preceding
    // the public suffix.
    //
    // examples:
    //   1. not.evil.co.uk  => evil.co.uk
    //         ^    ^
    //         |    | start of public suffix
    //         | index of the last dot
    //
    //   2. example.co.uk   => example.co.uk
    //     ^       ^
    //     |       | start of public suffix
    //     |
    //     | (-1) no dot found before the public suffix
    const publicSuffixIndex = hostname.length - publicSuffix.length - 2;
    const lastDotBeforeSuffixIndex = hostname.lastIndexOf('.', publicSuffixIndex);
    // No '.' found, then `hostname` is the general domain (no sub-domain)
    if (lastDotBeforeSuffixIndex === -1) {
        return hostname;
    }
    // Extract the part between the last '.'
    return hostname.slice(lastDotBeforeSuffixIndex + 1);
}
/**
 * Detects the domain based on rules and upon and a host string
 */
function getDomain(suffix, hostname, options) {
    // Check if `hostname` ends with a member of `validHosts`.
    if (options.validHosts !== null) {
        const validHosts = options.validHosts;
        for (let i = 0; i < validHosts.length; i += 1) {
            const vhost = validHosts[i];
            if ( /*@__INLINE__*/shareSameDomainSuffix(hostname, vhost) === true) {
                return vhost;
            }
        }
    }
    // If `hostname` is a valid public suffix, then there is no domain to return.
    // Since we already know that `getPublicSuffix` returns a suffix of `hostname`
    // there is no need to perform a string comparison and we only compare the
    // size.
    if (suffix.length === hostname.length) {
        return null;
    }
    // To extract the general domain, we start by identifying the public suffix
    // (if any), then consider the domain to be the public suffix with one added
    // level of depth. (e.g.: if hostname is `not.evil.co.uk` and public suffix:
    // `co.uk`, then we take one more level: `evil`, giving the final result:
    // `evil.co.uk`).
    return /*@__INLINE__*/ extractDomainWithSuffix(hostname, suffix);
}

;// CONCATENATED MODULE: ./node_modules/.pnpm/tldts-core@5.7.112/node_modules/tldts-core/dist/es6/src/domain-without-suffix.js
/**
 * Return the part of domain without suffix.
 *
 * Example: for domain 'foo.com', the result would be 'foo'.
 */
function getDomainWithoutSuffix(domain, suffix) {
    // Note: here `domain` and `suffix` cannot have the same length because in
    // this case we set `domain` to `null` instead. It is thus safe to assume
    // that `suffix` is shorter than `domain`.
    return domain.slice(0, -suffix.length - 1);
}

;// CONCATENATED MODULE: ./node_modules/.pnpm/tldts-core@5.7.112/node_modules/tldts-core/dist/es6/src/extract-hostname.js
/**
 * @param url - URL we want to extract a hostname from.
 * @param urlIsValidHostname - hint from caller; true if `url` is already a valid hostname.
 */
function extractHostname(url, urlIsValidHostname) {
    let start = 0;
    let end = url.length;
    let hasUpper = false;
    // If url is not already a valid hostname, then try to extract hostname.
    if (urlIsValidHostname === false) {
        // Special handling of data URLs
        if (url.startsWith('data:') === true) {
            return null;
        }
        // Trim leading spaces
        while (start < url.length && url.charCodeAt(start) <= 32) {
            start += 1;
        }
        // Trim trailing spaces
        while (end > start + 1 && url.charCodeAt(end - 1) <= 32) {
            end -= 1;
        }
        // Skip scheme.
        if (url.charCodeAt(start) === 47 /* '/' */ &&
            url.charCodeAt(start + 1) === 47 /* '/' */) {
            start += 2;
        }
        else {
            const indexOfProtocol = url.indexOf(':/', start);
            if (indexOfProtocol !== -1) {
                // Implement fast-path for common protocols. We expect most protocols
                // should be one of these 4 and thus we will not need to perform the
                // more expansive validity check most of the time.
                const protocolSize = indexOfProtocol - start;
                const c0 = url.charCodeAt(start);
                const c1 = url.charCodeAt(start + 1);
                const c2 = url.charCodeAt(start + 2);
                const c3 = url.charCodeAt(start + 3);
                const c4 = url.charCodeAt(start + 4);
                if (protocolSize === 5 &&
                    c0 === 104 /* 'h' */ &&
                    c1 === 116 /* 't' */ &&
                    c2 === 116 /* 't' */ &&
                    c3 === 112 /* 'p' */ &&
                    c4 === 115 /* 's' */) {
                    // https
                }
                else if (protocolSize === 4 &&
                    c0 === 104 /* 'h' */ &&
                    c1 === 116 /* 't' */ &&
                    c2 === 116 /* 't' */ &&
                    c3 === 112 /* 'p' */) {
                    // http
                }
                else if (protocolSize === 3 &&
                    c0 === 119 /* 'w' */ &&
                    c1 === 115 /* 's' */ &&
                    c2 === 115 /* 's' */) {
                    // wss
                }
                else if (protocolSize === 2 &&
                    c0 === 119 /* 'w' */ &&
                    c1 === 115 /* 's' */) {
                    // ws
                }
                else {
                    // Check that scheme is valid
                    for (let i = start; i < indexOfProtocol; i += 1) {
                        const lowerCaseCode = url.charCodeAt(i) | 32;
                        if (((lowerCaseCode >= 97 && lowerCaseCode <= 122) || // [a, z]
                            (lowerCaseCode >= 48 && lowerCaseCode <= 57) || // [0, 9]
                            lowerCaseCode === 46 || // '.'
                            lowerCaseCode === 45 || // '-'
                            lowerCaseCode === 43) === false // '+'
                        ) {
                            return null;
                        }
                    }
                }
                // Skip 0, 1 or more '/' after ':/'
                start = indexOfProtocol + 2;
                while (url.charCodeAt(start) === 47 /* '/' */) {
                    start += 1;
                }
            }
        }
        // Detect first occurrence of '/', '?' or '#'. We also keep track of the
        // last occurrence of '@', ']' or ':' to speed-up subsequent parsing of
        // (respectively), identifier, ipv6 or port.
        let indexOfIdentifier = -1;
        let indexOfClosingBracket = -1;
        let indexOfPort = -1;
        for (let i = start; i < end; i += 1) {
            const code = url.charCodeAt(i);
            if (code === 35 || // '#'
                code === 47 || // '/'
                code === 63 // '?'
            ) {
                end = i;
                break;
            }
            else if (code === 64) {
                // '@'
                indexOfIdentifier = i;
            }
            else if (code === 93) {
                // ']'
                indexOfClosingBracket = i;
            }
            else if (code === 58) {
                // ':'
                indexOfPort = i;
            }
            else if (code >= 65 && code <= 90) {
                hasUpper = true;
            }
        }
        // Detect identifier: '@'
        if (indexOfIdentifier !== -1 &&
            indexOfIdentifier > start &&
            indexOfIdentifier < end) {
            start = indexOfIdentifier + 1;
        }
        // Handle ipv6 addresses
        if (url.charCodeAt(start) === 91 /* '[' */) {
            if (indexOfClosingBracket !== -1) {
                return url.slice(start + 1, indexOfClosingBracket).toLowerCase();
            }
            return null;
        }
        else if (indexOfPort !== -1 && indexOfPort > start && indexOfPort < end) {
            // Detect port: ':'
            end = indexOfPort;
        }
    }
    // Trim trailing dots
    while (end > start + 1 && url.charCodeAt(end - 1) === 46 /* '.' */) {
        end -= 1;
    }
    const hostname = start !== 0 || end !== url.length ? url.slice(start, end) : url;
    if (hasUpper) {
        return hostname.toLowerCase();
    }
    return hostname;
}

;// CONCATENATED MODULE: ./node_modules/.pnpm/tldts-core@5.7.112/node_modules/tldts-core/dist/es6/src/is-ip.js
/**
 * Check if a hostname is an IP. You should be aware that this only works
 * because `hostname` is already garanteed to be a valid hostname!
 */
function isProbablyIpv4(hostname) {
    // Cannot be shorted than 1.1.1.1
    if (hostname.length < 7) {
        return false;
    }
    // Cannot be longer than: 255.255.255.255
    if (hostname.length > 15) {
        return false;
    }
    let numberOfDots = 0;
    for (let i = 0; i < hostname.length; i += 1) {
        const code = hostname.charCodeAt(i);
        if (code === 46 /* '.' */) {
            numberOfDots += 1;
        }
        else if (code < 48 /* '0' */ || code > 57 /* '9' */) {
            return false;
        }
    }
    return (numberOfDots === 3 &&
        hostname.charCodeAt(0) !== 46 /* '.' */ &&
        hostname.charCodeAt(hostname.length - 1) !== 46 /* '.' */);
}
/**
 * Similar to isProbablyIpv4.
 */
function isProbablyIpv6(hostname) {
    if (hostname.length < 3) {
        return false;
    }
    let start = hostname[0] === '[' ? 1 : 0;
    let end = hostname.length;
    if (hostname[end - 1] === ']') {
        end -= 1;
    }
    // We only consider the maximum size of a normal IPV6. Note that this will
    // fail on so-called "IPv4 mapped IPv6 addresses" but this is a corner-case
    // and a proper validation library should be used for these.
    if (end - start > 39) {
        return false;
    }
    let hasColon = false;
    for (; start < end; start += 1) {
        const code = hostname.charCodeAt(start);
        if (code === 58 /* ':' */) {
            hasColon = true;
        }
        else if (((code >= 48 && code <= 57) || // 0-9
            (code >= 97 && code <= 102) || // a-f
            (code >= 65 && code <= 90)) === // A-F
            false) {
            return false;
        }
    }
    return hasColon;
}
/**
 * Check if `hostname` is *probably* a valid ip addr (either ipv6 or ipv4).
 * This *will not* work on any string. We need `hostname` to be a valid
 * hostname.
 */
function isIp(hostname) {
    return isProbablyIpv6(hostname) || isProbablyIpv4(hostname);
}

;// CONCATENATED MODULE: ./node_modules/.pnpm/tldts-core@5.7.112/node_modules/tldts-core/dist/es6/src/is-valid.js
/**
 * Implements fast shallow verification of hostnames. This does not perform a
 * struct check on the content of labels (classes of Unicode characters, etc.)
 * but instead check that the structure is valid (number of labels, length of
 * labels, etc.).
 *
 * If you need stricter validation, consider using an external library.
 */
function isValidAscii(code) {
    return ((code >= 97 && code <= 122) || (code >= 48 && code <= 57) || code > 127);
}
/**
 * Check if a hostname string is valid. It's usually a preliminary check before
 * trying to use getDomain or anything else.
 *
 * Beware: it does not check if the TLD exists.
 */
/* harmony default export */ function is_valid(hostname) {
    if (hostname.length > 255) {
        return false;
    }
    if (hostname.length === 0) {
        return false;
    }
    if ( /*@__INLINE__*/isValidAscii(hostname.charCodeAt(0)) === false) {
        return false;
    }
    // Validate hostname according to RFC
    let lastDotIndex = -1;
    let lastCharCode = -1;
    const len = hostname.length;
    for (let i = 0; i < len; i += 1) {
        const code = hostname.charCodeAt(i);
        if (code === 46 /* '.' */) {
            if (
            // Check that previous label is < 63 bytes long (64 = 63 + '.')
            i - lastDotIndex > 64 ||
                // Check that previous character was not already a '.'
                lastCharCode === 46 ||
                // Check that the previous label does not end with a '-' (dash)
                lastCharCode === 45 ||
                // Check that the previous label does not end with a '_' (underscore)
                lastCharCode === 95) {
                return false;
            }
            lastDotIndex = i;
        }
        else if (( /*@__INLINE__*/isValidAscii(code) || code === 45 || code === 95) ===
            false) {
            // Check if there is a forbidden character in the label
            return false;
        }
        lastCharCode = code;
    }
    return (
    // Check that last label is shorter than 63 chars
    len - lastDotIndex - 1 <= 63 &&
        // Check that the last character is an allowed trailing label character.
        // Since we already checked that the char is a valid hostname character,
        // we only need to check that it's different from '-'.
        lastCharCode !== 45);
}

;// CONCATENATED MODULE: ./node_modules/.pnpm/tldts-core@5.7.112/node_modules/tldts-core/dist/es6/src/options.js
function setDefaultsImpl({ allowIcannDomains = true, allowPrivateDomains = false, detectIp = true, extractHostname = true, mixedInputs = true, validHosts = null, validateHostname = true, }) {
    return {
        allowIcannDomains,
        allowPrivateDomains,
        detectIp,
        extractHostname,
        mixedInputs,
        validHosts,
        validateHostname,
    };
}
const DEFAULT_OPTIONS = /*@__INLINE__*/ setDefaultsImpl({});
function setDefaults(options) {
    if (options === undefined) {
        return DEFAULT_OPTIONS;
    }
    return /*@__INLINE__*/ setDefaultsImpl(options);
}

;// CONCATENATED MODULE: ./node_modules/.pnpm/tldts-core@5.7.112/node_modules/tldts-core/dist/es6/src/subdomain.js
/**
 * Returns the subdomain of a hostname string
 */
function getSubdomain(hostname, domain) {
    // If `hostname` and `domain` are the same, then there is no sub-domain
    if (domain.length === hostname.length) {
        return '';
    }
    return hostname.slice(0, -domain.length - 1);
}

;// CONCATENATED MODULE: ./node_modules/.pnpm/tldts-core@5.7.112/node_modules/tldts-core/dist/es6/src/factory.js
/**
 * Implement a factory allowing to plug different implementations of suffix
 * lookup (e.g.: using a trie or the packed hashes datastructures). This is used
 * and exposed in `tldts.ts` and `tldts-experimental.ts` bundle entrypoints.
 */







function getEmptyResult() {
    return {
        domain: null,
        domainWithoutSuffix: null,
        hostname: null,
        isIcann: null,
        isIp: null,
        isPrivate: null,
        publicSuffix: null,
        subdomain: null,
    };
}
function resetResult(result) {
    result.domain = null;
    result.domainWithoutSuffix = null;
    result.hostname = null;
    result.isIcann = null;
    result.isIp = null;
    result.isPrivate = null;
    result.publicSuffix = null;
    result.subdomain = null;
}
function parseImpl(url, step, suffixLookup, partialOptions, result) {
    const options = /*@__INLINE__*/ setDefaults(partialOptions);
    // Very fast approximate check to make sure `url` is a string. This is needed
    // because the library will not necessarily be used in a typed setup and
    // values of arbitrary types might be given as argument.
    if (typeof url !== 'string') {
        return result;
    }
    // Extract hostname from `url` only if needed. This can be made optional
    // using `options.extractHostname`. This option will typically be used
    // whenever we are sure the inputs to `parse` are already hostnames and not
    // arbitrary URLs.
    //
    // `mixedInput` allows to specify if we expect a mix of URLs and hostnames
    // as input. If only hostnames are expected then `extractHostname` can be
    // set to `false` to speed-up parsing. If only URLs are expected then
    // `mixedInputs` can be set to `false`. The `mixedInputs` is only a hint
    // and will not change the behavior of the library.
    if (options.extractHostname === false) {
        result.hostname = url;
    }
    else if (options.mixedInputs === true) {
        result.hostname = extractHostname(url, is_valid(url));
    }
    else {
        result.hostname = extractHostname(url, false);
    }
    if (step === 0 /* FLAG.HOSTNAME */ || result.hostname === null) {
        return result;
    }
    // Check if `hostname` is a valid ip address
    if (options.detectIp === true) {
        result.isIp = isIp(result.hostname);
        if (result.isIp === true) {
            return result;
        }
    }
    // Perform optional hostname validation. If hostname is not valid, no need to
    // go further as there will be no valid domain or sub-domain.
    if (options.validateHostname === true &&
        options.extractHostname === true &&
        is_valid(result.hostname) === false) {
        result.hostname = null;
        return result;
    }
    // Extract public suffix
    suffixLookup(result.hostname, options, result);
    if (step === 2 /* FLAG.PUBLIC_SUFFIX */ || result.publicSuffix === null) {
        return result;
    }
    // Extract domain
    result.domain = getDomain(result.publicSuffix, result.hostname, options);
    if (step === 3 /* FLAG.DOMAIN */ || result.domain === null) {
        return result;
    }
    // Extract subdomain
    result.subdomain = getSubdomain(result.hostname, result.domain);
    if (step === 4 /* FLAG.SUB_DOMAIN */) {
        return result;
    }
    // Extract domain without suffix
    result.domainWithoutSuffix = getDomainWithoutSuffix(result.domain, result.publicSuffix);
    return result;
}

;// CONCATENATED MODULE: ./node_modules/.pnpm/tldts-core@5.7.112/node_modules/tldts-core/dist/es6/src/lookup/fast-path.js
/* harmony default export */ function fast_path(hostname, options, out) {
    // Fast path for very popular suffixes; this allows to by-pass lookup
    // completely as well as any extra allocation or string manipulation.
    if (options.allowPrivateDomains === false && hostname.length > 3) {
        const last = hostname.length - 1;
        const c3 = hostname.charCodeAt(last);
        const c2 = hostname.charCodeAt(last - 1);
        const c1 = hostname.charCodeAt(last - 2);
        const c0 = hostname.charCodeAt(last - 3);
        if (c3 === 109 /* 'm' */ &&
            c2 === 111 /* 'o' */ &&
            c1 === 99 /* 'c' */ &&
            c0 === 46 /* '.' */) {
            out.isIcann = true;
            out.isPrivate = false;
            out.publicSuffix = 'com';
            return true;
        }
        else if (c3 === 103 /* 'g' */ &&
            c2 === 114 /* 'r' */ &&
            c1 === 111 /* 'o' */ &&
            c0 === 46 /* '.' */) {
            out.isIcann = true;
            out.isPrivate = false;
            out.publicSuffix = 'org';
            return true;
        }
        else if (c3 === 117 /* 'u' */ &&
            c2 === 100 /* 'd' */ &&
            c1 === 101 /* 'e' */ &&
            c0 === 46 /* '.' */) {
            out.isIcann = true;
            out.isPrivate = false;
            out.publicSuffix = 'edu';
            return true;
        }
        else if (c3 === 118 /* 'v' */ &&
            c2 === 111 /* 'o' */ &&
            c1 === 103 /* 'g' */ &&
            c0 === 46 /* '.' */) {
            out.isIcann = true;
            out.isPrivate = false;
            out.publicSuffix = 'gov';
            return true;
        }
        else if (c3 === 116 /* 't' */ &&
            c2 === 101 /* 'e' */ &&
            c1 === 110 /* 'n' */ &&
            c0 === 46 /* '.' */) {
            out.isIcann = true;
            out.isPrivate = false;
            out.publicSuffix = 'net';
            return true;
        }
        else if (c3 === 101 /* 'e' */ &&
            c2 === 100 /* 'd' */ &&
            c1 === 46 /* '.' */) {
            out.isIcann = true;
            out.isPrivate = false;
            out.publicSuffix = 'de';
            return true;
        }
    }
    return false;
}

;// CONCATENATED MODULE: ./node_modules/.pnpm/tldts-core@5.7.112/node_modules/tldts-core/dist/es6/index.js





/***/ }),

/***/ 85258:
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {

"use strict";

// EXPORTS
__webpack_require__.d(__webpack_exports__, {
  "Fo": () => (/* binding */ getHostname),
  "cH": () => (/* binding */ getPublicSuffix),
  "Qc": () => (/* binding */ parse)
});

// UNUSED EXPORTS: getDomain, getDomainWithoutSuffix, getSubdomain

// EXTERNAL MODULE: ./node_modules/.pnpm/tldts-core@5.7.112/node_modules/tldts-core/dist/es6/index.js + 9 modules
var es6 = __webpack_require__(58782);
;// CONCATENATED MODULE: ./node_modules/.pnpm/tldts@5.6.45/node_modules/tldts/dist/es6/src/data/trie.js
const exceptions = (function () {
    const _0 = { "$": 1, "succ": {} }, _1 = { "$": 0, "succ": { "city": _0 } };
    const exceptions = { "$": 0, "succ": { "ck": { "$": 0, "succ": { "www": _0 } }, "jp": { "$": 0, "succ": { "kawasaki": _1, "kitakyushu": _1, "kobe": _1, "nagoya": _1, "sapporo": _1, "sendai": _1, "yokohama": _1 } } } };
    ;
    return exceptions;
})();
const rules = (function () {
    const _2 = { "$": 1, "succ": {} }, _3 = { "$": 1, "succ": { "com": _2, "edu": _2, "gov": _2, "net": _2, "mil": _2, "org": _2 } }, _4 = { "$": 2, "succ": {} }, _5 = { "$": 1, "succ": { "blogspot": _4 } }, _6 = { "$": 1, "succ": { "gov": _2 } }, _7 = { "$": 0, "succ": { "*": _4 } }, _8 = { "$": 0, "succ": { "*": _2 } }, _9 = { "$": 1, "succ": { "com": _2, "edu": _2, "net": _2, "org": _2, "gov": _2 } }, _10 = { "$": 1, "succ": { "co": _4 } }, _11 = { "$": 1, "succ": { "ng": _4 } }, _12 = { "$": 0, "succ": { "s3": _4 } }, _13 = { "$": 0, "succ": { "dualstack": _12 } }, _14 = { "$": 0, "succ": { "s3": _4, "dualstack": _12, "s3-website": _4 } }, _15 = { "$": 0, "succ": { "apps": _4 } }, _16 = { "$": 0, "succ": { "app": _4 } }, _17 = { "$": 0, "succ": { "j": _4 } }, _18 = { "$": 0, "succ": { "user": _4 } }, _19 = { "$": 1, "succ": { "ybo": _4 } }, _20 = { "$": 1, "succ": { "gov": _2, "blogspot": _4, "nym": _4 } }, _21 = { "$": 0, "succ": { "cust": _4 } }, _22 = { "$": 1, "succ": { "edu": _2, "biz": _2, "net": _2, "org": _2, "gov": _2, "info": _2, "com": _2 } }, _23 = { "$": 1, "succ": { "blogspot": _4, "nym": _4 } }, _24 = { "$": 1, "succ": { "for": _4 } }, _25 = { "$": 1, "succ": { "barsy": _4 } }, _26 = { "$": 0, "succ": { "forgot": _4 } }, _27 = { "$": 0, "succ": { "jelastic": _4 } }, _28 = { "$": 1, "succ": { "gs": _2 } }, _29 = { "$": 0, "succ": { "nes": _2 } }, _30 = { "$": 1, "succ": { "k12": _2, "cc": _2, "lib": _2 } }, _31 = { "$": 1, "succ": { "cc": _2, "lib": _2 } };
    const rules = { "$": 0, "succ": { "ac": _3, "ad": { "$": 1, "succ": { "nom": _2 } }, "ae": { "$": 1, "succ": { "co": _2, "net": _2, "org": _2, "sch": _2, "ac": _2, "gov": _2, "mil": _2, "blogspot": _4, "nom": _4 } }, "aero": { "$": 1, "succ": { "accident-investigation": _2, "accident-prevention": _2, "aerobatic": _2, "aeroclub": _2, "aerodrome": _2, "agents": _2, "aircraft": _2, "airline": _2, "airport": _2, "air-surveillance": _2, "airtraffic": _2, "air-traffic-control": _2, "ambulance": _2, "amusement": _2, "association": _2, "author": _2, "ballooning": _2, "broker": _2, "caa": _2, "cargo": _2, "catering": _2, "certification": _2, "championship": _2, "charter": _2, "civilaviation": _2, "club": _2, "conference": _2, "consultant": _2, "consulting": _2, "control": _2, "council": _2, "crew": _2, "design": _2, "dgca": _2, "educator": _2, "emergency": _2, "engine": _2, "engineer": _2, "entertainment": _2, "equipment": _2, "exchange": _2, "express": _2, "federation": _2, "flight": _2, "fuel": _2, "gliding": _2, "government": _2, "groundhandling": _2, "group": _2, "hanggliding": _2, "homebuilt": _2, "insurance": _2, "journal": _2, "journalist": _2, "leasing": _2, "logistics": _2, "magazine": _2, "maintenance": _2, "media": _2, "microlight": _2, "modelling": _2, "navigation": _2, "parachuting": _2, "paragliding": _2, "passenger-association": _2, "pilot": _2, "press": _2, "production": _2, "recreation": _2, "repbody": _2, "res": _2, "research": _2, "rotorcraft": _2, "safety": _2, "scientist": _2, "services": _2, "show": _2, "skydiving": _2, "software": _2, "student": _2, "trader": _2, "trading": _2, "trainer": _2, "union": _2, "workinggroup": _2, "works": _2 } }, "af": { "$": 1, "succ": { "gov": _2, "com": _2, "org": _2, "net": _2, "edu": _2, "nom": _4 } }, "ag": { "$": 1, "succ": { "com": _2, "org": _2, "net": _2, "co": _2, "nom": _2 } }, "ai": { "$": 1, "succ": { "off": _2, "com": _2, "net": _2, "org": _2, "uwu": _4, "nom": _4 } }, "al": { "$": 1, "succ": { "com": _2, "edu": _2, "gov": _2, "mil": _2, "net": _2, "org": _2, "blogspot": _4, "nom": _4 } }, "am": { "$": 1, "succ": { "co": _2, "com": _2, "commune": _2, "net": _2, "org": _2, "blogspot": _4, "neko": _4, "nyaa": _4 } }, "ao": { "$": 1, "succ": { "ed": _2, "gv": _2, "og": _2, "co": _2, "pb": _2, "it": _2 } }, "aq": _2, "ar": { "$": 1, "succ": { "com": _5, "edu": _2, "gob": _2, "gov": _2, "int": _2, "mil": _2, "musica": _2, "net": _2, "org": _2, "tur": _2 } }, "arpa": { "$": 1, "succ": { "e164": _2, "in-addr": _2, "ip6": _2, "iris": _2, "uri": _2, "urn": _2 } }, "as": _6, "asia": { "$": 1, "succ": { "cloudns": _4 } }, "at": { "$": 1, "succ": { "ac": { "$": 1, "succ": { "sth": _2 } }, "co": _5, "gv": _2, "or": _2, "funkfeuer": { "$": 0, "succ": { "wien": _4 } }, "futurecms": { "$": 0, "succ": { "*": _4, "ex": _7, "in": _7 } }, "futurehosting": _4, "futuremailing": _4, "ortsinfo": { "$": 0, "succ": { "ex": _7, "kunden": _7 } }, "biz": _4, "info": _4, "priv": _4, "12hp": _4, "2ix": _4, "4lima": _4, "lima-city": _4 } }, "au": { "$": 1, "succ": { "com": _5, "net": _2, "org": _2, "edu": { "$": 1, "succ": { "act": _2, "catholic": _2, "nsw": { "$": 1, "succ": { "schools": _2 } }, "nt": _2, "qld": _2, "sa": _2, "tas": _2, "vic": _2, "wa": _2 } }, "gov": { "$": 1, "succ": { "qld": _2, "sa": _2, "tas": _2, "vic": _2, "wa": _2 } }, "asn": _2, "id": _2, "info": _2, "conf": _2, "oz": _2, "act": _2, "nsw": _2, "nt": _2, "qld": _2, "sa": _2, "tas": _2, "vic": _2, "wa": _2 } }, "aw": { "$": 1, "succ": { "com": _2 } }, "ax": { "$": 1, "succ": { "be": _4, "cat": _4, "es": _4, "eu": _4, "gg": _4, "mc": _4, "us": _4, "xy": _4 } }, "az": { "$": 1, "succ": { "com": _2, "net": _2, "int": _2, "gov": _2, "org": _2, "edu": _2, "info": _2, "pp": _2, "mil": _2, "name": _2, "pro": _2, "biz": _2 } }, "ba": { "$": 1, "succ": { "com": _2, "edu": _2, "gov": _2, "mil": _2, "net": _2, "org": _2, "blogspot": _4 } }, "bb": { "$": 1, "succ": { "biz": _2, "co": _2, "com": _2, "edu": _2, "gov": _2, "info": _2, "net": _2, "org": _2, "store": _2, "tv": _2 } }, "bd": _8, "be": { "$": 1, "succ": { "ac": _2, "webhosting": _4, "blogspot": _4, "transurl": _7 } }, "bf": _6, "bg": { "$": 1, "succ": { "0": _2, "1": _2, "2": _2, "3": _2, "4": _2, "5": _2, "6": _2, "7": _2, "8": _2, "9": _2, "a": _2, "b": _2, "c": _2, "d": _2, "e": _2, "f": _2, "g": _2, "h": _2, "i": _2, "j": _2, "k": _2, "l": _2, "m": _2, "n": _2, "o": _2, "p": _2, "q": _2, "r": _2, "s": _2, "t": _2, "u": _2, "v": _2, "w": _2, "x": _2, "y": _2, "z": _2, "blogspot": _4, "barsy": _4 } }, "bh": _9, "bi": { "$": 1, "succ": { "co": _2, "com": _2, "edu": _2, "or": _2, "org": _2 } }, "biz": { "$": 1, "succ": { "cloudns": _4, "dyndns": _4, "for-better": _4, "for-more": _4, "for-some": _4, "for-the": _4, "selfip": _4, "webhop": _4, "bpl": _4, "orx": _4, "mmafan": _4, "myftp": _4, "no-ip": _4, "dscloud": _4 } }, "bj": { "$": 1, "succ": { "asso": _2, "barreau": _2, "gouv": _2, "blogspot": _4 } }, "bm": _9, "bn": { "$": 1, "succ": { "com": _2, "edu": _2, "gov": _2, "net": _2, "org": _2, "co": _4 } }, "bo": { "$": 1, "succ": { "com": _2, "edu": _2, "gob": _2, "int": _2, "org": _2, "net": _2, "mil": _2, "tv": _2, "web": _2, "academia": _2, "agro": _2, "arte": _2, "blog": _2, "bolivia": _2, "ciencia": _2, "cooperativa": _2, "democracia": _2, "deporte": _2, "ecologia": _2, "economia": _2, "empresa": _2, "indigena": _2, "industria": _2, "info": _2, "medicina": _2, "movimiento": _2, "musica": _2, "natural": _2, "nombre": _2, "noticias": _2, "patria": _2, "politica": _2, "profesional": _2, "plurinacional": _2, "pueblo": _2, "revista": _2, "salud": _2, "tecnologia": _2, "tksat": _2, "transporte": _2, "wiki": _2 } }, "br": { "$": 1, "succ": { "9guacu": _2, "abc": _2, "adm": _2, "adv": _2, "agr": _2, "aju": _2, "am": _2, "anani": _2, "aparecida": _2, "app": _2, "arq": _2, "art": _2, "ato": _2, "b": _2, "barueri": _2, "belem": _2, "bhz": _2, "bib": _2, "bio": _2, "blog": _2, "bmd": _2, "boavista": _2, "bsb": _2, "campinagrande": _2, "campinas": _2, "caxias": _2, "cim": _2, "cng": _2, "cnt": _2, "com": _5, "contagem": _2, "coop": _2, "coz": _2, "cri": _2, "cuiaba": _2, "curitiba": _2, "def": _2, "des": _2, "det": _2, "dev": _2, "ecn": _2, "eco": _2, "edu": _2, "emp": _2, "enf": _2, "eng": _2, "esp": _2, "etc": _2, "eti": _2, "far": _2, "feira": _2, "flog": _2, "floripa": _2, "fm": _2, "fnd": _2, "fortal": _2, "fot": _2, "foz": _2, "fst": _2, "g12": _2, "geo": _2, "ggf": _2, "goiania": _2, "gov": { "$": 1, "succ": { "ac": _2, "al": _2, "am": _2, "ap": _2, "ba": _2, "ce": _2, "df": _2, "es": _2, "go": _2, "ma": _2, "mg": _2, "ms": _2, "mt": _2, "pa": _2, "pb": _2, "pe": _2, "pi": _2, "pr": _2, "rj": _2, "rn": _2, "ro": _2, "rr": _2, "rs": _2, "sc": _2, "se": _2, "sp": _2, "to": _2 } }, "gru": _2, "imb": _2, "ind": _2, "inf": _2, "jab": _2, "jampa": _2, "jdf": _2, "joinville": _2, "jor": _2, "jus": _2, "leg": { "$": 1, "succ": { "ac": _4, "al": _4, "am": _4, "ap": _4, "ba": _4, "ce": _4, "df": _4, "es": _4, "go": _4, "ma": _4, "mg": _4, "ms": _4, "mt": _4, "pa": _4, "pb": _4, "pe": _4, "pi": _4, "pr": _4, "rj": _4, "rn": _4, "ro": _4, "rr": _4, "rs": _4, "sc": _4, "se": _4, "sp": _4, "to": _4 } }, "lel": _2, "log": _2, "londrina": _2, "macapa": _2, "maceio": _2, "manaus": _2, "maringa": _2, "mat": _2, "med": _2, "mil": _2, "morena": _2, "mp": _2, "mus": _2, "natal": _2, "net": _2, "niteroi": _2, "nom": _8, "not": _2, "ntr": _2, "odo": _2, "ong": _2, "org": _2, "osasco": _2, "palmas": _2, "poa": _2, "ppg": _2, "pro": _2, "psc": _2, "psi": _2, "pvh": _2, "qsl": _2, "radio": _2, "rec": _2, "recife": _2, "rep": _2, "ribeirao": _2, "rio": _2, "riobranco": _2, "riopreto": _2, "salvador": _2, "sampa": _2, "santamaria": _2, "santoandre": _2, "saobernardo": _2, "saogonca": _2, "seg": _2, "sjc": _2, "slg": _2, "slz": _2, "sorocaba": _2, "srv": _2, "taxi": _2, "tc": _2, "tec": _2, "teo": _2, "the": _2, "tmp": _2, "trd": _2, "tur": _2, "tv": _2, "udi": _2, "vet": _2, "vix": _2, "vlog": _2, "wiki": _2, "zlg": _2 } }, "bs": { "$": 1, "succ": { "com": _2, "net": _2, "org": _2, "edu": _2, "gov": _2, "we": _4 } }, "bt": _9, "bv": _2, "bw": { "$": 1, "succ": { "co": _2, "org": _2 } }, "by": { "$": 1, "succ": { "gov": _2, "mil": _2, "com": _5, "of": _2, "nym": _4 } }, "bz": { "$": 1, "succ": { "com": _2, "net": _2, "org": _2, "edu": _2, "gov": _2, "za": _4, "nom": _4, "nym": _4 } }, "ca": { "$": 1, "succ": { "ab": _2, "bc": _2, "mb": _2, "nb": _2, "nf": _2, "nl": _2, "ns": _2, "nt": _2, "nu": _2, "on": _2, "pe": _2, "qc": _2, "sk": _2, "yk": _2, "gc": _2, "barsy": _4, "awdev": _7, "co": _4, "blogspot": _4, "no-ip": _4 } }, "cat": _2, "cc": { "$": 1, "succ": { "cloudns": _4, "ftpaccess": _4, "game-server": _4, "myphotos": _4, "scrapping": _4, "twmail": _4, "csx": _4, "fantasyleague": _4 } }, "cd": _6, "cf": _5, "cg": _2, "ch": { "$": 1, "succ": { "square7": _4, "blogspot": _4, "linkyard-cloud": _4, "dnsking": _4, "gotdns": _4, "12hp": _4, "2ix": _4, "4lima": _4, "lima-city": _4 } }, "ci": { "$": 1, "succ": { "org": _2, "or": _2, "com": _2, "co": _2, "edu": _2, "ed": _2, "ac": _2, "net": _2, "go": _2, "asso": _2, "xn--aroport-bya": _2, "aéroport": _2, "int": _2, "presse": _2, "md": _2, "gouv": _2, "fin": _4, "nl": _4 } }, "ck": _8, "cl": { "$": 1, "succ": { "aprendemas": _2, "co": _2, "gob": _2, "gov": _2, "mil": _2, "blogspot": _4, "nom": _4 } }, "cm": { "$": 1, "succ": { "co": _2, "com": _2, "gov": _2, "net": _2 } }, "cn": { "$": 1, "succ": { "ac": _2, "com": { "$": 1, "succ": { "amazonaws": { "$": 0, "succ": { "compute": _7, "eb": { "$": 0, "succ": { "cn-north-1": _4, "cn-northwest-1": _4 } }, "elb": _7, "cn-north-1": _12 } } } }, "edu": _2, "gov": _2, "net": _2, "org": _2, "mil": _2, "xn--55qx5d": _2, "公司": _2, "xn--io0a7i": _2, "网络": _2, "xn--od0alg": _2, "網絡": _2, "ah": _2, "bj": _2, "cq": _2, "fj": _2, "gd": _2, "gs": _2, "gz": _2, "gx": _2, "ha": _2, "hb": _2, "he": _2, "hi": _2, "hl": _2, "hn": _2, "jl": _2, "js": _2, "jx": _2, "ln": _2, "nm": _2, "nx": _2, "qh": _2, "sc": _2, "sd": _2, "sh": _2, "sn": _2, "sx": _2, "tj": _2, "xj": _2, "xz": _2, "yn": _2, "zj": _2, "hk": _2, "mo": _2, "tw": _2, "instantcloud": _4 } }, "co": { "$": 1, "succ": { "arts": _2, "com": _5, "edu": _2, "firm": _2, "gov": _2, "info": _2, "int": _2, "mil": _2, "net": _2, "nom": _2, "org": _2, "rec": _2, "web": _2, "carrd": _4, "crd": _4, "otap": _7, "leadpages": _4, "lpages": _4, "mypi": _4, "n4t": _4, "nodum": _4, "repl": _4 } }, "com": { "$": 1, "succ": { "adobeaemcloud": { "$": 2, "succ": { "dev": _7 } }, "kasserver": _4, "amazonaws": { "$": 0, "succ": { "compute": _7, "compute-1": _7, "us-east-1": { "$": 2, "succ": { "dualstack": _12 } }, "elb": _7, "s3": _4, "s3-ap-northeast-1": _4, "s3-ap-northeast-2": _4, "s3-ap-south-1": _4, "s3-ap-southeast-1": _4, "s3-ap-southeast-2": _4, "s3-ca-central-1": _4, "s3-eu-central-1": _4, "s3-eu-west-1": _4, "s3-eu-west-2": _4, "s3-eu-west-3": _4, "s3-external-1": _4, "s3-fips-us-gov-west-1": _4, "s3-sa-east-1": _4, "s3-us-gov-west-1": _4, "s3-us-east-2": _4, "s3-us-west-1": _4, "s3-us-west-2": _4, "ap-northeast-2": _14, "ap-south-1": _14, "ca-central-1": _14, "eu-central-1": _14, "eu-west-2": _14, "eu-west-3": _14, "us-east-2": _14, "ap-northeast-1": _13, "ap-southeast-1": _13, "ap-southeast-2": _13, "eu-west-1": _13, "sa-east-1": _13, "s3-website-us-east-1": _4, "s3-website-us-west-1": _4, "s3-website-us-west-2": _4, "s3-website-ap-northeast-1": _4, "s3-website-ap-southeast-1": _4, "s3-website-ap-southeast-2": _4, "s3-website-eu-west-1": _4, "s3-website-sa-east-1": _4 } }, "elasticbeanstalk": { "$": 2, "succ": { "ap-northeast-1": _4, "ap-northeast-2": _4, "ap-northeast-3": _4, "ap-south-1": _4, "ap-southeast-1": _4, "ap-southeast-2": _4, "ca-central-1": _4, "eu-central-1": _4, "eu-west-1": _4, "eu-west-2": _4, "eu-west-3": _4, "sa-east-1": _4, "us-east-1": _4, "us-east-2": _4, "us-gov-west-1": _4, "us-west-1": _4, "us-west-2": _4 } }, "on-aptible": _4, "myasustor": _4, "balena-devices": _4, "betainabox": _4, "bplaced": _4, "ar": _4, "br": _4, "cn": _4, "de": _4, "eu": _4, "gb": _4, "hu": _4, "jpn": _4, "kr": _4, "mex": _4, "no": _4, "qc": _4, "ru": _4, "sa": _4, "uk": _4, "us": _4, "uy": _4, "za": _4, "africa": _4, "gr": _4, "co": _4, "xenapponazure": _4, "jdevcloud": _4, "wpdevcloud": _4, "cloudcontrolled": _4, "cloudcontrolapp": _4, "trycloudflare": _4, "customer-oci": { "$": 0, "succ": { "*": _4, "oci": _7, "ocp": _7, "ocs": _7 } }, "dattolocal": _4, "dattorelay": _4, "dattoweb": _4, "mydatto": _4, "builtwithdark": _4, "drayddns": _4, "dreamhosters": _4, "mydrobo": _4, "dyndns-at-home": _4, "dyndns-at-work": _4, "dyndns-blog": _4, "dyndns-free": _4, "dyndns-home": _4, "dyndns-ip": _4, "dyndns-mail": _4, "dyndns-office": _4, "dyndns-pics": _4, "dyndns-remote": _4, "dyndns-server": _4, "dyndns-web": _4, "dyndns-wiki": _4, "dyndns-work": _4, "blogdns": _4, "cechire": _4, "dnsalias": _4, "dnsdojo": _4, "doesntexist": _4, "dontexist": _4, "doomdns": _4, "dyn-o-saur": _4, "dynalias": _4, "est-a-la-maison": _4, "est-a-la-masion": _4, "est-le-patron": _4, "est-mon-blogueur": _4, "from-ak": _4, "from-al": _4, "from-ar": _4, "from-ca": _4, "from-ct": _4, "from-dc": _4, "from-de": _4, "from-fl": _4, "from-ga": _4, "from-hi": _4, "from-ia": _4, "from-id": _4, "from-il": _4, "from-in": _4, "from-ks": _4, "from-ky": _4, "from-ma": _4, "from-md": _4, "from-mi": _4, "from-mn": _4, "from-mo": _4, "from-ms": _4, "from-mt": _4, "from-nc": _4, "from-nd": _4, "from-ne": _4, "from-nh": _4, "from-nj": _4, "from-nm": _4, "from-nv": _4, "from-oh": _4, "from-ok": _4, "from-or": _4, "from-pa": _4, "from-pr": _4, "from-ri": _4, "from-sc": _4, "from-sd": _4, "from-tn": _4, "from-tx": _4, "from-ut": _4, "from-va": _4, "from-vt": _4, "from-wa": _4, "from-wi": _4, "from-wv": _4, "from-wy": _4, "getmyip": _4, "gotdns": _4, "hobby-site": _4, "homelinux": _4, "homeunix": _4, "iamallama": _4, "is-a-anarchist": _4, "is-a-blogger": _4, "is-a-bookkeeper": _4, "is-a-bulls-fan": _4, "is-a-caterer": _4, "is-a-chef": _4, "is-a-conservative": _4, "is-a-cpa": _4, "is-a-cubicle-slave": _4, "is-a-democrat": _4, "is-a-designer": _4, "is-a-doctor": _4, "is-a-financialadvisor": _4, "is-a-geek": _4, "is-a-green": _4, "is-a-guru": _4, "is-a-hard-worker": _4, "is-a-hunter": _4, "is-a-landscaper": _4, "is-a-lawyer": _4, "is-a-liberal": _4, "is-a-libertarian": _4, "is-a-llama": _4, "is-a-musician": _4, "is-a-nascarfan": _4, "is-a-nurse": _4, "is-a-painter": _4, "is-a-personaltrainer": _4, "is-a-photographer": _4, "is-a-player": _4, "is-a-republican": _4, "is-a-rockstar": _4, "is-a-socialist": _4, "is-a-student": _4, "is-a-teacher": _4, "is-a-techie": _4, "is-a-therapist": _4, "is-an-accountant": _4, "is-an-actor": _4, "is-an-actress": _4, "is-an-anarchist": _4, "is-an-artist": _4, "is-an-engineer": _4, "is-an-entertainer": _4, "is-certified": _4, "is-gone": _4, "is-into-anime": _4, "is-into-cars": _4, "is-into-cartoons": _4, "is-into-games": _4, "is-leet": _4, "is-not-certified": _4, "is-slick": _4, "is-uberleet": _4, "is-with-theband": _4, "isa-geek": _4, "isa-hockeynut": _4, "issmarterthanyou": _4, "likes-pie": _4, "likescandy": _4, "neat-url": _4, "saves-the-whales": _4, "selfip": _4, "sells-for-less": _4, "sells-for-u": _4, "servebbs": _4, "simple-url": _4, "space-to-rent": _4, "teaches-yoga": _4, "writesthisblog": _4, "ddnsfree": _4, "ddnsgeek": _4, "giize": _4, "gleeze": _4, "kozow": _4, "loseyourip": _4, "ooguy": _4, "theworkpc": _4, "mytuleap": _4, "evennode": { "$": 0, "succ": { "eu-1": _4, "eu-2": _4, "eu-3": _4, "eu-4": _4, "us-1": _4, "us-2": _4, "us-3": _4, "us-4": _4 } }, "onfabrica": _4, "fbsbx": _15, "fastly-terrarium": _4, "fastvps-server": _4, "mydobiss": _4, "firebaseapp": _4, "freebox-os": _4, "freeboxos": _4, "gentapps": _4, "gentlentapis": _4, "githubusercontent": _4, "0emm": _7, "appspot": { "$": 2, "succ": { "r": _7 } }, "blogspot": _4, "codespot": _4, "googleapis": _4, "googlecode": _4, "pagespeedmobilizer": _4, "publishproxy": _4, "withgoogle": _4, "withyoutube": _4, "awsmppl": _4, "herokuapp": _4, "herokussl": _4, "myravendb": _4, "pixolino": _4, "dopaas": _4, "hidora": _4, "ik-server": { "$": 0, "succ": { "jcloud": _4 } }, "jelastic": { "$": 0, "succ": { "demo": _4 } }, "joyent": { "$": 0, "succ": { "cns": _7 } }, "lpusercontent": _4, "lmpm": _16, "linode": { "$": 0, "succ": { "members": _4, "nodebalancer": _7 } }, "linodeobjects": _7, "barsycenter": _4, "barsyonline": _4, "miniserver": _4, "meteorapp": { "$": 2, "succ": { "eu": _4 } }, "4u": _4, "nfshost": _4, "001www": _4, "ddnslive": _4, "myiphost": _4, "blogsyte": _4, "ciscofreak": _4, "damnserver": _4, "ditchyourip": _4, "dnsiskinky": _4, "dynns": _4, "geekgalaxy": _4, "health-carereform": _4, "homesecuritymac": _4, "homesecuritypc": _4, "myactivedirectory": _4, "mysecuritycamera": _4, "net-freaks": _4, "onthewifi": _4, "point2this": _4, "quicksytes": _4, "securitytactics": _4, "serveexchange": _4, "servehumour": _4, "servep2p": _4, "servesarcasm": _4, "stufftoread": _4, "unusualperson": _4, "workisboring": _4, "3utilities": _4, "ddnsking": _4, "myvnc": _4, "servebeer": _4, "servecounterstrike": _4, "serveftp": _4, "servegame": _4, "servehalflife": _4, "servehttp": _4, "serveirc": _4, "servemp3": _4, "servepics": _4, "servequake": _4, "observableusercontent": { "$": 0, "succ": { "static": _4 } }, "operaunite": _4, "skygearapp": _4, "outsystemscloud": _4, "ownprovider": _4, "pgfog": _4, "pagefrontapp": _4, "pagexl": _4, "gotpantheon": _4, "platter-app": _4, "pleskns": _4, "prgmr": { "$": 0, "succ": { "xen": _4 } }, "qualifioapp": _4, "qbuser": _4, "qa2": _4, "dev-myqnapcloud": _4, "alpha-myqnapcloud": _4, "myqnapcloud": _4, "quipelements": _7, "rackmaze": _4, "rhcloud": _4, "render": _16, "onrender": _4, "logoip": _4, "scrysec": _4, "firewall-gateway": _4, "myshopblocks": _4, "shopitsite": _4, "1kapp": _4, "appchizi": _4, "applinzi": _4, "sinaapp": _4, "vipsinaapp": _4, "bounty-full": { "$": 2, "succ": { "alpha": _4, "beta": _4 } }, "stackhero-network": _4, "playstation-cloud": _4, "stdlib": { "$": 0, "succ": { "api": _4 } }, "temp-dns": _4, "dsmynas": _4, "familyds": _4, "thingdustdata": _4, "bloxcms": _4, "townnews-staging": _4, "hk": _4, "wafflecell": _4, "remotewd": _4, "wiardweb": { "$": 0, "succ": { "pages": _4 } }, "xnbay": { "$": 2, "succ": { "u2": _4, "u2-local": _4 } }, "yolasite": _4, "wpenginepowered": _4, "impertrixcdn": _4, "impertrix": _4 } }, "coop": _2, "cr": { "$": 1, "succ": { "ac": _2, "co": _2, "ed": _2, "fi": _2, "go": _2, "or": _2, "sa": _2 } }, "cu": { "$": 1, "succ": { "com": _2, "edu": _2, "org": _2, "net": _2, "gov": _2, "inf": _2 } }, "cv": _5, "cw": { "$": 1, "succ": { "com": _2, "edu": _2, "net": _2, "org": _2 } }, "cx": { "$": 1, "succ": { "gov": _2, "ath": _4, "info": _4 } }, "cy": { "$": 1, "succ": { "ac": _2, "biz": _2, "com": { "$": 1, "succ": { "blogspot": _4, "scaleforce": _17 } }, "ekloges": _2, "gov": _2, "ltd": _2, "name": _2, "net": _2, "org": _2, "parliament": _2, "press": _2, "pro": _2, "tm": _2 } }, "cz": { "$": 1, "succ": { "co": _4, "realm": _4, "e4": _4, "blogspot": _4, "metacentrum": { "$": 0, "succ": { "cloud": _4, "custom": _4 } }, "muni": { "$": 0, "succ": { "cloud": { "$": 0, "succ": { "flt": _4, "usr": _4 } } } } } }, "de": { "$": 1, "succ": { "bplaced": _4, "square7": _4, "com": _4, "cosidns": { "$": 0, "succ": { "dyn": _4 } }, "dynamisches-dns": _4, "dnsupdater": _4, "internet-dns": _4, "l-o-g-i-n": _4, "dnshome": _4, "fuettertdasnetz": _4, "isteingeek": _4, "istmein": _4, "lebtimnetz": _4, "leitungsen": _4, "traeumtgerade": _4, "ddnss": { "$": 2, "succ": { "dyn": _4, "dyndns": _4 } }, "dyndns1": _4, "dyn-ip24": _4, "home-webserver": { "$": 2, "succ": { "dyn": _4 } }, "myhome-server": _4, "goip": _4, "blogspot": _4, "dyn-berlin": _4, "in-berlin": _4, "in-brb": _4, "in-butter": _4, "in-dsl": _4, "in-vpn": _4, "mein-iserv": _4, "schulserver": _4, "test-iserv": _4, "keymachine": _4, "git-repos": _4, "lcube-server": _4, "svn-repos": _4, "barsy": _4, "logoip": _4, "firewall-gateway": _4, "my-gateway": _4, "my-router": _4, "spdns": _4, "speedpartner": { "$": 0, "succ": { "customer": _4 } }, "taifun-dns": _4, "12hp": _4, "2ix": _4, "4lima": _4, "lima-city": _4, "dd-dns": _4, "dray-dns": _4, "draydns": _4, "dyn-vpn": _4, "dynvpn": _4, "mein-vigor": _4, "my-vigor": _4, "my-wan": _4, "syno-ds": _4, "synology-diskstation": _4, "synology-ds": _4, "uberspace": _7, "virtualuser": _4, "virtual-user": _4, "community-pro": _4, "diskussionsbereich": _4 } }, "dj": _2, "dk": { "$": 1, "succ": { "biz": _4, "co": _4, "firm": _4, "reg": _4, "store": _4, "blogspot": _4 } }, "dm": _9, "do": { "$": 1, "succ": { "art": _2, "com": _2, "edu": _2, "gob": _2, "gov": _2, "mil": _2, "net": _2, "org": _2, "sld": _2, "web": _2 } }, "dz": { "$": 1, "succ": { "com": _2, "org": _2, "net": _2, "gov": _2, "edu": _2, "asso": _2, "pol": _2, "art": _2 } }, "ec": { "$": 1, "succ": { "com": _2, "info": _2, "net": _2, "fin": _2, "k12": _2, "med": _2, "pro": _2, "org": _2, "edu": _2, "gov": _2, "gob": _2, "mil": _2, "nym": _4 } }, "edu": { "$": 1, "succ": { "rit": { "$": 0, "succ": { "git-pages": _4 } } } }, "ee": { "$": 1, "succ": { "edu": _2, "gov": _2, "riik": _2, "lib": _2, "med": _2, "com": _5, "pri": _2, "aip": _2, "org": _2, "fie": _2 } }, "eg": { "$": 1, "succ": { "com": _5, "edu": _2, "eun": _2, "gov": _2, "mil": _2, "name": _2, "net": _2, "org": _2, "sci": _2 } }, "er": _8, "es": { "$": 1, "succ": { "com": _5, "nom": _2, "org": _2, "gob": _2, "edu": _2 } }, "et": { "$": 1, "succ": { "com": _2, "gov": _2, "org": _2, "edu": _2, "biz": _2, "name": _2, "info": _2, "net": _2 } }, "eu": { "$": 1, "succ": { "mycd": _4, "cloudns": _4, "barsy": _4, "wellbeingzone": _4, "spdns": _4, "transurl": _7, "diskstation": _4 } }, "fi": { "$": 1, "succ": { "aland": _2, "dy": _4, "blogspot": _4, "xn--hkkinen-5wa": _4, "häkkinen": _4, "iki": _4 } }, "fj": { "$": 1, "succ": { "ac": _2, "biz": _2, "com": _2, "gov": _2, "info": _2, "mil": _2, "name": _2, "net": _2, "org": _2, "pro": _2 } }, "fk": _8, "fm": _2, "fo": _2, "fr": { "$": 1, "succ": { "asso": _2, "com": _2, "gouv": _2, "nom": _2, "prd": _2, "tm": _2, "aeroport": _2, "avocat": _2, "avoues": _2, "cci": _2, "chambagri": _2, "chirurgiens-dentistes": _2, "experts-comptables": _2, "geometre-expert": _2, "greta": _2, "huissier-justice": _2, "medecin": _2, "notaires": _2, "pharmacien": _2, "port": _2, "veterinaire": _2, "en-root": _4, "fbx-os": _4, "fbxos": _4, "freebox-os": _4, "freeboxos": _4, "blogspot": _4, "on-web": _4, "chirurgiens-dentistes-en-france": _4 } }, "ga": _2, "gb": _2, "gd": { "$": 1, "succ": { "nom": _4 } }, "ge": { "$": 1, "succ": { "com": _2, "edu": _2, "gov": _2, "org": _2, "mil": _2, "net": _2, "pvt": _2, "nom": _4 } }, "gf": _2, "gg": { "$": 1, "succ": { "co": _2, "net": _2, "org": _2, "kaas": _4, "cya": _4, "panel": { "$": 2, "succ": { "daemon": _4 } } } }, "gh": { "$": 1, "succ": { "com": _2, "edu": _2, "gov": _2, "org": _2, "mil": _2 } }, "gi": { "$": 1, "succ": { "com": _2, "ltd": _2, "gov": _2, "mod": _2, "edu": _2, "org": _2 } }, "gl": { "$": 1, "succ": { "co": _2, "com": _2, "edu": _2, "net": _2, "org": _2, "biz": _4, "nom": _4, "xx": _4 } }, "gm": _2, "gn": { "$": 1, "succ": { "ac": _2, "com": _2, "edu": _2, "gov": _2, "org": _2, "net": _2 } }, "gov": _2, "gp": { "$": 1, "succ": { "com": _2, "net": _2, "mobi": _2, "edu": _2, "org": _2, "asso": _2, "app": _4 } }, "gq": _2, "gr": { "$": 1, "succ": { "com": _2, "edu": _2, "net": _2, "org": _2, "gov": _2, "blogspot": _4, "nym": _4 } }, "gs": _2, "gt": { "$": 1, "succ": { "com": _2, "edu": _2, "gob": _2, "ind": _2, "mil": _2, "net": _2, "org": _2, "nom": _4, "blog": _4, "de": _4, "to": _4 } }, "gu": { "$": 1, "succ": { "com": _2, "edu": _2, "gov": _2, "guam": _2, "info": _2, "net": _2, "org": _2, "web": _2 } }, "gw": _2, "gy": { "$": 1, "succ": { "co": _2, "com": _2, "edu": _2, "gov": _2, "net": _2, "org": _2, "nym": _4, "be": _4 } }, "hk": { "$": 1, "succ": { "com": _2, "edu": _2, "gov": _2, "idv": _2, "net": _2, "org": _2, "xn--55qx5d": _2, "公司": _2, "xn--wcvs22d": _2, "教育": _2, "xn--lcvr32d": _2, "敎育": _2, "xn--mxtq1m": _2, "政府": _2, "xn--gmqw5a": _2, "個人": _2, "xn--ciqpn": _2, "个人": _2, "xn--gmq050i": _2, "箇人": _2, "xn--zf0avx": _2, "網络": _2, "xn--io0a7i": _2, "网络": _2, "xn--mk0axi": _2, "组織": _2, "xn--od0alg": _2, "網絡": _2, "xn--od0aq3b": _2, "网絡": _2, "xn--tn0ag": _2, "组织": _2, "xn--uc0atv": _2, "組織": _2, "xn--uc0ay4a": _2, "組织": _2, "blogspot": _4, "nym": _4, "ltd": _4, "inc": _4 } }, "hm": _2, "hn": { "$": 1, "succ": { "com": _2, "edu": _2, "org": _2, "net": _2, "mil": _2, "gob": _2, "nom": _4, "cc": _4 } }, "hr": { "$": 1, "succ": { "iz": _2, "from": _2, "name": _2, "com": _2, "blogspot": _4, "free": _4 } }, "ht": { "$": 1, "succ": { "com": _2, "shop": _2, "firm": _2, "info": _2, "adult": _2, "net": _2, "pro": _2, "org": _2, "med": _2, "art": _2, "coop": _2, "pol": _2, "asso": _2, "edu": _2, "rel": _2, "gouv": _2, "perso": _2 } }, "hu": { "$": 1, "succ": { "2000": _2, "co": _2, "info": _2, "org": _2, "priv": _2, "sport": _2, "tm": _2, "agrar": _2, "bolt": _2, "casino": _2, "city": _2, "erotica": _2, "erotika": _2, "film": _2, "forum": _2, "games": _2, "hotel": _2, "ingatlan": _2, "jogasz": _2, "konyvelo": _2, "lakas": _2, "media": _2, "news": _2, "reklam": _2, "sex": _2, "shop": _2, "suli": _2, "szex": _2, "tozsde": _2, "utazas": _2, "video": _2, "blogspot": _4 } }, "id": { "$": 1, "succ": { "ac": _2, "biz": _2, "co": _5, "desa": _2, "go": _2, "mil": _2, "my": _2, "net": _2, "or": _2, "ponpes": _2, "sch": _2, "web": _2 } }, "ie": _20, "il": { "$": 1, "succ": { "ac": _2, "co": _5, "gov": _2, "idf": _2, "k12": _2, "muni": _2, "net": _2, "org": _2 } }, "im": { "$": 1, "succ": { "ac": _2, "co": { "$": 1, "succ": { "ltd": _2, "plc": _2 } }, "com": _2, "net": _2, "org": _2, "tt": _2, "tv": _2, "ro": _4, "nom": _4 } }, "in": { "$": 1, "succ": { "co": _2, "firm": _2, "net": _2, "org": _2, "gen": _2, "ind": _2, "nic": _2, "ac": _2, "edu": _2, "res": _2, "gov": _2, "mil": _2, "cloudns": _4, "blogspot": _4, "barsy": _4 } }, "info": { "$": 1, "succ": { "cloudns": _4, "dynamic-dns": _4, "dyndns": _4, "barrel-of-knowledge": _4, "barrell-of-knowledge": _4, "for-our": _4, "groks-the": _4, "groks-this": _4, "here-for-more": _4, "knowsitall": _4, "selfip": _4, "webhop": _4, "barsy": _4, "mayfirst": _4, "forumz": _4, "nsupdate": _4, "dvrcam": _4, "ilovecollege": _4, "no-ip": _4, "dnsupdate": _4, "v-info": _4 } }, "int": { "$": 1, "succ": { "eu": _2 } }, "io": { "$": 1, "succ": { "2038": _4, "com": _2, "apigee": _4, "b-data": _4, "backplaneapp": _4, "banzaicloud": { "$": 0, "succ": { "app": _4, "backyards": _7 } }, "boxfuse": _4, "browsersafetymark": _4, "bigv": { "$": 0, "succ": { "uk0": _4 } }, "cleverapps": _4, "dappnode": { "$": 0, "succ": { "dyndns": _4 } }, "dedyn": _4, "drud": _4, "definima": _4, "enonic": { "$": 2, "succ": { "customer": _4 } }, "shw": _4, "github": _4, "gitlab": _4, "lolipop": _4, "hasura-app": _4, "hostyhosting": _4, "moonscale": _7, "jele": _4, "loginline": _4, "barsy": _4, "azurecontainer": _7, "ngrok": _4, "nodeart": { "$": 0, "succ": { "stage": _4 } }, "nodum": _4, "nid": _4, "pantheonsite": _4, "dyn53": _4, "protonet": _4, "qcx": { "$": 2, "succ": { "sys": _7 } }, "vaporcloud": _4, "vbrplsbx": { "$": 0, "succ": { "g": _4 } }, "on-k3s": _7, "on-rio": _7, "readthedocs": _4, "resindevice": _4, "resinstaging": { "$": 0, "succ": { "devices": _4 } }, "hzc": _4, "sandcats": _4, "shiftedit": _4, "mo-siemens": _4, "lair": _15, "stolos": _7, "spacekit": _4, "utwente": _4, "applicationcloud": _4, "scapp": _4, "s5y": _7, "telebit": _4, "thingdust": { "$": 0, "succ": { "dev": _21, "disrec": _21, "prod": _21, "testing": _21 } }, "wedeploy": _4, "basicserver": _4, "virtualserver": _4 } }, "iq": _3, "ir": { "$": 1, "succ": { "ac": _2, "co": _2, "gov": _2, "id": _2, "net": _2, "org": _2, "sch": _2, "xn--mgba3a4f16a": _2, "ایران": _2, "xn--mgba3a4fra": _2, "ايران": _2 } }, "is": { "$": 1, "succ": { "net": _2, "com": _2, "edu": _2, "gov": _2, "org": _2, "int": _2, "cupcake": _4, "blogspot": _4 } }, "it": { "$": 1, "succ": { "gov": _2, "edu": _2, "abr": _2, "abruzzo": _2, "aosta-valley": _2, "aostavalley": _2, "bas": _2, "basilicata": _2, "cal": _2, "calabria": _2, "cam": _2, "campania": _2, "emilia-romagna": _2, "emiliaromagna": _2, "emr": _2, "friuli-v-giulia": _2, "friuli-ve-giulia": _2, "friuli-vegiulia": _2, "friuli-venezia-giulia": _2, "friuli-veneziagiulia": _2, "friuli-vgiulia": _2, "friuliv-giulia": _2, "friulive-giulia": _2, "friulivegiulia": _2, "friulivenezia-giulia": _2, "friuliveneziagiulia": _2, "friulivgiulia": _2, "fvg": _2, "laz": _2, "lazio": _2, "lig": _2, "liguria": _2, "lom": _2, "lombardia": _2, "lombardy": _2, "lucania": _2, "mar": _2, "marche": _2, "mol": _2, "molise": _2, "piedmont": _2, "piemonte": _2, "pmn": _2, "pug": _2, "puglia": _2, "sar": _2, "sardegna": _2, "sardinia": _2, "sic": _2, "sicilia": _2, "sicily": _2, "taa": _2, "tos": _2, "toscana": _2, "trentin-sud-tirol": _2, "xn--trentin-sd-tirol-rzb": _2, "trentin-süd-tirol": _2, "trentin-sudtirol": _2, "xn--trentin-sdtirol-7vb": _2, "trentin-südtirol": _2, "trentin-sued-tirol": _2, "trentin-suedtirol": _2, "trentino-a-adige": _2, "trentino-aadige": _2, "trentino-alto-adige": _2, "trentino-altoadige": _2, "trentino-s-tirol": _2, "trentino-stirol": _2, "trentino-sud-tirol": _2, "xn--trentino-sd-tirol-c3b": _2, "trentino-süd-tirol": _2, "trentino-sudtirol": _2, "xn--trentino-sdtirol-szb": _2, "trentino-südtirol": _2, "trentino-sued-tirol": _2, "trentino-suedtirol": _2, "trentino": _2, "trentinoa-adige": _2, "trentinoaadige": _2, "trentinoalto-adige": _2, "trentinoaltoadige": _2, "trentinos-tirol": _2, "trentinostirol": _2, "trentinosud-tirol": _2, "xn--trentinosd-tirol-rzb": _2, "trentinosüd-tirol": _2, "trentinosudtirol": _2, "xn--trentinosdtirol-7vb": _2, "trentinosüdtirol": _2, "trentinosued-tirol": _2, "trentinosuedtirol": _2, "trentinsud-tirol": _2, "xn--trentinsd-tirol-6vb": _2, "trentinsüd-tirol": _2, "trentinsudtirol": _2, "xn--trentinsdtirol-nsb": _2, "trentinsüdtirol": _2, "trentinsued-tirol": _2, "trentinsuedtirol": _2, "tuscany": _2, "umb": _2, "umbria": _2, "val-d-aosta": _2, "val-daosta": _2, "vald-aosta": _2, "valdaosta": _2, "valle-aosta": _2, "valle-d-aosta": _2, "valle-daosta": _2, "valleaosta": _2, "valled-aosta": _2, "valledaosta": _2, "vallee-aoste": _2, "xn--valle-aoste-ebb": _2, "vallée-aoste": _2, "vallee-d-aoste": _2, "xn--valle-d-aoste-ehb": _2, "vallée-d-aoste": _2, "valleeaoste": _2, "xn--valleaoste-e7a": _2, "valléeaoste": _2, "valleedaoste": _2, "xn--valledaoste-ebb": _2, "valléedaoste": _2, "vao": _2, "vda": _2, "ven": _2, "veneto": _2, "ag": _2, "agrigento": _2, "al": _2, "alessandria": _2, "alto-adige": _2, "altoadige": _2, "an": _2, "ancona": _2, "andria-barletta-trani": _2, "andria-trani-barletta": _2, "andriabarlettatrani": _2, "andriatranibarletta": _2, "ao": _2, "aosta": _2, "aoste": _2, "ap": _2, "aq": _2, "aquila": _2, "ar": _2, "arezzo": _2, "ascoli-piceno": _2, "ascolipiceno": _2, "asti": _2, "at": _2, "av": _2, "avellino": _2, "ba": _2, "balsan-sudtirol": _2, "xn--balsan-sdtirol-nsb": _2, "balsan-südtirol": _2, "balsan-suedtirol": _2, "balsan": _2, "bari": _2, "barletta-trani-andria": _2, "barlettatraniandria": _2, "belluno": _2, "benevento": _2, "bergamo": _2, "bg": _2, "bi": _2, "biella": _2, "bl": _2, "bn": _2, "bo": _2, "bologna": _2, "bolzano-altoadige": _2, "bolzano": _2, "bozen-sudtirol": _2, "xn--bozen-sdtirol-2ob": _2, "bozen-südtirol": _2, "bozen-suedtirol": _2, "bozen": _2, "br": _2, "brescia": _2, "brindisi": _2, "bs": _2, "bt": _2, "bulsan-sudtirol": _2, "xn--bulsan-sdtirol-nsb": _2, "bulsan-südtirol": _2, "bulsan-suedtirol": _2, "bulsan": _2, "bz": _2, "ca": _2, "cagliari": _2, "caltanissetta": _2, "campidano-medio": _2, "campidanomedio": _2, "campobasso": _2, "carbonia-iglesias": _2, "carboniaiglesias": _2, "carrara-massa": _2, "carraramassa": _2, "caserta": _2, "catania": _2, "catanzaro": _2, "cb": _2, "ce": _2, "cesena-forli": _2, "xn--cesena-forl-mcb": _2, "cesena-forlì": _2, "cesenaforli": _2, "xn--cesenaforl-i8a": _2, "cesenaforlì": _2, "ch": _2, "chieti": _2, "ci": _2, "cl": _2, "cn": _2, "co": _2, "como": _2, "cosenza": _2, "cr": _2, "cremona": _2, "crotone": _2, "cs": _2, "ct": _2, "cuneo": _2, "cz": _2, "dell-ogliastra": _2, "dellogliastra": _2, "en": _2, "enna": _2, "fc": _2, "fe": _2, "fermo": _2, "ferrara": _2, "fg": _2, "fi": _2, "firenze": _2, "florence": _2, "fm": _2, "foggia": _2, "forli-cesena": _2, "xn--forl-cesena-fcb": _2, "forlì-cesena": _2, "forlicesena": _2, "xn--forlcesena-c8a": _2, "forlìcesena": _2, "fr": _2, "frosinone": _2, "ge": _2, "genoa": _2, "genova": _2, "go": _2, "gorizia": _2, "gr": _2, "grosseto": _2, "iglesias-carbonia": _2, "iglesiascarbonia": _2, "im": _2, "imperia": _2, "is": _2, "isernia": _2, "kr": _2, "la-spezia": _2, "laquila": _2, "laspezia": _2, "latina": _2, "lc": _2, "le": _2, "lecce": _2, "lecco": _2, "li": _2, "livorno": _2, "lo": _2, "lodi": _2, "lt": _2, "lu": _2, "lucca": _2, "macerata": _2, "mantova": _2, "massa-carrara": _2, "massacarrara": _2, "matera": _2, "mb": _2, "mc": _2, "me": _2, "medio-campidano": _2, "mediocampidano": _2, "messina": _2, "mi": _2, "milan": _2, "milano": _2, "mn": _2, "mo": _2, "modena": _2, "monza-brianza": _2, "monza-e-della-brianza": _2, "monza": _2, "monzabrianza": _2, "monzaebrianza": _2, "monzaedellabrianza": _2, "ms": _2, "mt": _2, "na": _2, "naples": _2, "napoli": _2, "no": _2, "novara": _2, "nu": _2, "nuoro": _2, "og": _2, "ogliastra": _2, "olbia-tempio": _2, "olbiatempio": _2, "or": _2, "oristano": _2, "ot": _2, "pa": _2, "padova": _2, "padua": _2, "palermo": _2, "parma": _2, "pavia": _2, "pc": _2, "pd": _2, "pe": _2, "perugia": _2, "pesaro-urbino": _2, "pesarourbino": _2, "pescara": _2, "pg": _2, "pi": _2, "piacenza": _2, "pisa": _2, "pistoia": _2, "pn": _2, "po": _2, "pordenone": _2, "potenza": _2, "pr": _2, "prato": _2, "pt": _2, "pu": _2, "pv": _2, "pz": _2, "ra": _2, "ragusa": _2, "ravenna": _2, "rc": _2, "re": _2, "reggio-calabria": _2, "reggio-emilia": _2, "reggiocalabria": _2, "reggioemilia": _2, "rg": _2, "ri": _2, "rieti": _2, "rimini": _2, "rm": _2, "rn": _2, "ro": _2, "roma": _2, "rome": _2, "rovigo": _2, "sa": _2, "salerno": _2, "sassari": _2, "savona": _2, "si": _2, "siena": _2, "siracusa": _2, "so": _2, "sondrio": _2, "sp": _2, "sr": _2, "ss": _2, "suedtirol": _2, "xn--sdtirol-n2a": _2, "südtirol": _2, "sv": _2, "ta": _2, "taranto": _2, "te": _2, "tempio-olbia": _2, "tempioolbia": _2, "teramo": _2, "terni": _2, "tn": _2, "to": _2, "torino": _2, "tp": _2, "tr": _2, "trani-andria-barletta": _2, "trani-barletta-andria": _2, "traniandriabarletta": _2, "tranibarlettaandria": _2, "trapani": _2, "trento": _2, "treviso": _2, "trieste": _2, "ts": _2, "turin": _2, "tv": _2, "ud": _2, "udine": _2, "urbino-pesaro": _2, "urbinopesaro": _2, "va": _2, "varese": _2, "vb": _2, "vc": _2, "ve": _2, "venezia": _2, "venice": _2, "verbania": _2, "vercelli": _2, "verona": _2, "vi": _2, "vibo-valentia": _2, "vibovalentia": _2, "vicenza": _2, "viterbo": _2, "vr": _2, "vs": _2, "vt": _2, "vv": _2, "blogspot": _4, "16-b": _4, "32-b": _4, "64-b": _4, "syncloud": _4 } }, "je": { "$": 1, "succ": { "co": _2, "net": _2, "org": _2 } }, "jm": _8, "jo": { "$": 1, "succ": { "com": _2, "org": _2, "net": _2, "edu": _2, "sch": _2, "gov": _2, "mil": _2, "name": _2 } }, "jobs": _2, "jp": { "$": 1, "succ": { "ac": _2, "ad": _2, "co": _2, "ed": _2, "go": _2, "gr": _2, "lg": _2, "ne": { "$": 1, "succ": { "aseinet": _18, "gehirn": _4 } }, "or": _2, "aichi": { "$": 1, "succ": { "aisai": _2, "ama": _2, "anjo": _2, "asuke": _2, "chiryu": _2, "chita": _2, "fuso": _2, "gamagori": _2, "handa": _2, "hazu": _2, "hekinan": _2, "higashiura": _2, "ichinomiya": _2, "inazawa": _2, "inuyama": _2, "isshiki": _2, "iwakura": _2, "kanie": _2, "kariya": _2, "kasugai": _2, "kira": _2, "kiyosu": _2, "komaki": _2, "konan": _2, "kota": _2, "mihama": _2, "miyoshi": _2, "nishio": _2, "nisshin": _2, "obu": _2, "oguchi": _2, "oharu": _2, "okazaki": _2, "owariasahi": _2, "seto": _2, "shikatsu": _2, "shinshiro": _2, "shitara": _2, "tahara": _2, "takahama": _2, "tobishima": _2, "toei": _2, "togo": _2, "tokai": _2, "tokoname": _2, "toyoake": _2, "toyohashi": _2, "toyokawa": _2, "toyone": _2, "toyota": _2, "tsushima": _2, "yatomi": _2 } }, "akita": { "$": 1, "succ": { "akita": _2, "daisen": _2, "fujisato": _2, "gojome": _2, "hachirogata": _2, "happou": _2, "higashinaruse": _2, "honjo": _2, "honjyo": _2, "ikawa": _2, "kamikoani": _2, "kamioka": _2, "katagami": _2, "kazuno": _2, "kitaakita": _2, "kosaka": _2, "kyowa": _2, "misato": _2, "mitane": _2, "moriyoshi": _2, "nikaho": _2, "noshiro": _2, "odate": _2, "oga": _2, "ogata": _2, "semboku": _2, "yokote": _2, "yurihonjo": _2 } }, "aomori": { "$": 1, "succ": { "aomori": _2, "gonohe": _2, "hachinohe": _2, "hashikami": _2, "hiranai": _2, "hirosaki": _2, "itayanagi": _2, "kuroishi": _2, "misawa": _2, "mutsu": _2, "nakadomari": _2, "noheji": _2, "oirase": _2, "owani": _2, "rokunohe": _2, "sannohe": _2, "shichinohe": _2, "shingo": _2, "takko": _2, "towada": _2, "tsugaru": _2, "tsuruta": _2 } }, "chiba": { "$": 1, "succ": { "abiko": _2, "asahi": _2, "chonan": _2, "chosei": _2, "choshi": _2, "chuo": _2, "funabashi": _2, "futtsu": _2, "hanamigawa": _2, "ichihara": _2, "ichikawa": _2, "ichinomiya": _2, "inzai": _2, "isumi": _2, "kamagaya": _2, "kamogawa": _2, "kashiwa": _2, "katori": _2, "katsuura": _2, "kimitsu": _2, "kisarazu": _2, "kozaki": _2, "kujukuri": _2, "kyonan": _2, "matsudo": _2, "midori": _2, "mihama": _2, "minamiboso": _2, "mobara": _2, "mutsuzawa": _2, "nagara": _2, "nagareyama": _2, "narashino": _2, "narita": _2, "noda": _2, "oamishirasato": _2, "omigawa": _2, "onjuku": _2, "otaki": _2, "sakae": _2, "sakura": _2, "shimofusa": _2, "shirako": _2, "shiroi": _2, "shisui": _2, "sodegaura": _2, "sosa": _2, "tako": _2, "tateyama": _2, "togane": _2, "tohnosho": _2, "tomisato": _2, "urayasu": _2, "yachimata": _2, "yachiyo": _2, "yokaichiba": _2, "yokoshibahikari": _2, "yotsukaido": _2 } }, "ehime": { "$": 1, "succ": { "ainan": _2, "honai": _2, "ikata": _2, "imabari": _2, "iyo": _2, "kamijima": _2, "kihoku": _2, "kumakogen": _2, "masaki": _2, "matsuno": _2, "matsuyama": _2, "namikata": _2, "niihama": _2, "ozu": _2, "saijo": _2, "seiyo": _2, "shikokuchuo": _2, "tobe": _2, "toon": _2, "uchiko": _2, "uwajima": _2, "yawatahama": _2 } }, "fukui": { "$": 1, "succ": { "echizen": _2, "eiheiji": _2, "fukui": _2, "ikeda": _2, "katsuyama": _2, "mihama": _2, "minamiechizen": _2, "obama": _2, "ohi": _2, "ono": _2, "sabae": _2, "sakai": _2, "takahama": _2, "tsuruga": _2, "wakasa": _2 } }, "fukuoka": { "$": 1, "succ": { "ashiya": _2, "buzen": _2, "chikugo": _2, "chikuho": _2, "chikujo": _2, "chikushino": _2, "chikuzen": _2, "chuo": _2, "dazaifu": _2, "fukuchi": _2, "hakata": _2, "higashi": _2, "hirokawa": _2, "hisayama": _2, "iizuka": _2, "inatsuki": _2, "kaho": _2, "kasuga": _2, "kasuya": _2, "kawara": _2, "keisen": _2, "koga": _2, "kurate": _2, "kurogi": _2, "kurume": _2, "minami": _2, "miyako": _2, "miyama": _2, "miyawaka": _2, "mizumaki": _2, "munakata": _2, "nakagawa": _2, "nakama": _2, "nishi": _2, "nogata": _2, "ogori": _2, "okagaki": _2, "okawa": _2, "oki": _2, "omuta": _2, "onga": _2, "onojo": _2, "oto": _2, "saigawa": _2, "sasaguri": _2, "shingu": _2, "shinyoshitomi": _2, "shonai": _2, "soeda": _2, "sue": _2, "tachiarai": _2, "tagawa": _2, "takata": _2, "toho": _2, "toyotsu": _2, "tsuiki": _2, "ukiha": _2, "umi": _2, "usui": _2, "yamada": _2, "yame": _2, "yanagawa": _2, "yukuhashi": _2 } }, "fukushima": { "$": 1, "succ": { "aizubange": _2, "aizumisato": _2, "aizuwakamatsu": _2, "asakawa": _2, "bandai": _2, "date": _2, "fukushima": _2, "furudono": _2, "futaba": _2, "hanawa": _2, "higashi": _2, "hirata": _2, "hirono": _2, "iitate": _2, "inawashiro": _2, "ishikawa": _2, "iwaki": _2, "izumizaki": _2, "kagamiishi": _2, "kaneyama": _2, "kawamata": _2, "kitakata": _2, "kitashiobara": _2, "koori": _2, "koriyama": _2, "kunimi": _2, "miharu": _2, "mishima": _2, "namie": _2, "nango": _2, "nishiaizu": _2, "nishigo": _2, "okuma": _2, "omotego": _2, "ono": _2, "otama": _2, "samegawa": _2, "shimogo": _2, "shirakawa": _2, "showa": _2, "soma": _2, "sukagawa": _2, "taishin": _2, "tamakawa": _2, "tanagura": _2, "tenei": _2, "yabuki": _2, "yamato": _2, "yamatsuri": _2, "yanaizu": _2, "yugawa": _2 } }, "gifu": { "$": 1, "succ": { "anpachi": _2, "ena": _2, "gifu": _2, "ginan": _2, "godo": _2, "gujo": _2, "hashima": _2, "hichiso": _2, "hida": _2, "higashishirakawa": _2, "ibigawa": _2, "ikeda": _2, "kakamigahara": _2, "kani": _2, "kasahara": _2, "kasamatsu": _2, "kawaue": _2, "kitagata": _2, "mino": _2, "minokamo": _2, "mitake": _2, "mizunami": _2, "motosu": _2, "nakatsugawa": _2, "ogaki": _2, "sakahogi": _2, "seki": _2, "sekigahara": _2, "shirakawa": _2, "tajimi": _2, "takayama": _2, "tarui": _2, "toki": _2, "tomika": _2, "wanouchi": _2, "yamagata": _2, "yaotsu": _2, "yoro": _2 } }, "gunma": { "$": 1, "succ": { "annaka": _2, "chiyoda": _2, "fujioka": _2, "higashiagatsuma": _2, "isesaki": _2, "itakura": _2, "kanna": _2, "kanra": _2, "katashina": _2, "kawaba": _2, "kiryu": _2, "kusatsu": _2, "maebashi": _2, "meiwa": _2, "midori": _2, "minakami": _2, "naganohara": _2, "nakanojo": _2, "nanmoku": _2, "numata": _2, "oizumi": _2, "ora": _2, "ota": _2, "shibukawa": _2, "shimonita": _2, "shinto": _2, "showa": _2, "takasaki": _2, "takayama": _2, "tamamura": _2, "tatebayashi": _2, "tomioka": _2, "tsukiyono": _2, "tsumagoi": _2, "ueno": _2, "yoshioka": _2 } }, "hiroshima": { "$": 1, "succ": { "asaminami": _2, "daiwa": _2, "etajima": _2, "fuchu": _2, "fukuyama": _2, "hatsukaichi": _2, "higashihiroshima": _2, "hongo": _2, "jinsekikogen": _2, "kaita": _2, "kui": _2, "kumano": _2, "kure": _2, "mihara": _2, "miyoshi": _2, "naka": _2, "onomichi": _2, "osakikamijima": _2, "otake": _2, "saka": _2, "sera": _2, "seranishi": _2, "shinichi": _2, "shobara": _2, "takehara": _2 } }, "hokkaido": { "$": 1, "succ": { "abashiri": _2, "abira": _2, "aibetsu": _2, "akabira": _2, "akkeshi": _2, "asahikawa": _2, "ashibetsu": _2, "ashoro": _2, "assabu": _2, "atsuma": _2, "bibai": _2, "biei": _2, "bifuka": _2, "bihoro": _2, "biratori": _2, "chippubetsu": _2, "chitose": _2, "date": _2, "ebetsu": _2, "embetsu": _2, "eniwa": _2, "erimo": _2, "esan": _2, "esashi": _2, "fukagawa": _2, "fukushima": _2, "furano": _2, "furubira": _2, "haboro": _2, "hakodate": _2, "hamatonbetsu": _2, "hidaka": _2, "higashikagura": _2, "higashikawa": _2, "hiroo": _2, "hokuryu": _2, "hokuto": _2, "honbetsu": _2, "horokanai": _2, "horonobe": _2, "ikeda": _2, "imakane": _2, "ishikari": _2, "iwamizawa": _2, "iwanai": _2, "kamifurano": _2, "kamikawa": _2, "kamishihoro": _2, "kamisunagawa": _2, "kamoenai": _2, "kayabe": _2, "kembuchi": _2, "kikonai": _2, "kimobetsu": _2, "kitahiroshima": _2, "kitami": _2, "kiyosato": _2, "koshimizu": _2, "kunneppu": _2, "kuriyama": _2, "kuromatsunai": _2, "kushiro": _2, "kutchan": _2, "kyowa": _2, "mashike": _2, "matsumae": _2, "mikasa": _2, "minamifurano": _2, "mombetsu": _2, "moseushi": _2, "mukawa": _2, "muroran": _2, "naie": _2, "nakagawa": _2, "nakasatsunai": _2, "nakatombetsu": _2, "nanae": _2, "nanporo": _2, "nayoro": _2, "nemuro": _2, "niikappu": _2, "niki": _2, "nishiokoppe": _2, "noboribetsu": _2, "numata": _2, "obihiro": _2, "obira": _2, "oketo": _2, "okoppe": _2, "otaru": _2, "otobe": _2, "otofuke": _2, "otoineppu": _2, "oumu": _2, "ozora": _2, "pippu": _2, "rankoshi": _2, "rebun": _2, "rikubetsu": _2, "rishiri": _2, "rishirifuji": _2, "saroma": _2, "sarufutsu": _2, "shakotan": _2, "shari": _2, "shibecha": _2, "shibetsu": _2, "shikabe": _2, "shikaoi": _2, "shimamaki": _2, "shimizu": _2, "shimokawa": _2, "shinshinotsu": _2, "shintoku": _2, "shiranuka": _2, "shiraoi": _2, "shiriuchi": _2, "sobetsu": _2, "sunagawa": _2, "taiki": _2, "takasu": _2, "takikawa": _2, "takinoue": _2, "teshikaga": _2, "tobetsu": _2, "tohma": _2, "tomakomai": _2, "tomari": _2, "toya": _2, "toyako": _2, "toyotomi": _2, "toyoura": _2, "tsubetsu": _2, "tsukigata": _2, "urakawa": _2, "urausu": _2, "uryu": _2, "utashinai": _2, "wakkanai": _2, "wassamu": _2, "yakumo": _2, "yoichi": _2 } }, "hyogo": { "$": 1, "succ": { "aioi": _2, "akashi": _2, "ako": _2, "amagasaki": _2, "aogaki": _2, "asago": _2, "ashiya": _2, "awaji": _2, "fukusaki": _2, "goshiki": _2, "harima": _2, "himeji": _2, "ichikawa": _2, "inagawa": _2, "itami": _2, "kakogawa": _2, "kamigori": _2, "kamikawa": _2, "kasai": _2, "kasuga": _2, "kawanishi": _2, "miki": _2, "minamiawaji": _2, "nishinomiya": _2, "nishiwaki": _2, "ono": _2, "sanda": _2, "sannan": _2, "sasayama": _2, "sayo": _2, "shingu": _2, "shinonsen": _2, "shiso": _2, "sumoto": _2, "taishi": _2, "taka": _2, "takarazuka": _2, "takasago": _2, "takino": _2, "tamba": _2, "tatsuno": _2, "toyooka": _2, "yabu": _2, "yashiro": _2, "yoka": _2, "yokawa": _2 } }, "ibaraki": { "$": 1, "succ": { "ami": _2, "asahi": _2, "bando": _2, "chikusei": _2, "daigo": _2, "fujishiro": _2, "hitachi": _2, "hitachinaka": _2, "hitachiomiya": _2, "hitachiota": _2, "ibaraki": _2, "ina": _2, "inashiki": _2, "itako": _2, "iwama": _2, "joso": _2, "kamisu": _2, "kasama": _2, "kashima": _2, "kasumigaura": _2, "koga": _2, "miho": _2, "mito": _2, "moriya": _2, "naka": _2, "namegata": _2, "oarai": _2, "ogawa": _2, "omitama": _2, "ryugasaki": _2, "sakai": _2, "sakuragawa": _2, "shimodate": _2, "shimotsuma": _2, "shirosato": _2, "sowa": _2, "suifu": _2, "takahagi": _2, "tamatsukuri": _2, "tokai": _2, "tomobe": _2, "tone": _2, "toride": _2, "tsuchiura": _2, "tsukuba": _2, "uchihara": _2, "ushiku": _2, "yachiyo": _2, "yamagata": _2, "yawara": _2, "yuki": _2 } }, "ishikawa": { "$": 1, "succ": { "anamizu": _2, "hakui": _2, "hakusan": _2, "kaga": _2, "kahoku": _2, "kanazawa": _2, "kawakita": _2, "komatsu": _2, "nakanoto": _2, "nanao": _2, "nomi": _2, "nonoichi": _2, "noto": _2, "shika": _2, "suzu": _2, "tsubata": _2, "tsurugi": _2, "uchinada": _2, "wajima": _2 } }, "iwate": { "$": 1, "succ": { "fudai": _2, "fujisawa": _2, "hanamaki": _2, "hiraizumi": _2, "hirono": _2, "ichinohe": _2, "ichinoseki": _2, "iwaizumi": _2, "iwate": _2, "joboji": _2, "kamaishi": _2, "kanegasaki": _2, "karumai": _2, "kawai": _2, "kitakami": _2, "kuji": _2, "kunohe": _2, "kuzumaki": _2, "miyako": _2, "mizusawa": _2, "morioka": _2, "ninohe": _2, "noda": _2, "ofunato": _2, "oshu": _2, "otsuchi": _2, "rikuzentakata": _2, "shiwa": _2, "shizukuishi": _2, "sumita": _2, "tanohata": _2, "tono": _2, "yahaba": _2, "yamada": _2 } }, "kagawa": { "$": 1, "succ": { "ayagawa": _2, "higashikagawa": _2, "kanonji": _2, "kotohira": _2, "manno": _2, "marugame": _2, "mitoyo": _2, "naoshima": _2, "sanuki": _2, "tadotsu": _2, "takamatsu": _2, "tonosho": _2, "uchinomi": _2, "utazu": _2, "zentsuji": _2 } }, "kagoshima": { "$": 1, "succ": { "akune": _2, "amami": _2, "hioki": _2, "isa": _2, "isen": _2, "izumi": _2, "kagoshima": _2, "kanoya": _2, "kawanabe": _2, "kinko": _2, "kouyama": _2, "makurazaki": _2, "matsumoto": _2, "minamitane": _2, "nakatane": _2, "nishinoomote": _2, "satsumasendai": _2, "soo": _2, "tarumizu": _2, "yusui": _2 } }, "kanagawa": { "$": 1, "succ": { "aikawa": _2, "atsugi": _2, "ayase": _2, "chigasaki": _2, "ebina": _2, "fujisawa": _2, "hadano": _2, "hakone": _2, "hiratsuka": _2, "isehara": _2, "kaisei": _2, "kamakura": _2, "kiyokawa": _2, "matsuda": _2, "minamiashigara": _2, "miura": _2, "nakai": _2, "ninomiya": _2, "odawara": _2, "oi": _2, "oiso": _2, "sagamihara": _2, "samukawa": _2, "tsukui": _2, "yamakita": _2, "yamato": _2, "yokosuka": _2, "yugawara": _2, "zama": _2, "zushi": _2 } }, "kochi": { "$": 1, "succ": { "aki": _2, "geisei": _2, "hidaka": _2, "higashitsuno": _2, "ino": _2, "kagami": _2, "kami": _2, "kitagawa": _2, "kochi": _2, "mihara": _2, "motoyama": _2, "muroto": _2, "nahari": _2, "nakamura": _2, "nankoku": _2, "nishitosa": _2, "niyodogawa": _2, "ochi": _2, "okawa": _2, "otoyo": _2, "otsuki": _2, "sakawa": _2, "sukumo": _2, "susaki": _2, "tosa": _2, "tosashimizu": _2, "toyo": _2, "tsuno": _2, "umaji": _2, "yasuda": _2, "yusuhara": _2 } }, "kumamoto": { "$": 1, "succ": { "amakusa": _2, "arao": _2, "aso": _2, "choyo": _2, "gyokuto": _2, "kamiamakusa": _2, "kikuchi": _2, "kumamoto": _2, "mashiki": _2, "mifune": _2, "minamata": _2, "minamioguni": _2, "nagasu": _2, "nishihara": _2, "oguni": _2, "ozu": _2, "sumoto": _2, "takamori": _2, "uki": _2, "uto": _2, "yamaga": _2, "yamato": _2, "yatsushiro": _2 } }, "kyoto": { "$": 1, "succ": { "ayabe": _2, "fukuchiyama": _2, "higashiyama": _2, "ide": _2, "ine": _2, "joyo": _2, "kameoka": _2, "kamo": _2, "kita": _2, "kizu": _2, "kumiyama": _2, "kyotamba": _2, "kyotanabe": _2, "kyotango": _2, "maizuru": _2, "minami": _2, "minamiyamashiro": _2, "miyazu": _2, "muko": _2, "nagaokakyo": _2, "nakagyo": _2, "nantan": _2, "oyamazaki": _2, "sakyo": _2, "seika": _2, "tanabe": _2, "uji": _2, "ujitawara": _2, "wazuka": _2, "yamashina": _2, "yawata": _2 } }, "mie": { "$": 1, "succ": { "asahi": _2, "inabe": _2, "ise": _2, "kameyama": _2, "kawagoe": _2, "kiho": _2, "kisosaki": _2, "kiwa": _2, "komono": _2, "kumano": _2, "kuwana": _2, "matsusaka": _2, "meiwa": _2, "mihama": _2, "minamiise": _2, "misugi": _2, "miyama": _2, "nabari": _2, "shima": _2, "suzuka": _2, "tado": _2, "taiki": _2, "taki": _2, "tamaki": _2, "toba": _2, "tsu": _2, "udono": _2, "ureshino": _2, "watarai": _2, "yokkaichi": _2 } }, "miyagi": { "$": 1, "succ": { "furukawa": _2, "higashimatsushima": _2, "ishinomaki": _2, "iwanuma": _2, "kakuda": _2, "kami": _2, "kawasaki": _2, "marumori": _2, "matsushima": _2, "minamisanriku": _2, "misato": _2, "murata": _2, "natori": _2, "ogawara": _2, "ohira": _2, "onagawa": _2, "osaki": _2, "rifu": _2, "semine": _2, "shibata": _2, "shichikashuku": _2, "shikama": _2, "shiogama": _2, "shiroishi": _2, "tagajo": _2, "taiwa": _2, "tome": _2, "tomiya": _2, "wakuya": _2, "watari": _2, "yamamoto": _2, "zao": _2 } }, "miyazaki": { "$": 1, "succ": { "aya": _2, "ebino": _2, "gokase": _2, "hyuga": _2, "kadogawa": _2, "kawaminami": _2, "kijo": _2, "kitagawa": _2, "kitakata": _2, "kitaura": _2, "kobayashi": _2, "kunitomi": _2, "kushima": _2, "mimata": _2, "miyakonojo": _2, "miyazaki": _2, "morotsuka": _2, "nichinan": _2, "nishimera": _2, "nobeoka": _2, "saito": _2, "shiiba": _2, "shintomi": _2, "takaharu": _2, "takanabe": _2, "takazaki": _2, "tsuno": _2 } }, "nagano": { "$": 1, "succ": { "achi": _2, "agematsu": _2, "anan": _2, "aoki": _2, "asahi": _2, "azumino": _2, "chikuhoku": _2, "chikuma": _2, "chino": _2, "fujimi": _2, "hakuba": _2, "hara": _2, "hiraya": _2, "iida": _2, "iijima": _2, "iiyama": _2, "iizuna": _2, "ikeda": _2, "ikusaka": _2, "ina": _2, "karuizawa": _2, "kawakami": _2, "kiso": _2, "kisofukushima": _2, "kitaaiki": _2, "komagane": _2, "komoro": _2, "matsukawa": _2, "matsumoto": _2, "miasa": _2, "minamiaiki": _2, "minamimaki": _2, "minamiminowa": _2, "minowa": _2, "miyada": _2, "miyota": _2, "mochizuki": _2, "nagano": _2, "nagawa": _2, "nagiso": _2, "nakagawa": _2, "nakano": _2, "nozawaonsen": _2, "obuse": _2, "ogawa": _2, "okaya": _2, "omachi": _2, "omi": _2, "ookuwa": _2, "ooshika": _2, "otaki": _2, "otari": _2, "sakae": _2, "sakaki": _2, "saku": _2, "sakuho": _2, "shimosuwa": _2, "shinanomachi": _2, "shiojiri": _2, "suwa": _2, "suzaka": _2, "takagi": _2, "takamori": _2, "takayama": _2, "tateshina": _2, "tatsuno": _2, "togakushi": _2, "togura": _2, "tomi": _2, "ueda": _2, "wada": _2, "yamagata": _2, "yamanouchi": _2, "yasaka": _2, "yasuoka": _2 } }, "nagasaki": { "$": 1, "succ": { "chijiwa": _2, "futsu": _2, "goto": _2, "hasami": _2, "hirado": _2, "iki": _2, "isahaya": _2, "kawatana": _2, "kuchinotsu": _2, "matsuura": _2, "nagasaki": _2, "obama": _2, "omura": _2, "oseto": _2, "saikai": _2, "sasebo": _2, "seihi": _2, "shimabara": _2, "shinkamigoto": _2, "togitsu": _2, "tsushima": _2, "unzen": _2 } }, "nara": { "$": 1, "succ": { "ando": _2, "gose": _2, "heguri": _2, "higashiyoshino": _2, "ikaruga": _2, "ikoma": _2, "kamikitayama": _2, "kanmaki": _2, "kashiba": _2, "kashihara": _2, "katsuragi": _2, "kawai": _2, "kawakami": _2, "kawanishi": _2, "koryo": _2, "kurotaki": _2, "mitsue": _2, "miyake": _2, "nara": _2, "nosegawa": _2, "oji": _2, "ouda": _2, "oyodo": _2, "sakurai": _2, "sango": _2, "shimoichi": _2, "shimokitayama": _2, "shinjo": _2, "soni": _2, "takatori": _2, "tawaramoto": _2, "tenkawa": _2, "tenri": _2, "uda": _2, "yamatokoriyama": _2, "yamatotakada": _2, "yamazoe": _2, "yoshino": _2 } }, "niigata": { "$": 1, "succ": { "aga": _2, "agano": _2, "gosen": _2, "itoigawa": _2, "izumozaki": _2, "joetsu": _2, "kamo": _2, "kariwa": _2, "kashiwazaki": _2, "minamiuonuma": _2, "mitsuke": _2, "muika": _2, "murakami": _2, "myoko": _2, "nagaoka": _2, "niigata": _2, "ojiya": _2, "omi": _2, "sado": _2, "sanjo": _2, "seiro": _2, "seirou": _2, "sekikawa": _2, "shibata": _2, "tagami": _2, "tainai": _2, "tochio": _2, "tokamachi": _2, "tsubame": _2, "tsunan": _2, "uonuma": _2, "yahiko": _2, "yoita": _2, "yuzawa": _2 } }, "oita": { "$": 1, "succ": { "beppu": _2, "bungoono": _2, "bungotakada": _2, "hasama": _2, "hiji": _2, "himeshima": _2, "hita": _2, "kamitsue": _2, "kokonoe": _2, "kuju": _2, "kunisaki": _2, "kusu": _2, "oita": _2, "saiki": _2, "taketa": _2, "tsukumi": _2, "usa": _2, "usuki": _2, "yufu": _2 } }, "okayama": { "$": 1, "succ": { "akaiwa": _2, "asakuchi": _2, "bizen": _2, "hayashima": _2, "ibara": _2, "kagamino": _2, "kasaoka": _2, "kibichuo": _2, "kumenan": _2, "kurashiki": _2, "maniwa": _2, "misaki": _2, "nagi": _2, "niimi": _2, "nishiawakura": _2, "okayama": _2, "satosho": _2, "setouchi": _2, "shinjo": _2, "shoo": _2, "soja": _2, "takahashi": _2, "tamano": _2, "tsuyama": _2, "wake": _2, "yakage": _2 } }, "okinawa": { "$": 1, "succ": { "aguni": _2, "ginowan": _2, "ginoza": _2, "gushikami": _2, "haebaru": _2, "higashi": _2, "hirara": _2, "iheya": _2, "ishigaki": _2, "ishikawa": _2, "itoman": _2, "izena": _2, "kadena": _2, "kin": _2, "kitadaito": _2, "kitanakagusuku": _2, "kumejima": _2, "kunigami": _2, "minamidaito": _2, "motobu": _2, "nago": _2, "naha": _2, "nakagusuku": _2, "nakijin": _2, "nanjo": _2, "nishihara": _2, "ogimi": _2, "okinawa": _2, "onna": _2, "shimoji": _2, "taketomi": _2, "tarama": _2, "tokashiki": _2, "tomigusuku": _2, "tonaki": _2, "urasoe": _2, "uruma": _2, "yaese": _2, "yomitan": _2, "yonabaru": _2, "yonaguni": _2, "zamami": _2 } }, "osaka": { "$": 1, "succ": { "abeno": _2, "chihayaakasaka": _2, "chuo": _2, "daito": _2, "fujiidera": _2, "habikino": _2, "hannan": _2, "higashiosaka": _2, "higashisumiyoshi": _2, "higashiyodogawa": _2, "hirakata": _2, "ibaraki": _2, "ikeda": _2, "izumi": _2, "izumiotsu": _2, "izumisano": _2, "kadoma": _2, "kaizuka": _2, "kanan": _2, "kashiwara": _2, "katano": _2, "kawachinagano": _2, "kishiwada": _2, "kita": _2, "kumatori": _2, "matsubara": _2, "minato": _2, "minoh": _2, "misaki": _2, "moriguchi": _2, "neyagawa": _2, "nishi": _2, "nose": _2, "osakasayama": _2, "sakai": _2, "sayama": _2, "sennan": _2, "settsu": _2, "shijonawate": _2, "shimamoto": _2, "suita": _2, "tadaoka": _2, "taishi": _2, "tajiri": _2, "takaishi": _2, "takatsuki": _2, "tondabayashi": _2, "toyonaka": _2, "toyono": _2, "yao": _2 } }, "saga": { "$": 1, "succ": { "ariake": _2, "arita": _2, "fukudomi": _2, "genkai": _2, "hamatama": _2, "hizen": _2, "imari": _2, "kamimine": _2, "kanzaki": _2, "karatsu": _2, "kashima": _2, "kitagata": _2, "kitahata": _2, "kiyama": _2, "kouhoku": _2, "kyuragi": _2, "nishiarita": _2, "ogi": _2, "omachi": _2, "ouchi": _2, "saga": _2, "shiroishi": _2, "taku": _2, "tara": _2, "tosu": _2, "yoshinogari": _2 } }, "saitama": { "$": 1, "succ": { "arakawa": _2, "asaka": _2, "chichibu": _2, "fujimi": _2, "fujimino": _2, "fukaya": _2, "hanno": _2, "hanyu": _2, "hasuda": _2, "hatogaya": _2, "hatoyama": _2, "hidaka": _2, "higashichichibu": _2, "higashimatsuyama": _2, "honjo": _2, "ina": _2, "iruma": _2, "iwatsuki": _2, "kamiizumi": _2, "kamikawa": _2, "kamisato": _2, "kasukabe": _2, "kawagoe": _2, "kawaguchi": _2, "kawajima": _2, "kazo": _2, "kitamoto": _2, "koshigaya": _2, "kounosu": _2, "kuki": _2, "kumagaya": _2, "matsubushi": _2, "minano": _2, "misato": _2, "miyashiro": _2, "miyoshi": _2, "moroyama": _2, "nagatoro": _2, "namegawa": _2, "niiza": _2, "ogano": _2, "ogawa": _2, "ogose": _2, "okegawa": _2, "omiya": _2, "otaki": _2, "ranzan": _2, "ryokami": _2, "saitama": _2, "sakado": _2, "satte": _2, "sayama": _2, "shiki": _2, "shiraoka": _2, "soka": _2, "sugito": _2, "toda": _2, "tokigawa": _2, "tokorozawa": _2, "tsurugashima": _2, "urawa": _2, "warabi": _2, "yashio": _2, "yokoze": _2, "yono": _2, "yorii": _2, "yoshida": _2, "yoshikawa": _2, "yoshimi": _2 } }, "shiga": { "$": 1, "succ": { "aisho": _2, "gamo": _2, "higashiomi": _2, "hikone": _2, "koka": _2, "konan": _2, "kosei": _2, "koto": _2, "kusatsu": _2, "maibara": _2, "moriyama": _2, "nagahama": _2, "nishiazai": _2, "notogawa": _2, "omihachiman": _2, "otsu": _2, "ritto": _2, "ryuoh": _2, "takashima": _2, "takatsuki": _2, "torahime": _2, "toyosato": _2, "yasu": _2 } }, "shimane": { "$": 1, "succ": { "akagi": _2, "ama": _2, "gotsu": _2, "hamada": _2, "higashiizumo": _2, "hikawa": _2, "hikimi": _2, "izumo": _2, "kakinoki": _2, "masuda": _2, "matsue": _2, "misato": _2, "nishinoshima": _2, "ohda": _2, "okinoshima": _2, "okuizumo": _2, "shimane": _2, "tamayu": _2, "tsuwano": _2, "unnan": _2, "yakumo": _2, "yasugi": _2, "yatsuka": _2 } }, "shizuoka": { "$": 1, "succ": { "arai": _2, "atami": _2, "fuji": _2, "fujieda": _2, "fujikawa": _2, "fujinomiya": _2, "fukuroi": _2, "gotemba": _2, "haibara": _2, "hamamatsu": _2, "higashiizu": _2, "ito": _2, "iwata": _2, "izu": _2, "izunokuni": _2, "kakegawa": _2, "kannami": _2, "kawanehon": _2, "kawazu": _2, "kikugawa": _2, "kosai": _2, "makinohara": _2, "matsuzaki": _2, "minamiizu": _2, "mishima": _2, "morimachi": _2, "nishiizu": _2, "numazu": _2, "omaezaki": _2, "shimada": _2, "shimizu": _2, "shimoda": _2, "shizuoka": _2, "susono": _2, "yaizu": _2, "yoshida": _2 } }, "tochigi": { "$": 1, "succ": { "ashikaga": _2, "bato": _2, "haga": _2, "ichikai": _2, "iwafune": _2, "kaminokawa": _2, "kanuma": _2, "karasuyama": _2, "kuroiso": _2, "mashiko": _2, "mibu": _2, "moka": _2, "motegi": _2, "nasu": _2, "nasushiobara": _2, "nikko": _2, "nishikata": _2, "nogi": _2, "ohira": _2, "ohtawara": _2, "oyama": _2, "sakura": _2, "sano": _2, "shimotsuke": _2, "shioya": _2, "takanezawa": _2, "tochigi": _2, "tsuga": _2, "ujiie": _2, "utsunomiya": _2, "yaita": _2 } }, "tokushima": { "$": 1, "succ": { "aizumi": _2, "anan": _2, "ichiba": _2, "itano": _2, "kainan": _2, "komatsushima": _2, "matsushige": _2, "mima": _2, "minami": _2, "miyoshi": _2, "mugi": _2, "nakagawa": _2, "naruto": _2, "sanagochi": _2, "shishikui": _2, "tokushima": _2, "wajiki": _2 } }, "tokyo": { "$": 1, "succ": { "adachi": _2, "akiruno": _2, "akishima": _2, "aogashima": _2, "arakawa": _2, "bunkyo": _2, "chiyoda": _2, "chofu": _2, "chuo": _2, "edogawa": _2, "fuchu": _2, "fussa": _2, "hachijo": _2, "hachioji": _2, "hamura": _2, "higashikurume": _2, "higashimurayama": _2, "higashiyamato": _2, "hino": _2, "hinode": _2, "hinohara": _2, "inagi": _2, "itabashi": _2, "katsushika": _2, "kita": _2, "kiyose": _2, "kodaira": _2, "koganei": _2, "kokubunji": _2, "komae": _2, "koto": _2, "kouzushima": _2, "kunitachi": _2, "machida": _2, "meguro": _2, "minato": _2, "mitaka": _2, "mizuho": _2, "musashimurayama": _2, "musashino": _2, "nakano": _2, "nerima": _2, "ogasawara": _2, "okutama": _2, "ome": _2, "oshima": _2, "ota": _2, "setagaya": _2, "shibuya": _2, "shinagawa": _2, "shinjuku": _2, "suginami": _2, "sumida": _2, "tachikawa": _2, "taito": _2, "tama": _2, "toshima": _2 } }, "tottori": { "$": 1, "succ": { "chizu": _2, "hino": _2, "kawahara": _2, "koge": _2, "kotoura": _2, "misasa": _2, "nanbu": _2, "nichinan": _2, "sakaiminato": _2, "tottori": _2, "wakasa": _2, "yazu": _2, "yonago": _2 } }, "toyama": { "$": 1, "succ": { "asahi": _2, "fuchu": _2, "fukumitsu": _2, "funahashi": _2, "himi": _2, "imizu": _2, "inami": _2, "johana": _2, "kamiichi": _2, "kurobe": _2, "nakaniikawa": _2, "namerikawa": _2, "nanto": _2, "nyuzen": _2, "oyabe": _2, "taira": _2, "takaoka": _2, "tateyama": _2, "toga": _2, "tonami": _2, "toyama": _2, "unazuki": _2, "uozu": _2, "yamada": _2 } }, "wakayama": { "$": 1, "succ": { "arida": _2, "aridagawa": _2, "gobo": _2, "hashimoto": _2, "hidaka": _2, "hirogawa": _2, "inami": _2, "iwade": _2, "kainan": _2, "kamitonda": _2, "katsuragi": _2, "kimino": _2, "kinokawa": _2, "kitayama": _2, "koya": _2, "koza": _2, "kozagawa": _2, "kudoyama": _2, "kushimoto": _2, "mihama": _2, "misato": _2, "nachikatsuura": _2, "shingu": _2, "shirahama": _2, "taiji": _2, "tanabe": _2, "wakayama": _2, "yuasa": _2, "yura": _2 } }, "yamagata": { "$": 1, "succ": { "asahi": _2, "funagata": _2, "higashine": _2, "iide": _2, "kahoku": _2, "kaminoyama": _2, "kaneyama": _2, "kawanishi": _2, "mamurogawa": _2, "mikawa": _2, "murayama": _2, "nagai": _2, "nakayama": _2, "nanyo": _2, "nishikawa": _2, "obanazawa": _2, "oe": _2, "oguni": _2, "ohkura": _2, "oishida": _2, "sagae": _2, "sakata": _2, "sakegawa": _2, "shinjo": _2, "shirataka": _2, "shonai": _2, "takahata": _2, "tendo": _2, "tozawa": _2, "tsuruoka": _2, "yamagata": _2, "yamanobe": _2, "yonezawa": _2, "yuza": _2 } }, "yamaguchi": { "$": 1, "succ": { "abu": _2, "hagi": _2, "hikari": _2, "hofu": _2, "iwakuni": _2, "kudamatsu": _2, "mitou": _2, "nagato": _2, "oshima": _2, "shimonoseki": _2, "shunan": _2, "tabuse": _2, "tokuyama": _2, "toyota": _2, "ube": _2, "yuu": _2 } }, "yamanashi": { "$": 1, "succ": { "chuo": _2, "doshi": _2, "fuefuki": _2, "fujikawa": _2, "fujikawaguchiko": _2, "fujiyoshida": _2, "hayakawa": _2, "hokuto": _2, "ichikawamisato": _2, "kai": _2, "kofu": _2, "koshu": _2, "kosuge": _2, "minami-alps": _2, "minobu": _2, "nakamichi": _2, "nanbu": _2, "narusawa": _2, "nirasaki": _2, "nishikatsura": _2, "oshino": _2, "otsuki": _2, "showa": _2, "tabayama": _2, "tsuru": _2, "uenohara": _2, "yamanakako": _2, "yamanashi": _2 } }, "xn--4pvxs": _2, "栃木": _2, "xn--vgu402c": _2, "愛知": _2, "xn--c3s14m": _2, "愛媛": _2, "xn--f6qx53a": _2, "兵庫": _2, "xn--8pvr4u": _2, "熊本": _2, "xn--uist22h": _2, "茨城": _2, "xn--djrs72d6uy": _2, "北海道": _2, "xn--mkru45i": _2, "千葉": _2, "xn--0trq7p7nn": _2, "和歌山": _2, "xn--8ltr62k": _2, "長崎": _2, "xn--2m4a15e": _2, "長野": _2, "xn--efvn9s": _2, "新潟": _2, "xn--32vp30h": _2, "青森": _2, "xn--4it797k": _2, "静岡": _2, "xn--1lqs71d": _2, "東京": _2, "xn--5rtp49c": _2, "石川": _2, "xn--5js045d": _2, "埼玉": _2, "xn--ehqz56n": _2, "三重": _2, "xn--1lqs03n": _2, "京都": _2, "xn--qqqt11m": _2, "佐賀": _2, "xn--kbrq7o": _2, "大分": _2, "xn--pssu33l": _2, "大阪": _2, "xn--ntsq17g": _2, "奈良": _2, "xn--uisz3g": _2, "宮城": _2, "xn--6btw5a": _2, "宮崎": _2, "xn--1ctwo": _2, "富山": _2, "xn--6orx2r": _2, "山口": _2, "xn--rht61e": _2, "山形": _2, "xn--rht27z": _2, "山梨": _2, "xn--djty4k": _2, "岩手": _2, "xn--nit225k": _2, "岐阜": _2, "xn--rht3d": _2, "岡山": _2, "xn--klty5x": _2, "島根": _2, "xn--kltx9a": _2, "広島": _2, "xn--kltp7d": _2, "徳島": _2, "xn--uuwu58a": _2, "沖縄": _2, "xn--zbx025d": _2, "滋賀": _2, "xn--ntso0iqx3a": _2, "神奈川": _2, "xn--elqq16h": _2, "福井": _2, "xn--4it168d": _2, "福岡": _2, "xn--klt787d": _2, "福島": _2, "xn--rny31h": _2, "秋田": _2, "xn--7t0a264c": _2, "群馬": _2, "xn--5rtq34k": _2, "香川": _2, "xn--k7yn95e": _2, "高知": _2, "xn--tor131o": _2, "鳥取": _2, "xn--d5qv7z876c": _2, "鹿児島": _2, "kawasaki": _8, "kitakyushu": _8, "kobe": _8, "nagoya": _8, "sapporo": _8, "sendai": _8, "yokohama": _8, "usercontent": _4, "blogspot": _4 } }, "ke": { "$": 1, "succ": { "ac": _2, "co": _5, "go": _2, "info": _2, "me": _2, "mobi": _2, "ne": _2, "or": _2, "sc": _2, "nom": _4 } }, "kg": { "$": 1, "succ": { "org": _2, "net": _2, "com": _2, "edu": _2, "gov": _2, "mil": _2, "blog": _4, "io": _4, "jp": _4, "tv": _4, "uk": _4, "us": _4 } }, "kh": _8, "ki": _22, "km": { "$": 1, "succ": { "org": _2, "nom": _2, "gov": _2, "prd": _2, "tm": _2, "edu": _2, "mil": _2, "ass": _2, "com": _2, "coop": _2, "asso": _2, "presse": _2, "medecin": _2, "notaires": _2, "pharmaciens": _2, "veterinaire": _2, "gouv": _2 } }, "kn": { "$": 1, "succ": { "net": _2, "org": _2, "edu": _2, "gov": _2 } }, "kp": { "$": 1, "succ": { "com": _2, "edu": _2, "gov": _2, "org": _2, "rep": _2, "tra": _2 } }, "kr": { "$": 1, "succ": { "ac": _2, "co": _2, "es": _2, "go": _2, "hs": _2, "kg": _2, "mil": _2, "ms": _2, "ne": _2, "or": _2, "pe": _2, "re": _2, "sc": _2, "busan": _2, "chungbuk": _2, "chungnam": _2, "daegu": _2, "daejeon": _2, "gangwon": _2, "gwangju": _2, "gyeongbuk": _2, "gyeonggi": _2, "gyeongnam": _2, "incheon": _2, "jeju": _2, "jeonbuk": _2, "jeonnam": _2, "seoul": _2, "ulsan": _2, "blogspot": _4 } }, "kw": { "$": 1, "succ": { "com": _2, "edu": _2, "emb": _2, "gov": _2, "ind": _2, "net": _2, "org": _2 } }, "ky": _9, "kz": { "$": 1, "succ": { "org": _2, "edu": _2, "net": _2, "gov": _2, "mil": _2, "com": _2, "nym": _4 } }, "la": { "$": 1, "succ": { "int": _2, "net": _2, "info": _2, "edu": _2, "gov": _2, "per": _2, "com": _2, "org": _2, "bnr": _4, "c": _4, "nym": _4 } }, "lb": _9, "lc": { "$": 1, "succ": { "com": _2, "net": _2, "co": _2, "org": _2, "edu": _2, "gov": _2, "nym": _4, "oy": _4 } }, "li": { "$": 1, "succ": { "blogspot": _4, "caa": _4, "nom": _4, "nym": _4 } }, "lk": { "$": 1, "succ": { "gov": _2, "sch": _2, "net": _2, "int": _2, "com": _2, "org": _2, "edu": _2, "ngo": _2, "soc": _2, "web": _2, "ltd": _2, "assn": _2, "grp": _2, "hotel": _2, "ac": _2 } }, "lr": _9, "ls": { "$": 1, "succ": { "ac": _2, "biz": _2, "co": _2, "edu": _2, "gov": _2, "info": _2, "net": _2, "org": _2, "sc": _2, "de": _4 } }, "lt": _20, "lu": _23, "lv": { "$": 1, "succ": { "com": _2, "edu": _2, "gov": _2, "org": _2, "mil": _2, "id": _2, "net": _2, "asn": _2, "conf": _2, "nom": _4 } }, "ly": { "$": 1, "succ": { "com": _2, "net": _2, "gov": _2, "plc": _2, "edu": _2, "sch": _2, "med": _2, "org": _2, "id": _2 } }, "ma": { "$": 1, "succ": { "co": _2, "net": _2, "gov": _2, "org": _2, "ac": _2, "press": _2 } }, "mc": { "$": 1, "succ": { "tm": _2, "asso": _2 } }, "md": { "$": 1, "succ": { "blogspot": _4, "at": _4, "de": _4, "jp": _4, "to": _4 } }, "me": { "$": 1, "succ": { "co": _2, "net": _2, "org": _2, "edu": _2, "ac": _2, "gov": _2, "its": _2, "priv": _2, "c66": _4, "daplie": { "$": 2, "succ": { "localhost": _4 } }, "edgestack": _4, "couk": _4, "ukco": _4, "filegear": _4, "filegear-au": _4, "filegear-de": _4, "filegear-gb": _4, "filegear-ie": _4, "filegear-jp": _4, "filegear-sg": _4, "glitch": _4, "ravendb": _4, "barsy": _4, "nctu": _4, "soundcast": _4, "tcp4": _4, "brasilia": _4, "ddns": _4, "dnsfor": _4, "hopto": _4, "loginto": _4, "noip": _4, "webhop": _4, "nym": _4, "diskstation": _4, "dscloud": _4, "i234": _4, "myds": _4, "synology": _4, "wedeploy": _4, "yombo": _4, "nohost": _4 } }, "mg": { "$": 1, "succ": { "org": _2, "nom": _2, "gov": _2, "prd": _2, "tm": _2, "edu": _2, "mil": _2, "com": _2, "co": _2 } }, "mh": _2, "mil": _2, "mk": { "$": 1, "succ": { "com": _2, "org": _2, "net": _2, "edu": _2, "gov": _2, "inf": _2, "name": _2, "blogspot": _4, "nom": _4 } }, "ml": { "$": 1, "succ": { "com": _2, "edu": _2, "gouv": _2, "gov": _2, "net": _2, "org": _2, "presse": _2 } }, "mm": _8, "mn": { "$": 1, "succ": { "gov": _2, "edu": _2, "org": _2, "nyc": _4, "nym": _4 } }, "mo": _9, "mobi": { "$": 1, "succ": { "barsy": _4, "dscloud": _4 } }, "mp": _2, "mq": _2, "mr": { "$": 1, "succ": { "gov": _2, "blogspot": _4 } }, "ms": { "$": 1, "succ": { "com": _2, "edu": _2, "gov": _2, "net": _2, "org": _2, "lab": _4 } }, "mt": { "$": 1, "succ": { "com": _5, "edu": _2, "net": _2, "org": _2 } }, "mu": { "$": 1, "succ": { "com": _2, "net": _2, "org": _2, "gov": _2, "ac": _2, "co": _2, "or": _2 } }, "museum": { "$": 1, "succ": { "academy": _2, "agriculture": _2, "air": _2, "airguard": _2, "alabama": _2, "alaska": _2, "amber": _2, "ambulance": _2, "american": _2, "americana": _2, "americanantiques": _2, "americanart": _2, "amsterdam": _2, "and": _2, "annefrank": _2, "anthro": _2, "anthropology": _2, "antiques": _2, "aquarium": _2, "arboretum": _2, "archaeological": _2, "archaeology": _2, "architecture": _2, "art": _2, "artanddesign": _2, "artcenter": _2, "artdeco": _2, "arteducation": _2, "artgallery": _2, "arts": _2, "artsandcrafts": _2, "asmatart": _2, "assassination": _2, "assisi": _2, "association": _2, "astronomy": _2, "atlanta": _2, "austin": _2, "australia": _2, "automotive": _2, "aviation": _2, "axis": _2, "badajoz": _2, "baghdad": _2, "bahn": _2, "bale": _2, "baltimore": _2, "barcelona": _2, "baseball": _2, "basel": _2, "baths": _2, "bauern": _2, "beauxarts": _2, "beeldengeluid": _2, "bellevue": _2, "bergbau": _2, "berkeley": _2, "berlin": _2, "bern": _2, "bible": _2, "bilbao": _2, "bill": _2, "birdart": _2, "birthplace": _2, "bonn": _2, "boston": _2, "botanical": _2, "botanicalgarden": _2, "botanicgarden": _2, "botany": _2, "brandywinevalley": _2, "brasil": _2, "bristol": _2, "british": _2, "britishcolumbia": _2, "broadcast": _2, "brunel": _2, "brussel": _2, "brussels": _2, "bruxelles": _2, "building": _2, "burghof": _2, "bus": _2, "bushey": _2, "cadaques": _2, "california": _2, "cambridge": _2, "can": _2, "canada": _2, "capebreton": _2, "carrier": _2, "cartoonart": _2, "casadelamoneda": _2, "castle": _2, "castres": _2, "celtic": _2, "center": _2, "chattanooga": _2, "cheltenham": _2, "chesapeakebay": _2, "chicago": _2, "children": _2, "childrens": _2, "childrensgarden": _2, "chiropractic": _2, "chocolate": _2, "christiansburg": _2, "cincinnati": _2, "cinema": _2, "circus": _2, "civilisation": _2, "civilization": _2, "civilwar": _2, "clinton": _2, "clock": _2, "coal": _2, "coastaldefence": _2, "cody": _2, "coldwar": _2, "collection": _2, "colonialwilliamsburg": _2, "coloradoplateau": _2, "columbia": _2, "columbus": _2, "communication": _2, "communications": _2, "community": _2, "computer": _2, "computerhistory": _2, "xn--comunicaes-v6a2o": _2, "comunicações": _2, "contemporary": _2, "contemporaryart": _2, "convent": _2, "copenhagen": _2, "corporation": _2, "xn--correios-e-telecomunicaes-ghc29a": _2, "correios-e-telecomunicações": _2, "corvette": _2, "costume": _2, "countryestate": _2, "county": _2, "crafts": _2, "cranbrook": _2, "creation": _2, "cultural": _2, "culturalcenter": _2, "culture": _2, "cyber": _2, "cymru": _2, "dali": _2, "dallas": _2, "database": _2, "ddr": _2, "decorativearts": _2, "delaware": _2, "delmenhorst": _2, "denmark": _2, "depot": _2, "design": _2, "detroit": _2, "dinosaur": _2, "discovery": _2, "dolls": _2, "donostia": _2, "durham": _2, "eastafrica": _2, "eastcoast": _2, "education": _2, "educational": _2, "egyptian": _2, "eisenbahn": _2, "elburg": _2, "elvendrell": _2, "embroidery": _2, "encyclopedic": _2, "england": _2, "entomology": _2, "environment": _2, "environmentalconservation": _2, "epilepsy": _2, "essex": _2, "estate": _2, "ethnology": _2, "exeter": _2, "exhibition": _2, "family": _2, "farm": _2, "farmequipment": _2, "farmers": _2, "farmstead": _2, "field": _2, "figueres": _2, "filatelia": _2, "film": _2, "fineart": _2, "finearts": _2, "finland": _2, "flanders": _2, "florida": _2, "force": _2, "fortmissoula": _2, "fortworth": _2, "foundation": _2, "francaise": _2, "frankfurt": _2, "franziskaner": _2, "freemasonry": _2, "freiburg": _2, "fribourg": _2, "frog": _2, "fundacio": _2, "furniture": _2, "gallery": _2, "garden": _2, "gateway": _2, "geelvinck": _2, "gemological": _2, "geology": _2, "georgia": _2, "giessen": _2, "glas": _2, "glass": _2, "gorge": _2, "grandrapids": _2, "graz": _2, "guernsey": _2, "halloffame": _2, "hamburg": _2, "handson": _2, "harvestcelebration": _2, "hawaii": _2, "health": _2, "heimatunduhren": _2, "hellas": _2, "helsinki": _2, "hembygdsforbund": _2, "heritage": _2, "histoire": _2, "historical": _2, "historicalsociety": _2, "historichouses": _2, "historisch": _2, "historisches": _2, "history": _2, "historyofscience": _2, "horology": _2, "house": _2, "humanities": _2, "illustration": _2, "imageandsound": _2, "indian": _2, "indiana": _2, "indianapolis": _2, "indianmarket": _2, "intelligence": _2, "interactive": _2, "iraq": _2, "iron": _2, "isleofman": _2, "jamison": _2, "jefferson": _2, "jerusalem": _2, "jewelry": _2, "jewish": _2, "jewishart": _2, "jfk": _2, "journalism": _2, "judaica": _2, "judygarland": _2, "juedisches": _2, "juif": _2, "karate": _2, "karikatur": _2, "kids": _2, "koebenhavn": _2, "koeln": _2, "kunst": _2, "kunstsammlung": _2, "kunstunddesign": _2, "labor": _2, "labour": _2, "lajolla": _2, "lancashire": _2, "landes": _2, "lans": _2, "xn--lns-qla": _2, "läns": _2, "larsson": _2, "lewismiller": _2, "lincoln": _2, "linz": _2, "living": _2, "livinghistory": _2, "localhistory": _2, "london": _2, "losangeles": _2, "louvre": _2, "loyalist": _2, "lucerne": _2, "luxembourg": _2, "luzern": _2, "mad": _2, "madrid": _2, "mallorca": _2, "manchester": _2, "mansion": _2, "mansions": _2, "manx": _2, "marburg": _2, "maritime": _2, "maritimo": _2, "maryland": _2, "marylhurst": _2, "media": _2, "medical": _2, "medizinhistorisches": _2, "meeres": _2, "memorial": _2, "mesaverde": _2, "michigan": _2, "midatlantic": _2, "military": _2, "mill": _2, "miners": _2, "mining": _2, "minnesota": _2, "missile": _2, "missoula": _2, "modern": _2, "moma": _2, "money": _2, "monmouth": _2, "monticello": _2, "montreal": _2, "moscow": _2, "motorcycle": _2, "muenchen": _2, "muenster": _2, "mulhouse": _2, "muncie": _2, "museet": _2, "museumcenter": _2, "museumvereniging": _2, "music": _2, "national": _2, "nationalfirearms": _2, "nationalheritage": _2, "nativeamerican": _2, "naturalhistory": _2, "naturalhistorymuseum": _2, "naturalsciences": _2, "nature": _2, "naturhistorisches": _2, "natuurwetenschappen": _2, "naumburg": _2, "naval": _2, "nebraska": _2, "neues": _2, "newhampshire": _2, "newjersey": _2, "newmexico": _2, "newport": _2, "newspaper": _2, "newyork": _2, "niepce": _2, "norfolk": _2, "north": _2, "nrw": _2, "nyc": _2, "nyny": _2, "oceanographic": _2, "oceanographique": _2, "omaha": _2, "online": _2, "ontario": _2, "openair": _2, "oregon": _2, "oregontrail": _2, "otago": _2, "oxford": _2, "pacific": _2, "paderborn": _2, "palace": _2, "paleo": _2, "palmsprings": _2, "panama": _2, "paris": _2, "pasadena": _2, "pharmacy": _2, "philadelphia": _2, "philadelphiaarea": _2, "philately": _2, "phoenix": _2, "photography": _2, "pilots": _2, "pittsburgh": _2, "planetarium": _2, "plantation": _2, "plants": _2, "plaza": _2, "portal": _2, "portland": _2, "portlligat": _2, "posts-and-telecommunications": _2, "preservation": _2, "presidio": _2, "press": _2, "project": _2, "public": _2, "pubol": _2, "quebec": _2, "railroad": _2, "railway": _2, "research": _2, "resistance": _2, "riodejaneiro": _2, "rochester": _2, "rockart": _2, "roma": _2, "russia": _2, "saintlouis": _2, "salem": _2, "salvadordali": _2, "salzburg": _2, "sandiego": _2, "sanfrancisco": _2, "santabarbara": _2, "santacruz": _2, "santafe": _2, "saskatchewan": _2, "satx": _2, "savannahga": _2, "schlesisches": _2, "schoenbrunn": _2, "schokoladen": _2, "school": _2, "schweiz": _2, "science": _2, "scienceandhistory": _2, "scienceandindustry": _2, "sciencecenter": _2, "sciencecenters": _2, "science-fiction": _2, "sciencehistory": _2, "sciences": _2, "sciencesnaturelles": _2, "scotland": _2, "seaport": _2, "settlement": _2, "settlers": _2, "shell": _2, "sherbrooke": _2, "sibenik": _2, "silk": _2, "ski": _2, "skole": _2, "society": _2, "sologne": _2, "soundandvision": _2, "southcarolina": _2, "southwest": _2, "space": _2, "spy": _2, "square": _2, "stadt": _2, "stalbans": _2, "starnberg": _2, "state": _2, "stateofdelaware": _2, "station": _2, "steam": _2, "steiermark": _2, "stjohn": _2, "stockholm": _2, "stpetersburg": _2, "stuttgart": _2, "suisse": _2, "surgeonshall": _2, "surrey": _2, "svizzera": _2, "sweden": _2, "sydney": _2, "tank": _2, "tcm": _2, "technology": _2, "telekommunikation": _2, "television": _2, "texas": _2, "textile": _2, "theater": _2, "time": _2, "timekeeping": _2, "topology": _2, "torino": _2, "touch": _2, "town": _2, "transport": _2, "tree": _2, "trolley": _2, "trust": _2, "trustee": _2, "uhren": _2, "ulm": _2, "undersea": _2, "university": _2, "usa": _2, "usantiques": _2, "usarts": _2, "uscountryestate": _2, "usculture": _2, "usdecorativearts": _2, "usgarden": _2, "ushistory": _2, "ushuaia": _2, "uslivinghistory": _2, "utah": _2, "uvic": _2, "valley": _2, "vantaa": _2, "versailles": _2, "viking": _2, "village": _2, "virginia": _2, "virtual": _2, "virtuel": _2, "vlaanderen": _2, "volkenkunde": _2, "wales": _2, "wallonie": _2, "war": _2, "washingtondc": _2, "watchandclock": _2, "watch-and-clock": _2, "western": _2, "westfalen": _2, "whaling": _2, "wildlife": _2, "williamsburg": _2, "windmill": _2, "workshop": _2, "york": _2, "yorkshire": _2, "yosemite": _2, "youth": _2, "zoological": _2, "zoology": _2, "xn--9dbhblg6di": _2, "ירושלים": _2, "xn--h1aegh": _2, "иком": _2 } }, "mv": { "$": 1, "succ": { "aero": _2, "biz": _2, "com": _2, "coop": _2, "edu": _2, "gov": _2, "info": _2, "int": _2, "mil": _2, "museum": _2, "name": _2, "net": _2, "org": _2, "pro": _2 } }, "mw": { "$": 1, "succ": { "ac": _2, "biz": _2, "co": _2, "com": _2, "coop": _2, "edu": _2, "gov": _2, "int": _2, "museum": _2, "net": _2, "org": _2 } }, "mx": { "$": 1, "succ": { "com": _2, "org": _2, "gob": _2, "edu": _2, "net": _2, "blogspot": _4, "nym": _4 } }, "my": { "$": 1, "succ": { "com": _2, "net": _2, "org": _2, "gov": _2, "edu": _2, "mil": _2, "name": _2, "blogspot": _4 } }, "mz": { "$": 1, "succ": { "ac": _2, "adv": _2, "co": _2, "edu": _2, "gov": _2, "mil": _2, "net": _2, "org": _2 } }, "na": { "$": 1, "succ": { "info": _2, "pro": _2, "name": _2, "school": _2, "or": _2, "dr": _2, "us": _2, "mx": _2, "ca": _2, "in": _2, "cc": _2, "tv": _2, "ws": _2, "mobi": _2, "co": _2, "com": _2, "org": _2 } }, "name": { "$": 1, "succ": { "her": _26, "his": _26 } }, "nc": { "$": 1, "succ": { "asso": _2, "nom": _2 } }, "ne": _2, "net": { "$": 1, "succ": { "adobeaemcloud": _4, "alwaysdata": _4, "cloudfront": _4, "t3l3p0rt": _4, "myfritz": _4, "blackbaudcdn": _4, "boomla": _4, "bplaced": _4, "square7": _4, "gb": _4, "hu": _4, "jp": _4, "se": _4, "uk": _4, "in": _4, "clic2000": _4, "cloudaccess": _4, "cdn77-ssl": _4, "cdn77": { "$": 0, "succ": { "r": _4 } }, "cloudeity": _4, "feste-ip": _4, "knx-server": _4, "static-access": _4, "cryptonomic": _7, "dattolocal": _4, "mydatto": _4, "debian": _4, "bitbridge": _4, "at-band-camp": _4, "blogdns": _4, "broke-it": _4, "buyshouses": _4, "dnsalias": _4, "dnsdojo": _4, "does-it": _4, "dontexist": _4, "dynalias": _4, "dynathome": _4, "endofinternet": _4, "from-az": _4, "from-co": _4, "from-la": _4, "from-ny": _4, "gets-it": _4, "ham-radio-op": _4, "homeftp": _4, "homeip": _4, "homelinux": _4, "homeunix": _4, "in-the-band": _4, "is-a-chef": _4, "is-a-geek": _4, "isa-geek": _4, "kicks-ass": _4, "office-on-the": _4, "podzone": _4, "scrapper-site": _4, "selfip": _4, "sells-it": _4, "servebbs": _4, "serveftp": _4, "thruhere": _4, "webhop": _4, "definima": _4, "casacam": _4, "dynu": _4, "dynv6": _4, "twmail": _4, "ru": _4, "channelsdvr": { "$": 2, "succ": { "u": _4 } }, "fastlylb": { "$": 2, "succ": { "map": _4 } }, "fastly": { "$": 0, "succ": { "freetls": _4, "map": _4, "prod": { "$": 0, "succ": { "a": _4, "global": _4 } }, "ssl": { "$": 0, "succ": { "a": _4, "b": _4, "global": _4 } } } }, "edgeapp": _4, "flynnhosting": _4, "cloudfunctions": _4, "moonscale": _4, "in-dsl": _4, "in-vpn": _4, "ipifony": _4, "iobb": _4, "cloudjiffy": _4, "elastx": { "$": 0, "succ": { "jls-sto1": _4 } }, "saveincloud": _27, "kinghost": _4, "uni5": _4, "barsy": _4, "memset": _4, "azurewebsites": _4, "azure-mobile": _4, "cloudapp": _4, "dnsup": _4, "hicam": _4, "now-dns": _4, "ownip": _4, "vpndns": _4, "eating-organic": _4, "mydissent": _4, "myeffect": _4, "mymediapc": _4, "mypsx": _4, "mysecuritycamera": _4, "nhlfan": _4, "no-ip": _4, "pgafan": _4, "privatizehealthinsurance": _4, "bounceme": _4, "ddns": _4, "redirectme": _4, "serveblog": _4, "serveminecraft": _4, "sytes": _4, "cloudycluster": _4, "rackmaze": _4, "schokokeks": _4, "firewall-gateway": _4, "seidat": _4, "senseering": _4, "siteleaf": _4, "srcf": { "$": 0, "succ": { "soc": _4, "user": _4 } }, "dsmynas": _4, "familyds": _4, "community-pro": _4, "meinforum": _4, "yandexcloud": { "$": 2, "succ": { "storage": _4, "website": _4 } }, "za": _4 } }, "nf": { "$": 1, "succ": { "com": _2, "net": _2, "per": _2, "rec": _2, "web": _2, "arts": _2, "firm": _2, "info": _2, "other": _2, "store": _2 } }, "ng": { "$": 1, "succ": { "com": _5, "edu": _2, "gov": _2, "i": _2, "mil": _2, "mobi": _2, "name": _2, "net": _2, "org": _2, "sch": _2, "col": _4, "firm": _4, "gen": _4, "ltd": _4, "ngo": _4 } }, "ni": { "$": 1, "succ": { "ac": _2, "biz": _2, "co": _2, "com": _2, "edu": _2, "gob": _2, "in": _2, "info": _2, "int": _2, "mil": _2, "net": _2, "nom": _2, "org": _2, "web": _2 } }, "nl": { "$": 1, "succ": { "amsw": _4, "virtueeldomein": _4, "co": _4, "hosting-cluster": _4, "blogspot": _4, "khplay": _4, "transurl": _7, "cistron": _4, "demon": _4 } }, "no": { "$": 1, "succ": { "fhs": _2, "vgs": _2, "fylkesbibl": _2, "folkebibl": _2, "museum": _2, "idrett": _2, "priv": _2, "mil": _2, "stat": _2, "dep": _2, "kommune": _2, "herad": _2, "aa": _28, "ah": _28, "bu": _28, "fm": _28, "hl": _28, "hm": _28, "jan-mayen": _28, "mr": _28, "nl": _28, "nt": _28, "of": _28, "ol": _28, "oslo": _28, "rl": _28, "sf": _28, "st": _28, "svalbard": _28, "tm": _28, "tr": _28, "va": _28, "vf": _28, "akrehamn": _2, "xn--krehamn-dxa": _2, "åkrehamn": _2, "algard": _2, "xn--lgrd-poac": _2, "ålgård": _2, "arna": _2, "brumunddal": _2, "bryne": _2, "bronnoysund": _2, "xn--brnnysund-m8ac": _2, "brønnøysund": _2, "drobak": _2, "xn--drbak-wua": _2, "drøbak": _2, "egersund": _2, "fetsund": _2, "floro": _2, "xn--flor-jra": _2, "florø": _2, "fredrikstad": _2, "hokksund": _2, "honefoss": _2, "xn--hnefoss-q1a": _2, "hønefoss": _2, "jessheim": _2, "jorpeland": _2, "xn--jrpeland-54a": _2, "jørpeland": _2, "kirkenes": _2, "kopervik": _2, "krokstadelva": _2, "langevag": _2, "xn--langevg-jxa": _2, "langevåg": _2, "leirvik": _2, "mjondalen": _2, "xn--mjndalen-64a": _2, "mjøndalen": _2, "mo-i-rana": _2, "mosjoen": _2, "xn--mosjen-eya": _2, "mosjøen": _2, "nesoddtangen": _2, "orkanger": _2, "osoyro": _2, "xn--osyro-wua": _2, "osøyro": _2, "raholt": _2, "xn--rholt-mra": _2, "råholt": _2, "sandnessjoen": _2, "xn--sandnessjen-ogb": _2, "sandnessjøen": _2, "skedsmokorset": _2, "slattum": _2, "spjelkavik": _2, "stathelle": _2, "stavern": _2, "stjordalshalsen": _2, "xn--stjrdalshalsen-sqb": _2, "stjørdalshalsen": _2, "tananger": _2, "tranby": _2, "vossevangen": _2, "afjord": _2, "xn--fjord-lra": _2, "åfjord": _2, "agdenes": _2, "al": _2, "xn--l-1fa": _2, "ål": _2, "alesund": _2, "xn--lesund-hua": _2, "ålesund": _2, "alstahaug": _2, "alta": _2, "xn--lt-liac": _2, "áltá": _2, "alaheadju": _2, "xn--laheadju-7ya": _2, "álaheadju": _2, "alvdal": _2, "amli": _2, "xn--mli-tla": _2, "åmli": _2, "amot": _2, "xn--mot-tla": _2, "åmot": _2, "andebu": _2, "andoy": _2, "xn--andy-ira": _2, "andøy": _2, "andasuolo": _2, "ardal": _2, "xn--rdal-poa": _2, "årdal": _2, "aremark": _2, "arendal": _2, "xn--s-1fa": _2, "ås": _2, "aseral": _2, "xn--seral-lra": _2, "åseral": _2, "asker": _2, "askim": _2, "askvoll": _2, "askoy": _2, "xn--asky-ira": _2, "askøy": _2, "asnes": _2, "xn--snes-poa": _2, "åsnes": _2, "audnedaln": _2, "aukra": _2, "aure": _2, "aurland": _2, "aurskog-holand": _2, "xn--aurskog-hland-jnb": _2, "aurskog-høland": _2, "austevoll": _2, "austrheim": _2, "averoy": _2, "xn--avery-yua": _2, "averøy": _2, "balestrand": _2, "ballangen": _2, "balat": _2, "xn--blt-elab": _2, "bálát": _2, "balsfjord": _2, "bahccavuotna": _2, "xn--bhccavuotna-k7a": _2, "báhccavuotna": _2, "bamble": _2, "bardu": _2, "beardu": _2, "beiarn": _2, "bajddar": _2, "xn--bjddar-pta": _2, "bájddar": _2, "baidar": _2, "xn--bidr-5nac": _2, "báidár": _2, "berg": _2, "bergen": _2, "berlevag": _2, "xn--berlevg-jxa": _2, "berlevåg": _2, "bearalvahki": _2, "xn--bearalvhki-y4a": _2, "bearalváhki": _2, "bindal": _2, "birkenes": _2, "bjarkoy": _2, "xn--bjarky-fya": _2, "bjarkøy": _2, "bjerkreim": _2, "bjugn": _2, "bodo": _2, "xn--bod-2na": _2, "bodø": _2, "badaddja": _2, "xn--bdddj-mrabd": _2, "bådåddjå": _2, "budejju": _2, "bokn": _2, "bremanger": _2, "bronnoy": _2, "xn--brnny-wuac": _2, "brønnøy": _2, "bygland": _2, "bykle": _2, "barum": _2, "xn--brum-voa": _2, "bærum": _2, "telemark": { "$": 0, "succ": { "bo": _2, "xn--b-5ga": _2, "bø": _2 } }, "nordland": { "$": 0, "succ": { "bo": _2, "xn--b-5ga": _2, "bø": _2, "heroy": _2, "xn--hery-ira": _2, "herøy": _2 } }, "bievat": _2, "xn--bievt-0qa": _2, "bievát": _2, "bomlo": _2, "xn--bmlo-gra": _2, "bømlo": _2, "batsfjord": _2, "xn--btsfjord-9za": _2, "båtsfjord": _2, "bahcavuotna": _2, "xn--bhcavuotna-s4a": _2, "báhcavuotna": _2, "dovre": _2, "drammen": _2, "drangedal": _2, "dyroy": _2, "xn--dyry-ira": _2, "dyrøy": _2, "donna": _2, "xn--dnna-gra": _2, "dønna": _2, "eid": _2, "eidfjord": _2, "eidsberg": _2, "eidskog": _2, "eidsvoll": _2, "eigersund": _2, "elverum": _2, "enebakk": _2, "engerdal": _2, "etne": _2, "etnedal": _2, "evenes": _2, "evenassi": _2, "xn--eveni-0qa01ga": _2, "evenášši": _2, "evje-og-hornnes": _2, "farsund": _2, "fauske": _2, "fuossko": _2, "fuoisku": _2, "fedje": _2, "fet": _2, "finnoy": _2, "xn--finny-yua": _2, "finnøy": _2, "fitjar": _2, "fjaler": _2, "fjell": _2, "flakstad": _2, "flatanger": _2, "flekkefjord": _2, "flesberg": _2, "flora": _2, "fla": _2, "xn--fl-zia": _2, "flå": _2, "folldal": _2, "forsand": _2, "fosnes": _2, "frei": _2, "frogn": _2, "froland": _2, "frosta": _2, "frana": _2, "xn--frna-woa": _2, "fræna": _2, "froya": _2, "xn--frya-hra": _2, "frøya": _2, "fusa": _2, "fyresdal": _2, "forde": _2, "xn--frde-gra": _2, "førde": _2, "gamvik": _2, "gangaviika": _2, "xn--ggaviika-8ya47h": _2, "gáŋgaviika": _2, "gaular": _2, "gausdal": _2, "gildeskal": _2, "xn--gildeskl-g0a": _2, "gildeskål": _2, "giske": _2, "gjemnes": _2, "gjerdrum": _2, "gjerstad": _2, "gjesdal": _2, "gjovik": _2, "xn--gjvik-wua": _2, "gjøvik": _2, "gloppen": _2, "gol": _2, "gran": _2, "grane": _2, "granvin": _2, "gratangen": _2, "grimstad": _2, "grong": _2, "kraanghke": _2, "xn--kranghke-b0a": _2, "kråanghke": _2, "grue": _2, "gulen": _2, "hadsel": _2, "halden": _2, "halsa": _2, "hamar": _2, "hamaroy": _2, "habmer": _2, "xn--hbmer-xqa": _2, "hábmer": _2, "hapmir": _2, "xn--hpmir-xqa": _2, "hápmir": _2, "hammerfest": _2, "hammarfeasta": _2, "xn--hmmrfeasta-s4ac": _2, "hámmárfeasta": _2, "haram": _2, "hareid": _2, "harstad": _2, "hasvik": _2, "aknoluokta": _2, "xn--koluokta-7ya57h": _2, "ákŋoluokta": _2, "hattfjelldal": _2, "aarborte": _2, "haugesund": _2, "hemne": _2, "hemnes": _2, "hemsedal": _2, "more-og-romsdal": { "$": 0, "succ": { "heroy": _2, "sande": _2 } }, "xn--mre-og-romsdal-qqb": { "$": 0, "succ": { "xn--hery-ira": _2, "sande": _2 } }, "møre-og-romsdal": { "$": 0, "succ": { "herøy": _2, "sande": _2 } }, "hitra": _2, "hjartdal": _2, "hjelmeland": _2, "hobol": _2, "xn--hobl-ira": _2, "hobøl": _2, "hof": _2, "hol": _2, "hole": _2, "holmestrand": _2, "holtalen": _2, "xn--holtlen-hxa": _2, "holtålen": _2, "hornindal": _2, "horten": _2, "hurdal": _2, "hurum": _2, "hvaler": _2, "hyllestad": _2, "hagebostad": _2, "xn--hgebostad-g3a": _2, "hægebostad": _2, "hoyanger": _2, "xn--hyanger-q1a": _2, "høyanger": _2, "hoylandet": _2, "xn--hylandet-54a": _2, "høylandet": _2, "ha": _2, "xn--h-2fa": _2, "hå": _2, "ibestad": _2, "inderoy": _2, "xn--indery-fya": _2, "inderøy": _2, "iveland": _2, "jevnaker": _2, "jondal": _2, "jolster": _2, "xn--jlster-bya": _2, "jølster": _2, "karasjok": _2, "karasjohka": _2, "xn--krjohka-hwab49j": _2, "kárášjohka": _2, "karlsoy": _2, "galsa": _2, "xn--gls-elac": _2, "gálsá": _2, "karmoy": _2, "xn--karmy-yua": _2, "karmøy": _2, "kautokeino": _2, "guovdageaidnu": _2, "klepp": _2, "klabu": _2, "xn--klbu-woa": _2, "klæbu": _2, "kongsberg": _2, "kongsvinger": _2, "kragero": _2, "xn--krager-gya": _2, "kragerø": _2, "kristiansand": _2, "kristiansund": _2, "krodsherad": _2, "xn--krdsherad-m8a": _2, "krødsherad": _2, "kvalsund": _2, "rahkkeravju": _2, "xn--rhkkervju-01af": _2, "ráhkkerávju": _2, "kvam": _2, "kvinesdal": _2, "kvinnherad": _2, "kviteseid": _2, "kvitsoy": _2, "xn--kvitsy-fya": _2, "kvitsøy": _2, "kvafjord": _2, "xn--kvfjord-nxa": _2, "kvæfjord": _2, "giehtavuoatna": _2, "kvanangen": _2, "xn--kvnangen-k0a": _2, "kvænangen": _2, "navuotna": _2, "xn--nvuotna-hwa": _2, "návuotna": _2, "kafjord": _2, "xn--kfjord-iua": _2, "kåfjord": _2, "gaivuotna": _2, "xn--givuotna-8ya": _2, "gáivuotna": _2, "larvik": _2, "lavangen": _2, "lavagis": _2, "loabat": _2, "xn--loabt-0qa": _2, "loabát": _2, "lebesby": _2, "davvesiida": _2, "leikanger": _2, "leirfjord": _2, "leka": _2, "leksvik": _2, "lenvik": _2, "leangaviika": _2, "xn--leagaviika-52b": _2, "leaŋgaviika": _2, "lesja": _2, "levanger": _2, "lier": _2, "lierne": _2, "lillehammer": _2, "lillesand": _2, "lindesnes": _2, "lindas": _2, "xn--linds-pra": _2, "lindås": _2, "lom": _2, "loppa": _2, "lahppi": _2, "xn--lhppi-xqa": _2, "láhppi": _2, "lund": _2, "lunner": _2, "luroy": _2, "xn--lury-ira": _2, "lurøy": _2, "luster": _2, "lyngdal": _2, "lyngen": _2, "ivgu": _2, "lardal": _2, "lerdal": _2, "xn--lrdal-sra": _2, "lærdal": _2, "lodingen": _2, "xn--ldingen-q1a": _2, "lødingen": _2, "lorenskog": _2, "xn--lrenskog-54a": _2, "lørenskog": _2, "loten": _2, "xn--lten-gra": _2, "løten": _2, "malvik": _2, "masoy": _2, "xn--msy-ula0h": _2, "måsøy": _2, "muosat": _2, "xn--muost-0qa": _2, "muosát": _2, "mandal": _2, "marker": _2, "marnardal": _2, "masfjorden": _2, "meland": _2, "meldal": _2, "melhus": _2, "meloy": _2, "xn--mely-ira": _2, "meløy": _2, "meraker": _2, "xn--merker-kua": _2, "meråker": _2, "moareke": _2, "xn--moreke-jua": _2, "moåreke": _2, "midsund": _2, "midtre-gauldal": _2, "modalen": _2, "modum": _2, "molde": _2, "moskenes": _2, "moss": _2, "mosvik": _2, "malselv": _2, "xn--mlselv-iua": _2, "målselv": _2, "malatvuopmi": _2, "xn--mlatvuopmi-s4a": _2, "málatvuopmi": _2, "namdalseid": _2, "aejrie": _2, "namsos": _2, "namsskogan": _2, "naamesjevuemie": _2, "xn--nmesjevuemie-tcba": _2, "nååmesjevuemie": _2, "laakesvuemie": _2, "nannestad": _2, "narvik": _2, "narviika": _2, "naustdal": _2, "nedre-eiker": _2, "akershus": _29, "buskerud": _29, "nesna": _2, "nesodden": _2, "nesseby": _2, "unjarga": _2, "xn--unjrga-rta": _2, "unjárga": _2, "nesset": _2, "nissedal": _2, "nittedal": _2, "nord-aurdal": _2, "nord-fron": _2, "nord-odal": _2, "norddal": _2, "nordkapp": _2, "davvenjarga": _2, "xn--davvenjrga-y4a": _2, "davvenjárga": _2, "nordre-land": _2, "nordreisa": _2, "raisa": _2, "xn--risa-5na": _2, "ráisa": _2, "nore-og-uvdal": _2, "notodden": _2, "naroy": _2, "xn--nry-yla5g": _2, "nærøy": _2, "notteroy": _2, "xn--nttery-byae": _2, "nøtterøy": _2, "odda": _2, "oksnes": _2, "xn--ksnes-uua": _2, "øksnes": _2, "oppdal": _2, "oppegard": _2, "xn--oppegrd-ixa": _2, "oppegård": _2, "orkdal": _2, "orland": _2, "xn--rland-uua": _2, "ørland": _2, "orskog": _2, "xn--rskog-uua": _2, "ørskog": _2, "orsta": _2, "xn--rsta-fra": _2, "ørsta": _2, "hedmark": { "$": 0, "succ": { "os": _2, "valer": _2, "xn--vler-qoa": _2, "våler": _2 } }, "hordaland": { "$": 0, "succ": { "os": _2 } }, "osen": _2, "osteroy": _2, "xn--ostery-fya": _2, "osterøy": _2, "ostre-toten": _2, "xn--stre-toten-zcb": _2, "østre-toten": _2, "overhalla": _2, "ovre-eiker": _2, "xn--vre-eiker-k8a": _2, "øvre-eiker": _2, "oyer": _2, "xn--yer-zna": _2, "øyer": _2, "oygarden": _2, "xn--ygarden-p1a": _2, "øygarden": _2, "oystre-slidre": _2, "xn--ystre-slidre-ujb": _2, "øystre-slidre": _2, "porsanger": _2, "porsangu": _2, "xn--porsgu-sta26f": _2, "porsáŋgu": _2, "porsgrunn": _2, "radoy": _2, "xn--rady-ira": _2, "radøy": _2, "rakkestad": _2, "rana": _2, "ruovat": _2, "randaberg": _2, "rauma": _2, "rendalen": _2, "rennebu": _2, "rennesoy": _2, "xn--rennesy-v1a": _2, "rennesøy": _2, "rindal": _2, "ringebu": _2, "ringerike": _2, "ringsaker": _2, "rissa": _2, "risor": _2, "xn--risr-ira": _2, "risør": _2, "roan": _2, "rollag": _2, "rygge": _2, "ralingen": _2, "xn--rlingen-mxa": _2, "rælingen": _2, "rodoy": _2, "xn--rdy-0nab": _2, "rødøy": _2, "romskog": _2, "xn--rmskog-bya": _2, "rømskog": _2, "roros": _2, "xn--rros-gra": _2, "røros": _2, "rost": _2, "xn--rst-0na": _2, "røst": _2, "royken": _2, "xn--ryken-vua": _2, "røyken": _2, "royrvik": _2, "xn--ryrvik-bya": _2, "røyrvik": _2, "rade": _2, "xn--rde-ula": _2, "råde": _2, "salangen": _2, "siellak": _2, "saltdal": _2, "salat": _2, "xn--slt-elab": _2, "sálát": _2, "xn--slat-5na": _2, "sálat": _2, "samnanger": _2, "vestfold": { "$": 0, "succ": { "sande": _2 } }, "sandefjord": _2, "sandnes": _2, "sandoy": _2, "xn--sandy-yua": _2, "sandøy": _2, "sarpsborg": _2, "sauda": _2, "sauherad": _2, "sel": _2, "selbu": _2, "selje": _2, "seljord": _2, "sigdal": _2, "siljan": _2, "sirdal": _2, "skaun": _2, "skedsmo": _2, "ski": _2, "skien": _2, "skiptvet": _2, "skjervoy": _2, "xn--skjervy-v1a": _2, "skjervøy": _2, "skierva": _2, "xn--skierv-uta": _2, "skiervá": _2, "skjak": _2, "xn--skjk-soa": _2, "skjåk": _2, "skodje": _2, "skanland": _2, "xn--sknland-fxa": _2, "skånland": _2, "skanit": _2, "xn--sknit-yqa": _2, "skánit": _2, "smola": _2, "xn--smla-hra": _2, "smøla": _2, "snillfjord": _2, "snasa": _2, "xn--snsa-roa": _2, "snåsa": _2, "snoasa": _2, "snaase": _2, "xn--snase-nra": _2, "snåase": _2, "sogndal": _2, "sokndal": _2, "sola": _2, "solund": _2, "songdalen": _2, "sortland": _2, "spydeberg": _2, "stange": _2, "stavanger": _2, "steigen": _2, "steinkjer": _2, "stjordal": _2, "xn--stjrdal-s1a": _2, "stjørdal": _2, "stokke": _2, "stor-elvdal": _2, "stord": _2, "stordal": _2, "storfjord": _2, "omasvuotna": _2, "strand": _2, "stranda": _2, "stryn": _2, "sula": _2, "suldal": _2, "sund": _2, "sunndal": _2, "surnadal": _2, "sveio": _2, "svelvik": _2, "sykkylven": _2, "sogne": _2, "xn--sgne-gra": _2, "søgne": _2, "somna": _2, "xn--smna-gra": _2, "sømna": _2, "sondre-land": _2, "xn--sndre-land-0cb": _2, "søndre-land": _2, "sor-aurdal": _2, "xn--sr-aurdal-l8a": _2, "sør-aurdal": _2, "sor-fron": _2, "xn--sr-fron-q1a": _2, "sør-fron": _2, "sor-odal": _2, "xn--sr-odal-q1a": _2, "sør-odal": _2, "sor-varanger": _2, "xn--sr-varanger-ggb": _2, "sør-varanger": _2, "matta-varjjat": _2, "xn--mtta-vrjjat-k7af": _2, "mátta-várjjat": _2, "sorfold": _2, "xn--srfold-bya": _2, "sørfold": _2, "sorreisa": _2, "xn--srreisa-q1a": _2, "sørreisa": _2, "sorum": _2, "xn--srum-gra": _2, "sørum": _2, "tana": _2, "deatnu": _2, "time": _2, "tingvoll": _2, "tinn": _2, "tjeldsund": _2, "dielddanuorri": _2, "tjome": _2, "xn--tjme-hra": _2, "tjøme": _2, "tokke": _2, "tolga": _2, "torsken": _2, "tranoy": _2, "xn--trany-yua": _2, "tranøy": _2, "tromso": _2, "xn--troms-zua": _2, "tromsø": _2, "tromsa": _2, "romsa": _2, "trondheim": _2, "troandin": _2, "trysil": _2, "trana": _2, "xn--trna-woa": _2, "træna": _2, "trogstad": _2, "xn--trgstad-r1a": _2, "trøgstad": _2, "tvedestrand": _2, "tydal": _2, "tynset": _2, "tysfjord": _2, "divtasvuodna": _2, "divttasvuotna": _2, "tysnes": _2, "tysvar": _2, "xn--tysvr-vra": _2, "tysvær": _2, "tonsberg": _2, "xn--tnsberg-q1a": _2, "tønsberg": _2, "ullensaker": _2, "ullensvang": _2, "ulvik": _2, "utsira": _2, "vadso": _2, "xn--vads-jra": _2, "vadsø": _2, "cahcesuolo": _2, "xn--hcesuolo-7ya35b": _2, "čáhcesuolo": _2, "vaksdal": _2, "valle": _2, "vang": _2, "vanylven": _2, "vardo": _2, "xn--vard-jra": _2, "vardø": _2, "varggat": _2, "xn--vrggt-xqad": _2, "várggát": _2, "vefsn": _2, "vaapste": _2, "vega": _2, "vegarshei": _2, "xn--vegrshei-c0a": _2, "vegårshei": _2, "vennesla": _2, "verdal": _2, "verran": _2, "vestby": _2, "vestnes": _2, "vestre-slidre": _2, "vestre-toten": _2, "vestvagoy": _2, "xn--vestvgy-ixa6o": _2, "vestvågøy": _2, "vevelstad": _2, "vik": _2, "vikna": _2, "vindafjord": _2, "volda": _2, "voss": _2, "varoy": _2, "xn--vry-yla5g": _2, "værøy": _2, "vagan": _2, "xn--vgan-qoa": _2, "vågan": _2, "voagat": _2, "vagsoy": _2, "xn--vgsy-qoa0j": _2, "vågsøy": _2, "vaga": _2, "xn--vg-yiab": _2, "vågå": _2, "ostfold": { "$": 0, "succ": { "valer": _2 } }, "xn--stfold-9xa": { "$": 0, "succ": { "xn--vler-qoa": _2 } }, "østfold": { "$": 0, "succ": { "våler": _2 } }, "co": _4, "blogspot": _4 } }, "np": _8, "nr": _22, "nu": { "$": 1, "succ": { "merseine": _4, "mine": _4, "shacknet": _4, "nom": _4, "uwu": _4, "enterprisecloud": _4 } }, "nz": { "$": 1, "succ": { "ac": _2, "co": _5, "cri": _2, "geek": _2, "gen": _2, "govt": _2, "health": _2, "iwi": _2, "kiwi": _2, "maori": _2, "mil": _2, "xn--mori-qsa": _2, "māori": _2, "net": _2, "org": _2, "parliament": _2, "school": _2, "nym": _4 } }, "om": { "$": 1, "succ": { "co": _2, "com": _2, "edu": _2, "gov": _2, "med": _2, "museum": _2, "net": _2, "org": _2, "pro": _2 } }, "onion": _2, "org": { "$": 1, "succ": { "altervista": _4, "amune": { "$": 0, "succ": { "tele": _4 } }, "pimienta": _4, "poivron": _4, "potager": _4, "sweetpepper": _4, "ae": _4, "us": _4, "certmgr": _4, "cdn77": { "$": 0, "succ": { "c": _4, "rsc": _4 } }, "cdn77-secure": { "$": 0, "succ": { "origin": { "$": 0, "succ": { "ssl": _4 } } } }, "cloudns": _4, "duckdns": _4, "tunk": _4, "dyndns": { "$": 2, "succ": { "go": _4, "home": _4 } }, "blogdns": _4, "blogsite": _4, "boldlygoingnowhere": _4, "dnsalias": _4, "dnsdojo": _4, "doesntexist": _4, "dontexist": _4, "doomdns": _4, "dvrdns": _4, "dynalias": _4, "endofinternet": _4, "endoftheinternet": _4, "from-me": _4, "game-host": _4, "gotdns": _4, "hobby-site": _4, "homedns": _4, "homeftp": _4, "homelinux": _4, "homeunix": _4, "is-a-bruinsfan": _4, "is-a-candidate": _4, "is-a-celticsfan": _4, "is-a-chef": _4, "is-a-geek": _4, "is-a-knight": _4, "is-a-linux-user": _4, "is-a-patsfan": _4, "is-a-soxfan": _4, "is-found": _4, "is-lost": _4, "is-saved": _4, "is-very-bad": _4, "is-very-evil": _4, "is-very-good": _4, "is-very-nice": _4, "is-very-sweet": _4, "isa-geek": _4, "kicks-ass": _4, "misconfused": _4, "podzone": _4, "readmyblog": _4, "selfip": _4, "sellsyourhome": _4, "servebbs": _4, "serveftp": _4, "servegame": _4, "stuff-4-sale": _4, "webhop": _4, "ddnss": _4, "accesscam": _4, "camdvr": _4, "freeddns": _4, "mywire": _4, "webredirect": _4, "eu": { "$": 2, "succ": { "al": _4, "asso": _4, "at": _4, "au": _4, "be": _4, "bg": _4, "ca": _4, "cd": _4, "ch": _4, "cn": _4, "cy": _4, "cz": _4, "de": _4, "dk": _4, "edu": _4, "ee": _4, "es": _4, "fi": _4, "fr": _4, "gr": _4, "hr": _4, "hu": _4, "ie": _4, "il": _4, "in": _4, "int": _4, "is": _4, "it": _4, "jp": _4, "kr": _4, "lt": _4, "lu": _4, "lv": _4, "mc": _4, "me": _4, "mk": _4, "mt": _4, "my": _4, "net": _4, "ng": _4, "nl": _4, "no": _4, "nz": _4, "paris": _4, "pl": _4, "pt": _4, "q-a": _4, "ro": _4, "ru": _4, "se": _4, "si": _4, "sk": _4, "tr": _4, "uk": _4, "us": _4 } }, "twmail": _4, "fedorainfracloud": _4, "fedorapeople": _4, "fedoraproject": { "$": 0, "succ": { "cloud": _4, "os": _16, "stg": { "$": 0, "succ": { "os": _16 } } } }, "freedesktop": _4, "hepforge": _4, "in-dsl": _4, "in-vpn": _4, "js": _4, "uklugs": _4, "barsy": _4, "mayfirst": _4, "mozilla-iot": _4, "bmoattachments": _4, "dynserv": _4, "now-dns": _4, "cable-modem": _4, "collegefan": _4, "couchpotatofries": _4, "mlbfan": _4, "mysecuritycamera": _4, "nflfan": _4, "read-books": _4, "ufcfan": _4, "hopto": _4, "myftp": _4, "no-ip": _4, "zapto": _4, "pubtls": _4, "my-firewall": _4, "myfirewall": _4, "spdns": _4, "dsmynas": _4, "familyds": _4, "edugit": _4, "tuxfamily": _4, "diskstation": _4, "hk": _4, "wmflabs": _4, "toolforge": _4, "wmcloud": _4, "za": _4 } }, "pa": { "$": 1, "succ": { "ac": _2, "gob": _2, "com": _2, "org": _2, "sld": _2, "edu": _2, "net": _2, "ing": _2, "abo": _2, "med": _2, "nom": _2 } }, "pe": { "$": 1, "succ": { "edu": _2, "gob": _2, "nom": _2, "mil": _2, "org": _2, "com": _2, "net": _2, "blogspot": _4, "nym": _4 } }, "pf": { "$": 1, "succ": { "com": _2, "org": _2, "edu": _2 } }, "pg": _8, "ph": { "$": 1, "succ": { "com": _2, "net": _2, "org": _2, "gov": _2, "edu": _2, "ngo": _2, "mil": _2, "i": _2 } }, "pk": { "$": 1, "succ": { "com": _2, "net": _2, "edu": _2, "org": _2, "fam": _2, "biz": _2, "web": _2, "gov": _2, "gob": _2, "gok": _2, "gon": _2, "gop": _2, "gos": _2, "info": _2 } }, "pl": { "$": 1, "succ": { "com": _2, "net": _2, "org": _2, "aid": _2, "agro": _2, "atm": _2, "auto": _2, "biz": _2, "edu": _2, "gmina": _2, "gsm": _2, "info": _2, "mail": _2, "miasta": _2, "media": _2, "mil": _2, "nieruchomosci": _2, "nom": _2, "pc": _2, "powiat": _2, "priv": _2, "realestate": _2, "rel": _2, "sex": _2, "shop": _2, "sklep": _2, "sos": _2, "szkola": _2, "targi": _2, "tm": _2, "tourism": _2, "travel": _2, "turystyka": _2, "gov": { "$": 1, "succ": { "ap": _2, "ic": _2, "is": _2, "us": _2, "kmpsp": _2, "kppsp": _2, "kwpsp": _2, "psp": _2, "wskr": _2, "kwp": _2, "mw": _2, "ug": _2, "um": _2, "umig": _2, "ugim": _2, "upow": _2, "uw": _2, "starostwo": _2, "pa": _2, "po": _2, "psse": _2, "pup": _2, "rzgw": _2, "sa": _2, "so": _2, "sr": _2, "wsa": _2, "sko": _2, "uzs": _2, "wiih": _2, "winb": _2, "pinb": _2, "wios": _2, "witd": _2, "wzmiuw": _2, "piw": _2, "wiw": _2, "griw": _2, "wif": _2, "oum": _2, "sdn": _2, "zp": _2, "uppo": _2, "mup": _2, "wuoz": _2, "konsulat": _2, "oirm": _2 } }, "augustow": _2, "babia-gora": _2, "bedzin": _2, "beskidy": _2, "bialowieza": _2, "bialystok": _2, "bielawa": _2, "bieszczady": _2, "boleslawiec": _2, "bydgoszcz": _2, "bytom": _2, "cieszyn": _2, "czeladz": _2, "czest": _2, "dlugoleka": _2, "elblag": _2, "elk": _2, "glogow": _2, "gniezno": _2, "gorlice": _2, "grajewo": _2, "ilawa": _2, "jaworzno": _2, "jelenia-gora": _2, "jgora": _2, "kalisz": _2, "kazimierz-dolny": _2, "karpacz": _2, "kartuzy": _2, "kaszuby": _2, "katowice": _2, "kepno": _2, "ketrzyn": _2, "klodzko": _2, "kobierzyce": _2, "kolobrzeg": _2, "konin": _2, "konskowola": _2, "kutno": _2, "lapy": _2, "lebork": _2, "legnica": _2, "lezajsk": _2, "limanowa": _2, "lomza": _2, "lowicz": _2, "lubin": _2, "lukow": _2, "malbork": _2, "malopolska": _2, "mazowsze": _2, "mazury": _2, "mielec": _2, "mielno": _2, "mragowo": _2, "naklo": _2, "nowaruda": _2, "nysa": _2, "olawa": _2, "olecko": _2, "olkusz": _2, "olsztyn": _2, "opoczno": _2, "opole": _2, "ostroda": _2, "ostroleka": _2, "ostrowiec": _2, "ostrowwlkp": _2, "pila": _2, "pisz": _2, "podhale": _2, "podlasie": _2, "polkowice": _2, "pomorze": _2, "pomorskie": _2, "prochowice": _2, "pruszkow": _2, "przeworsk": _2, "pulawy": _2, "radom": _2, "rawa-maz": _2, "rybnik": _2, "rzeszow": _2, "sanok": _2, "sejny": _2, "slask": _2, "slupsk": _2, "sosnowiec": _2, "stalowa-wola": _2, "skoczow": _2, "starachowice": _2, "stargard": _2, "suwalki": _2, "swidnica": _2, "swiebodzin": _2, "swinoujscie": _2, "szczecin": _2, "szczytno": _2, "tarnobrzeg": _2, "tgory": _2, "turek": _2, "tychy": _2, "ustka": _2, "walbrzych": _2, "warmia": _2, "warszawa": _2, "waw": _2, "wegrow": _2, "wielun": _2, "wlocl": _2, "wloclawek": _2, "wodzislaw": _2, "wolomin": _2, "wroclaw": _2, "zachpomor": _2, "zagan": _2, "zarow": _2, "zgora": _2, "zgorzelec": _2, "beep": _4, "krasnik": _4, "leczna": _4, "lubartow": _4, "lublin": _4, "poniatowa": _4, "swidnik": _4, "co": _4, "art": _4, "gliwice": _4, "krakow": _4, "poznan": _4, "wroc": _4, "zakopane": _4, "gda": _4, "gdansk": _4, "gdynia": _4, "med": _4, "sopot": _4 } }, "pm": { "$": 1, "succ": { "own": _4 } }, "pn": { "$": 1, "succ": { "gov": _2, "co": _2, "org": _2, "edu": _2, "net": _2 } }, "post": _2, "pr": { "$": 1, "succ": { "com": _2, "net": _2, "org": _2, "gov": _2, "edu": _2, "isla": _2, "pro": _2, "biz": _2, "info": _2, "name": _2, "est": _2, "prof": _2, "ac": _2 } }, "pro": { "$": 1, "succ": { "aaa": _2, "aca": _2, "acct": _2, "avocat": _2, "bar": _2, "cpa": _2, "eng": _2, "jur": _2, "law": _2, "med": _2, "recht": _2, "cloudns": _4, "dnstrace": { "$": 0, "succ": { "bci": _4 } }, "barsy": _4 } }, "ps": { "$": 1, "succ": { "edu": _2, "gov": _2, "sec": _2, "plo": _2, "com": _2, "org": _2, "net": _2 } }, "pt": { "$": 1, "succ": { "net": _2, "gov": _2, "org": _2, "edu": _2, "int": _2, "publ": _2, "com": _2, "nome": _2, "blogspot": _4, "nym": _4 } }, "pw": { "$": 1, "succ": { "co": _2, "ne": _2, "or": _2, "ed": _2, "go": _2, "belau": _2, "cloudns": _4, "x443": _4, "nom": _4 } }, "py": { "$": 1, "succ": { "com": _2, "coop": _2, "edu": _2, "gov": _2, "mil": _2, "net": _2, "org": _2 } }, "qa": { "$": 1, "succ": { "com": _2, "edu": _2, "gov": _2, "mil": _2, "name": _2, "net": _2, "org": _2, "sch": _2, "blogspot": _4, "nom": _4 } }, "re": { "$": 1, "succ": { "asso": _2, "com": _2, "nom": _2, "blogspot": _4 } }, "ro": { "$": 1, "succ": { "arts": _2, "com": _2, "firm": _2, "info": _2, "nom": _2, "nt": _2, "org": _2, "rec": _2, "store": _2, "tm": _2, "www": _2, "shop": _4, "blogspot": _4, "nym": _4 } }, "rs": { "$": 1, "succ": { "ac": _2, "co": _2, "edu": _2, "gov": _2, "in": _2, "org": _2, "blogspot": _4, "ua": _4, "nom": _4, "ox": _4 } }, "ru": { "$": 1, "succ": { "ac": _4, "edu": _4, "gov": _4, "int": _4, "mil": _4, "test": _4, "adygeya": _4, "bashkiria": _4, "bir": _4, "cbg": _4, "com": _4, "dagestan": _4, "grozny": _4, "kalmykia": _4, "kustanai": _4, "marine": _4, "mordovia": _4, "msk": _4, "mytis": _4, "nalchik": _4, "nov": _4, "pyatigorsk": _4, "spb": _4, "vladikavkaz": _4, "vladimir": _4, "blogspot": _4, "regruhosting": _27, "myjino": { "$": 2, "succ": { "hosting": _7, "landing": _7, "spectrum": _7, "vps": _7 } }, "cldmail": { "$": 0, "succ": { "hb": _4 } }, "net": _4, "org": _4, "pp": _4, "ras": _4 } }, "rw": { "$": 1, "succ": { "ac": _2, "co": _2, "coop": _2, "gov": _2, "mil": _2, "net": _2, "org": _2 } }, "sa": { "$": 1, "succ": { "com": _2, "net": _2, "org": _2, "gov": _2, "med": _2, "pub": _2, "edu": _2, "sch": _2 } }, "sb": _9, "sc": _9, "sd": { "$": 1, "succ": { "com": _2, "net": _2, "org": _2, "edu": _2, "med": _2, "tv": _2, "gov": _2, "info": _2 } }, "se": { "$": 1, "succ": { "a": _2, "ac": _2, "b": _2, "bd": _2, "brand": _2, "c": _2, "d": _2, "e": _2, "f": _2, "fh": _2, "fhsk": _2, "fhv": _2, "g": _2, "h": _2, "i": _2, "k": _2, "komforb": _2, "kommunalforbund": _2, "komvux": _2, "l": _2, "lanbib": _2, "m": _2, "n": _2, "naturbruksgymn": _2, "o": _2, "org": _2, "p": _2, "parti": _2, "pp": _2, "press": _2, "r": _2, "s": _2, "t": _2, "tm": _2, "u": _2, "w": _2, "x": _2, "y": _2, "z": _2, "com": _4, "blogspot": _4, "conf": _4 } }, "sg": { "$": 1, "succ": { "com": _2, "net": _2, "org": _2, "gov": _2, "edu": _2, "per": _2, "blogspot": _4 } }, "sh": { "$": 1, "succ": { "com": _2, "net": _2, "gov": _2, "org": _2, "mil": _2, "hashbang": _4, "platform": { "$": 0, "succ": { "bc": _4, "ent": _4, "eu": _4, "us": _4 } }, "now": _4, "vxl": _4, "wedeploy": _4 } }, "si": { "$": 1, "succ": { "gitpage": _4, "blogspot": _4, "nom": _4 } }, "sj": _2, "sk": _23, "sl": _9, "sm": _2, "sn": { "$": 1, "succ": { "art": _2, "com": _2, "edu": _2, "gouv": _2, "org": _2, "perso": _2, "univ": _2, "blogspot": _4 } }, "so": { "$": 1, "succ": { "com": _2, "edu": _2, "gov": _2, "me": _2, "net": _2, "org": _2, "sch": _4 } }, "sr": _2, "ss": { "$": 1, "succ": { "biz": _2, "com": _2, "edu": _2, "gov": _2, "net": _2, "org": _2 } }, "st": { "$": 1, "succ": { "co": _2, "com": _2, "consulado": _2, "edu": _2, "embaixada": _2, "gov": _2, "mil": _2, "net": _2, "org": _2, "principe": _2, "saotome": _2, "store": _2, "nom": _4, "noho": _4 } }, "su": { "$": 1, "succ": { "abkhazia": _4, "adygeya": _4, "aktyubinsk": _4, "arkhangelsk": _4, "armenia": _4, "ashgabad": _4, "azerbaijan": _4, "balashov": _4, "bashkiria": _4, "bryansk": _4, "bukhara": _4, "chimkent": _4, "dagestan": _4, "east-kazakhstan": _4, "exnet": _4, "georgia": _4, "grozny": _4, "ivanovo": _4, "jambyl": _4, "kalmykia": _4, "kaluga": _4, "karacol": _4, "karaganda": _4, "karelia": _4, "khakassia": _4, "krasnodar": _4, "kurgan": _4, "kustanai": _4, "lenug": _4, "mangyshlak": _4, "mordovia": _4, "msk": _4, "murmansk": _4, "nalchik": _4, "navoi": _4, "north-kazakhstan": _4, "nov": _4, "obninsk": _4, "penza": _4, "pokrovsk": _4, "sochi": _4, "spb": _4, "tashkent": _4, "termez": _4, "togliatti": _4, "troitsk": _4, "tselinograd": _4, "tula": _4, "tuva": _4, "vladikavkaz": _4, "vladimir": _4, "vologda": _4, "nym": _4 } }, "sv": { "$": 1, "succ": { "com": _2, "edu": _2, "gob": _2, "org": _2, "red": _2 } }, "sx": { "$": 1, "succ": { "gov": _2, "nym": _4 } }, "sy": _3, "sz": { "$": 1, "succ": { "co": _2, "ac": _2, "org": _2 } }, "tc": { "$": 1, "succ": { "ch": _4, "me": _4, "we": _4 } }, "td": _5, "tel": _2, "tf": _2, "tg": _2, "th": { "$": 1, "succ": { "ac": _2, "co": _2, "go": _2, "in": _2, "mi": _2, "net": _2, "or": _2, "online": _4, "shop": _4 } }, "tj": { "$": 1, "succ": { "ac": _2, "biz": _2, "co": _2, "com": _2, "edu": _2, "go": _2, "gov": _2, "int": _2, "mil": _2, "name": _2, "net": _2, "nic": _2, "org": _2, "test": _2, "web": _2, "nom": _4 } }, "tk": _2, "tl": _6, "tm": { "$": 1, "succ": { "com": _2, "co": _2, "org": _2, "net": _2, "nom": _2, "gov": _2, "mil": _2, "edu": _2 } }, "tn": { "$": 1, "succ": { "com": _2, "ens": _2, "fin": _2, "gov": _2, "ind": _2, "intl": _2, "nat": _2, "net": _2, "org": _2, "info": _2, "perso": _2, "tourism": _2, "edunet": _2, "rnrt": _2, "rns": _2, "rnu": _2, "mincom": _2, "agrinet": _2, "defense": _2, "turen": _2 } }, "to": { "$": 1, "succ": { "611": _4, "com": _2, "gov": _2, "net": _2, "org": _2, "edu": _2, "mil": _2, "oya": _4, "vpnplus": _4, "quickconnect": { "$": 0, "succ": { "direct": _4 } }, "nyan": _4 } }, "tr": { "$": 1, "succ": { "av": _2, "bbs": _2, "bel": _2, "biz": _2, "com": _5, "dr": _2, "edu": _2, "gen": _2, "gov": _2, "info": _2, "mil": _2, "k12": _2, "kep": _2, "name": _2, "net": _2, "org": _2, "pol": _2, "tel": _2, "tsk": _2, "tv": _2, "web": _2, "nc": _6 } }, "tt": { "$": 1, "succ": { "co": _2, "com": _2, "org": _2, "net": _2, "biz": _2, "info": _2, "pro": _2, "int": _2, "coop": _2, "jobs": _2, "mobi": _2, "travel": _2, "museum": _2, "aero": _2, "name": _2, "gov": _2, "edu": _2 } }, "tv": { "$": 1, "succ": { "dyndns": _4, "better-than": _4, "on-the-web": _4, "worse-than": _4 } }, "tw": { "$": 1, "succ": { "edu": _2, "gov": _2, "mil": _2, "com": { "$": 1, "succ": { "mymailer": _4 } }, "net": _2, "org": _2, "idv": _2, "game": _2, "ebiz": _2, "club": _2, "xn--zf0ao64a": _2, "網路": _2, "xn--uc0atv": _2, "組織": _2, "xn--czrw28b": _2, "商業": _2, "url": _4, "blogspot": _4, "nym": _4 } }, "tz": { "$": 1, "succ": { "ac": _2, "co": _2, "go": _2, "hotel": _2, "info": _2, "me": _2, "mil": _2, "mobi": _2, "ne": _2, "or": _2, "sc": _2, "tv": _2 } }, "ua": { "$": 1, "succ": { "com": _2, "edu": _2, "gov": _2, "in": _2, "net": _2, "org": _2, "cherkassy": _2, "cherkasy": _2, "chernigov": _2, "chernihiv": _2, "chernivtsi": _2, "chernovtsy": _2, "ck": _2, "cn": _2, "cr": _2, "crimea": _2, "cv": _2, "dn": _2, "dnepropetrovsk": _2, "dnipropetrovsk": _2, "donetsk": _2, "dp": _2, "if": _2, "ivano-frankivsk": _2, "kh": _2, "kharkiv": _2, "kharkov": _2, "kherson": _2, "khmelnitskiy": _2, "khmelnytskyi": _2, "kiev": _2, "kirovograd": _2, "km": _2, "kr": _2, "krym": _2, "ks": _2, "kv": _2, "kyiv": _2, "lg": _2, "lt": _2, "lugansk": _2, "lutsk": _2, "lv": _2, "lviv": _2, "mk": _2, "mykolaiv": _2, "nikolaev": _2, "od": _2, "odesa": _2, "odessa": _2, "pl": _2, "poltava": _2, "rivne": _2, "rovno": _2, "rv": _2, "sb": _2, "sebastopol": _2, "sevastopol": _2, "sm": _2, "sumy": _2, "te": _2, "ternopil": _2, "uz": _2, "uzhgorod": _2, "vinnica": _2, "vinnytsia": _2, "vn": _2, "volyn": _2, "yalta": _2, "zaporizhzhe": _2, "zaporizhzhia": _2, "zhitomir": _2, "zhytomyr": _2, "zp": _2, "zt": _2, "cc": _4, "inf": _4, "ltd": _4, "biz": _4, "co": _4, "pp": _4, "v": _4 } }, "ug": { "$": 1, "succ": { "co": _2, "or": _2, "ac": _2, "sc": _2, "go": _2, "ne": _2, "com": _2, "org": _2, "blogspot": _4, "nom": _4 } }, "uk": { "$": 1, "succ": { "ac": _2, "co": { "$": 1, "succ": { "bytemark": { "$": 0, "succ": { "dh": _4, "vm": _4 } }, "blogspot": _4, "layershift": _17, "barsy": _4, "barsyonline": _4, "nh-serv": _4, "no-ip": _4, "wellbeingzone": _4, "gwiddle": _4 } }, "gov": { "$": 1, "succ": { "service": _4, "homeoffice": _4 } }, "ltd": _2, "me": _2, "net": _2, "nhs": _2, "org": { "$": 1, "succ": { "glug": _4, "lug": _4, "lugs": _4 } }, "plc": _2, "police": _2, "sch": _8, "conn": _4, "copro": _4, "barsy": _4 } }, "us": { "$": 1, "succ": { "dni": _2, "fed": _2, "isa": _2, "kids": _2, "nsn": _2, "ak": _30, "al": _30, "ar": _30, "as": _30, "az": _30, "ca": _30, "co": _30, "ct": _30, "dc": _30, "de": { "$": 1, "succ": { "k12": _2, "cc": _2, "lib": _4 } }, "fl": _30, "ga": _30, "gu": _30, "hi": _31, "ia": _30, "id": _30, "il": _30, "in": _30, "ks": _30, "ky": _30, "la": _30, "ma": { "$": 1, "succ": { "k12": { "$": 1, "succ": { "pvt": _2, "chtr": _2, "paroch": _2 } }, "cc": _2, "lib": _2 } }, "md": _30, "me": _30, "mi": { "$": 1, "succ": { "k12": _2, "cc": _2, "lib": _2, "ann-arbor": _2, "cog": _2, "dst": _2, "eaton": _2, "gen": _2, "mus": _2, "tec": _2, "washtenaw": _2 } }, "mn": _30, "mo": _30, "ms": _30, "mt": _30, "nc": _30, "nd": _31, "ne": _30, "nh": _30, "nj": _30, "nm": _30, "nv": _30, "ny": _30, "oh": _30, "ok": _30, "or": _30, "pa": _30, "pr": _30, "ri": _31, "sc": _30, "sd": _31, "tn": _30, "tx": _30, "ut": _30, "vi": _30, "vt": _30, "va": _30, "wa": _30, "wi": _30, "wv": { "$": 1, "succ": { "cc": _2 } }, "wy": _30, "cloudns": _4, "drud": _4, "is-by": _4, "land-4-sale": _4, "stuff-4-sale": _4, "graphox": _4, "freeddns": _4, "golffan": _4, "noip": _4, "pointto": _4, "platterp": _4 } }, "uy": { "$": 1, "succ": { "com": _5, "edu": _2, "gub": _2, "mil": _2, "net": _2, "org": _2, "nom": _4 } }, "uz": { "$": 1, "succ": { "co": _2, "com": _2, "net": _2, "org": _2 } }, "va": _2, "vc": { "$": 1, "succ": { "com": _2, "net": _2, "org": _2, "gov": _2, "mil": _2, "edu": _2, "gv": { "$": 2, "succ": { "d": _4 } }, "0e": _4, "nom": _4 } }, "ve": { "$": 1, "succ": { "arts": _2, "co": _2, "com": _2, "e12": _2, "edu": _2, "firm": _2, "gob": _2, "gov": _2, "info": _2, "int": _2, "mil": _2, "net": _2, "org": _2, "rec": _2, "store": _2, "tec": _2, "web": _2 } }, "vg": { "$": 1, "succ": { "nom": _4, "at": _4 } }, "vi": { "$": 1, "succ": { "co": _2, "com": _2, "k12": _2, "net": _2, "org": _2 } }, "vn": { "$": 1, "succ": { "com": _2, "net": _2, "org": _2, "edu": _2, "gov": _2, "int": _2, "ac": _2, "biz": _2, "info": _2, "name": _2, "pro": _2, "health": _2, "blogspot": _4 } }, "vu": { "$": 1, "succ": { "com": _2, "edu": _2, "net": _2, "org": _2, "blog": _4, "dev": _4, "me": _4, "cn": _4 } }, "wf": _2, "ws": { "$": 1, "succ": { "com": _2, "net": _2, "org": _2, "gov": _2, "edu": _2, "advisor": _7, "cloud66": _4, "dyndns": _4, "mypets": _4 } }, "yt": _2, "xn--mgbaam7a8h": _2, "امارات": _2, "xn--y9a3aq": _2, "հայ": _2, "xn--54b7fta0cc": _2, "বাংলা": _2, "xn--90ae": _2, "бг": _2, "xn--90ais": _2, "бел": _2, "xn--fiqs8s": _2, "中国": _2, "xn--fiqz9s": _2, "中國": _2, "xn--lgbbat1ad8j": _2, "الجزائر": _2, "xn--wgbh1c": _2, "مصر": _2, "xn--e1a4c": _2, "ею": _2, "xn--qxa6a": _2, "ευ": _2, "xn--mgbah1a3hjkrd": _2, "موريتانيا": _2, "xn--node": _2, "გე": _2, "xn--qxam": _2, "ελ": _2, "xn--j6w193g": { "$": 1, "succ": { "xn--55qx5d": _2, "xn--wcvs22d": _2, "xn--mxtq1m": _2, "xn--gmqw5a": _2, "xn--od0alg": _2, "xn--uc0atv": _2 } }, "香港": { "$": 1, "succ": { "公司": _2, "教育": _2, "政府": _2, "個人": _2, "網絡": _2, "組織": _2 } }, "xn--2scrj9c": _2, "ಭಾರತ": _2, "xn--3hcrj9c": _2, "ଭାରତ": _2, "xn--45br5cyl": _2, "ভাৰত": _2, "xn--h2breg3eve": _2, "भारतम्": _2, "xn--h2brj9c8c": _2, "भारोत": _2, "xn--mgbgu82a": _2, "ڀارت": _2, "xn--rvc1e0am3e": _2, "ഭാരതം": _2, "xn--h2brj9c": _2, "भारत": _2, "xn--mgbbh1a": _2, "بارت": _2, "xn--mgbbh1a71e": _2, "بھارت": _2, "xn--fpcrj9c3d": _2, "భారత్": _2, "xn--gecrj9c": _2, "ભારત": _2, "xn--s9brj9c": _2, "ਭਾਰਤ": _2, "xn--45brj9c": _2, "ভারত": _2, "xn--xkc2dl3a5ee0h": _2, "இந்தியா": _2, "xn--mgba3a4f16a": _2, "ایران": _2, "xn--mgba3a4fra": _2, "ايران": _2, "xn--mgbtx2b": _2, "عراق": _2, "xn--mgbayh7gpa": _2, "الاردن": _2, "xn--3e0b707e": _2, "한국": _2, "xn--80ao21a": _2, "қаз": _2, "xn--fzc2c9e2c": _2, "ලංකා": _2, "xn--xkc2al3hye2a": _2, "இலங்கை": _2, "xn--mgbc0a9azcg": _2, "المغرب": _2, "xn--d1alf": _2, "мкд": _2, "xn--l1acc": _2, "мон": _2, "xn--mix891f": _2, "澳門": _2, "xn--mix082f": _2, "澳门": _2, "xn--mgbx4cd0ab": _2, "مليسيا": _2, "xn--mgb9awbf": _2, "عمان": _2, "xn--mgbai9azgqp6j": _2, "پاکستان": _2, "xn--mgbai9a5eva00b": _2, "پاكستان": _2, "xn--ygbi2ammx": _2, "فلسطين": _2, "xn--90a3ac": { "$": 1, "succ": { "xn--o1ac": _2, "xn--c1avg": _2, "xn--90azh": _2, "xn--d1at": _2, "xn--o1ach": _2, "xn--80au": _2 } }, "срб": { "$": 1, "succ": { "пр": _2, "орг": _2, "обр": _2, "од": _2, "упр": _2, "ак": _2 } }, "xn--p1ai": _2, "рф": _2, "xn--wgbl6a": _2, "قطر": _2, "xn--mgberp4a5d4ar": _2, "السعودية": _2, "xn--mgberp4a5d4a87g": _2, "السعودیة": _2, "xn--mgbqly7c0a67fbc": _2, "السعودیۃ": _2, "xn--mgbqly7cvafr": _2, "السعوديه": _2, "xn--mgbpl2fh": _2, "سودان": _2, "xn--yfro4i67o": _2, "新加坡": _2, "xn--clchc0ea0b2g2a9gcd": _2, "சிங்கப்பூர்": _2, "xn--ogbpf8fl": _2, "سورية": _2, "xn--mgbtf8fl": _2, "سوريا": _2, "xn--o3cw4h": { "$": 1, "succ": { "xn--12c1fe0br": _2, "xn--12co0c3b4eva": _2, "xn--h3cuzk1di": _2, "xn--o3cyx2a": _2, "xn--m3ch0j3a": _2, "xn--12cfi8ixb8l": _2 } }, "ไทย": { "$": 1, "succ": { "ศึกษา": _2, "ธุรกิจ": _2, "รัฐบาล": _2, "ทหาร": _2, "เน็ต": _2, "องค์กร": _2 } }, "xn--pgbs0dh": _2, "تونس": _2, "xn--kpry57d": _2, "台灣": _2, "xn--kprw13d": _2, "台湾": _2, "xn--nnx388a": _2, "臺灣": _2, "xn--j1amh": _2, "укр": _2, "xn--mgb2ddes": _2, "اليمن": _2, "xxx": _2, "ye": _8, "za": { "$": 0, "succ": { "ac": _2, "agric": _2, "alt": _2, "co": _5, "edu": _2, "gov": _2, "grondar": _2, "law": _2, "mil": _2, "net": _2, "ngo": _2, "nic": _2, "nis": _2, "nom": _2, "org": _2, "school": _2, "tm": _2, "web": _2 } }, "zm": { "$": 1, "succ": { "ac": _2, "biz": _2, "co": _2, "com": _2, "edu": _2, "gov": _2, "info": _2, "mil": _2, "net": _2, "org": _2, "sch": _2 } }, "zw": { "$": 1, "succ": { "ac": _2, "co": _2, "gov": _2, "mil": _2, "org": _2 } }, "aaa": _2, "aarp": _2, "abarth": _2, "abb": _2, "abbott": _2, "abbvie": _2, "abc": _2, "able": _2, "abogado": _2, "abudhabi": _2, "academy": { "$": 1, "succ": { "official": _4 } }, "accenture": _2, "accountant": _2, "accountants": _2, "aco": _2, "actor": _2, "adac": _2, "ads": _2, "adult": _2, "aeg": _2, "aetna": _2, "afamilycompany": _2, "afl": _2, "africa": _2, "agakhan": _2, "agency": _2, "aig": _2, "airbus": _2, "airforce": _2, "airtel": _2, "akdn": _2, "alfaromeo": _2, "alibaba": _2, "alipay": _2, "allfinanz": _2, "allstate": _2, "ally": _2, "alsace": _2, "alstom": _2, "amazon": _2, "americanexpress": _2, "americanfamily": _2, "amex": _2, "amfam": _2, "amica": _2, "amsterdam": _2, "analytics": _2, "android": _2, "anquan": _2, "anz": _2, "aol": _2, "apartments": _2, "app": { "$": 1, "succ": { "wnext": _4, "run": { "$": 2, "succ": { "a": _4 } }, "web": _4, "hasura": _4, "loginline": _4, "netlify": _4, "telebit": _4, "vercel": _4 } }, "apple": _2, "aquarelle": _2, "arab": _2, "aramco": _2, "archi": _2, "army": _2, "art": _2, "arte": _2, "asda": _2, "associates": _2, "athleta": _2, "attorney": _2, "auction": _2, "audi": _2, "audible": _2, "audio": _2, "auspost": _2, "author": _2, "auto": _2, "autos": _2, "avianca": _2, "aws": _2, "axa": _2, "azure": _2, "baby": _2, "baidu": _2, "banamex": _2, "bananarepublic": _2, "band": _2, "bank": _2, "bar": _2, "barcelona": _2, "barclaycard": _2, "barclays": _2, "barefoot": _2, "bargains": _2, "baseball": _2, "basketball": _2, "bauhaus": _2, "bayern": _2, "bbc": _2, "bbt": _2, "bbva": _2, "bcg": _2, "bcn": _2, "beats": _2, "beauty": _2, "beer": _2, "bentley": _2, "berlin": _2, "best": _2, "bestbuy": _2, "bet": _2, "bharti": _2, "bible": _2, "bid": _2, "bike": _2, "bing": _2, "bingo": _2, "bio": _2, "black": _2, "blackfriday": _2, "blockbuster": _2, "blog": _2, "bloomberg": _2, "blue": _2, "bms": _2, "bmw": _2, "bnpparibas": _2, "boats": _2, "boehringer": _2, "bofa": _2, "bom": _2, "bond": _2, "boo": _2, "book": _2, "booking": _2, "bosch": _2, "bostik": _2, "boston": _2, "bot": _2, "boutique": _2, "box": _2, "bradesco": _2, "bridgestone": _2, "broadway": _2, "broker": _2, "brother": _2, "brussels": _2, "budapest": _2, "bugatti": _2, "build": _2, "builders": _2, "business": _10, "buy": _2, "buzz": _2, "bzh": _2, "cab": _2, "cafe": _2, "cal": _2, "call": _2, "calvinklein": _2, "cam": _2, "camera": _2, "camp": _2, "cancerresearch": _2, "canon": _2, "capetown": _2, "capital": _2, "capitalone": _2, "car": _2, "caravan": _2, "cards": _2, "care": _2, "career": _2, "careers": _2, "cars": _2, "casa": { "$": 1, "succ": { "nabu": { "$": 0, "succ": { "ui": _4 } } } }, "case": _2, "caseih": _2, "cash": _2, "casino": _2, "catering": _2, "catholic": _2, "cba": _2, "cbn": _2, "cbre": _2, "cbs": _2, "ceb": _2, "center": _2, "ceo": _2, "cern": _2, "cfa": _2, "cfd": _2, "chanel": _2, "channel": _2, "charity": _2, "chase": _2, "chat": _2, "cheap": _2, "chintai": _2, "christmas": _2, "chrome": _2, "church": _2, "cipriani": _2, "circle": _2, "cisco": _2, "citadel": _2, "citi": _2, "citic": _2, "city": _11, "cityeats": _2, "claims": _2, "cleaning": _2, "click": _2, "clinic": _2, "clinique": _2, "clothing": _2, "cloud": { "$": 1, "succ": { "banzai": _7, "statics": _7, "jele": _4, "linkyard": _4, "magentosite": _7, "perspecta": _4, "vapor": _4, "on-rancher": _7, "sensiosite": _7, "trafficplex": _4, "urown": _4, "voorloper": _4 } }, "club": { "$": 1, "succ": { "cloudns": _4, "jele": _4, "barsy": _4, "pony": _4 } }, "clubmed": _2, "coach": _2, "codes": { "$": 1, "succ": { "owo": _7 } }, "coffee": _2, "college": _2, "cologne": _2, "comcast": _2, "commbank": _2, "community": { "$": 1, "succ": { "ravendb": _4, "myforum": _4 } }, "company": _2, "compare": _2, "computer": _2, "comsec": _2, "condos": _2, "construction": _2, "consulting": _2, "contact": _2, "contractors": _2, "cooking": _2, "cookingchannel": _2, "cool": { "$": 1, "succ": { "de": _4 } }, "corsica": _2, "country": _2, "coupon": _2, "coupons": _2, "courses": _2, "cpa": _2, "credit": _2, "creditcard": _2, "creditunion": _2, "cricket": _2, "crown": _2, "crs": _2, "cruise": _2, "cruises": _2, "csc": _2, "cuisinella": _2, "cymru": _2, "cyou": _2, "dabur": _2, "dad": _2, "dance": _2, "data": _2, "date": _2, "dating": _2, "datsun": _2, "day": _2, "dclk": _2, "dds": _2, "deal": _2, "dealer": _2, "deals": _2, "degree": _2, "delivery": _2, "dell": _2, "deloitte": _2, "delta": _2, "democrat": _2, "dental": _2, "dentist": _2, "desi": _2, "design": { "$": 1, "succ": { "bss": _4 } }, "dev": { "$": 1, "succ": { "lcl": _7, "stg": _7, "workers": _4, "curv": _4, "fly": _4, "iserv": _4, "loginline": _4, "platter-app": _4, "vercel": _4, "webhare": _7 } }, "dhl": _2, "diamonds": _2, "diet": _2, "digital": { "$": 1, "succ": { "cloudapps": { "$": 2, "succ": { "london": _4 } } } }, "direct": _2, "directory": _2, "discount": _2, "discover": _2, "dish": _2, "diy": _2, "dnp": _2, "docs": _2, "doctor": _2, "dog": _2, "domains": _2, "dot": _2, "download": _2, "drive": _2, "dtv": _2, "dubai": _2, "duck": _2, "dunlop": _2, "dupont": _2, "durban": _2, "dvag": _2, "dvr": _2, "earth": { "$": 1, "succ": { "dapps": { "$": 0, "succ": { "*": _4, "bzz": _7 } } } }, "eat": _2, "eco": _2, "edeka": _2, "education": _10, "email": _2, "emerck": _2, "energy": _2, "engineer": _2, "engineering": _2, "enterprises": _2, "epson": _2, "equipment": _2, "ericsson": _2, "erni": _2, "esq": _2, "estate": { "$": 1, "succ": { "compute": _7 } }, "etisalat": _2, "eurovision": _2, "eus": { "$": 1, "succ": { "party": _18 } }, "events": _10, "exchange": _2, "expert": _2, "exposed": _2, "express": _2, "extraspace": _2, "fage": _2, "fail": _2, "fairwinds": _2, "faith": _19, "family": _2, "fan": _2, "fans": _2, "farm": { "$": 1, "succ": { "storj": _4 } }, "farmers": _2, "fashion": { "$": 1, "succ": { "of": _4, "on": _4 } }, "fast": _2, "fedex": _2, "feedback": _2, "ferrari": _2, "ferrero": _2, "fiat": _2, "fidelity": _2, "fido": _2, "film": _2, "final": _2, "finance": _2, "financial": _10, "fire": _2, "firestone": _2, "firmdale": _2, "fish": _2, "fishing": _2, "fit": { "$": 1, "succ": { "ptplus": _4 } }, "fitness": _2, "flickr": _2, "flights": _2, "flir": _2, "florist": _2, "flowers": _2, "fly": _2, "foo": _2, "food": _2, "foodnetwork": _2, "football": { "$": 1, "succ": { "of": _4 } }, "ford": _2, "forex": _2, "forsale": _2, "forum": _2, "foundation": _2, "fox": _2, "free": _2, "fresenius": _2, "frl": _2, "frogans": _2, "frontdoor": _2, "frontier": _2, "ftr": _2, "fujitsu": _2, "fujixerox": _2, "fun": _2, "fund": _2, "furniture": _2, "futbol": _2, "fyi": _2, "gal": _2, "gallery": _2, "gallo": _2, "gallup": _2, "game": _2, "games": _2, "gap": _2, "garden": _2, "gay": _2, "gbiz": _2, "gdn": { "$": 1, "succ": { "cnpy": _4 } }, "gea": _2, "gent": _2, "genting": _2, "george": _2, "ggee": _2, "gift": _2, "gifts": _2, "gives": _2, "giving": _2, "glade": _2, "glass": _2, "gle": _2, "global": _2, "globo": _2, "gmail": _2, "gmbh": _2, "gmo": _2, "gmx": _2, "godaddy": _2, "gold": _2, "goldpoint": _2, "golf": _2, "goo": _2, "goodyear": _2, "goog": { "$": 1, "succ": { "cloud": _4 } }, "google": _2, "gop": _2, "got": _2, "grainger": _2, "graphics": _2, "gratis": _2, "green": _2, "gripe": _2, "grocery": _2, "group": { "$": 1, "succ": { "discourse": _4 } }, "guardian": _2, "gucci": _2, "guge": _2, "guide": _2, "guitars": _2, "guru": _2, "hair": _2, "hamburg": _2, "hangout": _2, "haus": _2, "hbo": _2, "hdfc": _2, "hdfcbank": _2, "health": _2, "healthcare": _2, "help": _2, "helsinki": _2, "here": _2, "hermes": _2, "hgtv": _2, "hiphop": _2, "hisamitsu": _2, "hitachi": _2, "hiv": _2, "hkt": _2, "hockey": _2, "holdings": _2, "holiday": _2, "homedepot": _2, "homegoods": _2, "homes": _2, "homesense": _2, "honda": _2, "horse": _2, "hospital": _2, "host": { "$": 1, "succ": { "cloudaccess": _4, "freesite": _4, "fastvps": _4, "myfast": _4, "jele": _4, "mircloud": _4, "pcloud": _4, "half": _4 } }, "hosting": { "$": 1, "succ": { "opencraft": _4 } }, "hot": _2, "hoteles": _2, "hotels": _2, "hotmail": _2, "house": _2, "how": _2, "hsbc": _2, "hughes": _2, "hyatt": _2, "hyundai": _2, "ibm": _2, "icbc": _2, "ice": _2, "icu": _2, "ieee": _2, "ifm": _2, "ikano": _2, "imamat": _2, "imdb": _2, "immo": _2, "immobilien": _2, "inc": _2, "industries": _2, "infiniti": _2, "ing": _2, "ink": _11, "institute": _2, "insurance": _2, "insure": _2, "intel": _2, "international": _2, "intuit": _2, "investments": _2, "ipiranga": _2, "irish": _2, "ismaili": _2, "ist": _2, "istanbul": _2, "itau": _2, "itv": _2, "iveco": _2, "jaguar": _2, "java": _2, "jcb": _2, "jcp": _2, "jeep": _2, "jetzt": _2, "jewelry": _2, "jio": _2, "jll": _2, "jmp": _2, "jnj": _2, "joburg": _2, "jot": _2, "joy": _2, "jpmorgan": _2, "jprs": _2, "juegos": _2, "juniper": _2, "kaufen": _2, "kddi": _2, "kerryhotels": _2, "kerrylogistics": _2, "kerryproperties": _2, "kfh": _2, "kia": _2, "kim": _2, "kinder": _2, "kindle": _2, "kitchen": _2, "kiwi": _2, "koeln": _2, "komatsu": _2, "kosher": _2, "kpmg": _2, "kpn": _2, "krd": { "$": 1, "succ": { "co": _4, "edu": _4 } }, "kred": _2, "kuokgroup": _2, "kyoto": _2, "lacaixa": _2, "lamborghini": _2, "lamer": _2, "lancaster": _2, "lancia": _2, "land": { "$": 1, "succ": { "static": { "$": 2, "succ": { "dev": _4, "sites": _4 } } } }, "landrover": _2, "lanxess": _2, "lasalle": _2, "lat": _2, "latino": _2, "latrobe": _2, "law": _2, "lawyer": _2, "lds": _2, "lease": _2, "leclerc": _2, "lefrak": _2, "legal": _2, "lego": _2, "lexus": _2, "lgbt": _2, "lidl": _2, "life": _2, "lifeinsurance": _2, "lifestyle": _2, "lighting": _2, "like": _2, "lilly": _2, "limited": _2, "limo": _2, "lincoln": _2, "linde": _2, "link": { "$": 1, "succ": { "cyon": _4, "mypep": _4, "dweb": _7 } }, "lipsy": _2, "live": _2, "living": _2, "lixil": _2, "llc": _2, "llp": _2, "loan": _2, "loans": _2, "locker": _2, "locus": _2, "loft": _2, "lol": _2, "london": { "$": 1, "succ": { "in": _4, "of": _4 } }, "lotte": _2, "lotto": _2, "love": _2, "lpl": _2, "lplfinancial": _2, "ltd": _2, "ltda": _2, "lundbeck": _2, "lupin": _2, "luxe": _2, "luxury": _2, "macys": _2, "madrid": _2, "maif": _2, "maison": _2, "makeup": _2, "man": _2, "management": { "$": 1, "succ": { "router": _4 } }, "mango": _2, "map": _2, "market": _2, "marketing": _2, "markets": _2, "marriott": _2, "marshalls": _2, "maserati": _2, "mattel": _2, "mba": _2, "mckinsey": _2, "med": _2, "media": _2, "meet": _2, "melbourne": _2, "meme": _2, "memorial": _2, "men": _24, "menu": _25, "merckmsd": _2, "metlife": _2, "miami": _2, "microsoft": _2, "mini": _2, "mint": _2, "mit": _2, "mitsubishi": _2, "mlb": _2, "mls": _2, "mma": _2, "mobile": _2, "moda": _2, "moe": _2, "moi": _2, "mom": { "$": 1, "succ": { "and": _4, "for": _4 } }, "monash": _2, "money": _2, "monster": _2, "mormon": _2, "mortgage": _2, "moscow": _2, "moto": _2, "motorcycles": _2, "mov": _2, "movie": _2, "msd": _2, "mtn": _2, "mtr": _2, "mutual": _2, "nab": _2, "nagoya": _2, "nationwide": _2, "natura": _2, "navy": _2, "nba": _2, "nec": _2, "netbank": _2, "netflix": _2, "network": { "$": 1, "succ": { "alces": _7, "co": _4, "arvo": _4, "azimuth": _4 } }, "neustar": _2, "new": _2, "newholland": _2, "news": _2, "next": _2, "nextdirect": _2, "nexus": _2, "nfl": _2, "ngo": _2, "nhk": _2, "nico": _2, "nike": _2, "nikon": _2, "ninja": _2, "nissan": _2, "nissay": _2, "nokia": _2, "northwesternmutual": _2, "norton": _2, "now": _2, "nowruz": _2, "nowtv": _2, "nra": _2, "nrw": _2, "ntt": _2, "nyc": _2, "obi": _2, "observer": _2, "off": _2, "office": _2, "okinawa": _2, "olayan": _2, "olayangroup": _2, "oldnavy": _2, "ollo": _2, "omega": _2, "one": { "$": 1, "succ": { "onred": { "$": 2, "succ": { "staging": _4 } }, "for": _4, "homelink": _4 } }, "ong": _2, "onl": _2, "online": _25, "onyourside": _2, "ooo": _2, "open": _2, "oracle": _2, "orange": _2, "organic": _2, "origins": _2, "osaka": _2, "otsuka": _2, "ott": _2, "ovh": { "$": 1, "succ": { "nerdpol": _4 } }, "page": { "$": 1, "succ": { "pdns": _4, "plesk": _4, "prvcy": _4 } }, "panasonic": _2, "paris": _2, "pars": _2, "partners": _2, "parts": _2, "party": _19, "passagens": _2, "pay": _2, "pccw": _2, "pet": _2, "pfizer": _2, "pharmacy": _2, "phd": _2, "philips": _2, "phone": _2, "photo": _2, "photography": _2, "photos": _2, "physio": _2, "pics": _2, "pictet": _2, "pictures": { "$": 1, "succ": { "1337": _4 } }, "pid": _2, "pin": _2, "ping": _2, "pink": _2, "pioneer": _2, "pizza": _2, "place": _10, "play": _2, "playstation": _2, "plumbing": _2, "plus": _2, "pnc": _2, "pohl": _2, "poker": _2, "politie": _2, "porn": { "$": 1, "succ": { "indie": _4 } }, "pramerica": _2, "praxi": _2, "press": _2, "prime": _2, "prod": _2, "productions": _2, "prof": _2, "progressive": _2, "promo": _2, "properties": _2, "property": _2, "protection": _2, "pru": _2, "prudential": _2, "pub": _25, "pwc": _2, "qpon": _2, "quebec": _2, "quest": _2, "qvc": _2, "racing": _2, "radio": _2, "raid": _2, "read": _2, "realestate": _2, "realtor": _2, "realty": _2, "recipes": _2, "red": _2, "redstone": _2, "redumbrella": _2, "rehab": _2, "reise": _2, "reisen": _2, "reit": _2, "reliance": _2, "ren": _2, "rent": _2, "rentals": _2, "repair": _2, "report": _2, "republican": _2, "rest": _2, "restaurant": _2, "review": _19, "reviews": _2, "rexroth": _2, "rich": _2, "richardli": _2, "ricoh": _2, "ril": _2, "rio": _2, "rip": { "$": 1, "succ": { "clan": _4 } }, "rmit": _2, "rocher": _2, "rocks": { "$": 1, "succ": { "myddns": _4, "lima-city": _4, "webspace": _4 } }, "rodeo": _2, "rogers": _2, "room": _2, "rsvp": _2, "rugby": _2, "ruhr": _2, "run": { "$": 1, "succ": { "hs": _4, "development": _4, "ravendb": _4, "repl": _4 } }, "rwe": _2, "ryukyu": _2, "saarland": _2, "safe": _2, "safety": _2, "sakura": _2, "sale": _24, "salon": _2, "samsclub": _2, "samsung": _2, "sandvik": _2, "sandvikcoromant": _2, "sanofi": _2, "sap": _2, "sarl": _2, "sas": _2, "save": _2, "saxo": _2, "sbi": _2, "sbs": _2, "sca": _2, "scb": _2, "schaeffler": _2, "schmidt": _2, "scholarships": _2, "school": _11, "schule": _2, "schwarz": _2, "science": _19, "scjohnson": _2, "scot": { "$": 1, "succ": { "gov": _4 } }, "search": _2, "seat": _2, "secure": _2, "security": _2, "seek": _2, "select": _2, "sener": _2, "services": { "$": 1, "succ": { "loginline": _4 } }, "ses": _2, "seven": _2, "sew": _2, "sex": _2, "sexy": _2, "sfr": _2, "shangrila": _2, "sharp": _2, "shaw": _2, "shell": _2, "shia": _2, "shiksha": _2, "shoes": _2, "shop": _25, "shopping": _2, "shouji": _2, "show": _2, "showtime": _2, "shriram": _2, "silk": _2, "sina": _2, "singles": _2, "site": { "$": 1, "succ": { "cloudera": _4, "cyon": _4, "fastvps": _4, "jele": _4, "lelux": _4, "loginline": _4, "barsy": _4, "opensocial": _4, "platformsh": _7, "byen": _4, "mintere": _4 } }, "ski": _2, "skin": _2, "sky": _2, "skype": _2, "sling": _2, "smart": _2, "smile": _2, "sncf": _2, "soccer": _2, "social": _2, "softbank": _2, "software": _2, "sohu": _2, "solar": _2, "solutions": _2, "song": _2, "sony": _2, "soy": _2, "spa": _2, "space": { "$": 1, "succ": { "myfast": _4, "linkitools": _4, "uber": _4, "xs4all": _4 } }, "sport": _2, "spot": _2, "spreadbetting": _2, "srl": _2, "stada": _2, "staples": _2, "star": _2, "statebank": _2, "statefarm": _2, "stc": _2, "stcgroup": _2, "stockholm": _2, "storage": _2, "store": { "$": 1, "succ": { "shopware": _4 } }, "stream": _2, "studio": _2, "study": _2, "style": _2, "sucks": _2, "supplies": _2, "supply": _2, "support": _25, "surf": _2, "surgery": _2, "suzuki": _2, "swatch": _2, "swiftcover": _2, "swiss": _2, "sydney": _2, "systems": { "$": 1, "succ": { "knightpoint": _4 } }, "tab": _2, "taipei": _2, "talk": _2, "taobao": _2, "target": _2, "tatamotors": _2, "tatar": _2, "tattoo": _2, "tax": _2, "taxi": _2, "tci": _2, "tdk": _2, "team": { "$": 1, "succ": { "discourse": _4, "jelastic": _4 } }, "tech": _2, "technology": _10, "temasek": _2, "tennis": _2, "teva": _2, "thd": _2, "theater": _2, "theatre": _2, "tiaa": _2, "tickets": _2, "tienda": _2, "tiffany": _2, "tips": _2, "tires": _2, "tirol": _2, "tjmaxx": _2, "tjx": _2, "tkmaxx": _2, "tmall": _2, "today": _2, "tokyo": _2, "tools": _2, "top": { "$": 1, "succ": { "now-dns": _4, "ntdll": _4 } }, "toray": _2, "toshiba": _2, "total": _2, "tours": _2, "town": _2, "toyota": _2, "toys": _2, "trade": _19, "trading": _2, "training": _2, "travel": _2, "travelchannel": _2, "travelers": _2, "travelersinsurance": _2, "trust": _2, "trv": _2, "tube": _2, "tui": _2, "tunes": _2, "tushu": _2, "tvs": _2, "ubank": _2, "ubs": _2, "unicom": _2, "university": _2, "uno": _2, "uol": _2, "ups": _2, "vacations": _2, "vana": _2, "vanguard": _2, "vegas": _2, "ventures": _2, "verisign": _2, "versicherung": _2, "vet": _2, "viajes": _2, "video": _2, "vig": _2, "viking": _2, "villas": _2, "vin": _2, "vip": _2, "virgin": _2, "visa": _2, "vision": _2, "viva": _2, "vivo": _2, "vlaanderen": _2, "vodka": _2, "volkswagen": _2, "volvo": _2, "vote": _2, "voting": _2, "voto": _2, "voyage": _2, "vuelos": _2, "wales": _2, "walmart": _2, "walter": _2, "wang": _2, "wanggou": _2, "watch": _2, "watches": _2, "weather": _2, "weatherchannel": _2, "webcam": _2, "weber": _2, "website": _2, "wed": _2, "wedding": _2, "weibo": _2, "weir": _2, "whoswho": _2, "wien": _2, "wiki": _2, "williamhill": _2, "win": _2, "windows": _2, "wine": _2, "winners": _2, "wme": _2, "wolterskluwer": _2, "woodside": _2, "work": { "$": 1, "succ": { "of": _4, "to": _4 } }, "works": _2, "world": _2, "wow": _2, "wtc": _2, "wtf": _2, "xbox": _2, "xerox": _2, "xfinity": _2, "xihuan": _2, "xin": _2, "xn--11b4c3d": _2, "कॉम": _2, "xn--1ck2e1b": _2, "セール": _2, "xn--1qqw23a": _2, "佛山": _2, "xn--30rr7y": _2, "慈善": _2, "xn--3bst00m": _2, "集团": _2, "xn--3ds443g": _2, "在线": _2, "xn--3oq18vl8pn36a": _2, "大众汽车": _2, "xn--3pxu8k": _2, "点看": _2, "xn--42c2d9a": _2, "คอม": _2, "xn--45q11c": _2, "八卦": _2, "xn--4gbrim": _2, "موقع": _2, "xn--55qw42g": _2, "公益": _2, "xn--55qx5d": _2, "公司": _2, "xn--5su34j936bgsg": _2, "香格里拉": _2, "xn--5tzm5g": _2, "网站": _2, "xn--6frz82g": _2, "移动": _2, "xn--6qq986b3xl": _2, "我爱你": _2, "xn--80adxhks": _2, "москва": _2, "xn--80aqecdr1a": _2, "католик": _2, "xn--80asehdb": _2, "онлайн": _2, "xn--80aswg": _2, "сайт": _2, "xn--8y0a063a": _2, "联通": _2, "xn--9dbq2a": _2, "קום": _2, "xn--9et52u": _2, "时尚": _2, "xn--9krt00a": _2, "微博": _2, "xn--b4w605ferd": _2, "淡马锡": _2, "xn--bck1b9a5dre4c": _2, "ファッション": _2, "xn--c1avg": _2, "орг": _2, "xn--c2br7g": _2, "नेट": _2, "xn--cck2b3b": _2, "ストア": _2, "xn--cckwcxetd": _2, "アマゾン": _2, "xn--cg4bki": _2, "삼성": _2, "xn--czr694b": _2, "商标": _2, "xn--czrs0t": _2, "商店": _2, "xn--czru2d": _2, "商城": _2, "xn--d1acj3b": _2, "дети": _2, "xn--eckvdtc9d": _2, "ポイント": _2, "xn--efvy88h": _2, "新闻": _2, "xn--fct429k": _2, "家電": _2, "xn--fhbei": _2, "كوم": _2, "xn--fiq228c5hs": _2, "中文网": _2, "xn--fiq64b": _2, "中信": _2, "xn--fjq720a": _2, "娱乐": _2, "xn--flw351e": _2, "谷歌": _2, "xn--fzys8d69uvgm": _2, "電訊盈科": _2, "xn--g2xx48c": _2, "购物": _2, "xn--gckr3f0f": _2, "クラウド": _2, "xn--gk3at1e": _2, "通販": _2, "xn--hxt814e": _2, "网店": _2, "xn--i1b6b1a6a2e": _2, "संगठन": _2, "xn--imr513n": _2, "餐厅": _2, "xn--io0a7i": _2, "网络": _2, "xn--j1aef": _2, "ком": _2, "xn--jlq480n2rg": _2, "亚马逊": _2, "xn--jlq61u9w7b": _2, "诺基亚": _2, "xn--jvr189m": _2, "食品": _2, "xn--kcrx77d1x4a": _2, "飞利浦": _2, "xn--kput3i": _2, "手机": _2, "xn--mgba3a3ejt": _2, "ارامكو": _2, "xn--mgba7c0bbn0a": _2, "العليان": _2, "xn--mgbaakc7dvf": _2, "اتصالات": _2, "xn--mgbab2bd": _2, "بازار": _2, "xn--mgbca7dzdo": _2, "ابوظبي": _2, "xn--mgbi4ecexp": _2, "كاثوليك": _2, "xn--mgbt3dhd": _2, "همراه": _2, "xn--mk1bu44c": _2, "닷컴": _2, "xn--mxtq1m": _2, "政府": _2, "xn--ngbc5azd": _2, "شبكة": _2, "xn--ngbe9e0a": _2, "بيتك": _2, "xn--ngbrx": _2, "عرب": _2, "xn--nqv7f": _2, "机构": _2, "xn--nqv7fs00ema": _2, "组织机构": _2, "xn--nyqy26a": _2, "健康": _2, "xn--otu796d": _2, "招聘": _2, "xn--p1acf": _2, "рус": _2, "xn--pssy2u": _2, "大拿": _2, "xn--q9jyb4c": _2, "みんな": _2, "xn--qcka1pmc": _2, "グーグル": _2, "xn--rhqv96g": _2, "世界": _2, "xn--rovu88b": _2, "書籍": _2, "xn--ses554g": _2, "网址": _2, "xn--t60b56a": _2, "닷넷": _2, "xn--tckwe": _2, "コム": _2, "xn--tiq49xqyj": _2, "天主教": _2, "xn--unup4y": _2, "游戏": _2, "xn--vermgensberater-ctb": _2, "vermögensberater": _2, "xn--vermgensberatung-pwb": _2, "vermögensberatung": _2, "xn--vhquv": _2, "企业": _2, "xn--vuq861b": _2, "信息": _2, "xn--w4r85el8fhu5dnra": _2, "嘉里大酒店": _2, "xn--w4rs40l": _2, "嘉里": _2, "xn--xhq521b": _2, "广东": _2, "xn--zfr164b": _2, "政务": _2, "xyz": { "$": 1, "succ": { "blogsite": _4, "fhapp": _4, "crafting": _4, "zapto": _4, "telebit": _7 } }, "yachts": _2, "yahoo": _2, "yamaxun": _2, "yandex": _2, "yodobashi": _2, "yoga": _2, "yokohama": _2, "you": _2, "youtube": _2, "yun": _2, "zappos": _2, "zara": _2, "zero": _2, "zip": _2, "zone": { "$": 1, "succ": { "cloud66": _4, "hs": _4, "triton": _7, "lima": _4 } }, "zuerich": _2 } };
    ;
    return rules;
})();

;// CONCATENATED MODULE: ./node_modules/.pnpm/tldts@5.6.45/node_modules/tldts/dist/es6/src/suffix-trie.js


/**
 * Lookup parts of domain in Trie
 */
function lookupInTrie(parts, trie, index, allowedMask) {
    let result = null;
    let node = trie;
    while (node !== undefined) {
        // We have a match!
        if ((node.$ & allowedMask) !== 0) {
            result = {
                index: index + 1,
                isIcann: node.$ === 1 /* ICANN */,
                isPrivate: node.$ === 2 /* PRIVATE */,
            };
        }
        // No more `parts` to look for
        if (index === -1) {
            break;
        }
        const succ = node.succ;
        node = succ && (succ[parts[index]] || succ['*']);
        index -= 1;
    }
    return result;
}
/**
 * Check if `hostname` has a valid public suffix in `trie`.
 */
function suffix_trie_suffixLookup(hostname, options, out) {
    if ((0,es6/* fastPathLookup */.m5)(hostname, options, out) === true) {
        return;
    }
    const hostnameParts = hostname.split('.');
    const allowedMask = (options.allowPrivateDomains === true ? 2 /* PRIVATE */ : 0) |
        (options.allowIcannDomains === true ? 1 /* ICANN */ : 0);
    // Look for exceptions
    const exceptionMatch = lookupInTrie(hostnameParts, exceptions, hostnameParts.length - 1, allowedMask);
    if (exceptionMatch !== null) {
        out.isIcann = exceptionMatch.isIcann;
        out.isPrivate = exceptionMatch.isPrivate;
        out.publicSuffix = hostnameParts.slice(exceptionMatch.index + 1).join('.');
        return;
    }
    // Look for a match in rules
    const rulesMatch = lookupInTrie(hostnameParts, rules, hostnameParts.length - 1, allowedMask);
    if (rulesMatch !== null) {
        out.isIcann = rulesMatch.isIcann;
        out.isPrivate = rulesMatch.isPrivate;
        out.publicSuffix = hostnameParts.slice(rulesMatch.index).join('.');
        return;
    }
    // No match found...
    // Prevailing rule is '*' so we consider the top-level domain to be the
    // public suffix of `hostname` (e.g.: 'example.org' => 'org').
    out.isIcann = false;
    out.isPrivate = false;
    out.publicSuffix = hostnameParts[hostnameParts.length - 1];
}

;// CONCATENATED MODULE: ./node_modules/.pnpm/tldts@5.6.45/node_modules/tldts/dist/es6/index.js


// For all methods but 'parse', it does not make sense to allocate an object
// every single time to only return the value of a specific attribute. To avoid
// this un-necessary allocation, we use a global object which is re-used.
const RESULT = (0,es6/* getEmptyResult */.e4)();
function parse(url, options = {}) {
    return (0,es6/* parseImpl */.kL)(url, 5 /* ALL */, suffix_trie_suffixLookup, options, (0,es6/* getEmptyResult */.e4)());
}
function getHostname(url, options = {}) {
    (0,es6/* resetResult */.a7)(RESULT);
    return (0,es6/* parseImpl */.kL)(url, 0 /* HOSTNAME */, suffix_trie_suffixLookup, options, RESULT).hostname;
}
function getPublicSuffix(url, options = {}) {
    (0,es6/* resetResult */.a7)(RESULT);
    return (0,es6/* parseImpl */.kL)(url, 2 /* PUBLIC_SUFFIX */, suffix_trie_suffixLookup, options, RESULT).publicSuffix;
}
function getDomain(url, options = {}) {
    resetResult(RESULT);
    return parseImpl(url, 3 /* DOMAIN */, suffixLookup, options, RESULT).domain;
}
function getSubdomain(url, options = {}) {
    resetResult(RESULT);
    return parseImpl(url, 4 /* SUB_DOMAIN */, suffixLookup, options, RESULT).subdomain;
}
function getDomainWithoutSuffix(url, options = {}) {
    resetResult(RESULT);
    return parseImpl(url, 5 /* ALL */, suffixLookup, options, RESULT).domainWithoutSuffix;
}


/***/ }),

/***/ 1581:
/***/ ((module, exports, __webpack_require__) => {

"use strict";


var _Object$defineProperty = __webpack_require__(3414);

var _interopRequireDefault = __webpack_require__(69598);

_Object$defineProperty(exports, "__esModule", {
  value: true
});

exports["default"] = void 0;

var _reduce = _interopRequireDefault(__webpack_require__(86983));

var _map = _interopRequireDefault(__webpack_require__(33890));

var _indexOf = _interopRequireDefault(__webpack_require__(38230));

var _concat = _interopRequireDefault(__webpack_require__(7486));

/*!
 * XRegExp.build 5.1.1
 * <xregexp.com>
 * Steven Levithan (c) 2012-present MIT License
 */
var _default = function _default(XRegExp) {
  var REGEX_DATA = 'xregexp';
  var subParts = /(\()(?!\?)|\\([1-9]\d*)|\\[\s\S]|\[(?:[^\\\]]|\\[\s\S])*\]/g;
  var parts = XRegExp.union([/\({{([\w$]+)}}\)|{{([\w$]+)}}/, subParts], 'g', {
    conjunction: 'or'
  });
  /**
   * Strips a leading `^` and trailing unescaped `$`, if both are present.
   *
   * @private
   * @param {String} pattern Pattern to process.
   * @returns {String} Pattern with edge anchors removed.
   */

  function deanchor(pattern) {
    // Allow any number of empty noncapturing groups before/after anchors, because regexes
    // built/generated by XRegExp sometimes include them
    var leadingAnchor = /^(?:\(\?:\))*\^/;
    var trailingAnchor = /\$(?:\(\?:\))*$/;

    if (leadingAnchor.test(pattern) && trailingAnchor.test(pattern) && // Ensure that the trailing `$` isn't escaped
    trailingAnchor.test(pattern.replace(/\\[\s\S]/g, ''))) {
      return pattern.replace(leadingAnchor, '').replace(trailingAnchor, '');
    }

    return pattern;
  }
  /**
   * Converts the provided value to an XRegExp. Native RegExp flags are not preserved.
   *
   * @private
   * @param {String|RegExp} value Value to convert.
   * @param {Boolean} [addFlagX] Whether to apply the `x` flag in cases when `value` is not
   *   already a regex generated by XRegExp
   * @returns {RegExp} XRegExp object with XRegExp syntax applied.
   */


  function asXRegExp(value, addFlagX) {
    var flags = addFlagX ? 'x' : '';
    return XRegExp.isRegExp(value) ? value[REGEX_DATA] && value[REGEX_DATA].captureNames ? // Don't recompile, to preserve capture names
    value : // Recompile as XRegExp
    XRegExp(value.source, flags) : // Compile string as XRegExp
    XRegExp(value, flags);
  }

  function interpolate(substitution) {
    return substitution instanceof RegExp ? substitution : XRegExp.escape(substitution);
  }

  function reduceToSubpatternsObject(subpatterns, interpolated, subpatternIndex) {
    subpatterns["subpattern".concat(subpatternIndex)] = interpolated;
    return subpatterns;
  }

  function embedSubpatternAfter(raw, subpatternIndex, rawLiterals) {
    var hasSubpattern = subpatternIndex < rawLiterals.length - 1;
    return raw + (hasSubpattern ? "{{subpattern".concat(subpatternIndex, "}}") : '');
  }
  /**
   * Provides tagged template literals that create regexes with XRegExp syntax and flags. The
   * provided pattern is handled as a raw string, so backslashes don't need to be escaped.
   *
   * Interpolation of strings and regexes shares the features of `XRegExp.build`. Interpolated
   * patterns are treated as atomic units when quantified, interpolated strings have their special
   * characters escaped, a leading `^` and trailing unescaped `$` are stripped from interpolated
   * regexes if both are present, and any backreferences within an interpolated regex are
   * rewritten to work within the overall pattern.
   *
   * @memberOf XRegExp
   * @param {String} [flags] Any combination of XRegExp flags.
   * @returns {Function} Handler for template literals that construct regexes with XRegExp syntax.
   * @example
   *
   * XRegExp.tag()`\b\w+\b`.test('word'); // -> true
   *
   * const hours = /1[0-2]|0?[1-9]/;
   * const minutes = /(?<minutes>[0-5][0-9])/;
   * const time = XRegExp.tag('x')`\b ${hours} : ${minutes} \b`;
   * time.test('10:59'); // -> true
   * XRegExp.exec('10:59', time).groups.minutes; // -> '59'
   *
   * const backref1 = /(a)\1/;
   * const backref2 = /(b)\1/;
   * XRegExp.tag()`${backref1}${backref2}`.test('aabb'); // -> true
   */


  XRegExp.tag = function (flags) {
    return function (literals) {
      var _context, _context2;

      for (var _len = arguments.length, substitutions = new Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
        substitutions[_key - 1] = arguments[_key];
      }

      var subpatterns = (0, _reduce["default"])(_context = (0, _map["default"])(substitutions).call(substitutions, interpolate)).call(_context, reduceToSubpatternsObject, {});
      var pattern = (0, _map["default"])(_context2 = literals.raw).call(_context2, embedSubpatternAfter).join('');
      return XRegExp.build(pattern, subpatterns, flags);
    };
  };
  /**
   * Builds regexes using named subpatterns, for readability and pattern reuse. Backreferences in
   * the outer pattern and provided subpatterns are automatically renumbered to work correctly.
   * Native flags used by provided subpatterns are ignored in favor of the `flags` argument.
   *
   * @memberOf XRegExp
   * @param {String} pattern XRegExp pattern using `{{name}}` for embedded subpatterns. Allows
   *   `({{name}})` as shorthand for `(?<name>{{name}})`. Patterns cannot be embedded within
   *   character classes.
   * @param {Object} subs Lookup object for named subpatterns. Values can be strings or regexes. A
   *   leading `^` and trailing unescaped `$` are stripped from subpatterns, if both are present.
   * @param {String} [flags] Any combination of XRegExp flags.
   * @returns {RegExp} Regex with interpolated subpatterns.
   * @example
   *
   * const time = XRegExp.build('(?x)^ {{hours}} ({{minutes}}) $', {
   *   hours: XRegExp.build('{{h12}} : | {{h24}}', {
   *     h12: /1[0-2]|0?[1-9]/,
   *     h24: /2[0-3]|[01][0-9]/
   *   }, 'x'),
   *   minutes: /^[0-5][0-9]$/
   * });
   * time.test('10:59'); // -> true
   * XRegExp.exec('10:59', time).groups.minutes; // -> '59'
   */


  XRegExp.build = function (pattern, subs, flags) {
    flags = flags || ''; // Used with `asXRegExp` calls for `pattern` and subpatterns in `subs`, to work around how
    // some browsers convert `RegExp('\n')` to a regex that contains the literal characters `\`
    // and `n`. See more details at <https://github.com/slevithan/xregexp/pull/163>.

    var addFlagX = (0, _indexOf["default"])(flags).call(flags, 'x') !== -1;
    var inlineFlags = /^\(\?([\w$]+)\)/.exec(pattern); // Add flags within a leading mode modifier to the overall pattern's flags

    if (inlineFlags) {
      flags = XRegExp._clipDuplicates(flags + inlineFlags[1]);
    }

    var data = {};

    for (var p in subs) {
      if (subs.hasOwnProperty(p)) {
        // Passing to XRegExp enables extended syntax and ensures independent validity,
        // lest an unescaped `(`, `)`, `[`, or trailing `\` breaks the `(?:)` wrapper. For
        // subpatterns provided as native regexes, it dies on octals and adds the property
        // used to hold extended regex instance data, for simplicity.
        var sub = asXRegExp(subs[p], addFlagX);
        data[p] = {
          // Deanchoring allows embedding independently useful anchored regexes. If you
          // really need to keep your anchors, double them (i.e., `^^...$$`).
          pattern: deanchor(sub.source),
          names: sub[REGEX_DATA].captureNames || []
        };
      }
    } // Passing to XRegExp dies on octals and ensures the outer pattern is independently valid;
    // helps keep this simple. Named captures will be put back.


    var patternAsRegex = asXRegExp(pattern, addFlagX); // 'Caps' is short for 'captures'

    var numCaps = 0;
    var numPriorCaps;
    var numOuterCaps = 0;
    var outerCapsMap = [0];
    var outerCapNames = patternAsRegex[REGEX_DATA].captureNames || [];
    var output = patternAsRegex.source.replace(parts, function ($0, $1, $2, $3, $4) {
      var subName = $1 || $2;
      var capName;
      var intro;
      var localCapIndex; // Named subpattern

      if (subName) {
        var _context3;

        if (!data.hasOwnProperty(subName)) {
          throw new ReferenceError("Undefined property ".concat($0));
        } // Named subpattern was wrapped in a capturing group


        if ($1) {
          capName = outerCapNames[numOuterCaps];
          outerCapsMap[++numOuterCaps] = ++numCaps; // If it's a named group, preserve the name. Otherwise, use the subpattern name
          // as the capture name

          intro = "(?<".concat(capName || subName, ">");
        } else {
          intro = '(?:';
        }

        numPriorCaps = numCaps;
        var rewrittenSubpattern = data[subName].pattern.replace(subParts, function (match, paren, backref) {
          // Capturing group
          if (paren) {
            capName = data[subName].names[numCaps - numPriorCaps];
            ++numCaps; // If the current capture has a name, preserve the name

            if (capName) {
              return "(?<".concat(capName, ">");
            } // Backreference

          } else if (backref) {
            localCapIndex = +backref - 1; // Rewrite the backreference

            return data[subName].names[localCapIndex] ? // Need to preserve the backreference name in case using flag `n`
            "\\k<".concat(data[subName].names[localCapIndex], ">") : "\\".concat(+backref + numPriorCaps);
          }

          return match;
        });
        return (0, _concat["default"])(_context3 = "".concat(intro)).call(_context3, rewrittenSubpattern, ")");
      } // Capturing group


      if ($3) {
        capName = outerCapNames[numOuterCaps];
        outerCapsMap[++numOuterCaps] = ++numCaps; // If the current capture has a name, preserve the name

        if (capName) {
          return "(?<".concat(capName, ">");
        } // Backreference

      } else if ($4) {
        localCapIndex = +$4 - 1; // Rewrite the backreference

        return outerCapNames[localCapIndex] ? // Need to preserve the backreference name in case using flag `n`
        "\\k<".concat(outerCapNames[localCapIndex], ">") : "\\".concat(outerCapsMap[+$4]);
      }

      return $0;
    });
    return XRegExp(output, flags);
  };
};

exports["default"] = _default;
module.exports = exports.default;

/***/ }),

/***/ 11554:
/***/ ((module, exports, __webpack_require__) => {

"use strict";


var _Object$defineProperty = __webpack_require__(3414);

var _interopRequireDefault = __webpack_require__(69598);

_Object$defineProperty(exports, "__esModule", {
  value: true
});

exports["default"] = void 0;

var _indexOf = _interopRequireDefault(__webpack_require__(38230));

var _concat = _interopRequireDefault(__webpack_require__(7486));

var _slice = _interopRequireDefault(__webpack_require__(8300));

/*!
 * XRegExp.matchRecursive 5.1.1
 * <xregexp.com>
 * Steven Levithan (c) 2009-present MIT License
 */
var _default = function _default(XRegExp) {
  /**
   * Returns a match detail object composed of the provided values.
   *
   * @private
   */
  function row(name, value, start, end) {
    return {
      name: name,
      value: value,
      start: start,
      end: end
    };
  }
  /**
   * Returns an array of match strings between outermost left and right delimiters, or an array of
   * objects with detailed match parts and position data. By default, an error is thrown if
   * delimiters are unbalanced within the subject string.
   *
   * @memberOf XRegExp
   * @param {String} str String to search.
   * @param {String} left Left delimiter as an XRegExp pattern.
   * @param {String} right Right delimiter as an XRegExp pattern.
   * @param {String} [flags] Any combination of XRegExp flags, used for the left and right delimiters.
   * @param {Object} [options] Options object with optional properties:
   *   - `valueNames` {Array} Providing `valueNames` changes the return value from an array of
   *     matched strings to an array of objects that provide the value and start/end positions
   *     for the matched strings as well as the matched delimiters and unmatched string segments.
   *     To use this extended information mode, provide an array of 4 strings that name the parts
   *     to be returned:
   *     1. String segments outside of (before, between, and after) matches.
   *     2. Matched outermost left delimiters.
   *     3. Matched text between the outermost left and right delimiters.
   *     4. Matched outermost right delimiters.
   *     Taken together, these parts include the entire subject string if used with flag g.
   *     Use `null` for any of these values to omit unneeded parts from the returned results.
   *   - `escapeChar` {String} Single char used to escape delimiters within the subject string.
   *   - `unbalanced` {String} Handling mode for unbalanced delimiters. Options are:
   *     - 'error' - throw (default)
   *     - 'skip' - unbalanced delimiters are treated as part of the text between delimiters, and
   *       searches continue at the end of the unbalanced delimiter.
   *     - 'skip-lazy' - unbalanced delimiters are treated as part of the text between delimiters,
   *       and searches continue one character after the start of the unbalanced delimiter.
   * @returns {Array} Array of matches, or an empty array.
   * @example
   *
   * // Basic usage
   * const str1 = '(t((e))s)t()(ing)';
   * XRegExp.matchRecursive(str1, '\\(', '\\)', 'g');
   * // -> ['t((e))s', '', 'ing']
   *
   * // Extended information mode with valueNames
   * const str2 = 'Here is <div> <div>an</div></div> example';
   * XRegExp.matchRecursive(str2, '<div\\s*>', '</div>', 'gi', {
   *   valueNames: ['between', 'left', 'match', 'right']
   * });
   * // -> [
   * // {name: 'between', value: 'Here is ',       start: 0,  end: 8},
   * // {name: 'left',    value: '<div>',          start: 8,  end: 13},
   * // {name: 'match',   value: ' <div>an</div>', start: 13, end: 27},
   * // {name: 'right',   value: '</div>',         start: 27, end: 33},
   * // {name: 'between', value: ' example',       start: 33, end: 41}
   * // ]
   *
   * // Omitting unneeded parts with null valueNames, and using escapeChar
   * const str3 = '...{1}.\\{{function(x,y){return {y:x}}}';
   * XRegExp.matchRecursive(str3, '{', '}', 'g', {
   *   valueNames: ['literal', null, 'value', null],
   *   escapeChar: '\\'
   * });
   * // -> [
   * // {name: 'literal', value: '...',  start: 0, end: 3},
   * // {name: 'value',   value: '1',    start: 4, end: 5},
   * // {name: 'literal', value: '.\\{', start: 6, end: 9},
   * // {name: 'value',   value: 'function(x,y){return {y:x}}', start: 10, end: 37}
   * // ]
   *
   * // Sticky mode via flag y
   * const str4 = '<1><<<2>>><3>4<5>';
   * XRegExp.matchRecursive(str4, '<', '>', 'gy');
   * // -> ['1', '<<2>>', '3']
   *
   * // Skipping unbalanced delimiters instead of erroring
   * const str5 = 'Here is <div> <div>an</div> unbalanced example';
   * XRegExp.matchRecursive(str5, '<div\\s*>', '</div>', 'gi', {
   *     unbalanced: 'skip'
   * });
   * // -> ['an']
   */


  XRegExp.matchRecursive = function (str, left, right, flags, options) {
    flags = flags || '';
    options = options || {};
    var global = (0, _indexOf["default"])(flags).call(flags, 'g') !== -1;
    var sticky = (0, _indexOf["default"])(flags).call(flags, 'y') !== -1; // Flag `y` is handled manually

    var basicFlags = flags.replace(/y/g, '');
    left = XRegExp(left, basicFlags);
    right = XRegExp(right, basicFlags);
    var esc;
    var _options = options,
        escapeChar = _options.escapeChar;

    if (escapeChar) {
      var _context, _context2;

      if (escapeChar.length > 1) {
        throw new Error('Cannot use more than one escape character');
      }

      escapeChar = XRegExp.escape(escapeChar); // Example of concatenated `esc` regex:
      // `escapeChar`: '%'
      // `left`: '<'
      // `right`: '>'
      // Regex is: /(?:%[\S\s]|(?:(?!<|>)[^%])+)+/

      esc = new RegExp((0, _concat["default"])(_context = (0, _concat["default"])(_context2 = "(?:".concat(escapeChar, "[\\S\\s]|(?:(?!")).call(_context2, // Using `XRegExp.union` safely rewrites backreferences in `left` and `right`.
      // Intentionally not passing `basicFlags` to `XRegExp.union` since any syntax
      // transformation resulting from those flags was already applied to `left` and
      // `right` when they were passed through the XRegExp constructor above.
      XRegExp.union([left, right], '', {
        conjunction: 'or'
      }).source, ")[^")).call(_context, escapeChar, "])+)+"), // Flags `dgy` not needed here
      flags.replace(XRegExp._hasNativeFlag('s') ? /[^imsu]/g : /[^imu]/g, ''));
    }

    var openTokens = 0;
    var delimStart = 0;
    var delimEnd = 0;
    var lastOuterEnd = 0;
    var outerStart;
    var innerStart;
    var leftMatch;
    var rightMatch;
    var vN = options.valueNames;
    var output = [];

    while (true) {
      // If using an escape character, advance to the delimiter's next starting position,
      // skipping any escaped characters in between
      if (escapeChar) {
        delimEnd += (XRegExp.exec(str, esc, delimEnd, 'sticky') || [''])[0].length;
      }

      leftMatch = XRegExp.exec(str, left, delimEnd);
      rightMatch = XRegExp.exec(str, right, delimEnd); // Keep the leftmost match only

      if (leftMatch && rightMatch) {
        if (leftMatch.index <= rightMatch.index) {
          rightMatch = null;
        } else {
          leftMatch = null;
        }
      } // Paths (LM: leftMatch, RM: rightMatch, OT: openTokens):
      // LM | RM | OT | Result
      // 1  | 0  | 1  | loop
      // 1  | 0  | 0  | loop
      // 0  | 1  | 1  | loop
      // 0  | 1  | 0  | throw
      // 0  | 0  | 1  | throw
      // 0  | 0  | 0  | break
      // The paths above don't include the sticky mode special case. The loop ends after the
      // first completed match if not `global`.


      if (leftMatch || rightMatch) {
        delimStart = (leftMatch || rightMatch).index;
        delimEnd = delimStart + (leftMatch || rightMatch)[0].length;
      } else if (!openTokens) {
        break;
      }

      if (sticky && !openTokens && delimStart > lastOuterEnd) {
        break;
      }

      if (leftMatch) {
        if (!openTokens) {
          outerStart = delimStart;
          innerStart = delimEnd;
        }

        openTokens += 1;
      } else if (rightMatch && openTokens) {
        openTokens -= 1;

        if (!openTokens) {
          if (vN) {
            if (vN[0] && outerStart > lastOuterEnd) {
              output.push(row(vN[0], (0, _slice["default"])(str).call(str, lastOuterEnd, outerStart), lastOuterEnd, outerStart));
            }

            if (vN[1]) {
              output.push(row(vN[1], (0, _slice["default"])(str).call(str, outerStart, innerStart), outerStart, innerStart));
            }

            if (vN[2]) {
              output.push(row(vN[2], (0, _slice["default"])(str).call(str, innerStart, delimStart), innerStart, delimStart));
            }

            if (vN[3]) {
              output.push(row(vN[3], (0, _slice["default"])(str).call(str, delimStart, delimEnd), delimStart, delimEnd));
            }
          } else {
            output.push((0, _slice["default"])(str).call(str, innerStart, delimStart));
          }

          lastOuterEnd = delimEnd;

          if (!global) {
            break;
          }
        } // Found unbalanced delimiter

      } else {
        var unbalanced = options.unbalanced || 'error';

        if (unbalanced === 'skip' || unbalanced === 'skip-lazy') {
          if (rightMatch) {
            rightMatch = null; // No `leftMatch` for unbalanced left delimiter because we've reached the string end
          } else {
            if (unbalanced === 'skip') {
              var outerStartDelimLength = XRegExp.exec(str, left, outerStart, 'sticky')[0].length;
              delimEnd = outerStart + (outerStartDelimLength || 1);
            } else {
              delimEnd = outerStart + 1;
            }

            openTokens = 0;
          }
        } else if (unbalanced === 'error') {
          var _context3;

          var delimSide = rightMatch ? 'right' : 'left';
          var errorPos = rightMatch ? delimStart : outerStart;
          throw new Error((0, _concat["default"])(_context3 = "Unbalanced ".concat(delimSide, " delimiter found in string at position ")).call(_context3, errorPos));
        } else {
          throw new Error("Unsupported value for unbalanced: ".concat(unbalanced));
        }
      } // If the delimiter matched an empty string, avoid an infinite loop


      if (delimStart === delimEnd) {
        delimEnd += 1;
      }
    }

    if (global && output.length > 0 && !sticky && vN && vN[0] && str.length > lastOuterEnd) {
      output.push(row(vN[0], (0, _slice["default"])(str).call(str, lastOuterEnd), lastOuterEnd, str.length));
    }

    return output;
  };
};

exports["default"] = _default;
module.exports = exports.default;

/***/ }),

/***/ 63466:
/***/ ((module, exports, __webpack_require__) => {

"use strict";


var _sliceInstanceProperty = __webpack_require__(8300);

var _Array$from = __webpack_require__(83820);

var _Symbol = __webpack_require__(39189);

var _getIteratorMethod = __webpack_require__(82219);

var _Array$isArray = __webpack_require__(32454);

var _Object$defineProperty = __webpack_require__(3414);

var _interopRequireDefault = __webpack_require__(69598);

_Object$defineProperty(exports, "__esModule", {
  value: true
});

exports["default"] = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(1153));

var _forEach = _interopRequireDefault(__webpack_require__(56663));

var _concat = _interopRequireDefault(__webpack_require__(7486));

var _indexOf = _interopRequireDefault(__webpack_require__(38230));

function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof _Symbol !== "undefined" && _getIteratorMethod(o) || o["@@iterator"]; if (!it) { if (_Array$isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }

function _unsupportedIterableToArray(o, minLen) { var _context4; if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = _sliceInstanceProperty(_context4 = Object.prototype.toString.call(o)).call(_context4, 8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return _Array$from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }

function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }

/*!
 * XRegExp Unicode Base 5.1.1
 * <xregexp.com>
 * Steven Levithan (c) 2008-present MIT License
 */
var _default = function _default(XRegExp) {
  /**
   * Adds base support for Unicode matching:
   * - Adds syntax `\p{..}` for matching Unicode tokens. Tokens can be inverted using `\P{..}` or
   *   `\p{^..}`. Token names ignore case, spaces, hyphens, and underscores. You can omit the
   *   braces for token names that are a single letter (e.g. `\pL` or `PL`).
   * - Adds flag A (astral), which enables 21-bit Unicode support.
   * - Adds the `XRegExp.addUnicodeData` method used by other addons to provide character data.
   *
   * Unicode Base relies on externally provided Unicode character data. Official addons are
   * available to provide data for Unicode categories, scripts, and properties.
   *
   * @requires XRegExp
   */
  // ==--------------------------==
  // Private stuff
  // ==--------------------------==
  // Storage for Unicode data
  var unicode = {};
  var unicodeTypes = {}; // Reuse utils

  var dec = XRegExp._dec;
  var hex = XRegExp._hex;
  var pad4 = XRegExp._pad4; // Generates a token lookup name: lowercase, with hyphens, spaces, and underscores removed

  function normalize(name) {
    return name.replace(/[- _]+/g, '').toLowerCase();
  } // Gets the decimal code of a literal code unit, \xHH, \uHHHH, or a backslash-escaped literal


  function charCode(chr) {
    var esc = /^\\[xu](.+)/.exec(chr);
    return esc ? dec(esc[1]) : chr.charCodeAt(chr[0] === '\\' ? 1 : 0);
  } // Inverts a list of ordered BMP characters and ranges


  function invertBmp(range) {
    var output = '';
    var lastEnd = -1;
    (0, _forEach["default"])(XRegExp).call(XRegExp, range, /(\\x..|\\u....|\\?[\s\S])(?:-(\\x..|\\u....|\\?[\s\S]))?/, function (m) {
      var start = charCode(m[1]);

      if (start > lastEnd + 1) {
        output += "\\u".concat(pad4(hex(lastEnd + 1)));

        if (start > lastEnd + 2) {
          output += "-\\u".concat(pad4(hex(start - 1)));
        }
      }

      lastEnd = charCode(m[2] || m[1]);
    });

    if (lastEnd < 0xFFFF) {
      output += "\\u".concat(pad4(hex(lastEnd + 1)));

      if (lastEnd < 0xFFFE) {
        output += '-\\uFFFF';
      }
    }

    return output;
  } // Generates an inverted BMP range on first use


  function cacheInvertedBmp(slug) {
    var prop = 'b!';
    return unicode[slug][prop] || (unicode[slug][prop] = invertBmp(unicode[slug].bmp));
  } // Combines and optionally negates BMP and astral data


  function buildAstral(slug, isNegated) {
    var item = unicode[slug];
    var combined = '';

    if (item.bmp && !item.isBmpLast) {
      var _context;

      combined = (0, _concat["default"])(_context = "[".concat(item.bmp, "]")).call(_context, item.astral ? '|' : '');
    }

    if (item.astral) {
      combined += item.astral;
    }

    if (item.isBmpLast && item.bmp) {
      var _context2;

      combined += (0, _concat["default"])(_context2 = "".concat(item.astral ? '|' : '', "[")).call(_context2, item.bmp, "]");
    } // Astral Unicode tokens always match a code point, never a code unit


    return isNegated ? "(?:(?!".concat(combined, ")(?:[\uD800-\uDBFF][\uDC00-\uDFFF]|[\0-\uFFFF]))") : "(?:".concat(combined, ")");
  } // Builds a complete astral pattern on first use


  function cacheAstral(slug, isNegated) {
    var prop = isNegated ? 'a!' : 'a=';
    return unicode[slug][prop] || (unicode[slug][prop] = buildAstral(slug, isNegated));
  } // ==--------------------------==
  // Core functionality
  // ==--------------------------==

  /*
   * Add astral mode (flag A) and Unicode token syntax: `\p{..}`, `\P{..}`, `\p{^..}`, `\pC`.
   */


  XRegExp.addToken( // Use `*` instead of `+` to avoid capturing `^` as the token name in `\p{^}`
  /\\([pP])(?:{(\^?)(?:(\w+)=)?([^}]*)}|([A-Za-z]))/, function (match, scope, flags) {
    var ERR_DOUBLE_NEG = 'Invalid double negation ';
    var ERR_UNKNOWN_NAME = 'Unknown Unicode token ';
    var ERR_UNKNOWN_REF = 'Unicode token missing data ';
    var ERR_ASTRAL_ONLY = 'Astral mode required for Unicode token ';
    var ERR_ASTRAL_IN_CLASS = 'Astral mode does not support Unicode tokens within character classes';

    var _match = (0, _slicedToArray2["default"])(match, 6),
        fullToken = _match[0],
        pPrefix = _match[1],
        caretNegation = _match[2],
        typePrefix = _match[3],
        tokenName = _match[4],
        tokenSingleCharName = _match[5]; // Negated via \P{..} or \p{^..}


    var isNegated = pPrefix === 'P' || !!caretNegation; // Switch from BMP (0-FFFF) to astral (0-10FFFF) mode via flag A

    var isAstralMode = (0, _indexOf["default"])(flags).call(flags, 'A') !== -1; // Token lookup name. Check `tokenSingleCharName` first to avoid passing `undefined`
    // via `\p{}`

    var slug = normalize(tokenSingleCharName || tokenName); // Token data object

    var item = unicode[slug];

    if (pPrefix === 'P' && caretNegation) {
      throw new SyntaxError(ERR_DOUBLE_NEG + fullToken);
    }

    if (!unicode.hasOwnProperty(slug)) {
      throw new SyntaxError(ERR_UNKNOWN_NAME + fullToken);
    }

    if (typePrefix) {
      if (!(unicodeTypes[typePrefix] && unicodeTypes[typePrefix][slug])) {
        throw new SyntaxError(ERR_UNKNOWN_NAME + fullToken);
      }
    } // Switch to the negated form of the referenced Unicode token


    if (item.inverseOf) {
      slug = normalize(item.inverseOf);

      if (!unicode.hasOwnProperty(slug)) {
        var _context3;

        throw new ReferenceError((0, _concat["default"])(_context3 = "".concat(ERR_UNKNOWN_REF + fullToken, " -> ")).call(_context3, item.inverseOf));
      }

      item = unicode[slug];
      isNegated = !isNegated;
    }

    if (!(item.bmp || isAstralMode)) {
      throw new SyntaxError(ERR_ASTRAL_ONLY + fullToken);
    }

    if (isAstralMode) {
      if (scope === 'class') {
        throw new SyntaxError(ERR_ASTRAL_IN_CLASS);
      }

      return cacheAstral(slug, isNegated);
    }

    return scope === 'class' ? isNegated ? cacheInvertedBmp(slug) : item.bmp : "".concat((isNegated ? '[^' : '[') + item.bmp, "]");
  }, {
    scope: 'all',
    optionalFlags: 'A',
    leadChar: '\\'
  });
  /**
   * Adds to the list of Unicode tokens that XRegExp regexes can match via `\p` or `\P`.
   *
   * @memberOf XRegExp
   * @param {Array} data Objects with named character ranges. Each object may have properties
   *   `name`, `alias`, `isBmpLast`, `inverseOf`, `bmp`, and `astral`. All but `name` are
   *   optional, although one of `bmp` or `astral` is required (unless `inverseOf` is set). If
   *   `astral` is absent, the `bmp` data is used for BMP and astral modes. If `bmp` is absent,
   *   the name errors in BMP mode but works in astral mode. If both `bmp` and `astral` are
   *   provided, the `bmp` data only is used in BMP mode, and the combination of `bmp` and
   *   `astral` data is used in astral mode. `isBmpLast` is needed when a token matches orphan
   *   high surrogates *and* uses surrogate pairs to match astral code points. The `bmp` and
   *   `astral` data should be a combination of literal characters and `\xHH` or `\uHHHH` escape
   *   sequences, with hyphens to create ranges. Any regex metacharacters in the data should be
   *   escaped, apart from range-creating hyphens. The `astral` data can additionally use
   *   character classes and alternation, and should use surrogate pairs to represent astral code
   *   points. `inverseOf` can be used to avoid duplicating character data if a Unicode token is
   *   defined as the exact inverse of another token.
   * @param {String} [typePrefix] Enables optionally using this type as a prefix for all of the
   *   provided Unicode tokens, e.g. if given `'Type'`, then `\p{TokenName}` can also be written
   *   as `\p{Type=TokenName}`.
   * @example
   *
   * // Basic use
   * XRegExp.addUnicodeData([{
   *   name: 'XDigit',
   *   alias: 'Hexadecimal',
   *   bmp: '0-9A-Fa-f'
   * }]);
   * XRegExp('\\p{XDigit}:\\p{Hexadecimal}+').test('0:3D'); // -> true
   */

  XRegExp.addUnicodeData = function (data, typePrefix) {
    var ERR_NO_NAME = 'Unicode token requires name';
    var ERR_NO_DATA = 'Unicode token has no character data ';

    if (typePrefix) {
      // Case sensitive to match ES2018
      unicodeTypes[typePrefix] = {};
    }

    var _iterator = _createForOfIteratorHelper(data),
        _step;

    try {
      for (_iterator.s(); !(_step = _iterator.n()).done;) {
        var item = _step.value;

        if (!item.name) {
          throw new Error(ERR_NO_NAME);
        }

        if (!(item.inverseOf || item.bmp || item.astral)) {
          throw new Error(ERR_NO_DATA + item.name);
        }

        var normalizedName = normalize(item.name);
        unicode[normalizedName] = item;

        if (typePrefix) {
          unicodeTypes[typePrefix][normalizedName] = true;
        }

        if (item.alias) {
          var normalizedAlias = normalize(item.alias);
          unicode[normalizedAlias] = item;

          if (typePrefix) {
            unicodeTypes[typePrefix][normalizedAlias] = true;
          }
        }
      } // Reset the pattern cache used by the `XRegExp` constructor, since the same pattern and
      // flags might now produce different results

    } catch (err) {
      _iterator.e(err);
    } finally {
      _iterator.f();
    }

    XRegExp.cache.flush('patterns');
  };
  /**
   * @ignore
   *
   * Return a reference to the internal Unicode definition structure for the given Unicode
   * Property if the given name is a legal Unicode Property for use in XRegExp `\p` or `\P` regex
   * constructs.
   *
   * @memberOf XRegExp
   * @param {String} name Name by which the Unicode Property may be recognized (case-insensitive),
   *   e.g. `'N'` or `'Number'`. The given name is matched against all registered Unicode
   *   Properties and Property Aliases.
   * @returns {Object} Reference to definition structure when the name matches a Unicode Property.
   *
   * @note
   * For more info on Unicode Properties, see also http://unicode.org/reports/tr18/#Categories.
   *
   * @note
   * This method is *not* part of the officially documented API and may change or be removed in
   * the future. It is meant for userland code that wishes to reuse the (large) internal Unicode
   * structures set up by XRegExp.
   */


  XRegExp._getUnicodeProperty = function (name) {
    var slug = normalize(name);
    return unicode[slug];
  };
};

exports["default"] = _default;
module.exports = exports.default;

/***/ }),

/***/ 8091:
/***/ ((module, exports, __webpack_require__) => {

"use strict";


var _Object$defineProperty = __webpack_require__(3414);

var _interopRequireDefault = __webpack_require__(69598);

_Object$defineProperty(exports, "__esModule", {
  value: true
});

exports["default"] = void 0;

var _categories = _interopRequireDefault(__webpack_require__(33082));

/*!
 * XRegExp Unicode Categories 5.1.1
 * <xregexp.com>
 * Steven Levithan (c) 2010-present MIT License
 * Unicode data by Mathias Bynens <mathiasbynens.be>
 */
var _default = function _default(XRegExp) {
  /**
   * Adds support for Unicode's general categories. E.g., `\p{Lu}` or `\p{Uppercase Letter}`. See
   * category descriptions in UAX #44 <http://unicode.org/reports/tr44/#GC_Values_Table>. Token
   * names are case insensitive, and any spaces, hyphens, and underscores are ignored.
   *
   * Uses Unicode 14.0.0.
   *
   * @requires XRegExp, Unicode Base
   */
  if (!XRegExp.addUnicodeData) {
    throw new ReferenceError('Unicode Base must be loaded before Unicode Categories');
  }

  XRegExp.addUnicodeData(_categories["default"]);
};

exports["default"] = _default;
module.exports = exports.default;

/***/ }),

/***/ 34093:
/***/ ((module, exports, __webpack_require__) => {

"use strict";


var _Object$defineProperty = __webpack_require__(3414);

var _interopRequireDefault = __webpack_require__(69598);

_Object$defineProperty(exports, "__esModule", {
  value: true
});

exports["default"] = void 0;

var _properties = _interopRequireDefault(__webpack_require__(54709));

/*!
 * XRegExp Unicode Properties 5.1.1
 * <xregexp.com>
 * Steven Levithan (c) 2012-present MIT License
 * Unicode data by Mathias Bynens <mathiasbynens.be>
 */
var _default = function _default(XRegExp) {
  /**
   * Adds properties to meet the UTS #18 Level 1 RL1.2 requirements for Unicode regex support. See
   * <http://unicode.org/reports/tr18/#RL1.2>. Following are definitions of these properties from
   * UAX #44 <http://unicode.org/reports/tr44/>:
   *
   * - Alphabetic
   *   Characters with the Alphabetic property. Generated from: Lowercase + Uppercase + Lt + Lm +
   *   Lo + Nl + Other_Alphabetic.
   *
   * - Default_Ignorable_Code_Point
   *   For programmatic determination of default ignorable code points. New characters that should
   *   be ignored in rendering (unless explicitly supported) will be assigned in these ranges,
   *   permitting programs to correctly handle the default rendering of such characters when not
   *   otherwise supported.
   *
   * - Lowercase
   *   Characters with the Lowercase property. Generated from: Ll + Other_Lowercase.
   *
   * - Noncharacter_Code_Point
   *   Code points permanently reserved for internal use.
   *
   * - Uppercase
   *   Characters with the Uppercase property. Generated from: Lu + Other_Uppercase.
   *
   * - White_Space
   *   Spaces, separator characters and other control characters which should be treated by
   *   programming languages as "white space" for the purpose of parsing elements.
   *
   * The properties ASCII, Any, and Assigned are also included but are not defined in UAX #44. UTS
   * #18 RL1.2 additionally requires support for Unicode scripts and general categories. These are
   * included in XRegExp's Unicode Categories and Unicode Scripts addons.
   *
   * Token names are case insensitive, and any spaces, hyphens, and underscores are ignored.
   *
   * Uses Unicode 14.0.0.
   *
   * @requires XRegExp, Unicode Base
   */
  if (!XRegExp.addUnicodeData) {
    throw new ReferenceError('Unicode Base must be loaded before Unicode Properties');
  }

  var unicodeData = _properties["default"]; // Add non-generated data

  unicodeData.push({
    name: 'Assigned',
    // Since this is defined as the inverse of Unicode category Cn (Unassigned), the Unicode
    // Categories addon is required to use this property
    inverseOf: 'Cn'
  });
  XRegExp.addUnicodeData(unicodeData);
};

exports["default"] = _default;
module.exports = exports.default;

/***/ }),

/***/ 51715:
/***/ ((module, exports, __webpack_require__) => {

"use strict";


var _Object$defineProperty = __webpack_require__(3414);

var _interopRequireDefault = __webpack_require__(69598);

_Object$defineProperty(exports, "__esModule", {
  value: true
});

exports["default"] = void 0;

var _scripts = _interopRequireDefault(__webpack_require__(36749));

/*!
 * XRegExp Unicode Scripts 5.1.1
 * <xregexp.com>
 * Steven Levithan (c) 2010-present MIT License
 * Unicode data by Mathias Bynens <mathiasbynens.be>
 */
var _default = function _default(XRegExp) {
  /**
   * Adds support for all Unicode scripts. E.g., `\p{Latin}`. Token names are case insensitive,
   * and any spaces, hyphens, and underscores are ignored.
   *
   * Uses Unicode 14.0.0.
   *
   * @requires XRegExp, Unicode Base
   */
  if (!XRegExp.addUnicodeData) {
    throw new ReferenceError('Unicode Base must be loaded before Unicode Scripts');
  }

  XRegExp.addUnicodeData(_scripts["default"], 'Script');
};

exports["default"] = _default;
module.exports = exports.default;

/***/ }),

/***/ 86378:
/***/ ((module, exports, __webpack_require__) => {

"use strict";


var _Object$defineProperty = __webpack_require__(3414);

var _interopRequireDefault = __webpack_require__(69598);

_Object$defineProperty(exports, "__esModule", {
  value: true
});

exports["default"] = void 0;

var _xregexp = _interopRequireDefault(__webpack_require__(32858));

var _build = _interopRequireDefault(__webpack_require__(1581));

var _matchrecursive = _interopRequireDefault(__webpack_require__(11554));

var _unicodeBase = _interopRequireDefault(__webpack_require__(63466));

var _unicodeCategories = _interopRequireDefault(__webpack_require__(8091));

var _unicodeProperties = _interopRequireDefault(__webpack_require__(34093));

var _unicodeScripts = _interopRequireDefault(__webpack_require__(51715));

(0, _build["default"])(_xregexp["default"]);
(0, _matchrecursive["default"])(_xregexp["default"]);
(0, _unicodeBase["default"])(_xregexp["default"]);
(0, _unicodeCategories["default"])(_xregexp["default"]);
(0, _unicodeProperties["default"])(_xregexp["default"]);
(0, _unicodeScripts["default"])(_xregexp["default"]);
var _default = _xregexp["default"];
exports["default"] = _default;
module.exports = exports.default;

/***/ }),

/***/ 32858:
/***/ ((module, exports, __webpack_require__) => {

"use strict";


var _sliceInstanceProperty2 = __webpack_require__(8300);

var _Array$from = __webpack_require__(83820);

var _Symbol = __webpack_require__(39189);

var _getIteratorMethod = __webpack_require__(82219);

var _Array$isArray = __webpack_require__(32454);

var _Object$defineProperty = __webpack_require__(3414);

var _interopRequireDefault = __webpack_require__(69598);

_Object$defineProperty(exports, "__esModule", {
  value: true
});

exports["default"] = void 0;

var _slicedToArray2 = _interopRequireDefault(__webpack_require__(1153));

var _flags = _interopRequireDefault(__webpack_require__(47415));

var _sort = _interopRequireDefault(__webpack_require__(80469));

var _slice = _interopRequireDefault(__webpack_require__(8300));

var _parseInt2 = _interopRequireDefault(__webpack_require__(56728));

var _indexOf = _interopRequireDefault(__webpack_require__(38230));

var _forEach = _interopRequireDefault(__webpack_require__(56663));

var _create = _interopRequireDefault(__webpack_require__(38767));

var _concat = _interopRequireDefault(__webpack_require__(7486));

function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof _Symbol !== "undefined" && _getIteratorMethod(o) || o["@@iterator"]; if (!it) { if (_Array$isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }

function _unsupportedIterableToArray(o, minLen) { var _context9; if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = _sliceInstanceProperty2(_context9 = Object.prototype.toString.call(o)).call(_context9, 8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return _Array$from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }

function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }

/*!
 * XRegExp 5.1.1
 * <xregexp.com>
 * Steven Levithan (c) 2007-present MIT License
 */

/**
 * XRegExp provides augmented, extensible regular expressions. You get additional regex syntax and
 * flags, beyond what browsers support natively. XRegExp is also a regex utility belt with tools to
 * make your client-side grepping simpler and more powerful, while freeing you from related
 * cross-browser inconsistencies.
 */
// ==--------------------------==
// Private stuff
// ==--------------------------==
// Property name used for extended regex instance data
var REGEX_DATA = 'xregexp'; // Optional features that can be installed and uninstalled

var features = {
  astral: false,
  namespacing: true
}; // Storage for fixed/extended native methods

var fixed = {}; // Storage for regexes cached by `XRegExp.cache`

var regexCache = {}; // Storage for pattern details cached by the `XRegExp` constructor

var patternCache = {}; // Storage for regex syntax tokens added internally or by `XRegExp.addToken`

var tokens = []; // Token scopes

var defaultScope = 'default';
var classScope = 'class'; // Regexes that match native regex syntax, including octals

var nativeTokens = {
  // Any native multicharacter token in default scope, or any single character
  'default': /\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9]\d*|x[\dA-Fa-f]{2}|u(?:[\dA-Fa-f]{4}|{[\dA-Fa-f]+})|c[A-Za-z]|[\s\S])|\(\?(?:[:=!]|<[=!])|[?*+]\?|{\d+(?:,\d*)?}\??|[\s\S]/,
  // Any native multicharacter token in character class scope, or any single character
  'class': /\\(?:[0-3][0-7]{0,2}|[4-7][0-7]?|x[\dA-Fa-f]{2}|u(?:[\dA-Fa-f]{4}|{[\dA-Fa-f]+})|c[A-Za-z]|[\s\S])|[\s\S]/
}; // Any backreference or dollar-prefixed character in replacement strings

var replacementToken = /\$(?:\{([^\}]+)\}|<([^>]+)>|(\d\d?|[\s\S]?))/g; // Check for correct `exec` handling of nonparticipating capturing groups

var correctExecNpcg = /()??/.exec('')[1] === undefined; // Check for ES6 `flags` prop support

var hasFlagsProp = (0, _flags["default"])(/x/) !== undefined;

function hasNativeFlag(flag) {
  // Can't check based on the presence of properties/getters since browsers might support such
  // properties even when they don't support the corresponding flag in regex construction (tested
  // in Chrome 48, where `'unicode' in /x/` is true but trying to construct a regex with flag `u`
  // throws an error)
  var isSupported = true;

  try {
    // Can't use regex literals for testing even in a `try` because regex literals with
    // unsupported flags cause a compilation error in IE
    new RegExp('', flag); // Work around a broken/incomplete IE11 polyfill for sticky introduced in core-js 3.6.0

    if (flag === 'y') {
      // Using function to avoid babel transform to regex literal
      var gy = function () {
        return 'gy';
      }();

      var incompleteY = '.a'.replace(new RegExp('a', gy), '.') === '..';

      if (incompleteY) {
        isSupported = false;
      }
    }
  } catch (exception) {
    isSupported = false;
  }

  return isSupported;
} // Check for ES2021 `d` flag support


var hasNativeD = hasNativeFlag('d'); // Check for ES2018 `s` flag support

var hasNativeS = hasNativeFlag('s'); // Check for ES6 `u` flag support

var hasNativeU = hasNativeFlag('u'); // Check for ES6 `y` flag support

var hasNativeY = hasNativeFlag('y'); // Tracker for known flags, including addon flags

var registeredFlags = {
  d: hasNativeD,
  g: true,
  i: true,
  m: true,
  s: hasNativeS,
  u: hasNativeU,
  y: hasNativeY
}; // Flags to remove when passing to native `RegExp` constructor

var nonnativeFlags = hasNativeS ? /[^dgimsuy]+/g : /[^dgimuy]+/g;
/**
 * Attaches extended data and `XRegExp.prototype` properties to a regex object.
 *
 * @private
 * @param {RegExp} regex Regex to augment.
 * @param {Array} captureNames Array with capture names, or `null`.
 * @param {String} xSource XRegExp pattern used to generate `regex`, or `null` if N/A.
 * @param {String} xFlags XRegExp flags used to generate `regex`, or `null` if N/A.
 * @param {Boolean} [isInternalOnly=false] Whether the regex will be used only for internal
 *   operations, and never exposed to users. For internal-only regexes, we can improve perf by
 *   skipping some operations like attaching `XRegExp.prototype` properties.
 * @returns {!RegExp} Augmented regex.
 */

function augment(regex, captureNames, xSource, xFlags, isInternalOnly) {
  var _context;

  regex[REGEX_DATA] = {
    captureNames: captureNames
  };

  if (isInternalOnly) {
    return regex;
  } // Can't auto-inherit these since the XRegExp constructor returns a nonprimitive value


  if (regex.__proto__) {
    regex.__proto__ = XRegExp.prototype;
  } else {
    for (var p in XRegExp.prototype) {
      // An `XRegExp.prototype.hasOwnProperty(p)` check wouldn't be worth it here, since this
      // is performance sensitive, and enumerable `Object.prototype` or `RegExp.prototype`
      // extensions exist on `regex.prototype` anyway
      regex[p] = XRegExp.prototype[p];
    }
  }

  regex[REGEX_DATA].source = xSource; // Emulate the ES6 `flags` prop by ensuring flags are in alphabetical order

  regex[REGEX_DATA].flags = xFlags ? (0, _sort["default"])(_context = xFlags.split('')).call(_context).join('') : xFlags;
  return regex;
}
/**
 * Removes any duplicate characters from the provided string.
 *
 * @private
 * @param {String} str String to remove duplicate characters from.
 * @returns {string} String with any duplicate characters removed.
 */


function clipDuplicates(str) {
  return str.replace(/([\s\S])(?=[\s\S]*\1)/g, '');
}
/**
 * Copies a regex object while preserving extended data and augmenting with `XRegExp.prototype`
 * properties. The copy has a fresh `lastIndex` property (set to zero). Allows adding and removing
 * flags g and y while copying the regex.
 *
 * @private
 * @param {RegExp} regex Regex to copy.
 * @param {Object} [options] Options object with optional properties:
 *   - `addG` {Boolean} Add flag g while copying the regex.
 *   - `addY` {Boolean} Add flag y while copying the regex.
 *   - `removeG` {Boolean} Remove flag g while copying the regex.
 *   - `removeY` {Boolean} Remove flag y while copying the regex.
 *   - `isInternalOnly` {Boolean} Whether the copied regex will be used only for internal
 *     operations, and never exposed to users. For internal-only regexes, we can improve perf by
 *     skipping some operations like attaching `XRegExp.prototype` properties.
 *   - `source` {String} Overrides `<regex>.source`, for special cases.
 * @returns {RegExp} Copy of the provided regex, possibly with modified flags.
 */


function copyRegex(regex, options) {
  var _context2;

  if (!XRegExp.isRegExp(regex)) {
    throw new TypeError('Type RegExp expected');
  }

  var xData = regex[REGEX_DATA] || {};
  var flags = getNativeFlags(regex);
  var flagsToAdd = '';
  var flagsToRemove = '';
  var xregexpSource = null;
  var xregexpFlags = null;
  options = options || {};

  if (options.removeG) {
    flagsToRemove += 'g';
  }

  if (options.removeY) {
    flagsToRemove += 'y';
  }

  if (flagsToRemove) {
    flags = flags.replace(new RegExp("[".concat(flagsToRemove, "]+"), 'g'), '');
  }

  if (options.addG) {
    flagsToAdd += 'g';
  }

  if (options.addY) {
    flagsToAdd += 'y';
  }

  if (flagsToAdd) {
    flags = clipDuplicates(flags + flagsToAdd);
  }

  if (!options.isInternalOnly) {
    if (xData.source !== undefined) {
      xregexpSource = xData.source;
    } // null or undefined; don't want to add to `flags` if the previous value was null, since
    // that indicates we're not tracking original precompilation flags


    if ((0, _flags["default"])(xData) != null) {
      // Flags are only added for non-internal regexes by `XRegExp.globalize`. Flags are never
      // removed for non-internal regexes, so don't need to handle it
      xregexpFlags = flagsToAdd ? clipDuplicates((0, _flags["default"])(xData) + flagsToAdd) : (0, _flags["default"])(xData);
    }
  } // Augment with `XRegExp.prototype` properties, but use the native `RegExp` constructor to avoid
  // searching for special tokens. That would be wrong for regexes constructed by `RegExp`, and
  // unnecessary for regexes constructed by `XRegExp` because the regex has already undergone the
  // translation to native regex syntax


  regex = augment(new RegExp(options.source || regex.source, flags), hasNamedCapture(regex) ? (0, _slice["default"])(_context2 = xData.captureNames).call(_context2, 0) : null, xregexpSource, xregexpFlags, options.isInternalOnly);
  return regex;
}
/**
 * Converts hexadecimal to decimal.
 *
 * @private
 * @param {String} hex
 * @returns {number}
 */


function dec(hex) {
  return (0, _parseInt2["default"])(hex, 16);
}
/**
 * Returns a pattern that can be used in a native RegExp in place of an ignorable token such as an
 * inline comment or whitespace with flag x. This is used directly as a token handler function
 * passed to `XRegExp.addToken`.
 *
 * @private
 * @param {String} match Match arg of `XRegExp.addToken` handler
 * @param {String} scope Scope arg of `XRegExp.addToken` handler
 * @param {String} flags Flags arg of `XRegExp.addToken` handler
 * @returns {string} Either '' or '(?:)', depending on which is needed in the context of the match.
 */


function getContextualTokenSeparator(match, scope, flags) {
  var matchEndPos = match.index + match[0].length;
  var precedingChar = match.input[match.index - 1];
  var followingChar = match.input[matchEndPos];

  if ( // No need to separate tokens if at the beginning or end of a group, before or after a
  // group, or before or after a `|`
  /^[()|]$/.test(precedingChar) || /^[()|]$/.test(followingChar) || // No need to separate tokens if at the beginning or end of the pattern
  match.index === 0 || matchEndPos === match.input.length || // No need to separate tokens if at the beginning of a noncapturing group or lookaround.
  // Looks only at the last 4 chars (at most) for perf when constructing long regexes.
  /\(\?(?:[:=!]|<[=!])$/.test(match.input.substring(match.index - 4, match.index)) || // Avoid separating tokens when the following token is a quantifier
  isQuantifierNext(match.input, matchEndPos, flags)) {
    return '';
  } // Keep tokens separated. This avoids e.g. inadvertedly changing `\1 1` or `\1(?#)1` to `\11`.
  // This also ensures all tokens remain as discrete atoms, e.g. it prevents converting the
  // syntax error `(? :` into `(?:`.


  return '(?:)';
}
/**
 * Returns native `RegExp` flags used by a regex object.
 *
 * @private
 * @param {RegExp} regex Regex to check.
 * @returns {string} Native flags in use.
 */


function getNativeFlags(regex) {
  return hasFlagsProp ? (0, _flags["default"])(regex) : // Explicitly using `RegExp.prototype.toString` (rather than e.g. `String` or concatenation
  // with an empty string) allows this to continue working predictably when
  // `XRegExp.proptotype.toString` is overridden
  /\/([a-z]*)$/i.exec(RegExp.prototype.toString.call(regex))[1];
}
/**
 * Determines whether a regex has extended instance data used to track capture names.
 *
 * @private
 * @param {RegExp} regex Regex to check.
 * @returns {boolean} Whether the regex uses named capture.
 */


function hasNamedCapture(regex) {
  return !!(regex[REGEX_DATA] && regex[REGEX_DATA].captureNames);
}
/**
 * Converts decimal to hexadecimal.
 *
 * @private
 * @param {Number|String} dec
 * @returns {string}
 */


function hex(dec) {
  return (0, _parseInt2["default"])(dec, 10).toString(16);
}
/**
 * Checks whether the next nonignorable token after the specified position is a quantifier.
 *
 * @private
 * @param {String} pattern Pattern to search within.
 * @param {Number} pos Index in `pattern` to search at.
 * @param {String} flags Flags used by the pattern.
 * @returns {Boolean} Whether the next nonignorable token is a quantifier.
 */


function isQuantifierNext(pattern, pos, flags) {
  var inlineCommentPattern = '\\(\\?#[^)]*\\)';
  var lineCommentPattern = '#[^#\\n]*';
  var quantifierPattern = '[?*+]|{\\d+(?:,\\d*)?}';
  var regex = (0, _indexOf["default"])(flags).call(flags, 'x') !== -1 ? // Ignore any leading whitespace, line comments, and inline comments
  /^(?:\s|#[^#\n]*|\(\?#[^)]*\))*(?:[?*+]|{\d+(?:,\d*)?})/ : // Ignore any leading inline comments
  /^(?:\(\?#[^)]*\))*(?:[?*+]|{\d+(?:,\d*)?})/;
  return regex.test((0, _slice["default"])(pattern).call(pattern, pos));
}
/**
 * Determines whether a value is of the specified type, by resolving its internal [[Class]].
 *
 * @private
 * @param {*} value Object to check.
 * @param {String} type Type to check for, in TitleCase.
 * @returns {boolean} Whether the object matches the type.
 */


function isType(value, type) {
  return Object.prototype.toString.call(value) === "[object ".concat(type, "]");
}
/**
 * Returns the object, or throws an error if it is `null` or `undefined`. This is used to follow
 * the ES5 abstract operation `ToObject`.
 *
 * @private
 * @param {*} value Object to check and return.
 * @returns {*} The provided object.
 */


function nullThrows(value) {
  // null or undefined
  if (value == null) {
    throw new TypeError('Cannot convert null or undefined to object');
  }

  return value;
}
/**
 * Adds leading zeros if shorter than four characters. Used for fixed-length hexadecimal values.
 *
 * @private
 * @param {String} str
 * @returns {string}
 */


function pad4(str) {
  while (str.length < 4) {
    str = "0".concat(str);
  }

  return str;
}
/**
 * Checks for flag-related errors, and strips/applies flags in a leading mode modifier. Offloads
 * the flag preparation logic from the `XRegExp` constructor.
 *
 * @private
 * @param {String} pattern Regex pattern, possibly with a leading mode modifier.
 * @param {String} flags Any combination of flags.
 * @returns {!Object} Object with properties `pattern` and `flags`.
 */


function prepareFlags(pattern, flags) {
  // Recent browsers throw on duplicate flags, so copy this behavior for nonnative flags
  if (clipDuplicates(flags) !== flags) {
    throw new SyntaxError("Invalid duplicate regex flag ".concat(flags));
  } // Strip and apply a leading mode modifier with any combination of flags except `dgy`


  pattern = pattern.replace(/^\(\?([\w$]+)\)/, function ($0, $1) {
    if (/[dgy]/.test($1)) {
      throw new SyntaxError("Cannot use flags dgy in mode modifier ".concat($0));
    } // Allow duplicate flags within the mode modifier


    flags = clipDuplicates(flags + $1);
    return '';
  }); // Throw on unknown native or nonnative flags

  var _iterator = _createForOfIteratorHelper(flags),
      _step;

  try {
    for (_iterator.s(); !(_step = _iterator.n()).done;) {
      var flag = _step.value;

      if (!registeredFlags[flag]) {
        throw new SyntaxError("Unknown regex flag ".concat(flag));
      }
    }
  } catch (err) {
    _iterator.e(err);
  } finally {
    _iterator.f();
  }

  return {
    pattern: pattern,
    flags: flags
  };
}
/**
 * Prepares an options object from the given value.
 *
 * @private
 * @param {String|Object} value Value to convert to an options object.
 * @returns {Object} Options object.
 */


function prepareOptions(value) {
  var options = {};

  if (isType(value, 'String')) {
    (0, _forEach["default"])(XRegExp).call(XRegExp, value, /[^\s,]+/, function (match) {
      options[match] = true;
    });
    return options;
  }

  return value;
}
/**
 * Registers a flag so it doesn't throw an 'unknown flag' error.
 *
 * @private
 * @param {String} flag Single-character flag to register.
 */


function registerFlag(flag) {
  if (!/^[\w$]$/.test(flag)) {
    throw new Error('Flag must be a single character A-Za-z0-9_$');
  }

  registeredFlags[flag] = true;
}
/**
 * Runs built-in and custom regex syntax tokens in reverse insertion order at the specified
 * position, until a match is found.
 *
 * @private
 * @param {String} pattern Original pattern from which an XRegExp object is being built.
 * @param {String} flags Flags being used to construct the regex.
 * @param {Number} pos Position to search for tokens within `pattern`.
 * @param {Number} scope Regex scope to apply: 'default' or 'class'.
 * @param {Object} context Context object to use for token handler functions.
 * @returns {Object} Object with properties `matchLength`, `output`, and `reparse`; or `null`.
 */


function runTokens(pattern, flags, pos, scope, context) {
  var i = tokens.length;
  var leadChar = pattern[pos];
  var result = null;
  var match;
  var t; // Run in reverse insertion order

  while (i--) {
    t = tokens[i];

    if (t.leadChar && t.leadChar !== leadChar || t.scope !== scope && t.scope !== 'all' || t.flag && !((0, _indexOf["default"])(flags).call(flags, t.flag) !== -1)) {
      continue;
    }

    match = XRegExp.exec(pattern, t.regex, pos, 'sticky');

    if (match) {
      result = {
        matchLength: match[0].length,
        output: t.handler.call(context, match, scope, flags),
        reparse: t.reparse
      }; // Finished with token tests

      break;
    }
  }

  return result;
}
/**
 * Enables or disables implicit astral mode opt-in. When enabled, flag A is automatically added to
 * all new regexes created by XRegExp. This causes an error to be thrown when creating regexes if
 * the Unicode Base addon is not available, since flag A is registered by that addon.
 *
 * @private
 * @param {Boolean} on `true` to enable; `false` to disable.
 */


function setAstral(on) {
  features.astral = on;
}
/**
 * Adds named capture groups to the `groups` property of match arrays. See here for details:
 * https://github.com/tc39/proposal-regexp-named-groups
 *
 * @private
 * @param {Boolean} on `true` to enable; `false` to disable.
 */


function setNamespacing(on) {
  features.namespacing = on;
} // ==--------------------------==
// Constructor
// ==--------------------------==

/**
 * Creates an extended regular expression object for matching text with a pattern. Differs from a
 * native regular expression in that additional syntax and flags are supported. The returned object
 * is in fact a native `RegExp` and works with all native methods.
 *
 * @class XRegExp
 * @constructor
 * @param {String|RegExp} pattern Regex pattern string, or an existing regex object to copy.
 * @param {String} [flags] Any combination of flags.
 *   Native flags:
 *     - `d` - indices for capturing groups (ES2021)
 *     - `g` - global
 *     - `i` - ignore case
 *     - `m` - multiline anchors
 *     - `u` - unicode (ES6)
 *     - `y` - sticky (Firefox 3+, ES6)
 *   Additional XRegExp flags:
 *     - `n` - named capture only
 *     - `s` - dot matches all (aka singleline) - works even when not natively supported
 *     - `x` - free-spacing and line comments (aka extended)
 *     - `A` - 21-bit Unicode properties (aka astral) - requires the Unicode Base addon
 *   Flags cannot be provided when constructing one `RegExp` from another.
 * @returns {RegExp} Extended regular expression object.
 * @example
 *
 * // With named capture and flag x
 * XRegExp(`(?<year>  [0-9]{4} ) -?  # year
 *          (?<month> [0-9]{2} ) -?  # month
 *          (?<day>   [0-9]{2} )     # day`, 'x');
 *
 * // Providing a regex object copies it. Native regexes are recompiled using native (not XRegExp)
 * // syntax. Copies maintain extended data, are augmented with `XRegExp.prototype` properties, and
 * // have fresh `lastIndex` properties (set to zero).
 * XRegExp(/regex/);
 */


function XRegExp(pattern, flags) {
  if (XRegExp.isRegExp(pattern)) {
    if (flags !== undefined) {
      throw new TypeError('Cannot supply flags when copying a RegExp');
    }

    return copyRegex(pattern);
  } // Copy the argument behavior of `RegExp`


  pattern = pattern === undefined ? '' : String(pattern);
  flags = flags === undefined ? '' : String(flags);

  if (XRegExp.isInstalled('astral') && !((0, _indexOf["default"])(flags).call(flags, 'A') !== -1)) {
    // This causes an error to be thrown if the Unicode Base addon is not available
    flags += 'A';
  }

  if (!patternCache[pattern]) {
    patternCache[pattern] = {};
  }

  if (!patternCache[pattern][flags]) {
    var context = {
      hasNamedCapture: false,
      captureNames: []
    };
    var scope = defaultScope;
    var output = '';
    var pos = 0;
    var result; // Check for flag-related errors, and strip/apply flags in a leading mode modifier

    var applied = prepareFlags(pattern, flags);
    var appliedPattern = applied.pattern;
    var appliedFlags = (0, _flags["default"])(applied); // Use XRegExp's tokens to translate the pattern to a native regex pattern.
    // `appliedPattern.length` may change on each iteration if tokens use `reparse`

    while (pos < appliedPattern.length) {
      do {
        // Check for custom tokens at the current position
        result = runTokens(appliedPattern, appliedFlags, pos, scope, context); // If the matched token used the `reparse` option, splice its output into the
        // pattern before running tokens again at the same position

        if (result && result.reparse) {
          appliedPattern = (0, _slice["default"])(appliedPattern).call(appliedPattern, 0, pos) + result.output + (0, _slice["default"])(appliedPattern).call(appliedPattern, pos + result.matchLength);
        }
      } while (result && result.reparse);

      if (result) {
        output += result.output;
        pos += result.matchLength || 1;
      } else {
        // Get the native token at the current position
        var _XRegExp$exec = XRegExp.exec(appliedPattern, nativeTokens[scope], pos, 'sticky'),
            _XRegExp$exec2 = (0, _slicedToArray2["default"])(_XRegExp$exec, 1),
            token = _XRegExp$exec2[0];

        output += token;
        pos += token.length;

        if (token === '[' && scope === defaultScope) {
          scope = classScope;
        } else if (token === ']' && scope === classScope) {
          scope = defaultScope;
        }
      }
    }

    patternCache[pattern][flags] = {
      // Use basic cleanup to collapse repeated empty groups like `(?:)(?:)` to `(?:)`. Empty
      // groups are sometimes inserted during regex transpilation in order to keep tokens
      // separated. However, more than one empty group in a row is never needed.
      pattern: output.replace(/(?:\(\?:\))+/g, '(?:)'),
      // Strip all but native flags
      flags: appliedFlags.replace(nonnativeFlags, ''),
      // `context.captureNames` has an item for each capturing group, even if unnamed
      captures: context.hasNamedCapture ? context.captureNames : null
    };
  }

  var generated = patternCache[pattern][flags];
  return augment(new RegExp(generated.pattern, (0, _flags["default"])(generated)), generated.captures, pattern, flags);
} // Add `RegExp.prototype` to the prototype chain


XRegExp.prototype = /(?:)/; // ==--------------------------==
// Public properties
// ==--------------------------==

/**
 * The XRegExp version number as a string containing three dot-separated parts. For example,
 * '2.0.0-beta-3'.
 *
 * @static
 * @memberOf XRegExp
 * @type String
 */

XRegExp.version = '5.1.1'; // ==--------------------------==
// Public methods
// ==--------------------------==
// Intentionally undocumented; used in tests and addons

XRegExp._clipDuplicates = clipDuplicates;
XRegExp._hasNativeFlag = hasNativeFlag;
XRegExp._dec = dec;
XRegExp._hex = hex;
XRegExp._pad4 = pad4;
/**
 * Extends XRegExp syntax and allows custom flags. This is used internally and can be used to
 * create XRegExp addons. If more than one token can match the same string, the last added wins.
 *
 * @memberOf XRegExp
 * @param {RegExp} regex Regex object that matches the new token.
 * @param {Function} handler Function that returns a new pattern string (using native regex syntax)
 *   to replace the matched token within all future XRegExp regexes. Has access to persistent
 *   properties of the regex being built, through `this`. Invoked with three arguments:
 *   - The match array, with named backreference properties.
 *   - The regex scope where the match was found: 'default' or 'class'.
 *   - The flags used by the regex, including any flags in a leading mode modifier.
 *   The handler function becomes part of the XRegExp construction process, so be careful not to
 *   construct XRegExps within the function or you will trigger infinite recursion.
 * @param {Object} [options] Options object with optional properties:
 *   - `scope` {String} Scope where the token applies: 'default', 'class', or 'all'.
 *   - `flag` {String} Single-character flag that triggers the token. This also registers the
 *     flag, which prevents XRegExp from throwing an 'unknown flag' error when the flag is used.
 *   - `optionalFlags` {String} Any custom flags checked for within the token `handler` that are
 *     not required to trigger the token. This registers the flags, to prevent XRegExp from
 *     throwing an 'unknown flag' error when any of the flags are used.
 *   - `reparse` {Boolean} Whether the `handler` function's output should not be treated as
 *     final, and instead be reparseable by other tokens (including the current token). Allows
 *     token chaining or deferring.
 *   - `leadChar` {String} Single character that occurs at the beginning of any successful match
 *     of the token (not always applicable). This doesn't change the behavior of the token unless
 *     you provide an erroneous value. However, providing it can increase the token's performance
 *     since the token can be skipped at any positions where this character doesn't appear.
 * @example
 *
 * // Basic usage: Add \a for the ALERT control code
 * XRegExp.addToken(
 *   /\\a/,
 *   () => '\\x07',
 *   {scope: 'all'}
 * );
 * XRegExp('\\a[\\a-\\n]+').test('\x07\n\x07'); // -> true
 *
 * // Add the U (ungreedy) flag from PCRE and RE2, which reverses greedy and lazy quantifiers.
 * // Since `scope` is not specified, it uses 'default' (i.e., transformations apply outside of
 * // character classes only)
 * XRegExp.addToken(
 *   /([?*+]|{\d+(?:,\d*)?})(\??)/,
 *   (match) => `${match[1]}${match[2] ? '' : '?'}`,
 *   {flag: 'U'}
 * );
 * XRegExp('a+', 'U').exec('aaa')[0]; // -> 'a'
 * XRegExp('a+?', 'U').exec('aaa')[0]; // -> 'aaa'
 */

XRegExp.addToken = function (regex, handler, options) {
  options = options || {};
  var _options = options,
      optionalFlags = _options.optionalFlags;

  if (options.flag) {
    registerFlag(options.flag);
  }

  if (optionalFlags) {
    optionalFlags = optionalFlags.split('');

    var _iterator2 = _createForOfIteratorHelper(optionalFlags),
        _step2;

    try {
      for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
        var flag = _step2.value;
        registerFlag(flag);
      }
    } catch (err) {
      _iterator2.e(err);
    } finally {
      _iterator2.f();
    }
  } // Add to the private list of syntax tokens


  tokens.push({
    regex: copyRegex(regex, {
      addG: true,
      addY: hasNativeY,
      isInternalOnly: true
    }),
    handler: handler,
    scope: options.scope || defaultScope,
    flag: options.flag,
    reparse: options.reparse,
    leadChar: options.leadChar
  }); // Reset the pattern cache used by the `XRegExp` constructor, since the same pattern and flags
  // might now produce different results

  XRegExp.cache.flush('patterns');
};
/**
 * Caches and returns the result of calling `XRegExp(pattern, flags)`. On any subsequent call with
 * the same pattern and flag combination, the cached copy of the regex is returned.
 *
 * @memberOf XRegExp
 * @param {String} pattern Regex pattern string.
 * @param {String} [flags] Any combination of XRegExp flags.
 * @returns {RegExp} Cached XRegExp object.
 * @example
 *
 * let match;
 * while (match = XRegExp.cache('.', 'gs').exec('abc')) {
 *   // The regex is compiled once only
 * }
 */


XRegExp.cache = function (pattern, flags) {
  if (!regexCache[pattern]) {
    regexCache[pattern] = {};
  }

  return regexCache[pattern][flags] || (regexCache[pattern][flags] = XRegExp(pattern, flags));
}; // Intentionally undocumented; used in tests


XRegExp.cache.flush = function (cacheName) {
  if (cacheName === 'patterns') {
    // Flush the pattern cache used by the `XRegExp` constructor
    patternCache = {};
  } else {
    // Flush the regex cache populated by `XRegExp.cache`
    regexCache = {};
  }
};
/**
 * Escapes any regular expression metacharacters, for use when matching literal strings. The result
 * can safely be used at any position within a regex that uses any flags.
 *
 * @memberOf XRegExp
 * @param {String} str String to escape.
 * @returns {string} String with regex metacharacters escaped.
 * @example
 *
 * XRegExp.escape('Escaped? <.>');
 * // -> 'Escaped\?\u0020<\.>'
 */
// Following are the contexts where each metacharacter needs to be escaped because it would
// otherwise have a special meaning, change the meaning of surrounding characters, or cause an
// error. Context 'default' means outside character classes only.
// - `\` - context: all
// - `[()*+?.$|` - context: default
// - `]` - context: default with flag u or if forming the end of a character class
// - `{}` - context: default with flag u or if part of a valid/complete quantifier pattern
// - `,` - context: default if in a position that causes an unescaped `{` to turn into a quantifier.
//   Ex: `/^a{1\,2}$/` matches `'a{1,2}'`, but `/^a{1,2}$/` matches `'a'` or `'aa'`
// - `#` and <whitespace> - context: default with flag x
// - `^` - context: default, and context: class if it's the first character in the class
// - `-` - context: class if part of a valid character class range


XRegExp.escape = function (str) {
  return String(nullThrows(str)). // Escape most special chars with a backslash
  replace(/[\\\[\]{}()*+?.^$|]/g, '\\$&'). // Convert to \uNNNN for special chars that can't be escaped when used with ES6 flag `u`
  replace(/[\s#\-,]/g, function (match) {
    return "\\u".concat(pad4(hex(match.charCodeAt(0))));
  });
};
/**
 * Executes a regex search in a specified string. Returns a match array or `null`. If the provided
 * regex uses named capture, named capture properties are included on the match array's `groups`
 * property. Optional `pos` and `sticky` arguments specify the search start position, and whether
 * the match must start at the specified position only. The `lastIndex` property of the provided
 * regex is not used, but is updated for compatibility. Also fixes browser bugs compared to the
 * native `RegExp.prototype.exec` and can be used reliably cross-browser.
 *
 * @memberOf XRegExp
 * @param {String} str String to search.
 * @param {RegExp} regex Regex to search with.
 * @param {Number} [pos=0] Zero-based index at which to start the search.
 * @param {Boolean|String} [sticky=false] Whether the match must start at the specified position
 *   only. The string `'sticky'` is accepted as an alternative to `true`.
 * @returns {Array} Match array with named capture properties on the `groups` object, or `null`. If
 *   the `namespacing` feature is off, named capture properties are directly on the match array.
 * @example
 *
 * // Basic use, with named capturing group
 * let match = XRegExp.exec('U+2620', XRegExp('U\\+(?<hex>[0-9A-F]{4})'));
 * match.groups.hex; // -> '2620'
 *
 * // With pos and sticky, in a loop
 * let pos = 3, result = [], match;
 * while (match = XRegExp.exec('<1><2><3><4>5<6>', /<(\d)>/, pos, 'sticky')) {
 *   result.push(match[1]);
 *   pos = match.index + match[0].length;
 * }
 * // result -> ['2', '3', '4']
 */


XRegExp.exec = function (str, regex, pos, sticky) {
  var cacheKey = 'g';
  var addY = false;
  var fakeY = false;
  var match;
  addY = hasNativeY && !!(sticky || regex.sticky && sticky !== false);

  if (addY) {
    cacheKey += 'y';
  } else if (sticky) {
    // Simulate sticky matching by appending an empty capture to the original regex. The
    // resulting regex will succeed no matter what at the current index (set with `lastIndex`),
    // and will not search the rest of the subject string. We'll know that the original regex
    // has failed if that last capture is `''` rather than `undefined` (i.e., if that last
    // capture participated in the match).
    fakeY = true;
    cacheKey += 'FakeY';
  }

  regex[REGEX_DATA] = regex[REGEX_DATA] || {}; // Shares cached copies with `XRegExp.match`/`replace`

  var r2 = regex[REGEX_DATA][cacheKey] || (regex[REGEX_DATA][cacheKey] = copyRegex(regex, {
    addG: true,
    addY: addY,
    source: fakeY ? "".concat(regex.source, "|()") : undefined,
    removeY: sticky === false,
    isInternalOnly: true
  }));
  pos = pos || 0;
  r2.lastIndex = pos; // Fixed `exec` required for `lastIndex` fix, named backreferences, etc.

  match = fixed.exec.call(r2, str); // Get rid of the capture added by the pseudo-sticky matcher if needed. An empty string means
  // the original regexp failed (see above).

  if (fakeY && match && match.pop() === '') {
    match = null;
  }

  if (regex.global) {
    regex.lastIndex = match ? r2.lastIndex : 0;
  }

  return match;
};
/**
 * Executes a provided function once per regex match. Searches always start at the beginning of the
 * string and continue until the end, regardless of the state of the regex's `global` property and
 * initial `lastIndex`.
 *
 * @memberOf XRegExp
 * @param {String} str String to search.
 * @param {RegExp} regex Regex to search with.
 * @param {Function} callback Function to execute for each match. Invoked with four arguments:
 *   - The match array, with named backreference properties.
 *   - The zero-based match index.
 *   - The string being traversed.
 *   - The regex object being used to traverse the string.
 * @example
 *
 * // Extracts every other digit from a string
 * const evens = [];
 * XRegExp.forEach('1a2345', /\d/, (match, i) => {
 *   if (i % 2) evens.push(+match[0]);
 * });
 * // evens -> [2, 4]
 */


XRegExp.forEach = function (str, regex, callback) {
  var pos = 0;
  var i = -1;
  var match;

  while (match = XRegExp.exec(str, regex, pos)) {
    // Because `regex` is provided to `callback`, the function could use the deprecated/
    // nonstandard `RegExp.prototype.compile` to mutate the regex. However, since `XRegExp.exec`
    // doesn't use `lastIndex` to set the search position, this can't lead to an infinite loop,
    // at least. Actually, because of the way `XRegExp.exec` caches globalized versions of
    // regexes, mutating the regex will not have any effect on the iteration or matched strings,
    // which is a nice side effect that brings extra safety.
    callback(match, ++i, str, regex);
    pos = match.index + (match[0].length || 1);
  }
};
/**
 * Copies a regex object and adds flag `g`. The copy maintains extended data, is augmented with
 * `XRegExp.prototype` properties, and has a fresh `lastIndex` property (set to zero). Native
 * regexes are not recompiled using XRegExp syntax.
 *
 * @memberOf XRegExp
 * @param {RegExp} regex Regex to globalize.
 * @returns {RegExp} Copy of the provided regex with flag `g` added.
 * @example
 *
 * const globalCopy = XRegExp.globalize(/regex/);
 * globalCopy.global; // -> true
 */


XRegExp.globalize = function (regex) {
  return copyRegex(regex, {
    addG: true
  });
};
/**
 * Installs optional features according to the specified options. Can be undone using
 * `XRegExp.uninstall`.
 *
 * @memberOf XRegExp
 * @param {Object|String} options Options object or string.
 * @example
 *
 * // With an options object
 * XRegExp.install({
 *   // Enables support for astral code points in Unicode addons (implicitly sets flag A)
 *   astral: true,
 *
 *   // Adds named capture groups to the `groups` property of matches
 *   namespacing: true
 * });
 *
 * // With an options string
 * XRegExp.install('astral namespacing');
 */


XRegExp.install = function (options) {
  options = prepareOptions(options);

  if (!features.astral && options.astral) {
    setAstral(true);
  }

  if (!features.namespacing && options.namespacing) {
    setNamespacing(true);
  }
};
/**
 * Checks whether an individual optional feature is installed.
 *
 * @memberOf XRegExp
 * @param {String} feature Name of the feature to check. One of:
 *   - `astral`
 *   - `namespacing`
 * @returns {boolean} Whether the feature is installed.
 * @example
 *
 * XRegExp.isInstalled('astral');
 */


XRegExp.isInstalled = function (feature) {
  return !!features[feature];
};
/**
 * Returns `true` if an object is a regex; `false` if it isn't. This works correctly for regexes
 * created in another frame, when `instanceof` and `constructor` checks would fail.
 *
 * @memberOf XRegExp
 * @param {*} value Object to check.
 * @returns {boolean} Whether the object is a `RegExp` object.
 * @example
 *
 * XRegExp.isRegExp('string'); // -> false
 * XRegExp.isRegExp(/regex/i); // -> true
 * XRegExp.isRegExp(RegExp('^', 'm')); // -> true
 * XRegExp.isRegExp(XRegExp('(?s).')); // -> true
 */


XRegExp.isRegExp = function (value) {
  return Object.prototype.toString.call(value) === '[object RegExp]';
}; // Same as `isType(value, 'RegExp')`, but avoiding that function call here for perf since
// `isRegExp` is used heavily by internals including regex construction

/**
 * Returns the first matched string, or in global mode, an array containing all matched strings.
 * This is essentially a more convenient re-implementation of `String.prototype.match` that gives
 * the result types you actually want (string instead of `exec`-style array in match-first mode,
 * and an empty array instead of `null` when no matches are found in match-all mode). It also lets
 * you override flag g and ignore `lastIndex`, and fixes browser bugs.
 *
 * @memberOf XRegExp
 * @param {String} str String to search.
 * @param {RegExp} regex Regex to search with.
 * @param {String} [scope='one'] Use 'one' to return the first match as a string. Use 'all' to
 *   return an array of all matched strings. If not explicitly specified and `regex` uses flag g,
 *   `scope` is 'all'.
 * @returns {String|Array} In match-first mode: First match as a string, or `null`. In match-all
 *   mode: Array of all matched strings, or an empty array.
 * @example
 *
 * // Match first
 * XRegExp.match('abc', /\w/); // -> 'a'
 * XRegExp.match('abc', /\w/g, 'one'); // -> 'a'
 * XRegExp.match('abc', /x/g, 'one'); // -> null
 *
 * // Match all
 * XRegExp.match('abc', /\w/g); // -> ['a', 'b', 'c']
 * XRegExp.match('abc', /\w/, 'all'); // -> ['a', 'b', 'c']
 * XRegExp.match('abc', /x/, 'all'); // -> []
 */


XRegExp.match = function (str, regex, scope) {
  var global = regex.global && scope !== 'one' || scope === 'all';
  var cacheKey = (global ? 'g' : '') + (regex.sticky ? 'y' : '') || 'noGY';
  regex[REGEX_DATA] = regex[REGEX_DATA] || {}; // Shares cached copies with `XRegExp.exec`/`replace`

  var r2 = regex[REGEX_DATA][cacheKey] || (regex[REGEX_DATA][cacheKey] = copyRegex(regex, {
    addG: !!global,
    removeG: scope === 'one',
    isInternalOnly: true
  }));
  var result = String(nullThrows(str)).match(r2);

  if (regex.global) {
    regex.lastIndex = scope === 'one' && result ? // Can't use `r2.lastIndex` since `r2` is nonglobal in this case
    result.index + result[0].length : 0;
  }

  return global ? result || [] : result && result[0];
};
/**
 * Retrieves the matches from searching a string using a chain of regexes that successively search
 * within previous matches. The provided `chain` array can contain regexes and or objects with
 * `regex` and `backref` properties. When a backreference is specified, the named or numbered
 * backreference is passed forward to the next regex or returned.
 *
 * @memberOf XRegExp
 * @param {String} str String to search.
 * @param {Array} chain Regexes that each search for matches within preceding results.
 * @returns {Array} Matches by the last regex in the chain, or an empty array.
 * @example
 *
 * // Basic usage; matches numbers within <b> tags
 * XRegExp.matchChain('1 <b>2</b> 3 <b>4 a 56</b>', [
 *   XRegExp('(?is)<b>.*?</b>'),
 *   /\d+/
 * ]);
 * // -> ['2', '4', '56']
 *
 * // Passing forward and returning specific backreferences
 * const html = `<a href="http://xregexp.com/api/">XRegExp</a>
 *               <a href="http://www.google.com/">Google</a>`;
 * XRegExp.matchChain(html, [
 *   {regex: /<a href="([^"]+)">/i, backref: 1},
 *   {regex: XRegExp('(?i)^https?://(?<domain>[^/?#]+)'), backref: 'domain'}
 * ]);
 * // -> ['xregexp.com', 'www.google.com']
 */


XRegExp.matchChain = function (str, chain) {
  return function recurseChain(values, level) {
    var item = chain[level].regex ? chain[level] : {
      regex: chain[level]
    };
    var matches = [];

    function addMatch(match) {
      if (item.backref) {
        var ERR_UNDEFINED_GROUP = "Backreference to undefined group: ".concat(item.backref);
        var isNamedBackref = isNaN(item.backref);

        if (isNamedBackref && XRegExp.isInstalled('namespacing')) {
          // `groups` has `null` as prototype, so using `in` instead of `hasOwnProperty`
          if (!(match.groups && item.backref in match.groups)) {
            throw new ReferenceError(ERR_UNDEFINED_GROUP);
          }
        } else if (!match.hasOwnProperty(item.backref)) {
          throw new ReferenceError(ERR_UNDEFINED_GROUP);
        }

        var backrefValue = isNamedBackref && XRegExp.isInstalled('namespacing') ? match.groups[item.backref] : match[item.backref];
        matches.push(backrefValue || '');
      } else {
        matches.push(match[0]);
      }
    }

    var _iterator3 = _createForOfIteratorHelper(values),
        _step3;

    try {
      for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
        var value = _step3.value;
        (0, _forEach["default"])(XRegExp).call(XRegExp, value, item.regex, addMatch);
      }
    } catch (err) {
      _iterator3.e(err);
    } finally {
      _iterator3.f();
    }

    return level === chain.length - 1 || !matches.length ? matches : recurseChain(matches, level + 1);
  }([str], 0);
};
/**
 * Returns a new string with one or all matches of a pattern replaced. The pattern can be a string
 * or regex, and the replacement can be a string or a function to be called for each match. To
 * perform a global search and replace, use the optional `scope` argument or include flag g if using
 * a regex. Replacement strings can use `$<n>` or `${n}` for named and numbered backreferences.
 * Replacement functions can use named backreferences via the last argument. Also fixes browser bugs
 * compared to the native `String.prototype.replace` and can be used reliably cross-browser.
 *
 * @memberOf XRegExp
 * @param {String} str String to search.
 * @param {RegExp|String} search Search pattern to be replaced.
 * @param {String|Function} replacement Replacement string or a function invoked to create it.
 *   Replacement strings can include special replacement syntax:
 *     - $$ - Inserts a literal $ character.
 *     - $&, $0 - Inserts the matched substring.
 *     - $` - Inserts the string that precedes the matched substring (left context).
 *     - $' - Inserts the string that follows the matched substring (right context).
 *     - $n, $nn - Where n/nn are digits referencing an existing capturing group, inserts
 *       backreference n/nn.
 *     - $<n>, ${n} - Where n is a name or any number of digits that reference an existing capturing
 *       group, inserts backreference n.
 *   Replacement functions are invoked with three or more arguments:
 *     - args[0] - The matched substring (corresponds to `$&` above). If the `namespacing` feature
 *       is off, named backreferences are accessible as properties of this argument.
 *     - args[1..n] - One argument for each backreference (corresponding to `$1`, `$2`, etc. above).
 *       If the regex has no capturing groups, no arguments appear in this position.
 *     - args[n+1] - The zero-based index of the match within the entire search string.
 *     - args[n+2] - The total string being searched.
 *     - args[n+3] - If the the search pattern is a regex with named capturing groups, the last
 *       argument is the groups object. Its keys are the backreference names and its values are the
 *       backreference values. If the `namespacing` feature is off, this argument is not present.
 * @param {String} [scope] Use 'one' to replace the first match only, or 'all'. Defaults to 'one'.
 *   Defaults to 'all' if using a regex with flag g.
 * @returns {String} New string with one or all matches replaced.
 * @example
 *
 * // Regex search, using named backreferences in replacement string
 * const name = XRegExp('(?<first>\\w+) (?<last>\\w+)');
 * XRegExp.replace('John Smith', name, '$<last>, $<first>');
 * // -> 'Smith, John'
 *
 * // Regex search, using named backreferences in replacement function
 * XRegExp.replace('John Smith', name, (...args) => {
 *   const groups = args[args.length - 1];
 *   return `${groups.last}, ${groups.first}`;
 * });
 * // -> 'Smith, John'
 *
 * // String search, with replace-all
 * XRegExp.replace('RegExp builds RegExps', 'RegExp', 'XRegExp', 'all');
 * // -> 'XRegExp builds XRegExps'
 */


XRegExp.replace = function (str, search, replacement, scope) {
  var isRegex = XRegExp.isRegExp(search);
  var global = search.global && scope !== 'one' || scope === 'all';
  var cacheKey = (global ? 'g' : '') + (search.sticky ? 'y' : '') || 'noGY';
  var s2 = search;

  if (isRegex) {
    search[REGEX_DATA] = search[REGEX_DATA] || {}; // Shares cached copies with `XRegExp.exec`/`match`. Since a copy is used, `search`'s
    // `lastIndex` isn't updated *during* replacement iterations

    s2 = search[REGEX_DATA][cacheKey] || (search[REGEX_DATA][cacheKey] = copyRegex(search, {
      addG: !!global,
      removeG: scope === 'one',
      isInternalOnly: true
    }));
  } else if (global) {
    s2 = new RegExp(XRegExp.escape(String(search)), 'g');
  } // Fixed `replace` required for named backreferences, etc.


  var result = fixed.replace.call(nullThrows(str), s2, replacement);

  if (isRegex && search.global) {
    // Fixes IE, Safari bug (last tested IE 9, Safari 5.1)
    search.lastIndex = 0;
  }

  return result;
};
/**
 * Performs batch processing of string replacements. Used like `XRegExp.replace`, but accepts an
 * array of replacement details. Later replacements operate on the output of earlier replacements.
 * Replacement details are accepted as an array with a regex or string to search for, the
 * replacement string or function, and an optional scope of 'one' or 'all'. Uses the XRegExp
 * replacement text syntax, which supports named backreference properties via `$<name>` or
 * `${name}`.
 *
 * @memberOf XRegExp
 * @param {String} str String to search.
 * @param {Array} replacements Array of replacement detail arrays.
 * @returns {String} New string with all replacements.
 * @example
 *
 * str = XRegExp.replaceEach(str, [
 *   [XRegExp('(?<name>a)'), 'z$<name>'],
 *   [/b/gi, 'y'],
 *   [/c/g, 'x', 'one'], // scope 'one' overrides /g
 *   [/d/, 'w', 'all'],  // scope 'all' overrides lack of /g
 *   ['e', 'v', 'all'],  // scope 'all' allows replace-all for strings
 *   [/f/g, (match) => match.toUpperCase()]
 * ]);
 */


XRegExp.replaceEach = function (str, replacements) {
  var _iterator4 = _createForOfIteratorHelper(replacements),
      _step4;

  try {
    for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
      var r = _step4.value;
      str = XRegExp.replace(str, r[0], r[1], r[2]);
    }
  } catch (err) {
    _iterator4.e(err);
  } finally {
    _iterator4.f();
  }

  return str;
};
/**
 * Splits a string into an array of strings using a regex or string separator. Matches of the
 * separator are not included in the result array. However, if `separator` is a regex that contains
 * capturing groups, backreferences are spliced into the result each time `separator` is matched.
 * Fixes browser bugs compared to the native `String.prototype.split` and can be used reliably
 * cross-browser.
 *
 * @memberOf XRegExp
 * @param {String} str String to split.
 * @param {RegExp|String} separator Regex or string to use for separating the string.
 * @param {Number} [limit] Maximum number of items to include in the result array.
 * @returns {Array} Array of substrings.
 * @example
 *
 * // Basic use
 * XRegExp.split('a b c', ' ');
 * // -> ['a', 'b', 'c']
 *
 * // With limit
 * XRegExp.split('a b c', ' ', 2);
 * // -> ['a', 'b']
 *
 * // Backreferences in result array
 * XRegExp.split('..word1..', /([a-z]+)(\d+)/i);
 * // -> ['..', 'word', '1', '..']
 */


XRegExp.split = function (str, separator, limit) {
  return fixed.split.call(nullThrows(str), separator, limit);
};
/**
 * Executes a regex search in a specified string. Returns `true` or `false`. Optional `pos` and
 * `sticky` arguments specify the search start position, and whether the match must start at the
 * specified position only. The `lastIndex` property of the provided regex is not used, but is
 * updated for compatibility. Also fixes browser bugs compared to the native
 * `RegExp.prototype.test` and can be used reliably cross-browser.
 *
 * @memberOf XRegExp
 * @param {String} str String to search.
 * @param {RegExp} regex Regex to search with.
 * @param {Number} [pos=0] Zero-based index at which to start the search.
 * @param {Boolean|String} [sticky=false] Whether the match must start at the specified position
 *   only. The string `'sticky'` is accepted as an alternative to `true`.
 * @returns {boolean} Whether the regex matched the provided value.
 * @example
 *
 * // Basic use
 * XRegExp.test('abc', /c/); // -> true
 *
 * // With pos and sticky
 * XRegExp.test('abc', /c/, 0, 'sticky'); // -> false
 * XRegExp.test('abc', /c/, 2, 'sticky'); // -> true
 */
// Do this the easy way :-)


XRegExp.test = function (str, regex, pos, sticky) {
  return !!XRegExp.exec(str, regex, pos, sticky);
};
/**
 * Uninstalls optional features according to the specified options. Used to undo the actions of
 * `XRegExp.install`.
 *
 * @memberOf XRegExp
 * @param {Object|String} options Options object or string.
 * @example
 *
 * // With an options object
 * XRegExp.uninstall({
 *   // Disables support for astral code points in Unicode addons (unless enabled per regex)
 *   astral: true,
 *
 *   // Don't add named capture groups to the `groups` property of matches
 *   namespacing: true
 * });
 *
 * // With an options string
 * XRegExp.uninstall('astral namespacing');
 */


XRegExp.uninstall = function (options) {
  options = prepareOptions(options);

  if (features.astral && options.astral) {
    setAstral(false);
  }

  if (features.namespacing && options.namespacing) {
    setNamespacing(false);
  }
};
/**
 * Returns an XRegExp object that is the union of the given patterns. Patterns can be provided as
 * regex objects or strings. Metacharacters are escaped in patterns provided as strings.
 * Backreferences in provided regex objects are automatically renumbered to work correctly within
 * the larger combined pattern. Native flags used by provided regexes are ignored in favor of the
 * `flags` argument.
 *
 * @memberOf XRegExp
 * @param {Array} patterns Regexes and strings to combine.
 * @param {String} [flags] Any combination of XRegExp flags.
 * @param {Object} [options] Options object with optional properties:
 *   - `conjunction` {String} Type of conjunction to use: 'or' (default) or 'none'.
 * @returns {RegExp} Union of the provided regexes and strings.
 * @example
 *
 * XRegExp.union(['a+b*c', /(dogs)\1/, /(cats)\1/], 'i');
 * // -> /a\+b\*c|(dogs)\1|(cats)\2/i
 *
 * XRegExp.union([/man/, /bear/, /pig/], 'i', {conjunction: 'none'});
 * // -> /manbearpig/i
 */


XRegExp.union = function (patterns, flags, options) {
  options = options || {};
  var conjunction = options.conjunction || 'or';
  var numCaptures = 0;
  var numPriorCaptures;
  var captureNames;

  function rewrite(match, paren, backref) {
    var name = captureNames[numCaptures - numPriorCaptures]; // Capturing group

    if (paren) {
      ++numCaptures; // If the current capture has a name, preserve the name

      if (name) {
        return "(?<".concat(name, ">");
      } // Backreference

    } else if (backref) {
      // Rewrite the backreference
      return "\\".concat(+backref + numPriorCaptures);
    }

    return match;
  }

  if (!(isType(patterns, 'Array') && patterns.length)) {
    throw new TypeError('Must provide a nonempty array of patterns to merge');
  }

  var parts = /(\()(?!\?)|\\([1-9]\d*)|\\[\s\S]|\[(?:[^\\\]]|\\[\s\S])*\]/g;
  var output = [];

  var _iterator5 = _createForOfIteratorHelper(patterns),
      _step5;

  try {
    for (_iterator5.s(); !(_step5 = _iterator5.n()).done;) {
      var pattern = _step5.value;

      if (XRegExp.isRegExp(pattern)) {
        numPriorCaptures = numCaptures;
        captureNames = pattern[REGEX_DATA] && pattern[REGEX_DATA].captureNames || []; // Rewrite backreferences. Passing to XRegExp dies on octals and ensures patterns are
        // independently valid; helps keep this simple. Named captures are put back

        output.push(XRegExp(pattern.source).source.replace(parts, rewrite));
      } else {
        output.push(XRegExp.escape(pattern));
      }
    }
  } catch (err) {
    _iterator5.e(err);
  } finally {
    _iterator5.f();
  }

  var separator = conjunction === 'none' ? '' : '|';
  return XRegExp(output.join(separator), flags);
}; // ==--------------------------==
// Fixed/extended native methods
// ==--------------------------==

/**
 * Adds named capture support (with backreferences returned as `result.name`), and fixes browser
 * bugs in the native `RegExp.prototype.exec`. Use via `XRegExp.exec`.
 *
 * @memberOf RegExp
 * @param {String} str String to search.
 * @returns {Array} Match array with named backreference properties, or `null`.
 */


fixed.exec = function (str) {
  var origLastIndex = this.lastIndex;
  var match = RegExp.prototype.exec.apply(this, arguments);

  if (match) {
    // Fix browsers whose `exec` methods don't return `undefined` for nonparticipating capturing
    // groups. This fixes IE 5.5-8, but not IE 9's quirks mode or emulation of older IEs. IE 9
    // in standards mode follows the spec.
    if (!correctExecNpcg && match.length > 1 && (0, _indexOf["default"])(match).call(match, '') !== -1) {
      var _context3;

      var r2 = copyRegex(this, {
        removeG: true,
        isInternalOnly: true
      }); // Using `str.slice(match.index)` rather than `match[0]` in case lookahead allowed
      // matching due to characters outside the match

      (0, _slice["default"])(_context3 = String(str)).call(_context3, match.index).replace(r2, function () {
        var len = arguments.length; // Skip index 0 and the last 2

        for (var i = 1; i < len - 2; ++i) {
          if ((i < 0 || arguments.length <= i ? undefined : arguments[i]) === undefined) {
            match[i] = undefined;
          }
        }
      });
    } // Attach named capture properties


    if (this[REGEX_DATA] && this[REGEX_DATA].captureNames) {
      var groupsObject = match;

      if (XRegExp.isInstalled('namespacing')) {
        // https://tc39.github.io/proposal-regexp-named-groups/#sec-regexpbuiltinexec
        match.groups = (0, _create["default"])(null);
        groupsObject = match.groups;
      } // Skip index 0


      for (var i = 1; i < match.length; ++i) {
        var name = this[REGEX_DATA].captureNames[i - 1];

        if (name) {
          groupsObject[name] = match[i];
        }
      } // Preserve any existing `groups` obj that came from native ES2018 named capture

    } else if (!match.groups && XRegExp.isInstalled('namespacing')) {
      match.groups = undefined;
    } // Fix browsers that increment `lastIndex` after zero-length matches


    if (this.global && !match[0].length && this.lastIndex > match.index) {
      this.lastIndex = match.index;
    }
  }

  if (!this.global) {
    // Fixes IE, Opera bug (last tested IE 9, Opera 11.6)
    this.lastIndex = origLastIndex;
  }

  return match;
};
/**
 * Fixes browser bugs in the native `RegExp.prototype.test`.
 *
 * @memberOf RegExp
 * @param {String} str String to search.
 * @returns {boolean} Whether the regex matched the provided value.
 */


fixed.test = function (str) {
  // Do this the easy way :-)
  return !!fixed.exec.call(this, str);
};
/**
 * Adds named capture support (with backreferences returned as `result.name`), and fixes browser
 * bugs in the native `String.prototype.match`.
 *
 * @memberOf String
 * @param {RegExp|*} regex Regex to search with. If not a regex object, it is passed to `RegExp`.
 * @returns {Array} If `regex` uses flag g, an array of match strings or `null`. Without flag g,
 *   the result of calling `regex.exec(this)`.
 */


fixed.match = function (regex) {
  if (!XRegExp.isRegExp(regex)) {
    // Use the native `RegExp` rather than `XRegExp`
    regex = new RegExp(regex);
  } else if (regex.global) {
    var result = String.prototype.match.apply(this, arguments); // Fixes IE bug

    regex.lastIndex = 0;
    return result;
  }

  return fixed.exec.call(regex, nullThrows(this));
};
/**
 * Adds support for `${n}` (or `$<n>`) tokens for named and numbered backreferences in replacement
 * text, and provides named backreferences to replacement functions as `arguments[0].name`. Also
 * fixes browser bugs in replacement text syntax when performing a replacement using a nonregex
 * search value, and the value of a replacement regex's `lastIndex` property during replacement
 * iterations and upon completion. Note that this doesn't support SpiderMonkey's proprietary third
 * (`flags`) argument. Use via `XRegExp.replace`.
 *
 * @memberOf String
 * @param {RegExp|String} search Search pattern to be replaced.
 * @param {String|Function} replacement Replacement string or a function invoked to create it.
 * @returns {string} New string with one or all matches replaced.
 */


fixed.replace = function (search, replacement) {
  var isRegex = XRegExp.isRegExp(search);
  var origLastIndex;
  var captureNames;
  var result;

  if (isRegex) {
    if (search[REGEX_DATA]) {
      captureNames = search[REGEX_DATA].captureNames;
    } // Only needed if `search` is nonglobal


    origLastIndex = search.lastIndex;
  } else {
    search += ''; // Type-convert
  } // Don't use `typeof`; some older browsers return 'function' for regex objects


  if (isType(replacement, 'Function')) {
    // Stringifying `this` fixes a bug in IE < 9 where the last argument in replacement
    // functions isn't type-converted to a string
    result = String(this).replace(search, function () {
      for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
        args[_key] = arguments[_key];
      }

      if (captureNames) {
        var groupsObject;

        if (XRegExp.isInstalled('namespacing')) {
          // https://tc39.github.io/proposal-regexp-named-groups/#sec-regexpbuiltinexec
          groupsObject = (0, _create["default"])(null);
          args.push(groupsObject);
        } else {
          // Change the `args[0]` string primitive to a `String` object that can store
          // properties. This really does need to use `String` as a constructor
          args[0] = new String(args[0]);
          groupsObject = args[0];
        } // Store named backreferences


        for (var i = 0; i < captureNames.length; ++i) {
          if (captureNames[i]) {
            groupsObject[captureNames[i]] = args[i + 1];
          }
        }
      } // ES6 specs the context for replacement functions as `undefined`


      return replacement.apply(void 0, args);
    });
  } else {
    // Ensure that the last value of `args` will be a string when given nonstring `this`,
    // while still throwing on null or undefined context
    result = String(nullThrows(this)).replace(search, function () {
      for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
        args[_key2] = arguments[_key2];
      }

      return String(replacement).replace(replacementToken, replacer);

      function replacer($0, bracketed, angled, dollarToken) {
        bracketed = bracketed || angled; // ES2018 added a new trailing `groups` arg that's passed to replacement functions
        // when the search regex uses native named capture

        var numNonCaptureArgs = isType(args[args.length - 1], 'Object') ? 4 : 3;
        var numCaptures = args.length - numNonCaptureArgs; // Handle named or numbered backreference with curly or angled braces: ${n}, $<n>

        if (bracketed) {
          // Handle backreference to numbered capture, if `bracketed` is an integer. Use
          // `0` for the entire match. Any number of leading zeros may be used.
          if (/^\d+$/.test(bracketed)) {
            // Type-convert and drop leading zeros
            var _n = +bracketed;

            if (_n <= numCaptures) {
              return args[_n] || '';
            }
          } // Handle backreference to named capture. If the name does not refer to an
          // existing capturing group, it's an error. Also handles the error for numbered
          // backference that does not refer to an existing group.
          // Using `indexOf` since having groups with the same name is already an error,
          // otherwise would need `lastIndexOf`.


          var n = captureNames ? (0, _indexOf["default"])(captureNames).call(captureNames, bracketed) : -1;

          if (n < 0) {
            throw new SyntaxError("Backreference to undefined group ".concat($0));
          }

          return args[n + 1] || '';
        } // Handle `$`-prefixed variable
        // Handle space/blank first because type conversion with `+` drops space padding
        // and converts spaces and empty strings to `0`


        if (dollarToken === '' || dollarToken === ' ') {
          throw new SyntaxError("Invalid token ".concat($0));
        }

        if (dollarToken === '&' || +dollarToken === 0) {
          // $&, $0 (not followed by 1-9), $00
          return args[0];
        }

        if (dollarToken === '$') {
          // $$
          return '$';
        }

        if (dollarToken === '`') {
          var _context4;

          // $` (left context)
          return (0, _slice["default"])(_context4 = args[args.length - 1]).call(_context4, 0, args[args.length - 2]);
        }

        if (dollarToken === "'") {
          var _context5;

          // $' (right context)
          return (0, _slice["default"])(_context5 = args[args.length - 1]).call(_context5, args[args.length - 2] + args[0].length);
        } // Handle numbered backreference without braces
        // Type-convert and drop leading zero


        dollarToken = +dollarToken; // XRegExp behavior for `$n` and `$nn`:
        // - Backrefs end after 1 or 2 digits. Use `${..}` or `$<..>` for more digits.
        // - `$1` is an error if no capturing groups.
        // - `$10` is an error if less than 10 capturing groups. Use `${1}0` or `$<1>0`
        //   instead.
        // - `$01` is `$1` if at least one capturing group, else it's an error.
        // - `$0` (not followed by 1-9) and `$00` are the entire match.
        // Native behavior, for comparison:
        // - Backrefs end after 1 or 2 digits. Cannot reference capturing group 100+.
        // - `$1` is a literal `$1` if no capturing groups.
        // - `$10` is `$1` followed by a literal `0` if less than 10 capturing groups.
        // - `$01` is `$1` if at least one capturing group, else it's a literal `$01`.
        // - `$0` is a literal `$0`.

        if (!isNaN(dollarToken)) {
          if (dollarToken > numCaptures) {
            throw new SyntaxError("Backreference to undefined group ".concat($0));
          }

          return args[dollarToken] || '';
        } // `$` followed by an unsupported char is an error, unlike native JS


        throw new SyntaxError("Invalid token ".concat($0));
      }
    });
  }

  if (isRegex) {
    if (search.global) {
      // Fixes IE, Safari bug (last tested IE 9, Safari 5.1)
      search.lastIndex = 0;
    } else {
      // Fixes IE, Opera bug (last tested IE 9, Opera 11.6)
      search.lastIndex = origLastIndex;
    }
  }

  return result;
};
/**
 * Fixes browser bugs in the native `String.prototype.split`. Use via `XRegExp.split`.
 *
 * @memberOf String
 * @param {RegExp|String} separator Regex or string to use for separating the string.
 * @param {Number} [limit] Maximum number of items to include in the result array.
 * @returns {!Array} Array of substrings.
 */


fixed.split = function (separator, limit) {
  if (!XRegExp.isRegExp(separator)) {
    // Browsers handle nonregex split correctly, so use the faster native method
    return String.prototype.split.apply(this, arguments);
  }

  var str = String(this);
  var output = [];
  var origLastIndex = separator.lastIndex;
  var lastLastIndex = 0;
  var lastLength; // Values for `limit`, per the spec:
  // If undefined: pow(2,32) - 1
  // If 0, Infinity, or NaN: 0
  // If positive number: limit = floor(limit); if (limit >= pow(2,32)) limit -= pow(2,32);
  // If negative number: pow(2,32) - floor(abs(limit))
  // If other: Type-convert, then use the above rules
  // This line fails in very strange ways for some values of `limit` in Opera 10.5-10.63, unless
  // Opera Dragonfly is open (go figure). It works in at least Opera 9.5-10.1 and 11+

  limit = (limit === undefined ? -1 : limit) >>> 0;
  (0, _forEach["default"])(XRegExp).call(XRegExp, str, separator, function (match) {
    // This condition is not the same as `if (match[0].length)`
    if (match.index + match[0].length > lastLastIndex) {
      output.push((0, _slice["default"])(str).call(str, lastLastIndex, match.index));

      if (match.length > 1 && match.index < str.length) {
        Array.prototype.push.apply(output, (0, _slice["default"])(match).call(match, 1));
      }

      lastLength = match[0].length;
      lastLastIndex = match.index + lastLength;
    }
  });

  if (lastLastIndex === str.length) {
    if (!separator.test('') || lastLength) {
      output.push('');
    }
  } else {
    output.push((0, _slice["default"])(str).call(str, lastLastIndex));
  }

  separator.lastIndex = origLastIndex;
  return output.length > limit ? (0, _slice["default"])(output).call(output, 0, limit) : output;
}; // ==--------------------------==
// Built-in syntax/flag tokens
// ==--------------------------==

/*
 * Letter escapes that natively match literal characters: `\a`, `\A`, etc. These should be
 * SyntaxErrors but are allowed in web reality. XRegExp makes them errors for cross-browser
 * consistency and to reserve their syntax, but lets them be superseded by addons.
 */


XRegExp.addToken(/\\([ABCE-RTUVXYZaeg-mopqyz]|c(?![A-Za-z])|u(?![\dA-Fa-f]{4}|{[\dA-Fa-f]+})|x(?![\dA-Fa-f]{2}))/, function (match, scope) {
  // \B is allowed in default scope only
  if (match[1] === 'B' && scope === defaultScope) {
    return match[0];
  }

  throw new SyntaxError("Invalid escape ".concat(match[0]));
}, {
  scope: 'all',
  leadChar: '\\'
});
/*
 * Unicode code point escape with curly braces: `\u{N..}`. `N..` is any one or more digit
 * hexadecimal number from 0-10FFFF, and can include leading zeros. Requires the native ES6 `u` flag
 * to support code points greater than U+FFFF. Avoids converting code points above U+FFFF to
 * surrogate pairs (which could be done without flag `u`), since that could lead to broken behavior
 * if you follow a `\u{N..}` token that references a code point above U+FFFF with a quantifier, or
 * if you use the same in a character class.
 */

XRegExp.addToken(/\\u{([\dA-Fa-f]+)}/, function (match, scope, flags) {
  var code = dec(match[1]);

  if (code > 0x10FFFF) {
    throw new SyntaxError("Invalid Unicode code point ".concat(match[0]));
  }

  if (code <= 0xFFFF) {
    // Converting to \uNNNN avoids needing to escape the literal character and keep it
    // separate from preceding tokens
    return "\\u".concat(pad4(hex(code)));
  } // If `code` is between 0xFFFF and 0x10FFFF, require and defer to native handling


  if (hasNativeU && (0, _indexOf["default"])(flags).call(flags, 'u') !== -1) {
    return match[0];
  }

  throw new SyntaxError('Cannot use Unicode code point above \\u{FFFF} without flag u');
}, {
  scope: 'all',
  leadChar: '\\'
});
/*
 * Comment pattern: `(?# )`. Inline comments are an alternative to the line comments allowed in
 * free-spacing mode (flag x).
 */

XRegExp.addToken(/\(\?#[^)]*\)/, getContextualTokenSeparator, {
  leadChar: '('
});
/*
 * Whitespace and line comments, in free-spacing mode (aka extended mode, flag x) only.
 */

XRegExp.addToken(/\s+|#[^\n]*\n?/, getContextualTokenSeparator, {
  flag: 'x'
});
/*
 * Dot, in dotAll mode (aka singleline mode, flag s) only.
 */

if (!hasNativeS) {
  XRegExp.addToken(/\./, function () {
    return '[\\s\\S]';
  }, {
    flag: 's',
    leadChar: '.'
  });
}
/*
 * Named backreference: `\k<name>`. Backreference names can use RegExpIdentifierName characters
 * only. Also allows numbered backreferences as `\k<n>`.
 */


XRegExp.addToken(/\\k<([^>]+)>/, function (match) {
  var _context6, _context7;

  // Groups with the same name is an error, else would need `lastIndexOf`
  var index = isNaN(match[1]) ? (0, _indexOf["default"])(_context6 = this.captureNames).call(_context6, match[1]) + 1 : +match[1];
  var endIndex = match.index + match[0].length;

  if (!index || index > this.captureNames.length) {
    throw new SyntaxError("Backreference to undefined group ".concat(match[0]));
  } // Keep backreferences separate from subsequent literal numbers. This avoids e.g.
  // inadvertedly changing `(?<n>)\k<n>1` to `()\11`.


  return (0, _concat["default"])(_context7 = "\\".concat(index)).call(_context7, endIndex === match.input.length || isNaN(match.input[endIndex]) ? '' : '(?:)');
}, {
  leadChar: '\\'
});
/*
 * Numbered backreference or octal, plus any following digits: `\0`, `\11`, etc. Octals except `\0`
 * not followed by 0-9 and backreferences to unopened capture groups throw an error. Other matches
 * are returned unaltered. IE < 9 doesn't support backreferences above `\99` in regex syntax.
 */

XRegExp.addToken(/\\(\d+)/, function (match, scope) {
  if (!(scope === defaultScope && /^[1-9]/.test(match[1]) && +match[1] <= this.captureNames.length) && match[1] !== '0') {
    throw new SyntaxError("Cannot use octal escape or backreference to undefined group ".concat(match[0]));
  }

  return match[0];
}, {
  scope: 'all',
  leadChar: '\\'
});
/*
 * Named capturing group; match the opening delimiter only: `(?<name>`. Capture names can use the
 * RegExpIdentifierName characters only. Names can't be integers. Supports Python-style
 * `(?P<name>` as an alternate syntax to avoid issues in some older versions of Opera which natively
 * supported the Python-style syntax. Otherwise, XRegExp might treat numbered backreferences to
 * Python-style named capture as octals.
 */

XRegExp.addToken(/\(\?P?<((?:[\$A-Z_a-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u0870-\u0887\u0889-\u088E\u08A0-\u08C9\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C5D\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u1711\u171F-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1878\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4C\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309B-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u31A0-\u31BF\u31F0-\u31FF\u3400-\u4DBF\u4E00-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7CA\uA7D0\uA7D1\uA7D3\uA7D5-\uA7D9\uA7F2-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDD70-\uDD7A\uDD7C-\uDD8A\uDD8C-\uDD92\uDD94\uDD95\uDD97-\uDDA1\uDDA3-\uDDB1\uDDB3-\uDDB9\uDDBB\uDDBC\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67\uDF80-\uDF85\uDF87-\uDFB0\uDFB2-\uDFBA]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDD00-\uDD23\uDE80-\uDEA9\uDEB0\uDEB1\uDF00-\uDF1C\uDF27\uDF30-\uDF45\uDF70-\uDF81\uDFB0-\uDFC4\uDFE0-\uDFF6]|\uD804[\uDC03-\uDC37\uDC71\uDC72\uDC75\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD44\uDD47\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC5F-\uDC61\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDEB8\uDF00-\uDF1A\uDF40-\uDF46]|\uD806[\uDC00-\uDC2B\uDCA0-\uDCDF\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD2F\uDD3F\uDD41\uDDA0-\uDDA7\uDDAA-\uDDD0\uDDE1\uDDE3\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE89\uDE9D\uDEB0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD89\uDD98\uDEE0-\uDEF2\uDFB0]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|\uD80B[\uDF90-\uDFF0]|[\uD80C\uD81C-\uD820\uD822\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879\uD880-\uD883][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE70-\uDEBE\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDE40-\uDE7F\uDF00-\uDF4A\uDF50\uDF93-\uDF9F\uDFE0\uDFE1\uDFE3]|\uD821[\uDC00-\uDFF7]|\uD823[\uDC00-\uDCD5\uDD00-\uDD08]|\uD82B[\uDFF0-\uDFF3\uDFF5-\uDFFB\uDFFD\uDFFE]|\uD82C[\uDC00-\uDD22\uDD50-\uDD52\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD837[\uDF00-\uDF1E]|\uD838[\uDD00-\uDD2C\uDD37-\uDD3D\uDD4E\uDE90-\uDEAD\uDEC0-\uDEEB]|\uD839[\uDFE0-\uDFE6\uDFE8-\uDFEB\uDFED\uDFEE\uDFF0-\uDFFE]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43\uDD4B]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDEDF\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF38\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A])(?:[\$0-9A-Z_a-z\xAA\xB5\xB7\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05EF-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u07FD\u0800-\u082D\u0840-\u085B\u0860-\u086A\u0870-\u0887\u0889-\u088E\u0898-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u09FE\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B55-\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3C-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C5D\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDD\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D81-\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1369-\u1371\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u1715\u171F-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u180F-\u1819\u1820-\u1878\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1ABF-\u1ACE\u1B00-\u1B4C\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1CD0-\u1CD2\u1CD4-\u1CFA\u1D00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2118-\u211D\u2124\u2126\u2128\u212A-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u31A0-\u31BF\u31F0-\u31FF\u3400-\u4DBF\u4E00-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7CA\uA7D0\uA7D1\uA7D3\uA7D5-\uA7D9\uA7F2-\uA827\uA82C\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDD70-\uDD7A\uDD7C-\uDD8A\uDD8C-\uDD92\uDD94\uDD95\uDD97-\uDDA1\uDDA3-\uDDB1\uDDB3-\uDDB9\uDDBB\uDDBC\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67\uDF80-\uDF85\uDF87-\uDFB0\uDFB2-\uDFBA]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDD00-\uDD27\uDD30-\uDD39\uDE80-\uDEA9\uDEAB\uDEAC\uDEB0\uDEB1\uDF00-\uDF1C\uDF27\uDF30-\uDF50\uDF70-\uDF85\uDFB0-\uDFC4\uDFE0-\uDFF6]|\uD804[\uDC00-\uDC46\uDC66-\uDC75\uDC7F-\uDCBA\uDCC2\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD44-\uDD47\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDC9-\uDDCC\uDDCE-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3B-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC5E-\uDC61\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB8\uDEC0-\uDEC9\uDF00-\uDF1A\uDF1D-\uDF2B\uDF30-\uDF39\uDF40-\uDF46]|\uD806[\uDC00-\uDC3A\uDCA0-\uDCE9\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD35\uDD37\uDD38\uDD3B-\uDD43\uDD50-\uDD59\uDDA0-\uDDA7\uDDAA-\uDDD7\uDDDA-\uDDE1\uDDE3\uDDE4\uDE00-\uDE3E\uDE47\uDE50-\uDE99\uDE9D\uDEB0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD8E\uDD90\uDD91\uDD93-\uDD98\uDDA0-\uDDA9\uDEE0-\uDEF6\uDFB0]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|\uD80B[\uDF90-\uDFF0]|[\uD80C\uD81C-\uD820\uD822\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879\uD880-\uD883][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDE70-\uDEBE\uDEC0-\uDEC9\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDE40-\uDE7F\uDF00-\uDF4A\uDF4F-\uDF87\uDF8F-\uDF9F\uDFE0\uDFE1\uDFE3\uDFE4\uDFF0\uDFF1]|\uD821[\uDC00-\uDFF7]|\uD823[\uDC00-\uDCD5\uDD00-\uDD08]|\uD82B[\uDFF0-\uDFF3\uDFF5-\uDFFB\uDFFD\uDFFE]|\uD82C[\uDC00-\uDD22\uDD50-\uDD52\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD833[\uDF00-\uDF2D\uDF30-\uDF46]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD837[\uDF00-\uDF1E]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A\uDD00-\uDD2C\uDD30-\uDD3D\uDD40-\uDD49\uDD4E\uDE90-\uDEAE\uDEC0-\uDEF9]|\uD839[\uDFE0-\uDFE6\uDFE8-\uDFEB\uDFED\uDFEE\uDFF0-\uDFFE]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4B\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD83E[\uDFF0-\uDFF9]|\uD869[\uDC00-\uDEDF\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF38\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A]|\uDB40[\uDD00-\uDDEF])*)>/, function (match) {
  var _context8;

  if (!XRegExp.isInstalled('namespacing') && (match[1] === 'length' || match[1] === '__proto__')) {
    throw new SyntaxError("Cannot use reserved word as capture name ".concat(match[0]));
  }

  if ((0, _indexOf["default"])(_context8 = this.captureNames).call(_context8, match[1]) !== -1) {
    throw new SyntaxError("Cannot use same name for multiple groups ".concat(match[0]));
  }

  this.captureNames.push(match[1]);
  this.hasNamedCapture = true;
  return '(';
}, {
  leadChar: '('
});
/*
 * Capturing group; match the opening parenthesis only. Required for support of named capturing
 * groups. Also adds named capture only mode (flag n).
 */

XRegExp.addToken(/\((?!\?)/, function (match, scope, flags) {
  if ((0, _indexOf["default"])(flags).call(flags, 'n') !== -1) {
    return '(?:';
  }

  this.captureNames.push(null);
  return '(';
}, {
  optionalFlags: 'n',
  leadChar: '('
});
var _default = XRegExp;
exports["default"] = _default;
module.exports = exports.default;

/***/ }),

/***/ 33082:
/***/ ((module) => {

module.exports = [
    {
        'name': 'C',
        'alias': 'Other',
        'isBmpLast': true,
        'bmp': '\0-\x1F\x7F-\x9F\xAD\u0378\u0379\u0380-\u0383\u038B\u038D\u03A2\u0530\u0557\u0558\u058B\u058C\u0590\u05C8-\u05CF\u05EB-\u05EE\u05F5-\u0605\u061C\u06DD\u070E\u070F\u074B\u074C\u07B2-\u07BF\u07FB\u07FC\u082E\u082F\u083F\u085C\u085D\u085F\u086B-\u086F\u088F-\u0897\u08E2\u0984\u098D\u098E\u0991\u0992\u09A9\u09B1\u09B3-\u09B5\u09BA\u09BB\u09C5\u09C6\u09C9\u09CA\u09CF-\u09D6\u09D8-\u09DB\u09DE\u09E4\u09E5\u09FF\u0A00\u0A04\u0A0B-\u0A0E\u0A11\u0A12\u0A29\u0A31\u0A34\u0A37\u0A3A\u0A3B\u0A3D\u0A43-\u0A46\u0A49\u0A4A\u0A4E-\u0A50\u0A52-\u0A58\u0A5D\u0A5F-\u0A65\u0A77-\u0A80\u0A84\u0A8E\u0A92\u0AA9\u0AB1\u0AB4\u0ABA\u0ABB\u0AC6\u0ACA\u0ACE\u0ACF\u0AD1-\u0ADF\u0AE4\u0AE5\u0AF2-\u0AF8\u0B00\u0B04\u0B0D\u0B0E\u0B11\u0B12\u0B29\u0B31\u0B34\u0B3A\u0B3B\u0B45\u0B46\u0B49\u0B4A\u0B4E-\u0B54\u0B58-\u0B5B\u0B5E\u0B64\u0B65\u0B78-\u0B81\u0B84\u0B8B-\u0B8D\u0B91\u0B96-\u0B98\u0B9B\u0B9D\u0BA0-\u0BA2\u0BA5-\u0BA7\u0BAB-\u0BAD\u0BBA-\u0BBD\u0BC3-\u0BC5\u0BC9\u0BCE\u0BCF\u0BD1-\u0BD6\u0BD8-\u0BE5\u0BFB-\u0BFF\u0C0D\u0C11\u0C29\u0C3A\u0C3B\u0C45\u0C49\u0C4E-\u0C54\u0C57\u0C5B\u0C5C\u0C5E\u0C5F\u0C64\u0C65\u0C70-\u0C76\u0C8D\u0C91\u0CA9\u0CB4\u0CBA\u0CBB\u0CC5\u0CC9\u0CCE-\u0CD4\u0CD7-\u0CDC\u0CDF\u0CE4\u0CE5\u0CF0\u0CF3-\u0CFF\u0D0D\u0D11\u0D45\u0D49\u0D50-\u0D53\u0D64\u0D65\u0D80\u0D84\u0D97-\u0D99\u0DB2\u0DBC\u0DBE\u0DBF\u0DC7-\u0DC9\u0DCB-\u0DCE\u0DD5\u0DD7\u0DE0-\u0DE5\u0DF0\u0DF1\u0DF5-\u0E00\u0E3B-\u0E3E\u0E5C-\u0E80\u0E83\u0E85\u0E8B\u0EA4\u0EA6\u0EBE\u0EBF\u0EC5\u0EC7\u0ECE\u0ECF\u0EDA\u0EDB\u0EE0-\u0EFF\u0F48\u0F6D-\u0F70\u0F98\u0FBD\u0FCD\u0FDB-\u0FFF\u10C6\u10C8-\u10CC\u10CE\u10CF\u1249\u124E\u124F\u1257\u1259\u125E\u125F\u1289\u128E\u128F\u12B1\u12B6\u12B7\u12BF\u12C1\u12C6\u12C7\u12D7\u1311\u1316\u1317\u135B\u135C\u137D-\u137F\u139A-\u139F\u13F6\u13F7\u13FE\u13FF\u169D-\u169F\u16F9-\u16FF\u1716-\u171E\u1737-\u173F\u1754-\u175F\u176D\u1771\u1774-\u177F\u17DE\u17DF\u17EA-\u17EF\u17FA-\u17FF\u180E\u181A-\u181F\u1879-\u187F\u18AB-\u18AF\u18F6-\u18FF\u191F\u192C-\u192F\u193C-\u193F\u1941-\u1943\u196E\u196F\u1975-\u197F\u19AC-\u19AF\u19CA-\u19CF\u19DB-\u19DD\u1A1C\u1A1D\u1A5F\u1A7D\u1A7E\u1A8A-\u1A8F\u1A9A-\u1A9F\u1AAE\u1AAF\u1ACF-\u1AFF\u1B4D-\u1B4F\u1B7F\u1BF4-\u1BFB\u1C38-\u1C3A\u1C4A-\u1C4C\u1C89-\u1C8F\u1CBB\u1CBC\u1CC8-\u1CCF\u1CFB-\u1CFF\u1F16\u1F17\u1F1E\u1F1F\u1F46\u1F47\u1F4E\u1F4F\u1F58\u1F5A\u1F5C\u1F5E\u1F7E\u1F7F\u1FB5\u1FC5\u1FD4\u1FD5\u1FDC\u1FF0\u1FF1\u1FF5\u1FFF\u200B-\u200F\u202A-\u202E\u2060-\u206F\u2072\u2073\u208F\u209D-\u209F\u20C1-\u20CF\u20F1-\u20FF\u218C-\u218F\u2427-\u243F\u244B-\u245F\u2B74\u2B75\u2B96\u2CF4-\u2CF8\u2D26\u2D28-\u2D2C\u2D2E\u2D2F\u2D68-\u2D6E\u2D71-\u2D7E\u2D97-\u2D9F\u2DA7\u2DAF\u2DB7\u2DBF\u2DC7\u2DCF\u2DD7\u2DDF\u2E5E-\u2E7F\u2E9A\u2EF4-\u2EFF\u2FD6-\u2FEF\u2FFC-\u2FFF\u3040\u3097\u3098\u3100-\u3104\u3130\u318F\u31E4-\u31EF\u321F\uA48D-\uA48F\uA4C7-\uA4CF\uA62C-\uA63F\uA6F8-\uA6FF\uA7CB-\uA7CF\uA7D2\uA7D4\uA7DA-\uA7F1\uA82D-\uA82F\uA83A-\uA83F\uA878-\uA87F\uA8C6-\uA8CD\uA8DA-\uA8DF\uA954-\uA95E\uA97D-\uA97F\uA9CE\uA9DA-\uA9DD\uA9FF\uAA37-\uAA3F\uAA4E\uAA4F\uAA5A\uAA5B\uAAC3-\uAADA\uAAF7-\uAB00\uAB07\uAB08\uAB0F\uAB10\uAB17-\uAB1F\uAB27\uAB2F\uAB6C-\uAB6F\uABEE\uABEF\uABFA-\uABFF\uD7A4-\uD7AF\uD7C7-\uD7CA\uD7FC-\uF8FF\uFA6E\uFA6F\uFADA-\uFAFF\uFB07-\uFB12\uFB18-\uFB1C\uFB37\uFB3D\uFB3F\uFB42\uFB45\uFBC3-\uFBD2\uFD90\uFD91\uFDC8-\uFDCE\uFDD0-\uFDEF\uFE1A-\uFE1F\uFE53\uFE67\uFE6C-\uFE6F\uFE75\uFEFD-\uFF00\uFFBF-\uFFC1\uFFC8\uFFC9\uFFD0\uFFD1\uFFD8\uFFD9\uFFDD-\uFFDF\uFFE7\uFFEF-\uFFFB\uFFFE\uFFFF',
        'astral': '\uD800[\uDC0C\uDC27\uDC3B\uDC3E\uDC4E\uDC4F\uDC5E-\uDC7F\uDCFB-\uDCFF\uDD03-\uDD06\uDD34-\uDD36\uDD8F\uDD9D-\uDD9F\uDDA1-\uDDCF\uDDFE-\uDE7F\uDE9D-\uDE9F\uDED1-\uDEDF\uDEFC-\uDEFF\uDF24-\uDF2C\uDF4B-\uDF4F\uDF7B-\uDF7F\uDF9E\uDFC4-\uDFC7\uDFD6-\uDFFF]|\uD801[\uDC9E\uDC9F\uDCAA-\uDCAF\uDCD4-\uDCD7\uDCFC-\uDCFF\uDD28-\uDD2F\uDD64-\uDD6E\uDD7B\uDD8B\uDD93\uDD96\uDDA2\uDDB2\uDDBA\uDDBD-\uDDFF\uDF37-\uDF3F\uDF56-\uDF5F\uDF68-\uDF7F\uDF86\uDFB1\uDFBB-\uDFFF]|\uD802[\uDC06\uDC07\uDC09\uDC36\uDC39-\uDC3B\uDC3D\uDC3E\uDC56\uDC9F-\uDCA6\uDCB0-\uDCDF\uDCF3\uDCF6-\uDCFA\uDD1C-\uDD1E\uDD3A-\uDD3E\uDD40-\uDD7F\uDDB8-\uDDBB\uDDD0\uDDD1\uDE04\uDE07-\uDE0B\uDE14\uDE18\uDE36\uDE37\uDE3B-\uDE3E\uDE49-\uDE4F\uDE59-\uDE5F\uDEA0-\uDEBF\uDEE7-\uDEEA\uDEF7-\uDEFF\uDF36-\uDF38\uDF56\uDF57\uDF73-\uDF77\uDF92-\uDF98\uDF9D-\uDFA8\uDFB0-\uDFFF]|\uD803[\uDC49-\uDC7F\uDCB3-\uDCBF\uDCF3-\uDCF9\uDD28-\uDD2F\uDD3A-\uDE5F\uDE7F\uDEAA\uDEAE\uDEAF\uDEB2-\uDEFF\uDF28-\uDF2F\uDF5A-\uDF6F\uDF8A-\uDFAF\uDFCC-\uDFDF\uDFF7-\uDFFF]|\uD804[\uDC4E-\uDC51\uDC76-\uDC7E\uDCBD\uDCC3-\uDCCF\uDCE9-\uDCEF\uDCFA-\uDCFF\uDD35\uDD48-\uDD4F\uDD77-\uDD7F\uDDE0\uDDF5-\uDDFF\uDE12\uDE3F-\uDE7F\uDE87\uDE89\uDE8E\uDE9E\uDEAA-\uDEAF\uDEEB-\uDEEF\uDEFA-\uDEFF\uDF04\uDF0D\uDF0E\uDF11\uDF12\uDF29\uDF31\uDF34\uDF3A\uDF45\uDF46\uDF49\uDF4A\uDF4E\uDF4F\uDF51-\uDF56\uDF58-\uDF5C\uDF64\uDF65\uDF6D-\uDF6F\uDF75-\uDFFF]|\uD805[\uDC5C\uDC62-\uDC7F\uDCC8-\uDCCF\uDCDA-\uDD7F\uDDB6\uDDB7\uDDDE-\uDDFF\uDE45-\uDE4F\uDE5A-\uDE5F\uDE6D-\uDE7F\uDEBA-\uDEBF\uDECA-\uDEFF\uDF1B\uDF1C\uDF2C-\uDF2F\uDF47-\uDFFF]|\uD806[\uDC3C-\uDC9F\uDCF3-\uDCFE\uDD07\uDD08\uDD0A\uDD0B\uDD14\uDD17\uDD36\uDD39\uDD3A\uDD47-\uDD4F\uDD5A-\uDD9F\uDDA8\uDDA9\uDDD8\uDDD9\uDDE5-\uDDFF\uDE48-\uDE4F\uDEA3-\uDEAF\uDEF9-\uDFFF]|\uD807[\uDC09\uDC37\uDC46-\uDC4F\uDC6D-\uDC6F\uDC90\uDC91\uDCA8\uDCB7-\uDCFF\uDD07\uDD0A\uDD37-\uDD39\uDD3B\uDD3E\uDD48-\uDD4F\uDD5A-\uDD5F\uDD66\uDD69\uDD8F\uDD92\uDD99-\uDD9F\uDDAA-\uDEDF\uDEF9-\uDFAF\uDFB1-\uDFBF\uDFF2-\uDFFE]|\uD808[\uDF9A-\uDFFF]|\uD809[\uDC6F\uDC75-\uDC7F\uDD44-\uDFFF]|[\uD80A\uD80E-\uD810\uD812-\uD819\uD824-\uD82A\uD82D\uD82E\uD830-\uD832\uD83F\uD87B-\uD87D\uD87F\uD885-\uDB3F\uDB41-\uDBFF][\uDC00-\uDFFF]|\uD80B[\uDC00-\uDF8F\uDFF3-\uDFFF]|\uD80D[\uDC2F-\uDFFF]|\uD811[\uDE47-\uDFFF]|\uD81A[\uDE39-\uDE3F\uDE5F\uDE6A-\uDE6D\uDEBF\uDECA-\uDECF\uDEEE\uDEEF\uDEF6-\uDEFF\uDF46-\uDF4F\uDF5A\uDF62\uDF78-\uDF7C\uDF90-\uDFFF]|\uD81B[\uDC00-\uDE3F\uDE9B-\uDEFF\uDF4B-\uDF4E\uDF88-\uDF8E\uDFA0-\uDFDF\uDFE5-\uDFEF\uDFF2-\uDFFF]|\uD821[\uDFF8-\uDFFF]|\uD823[\uDCD6-\uDCFF\uDD09-\uDFFF]|\uD82B[\uDC00-\uDFEF\uDFF4\uDFFC\uDFFF]|\uD82C[\uDD23-\uDD4F\uDD53-\uDD63\uDD68-\uDD6F\uDEFC-\uDFFF]|\uD82F[\uDC6B-\uDC6F\uDC7D-\uDC7F\uDC89-\uDC8F\uDC9A\uDC9B\uDCA0-\uDFFF]|\uD833[\uDC00-\uDEFF\uDF2E\uDF2F\uDF47-\uDF4F\uDFC4-\uDFFF]|\uD834[\uDCF6-\uDCFF\uDD27\uDD28\uDD73-\uDD7A\uDDEB-\uDDFF\uDE46-\uDEDF\uDEF4-\uDEFF\uDF57-\uDF5F\uDF79-\uDFFF]|\uD835[\uDC55\uDC9D\uDCA0\uDCA1\uDCA3\uDCA4\uDCA7\uDCA8\uDCAD\uDCBA\uDCBC\uDCC4\uDD06\uDD0B\uDD0C\uDD15\uDD1D\uDD3A\uDD3F\uDD45\uDD47-\uDD49\uDD51\uDEA6\uDEA7\uDFCC\uDFCD]|\uD836[\uDE8C-\uDE9A\uDEA0\uDEB0-\uDFFF]|\uD837[\uDC00-\uDEFF\uDF1F-\uDFFF]|\uD838[\uDC07\uDC19\uDC1A\uDC22\uDC25\uDC2B-\uDCFF\uDD2D-\uDD2F\uDD3E\uDD3F\uDD4A-\uDD4D\uDD50-\uDE8F\uDEAF-\uDEBF\uDEFA-\uDEFE\uDF00-\uDFFF]|\uD839[\uDC00-\uDFDF\uDFE7\uDFEC\uDFEF\uDFFF]|\uD83A[\uDCC5\uDCC6\uDCD7-\uDCFF\uDD4C-\uDD4F\uDD5A-\uDD5D\uDD60-\uDFFF]|\uD83B[\uDC00-\uDC70\uDCB5-\uDD00\uDD3E-\uDDFF\uDE04\uDE20\uDE23\uDE25\uDE26\uDE28\uDE33\uDE38\uDE3A\uDE3C-\uDE41\uDE43-\uDE46\uDE48\uDE4A\uDE4C\uDE50\uDE53\uDE55\uDE56\uDE58\uDE5A\uDE5C\uDE5E\uDE60\uDE63\uDE65\uDE66\uDE6B\uDE73\uDE78\uDE7D\uDE7F\uDE8A\uDE9C-\uDEA0\uDEA4\uDEAA\uDEBC-\uDEEF\uDEF2-\uDFFF]|\uD83C[\uDC2C-\uDC2F\uDC94-\uDC9F\uDCAF\uDCB0\uDCC0\uDCD0\uDCF6-\uDCFF\uDDAE-\uDDE5\uDE03-\uDE0F\uDE3C-\uDE3F\uDE49-\uDE4F\uDE52-\uDE5F\uDE66-\uDEFF]|\uD83D[\uDED8-\uDEDC\uDEED-\uDEEF\uDEFD-\uDEFF\uDF74-\uDF7F\uDFD9-\uDFDF\uDFEC-\uDFEF\uDFF1-\uDFFF]|\uD83E[\uDC0C-\uDC0F\uDC48-\uDC4F\uDC5A-\uDC5F\uDC88-\uDC8F\uDCAE\uDCAF\uDCB2-\uDCFF\uDE54-\uDE5F\uDE6E\uDE6F\uDE75-\uDE77\uDE7D-\uDE7F\uDE87-\uDE8F\uDEAD-\uDEAF\uDEBB-\uDEBF\uDEC6-\uDECF\uDEDA-\uDEDF\uDEE8-\uDEEF\uDEF7-\uDEFF\uDF93\uDFCB-\uDFEF\uDFFA-\uDFFF]|\uD869[\uDEE0-\uDEFF]|\uD86D[\uDF39-\uDF3F]|\uD86E[\uDC1E\uDC1F]|\uD873[\uDEA2-\uDEAF]|\uD87A[\uDFE1-\uDFFF]|\uD87E[\uDE1E-\uDFFF]|\uD884[\uDF4B-\uDFFF]|\uDB40[\uDC00-\uDCFF\uDDF0-\uDFFF]'
    },
    {
        'name': 'Cc',
        'alias': 'Control',
        'bmp': '\0-\x1F\x7F-\x9F'
    },
    {
        'name': 'Cf',
        'alias': 'Format',
        'bmp': '\xAD\u0600-\u0605\u061C\u06DD\u070F\u0890\u0891\u08E2\u180E\u200B-\u200F\u202A-\u202E\u2060-\u2064\u2066-\u206F\uFEFF\uFFF9-\uFFFB',
        'astral': '\uD804[\uDCBD\uDCCD]|\uD80D[\uDC30-\uDC38]|\uD82F[\uDCA0-\uDCA3]|\uD834[\uDD73-\uDD7A]|\uDB40[\uDC01\uDC20-\uDC7F]'
    },
    {
        'name': 'Cn',
        'alias': 'Unassigned',
        'bmp': '\u0378\u0379\u0380-\u0383\u038B\u038D\u03A2\u0530\u0557\u0558\u058B\u058C\u0590\u05C8-\u05CF\u05EB-\u05EE\u05F5-\u05FF\u070E\u074B\u074C\u07B2-\u07BF\u07FB\u07FC\u082E\u082F\u083F\u085C\u085D\u085F\u086B-\u086F\u088F\u0892-\u0897\u0984\u098D\u098E\u0991\u0992\u09A9\u09B1\u09B3-\u09B5\u09BA\u09BB\u09C5\u09C6\u09C9\u09CA\u09CF-\u09D6\u09D8-\u09DB\u09DE\u09E4\u09E5\u09FF\u0A00\u0A04\u0A0B-\u0A0E\u0A11\u0A12\u0A29\u0A31\u0A34\u0A37\u0A3A\u0A3B\u0A3D\u0A43-\u0A46\u0A49\u0A4A\u0A4E-\u0A50\u0A52-\u0A58\u0A5D\u0A5F-\u0A65\u0A77-\u0A80\u0A84\u0A8E\u0A92\u0AA9\u0AB1\u0AB4\u0ABA\u0ABB\u0AC6\u0ACA\u0ACE\u0ACF\u0AD1-\u0ADF\u0AE4\u0AE5\u0AF2-\u0AF8\u0B00\u0B04\u0B0D\u0B0E\u0B11\u0B12\u0B29\u0B31\u0B34\u0B3A\u0B3B\u0B45\u0B46\u0B49\u0B4A\u0B4E-\u0B54\u0B58-\u0B5B\u0B5E\u0B64\u0B65\u0B78-\u0B81\u0B84\u0B8B-\u0B8D\u0B91\u0B96-\u0B98\u0B9B\u0B9D\u0BA0-\u0BA2\u0BA5-\u0BA7\u0BAB-\u0BAD\u0BBA-\u0BBD\u0BC3-\u0BC5\u0BC9\u0BCE\u0BCF\u0BD1-\u0BD6\u0BD8-\u0BE5\u0BFB-\u0BFF\u0C0D\u0C11\u0C29\u0C3A\u0C3B\u0C45\u0C49\u0C4E-\u0C54\u0C57\u0C5B\u0C5C\u0C5E\u0C5F\u0C64\u0C65\u0C70-\u0C76\u0C8D\u0C91\u0CA9\u0CB4\u0CBA\u0CBB\u0CC5\u0CC9\u0CCE-\u0CD4\u0CD7-\u0CDC\u0CDF\u0CE4\u0CE5\u0CF0\u0CF3-\u0CFF\u0D0D\u0D11\u0D45\u0D49\u0D50-\u0D53\u0D64\u0D65\u0D80\u0D84\u0D97-\u0D99\u0DB2\u0DBC\u0DBE\u0DBF\u0DC7-\u0DC9\u0DCB-\u0DCE\u0DD5\u0DD7\u0DE0-\u0DE5\u0DF0\u0DF1\u0DF5-\u0E00\u0E3B-\u0E3E\u0E5C-\u0E80\u0E83\u0E85\u0E8B\u0EA4\u0EA6\u0EBE\u0EBF\u0EC5\u0EC7\u0ECE\u0ECF\u0EDA\u0EDB\u0EE0-\u0EFF\u0F48\u0F6D-\u0F70\u0F98\u0FBD\u0FCD\u0FDB-\u0FFF\u10C6\u10C8-\u10CC\u10CE\u10CF\u1249\u124E\u124F\u1257\u1259\u125E\u125F\u1289\u128E\u128F\u12B1\u12B6\u12B7\u12BF\u12C1\u12C6\u12C7\u12D7\u1311\u1316\u1317\u135B\u135C\u137D-\u137F\u139A-\u139F\u13F6\u13F7\u13FE\u13FF\u169D-\u169F\u16F9-\u16FF\u1716-\u171E\u1737-\u173F\u1754-\u175F\u176D\u1771\u1774-\u177F\u17DE\u17DF\u17EA-\u17EF\u17FA-\u17FF\u181A-\u181F\u1879-\u187F\u18AB-\u18AF\u18F6-\u18FF\u191F\u192C-\u192F\u193C-\u193F\u1941-\u1943\u196E\u196F\u1975-\u197F\u19AC-\u19AF\u19CA-\u19CF\u19DB-\u19DD\u1A1C\u1A1D\u1A5F\u1A7D\u1A7E\u1A8A-\u1A8F\u1A9A-\u1A9F\u1AAE\u1AAF\u1ACF-\u1AFF\u1B4D-\u1B4F\u1B7F\u1BF4-\u1BFB\u1C38-\u1C3A\u1C4A-\u1C4C\u1C89-\u1C8F\u1CBB\u1CBC\u1CC8-\u1CCF\u1CFB-\u1CFF\u1F16\u1F17\u1F1E\u1F1F\u1F46\u1F47\u1F4E\u1F4F\u1F58\u1F5A\u1F5C\u1F5E\u1F7E\u1F7F\u1FB5\u1FC5\u1FD4\u1FD5\u1FDC\u1FF0\u1FF1\u1FF5\u1FFF\u2065\u2072\u2073\u208F\u209D-\u209F\u20C1-\u20CF\u20F1-\u20FF\u218C-\u218F\u2427-\u243F\u244B-\u245F\u2B74\u2B75\u2B96\u2CF4-\u2CF8\u2D26\u2D28-\u2D2C\u2D2E\u2D2F\u2D68-\u2D6E\u2D71-\u2D7E\u2D97-\u2D9F\u2DA7\u2DAF\u2DB7\u2DBF\u2DC7\u2DCF\u2DD7\u2DDF\u2E5E-\u2E7F\u2E9A\u2EF4-\u2EFF\u2FD6-\u2FEF\u2FFC-\u2FFF\u3040\u3097\u3098\u3100-\u3104\u3130\u318F\u31E4-\u31EF\u321F\uA48D-\uA48F\uA4C7-\uA4CF\uA62C-\uA63F\uA6F8-\uA6FF\uA7CB-\uA7CF\uA7D2\uA7D4\uA7DA-\uA7F1\uA82D-\uA82F\uA83A-\uA83F\uA878-\uA87F\uA8C6-\uA8CD\uA8DA-\uA8DF\uA954-\uA95E\uA97D-\uA97F\uA9CE\uA9DA-\uA9DD\uA9FF\uAA37-\uAA3F\uAA4E\uAA4F\uAA5A\uAA5B\uAAC3-\uAADA\uAAF7-\uAB00\uAB07\uAB08\uAB0F\uAB10\uAB17-\uAB1F\uAB27\uAB2F\uAB6C-\uAB6F\uABEE\uABEF\uABFA-\uABFF\uD7A4-\uD7AF\uD7C7-\uD7CA\uD7FC-\uD7FF\uFA6E\uFA6F\uFADA-\uFAFF\uFB07-\uFB12\uFB18-\uFB1C\uFB37\uFB3D\uFB3F\uFB42\uFB45\uFBC3-\uFBD2\uFD90\uFD91\uFDC8-\uFDCE\uFDD0-\uFDEF\uFE1A-\uFE1F\uFE53\uFE67\uFE6C-\uFE6F\uFE75\uFEFD\uFEFE\uFF00\uFFBF-\uFFC1\uFFC8\uFFC9\uFFD0\uFFD1\uFFD8\uFFD9\uFFDD-\uFFDF\uFFE7\uFFEF-\uFFF8\uFFFE\uFFFF',
        'astral': '\uD800[\uDC0C\uDC27\uDC3B\uDC3E\uDC4E\uDC4F\uDC5E-\uDC7F\uDCFB-\uDCFF\uDD03-\uDD06\uDD34-\uDD36\uDD8F\uDD9D-\uDD9F\uDDA1-\uDDCF\uDDFE-\uDE7F\uDE9D-\uDE9F\uDED1-\uDEDF\uDEFC-\uDEFF\uDF24-\uDF2C\uDF4B-\uDF4F\uDF7B-\uDF7F\uDF9E\uDFC4-\uDFC7\uDFD6-\uDFFF]|\uD801[\uDC9E\uDC9F\uDCAA-\uDCAF\uDCD4-\uDCD7\uDCFC-\uDCFF\uDD28-\uDD2F\uDD64-\uDD6E\uDD7B\uDD8B\uDD93\uDD96\uDDA2\uDDB2\uDDBA\uDDBD-\uDDFF\uDF37-\uDF3F\uDF56-\uDF5F\uDF68-\uDF7F\uDF86\uDFB1\uDFBB-\uDFFF]|\uD802[\uDC06\uDC07\uDC09\uDC36\uDC39-\uDC3B\uDC3D\uDC3E\uDC56\uDC9F-\uDCA6\uDCB0-\uDCDF\uDCF3\uDCF6-\uDCFA\uDD1C-\uDD1E\uDD3A-\uDD3E\uDD40-\uDD7F\uDDB8-\uDDBB\uDDD0\uDDD1\uDE04\uDE07-\uDE0B\uDE14\uDE18\uDE36\uDE37\uDE3B-\uDE3E\uDE49-\uDE4F\uDE59-\uDE5F\uDEA0-\uDEBF\uDEE7-\uDEEA\uDEF7-\uDEFF\uDF36-\uDF38\uDF56\uDF57\uDF73-\uDF77\uDF92-\uDF98\uDF9D-\uDFA8\uDFB0-\uDFFF]|\uD803[\uDC49-\uDC7F\uDCB3-\uDCBF\uDCF3-\uDCF9\uDD28-\uDD2F\uDD3A-\uDE5F\uDE7F\uDEAA\uDEAE\uDEAF\uDEB2-\uDEFF\uDF28-\uDF2F\uDF5A-\uDF6F\uDF8A-\uDFAF\uDFCC-\uDFDF\uDFF7-\uDFFF]|\uD804[\uDC4E-\uDC51\uDC76-\uDC7E\uDCC3-\uDCCC\uDCCE\uDCCF\uDCE9-\uDCEF\uDCFA-\uDCFF\uDD35\uDD48-\uDD4F\uDD77-\uDD7F\uDDE0\uDDF5-\uDDFF\uDE12\uDE3F-\uDE7F\uDE87\uDE89\uDE8E\uDE9E\uDEAA-\uDEAF\uDEEB-\uDEEF\uDEFA-\uDEFF\uDF04\uDF0D\uDF0E\uDF11\uDF12\uDF29\uDF31\uDF34\uDF3A\uDF45\uDF46\uDF49\uDF4A\uDF4E\uDF4F\uDF51-\uDF56\uDF58-\uDF5C\uDF64\uDF65\uDF6D-\uDF6F\uDF75-\uDFFF]|\uD805[\uDC5C\uDC62-\uDC7F\uDCC8-\uDCCF\uDCDA-\uDD7F\uDDB6\uDDB7\uDDDE-\uDDFF\uDE45-\uDE4F\uDE5A-\uDE5F\uDE6D-\uDE7F\uDEBA-\uDEBF\uDECA-\uDEFF\uDF1B\uDF1C\uDF2C-\uDF2F\uDF47-\uDFFF]|\uD806[\uDC3C-\uDC9F\uDCF3-\uDCFE\uDD07\uDD08\uDD0A\uDD0B\uDD14\uDD17\uDD36\uDD39\uDD3A\uDD47-\uDD4F\uDD5A-\uDD9F\uDDA8\uDDA9\uDDD8\uDDD9\uDDE5-\uDDFF\uDE48-\uDE4F\uDEA3-\uDEAF\uDEF9-\uDFFF]|\uD807[\uDC09\uDC37\uDC46-\uDC4F\uDC6D-\uDC6F\uDC90\uDC91\uDCA8\uDCB7-\uDCFF\uDD07\uDD0A\uDD37-\uDD39\uDD3B\uDD3E\uDD48-\uDD4F\uDD5A-\uDD5F\uDD66\uDD69\uDD8F\uDD92\uDD99-\uDD9F\uDDAA-\uDEDF\uDEF9-\uDFAF\uDFB1-\uDFBF\uDFF2-\uDFFE]|\uD808[\uDF9A-\uDFFF]|\uD809[\uDC6F\uDC75-\uDC7F\uDD44-\uDFFF]|[\uD80A\uD80E-\uD810\uD812-\uD819\uD824-\uD82A\uD82D\uD82E\uD830-\uD832\uD83F\uD87B-\uD87D\uD87F\uD885-\uDB3F\uDB41-\uDB7F][\uDC00-\uDFFF]|\uD80B[\uDC00-\uDF8F\uDFF3-\uDFFF]|\uD80D[\uDC2F\uDC39-\uDFFF]|\uD811[\uDE47-\uDFFF]|\uD81A[\uDE39-\uDE3F\uDE5F\uDE6A-\uDE6D\uDEBF\uDECA-\uDECF\uDEEE\uDEEF\uDEF6-\uDEFF\uDF46-\uDF4F\uDF5A\uDF62\uDF78-\uDF7C\uDF90-\uDFFF]|\uD81B[\uDC00-\uDE3F\uDE9B-\uDEFF\uDF4B-\uDF4E\uDF88-\uDF8E\uDFA0-\uDFDF\uDFE5-\uDFEF\uDFF2-\uDFFF]|\uD821[\uDFF8-\uDFFF]|\uD823[\uDCD6-\uDCFF\uDD09-\uDFFF]|\uD82B[\uDC00-\uDFEF\uDFF4\uDFFC\uDFFF]|\uD82C[\uDD23-\uDD4F\uDD53-\uDD63\uDD68-\uDD6F\uDEFC-\uDFFF]|\uD82F[\uDC6B-\uDC6F\uDC7D-\uDC7F\uDC89-\uDC8F\uDC9A\uDC9B\uDCA4-\uDFFF]|\uD833[\uDC00-\uDEFF\uDF2E\uDF2F\uDF47-\uDF4F\uDFC4-\uDFFF]|\uD834[\uDCF6-\uDCFF\uDD27\uDD28\uDDEB-\uDDFF\uDE46-\uDEDF\uDEF4-\uDEFF\uDF57-\uDF5F\uDF79-\uDFFF]|\uD835[\uDC55\uDC9D\uDCA0\uDCA1\uDCA3\uDCA4\uDCA7\uDCA8\uDCAD\uDCBA\uDCBC\uDCC4\uDD06\uDD0B\uDD0C\uDD15\uDD1D\uDD3A\uDD3F\uDD45\uDD47-\uDD49\uDD51\uDEA6\uDEA7\uDFCC\uDFCD]|\uD836[\uDE8C-\uDE9A\uDEA0\uDEB0-\uDFFF]|\uD837[\uDC00-\uDEFF\uDF1F-\uDFFF]|\uD838[\uDC07\uDC19\uDC1A\uDC22\uDC25\uDC2B-\uDCFF\uDD2D-\uDD2F\uDD3E\uDD3F\uDD4A-\uDD4D\uDD50-\uDE8F\uDEAF-\uDEBF\uDEFA-\uDEFE\uDF00-\uDFFF]|\uD839[\uDC00-\uDFDF\uDFE7\uDFEC\uDFEF\uDFFF]|\uD83A[\uDCC5\uDCC6\uDCD7-\uDCFF\uDD4C-\uDD4F\uDD5A-\uDD5D\uDD60-\uDFFF]|\uD83B[\uDC00-\uDC70\uDCB5-\uDD00\uDD3E-\uDDFF\uDE04\uDE20\uDE23\uDE25\uDE26\uDE28\uDE33\uDE38\uDE3A\uDE3C-\uDE41\uDE43-\uDE46\uDE48\uDE4A\uDE4C\uDE50\uDE53\uDE55\uDE56\uDE58\uDE5A\uDE5C\uDE5E\uDE60\uDE63\uDE65\uDE66\uDE6B\uDE73\uDE78\uDE7D\uDE7F\uDE8A\uDE9C-\uDEA0\uDEA4\uDEAA\uDEBC-\uDEEF\uDEF2-\uDFFF]|\uD83C[\uDC2C-\uDC2F\uDC94-\uDC9F\uDCAF\uDCB0\uDCC0\uDCD0\uDCF6-\uDCFF\uDDAE-\uDDE5\uDE03-\uDE0F\uDE3C-\uDE3F\uDE49-\uDE4F\uDE52-\uDE5F\uDE66-\uDEFF]|\uD83D[\uDED8-\uDEDC\uDEED-\uDEEF\uDEFD-\uDEFF\uDF74-\uDF7F\uDFD9-\uDFDF\uDFEC-\uDFEF\uDFF1-\uDFFF]|\uD83E[\uDC0C-\uDC0F\uDC48-\uDC4F\uDC5A-\uDC5F\uDC88-\uDC8F\uDCAE\uDCAF\uDCB2-\uDCFF\uDE54-\uDE5F\uDE6E\uDE6F\uDE75-\uDE77\uDE7D-\uDE7F\uDE87-\uDE8F\uDEAD-\uDEAF\uDEBB-\uDEBF\uDEC6-\uDECF\uDEDA-\uDEDF\uDEE8-\uDEEF\uDEF7-\uDEFF\uDF93\uDFCB-\uDFEF\uDFFA-\uDFFF]|\uD869[\uDEE0-\uDEFF]|\uD86D[\uDF39-\uDF3F]|\uD86E[\uDC1E\uDC1F]|\uD873[\uDEA2-\uDEAF]|\uD87A[\uDFE1-\uDFFF]|\uD87E[\uDE1E-\uDFFF]|\uD884[\uDF4B-\uDFFF]|\uDB40[\uDC00\uDC02-\uDC1F\uDC80-\uDCFF\uDDF0-\uDFFF]|[\uDBBF\uDBFF][\uDFFE\uDFFF]'
    },
    {
        'name': 'Co',
        'alias': 'Private_Use',
        'bmp': '\uE000-\uF8FF',
        'astral': '[\uDB80-\uDBBE\uDBC0-\uDBFE][\uDC00-\uDFFF]|[\uDBBF\uDBFF][\uDC00-\uDFFD]'
    },
    {
        'name': 'Cs',
        'alias': 'Surrogate',
        'bmp': '\uD800-\uDFFF'
    },
    {
        'name': 'L',
        'alias': 'Letter',
        'bmp': 'A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05D0-\u05EA\u05EF-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u0870-\u0887\u0889-\u088E\u08A0-\u08C9\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C5D\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u1711\u171F-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1878\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4C\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005\u3006\u3031-\u3035\u303B\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u31A0-\u31BF\u31F0-\u31FF\u3400-\u4DBF\u4E00-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6E5\uA717-\uA71F\uA722-\uA788\uA78B-\uA7CA\uA7D0\uA7D1\uA7D3\uA7D5-\uA7D9\uA7F2-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC',
        'astral': '\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF40\uDF42-\uDF49\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDD70-\uDD7A\uDD7C-\uDD8A\uDD8C-\uDD92\uDD94\uDD95\uDD97-\uDDA1\uDDA3-\uDDB1\uDDB3-\uDDB9\uDDBB\uDDBC\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67\uDF80-\uDF85\uDF87-\uDFB0\uDFB2-\uDFBA]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDD00-\uDD23\uDE80-\uDEA9\uDEB0\uDEB1\uDF00-\uDF1C\uDF27\uDF30-\uDF45\uDF70-\uDF81\uDFB0-\uDFC4\uDFE0-\uDFF6]|\uD804[\uDC03-\uDC37\uDC71\uDC72\uDC75\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD44\uDD47\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC5F-\uDC61\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDEB8\uDF00-\uDF1A\uDF40-\uDF46]|\uD806[\uDC00-\uDC2B\uDCA0-\uDCDF\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD2F\uDD3F\uDD41\uDDA0-\uDDA7\uDDAA-\uDDD0\uDDE1\uDDE3\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE89\uDE9D\uDEB0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD89\uDD98\uDEE0-\uDEF2\uDFB0]|\uD808[\uDC00-\uDF99]|\uD809[\uDC80-\uDD43]|\uD80B[\uDF90-\uDFF0]|[\uD80C\uD81C-\uD820\uD822\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879\uD880-\uD883][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE70-\uDEBE\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDE40-\uDE7F\uDF00-\uDF4A\uDF50\uDF93-\uDF9F\uDFE0\uDFE1\uDFE3]|\uD821[\uDC00-\uDFF7]|\uD823[\uDC00-\uDCD5\uDD00-\uDD08]|\uD82B[\uDFF0-\uDFF3\uDFF5-\uDFFB\uDFFD\uDFFE]|\uD82C[\uDC00-\uDD22\uDD50-\uDD52\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD837[\uDF00-\uDF1E]|\uD838[\uDD00-\uDD2C\uDD37-\uDD3D\uDD4E\uDE90-\uDEAD\uDEC0-\uDEEB]|\uD839[\uDFE0-\uDFE6\uDFE8-\uDFEB\uDFED\uDFEE\uDFF0-\uDFFE]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43\uDD4B]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDEDF\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF38\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A]'
    },
    {
        'name': 'LC',
        'alias': 'Cased_Letter',
        'bmp': 'A-Za-z\xB5\xC0-\xD6\xD8-\xF6\xF8-\u01BA\u01BC-\u01BF\u01C4-\u0293\u0295-\u02AF\u0370-\u0373\u0376\u0377\u037B-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0560-\u0588\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FD-\u10FF\u13A0-\u13F5\u13F8-\u13FD\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1D00-\u1D2B\u1D6B-\u1D77\u1D79-\u1D9A\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2134\u2139\u213C-\u213F\u2145-\u2149\u214E\u2183\u2184\u2C00-\u2C7B\u2C7E-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\uA640-\uA66D\uA680-\uA69B\uA722-\uA76F\uA771-\uA787\uA78B-\uA78E\uA790-\uA7CA\uA7D0\uA7D1\uA7D3\uA7D5-\uA7D9\uA7F5\uA7F6\uA7FA\uAB30-\uAB5A\uAB60-\uAB68\uAB70-\uABBF\uFB00-\uFB06\uFB13-\uFB17\uFF21-\uFF3A\uFF41-\uFF5A',
        'astral': '\uD801[\uDC00-\uDC4F\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD70-\uDD7A\uDD7C-\uDD8A\uDD8C-\uDD92\uDD94\uDD95\uDD97-\uDDA1\uDDA3-\uDDB1\uDDB3-\uDDB9\uDDBB\uDDBC]|\uD803[\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD806[\uDCA0-\uDCDF]|\uD81B[\uDE40-\uDE7F]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD837[\uDF00-\uDF09\uDF0B-\uDF1E]|\uD83A[\uDD00-\uDD43]'
    },
    {
        'name': 'Ll',
        'alias': 'Lowercase_Letter',
        'bmp': 'a-z\xB5\xDF-\xF6\xF8-\xFF\u0101\u0103\u0105\u0107\u0109\u010B\u010D\u010F\u0111\u0113\u0115\u0117\u0119\u011B\u011D\u011F\u0121\u0123\u0125\u0127\u0129\u012B\u012D\u012F\u0131\u0133\u0135\u0137\u0138\u013A\u013C\u013E\u0140\u0142\u0144\u0146\u0148\u0149\u014B\u014D\u014F\u0151\u0153\u0155\u0157\u0159\u015B\u015D\u015F\u0161\u0163\u0165\u0167\u0169\u016B\u016D\u016F\u0171\u0173\u0175\u0177\u017A\u017C\u017E-\u0180\u0183\u0185\u0188\u018C\u018D\u0192\u0195\u0199-\u019B\u019E\u01A1\u01A3\u01A5\u01A8\u01AA\u01AB\u01AD\u01B0\u01B4\u01B6\u01B9\u01BA\u01BD-\u01BF\u01C6\u01C9\u01CC\u01CE\u01D0\u01D2\u01D4\u01D6\u01D8\u01DA\u01DC\u01DD\u01DF\u01E1\u01E3\u01E5\u01E7\u01E9\u01EB\u01ED\u01EF\u01F0\u01F3\u01F5\u01F9\u01FB\u01FD\u01FF\u0201\u0203\u0205\u0207\u0209\u020B\u020D\u020F\u0211\u0213\u0215\u0217\u0219\u021B\u021D\u021F\u0221\u0223\u0225\u0227\u0229\u022B\u022D\u022F\u0231\u0233-\u0239\u023C\u023F\u0240\u0242\u0247\u0249\u024B\u024D\u024F-\u0293\u0295-\u02AF\u0371\u0373\u0377\u037B-\u037D\u0390\u03AC-\u03CE\u03D0\u03D1\u03D5-\u03D7\u03D9\u03DB\u03DD\u03DF\u03E1\u03E3\u03E5\u03E7\u03E9\u03EB\u03ED\u03EF-\u03F3\u03F5\u03F8\u03FB\u03FC\u0430-\u045F\u0461\u0463\u0465\u0467\u0469\u046B\u046D\u046F\u0471\u0473\u0475\u0477\u0479\u047B\u047D\u047F\u0481\u048B\u048D\u048F\u0491\u0493\u0495\u0497\u0499\u049B\u049D\u049F\u04A1\u04A3\u04A5\u04A7\u04A9\u04AB\u04AD\u04AF\u04B1\u04B3\u04B5\u04B7\u04B9\u04BB\u04BD\u04BF\u04C2\u04C4\u04C6\u04C8\u04CA\u04CC\u04CE\u04CF\u04D1\u04D3\u04D5\u04D7\u04D9\u04DB\u04DD\u04DF\u04E1\u04E3\u04E5\u04E7\u04E9\u04EB\u04ED\u04EF\u04F1\u04F3\u04F5\u04F7\u04F9\u04FB\u04FD\u04FF\u0501\u0503\u0505\u0507\u0509\u050B\u050D\u050F\u0511\u0513\u0515\u0517\u0519\u051B\u051D\u051F\u0521\u0523\u0525\u0527\u0529\u052B\u052D\u052F\u0560-\u0588\u10D0-\u10FA\u10FD-\u10FF\u13F8-\u13FD\u1C80-\u1C88\u1D00-\u1D2B\u1D6B-\u1D77\u1D79-\u1D9A\u1E01\u1E03\u1E05\u1E07\u1E09\u1E0B\u1E0D\u1E0F\u1E11\u1E13\u1E15\u1E17\u1E19\u1E1B\u1E1D\u1E1F\u1E21\u1E23\u1E25\u1E27\u1E29\u1E2B\u1E2D\u1E2F\u1E31\u1E33\u1E35\u1E37\u1E39\u1E3B\u1E3D\u1E3F\u1E41\u1E43\u1E45\u1E47\u1E49\u1E4B\u1E4D\u1E4F\u1E51\u1E53\u1E55\u1E57\u1E59\u1E5B\u1E5D\u1E5F\u1E61\u1E63\u1E65\u1E67\u1E69\u1E6B\u1E6D\u1E6F\u1E71\u1E73\u1E75\u1E77\u1E79\u1E7B\u1E7D\u1E7F\u1E81\u1E83\u1E85\u1E87\u1E89\u1E8B\u1E8D\u1E8F\u1E91\u1E93\u1E95-\u1E9D\u1E9F\u1EA1\u1EA3\u1EA5\u1EA7\u1EA9\u1EAB\u1EAD\u1EAF\u1EB1\u1EB3\u1EB5\u1EB7\u1EB9\u1EBB\u1EBD\u1EBF\u1EC1\u1EC3\u1EC5\u1EC7\u1EC9\u1ECB\u1ECD\u1ECF\u1ED1\u1ED3\u1ED5\u1ED7\u1ED9\u1EDB\u1EDD\u1EDF\u1EE1\u1EE3\u1EE5\u1EE7\u1EE9\u1EEB\u1EED\u1EEF\u1EF1\u1EF3\u1EF5\u1EF7\u1EF9\u1EFB\u1EFD\u1EFF-\u1F07\u1F10-\u1F15\u1F20-\u1F27\u1F30-\u1F37\u1F40-\u1F45\u1F50-\u1F57\u1F60-\u1F67\u1F70-\u1F7D\u1F80-\u1F87\u1F90-\u1F97\u1FA0-\u1FA7\u1FB0-\u1FB4\u1FB6\u1FB7\u1FBE\u1FC2-\u1FC4\u1FC6\u1FC7\u1FD0-\u1FD3\u1FD6\u1FD7\u1FE0-\u1FE7\u1FF2-\u1FF4\u1FF6\u1FF7\u210A\u210E\u210F\u2113\u212F\u2134\u2139\u213C\u213D\u2146-\u2149\u214E\u2184\u2C30-\u2C5F\u2C61\u2C65\u2C66\u2C68\u2C6A\u2C6C\u2C71\u2C73\u2C74\u2C76-\u2C7B\u2C81\u2C83\u2C85\u2C87\u2C89\u2C8B\u2C8D\u2C8F\u2C91\u2C93\u2C95\u2C97\u2C99\u2C9B\u2C9D\u2C9F\u2CA1\u2CA3\u2CA5\u2CA7\u2CA9\u2CAB\u2CAD\u2CAF\u2CB1\u2CB3\u2CB5\u2CB7\u2CB9\u2CBB\u2CBD\u2CBF\u2CC1\u2CC3\u2CC5\u2CC7\u2CC9\u2CCB\u2CCD\u2CCF\u2CD1\u2CD3\u2CD5\u2CD7\u2CD9\u2CDB\u2CDD\u2CDF\u2CE1\u2CE3\u2CE4\u2CEC\u2CEE\u2CF3\u2D00-\u2D25\u2D27\u2D2D\uA641\uA643\uA645\uA647\uA649\uA64B\uA64D\uA64F\uA651\uA653\uA655\uA657\uA659\uA65B\uA65D\uA65F\uA661\uA663\uA665\uA667\uA669\uA66B\uA66D\uA681\uA683\uA685\uA687\uA689\uA68B\uA68D\uA68F\uA691\uA693\uA695\uA697\uA699\uA69B\uA723\uA725\uA727\uA729\uA72B\uA72D\uA72F-\uA731\uA733\uA735\uA737\uA739\uA73B\uA73D\uA73F\uA741\uA743\uA745\uA747\uA749\uA74B\uA74D\uA74F\uA751\uA753\uA755\uA757\uA759\uA75B\uA75D\uA75F\uA761\uA763\uA765\uA767\uA769\uA76B\uA76D\uA76F\uA771-\uA778\uA77A\uA77C\uA77F\uA781\uA783\uA785\uA787\uA78C\uA78E\uA791\uA793-\uA795\uA797\uA799\uA79B\uA79D\uA79F\uA7A1\uA7A3\uA7A5\uA7A7\uA7A9\uA7AF\uA7B5\uA7B7\uA7B9\uA7BB\uA7BD\uA7BF\uA7C1\uA7C3\uA7C8\uA7CA\uA7D1\uA7D3\uA7D5\uA7D7\uA7D9\uA7F6\uA7FA\uAB30-\uAB5A\uAB60-\uAB68\uAB70-\uABBF\uFB00-\uFB06\uFB13-\uFB17\uFF41-\uFF5A',
        'astral': '\uD801[\uDC28-\uDC4F\uDCD8-\uDCFB\uDD97-\uDDA1\uDDA3-\uDDB1\uDDB3-\uDDB9\uDDBB\uDDBC]|\uD803[\uDCC0-\uDCF2]|\uD806[\uDCC0-\uDCDF]|\uD81B[\uDE60-\uDE7F]|\uD835[\uDC1A-\uDC33\uDC4E-\uDC54\uDC56-\uDC67\uDC82-\uDC9B\uDCB6-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDCCF\uDCEA-\uDD03\uDD1E-\uDD37\uDD52-\uDD6B\uDD86-\uDD9F\uDDBA-\uDDD3\uDDEE-\uDE07\uDE22-\uDE3B\uDE56-\uDE6F\uDE8A-\uDEA5\uDEC2-\uDEDA\uDEDC-\uDEE1\uDEFC-\uDF14\uDF16-\uDF1B\uDF36-\uDF4E\uDF50-\uDF55\uDF70-\uDF88\uDF8A-\uDF8F\uDFAA-\uDFC2\uDFC4-\uDFC9\uDFCB]|\uD837[\uDF00-\uDF09\uDF0B-\uDF1E]|\uD83A[\uDD22-\uDD43]'
    },
    {
        'name': 'Lm',
        'alias': 'Modifier_Letter',
        'bmp': '\u02B0-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0374\u037A\u0559\u0640\u06E5\u06E6\u07F4\u07F5\u07FA\u081A\u0824\u0828\u08C9\u0971\u0E46\u0EC6\u10FC\u17D7\u1843\u1AA7\u1C78-\u1C7D\u1D2C-\u1D6A\u1D78\u1D9B-\u1DBF\u2071\u207F\u2090-\u209C\u2C7C\u2C7D\u2D6F\u2E2F\u3005\u3031-\u3035\u303B\u309D\u309E\u30FC-\u30FE\uA015\uA4F8-\uA4FD\uA60C\uA67F\uA69C\uA69D\uA717-\uA71F\uA770\uA788\uA7F2-\uA7F4\uA7F8\uA7F9\uA9CF\uA9E6\uAA70\uAADD\uAAF3\uAAF4\uAB5C-\uAB5F\uAB69\uFF70\uFF9E\uFF9F',
        'astral': '\uD801[\uDF80-\uDF85\uDF87-\uDFB0\uDFB2-\uDFBA]|\uD81A[\uDF40-\uDF43]|\uD81B[\uDF93-\uDF9F\uDFE0\uDFE1\uDFE3]|\uD82B[\uDFF0-\uDFF3\uDFF5-\uDFFB\uDFFD\uDFFE]|\uD838[\uDD37-\uDD3D]|\uD83A\uDD4B'
    },
    {
        'name': 'Lo',
        'alias': 'Other_Letter',
        'bmp': '\xAA\xBA\u01BB\u01C0-\u01C3\u0294\u05D0-\u05EA\u05EF-\u05F2\u0620-\u063F\u0641-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u0800-\u0815\u0840-\u0858\u0860-\u086A\u0870-\u0887\u0889-\u088E\u08A0-\u08C8\u0904-\u0939\u093D\u0950\u0958-\u0961\u0972-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C5D\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D04-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E45\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u1100-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u1711\u171F-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17DC\u1820-\u1842\u1844-\u1878\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1B05-\u1B33\u1B45-\u1B4C\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C77\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u2135-\u2138\u2D30-\u2D67\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3006\u303C\u3041-\u3096\u309F\u30A1-\u30FA\u30FF\u3105-\u312F\u3131-\u318E\u31A0-\u31BF\u31F0-\u31FF\u3400-\u4DBF\u4E00-\uA014\uA016-\uA48C\uA4D0-\uA4F7\uA500-\uA60B\uA610-\uA61F\uA62A\uA62B\uA66E\uA6A0-\uA6E5\uA78F\uA7F7\uA7FB-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA8FE\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9E0-\uA9E4\uA9E7-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA6F\uAA71-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB\uAADC\uAAE0-\uAAEA\uAAF2\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF66-\uFF6F\uFF71-\uFF9D\uFFA0-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC',
        'astral': '\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF40\uDF42-\uDF49\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF]|\uD801[\uDC50-\uDC9D\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDD00-\uDD23\uDE80-\uDEA9\uDEB0\uDEB1\uDF00-\uDF1C\uDF27\uDF30-\uDF45\uDF70-\uDF81\uDFB0-\uDFC4\uDFE0-\uDFF6]|\uD804[\uDC03-\uDC37\uDC71\uDC72\uDC75\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD44\uDD47\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC5F-\uDC61\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDEB8\uDF00-\uDF1A\uDF40-\uDF46]|\uD806[\uDC00-\uDC2B\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD2F\uDD3F\uDD41\uDDA0-\uDDA7\uDDAA-\uDDD0\uDDE1\uDDE3\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE89\uDE9D\uDEB0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD89\uDD98\uDEE0-\uDEF2\uDFB0]|\uD808[\uDC00-\uDF99]|\uD809[\uDC80-\uDD43]|\uD80B[\uDF90-\uDFF0]|[\uD80C\uD81C-\uD820\uD822\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879\uD880-\uD883][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE70-\uDEBE\uDED0-\uDEED\uDF00-\uDF2F\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF4A\uDF50]|\uD821[\uDC00-\uDFF7]|\uD823[\uDC00-\uDCD5\uDD00-\uDD08]|\uD82C[\uDC00-\uDD22\uDD50-\uDD52\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD837\uDF0A|\uD838[\uDD00-\uDD2C\uDD4E\uDE90-\uDEAD\uDEC0-\uDEEB]|\uD839[\uDFE0-\uDFE6\uDFE8-\uDFEB\uDFED\uDFEE\uDFF0-\uDFFE]|\uD83A[\uDC00-\uDCC4]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDEDF\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF38\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A]'
    },
    {
        'name': 'Lt',
        'alias': 'Titlecase_Letter',
        'bmp': '\u01C5\u01C8\u01CB\u01F2\u1F88-\u1F8F\u1F98-\u1F9F\u1FA8-\u1FAF\u1FBC\u1FCC\u1FFC'
    },
    {
        'name': 'Lu',
        'alias': 'Uppercase_Letter',
        'bmp': 'A-Z\xC0-\xD6\xD8-\xDE\u0100\u0102\u0104\u0106\u0108\u010A\u010C\u010E\u0110\u0112\u0114\u0116\u0118\u011A\u011C\u011E\u0120\u0122\u0124\u0126\u0128\u012A\u012C\u012E\u0130\u0132\u0134\u0136\u0139\u013B\u013D\u013F\u0141\u0143\u0145\u0147\u014A\u014C\u014E\u0150\u0152\u0154\u0156\u0158\u015A\u015C\u015E\u0160\u0162\u0164\u0166\u0168\u016A\u016C\u016E\u0170\u0172\u0174\u0176\u0178\u0179\u017B\u017D\u0181\u0182\u0184\u0186\u0187\u0189-\u018B\u018E-\u0191\u0193\u0194\u0196-\u0198\u019C\u019D\u019F\u01A0\u01A2\u01A4\u01A6\u01A7\u01A9\u01AC\u01AE\u01AF\u01B1-\u01B3\u01B5\u01B7\u01B8\u01BC\u01C4\u01C7\u01CA\u01CD\u01CF\u01D1\u01D3\u01D5\u01D7\u01D9\u01DB\u01DE\u01E0\u01E2\u01E4\u01E6\u01E8\u01EA\u01EC\u01EE\u01F1\u01F4\u01F6-\u01F8\u01FA\u01FC\u01FE\u0200\u0202\u0204\u0206\u0208\u020A\u020C\u020E\u0210\u0212\u0214\u0216\u0218\u021A\u021C\u021E\u0220\u0222\u0224\u0226\u0228\u022A\u022C\u022E\u0230\u0232\u023A\u023B\u023D\u023E\u0241\u0243-\u0246\u0248\u024A\u024C\u024E\u0370\u0372\u0376\u037F\u0386\u0388-\u038A\u038C\u038E\u038F\u0391-\u03A1\u03A3-\u03AB\u03CF\u03D2-\u03D4\u03D8\u03DA\u03DC\u03DE\u03E0\u03E2\u03E4\u03E6\u03E8\u03EA\u03EC\u03EE\u03F4\u03F7\u03F9\u03FA\u03FD-\u042F\u0460\u0462\u0464\u0466\u0468\u046A\u046C\u046E\u0470\u0472\u0474\u0476\u0478\u047A\u047C\u047E\u0480\u048A\u048C\u048E\u0490\u0492\u0494\u0496\u0498\u049A\u049C\u049E\u04A0\u04A2\u04A4\u04A6\u04A8\u04AA\u04AC\u04AE\u04B0\u04B2\u04B4\u04B6\u04B8\u04BA\u04BC\u04BE\u04C0\u04C1\u04C3\u04C5\u04C7\u04C9\u04CB\u04CD\u04D0\u04D2\u04D4\u04D6\u04D8\u04DA\u04DC\u04DE\u04E0\u04E2\u04E4\u04E6\u04E8\u04EA\u04EC\u04EE\u04F0\u04F2\u04F4\u04F6\u04F8\u04FA\u04FC\u04FE\u0500\u0502\u0504\u0506\u0508\u050A\u050C\u050E\u0510\u0512\u0514\u0516\u0518\u051A\u051C\u051E\u0520\u0522\u0524\u0526\u0528\u052A\u052C\u052E\u0531-\u0556\u10A0-\u10C5\u10C7\u10CD\u13A0-\u13F5\u1C90-\u1CBA\u1CBD-\u1CBF\u1E00\u1E02\u1E04\u1E06\u1E08\u1E0A\u1E0C\u1E0E\u1E10\u1E12\u1E14\u1E16\u1E18\u1E1A\u1E1C\u1E1E\u1E20\u1E22\u1E24\u1E26\u1E28\u1E2A\u1E2C\u1E2E\u1E30\u1E32\u1E34\u1E36\u1E38\u1E3A\u1E3C\u1E3E\u1E40\u1E42\u1E44\u1E46\u1E48\u1E4A\u1E4C\u1E4E\u1E50\u1E52\u1E54\u1E56\u1E58\u1E5A\u1E5C\u1E5E\u1E60\u1E62\u1E64\u1E66\u1E68\u1E6A\u1E6C\u1E6E\u1E70\u1E72\u1E74\u1E76\u1E78\u1E7A\u1E7C\u1E7E\u1E80\u1E82\u1E84\u1E86\u1E88\u1E8A\u1E8C\u1E8E\u1E90\u1E92\u1E94\u1E9E\u1EA0\u1EA2\u1EA4\u1EA6\u1EA8\u1EAA\u1EAC\u1EAE\u1EB0\u1EB2\u1EB4\u1EB6\u1EB8\u1EBA\u1EBC\u1EBE\u1EC0\u1EC2\u1EC4\u1EC6\u1EC8\u1ECA\u1ECC\u1ECE\u1ED0\u1ED2\u1ED4\u1ED6\u1ED8\u1EDA\u1EDC\u1EDE\u1EE0\u1EE2\u1EE4\u1EE6\u1EE8\u1EEA\u1EEC\u1EEE\u1EF0\u1EF2\u1EF4\u1EF6\u1EF8\u1EFA\u1EFC\u1EFE\u1F08-\u1F0F\u1F18-\u1F1D\u1F28-\u1F2F\u1F38-\u1F3F\u1F48-\u1F4D\u1F59\u1F5B\u1F5D\u1F5F\u1F68-\u1F6F\u1FB8-\u1FBB\u1FC8-\u1FCB\u1FD8-\u1FDB\u1FE8-\u1FEC\u1FF8-\u1FFB\u2102\u2107\u210B-\u210D\u2110-\u2112\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u2130-\u2133\u213E\u213F\u2145\u2183\u2C00-\u2C2F\u2C60\u2C62-\u2C64\u2C67\u2C69\u2C6B\u2C6D-\u2C70\u2C72\u2C75\u2C7E-\u2C80\u2C82\u2C84\u2C86\u2C88\u2C8A\u2C8C\u2C8E\u2C90\u2C92\u2C94\u2C96\u2C98\u2C9A\u2C9C\u2C9E\u2CA0\u2CA2\u2CA4\u2CA6\u2CA8\u2CAA\u2CAC\u2CAE\u2CB0\u2CB2\u2CB4\u2CB6\u2CB8\u2CBA\u2CBC\u2CBE\u2CC0\u2CC2\u2CC4\u2CC6\u2CC8\u2CCA\u2CCC\u2CCE\u2CD0\u2CD2\u2CD4\u2CD6\u2CD8\u2CDA\u2CDC\u2CDE\u2CE0\u2CE2\u2CEB\u2CED\u2CF2\uA640\uA642\uA644\uA646\uA648\uA64A\uA64C\uA64E\uA650\uA652\uA654\uA656\uA658\uA65A\uA65C\uA65E\uA660\uA662\uA664\uA666\uA668\uA66A\uA66C\uA680\uA682\uA684\uA686\uA688\uA68A\uA68C\uA68E\uA690\uA692\uA694\uA696\uA698\uA69A\uA722\uA724\uA726\uA728\uA72A\uA72C\uA72E\uA732\uA734\uA736\uA738\uA73A\uA73C\uA73E\uA740\uA742\uA744\uA746\uA748\uA74A\uA74C\uA74E\uA750\uA752\uA754\uA756\uA758\uA75A\uA75C\uA75E\uA760\uA762\uA764\uA766\uA768\uA76A\uA76C\uA76E\uA779\uA77B\uA77D\uA77E\uA780\uA782\uA784\uA786\uA78B\uA78D\uA790\uA792\uA796\uA798\uA79A\uA79C\uA79E\uA7A0\uA7A2\uA7A4\uA7A6\uA7A8\uA7AA-\uA7AE\uA7B0-\uA7B4\uA7B6\uA7B8\uA7BA\uA7BC\uA7BE\uA7C0\uA7C2\uA7C4-\uA7C7\uA7C9\uA7D0\uA7D6\uA7D8\uA7F5\uFF21-\uFF3A',
        'astral': '\uD801[\uDC00-\uDC27\uDCB0-\uDCD3\uDD70-\uDD7A\uDD7C-\uDD8A\uDD8C-\uDD92\uDD94\uDD95]|\uD803[\uDC80-\uDCB2]|\uD806[\uDCA0-\uDCBF]|\uD81B[\uDE40-\uDE5F]|\uD835[\uDC00-\uDC19\uDC34-\uDC4D\uDC68-\uDC81\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB5\uDCD0-\uDCE9\uDD04\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD38\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD6C-\uDD85\uDDA0-\uDDB9\uDDD4-\uDDED\uDE08-\uDE21\uDE3C-\uDE55\uDE70-\uDE89\uDEA8-\uDEC0\uDEE2-\uDEFA\uDF1C-\uDF34\uDF56-\uDF6E\uDF90-\uDFA8\uDFCA]|\uD83A[\uDD00-\uDD21]'
    },
    {
        'name': 'M',
        'alias': 'Mark',
        'bmp': '\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u07FD\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u0898-\u089F\u08CA-\u08E1\u08E3-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u09FE\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0AFA-\u0AFF\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B55-\u0B57\u0B62\u0B63\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C00-\u0C04\u0C3C\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D00-\u0D03\u0D3B\u0D3C\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D81-\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F\u109A-\u109D\u135D-\u135F\u1712-\u1715\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u180B-\u180D\u180F\u1885\u1886\u18A9\u1920-\u192B\u1930-\u193B\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F\u1AB0-\u1ACE\u1B00-\u1B04\u1B34-\u1B44\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BE6-\u1BF3\u1C24-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF4\u1CF7-\u1CF9\u1DC0-\u1DFF\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69E\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA82C\uA880\uA881\uA8B4-\uA8C5\uA8E0-\uA8F1\uA8FF\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9E5\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F',
        'astral': '\uD800[\uDDFD\uDEE0\uDF76-\uDF7A]|\uD802[\uDE01-\uDE03\uDE05\uDE06\uDE0C-\uDE0F\uDE38-\uDE3A\uDE3F\uDEE5\uDEE6]|\uD803[\uDD24-\uDD27\uDEAB\uDEAC\uDF46-\uDF50\uDF82-\uDF85]|\uD804[\uDC00-\uDC02\uDC38-\uDC46\uDC70\uDC73\uDC74\uDC7F-\uDC82\uDCB0-\uDCBA\uDCC2\uDD00-\uDD02\uDD27-\uDD34\uDD45\uDD46\uDD73\uDD80-\uDD82\uDDB3-\uDDC0\uDDC9-\uDDCC\uDDCE\uDDCF\uDE2C-\uDE37\uDE3E\uDEDF-\uDEEA\uDF00-\uDF03\uDF3B\uDF3C\uDF3E-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF57\uDF62\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC35-\uDC46\uDC5E\uDCB0-\uDCC3\uDDAF-\uDDB5\uDDB8-\uDDC0\uDDDC\uDDDD\uDE30-\uDE40\uDEAB-\uDEB7\uDF1D-\uDF2B]|\uD806[\uDC2C-\uDC3A\uDD30-\uDD35\uDD37\uDD38\uDD3B-\uDD3E\uDD40\uDD42\uDD43\uDDD1-\uDDD7\uDDDA-\uDDE0\uDDE4\uDE01-\uDE0A\uDE33-\uDE39\uDE3B-\uDE3E\uDE47\uDE51-\uDE5B\uDE8A-\uDE99]|\uD807[\uDC2F-\uDC36\uDC38-\uDC3F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD31-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD45\uDD47\uDD8A-\uDD8E\uDD90\uDD91\uDD93-\uDD97\uDEF3-\uDEF6]|\uD81A[\uDEF0-\uDEF4\uDF30-\uDF36]|\uD81B[\uDF4F\uDF51-\uDF87\uDF8F-\uDF92\uDFE4\uDFF0\uDFF1]|\uD82F[\uDC9D\uDC9E]|\uD833[\uDF00-\uDF2D\uDF30-\uDF46]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A\uDD30-\uDD36\uDEAE\uDEEC-\uDEEF]|\uD83A[\uDCD0-\uDCD6\uDD44-\uDD4A]|\uDB40[\uDD00-\uDDEF]'
    },
    {
        'name': 'Mc',
        'alias': 'Spacing_Mark',
        'bmp': '\u0903\u093B\u093E-\u0940\u0949-\u094C\u094E\u094F\u0982\u0983\u09BE-\u09C0\u09C7\u09C8\u09CB\u09CC\u09D7\u0A03\u0A3E-\u0A40\u0A83\u0ABE-\u0AC0\u0AC9\u0ACB\u0ACC\u0B02\u0B03\u0B3E\u0B40\u0B47\u0B48\u0B4B\u0B4C\u0B57\u0BBE\u0BBF\u0BC1\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCC\u0BD7\u0C01-\u0C03\u0C41-\u0C44\u0C82\u0C83\u0CBE\u0CC0-\u0CC4\u0CC7\u0CC8\u0CCA\u0CCB\u0CD5\u0CD6\u0D02\u0D03\u0D3E-\u0D40\u0D46-\u0D48\u0D4A-\u0D4C\u0D57\u0D82\u0D83\u0DCF-\u0DD1\u0DD8-\u0DDF\u0DF2\u0DF3\u0F3E\u0F3F\u0F7F\u102B\u102C\u1031\u1038\u103B\u103C\u1056\u1057\u1062-\u1064\u1067-\u106D\u1083\u1084\u1087-\u108C\u108F\u109A-\u109C\u1715\u1734\u17B6\u17BE-\u17C5\u17C7\u17C8\u1923-\u1926\u1929-\u192B\u1930\u1931\u1933-\u1938\u1A19\u1A1A\u1A55\u1A57\u1A61\u1A63\u1A64\u1A6D-\u1A72\u1B04\u1B35\u1B3B\u1B3D-\u1B41\u1B43\u1B44\u1B82\u1BA1\u1BA6\u1BA7\u1BAA\u1BE7\u1BEA-\u1BEC\u1BEE\u1BF2\u1BF3\u1C24-\u1C2B\u1C34\u1C35\u1CE1\u1CF7\u302E\u302F\uA823\uA824\uA827\uA880\uA881\uA8B4-\uA8C3\uA952\uA953\uA983\uA9B4\uA9B5\uA9BA\uA9BB\uA9BE-\uA9C0\uAA2F\uAA30\uAA33\uAA34\uAA4D\uAA7B\uAA7D\uAAEB\uAAEE\uAAEF\uAAF5\uABE3\uABE4\uABE6\uABE7\uABE9\uABEA\uABEC',
        'astral': '\uD804[\uDC00\uDC02\uDC82\uDCB0-\uDCB2\uDCB7\uDCB8\uDD2C\uDD45\uDD46\uDD82\uDDB3-\uDDB5\uDDBF\uDDC0\uDDCE\uDE2C-\uDE2E\uDE32\uDE33\uDE35\uDEE0-\uDEE2\uDF02\uDF03\uDF3E\uDF3F\uDF41-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF57\uDF62\uDF63]|\uD805[\uDC35-\uDC37\uDC40\uDC41\uDC45\uDCB0-\uDCB2\uDCB9\uDCBB-\uDCBE\uDCC1\uDDAF-\uDDB1\uDDB8-\uDDBB\uDDBE\uDE30-\uDE32\uDE3B\uDE3C\uDE3E\uDEAC\uDEAE\uDEAF\uDEB6\uDF20\uDF21\uDF26]|\uD806[\uDC2C-\uDC2E\uDC38\uDD30-\uDD35\uDD37\uDD38\uDD3D\uDD40\uDD42\uDDD1-\uDDD3\uDDDC-\uDDDF\uDDE4\uDE39\uDE57\uDE58\uDE97]|\uD807[\uDC2F\uDC3E\uDCA9\uDCB1\uDCB4\uDD8A-\uDD8E\uDD93\uDD94\uDD96\uDEF5\uDEF6]|\uD81B[\uDF51-\uDF87\uDFF0\uDFF1]|\uD834[\uDD65\uDD66\uDD6D-\uDD72]'
    },
    {
        'name': 'Me',
        'alias': 'Enclosing_Mark',
        'bmp': '\u0488\u0489\u1ABE\u20DD-\u20E0\u20E2-\u20E4\uA670-\uA672'
    },
    {
        'name': 'Mn',
        'alias': 'Nonspacing_Mark',
        'bmp': '\u0300-\u036F\u0483-\u0487\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u07FD\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u0898-\u089F\u08CA-\u08E1\u08E3-\u0902\u093A\u093C\u0941-\u0948\u094D\u0951-\u0957\u0962\u0963\u0981\u09BC\u09C1-\u09C4\u09CD\u09E2\u09E3\u09FE\u0A01\u0A02\u0A3C\u0A41\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81\u0A82\u0ABC\u0AC1-\u0AC5\u0AC7\u0AC8\u0ACD\u0AE2\u0AE3\u0AFA-\u0AFF\u0B01\u0B3C\u0B3F\u0B41-\u0B44\u0B4D\u0B55\u0B56\u0B62\u0B63\u0B82\u0BC0\u0BCD\u0C00\u0C04\u0C3C\u0C3E-\u0C40\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81\u0CBC\u0CBF\u0CC6\u0CCC\u0CCD\u0CE2\u0CE3\u0D00\u0D01\u0D3B\u0D3C\u0D41-\u0D44\u0D4D\u0D62\u0D63\u0D81\u0DCA\u0DD2-\u0DD4\u0DD6\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F71-\u0F7E\u0F80-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102D-\u1030\u1032-\u1037\u1039\u103A\u103D\u103E\u1058\u1059\u105E-\u1060\u1071-\u1074\u1082\u1085\u1086\u108D\u109D\u135D-\u135F\u1712-\u1714\u1732\u1733\u1752\u1753\u1772\u1773\u17B4\u17B5\u17B7-\u17BD\u17C6\u17C9-\u17D3\u17DD\u180B-\u180D\u180F\u1885\u1886\u18A9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193B\u1A17\u1A18\u1A1B\u1A56\u1A58-\u1A5E\u1A60\u1A62\u1A65-\u1A6C\u1A73-\u1A7C\u1A7F\u1AB0-\u1ABD\u1ABF-\u1ACE\u1B00-\u1B03\u1B34\u1B36-\u1B3A\u1B3C\u1B42\u1B6B-\u1B73\u1B80\u1B81\u1BA2-\u1BA5\u1BA8\u1BA9\u1BAB-\u1BAD\u1BE6\u1BE8\u1BE9\u1BED\u1BEF-\u1BF1\u1C2C-\u1C33\u1C36\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE0\u1CE2-\u1CE8\u1CED\u1CF4\u1CF8\u1CF9\u1DC0-\u1DFF\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302D\u3099\u309A\uA66F\uA674-\uA67D\uA69E\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA825\uA826\uA82C\uA8C4\uA8C5\uA8E0-\uA8F1\uA8FF\uA926-\uA92D\uA947-\uA951\uA980-\uA982\uA9B3\uA9B6-\uA9B9\uA9BC\uA9BD\uA9E5\uAA29-\uAA2E\uAA31\uAA32\uAA35\uAA36\uAA43\uAA4C\uAA7C\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEC\uAAED\uAAF6\uABE5\uABE8\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F',
        'astral': '\uD800[\uDDFD\uDEE0\uDF76-\uDF7A]|\uD802[\uDE01-\uDE03\uDE05\uDE06\uDE0C-\uDE0F\uDE38-\uDE3A\uDE3F\uDEE5\uDEE6]|\uD803[\uDD24-\uDD27\uDEAB\uDEAC\uDF46-\uDF50\uDF82-\uDF85]|\uD804[\uDC01\uDC38-\uDC46\uDC70\uDC73\uDC74\uDC7F-\uDC81\uDCB3-\uDCB6\uDCB9\uDCBA\uDCC2\uDD00-\uDD02\uDD27-\uDD2B\uDD2D-\uDD34\uDD73\uDD80\uDD81\uDDB6-\uDDBE\uDDC9-\uDDCC\uDDCF\uDE2F-\uDE31\uDE34\uDE36\uDE37\uDE3E\uDEDF\uDEE3-\uDEEA\uDF00\uDF01\uDF3B\uDF3C\uDF40\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC38-\uDC3F\uDC42-\uDC44\uDC46\uDC5E\uDCB3-\uDCB8\uDCBA\uDCBF\uDCC0\uDCC2\uDCC3\uDDB2-\uDDB5\uDDBC\uDDBD\uDDBF\uDDC0\uDDDC\uDDDD\uDE33-\uDE3A\uDE3D\uDE3F\uDE40\uDEAB\uDEAD\uDEB0-\uDEB5\uDEB7\uDF1D-\uDF1F\uDF22-\uDF25\uDF27-\uDF2B]|\uD806[\uDC2F-\uDC37\uDC39\uDC3A\uDD3B\uDD3C\uDD3E\uDD43\uDDD4-\uDDD7\uDDDA\uDDDB\uDDE0\uDE01-\uDE0A\uDE33-\uDE38\uDE3B-\uDE3E\uDE47\uDE51-\uDE56\uDE59-\uDE5B\uDE8A-\uDE96\uDE98\uDE99]|\uD807[\uDC30-\uDC36\uDC38-\uDC3D\uDC3F\uDC92-\uDCA7\uDCAA-\uDCB0\uDCB2\uDCB3\uDCB5\uDCB6\uDD31-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD45\uDD47\uDD90\uDD91\uDD95\uDD97\uDEF3\uDEF4]|\uD81A[\uDEF0-\uDEF4\uDF30-\uDF36]|\uD81B[\uDF4F\uDF8F-\uDF92\uDFE4]|\uD82F[\uDC9D\uDC9E]|\uD833[\uDF00-\uDF2D\uDF30-\uDF46]|\uD834[\uDD67-\uDD69\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A\uDD30-\uDD36\uDEAE\uDEEC-\uDEEF]|\uD83A[\uDCD0-\uDCD6\uDD44-\uDD4A]|\uDB40[\uDD00-\uDDEF]'
    },
    {
        'name': 'N',
        'alias': 'Number',
        'bmp': '0-9\xB2\xB3\xB9\xBC-\xBE\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u09F4-\u09F9\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0B72-\u0B77\u0BE6-\u0BF2\u0C66-\u0C6F\u0C78-\u0C7E\u0CE6-\u0CEF\u0D58-\u0D5E\u0D66-\u0D78\u0DE6-\u0DEF\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F33\u1040-\u1049\u1090-\u1099\u1369-\u137C\u16EE-\u16F0\u17E0-\u17E9\u17F0-\u17F9\u1810-\u1819\u1946-\u194F\u19D0-\u19DA\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\u2070\u2074-\u2079\u2080-\u2089\u2150-\u2182\u2185-\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2CFD\u3007\u3021-\u3029\u3038-\u303A\u3192-\u3195\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\uA620-\uA629\uA6E6-\uA6EF\uA830-\uA835\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uA9F0-\uA9F9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19',
        'astral': '\uD800[\uDD07-\uDD33\uDD40-\uDD78\uDD8A\uDD8B\uDEE1-\uDEFB\uDF20-\uDF23\uDF41\uDF4A\uDFD1-\uDFD5]|\uD801[\uDCA0-\uDCA9]|\uD802[\uDC58-\uDC5F\uDC79-\uDC7F\uDCA7-\uDCAF\uDCFB-\uDCFF\uDD16-\uDD1B\uDDBC\uDDBD\uDDC0-\uDDCF\uDDD2-\uDDFF\uDE40-\uDE48\uDE7D\uDE7E\uDE9D-\uDE9F\uDEEB-\uDEEF\uDF58-\uDF5F\uDF78-\uDF7F\uDFA9-\uDFAF]|\uD803[\uDCFA-\uDCFF\uDD30-\uDD39\uDE60-\uDE7E\uDF1D-\uDF26\uDF51-\uDF54\uDFC5-\uDFCB]|\uD804[\uDC52-\uDC6F\uDCF0-\uDCF9\uDD36-\uDD3F\uDDD0-\uDDD9\uDDE1-\uDDF4\uDEF0-\uDEF9]|\uD805[\uDC50-\uDC59\uDCD0-\uDCD9\uDE50-\uDE59\uDEC0-\uDEC9\uDF30-\uDF3B]|\uD806[\uDCE0-\uDCF2\uDD50-\uDD59]|\uD807[\uDC50-\uDC6C\uDD50-\uDD59\uDDA0-\uDDA9\uDFC0-\uDFD4]|\uD809[\uDC00-\uDC6E]|\uD81A[\uDE60-\uDE69\uDEC0-\uDEC9\uDF50-\uDF59\uDF5B-\uDF61]|\uD81B[\uDE80-\uDE96]|\uD834[\uDEE0-\uDEF3\uDF60-\uDF78]|\uD835[\uDFCE-\uDFFF]|\uD838[\uDD40-\uDD49\uDEF0-\uDEF9]|\uD83A[\uDCC7-\uDCCF\uDD50-\uDD59]|\uD83B[\uDC71-\uDCAB\uDCAD-\uDCAF\uDCB1-\uDCB4\uDD01-\uDD2D\uDD2F-\uDD3D]|\uD83C[\uDD00-\uDD0C]|\uD83E[\uDFF0-\uDFF9]'
    },
    {
        'name': 'Nd',
        'alias': 'Decimal_Number',
        'bmp': '0-9\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0BE6-\u0BEF\u0C66-\u0C6F\u0CE6-\u0CEF\u0D66-\u0D6F\u0DE6-\u0DEF\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F29\u1040-\u1049\u1090-\u1099\u17E0-\u17E9\u1810-\u1819\u1946-\u194F\u19D0-\u19D9\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\uA620-\uA629\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uA9F0-\uA9F9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19',
        'astral': '\uD801[\uDCA0-\uDCA9]|\uD803[\uDD30-\uDD39]|\uD804[\uDC66-\uDC6F\uDCF0-\uDCF9\uDD36-\uDD3F\uDDD0-\uDDD9\uDEF0-\uDEF9]|\uD805[\uDC50-\uDC59\uDCD0-\uDCD9\uDE50-\uDE59\uDEC0-\uDEC9\uDF30-\uDF39]|\uD806[\uDCE0-\uDCE9\uDD50-\uDD59]|\uD807[\uDC50-\uDC59\uDD50-\uDD59\uDDA0-\uDDA9]|\uD81A[\uDE60-\uDE69\uDEC0-\uDEC9\uDF50-\uDF59]|\uD835[\uDFCE-\uDFFF]|\uD838[\uDD40-\uDD49\uDEF0-\uDEF9]|\uD83A[\uDD50-\uDD59]|\uD83E[\uDFF0-\uDFF9]'
    },
    {
        'name': 'Nl',
        'alias': 'Letter_Number',
        'bmp': '\u16EE-\u16F0\u2160-\u2182\u2185-\u2188\u3007\u3021-\u3029\u3038-\u303A\uA6E6-\uA6EF',
        'astral': '\uD800[\uDD40-\uDD74\uDF41\uDF4A\uDFD1-\uDFD5]|\uD809[\uDC00-\uDC6E]'
    },
    {
        'name': 'No',
        'alias': 'Other_Number',
        'bmp': '\xB2\xB3\xB9\xBC-\xBE\u09F4-\u09F9\u0B72-\u0B77\u0BF0-\u0BF2\u0C78-\u0C7E\u0D58-\u0D5E\u0D70-\u0D78\u0F2A-\u0F33\u1369-\u137C\u17F0-\u17F9\u19DA\u2070\u2074-\u2079\u2080-\u2089\u2150-\u215F\u2189\u2460-\u249B\u24EA-\u24FF\u2776-\u2793\u2CFD\u3192-\u3195\u3220-\u3229\u3248-\u324F\u3251-\u325F\u3280-\u3289\u32B1-\u32BF\uA830-\uA835',
        'astral': '\uD800[\uDD07-\uDD33\uDD75-\uDD78\uDD8A\uDD8B\uDEE1-\uDEFB\uDF20-\uDF23]|\uD802[\uDC58-\uDC5F\uDC79-\uDC7F\uDCA7-\uDCAF\uDCFB-\uDCFF\uDD16-\uDD1B\uDDBC\uDDBD\uDDC0-\uDDCF\uDDD2-\uDDFF\uDE40-\uDE48\uDE7D\uDE7E\uDE9D-\uDE9F\uDEEB-\uDEEF\uDF58-\uDF5F\uDF78-\uDF7F\uDFA9-\uDFAF]|\uD803[\uDCFA-\uDCFF\uDE60-\uDE7E\uDF1D-\uDF26\uDF51-\uDF54\uDFC5-\uDFCB]|\uD804[\uDC52-\uDC65\uDDE1-\uDDF4]|\uD805[\uDF3A\uDF3B]|\uD806[\uDCEA-\uDCF2]|\uD807[\uDC5A-\uDC6C\uDFC0-\uDFD4]|\uD81A[\uDF5B-\uDF61]|\uD81B[\uDE80-\uDE96]|\uD834[\uDEE0-\uDEF3\uDF60-\uDF78]|\uD83A[\uDCC7-\uDCCF]|\uD83B[\uDC71-\uDCAB\uDCAD-\uDCAF\uDCB1-\uDCB4\uDD01-\uDD2D\uDD2F-\uDD3D]|\uD83C[\uDD00-\uDD0C]'
    },
    {
        'name': 'P',
        'alias': 'Punctuation',
        'bmp': '!-#%-\\*,-\\/:;\\?@\\[-\\]_\\{\\}\xA1\xA7\xAB\xB6\xB7\xBB\xBF\u037E\u0387\u055A-\u055F\u0589\u058A\u05BE\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F3A-\u0F3D\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u1400\u166E\u169B\u169C\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1B7D\u1B7E\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2010-\u2027\u2030-\u2043\u2045-\u2051\u2053-\u205E\u207D\u207E\u208D\u208E\u2308-\u230B\u2329\u232A\u2768-\u2775\u27C5\u27C6\u27E6-\u27EF\u2983-\u2998\u29D8-\u29DB\u29FC\u29FD\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00-\u2E2E\u2E30-\u2E4F\u2E52-\u2E5D\u3001-\u3003\u3008-\u3011\u3014-\u301F\u3030\u303D\u30A0\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE61\uFE63\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF0A\uFF0C-\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3B-\uFF3D\uFF3F\uFF5B\uFF5D\uFF5F-\uFF65',
        'astral': '\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD803[\uDEAD\uDF55-\uDF59\uDF86-\uDF89]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC8\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9]|\uD805[\uDC4B-\uDC4F\uDC5A\uDC5B\uDC5D\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDE60-\uDE6C\uDEB9\uDF3C-\uDF3E]|\uD806[\uDC3B\uDD44-\uDD46\uDDE2\uDE3F-\uDE46\uDE9A-\uDE9C\uDE9E-\uDEA2]|\uD807[\uDC41-\uDC45\uDC70\uDC71\uDEF7\uDEF8\uDFFF]|\uD809[\uDC70-\uDC74]|\uD80B[\uDFF1\uDFF2]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD81B[\uDE97-\uDE9A\uDFE2]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B]|\uD83A[\uDD5E\uDD5F]'
    },
    {
        'name': 'Pc',
        'alias': 'Connector_Punctuation',
        'bmp': '_\u203F\u2040\u2054\uFE33\uFE34\uFE4D-\uFE4F\uFF3F'
    },
    {
        'name': 'Pd',
        'alias': 'Dash_Punctuation',
        'bmp': '\\-\u058A\u05BE\u1400\u1806\u2010-\u2015\u2E17\u2E1A\u2E3A\u2E3B\u2E40\u2E5D\u301C\u3030\u30A0\uFE31\uFE32\uFE58\uFE63\uFF0D',
        'astral': '\uD803\uDEAD'
    },
    {
        'name': 'Pe',
        'alias': 'Close_Punctuation',
        'bmp': '\\)\\]\\}\u0F3B\u0F3D\u169C\u2046\u207E\u208E\u2309\u230B\u232A\u2769\u276B\u276D\u276F\u2771\u2773\u2775\u27C6\u27E7\u27E9\u27EB\u27ED\u27EF\u2984\u2986\u2988\u298A\u298C\u298E\u2990\u2992\u2994\u2996\u2998\u29D9\u29DB\u29FD\u2E23\u2E25\u2E27\u2E29\u2E56\u2E58\u2E5A\u2E5C\u3009\u300B\u300D\u300F\u3011\u3015\u3017\u3019\u301B\u301E\u301F\uFD3E\uFE18\uFE36\uFE38\uFE3A\uFE3C\uFE3E\uFE40\uFE42\uFE44\uFE48\uFE5A\uFE5C\uFE5E\uFF09\uFF3D\uFF5D\uFF60\uFF63'
    },
    {
        'name': 'Pf',
        'alias': 'Final_Punctuation',
        'bmp': '\xBB\u2019\u201D\u203A\u2E03\u2E05\u2E0A\u2E0D\u2E1D\u2E21'
    },
    {
        'name': 'Pi',
        'alias': 'Initial_Punctuation',
        'bmp': '\xAB\u2018\u201B\u201C\u201F\u2039\u2E02\u2E04\u2E09\u2E0C\u2E1C\u2E20'
    },
    {
        'name': 'Po',
        'alias': 'Other_Punctuation',
        'bmp': '!-#%-\'\\*,\\.\\/:;\\?@\\\xA1\xA7\xB6\xB7\xBF\u037E\u0387\u055A-\u055F\u0589\u05C0\u05C3\u05C6\u05F3\u05F4\u0609\u060A\u060C\u060D\u061B\u061D-\u061F\u066A-\u066D\u06D4\u0700-\u070D\u07F7-\u07F9\u0830-\u083E\u085E\u0964\u0965\u0970\u09FD\u0A76\u0AF0\u0C77\u0C84\u0DF4\u0E4F\u0E5A\u0E5B\u0F04-\u0F12\u0F14\u0F85\u0FD0-\u0FD4\u0FD9\u0FDA\u104A-\u104F\u10FB\u1360-\u1368\u166E\u16EB-\u16ED\u1735\u1736\u17D4-\u17D6\u17D8-\u17DA\u1800-\u1805\u1807-\u180A\u1944\u1945\u1A1E\u1A1F\u1AA0-\u1AA6\u1AA8-\u1AAD\u1B5A-\u1B60\u1B7D\u1B7E\u1BFC-\u1BFF\u1C3B-\u1C3F\u1C7E\u1C7F\u1CC0-\u1CC7\u1CD3\u2016\u2017\u2020-\u2027\u2030-\u2038\u203B-\u203E\u2041-\u2043\u2047-\u2051\u2053\u2055-\u205E\u2CF9-\u2CFC\u2CFE\u2CFF\u2D70\u2E00\u2E01\u2E06-\u2E08\u2E0B\u2E0E-\u2E16\u2E18\u2E19\u2E1B\u2E1E\u2E1F\u2E2A-\u2E2E\u2E30-\u2E39\u2E3C-\u2E3F\u2E41\u2E43-\u2E4F\u2E52-\u2E54\u3001-\u3003\u303D\u30FB\uA4FE\uA4FF\uA60D-\uA60F\uA673\uA67E\uA6F2-\uA6F7\uA874-\uA877\uA8CE\uA8CF\uA8F8-\uA8FA\uA8FC\uA92E\uA92F\uA95F\uA9C1-\uA9CD\uA9DE\uA9DF\uAA5C-\uAA5F\uAADE\uAADF\uAAF0\uAAF1\uABEB\uFE10-\uFE16\uFE19\uFE30\uFE45\uFE46\uFE49-\uFE4C\uFE50-\uFE52\uFE54-\uFE57\uFE5F-\uFE61\uFE68\uFE6A\uFE6B\uFF01-\uFF03\uFF05-\uFF07\uFF0A\uFF0C\uFF0E\uFF0F\uFF1A\uFF1B\uFF1F\uFF20\uFF3C\uFF61\uFF64\uFF65',
        'astral': '\uD800[\uDD00-\uDD02\uDF9F\uDFD0]|\uD801\uDD6F|\uD802[\uDC57\uDD1F\uDD3F\uDE50-\uDE58\uDE7F\uDEF0-\uDEF6\uDF39-\uDF3F\uDF99-\uDF9C]|\uD803[\uDF55-\uDF59\uDF86-\uDF89]|\uD804[\uDC47-\uDC4D\uDCBB\uDCBC\uDCBE-\uDCC1\uDD40-\uDD43\uDD74\uDD75\uDDC5-\uDDC8\uDDCD\uDDDB\uDDDD-\uDDDF\uDE38-\uDE3D\uDEA9]|\uD805[\uDC4B-\uDC4F\uDC5A\uDC5B\uDC5D\uDCC6\uDDC1-\uDDD7\uDE41-\uDE43\uDE60-\uDE6C\uDEB9\uDF3C-\uDF3E]|\uD806[\uDC3B\uDD44-\uDD46\uDDE2\uDE3F-\uDE46\uDE9A-\uDE9C\uDE9E-\uDEA2]|\uD807[\uDC41-\uDC45\uDC70\uDC71\uDEF7\uDEF8\uDFFF]|\uD809[\uDC70-\uDC74]|\uD80B[\uDFF1\uDFF2]|\uD81A[\uDE6E\uDE6F\uDEF5\uDF37-\uDF3B\uDF44]|\uD81B[\uDE97-\uDE9A\uDFE2]|\uD82F\uDC9F|\uD836[\uDE87-\uDE8B]|\uD83A[\uDD5E\uDD5F]'
    },
    {
        'name': 'Ps',
        'alias': 'Open_Punctuation',
        'bmp': '\\(\\[\\{\u0F3A\u0F3C\u169B\u201A\u201E\u2045\u207D\u208D\u2308\u230A\u2329\u2768\u276A\u276C\u276E\u2770\u2772\u2774\u27C5\u27E6\u27E8\u27EA\u27EC\u27EE\u2983\u2985\u2987\u2989\u298B\u298D\u298F\u2991\u2993\u2995\u2997\u29D8\u29DA\u29FC\u2E22\u2E24\u2E26\u2E28\u2E42\u2E55\u2E57\u2E59\u2E5B\u3008\u300A\u300C\u300E\u3010\u3014\u3016\u3018\u301A\u301D\uFD3F\uFE17\uFE35\uFE37\uFE39\uFE3B\uFE3D\uFE3F\uFE41\uFE43\uFE47\uFE59\uFE5B\uFE5D\uFF08\uFF3B\uFF5B\uFF5F\uFF62'
    },
    {
        'name': 'S',
        'alias': 'Symbol',
        'bmp': '\\$\\+<->\\^`\\|~\xA2-\xA6\xA8\xA9\xAC\xAE-\xB1\xB4\xB8\xD7\xF7\u02C2-\u02C5\u02D2-\u02DF\u02E5-\u02EB\u02ED\u02EF-\u02FF\u0375\u0384\u0385\u03F6\u0482\u058D-\u058F\u0606-\u0608\u060B\u060E\u060F\u06DE\u06E9\u06FD\u06FE\u07F6\u07FE\u07FF\u0888\u09F2\u09F3\u09FA\u09FB\u0AF1\u0B70\u0BF3-\u0BFA\u0C7F\u0D4F\u0D79\u0E3F\u0F01-\u0F03\u0F13\u0F15-\u0F17\u0F1A-\u0F1F\u0F34\u0F36\u0F38\u0FBE-\u0FC5\u0FC7-\u0FCC\u0FCE\u0FCF\u0FD5-\u0FD8\u109E\u109F\u1390-\u1399\u166D\u17DB\u1940\u19DE-\u19FF\u1B61-\u1B6A\u1B74-\u1B7C\u1FBD\u1FBF-\u1FC1\u1FCD-\u1FCF\u1FDD-\u1FDF\u1FED-\u1FEF\u1FFD\u1FFE\u2044\u2052\u207A-\u207C\u208A-\u208C\u20A0-\u20C0\u2100\u2101\u2103-\u2106\u2108\u2109\u2114\u2116-\u2118\u211E-\u2123\u2125\u2127\u2129\u212E\u213A\u213B\u2140-\u2144\u214A-\u214D\u214F\u218A\u218B\u2190-\u2307\u230C-\u2328\u232B-\u2426\u2440-\u244A\u249C-\u24E9\u2500-\u2767\u2794-\u27C4\u27C7-\u27E5\u27F0-\u2982\u2999-\u29D7\u29DC-\u29FB\u29FE-\u2B73\u2B76-\u2B95\u2B97-\u2BFF\u2CE5-\u2CEA\u2E50\u2E51\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3004\u3012\u3013\u3020\u3036\u3037\u303E\u303F\u309B\u309C\u3190\u3191\u3196-\u319F\u31C0-\u31E3\u3200-\u321E\u322A-\u3247\u3250\u3260-\u327F\u328A-\u32B0\u32C0-\u33FF\u4DC0-\u4DFF\uA490-\uA4C6\uA700-\uA716\uA720\uA721\uA789\uA78A\uA828-\uA82B\uA836-\uA839\uAA77-\uAA79\uAB5B\uAB6A\uAB6B\uFB29\uFBB2-\uFBC2\uFD40-\uFD4F\uFDCF\uFDFC-\uFDFF\uFE62\uFE64-\uFE66\uFE69\uFF04\uFF0B\uFF1C-\uFF1E\uFF3E\uFF40\uFF5C\uFF5E\uFFE0-\uFFE6\uFFE8-\uFFEE\uFFFC\uFFFD',
        'astral': '\uD800[\uDD37-\uDD3F\uDD79-\uDD89\uDD8C-\uDD8E\uDD90-\uDD9C\uDDA0\uDDD0-\uDDFC]|\uD802[\uDC77\uDC78\uDEC8]|\uD805\uDF3F|\uD807[\uDFD5-\uDFF1]|\uD81A[\uDF3C-\uDF3F\uDF45]|\uD82F\uDC9C|\uD833[\uDF50-\uDFC3]|\uD834[\uDC00-\uDCF5\uDD00-\uDD26\uDD29-\uDD64\uDD6A-\uDD6C\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDDEA\uDE00-\uDE41\uDE45\uDF00-\uDF56]|\uD835[\uDEC1\uDEDB\uDEFB\uDF15\uDF35\uDF4F\uDF6F\uDF89\uDFA9\uDFC3]|\uD836[\uDC00-\uDDFF\uDE37-\uDE3A\uDE6D-\uDE74\uDE76-\uDE83\uDE85\uDE86]|\uD838[\uDD4F\uDEFF]|\uD83B[\uDCAC\uDCB0\uDD2E\uDEF0\uDEF1]|\uD83C[\uDC00-\uDC2B\uDC30-\uDC93\uDCA0-\uDCAE\uDCB1-\uDCBF\uDCC1-\uDCCF\uDCD1-\uDCF5\uDD0D-\uDDAD\uDDE6-\uDE02\uDE10-\uDE3B\uDE40-\uDE48\uDE50\uDE51\uDE60-\uDE65\uDF00-\uDFFF]|\uD83D[\uDC00-\uDED7\uDEDD-\uDEEC\uDEF0-\uDEFC\uDF00-\uDF73\uDF80-\uDFD8\uDFE0-\uDFEB\uDFF0]|\uD83E[\uDC00-\uDC0B\uDC10-\uDC47\uDC50-\uDC59\uDC60-\uDC87\uDC90-\uDCAD\uDCB0\uDCB1\uDD00-\uDE53\uDE60-\uDE6D\uDE70-\uDE74\uDE78-\uDE7C\uDE80-\uDE86\uDE90-\uDEAC\uDEB0-\uDEBA\uDEC0-\uDEC5\uDED0-\uDED9\uDEE0-\uDEE7\uDEF0-\uDEF6\uDF00-\uDF92\uDF94-\uDFCA]'
    },
    {
        'name': 'Sc',
        'alias': 'Currency_Symbol',
        'bmp': '\\$\xA2-\xA5\u058F\u060B\u07FE\u07FF\u09F2\u09F3\u09FB\u0AF1\u0BF9\u0E3F\u17DB\u20A0-\u20C0\uA838\uFDFC\uFE69\uFF04\uFFE0\uFFE1\uFFE5\uFFE6',
        'astral': '\uD807[\uDFDD-\uDFE0]|\uD838\uDEFF|\uD83B\uDCB0'
    },
    {
        'name': 'Sk',
        'alias': 'Modifier_Symbol',
        'bmp': '\\^`\xA8\xAF\xB4\xB8\u02C2-\u02C5\u02D2-\u02DF\u02E5-\u02EB\u02ED\u02EF-\u02FF\u0375\u0384\u0385\u0888\u1FBD\u1FBF-\u1FC1\u1FCD-\u1FCF\u1FDD-\u1FDF\u1FED-\u1FEF\u1FFD\u1FFE\u309B\u309C\uA700-\uA716\uA720\uA721\uA789\uA78A\uAB5B\uAB6A\uAB6B\uFBB2-\uFBC2\uFF3E\uFF40\uFFE3',
        'astral': '\uD83C[\uDFFB-\uDFFF]'
    },
    {
        'name': 'Sm',
        'alias': 'Math_Symbol',
        'bmp': '\\+<->\\|~\xAC\xB1\xD7\xF7\u03F6\u0606-\u0608\u2044\u2052\u207A-\u207C\u208A-\u208C\u2118\u2140-\u2144\u214B\u2190-\u2194\u219A\u219B\u21A0\u21A3\u21A6\u21AE\u21CE\u21CF\u21D2\u21D4\u21F4-\u22FF\u2320\u2321\u237C\u239B-\u23B3\u23DC-\u23E1\u25B7\u25C1\u25F8-\u25FF\u266F\u27C0-\u27C4\u27C7-\u27E5\u27F0-\u27FF\u2900-\u2982\u2999-\u29D7\u29DC-\u29FB\u29FE-\u2AFF\u2B30-\u2B44\u2B47-\u2B4C\uFB29\uFE62\uFE64-\uFE66\uFF0B\uFF1C-\uFF1E\uFF5C\uFF5E\uFFE2\uFFE9-\uFFEC',
        'astral': '\uD835[\uDEC1\uDEDB\uDEFB\uDF15\uDF35\uDF4F\uDF6F\uDF89\uDFA9\uDFC3]|\uD83B[\uDEF0\uDEF1]'
    },
    {
        'name': 'So',
        'alias': 'Other_Symbol',
        'bmp': '\xA6\xA9\xAE\xB0\u0482\u058D\u058E\u060E\u060F\u06DE\u06E9\u06FD\u06FE\u07F6\u09FA\u0B70\u0BF3-\u0BF8\u0BFA\u0C7F\u0D4F\u0D79\u0F01-\u0F03\u0F13\u0F15-\u0F17\u0F1A-\u0F1F\u0F34\u0F36\u0F38\u0FBE-\u0FC5\u0FC7-\u0FCC\u0FCE\u0FCF\u0FD5-\u0FD8\u109E\u109F\u1390-\u1399\u166D\u1940\u19DE-\u19FF\u1B61-\u1B6A\u1B74-\u1B7C\u2100\u2101\u2103-\u2106\u2108\u2109\u2114\u2116\u2117\u211E-\u2123\u2125\u2127\u2129\u212E\u213A\u213B\u214A\u214C\u214D\u214F\u218A\u218B\u2195-\u2199\u219C-\u219F\u21A1\u21A2\u21A4\u21A5\u21A7-\u21AD\u21AF-\u21CD\u21D0\u21D1\u21D3\u21D5-\u21F3\u2300-\u2307\u230C-\u231F\u2322-\u2328\u232B-\u237B\u237D-\u239A\u23B4-\u23DB\u23E2-\u2426\u2440-\u244A\u249C-\u24E9\u2500-\u25B6\u25B8-\u25C0\u25C2-\u25F7\u2600-\u266E\u2670-\u2767\u2794-\u27BF\u2800-\u28FF\u2B00-\u2B2F\u2B45\u2B46\u2B4D-\u2B73\u2B76-\u2B95\u2B97-\u2BFF\u2CE5-\u2CEA\u2E50\u2E51\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3004\u3012\u3013\u3020\u3036\u3037\u303E\u303F\u3190\u3191\u3196-\u319F\u31C0-\u31E3\u3200-\u321E\u322A-\u3247\u3250\u3260-\u327F\u328A-\u32B0\u32C0-\u33FF\u4DC0-\u4DFF\uA490-\uA4C6\uA828-\uA82B\uA836\uA837\uA839\uAA77-\uAA79\uFD40-\uFD4F\uFDCF\uFDFD-\uFDFF\uFFE4\uFFE8\uFFED\uFFEE\uFFFC\uFFFD',
        'astral': '\uD800[\uDD37-\uDD3F\uDD79-\uDD89\uDD8C-\uDD8E\uDD90-\uDD9C\uDDA0\uDDD0-\uDDFC]|\uD802[\uDC77\uDC78\uDEC8]|\uD805\uDF3F|\uD807[\uDFD5-\uDFDC\uDFE1-\uDFF1]|\uD81A[\uDF3C-\uDF3F\uDF45]|\uD82F\uDC9C|\uD833[\uDF50-\uDFC3]|\uD834[\uDC00-\uDCF5\uDD00-\uDD26\uDD29-\uDD64\uDD6A-\uDD6C\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDDEA\uDE00-\uDE41\uDE45\uDF00-\uDF56]|\uD836[\uDC00-\uDDFF\uDE37-\uDE3A\uDE6D-\uDE74\uDE76-\uDE83\uDE85\uDE86]|\uD838\uDD4F|\uD83B[\uDCAC\uDD2E]|\uD83C[\uDC00-\uDC2B\uDC30-\uDC93\uDCA0-\uDCAE\uDCB1-\uDCBF\uDCC1-\uDCCF\uDCD1-\uDCF5\uDD0D-\uDDAD\uDDE6-\uDE02\uDE10-\uDE3B\uDE40-\uDE48\uDE50\uDE51\uDE60-\uDE65\uDF00-\uDFFA]|\uD83D[\uDC00-\uDED7\uDEDD-\uDEEC\uDEF0-\uDEFC\uDF00-\uDF73\uDF80-\uDFD8\uDFE0-\uDFEB\uDFF0]|\uD83E[\uDC00-\uDC0B\uDC10-\uDC47\uDC50-\uDC59\uDC60-\uDC87\uDC90-\uDCAD\uDCB0\uDCB1\uDD00-\uDE53\uDE60-\uDE6D\uDE70-\uDE74\uDE78-\uDE7C\uDE80-\uDE86\uDE90-\uDEAC\uDEB0-\uDEBA\uDEC0-\uDEC5\uDED0-\uDED9\uDEE0-\uDEE7\uDEF0-\uDEF6\uDF00-\uDF92\uDF94-\uDFCA]'
    },
    {
        'name': 'Z',
        'alias': 'Separator',
        'bmp': ' \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000'
    },
    {
        'name': 'Zl',
        'alias': 'Line_Separator',
        'bmp': '\u2028'
    },
    {
        'name': 'Zp',
        'alias': 'Paragraph_Separator',
        'bmp': '\u2029'
    },
    {
        'name': 'Zs',
        'alias': 'Space_Separator',
        'bmp': ' \xA0\u1680\u2000-\u200A\u202F\u205F\u3000'
    }
];


/***/ }),

/***/ 54709:
/***/ ((module) => {

module.exports = [
    {
        'name': 'ASCII',
        'bmp': '\0-\x7F'
    },
    {
        'name': 'Alphabetic',
        'bmp': 'A-Za-z\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0345\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0560-\u0588\u05B0-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05EF-\u05F2\u0610-\u061A\u0620-\u0657\u0659-\u065F\u066E-\u06D3\u06D5-\u06DC\u06E1-\u06E8\u06ED-\u06EF\u06FA-\u06FC\u06FF\u0710-\u073F\u074D-\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0817\u081A-\u082C\u0840-\u0858\u0860-\u086A\u0870-\u0887\u0889-\u088E\u08A0-\u08C9\u08D4-\u08DF\u08E3-\u08E9\u08F0-\u093B\u093D-\u094C\u094E-\u0950\u0955-\u0963\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD-\u09C4\u09C7\u09C8\u09CB\u09CC\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09F0\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3E-\u0A42\u0A47\u0A48\u0A4B\u0A4C\u0A51\u0A59-\u0A5C\u0A5E\u0A70-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD-\u0AC5\u0AC7-\u0AC9\u0ACB\u0ACC\u0AD0\u0AE0-\u0AE3\u0AF9-\u0AFC\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D-\u0B44\u0B47\u0B48\u0B4B\u0B4C\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCC\u0BD0\u0BD7\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4C\u0C55\u0C56\u0C58-\u0C5A\u0C5D\u0C60-\u0C63\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCC\u0CD5\u0CD6\u0CDD\u0CDE\u0CE0-\u0CE3\u0CF1\u0CF2\u0D00-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4C\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D7A-\u0D7F\u0D81-\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E46\u0E4D\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0ECD\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F71-\u0F81\u0F88-\u0F97\u0F99-\u0FBC\u1000-\u1036\u1038\u103B-\u103F\u1050-\u108F\u109A-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u1713\u171F-\u1733\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17B3\u17B6-\u17C8\u17D7\u17DC\u1820-\u1878\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u1938\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A1B\u1A20-\u1A5E\u1A61-\u1A74\u1AA7\u1ABF\u1AC0\u1ACC-\u1ACE\u1B00-\u1B33\u1B35-\u1B43\u1B45-\u1B4C\u1B80-\u1BA9\u1BAC-\u1BAF\u1BBA-\u1BE5\u1BE7-\u1BF1\u1C00-\u1C36\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1C90-\u1CBA\u1CBD-\u1CBF\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5\u1CF6\u1CFA\u1D00-\u1DBF\u1DE7-\u1DF4\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u24B6-\u24E9\u2C00-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312F\u3131-\u318E\u31A0-\u31BF\u31F0-\u31FF\u3400-\u4DBF\u4E00-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA674-\uA67B\uA67F-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7CA\uA7D0\uA7D1\uA7D3\uA7D5-\uA7D9\uA7F2-\uA805\uA807-\uA827\uA840-\uA873\uA880-\uA8C3\uA8C5\uA8F2-\uA8F7\uA8FB\uA8FD-\uA8FF\uA90A-\uA92A\uA930-\uA952\uA960-\uA97C\uA980-\uA9B2\uA9B4-\uA9BF\uA9CF\uA9E0-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA60-\uAA76\uAA7A-\uAABE\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF5\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB69\uAB70-\uABEA\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC',
        'astral': '\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDD70-\uDD7A\uDD7C-\uDD8A\uDD8C-\uDD92\uDD94\uDD95\uDD97-\uDDA1\uDDA3-\uDDB1\uDDB3-\uDDB9\uDDBB\uDDBC\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67\uDF80-\uDF85\uDF87-\uDFB0\uDFB2-\uDFBA]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2\uDD00-\uDD27\uDE80-\uDEA9\uDEAB\uDEAC\uDEB0\uDEB1\uDF00-\uDF1C\uDF27\uDF30-\uDF45\uDF70-\uDF81\uDFB0-\uDFC4\uDFE0-\uDFF6]|\uD804[\uDC00-\uDC45\uDC71-\uDC75\uDC82-\uDCB8\uDCC2\uDCD0-\uDCE8\uDD00-\uDD32\uDD44-\uDD47\uDD50-\uDD72\uDD76\uDD80-\uDDBF\uDDC1-\uDDC4\uDDCE\uDDCF\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE34\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEE8\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D-\uDF44\uDF47\uDF48\uDF4B\uDF4C\uDF50\uDF57\uDF5D-\uDF63]|\uD805[\uDC00-\uDC41\uDC43-\uDC45\uDC47-\uDC4A\uDC5F-\uDC61\uDC80-\uDCC1\uDCC4\uDCC5\uDCC7\uDD80-\uDDB5\uDDB8-\uDDBE\uDDD8-\uDDDD\uDE00-\uDE3E\uDE40\uDE44\uDE80-\uDEB5\uDEB8\uDF00-\uDF1A\uDF1D-\uDF2A\uDF40-\uDF46]|\uD806[\uDC00-\uDC38\uDCA0-\uDCDF\uDCFF-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD35\uDD37\uDD38\uDD3B\uDD3C\uDD3F-\uDD42\uDDA0-\uDDA7\uDDAA-\uDDD7\uDDDA-\uDDDF\uDDE1\uDDE3\uDDE4\uDE00-\uDE32\uDE35-\uDE3E\uDE50-\uDE97\uDE9D\uDEB0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC3E\uDC40\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD41\uDD43\uDD46\uDD47\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD8E\uDD90\uDD91\uDD93-\uDD96\uDD98\uDEE0-\uDEF6\uDFB0]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|\uD80B[\uDF90-\uDFF0]|[\uD80C\uD81C-\uD820\uD822\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879\uD880-\uD883][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE70-\uDEBE\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDE40-\uDE7F\uDF00-\uDF4A\uDF4F-\uDF87\uDF8F-\uDF9F\uDFE0\uDFE1\uDFE3\uDFF0\uDFF1]|\uD821[\uDC00-\uDFF7]|\uD823[\uDC00-\uDCD5\uDD00-\uDD08]|\uD82B[\uDFF0-\uDFF3\uDFF5-\uDFFB\uDFFD\uDFFE]|\uD82C[\uDC00-\uDD22\uDD50-\uDD52\uDD64-\uDD67\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9E]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD837[\uDF00-\uDF1E]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A\uDD00-\uDD2C\uDD37-\uDD3D\uDD4E\uDE90-\uDEAD\uDEC0-\uDEEB]|\uD839[\uDFE0-\uDFE6\uDFE8-\uDFEB\uDFED\uDFEE\uDFF0-\uDFFE]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43\uDD47\uDD4B]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD83C[\uDD30-\uDD49\uDD50-\uDD69\uDD70-\uDD89]|\uD869[\uDC00-\uDEDF\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF38\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A]'
    },
    {
        'name': 'Any',
        'isBmpLast': true,
        'bmp': '\0-\uFFFF',
        'astral': '[\uD800-\uDBFF][\uDC00-\uDFFF]'
    },
    {
        'name': 'Default_Ignorable_Code_Point',
        'bmp': '\xAD\u034F\u061C\u115F\u1160\u17B4\u17B5\u180B-\u180F\u200B-\u200F\u202A-\u202E\u2060-\u206F\u3164\uFE00-\uFE0F\uFEFF\uFFA0\uFFF0-\uFFF8',
        'astral': '\uD82F[\uDCA0-\uDCA3]|\uD834[\uDD73-\uDD7A]|[\uDB40-\uDB43][\uDC00-\uDFFF]'
    },
    {
        'name': 'Lowercase',
        'bmp': 'a-z\xAA\xB5\xBA\xDF-\xF6\xF8-\xFF\u0101\u0103\u0105\u0107\u0109\u010B\u010D\u010F\u0111\u0113\u0115\u0117\u0119\u011B\u011D\u011F\u0121\u0123\u0125\u0127\u0129\u012B\u012D\u012F\u0131\u0133\u0135\u0137\u0138\u013A\u013C\u013E\u0140\u0142\u0144\u0146\u0148\u0149\u014B\u014D\u014F\u0151\u0153\u0155\u0157\u0159\u015B\u015D\u015F\u0161\u0163\u0165\u0167\u0169\u016B\u016D\u016F\u0171\u0173\u0175\u0177\u017A\u017C\u017E-\u0180\u0183\u0185\u0188\u018C\u018D\u0192\u0195\u0199-\u019B\u019E\u01A1\u01A3\u01A5\u01A8\u01AA\u01AB\u01AD\u01B0\u01B4\u01B6\u01B9\u01BA\u01BD-\u01BF\u01C6\u01C9\u01CC\u01CE\u01D0\u01D2\u01D4\u01D6\u01D8\u01DA\u01DC\u01DD\u01DF\u01E1\u01E3\u01E5\u01E7\u01E9\u01EB\u01ED\u01EF\u01F0\u01F3\u01F5\u01F9\u01FB\u01FD\u01FF\u0201\u0203\u0205\u0207\u0209\u020B\u020D\u020F\u0211\u0213\u0215\u0217\u0219\u021B\u021D\u021F\u0221\u0223\u0225\u0227\u0229\u022B\u022D\u022F\u0231\u0233-\u0239\u023C\u023F\u0240\u0242\u0247\u0249\u024B\u024D\u024F-\u0293\u0295-\u02B8\u02C0\u02C1\u02E0-\u02E4\u0345\u0371\u0373\u0377\u037A-\u037D\u0390\u03AC-\u03CE\u03D0\u03D1\u03D5-\u03D7\u03D9\u03DB\u03DD\u03DF\u03E1\u03E3\u03E5\u03E7\u03E9\u03EB\u03ED\u03EF-\u03F3\u03F5\u03F8\u03FB\u03FC\u0430-\u045F\u0461\u0463\u0465\u0467\u0469\u046B\u046D\u046F\u0471\u0473\u0475\u0477\u0479\u047B\u047D\u047F\u0481\u048B\u048D\u048F\u0491\u0493\u0495\u0497\u0499\u049B\u049D\u049F\u04A1\u04A3\u04A5\u04A7\u04A9\u04AB\u04AD\u04AF\u04B1\u04B3\u04B5\u04B7\u04B9\u04BB\u04BD\u04BF\u04C2\u04C4\u04C6\u04C8\u04CA\u04CC\u04CE\u04CF\u04D1\u04D3\u04D5\u04D7\u04D9\u04DB\u04DD\u04DF\u04E1\u04E3\u04E5\u04E7\u04E9\u04EB\u04ED\u04EF\u04F1\u04F3\u04F5\u04F7\u04F9\u04FB\u04FD\u04FF\u0501\u0503\u0505\u0507\u0509\u050B\u050D\u050F\u0511\u0513\u0515\u0517\u0519\u051B\u051D\u051F\u0521\u0523\u0525\u0527\u0529\u052B\u052D\u052F\u0560-\u0588\u10D0-\u10FA\u10FD-\u10FF\u13F8-\u13FD\u1C80-\u1C88\u1D00-\u1DBF\u1E01\u1E03\u1E05\u1E07\u1E09\u1E0B\u1E0D\u1E0F\u1E11\u1E13\u1E15\u1E17\u1E19\u1E1B\u1E1D\u1E1F\u1E21\u1E23\u1E25\u1E27\u1E29\u1E2B\u1E2D\u1E2F\u1E31\u1E33\u1E35\u1E37\u1E39\u1E3B\u1E3D\u1E3F\u1E41\u1E43\u1E45\u1E47\u1E49\u1E4B\u1E4D\u1E4F\u1E51\u1E53\u1E55\u1E57\u1E59\u1E5B\u1E5D\u1E5F\u1E61\u1E63\u1E65\u1E67\u1E69\u1E6B\u1E6D\u1E6F\u1E71\u1E73\u1E75\u1E77\u1E79\u1E7B\u1E7D\u1E7F\u1E81\u1E83\u1E85\u1E87\u1E89\u1E8B\u1E8D\u1E8F\u1E91\u1E93\u1E95-\u1E9D\u1E9F\u1EA1\u1EA3\u1EA5\u1EA7\u1EA9\u1EAB\u1EAD\u1EAF\u1EB1\u1EB3\u1EB5\u1EB7\u1EB9\u1EBB\u1EBD\u1EBF\u1EC1\u1EC3\u1EC5\u1EC7\u1EC9\u1ECB\u1ECD\u1ECF\u1ED1\u1ED3\u1ED5\u1ED7\u1ED9\u1EDB\u1EDD\u1EDF\u1EE1\u1EE3\u1EE5\u1EE7\u1EE9\u1EEB\u1EED\u1EEF\u1EF1\u1EF3\u1EF5\u1EF7\u1EF9\u1EFB\u1EFD\u1EFF-\u1F07\u1F10-\u1F15\u1F20-\u1F27\u1F30-\u1F37\u1F40-\u1F45\u1F50-\u1F57\u1F60-\u1F67\u1F70-\u1F7D\u1F80-\u1F87\u1F90-\u1F97\u1FA0-\u1FA7\u1FB0-\u1FB4\u1FB6\u1FB7\u1FBE\u1FC2-\u1FC4\u1FC6\u1FC7\u1FD0-\u1FD3\u1FD6\u1FD7\u1FE0-\u1FE7\u1FF2-\u1FF4\u1FF6\u1FF7\u2071\u207F\u2090-\u209C\u210A\u210E\u210F\u2113\u212F\u2134\u2139\u213C\u213D\u2146-\u2149\u214E\u2170-\u217F\u2184\u24D0-\u24E9\u2C30-\u2C5F\u2C61\u2C65\u2C66\u2C68\u2C6A\u2C6C\u2C71\u2C73\u2C74\u2C76-\u2C7D\u2C81\u2C83\u2C85\u2C87\u2C89\u2C8B\u2C8D\u2C8F\u2C91\u2C93\u2C95\u2C97\u2C99\u2C9B\u2C9D\u2C9F\u2CA1\u2CA3\u2CA5\u2CA7\u2CA9\u2CAB\u2CAD\u2CAF\u2CB1\u2CB3\u2CB5\u2CB7\u2CB9\u2CBB\u2CBD\u2CBF\u2CC1\u2CC3\u2CC5\u2CC7\u2CC9\u2CCB\u2CCD\u2CCF\u2CD1\u2CD3\u2CD5\u2CD7\u2CD9\u2CDB\u2CDD\u2CDF\u2CE1\u2CE3\u2CE4\u2CEC\u2CEE\u2CF3\u2D00-\u2D25\u2D27\u2D2D\uA641\uA643\uA645\uA647\uA649\uA64B\uA64D\uA64F\uA651\uA653\uA655\uA657\uA659\uA65B\uA65D\uA65F\uA661\uA663\uA665\uA667\uA669\uA66B\uA66D\uA681\uA683\uA685\uA687\uA689\uA68B\uA68D\uA68F\uA691\uA693\uA695\uA697\uA699\uA69B-\uA69D\uA723\uA725\uA727\uA729\uA72B\uA72D\uA72F-\uA731\uA733\uA735\uA737\uA739\uA73B\uA73D\uA73F\uA741\uA743\uA745\uA747\uA749\uA74B\uA74D\uA74F\uA751\uA753\uA755\uA757\uA759\uA75B\uA75D\uA75F\uA761\uA763\uA765\uA767\uA769\uA76B\uA76D\uA76F-\uA778\uA77A\uA77C\uA77F\uA781\uA783\uA785\uA787\uA78C\uA78E\uA791\uA793-\uA795\uA797\uA799\uA79B\uA79D\uA79F\uA7A1\uA7A3\uA7A5\uA7A7\uA7A9\uA7AF\uA7B5\uA7B7\uA7B9\uA7BB\uA7BD\uA7BF\uA7C1\uA7C3\uA7C8\uA7CA\uA7D1\uA7D3\uA7D5\uA7D7\uA7D9\uA7F6\uA7F8-\uA7FA\uAB30-\uAB5A\uAB5C-\uAB68\uAB70-\uABBF\uFB00-\uFB06\uFB13-\uFB17\uFF41-\uFF5A',
        'astral': '\uD801[\uDC28-\uDC4F\uDCD8-\uDCFB\uDD97-\uDDA1\uDDA3-\uDDB1\uDDB3-\uDDB9\uDDBB\uDDBC\uDF80\uDF83-\uDF85\uDF87-\uDFB0\uDFB2-\uDFBA]|\uD803[\uDCC0-\uDCF2]|\uD806[\uDCC0-\uDCDF]|\uD81B[\uDE60-\uDE7F]|\uD835[\uDC1A-\uDC33\uDC4E-\uDC54\uDC56-\uDC67\uDC82-\uDC9B\uDCB6-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDCCF\uDCEA-\uDD03\uDD1E-\uDD37\uDD52-\uDD6B\uDD86-\uDD9F\uDDBA-\uDDD3\uDDEE-\uDE07\uDE22-\uDE3B\uDE56-\uDE6F\uDE8A-\uDEA5\uDEC2-\uDEDA\uDEDC-\uDEE1\uDEFC-\uDF14\uDF16-\uDF1B\uDF36-\uDF4E\uDF50-\uDF55\uDF70-\uDF88\uDF8A-\uDF8F\uDFAA-\uDFC2\uDFC4-\uDFC9\uDFCB]|\uD837[\uDF00-\uDF09\uDF0B-\uDF1E]|\uD83A[\uDD22-\uDD43]'
    },
    {
        'name': 'Noncharacter_Code_Point',
        'bmp': '\uFDD0-\uFDEF\uFFFE\uFFFF',
        'astral': '[\uD83F\uD87F\uD8BF\uD8FF\uD93F\uD97F\uD9BF\uD9FF\uDA3F\uDA7F\uDABF\uDAFF\uDB3F\uDB7F\uDBBF\uDBFF][\uDFFE\uDFFF]'
    },
    {
        'name': 'Uppercase',
        'bmp': 'A-Z\xC0-\xD6\xD8-\xDE\u0100\u0102\u0104\u0106\u0108\u010A\u010C\u010E\u0110\u0112\u0114\u0116\u0118\u011A\u011C\u011E\u0120\u0122\u0124\u0126\u0128\u012A\u012C\u012E\u0130\u0132\u0134\u0136\u0139\u013B\u013D\u013F\u0141\u0143\u0145\u0147\u014A\u014C\u014E\u0150\u0152\u0154\u0156\u0158\u015A\u015C\u015E\u0160\u0162\u0164\u0166\u0168\u016A\u016C\u016E\u0170\u0172\u0174\u0176\u0178\u0179\u017B\u017D\u0181\u0182\u0184\u0186\u0187\u0189-\u018B\u018E-\u0191\u0193\u0194\u0196-\u0198\u019C\u019D\u019F\u01A0\u01A2\u01A4\u01A6\u01A7\u01A9\u01AC\u01AE\u01AF\u01B1-\u01B3\u01B5\u01B7\u01B8\u01BC\u01C4\u01C7\u01CA\u01CD\u01CF\u01D1\u01D3\u01D5\u01D7\u01D9\u01DB\u01DE\u01E0\u01E2\u01E4\u01E6\u01E8\u01EA\u01EC\u01EE\u01F1\u01F4\u01F6-\u01F8\u01FA\u01FC\u01FE\u0200\u0202\u0204\u0206\u0208\u020A\u020C\u020E\u0210\u0212\u0214\u0216\u0218\u021A\u021C\u021E\u0220\u0222\u0224\u0226\u0228\u022A\u022C\u022E\u0230\u0232\u023A\u023B\u023D\u023E\u0241\u0243-\u0246\u0248\u024A\u024C\u024E\u0370\u0372\u0376\u037F\u0386\u0388-\u038A\u038C\u038E\u038F\u0391-\u03A1\u03A3-\u03AB\u03CF\u03D2-\u03D4\u03D8\u03DA\u03DC\u03DE\u03E0\u03E2\u03E4\u03E6\u03E8\u03EA\u03EC\u03EE\u03F4\u03F7\u03F9\u03FA\u03FD-\u042F\u0460\u0462\u0464\u0466\u0468\u046A\u046C\u046E\u0470\u0472\u0474\u0476\u0478\u047A\u047C\u047E\u0480\u048A\u048C\u048E\u0490\u0492\u0494\u0496\u0498\u049A\u049C\u049E\u04A0\u04A2\u04A4\u04A6\u04A8\u04AA\u04AC\u04AE\u04B0\u04B2\u04B4\u04B6\u04B8\u04BA\u04BC\u04BE\u04C0\u04C1\u04C3\u04C5\u04C7\u04C9\u04CB\u04CD\u04D0\u04D2\u04D4\u04D6\u04D8\u04DA\u04DC\u04DE\u04E0\u04E2\u04E4\u04E6\u04E8\u04EA\u04EC\u04EE\u04F0\u04F2\u04F4\u04F6\u04F8\u04FA\u04FC\u04FE\u0500\u0502\u0504\u0506\u0508\u050A\u050C\u050E\u0510\u0512\u0514\u0516\u0518\u051A\u051C\u051E\u0520\u0522\u0524\u0526\u0528\u052A\u052C\u052E\u0531-\u0556\u10A0-\u10C5\u10C7\u10CD\u13A0-\u13F5\u1C90-\u1CBA\u1CBD-\u1CBF\u1E00\u1E02\u1E04\u1E06\u1E08\u1E0A\u1E0C\u1E0E\u1E10\u1E12\u1E14\u1E16\u1E18\u1E1A\u1E1C\u1E1E\u1E20\u1E22\u1E24\u1E26\u1E28\u1E2A\u1E2C\u1E2E\u1E30\u1E32\u1E34\u1E36\u1E38\u1E3A\u1E3C\u1E3E\u1E40\u1E42\u1E44\u1E46\u1E48\u1E4A\u1E4C\u1E4E\u1E50\u1E52\u1E54\u1E56\u1E58\u1E5A\u1E5C\u1E5E\u1E60\u1E62\u1E64\u1E66\u1E68\u1E6A\u1E6C\u1E6E\u1E70\u1E72\u1E74\u1E76\u1E78\u1E7A\u1E7C\u1E7E\u1E80\u1E82\u1E84\u1E86\u1E88\u1E8A\u1E8C\u1E8E\u1E90\u1E92\u1E94\u1E9E\u1EA0\u1EA2\u1EA4\u1EA6\u1EA8\u1EAA\u1EAC\u1EAE\u1EB0\u1EB2\u1EB4\u1EB6\u1EB8\u1EBA\u1EBC\u1EBE\u1EC0\u1EC2\u1EC4\u1EC6\u1EC8\u1ECA\u1ECC\u1ECE\u1ED0\u1ED2\u1ED4\u1ED6\u1ED8\u1EDA\u1EDC\u1EDE\u1EE0\u1EE2\u1EE4\u1EE6\u1EE8\u1EEA\u1EEC\u1EEE\u1EF0\u1EF2\u1EF4\u1EF6\u1EF8\u1EFA\u1EFC\u1EFE\u1F08-\u1F0F\u1F18-\u1F1D\u1F28-\u1F2F\u1F38-\u1F3F\u1F48-\u1F4D\u1F59\u1F5B\u1F5D\u1F5F\u1F68-\u1F6F\u1FB8-\u1FBB\u1FC8-\u1FCB\u1FD8-\u1FDB\u1FE8-\u1FEC\u1FF8-\u1FFB\u2102\u2107\u210B-\u210D\u2110-\u2112\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u2130-\u2133\u213E\u213F\u2145\u2160-\u216F\u2183\u24B6-\u24CF\u2C00-\u2C2F\u2C60\u2C62-\u2C64\u2C67\u2C69\u2C6B\u2C6D-\u2C70\u2C72\u2C75\u2C7E-\u2C80\u2C82\u2C84\u2C86\u2C88\u2C8A\u2C8C\u2C8E\u2C90\u2C92\u2C94\u2C96\u2C98\u2C9A\u2C9C\u2C9E\u2CA0\u2CA2\u2CA4\u2CA6\u2CA8\u2CAA\u2CAC\u2CAE\u2CB0\u2CB2\u2CB4\u2CB6\u2CB8\u2CBA\u2CBC\u2CBE\u2CC0\u2CC2\u2CC4\u2CC6\u2CC8\u2CCA\u2CCC\u2CCE\u2CD0\u2CD2\u2CD4\u2CD6\u2CD8\u2CDA\u2CDC\u2CDE\u2CE0\u2CE2\u2CEB\u2CED\u2CF2\uA640\uA642\uA644\uA646\uA648\uA64A\uA64C\uA64E\uA650\uA652\uA654\uA656\uA658\uA65A\uA65C\uA65E\uA660\uA662\uA664\uA666\uA668\uA66A\uA66C\uA680\uA682\uA684\uA686\uA688\uA68A\uA68C\uA68E\uA690\uA692\uA694\uA696\uA698\uA69A\uA722\uA724\uA726\uA728\uA72A\uA72C\uA72E\uA732\uA734\uA736\uA738\uA73A\uA73C\uA73E\uA740\uA742\uA744\uA746\uA748\uA74A\uA74C\uA74E\uA750\uA752\uA754\uA756\uA758\uA75A\uA75C\uA75E\uA760\uA762\uA764\uA766\uA768\uA76A\uA76C\uA76E\uA779\uA77B\uA77D\uA77E\uA780\uA782\uA784\uA786\uA78B\uA78D\uA790\uA792\uA796\uA798\uA79A\uA79C\uA79E\uA7A0\uA7A2\uA7A4\uA7A6\uA7A8\uA7AA-\uA7AE\uA7B0-\uA7B4\uA7B6\uA7B8\uA7BA\uA7BC\uA7BE\uA7C0\uA7C2\uA7C4-\uA7C7\uA7C9\uA7D0\uA7D6\uA7D8\uA7F5\uFF21-\uFF3A',
        'astral': '\uD801[\uDC00-\uDC27\uDCB0-\uDCD3\uDD70-\uDD7A\uDD7C-\uDD8A\uDD8C-\uDD92\uDD94\uDD95]|\uD803[\uDC80-\uDCB2]|\uD806[\uDCA0-\uDCBF]|\uD81B[\uDE40-\uDE5F]|\uD835[\uDC00-\uDC19\uDC34-\uDC4D\uDC68-\uDC81\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB5\uDCD0-\uDCE9\uDD04\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD38\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD6C-\uDD85\uDDA0-\uDDB9\uDDD4-\uDDED\uDE08-\uDE21\uDE3C-\uDE55\uDE70-\uDE89\uDEA8-\uDEC0\uDEE2-\uDEFA\uDF1C-\uDF34\uDF56-\uDF6E\uDF90-\uDFA8\uDFCA]|\uD83A[\uDD00-\uDD21]|\uD83C[\uDD30-\uDD49\uDD50-\uDD69\uDD70-\uDD89]'
    },
    {
        'name': 'White_Space',
        'bmp': '\t-\r \x85\xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000'
    }
];


/***/ }),

/***/ 36749:
/***/ ((module) => {

module.exports = [
    {
        'name': 'Adlam',
        'astral': '\uD83A[\uDD00-\uDD4B\uDD50-\uDD59\uDD5E\uDD5F]'
    },
    {
        'name': 'Ahom',
        'astral': '\uD805[\uDF00-\uDF1A\uDF1D-\uDF2B\uDF30-\uDF46]'
    },
    {
        'name': 'Anatolian_Hieroglyphs',
        'astral': '\uD811[\uDC00-\uDE46]'
    },
    {
        'name': 'Arabic',
        'bmp': '\u0600-\u0604\u0606-\u060B\u060D-\u061A\u061C-\u061E\u0620-\u063F\u0641-\u064A\u0656-\u066F\u0671-\u06DC\u06DE-\u06FF\u0750-\u077F\u0870-\u088E\u0890\u0891\u0898-\u08E1\u08E3-\u08FF\uFB50-\uFBC2\uFBD3-\uFD3D\uFD40-\uFD8F\uFD92-\uFDC7\uFDCF\uFDF0-\uFDFF\uFE70-\uFE74\uFE76-\uFEFC',
        'astral': '\uD803[\uDE60-\uDE7E]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB\uDEF0\uDEF1]'
    },
    {
        'name': 'Armenian',
        'bmp': '\u0531-\u0556\u0559-\u058A\u058D-\u058F\uFB13-\uFB17'
    },
    {
        'name': 'Avestan',
        'astral': '\uD802[\uDF00-\uDF35\uDF39-\uDF3F]'
    },
    {
        'name': 'Balinese',
        'bmp': '\u1B00-\u1B4C\u1B50-\u1B7E'
    },
    {
        'name': 'Bamum',
        'bmp': '\uA6A0-\uA6F7',
        'astral': '\uD81A[\uDC00-\uDE38]'
    },
    {
        'name': 'Bassa_Vah',
        'astral': '\uD81A[\uDED0-\uDEED\uDEF0-\uDEF5]'
    },
    {
        'name': 'Batak',
        'bmp': '\u1BC0-\u1BF3\u1BFC-\u1BFF'
    },
    {
        'name': 'Bengali',
        'bmp': '\u0980-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09FE'
    },
    {
        'name': 'Bhaiksuki',
        'astral': '\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC45\uDC50-\uDC6C]'
    },
    {
        'name': 'Bopomofo',
        'bmp': '\u02EA\u02EB\u3105-\u312F\u31A0-\u31BF'
    },
    {
        'name': 'Brahmi',
        'astral': '\uD804[\uDC00-\uDC4D\uDC52-\uDC75\uDC7F]'
    },
    {
        'name': 'Braille',
        'bmp': '\u2800-\u28FF'
    },
    {
        'name': 'Buginese',
        'bmp': '\u1A00-\u1A1B\u1A1E\u1A1F'
    },
    {
        'name': 'Buhid',
        'bmp': '\u1740-\u1753'
    },
    {
        'name': 'Canadian_Aboriginal',
        'bmp': '\u1400-\u167F\u18B0-\u18F5',
        'astral': '\uD806[\uDEB0-\uDEBF]'
    },
    {
        'name': 'Carian',
        'astral': '\uD800[\uDEA0-\uDED0]'
    },
    {
        'name': 'Caucasian_Albanian',
        'astral': '\uD801[\uDD30-\uDD63\uDD6F]'
    },
    {
        'name': 'Chakma',
        'astral': '\uD804[\uDD00-\uDD34\uDD36-\uDD47]'
    },
    {
        'name': 'Cham',
        'bmp': '\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA5C-\uAA5F'
    },
    {
        'name': 'Cherokee',
        'bmp': '\u13A0-\u13F5\u13F8-\u13FD\uAB70-\uABBF'
    },
    {
        'name': 'Chorasmian',
        'astral': '\uD803[\uDFB0-\uDFCB]'
    },
    {
        'name': 'Common',
        'bmp': '\0-@\\[-`\\{-\xA9\xAB-\xB9\xBB-\xBF\xD7\xF7\u02B9-\u02DF\u02E5-\u02E9\u02EC-\u02FF\u0374\u037E\u0385\u0387\u0605\u060C\u061B\u061F\u0640\u06DD\u08E2\u0964\u0965\u0E3F\u0FD5-\u0FD8\u10FB\u16EB-\u16ED\u1735\u1736\u1802\u1803\u1805\u1CD3\u1CE1\u1CE9-\u1CEC\u1CEE-\u1CF3\u1CF5-\u1CF7\u1CFA\u2000-\u200B\u200E-\u2064\u2066-\u2070\u2074-\u207E\u2080-\u208E\u20A0-\u20C0\u2100-\u2125\u2127-\u2129\u212C-\u2131\u2133-\u214D\u214F-\u215F\u2189-\u218B\u2190-\u2426\u2440-\u244A\u2460-\u27FF\u2900-\u2B73\u2B76-\u2B95\u2B97-\u2BFF\u2E00-\u2E5D\u2FF0-\u2FFB\u3000-\u3004\u3006\u3008-\u3020\u3030-\u3037\u303C-\u303F\u309B\u309C\u30A0\u30FB\u30FC\u3190-\u319F\u31C0-\u31E3\u3220-\u325F\u327F-\u32CF\u32FF\u3358-\u33FF\u4DC0-\u4DFF\uA700-\uA721\uA788-\uA78A\uA830-\uA839\uA92E\uA9CF\uAB5B\uAB6A\uAB6B\uFD3E\uFD3F\uFE10-\uFE19\uFE30-\uFE52\uFE54-\uFE66\uFE68-\uFE6B\uFEFF\uFF01-\uFF20\uFF3B-\uFF40\uFF5B-\uFF65\uFF70\uFF9E\uFF9F\uFFE0-\uFFE6\uFFE8-\uFFEE\uFFF9-\uFFFD',
        'astral': '\uD800[\uDD00-\uDD02\uDD07-\uDD33\uDD37-\uDD3F\uDD90-\uDD9C\uDDD0-\uDDFC\uDEE1-\uDEFB]|\uD82F[\uDCA0-\uDCA3]|\uD833[\uDF50-\uDFC3]|\uD834[\uDC00-\uDCF5\uDD00-\uDD26\uDD29-\uDD66\uDD6A-\uDD7A\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDDEA\uDEE0-\uDEF3\uDF00-\uDF56\uDF60-\uDF78]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDFCB\uDFCE-\uDFFF]|\uD83B[\uDC71-\uDCB4\uDD01-\uDD3D]|\uD83C[\uDC00-\uDC2B\uDC30-\uDC93\uDCA0-\uDCAE\uDCB1-\uDCBF\uDCC1-\uDCCF\uDCD1-\uDCF5\uDD00-\uDDAD\uDDE6-\uDDFF\uDE01\uDE02\uDE10-\uDE3B\uDE40-\uDE48\uDE50\uDE51\uDE60-\uDE65\uDF00-\uDFFF]|\uD83D[\uDC00-\uDED7\uDEDD-\uDEEC\uDEF0-\uDEFC\uDF00-\uDF73\uDF80-\uDFD8\uDFE0-\uDFEB\uDFF0]|\uD83E[\uDC00-\uDC0B\uDC10-\uDC47\uDC50-\uDC59\uDC60-\uDC87\uDC90-\uDCAD\uDCB0\uDCB1\uDD00-\uDE53\uDE60-\uDE6D\uDE70-\uDE74\uDE78-\uDE7C\uDE80-\uDE86\uDE90-\uDEAC\uDEB0-\uDEBA\uDEC0-\uDEC5\uDED0-\uDED9\uDEE0-\uDEE7\uDEF0-\uDEF6\uDF00-\uDF92\uDF94-\uDFCA\uDFF0-\uDFF9]|\uDB40[\uDC01\uDC20-\uDC7F]'
    },
    {
        'name': 'Coptic',
        'bmp': '\u03E2-\u03EF\u2C80-\u2CF3\u2CF9-\u2CFF'
    },
    {
        'name': 'Cuneiform',
        'astral': '\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC70-\uDC74\uDC80-\uDD43]'
    },
    {
        'name': 'Cypriot',
        'astral': '\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F]'
    },
    {
        'name': 'Cypro_Minoan',
        'astral': '\uD80B[\uDF90-\uDFF2]'
    },
    {
        'name': 'Cyrillic',
        'bmp': '\u0400-\u0484\u0487-\u052F\u1C80-\u1C88\u1D2B\u1D78\u2DE0-\u2DFF\uA640-\uA69F\uFE2E\uFE2F'
    },
    {
        'name': 'Deseret',
        'astral': '\uD801[\uDC00-\uDC4F]'
    },
    {
        'name': 'Devanagari',
        'bmp': '\u0900-\u0950\u0955-\u0963\u0966-\u097F\uA8E0-\uA8FF'
    },
    {
        'name': 'Dives_Akuru',
        'astral': '\uD806[\uDD00-\uDD06\uDD09\uDD0C-\uDD13\uDD15\uDD16\uDD18-\uDD35\uDD37\uDD38\uDD3B-\uDD46\uDD50-\uDD59]'
    },
    {
        'name': 'Dogra',
        'astral': '\uD806[\uDC00-\uDC3B]'
    },
    {
        'name': 'Duployan',
        'astral': '\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9C-\uDC9F]'
    },
    {
        'name': 'Egyptian_Hieroglyphs',
        'astral': '\uD80C[\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E\uDC30-\uDC38]'
    },
    {
        'name': 'Elbasan',
        'astral': '\uD801[\uDD00-\uDD27]'
    },
    {
        'name': 'Elymaic',
        'astral': '\uD803[\uDFE0-\uDFF6]'
    },
    {
        'name': 'Ethiopic',
        'bmp': '\u1200-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u137C\u1380-\u1399\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E',
        'astral': '\uD839[\uDFE0-\uDFE6\uDFE8-\uDFEB\uDFED\uDFEE\uDFF0-\uDFFE]'
    },
    {
        'name': 'Georgian',
        'bmp': '\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u10FF\u1C90-\u1CBA\u1CBD-\u1CBF\u2D00-\u2D25\u2D27\u2D2D'
    },
    {
        'name': 'Glagolitic',
        'bmp': '\u2C00-\u2C5F',
        'astral': '\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]'
    },
    {
        'name': 'Gothic',
        'astral': '\uD800[\uDF30-\uDF4A]'
    },
    {
        'name': 'Grantha',
        'astral': '\uD804[\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]'
    },
    {
        'name': 'Greek',
        'bmp': '\u0370-\u0373\u0375-\u0377\u037A-\u037D\u037F\u0384\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03E1\u03F0-\u03FF\u1D26-\u1D2A\u1D5D-\u1D61\u1D66-\u1D6A\u1DBF\u1F00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FC4\u1FC6-\u1FD3\u1FD6-\u1FDB\u1FDD-\u1FEF\u1FF2-\u1FF4\u1FF6-\u1FFE\u2126\uAB65',
        'astral': '\uD800[\uDD40-\uDD8E\uDDA0]|\uD834[\uDE00-\uDE45]'
    },
    {
        'name': 'Gujarati',
        'bmp': '\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AF1\u0AF9-\u0AFF'
    },
    {
        'name': 'Gunjala_Gondi',
        'astral': '\uD807[\uDD60-\uDD65\uDD67\uDD68\uDD6A-\uDD8E\uDD90\uDD91\uDD93-\uDD98\uDDA0-\uDDA9]'
    },
    {
        'name': 'Gurmukhi',
        'bmp': '\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A76'
    },
    {
        'name': 'Han',
        'bmp': '\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u3005\u3007\u3021-\u3029\u3038-\u303B\u3400-\u4DBF\u4E00-\u9FFF\uF900-\uFA6D\uFA70-\uFAD9',
        'astral': '\uD81B[\uDFE2\uDFE3\uDFF0\uDFF1]|[\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879\uD880-\uD883][\uDC00-\uDFFF]|\uD869[\uDC00-\uDEDF\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF38\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uD884[\uDC00-\uDF4A]'
    },
    {
        'name': 'Hangul',
        'bmp': '\u1100-\u11FF\u302E\u302F\u3131-\u318E\u3200-\u321E\u3260-\u327E\uA960-\uA97C\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uFFA0-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC'
    },
    {
        'name': 'Hanifi_Rohingya',
        'astral': '\uD803[\uDD00-\uDD27\uDD30-\uDD39]'
    },
    {
        'name': 'Hanunoo',
        'bmp': '\u1720-\u1734'
    },
    {
        'name': 'Hatran',
        'astral': '\uD802[\uDCE0-\uDCF2\uDCF4\uDCF5\uDCFB-\uDCFF]'
    },
    {
        'name': 'Hebrew',
        'bmp': '\u0591-\u05C7\u05D0-\u05EA\u05EF-\u05F4\uFB1D-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFB4F'
    },
    {
        'name': 'Hiragana',
        'bmp': '\u3041-\u3096\u309D-\u309F',
        'astral': '\uD82C[\uDC01-\uDD1F\uDD50-\uDD52]|\uD83C\uDE00'
    },
    {
        'name': 'Imperial_Aramaic',
        'astral': '\uD802[\uDC40-\uDC55\uDC57-\uDC5F]'
    },
    {
        'name': 'Inherited',
        'bmp': '\u0300-\u036F\u0485\u0486\u064B-\u0655\u0670\u0951-\u0954\u1AB0-\u1ACE\u1CD0-\u1CD2\u1CD4-\u1CE0\u1CE2-\u1CE8\u1CED\u1CF4\u1CF8\u1CF9\u1DC0-\u1DFF\u200C\u200D\u20D0-\u20F0\u302A-\u302D\u3099\u309A\uFE00-\uFE0F\uFE20-\uFE2D',
        'astral': '\uD800[\uDDFD\uDEE0]|\uD804\uDF3B|\uD833[\uDF00-\uDF2D\uDF30-\uDF46]|\uD834[\uDD67-\uDD69\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD]|\uDB40[\uDD00-\uDDEF]'
    },
    {
        'name': 'Inscriptional_Pahlavi',
        'astral': '\uD802[\uDF60-\uDF72\uDF78-\uDF7F]'
    },
    {
        'name': 'Inscriptional_Parthian',
        'astral': '\uD802[\uDF40-\uDF55\uDF58-\uDF5F]'
    },
    {
        'name': 'Javanese',
        'bmp': '\uA980-\uA9CD\uA9D0-\uA9D9\uA9DE\uA9DF'
    },
    {
        'name': 'Kaithi',
        'astral': '\uD804[\uDC80-\uDCC2\uDCCD]'
    },
    {
        'name': 'Kannada',
        'bmp': '\u0C80-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDD\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2'
    },
    {
        'name': 'Katakana',
        'bmp': '\u30A1-\u30FA\u30FD-\u30FF\u31F0-\u31FF\u32D0-\u32FE\u3300-\u3357\uFF66-\uFF6F\uFF71-\uFF9D',
        'astral': '\uD82B[\uDFF0-\uDFF3\uDFF5-\uDFFB\uDFFD\uDFFE]|\uD82C[\uDC00\uDD20-\uDD22\uDD64-\uDD67]'
    },
    {
        'name': 'Kayah_Li',
        'bmp': '\uA900-\uA92D\uA92F'
    },
    {
        'name': 'Kharoshthi',
        'astral': '\uD802[\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE35\uDE38-\uDE3A\uDE3F-\uDE48\uDE50-\uDE58]'
    },
    {
        'name': 'Khitan_Small_Script',
        'astral': '\uD81B\uDFE4|\uD822[\uDF00-\uDFFF]|\uD823[\uDC00-\uDCD5]'
    },
    {
        'name': 'Khmer',
        'bmp': '\u1780-\u17DD\u17E0-\u17E9\u17F0-\u17F9\u19E0-\u19FF'
    },
    {
        'name': 'Khojki',
        'astral': '\uD804[\uDE00-\uDE11\uDE13-\uDE3E]'
    },
    {
        'name': 'Khudawadi',
        'astral': '\uD804[\uDEB0-\uDEEA\uDEF0-\uDEF9]'
    },
    {
        'name': 'Lao',
        'bmp': '\u0E81\u0E82\u0E84\u0E86-\u0E8A\u0E8C-\u0EA3\u0EA5\u0EA7-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF'
    },
    {
        'name': 'Latin',
        'bmp': 'A-Za-z\xAA\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02B8\u02E0-\u02E4\u1D00-\u1D25\u1D2C-\u1D5C\u1D62-\u1D65\u1D6B-\u1D77\u1D79-\u1DBE\u1E00-\u1EFF\u2071\u207F\u2090-\u209C\u212A\u212B\u2132\u214E\u2160-\u2188\u2C60-\u2C7F\uA722-\uA787\uA78B-\uA7CA\uA7D0\uA7D1\uA7D3\uA7D5-\uA7D9\uA7F2-\uA7FF\uAB30-\uAB5A\uAB5C-\uAB64\uAB66-\uAB69\uFB00-\uFB06\uFF21-\uFF3A\uFF41-\uFF5A',
        'astral': '\uD801[\uDF80-\uDF85\uDF87-\uDFB0\uDFB2-\uDFBA]|\uD837[\uDF00-\uDF1E]'
    },
    {
        'name': 'Lepcha',
        'bmp': '\u1C00-\u1C37\u1C3B-\u1C49\u1C4D-\u1C4F'
    },
    {
        'name': 'Limbu',
        'bmp': '\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1940\u1944-\u194F'
    },
    {
        'name': 'Linear_A',
        'astral': '\uD801[\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]'
    },
    {
        'name': 'Linear_B',
        'astral': '\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA]'
    },
    {
        'name': 'Lisu',
        'bmp': '\uA4D0-\uA4FF',
        'astral': '\uD807\uDFB0'
    },
    {
        'name': 'Lycian',
        'astral': '\uD800[\uDE80-\uDE9C]'
    },
    {
        'name': 'Lydian',
        'astral': '\uD802[\uDD20-\uDD39\uDD3F]'
    },
    {
        'name': 'Mahajani',
        'astral': '\uD804[\uDD50-\uDD76]'
    },
    {
        'name': 'Makasar',
        'astral': '\uD807[\uDEE0-\uDEF8]'
    },
    {
        'name': 'Malayalam',
        'bmp': '\u0D00-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4F\u0D54-\u0D63\u0D66-\u0D7F'
    },
    {
        'name': 'Mandaic',
        'bmp': '\u0840-\u085B\u085E'
    },
    {
        'name': 'Manichaean',
        'astral': '\uD802[\uDEC0-\uDEE6\uDEEB-\uDEF6]'
    },
    {
        'name': 'Marchen',
        'astral': '\uD807[\uDC70-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6]'
    },
    {
        'name': 'Masaram_Gondi',
        'astral': '\uD807[\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]'
    },
    {
        'name': 'Medefaidrin',
        'astral': '\uD81B[\uDE40-\uDE9A]'
    },
    {
        'name': 'Meetei_Mayek',
        'bmp': '\uAAE0-\uAAF6\uABC0-\uABED\uABF0-\uABF9'
    },
    {
        'name': 'Mende_Kikakui',
        'astral': '\uD83A[\uDC00-\uDCC4\uDCC7-\uDCD6]'
    },
    {
        'name': 'Meroitic_Cursive',
        'astral': '\uD802[\uDDA0-\uDDB7\uDDBC-\uDDCF\uDDD2-\uDDFF]'
    },
    {
        'name': 'Meroitic_Hieroglyphs',
        'astral': '\uD802[\uDD80-\uDD9F]'
    },
    {
        'name': 'Miao',
        'astral': '\uD81B[\uDF00-\uDF4A\uDF4F-\uDF87\uDF8F-\uDF9F]'
    },
    {
        'name': 'Modi',
        'astral': '\uD805[\uDE00-\uDE44\uDE50-\uDE59]'
    },
    {
        'name': 'Mongolian',
        'bmp': '\u1800\u1801\u1804\u1806-\u1819\u1820-\u1878\u1880-\u18AA',
        'astral': '\uD805[\uDE60-\uDE6C]'
    },
    {
        'name': 'Mro',
        'astral': '\uD81A[\uDE40-\uDE5E\uDE60-\uDE69\uDE6E\uDE6F]'
    },
    {
        'name': 'Multani',
        'astral': '\uD804[\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA9]'
    },
    {
        'name': 'Myanmar',
        'bmp': '\u1000-\u109F\uA9E0-\uA9FE\uAA60-\uAA7F'
    },
    {
        'name': 'Nabataean',
        'astral': '\uD802[\uDC80-\uDC9E\uDCA7-\uDCAF]'
    },
    {
        'name': 'Nandinagari',
        'astral': '\uD806[\uDDA0-\uDDA7\uDDAA-\uDDD7\uDDDA-\uDDE4]'
    },
    {
        'name': 'New_Tai_Lue',
        'bmp': '\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19DA\u19DE\u19DF'
    },
    {
        'name': 'Newa',
        'astral': '\uD805[\uDC00-\uDC5B\uDC5D-\uDC61]'
    },
    {
        'name': 'Nko',
        'bmp': '\u07C0-\u07FA\u07FD-\u07FF'
    },
    {
        'name': 'Nushu',
        'astral': '\uD81B\uDFE1|\uD82C[\uDD70-\uDEFB]'
    },
    {
        'name': 'Nyiakeng_Puachue_Hmong',
        'astral': '\uD838[\uDD00-\uDD2C\uDD30-\uDD3D\uDD40-\uDD49\uDD4E\uDD4F]'
    },
    {
        'name': 'Ogham',
        'bmp': '\u1680-\u169C'
    },
    {
        'name': 'Ol_Chiki',
        'bmp': '\u1C50-\u1C7F'
    },
    {
        'name': 'Old_Hungarian',
        'astral': '\uD803[\uDC80-\uDCB2\uDCC0-\uDCF2\uDCFA-\uDCFF]'
    },
    {
        'name': 'Old_Italic',
        'astral': '\uD800[\uDF00-\uDF23\uDF2D-\uDF2F]'
    },
    {
        'name': 'Old_North_Arabian',
        'astral': '\uD802[\uDE80-\uDE9F]'
    },
    {
        'name': 'Old_Permic',
        'astral': '\uD800[\uDF50-\uDF7A]'
    },
    {
        'name': 'Old_Persian',
        'astral': '\uD800[\uDFA0-\uDFC3\uDFC8-\uDFD5]'
    },
    {
        'name': 'Old_Sogdian',
        'astral': '\uD803[\uDF00-\uDF27]'
    },
    {
        'name': 'Old_South_Arabian',
        'astral': '\uD802[\uDE60-\uDE7F]'
    },
    {
        'name': 'Old_Turkic',
        'astral': '\uD803[\uDC00-\uDC48]'
    },
    {
        'name': 'Old_Uyghur',
        'astral': '\uD803[\uDF70-\uDF89]'
    },
    {
        'name': 'Oriya',
        'bmp': '\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B55-\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B77'
    },
    {
        'name': 'Osage',
        'astral': '\uD801[\uDCB0-\uDCD3\uDCD8-\uDCFB]'
    },
    {
        'name': 'Osmanya',
        'astral': '\uD801[\uDC80-\uDC9D\uDCA0-\uDCA9]'
    },
    {
        'name': 'Pahawh_Hmong',
        'astral': '\uD81A[\uDF00-\uDF45\uDF50-\uDF59\uDF5B-\uDF61\uDF63-\uDF77\uDF7D-\uDF8F]'
    },
    {
        'name': 'Palmyrene',
        'astral': '\uD802[\uDC60-\uDC7F]'
    },
    {
        'name': 'Pau_Cin_Hau',
        'astral': '\uD806[\uDEC0-\uDEF8]'
    },
    {
        'name': 'Phags_Pa',
        'bmp': '\uA840-\uA877'
    },
    {
        'name': 'Phoenician',
        'astral': '\uD802[\uDD00-\uDD1B\uDD1F]'
    },
    {
        'name': 'Psalter_Pahlavi',
        'astral': '\uD802[\uDF80-\uDF91\uDF99-\uDF9C\uDFA9-\uDFAF]'
    },
    {
        'name': 'Rejang',
        'bmp': '\uA930-\uA953\uA95F'
    },
    {
        'name': 'Runic',
        'bmp': '\u16A0-\u16EA\u16EE-\u16F8'
    },
    {
        'name': 'Samaritan',
        'bmp': '\u0800-\u082D\u0830-\u083E'
    },
    {
        'name': 'Saurashtra',
        'bmp': '\uA880-\uA8C5\uA8CE-\uA8D9'
    },
    {
        'name': 'Sharada',
        'astral': '\uD804[\uDD80-\uDDDF]'
    },
    {
        'name': 'Shavian',
        'astral': '\uD801[\uDC50-\uDC7F]'
    },
    {
        'name': 'Siddham',
        'astral': '\uD805[\uDD80-\uDDB5\uDDB8-\uDDDD]'
    },
    {
        'name': 'SignWriting',
        'astral': '\uD836[\uDC00-\uDE8B\uDE9B-\uDE9F\uDEA1-\uDEAF]'
    },
    {
        'name': 'Sinhala',
        'bmp': '\u0D81-\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2-\u0DF4',
        'astral': '\uD804[\uDDE1-\uDDF4]'
    },
    {
        'name': 'Sogdian',
        'astral': '\uD803[\uDF30-\uDF59]'
    },
    {
        'name': 'Sora_Sompeng',
        'astral': '\uD804[\uDCD0-\uDCE8\uDCF0-\uDCF9]'
    },
    {
        'name': 'Soyombo',
        'astral': '\uD806[\uDE50-\uDEA2]'
    },
    {
        'name': 'Sundanese',
        'bmp': '\u1B80-\u1BBF\u1CC0-\u1CC7'
    },
    {
        'name': 'Syloti_Nagri',
        'bmp': '\uA800-\uA82C'
    },
    {
        'name': 'Syriac',
        'bmp': '\u0700-\u070D\u070F-\u074A\u074D-\u074F\u0860-\u086A'
    },
    {
        'name': 'Tagalog',
        'bmp': '\u1700-\u1715\u171F'
    },
    {
        'name': 'Tagbanwa',
        'bmp': '\u1760-\u176C\u176E-\u1770\u1772\u1773'
    },
    {
        'name': 'Tai_Le',
        'bmp': '\u1950-\u196D\u1970-\u1974'
    },
    {
        'name': 'Tai_Tham',
        'bmp': '\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA0-\u1AAD'
    },
    {
        'name': 'Tai_Viet',
        'bmp': '\uAA80-\uAAC2\uAADB-\uAADF'
    },
    {
        'name': 'Takri',
        'astral': '\uD805[\uDE80-\uDEB9\uDEC0-\uDEC9]'
    },
    {
        'name': 'Tamil',
        'bmp': '\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BFA',
        'astral': '\uD807[\uDFC0-\uDFF1\uDFFF]'
    },
    {
        'name': 'Tangsa',
        'astral': '\uD81A[\uDE70-\uDEBE\uDEC0-\uDEC9]'
    },
    {
        'name': 'Tangut',
        'astral': '\uD81B\uDFE0|[\uD81C-\uD820][\uDC00-\uDFFF]|\uD821[\uDC00-\uDFF7]|\uD822[\uDC00-\uDEFF]|\uD823[\uDD00-\uDD08]'
    },
    {
        'name': 'Telugu',
        'bmp': '\u0C00-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3C-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C5D\u0C60-\u0C63\u0C66-\u0C6F\u0C77-\u0C7F'
    },
    {
        'name': 'Thaana',
        'bmp': '\u0780-\u07B1'
    },
    {
        'name': 'Thai',
        'bmp': '\u0E01-\u0E3A\u0E40-\u0E5B'
    },
    {
        'name': 'Tibetan',
        'bmp': '\u0F00-\u0F47\u0F49-\u0F6C\u0F71-\u0F97\u0F99-\u0FBC\u0FBE-\u0FCC\u0FCE-\u0FD4\u0FD9\u0FDA'
    },
    {
        'name': 'Tifinagh',
        'bmp': '\u2D30-\u2D67\u2D6F\u2D70\u2D7F'
    },
    {
        'name': 'Tirhuta',
        'astral': '\uD805[\uDC80-\uDCC7\uDCD0-\uDCD9]'
    },
    {
        'name': 'Toto',
        'astral': '\uD838[\uDE90-\uDEAE]'
    },
    {
        'name': 'Ugaritic',
        'astral': '\uD800[\uDF80-\uDF9D\uDF9F]'
    },
    {
        'name': 'Vai',
        'bmp': '\uA500-\uA62B'
    },
    {
        'name': 'Vithkuqi',
        'astral': '\uD801[\uDD70-\uDD7A\uDD7C-\uDD8A\uDD8C-\uDD92\uDD94\uDD95\uDD97-\uDDA1\uDDA3-\uDDB1\uDDB3-\uDDB9\uDDBB\uDDBC]'
    },
    {
        'name': 'Wancho',
        'astral': '\uD838[\uDEC0-\uDEF9\uDEFF]'
    },
    {
        'name': 'Warang_Citi',
        'astral': '\uD806[\uDCA0-\uDCF2\uDCFF]'
    },
    {
        'name': 'Yezidi',
        'astral': '\uD803[\uDE80-\uDEA9\uDEAB-\uDEAD\uDEB0\uDEB1]'
    },
    {
        'name': 'Yi',
        'bmp': '\uA000-\uA48C\uA490-\uA4C6'
    },
    {
        'name': 'Zanabazar_Square',
        'astral': '\uD806[\uDE00-\uDE47]'
    }
];


/***/ }),

/***/ 83820:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

module.exports = __webpack_require__(54394);

/***/ }),

/***/ 32454:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

module.exports = __webpack_require__(15572);

/***/ }),

/***/ 7486:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

module.exports = __webpack_require__(90414);

/***/ }),

/***/ 47415:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

module.exports = __webpack_require__(40178);

/***/ }),

/***/ 56663:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

module.exports = __webpack_require__(15066);

/***/ }),

/***/ 38230:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

module.exports = __webpack_require__(1268);

/***/ }),

/***/ 33890:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

module.exports = __webpack_require__(76870);

/***/ }),

/***/ 86983:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

module.exports = __webpack_require__(45092);

/***/ }),

/***/ 8300:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

module.exports = __webpack_require__(53545);

/***/ }),

/***/ 80469:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

module.exports = __webpack_require__(99110);

/***/ }),

/***/ 38767:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

module.exports = __webpack_require__(80166);

/***/ }),

/***/ 3414:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

module.exports = __webpack_require__(78879);

/***/ }),

/***/ 56728:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

module.exports = __webpack_require__(88184);

/***/ }),

/***/ 39189:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

module.exports = __webpack_require__(90486);

/***/ }),

/***/ 82219:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

module.exports = __webpack_require__(13333);

/***/ }),

/***/ 20964:
/***/ ((module) => {

function _arrayLikeToArray(r, a) {
  (null == a || a > r.length) && (a = r.length);
  for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e];
  return n;
}
module.exports = _arrayLikeToArray, module.exports.__esModule = true, module.exports["default"] = module.exports;

/***/ }),

/***/ 92927:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

var _Array$isArray = __webpack_require__(88414);
function _arrayWithHoles(r) {
  if (_Array$isArray(r)) return r;
}
module.exports = _arrayWithHoles, module.exports.__esModule = true, module.exports["default"] = module.exports;

/***/ }),

/***/ 69598:
/***/ ((module) => {

function _interopRequireDefault(e) {
  return e && e.__esModule ? e : {
    "default": e
  };
}
module.exports = _interopRequireDefault, module.exports.__esModule = true, module.exports["default"] = module.exports;

/***/ }),

/***/ 3193:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

var _Symbol = __webpack_require__(23049);
var _getIteratorMethod = __webpack_require__(13333);
var _pushInstanceProperty = __webpack_require__(67231);
function _iterableToArrayLimit(r, l) {
  var t = null == r ? null : "undefined" != typeof _Symbol && _getIteratorMethod(r) || r["@@iterator"];
  if (null != t) {
    var e,
      n,
      i,
      u,
      a = [],
      f = !0,
      o = !1;
    try {
      if (i = (t = t.call(r)).next, 0 === l) {
        if (Object(t) !== t) return;
        f = !1;
      } else for (; !(f = (e = i.call(t)).done) && (_pushInstanceProperty(a).call(a, e.value), a.length !== l); f = !0);
    } catch (r) {
      o = !0, n = r;
    } finally {
      try {
        if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return;
      } finally {
        if (o) throw n;
      }
    }
    return a;
  }
}
module.exports = _iterableToArrayLimit, module.exports.__esModule = true, module.exports["default"] = module.exports;

/***/ }),

/***/ 95789:
/***/ ((module) => {

function _nonIterableRest() {
  throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
}
module.exports = _nonIterableRest, module.exports.__esModule = true, module.exports["default"] = module.exports;

/***/ }),

/***/ 1153:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

var arrayWithHoles = __webpack_require__(92927);
var iterableToArrayLimit = __webpack_require__(3193);
var unsupportedIterableToArray = __webpack_require__(84833);
var nonIterableRest = __webpack_require__(95789);
function _slicedToArray(r, e) {
  return arrayWithHoles(r) || iterableToArrayLimit(r, e) || unsupportedIterableToArray(r, e) || nonIterableRest();
}
module.exports = _slicedToArray, module.exports.__esModule = true, module.exports["default"] = module.exports;

/***/ }),

/***/ 84833:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

var _sliceInstanceProperty = __webpack_require__(15325);
var _Array$from = __webpack_require__(2052);
var arrayLikeToArray = __webpack_require__(20964);
function _unsupportedIterableToArray(r, a) {
  if (r) {
    var _context;
    if ("string" == typeof r) return arrayLikeToArray(r, a);
    var t = _sliceInstanceProperty(_context = {}.toString.call(r)).call(_context, 8, -1);
    return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? _Array$from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? arrayLikeToArray(r, a) : void 0;
  }
}
module.exports = _unsupportedIterableToArray, module.exports.__esModule = true, module.exports["default"] = module.exports;

/***/ }),

/***/ 1994:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var parent = __webpack_require__(54394);

module.exports = parent;


/***/ }),

/***/ 44283:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var parent = __webpack_require__(15572);

module.exports = parent;


/***/ }),

/***/ 62503:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var parent = __webpack_require__(28322);

module.exports = parent;


/***/ }),

/***/ 42928:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var parent = __webpack_require__(89652);

module.exports = parent;


/***/ }),

/***/ 27998:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var parent = __webpack_require__(53545);

module.exports = parent;


/***/ }),

/***/ 40586:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var parent = __webpack_require__(90486);

__webpack_require__(91307);
__webpack_require__(48561);
__webpack_require__(16241);
__webpack_require__(58579);

module.exports = parent;


/***/ }),

/***/ 65400:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

__webpack_require__(48299);
__webpack_require__(89864);
var path = __webpack_require__(81217);

module.exports = path.Array.from;


/***/ }),

/***/ 5885:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

__webpack_require__(44396);
var path = __webpack_require__(81217);

module.exports = path.Array.isArray;


/***/ }),

/***/ 27912:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

__webpack_require__(98566);
var getBuiltInPrototypeMethod = __webpack_require__(83043);

module.exports = getBuiltInPrototypeMethod('Array', 'concat');


/***/ }),

/***/ 10774:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

__webpack_require__(31471);
var getBuiltInPrototypeMethod = __webpack_require__(83043);

module.exports = getBuiltInPrototypeMethod('Array', 'forEach');


/***/ }),

/***/ 27948:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

__webpack_require__(334);
var getBuiltInPrototypeMethod = __webpack_require__(83043);

module.exports = getBuiltInPrototypeMethod('Array', 'indexOf');


/***/ }),

/***/ 73035:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

__webpack_require__(34903);
var getBuiltInPrototypeMethod = __webpack_require__(83043);

module.exports = getBuiltInPrototypeMethod('Array', 'map');


/***/ }),

/***/ 46774:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

__webpack_require__(13940);
var getBuiltInPrototypeMethod = __webpack_require__(83043);

module.exports = getBuiltInPrototypeMethod('Array', 'push');


/***/ }),

/***/ 12252:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

__webpack_require__(82378);
var getBuiltInPrototypeMethod = __webpack_require__(83043);

module.exports = getBuiltInPrototypeMethod('Array', 'reduce');


/***/ }),

/***/ 10795:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

__webpack_require__(79499);
var getBuiltInPrototypeMethod = __webpack_require__(83043);

module.exports = getBuiltInPrototypeMethod('Array', 'slice');


/***/ }),

/***/ 62761:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

__webpack_require__(50080);
var getBuiltInPrototypeMethod = __webpack_require__(83043);

module.exports = getBuiltInPrototypeMethod('Array', 'sort');


/***/ }),

/***/ 83279:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

__webpack_require__(55676);
__webpack_require__(48299);
var getIteratorMethod = __webpack_require__(17127);

module.exports = getIteratorMethod;


/***/ }),

/***/ 13372:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var isPrototypeOf = __webpack_require__(97022);
var method = __webpack_require__(27912);

var ArrayPrototype = Array.prototype;

module.exports = function (it) {
  var own = it.concat;
  return it === ArrayPrototype || (isPrototypeOf(ArrayPrototype, it) && own === ArrayPrototype.concat) ? method : own;
};


/***/ }),

/***/ 46253:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var isPrototypeOf = __webpack_require__(97022);
var flags = __webpack_require__(31633);

var RegExpPrototype = RegExp.prototype;

module.exports = function (it) {
  return (it === RegExpPrototype || isPrototypeOf(RegExpPrototype, it)) ? flags(it) : it.flags;
};


/***/ }),

/***/ 7389:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var isPrototypeOf = __webpack_require__(97022);
var method = __webpack_require__(27948);

var ArrayPrototype = Array.prototype;

module.exports = function (it) {
  var own = it.indexOf;
  return it === ArrayPrototype || (isPrototypeOf(ArrayPrototype, it) && own === ArrayPrototype.indexOf) ? method : own;
};


/***/ }),

/***/ 28050:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var isPrototypeOf = __webpack_require__(97022);
var method = __webpack_require__(73035);

var ArrayPrototype = Array.prototype;

module.exports = function (it) {
  var own = it.map;
  return it === ArrayPrototype || (isPrototypeOf(ArrayPrototype, it) && own === ArrayPrototype.map) ? method : own;
};


/***/ }),

/***/ 35417:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var isPrototypeOf = __webpack_require__(97022);
var method = __webpack_require__(46774);

var ArrayPrototype = Array.prototype;

module.exports = function (it) {
  var own = it.push;
  return it === ArrayPrototype || (isPrototypeOf(ArrayPrototype, it) && own === ArrayPrototype.push) ? method : own;
};


/***/ }),

/***/ 3905:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var isPrototypeOf = __webpack_require__(97022);
var method = __webpack_require__(12252);

var ArrayPrototype = Array.prototype;

module.exports = function (it) {
  var own = it.reduce;
  return it === ArrayPrototype || (isPrototypeOf(ArrayPrototype, it) && own === ArrayPrototype.reduce) ? method : own;
};


/***/ }),

/***/ 56673:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var isPrototypeOf = __webpack_require__(97022);
var method = __webpack_require__(10795);

var ArrayPrototype = Array.prototype;

module.exports = function (it) {
  var own = it.slice;
  return it === ArrayPrototype || (isPrototypeOf(ArrayPrototype, it) && own === ArrayPrototype.slice) ? method : own;
};


/***/ }),

/***/ 68592:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var isPrototypeOf = __webpack_require__(97022);
var method = __webpack_require__(62761);

var ArrayPrototype = Array.prototype;

module.exports = function (it) {
  var own = it.sort;
  return it === ArrayPrototype || (isPrototypeOf(ArrayPrototype, it) && own === ArrayPrototype.sort) ? method : own;
};


/***/ }),

/***/ 82200:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

__webpack_require__(85027);
var path = __webpack_require__(81217);

var Object = path.Object;

module.exports = function create(P, D) {
  return Object.create(P, D);
};


/***/ }),

/***/ 60169:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

__webpack_require__(57000);
var path = __webpack_require__(81217);

var Object = path.Object;

var defineProperty = module.exports = function defineProperty(it, key, desc) {
  return Object.defineProperty(it, key, desc);
};

if (Object.defineProperty.sham) defineProperty.sham = true;


/***/ }),

/***/ 66174:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

__webpack_require__(33380);
var path = __webpack_require__(81217);

module.exports = path.parseInt;


/***/ }),

/***/ 31633:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

__webpack_require__(71887);
var getRegExpFlags = __webpack_require__(76255);

module.exports = getRegExpFlags;


/***/ }),

/***/ 1302:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

__webpack_require__(98566);
__webpack_require__(77873);
__webpack_require__(45747);
__webpack_require__(7089);
__webpack_require__(12228);
__webpack_require__(71262);
__webpack_require__(13782);
__webpack_require__(81522);
__webpack_require__(43610);
__webpack_require__(83909);
__webpack_require__(30143);
__webpack_require__(5490);
__webpack_require__(3249);
__webpack_require__(50108);
__webpack_require__(1885);
__webpack_require__(6922);
__webpack_require__(86166);
__webpack_require__(61021);
__webpack_require__(18871);
__webpack_require__(97625);
var path = __webpack_require__(81217);

module.exports = path.Symbol;


/***/ }),

/***/ 2052:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

module.exports = __webpack_require__(85472);


/***/ }),

/***/ 88414:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

module.exports = __webpack_require__(47741);


/***/ }),

/***/ 13333:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

module.exports = __webpack_require__(95216);


/***/ }),

/***/ 67231:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

module.exports = __webpack_require__(91090);


/***/ }),

/***/ 15325:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

module.exports = __webpack_require__(38009);


/***/ }),

/***/ 23049:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

module.exports = __webpack_require__(90825);


/***/ }),

/***/ 85472:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var parent = __webpack_require__(1994);

module.exports = parent;


/***/ }),

/***/ 47741:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var parent = __webpack_require__(44283);

module.exports = parent;


/***/ }),

/***/ 95216:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var parent = __webpack_require__(62503);

module.exports = parent;


/***/ }),

/***/ 91090:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var parent = __webpack_require__(42928);

module.exports = parent;


/***/ }),

/***/ 38009:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var parent = __webpack_require__(27998);

module.exports = parent;


/***/ }),

/***/ 90825:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var parent = __webpack_require__(40586);
__webpack_require__(30898);
__webpack_require__(88064);
__webpack_require__(21561);
__webpack_require__(45169);
// TODO: Remove from `core-js@4`
__webpack_require__(96183);
__webpack_require__(73813);
__webpack_require__(56649);
__webpack_require__(6470);
__webpack_require__(73296);
__webpack_require__(47674);

module.exports = parent;


/***/ }),

/***/ 66049:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var isCallable = __webpack_require__(69949);
var tryToString = __webpack_require__(18458);

var $TypeError = TypeError;

// `Assert: IsCallable(argument) is true`
module.exports = function (argument) {
  if (isCallable(argument)) return argument;
  throw new $TypeError(tryToString(argument) + ' is not a function');
};


/***/ }),

/***/ 23886:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var isPossiblePrototype = __webpack_require__(53112);

var $String = String;
var $TypeError = TypeError;

module.exports = function (argument) {
  if (isPossiblePrototype(argument)) return argument;
  throw new $TypeError("Can't set " + $String(argument) + ' as a prototype');
};


/***/ }),

/***/ 23358:
/***/ ((module) => {

"use strict";

module.exports = function () { /* empty */ };


/***/ }),

/***/ 1681:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var isObject = __webpack_require__(63590);

var $String = String;
var $TypeError = TypeError;

// `Assert: Type(argument) is Object`
module.exports = function (argument) {
  if (isObject(argument)) return argument;
  throw new $TypeError($String(argument) + ' is not an object');
};


/***/ }),

/***/ 97959:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var $forEach = (__webpack_require__(30343).forEach);
var arrayMethodIsStrict = __webpack_require__(42786);

var STRICT_METHOD = arrayMethodIsStrict('forEach');

// `Array.prototype.forEach` method implementation
// https://tc39.es/ecma262/#sec-array.prototype.foreach
module.exports = !STRICT_METHOD ? function forEach(callbackfn /* , thisArg */) {
  return $forEach(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
// eslint-disable-next-line es/no-array-prototype-foreach -- safe
} : [].forEach;


/***/ }),

/***/ 2277:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var bind = __webpack_require__(12326);
var call = __webpack_require__(70492);
var toObject = __webpack_require__(85857);
var callWithSafeIterationClosing = __webpack_require__(48016);
var isArrayIteratorMethod = __webpack_require__(2111);
var isConstructor = __webpack_require__(62371);
var lengthOfArrayLike = __webpack_require__(46935);
var createProperty = __webpack_require__(19109);
var getIterator = __webpack_require__(97245);
var getIteratorMethod = __webpack_require__(17127);

var $Array = Array;

// `Array.from` method implementation
// https://tc39.es/ecma262/#sec-array.from
module.exports = function from(arrayLike /* , mapfn = undefined, thisArg = undefined */) {
  var O = toObject(arrayLike);
  var IS_CONSTRUCTOR = isConstructor(this);
  var argumentsLength = arguments.length;
  var mapfn = argumentsLength > 1 ? arguments[1] : undefined;
  var mapping = mapfn !== undefined;
  if (mapping) mapfn = bind(mapfn, argumentsLength > 2 ? arguments[2] : undefined);
  var iteratorMethod = getIteratorMethod(O);
  var index = 0;
  var length, result, step, iterator, next, value;
  // if the target is not iterable or it's an array with the default iterator - use a simple case
  if (iteratorMethod && !(this === $Array && isArrayIteratorMethod(iteratorMethod))) {
    result = IS_CONSTRUCTOR ? new this() : [];
    iterator = getIterator(O, iteratorMethod);
    next = iterator.next;
    for (;!(step = call(next, iterator)).done; index++) {
      value = mapping ? callWithSafeIterationClosing(iterator, mapfn, [step.value, index], true) : step.value;
      createProperty(result, index, value);
    }
  } else {
    length = lengthOfArrayLike(O);
    result = IS_CONSTRUCTOR ? new this(length) : $Array(length);
    for (;length > index; index++) {
      value = mapping ? mapfn(O[index], index) : O[index];
      createProperty(result, index, value);
    }
  }
  result.length = index;
  return result;
};


/***/ }),

/***/ 74895:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var toIndexedObject = __webpack_require__(10839);
var toAbsoluteIndex = __webpack_require__(13036);
var lengthOfArrayLike = __webpack_require__(46935);

// `Array.prototype.{ indexOf, includes }` methods implementation
var createMethod = function (IS_INCLUDES) {
  return function ($this, el, fromIndex) {
    var O = toIndexedObject($this);
    var length = lengthOfArrayLike(O);
    if (length === 0) return !IS_INCLUDES && -1;
    var index = toAbsoluteIndex(fromIndex, length);
    var value;
    // Array#includes uses SameValueZero equality algorithm
    // eslint-disable-next-line no-self-compare -- NaN check
    if (IS_INCLUDES && el !== el) while (length > index) {
      value = O[index++];
      // eslint-disable-next-line no-self-compare -- NaN check
      if (value !== value) return true;
    // Array#indexOf ignores holes, Array#includes - not
    } else for (;length > index; index++) {
      if ((IS_INCLUDES || index in O) && O[index] === el) return IS_INCLUDES || index || 0;
    } return !IS_INCLUDES && -1;
  };
};

module.exports = {
  // `Array.prototype.includes` method
  // https://tc39.es/ecma262/#sec-array.prototype.includes
  includes: createMethod(true),
  // `Array.prototype.indexOf` method
  // https://tc39.es/ecma262/#sec-array.prototype.indexof
  indexOf: createMethod(false)
};


/***/ }),

/***/ 30343:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var bind = __webpack_require__(12326);
var uncurryThis = __webpack_require__(41686);
var IndexedObject = __webpack_require__(92831);
var toObject = __webpack_require__(85857);
var lengthOfArrayLike = __webpack_require__(46935);
var arraySpeciesCreate = __webpack_require__(95405);

var push = uncurryThis([].push);

// `Array.prototype.{ forEach, map, filter, some, every, find, findIndex, filterReject }` methods implementation
var createMethod = function (TYPE) {
  var IS_MAP = TYPE === 1;
  var IS_FILTER = TYPE === 2;
  var IS_SOME = TYPE === 3;
  var IS_EVERY = TYPE === 4;
  var IS_FIND_INDEX = TYPE === 6;
  var IS_FILTER_REJECT = TYPE === 7;
  var NO_HOLES = TYPE === 5 || IS_FIND_INDEX;
  return function ($this, callbackfn, that, specificCreate) {
    var O = toObject($this);
    var self = IndexedObject(O);
    var length = lengthOfArrayLike(self);
    var boundFunction = bind(callbackfn, that);
    var index = 0;
    var create = specificCreate || arraySpeciesCreate;
    var target = IS_MAP ? create($this, length) : IS_FILTER || IS_FILTER_REJECT ? create($this, 0) : undefined;
    var value, result;
    for (;length > index; index++) if (NO_HOLES || index in self) {
      value = self[index];
      result = boundFunction(value, index, O);
      if (TYPE) {
        if (IS_MAP) target[index] = result; // map
        else if (result) switch (TYPE) {
          case 3: return true;              // some
          case 5: return value;             // find
          case 6: return index;             // findIndex
          case 2: push(target, value);      // filter
        } else switch (TYPE) {
          case 4: return false;             // every
          case 7: push(target, value);      // filterReject
        }
      }
    }
    return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : target;
  };
};

module.exports = {
  // `Array.prototype.forEach` method
  // https://tc39.es/ecma262/#sec-array.prototype.foreach
  forEach: createMethod(0),
  // `Array.prototype.map` method
  // https://tc39.es/ecma262/#sec-array.prototype.map
  map: createMethod(1),
  // `Array.prototype.filter` method
  // https://tc39.es/ecma262/#sec-array.prototype.filter
  filter: createMethod(2),
  // `Array.prototype.some` method
  // https://tc39.es/ecma262/#sec-array.prototype.some
  some: createMethod(3),
  // `Array.prototype.every` method
  // https://tc39.es/ecma262/#sec-array.prototype.every
  every: createMethod(4),
  // `Array.prototype.find` method
  // https://tc39.es/ecma262/#sec-array.prototype.find
  find: createMethod(5),
  // `Array.prototype.findIndex` method
  // https://tc39.es/ecma262/#sec-array.prototype.findIndex
  findIndex: createMethod(6),
  // `Array.prototype.filterReject` method
  // https://github.com/tc39/proposal-array-filtering
  filterReject: createMethod(7)
};


/***/ }),

/***/ 53741:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var fails = __webpack_require__(30676);
var wellKnownSymbol = __webpack_require__(21928);
var V8_VERSION = __webpack_require__(97711);

var SPECIES = wellKnownSymbol('species');

module.exports = function (METHOD_NAME) {
  // We can't use this feature detection in V8 since it causes
  // deoptimization and serious performance degradation
  // https://github.com/zloirock/core-js/issues/677
  return V8_VERSION >= 51 || !fails(function () {
    var array = [];
    var constructor = array.constructor = {};
    constructor[SPECIES] = function () {
      return { foo: 1 };
    };
    return array[METHOD_NAME](Boolean).foo !== 1;
  });
};


/***/ }),

/***/ 42786:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var fails = __webpack_require__(30676);

module.exports = function (METHOD_NAME, argument) {
  var method = [][METHOD_NAME];
  return !!method && fails(function () {
    // eslint-disable-next-line no-useless-call -- required for testing
    method.call(null, argument || function () { return 1; }, 1);
  });
};


/***/ }),

/***/ 17909:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var aCallable = __webpack_require__(66049);
var toObject = __webpack_require__(85857);
var IndexedObject = __webpack_require__(92831);
var lengthOfArrayLike = __webpack_require__(46935);

var $TypeError = TypeError;

var REDUCE_EMPTY = 'Reduce of empty array with no initial value';

// `Array.prototype.{ reduce, reduceRight }` methods implementation
var createMethod = function (IS_RIGHT) {
  return function (that, callbackfn, argumentsLength, memo) {
    var O = toObject(that);
    var self = IndexedObject(O);
    var length = lengthOfArrayLike(O);
    aCallable(callbackfn);
    if (length === 0 && argumentsLength < 2) throw new $TypeError(REDUCE_EMPTY);
    var index = IS_RIGHT ? length - 1 : 0;
    var i = IS_RIGHT ? -1 : 1;
    if (argumentsLength < 2) while (true) {
      if (index in self) {
        memo = self[index];
        index += i;
        break;
      }
      index += i;
      if (IS_RIGHT ? index < 0 : length <= index) {
        throw new $TypeError(REDUCE_EMPTY);
      }
    }
    for (;IS_RIGHT ? index >= 0 : length > index; index += i) if (index in self) {
      memo = callbackfn(memo, self[index], index, O);
    }
    return memo;
  };
};

module.exports = {
  // `Array.prototype.reduce` method
  // https://tc39.es/ecma262/#sec-array.prototype.reduce
  left: createMethod(false),
  // `Array.prototype.reduceRight` method
  // https://tc39.es/ecma262/#sec-array.prototype.reduceright
  right: createMethod(true)
};


/***/ }),

/***/ 6138:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var DESCRIPTORS = __webpack_require__(99262);
var isArray = __webpack_require__(84155);

var $TypeError = TypeError;
// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;

// Safari < 13 does not throw an error in this case
var SILENT_ON_NON_WRITABLE_LENGTH_SET = DESCRIPTORS && !function () {
  // makes no sense without proper strict mode support
  if (this !== undefined) return true;
  try {
    // eslint-disable-next-line es/no-object-defineproperty -- safe
    Object.defineProperty([], 'length', { writable: false }).length = 1;
  } catch (error) {
    return error instanceof TypeError;
  }
}();

module.exports = SILENT_ON_NON_WRITABLE_LENGTH_SET ? function (O, length) {
  if (isArray(O) && !getOwnPropertyDescriptor(O, 'length').writable) {
    throw new $TypeError('Cannot set read only .length');
  } return O.length = length;
} : function (O, length) {
  return O.length = length;
};


/***/ }),

/***/ 79919:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var uncurryThis = __webpack_require__(41686);

module.exports = uncurryThis([].slice);


/***/ }),

/***/ 21501:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var arraySlice = __webpack_require__(79919);

var floor = Math.floor;

var sort = function (array, comparefn) {
  var length = array.length;

  if (length < 8) {
    // insertion sort
    var i = 1;
    var element, j;

    while (i < length) {
      j = i;
      element = array[i];
      while (j && comparefn(array[j - 1], element) > 0) {
        array[j] = array[--j];
      }
      if (j !== i++) array[j] = element;
    }
  } else {
    // merge sort
    var middle = floor(length / 2);
    var left = sort(arraySlice(array, 0, middle), comparefn);
    var right = sort(arraySlice(array, middle), comparefn);
    var llength = left.length;
    var rlength = right.length;
    var lindex = 0;
    var rindex = 0;

    while (lindex < llength || rindex < rlength) {
      array[lindex + rindex] = (lindex < llength && rindex < rlength)
        ? comparefn(left[lindex], right[rindex]) <= 0 ? left[lindex++] : right[rindex++]
        : lindex < llength ? left[lindex++] : right[rindex++];
    }
  }

  return array;
};

module.exports = sort;


/***/ }),

/***/ 50311:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var isArray = __webpack_require__(84155);
var isConstructor = __webpack_require__(62371);
var isObject = __webpack_require__(63590);
var wellKnownSymbol = __webpack_require__(21928);

var SPECIES = wellKnownSymbol('species');
var $Array = Array;

// a part of `ArraySpeciesCreate` abstract operation
// https://tc39.es/ecma262/#sec-arrayspeciescreate
module.exports = function (originalArray) {
  var C;
  if (isArray(originalArray)) {
    C = originalArray.constructor;
    // cross-realm fallback
    if (isConstructor(C) && (C === $Array || isArray(C.prototype))) C = undefined;
    else if (isObject(C)) {
      C = C[SPECIES];
      if (C === null) C = undefined;
    }
  } return C === undefined ? $Array : C;
};


/***/ }),

/***/ 95405:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var arraySpeciesConstructor = __webpack_require__(50311);

// `ArraySpeciesCreate` abstract operation
// https://tc39.es/ecma262/#sec-arrayspeciescreate
module.exports = function (originalArray, length) {
  return new (arraySpeciesConstructor(originalArray))(length === 0 ? 0 : length);
};


/***/ }),

/***/ 48016:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var anObject = __webpack_require__(1681);
var iteratorClose = __webpack_require__(53086);

// call something on iterator step with safe closing on error
module.exports = function (iterator, fn, value, ENTRIES) {
  try {
    return ENTRIES ? fn(anObject(value)[0], value[1]) : fn(value);
  } catch (error) {
    iteratorClose(iterator, 'throw', error);
  }
};


/***/ }),

/***/ 14376:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var wellKnownSymbol = __webpack_require__(21928);

var ITERATOR = wellKnownSymbol('iterator');
var SAFE_CLOSING = false;

try {
  var called = 0;
  var iteratorWithReturn = {
    next: function () {
      return { done: !!called++ };
    },
    'return': function () {
      SAFE_CLOSING = true;
    }
  };
  iteratorWithReturn[ITERATOR] = function () {
    return this;
  };
  // eslint-disable-next-line es/no-array-from, no-throw-literal -- required for testing
  Array.from(iteratorWithReturn, function () { throw 2; });
} catch (error) { /* empty */ }

module.exports = function (exec, SKIP_CLOSING) {
  try {
    if (!SKIP_CLOSING && !SAFE_CLOSING) return false;
  } catch (error) { return false; } // workaround of old WebKit + `eval` bug
  var ITERATION_SUPPORT = false;
  try {
    var object = {};
    object[ITERATOR] = function () {
      return {
        next: function () {
          return { done: ITERATION_SUPPORT = true };
        }
      };
    };
    exec(object);
  } catch (error) { /* empty */ }
  return ITERATION_SUPPORT;
};


/***/ }),

/***/ 67324:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var uncurryThis = __webpack_require__(41686);

var toString = uncurryThis({}.toString);
var stringSlice = uncurryThis(''.slice);

module.exports = function (it) {
  return stringSlice(toString(it), 8, -1);
};


/***/ }),

/***/ 30487:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var TO_STRING_TAG_SUPPORT = __webpack_require__(79490);
var isCallable = __webpack_require__(69949);
var classofRaw = __webpack_require__(67324);
var wellKnownSymbol = __webpack_require__(21928);

var TO_STRING_TAG = wellKnownSymbol('toStringTag');
var $Object = Object;

// ES3 wrong here
var CORRECT_ARGUMENTS = classofRaw(function () { return arguments; }()) === 'Arguments';

// fallback for IE11 Script Access Denied error
var tryGet = function (it, key) {
  try {
    return it[key];
  } catch (error) { /* empty */ }
};

// getting tag from ES6+ `Object.prototype.toString`
module.exports = TO_STRING_TAG_SUPPORT ? classofRaw : function (it) {
  var O, tag, result;
  return it === undefined ? 'Undefined' : it === null ? 'Null'
    // @@toStringTag case
    : typeof (tag = tryGet(O = $Object(it), TO_STRING_TAG)) == 'string' ? tag
    // builtinTag case
    : CORRECT_ARGUMENTS ? classofRaw(O)
    // ES3 arguments fallback
    : (result = classofRaw(O)) === 'Object' && isCallable(O.callee) ? 'Arguments' : result;
};


/***/ }),

/***/ 4592:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var fails = __webpack_require__(30676);

module.exports = !fails(function () {
  function F() { /* empty */ }
  F.prototype.constructor = null;
  // eslint-disable-next-line es/no-object-getprototypeof -- required for testing
  return Object.getPrototypeOf(new F()) !== F.prototype;
});


/***/ }),

/***/ 99106:
/***/ ((module) => {

"use strict";

// `CreateIterResultObject` abstract operation
// https://tc39.es/ecma262/#sec-createiterresultobject
module.exports = function (value, done) {
  return { value: value, done: done };
};


/***/ }),

/***/ 87803:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var DESCRIPTORS = __webpack_require__(99262);
var definePropertyModule = __webpack_require__(45661);
var createPropertyDescriptor = __webpack_require__(16838);

module.exports = DESCRIPTORS ? function (object, key, value) {
  return definePropertyModule.f(object, key, createPropertyDescriptor(1, value));
} : function (object, key, value) {
  object[key] = value;
  return object;
};


/***/ }),

/***/ 16838:
/***/ ((module) => {

"use strict";

module.exports = function (bitmap, value) {
  return {
    enumerable: !(bitmap & 1),
    configurable: !(bitmap & 2),
    writable: !(bitmap & 4),
    value: value
  };
};


/***/ }),

/***/ 19109:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var DESCRIPTORS = __webpack_require__(99262);
var definePropertyModule = __webpack_require__(45661);
var createPropertyDescriptor = __webpack_require__(16838);

module.exports = function (object, key, value) {
  if (DESCRIPTORS) definePropertyModule.f(object, key, createPropertyDescriptor(0, value));
  else object[key] = value;
};


/***/ }),

/***/ 14443:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var defineProperty = __webpack_require__(45661);

module.exports = function (target, name, descriptor) {
  return defineProperty.f(target, name, descriptor);
};


/***/ }),

/***/ 84406:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var createNonEnumerableProperty = __webpack_require__(87803);

module.exports = function (target, key, value, options) {
  if (options && options.enumerable) target[key] = value;
  else createNonEnumerableProperty(target, key, value);
  return target;
};


/***/ }),

/***/ 68053:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var global = __webpack_require__(68647);

// eslint-disable-next-line es/no-object-defineproperty -- safe
var defineProperty = Object.defineProperty;

module.exports = function (key, value) {
  try {
    defineProperty(global, key, { value: value, configurable: true, writable: true });
  } catch (error) {
    global[key] = value;
  } return value;
};


/***/ }),

/***/ 78880:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var tryToString = __webpack_require__(18458);

var $TypeError = TypeError;

module.exports = function (O, P) {
  if (!delete O[P]) throw new $TypeError('Cannot delete property ' + tryToString(P) + ' of ' + tryToString(O));
};


/***/ }),

/***/ 99262:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var fails = __webpack_require__(30676);

// Detect IE8's incomplete defineProperty implementation
module.exports = !fails(function () {
  // eslint-disable-next-line es/no-object-defineproperty -- required for testing
  return Object.defineProperty({}, 1, { get: function () { return 7; } })[1] !== 7;
});


/***/ }),

/***/ 79927:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var global = __webpack_require__(68647);
var isObject = __webpack_require__(63590);

var document = global.document;
// typeof document.createElement is 'object' in old IE
var EXISTS = isObject(document) && isObject(document.createElement);

module.exports = function (it) {
  return EXISTS ? document.createElement(it) : {};
};


/***/ }),

/***/ 27890:
/***/ ((module) => {

"use strict";

var $TypeError = TypeError;
var MAX_SAFE_INTEGER = 0x1FFFFFFFFFFFFF; // 2 ** 53 - 1 == 9007199254740991

module.exports = function (it) {
  if (it > MAX_SAFE_INTEGER) throw $TypeError('Maximum allowed index exceeded');
  return it;
};


/***/ }),

/***/ 24228:
/***/ ((module) => {

"use strict";

// iterable DOM collections
// flag - `iterable` interface - 'entries', 'keys', 'values', 'forEach' methods
module.exports = {
  CSSRuleList: 0,
  CSSStyleDeclaration: 0,
  CSSValueList: 0,
  ClientRectList: 0,
  DOMRectList: 0,
  DOMStringList: 0,
  DOMTokenList: 1,
  DataTransferItemList: 0,
  FileList: 0,
  HTMLAllCollection: 0,
  HTMLCollection: 0,
  HTMLFormElement: 0,
  HTMLSelectElement: 0,
  MediaList: 0,
  MimeTypeArray: 0,
  NamedNodeMap: 0,
  NodeList: 1,
  PaintRequestList: 0,
  Plugin: 0,
  PluginArray: 0,
  SVGLengthList: 0,
  SVGNumberList: 0,
  SVGPathSegList: 0,
  SVGPointList: 0,
  SVGStringList: 0,
  SVGTransformList: 0,
  SourceBufferList: 0,
  StyleSheetList: 0,
  TextTrackCueList: 0,
  TextTrackList: 0,
  TouchList: 0
};


/***/ }),

/***/ 10087:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var userAgent = __webpack_require__(76536);

var firefox = userAgent.match(/firefox\/(\d+)/i);

module.exports = !!firefox && +firefox[1];


/***/ }),

/***/ 18151:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var UA = __webpack_require__(76536);

module.exports = /MSIE|Trident/.test(UA);


/***/ }),

/***/ 9420:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var global = __webpack_require__(68647);
var classof = __webpack_require__(67324);

module.exports = classof(global.process) === 'process';


/***/ }),

/***/ 76536:
/***/ ((module) => {

"use strict";

module.exports = typeof navigator != 'undefined' && String(navigator.userAgent) || '';


/***/ }),

/***/ 97711:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var global = __webpack_require__(68647);
var userAgent = __webpack_require__(76536);

var process = global.process;
var Deno = global.Deno;
var versions = process && process.versions || Deno && Deno.version;
var v8 = versions && versions.v8;
var match, version;

if (v8) {
  match = v8.split('.');
  // in old Chrome, versions of V8 isn't V8 = Chrome / 10
  // but their correct versions are not interesting for us
  version = match[0] > 0 && match[0] < 4 ? 1 : +(match[0] + match[1]);
}

// BrowserFS NodeJS `process` polyfill incorrectly set `.v8` to `0.0`
// so check `userAgent` even if `.v8` exists, but 0
if (!version && userAgent) {
  match = userAgent.match(/Edge\/(\d+)/);
  if (!match || match[1] >= 74) {
    match = userAgent.match(/Chrome\/(\d+)/);
    if (match) version = +match[1];
  }
}

module.exports = version;


/***/ }),

/***/ 15548:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var userAgent = __webpack_require__(76536);

var webkit = userAgent.match(/AppleWebKit\/(\d+)\./);

module.exports = !!webkit && +webkit[1];


/***/ }),

/***/ 33527:
/***/ ((module) => {

"use strict";

// IE8- don't enum bug keys
module.exports = [
  'constructor',
  'hasOwnProperty',
  'isPrototypeOf',
  'propertyIsEnumerable',
  'toLocaleString',
  'toString',
  'valueOf'
];


/***/ }),

/***/ 97934:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var global = __webpack_require__(68647);
var apply = __webpack_require__(54553);
var uncurryThis = __webpack_require__(69021);
var isCallable = __webpack_require__(69949);
var getOwnPropertyDescriptor = (__webpack_require__(10656).f);
var isForced = __webpack_require__(29924);
var path = __webpack_require__(81217);
var bind = __webpack_require__(12326);
var createNonEnumerableProperty = __webpack_require__(87803);
var hasOwn = __webpack_require__(48314);
// add debugging info
__webpack_require__(99346);

var wrapConstructor = function (NativeConstructor) {
  var Wrapper = function (a, b, c) {
    if (this instanceof Wrapper) {
      switch (arguments.length) {
        case 0: return new NativeConstructor();
        case 1: return new NativeConstructor(a);
        case 2: return new NativeConstructor(a, b);
      } return new NativeConstructor(a, b, c);
    } return apply(NativeConstructor, this, arguments);
  };
  Wrapper.prototype = NativeConstructor.prototype;
  return Wrapper;
};

/*
  options.target         - name of the target object
  options.global         - target is the global object
  options.stat           - export as static methods of target
  options.proto          - export as prototype methods of target
  options.real           - real prototype method for the `pure` version
  options.forced         - export even if the native feature is available
  options.bind           - bind methods to the target, required for the `pure` version
  options.wrap           - wrap constructors to preventing global pollution, required for the `pure` version
  options.unsafe         - use the simple assignment of property instead of delete + defineProperty
  options.sham           - add a flag to not completely full polyfills
  options.enumerable     - export as enumerable property
  options.dontCallGetSet - prevent calling a getter on target
  options.name           - the .name of the function if it does not match the key
*/
module.exports = function (options, source) {
  var TARGET = options.target;
  var GLOBAL = options.global;
  var STATIC = options.stat;
  var PROTO = options.proto;

  var nativeSource = GLOBAL ? global : STATIC ? global[TARGET] : global[TARGET] && global[TARGET].prototype;

  var target = GLOBAL ? path : path[TARGET] || createNonEnumerableProperty(path, TARGET, {})[TARGET];
  var targetPrototype = target.prototype;

  var FORCED, USE_NATIVE, VIRTUAL_PROTOTYPE;
  var key, sourceProperty, targetProperty, nativeProperty, resultProperty, descriptor;

  for (key in source) {
    FORCED = isForced(GLOBAL ? key : TARGET + (STATIC ? '.' : '#') + key, options.forced);
    // contains in native
    USE_NATIVE = !FORCED && nativeSource && hasOwn(nativeSource, key);

    targetProperty = target[key];

    if (USE_NATIVE) if (options.dontCallGetSet) {
      descriptor = getOwnPropertyDescriptor(nativeSource, key);
      nativeProperty = descriptor && descriptor.value;
    } else nativeProperty = nativeSource[key];

    // export native or implementation
    sourceProperty = (USE_NATIVE && nativeProperty) ? nativeProperty : source[key];

    if (!FORCED && !PROTO && typeof targetProperty == typeof sourceProperty) continue;

    // bind methods to global for calling from export context
    if (options.bind && USE_NATIVE) resultProperty = bind(sourceProperty, global);
    // wrap global constructors for prevent changes in this version
    else if (options.wrap && USE_NATIVE) resultProperty = wrapConstructor(sourceProperty);
    // make static versions for prototype methods
    else if (PROTO && isCallable(sourceProperty)) resultProperty = uncurryThis(sourceProperty);
    // default case
    else resultProperty = sourceProperty;

    // add a flag to not completely full polyfills
    if (options.sham || (sourceProperty && sourceProperty.sham) || (targetProperty && targetProperty.sham)) {
      createNonEnumerableProperty(resultProperty, 'sham', true);
    }

    createNonEnumerableProperty(target, key, resultProperty);

    if (PROTO) {
      VIRTUAL_PROTOTYPE = TARGET + 'Prototype';
      if (!hasOwn(path, VIRTUAL_PROTOTYPE)) {
        createNonEnumerableProperty(path, VIRTUAL_PROTOTYPE, {});
      }
      // export virtual prototype methods
      createNonEnumerableProperty(path[VIRTUAL_PROTOTYPE], key, sourceProperty);
      // export real prototype methods
      if (options.real && targetPrototype && (FORCED || !targetPrototype[key])) {
        createNonEnumerableProperty(targetPrototype, key, sourceProperty);
      }
    }
  }
};


/***/ }),

/***/ 30676:
/***/ ((module) => {

"use strict";

module.exports = function (exec) {
  try {
    return !!exec();
  } catch (error) {
    return true;
  }
};


/***/ }),

/***/ 54553:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var NATIVE_BIND = __webpack_require__(56241);

var FunctionPrototype = Function.prototype;
var apply = FunctionPrototype.apply;
var call = FunctionPrototype.call;

// eslint-disable-next-line es/no-reflect -- safe
module.exports = typeof Reflect == 'object' && Reflect.apply || (NATIVE_BIND ? call.bind(apply) : function () {
  return call.apply(apply, arguments);
});


/***/ }),

/***/ 12326:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var uncurryThis = __webpack_require__(69021);
var aCallable = __webpack_require__(66049);
var NATIVE_BIND = __webpack_require__(56241);

var bind = uncurryThis(uncurryThis.bind);

// optional / simple context binding
module.exports = function (fn, that) {
  aCallable(fn);
  return that === undefined ? fn : NATIVE_BIND ? bind(fn, that) : function (/* ...args */) {
    return fn.apply(that, arguments);
  };
};


/***/ }),

/***/ 56241:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var fails = __webpack_require__(30676);

module.exports = !fails(function () {
  // eslint-disable-next-line es/no-function-prototype-bind -- safe
  var test = (function () { /* empty */ }).bind();
  // eslint-disable-next-line no-prototype-builtins -- safe
  return typeof test != 'function' || test.hasOwnProperty('prototype');
});


/***/ }),

/***/ 70492:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var NATIVE_BIND = __webpack_require__(56241);

var call = Function.prototype.call;

module.exports = NATIVE_BIND ? call.bind(call) : function () {
  return call.apply(call, arguments);
};


/***/ }),

/***/ 97745:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var DESCRIPTORS = __webpack_require__(99262);
var hasOwn = __webpack_require__(48314);

var FunctionPrototype = Function.prototype;
// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
var getDescriptor = DESCRIPTORS && Object.getOwnPropertyDescriptor;

var EXISTS = hasOwn(FunctionPrototype, 'name');
// additional protection from minified / mangled / dropped function names
var PROPER = EXISTS && (function something() { /* empty */ }).name === 'something';
var CONFIGURABLE = EXISTS && (!DESCRIPTORS || (DESCRIPTORS && getDescriptor(FunctionPrototype, 'name').configurable));

module.exports = {
  EXISTS: EXISTS,
  PROPER: PROPER,
  CONFIGURABLE: CONFIGURABLE
};


/***/ }),

/***/ 25933:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var uncurryThis = __webpack_require__(41686);
var aCallable = __webpack_require__(66049);

module.exports = function (object, key, method) {
  try {
    // eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
    return uncurryThis(aCallable(Object.getOwnPropertyDescriptor(object, key)[method]));
  } catch (error) { /* empty */ }
};


/***/ }),

/***/ 69021:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var classofRaw = __webpack_require__(67324);
var uncurryThis = __webpack_require__(41686);

module.exports = function (fn) {
  // Nashorn bug:
  //   https://github.com/zloirock/core-js/issues/1128
  //   https://github.com/zloirock/core-js/issues/1130
  if (classofRaw(fn) === 'Function') return uncurryThis(fn);
};


/***/ }),

/***/ 41686:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var NATIVE_BIND = __webpack_require__(56241);

var FunctionPrototype = Function.prototype;
var call = FunctionPrototype.call;
var uncurryThisWithBind = NATIVE_BIND && FunctionPrototype.bind.bind(call, call);

module.exports = NATIVE_BIND ? uncurryThisWithBind : function (fn) {
  return function () {
    return call.apply(fn, arguments);
  };
};


/***/ }),

/***/ 83043:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var global = __webpack_require__(68647);
var path = __webpack_require__(81217);

module.exports = function (CONSTRUCTOR, METHOD) {
  var Namespace = path[CONSTRUCTOR + 'Prototype'];
  var pureMethod = Namespace && Namespace[METHOD];
  if (pureMethod) return pureMethod;
  var NativeConstructor = global[CONSTRUCTOR];
  var NativePrototype = NativeConstructor && NativeConstructor.prototype;
  return NativePrototype && NativePrototype[METHOD];
};


/***/ }),

/***/ 94228:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var path = __webpack_require__(81217);
var global = __webpack_require__(68647);
var isCallable = __webpack_require__(69949);

var aFunction = function (variable) {
  return isCallable(variable) ? variable : undefined;
};

module.exports = function (namespace, method) {
  return arguments.length < 2 ? aFunction(path[namespace]) || aFunction(global[namespace])
    : path[namespace] && path[namespace][method] || global[namespace] && global[namespace][method];
};


/***/ }),

/***/ 17127:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var classof = __webpack_require__(30487);
var getMethod = __webpack_require__(36750);
var isNullOrUndefined = __webpack_require__(40446);
var Iterators = __webpack_require__(69885);
var wellKnownSymbol = __webpack_require__(21928);

var ITERATOR = wellKnownSymbol('iterator');

module.exports = function (it) {
  if (!isNullOrUndefined(it)) return getMethod(it, ITERATOR)
    || getMethod(it, '@@iterator')
    || Iterators[classof(it)];
};


/***/ }),

/***/ 97245:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var call = __webpack_require__(70492);
var aCallable = __webpack_require__(66049);
var anObject = __webpack_require__(1681);
var tryToString = __webpack_require__(18458);
var getIteratorMethod = __webpack_require__(17127);

var $TypeError = TypeError;

module.exports = function (argument, usingIterator) {
  var iteratorMethod = arguments.length < 2 ? getIteratorMethod(argument) : usingIterator;
  if (aCallable(iteratorMethod)) return anObject(call(iteratorMethod, argument));
  throw new $TypeError(tryToString(argument) + ' is not iterable');
};


/***/ }),

/***/ 52730:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var uncurryThis = __webpack_require__(41686);
var isArray = __webpack_require__(84155);
var isCallable = __webpack_require__(69949);
var classof = __webpack_require__(67324);
var toString = __webpack_require__(87365);

var push = uncurryThis([].push);

module.exports = function (replacer) {
  if (isCallable(replacer)) return replacer;
  if (!isArray(replacer)) return;
  var rawLength = replacer.length;
  var keys = [];
  for (var i = 0; i < rawLength; i++) {
    var element = replacer[i];
    if (typeof element == 'string') push(keys, element);
    else if (typeof element == 'number' || classof(element) === 'Number' || classof(element) === 'String') push(keys, toString(element));
  }
  var keysLength = keys.length;
  var root = true;
  return function (key, value) {
    if (root) {
      root = false;
      return value;
    }
    if (isArray(this)) return value;
    for (var j = 0; j < keysLength; j++) if (keys[j] === key) return value;
  };
};


/***/ }),

/***/ 36750:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var aCallable = __webpack_require__(66049);
var isNullOrUndefined = __webpack_require__(40446);

// `GetMethod` abstract operation
// https://tc39.es/ecma262/#sec-getmethod
module.exports = function (V, P) {
  var func = V[P];
  return isNullOrUndefined(func) ? undefined : aCallable(func);
};


/***/ }),

/***/ 68647:
/***/ (function(module, __unused_webpack_exports, __webpack_require__) {

"use strict";

var check = function (it) {
  return it && it.Math === Math && it;
};

// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028
module.exports =
  // eslint-disable-next-line es/no-global-this -- safe
  check(typeof globalThis == 'object' && globalThis) ||
  check(typeof window == 'object' && window) ||
  // eslint-disable-next-line no-restricted-globals -- safe
  check(typeof self == 'object' && self) ||
  check(typeof __webpack_require__.g == 'object' && __webpack_require__.g) ||
  check(typeof this == 'object' && this) ||
  // eslint-disable-next-line no-new-func -- fallback
  (function () { return this; })() || Function('return this')();


/***/ }),

/***/ 48314:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var uncurryThis = __webpack_require__(41686);
var toObject = __webpack_require__(85857);

var hasOwnProperty = uncurryThis({}.hasOwnProperty);

// `HasOwnProperty` abstract operation
// https://tc39.es/ecma262/#sec-hasownproperty
// eslint-disable-next-line es/no-object-hasown -- safe
module.exports = Object.hasOwn || function hasOwn(it, key) {
  return hasOwnProperty(toObject(it), key);
};


/***/ }),

/***/ 14983:
/***/ ((module) => {

"use strict";

module.exports = {};


/***/ }),

/***/ 76055:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var getBuiltIn = __webpack_require__(94228);

module.exports = getBuiltIn('document', 'documentElement');


/***/ }),

/***/ 40123:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var DESCRIPTORS = __webpack_require__(99262);
var fails = __webpack_require__(30676);
var createElement = __webpack_require__(79927);

// Thanks to IE8 for its funny defineProperty
module.exports = !DESCRIPTORS && !fails(function () {
  // eslint-disable-next-line es/no-object-defineproperty -- required for testing
  return Object.defineProperty(createElement('div'), 'a', {
    get: function () { return 7; }
  }).a !== 7;
});


/***/ }),

/***/ 92831:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var uncurryThis = __webpack_require__(41686);
var fails = __webpack_require__(30676);
var classof = __webpack_require__(67324);

var $Object = Object;
var split = uncurryThis(''.split);

// fallback for non-array-like ES3 and non-enumerable old V8 strings
module.exports = fails(function () {
  // throws an error in rhino, see https://github.com/mozilla/rhino/issues/346
  // eslint-disable-next-line no-prototype-builtins -- safe
  return !$Object('z').propertyIsEnumerable(0);
}) ? function (it) {
  return classof(it) === 'String' ? split(it, '') : $Object(it);
} : $Object;


/***/ }),

/***/ 74949:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var uncurryThis = __webpack_require__(41686);
var isCallable = __webpack_require__(69949);
var store = __webpack_require__(99346);

var functionToString = uncurryThis(Function.toString);

// this helper broken in `core-js@3.4.1-3.4.4`, so we can't use `shared` helper
if (!isCallable(store.inspectSource)) {
  store.inspectSource = function (it) {
    return functionToString(it);
  };
}

module.exports = store.inspectSource;


/***/ }),

/***/ 36653:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var NATIVE_WEAK_MAP = __webpack_require__(34011);
var global = __webpack_require__(68647);
var isObject = __webpack_require__(63590);
var createNonEnumerableProperty = __webpack_require__(87803);
var hasOwn = __webpack_require__(48314);
var shared = __webpack_require__(99346);
var sharedKey = __webpack_require__(66660);
var hiddenKeys = __webpack_require__(14983);

var OBJECT_ALREADY_INITIALIZED = 'Object already initialized';
var TypeError = global.TypeError;
var WeakMap = global.WeakMap;
var set, get, has;

var enforce = function (it) {
  return has(it) ? get(it) : set(it, {});
};

var getterFor = function (TYPE) {
  return function (it) {
    var state;
    if (!isObject(it) || (state = get(it)).type !== TYPE) {
      throw new TypeError('Incompatible receiver, ' + TYPE + ' required');
    } return state;
  };
};

if (NATIVE_WEAK_MAP || shared.state) {
  var store = shared.state || (shared.state = new WeakMap());
  /* eslint-disable no-self-assign -- prototype methods protection */
  store.get = store.get;
  store.has = store.has;
  store.set = store.set;
  /* eslint-enable no-self-assign -- prototype methods protection */
  set = function (it, metadata) {
    if (store.has(it)) throw new TypeError(OBJECT_ALREADY_INITIALIZED);
    metadata.facade = it;
    store.set(it, metadata);
    return metadata;
  };
  get = function (it) {
    return store.get(it) || {};
  };
  has = function (it) {
    return store.has(it);
  };
} else {
  var STATE = sharedKey('state');
  hiddenKeys[STATE] = true;
  set = function (it, metadata) {
    if (hasOwn(it, STATE)) throw new TypeError(OBJECT_ALREADY_INITIALIZED);
    metadata.facade = it;
    createNonEnumerableProperty(it, STATE, metadata);
    return metadata;
  };
  get = function (it) {
    return hasOwn(it, STATE) ? it[STATE] : {};
  };
  has = function (it) {
    return hasOwn(it, STATE);
  };
}

module.exports = {
  set: set,
  get: get,
  has: has,
  enforce: enforce,
  getterFor: getterFor
};


/***/ }),

/***/ 2111:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var wellKnownSymbol = __webpack_require__(21928);
var Iterators = __webpack_require__(69885);

var ITERATOR = wellKnownSymbol('iterator');
var ArrayPrototype = Array.prototype;

// check on default Array iterator
module.exports = function (it) {
  return it !== undefined && (Iterators.Array === it || ArrayPrototype[ITERATOR] === it);
};


/***/ }),

/***/ 84155:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var classof = __webpack_require__(67324);

// `IsArray` abstract operation
// https://tc39.es/ecma262/#sec-isarray
// eslint-disable-next-line es/no-array-isarray -- safe
module.exports = Array.isArray || function isArray(argument) {
  return classof(argument) === 'Array';
};


/***/ }),

/***/ 69949:
/***/ ((module) => {

"use strict";

// https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot
var documentAll = typeof document == 'object' && document.all;

// `IsCallable` abstract operation
// https://tc39.es/ecma262/#sec-iscallable
// eslint-disable-next-line unicorn/no-typeof-undefined -- required for testing
module.exports = typeof documentAll == 'undefined' && documentAll !== undefined ? function (argument) {
  return typeof argument == 'function' || argument === documentAll;
} : function (argument) {
  return typeof argument == 'function';
};


/***/ }),

/***/ 62371:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var uncurryThis = __webpack_require__(41686);
var fails = __webpack_require__(30676);
var isCallable = __webpack_require__(69949);
var classof = __webpack_require__(30487);
var getBuiltIn = __webpack_require__(94228);
var inspectSource = __webpack_require__(74949);

var noop = function () { /* empty */ };
var construct = getBuiltIn('Reflect', 'construct');
var constructorRegExp = /^\s*(?:class|function)\b/;
var exec = uncurryThis(constructorRegExp.exec);
var INCORRECT_TO_STRING = !constructorRegExp.test(noop);

var isConstructorModern = function isConstructor(argument) {
  if (!isCallable(argument)) return false;
  try {
    construct(noop, [], argument);
    return true;
  } catch (error) {
    return false;
  }
};

var isConstructorLegacy = function isConstructor(argument) {
  if (!isCallable(argument)) return false;
  switch (classof(argument)) {
    case 'AsyncFunction':
    case 'GeneratorFunction':
    case 'AsyncGeneratorFunction': return false;
  }
  try {
    // we can't check .prototype since constructors produced by .bind haven't it
    // `Function#toString` throws on some built-it function in some legacy engines
    // (for example, `DOMQuad` and similar in FF41-)
    return INCORRECT_TO_STRING || !!exec(constructorRegExp, inspectSource(argument));
  } catch (error) {
    return true;
  }
};

isConstructorLegacy.sham = true;

// `IsConstructor` abstract operation
// https://tc39.es/ecma262/#sec-isconstructor
module.exports = !construct || fails(function () {
  var called;
  return isConstructorModern(isConstructorModern.call)
    || !isConstructorModern(Object)
    || !isConstructorModern(function () { called = true; })
    || called;
}) ? isConstructorLegacy : isConstructorModern;


/***/ }),

/***/ 29924:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var fails = __webpack_require__(30676);
var isCallable = __webpack_require__(69949);

var replacement = /#|\.prototype\./;

var isForced = function (feature, detection) {
  var value = data[normalize(feature)];
  return value === POLYFILL ? true
    : value === NATIVE ? false
    : isCallable(detection) ? fails(detection)
    : !!detection;
};

var normalize = isForced.normalize = function (string) {
  return String(string).replace(replacement, '.').toLowerCase();
};

var data = isForced.data = {};
var NATIVE = isForced.NATIVE = 'N';
var POLYFILL = isForced.POLYFILL = 'P';

module.exports = isForced;


/***/ }),

/***/ 40446:
/***/ ((module) => {

"use strict";

// we can't use just `it == null` since of `document.all` special case
// https://tc39.es/ecma262/#sec-IsHTMLDDA-internal-slot-aec
module.exports = function (it) {
  return it === null || it === undefined;
};


/***/ }),

/***/ 63590:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var isCallable = __webpack_require__(69949);

module.exports = function (it) {
  return typeof it == 'object' ? it !== null : isCallable(it);
};


/***/ }),

/***/ 53112:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var isObject = __webpack_require__(63590);

module.exports = function (argument) {
  return isObject(argument) || argument === null;
};


/***/ }),

/***/ 96314:
/***/ ((module) => {

"use strict";

module.exports = true;


/***/ }),

/***/ 62296:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var getBuiltIn = __webpack_require__(94228);
var isCallable = __webpack_require__(69949);
var isPrototypeOf = __webpack_require__(97022);
var USE_SYMBOL_AS_UID = __webpack_require__(7238);

var $Object = Object;

module.exports = USE_SYMBOL_AS_UID ? function (it) {
  return typeof it == 'symbol';
} : function (it) {
  var $Symbol = getBuiltIn('Symbol');
  return isCallable($Symbol) && isPrototypeOf($Symbol.prototype, $Object(it));
};


/***/ }),

/***/ 53086:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var call = __webpack_require__(70492);
var anObject = __webpack_require__(1681);
var getMethod = __webpack_require__(36750);

module.exports = function (iterator, kind, value) {
  var innerResult, innerError;
  anObject(iterator);
  try {
    innerResult = getMethod(iterator, 'return');
    if (!innerResult) {
      if (kind === 'throw') throw value;
      return value;
    }
    innerResult = call(innerResult, iterator);
  } catch (error) {
    innerError = true;
    innerResult = error;
  }
  if (kind === 'throw') throw value;
  if (innerError) throw innerResult;
  anObject(innerResult);
  return value;
};


/***/ }),

/***/ 35402:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var IteratorPrototype = (__webpack_require__(97364).IteratorPrototype);
var create = __webpack_require__(82448);
var createPropertyDescriptor = __webpack_require__(16838);
var setToStringTag = __webpack_require__(73279);
var Iterators = __webpack_require__(69885);

var returnThis = function () { return this; };

module.exports = function (IteratorConstructor, NAME, next, ENUMERABLE_NEXT) {
  var TO_STRING_TAG = NAME + ' Iterator';
  IteratorConstructor.prototype = create(IteratorPrototype, { next: createPropertyDescriptor(+!ENUMERABLE_NEXT, next) });
  setToStringTag(IteratorConstructor, TO_STRING_TAG, false, true);
  Iterators[TO_STRING_TAG] = returnThis;
  return IteratorConstructor;
};


/***/ }),

/***/ 79117:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var $ = __webpack_require__(97934);
var call = __webpack_require__(70492);
var IS_PURE = __webpack_require__(96314);
var FunctionName = __webpack_require__(97745);
var isCallable = __webpack_require__(69949);
var createIteratorConstructor = __webpack_require__(35402);
var getPrototypeOf = __webpack_require__(12846);
var setPrototypeOf = __webpack_require__(9741);
var setToStringTag = __webpack_require__(73279);
var createNonEnumerableProperty = __webpack_require__(87803);
var defineBuiltIn = __webpack_require__(84406);
var wellKnownSymbol = __webpack_require__(21928);
var Iterators = __webpack_require__(69885);
var IteratorsCore = __webpack_require__(97364);

var PROPER_FUNCTION_NAME = FunctionName.PROPER;
var CONFIGURABLE_FUNCTION_NAME = FunctionName.CONFIGURABLE;
var IteratorPrototype = IteratorsCore.IteratorPrototype;
var BUGGY_SAFARI_ITERATORS = IteratorsCore.BUGGY_SAFARI_ITERATORS;
var ITERATOR = wellKnownSymbol('iterator');
var KEYS = 'keys';
var VALUES = 'values';
var ENTRIES = 'entries';

var returnThis = function () { return this; };

module.exports = function (Iterable, NAME, IteratorConstructor, next, DEFAULT, IS_SET, FORCED) {
  createIteratorConstructor(IteratorConstructor, NAME, next);

  var getIterationMethod = function (KIND) {
    if (KIND === DEFAULT && defaultIterator) return defaultIterator;
    if (!BUGGY_SAFARI_ITERATORS && KIND && KIND in IterablePrototype) return IterablePrototype[KIND];

    switch (KIND) {
      case KEYS: return function keys() { return new IteratorConstructor(this, KIND); };
      case VALUES: return function values() { return new IteratorConstructor(this, KIND); };
      case ENTRIES: return function entries() { return new IteratorConstructor(this, KIND); };
    }

    return function () { return new IteratorConstructor(this); };
  };

  var TO_STRING_TAG = NAME + ' Iterator';
  var INCORRECT_VALUES_NAME = false;
  var IterablePrototype = Iterable.prototype;
  var nativeIterator = IterablePrototype[ITERATOR]
    || IterablePrototype['@@iterator']
    || DEFAULT && IterablePrototype[DEFAULT];
  var defaultIterator = !BUGGY_SAFARI_ITERATORS && nativeIterator || getIterationMethod(DEFAULT);
  var anyNativeIterator = NAME === 'Array' ? IterablePrototype.entries || nativeIterator : nativeIterator;
  var CurrentIteratorPrototype, methods, KEY;

  // fix native
  if (anyNativeIterator) {
    CurrentIteratorPrototype = getPrototypeOf(anyNativeIterator.call(new Iterable()));
    if (CurrentIteratorPrototype !== Object.prototype && CurrentIteratorPrototype.next) {
      if (!IS_PURE && getPrototypeOf(CurrentIteratorPrototype) !== IteratorPrototype) {
        if (setPrototypeOf) {
          setPrototypeOf(CurrentIteratorPrototype, IteratorPrototype);
        } else if (!isCallable(CurrentIteratorPrototype[ITERATOR])) {
          defineBuiltIn(CurrentIteratorPrototype, ITERATOR, returnThis);
        }
      }
      // Set @@toStringTag to native iterators
      setToStringTag(CurrentIteratorPrototype, TO_STRING_TAG, true, true);
      if (IS_PURE) Iterators[TO_STRING_TAG] = returnThis;
    }
  }

  // fix Array.prototype.{ values, @@iterator }.name in V8 / FF
  if (PROPER_FUNCTION_NAME && DEFAULT === VALUES && nativeIterator && nativeIterator.name !== VALUES) {
    if (!IS_PURE && CONFIGURABLE_FUNCTION_NAME) {
      createNonEnumerableProperty(IterablePrototype, 'name', VALUES);
    } else {
      INCORRECT_VALUES_NAME = true;
      defaultIterator = function values() { return call(nativeIterator, this); };
    }
  }

  // export additional methods
  if (DEFAULT) {
    methods = {
      values: getIterationMethod(VALUES),
      keys: IS_SET ? defaultIterator : getIterationMethod(KEYS),
      entries: getIterationMethod(ENTRIES)
    };
    if (FORCED) for (KEY in methods) {
      if (BUGGY_SAFARI_ITERATORS || INCORRECT_VALUES_NAME || !(KEY in IterablePrototype)) {
        defineBuiltIn(IterablePrototype, KEY, methods[KEY]);
      }
    } else $({ target: NAME, proto: true, forced: BUGGY_SAFARI_ITERATORS || INCORRECT_VALUES_NAME }, methods);
  }

  // define iterator
  if ((!IS_PURE || FORCED) && IterablePrototype[ITERATOR] !== defaultIterator) {
    defineBuiltIn(IterablePrototype, ITERATOR, defaultIterator, { name: DEFAULT });
  }
  Iterators[NAME] = defaultIterator;

  return methods;
};


/***/ }),

/***/ 97364:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var fails = __webpack_require__(30676);
var isCallable = __webpack_require__(69949);
var isObject = __webpack_require__(63590);
var create = __webpack_require__(82448);
var getPrototypeOf = __webpack_require__(12846);
var defineBuiltIn = __webpack_require__(84406);
var wellKnownSymbol = __webpack_require__(21928);
var IS_PURE = __webpack_require__(96314);

var ITERATOR = wellKnownSymbol('iterator');
var BUGGY_SAFARI_ITERATORS = false;

// `%IteratorPrototype%` object
// https://tc39.es/ecma262/#sec-%iteratorprototype%-object
var IteratorPrototype, PrototypeOfArrayIteratorPrototype, arrayIterator;

/* eslint-disable es/no-array-prototype-keys -- safe */
if ([].keys) {
  arrayIterator = [].keys();
  // Safari 8 has buggy iterators w/o `next`
  if (!('next' in arrayIterator)) BUGGY_SAFARI_ITERATORS = true;
  else {
    PrototypeOfArrayIteratorPrototype = getPrototypeOf(getPrototypeOf(arrayIterator));
    if (PrototypeOfArrayIteratorPrototype !== Object.prototype) IteratorPrototype = PrototypeOfArrayIteratorPrototype;
  }
}

var NEW_ITERATOR_PROTOTYPE = !isObject(IteratorPrototype) || fails(function () {
  var test = {};
  // FF44- legacy iterators case
  return IteratorPrototype[ITERATOR].call(test) !== test;
});

if (NEW_ITERATOR_PROTOTYPE) IteratorPrototype = {};
else if (IS_PURE) IteratorPrototype = create(IteratorPrototype);

// `%IteratorPrototype%[@@iterator]()` method
// https://tc39.es/ecma262/#sec-%iteratorprototype%-@@iterator
if (!isCallable(IteratorPrototype[ITERATOR])) {
  defineBuiltIn(IteratorPrototype, ITERATOR, function () {
    return this;
  });
}

module.exports = {
  IteratorPrototype: IteratorPrototype,
  BUGGY_SAFARI_ITERATORS: BUGGY_SAFARI_ITERATORS
};


/***/ }),

/***/ 69885:
/***/ ((module) => {

"use strict";

module.exports = {};


/***/ }),

/***/ 46935:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var toLength = __webpack_require__(74333);

// `LengthOfArrayLike` abstract operation
// https://tc39.es/ecma262/#sec-lengthofarraylike
module.exports = function (obj) {
  return toLength(obj.length);
};


/***/ }),

/***/ 7338:
/***/ ((module) => {

"use strict";

var ceil = Math.ceil;
var floor = Math.floor;

// `Math.trunc` method
// https://tc39.es/ecma262/#sec-math.trunc
// eslint-disable-next-line es/no-math-trunc -- safe
module.exports = Math.trunc || function trunc(x) {
  var n = +x;
  return (n > 0 ? floor : ceil)(n);
};


/***/ }),

/***/ 38167:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var global = __webpack_require__(68647);
var fails = __webpack_require__(30676);
var uncurryThis = __webpack_require__(41686);
var toString = __webpack_require__(87365);
var trim = (__webpack_require__(82935).trim);
var whitespaces = __webpack_require__(15751);

var $parseInt = global.parseInt;
var Symbol = global.Symbol;
var ITERATOR = Symbol && Symbol.iterator;
var hex = /^[+-]?0x/i;
var exec = uncurryThis(hex.exec);
var FORCED = $parseInt(whitespaces + '08') !== 8 || $parseInt(whitespaces + '0x16') !== 22
  // MS Edge 18- broken with boxed symbols
  || (ITERATOR && !fails(function () { $parseInt(Object(ITERATOR)); }));

// `parseInt` method
// https://tc39.es/ecma262/#sec-parseint-string-radix
module.exports = FORCED ? function parseInt(string, radix) {
  var S = trim(toString(string));
  return $parseInt(S, (radix >>> 0) || (exec(hex, S) ? 16 : 10));
} : $parseInt;


/***/ }),

/***/ 82448:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

/* global ActiveXObject -- old IE, WSH */
var anObject = __webpack_require__(1681);
var definePropertiesModule = __webpack_require__(16514);
var enumBugKeys = __webpack_require__(33527);
var hiddenKeys = __webpack_require__(14983);
var html = __webpack_require__(76055);
var documentCreateElement = __webpack_require__(79927);
var sharedKey = __webpack_require__(66660);

var GT = '>';
var LT = '<';
var PROTOTYPE = 'prototype';
var SCRIPT = 'script';
var IE_PROTO = sharedKey('IE_PROTO');

var EmptyConstructor = function () { /* empty */ };

var scriptTag = function (content) {
  return LT + SCRIPT + GT + content + LT + '/' + SCRIPT + GT;
};

// Create object with fake `null` prototype: use ActiveX Object with cleared prototype
var NullProtoObjectViaActiveX = function (activeXDocument) {
  activeXDocument.write(scriptTag(''));
  activeXDocument.close();
  var temp = activeXDocument.parentWindow.Object;
  activeXDocument = null; // avoid memory leak
  return temp;
};

// Create object with fake `null` prototype: use iframe Object with cleared prototype
var NullProtoObjectViaIFrame = function () {
  // Thrash, waste and sodomy: IE GC bug
  var iframe = documentCreateElement('iframe');
  var JS = 'java' + SCRIPT + ':';
  var iframeDocument;
  iframe.style.display = 'none';
  html.appendChild(iframe);
  // https://github.com/zloirock/core-js/issues/475
  iframe.src = String(JS);
  iframeDocument = iframe.contentWindow.document;
  iframeDocument.open();
  iframeDocument.write(scriptTag('document.F=Object'));
  iframeDocument.close();
  return iframeDocument.F;
};

// Check for document.domain and active x support
// No need to use active x approach when document.domain is not set
// see https://github.com/es-shims/es5-shim/issues/150
// variation of https://github.com/kitcambridge/es5-shim/commit/4f738ac066346
// avoid IE GC bug
var activeXDocument;
var NullProtoObject = function () {
  try {
    activeXDocument = new ActiveXObject('htmlfile');
  } catch (error) { /* ignore */ }
  NullProtoObject = typeof document != 'undefined'
    ? document.domain && activeXDocument
      ? NullProtoObjectViaActiveX(activeXDocument) // old IE
      : NullProtoObjectViaIFrame()
    : NullProtoObjectViaActiveX(activeXDocument); // WSH
  var length = enumBugKeys.length;
  while (length--) delete NullProtoObject[PROTOTYPE][enumBugKeys[length]];
  return NullProtoObject();
};

hiddenKeys[IE_PROTO] = true;

// `Object.create` method
// https://tc39.es/ecma262/#sec-object.create
// eslint-disable-next-line es/no-object-create -- safe
module.exports = Object.create || function create(O, Properties) {
  var result;
  if (O !== null) {
    EmptyConstructor[PROTOTYPE] = anObject(O);
    result = new EmptyConstructor();
    EmptyConstructor[PROTOTYPE] = null;
    // add "__proto__" for Object.getPrototypeOf polyfill
    result[IE_PROTO] = O;
  } else result = NullProtoObject();
  return Properties === undefined ? result : definePropertiesModule.f(result, Properties);
};


/***/ }),

/***/ 16514:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {

"use strict";

var DESCRIPTORS = __webpack_require__(99262);
var V8_PROTOTYPE_DEFINE_BUG = __webpack_require__(63222);
var definePropertyModule = __webpack_require__(45661);
var anObject = __webpack_require__(1681);
var toIndexedObject = __webpack_require__(10839);
var objectKeys = __webpack_require__(57744);

// `Object.defineProperties` method
// https://tc39.es/ecma262/#sec-object.defineproperties
// eslint-disable-next-line es/no-object-defineproperties -- safe
exports.f = DESCRIPTORS && !V8_PROTOTYPE_DEFINE_BUG ? Object.defineProperties : function defineProperties(O, Properties) {
  anObject(O);
  var props = toIndexedObject(Properties);
  var keys = objectKeys(Properties);
  var length = keys.length;
  var index = 0;
  var key;
  while (length > index) definePropertyModule.f(O, key = keys[index++], props[key]);
  return O;
};


/***/ }),

/***/ 45661:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {

"use strict";

var DESCRIPTORS = __webpack_require__(99262);
var IE8_DOM_DEFINE = __webpack_require__(40123);
var V8_PROTOTYPE_DEFINE_BUG = __webpack_require__(63222);
var anObject = __webpack_require__(1681);
var toPropertyKey = __webpack_require__(92881);

var $TypeError = TypeError;
// eslint-disable-next-line es/no-object-defineproperty -- safe
var $defineProperty = Object.defineProperty;
// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
var $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
var ENUMERABLE = 'enumerable';
var CONFIGURABLE = 'configurable';
var WRITABLE = 'writable';

// `Object.defineProperty` method
// https://tc39.es/ecma262/#sec-object.defineproperty
exports.f = DESCRIPTORS ? V8_PROTOTYPE_DEFINE_BUG ? function defineProperty(O, P, Attributes) {
  anObject(O);
  P = toPropertyKey(P);
  anObject(Attributes);
  if (typeof O === 'function' && P === 'prototype' && 'value' in Attributes && WRITABLE in Attributes && !Attributes[WRITABLE]) {
    var current = $getOwnPropertyDescriptor(O, P);
    if (current && current[WRITABLE]) {
      O[P] = Attributes.value;
      Attributes = {
        configurable: CONFIGURABLE in Attributes ? Attributes[CONFIGURABLE] : current[CONFIGURABLE],
        enumerable: ENUMERABLE in Attributes ? Attributes[ENUMERABLE] : current[ENUMERABLE],
        writable: false
      };
    }
  } return $defineProperty(O, P, Attributes);
} : $defineProperty : function defineProperty(O, P, Attributes) {
  anObject(O);
  P = toPropertyKey(P);
  anObject(Attributes);
  if (IE8_DOM_DEFINE) try {
    return $defineProperty(O, P, Attributes);
  } catch (error) { /* empty */ }
  if ('get' in Attributes || 'set' in Attributes) throw new $TypeError('Accessors not supported');
  if ('value' in Attributes) O[P] = Attributes.value;
  return O;
};


/***/ }),

/***/ 10656:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {

"use strict";

var DESCRIPTORS = __webpack_require__(99262);
var call = __webpack_require__(70492);
var propertyIsEnumerableModule = __webpack_require__(86652);
var createPropertyDescriptor = __webpack_require__(16838);
var toIndexedObject = __webpack_require__(10839);
var toPropertyKey = __webpack_require__(92881);
var hasOwn = __webpack_require__(48314);
var IE8_DOM_DEFINE = __webpack_require__(40123);

// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
var $getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;

// `Object.getOwnPropertyDescriptor` method
// https://tc39.es/ecma262/#sec-object.getownpropertydescriptor
exports.f = DESCRIPTORS ? $getOwnPropertyDescriptor : function getOwnPropertyDescriptor(O, P) {
  O = toIndexedObject(O);
  P = toPropertyKey(P);
  if (IE8_DOM_DEFINE) try {
    return $getOwnPropertyDescriptor(O, P);
  } catch (error) { /* empty */ }
  if (hasOwn(O, P)) return createPropertyDescriptor(!call(propertyIsEnumerableModule.f, O, P), O[P]);
};


/***/ }),

/***/ 82847:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

/* eslint-disable es/no-object-getownpropertynames -- safe */
var classof = __webpack_require__(67324);
var toIndexedObject = __webpack_require__(10839);
var $getOwnPropertyNames = (__webpack_require__(62435).f);
var arraySlice = __webpack_require__(79919);

var windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames
  ? Object.getOwnPropertyNames(window) : [];

var getWindowNames = function (it) {
  try {
    return $getOwnPropertyNames(it);
  } catch (error) {
    return arraySlice(windowNames);
  }
};

// fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window
module.exports.f = function getOwnPropertyNames(it) {
  return windowNames && classof(it) === 'Window'
    ? getWindowNames(it)
    : $getOwnPropertyNames(toIndexedObject(it));
};


/***/ }),

/***/ 62435:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {

"use strict";

var internalObjectKeys = __webpack_require__(76439);
var enumBugKeys = __webpack_require__(33527);

var hiddenKeys = enumBugKeys.concat('length', 'prototype');

// `Object.getOwnPropertyNames` method
// https://tc39.es/ecma262/#sec-object.getownpropertynames
// eslint-disable-next-line es/no-object-getownpropertynames -- safe
exports.f = Object.getOwnPropertyNames || function getOwnPropertyNames(O) {
  return internalObjectKeys(O, hiddenKeys);
};


/***/ }),

/***/ 26640:
/***/ ((__unused_webpack_module, exports) => {

"use strict";

// eslint-disable-next-line es/no-object-getownpropertysymbols -- safe
exports.f = Object.getOwnPropertySymbols;


/***/ }),

/***/ 12846:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var hasOwn = __webpack_require__(48314);
var isCallable = __webpack_require__(69949);
var toObject = __webpack_require__(85857);
var sharedKey = __webpack_require__(66660);
var CORRECT_PROTOTYPE_GETTER = __webpack_require__(4592);

var IE_PROTO = sharedKey('IE_PROTO');
var $Object = Object;
var ObjectPrototype = $Object.prototype;

// `Object.getPrototypeOf` method
// https://tc39.es/ecma262/#sec-object.getprototypeof
// eslint-disable-next-line es/no-object-getprototypeof -- safe
module.exports = CORRECT_PROTOTYPE_GETTER ? $Object.getPrototypeOf : function (O) {
  var object = toObject(O);
  if (hasOwn(object, IE_PROTO)) return object[IE_PROTO];
  var constructor = object.constructor;
  if (isCallable(constructor) && object instanceof constructor) {
    return constructor.prototype;
  } return object instanceof $Object ? ObjectPrototype : null;
};


/***/ }),

/***/ 97022:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var uncurryThis = __webpack_require__(41686);

module.exports = uncurryThis({}.isPrototypeOf);


/***/ }),

/***/ 76439:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var uncurryThis = __webpack_require__(41686);
var hasOwn = __webpack_require__(48314);
var toIndexedObject = __webpack_require__(10839);
var indexOf = (__webpack_require__(74895).indexOf);
var hiddenKeys = __webpack_require__(14983);

var push = uncurryThis([].push);

module.exports = function (object, names) {
  var O = toIndexedObject(object);
  var i = 0;
  var result = [];
  var key;
  for (key in O) !hasOwn(hiddenKeys, key) && hasOwn(O, key) && push(result, key);
  // Don't enum bug & hidden keys
  while (names.length > i) if (hasOwn(O, key = names[i++])) {
    ~indexOf(result, key) || push(result, key);
  }
  return result;
};


/***/ }),

/***/ 57744:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var internalObjectKeys = __webpack_require__(76439);
var enumBugKeys = __webpack_require__(33527);

// `Object.keys` method
// https://tc39.es/ecma262/#sec-object.keys
// eslint-disable-next-line es/no-object-keys -- safe
module.exports = Object.keys || function keys(O) {
  return internalObjectKeys(O, enumBugKeys);
};


/***/ }),

/***/ 86652:
/***/ ((__unused_webpack_module, exports) => {

"use strict";

var $propertyIsEnumerable = {}.propertyIsEnumerable;
// eslint-disable-next-line es/no-object-getownpropertydescriptor -- safe
var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;

// Nashorn ~ JDK8 bug
var NASHORN_BUG = getOwnPropertyDescriptor && !$propertyIsEnumerable.call({ 1: 2 }, 1);

// `Object.prototype.propertyIsEnumerable` method implementation
// https://tc39.es/ecma262/#sec-object.prototype.propertyisenumerable
exports.f = NASHORN_BUG ? function propertyIsEnumerable(V) {
  var descriptor = getOwnPropertyDescriptor(this, V);
  return !!descriptor && descriptor.enumerable;
} : $propertyIsEnumerable;


/***/ }),

/***/ 9741:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

/* eslint-disable no-proto -- safe */
var uncurryThisAccessor = __webpack_require__(25933);
var isObject = __webpack_require__(63590);
var requireObjectCoercible = __webpack_require__(91462);
var aPossiblePrototype = __webpack_require__(23886);

// `Object.setPrototypeOf` method
// https://tc39.es/ecma262/#sec-object.setprototypeof
// Works with __proto__ only. Old v8 can't work with null proto objects.
// eslint-disable-next-line es/no-object-setprototypeof -- safe
module.exports = Object.setPrototypeOf || ('__proto__' in {} ? function () {
  var CORRECT_SETTER = false;
  var test = {};
  var setter;
  try {
    setter = uncurryThisAccessor(Object.prototype, '__proto__', 'set');
    setter(test, []);
    CORRECT_SETTER = test instanceof Array;
  } catch (error) { /* empty */ }
  return function setPrototypeOf(O, proto) {
    requireObjectCoercible(O);
    aPossiblePrototype(proto);
    if (!isObject(O)) return O;
    if (CORRECT_SETTER) setter(O, proto);
    else O.__proto__ = proto;
    return O;
  };
}() : undefined);


/***/ }),

/***/ 84594:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var TO_STRING_TAG_SUPPORT = __webpack_require__(79490);
var classof = __webpack_require__(30487);

// `Object.prototype.toString` method implementation
// https://tc39.es/ecma262/#sec-object.prototype.tostring
module.exports = TO_STRING_TAG_SUPPORT ? {}.toString : function toString() {
  return '[object ' + classof(this) + ']';
};


/***/ }),

/***/ 71430:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var call = __webpack_require__(70492);
var isCallable = __webpack_require__(69949);
var isObject = __webpack_require__(63590);

var $TypeError = TypeError;

// `OrdinaryToPrimitive` abstract operation
// https://tc39.es/ecma262/#sec-ordinarytoprimitive
module.exports = function (input, pref) {
  var fn, val;
  if (pref === 'string' && isCallable(fn = input.toString) && !isObject(val = call(fn, input))) return val;
  if (isCallable(fn = input.valueOf) && !isObject(val = call(fn, input))) return val;
  if (pref !== 'string' && isCallable(fn = input.toString) && !isObject(val = call(fn, input))) return val;
  throw new $TypeError("Can't convert object to primitive value");
};


/***/ }),

/***/ 81217:
/***/ ((module) => {

"use strict";

module.exports = {};


/***/ }),

/***/ 39128:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var anObject = __webpack_require__(1681);

// `RegExp.prototype.flags` getter implementation
// https://tc39.es/ecma262/#sec-get-regexp.prototype.flags
module.exports = function () {
  var that = anObject(this);
  var result = '';
  if (that.hasIndices) result += 'd';
  if (that.global) result += 'g';
  if (that.ignoreCase) result += 'i';
  if (that.multiline) result += 'm';
  if (that.dotAll) result += 's';
  if (that.unicode) result += 'u';
  if (that.unicodeSets) result += 'v';
  if (that.sticky) result += 'y';
  return result;
};


/***/ }),

/***/ 76255:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var call = __webpack_require__(70492);
var hasOwn = __webpack_require__(48314);
var isPrototypeOf = __webpack_require__(97022);
var regExpFlags = __webpack_require__(39128);

var RegExpPrototype = RegExp.prototype;

module.exports = function (R) {
  var flags = R.flags;
  return flags === undefined && !('flags' in RegExpPrototype) && !hasOwn(R, 'flags') && isPrototypeOf(RegExpPrototype, R)
    ? call(regExpFlags, R) : flags;
};


/***/ }),

/***/ 91462:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var isNullOrUndefined = __webpack_require__(40446);

var $TypeError = TypeError;

// `RequireObjectCoercible` abstract operation
// https://tc39.es/ecma262/#sec-requireobjectcoercible
module.exports = function (it) {
  if (isNullOrUndefined(it)) throw new $TypeError("Can't call method on " + it);
  return it;
};


/***/ }),

/***/ 73279:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var TO_STRING_TAG_SUPPORT = __webpack_require__(79490);
var defineProperty = (__webpack_require__(45661).f);
var createNonEnumerableProperty = __webpack_require__(87803);
var hasOwn = __webpack_require__(48314);
var toString = __webpack_require__(84594);
var wellKnownSymbol = __webpack_require__(21928);

var TO_STRING_TAG = wellKnownSymbol('toStringTag');

module.exports = function (it, TAG, STATIC, SET_METHOD) {
  var target = STATIC ? it : it && it.prototype;
  if (target) {
    if (!hasOwn(target, TO_STRING_TAG)) {
      defineProperty(target, TO_STRING_TAG, { configurable: true, value: TAG });
    }
    if (SET_METHOD && !TO_STRING_TAG_SUPPORT) {
      createNonEnumerableProperty(target, 'toString', toString);
    }
  }
};


/***/ }),

/***/ 66660:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var shared = __webpack_require__(56314);
var uid = __webpack_require__(60220);

var keys = shared('keys');

module.exports = function (key) {
  return keys[key] || (keys[key] = uid(key));
};


/***/ }),

/***/ 99346:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var IS_PURE = __webpack_require__(96314);
var globalThis = __webpack_require__(68647);
var defineGlobalProperty = __webpack_require__(68053);

var SHARED = '__core-js_shared__';
var store = module.exports = globalThis[SHARED] || defineGlobalProperty(SHARED, {});

(store.versions || (store.versions = [])).push({
  version: '3.37.1',
  mode: IS_PURE ? 'pure' : 'global',
  copyright: '© 2014-2024 Denis Pushkarev (zloirock.ru)',
  license: 'https://github.com/zloirock/core-js/blob/v3.37.1/LICENSE',
  source: 'https://github.com/zloirock/core-js'
});


/***/ }),

/***/ 56314:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var store = __webpack_require__(99346);

module.exports = function (key, value) {
  return store[key] || (store[key] = value || {});
};


/***/ }),

/***/ 27489:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var uncurryThis = __webpack_require__(41686);
var toIntegerOrInfinity = __webpack_require__(9889);
var toString = __webpack_require__(87365);
var requireObjectCoercible = __webpack_require__(91462);

var charAt = uncurryThis(''.charAt);
var charCodeAt = uncurryThis(''.charCodeAt);
var stringSlice = uncurryThis(''.slice);

var createMethod = function (CONVERT_TO_STRING) {
  return function ($this, pos) {
    var S = toString(requireObjectCoercible($this));
    var position = toIntegerOrInfinity(pos);
    var size = S.length;
    var first, second;
    if (position < 0 || position >= size) return CONVERT_TO_STRING ? '' : undefined;
    first = charCodeAt(S, position);
    return first < 0xD800 || first > 0xDBFF || position + 1 === size
      || (second = charCodeAt(S, position + 1)) < 0xDC00 || second > 0xDFFF
        ? CONVERT_TO_STRING
          ? charAt(S, position)
          : first
        : CONVERT_TO_STRING
          ? stringSlice(S, position, position + 2)
          : (first - 0xD800 << 10) + (second - 0xDC00) + 0x10000;
  };
};

module.exports = {
  // `String.prototype.codePointAt` method
  // https://tc39.es/ecma262/#sec-string.prototype.codepointat
  codeAt: createMethod(false),
  // `String.prototype.at` method
  // https://github.com/mathiasbynens/String.prototype.at
  charAt: createMethod(true)
};


/***/ }),

/***/ 82935:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var uncurryThis = __webpack_require__(41686);
var requireObjectCoercible = __webpack_require__(91462);
var toString = __webpack_require__(87365);
var whitespaces = __webpack_require__(15751);

var replace = uncurryThis(''.replace);
var ltrim = RegExp('^[' + whitespaces + ']+');
var rtrim = RegExp('(^|[^' + whitespaces + '])[' + whitespaces + ']+$');

// `String.prototype.{ trim, trimStart, trimEnd, trimLeft, trimRight }` methods implementation
var createMethod = function (TYPE) {
  return function ($this) {
    var string = toString(requireObjectCoercible($this));
    if (TYPE & 1) string = replace(string, ltrim, '');
    if (TYPE & 2) string = replace(string, rtrim, '$1');
    return string;
  };
};

module.exports = {
  // `String.prototype.{ trimLeft, trimStart }` methods
  // https://tc39.es/ecma262/#sec-string.prototype.trimstart
  start: createMethod(1),
  // `String.prototype.{ trimRight, trimEnd }` methods
  // https://tc39.es/ecma262/#sec-string.prototype.trimend
  end: createMethod(2),
  // `String.prototype.trim` method
  // https://tc39.es/ecma262/#sec-string.prototype.trim
  trim: createMethod(3)
};


/***/ }),

/***/ 23570:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

/* eslint-disable es/no-symbol -- required for testing */
var V8_VERSION = __webpack_require__(97711);
var fails = __webpack_require__(30676);
var global = __webpack_require__(68647);

var $String = global.String;

// eslint-disable-next-line es/no-object-getownpropertysymbols -- required for testing
module.exports = !!Object.getOwnPropertySymbols && !fails(function () {
  var symbol = Symbol('symbol detection');
  // Chrome 38 Symbol has incorrect toString conversion
  // `get-own-property-symbols` polyfill symbols converted to object are not Symbol instances
  // nb: Do not call `String` directly to avoid this being optimized out to `symbol+''` which will,
  // of course, fail.
  return !$String(symbol) || !(Object(symbol) instanceof Symbol) ||
    // Chrome 38-40 symbols are not inherited from DOM collections prototypes to instances
    !Symbol.sham && V8_VERSION && V8_VERSION < 41;
});


/***/ }),

/***/ 92933:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var call = __webpack_require__(70492);
var getBuiltIn = __webpack_require__(94228);
var wellKnownSymbol = __webpack_require__(21928);
var defineBuiltIn = __webpack_require__(84406);

module.exports = function () {
  var Symbol = getBuiltIn('Symbol');
  var SymbolPrototype = Symbol && Symbol.prototype;
  var valueOf = SymbolPrototype && SymbolPrototype.valueOf;
  var TO_PRIMITIVE = wellKnownSymbol('toPrimitive');

  if (SymbolPrototype && !SymbolPrototype[TO_PRIMITIVE]) {
    // `Symbol.prototype[@@toPrimitive]` method
    // https://tc39.es/ecma262/#sec-symbol.prototype-@@toprimitive
    // eslint-disable-next-line no-unused-vars -- required for .length
    defineBuiltIn(SymbolPrototype, TO_PRIMITIVE, function (hint) {
      return call(valueOf, this);
    }, { arity: 1 });
  }
};


/***/ }),

/***/ 14136:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var getBuiltIn = __webpack_require__(94228);
var uncurryThis = __webpack_require__(41686);

var Symbol = getBuiltIn('Symbol');
var keyFor = Symbol.keyFor;
var thisSymbolValue = uncurryThis(Symbol.prototype.valueOf);

// `Symbol.isRegisteredSymbol` method
// https://tc39.es/proposal-symbol-predicates/#sec-symbol-isregisteredsymbol
module.exports = Symbol.isRegisteredSymbol || function isRegisteredSymbol(value) {
  try {
    return keyFor(thisSymbolValue(value)) !== undefined;
  } catch (error) {
    return false;
  }
};


/***/ }),

/***/ 6635:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var shared = __webpack_require__(56314);
var getBuiltIn = __webpack_require__(94228);
var uncurryThis = __webpack_require__(41686);
var isSymbol = __webpack_require__(62296);
var wellKnownSymbol = __webpack_require__(21928);

var Symbol = getBuiltIn('Symbol');
var $isWellKnownSymbol = Symbol.isWellKnownSymbol;
var getOwnPropertyNames = getBuiltIn('Object', 'getOwnPropertyNames');
var thisSymbolValue = uncurryThis(Symbol.prototype.valueOf);
var WellKnownSymbolsStore = shared('wks');

for (var i = 0, symbolKeys = getOwnPropertyNames(Symbol), symbolKeysLength = symbolKeys.length; i < symbolKeysLength; i++) {
  // some old engines throws on access to some keys like `arguments` or `caller`
  try {
    var symbolKey = symbolKeys[i];
    if (isSymbol(Symbol[symbolKey])) wellKnownSymbol(symbolKey);
  } catch (error) { /* empty */ }
}

// `Symbol.isWellKnownSymbol` method
// https://tc39.es/proposal-symbol-predicates/#sec-symbol-iswellknownsymbol
// We should patch it for newly added well-known symbols. If it's not required, this module just will not be injected
module.exports = function isWellKnownSymbol(value) {
  if ($isWellKnownSymbol && $isWellKnownSymbol(value)) return true;
  try {
    var symbol = thisSymbolValue(value);
    for (var j = 0, keys = getOwnPropertyNames(WellKnownSymbolsStore), keysLength = keys.length; j < keysLength; j++) {
      // eslint-disable-next-line eqeqeq -- polyfilled symbols case
      if (WellKnownSymbolsStore[keys[j]] == symbol) return true;
    }
  } catch (error) { /* empty */ }
  return false;
};


/***/ }),

/***/ 23756:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var NATIVE_SYMBOL = __webpack_require__(23570);

/* eslint-disable es/no-symbol -- safe */
module.exports = NATIVE_SYMBOL && !!Symbol['for'] && !!Symbol.keyFor;


/***/ }),

/***/ 13036:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var toIntegerOrInfinity = __webpack_require__(9889);

var max = Math.max;
var min = Math.min;

// Helper for a popular repeating case of the spec:
// Let integer be ? ToInteger(index).
// If integer < 0, let result be max((length + integer), 0); else let result be min(integer, length).
module.exports = function (index, length) {
  var integer = toIntegerOrInfinity(index);
  return integer < 0 ? max(integer + length, 0) : min(integer, length);
};


/***/ }),

/***/ 10839:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

// toObject with fallback for non-array-like ES3 strings
var IndexedObject = __webpack_require__(92831);
var requireObjectCoercible = __webpack_require__(91462);

module.exports = function (it) {
  return IndexedObject(requireObjectCoercible(it));
};


/***/ }),

/***/ 9889:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var trunc = __webpack_require__(7338);

// `ToIntegerOrInfinity` abstract operation
// https://tc39.es/ecma262/#sec-tointegerorinfinity
module.exports = function (argument) {
  var number = +argument;
  // eslint-disable-next-line no-self-compare -- NaN check
  return number !== number || number === 0 ? 0 : trunc(number);
};


/***/ }),

/***/ 74333:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var toIntegerOrInfinity = __webpack_require__(9889);

var min = Math.min;

// `ToLength` abstract operation
// https://tc39.es/ecma262/#sec-tolength
module.exports = function (argument) {
  var len = toIntegerOrInfinity(argument);
  return len > 0 ? min(len, 0x1FFFFFFFFFFFFF) : 0; // 2 ** 53 - 1 == 9007199254740991
};


/***/ }),

/***/ 85857:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var requireObjectCoercible = __webpack_require__(91462);

var $Object = Object;

// `ToObject` abstract operation
// https://tc39.es/ecma262/#sec-toobject
module.exports = function (argument) {
  return $Object(requireObjectCoercible(argument));
};


/***/ }),

/***/ 32641:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var call = __webpack_require__(70492);
var isObject = __webpack_require__(63590);
var isSymbol = __webpack_require__(62296);
var getMethod = __webpack_require__(36750);
var ordinaryToPrimitive = __webpack_require__(71430);
var wellKnownSymbol = __webpack_require__(21928);

var $TypeError = TypeError;
var TO_PRIMITIVE = wellKnownSymbol('toPrimitive');

// `ToPrimitive` abstract operation
// https://tc39.es/ecma262/#sec-toprimitive
module.exports = function (input, pref) {
  if (!isObject(input) || isSymbol(input)) return input;
  var exoticToPrim = getMethod(input, TO_PRIMITIVE);
  var result;
  if (exoticToPrim) {
    if (pref === undefined) pref = 'default';
    result = call(exoticToPrim, input, pref);
    if (!isObject(result) || isSymbol(result)) return result;
    throw new $TypeError("Can't convert object to primitive value");
  }
  if (pref === undefined) pref = 'number';
  return ordinaryToPrimitive(input, pref);
};


/***/ }),

/***/ 92881:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var toPrimitive = __webpack_require__(32641);
var isSymbol = __webpack_require__(62296);

// `ToPropertyKey` abstract operation
// https://tc39.es/ecma262/#sec-topropertykey
module.exports = function (argument) {
  var key = toPrimitive(argument, 'string');
  return isSymbol(key) ? key : key + '';
};


/***/ }),

/***/ 79490:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var wellKnownSymbol = __webpack_require__(21928);

var TO_STRING_TAG = wellKnownSymbol('toStringTag');
var test = {};

test[TO_STRING_TAG] = 'z';

module.exports = String(test) === '[object z]';


/***/ }),

/***/ 87365:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var classof = __webpack_require__(30487);

var $String = String;

module.exports = function (argument) {
  if (classof(argument) === 'Symbol') throw new TypeError('Cannot convert a Symbol value to a string');
  return $String(argument);
};


/***/ }),

/***/ 18458:
/***/ ((module) => {

"use strict";

var $String = String;

module.exports = function (argument) {
  try {
    return $String(argument);
  } catch (error) {
    return 'Object';
  }
};


/***/ }),

/***/ 60220:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var uncurryThis = __webpack_require__(41686);

var id = 0;
var postfix = Math.random();
var toString = uncurryThis(1.0.toString);

module.exports = function (key) {
  return 'Symbol(' + (key === undefined ? '' : key) + ')_' + toString(++id + postfix, 36);
};


/***/ }),

/***/ 7238:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

/* eslint-disable es/no-symbol -- required for testing */
var NATIVE_SYMBOL = __webpack_require__(23570);

module.exports = NATIVE_SYMBOL
  && !Symbol.sham
  && typeof Symbol.iterator == 'symbol';


/***/ }),

/***/ 63222:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var DESCRIPTORS = __webpack_require__(99262);
var fails = __webpack_require__(30676);

// V8 ~ Chrome 36-
// https://bugs.chromium.org/p/v8/issues/detail?id=3334
module.exports = DESCRIPTORS && fails(function () {
  // eslint-disable-next-line es/no-object-defineproperty -- required for testing
  return Object.defineProperty(function () { /* empty */ }, 'prototype', {
    value: 42,
    writable: false
  }).prototype !== 42;
});


/***/ }),

/***/ 34011:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var global = __webpack_require__(68647);
var isCallable = __webpack_require__(69949);

var WeakMap = global.WeakMap;

module.exports = isCallable(WeakMap) && /native code/.test(String(WeakMap));


/***/ }),

/***/ 82473:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var path = __webpack_require__(81217);
var hasOwn = __webpack_require__(48314);
var wrappedWellKnownSymbolModule = __webpack_require__(49738);
var defineProperty = (__webpack_require__(45661).f);

module.exports = function (NAME) {
  var Symbol = path.Symbol || (path.Symbol = {});
  if (!hasOwn(Symbol, NAME)) defineProperty(Symbol, NAME, {
    value: wrappedWellKnownSymbolModule.f(NAME)
  });
};


/***/ }),

/***/ 49738:
/***/ ((__unused_webpack_module, exports, __webpack_require__) => {

"use strict";

var wellKnownSymbol = __webpack_require__(21928);

exports.f = wellKnownSymbol;


/***/ }),

/***/ 21928:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var global = __webpack_require__(68647);
var shared = __webpack_require__(56314);
var hasOwn = __webpack_require__(48314);
var uid = __webpack_require__(60220);
var NATIVE_SYMBOL = __webpack_require__(23570);
var USE_SYMBOL_AS_UID = __webpack_require__(7238);

var Symbol = global.Symbol;
var WellKnownSymbolsStore = shared('wks');
var createWellKnownSymbol = USE_SYMBOL_AS_UID ? Symbol['for'] || Symbol : Symbol && Symbol.withoutSetter || uid;

module.exports = function (name) {
  if (!hasOwn(WellKnownSymbolsStore, name)) {
    WellKnownSymbolsStore[name] = NATIVE_SYMBOL && hasOwn(Symbol, name)
      ? Symbol[name]
      : createWellKnownSymbol('Symbol.' + name);
  } return WellKnownSymbolsStore[name];
};


/***/ }),

/***/ 15751:
/***/ ((module) => {

"use strict";

// a string of all valid unicode whitespaces
module.exports = '\u0009\u000A\u000B\u000C\u000D\u0020\u00A0\u1680\u2000\u2001\u2002' +
  '\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF';


/***/ }),

/***/ 98566:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var $ = __webpack_require__(97934);
var fails = __webpack_require__(30676);
var isArray = __webpack_require__(84155);
var isObject = __webpack_require__(63590);
var toObject = __webpack_require__(85857);
var lengthOfArrayLike = __webpack_require__(46935);
var doesNotExceedSafeInteger = __webpack_require__(27890);
var createProperty = __webpack_require__(19109);
var arraySpeciesCreate = __webpack_require__(95405);
var arrayMethodHasSpeciesSupport = __webpack_require__(53741);
var wellKnownSymbol = __webpack_require__(21928);
var V8_VERSION = __webpack_require__(97711);

var IS_CONCAT_SPREADABLE = wellKnownSymbol('isConcatSpreadable');

// We can't use this feature detection in V8 since it causes
// deoptimization and serious performance degradation
// https://github.com/zloirock/core-js/issues/679
var IS_CONCAT_SPREADABLE_SUPPORT = V8_VERSION >= 51 || !fails(function () {
  var array = [];
  array[IS_CONCAT_SPREADABLE] = false;
  return array.concat()[0] !== array;
});

var isConcatSpreadable = function (O) {
  if (!isObject(O)) return false;
  var spreadable = O[IS_CONCAT_SPREADABLE];
  return spreadable !== undefined ? !!spreadable : isArray(O);
};

var FORCED = !IS_CONCAT_SPREADABLE_SUPPORT || !arrayMethodHasSpeciesSupport('concat');

// `Array.prototype.concat` method
// https://tc39.es/ecma262/#sec-array.prototype.concat
// with adding support of @@isConcatSpreadable and @@species
$({ target: 'Array', proto: true, arity: 1, forced: FORCED }, {
  // eslint-disable-next-line no-unused-vars -- required for `.length`
  concat: function concat(arg) {
    var O = toObject(this);
    var A = arraySpeciesCreate(O, 0);
    var n = 0;
    var i, k, length, len, E;
    for (i = -1, length = arguments.length; i < length; i++) {
      E = i === -1 ? O : arguments[i];
      if (isConcatSpreadable(E)) {
        len = lengthOfArrayLike(E);
        doesNotExceedSafeInteger(n + len);
        for (k = 0; k < len; k++, n++) if (k in E) createProperty(A, n, E[k]);
      } else {
        doesNotExceedSafeInteger(n + 1);
        createProperty(A, n++, E);
      }
    }
    A.length = n;
    return A;
  }
});


/***/ }),

/***/ 31471:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var $ = __webpack_require__(97934);
var forEach = __webpack_require__(97959);

// `Array.prototype.forEach` method
// https://tc39.es/ecma262/#sec-array.prototype.foreach
// eslint-disable-next-line es/no-array-prototype-foreach -- safe
$({ target: 'Array', proto: true, forced: [].forEach !== forEach }, {
  forEach: forEach
});


/***/ }),

/***/ 89864:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var $ = __webpack_require__(97934);
var from = __webpack_require__(2277);
var checkCorrectnessOfIteration = __webpack_require__(14376);

var INCORRECT_ITERATION = !checkCorrectnessOfIteration(function (iterable) {
  // eslint-disable-next-line es/no-array-from -- required for testing
  Array.from(iterable);
});

// `Array.from` method
// https://tc39.es/ecma262/#sec-array.from
$({ target: 'Array', stat: true, forced: INCORRECT_ITERATION }, {
  from: from
});


/***/ }),

/***/ 334:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

/* eslint-disable es/no-array-prototype-indexof -- required for testing */
var $ = __webpack_require__(97934);
var uncurryThis = __webpack_require__(69021);
var $indexOf = (__webpack_require__(74895).indexOf);
var arrayMethodIsStrict = __webpack_require__(42786);

var nativeIndexOf = uncurryThis([].indexOf);

var NEGATIVE_ZERO = !!nativeIndexOf && 1 / nativeIndexOf([1], 1, -0) < 0;
var FORCED = NEGATIVE_ZERO || !arrayMethodIsStrict('indexOf');

// `Array.prototype.indexOf` method
// https://tc39.es/ecma262/#sec-array.prototype.indexof
$({ target: 'Array', proto: true, forced: FORCED }, {
  indexOf: function indexOf(searchElement /* , fromIndex = 0 */) {
    var fromIndex = arguments.length > 1 ? arguments[1] : undefined;
    return NEGATIVE_ZERO
      // convert -0 to +0
      ? nativeIndexOf(this, searchElement, fromIndex) || 0
      : $indexOf(this, searchElement, fromIndex);
  }
});


/***/ }),

/***/ 44396:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var $ = __webpack_require__(97934);
var isArray = __webpack_require__(84155);

// `Array.isArray` method
// https://tc39.es/ecma262/#sec-array.isarray
$({ target: 'Array', stat: true }, {
  isArray: isArray
});


/***/ }),

/***/ 55676:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var toIndexedObject = __webpack_require__(10839);
var addToUnscopables = __webpack_require__(23358);
var Iterators = __webpack_require__(69885);
var InternalStateModule = __webpack_require__(36653);
var defineProperty = (__webpack_require__(45661).f);
var defineIterator = __webpack_require__(79117);
var createIterResultObject = __webpack_require__(99106);
var IS_PURE = __webpack_require__(96314);
var DESCRIPTORS = __webpack_require__(99262);

var ARRAY_ITERATOR = 'Array Iterator';
var setInternalState = InternalStateModule.set;
var getInternalState = InternalStateModule.getterFor(ARRAY_ITERATOR);

// `Array.prototype.entries` method
// https://tc39.es/ecma262/#sec-array.prototype.entries
// `Array.prototype.keys` method
// https://tc39.es/ecma262/#sec-array.prototype.keys
// `Array.prototype.values` method
// https://tc39.es/ecma262/#sec-array.prototype.values
// `Array.prototype[@@iterator]` method
// https://tc39.es/ecma262/#sec-array.prototype-@@iterator
// `CreateArrayIterator` internal method
// https://tc39.es/ecma262/#sec-createarrayiterator
module.exports = defineIterator(Array, 'Array', function (iterated, kind) {
  setInternalState(this, {
    type: ARRAY_ITERATOR,
    target: toIndexedObject(iterated), // target
    index: 0,                          // next index
    kind: kind                         // kind
  });
// `%ArrayIteratorPrototype%.next` method
// https://tc39.es/ecma262/#sec-%arrayiteratorprototype%.next
}, function () {
  var state = getInternalState(this);
  var target = state.target;
  var index = state.index++;
  if (!target || index >= target.length) {
    state.target = undefined;
    return createIterResultObject(undefined, true);
  }
  switch (state.kind) {
    case 'keys': return createIterResultObject(index, false);
    case 'values': return createIterResultObject(target[index], false);
  } return createIterResultObject([index, target[index]], false);
}, 'values');

// argumentsList[@@iterator] is %ArrayProto_values%
// https://tc39.es/ecma262/#sec-createunmappedargumentsobject
// https://tc39.es/ecma262/#sec-createmappedargumentsobject
var values = Iterators.Arguments = Iterators.Array;

// https://tc39.es/ecma262/#sec-array.prototype-@@unscopables
addToUnscopables('keys');
addToUnscopables('values');
addToUnscopables('entries');

// V8 ~ Chrome 45- bug
if (!IS_PURE && DESCRIPTORS && values.name !== 'values') try {
  defineProperty(values, 'name', { value: 'values' });
} catch (error) { /* empty */ }


/***/ }),

/***/ 34903:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var $ = __webpack_require__(97934);
var $map = (__webpack_require__(30343).map);
var arrayMethodHasSpeciesSupport = __webpack_require__(53741);

var HAS_SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('map');

// `Array.prototype.map` method
// https://tc39.es/ecma262/#sec-array.prototype.map
// with adding support of @@species
$({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT }, {
  map: function map(callbackfn /* , thisArg */) {
    return $map(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined);
  }
});


/***/ }),

/***/ 13940:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var $ = __webpack_require__(97934);
var toObject = __webpack_require__(85857);
var lengthOfArrayLike = __webpack_require__(46935);
var setArrayLength = __webpack_require__(6138);
var doesNotExceedSafeInteger = __webpack_require__(27890);
var fails = __webpack_require__(30676);

var INCORRECT_TO_LENGTH = fails(function () {
  return [].push.call({ length: 0x100000000 }, 1) !== 4294967297;
});

// V8 <= 121 and Safari <= 15.4; FF < 23 throws InternalError
// https://bugs.chromium.org/p/v8/issues/detail?id=12681
var properErrorOnNonWritableLength = function () {
  try {
    // eslint-disable-next-line es/no-object-defineproperty -- safe
    Object.defineProperty([], 'length', { writable: false }).push();
  } catch (error) {
    return error instanceof TypeError;
  }
};

var FORCED = INCORRECT_TO_LENGTH || !properErrorOnNonWritableLength();

// `Array.prototype.push` method
// https://tc39.es/ecma262/#sec-array.prototype.push
$({ target: 'Array', proto: true, arity: 1, forced: FORCED }, {
  // eslint-disable-next-line no-unused-vars -- required for `.length`
  push: function push(item) {
    var O = toObject(this);
    var len = lengthOfArrayLike(O);
    var argCount = arguments.length;
    doesNotExceedSafeInteger(len + argCount);
    for (var i = 0; i < argCount; i++) {
      O[len] = arguments[i];
      len++;
    }
    setArrayLength(O, len);
    return len;
  }
});


/***/ }),

/***/ 82378:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var $ = __webpack_require__(97934);
var $reduce = (__webpack_require__(17909).left);
var arrayMethodIsStrict = __webpack_require__(42786);
var CHROME_VERSION = __webpack_require__(97711);
var IS_NODE = __webpack_require__(9420);

// Chrome 80-82 has a critical bug
// https://bugs.chromium.org/p/chromium/issues/detail?id=1049982
var CHROME_BUG = !IS_NODE && CHROME_VERSION > 79 && CHROME_VERSION < 83;
var FORCED = CHROME_BUG || !arrayMethodIsStrict('reduce');

// `Array.prototype.reduce` method
// https://tc39.es/ecma262/#sec-array.prototype.reduce
$({ target: 'Array', proto: true, forced: FORCED }, {
  reduce: function reduce(callbackfn /* , initialValue */) {
    var length = arguments.length;
    return $reduce(this, callbackfn, length, length > 1 ? arguments[1] : undefined);
  }
});


/***/ }),

/***/ 79499:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var $ = __webpack_require__(97934);
var isArray = __webpack_require__(84155);
var isConstructor = __webpack_require__(62371);
var isObject = __webpack_require__(63590);
var toAbsoluteIndex = __webpack_require__(13036);
var lengthOfArrayLike = __webpack_require__(46935);
var toIndexedObject = __webpack_require__(10839);
var createProperty = __webpack_require__(19109);
var wellKnownSymbol = __webpack_require__(21928);
var arrayMethodHasSpeciesSupport = __webpack_require__(53741);
var nativeSlice = __webpack_require__(79919);

var HAS_SPECIES_SUPPORT = arrayMethodHasSpeciesSupport('slice');

var SPECIES = wellKnownSymbol('species');
var $Array = Array;
var max = Math.max;

// `Array.prototype.slice` method
// https://tc39.es/ecma262/#sec-array.prototype.slice
// fallback for not array-like ES3 strings and DOM objects
$({ target: 'Array', proto: true, forced: !HAS_SPECIES_SUPPORT }, {
  slice: function slice(start, end) {
    var O = toIndexedObject(this);
    var length = lengthOfArrayLike(O);
    var k = toAbsoluteIndex(start, length);
    var fin = toAbsoluteIndex(end === undefined ? length : end, length);
    // inline `ArraySpeciesCreate` for usage native `Array#slice` where it's possible
    var Constructor, result, n;
    if (isArray(O)) {
      Constructor = O.constructor;
      // cross-realm fallback
      if (isConstructor(Constructor) && (Constructor === $Array || isArray(Constructor.prototype))) {
        Constructor = undefined;
      } else if (isObject(Constructor)) {
        Constructor = Constructor[SPECIES];
        if (Constructor === null) Constructor = undefined;
      }
      if (Constructor === $Array || Constructor === undefined) {
        return nativeSlice(O, k, fin);
      }
    }
    result = new (Constructor === undefined ? $Array : Constructor)(max(fin - k, 0));
    for (n = 0; k < fin; k++, n++) if (k in O) createProperty(result, n, O[k]);
    result.length = n;
    return result;
  }
});


/***/ }),

/***/ 50080:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var $ = __webpack_require__(97934);
var uncurryThis = __webpack_require__(41686);
var aCallable = __webpack_require__(66049);
var toObject = __webpack_require__(85857);
var lengthOfArrayLike = __webpack_require__(46935);
var deletePropertyOrThrow = __webpack_require__(78880);
var toString = __webpack_require__(87365);
var fails = __webpack_require__(30676);
var internalSort = __webpack_require__(21501);
var arrayMethodIsStrict = __webpack_require__(42786);
var FF = __webpack_require__(10087);
var IE_OR_EDGE = __webpack_require__(18151);
var V8 = __webpack_require__(97711);
var WEBKIT = __webpack_require__(15548);

var test = [];
var nativeSort = uncurryThis(test.sort);
var push = uncurryThis(test.push);

// IE8-
var FAILS_ON_UNDEFINED = fails(function () {
  test.sort(undefined);
});
// V8 bug
var FAILS_ON_NULL = fails(function () {
  test.sort(null);
});
// Old WebKit
var STRICT_METHOD = arrayMethodIsStrict('sort');

var STABLE_SORT = !fails(function () {
  // feature detection can be too slow, so check engines versions
  if (V8) return V8 < 70;
  if (FF && FF > 3) return;
  if (IE_OR_EDGE) return true;
  if (WEBKIT) return WEBKIT < 603;

  var result = '';
  var code, chr, value, index;

  // generate an array with more 512 elements (Chakra and old V8 fails only in this case)
  for (code = 65; code < 76; code++) {
    chr = String.fromCharCode(code);

    switch (code) {
      case 66: case 69: case 70: case 72: value = 3; break;
      case 68: case 71: value = 4; break;
      default: value = 2;
    }

    for (index = 0; index < 47; index++) {
      test.push({ k: chr + index, v: value });
    }
  }

  test.sort(function (a, b) { return b.v - a.v; });

  for (index = 0; index < test.length; index++) {
    chr = test[index].k.charAt(0);
    if (result.charAt(result.length - 1) !== chr) result += chr;
  }

  return result !== 'DGBEFHACIJK';
});

var FORCED = FAILS_ON_UNDEFINED || !FAILS_ON_NULL || !STRICT_METHOD || !STABLE_SORT;

var getSortCompare = function (comparefn) {
  return function (x, y) {
    if (y === undefined) return -1;
    if (x === undefined) return 1;
    if (comparefn !== undefined) return +comparefn(x, y) || 0;
    return toString(x) > toString(y) ? 1 : -1;
  };
};

// `Array.prototype.sort` method
// https://tc39.es/ecma262/#sec-array.prototype.sort
$({ target: 'Array', proto: true, forced: FORCED }, {
  sort: function sort(comparefn) {
    if (comparefn !== undefined) aCallable(comparefn);

    var array = toObject(this);

    if (STABLE_SORT) return comparefn === undefined ? nativeSort(array) : nativeSort(array, comparefn);

    var items = [];
    var arrayLength = lengthOfArrayLike(array);
    var itemsLength, index;

    for (index = 0; index < arrayLength; index++) {
      if (index in array) push(items, array[index]);
    }

    internalSort(items, getSortCompare(comparefn));

    itemsLength = lengthOfArrayLike(items);
    index = 0;

    while (index < itemsLength) array[index] = items[index++];
    while (index < arrayLength) deletePropertyOrThrow(array, index++);

    return array;
  }
});


/***/ }),

/***/ 89495:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var $ = __webpack_require__(97934);
var getBuiltIn = __webpack_require__(94228);
var apply = __webpack_require__(54553);
var call = __webpack_require__(70492);
var uncurryThis = __webpack_require__(41686);
var fails = __webpack_require__(30676);
var isCallable = __webpack_require__(69949);
var isSymbol = __webpack_require__(62296);
var arraySlice = __webpack_require__(79919);
var getReplacerFunction = __webpack_require__(52730);
var NATIVE_SYMBOL = __webpack_require__(23570);

var $String = String;
var $stringify = getBuiltIn('JSON', 'stringify');
var exec = uncurryThis(/./.exec);
var charAt = uncurryThis(''.charAt);
var charCodeAt = uncurryThis(''.charCodeAt);
var replace = uncurryThis(''.replace);
var numberToString = uncurryThis(1.0.toString);

var tester = /[\uD800-\uDFFF]/g;
var low = /^[\uD800-\uDBFF]$/;
var hi = /^[\uDC00-\uDFFF]$/;

var WRONG_SYMBOLS_CONVERSION = !NATIVE_SYMBOL || fails(function () {
  var symbol = getBuiltIn('Symbol')('stringify detection');
  // MS Edge converts symbol values to JSON as {}
  return $stringify([symbol]) !== '[null]'
    // WebKit converts symbol values to JSON as null
    || $stringify({ a: symbol }) !== '{}'
    // V8 throws on boxed symbols
    || $stringify(Object(symbol)) !== '{}';
});

// https://github.com/tc39/proposal-well-formed-stringify
var ILL_FORMED_UNICODE = fails(function () {
  return $stringify('\uDF06\uD834') !== '"\\udf06\\ud834"'
    || $stringify('\uDEAD') !== '"\\udead"';
});

var stringifyWithSymbolsFix = function (it, replacer) {
  var args = arraySlice(arguments);
  var $replacer = getReplacerFunction(replacer);
  if (!isCallable($replacer) && (it === undefined || isSymbol(it))) return; // IE8 returns string on undefined
  args[1] = function (key, value) {
    // some old implementations (like WebKit) could pass numbers as keys
    if (isCallable($replacer)) value = call($replacer, this, $String(key), value);
    if (!isSymbol(value)) return value;
  };
  return apply($stringify, null, args);
};

var fixIllFormed = function (match, offset, string) {
  var prev = charAt(string, offset - 1);
  var next = charAt(string, offset + 1);
  if ((exec(low, match) && !exec(hi, next)) || (exec(hi, match) && !exec(low, prev))) {
    return '\\u' + numberToString(charCodeAt(match, 0), 16);
  } return match;
};

if ($stringify) {
  // `JSON.stringify` method
  // https://tc39.es/ecma262/#sec-json.stringify
  $({ target: 'JSON', stat: true, arity: 3, forced: WRONG_SYMBOLS_CONVERSION || ILL_FORMED_UNICODE }, {
    // eslint-disable-next-line no-unused-vars -- required for `.length`
    stringify: function stringify(it, replacer, space) {
      var args = arraySlice(arguments);
      var result = apply(WRONG_SYMBOLS_CONVERSION ? stringifyWithSymbolsFix : $stringify, null, args);
      return ILL_FORMED_UNICODE && typeof result == 'string' ? replace(result, tester, fixIllFormed) : result;
    }
  });
}


/***/ }),

/***/ 61021:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var global = __webpack_require__(68647);
var setToStringTag = __webpack_require__(73279);

// JSON[@@toStringTag] property
// https://tc39.es/ecma262/#sec-json-@@tostringtag
setToStringTag(global.JSON, 'JSON', true);


/***/ }),

/***/ 18871:
/***/ (() => {

// empty


/***/ }),

/***/ 85027:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

// TODO: Remove from `core-js@4`
var $ = __webpack_require__(97934);
var DESCRIPTORS = __webpack_require__(99262);
var create = __webpack_require__(82448);

// `Object.create` method
// https://tc39.es/ecma262/#sec-object.create
$({ target: 'Object', stat: true, sham: !DESCRIPTORS }, {
  create: create
});


/***/ }),

/***/ 57000:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var $ = __webpack_require__(97934);
var DESCRIPTORS = __webpack_require__(99262);
var defineProperty = (__webpack_require__(45661).f);

// `Object.defineProperty` method
// https://tc39.es/ecma262/#sec-object.defineproperty
// eslint-disable-next-line es/no-object-defineproperty -- safe
$({ target: 'Object', stat: true, forced: Object.defineProperty !== defineProperty, sham: !DESCRIPTORS }, {
  defineProperty: defineProperty
});


/***/ }),

/***/ 95110:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var $ = __webpack_require__(97934);
var NATIVE_SYMBOL = __webpack_require__(23570);
var fails = __webpack_require__(30676);
var getOwnPropertySymbolsModule = __webpack_require__(26640);
var toObject = __webpack_require__(85857);

// V8 ~ Chrome 38 and 39 `Object.getOwnPropertySymbols` fails on primitives
// https://bugs.chromium.org/p/v8/issues/detail?id=3443
var FORCED = !NATIVE_SYMBOL || fails(function () { getOwnPropertySymbolsModule.f(1); });

// `Object.getOwnPropertySymbols` method
// https://tc39.es/ecma262/#sec-object.getownpropertysymbols
$({ target: 'Object', stat: true, forced: FORCED }, {
  getOwnPropertySymbols: function getOwnPropertySymbols(it) {
    var $getOwnPropertySymbols = getOwnPropertySymbolsModule.f;
    return $getOwnPropertySymbols ? $getOwnPropertySymbols(toObject(it)) : [];
  }
});


/***/ }),

/***/ 77873:
/***/ (() => {

// empty


/***/ }),

/***/ 33380:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var $ = __webpack_require__(97934);
var $parseInt = __webpack_require__(38167);

// `parseInt` method
// https://tc39.es/ecma262/#sec-parseint-string-radix
$({ global: true, forced: parseInt !== $parseInt }, {
  parseInt: $parseInt
});


/***/ }),

/***/ 97625:
/***/ (() => {

// empty


/***/ }),

/***/ 71887:
/***/ (() => {

// empty


/***/ }),

/***/ 48299:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var charAt = (__webpack_require__(27489).charAt);
var toString = __webpack_require__(87365);
var InternalStateModule = __webpack_require__(36653);
var defineIterator = __webpack_require__(79117);
var createIterResultObject = __webpack_require__(99106);

var STRING_ITERATOR = 'String Iterator';
var setInternalState = InternalStateModule.set;
var getInternalState = InternalStateModule.getterFor(STRING_ITERATOR);

// `String.prototype[@@iterator]` method
// https://tc39.es/ecma262/#sec-string.prototype-@@iterator
defineIterator(String, 'String', function (iterated) {
  setInternalState(this, {
    type: STRING_ITERATOR,
    string: toString(iterated),
    index: 0
  });
// `%StringIteratorPrototype%.next` method
// https://tc39.es/ecma262/#sec-%stringiteratorprototype%.next
}, function next() {
  var state = getInternalState(this);
  var string = state.string;
  var index = state.index;
  var point;
  if (index >= string.length) return createIterResultObject(undefined, true);
  point = charAt(string, index);
  state.index += point.length;
  return createIterResultObject(point, false);
});


/***/ }),

/***/ 7089:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var defineWellKnownSymbol = __webpack_require__(82473);

// `Symbol.asyncIterator` well-known symbol
// https://tc39.es/ecma262/#sec-symbol.asynciterator
defineWellKnownSymbol('asyncIterator');


/***/ }),

/***/ 50209:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var $ = __webpack_require__(97934);
var global = __webpack_require__(68647);
var call = __webpack_require__(70492);
var uncurryThis = __webpack_require__(41686);
var IS_PURE = __webpack_require__(96314);
var DESCRIPTORS = __webpack_require__(99262);
var NATIVE_SYMBOL = __webpack_require__(23570);
var fails = __webpack_require__(30676);
var hasOwn = __webpack_require__(48314);
var isPrototypeOf = __webpack_require__(97022);
var anObject = __webpack_require__(1681);
var toIndexedObject = __webpack_require__(10839);
var toPropertyKey = __webpack_require__(92881);
var $toString = __webpack_require__(87365);
var createPropertyDescriptor = __webpack_require__(16838);
var nativeObjectCreate = __webpack_require__(82448);
var objectKeys = __webpack_require__(57744);
var getOwnPropertyNamesModule = __webpack_require__(62435);
var getOwnPropertyNamesExternal = __webpack_require__(82847);
var getOwnPropertySymbolsModule = __webpack_require__(26640);
var getOwnPropertyDescriptorModule = __webpack_require__(10656);
var definePropertyModule = __webpack_require__(45661);
var definePropertiesModule = __webpack_require__(16514);
var propertyIsEnumerableModule = __webpack_require__(86652);
var defineBuiltIn = __webpack_require__(84406);
var defineBuiltInAccessor = __webpack_require__(14443);
var shared = __webpack_require__(56314);
var sharedKey = __webpack_require__(66660);
var hiddenKeys = __webpack_require__(14983);
var uid = __webpack_require__(60220);
var wellKnownSymbol = __webpack_require__(21928);
var wrappedWellKnownSymbolModule = __webpack_require__(49738);
var defineWellKnownSymbol = __webpack_require__(82473);
var defineSymbolToPrimitive = __webpack_require__(92933);
var setToStringTag = __webpack_require__(73279);
var InternalStateModule = __webpack_require__(36653);
var $forEach = (__webpack_require__(30343).forEach);

var HIDDEN = sharedKey('hidden');
var SYMBOL = 'Symbol';
var PROTOTYPE = 'prototype';

var setInternalState = InternalStateModule.set;
var getInternalState = InternalStateModule.getterFor(SYMBOL);

var ObjectPrototype = Object[PROTOTYPE];
var $Symbol = global.Symbol;
var SymbolPrototype = $Symbol && $Symbol[PROTOTYPE];
var RangeError = global.RangeError;
var TypeError = global.TypeError;
var QObject = global.QObject;
var nativeGetOwnPropertyDescriptor = getOwnPropertyDescriptorModule.f;
var nativeDefineProperty = definePropertyModule.f;
var nativeGetOwnPropertyNames = getOwnPropertyNamesExternal.f;
var nativePropertyIsEnumerable = propertyIsEnumerableModule.f;
var push = uncurryThis([].push);

var AllSymbols = shared('symbols');
var ObjectPrototypeSymbols = shared('op-symbols');
var WellKnownSymbolsStore = shared('wks');

// Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173
var USE_SETTER = !QObject || !QObject[PROTOTYPE] || !QObject[PROTOTYPE].findChild;

// fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687
var fallbackDefineProperty = function (O, P, Attributes) {
  var ObjectPrototypeDescriptor = nativeGetOwnPropertyDescriptor(ObjectPrototype, P);
  if (ObjectPrototypeDescriptor) delete ObjectPrototype[P];
  nativeDefineProperty(O, P, Attributes);
  if (ObjectPrototypeDescriptor && O !== ObjectPrototype) {
    nativeDefineProperty(ObjectPrototype, P, ObjectPrototypeDescriptor);
  }
};

var setSymbolDescriptor = DESCRIPTORS && fails(function () {
  return nativeObjectCreate(nativeDefineProperty({}, 'a', {
    get: function () { return nativeDefineProperty(this, 'a', { value: 7 }).a; }
  })).a !== 7;
}) ? fallbackDefineProperty : nativeDefineProperty;

var wrap = function (tag, description) {
  var symbol = AllSymbols[tag] = nativeObjectCreate(SymbolPrototype);
  setInternalState(symbol, {
    type: SYMBOL,
    tag: tag,
    description: description
  });
  if (!DESCRIPTORS) symbol.description = description;
  return symbol;
};

var $defineProperty = function defineProperty(O, P, Attributes) {
  if (O === ObjectPrototype) $defineProperty(ObjectPrototypeSymbols, P, Attributes);
  anObject(O);
  var key = toPropertyKey(P);
  anObject(Attributes);
  if (hasOwn(AllSymbols, key)) {
    if (!Attributes.enumerable) {
      if (!hasOwn(O, HIDDEN)) nativeDefineProperty(O, HIDDEN, createPropertyDescriptor(1, nativeObjectCreate(null)));
      O[HIDDEN][key] = true;
    } else {
      if (hasOwn(O, HIDDEN) && O[HIDDEN][key]) O[HIDDEN][key] = false;
      Attributes = nativeObjectCreate(Attributes, { enumerable: createPropertyDescriptor(0, false) });
    } return setSymbolDescriptor(O, key, Attributes);
  } return nativeDefineProperty(O, key, Attributes);
};

var $defineProperties = function defineProperties(O, Properties) {
  anObject(O);
  var properties = toIndexedObject(Properties);
  var keys = objectKeys(properties).concat($getOwnPropertySymbols(properties));
  $forEach(keys, function (key) {
    if (!DESCRIPTORS || call($propertyIsEnumerable, properties, key)) $defineProperty(O, key, properties[key]);
  });
  return O;
};

var $create = function create(O, Properties) {
  return Properties === undefined ? nativeObjectCreate(O) : $defineProperties(nativeObjectCreate(O), Properties);
};

var $propertyIsEnumerable = function propertyIsEnumerable(V) {
  var P = toPropertyKey(V);
  var enumerable = call(nativePropertyIsEnumerable, this, P);
  if (this === ObjectPrototype && hasOwn(AllSymbols, P) && !hasOwn(ObjectPrototypeSymbols, P)) return false;
  return enumerable || !hasOwn(this, P) || !hasOwn(AllSymbols, P) || hasOwn(this, HIDDEN) && this[HIDDEN][P]
    ? enumerable : true;
};

var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(O, P) {
  var it = toIndexedObject(O);
  var key = toPropertyKey(P);
  if (it === ObjectPrototype && hasOwn(AllSymbols, key) && !hasOwn(ObjectPrototypeSymbols, key)) return;
  var descriptor = nativeGetOwnPropertyDescriptor(it, key);
  if (descriptor && hasOwn(AllSymbols, key) && !(hasOwn(it, HIDDEN) && it[HIDDEN][key])) {
    descriptor.enumerable = true;
  }
  return descriptor;
};

var $getOwnPropertyNames = function getOwnPropertyNames(O) {
  var names = nativeGetOwnPropertyNames(toIndexedObject(O));
  var result = [];
  $forEach(names, function (key) {
    if (!hasOwn(AllSymbols, key) && !hasOwn(hiddenKeys, key)) push(result, key);
  });
  return result;
};

var $getOwnPropertySymbols = function (O) {
  var IS_OBJECT_PROTOTYPE = O === ObjectPrototype;
  var names = nativeGetOwnPropertyNames(IS_OBJECT_PROTOTYPE ? ObjectPrototypeSymbols : toIndexedObject(O));
  var result = [];
  $forEach(names, function (key) {
    if (hasOwn(AllSymbols, key) && (!IS_OBJECT_PROTOTYPE || hasOwn(ObjectPrototype, key))) {
      push(result, AllSymbols[key]);
    }
  });
  return result;
};

// `Symbol` constructor
// https://tc39.es/ecma262/#sec-symbol-constructor
if (!NATIVE_SYMBOL) {
  $Symbol = function Symbol() {
    if (isPrototypeOf(SymbolPrototype, this)) throw new TypeError('Symbol is not a constructor');
    var description = !arguments.length || arguments[0] === undefined ? undefined : $toString(arguments[0]);
    var tag = uid(description);
    var setter = function (value) {
      var $this = this === undefined ? global : this;
      if ($this === ObjectPrototype) call(setter, ObjectPrototypeSymbols, value);
      if (hasOwn($this, HIDDEN) && hasOwn($this[HIDDEN], tag)) $this[HIDDEN][tag] = false;
      var descriptor = createPropertyDescriptor(1, value);
      try {
        setSymbolDescriptor($this, tag, descriptor);
      } catch (error) {
        if (!(error instanceof RangeError)) throw error;
        fallbackDefineProperty($this, tag, descriptor);
      }
    };
    if (DESCRIPTORS && USE_SETTER) setSymbolDescriptor(ObjectPrototype, tag, { configurable: true, set: setter });
    return wrap(tag, description);
  };

  SymbolPrototype = $Symbol[PROTOTYPE];

  defineBuiltIn(SymbolPrototype, 'toString', function toString() {
    return getInternalState(this).tag;
  });

  defineBuiltIn($Symbol, 'withoutSetter', function (description) {
    return wrap(uid(description), description);
  });

  propertyIsEnumerableModule.f = $propertyIsEnumerable;
  definePropertyModule.f = $defineProperty;
  definePropertiesModule.f = $defineProperties;
  getOwnPropertyDescriptorModule.f = $getOwnPropertyDescriptor;
  getOwnPropertyNamesModule.f = getOwnPropertyNamesExternal.f = $getOwnPropertyNames;
  getOwnPropertySymbolsModule.f = $getOwnPropertySymbols;

  wrappedWellKnownSymbolModule.f = function (name) {
    return wrap(wellKnownSymbol(name), name);
  };

  if (DESCRIPTORS) {
    // https://github.com/tc39/proposal-Symbol-description
    defineBuiltInAccessor(SymbolPrototype, 'description', {
      configurable: true,
      get: function description() {
        return getInternalState(this).description;
      }
    });
    if (!IS_PURE) {
      defineBuiltIn(ObjectPrototype, 'propertyIsEnumerable', $propertyIsEnumerable, { unsafe: true });
    }
  }
}

$({ global: true, constructor: true, wrap: true, forced: !NATIVE_SYMBOL, sham: !NATIVE_SYMBOL }, {
  Symbol: $Symbol
});

$forEach(objectKeys(WellKnownSymbolsStore), function (name) {
  defineWellKnownSymbol(name);
});

$({ target: SYMBOL, stat: true, forced: !NATIVE_SYMBOL }, {
  useSetter: function () { USE_SETTER = true; },
  useSimple: function () { USE_SETTER = false; }
});

$({ target: 'Object', stat: true, forced: !NATIVE_SYMBOL, sham: !DESCRIPTORS }, {
  // `Object.create` method
  // https://tc39.es/ecma262/#sec-object.create
  create: $create,
  // `Object.defineProperty` method
  // https://tc39.es/ecma262/#sec-object.defineproperty
  defineProperty: $defineProperty,
  // `Object.defineProperties` method
  // https://tc39.es/ecma262/#sec-object.defineproperties
  defineProperties: $defineProperties,
  // `Object.getOwnPropertyDescriptor` method
  // https://tc39.es/ecma262/#sec-object.getownpropertydescriptors
  getOwnPropertyDescriptor: $getOwnPropertyDescriptor
});

$({ target: 'Object', stat: true, forced: !NATIVE_SYMBOL }, {
  // `Object.getOwnPropertyNames` method
  // https://tc39.es/ecma262/#sec-object.getownpropertynames
  getOwnPropertyNames: $getOwnPropertyNames
});

// `Symbol.prototype[@@toPrimitive]` method
// https://tc39.es/ecma262/#sec-symbol.prototype-@@toprimitive
defineSymbolToPrimitive();

// `Symbol.prototype[@@toStringTag]` property
// https://tc39.es/ecma262/#sec-symbol.prototype-@@tostringtag
setToStringTag($Symbol, SYMBOL);

hiddenKeys[HIDDEN] = true;


/***/ }),

/***/ 12228:
/***/ (() => {

// empty


/***/ }),

/***/ 98689:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var $ = __webpack_require__(97934);
var getBuiltIn = __webpack_require__(94228);
var hasOwn = __webpack_require__(48314);
var toString = __webpack_require__(87365);
var shared = __webpack_require__(56314);
var NATIVE_SYMBOL_REGISTRY = __webpack_require__(23756);

var StringToSymbolRegistry = shared('string-to-symbol-registry');
var SymbolToStringRegistry = shared('symbol-to-string-registry');

// `Symbol.for` method
// https://tc39.es/ecma262/#sec-symbol.for
$({ target: 'Symbol', stat: true, forced: !NATIVE_SYMBOL_REGISTRY }, {
  'for': function (key) {
    var string = toString(key);
    if (hasOwn(StringToSymbolRegistry, string)) return StringToSymbolRegistry[string];
    var symbol = getBuiltIn('Symbol')(string);
    StringToSymbolRegistry[string] = symbol;
    SymbolToStringRegistry[symbol] = string;
    return symbol;
  }
});


/***/ }),

/***/ 71262:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var defineWellKnownSymbol = __webpack_require__(82473);

// `Symbol.hasInstance` well-known symbol
// https://tc39.es/ecma262/#sec-symbol.hasinstance
defineWellKnownSymbol('hasInstance');


/***/ }),

/***/ 13782:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var defineWellKnownSymbol = __webpack_require__(82473);

// `Symbol.isConcatSpreadable` well-known symbol
// https://tc39.es/ecma262/#sec-symbol.isconcatspreadable
defineWellKnownSymbol('isConcatSpreadable');


/***/ }),

/***/ 81522:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var defineWellKnownSymbol = __webpack_require__(82473);

// `Symbol.iterator` well-known symbol
// https://tc39.es/ecma262/#sec-symbol.iterator
defineWellKnownSymbol('iterator');


/***/ }),

/***/ 45747:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

// TODO: Remove this module from `core-js@4` since it's split to modules listed below
__webpack_require__(50209);
__webpack_require__(98689);
__webpack_require__(9255);
__webpack_require__(89495);
__webpack_require__(95110);


/***/ }),

/***/ 9255:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var $ = __webpack_require__(97934);
var hasOwn = __webpack_require__(48314);
var isSymbol = __webpack_require__(62296);
var tryToString = __webpack_require__(18458);
var shared = __webpack_require__(56314);
var NATIVE_SYMBOL_REGISTRY = __webpack_require__(23756);

var SymbolToStringRegistry = shared('symbol-to-string-registry');

// `Symbol.keyFor` method
// https://tc39.es/ecma262/#sec-symbol.keyfor
$({ target: 'Symbol', stat: true, forced: !NATIVE_SYMBOL_REGISTRY }, {
  keyFor: function keyFor(sym) {
    if (!isSymbol(sym)) throw new TypeError(tryToString(sym) + ' is not a symbol');
    if (hasOwn(SymbolToStringRegistry, sym)) return SymbolToStringRegistry[sym];
  }
});


/***/ }),

/***/ 83909:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var defineWellKnownSymbol = __webpack_require__(82473);

// `Symbol.matchAll` well-known symbol
// https://tc39.es/ecma262/#sec-symbol.matchall
defineWellKnownSymbol('matchAll');


/***/ }),

/***/ 43610:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var defineWellKnownSymbol = __webpack_require__(82473);

// `Symbol.match` well-known symbol
// https://tc39.es/ecma262/#sec-symbol.match
defineWellKnownSymbol('match');


/***/ }),

/***/ 30143:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var defineWellKnownSymbol = __webpack_require__(82473);

// `Symbol.replace` well-known symbol
// https://tc39.es/ecma262/#sec-symbol.replace
defineWellKnownSymbol('replace');


/***/ }),

/***/ 5490:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var defineWellKnownSymbol = __webpack_require__(82473);

// `Symbol.search` well-known symbol
// https://tc39.es/ecma262/#sec-symbol.search
defineWellKnownSymbol('search');


/***/ }),

/***/ 3249:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var defineWellKnownSymbol = __webpack_require__(82473);

// `Symbol.species` well-known symbol
// https://tc39.es/ecma262/#sec-symbol.species
defineWellKnownSymbol('species');


/***/ }),

/***/ 50108:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var defineWellKnownSymbol = __webpack_require__(82473);

// `Symbol.split` well-known symbol
// https://tc39.es/ecma262/#sec-symbol.split
defineWellKnownSymbol('split');


/***/ }),

/***/ 1885:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var defineWellKnownSymbol = __webpack_require__(82473);
var defineSymbolToPrimitive = __webpack_require__(92933);

// `Symbol.toPrimitive` well-known symbol
// https://tc39.es/ecma262/#sec-symbol.toprimitive
defineWellKnownSymbol('toPrimitive');

// `Symbol.prototype[@@toPrimitive]` method
// https://tc39.es/ecma262/#sec-symbol.prototype-@@toprimitive
defineSymbolToPrimitive();


/***/ }),

/***/ 6922:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var getBuiltIn = __webpack_require__(94228);
var defineWellKnownSymbol = __webpack_require__(82473);
var setToStringTag = __webpack_require__(73279);

// `Symbol.toStringTag` well-known symbol
// https://tc39.es/ecma262/#sec-symbol.tostringtag
defineWellKnownSymbol('toStringTag');

// `Symbol.prototype[@@toStringTag]` property
// https://tc39.es/ecma262/#sec-symbol.prototype-@@tostringtag
setToStringTag(getBuiltIn('Symbol'), 'Symbol');


/***/ }),

/***/ 86166:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var defineWellKnownSymbol = __webpack_require__(82473);

// `Symbol.unscopables` well-known symbol
// https://tc39.es/ecma262/#sec-symbol.unscopables
defineWellKnownSymbol('unscopables');


/***/ }),

/***/ 91307:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var wellKnownSymbol = __webpack_require__(21928);
var defineProperty = (__webpack_require__(45661).f);

var METADATA = wellKnownSymbol('metadata');
var FunctionPrototype = Function.prototype;

// Function.prototype[@@metadata]
// https://github.com/tc39/proposal-decorator-metadata
if (FunctionPrototype[METADATA] === undefined) {
  defineProperty(FunctionPrototype, METADATA, {
    value: null
  });
}


/***/ }),

/***/ 48561:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var defineWellKnownSymbol = __webpack_require__(82473);

// `Symbol.asyncDispose` well-known symbol
// https://github.com/tc39/proposal-async-explicit-resource-management
defineWellKnownSymbol('asyncDispose');


/***/ }),

/***/ 21561:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var defineWellKnownSymbol = __webpack_require__(82473);

// `Symbol.customMatcher` well-known symbol
// https://github.com/tc39/proposal-pattern-matching
defineWellKnownSymbol('customMatcher');


/***/ }),

/***/ 16241:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var defineWellKnownSymbol = __webpack_require__(82473);

// `Symbol.dispose` well-known symbol
// https://github.com/tc39/proposal-explicit-resource-management
defineWellKnownSymbol('dispose');


/***/ }),

/***/ 30898:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var $ = __webpack_require__(97934);
var isRegisteredSymbol = __webpack_require__(14136);

// `Symbol.isRegisteredSymbol` method
// https://tc39.es/proposal-symbol-predicates/#sec-symbol-isregisteredsymbol
$({ target: 'Symbol', stat: true }, {
  isRegisteredSymbol: isRegisteredSymbol
});


/***/ }),

/***/ 96183:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var $ = __webpack_require__(97934);
var isRegisteredSymbol = __webpack_require__(14136);

// `Symbol.isRegistered` method
// obsolete version of https://tc39.es/proposal-symbol-predicates/#sec-symbol-isregisteredsymbol
$({ target: 'Symbol', stat: true, name: 'isRegisteredSymbol' }, {
  isRegistered: isRegisteredSymbol
});


/***/ }),

/***/ 88064:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var $ = __webpack_require__(97934);
var isWellKnownSymbol = __webpack_require__(6635);

// `Symbol.isWellKnownSymbol` method
// https://tc39.es/proposal-symbol-predicates/#sec-symbol-iswellknownsymbol
// We should patch it for newly added well-known symbols. If it's not required, this module just will not be injected
$({ target: 'Symbol', stat: true, forced: true }, {
  isWellKnownSymbol: isWellKnownSymbol
});


/***/ }),

/***/ 73813:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var $ = __webpack_require__(97934);
var isWellKnownSymbol = __webpack_require__(6635);

// `Symbol.isWellKnown` method
// obsolete version of https://tc39.es/proposal-symbol-predicates/#sec-symbol-iswellknownsymbol
// We should patch it for newly added well-known symbols. If it's not required, this module just will not be injected
$({ target: 'Symbol', stat: true, name: 'isWellKnownSymbol', forced: true }, {
  isWellKnown: isWellKnownSymbol
});


/***/ }),

/***/ 56649:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var defineWellKnownSymbol = __webpack_require__(82473);

// `Symbol.matcher` well-known symbol
// https://github.com/tc39/proposal-pattern-matching
defineWellKnownSymbol('matcher');


/***/ }),

/***/ 6470:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

// TODO: Remove from `core-js@4`
var defineWellKnownSymbol = __webpack_require__(82473);

// `Symbol.metadataKey` well-known symbol
// https://github.com/tc39/proposal-decorator-metadata
defineWellKnownSymbol('metadataKey');


/***/ }),

/***/ 58579:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var defineWellKnownSymbol = __webpack_require__(82473);

// `Symbol.metadata` well-known symbol
// https://github.com/tc39/proposal-decorators
defineWellKnownSymbol('metadata');


/***/ }),

/***/ 45169:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var defineWellKnownSymbol = __webpack_require__(82473);

// `Symbol.observable` well-known symbol
// https://github.com/tc39/proposal-observable
defineWellKnownSymbol('observable');


/***/ }),

/***/ 73296:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

// TODO: remove from `core-js@4`
var defineWellKnownSymbol = __webpack_require__(82473);

// `Symbol.patternMatch` well-known symbol
// https://github.com/tc39/proposal-pattern-matching
defineWellKnownSymbol('patternMatch');


/***/ }),

/***/ 47674:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

// TODO: remove from `core-js@4`
var defineWellKnownSymbol = __webpack_require__(82473);

defineWellKnownSymbol('replaceAll');


/***/ }),

/***/ 56935:
/***/ (() => {

// empty


/***/ }),

/***/ 58860:
/***/ ((__unused_webpack_module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

__webpack_require__(55676);
var DOMIterables = __webpack_require__(24228);
var global = __webpack_require__(68647);
var setToStringTag = __webpack_require__(73279);
var Iterators = __webpack_require__(69885);

for (var COLLECTION_NAME in DOMIterables) {
  setToStringTag(global[COLLECTION_NAME], COLLECTION_NAME);
  Iterators[COLLECTION_NAME] = Iterators.Array;
}


/***/ }),

/***/ 54394:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var parent = __webpack_require__(65400);

module.exports = parent;


/***/ }),

/***/ 15572:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var parent = __webpack_require__(5885);

module.exports = parent;


/***/ }),

/***/ 42329:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var parent = __webpack_require__(10774);

module.exports = parent;


/***/ }),

/***/ 28322:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var parent = __webpack_require__(83279);
__webpack_require__(58860);

module.exports = parent;


/***/ }),

/***/ 90414:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var parent = __webpack_require__(13372);

module.exports = parent;


/***/ }),

/***/ 40178:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var parent = __webpack_require__(46253);

module.exports = parent;


/***/ }),

/***/ 15066:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var classof = __webpack_require__(30487);
var hasOwn = __webpack_require__(48314);
var isPrototypeOf = __webpack_require__(97022);
var method = __webpack_require__(42329);
__webpack_require__(56935);

var ArrayPrototype = Array.prototype;

var DOMIterables = {
  DOMTokenList: true,
  NodeList: true
};

module.exports = function (it) {
  var own = it.forEach;
  return it === ArrayPrototype || (isPrototypeOf(ArrayPrototype, it) && own === ArrayPrototype.forEach)
    || hasOwn(DOMIterables, classof(it)) ? method : own;
};


/***/ }),

/***/ 1268:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var parent = __webpack_require__(7389);

module.exports = parent;


/***/ }),

/***/ 76870:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var parent = __webpack_require__(28050);

module.exports = parent;


/***/ }),

/***/ 89652:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var parent = __webpack_require__(35417);

module.exports = parent;


/***/ }),

/***/ 45092:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var parent = __webpack_require__(3905);

module.exports = parent;


/***/ }),

/***/ 53545:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var parent = __webpack_require__(56673);

module.exports = parent;


/***/ }),

/***/ 99110:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var parent = __webpack_require__(68592);

module.exports = parent;


/***/ }),

/***/ 80166:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var parent = __webpack_require__(82200);

module.exports = parent;


/***/ }),

/***/ 78879:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var parent = __webpack_require__(60169);

module.exports = parent;


/***/ }),

/***/ 88184:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var parent = __webpack_require__(66174);

module.exports = parent;


/***/ }),

/***/ 90486:
/***/ ((module, __unused_webpack_exports, __webpack_require__) => {

"use strict";

var parent = __webpack_require__(1302);
__webpack_require__(58860);

module.exports = parent;


/***/ }),

/***/ 94287:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";

// EXPORTS
__webpack_require__.d(__webpack_exports__, {
  "wh": () => (/* binding */ ADG_SCRIPTLET_MASK),
  "qJ": () => (/* binding */ AdblockSyntax),
  "Hm": () => (/* binding */ COMMA_DOMAIN_LIST_SEPARATOR),
  "c3": () => (/* binding */ CosmeticRuleParser),
  "T9": () => (/* binding */ CosmeticRuleSeparatorUtils),
  "Az": () => (/* binding */ CosmeticRuleType),
  "Wf": () => (/* binding */ DomainListParser),
  "QM": () => (/* binding */ DomainUtils),
  "tL": () => (/* binding */ InputByteBuffer),
  "bS": () => (/* binding */ NetworkRuleType),
  "Yh": () => (/* binding */ OutputByteBuffer),
  "mC": () => (/* binding */ PIPE_MODIFIER_SEPARATOR),
  "Q_": () => (/* binding */ QuoteType),
  "tC": () => (/* binding */ QuoteUtils),
  "WV": () => (/* binding */ RuleCategory),
  "cR": () => (/* binding */ RuleConverter),
  "sR": () => (/* binding */ RuleParser),
  "Xm": () => (/* binding */ defaultParserOptions)
});

// UNUSED EXPORTS: ADBLOCK_URL_SEPARATOR, ADBLOCK_URL_SEPARATOR_REGEX, ADBLOCK_URL_START, ADBLOCK_URL_START_REGEX, ADBLOCK_WILDCARD, ADBLOCK_WILDCARD_REGEX, AGLINT_COMMAND_PREFIX, AGTREE_VERSION, AdblockSyntaxError, AgentCommentRuleParser, AgentParser, AppListParser, BINARY_SCHEMA_VERSION, BinarySchemaMismatchError, ByteBuffer, CommentMarker, CommentRuleParser, CommentRuleType, ConfigCommentRuleParser, CosmeticRuleSeparator, EXT_CSS_LEGACY_ATTRIBUTES, EXT_CSS_PSEUDO_CLASSES, FORBIDDEN_CSS_FUNCTIONS, FilterListConverter, FilterListParser, GenericPlatform, HINT_MARKER, HintCommentRuleParser, HintParser, HostRuleParser, IF, INCLUDE, KNOWN_METADATA_HEADERS, LogicalExpressionParser, LogicalExpressionUtils, MODIFIERS_SEPARATOR, MODIFIER_ASSIGN_OPERATOR, MetadataCommentRuleParser, MethodListParser, ModifierListParser, ModifierParser, NEGATION_MARKER, NETWORK_RULE_EXCEPTION_MARKER, NETWORK_RULE_SEPARATOR, NetworkRuleParser, NotImplementedError, PREPROCESSOR_MARKER, ParameterListParser, PositionProvider, PreProcessorCommentRuleParser, RawFilterListConverter, RawRuleConverter, RegExpUtils, ResourceType, RuleCategorizer, RuleConversionError, SAFARI_CB_AFFINITY, SPECIAL_REGEX_SYMBOLS, SpecificPlatform, StealthOptionListParser, UBO_SCRIPTLET_MASK, decodeTextPolyfill, encodeIntoPolyfill, getPlatformId, getResourceTypeModifier, getSpecificPlatformName, isGenericPlatform, isValidResourceType, modifierValidator, modifiersCompatibilityTable, parseRawPlatforms, redirectsCompatibilityTable, scriptletsCompatibilityTable

// EXTERNAL MODULE: ./node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/valid.js
var valid = __webpack_require__(57848);
// EXTERNAL MODULE: ./node_modules/.pnpm/semver@7.6.3/node_modules/semver/functions/coerce.js
var coerce = __webpack_require__(81950);
// EXTERNAL MODULE: ./node_modules/.pnpm/json5@2.2.3/node_modules/json5/dist/index.js
var dist = __webpack_require__(23176);
// EXTERNAL MODULE: ./node_modules/.pnpm/sprintf-js@1.1.3/node_modules/sprintf-js/src/sprintf.js
var sprintf = __webpack_require__(92046);
// EXTERNAL MODULE: ./node_modules/.pnpm/@adguard+css-tokenizer@1.1.1/node_modules/@adguard/css-tokenizer/dist/csstokenizer.mjs
var csstokenizer = __webpack_require__(97094);
// EXTERNAL MODULE: ./node_modules/.pnpm/tldts-core@5.7.112/node_modules/tldts-core/dist/es6/index.js + 9 modules
var es6 = __webpack_require__(58782);
;// CONCATENATED MODULE: ./node_modules/.pnpm/tldts@5.7.112/node_modules/tldts/dist/es6/src/data/trie.js
const exceptions = (function () {
    const _0 = { "$": 1, "succ": {} }, _1 = { "$": 0, "succ": { "city": _0 } };
    const exceptions = { "$": 0, "succ": { "ck": { "$": 0, "succ": { "www": _0 } }, "jp": { "$": 0, "succ": { "kawasaki": _1, "kitakyushu": _1, "kobe": _1, "nagoya": _1, "sapporo": _1, "sendai": _1, "yokohama": _1 } } } };
    ;
    return exceptions;
})();
const rules = (function () {
    const _2 = { "$": 1, "succ": {} }, _3 = { "$": 2, "succ": {} }, _4 = { "$": 1, "succ": { "gov": _2, "com": _2, "org": _2, "net": _2, "edu": _2 } }, _5 = { "$": 0, "succ": { "*": _3 } }, _6 = { "$": 1, "succ": { "blogspot": _3 } }, _7 = { "$": 1, "succ": { "gov": _2 } }, _8 = { "$": 0, "succ": { "*": _2 } }, _9 = { "$": 0, "succ": { "cloud": _3 } }, _10 = { "$": 1, "succ": { "co": _3 } }, _11 = { "$": 2, "succ": { "nodes": _3 } }, _12 = { "$": 0, "succ": { "s3": _3 } }, _13 = { "$": 0, "succ": { "direct": _3 } }, _14 = { "$": 2, "succ": { "id": _3 } }, _15 = { "$": 0, "succ": { "vfs": _3, "webview-assets": _3 } }, _16 = { "$": 0, "succ": { "cloud9": _15 } }, _17 = { "$": 0, "succ": { "dualstack": _12, "cloud9": _15 } }, _18 = { "$": 0, "succ": { "dualstack": _12, "s3": _3, "s3-website": _3, "cloud9": _15 } }, _19 = { "$": 0, "succ": { "apps": _3 } }, _20 = { "$": 0, "succ": { "paas": _3 } }, _21 = { "$": 0, "succ": { "app": _3 } }, _22 = { "$": 2, "succ": { "eu": _3 } }, _23 = { "$": 0, "succ": { "site": _3 } }, _24 = { "$": 0, "succ": { "pages": _3 } }, _25 = { "$": 1, "succ": { "com": _2, "edu": _2, "net": _2, "org": _2 } }, _26 = { "$": 0, "succ": { "j": _3 } }, _27 = { "$": 0, "succ": { "jelastic": _3 } }, _28 = { "$": 0, "succ": { "user": _3 } }, _29 = { "$": 1, "succ": { "ybo": _3 } }, _30 = { "$": 0, "succ": { "cust": _3, "reservd": _3 } }, _31 = { "$": 0, "succ": { "cust": _3 } }, _32 = { "$": 1, "succ": { "gov": _2, "edu": _2, "mil": _2, "com": _2, "org": _2, "net": _2 } }, _33 = { "$": 1, "succ": { "edu": _2, "biz": _2, "net": _2, "org": _2, "gov": _2, "info": _2, "com": _2 } }, _34 = { "$": 1, "succ": { "gov": _2, "blogspot": _3 } }, _35 = { "$": 1, "succ": { "framer": _3 } }, _36 = { "$": 1, "succ": { "barsy": _3 } }, _37 = { "$": 0, "succ": { "forgot": _3 } }, _38 = { "$": 1, "succ": { "gs": _2 } }, _39 = { "$": 0, "succ": { "nes": _2 } }, _40 = { "$": 1, "succ": { "k12": _2, "cc": _2, "lib": _2 } }, _41 = { "$": 1, "succ": { "cc": _2, "lib": _2 } };
    const rules = { "$": 0, "succ": { "ac": { "$": 1, "succ": { "com": _2, "edu": _2, "gov": _2, "net": _2, "mil": _2, "org": _2, "drr": _3 } }, "ad": { "$": 1, "succ": { "nom": _2 } }, "ae": { "$": 1, "succ": { "co": _2, "net": _2, "org": _2, "sch": _2, "ac": _2, "gov": _2, "mil": _2, "blogspot": _3 } }, "aero": { "$": 1, "succ": { "accident-investigation": _2, "accident-prevention": _2, "aerobatic": _2, "aeroclub": _2, "aerodrome": _2, "agents": _2, "aircraft": _2, "airline": _2, "airport": _2, "air-surveillance": _2, "airtraffic": _2, "air-traffic-control": _2, "ambulance": _2, "amusement": _2, "association": _2, "author": _2, "ballooning": _2, "broker": _2, "caa": _2, "cargo": _2, "catering": _2, "certification": _2, "championship": _2, "charter": _2, "civilaviation": _2, "club": _2, "conference": _2, "consultant": _2, "consulting": _2, "control": _2, "council": _2, "crew": _2, "design": _2, "dgca": _2, "educator": _2, "emergency": _2, "engine": _2, "engineer": _2, "entertainment": _2, "equipment": _2, "exchange": _2, "express": _2, "federation": _2, "flight": _2, "fuel": _2, "gliding": _2, "government": _2, "groundhandling": _2, "group": _2, "hanggliding": _2, "homebuilt": _2, "insurance": _2, "journal": _2, "journalist": _2, "leasing": _2, "logistics": _2, "magazine": _2, "maintenance": _2, "media": _2, "microlight": _2, "modelling": _2, "navigation": _2, "parachuting": _2, "paragliding": _2, "passenger-association": _2, "pilot": _2, "press": _2, "production": _2, "recreation": _2, "repbody": _2, "res": _2, "research": _2, "rotorcraft": _2, "safety": _2, "scientist": _2, "services": _2, "show": _2, "skydiving": _2, "software": _2, "student": _2, "trader": _2, "trading": _2, "trainer": _2, "union": _2, "workinggroup": _2, "works": _2 } }, "af": _4, "ag": { "$": 1, "succ": { "com": _2, "org": _2, "net": _2, "co": _2, "nom": _2 } }, "ai": { "$": 1, "succ": { "off": _2, "com": _2, "net": _2, "org": _2, "uwu": _3 } }, "al": { "$": 1, "succ": { "com": _2, "edu": _2, "gov": _2, "mil": _2, "net": _2, "org": _2, "blogspot": _3 } }, "am": { "$": 1, "succ": { "co": _2, "com": _2, "commune": _2, "net": _2, "org": _2, "radio": _3, "blogspot": _3, "neko": _3, "nyaa": _3 } }, "ao": { "$": 1, "succ": { "ed": _2, "gv": _2, "og": _2, "co": _2, "pb": _2, "it": _2 } }, "aq": _2, "ar": { "$": 1, "succ": { "bet": _2, "com": _6, "coop": _2, "edu": _2, "gob": _2, "gov": _2, "int": _2, "mil": _2, "musica": _2, "mutual": _2, "net": _2, "org": _2, "senasa": _2, "tur": _2 } }, "arpa": { "$": 1, "succ": { "e164": _2, "in-addr": _2, "ip6": _2, "iris": _2, "uri": _2, "urn": _2 } }, "as": _7, "asia": { "$": 1, "succ": { "cloudns": _3 } }, "at": { "$": 1, "succ": { "ac": { "$": 1, "succ": { "sth": _2 } }, "co": _6, "gv": _2, "or": _2, "funkfeuer": { "$": 0, "succ": { "wien": _3 } }, "futurecms": { "$": 0, "succ": { "*": _3, "ex": _5, "in": _5 } }, "futurehosting": _3, "futuremailing": _3, "ortsinfo": { "$": 0, "succ": { "ex": _5, "kunden": _5 } }, "biz": _3, "info": _3, "123webseite": _3, "priv": _3, "myspreadshop": _3, "12hp": _3, "2ix": _3, "4lima": _3, "lima-city": _3 } }, "au": { "$": 1, "succ": { "com": { "$": 1, "succ": { "blogspot": _3, "cloudlets": { "$": 0, "succ": { "mel": _3 } }, "myspreadshop": _3 } }, "net": _2, "org": _2, "edu": { "$": 1, "succ": { "act": _2, "catholic": _2, "nsw": { "$": 1, "succ": { "schools": _2 } }, "nt": _2, "qld": _2, "sa": _2, "tas": _2, "vic": _2, "wa": _2 } }, "gov": { "$": 1, "succ": { "qld": _2, "sa": _2, "tas": _2, "vic": _2, "wa": _2 } }, "asn": _2, "id": _2, "info": _2, "conf": _2, "oz": _2, "act": _2, "nsw": _2, "nt": _2, "qld": _2, "sa": _2, "tas": _2, "vic": _2, "wa": _2 } }, "aw": { "$": 1, "succ": { "com": _2 } }, "ax": { "$": 1, "succ": { "be": _3, "cat": _3, "es": _3, "eu": _3, "gg": _3, "mc": _3, "us": _3, "xy": _3 } }, "az": { "$": 1, "succ": { "com": _2, "net": _2, "int": _2, "gov": _2, "org": _2, "edu": _2, "info": _2, "pp": _2, "mil": _2, "name": _2, "pro": _2, "biz": _2 } }, "ba": { "$": 1, "succ": { "com": _2, "edu": _2, "gov": _2, "mil": _2, "net": _2, "org": _2, "rs": _3, "blogspot": _3 } }, "bb": { "$": 1, "succ": { "biz": _2, "co": _2, "com": _2, "edu": _2, "gov": _2, "info": _2, "net": _2, "org": _2, "store": _2, "tv": _2 } }, "bd": _8, "be": { "$": 1, "succ": { "ac": _2, "webhosting": _3, "blogspot": _3, "interhostsolutions": _9, "kuleuven": { "$": 0, "succ": { "ezproxy": _3 } }, "123website": _3, "myspreadshop": _3, "transurl": _5 } }, "bf": _7, "bg": { "$": 1, "succ": { "0": _2, "1": _2, "2": _2, "3": _2, "4": _2, "5": _2, "6": _2, "7": _2, "8": _2, "9": _2, "a": _2, "b": _2, "c": _2, "d": _2, "e": _2, "f": _2, "g": _2, "h": _2, "i": _2, "j": _2, "k": _2, "l": _2, "m": _2, "n": _2, "o": _2, "p": _2, "q": _2, "r": _2, "s": _2, "t": _2, "u": _2, "v": _2, "w": _2, "x": _2, "y": _2, "z": _2, "blogspot": _3, "barsy": _3 } }, "bh": _4, "bi": { "$": 1, "succ": { "co": _2, "com": _2, "edu": _2, "or": _2, "org": _2 } }, "biz": { "$": 1, "succ": { "activetrail": _3, "cloudns": _3, "jozi": _3, "dyndns": _3, "for-better": _3, "for-more": _3, "for-some": _3, "for-the": _3, "selfip": _3, "webhop": _3, "orx": _3, "mmafan": _3, "myftp": _3, "no-ip": _3, "dscloud": _3 } }, "bj": { "$": 1, "succ": { "africa": _2, "agro": _2, "architectes": _2, "assur": _2, "avocats": _2, "co": _2, "com": _2, "eco": _2, "econo": _2, "edu": _2, "info": _2, "loisirs": _2, "money": _2, "net": _2, "org": _2, "ote": _2, "resto": _2, "restaurant": _2, "tourism": _2, "univ": _2, "blogspot": _3 } }, "bm": _4, "bn": { "$": 1, "succ": { "com": _2, "edu": _2, "gov": _2, "net": _2, "org": _2, "co": _3 } }, "bo": { "$": 1, "succ": { "com": _2, "edu": _2, "gob": _2, "int": _2, "org": _2, "net": _2, "mil": _2, "tv": _2, "web": _2, "academia": _2, "agro": _2, "arte": _2, "blog": _2, "bolivia": _2, "ciencia": _2, "cooperativa": _2, "democracia": _2, "deporte": _2, "ecologia": _2, "economia": _2, "empresa": _2, "indigena": _2, "industria": _2, "info": _2, "medicina": _2, "movimiento": _2, "musica": _2, "natural": _2, "nombre": _2, "noticias": _2, "patria": _2, "politica": _2, "profesional": _2, "plurinacional": _2, "pueblo": _2, "revista": _2, "salud": _2, "tecnologia": _2, "tksat": _2, "transporte": _2, "wiki": _2 } }, "br": { "$": 1, "succ": { "9guacu": _2, "abc": _2, "adm": _2, "adv": _2, "agr": _2, "aju": _2, "am": _2, "anani": _2, "aparecida": _2, "app": _2, "arq": _2, "art": _2, "ato": _2, "b": _2, "barueri": _2, "belem": _2, "bhz": _2, "bib": _2, "bio": _2, "blog": _2, "bmd": _2, "boavista": _2, "bsb": _2, "campinagrande": _2, "campinas": _2, "caxias": _2, "cim": _2, "cng": _2, "cnt": _2, "com": { "$": 1, "succ": { "blogspot": _3, "virtualcloud": { "$": 0, "succ": { "scale": { "$": 0, "succ": { "users": _3 } } } }, "simplesite": _3 } }, "contagem": _2, "coop": _2, "coz": _2, "cri": _2, "cuiaba": _2, "curitiba": _2, "def": _2, "des": _2, "det": _2, "dev": _2, "ecn": _2, "eco": _2, "edu": _2, "emp": _2, "enf": _2, "eng": _2, "esp": _2, "etc": _2, "eti": _2, "far": _2, "feira": _2, "flog": _2, "floripa": _2, "fm": _2, "fnd": _2, "fortal": _2, "fot": _2, "foz": _2, "fst": _2, "g12": _2, "geo": _2, "ggf": _2, "goiania": _2, "gov": { "$": 1, "succ": { "ac": _2, "al": _2, "am": _2, "ap": _2, "ba": _2, "ce": _2, "df": _2, "es": _2, "go": _2, "ma": _2, "mg": _2, "ms": _2, "mt": _2, "pa": _2, "pb": _2, "pe": _2, "pi": _2, "pr": _2, "rj": _2, "rn": _2, "ro": _2, "rr": _2, "rs": _2, "sc": _2, "se": _2, "sp": _2, "to": _2 } }, "gru": _2, "imb": _2, "ind": _2, "inf": _2, "jab": _2, "jampa": _2, "jdf": _2, "joinville": _2, "jor": _2, "jus": _2, "leg": { "$": 1, "succ": { "ac": _3, "al": _3, "am": _3, "ap": _3, "ba": _3, "ce": _3, "df": _3, "es": _3, "go": _3, "ma": _3, "mg": _3, "ms": _3, "mt": _3, "pa": _3, "pb": _3, "pe": _3, "pi": _3, "pr": _3, "rj": _3, "rn": _3, "ro": _3, "rr": _3, "rs": _3, "sc": _3, "se": _3, "sp": _3, "to": _3 } }, "lel": _2, "log": _2, "londrina": _2, "macapa": _2, "maceio": _2, "manaus": _2, "maringa": _2, "mat": _2, "med": _2, "mil": _2, "morena": _2, "mp": _2, "mus": _2, "natal": _2, "net": _2, "niteroi": _2, "nom": _8, "not": _2, "ntr": _2, "odo": _2, "ong": _2, "org": _2, "osasco": _2, "palmas": _2, "poa": _2, "ppg": _2, "pro": _2, "psc": _2, "psi": _2, "pvh": _2, "qsl": _2, "radio": _2, "rec": _2, "recife": _2, "rep": _2, "ribeirao": _2, "rio": _2, "riobranco": _2, "riopreto": _2, "salvador": _2, "sampa": _2, "santamaria": _2, "santoandre": _2, "saobernardo": _2, "saogonca": _2, "seg": _2, "sjc": _2, "slg": _2, "slz": _2, "sorocaba": _2, "srv": _2, "taxi": _2, "tc": _2, "tec": _2, "teo": _2, "the": _2, "tmp": _2, "trd": _2, "tur": _2, "tv": _2, "udi": _2, "vet": _2, "vix": _2, "vlog": _2, "wiki": _2, "zlg": _2 } }, "bs": { "$": 1, "succ": { "com": _2, "net": _2, "org": _2, "edu": _2, "gov": _2, "we": _3 } }, "bt": _4, "bv": _2, "bw": { "$": 1, "succ": { "co": _2, "org": _2 } }, "by": { "$": 1, "succ": { "gov": _2, "mil": _2, "com": _6, "of": _2, "mycloud": _3, "mediatech": _3 } }, "bz": { "$": 1, "succ": { "com": _2, "net": _2, "org": _2, "edu": _2, "gov": _2, "za": _3, "gsj": _3 } }, "ca": { "$": 1, "succ": { "ab": _2, "bc": _2, "mb": _2, "nb": _2, "nf": _2, "nl": _2, "ns": _2, "nt": _2, "nu": _2, "on": _2, "pe": _2, "qc": _2, "sk": _2, "yk": _2, "gc": _2, "barsy": _3, "awdev": _5, "co": _3, "blogspot": _3, "no-ip": _3, "myspreadshop": _3 } }, "cat": _2, "cc": { "$": 1, "succ": { "cloudns": _3, "ftpaccess": _3, "game-server": _3, "myphotos": _3, "scrapping": _3, "twmail": _3, "csx": _3, "fantasyleague": _3, "spawn": { "$": 0, "succ": { "instances": _3 } } } }, "cd": _7, "cf": _6, "cg": _2, "ch": { "$": 1, "succ": { "square7": _3, "blogspot": _3, "flow": { "$": 0, "succ": { "ae": { "$": 0, "succ": { "alp1": _3 } }, "appengine": _3 } }, "linkyard-cloud": _3, "dnsking": _3, "gotdns": _3, "123website": _3, "myspreadshop": _3, "firenet": { "$": 0, "succ": { "*": _3, "svc": _5 } }, "12hp": _3, "2ix": _3, "4lima": _3, "lima-city": _3 } }, "ci": { "$": 1, "succ": { "org": _2, "or": _2, "com": _2, "co": _2, "edu": _2, "ed": _2, "ac": _2, "net": _2, "go": _2, "asso": _2, "xn--aroport-bya": _2, "aéroport": _2, "int": _2, "presse": _2, "md": _2, "gouv": _2, "fin": _3, "nl": _3 } }, "ck": _8, "cl": { "$": 1, "succ": { "co": _2, "gob": _2, "gov": _2, "mil": _2, "blogspot": _3 } }, "cm": { "$": 1, "succ": { "co": _2, "com": _2, "gov": _2, "net": _2 } }, "cn": { "$": 1, "succ": { "ac": _2, "com": { "$": 1, "succ": { "amazonaws": { "$": 0, "succ": { "compute": _5, "cn-north-1": _12, "eb": { "$": 0, "succ": { "cn-north-1": _3, "cn-northwest-1": _3 } }, "elb": _5 } } } }, "edu": _2, "gov": _2, "net": _2, "org": _2, "mil": _2, "xn--55qx5d": _2, "公司": _2, "xn--io0a7i": _2, "网络": _2, "xn--od0alg": _2, "網絡": _2, "ah": _2, "bj": _2, "cq": _2, "fj": _2, "gd": _2, "gs": _2, "gz": _2, "gx": _2, "ha": _2, "hb": _2, "he": _2, "hi": _2, "hl": _2, "hn": _2, "jl": _2, "js": _2, "jx": _2, "ln": _2, "nm": _2, "nx": _2, "qh": _2, "sc": _2, "sd": _2, "sh": _2, "sn": _2, "sx": _2, "tj": _2, "xj": _2, "xz": _2, "yn": _2, "zj": _2, "hk": _2, "mo": _2, "tw": _2, "canva-apps": _3, "instantcloud": _3, "quickconnect": _13 } }, "co": { "$": 1, "succ": { "arts": _2, "com": _6, "edu": _2, "firm": _2, "gov": _2, "info": _2, "int": _2, "mil": _2, "net": _2, "nom": _2, "org": _2, "rec": _2, "web": _2, "carrd": _3, "crd": _3, "otap": _5, "leadpages": _3, "lpages": _3, "mypi": _3, "n4t": _3, "firewalledreplit": _14, "repl": _14, "supabase": _3 } }, "com": { "$": 1, "succ": { "devcdnaccesso": _5, "adobeaemcloud": { "$": 2, "succ": { "dev": _5 } }, "airkitapps": _3, "airkitapps-au": _3, "aivencloud": _3, "kasserver": _3, "amazonaws": { "$": 0, "succ": { "compute": _5, "compute-1": _5, "us-east-1": { "$": 2, "succ": { "dualstack": _12, "cloud9": _15 } }, "ap-northeast-1": _17, "ap-northeast-2": _18, "ap-south-1": _18, "ap-southeast-1": _17, "ap-southeast-2": _17, "ca-central-1": _18, "eu-central-1": _18, "eu-west-1": _17, "eu-west-2": _18, "eu-west-3": _18, "s3": _3, "s3-ap-northeast-1": _3, "s3-ap-northeast-2": _3, "s3-ap-south-1": _3, "s3-ap-southeast-1": _3, "s3-ap-southeast-2": _3, "s3-ca-central-1": _3, "s3-eu-central-1": _3, "s3-eu-west-1": _3, "s3-eu-west-2": _3, "s3-eu-west-3": _3, "s3-external-1": _3, "s3-fips-us-gov-west-1": _3, "s3-sa-east-1": _3, "s3-us-east-2": _3, "s3-us-gov-west-1": _3, "s3-us-west-1": _3, "s3-us-west-2": _3, "s3-website-ap-northeast-1": _3, "s3-website-ap-southeast-1": _3, "s3-website-ap-southeast-2": _3, "s3-website-eu-west-1": _3, "s3-website-sa-east-1": _3, "s3-website-us-east-1": _3, "s3-website-us-west-1": _3, "s3-website-us-west-2": _3, "sa-east-1": _17, "us-east-2": _18, "af-south-1": _16, "ap-east-1": _16, "ap-northeast-3": _16, "eu-north-1": _16, "eu-south-1": _16, "me-south-1": _16, "us-west-1": _16, "us-west-2": _16, "elb": _5 } }, "elasticbeanstalk": { "$": 2, "succ": { "ap-northeast-1": _3, "ap-northeast-2": _3, "ap-northeast-3": _3, "ap-south-1": _3, "ap-southeast-1": _3, "ap-southeast-2": _3, "ca-central-1": _3, "eu-central-1": _3, "eu-west-1": _3, "eu-west-2": _3, "eu-west-3": _3, "sa-east-1": _3, "us-east-1": _3, "us-east-2": _3, "us-gov-west-1": _3, "us-west-1": _3, "us-west-2": _3 } }, "awsglobalaccelerator": _3, "siiites": _3, "appspacehosted": _3, "appspaceusercontent": _3, "on-aptible": _3, "myasustor": _3, "balena-devices": _3, "betainabox": _3, "boutir": _3, "bplaced": _3, "cafjs": _3, "canva-apps": _3, "br": _3, "cn": _3, "de": _3, "eu": _3, "jpn": _3, "mex": _3, "ru": _3, "sa": _3, "uk": _3, "us": _3, "za": _3, "ar": _3, "hu": _3, "kr": _3, "no": _3, "qc": _3, "uy": _3, "africa": _3, "gr": _3, "co": _3, "jdevcloud": _3, "wpdevcloud": _3, "cloudcontrolled": _3, "cloudcontrolapp": _3, "cf-ipfs": _3, "cloudflare-ipfs": _3, "trycloudflare": _3, "customer-oci": { "$": 0, "succ": { "*": _3, "oci": _5, "ocp": _5, "ocs": _5 } }, "dattolocal": _3, "dattorelay": _3, "dattoweb": _3, "mydatto": _3, "builtwithdark": _3, "datadetect": { "$": 0, "succ": { "demo": _3, "instance": _3 } }, "ddns5": _3, "discordsays": _3, "discordsez": _3, "drayddns": _3, "dreamhosters": _3, "mydrobo": _3, "dyndns-at-home": _3, "dyndns-at-work": _3, "dyndns-blog": _3, "dyndns-free": _3, "dyndns-home": _3, "dyndns-ip": _3, "dyndns-mail": _3, "dyndns-office": _3, "dyndns-pics": _3, "dyndns-remote": _3, "dyndns-server": _3, "dyndns-web": _3, "dyndns-wiki": _3, "dyndns-work": _3, "blogdns": _3, "cechire": _3, "dnsalias": _3, "dnsdojo": _3, "doesntexist": _3, "dontexist": _3, "doomdns": _3, "dyn-o-saur": _3, "dynalias": _3, "est-a-la-maison": _3, "est-a-la-masion": _3, "est-le-patron": _3, "est-mon-blogueur": _3, "from-ak": _3, "from-al": _3, "from-ar": _3, "from-ca": _3, "from-ct": _3, "from-dc": _3, "from-de": _3, "from-fl": _3, "from-ga": _3, "from-hi": _3, "from-ia": _3, "from-id": _3, "from-il": _3, "from-in": _3, "from-ks": _3, "from-ky": _3, "from-ma": _3, "from-md": _3, "from-mi": _3, "from-mn": _3, "from-mo": _3, "from-ms": _3, "from-mt": _3, "from-nc": _3, "from-nd": _3, "from-ne": _3, "from-nh": _3, "from-nj": _3, "from-nm": _3, "from-nv": _3, "from-oh": _3, "from-ok": _3, "from-or": _3, "from-pa": _3, "from-pr": _3, "from-ri": _3, "from-sc": _3, "from-sd": _3, "from-tn": _3, "from-tx": _3, "from-ut": _3, "from-va": _3, "from-vt": _3, "from-wa": _3, "from-wi": _3, "from-wv": _3, "from-wy": _3, "getmyip": _3, "gotdns": _3, "hobby-site": _3, "homelinux": _3, "homeunix": _3, "iamallama": _3, "is-a-anarchist": _3, "is-a-blogger": _3, "is-a-bookkeeper": _3, "is-a-bulls-fan": _3, "is-a-caterer": _3, "is-a-chef": _3, "is-a-conservative": _3, "is-a-cpa": _3, "is-a-cubicle-slave": _3, "is-a-democrat": _3, "is-a-designer": _3, "is-a-doctor": _3, "is-a-financialadvisor": _3, "is-a-geek": _3, "is-a-green": _3, "is-a-guru": _3, "is-a-hard-worker": _3, "is-a-hunter": _3, "is-a-landscaper": _3, "is-a-lawyer": _3, "is-a-liberal": _3, "is-a-libertarian": _3, "is-a-llama": _3, "is-a-musician": _3, "is-a-nascarfan": _3, "is-a-nurse": _3, "is-a-painter": _3, "is-a-personaltrainer": _3, "is-a-photographer": _3, "is-a-player": _3, "is-a-republican": _3, "is-a-rockstar": _3, "is-a-socialist": _3, "is-a-student": _3, "is-a-teacher": _3, "is-a-techie": _3, "is-a-therapist": _3, "is-an-accountant": _3, "is-an-actor": _3, "is-an-actress": _3, "is-an-anarchist": _3, "is-an-artist": _3, "is-an-engineer": _3, "is-an-entertainer": _3, "is-certified": _3, "is-gone": _3, "is-into-anime": _3, "is-into-cars": _3, "is-into-cartoons": _3, "is-into-games": _3, "is-leet": _3, "is-not-certified": _3, "is-slick": _3, "is-uberleet": _3, "is-with-theband": _3, "isa-geek": _3, "isa-hockeynut": _3, "issmarterthanyou": _3, "likes-pie": _3, "likescandy": _3, "neat-url": _3, "saves-the-whales": _3, "selfip": _3, "sells-for-less": _3, "sells-for-u": _3, "servebbs": _3, "simple-url": _3, "space-to-rent": _3, "teaches-yoga": _3, "writesthisblog": _3, "digitaloceanspaces": _5, "ddnsfree": _3, "ddnsgeek": _3, "giize": _3, "gleeze": _3, "kozow": _3, "loseyourip": _3, "ooguy": _3, "theworkpc": _3, "mytuleap": _3, "tuleap-partners": _3, "encoreapi": _3, "evennode": { "$": 0, "succ": { "eu-1": _3, "eu-2": _3, "eu-3": _3, "eu-4": _3, "us-1": _3, "us-2": _3, "us-3": _3, "us-4": _3 } }, "onfabrica": _3, "fbsbx": _19, "fastly-edge": _3, "fastly-terrarium": _3, "fastvps-server": _3, "mydobiss": _3, "firebaseapp": _3, "fldrv": _3, "forgeblocks": _3, "framercanvas": _3, "freebox-os": _3, "freeboxos": _3, "freemyip": _3, "gentapps": _3, "gentlentapis": _3, "githubusercontent": _3, "0emm": _5, "appspot": { "$": 2, "succ": { "r": _5 } }, "codespot": _3, "googleapis": _3, "googlecode": _3, "pagespeedmobilizer": _3, "publishproxy": _3, "withgoogle": _3, "withyoutube": _3, "blogspot": _3, "awsmppl": _3, "herokuapp": _3, "herokussl": _3, "impertrixcdn": _3, "impertrix": _3, "smushcdn": _3, "wphostedmail": _3, "wpmucdn": _3, "pixolino": _3, "amscompute": _3, "clicketcloud": _3, "dopaas": _3, "hidora": _3, "hosted-by-previder": _20, "hosteur": { "$": 0, "succ": { "rag-cloud": _3, "rag-cloud-ch": _3 } }, "ik-server": { "$": 0, "succ": { "jcloud": _3, "jcloud-ver-jpc": _3 } }, "jelastic": { "$": 0, "succ": { "demo": _3 } }, "kilatiron": _3, "massivegrid": _20, "wafaicloud": { "$": 0, "succ": { "jed": _3, "lon": _3, "ryd": _3 } }, "joyent": { "$": 0, "succ": { "cns": _5 } }, "ktistory": _3, "lpusercontent": _3, "lmpm": _21, "linode": { "$": 0, "succ": { "members": _3, "nodebalancer": _5 } }, "linodeobjects": _5, "linodeusercontent": { "$": 0, "succ": { "ip": _3 } }, "barsycenter": _3, "barsyonline": _3, "mazeplay": _3, "miniserver": _3, "meteorapp": _22, "hostedpi": _3, "mythic-beasts": { "$": 0, "succ": { "customer": _3, "caracal": _3, "fentiger": _3, "lynx": _3, "ocelot": _3, "oncilla": _3, "onza": _3, "sphinx": _3, "vs": _3, "x": _3, "yali": _3 } }, "nospamproxy": _9, "4u": _3, "nfshost": _3, "001www": _3, "ddnslive": _3, "myiphost": _3, "blogsyte": _3, "ciscofreak": _3, "damnserver": _3, "ditchyourip": _3, "dnsiskinky": _3, "dynns": _3, "geekgalaxy": _3, "health-carereform": _3, "homesecuritymac": _3, "homesecuritypc": _3, "myactivedirectory": _3, "mysecuritycamera": _3, "net-freaks": _3, "onthewifi": _3, "point2this": _3, "quicksytes": _3, "securitytactics": _3, "serveexchange": _3, "servehumour": _3, "servep2p": _3, "servesarcasm": _3, "stufftoread": _3, "unusualperson": _3, "workisboring": _3, "3utilities": _3, "ddnsking": _3, "myvnc": _3, "servebeer": _3, "servecounterstrike": _3, "serveftp": _3, "servegame": _3, "servehalflife": _3, "servehttp": _3, "serveirc": _3, "servemp3": _3, "servepics": _3, "servequake": _3, "observableusercontent": { "$": 0, "succ": { "static": _3 } }, "simplesite": _3, "orsites": _3, "operaunite": _3, "authgear-staging": _3, "authgearapps": _3, "skygearapp": _3, "outsystemscloud": _3, "ownprovider": _3, "pgfog": _3, "pagefrontapp": _3, "pagexl": _3, "paywhirl": _5, "gotpantheon": _3, "platter-app": _3, "pleskns": _3, "postman-echo": _3, "prgmr": { "$": 0, "succ": { "xen": _3 } }, "pythonanywhere": _22, "qualifioapp": _3, "qbuser": _3, "qa2": _3, "dev-myqnapcloud": _3, "alpha-myqnapcloud": _3, "myqnapcloud": _3, "quipelements": _5, "rackmaze": _3, "rhcloud": _3, "render": _21, "onrender": _3, "180r": _3, "dojin": _3, "sakuratan": _3, "sakuraweb": _3, "x0": _3, "code": { "$": 0, "succ": { "builder": _5, "dev-builder": _5, "stg-builder": _5 } }, "logoip": _3, "scrysec": _3, "firewall-gateway": _3, "myshopblocks": _3, "myshopify": _3, "shopitsite": _3, "1kapp": _3, "appchizi": _3, "applinzi": _3, "sinaapp": _3, "vipsinaapp": _3, "bounty-full": { "$": 2, "succ": { "alpha": _3, "beta": _3 } }, "streamlitapp": _3, "try-snowplow": _3, "stackhero-network": _3, "playstation-cloud": _3, "myspreadshop": _3, "stdlib": { "$": 0, "succ": { "api": _3 } }, "temp-dns": _3, "dsmynas": _3, "familyds": _3, "mytabit": _3, "tb-hosting": _23, "reservd": _3, "thingdustdata": _3, "bloxcms": _3, "townnews-staging": _3, "typeform": { "$": 0, "succ": { "pro": _3 } }, "hk": _3, "it": _3, "vultrobjects": _5, "wafflecell": _3, "reserve-online": _3, "hotelwithflight": _3, "remotewd": _3, "wiardweb": _24, "messwithdns": _3, "woltlab-demo": _3, "wpenginepowered": { "$": 2, "succ": { "js": _3 } }, "wixsite": _3, "xnbay": { "$": 2, "succ": { "u2": _3, "u2-local": _3 } }, "yolasite": _3 } }, "coop": _2, "cr": { "$": 1, "succ": { "ac": _2, "co": _2, "ed": _2, "fi": _2, "go": _2, "or": _2, "sa": _2 } }, "cu": { "$": 1, "succ": { "com": _2, "edu": _2, "org": _2, "net": _2, "gov": _2, "inf": _2 } }, "cv": { "$": 1, "succ": { "com": _2, "edu": _2, "int": _2, "nome": _2, "org": _2, "blogspot": _3 } }, "cw": _25, "cx": { "$": 1, "succ": { "gov": _2, "ath": _3, "info": _3 } }, "cy": { "$": 1, "succ": { "ac": _2, "biz": _2, "com": { "$": 1, "succ": { "blogspot": _3, "scaleforce": _26 } }, "ekloges": _2, "gov": _2, "ltd": _2, "mil": _2, "net": _2, "org": _2, "press": _2, "pro": _2, "tm": _2 } }, "cz": { "$": 1, "succ": { "co": _3, "realm": _3, "e4": _3, "blogspot": _3, "metacentrum": { "$": 0, "succ": { "cloud": _5, "custom": _3 } }, "muni": { "$": 0, "succ": { "cloud": { "$": 0, "succ": { "flt": _3, "usr": _3 } } } } } }, "de": { "$": 1, "succ": { "bplaced": _3, "square7": _3, "com": _3, "cosidns": { "$": 0, "succ": { "dyn": _3 } }, "dynamisches-dns": _3, "dnsupdater": _3, "internet-dns": _3, "l-o-g-i-n": _3, "dnshome": _3, "fuettertdasnetz": _3, "isteingeek": _3, "istmein": _3, "lebtimnetz": _3, "leitungsen": _3, "traeumtgerade": _3, "ddnss": { "$": 2, "succ": { "dyn": _3, "dyndns": _3 } }, "dyndns1": _3, "dyn-ip24": _3, "home-webserver": { "$": 2, "succ": { "dyn": _3 } }, "myhome-server": _3, "frusky": _5, "goip": _3, "blogspot": _3, "xn--gnstigbestellen-zvb": _3, "günstigbestellen": _3, "xn--gnstigliefern-wob": _3, "günstigliefern": _3, "hs-heilbronn": { "$": 0, "succ": { "it": _24 } }, "dyn-berlin": _3, "in-berlin": _3, "in-brb": _3, "in-butter": _3, "in-dsl": _3, "in-vpn": _3, "iservschule": _3, "mein-iserv": _3, "schulplattform": _3, "schulserver": _3, "test-iserv": _3, "keymachine": _3, "git-repos": _3, "lcube-server": _3, "svn-repos": _3, "barsy": _3, "123webseite": _3, "logoip": _3, "firewall-gateway": _3, "my-gateway": _3, "my-router": _3, "spdns": _3, "speedpartner": { "$": 0, "succ": { "customer": _3 } }, "myspreadshop": _3, "taifun-dns": _3, "12hp": _3, "2ix": _3, "4lima": _3, "lima-city": _3, "dd-dns": _3, "dray-dns": _3, "draydns": _3, "dyn-vpn": _3, "dynvpn": _3, "mein-vigor": _3, "my-vigor": _3, "my-wan": _3, "syno-ds": _3, "synology-diskstation": _3, "synology-ds": _3, "uberspace": _5, "virtualuser": _3, "virtual-user": _3, "community-pro": _3, "diskussionsbereich": _3 } }, "dj": _2, "dk": { "$": 1, "succ": { "biz": _3, "co": _3, "firm": _3, "reg": _3, "store": _3, "blogspot": _3, "123hjemmeside": _3, "myspreadshop": _3 } }, "dm": _4, "do": { "$": 1, "succ": { "art": _2, "com": _2, "edu": _2, "gob": _2, "gov": _2, "mil": _2, "net": _2, "org": _2, "sld": _2, "web": _2 } }, "dz": { "$": 1, "succ": { "art": _2, "asso": _2, "com": _2, "edu": _2, "gov": _2, "org": _2, "net": _2, "pol": _2, "soc": _2, "tm": _2 } }, "ec": { "$": 1, "succ": { "com": _2, "info": _2, "net": _2, "fin": _2, "k12": _2, "med": _2, "pro": _2, "org": _2, "edu": _2, "gov": _2, "gob": _2, "mil": _2, "base": _3, "official": _3 } }, "edu": { "$": 1, "succ": { "rit": { "$": 0, "succ": { "git-pages": _3 } } } }, "ee": { "$": 1, "succ": { "edu": _2, "gov": _2, "riik": _2, "lib": _2, "med": _2, "com": _6, "pri": _2, "aip": _2, "org": _2, "fie": _2 } }, "eg": { "$": 1, "succ": { "com": _6, "edu": _2, "eun": _2, "gov": _2, "mil": _2, "name": _2, "net": _2, "org": _2, "sci": _2 } }, "er": _8, "es": { "$": 1, "succ": { "com": _6, "nom": _2, "org": _2, "gob": _2, "edu": _2, "123miweb": _3, "myspreadshop": _3 } }, "et": { "$": 1, "succ": { "com": _2, "gov": _2, "org": _2, "edu": _2, "biz": _2, "name": _2, "info": _2, "net": _2 } }, "eu": { "$": 1, "succ": { "airkitapps": _3, "mycd": _3, "cloudns": _3, "dogado": _27, "barsy": _3, "wellbeingzone": _3, "spdns": _3, "transurl": _5, "diskstation": _3 } }, "fi": { "$": 1, "succ": { "aland": _2, "dy": _3, "blogspot": _3, "xn--hkkinen-5wa": _3, "häkkinen": _3, "iki": _3, "cloudplatform": { "$": 0, "succ": { "fi": _3 } }, "datacenter": { "$": 0, "succ": { "demo": _3, "paas": _3 } }, "kapsi": _3, "123kotisivu": _3, "myspreadshop": _3 } }, "fj": { "$": 1, "succ": { "ac": _2, "biz": _2, "com": _2, "gov": _2, "info": _2, "mil": _2, "name": _2, "net": _2, "org": _2, "pro": _2 } }, "fk": _8, "fm": { "$": 1, "succ": { "com": _2, "edu": _2, "net": _2, "org": _2, "radio": _3, "user": _5 } }, "fo": _2, "fr": { "$": 1, "succ": { "asso": _2, "com": _2, "gouv": _2, "nom": _2, "prd": _2, "tm": _2, "aeroport": _2, "avocat": _2, "avoues": _2, "cci": _2, "chambagri": _2, "chirurgiens-dentistes": _2, "experts-comptables": _2, "geometre-expert": _2, "greta": _2, "huissier-justice": _2, "medecin": _2, "notaires": _2, "pharmacien": _2, "port": _2, "veterinaire": _2, "en-root": _3, "fbx-os": _3, "fbxos": _3, "freebox-os": _3, "freeboxos": _3, "blogspot": _3, "goupile": _3, "123siteweb": _3, "on-web": _3, "chirurgiens-dentistes-en-france": _3, "dedibox": _3, "myspreadshop": _3, "ynh": _3 } }, "ga": _2, "gb": _2, "gd": { "$": 1, "succ": { "edu": _2, "gov": _2 } }, "ge": { "$": 1, "succ": { "com": _2, "edu": _2, "gov": _2, "org": _2, "mil": _2, "net": _2, "pvt": _2 } }, "gf": _2, "gg": { "$": 1, "succ": { "co": _2, "net": _2, "org": _2, "kaas": _3, "cya": _3, "panel": { "$": 2, "succ": { "daemon": _3 } } } }, "gh": { "$": 1, "succ": { "com": _2, "edu": _2, "gov": _2, "org": _2, "mil": _2 } }, "gi": { "$": 1, "succ": { "com": _2, "ltd": _2, "gov": _2, "mod": _2, "edu": _2, "org": _2 } }, "gl": { "$": 1, "succ": { "co": _2, "com": _2, "edu": _2, "net": _2, "org": _2, "biz": _3, "xx": _3 } }, "gm": _2, "gn": { "$": 1, "succ": { "ac": _2, "com": _2, "edu": _2, "gov": _2, "org": _2, "net": _2 } }, "gov": _2, "gp": { "$": 1, "succ": { "com": _2, "net": _2, "mobi": _2, "edu": _2, "org": _2, "asso": _2, "app": _3 } }, "gq": _2, "gr": { "$": 1, "succ": { "com": _2, "edu": _2, "net": _2, "org": _2, "gov": _2, "blogspot": _3, "simplesite": _3 } }, "gs": _2, "gt": { "$": 1, "succ": { "com": _2, "edu": _2, "gob": _2, "ind": _2, "mil": _2, "net": _2, "org": _2, "blog": _3, "de": _3, "to": _3 } }, "gu": { "$": 1, "succ": { "com": _2, "edu": _2, "gov": _2, "guam": _2, "info": _2, "net": _2, "org": _2, "web": _2 } }, "gw": _2, "gy": { "$": 1, "succ": { "co": _2, "com": _2, "edu": _2, "gov": _2, "net": _2, "org": _2, "be": _3 } }, "hk": { "$": 1, "succ": { "com": _2, "edu": _2, "gov": _2, "idv": _2, "net": _2, "org": _2, "xn--55qx5d": _2, "公司": _2, "xn--wcvs22d": _2, "教育": _2, "xn--lcvr32d": _2, "敎育": _2, "xn--mxtq1m": _2, "政府": _2, "xn--gmqw5a": _2, "個人": _2, "xn--ciqpn": _2, "个人": _2, "xn--gmq050i": _2, "箇人": _2, "xn--zf0avx": _2, "網络": _2, "xn--io0a7i": _2, "网络": _2, "xn--mk0axi": _2, "组織": _2, "xn--od0alg": _2, "網絡": _2, "xn--od0aq3b": _2, "网絡": _2, "xn--tn0ag": _2, "组织": _2, "xn--uc0atv": _2, "組織": _2, "xn--uc0ay4a": _2, "組织": _2, "blogspot": _3, "secaas": _3, "ltd": _3, "inc": _3 } }, "hm": _2, "hn": { "$": 1, "succ": { "com": _2, "edu": _2, "org": _2, "net": _2, "mil": _2, "gob": _2, "cc": _3 } }, "hr": { "$": 1, "succ": { "iz": _2, "from": _2, "name": _2, "com": _2, "blogspot": _3, "free": _3 } }, "ht": { "$": 1, "succ": { "com": _2, "shop": _2, "firm": _2, "info": _2, "adult": _2, "net": _2, "pro": _2, "org": _2, "med": _2, "art": _2, "coop": _2, "pol": _2, "asso": _2, "edu": _2, "rel": _2, "gouv": _2, "perso": _2 } }, "hu": { "$": 1, "succ": { "2000": _2, "co": _2, "info": _2, "org": _2, "priv": _2, "sport": _2, "tm": _2, "agrar": _2, "bolt": _2, "casino": _2, "city": _2, "erotica": _2, "erotika": _2, "film": _2, "forum": _2, "games": _2, "hotel": _2, "ingatlan": _2, "jogasz": _2, "konyvelo": _2, "lakas": _2, "media": _2, "news": _2, "reklam": _2, "sex": _2, "shop": _2, "suli": _2, "szex": _2, "tozsde": _2, "utazas": _2, "video": _2, "blogspot": _3 } }, "id": { "$": 1, "succ": { "ac": _2, "biz": _2, "co": _6, "desa": _2, "go": _2, "mil": _2, "my": { "$": 1, "succ": { "rss": _5 } }, "net": _2, "or": _2, "ponpes": _2, "sch": _2, "web": _2, "flap": _3, "forte": _3 } }, "ie": { "$": 1, "succ": { "gov": _2, "blogspot": _3, "myspreadshop": _3 } }, "il": { "$": 1, "succ": { "ac": _2, "co": { "$": 1, "succ": { "ravpage": _3, "blogspot": _3, "tabitorder": _3, "mytabit": _3 } }, "gov": _2, "idf": _2, "k12": _2, "muni": _2, "net": _2, "org": _2 } }, "xn--4dbrk0ce": { "$": 1, "succ": { "xn--4dbgdty6c": _2, "xn--5dbhl8d": _2, "xn--8dbq2a": _2, "xn--hebda8b": _2 } }, "ישראל": { "$": 1, "succ": { "אקדמיה": _2, "ישוב": _2, "צהל": _2, "ממשל": _2 } }, "im": { "$": 1, "succ": { "ac": _2, "co": { "$": 1, "succ": { "ltd": _2, "plc": _2 } }, "com": _2, "net": _2, "org": _2, "tt": _2, "tv": _2, "ro": _3 } }, "in": { "$": 1, "succ": { "5g": _2, "6g": _2, "ac": _2, "ai": _2, "am": _2, "bihar": _2, "biz": _2, "business": _2, "ca": _2, "cn": _2, "co": _2, "com": _2, "coop": _2, "cs": _2, "delhi": _2, "dr": _2, "edu": _2, "er": _2, "firm": _2, "gen": _2, "gov": _2, "gujarat": _2, "ind": _2, "info": _2, "int": _2, "internet": _2, "io": _2, "me": _2, "mil": _2, "net": _2, "nic": _2, "org": _2, "pg": _2, "post": _2, "pro": _2, "res": _2, "travel": _2, "tv": _2, "uk": _2, "up": _2, "us": _2, "web": _3, "cloudns": _3, "blogspot": _3, "barsy": _3, "supabase": _3 } }, "info": { "$": 1, "succ": { "cloudns": _3, "dynamic-dns": _3, "dyndns": _3, "barrel-of-knowledge": _3, "barrell-of-knowledge": _3, "for-our": _3, "groks-the": _3, "groks-this": _3, "here-for-more": _3, "knowsitall": _3, "selfip": _3, "webhop": _3, "barsy": _3, "mayfirst": _3, "forumz": _3, "nsupdate": _3, "dvrcam": _3, "ilovecollege": _3, "no-ip": _3, "dnsupdate": _3, "v-info": _3 } }, "int": { "$": 1, "succ": { "eu": _2 } }, "io": { "$": 1, "succ": { "2038": _3, "com": _2, "on-acorn": _5, "apigee": _3, "b-data": _3, "backplaneapp": _3, "banzaicloud": { "$": 0, "succ": { "app": _3, "backyards": _5 } }, "beagleboard": _3, "bitbucket": _3, "bluebite": _3, "boxfuse": _3, "browsersafetymark": _3, "bigv": { "$": 0, "succ": { "uk0": _3 } }, "cleverapps": _3, "dappnode": { "$": 0, "succ": { "dyndns": _3 } }, "dedyn": _3, "drud": _3, "definima": _3, "fh-muenster": _3, "shw": _3, "forgerock": { "$": 0, "succ": { "id": _3 } }, "ghost": _3, "github": _3, "gitlab": _3, "lolipop": _3, "hasura-app": _3, "hostyhosting": _3, "moonscale": _5, "beebyte": _20, "beebyteapp": { "$": 0, "succ": { "sekd1": _3 } }, "jele": _3, "unispace": { "$": 0, "succ": { "cloud-fr1": _3 } }, "webthings": _3, "loginline": _3, "barsy": _3, "azurecontainer": _5, "ngrok": { "$": 2, "succ": { "ap": _3, "au": _3, "eu": _3, "in": _3, "jp": _3, "sa": _3, "us": _3 } }, "nodeart": { "$": 0, "succ": { "stage": _3 } }, "nid": _3, "pantheonsite": _3, "dyn53": _3, "pstmn": { "$": 2, "succ": { "mock": _3 } }, "protonet": _3, "qoto": _3, "qcx": { "$": 2, "succ": { "sys": _5 } }, "vaporcloud": _3, "vbrplsbx": { "$": 0, "succ": { "g": _3 } }, "on-k3s": _5, "on-rio": _5, "readthedocs": _3, "resindevice": _3, "resinstaging": { "$": 0, "succ": { "devices": _3 } }, "hzc": _3, "sandcats": _3, "shiftcrypto": _3, "shiftedit": _3, "mo-siemens": _3, "musician": _3, "lair": _19, "stolos": _5, "spacekit": _3, "utwente": _3, "s5y": _5, "edugit": _3, "telebit": _3, "thingdust": { "$": 0, "succ": { "dev": _30, "disrec": _30, "prod": _31, "testing": _30 } }, "tickets": _3, "upli": _3, "wedeploy": _3, "editorx": _3, "basicserver": _3, "virtualserver": _3 } }, "iq": _32, "ir": { "$": 1, "succ": { "ac": _2, "co": _2, "gov": _2, "id": _2, "net": _2, "org": _2, "sch": _2, "xn--mgba3a4f16a": _2, "ایران": _2, "xn--mgba3a4fra": _2, "ايران": _2 } }, "is": { "$": 1, "succ": { "net": _2, "com": _2, "edu": _2, "gov": _2, "org": _2, "int": _2, "cupcake": _3, "blogspot": _3 } }, "it": { "$": 1, "succ": { "gov": _2, "edu": _2, "abr": _2, "abruzzo": _2, "aosta-valley": _2, "aostavalley": _2, "bas": _2, "basilicata": _2, "cal": _2, "calabria": _2, "cam": _2, "campania": _2, "emilia-romagna": _2, "emiliaromagna": _2, "emr": _2, "friuli-v-giulia": _2, "friuli-ve-giulia": _2, "friuli-vegiulia": _2, "friuli-venezia-giulia": _2, "friuli-veneziagiulia": _2, "friuli-vgiulia": _2, "friuliv-giulia": _2, "friulive-giulia": _2, "friulivegiulia": _2, "friulivenezia-giulia": _2, "friuliveneziagiulia": _2, "friulivgiulia": _2, "fvg": _2, "laz": _2, "lazio": _2, "lig": _2, "liguria": _2, "lom": _2, "lombardia": _2, "lombardy": _2, "lucania": _2, "mar": _2, "marche": _2, "mol": _2, "molise": _2, "piedmont": _2, "piemonte": _2, "pmn": _2, "pug": _2, "puglia": _2, "sar": _2, "sardegna": _2, "sardinia": _2, "sic": _2, "sicilia": _2, "sicily": _2, "taa": _2, "tos": _2, "toscana": _2, "trentin-sud-tirol": _2, "xn--trentin-sd-tirol-rzb": _2, "trentin-süd-tirol": _2, "trentin-sudtirol": _2, "xn--trentin-sdtirol-7vb": _2, "trentin-südtirol": _2, "trentin-sued-tirol": _2, "trentin-suedtirol": _2, "trentino-a-adige": _2, "trentino-aadige": _2, "trentino-alto-adige": _2, "trentino-altoadige": _2, "trentino-s-tirol": _2, "trentino-stirol": _2, "trentino-sud-tirol": _2, "xn--trentino-sd-tirol-c3b": _2, "trentino-süd-tirol": _2, "trentino-sudtirol": _2, "xn--trentino-sdtirol-szb": _2, "trentino-südtirol": _2, "trentino-sued-tirol": _2, "trentino-suedtirol": _2, "trentino": _2, "trentinoa-adige": _2, "trentinoaadige": _2, "trentinoalto-adige": _2, "trentinoaltoadige": _2, "trentinos-tirol": _2, "trentinostirol": _2, "trentinosud-tirol": _2, "xn--trentinosd-tirol-rzb": _2, "trentinosüd-tirol": _2, "trentinosudtirol": _2, "xn--trentinosdtirol-7vb": _2, "trentinosüdtirol": _2, "trentinosued-tirol": _2, "trentinosuedtirol": _2, "trentinsud-tirol": _2, "xn--trentinsd-tirol-6vb": _2, "trentinsüd-tirol": _2, "trentinsudtirol": _2, "xn--trentinsdtirol-nsb": _2, "trentinsüdtirol": _2, "trentinsued-tirol": _2, "trentinsuedtirol": _2, "tuscany": _2, "umb": _2, "umbria": _2, "val-d-aosta": _2, "val-daosta": _2, "vald-aosta": _2, "valdaosta": _2, "valle-aosta": _2, "valle-d-aosta": _2, "valle-daosta": _2, "valleaosta": _2, "valled-aosta": _2, "valledaosta": _2, "vallee-aoste": _2, "xn--valle-aoste-ebb": _2, "vallée-aoste": _2, "vallee-d-aoste": _2, "xn--valle-d-aoste-ehb": _2, "vallée-d-aoste": _2, "valleeaoste": _2, "xn--valleaoste-e7a": _2, "valléeaoste": _2, "valleedaoste": _2, "xn--valledaoste-ebb": _2, "valléedaoste": _2, "vao": _2, "vda": _2, "ven": _2, "veneto": _2, "ag": _2, "agrigento": _2, "al": _2, "alessandria": _2, "alto-adige": _2, "altoadige": _2, "an": _2, "ancona": _2, "andria-barletta-trani": _2, "andria-trani-barletta": _2, "andriabarlettatrani": _2, "andriatranibarletta": _2, "ao": _2, "aosta": _2, "aoste": _2, "ap": _2, "aq": _2, "aquila": _2, "ar": _2, "arezzo": _2, "ascoli-piceno": _2, "ascolipiceno": _2, "asti": _2, "at": _2, "av": _2, "avellino": _2, "ba": _2, "balsan-sudtirol": _2, "xn--balsan-sdtirol-nsb": _2, "balsan-südtirol": _2, "balsan-suedtirol": _2, "balsan": _2, "bari": _2, "barletta-trani-andria": _2, "barlettatraniandria": _2, "belluno": _2, "benevento": _2, "bergamo": _2, "bg": _2, "bi": _2, "biella": _2, "bl": _2, "bn": _2, "bo": _2, "bologna": _2, "bolzano-altoadige": _2, "bolzano": _2, "bozen-sudtirol": _2, "xn--bozen-sdtirol-2ob": _2, "bozen-südtirol": _2, "bozen-suedtirol": _2, "bozen": _2, "br": _2, "brescia": _2, "brindisi": _2, "bs": _2, "bt": _2, "bulsan-sudtirol": _2, "xn--bulsan-sdtirol-nsb": _2, "bulsan-südtirol": _2, "bulsan-suedtirol": _2, "bulsan": _2, "bz": _2, "ca": _2, "cagliari": _2, "caltanissetta": _2, "campidano-medio": _2, "campidanomedio": _2, "campobasso": _2, "carbonia-iglesias": _2, "carboniaiglesias": _2, "carrara-massa": _2, "carraramassa": _2, "caserta": _2, "catania": _2, "catanzaro": _2, "cb": _2, "ce": _2, "cesena-forli": _2, "xn--cesena-forl-mcb": _2, "cesena-forlì": _2, "cesenaforli": _2, "xn--cesenaforl-i8a": _2, "cesenaforlì": _2, "ch": _2, "chieti": _2, "ci": _2, "cl": _2, "cn": _2, "co": _2, "como": _2, "cosenza": _2, "cr": _2, "cremona": _2, "crotone": _2, "cs": _2, "ct": _2, "cuneo": _2, "cz": _2, "dell-ogliastra": _2, "dellogliastra": _2, "en": _2, "enna": _2, "fc": _2, "fe": _2, "fermo": _2, "ferrara": _2, "fg": _2, "fi": _2, "firenze": _2, "florence": _2, "fm": _2, "foggia": _2, "forli-cesena": _2, "xn--forl-cesena-fcb": _2, "forlì-cesena": _2, "forlicesena": _2, "xn--forlcesena-c8a": _2, "forlìcesena": _2, "fr": _2, "frosinone": _2, "ge": _2, "genoa": _2, "genova": _2, "go": _2, "gorizia": _2, "gr": _2, "grosseto": _2, "iglesias-carbonia": _2, "iglesiascarbonia": _2, "im": _2, "imperia": _2, "is": _2, "isernia": _2, "kr": _2, "la-spezia": _2, "laquila": _2, "laspezia": _2, "latina": _2, "lc": _2, "le": _2, "lecce": _2, "lecco": _2, "li": _2, "livorno": _2, "lo": _2, "lodi": _2, "lt": _2, "lu": _2, "lucca": _2, "macerata": _2, "mantova": _2, "massa-carrara": _2, "massacarrara": _2, "matera": _2, "mb": _2, "mc": _2, "me": _2, "medio-campidano": _2, "mediocampidano": _2, "messina": _2, "mi": _2, "milan": _2, "milano": _2, "mn": _2, "mo": _2, "modena": _2, "monza-brianza": _2, "monza-e-della-brianza": _2, "monza": _2, "monzabrianza": _2, "monzaebrianza": _2, "monzaedellabrianza": _2, "ms": _2, "mt": _2, "na": _2, "naples": _2, "napoli": _2, "no": _2, "novara": _2, "nu": _2, "nuoro": _2, "og": _2, "ogliastra": _2, "olbia-tempio": _2, "olbiatempio": _2, "or": _2, "oristano": _2, "ot": _2, "pa": _2, "padova": _2, "padua": _2, "palermo": _2, "parma": _2, "pavia": _2, "pc": _2, "pd": _2, "pe": _2, "perugia": _2, "pesaro-urbino": _2, "pesarourbino": _2, "pescara": _2, "pg": _2, "pi": _2, "piacenza": _2, "pisa": _2, "pistoia": _2, "pn": _2, "po": _2, "pordenone": _2, "potenza": _2, "pr": _2, "prato": _2, "pt": _2, "pu": _2, "pv": _2, "pz": _2, "ra": _2, "ragusa": _2, "ravenna": _2, "rc": _2, "re": _2, "reggio-calabria": _2, "reggio-emilia": _2, "reggiocalabria": _2, "reggioemilia": _2, "rg": _2, "ri": _2, "rieti": _2, "rimini": _2, "rm": _2, "rn": _2, "ro": _2, "roma": _2, "rome": _2, "rovigo": _2, "sa": _2, "salerno": _2, "sassari": _2, "savona": _2, "si": _2, "siena": _2, "siracusa": _2, "so": _2, "sondrio": _2, "sp": _2, "sr": _2, "ss": _2, "suedtirol": _2, "xn--sdtirol-n2a": _2, "südtirol": _2, "sv": _2, "ta": _2, "taranto": _2, "te": _2, "tempio-olbia": _2, "tempioolbia": _2, "teramo": _2, "terni": _2, "tn": _2, "to": _2, "torino": _2, "tp": _2, "tr": _2, "trani-andria-barletta": _2, "trani-barletta-andria": _2, "traniandriabarletta": _2, "tranibarlettaandria": _2, "trapani": _2, "trento": _2, "treviso": _2, "trieste": _2, "ts": _2, "turin": _2, "tv": _2, "ud": _2, "udine": _2, "urbino-pesaro": _2, "urbinopesaro": _2, "va": _2, "varese": _2, "vb": _2, "vc": _2, "ve": _2, "venezia": _2, "venice": _2, "verbania": _2, "vercelli": _2, "verona": _2, "vi": _2, "vibo-valentia": _2, "vibovalentia": _2, "vicenza": _2, "viterbo": _2, "vr": _2, "vs": _2, "vt": _2, "vv": _2, "blogspot": _3, "ibxos": _3, "iliadboxos": _3, "neen": { "$": 0, "succ": { "jc": _3 } }, "tim": { "$": 0, "succ": { "open": { "$": 0, "succ": { "jelastic": _9 } } } }, "16-b": _3, "32-b": _3, "64-b": _3, "123homepage": _3, "myspreadshop": _3, "syncloud": _3 } }, "je": { "$": 1, "succ": { "co": _2, "net": _2, "org": _2, "of": _3 } }, "jm": _8, "jo": { "$": 1, "succ": { "com": _2, "org": _2, "net": _2, "edu": _2, "sch": _2, "gov": _2, "mil": _2, "name": _2 } }, "jobs": _2, "jp": { "$": 1, "succ": { "ac": _2, "ad": _2, "co": _2, "ed": _2, "go": _2, "gr": _2, "lg": _2, "ne": { "$": 1, "succ": { "aseinet": _28, "gehirn": _3, "ivory": _3, "mail-box": _3, "mints": _3, "mokuren": _3, "opal": _3, "sakura": _3, "sumomo": _3, "topaz": _3 } }, "or": _2, "aichi": { "$": 1, "succ": { "aisai": _2, "ama": _2, "anjo": _2, "asuke": _2, "chiryu": _2, "chita": _2, "fuso": _2, "gamagori": _2, "handa": _2, "hazu": _2, "hekinan": _2, "higashiura": _2, "ichinomiya": _2, "inazawa": _2, "inuyama": _2, "isshiki": _2, "iwakura": _2, "kanie": _2, "kariya": _2, "kasugai": _2, "kira": _2, "kiyosu": _2, "komaki": _2, "konan": _2, "kota": _2, "mihama": _2, "miyoshi": _2, "nishio": _2, "nisshin": _2, "obu": _2, "oguchi": _2, "oharu": _2, "okazaki": _2, "owariasahi": _2, "seto": _2, "shikatsu": _2, "shinshiro": _2, "shitara": _2, "tahara": _2, "takahama": _2, "tobishima": _2, "toei": _2, "togo": _2, "tokai": _2, "tokoname": _2, "toyoake": _2, "toyohashi": _2, "toyokawa": _2, "toyone": _2, "toyota": _2, "tsushima": _2, "yatomi": _2 } }, "akita": { "$": 1, "succ": { "akita": _2, "daisen": _2, "fujisato": _2, "gojome": _2, "hachirogata": _2, "happou": _2, "higashinaruse": _2, "honjo": _2, "honjyo": _2, "ikawa": _2, "kamikoani": _2, "kamioka": _2, "katagami": _2, "kazuno": _2, "kitaakita": _2, "kosaka": _2, "kyowa": _2, "misato": _2, "mitane": _2, "moriyoshi": _2, "nikaho": _2, "noshiro": _2, "odate": _2, "oga": _2, "ogata": _2, "semboku": _2, "yokote": _2, "yurihonjo": _2 } }, "aomori": { "$": 1, "succ": { "aomori": _2, "gonohe": _2, "hachinohe": _2, "hashikami": _2, "hiranai": _2, "hirosaki": _2, "itayanagi": _2, "kuroishi": _2, "misawa": _2, "mutsu": _2, "nakadomari": _2, "noheji": _2, "oirase": _2, "owani": _2, "rokunohe": _2, "sannohe": _2, "shichinohe": _2, "shingo": _2, "takko": _2, "towada": _2, "tsugaru": _2, "tsuruta": _2 } }, "chiba": { "$": 1, "succ": { "abiko": _2, "asahi": _2, "chonan": _2, "chosei": _2, "choshi": _2, "chuo": _2, "funabashi": _2, "futtsu": _2, "hanamigawa": _2, "ichihara": _2, "ichikawa": _2, "ichinomiya": _2, "inzai": _2, "isumi": _2, "kamagaya": _2, "kamogawa": _2, "kashiwa": _2, "katori": _2, "katsuura": _2, "kimitsu": _2, "kisarazu": _2, "kozaki": _2, "kujukuri": _2, "kyonan": _2, "matsudo": _2, "midori": _2, "mihama": _2, "minamiboso": _2, "mobara": _2, "mutsuzawa": _2, "nagara": _2, "nagareyama": _2, "narashino": _2, "narita": _2, "noda": _2, "oamishirasato": _2, "omigawa": _2, "onjuku": _2, "otaki": _2, "sakae": _2, "sakura": _2, "shimofusa": _2, "shirako": _2, "shiroi": _2, "shisui": _2, "sodegaura": _2, "sosa": _2, "tako": _2, "tateyama": _2, "togane": _2, "tohnosho": _2, "tomisato": _2, "urayasu": _2, "yachimata": _2, "yachiyo": _2, "yokaichiba": _2, "yokoshibahikari": _2, "yotsukaido": _2 } }, "ehime": { "$": 1, "succ": { "ainan": _2, "honai": _2, "ikata": _2, "imabari": _2, "iyo": _2, "kamijima": _2, "kihoku": _2, "kumakogen": _2, "masaki": _2, "matsuno": _2, "matsuyama": _2, "namikata": _2, "niihama": _2, "ozu": _2, "saijo": _2, "seiyo": _2, "shikokuchuo": _2, "tobe": _2, "toon": _2, "uchiko": _2, "uwajima": _2, "yawatahama": _2 } }, "fukui": { "$": 1, "succ": { "echizen": _2, "eiheiji": _2, "fukui": _2, "ikeda": _2, "katsuyama": _2, "mihama": _2, "minamiechizen": _2, "obama": _2, "ohi": _2, "ono": _2, "sabae": _2, "sakai": _2, "takahama": _2, "tsuruga": _2, "wakasa": _2 } }, "fukuoka": { "$": 1, "succ": { "ashiya": _2, "buzen": _2, "chikugo": _2, "chikuho": _2, "chikujo": _2, "chikushino": _2, "chikuzen": _2, "chuo": _2, "dazaifu": _2, "fukuchi": _2, "hakata": _2, "higashi": _2, "hirokawa": _2, "hisayama": _2, "iizuka": _2, "inatsuki": _2, "kaho": _2, "kasuga": _2, "kasuya": _2, "kawara": _2, "keisen": _2, "koga": _2, "kurate": _2, "kurogi": _2, "kurume": _2, "minami": _2, "miyako": _2, "miyama": _2, "miyawaka": _2, "mizumaki": _2, "munakata": _2, "nakagawa": _2, "nakama": _2, "nishi": _2, "nogata": _2, "ogori": _2, "okagaki": _2, "okawa": _2, "oki": _2, "omuta": _2, "onga": _2, "onojo": _2, "oto": _2, "saigawa": _2, "sasaguri": _2, "shingu": _2, "shinyoshitomi": _2, "shonai": _2, "soeda": _2, "sue": _2, "tachiarai": _2, "tagawa": _2, "takata": _2, "toho": _2, "toyotsu": _2, "tsuiki": _2, "ukiha": _2, "umi": _2, "usui": _2, "yamada": _2, "yame": _2, "yanagawa": _2, "yukuhashi": _2 } }, "fukushima": { "$": 1, "succ": { "aizubange": _2, "aizumisato": _2, "aizuwakamatsu": _2, "asakawa": _2, "bandai": _2, "date": _2, "fukushima": _2, "furudono": _2, "futaba": _2, "hanawa": _2, "higashi": _2, "hirata": _2, "hirono": _2, "iitate": _2, "inawashiro": _2, "ishikawa": _2, "iwaki": _2, "izumizaki": _2, "kagamiishi": _2, "kaneyama": _2, "kawamata": _2, "kitakata": _2, "kitashiobara": _2, "koori": _2, "koriyama": _2, "kunimi": _2, "miharu": _2, "mishima": _2, "namie": _2, "nango": _2, "nishiaizu": _2, "nishigo": _2, "okuma": _2, "omotego": _2, "ono": _2, "otama": _2, "samegawa": _2, "shimogo": _2, "shirakawa": _2, "showa": _2, "soma": _2, "sukagawa": _2, "taishin": _2, "tamakawa": _2, "tanagura": _2, "tenei": _2, "yabuki": _2, "yamato": _2, "yamatsuri": _2, "yanaizu": _2, "yugawa": _2 } }, "gifu": { "$": 1, "succ": { "anpachi": _2, "ena": _2, "gifu": _2, "ginan": _2, "godo": _2, "gujo": _2, "hashima": _2, "hichiso": _2, "hida": _2, "higashishirakawa": _2, "ibigawa": _2, "ikeda": _2, "kakamigahara": _2, "kani": _2, "kasahara": _2, "kasamatsu": _2, "kawaue": _2, "kitagata": _2, "mino": _2, "minokamo": _2, "mitake": _2, "mizunami": _2, "motosu": _2, "nakatsugawa": _2, "ogaki": _2, "sakahogi": _2, "seki": _2, "sekigahara": _2, "shirakawa": _2, "tajimi": _2, "takayama": _2, "tarui": _2, "toki": _2, "tomika": _2, "wanouchi": _2, "yamagata": _2, "yaotsu": _2, "yoro": _2 } }, "gunma": { "$": 1, "succ": { "annaka": _2, "chiyoda": _2, "fujioka": _2, "higashiagatsuma": _2, "isesaki": _2, "itakura": _2, "kanna": _2, "kanra": _2, "katashina": _2, "kawaba": _2, "kiryu": _2, "kusatsu": _2, "maebashi": _2, "meiwa": _2, "midori": _2, "minakami": _2, "naganohara": _2, "nakanojo": _2, "nanmoku": _2, "numata": _2, "oizumi": _2, "ora": _2, "ota": _2, "shibukawa": _2, "shimonita": _2, "shinto": _2, "showa": _2, "takasaki": _2, "takayama": _2, "tamamura": _2, "tatebayashi": _2, "tomioka": _2, "tsukiyono": _2, "tsumagoi": _2, "ueno": _2, "yoshioka": _2 } }, "hiroshima": { "$": 1, "succ": { "asaminami": _2, "daiwa": _2, "etajima": _2, "fuchu": _2, "fukuyama": _2, "hatsukaichi": _2, "higashihiroshima": _2, "hongo": _2, "jinsekikogen": _2, "kaita": _2, "kui": _2, "kumano": _2, "kure": _2, "mihara": _2, "miyoshi": _2, "naka": _2, "onomichi": _2, "osakikamijima": _2, "otake": _2, "saka": _2, "sera": _2, "seranishi": _2, "shinichi": _2, "shobara": _2, "takehara": _2 } }, "hokkaido": { "$": 1, "succ": { "abashiri": _2, "abira": _2, "aibetsu": _2, "akabira": _2, "akkeshi": _2, "asahikawa": _2, "ashibetsu": _2, "ashoro": _2, "assabu": _2, "atsuma": _2, "bibai": _2, "biei": _2, "bifuka": _2, "bihoro": _2, "biratori": _2, "chippubetsu": _2, "chitose": _2, "date": _2, "ebetsu": _2, "embetsu": _2, "eniwa": _2, "erimo": _2, "esan": _2, "esashi": _2, "fukagawa": _2, "fukushima": _2, "furano": _2, "furubira": _2, "haboro": _2, "hakodate": _2, "hamatonbetsu": _2, "hidaka": _2, "higashikagura": _2, "higashikawa": _2, "hiroo": _2, "hokuryu": _2, "hokuto": _2, "honbetsu": _2, "horokanai": _2, "horonobe": _2, "ikeda": _2, "imakane": _2, "ishikari": _2, "iwamizawa": _2, "iwanai": _2, "kamifurano": _2, "kamikawa": _2, "kamishihoro": _2, "kamisunagawa": _2, "kamoenai": _2, "kayabe": _2, "kembuchi": _2, "kikonai": _2, "kimobetsu": _2, "kitahiroshima": _2, "kitami": _2, "kiyosato": _2, "koshimizu": _2, "kunneppu": _2, "kuriyama": _2, "kuromatsunai": _2, "kushiro": _2, "kutchan": _2, "kyowa": _2, "mashike": _2, "matsumae": _2, "mikasa": _2, "minamifurano": _2, "mombetsu": _2, "moseushi": _2, "mukawa": _2, "muroran": _2, "naie": _2, "nakagawa": _2, "nakasatsunai": _2, "nakatombetsu": _2, "nanae": _2, "nanporo": _2, "nayoro": _2, "nemuro": _2, "niikappu": _2, "niki": _2, "nishiokoppe": _2, "noboribetsu": _2, "numata": _2, "obihiro": _2, "obira": _2, "oketo": _2, "okoppe": _2, "otaru": _2, "otobe": _2, "otofuke": _2, "otoineppu": _2, "oumu": _2, "ozora": _2, "pippu": _2, "rankoshi": _2, "rebun": _2, "rikubetsu": _2, "rishiri": _2, "rishirifuji": _2, "saroma": _2, "sarufutsu": _2, "shakotan": _2, "shari": _2, "shibecha": _2, "shibetsu": _2, "shikabe": _2, "shikaoi": _2, "shimamaki": _2, "shimizu": _2, "shimokawa": _2, "shinshinotsu": _2, "shintoku": _2, "shiranuka": _2, "shiraoi": _2, "shiriuchi": _2, "sobetsu": _2, "sunagawa": _2, "taiki": _2, "takasu": _2, "takikawa": _2, "takinoue": _2, "teshikaga": _2, "tobetsu": _2, "tohma": _2, "tomakomai": _2, "tomari": _2, "toya": _2, "toyako": _2, "toyotomi": _2, "toyoura": _2, "tsubetsu": _2, "tsukigata": _2, "urakawa": _2, "urausu": _2, "uryu": _2, "utashinai": _2, "wakkanai": _2, "wassamu": _2, "yakumo": _2, "yoichi": _2 } }, "hyogo": { "$": 1, "succ": { "aioi": _2, "akashi": _2, "ako": _2, "amagasaki": _2, "aogaki": _2, "asago": _2, "ashiya": _2, "awaji": _2, "fukusaki": _2, "goshiki": _2, "harima": _2, "himeji": _2, "ichikawa": _2, "inagawa": _2, "itami": _2, "kakogawa": _2, "kamigori": _2, "kamikawa": _2, "kasai": _2, "kasuga": _2, "kawanishi": _2, "miki": _2, "minamiawaji": _2, "nishinomiya": _2, "nishiwaki": _2, "ono": _2, "sanda": _2, "sannan": _2, "sasayama": _2, "sayo": _2, "shingu": _2, "shinonsen": _2, "shiso": _2, "sumoto": _2, "taishi": _2, "taka": _2, "takarazuka": _2, "takasago": _2, "takino": _2, "tamba": _2, "tatsuno": _2, "toyooka": _2, "yabu": _2, "yashiro": _2, "yoka": _2, "yokawa": _2 } }, "ibaraki": { "$": 1, "succ": { "ami": _2, "asahi": _2, "bando": _2, "chikusei": _2, "daigo": _2, "fujishiro": _2, "hitachi": _2, "hitachinaka": _2, "hitachiomiya": _2, "hitachiota": _2, "ibaraki": _2, "ina": _2, "inashiki": _2, "itako": _2, "iwama": _2, "joso": _2, "kamisu": _2, "kasama": _2, "kashima": _2, "kasumigaura": _2, "koga": _2, "miho": _2, "mito": _2, "moriya": _2, "naka": _2, "namegata": _2, "oarai": _2, "ogawa": _2, "omitama": _2, "ryugasaki": _2, "sakai": _2, "sakuragawa": _2, "shimodate": _2, "shimotsuma": _2, "shirosato": _2, "sowa": _2, "suifu": _2, "takahagi": _2, "tamatsukuri": _2, "tokai": _2, "tomobe": _2, "tone": _2, "toride": _2, "tsuchiura": _2, "tsukuba": _2, "uchihara": _2, "ushiku": _2, "yachiyo": _2, "yamagata": _2, "yawara": _2, "yuki": _2 } }, "ishikawa": { "$": 1, "succ": { "anamizu": _2, "hakui": _2, "hakusan": _2, "kaga": _2, "kahoku": _2, "kanazawa": _2, "kawakita": _2, "komatsu": _2, "nakanoto": _2, "nanao": _2, "nomi": _2, "nonoichi": _2, "noto": _2, "shika": _2, "suzu": _2, "tsubata": _2, "tsurugi": _2, "uchinada": _2, "wajima": _2 } }, "iwate": { "$": 1, "succ": { "fudai": _2, "fujisawa": _2, "hanamaki": _2, "hiraizumi": _2, "hirono": _2, "ichinohe": _2, "ichinoseki": _2, "iwaizumi": _2, "iwate": _2, "joboji": _2, "kamaishi": _2, "kanegasaki": _2, "karumai": _2, "kawai": _2, "kitakami": _2, "kuji": _2, "kunohe": _2, "kuzumaki": _2, "miyako": _2, "mizusawa": _2, "morioka": _2, "ninohe": _2, "noda": _2, "ofunato": _2, "oshu": _2, "otsuchi": _2, "rikuzentakata": _2, "shiwa": _2, "shizukuishi": _2, "sumita": _2, "tanohata": _2, "tono": _2, "yahaba": _2, "yamada": _2 } }, "kagawa": { "$": 1, "succ": { "ayagawa": _2, "higashikagawa": _2, "kanonji": _2, "kotohira": _2, "manno": _2, "marugame": _2, "mitoyo": _2, "naoshima": _2, "sanuki": _2, "tadotsu": _2, "takamatsu": _2, "tonosho": _2, "uchinomi": _2, "utazu": _2, "zentsuji": _2 } }, "kagoshima": { "$": 1, "succ": { "akune": _2, "amami": _2, "hioki": _2, "isa": _2, "isen": _2, "izumi": _2, "kagoshima": _2, "kanoya": _2, "kawanabe": _2, "kinko": _2, "kouyama": _2, "makurazaki": _2, "matsumoto": _2, "minamitane": _2, "nakatane": _2, "nishinoomote": _2, "satsumasendai": _2, "soo": _2, "tarumizu": _2, "yusui": _2 } }, "kanagawa": { "$": 1, "succ": { "aikawa": _2, "atsugi": _2, "ayase": _2, "chigasaki": _2, "ebina": _2, "fujisawa": _2, "hadano": _2, "hakone": _2, "hiratsuka": _2, "isehara": _2, "kaisei": _2, "kamakura": _2, "kiyokawa": _2, "matsuda": _2, "minamiashigara": _2, "miura": _2, "nakai": _2, "ninomiya": _2, "odawara": _2, "oi": _2, "oiso": _2, "sagamihara": _2, "samukawa": _2, "tsukui": _2, "yamakita": _2, "yamato": _2, "yokosuka": _2, "yugawara": _2, "zama": _2, "zushi": _2 } }, "kochi": { "$": 1, "succ": { "aki": _2, "geisei": _2, "hidaka": _2, "higashitsuno": _2, "ino": _2, "kagami": _2, "kami": _2, "kitagawa": _2, "kochi": _2, "mihara": _2, "motoyama": _2, "muroto": _2, "nahari": _2, "nakamura": _2, "nankoku": _2, "nishitosa": _2, "niyodogawa": _2, "ochi": _2, "okawa": _2, "otoyo": _2, "otsuki": _2, "sakawa": _2, "sukumo": _2, "susaki": _2, "tosa": _2, "tosashimizu": _2, "toyo": _2, "tsuno": _2, "umaji": _2, "yasuda": _2, "yusuhara": _2 } }, "kumamoto": { "$": 1, "succ": { "amakusa": _2, "arao": _2, "aso": _2, "choyo": _2, "gyokuto": _2, "kamiamakusa": _2, "kikuchi": _2, "kumamoto": _2, "mashiki": _2, "mifune": _2, "minamata": _2, "minamioguni": _2, "nagasu": _2, "nishihara": _2, "oguni": _2, "ozu": _2, "sumoto": _2, "takamori": _2, "uki": _2, "uto": _2, "yamaga": _2, "yamato": _2, "yatsushiro": _2 } }, "kyoto": { "$": 1, "succ": { "ayabe": _2, "fukuchiyama": _2, "higashiyama": _2, "ide": _2, "ine": _2, "joyo": _2, "kameoka": _2, "kamo": _2, "kita": _2, "kizu": _2, "kumiyama": _2, "kyotamba": _2, "kyotanabe": _2, "kyotango": _2, "maizuru": _2, "minami": _2, "minamiyamashiro": _2, "miyazu": _2, "muko": _2, "nagaokakyo": _2, "nakagyo": _2, "nantan": _2, "oyamazaki": _2, "sakyo": _2, "seika": _2, "tanabe": _2, "uji": _2, "ujitawara": _2, "wazuka": _2, "yamashina": _2, "yawata": _2 } }, "mie": { "$": 1, "succ": { "asahi": _2, "inabe": _2, "ise": _2, "kameyama": _2, "kawagoe": _2, "kiho": _2, "kisosaki": _2, "kiwa": _2, "komono": _2, "kumano": _2, "kuwana": _2, "matsusaka": _2, "meiwa": _2, "mihama": _2, "minamiise": _2, "misugi": _2, "miyama": _2, "nabari": _2, "shima": _2, "suzuka": _2, "tado": _2, "taiki": _2, "taki": _2, "tamaki": _2, "toba": _2, "tsu": _2, "udono": _2, "ureshino": _2, "watarai": _2, "yokkaichi": _2 } }, "miyagi": { "$": 1, "succ": { "furukawa": _2, "higashimatsushima": _2, "ishinomaki": _2, "iwanuma": _2, "kakuda": _2, "kami": _2, "kawasaki": _2, "marumori": _2, "matsushima": _2, "minamisanriku": _2, "misato": _2, "murata": _2, "natori": _2, "ogawara": _2, "ohira": _2, "onagawa": _2, "osaki": _2, "rifu": _2, "semine": _2, "shibata": _2, "shichikashuku": _2, "shikama": _2, "shiogama": _2, "shiroishi": _2, "tagajo": _2, "taiwa": _2, "tome": _2, "tomiya": _2, "wakuya": _2, "watari": _2, "yamamoto": _2, "zao": _2 } }, "miyazaki": { "$": 1, "succ": { "aya": _2, "ebino": _2, "gokase": _2, "hyuga": _2, "kadogawa": _2, "kawaminami": _2, "kijo": _2, "kitagawa": _2, "kitakata": _2, "kitaura": _2, "kobayashi": _2, "kunitomi": _2, "kushima": _2, "mimata": _2, "miyakonojo": _2, "miyazaki": _2, "morotsuka": _2, "nichinan": _2, "nishimera": _2, "nobeoka": _2, "saito": _2, "shiiba": _2, "shintomi": _2, "takaharu": _2, "takanabe": _2, "takazaki": _2, "tsuno": _2 } }, "nagano": { "$": 1, "succ": { "achi": _2, "agematsu": _2, "anan": _2, "aoki": _2, "asahi": _2, "azumino": _2, "chikuhoku": _2, "chikuma": _2, "chino": _2, "fujimi": _2, "hakuba": _2, "hara": _2, "hiraya": _2, "iida": _2, "iijima": _2, "iiyama": _2, "iizuna": _2, "ikeda": _2, "ikusaka": _2, "ina": _2, "karuizawa": _2, "kawakami": _2, "kiso": _2, "kisofukushima": _2, "kitaaiki": _2, "komagane": _2, "komoro": _2, "matsukawa": _2, "matsumoto": _2, "miasa": _2, "minamiaiki": _2, "minamimaki": _2, "minamiminowa": _2, "minowa": _2, "miyada": _2, "miyota": _2, "mochizuki": _2, "nagano": _2, "nagawa": _2, "nagiso": _2, "nakagawa": _2, "nakano": _2, "nozawaonsen": _2, "obuse": _2, "ogawa": _2, "okaya": _2, "omachi": _2, "omi": _2, "ookuwa": _2, "ooshika": _2, "otaki": _2, "otari": _2, "sakae": _2, "sakaki": _2, "saku": _2, "sakuho": _2, "shimosuwa": _2, "shinanomachi": _2, "shiojiri": _2, "suwa": _2, "suzaka": _2, "takagi": _2, "takamori": _2, "takayama": _2, "tateshina": _2, "tatsuno": _2, "togakushi": _2, "togura": _2, "tomi": _2, "ueda": _2, "wada": _2, "yamagata": _2, "yamanouchi": _2, "yasaka": _2, "yasuoka": _2 } }, "nagasaki": { "$": 1, "succ": { "chijiwa": _2, "futsu": _2, "goto": _2, "hasami": _2, "hirado": _2, "iki": _2, "isahaya": _2, "kawatana": _2, "kuchinotsu": _2, "matsuura": _2, "nagasaki": _2, "obama": _2, "omura": _2, "oseto": _2, "saikai": _2, "sasebo": _2, "seihi": _2, "shimabara": _2, "shinkamigoto": _2, "togitsu": _2, "tsushima": _2, "unzen": _2 } }, "nara": { "$": 1, "succ": { "ando": _2, "gose": _2, "heguri": _2, "higashiyoshino": _2, "ikaruga": _2, "ikoma": _2, "kamikitayama": _2, "kanmaki": _2, "kashiba": _2, "kashihara": _2, "katsuragi": _2, "kawai": _2, "kawakami": _2, "kawanishi": _2, "koryo": _2, "kurotaki": _2, "mitsue": _2, "miyake": _2, "nara": _2, "nosegawa": _2, "oji": _2, "ouda": _2, "oyodo": _2, "sakurai": _2, "sango": _2, "shimoichi": _2, "shimokitayama": _2, "shinjo": _2, "soni": _2, "takatori": _2, "tawaramoto": _2, "tenkawa": _2, "tenri": _2, "uda": _2, "yamatokoriyama": _2, "yamatotakada": _2, "yamazoe": _2, "yoshino": _2 } }, "niigata": { "$": 1, "succ": { "aga": _2, "agano": _2, "gosen": _2, "itoigawa": _2, "izumozaki": _2, "joetsu": _2, "kamo": _2, "kariwa": _2, "kashiwazaki": _2, "minamiuonuma": _2, "mitsuke": _2, "muika": _2, "murakami": _2, "myoko": _2, "nagaoka": _2, "niigata": _2, "ojiya": _2, "omi": _2, "sado": _2, "sanjo": _2, "seiro": _2, "seirou": _2, "sekikawa": _2, "shibata": _2, "tagami": _2, "tainai": _2, "tochio": _2, "tokamachi": _2, "tsubame": _2, "tsunan": _2, "uonuma": _2, "yahiko": _2, "yoita": _2, "yuzawa": _2 } }, "oita": { "$": 1, "succ": { "beppu": _2, "bungoono": _2, "bungotakada": _2, "hasama": _2, "hiji": _2, "himeshima": _2, "hita": _2, "kamitsue": _2, "kokonoe": _2, "kuju": _2, "kunisaki": _2, "kusu": _2, "oita": _2, "saiki": _2, "taketa": _2, "tsukumi": _2, "usa": _2, "usuki": _2, "yufu": _2 } }, "okayama": { "$": 1, "succ": { "akaiwa": _2, "asakuchi": _2, "bizen": _2, "hayashima": _2, "ibara": _2, "kagamino": _2, "kasaoka": _2, "kibichuo": _2, "kumenan": _2, "kurashiki": _2, "maniwa": _2, "misaki": _2, "nagi": _2, "niimi": _2, "nishiawakura": _2, "okayama": _2, "satosho": _2, "setouchi": _2, "shinjo": _2, "shoo": _2, "soja": _2, "takahashi": _2, "tamano": _2, "tsuyama": _2, "wake": _2, "yakage": _2 } }, "okinawa": { "$": 1, "succ": { "aguni": _2, "ginowan": _2, "ginoza": _2, "gushikami": _2, "haebaru": _2, "higashi": _2, "hirara": _2, "iheya": _2, "ishigaki": _2, "ishikawa": _2, "itoman": _2, "izena": _2, "kadena": _2, "kin": _2, "kitadaito": _2, "kitanakagusuku": _2, "kumejima": _2, "kunigami": _2, "minamidaito": _2, "motobu": _2, "nago": _2, "naha": _2, "nakagusuku": _2, "nakijin": _2, "nanjo": _2, "nishihara": _2, "ogimi": _2, "okinawa": _2, "onna": _2, "shimoji": _2, "taketomi": _2, "tarama": _2, "tokashiki": _2, "tomigusuku": _2, "tonaki": _2, "urasoe": _2, "uruma": _2, "yaese": _2, "yomitan": _2, "yonabaru": _2, "yonaguni": _2, "zamami": _2 } }, "osaka": { "$": 1, "succ": { "abeno": _2, "chihayaakasaka": _2, "chuo": _2, "daito": _2, "fujiidera": _2, "habikino": _2, "hannan": _2, "higashiosaka": _2, "higashisumiyoshi": _2, "higashiyodogawa": _2, "hirakata": _2, "ibaraki": _2, "ikeda": _2, "izumi": _2, "izumiotsu": _2, "izumisano": _2, "kadoma": _2, "kaizuka": _2, "kanan": _2, "kashiwara": _2, "katano": _2, "kawachinagano": _2, "kishiwada": _2, "kita": _2, "kumatori": _2, "matsubara": _2, "minato": _2, "minoh": _2, "misaki": _2, "moriguchi": _2, "neyagawa": _2, "nishi": _2, "nose": _2, "osakasayama": _2, "sakai": _2, "sayama": _2, "sennan": _2, "settsu": _2, "shijonawate": _2, "shimamoto": _2, "suita": _2, "tadaoka": _2, "taishi": _2, "tajiri": _2, "takaishi": _2, "takatsuki": _2, "tondabayashi": _2, "toyonaka": _2, "toyono": _2, "yao": _2 } }, "saga": { "$": 1, "succ": { "ariake": _2, "arita": _2, "fukudomi": _2, "genkai": _2, "hamatama": _2, "hizen": _2, "imari": _2, "kamimine": _2, "kanzaki": _2, "karatsu": _2, "kashima": _2, "kitagata": _2, "kitahata": _2, "kiyama": _2, "kouhoku": _2, "kyuragi": _2, "nishiarita": _2, "ogi": _2, "omachi": _2, "ouchi": _2, "saga": _2, "shiroishi": _2, "taku": _2, "tara": _2, "tosu": _2, "yoshinogari": _2 } }, "saitama": { "$": 1, "succ": { "arakawa": _2, "asaka": _2, "chichibu": _2, "fujimi": _2, "fujimino": _2, "fukaya": _2, "hanno": _2, "hanyu": _2, "hasuda": _2, "hatogaya": _2, "hatoyama": _2, "hidaka": _2, "higashichichibu": _2, "higashimatsuyama": _2, "honjo": _2, "ina": _2, "iruma": _2, "iwatsuki": _2, "kamiizumi": _2, "kamikawa": _2, "kamisato": _2, "kasukabe": _2, "kawagoe": _2, "kawaguchi": _2, "kawajima": _2, "kazo": _2, "kitamoto": _2, "koshigaya": _2, "kounosu": _2, "kuki": _2, "kumagaya": _2, "matsubushi": _2, "minano": _2, "misato": _2, "miyashiro": _2, "miyoshi": _2, "moroyama": _2, "nagatoro": _2, "namegawa": _2, "niiza": _2, "ogano": _2, "ogawa": _2, "ogose": _2, "okegawa": _2, "omiya": _2, "otaki": _2, "ranzan": _2, "ryokami": _2, "saitama": _2, "sakado": _2, "satte": _2, "sayama": _2, "shiki": _2, "shiraoka": _2, "soka": _2, "sugito": _2, "toda": _2, "tokigawa": _2, "tokorozawa": _2, "tsurugashima": _2, "urawa": _2, "warabi": _2, "yashio": _2, "yokoze": _2, "yono": _2, "yorii": _2, "yoshida": _2, "yoshikawa": _2, "yoshimi": _2 } }, "shiga": { "$": 1, "succ": { "aisho": _2, "gamo": _2, "higashiomi": _2, "hikone": _2, "koka": _2, "konan": _2, "kosei": _2, "koto": _2, "kusatsu": _2, "maibara": _2, "moriyama": _2, "nagahama": _2, "nishiazai": _2, "notogawa": _2, "omihachiman": _2, "otsu": _2, "ritto": _2, "ryuoh": _2, "takashima": _2, "takatsuki": _2, "torahime": _2, "toyosato": _2, "yasu": _2 } }, "shimane": { "$": 1, "succ": { "akagi": _2, "ama": _2, "gotsu": _2, "hamada": _2, "higashiizumo": _2, "hikawa": _2, "hikimi": _2, "izumo": _2, "kakinoki": _2, "masuda": _2, "matsue": _2, "misato": _2, "nishinoshima": _2, "ohda": _2, "okinoshima": _2, "okuizumo": _2, "shimane": _2, "tamayu": _2, "tsuwano": _2, "unnan": _2, "yakumo": _2, "yasugi": _2, "yatsuka": _2 } }, "shizuoka": { "$": 1, "succ": { "arai": _2, "atami": _2, "fuji": _2, "fujieda": _2, "fujikawa": _2, "fujinomiya": _2, "fukuroi": _2, "gotemba": _2, "haibara": _2, "hamamatsu": _2, "higashiizu": _2, "ito": _2, "iwata": _2, "izu": _2, "izunokuni": _2, "kakegawa": _2, "kannami": _2, "kawanehon": _2, "kawazu": _2, "kikugawa": _2, "kosai": _2, "makinohara": _2, "matsuzaki": _2, "minamiizu": _2, "mishima": _2, "morimachi": _2, "nishiizu": _2, "numazu": _2, "omaezaki": _2, "shimada": _2, "shimizu": _2, "shimoda": _2, "shizuoka": _2, "susono": _2, "yaizu": _2, "yoshida": _2 } }, "tochigi": { "$": 1, "succ": { "ashikaga": _2, "bato": _2, "haga": _2, "ichikai": _2, "iwafune": _2, "kaminokawa": _2, "kanuma": _2, "karasuyama": _2, "kuroiso": _2, "mashiko": _2, "mibu": _2, "moka": _2, "motegi": _2, "nasu": _2, "nasushiobara": _2, "nikko": _2, "nishikata": _2, "nogi": _2, "ohira": _2, "ohtawara": _2, "oyama": _2, "sakura": _2, "sano": _2, "shimotsuke": _2, "shioya": _2, "takanezawa": _2, "tochigi": _2, "tsuga": _2, "ujiie": _2, "utsunomiya": _2, "yaita": _2 } }, "tokushima": { "$": 1, "succ": { "aizumi": _2, "anan": _2, "ichiba": _2, "itano": _2, "kainan": _2, "komatsushima": _2, "matsushige": _2, "mima": _2, "minami": _2, "miyoshi": _2, "mugi": _2, "nakagawa": _2, "naruto": _2, "sanagochi": _2, "shishikui": _2, "tokushima": _2, "wajiki": _2 } }, "tokyo": { "$": 1, "succ": { "adachi": _2, "akiruno": _2, "akishima": _2, "aogashima": _2, "arakawa": _2, "bunkyo": _2, "chiyoda": _2, "chofu": _2, "chuo": _2, "edogawa": _2, "fuchu": _2, "fussa": _2, "hachijo": _2, "hachioji": _2, "hamura": _2, "higashikurume": _2, "higashimurayama": _2, "higashiyamato": _2, "hino": _2, "hinode": _2, "hinohara": _2, "inagi": _2, "itabashi": _2, "katsushika": _2, "kita": _2, "kiyose": _2, "kodaira": _2, "koganei": _2, "kokubunji": _2, "komae": _2, "koto": _2, "kouzushima": _2, "kunitachi": _2, "machida": _2, "meguro": _2, "minato": _2, "mitaka": _2, "mizuho": _2, "musashimurayama": _2, "musashino": _2, "nakano": _2, "nerima": _2, "ogasawara": _2, "okutama": _2, "ome": _2, "oshima": _2, "ota": _2, "setagaya": _2, "shibuya": _2, "shinagawa": _2, "shinjuku": _2, "suginami": _2, "sumida": _2, "tachikawa": _2, "taito": _2, "tama": _2, "toshima": _2 } }, "tottori": { "$": 1, "succ": { "chizu": _2, "hino": _2, "kawahara": _2, "koge": _2, "kotoura": _2, "misasa": _2, "nanbu": _2, "nichinan": _2, "sakaiminato": _2, "tottori": _2, "wakasa": _2, "yazu": _2, "yonago": _2 } }, "toyama": { "$": 1, "succ": { "asahi": _2, "fuchu": _2, "fukumitsu": _2, "funahashi": _2, "himi": _2, "imizu": _2, "inami": _2, "johana": _2, "kamiichi": _2, "kurobe": _2, "nakaniikawa": _2, "namerikawa": _2, "nanto": _2, "nyuzen": _2, "oyabe": _2, "taira": _2, "takaoka": _2, "tateyama": _2, "toga": _2, "tonami": _2, "toyama": _2, "unazuki": _2, "uozu": _2, "yamada": _2 } }, "wakayama": { "$": 1, "succ": { "arida": _2, "aridagawa": _2, "gobo": _2, "hashimoto": _2, "hidaka": _2, "hirogawa": _2, "inami": _2, "iwade": _2, "kainan": _2, "kamitonda": _2, "katsuragi": _2, "kimino": _2, "kinokawa": _2, "kitayama": _2, "koya": _2, "koza": _2, "kozagawa": _2, "kudoyama": _2, "kushimoto": _2, "mihama": _2, "misato": _2, "nachikatsuura": _2, "shingu": _2, "shirahama": _2, "taiji": _2, "tanabe": _2, "wakayama": _2, "yuasa": _2, "yura": _2 } }, "yamagata": { "$": 1, "succ": { "asahi": _2, "funagata": _2, "higashine": _2, "iide": _2, "kahoku": _2, "kaminoyama": _2, "kaneyama": _2, "kawanishi": _2, "mamurogawa": _2, "mikawa": _2, "murayama": _2, "nagai": _2, "nakayama": _2, "nanyo": _2, "nishikawa": _2, "obanazawa": _2, "oe": _2, "oguni": _2, "ohkura": _2, "oishida": _2, "sagae": _2, "sakata": _2, "sakegawa": _2, "shinjo": _2, "shirataka": _2, "shonai": _2, "takahata": _2, "tendo": _2, "tozawa": _2, "tsuruoka": _2, "yamagata": _2, "yamanobe": _2, "yonezawa": _2, "yuza": _2 } }, "yamaguchi": { "$": 1, "succ": { "abu": _2, "hagi": _2, "hikari": _2, "hofu": _2, "iwakuni": _2, "kudamatsu": _2, "mitou": _2, "nagato": _2, "oshima": _2, "shimonoseki": _2, "shunan": _2, "tabuse": _2, "tokuyama": _2, "toyota": _2, "ube": _2, "yuu": _2 } }, "yamanashi": { "$": 1, "succ": { "chuo": _2, "doshi": _2, "fuefuki": _2, "fujikawa": _2, "fujikawaguchiko": _2, "fujiyoshida": _2, "hayakawa": _2, "hokuto": _2, "ichikawamisato": _2, "kai": _2, "kofu": _2, "koshu": _2, "kosuge": _2, "minami-alps": _2, "minobu": _2, "nakamichi": _2, "nanbu": _2, "narusawa": _2, "nirasaki": _2, "nishikatsura": _2, "oshino": _2, "otsuki": _2, "showa": _2, "tabayama": _2, "tsuru": _2, "uenohara": _2, "yamanakako": _2, "yamanashi": _2 } }, "xn--4pvxs": _2, "栃木": _2, "xn--vgu402c": _2, "愛知": _2, "xn--c3s14m": _2, "愛媛": _2, "xn--f6qx53a": _2, "兵庫": _2, "xn--8pvr4u": _2, "熊本": _2, "xn--uist22h": _2, "茨城": _2, "xn--djrs72d6uy": _2, "北海道": _2, "xn--mkru45i": _2, "千葉": _2, "xn--0trq7p7nn": _2, "和歌山": _2, "xn--8ltr62k": _2, "長崎": _2, "xn--2m4a15e": _2, "長野": _2, "xn--efvn9s": _2, "新潟": _2, "xn--32vp30h": _2, "青森": _2, "xn--4it797k": _2, "静岡": _2, "xn--1lqs71d": _2, "東京": _2, "xn--5rtp49c": _2, "石川": _2, "xn--5js045d": _2, "埼玉": _2, "xn--ehqz56n": _2, "三重": _2, "xn--1lqs03n": _2, "京都": _2, "xn--qqqt11m": _2, "佐賀": _2, "xn--kbrq7o": _2, "大分": _2, "xn--pssu33l": _2, "大阪": _2, "xn--ntsq17g": _2, "奈良": _2, "xn--uisz3g": _2, "宮城": _2, "xn--6btw5a": _2, "宮崎": _2, "xn--1ctwo": _2, "富山": _2, "xn--6orx2r": _2, "山口": _2, "xn--rht61e": _2, "山形": _2, "xn--rht27z": _2, "山梨": _2, "xn--djty4k": _2, "岩手": _2, "xn--nit225k": _2, "岐阜": _2, "xn--rht3d": _2, "岡山": _2, "xn--klty5x": _2, "島根": _2, "xn--kltx9a": _2, "広島": _2, "xn--kltp7d": _2, "徳島": _2, "xn--uuwu58a": _2, "沖縄": _2, "xn--zbx025d": _2, "滋賀": _2, "xn--ntso0iqx3a": _2, "神奈川": _2, "xn--elqq16h": _2, "福井": _2, "xn--4it168d": _2, "福岡": _2, "xn--klt787d": _2, "福島": _2, "xn--rny31h": _2, "秋田": _2, "xn--7t0a264c": _2, "群馬": _2, "xn--5rtq34k": _2, "香川": _2, "xn--k7yn95e": _2, "高知": _2, "xn--tor131o": _2, "鳥取": _2, "xn--d5qv7z876c": _2, "鹿児島": _2, "kawasaki": _8, "kitakyushu": _8, "kobe": _8, "nagoya": _8, "sapporo": _8, "sendai": _8, "yokohama": _8, "buyshop": _3, "fashionstore": _3, "handcrafted": _3, "kawaiishop": _3, "supersale": _3, "theshop": _3, "usercontent": _3, "angry": _3, "babyblue": _3, "babymilk": _3, "backdrop": _3, "bambina": _3, "bitter": _3, "blush": _3, "boo": _3, "boy": _3, "boyfriend": _3, "but": _3, "candypop": _3, "capoo": _3, "catfood": _3, "cheap": _3, "chicappa": _3, "chillout": _3, "chips": _3, "chowder": _3, "chu": _3, "ciao": _3, "cocotte": _3, "coolblog": _3, "cranky": _3, "cutegirl": _3, "daa": _3, "deca": _3, "deci": _3, "digick": _3, "egoism": _3, "fakefur": _3, "fem": _3, "flier": _3, "floppy": _3, "fool": _3, "frenchkiss": _3, "girlfriend": _3, "girly": _3, "gloomy": _3, "gonna": _3, "greater": _3, "hacca": _3, "heavy": _3, "her": _3, "hiho": _3, "hippy": _3, "holy": _3, "hungry": _3, "icurus": _3, "itigo": _3, "jellybean": _3, "kikirara": _3, "kill": _3, "kilo": _3, "kuron": _3, "littlestar": _3, "lolipopmc": _3, "lolitapunk": _3, "lomo": _3, "lovepop": _3, "lovesick": _3, "main": _3, "mods": _3, "mond": _3, "mongolian": _3, "moo": _3, "namaste": _3, "nikita": _3, "nobushi": _3, "noor": _3, "oops": _3, "parallel": _3, "parasite": _3, "pecori": _3, "peewee": _3, "penne": _3, "pepper": _3, "perma": _3, "pigboat": _3, "pinoko": _3, "punyu": _3, "pupu": _3, "pussycat": _3, "pya": _3, "raindrop": _3, "readymade": _3, "sadist": _3, "schoolbus": _3, "secret": _3, "staba": _3, "stripper": _3, "sub": _3, "sunnyday": _3, "thick": _3, "tonkotsu": _3, "under": _3, "upper": _3, "velvet": _3, "verse": _3, "versus": _3, "vivian": _3, "watson": _3, "weblike": _3, "whitesnow": _3, "zombie": _3, "blogspot": _3, "2-d": _3, "bona": _3, "crap": _3, "daynight": _3, "eek": _3, "flop": _3, "halfmoon": _3, "jeez": _3, "matrix": _3, "mimoza": _3, "netgamers": _3, "nyanta": _3, "o0o0": _3, "rdy": _3, "rgr": _3, "rulez": _3, "sakurastorage": { "$": 0, "succ": { "isk01": _12, "isk02": _12 } }, "saloon": _3, "sblo": _3, "skr": _3, "tank": _3, "uh-oh": _3, "undo": _3, "webaccel": { "$": 0, "succ": { "rs": _3, "user": _3 } }, "websozai": _3, "xii": _3 } }, "ke": { "$": 1, "succ": { "ac": _2, "co": _6, "go": _2, "info": _2, "me": _2, "mobi": _2, "ne": _2, "or": _2, "sc": _2 } }, "kg": { "$": 1, "succ": { "org": _2, "net": _2, "com": _2, "edu": _2, "gov": _2, "mil": _2, "blog": _3, "io": _3, "jp": _3, "tv": _3, "uk": _3, "us": _3 } }, "kh": _8, "ki": _33, "km": { "$": 1, "succ": { "org": _2, "nom": _2, "gov": _2, "prd": _2, "tm": _2, "edu": _2, "mil": _2, "ass": _2, "com": _2, "coop": _2, "asso": _2, "presse": _2, "medecin": _2, "notaires": _2, "pharmaciens": _2, "veterinaire": _2, "gouv": _2 } }, "kn": { "$": 1, "succ": { "net": _2, "org": _2, "edu": _2, "gov": _2 } }, "kp": { "$": 1, "succ": { "com": _2, "edu": _2, "gov": _2, "org": _2, "rep": _2, "tra": _2 } }, "kr": { "$": 1, "succ": { "ac": _2, "co": _2, "es": _2, "go": _2, "hs": _2, "kg": _2, "mil": _2, "ms": _2, "ne": _2, "or": _2, "pe": _2, "re": _2, "sc": _2, "busan": _2, "chungbuk": _2, "chungnam": _2, "daegu": _2, "daejeon": _2, "gangwon": _2, "gwangju": _2, "gyeongbuk": _2, "gyeonggi": _2, "gyeongnam": _2, "incheon": _2, "jeju": _2, "jeonbuk": _2, "jeonnam": _2, "seoul": _2, "ulsan": _2, "blogspot": _3 } }, "kw": { "$": 1, "succ": { "com": _2, "edu": _2, "emb": _2, "gov": _2, "ind": _2, "net": _2, "org": _2 } }, "ky": _25, "kz": { "$": 1, "succ": { "org": _2, "edu": _2, "net": _2, "gov": _2, "mil": _2, "com": _2, "jcloud": _3, "kazteleport": { "$": 0, "succ": { "upaas": _3 } } } }, "la": { "$": 1, "succ": { "int": _2, "net": _2, "info": _2, "edu": _2, "gov": _2, "per": _2, "com": _2, "org": _2, "bnr": _3, "c": _3 } }, "lb": _4, "lc": { "$": 1, "succ": { "com": _2, "net": _2, "co": _2, "org": _2, "edu": _2, "gov": _2, "oy": _3 } }, "li": { "$": 1, "succ": { "blogspot": _3, "caa": _3 } }, "lk": { "$": 1, "succ": { "gov": _2, "sch": _2, "net": _2, "int": _2, "com": _2, "org": _2, "edu": _2, "ngo": _2, "soc": _2, "web": _2, "ltd": _2, "assn": _2, "grp": _2, "hotel": _2, "ac": _2 } }, "lr": _4, "ls": { "$": 1, "succ": { "ac": _2, "biz": _2, "co": _2, "edu": _2, "gov": _2, "info": _2, "net": _2, "org": _2, "sc": _2, "de": _3 } }, "lt": _34, "lu": { "$": 1, "succ": { "blogspot": _3, "123website": _3 } }, "lv": { "$": 1, "succ": { "com": _2, "edu": _2, "gov": _2, "org": _2, "mil": _2, "id": _2, "net": _2, "asn": _2, "conf": _2 } }, "ly": { "$": 1, "succ": { "com": _2, "net": _2, "gov": _2, "plc": _2, "edu": _2, "sch": _2, "med": _2, "org": _2, "id": _2 } }, "ma": { "$": 1, "succ": { "co": _2, "net": _2, "gov": _2, "org": _2, "ac": _2, "press": _2 } }, "mc": { "$": 1, "succ": { "tm": _2, "asso": _2 } }, "md": { "$": 1, "succ": { "blogspot": _3, "at": _3, "de": _3, "jp": _3, "to": _3 } }, "me": { "$": 1, "succ": { "co": _2, "net": _2, "org": _2, "edu": _2, "ac": _2, "gov": _2, "its": _2, "priv": _2, "c66": _3, "daplie": { "$": 2, "succ": { "localhost": _3 } }, "edgestack": _3, "filegear": _3, "filegear-au": _3, "filegear-de": _3, "filegear-gb": _3, "filegear-ie": _3, "filegear-jp": _3, "filegear-sg": _3, "glitch": _3, "ravendb": _3, "lohmus": _3, "barsy": _3, "mcpe": _3, "mcdir": _3, "soundcast": _3, "tcp4": _3, "brasilia": _3, "ddns": _3, "dnsfor": _3, "hopto": _3, "loginto": _3, "noip": _3, "webhop": _3, "vp4": _3, "diskstation": _3, "dscloud": _3, "i234": _3, "myds": _3, "synology": _3, "transip": _23, "wedeploy": _3, "yombo": _3, "nohost": _3 } }, "mg": { "$": 1, "succ": { "org": _2, "nom": _2, "gov": _2, "prd": _2, "tm": _2, "edu": _2, "mil": _2, "com": _2, "co": _2 } }, "mh": _2, "mil": _2, "mk": { "$": 1, "succ": { "com": _2, "org": _2, "net": _2, "edu": _2, "gov": _2, "inf": _2, "name": _2, "blogspot": _3 } }, "ml": { "$": 1, "succ": { "com": _2, "edu": _2, "gouv": _2, "gov": _2, "net": _2, "org": _2, "presse": _2 } }, "mm": _8, "mn": { "$": 1, "succ": { "gov": _2, "edu": _2, "org": _2, "nyc": _3 } }, "mo": _4, "mobi": { "$": 1, "succ": { "barsy": _3, "dscloud": _3 } }, "mp": { "$": 1, "succ": { "ju": _3 } }, "mq": _2, "mr": _34, "ms": { "$": 1, "succ": { "com": _2, "edu": _2, "gov": _2, "net": _2, "org": _2, "lab": _3, "minisite": _3 } }, "mt": { "$": 1, "succ": { "com": _6, "edu": _2, "net": _2, "org": _2 } }, "mu": { "$": 1, "succ": { "com": _2, "net": _2, "org": _2, "gov": _2, "ac": _2, "co": _2, "or": _2 } }, "museum": { "$": 1, "succ": { "academy": _2, "agriculture": _2, "air": _2, "airguard": _2, "alabama": _2, "alaska": _2, "amber": _2, "ambulance": _2, "american": _2, "americana": _2, "americanantiques": _2, "americanart": _2, "amsterdam": _2, "and": _2, "annefrank": _2, "anthro": _2, "anthropology": _2, "antiques": _2, "aquarium": _2, "arboretum": _2, "archaeological": _2, "archaeology": _2, "architecture": _2, "art": _2, "artanddesign": _2, "artcenter": _2, "artdeco": _2, "arteducation": _2, "artgallery": _2, "arts": _2, "artsandcrafts": _2, "asmatart": _2, "assassination": _2, "assisi": _2, "association": _2, "astronomy": _2, "atlanta": _2, "austin": _2, "australia": _2, "automotive": _2, "aviation": _2, "axis": _2, "badajoz": _2, "baghdad": _2, "bahn": _2, "bale": _2, "baltimore": _2, "barcelona": _2, "baseball": _2, "basel": _2, "baths": _2, "bauern": _2, "beauxarts": _2, "beeldengeluid": _2, "bellevue": _2, "bergbau": _2, "berkeley": _2, "berlin": _2, "bern": _2, "bible": _2, "bilbao": _2, "bill": _2, "birdart": _2, "birthplace": _2, "bonn": _2, "boston": _2, "botanical": _2, "botanicalgarden": _2, "botanicgarden": _2, "botany": _2, "brandywinevalley": _2, "brasil": _2, "bristol": _2, "british": _2, "britishcolumbia": _2, "broadcast": _2, "brunel": _2, "brussel": _2, "brussels": _2, "bruxelles": _2, "building": _2, "burghof": _2, "bus": _2, "bushey": _2, "cadaques": _2, "california": _2, "cambridge": _2, "can": _2, "canada": _2, "capebreton": _2, "carrier": _2, "cartoonart": _2, "casadelamoneda": _2, "castle": _2, "castres": _2, "celtic": _2, "center": _2, "chattanooga": _2, "cheltenham": _2, "chesapeakebay": _2, "chicago": _2, "children": _2, "childrens": _2, "childrensgarden": _2, "chiropractic": _2, "chocolate": _2, "christiansburg": _2, "cincinnati": _2, "cinema": _2, "circus": _2, "civilisation": _2, "civilization": _2, "civilwar": _2, "clinton": _2, "clock": _2, "coal": _2, "coastaldefence": _2, "cody": _2, "coldwar": _2, "collection": _2, "colonialwilliamsburg": _2, "coloradoplateau": _2, "columbia": _2, "columbus": _2, "communication": _2, "communications": _2, "community": _2, "computer": _2, "computerhistory": _2, "xn--comunicaes-v6a2o": _2, "comunicações": _2, "contemporary": _2, "contemporaryart": _2, "convent": _2, "copenhagen": _2, "corporation": _2, "xn--correios-e-telecomunicaes-ghc29a": _2, "correios-e-telecomunicações": _2, "corvette": _2, "costume": _2, "countryestate": _2, "county": _2, "crafts": _2, "cranbrook": _2, "creation": _2, "cultural": _2, "culturalcenter": _2, "culture": _2, "cyber": _2, "cymru": _2, "dali": _2, "dallas": _2, "database": _2, "ddr": _2, "decorativearts": _2, "delaware": _2, "delmenhorst": _2, "denmark": _2, "depot": _2, "design": _2, "detroit": _2, "dinosaur": _2, "discovery": _2, "dolls": _2, "donostia": _2, "durham": _2, "eastafrica": _2, "eastcoast": _2, "education": _2, "educational": _2, "egyptian": _2, "eisenbahn": _2, "elburg": _2, "elvendrell": _2, "embroidery": _2, "encyclopedic": _2, "england": _2, "entomology": _2, "environment": _2, "environmentalconservation": _2, "epilepsy": _2, "essex": _2, "estate": _2, "ethnology": _2, "exeter": _2, "exhibition": _2, "family": _2, "farm": _2, "farmequipment": _2, "farmers": _2, "farmstead": _2, "field": _2, "figueres": _2, "filatelia": _2, "film": _2, "fineart": _2, "finearts": _2, "finland": _2, "flanders": _2, "florida": _2, "force": _2, "fortmissoula": _2, "fortworth": _2, "foundation": _2, "francaise": _2, "frankfurt": _2, "franziskaner": _2, "freemasonry": _2, "freiburg": _2, "fribourg": _2, "frog": _2, "fundacio": _2, "furniture": _2, "gallery": _2, "garden": _2, "gateway": _2, "geelvinck": _2, "gemological": _2, "geology": _2, "georgia": _2, "giessen": _2, "glas": _2, "glass": _2, "gorge": _2, "grandrapids": _2, "graz": _2, "guernsey": _2, "halloffame": _2, "hamburg": _2, "handson": _2, "harvestcelebration": _2, "hawaii": _2, "health": _2, "heimatunduhren": _2, "hellas": _2, "helsinki": _2, "hembygdsforbund": _2, "heritage": _2, "histoire": _2, "historical": _2, "historicalsociety": _2, "historichouses": _2, "historisch": _2, "historisches": _2, "history": _2, "historyofscience": _2, "horology": _2, "house": _2, "humanities": _2, "illustration": _2, "imageandsound": _2, "indian": _2, "indiana": _2, "indianapolis": _2, "indianmarket": _2, "intelligence": _2, "interactive": _2, "iraq": _2, "iron": _2, "isleofman": _2, "jamison": _2, "jefferson": _2, "jerusalem": _2, "jewelry": _2, "jewish": _2, "jewishart": _2, "jfk": _2, "journalism": _2, "judaica": _2, "judygarland": _2, "juedisches": _2, "juif": _2, "karate": _2, "karikatur": _2, "kids": _2, "koebenhavn": _2, "koeln": _2, "kunst": _2, "kunstsammlung": _2, "kunstunddesign": _2, "labor": _2, "labour": _2, "lajolla": _2, "lancashire": _2, "landes": _2, "lans": _2, "xn--lns-qla": _2, "läns": _2, "larsson": _2, "lewismiller": _2, "lincoln": _2, "linz": _2, "living": _2, "livinghistory": _2, "localhistory": _2, "london": _2, "losangeles": _2, "louvre": _2, "loyalist": _2, "lucerne": _2, "luxembourg": _2, "luzern": _2, "mad": _2, "madrid": _2, "mallorca": _2, "manchester": _2, "mansion": _2, "mansions": _2, "manx": _2, "marburg": _2, "maritime": _2, "maritimo": _2, "maryland": _2, "marylhurst": _2, "media": _2, "medical": _2, "medizinhistorisches": _2, "meeres": _2, "memorial": _2, "mesaverde": _2, "michigan": _2, "midatlantic": _2, "military": _2, "mill": _2, "miners": _2, "mining": _2, "minnesota": _2, "missile": _2, "missoula": _2, "modern": _2, "moma": _2, "money": _2, "monmouth": _2, "monticello": _2, "montreal": _2, "moscow": _2, "motorcycle": _2, "muenchen": _2, "muenster": _2, "mulhouse": _2, "muncie": _2, "museet": _2, "museumcenter": _2, "museumvereniging": _2, "music": _2, "national": _2, "nationalfirearms": _2, "nationalheritage": _2, "nativeamerican": _2, "naturalhistory": _2, "naturalhistorymuseum": _2, "naturalsciences": _2, "nature": _2, "naturhistorisches": _2, "natuurwetenschappen": _2, "naumburg": _2, "naval": _2, "nebraska": _2, "neues": _2, "newhampshire": _2, "newjersey": _2, "newmexico": _2, "newport": _2, "newspaper": _2, "newyork": _2, "niepce": _2, "norfolk": _2, "north": _2, "nrw": _2, "nyc": _2, "nyny": _2, "oceanographic": _2, "oceanographique": _2, "omaha": _2, "online": _2, "ontario": _2, "openair": _2, "oregon": _2, "oregontrail": _2, "otago": _2, "oxford": _2, "pacific": _2, "paderborn": _2, "palace": _2, "paleo": _2, "palmsprings": _2, "panama": _2, "paris": _2, "pasadena": _2, "pharmacy": _2, "philadelphia": _2, "philadelphiaarea": _2, "philately": _2, "phoenix": _2, "photography": _2, "pilots": _2, "pittsburgh": _2, "planetarium": _2, "plantation": _2, "plants": _2, "plaza": _2, "portal": _2, "portland": _2, "portlligat": _2, "posts-and-telecommunications": _2, "preservation": _2, "presidio": _2, "press": _2, "project": _2, "public": _2, "pubol": _2, "quebec": _2, "railroad": _2, "railway": _2, "research": _2, "resistance": _2, "riodejaneiro": _2, "rochester": _2, "rockart": _2, "roma": _2, "russia": _2, "saintlouis": _2, "salem": _2, "salvadordali": _2, "salzburg": _2, "sandiego": _2, "sanfrancisco": _2, "santabarbara": _2, "santacruz": _2, "santafe": _2, "saskatchewan": _2, "satx": _2, "savannahga": _2, "schlesisches": _2, "schoenbrunn": _2, "schokoladen": _2, "school": _2, "schweiz": _2, "science": _2, "scienceandhistory": _2, "scienceandindustry": _2, "sciencecenter": _2, "sciencecenters": _2, "science-fiction": _2, "sciencehistory": _2, "sciences": _2, "sciencesnaturelles": _2, "scotland": _2, "seaport": _2, "settlement": _2, "settlers": _2, "shell": _2, "sherbrooke": _2, "sibenik": _2, "silk": _2, "ski": _2, "skole": _2, "society": _2, "sologne": _2, "soundandvision": _2, "southcarolina": _2, "southwest": _2, "space": _2, "spy": _2, "square": _2, "stadt": _2, "stalbans": _2, "starnberg": _2, "state": _2, "stateofdelaware": _2, "station": _2, "steam": _2, "steiermark": _2, "stjohn": _2, "stockholm": _2, "stpetersburg": _2, "stuttgart": _2, "suisse": _2, "surgeonshall": _2, "surrey": _2, "svizzera": _2, "sweden": _2, "sydney": _2, "tank": _2, "tcm": _2, "technology": _2, "telekommunikation": _2, "television": _2, "texas": _2, "textile": _2, "theater": _2, "time": _2, "timekeeping": _2, "topology": _2, "torino": _2, "touch": _2, "town": _2, "transport": _2, "tree": _2, "trolley": _2, "trust": _2, "trustee": _2, "uhren": _2, "ulm": _2, "undersea": _2, "university": _2, "usa": _2, "usantiques": _2, "usarts": _2, "uscountryestate": _2, "usculture": _2, "usdecorativearts": _2, "usgarden": _2, "ushistory": _2, "ushuaia": _2, "uslivinghistory": _2, "utah": _2, "uvic": _2, "valley": _2, "vantaa": _2, "versailles": _2, "viking": _2, "village": _2, "virginia": _2, "virtual": _2, "virtuel": _2, "vlaanderen": _2, "volkenkunde": _2, "wales": _2, "wallonie": _2, "war": _2, "washingtondc": _2, "watchandclock": _2, "watch-and-clock": _2, "western": _2, "westfalen": _2, "whaling": _2, "wildlife": _2, "williamsburg": _2, "windmill": _2, "workshop": _2, "york": _2, "yorkshire": _2, "yosemite": _2, "youth": _2, "zoological": _2, "zoology": _2, "xn--9dbhblg6di": _2, "ירושלים": _2, "xn--h1aegh": _2, "иком": _2 } }, "mv": { "$": 1, "succ": { "aero": _2, "biz": _2, "com": _2, "coop": _2, "edu": _2, "gov": _2, "info": _2, "int": _2, "mil": _2, "museum": _2, "name": _2, "net": _2, "org": _2, "pro": _2 } }, "mw": { "$": 1, "succ": { "ac": _2, "biz": _2, "co": _2, "com": _2, "coop": _2, "edu": _2, "gov": _2, "int": _2, "museum": _2, "net": _2, "org": _2 } }, "mx": { "$": 1, "succ": { "com": _2, "org": _2, "gob": _2, "edu": _2, "net": _2, "blogspot": _3 } }, "my": { "$": 1, "succ": { "biz": _2, "com": _2, "edu": _2, "gov": _2, "mil": _2, "name": _2, "net": _2, "org": _2, "blogspot": _3 } }, "mz": { "$": 1, "succ": { "ac": _2, "adv": _2, "co": _2, "edu": _2, "gov": _2, "mil": _2, "net": _2, "org": _2 } }, "na": { "$": 1, "succ": { "info": _2, "pro": _2, "name": _2, "school": _2, "or": _2, "dr": _2, "us": _2, "mx": _2, "ca": _2, "in": _2, "cc": _2, "tv": _2, "ws": _2, "mobi": _2, "co": _2, "com": _2, "org": _2 } }, "name": { "$": 1, "succ": { "her": _37, "his": _37 } }, "nc": { "$": 1, "succ": { "asso": _2, "nom": _2 } }, "ne": _2, "net": { "$": 1, "succ": { "adobeaemcloud": _3, "adobeio-static": _3, "adobeioruntime": _3, "akadns": _3, "akamai": _3, "akamai-staging": _3, "akamaiedge": _3, "akamaiedge-staging": _3, "akamaihd": _3, "akamaihd-staging": _3, "akamaiorigin": _3, "akamaiorigin-staging": _3, "akamaized": _3, "akamaized-staging": _3, "edgekey": _3, "edgekey-staging": _3, "edgesuite": _3, "edgesuite-staging": _3, "alwaysdata": _3, "myamaze": _3, "cloudfront": _3, "t3l3p0rt": _3, "appudo": _3, "atlassian-dev": { "$": 0, "succ": { "prod": { "$": 0, "succ": { "cdn": _3 } } } }, "myfritz": _3, "onavstack": _3, "shopselect": _3, "blackbaudcdn": _3, "boomla": _3, "bplaced": _3, "square7": _3, "gb": _3, "hu": _3, "jp": _3, "se": _3, "uk": _3, "in": _3, "clickrising": _3, "cloudaccess": _3, "cdn77-ssl": _3, "cdn77": { "$": 0, "succ": { "r": _3 } }, "feste-ip": _3, "knx-server": _3, "static-access": _3, "cryptonomic": _5, "dattolocal": _3, "mydatto": _3, "debian": _3, "bitbridge": _3, "at-band-camp": _3, "blogdns": _3, "broke-it": _3, "buyshouses": _3, "dnsalias": _3, "dnsdojo": _3, "does-it": _3, "dontexist": _3, "dynalias": _3, "dynathome": _3, "endofinternet": _3, "from-az": _3, "from-co": _3, "from-la": _3, "from-ny": _3, "gets-it": _3, "ham-radio-op": _3, "homeftp": _3, "homeip": _3, "homelinux": _3, "homeunix": _3, "in-the-band": _3, "is-a-chef": _3, "is-a-geek": _3, "isa-geek": _3, "kicks-ass": _3, "office-on-the": _3, "podzone": _3, "scrapper-site": _3, "selfip": _3, "sells-it": _3, "servebbs": _3, "serveftp": _3, "thruhere": _3, "webhop": _3, "definima": _3, "casacam": _3, "dynu": _3, "dynv6": _3, "twmail": _3, "ru": _3, "channelsdvr": { "$": 2, "succ": { "u": _3 } }, "fastlylb": { "$": 2, "succ": { "map": _3 } }, "fastly": { "$": 0, "succ": { "freetls": _3, "map": _3, "prod": { "$": 0, "succ": { "a": _3, "global": _3 } }, "ssl": { "$": 0, "succ": { "a": _3, "b": _3, "global": _3 } } } }, "edgeapp": _3, "flynnhosting": _3, "cdn-edges": _3, "heteml": _3, "cloudfunctions": _3, "moonscale": _3, "in-dsl": _3, "in-vpn": _3, "ipifony": _3, "iobb": _3, "cloudjiffy": { "$": 2, "succ": { "fra1-de": _3, "west1-us": _3 } }, "elastx": { "$": 0, "succ": { "jls-sto1": _3, "jls-sto2": _3, "jls-sto3": _3 } }, "faststacks": _3, "massivegrid": { "$": 0, "succ": { "paas": { "$": 0, "succ": { "fr-1": _3, "lon-1": _3, "lon-2": _3, "ny-1": _3, "ny-2": _3, "sg-1": _3 } } } }, "saveincloud": { "$": 0, "succ": { "jelastic": _3, "nordeste-idc": _3 } }, "scaleforce": _26, "tsukaeru": _27, "kinghost": _3, "uni5": _3, "krellian": _3, "barsy": _3, "memset": _3, "azurewebsites": _3, "azure-mobile": _3, "cloudapp": _3, "azurestaticapps": { "$": 2, "succ": { "1": _3, "2": _3, "3": _3, "centralus": _3, "eastasia": _3, "eastus2": _3, "westeurope": _3, "westus2": _3 } }, "dnsup": _3, "hicam": _3, "now-dns": _3, "ownip": _3, "vpndns": _3, "eating-organic": _3, "mydissent": _3, "myeffect": _3, "mymediapc": _3, "mypsx": _3, "mysecuritycamera": _3, "nhlfan": _3, "no-ip": _3, "pgafan": _3, "privatizehealthinsurance": _3, "bounceme": _3, "ddns": _3, "redirectme": _3, "serveblog": _3, "serveminecraft": _3, "sytes": _3, "cloudycluster": _3, "ovh": { "$": 0, "succ": { "webpaas": _5, "hosting": _5 } }, "bar0": _3, "bar1": _3, "bar2": _3, "rackmaze": _3, "squares": _3, "schokokeks": _3, "firewall-gateway": _3, "seidat": _3, "senseering": _3, "siteleaf": _3, "vps-host": { "$": 2, "succ": { "jelastic": { "$": 0, "succ": { "atl": _3, "njs": _3, "ric": _3 } } } }, "myspreadshop": _3, "srcf": { "$": 0, "succ": { "soc": _3, "user": _3 } }, "supabase": _3, "dsmynas": _3, "familyds": _3, "tailscale": { "$": 0, "succ": { "beta": _3 } }, "ts": _3, "torproject": { "$": 2, "succ": { "pages": _3 } }, "reserve-online": _3, "community-pro": _3, "meinforum": _3, "yandexcloud": { "$": 2, "succ": { "storage": _3, "website": _3 } }, "za": _3 } }, "nf": { "$": 1, "succ": { "com": _2, "net": _2, "per": _2, "rec": _2, "web": _2, "arts": _2, "firm": _2, "info": _2, "other": _2, "store": _2 } }, "ng": { "$": 1, "succ": { "com": _6, "edu": _2, "gov": _2, "i": _2, "mil": _2, "mobi": _2, "name": _2, "net": _2, "org": _2, "sch": _2, "col": _3, "firm": _3, "gen": _3, "ltd": _3, "ngo": _3 } }, "ni": { "$": 1, "succ": { "ac": _2, "biz": _2, "co": _2, "com": _2, "edu": _2, "gob": _2, "in": _2, "info": _2, "int": _2, "mil": _2, "net": _2, "nom": _2, "org": _2, "web": _2 } }, "nl": { "$": 1, "succ": { "co": _3, "hosting-cluster": _3, "blogspot": _3, "gov": _3, "khplay": _3, "123website": _3, "myspreadshop": _3, "transurl": _5, "cistron": _3, "demon": _3 } }, "no": { "$": 1, "succ": { "fhs": _2, "vgs": _2, "fylkesbibl": _2, "folkebibl": _2, "museum": _2, "idrett": _2, "priv": _2, "mil": _2, "stat": _2, "dep": _2, "kommune": _2, "herad": _2, "aa": _38, "ah": _38, "bu": _38, "fm": _38, "hl": _38, "hm": _38, "jan-mayen": _38, "mr": _38, "nl": _38, "nt": _38, "of": _38, "ol": _38, "oslo": _38, "rl": _38, "sf": _38, "st": _38, "svalbard": _38, "tm": _38, "tr": _38, "va": _38, "vf": _38, "akrehamn": _2, "xn--krehamn-dxa": _2, "åkrehamn": _2, "algard": _2, "xn--lgrd-poac": _2, "ålgård": _2, "arna": _2, "brumunddal": _2, "bryne": _2, "bronnoysund": _2, "xn--brnnysund-m8ac": _2, "brønnøysund": _2, "drobak": _2, "xn--drbak-wua": _2, "drøbak": _2, "egersund": _2, "fetsund": _2, "floro": _2, "xn--flor-jra": _2, "florø": _2, "fredrikstad": _2, "hokksund": _2, "honefoss": _2, "xn--hnefoss-q1a": _2, "hønefoss": _2, "jessheim": _2, "jorpeland": _2, "xn--jrpeland-54a": _2, "jørpeland": _2, "kirkenes": _2, "kopervik": _2, "krokstadelva": _2, "langevag": _2, "xn--langevg-jxa": _2, "langevåg": _2, "leirvik": _2, "mjondalen": _2, "xn--mjndalen-64a": _2, "mjøndalen": _2, "mo-i-rana": _2, "mosjoen": _2, "xn--mosjen-eya": _2, "mosjøen": _2, "nesoddtangen": _2, "orkanger": _2, "osoyro": _2, "xn--osyro-wua": _2, "osøyro": _2, "raholt": _2, "xn--rholt-mra": _2, "råholt": _2, "sandnessjoen": _2, "xn--sandnessjen-ogb": _2, "sandnessjøen": _2, "skedsmokorset": _2, "slattum": _2, "spjelkavik": _2, "stathelle": _2, "stavern": _2, "stjordalshalsen": _2, "xn--stjrdalshalsen-sqb": _2, "stjørdalshalsen": _2, "tananger": _2, "tranby": _2, "vossevangen": _2, "afjord": _2, "xn--fjord-lra": _2, "åfjord": _2, "agdenes": _2, "al": _2, "xn--l-1fa": _2, "ål": _2, "alesund": _2, "xn--lesund-hua": _2, "ålesund": _2, "alstahaug": _2, "alta": _2, "xn--lt-liac": _2, "áltá": _2, "alaheadju": _2, "xn--laheadju-7ya": _2, "álaheadju": _2, "alvdal": _2, "amli": _2, "xn--mli-tla": _2, "åmli": _2, "amot": _2, "xn--mot-tla": _2, "åmot": _2, "andebu": _2, "andoy": _2, "xn--andy-ira": _2, "andøy": _2, "andasuolo": _2, "ardal": _2, "xn--rdal-poa": _2, "årdal": _2, "aremark": _2, "arendal": _2, "xn--s-1fa": _2, "ås": _2, "aseral": _2, "xn--seral-lra": _2, "åseral": _2, "asker": _2, "askim": _2, "askvoll": _2, "askoy": _2, "xn--asky-ira": _2, "askøy": _2, "asnes": _2, "xn--snes-poa": _2, "åsnes": _2, "audnedaln": _2, "aukra": _2, "aure": _2, "aurland": _2, "aurskog-holand": _2, "xn--aurskog-hland-jnb": _2, "aurskog-høland": _2, "austevoll": _2, "austrheim": _2, "averoy": _2, "xn--avery-yua": _2, "averøy": _2, "balestrand": _2, "ballangen": _2, "balat": _2, "xn--blt-elab": _2, "bálát": _2, "balsfjord": _2, "bahccavuotna": _2, "xn--bhccavuotna-k7a": _2, "báhccavuotna": _2, "bamble": _2, "bardu": _2, "beardu": _2, "beiarn": _2, "bajddar": _2, "xn--bjddar-pta": _2, "bájddar": _2, "baidar": _2, "xn--bidr-5nac": _2, "báidár": _2, "berg": _2, "bergen": _2, "berlevag": _2, "xn--berlevg-jxa": _2, "berlevåg": _2, "bearalvahki": _2, "xn--bearalvhki-y4a": _2, "bearalváhki": _2, "bindal": _2, "birkenes": _2, "bjarkoy": _2, "xn--bjarky-fya": _2, "bjarkøy": _2, "bjerkreim": _2, "bjugn": _2, "bodo": _2, "xn--bod-2na": _2, "bodø": _2, "badaddja": _2, "xn--bdddj-mrabd": _2, "bådåddjå": _2, "budejju": _2, "bokn": _2, "bremanger": _2, "bronnoy": _2, "xn--brnny-wuac": _2, "brønnøy": _2, "bygland": _2, "bykle": _2, "barum": _2, "xn--brum-voa": _2, "bærum": _2, "telemark": { "$": 0, "succ": { "bo": _2, "xn--b-5ga": _2, "bø": _2 } }, "nordland": { "$": 0, "succ": { "bo": _2, "xn--b-5ga": _2, "bø": _2, "heroy": _2, "xn--hery-ira": _2, "herøy": _2 } }, "bievat": _2, "xn--bievt-0qa": _2, "bievát": _2, "bomlo": _2, "xn--bmlo-gra": _2, "bømlo": _2, "batsfjord": _2, "xn--btsfjord-9za": _2, "båtsfjord": _2, "bahcavuotna": _2, "xn--bhcavuotna-s4a": _2, "báhcavuotna": _2, "dovre": _2, "drammen": _2, "drangedal": _2, "dyroy": _2, "xn--dyry-ira": _2, "dyrøy": _2, "donna": _2, "xn--dnna-gra": _2, "dønna": _2, "eid": _2, "eidfjord": _2, "eidsberg": _2, "eidskog": _2, "eidsvoll": _2, "eigersund": _2, "elverum": _2, "enebakk": _2, "engerdal": _2, "etne": _2, "etnedal": _2, "evenes": _2, "evenassi": _2, "xn--eveni-0qa01ga": _2, "evenášši": _2, "evje-og-hornnes": _2, "farsund": _2, "fauske": _2, "fuossko": _2, "fuoisku": _2, "fedje": _2, "fet": _2, "finnoy": _2, "xn--finny-yua": _2, "finnøy": _2, "fitjar": _2, "fjaler": _2, "fjell": _2, "flakstad": _2, "flatanger": _2, "flekkefjord": _2, "flesberg": _2, "flora": _2, "fla": _2, "xn--fl-zia": _2, "flå": _2, "folldal": _2, "forsand": _2, "fosnes": _2, "frei": _2, "frogn": _2, "froland": _2, "frosta": _2, "frana": _2, "xn--frna-woa": _2, "fræna": _2, "froya": _2, "xn--frya-hra": _2, "frøya": _2, "fusa": _2, "fyresdal": _2, "forde": _2, "xn--frde-gra": _2, "førde": _2, "gamvik": _2, "gangaviika": _2, "xn--ggaviika-8ya47h": _2, "gáŋgaviika": _2, "gaular": _2, "gausdal": _2, "gildeskal": _2, "xn--gildeskl-g0a": _2, "gildeskål": _2, "giske": _2, "gjemnes": _2, "gjerdrum": _2, "gjerstad": _2, "gjesdal": _2, "gjovik": _2, "xn--gjvik-wua": _2, "gjøvik": _2, "gloppen": _2, "gol": _2, "gran": _2, "grane": _2, "granvin": _2, "gratangen": _2, "grimstad": _2, "grong": _2, "kraanghke": _2, "xn--kranghke-b0a": _2, "kråanghke": _2, "grue": _2, "gulen": _2, "hadsel": _2, "halden": _2, "halsa": _2, "hamar": _2, "hamaroy": _2, "habmer": _2, "xn--hbmer-xqa": _2, "hábmer": _2, "hapmir": _2, "xn--hpmir-xqa": _2, "hápmir": _2, "hammerfest": _2, "hammarfeasta": _2, "xn--hmmrfeasta-s4ac": _2, "hámmárfeasta": _2, "haram": _2, "hareid": _2, "harstad": _2, "hasvik": _2, "aknoluokta": _2, "xn--koluokta-7ya57h": _2, "ákŋoluokta": _2, "hattfjelldal": _2, "aarborte": _2, "haugesund": _2, "hemne": _2, "hemnes": _2, "hemsedal": _2, "more-og-romsdal": { "$": 0, "succ": { "heroy": _2, "sande": _2 } }, "xn--mre-og-romsdal-qqb": { "$": 0, "succ": { "xn--hery-ira": _2, "sande": _2 } }, "møre-og-romsdal": { "$": 0, "succ": { "herøy": _2, "sande": _2 } }, "hitra": _2, "hjartdal": _2, "hjelmeland": _2, "hobol": _2, "xn--hobl-ira": _2, "hobøl": _2, "hof": _2, "hol": _2, "hole": _2, "holmestrand": _2, "holtalen": _2, "xn--holtlen-hxa": _2, "holtålen": _2, "hornindal": _2, "horten": _2, "hurdal": _2, "hurum": _2, "hvaler": _2, "hyllestad": _2, "hagebostad": _2, "xn--hgebostad-g3a": _2, "hægebostad": _2, "hoyanger": _2, "xn--hyanger-q1a": _2, "høyanger": _2, "hoylandet": _2, "xn--hylandet-54a": _2, "høylandet": _2, "ha": _2, "xn--h-2fa": _2, "hå": _2, "ibestad": _2, "inderoy": _2, "xn--indery-fya": _2, "inderøy": _2, "iveland": _2, "jevnaker": _2, "jondal": _2, "jolster": _2, "xn--jlster-bya": _2, "jølster": _2, "karasjok": _2, "karasjohka": _2, "xn--krjohka-hwab49j": _2, "kárášjohka": _2, "karlsoy": _2, "galsa": _2, "xn--gls-elac": _2, "gálsá": _2, "karmoy": _2, "xn--karmy-yua": _2, "karmøy": _2, "kautokeino": _2, "guovdageaidnu": _2, "klepp": _2, "klabu": _2, "xn--klbu-woa": _2, "klæbu": _2, "kongsberg": _2, "kongsvinger": _2, "kragero": _2, "xn--krager-gya": _2, "kragerø": _2, "kristiansand": _2, "kristiansund": _2, "krodsherad": _2, "xn--krdsherad-m8a": _2, "krødsherad": _2, "kvalsund": _2, "rahkkeravju": _2, "xn--rhkkervju-01af": _2, "ráhkkerávju": _2, "kvam": _2, "kvinesdal": _2, "kvinnherad": _2, "kviteseid": _2, "kvitsoy": _2, "xn--kvitsy-fya": _2, "kvitsøy": _2, "kvafjord": _2, "xn--kvfjord-nxa": _2, "kvæfjord": _2, "giehtavuoatna": _2, "kvanangen": _2, "xn--kvnangen-k0a": _2, "kvænangen": _2, "navuotna": _2, "xn--nvuotna-hwa": _2, "návuotna": _2, "kafjord": _2, "xn--kfjord-iua": _2, "kåfjord": _2, "gaivuotna": _2, "xn--givuotna-8ya": _2, "gáivuotna": _2, "larvik": _2, "lavangen": _2, "lavagis": _2, "loabat": _2, "xn--loabt-0qa": _2, "loabát": _2, "lebesby": _2, "davvesiida": _2, "leikanger": _2, "leirfjord": _2, "leka": _2, "leksvik": _2, "lenvik": _2, "leangaviika": _2, "xn--leagaviika-52b": _2, "leaŋgaviika": _2, "lesja": _2, "levanger": _2, "lier": _2, "lierne": _2, "lillehammer": _2, "lillesand": _2, "lindesnes": _2, "lindas": _2, "xn--linds-pra": _2, "lindås": _2, "lom": _2, "loppa": _2, "lahppi": _2, "xn--lhppi-xqa": _2, "láhppi": _2, "lund": _2, "lunner": _2, "luroy": _2, "xn--lury-ira": _2, "lurøy": _2, "luster": _2, "lyngdal": _2, "lyngen": _2, "ivgu": _2, "lardal": _2, "lerdal": _2, "xn--lrdal-sra": _2, "lærdal": _2, "lodingen": _2, "xn--ldingen-q1a": _2, "lødingen": _2, "lorenskog": _2, "xn--lrenskog-54a": _2, "lørenskog": _2, "loten": _2, "xn--lten-gra": _2, "løten": _2, "malvik": _2, "masoy": _2, "xn--msy-ula0h": _2, "måsøy": _2, "muosat": _2, "xn--muost-0qa": _2, "muosát": _2, "mandal": _2, "marker": _2, "marnardal": _2, "masfjorden": _2, "meland": _2, "meldal": _2, "melhus": _2, "meloy": _2, "xn--mely-ira": _2, "meløy": _2, "meraker": _2, "xn--merker-kua": _2, "meråker": _2, "moareke": _2, "xn--moreke-jua": _2, "moåreke": _2, "midsund": _2, "midtre-gauldal": _2, "modalen": _2, "modum": _2, "molde": _2, "moskenes": _2, "moss": _2, "mosvik": _2, "malselv": _2, "xn--mlselv-iua": _2, "målselv": _2, "malatvuopmi": _2, "xn--mlatvuopmi-s4a": _2, "málatvuopmi": _2, "namdalseid": _2, "aejrie": _2, "namsos": _2, "namsskogan": _2, "naamesjevuemie": _2, "xn--nmesjevuemie-tcba": _2, "nååmesjevuemie": _2, "laakesvuemie": _2, "nannestad": _2, "narvik": _2, "narviika": _2, "naustdal": _2, "nedre-eiker": _2, "akershus": _39, "buskerud": _39, "nesna": _2, "nesodden": _2, "nesseby": _2, "unjarga": _2, "xn--unjrga-rta": _2, "unjárga": _2, "nesset": _2, "nissedal": _2, "nittedal": _2, "nord-aurdal": _2, "nord-fron": _2, "nord-odal": _2, "norddal": _2, "nordkapp": _2, "davvenjarga": _2, "xn--davvenjrga-y4a": _2, "davvenjárga": _2, "nordre-land": _2, "nordreisa": _2, "raisa": _2, "xn--risa-5na": _2, "ráisa": _2, "nore-og-uvdal": _2, "notodden": _2, "naroy": _2, "xn--nry-yla5g": _2, "nærøy": _2, "notteroy": _2, "xn--nttery-byae": _2, "nøtterøy": _2, "odda": _2, "oksnes": _2, "xn--ksnes-uua": _2, "øksnes": _2, "oppdal": _2, "oppegard": _2, "xn--oppegrd-ixa": _2, "oppegård": _2, "orkdal": _2, "orland": _2, "xn--rland-uua": _2, "ørland": _2, "orskog": _2, "xn--rskog-uua": _2, "ørskog": _2, "orsta": _2, "xn--rsta-fra": _2, "ørsta": _2, "hedmark": { "$": 0, "succ": { "os": _2, "valer": _2, "xn--vler-qoa": _2, "våler": _2 } }, "hordaland": { "$": 0, "succ": { "os": _2 } }, "osen": _2, "osteroy": _2, "xn--ostery-fya": _2, "osterøy": _2, "ostre-toten": _2, "xn--stre-toten-zcb": _2, "østre-toten": _2, "overhalla": _2, "ovre-eiker": _2, "xn--vre-eiker-k8a": _2, "øvre-eiker": _2, "oyer": _2, "xn--yer-zna": _2, "øyer": _2, "oygarden": _2, "xn--ygarden-p1a": _2, "øygarden": _2, "oystre-slidre": _2, "xn--ystre-slidre-ujb": _2, "øystre-slidre": _2, "porsanger": _2, "porsangu": _2, "xn--porsgu-sta26f": _2, "porsáŋgu": _2, "porsgrunn": _2, "radoy": _2, "xn--rady-ira": _2, "radøy": _2, "rakkestad": _2, "rana": _2, "ruovat": _2, "randaberg": _2, "rauma": _2, "rendalen": _2, "rennebu": _2, "rennesoy": _2, "xn--rennesy-v1a": _2, "rennesøy": _2, "rindal": _2, "ringebu": _2, "ringerike": _2, "ringsaker": _2, "rissa": _2, "risor": _2, "xn--risr-ira": _2, "risør": _2, "roan": _2, "rollag": _2, "rygge": _2, "ralingen": _2, "xn--rlingen-mxa": _2, "rælingen": _2, "rodoy": _2, "xn--rdy-0nab": _2, "rødøy": _2, "romskog": _2, "xn--rmskog-bya": _2, "rømskog": _2, "roros": _2, "xn--rros-gra": _2, "røros": _2, "rost": _2, "xn--rst-0na": _2, "røst": _2, "royken": _2, "xn--ryken-vua": _2, "røyken": _2, "royrvik": _2, "xn--ryrvik-bya": _2, "røyrvik": _2, "rade": _2, "xn--rde-ula": _2, "råde": _2, "salangen": _2, "siellak": _2, "saltdal": _2, "salat": _2, "xn--slt-elab": _2, "sálát": _2, "xn--slat-5na": _2, "sálat": _2, "samnanger": _2, "vestfold": { "$": 0, "succ": { "sande": _2 } }, "sandefjord": _2, "sandnes": _2, "sandoy": _2, "xn--sandy-yua": _2, "sandøy": _2, "sarpsborg": _2, "sauda": _2, "sauherad": _2, "sel": _2, "selbu": _2, "selje": _2, "seljord": _2, "sigdal": _2, "siljan": _2, "sirdal": _2, "skaun": _2, "skedsmo": _2, "ski": _2, "skien": _2, "skiptvet": _2, "skjervoy": _2, "xn--skjervy-v1a": _2, "skjervøy": _2, "skierva": _2, "xn--skierv-uta": _2, "skiervá": _2, "skjak": _2, "xn--skjk-soa": _2, "skjåk": _2, "skodje": _2, "skanland": _2, "xn--sknland-fxa": _2, "skånland": _2, "skanit": _2, "xn--sknit-yqa": _2, "skánit": _2, "smola": _2, "xn--smla-hra": _2, "smøla": _2, "snillfjord": _2, "snasa": _2, "xn--snsa-roa": _2, "snåsa": _2, "snoasa": _2, "snaase": _2, "xn--snase-nra": _2, "snåase": _2, "sogndal": _2, "sokndal": _2, "sola": _2, "solund": _2, "songdalen": _2, "sortland": _2, "spydeberg": _2, "stange": _2, "stavanger": _2, "steigen": _2, "steinkjer": _2, "stjordal": _2, "xn--stjrdal-s1a": _2, "stjørdal": _2, "stokke": _2, "stor-elvdal": _2, "stord": _2, "stordal": _2, "storfjord": _2, "omasvuotna": _2, "strand": _2, "stranda": _2, "stryn": _2, "sula": _2, "suldal": _2, "sund": _2, "sunndal": _2, "surnadal": _2, "sveio": _2, "svelvik": _2, "sykkylven": _2, "sogne": _2, "xn--sgne-gra": _2, "søgne": _2, "somna": _2, "xn--smna-gra": _2, "sømna": _2, "sondre-land": _2, "xn--sndre-land-0cb": _2, "søndre-land": _2, "sor-aurdal": _2, "xn--sr-aurdal-l8a": _2, "sør-aurdal": _2, "sor-fron": _2, "xn--sr-fron-q1a": _2, "sør-fron": _2, "sor-odal": _2, "xn--sr-odal-q1a": _2, "sør-odal": _2, "sor-varanger": _2, "xn--sr-varanger-ggb": _2, "sør-varanger": _2, "matta-varjjat": _2, "xn--mtta-vrjjat-k7af": _2, "mátta-várjjat": _2, "sorfold": _2, "xn--srfold-bya": _2, "sørfold": _2, "sorreisa": _2, "xn--srreisa-q1a": _2, "sørreisa": _2, "sorum": _2, "xn--srum-gra": _2, "sørum": _2, "tana": _2, "deatnu": _2, "time": _2, "tingvoll": _2, "tinn": _2, "tjeldsund": _2, "dielddanuorri": _2, "tjome": _2, "xn--tjme-hra": _2, "tjøme": _2, "tokke": _2, "tolga": _2, "torsken": _2, "tranoy": _2, "xn--trany-yua": _2, "tranøy": _2, "tromso": _2, "xn--troms-zua": _2, "tromsø": _2, "tromsa": _2, "romsa": _2, "trondheim": _2, "troandin": _2, "trysil": _2, "trana": _2, "xn--trna-woa": _2, "træna": _2, "trogstad": _2, "xn--trgstad-r1a": _2, "trøgstad": _2, "tvedestrand": _2, "tydal": _2, "tynset": _2, "tysfjord": _2, "divtasvuodna": _2, "divttasvuotna": _2, "tysnes": _2, "tysvar": _2, "xn--tysvr-vra": _2, "tysvær": _2, "tonsberg": _2, "xn--tnsberg-q1a": _2, "tønsberg": _2, "ullensaker": _2, "ullensvang": _2, "ulvik": _2, "utsira": _2, "vadso": _2, "xn--vads-jra": _2, "vadsø": _2, "cahcesuolo": _2, "xn--hcesuolo-7ya35b": _2, "čáhcesuolo": _2, "vaksdal": _2, "valle": _2, "vang": _2, "vanylven": _2, "vardo": _2, "xn--vard-jra": _2, "vardø": _2, "varggat": _2, "xn--vrggt-xqad": _2, "várggát": _2, "vefsn": _2, "vaapste": _2, "vega": _2, "vegarshei": _2, "xn--vegrshei-c0a": _2, "vegårshei": _2, "vennesla": _2, "verdal": _2, "verran": _2, "vestby": _2, "vestnes": _2, "vestre-slidre": _2, "vestre-toten": _2, "vestvagoy": _2, "xn--vestvgy-ixa6o": _2, "vestvågøy": _2, "vevelstad": _2, "vik": _2, "vikna": _2, "vindafjord": _2, "volda": _2, "voss": _2, "varoy": _2, "xn--vry-yla5g": _2, "værøy": _2, "vagan": _2, "xn--vgan-qoa": _2, "vågan": _2, "voagat": _2, "vagsoy": _2, "xn--vgsy-qoa0j": _2, "vågsøy": _2, "vaga": _2, "xn--vg-yiab": _2, "vågå": _2, "ostfold": { "$": 0, "succ": { "valer": _2 } }, "xn--stfold-9xa": { "$": 0, "succ": { "xn--vler-qoa": _2 } }, "østfold": { "$": 0, "succ": { "våler": _2 } }, "co": _3, "blogspot": _3, "123hjemmeside": _3, "myspreadshop": _3 } }, "np": _8, "nr": _33, "nu": { "$": 1, "succ": { "merseine": _3, "mine": _3, "shacknet": _3, "enterprisecloud": _3 } }, "nz": { "$": 1, "succ": { "ac": _2, "co": _6, "cri": _2, "geek": _2, "gen": _2, "govt": _2, "health": _2, "iwi": _2, "kiwi": _2, "maori": _2, "mil": _2, "xn--mori-qsa": _2, "māori": _2, "net": _2, "org": _2, "parliament": _2, "school": _2 } }, "om": { "$": 1, "succ": { "co": _2, "com": _2, "edu": _2, "gov": _2, "med": _2, "museum": _2, "net": _2, "org": _2, "pro": _2 } }, "onion": _2, "org": { "$": 1, "succ": { "altervista": _3, "amune": { "$": 0, "succ": { "tele": _3 } }, "pimienta": _3, "poivron": _3, "potager": _3, "sweetpepper": _3, "ae": _3, "us": _3, "certmgr": _3, "cdn77": { "$": 0, "succ": { "c": _3, "rsc": _3 } }, "cdn77-secure": { "$": 0, "succ": { "origin": { "$": 0, "succ": { "ssl": _3 } } } }, "cloudns": _3, "duckdns": _3, "tunk": _3, "dyndns": { "$": 2, "succ": { "go": _3, "home": _3 } }, "blogdns": _3, "blogsite": _3, "boldlygoingnowhere": _3, "dnsalias": _3, "dnsdojo": _3, "doesntexist": _3, "dontexist": _3, "doomdns": _3, "dvrdns": _3, "dynalias": _3, "endofinternet": _3, "endoftheinternet": _3, "from-me": _3, "game-host": _3, "gotdns": _3, "hobby-site": _3, "homedns": _3, "homeftp": _3, "homelinux": _3, "homeunix": _3, "is-a-bruinsfan": _3, "is-a-candidate": _3, "is-a-celticsfan": _3, "is-a-chef": _3, "is-a-geek": _3, "is-a-knight": _3, "is-a-linux-user": _3, "is-a-patsfan": _3, "is-a-soxfan": _3, "is-found": _3, "is-lost": _3, "is-saved": _3, "is-very-bad": _3, "is-very-evil": _3, "is-very-good": _3, "is-very-nice": _3, "is-very-sweet": _3, "isa-geek": _3, "kicks-ass": _3, "misconfused": _3, "podzone": _3, "readmyblog": _3, "selfip": _3, "sellsyourhome": _3, "servebbs": _3, "serveftp": _3, "servegame": _3, "stuff-4-sale": _3, "webhop": _3, "ddnss": _3, "accesscam": _3, "camdvr": _3, "freeddns": _3, "mywire": _3, "webredirect": _3, "eu": { "$": 2, "succ": { "al": _3, "asso": _3, "at": _3, "au": _3, "be": _3, "bg": _3, "ca": _3, "cd": _3, "ch": _3, "cn": _3, "cy": _3, "cz": _3, "de": _3, "dk": _3, "edu": _3, "ee": _3, "es": _3, "fi": _3, "fr": _3, "gr": _3, "hr": _3, "hu": _3, "ie": _3, "il": _3, "in": _3, "int": _3, "is": _3, "it": _3, "jp": _3, "kr": _3, "lt": _3, "lu": _3, "lv": _3, "mc": _3, "me": _3, "mk": _3, "mt": _3, "my": _3, "net": _3, "ng": _3, "nl": _3, "no": _3, "nz": _3, "paris": _3, "pl": _3, "pt": _3, "q-a": _3, "ro": _3, "ru": _3, "se": _3, "si": _3, "sk": _3, "tr": _3, "uk": _3, "us": _3 } }, "twmail": _3, "fedorainfracloud": _3, "fedorapeople": _3, "fedoraproject": { "$": 0, "succ": { "cloud": _3, "os": _21, "stg": { "$": 0, "succ": { "os": _21 } } } }, "freedesktop": _3, "hepforge": _3, "in-dsl": _3, "in-vpn": _3, "js": _3, "barsy": _3, "mayfirst": _3, "mozilla-iot": _3, "bmoattachments": _3, "dynserv": _3, "now-dns": _3, "cable-modem": _3, "collegefan": _3, "couchpotatofries": _3, "mlbfan": _3, "mysecuritycamera": _3, "nflfan": _3, "read-books": _3, "ufcfan": _3, "hopto": _3, "myftp": _3, "no-ip": _3, "zapto": _3, "httpbin": _3, "pubtls": _3, "jpn": _3, "my-firewall": _3, "myfirewall": _3, "spdns": _3, "small-web": _3, "dsmynas": _3, "familyds": _3, "teckids": _12, "tuxfamily": _3, "diskstation": _3, "hk": _3, "wmflabs": _3, "toolforge": _3, "wmcloud": _3, "za": _3 } }, "pa": { "$": 1, "succ": { "ac": _2, "gob": _2, "com": _2, "org": _2, "sld": _2, "edu": _2, "net": _2, "ing": _2, "abo": _2, "med": _2, "nom": _2 } }, "pe": { "$": 1, "succ": { "edu": _2, "gob": _2, "nom": _2, "mil": _2, "org": _2, "com": _2, "net": _2, "blogspot": _3 } }, "pf": { "$": 1, "succ": { "com": _2, "org": _2, "edu": _2 } }, "pg": _8, "ph": { "$": 1, "succ": { "com": _2, "net": _2, "org": _2, "gov": _2, "edu": _2, "ngo": _2, "mil": _2, "i": _2 } }, "pk": { "$": 1, "succ": { "com": _2, "net": _2, "edu": _2, "org": _2, "fam": _2, "biz": _2, "web": _2, "gov": _2, "gob": _2, "gok": _2, "gon": _2, "gop": _2, "gos": _2, "info": _2 } }, "pl": { "$": 1, "succ": { "com": _2, "net": _2, "org": _2, "aid": _2, "agro": _2, "atm": _2, "auto": _2, "biz": _2, "edu": _2, "gmina": _2, "gsm": _2, "info": _2, "mail": _2, "miasta": _2, "media": _2, "mil": _2, "nieruchomosci": _2, "nom": _2, "pc": _2, "powiat": _2, "priv": _2, "realestate": _2, "rel": _2, "sex": _2, "shop": _2, "sklep": _2, "sos": _2, "szkola": _2, "targi": _2, "tm": _2, "tourism": _2, "travel": _2, "turystyka": _2, "gov": { "$": 1, "succ": { "ap": _2, "ic": _2, "is": _2, "us": _2, "kmpsp": _2, "kppsp": _2, "kwpsp": _2, "psp": _2, "wskr": _2, "kwp": _2, "mw": _2, "ug": _2, "um": _2, "umig": _2, "ugim": _2, "upow": _2, "uw": _2, "starostwo": _2, "pa": _2, "po": _2, "psse": _2, "pup": _2, "rzgw": _2, "sa": _2, "so": _2, "sr": _2, "wsa": _2, "sko": _2, "uzs": _2, "wiih": _2, "winb": _2, "pinb": _2, "wios": _2, "witd": _2, "wzmiuw": _2, "piw": _2, "wiw": _2, "griw": _2, "wif": _2, "oum": _2, "sdn": _2, "zp": _2, "uppo": _2, "mup": _2, "wuoz": _2, "konsulat": _2, "oirm": _2 } }, "augustow": _2, "babia-gora": _2, "bedzin": _2, "beskidy": _2, "bialowieza": _2, "bialystok": _2, "bielawa": _2, "bieszczady": _2, "boleslawiec": _2, "bydgoszcz": _2, "bytom": _2, "cieszyn": _2, "czeladz": _2, "czest": _2, "dlugoleka": _2, "elblag": _2, "elk": _2, "glogow": _2, "gniezno": _2, "gorlice": _2, "grajewo": _2, "ilawa": _2, "jaworzno": _2, "jelenia-gora": _2, "jgora": _2, "kalisz": _2, "kazimierz-dolny": _2, "karpacz": _2, "kartuzy": _2, "kaszuby": _2, "katowice": _2, "kepno": _2, "ketrzyn": _2, "klodzko": _2, "kobierzyce": _2, "kolobrzeg": _2, "konin": _2, "konskowola": _2, "kutno": _2, "lapy": _2, "lebork": _2, "legnica": _2, "lezajsk": _2, "limanowa": _2, "lomza": _2, "lowicz": _2, "lubin": _2, "lukow": _2, "malbork": _2, "malopolska": _2, "mazowsze": _2, "mazury": _2, "mielec": _2, "mielno": _2, "mragowo": _2, "naklo": _2, "nowaruda": _2, "nysa": _2, "olawa": _2, "olecko": _2, "olkusz": _2, "olsztyn": _2, "opoczno": _2, "opole": _2, "ostroda": _2, "ostroleka": _2, "ostrowiec": _2, "ostrowwlkp": _2, "pila": _2, "pisz": _2, "podhale": _2, "podlasie": _2, "polkowice": _2, "pomorze": _2, "pomorskie": _2, "prochowice": _2, "pruszkow": _2, "przeworsk": _2, "pulawy": _2, "radom": _2, "rawa-maz": _2, "rybnik": _2, "rzeszow": _2, "sanok": _2, "sejny": _2, "slask": _2, "slupsk": _2, "sosnowiec": _2, "stalowa-wola": _2, "skoczow": _2, "starachowice": _2, "stargard": _2, "suwalki": _2, "swidnica": _2, "swiebodzin": _2, "swinoujscie": _2, "szczecin": _2, "szczytno": _2, "tarnobrzeg": _2, "tgory": _2, "turek": _2, "tychy": _2, "ustka": _2, "walbrzych": _2, "warmia": _2, "warszawa": _2, "waw": _2, "wegrow": _2, "wielun": _2, "wlocl": _2, "wloclawek": _2, "wodzislaw": _2, "wolomin": _2, "wroclaw": _2, "zachpomor": _2, "zagan": _2, "zarow": _2, "zgora": _2, "zgorzelec": _2, "beep": _3, "ecommerce-shop": _3, "shoparena": _3, "homesklep": _3, "sdscloud": _3, "unicloud": _3, "krasnik": _3, "leczna": _3, "lubartow": _3, "lublin": _3, "poniatowa": _3, "swidnik": _3, "co": _3, "simplesite": _3, "art": _3, "gliwice": _3, "krakow": _3, "poznan": _3, "wroc": _3, "zakopane": _3, "myspreadshop": _3, "gda": _3, "gdansk": _3, "gdynia": _3, "med": _3, "sopot": _3 } }, "pm": { "$": 1, "succ": { "own": _3, "name": _3 } }, "pn": { "$": 1, "succ": { "gov": _2, "co": _2, "org": _2, "edu": _2, "net": _2 } }, "post": _2, "pr": { "$": 1, "succ": { "com": _2, "net": _2, "org": _2, "gov": _2, "edu": _2, "isla": _2, "pro": _2, "biz": _2, "info": _2, "name": _2, "est": _2, "prof": _2, "ac": _2 } }, "pro": { "$": 1, "succ": { "aaa": _2, "aca": _2, "acct": _2, "avocat": _2, "bar": _2, "cpa": _2, "eng": _2, "jur": _2, "law": _2, "med": _2, "recht": _2, "cloudns": _3, "dnstrace": { "$": 0, "succ": { "bci": _3 } }, "barsy": _3 } }, "ps": { "$": 1, "succ": { "edu": _2, "gov": _2, "sec": _2, "plo": _2, "com": _2, "org": _2, "net": _2 } }, "pt": { "$": 1, "succ": { "net": _2, "gov": _2, "org": _2, "edu": _2, "int": _2, "publ": _2, "com": _2, "nome": _2, "blogspot": _3, "123paginaweb": _3 } }, "pw": { "$": 1, "succ": { "co": _2, "ne": _2, "or": _2, "ed": _2, "go": _2, "belau": _2, "cloudns": _3, "x443": _3 } }, "py": { "$": 1, "succ": { "com": _2, "coop": _2, "edu": _2, "gov": _2, "mil": _2, "net": _2, "org": _2 } }, "qa": { "$": 1, "succ": { "com": _2, "edu": _2, "gov": _2, "mil": _2, "name": _2, "net": _2, "org": _2, "sch": _2, "blogspot": _3 } }, "re": { "$": 1, "succ": { "asso": _2, "com": _2, "nom": _2, "blogspot": _3 } }, "ro": { "$": 1, "succ": { "arts": _2, "com": _2, "firm": _2, "info": _2, "nom": _2, "nt": _2, "org": _2, "rec": _2, "store": _2, "tm": _2, "www": _2, "co": _3, "shop": _3, "blogspot": _3, "barsy": _3 } }, "rs": { "$": 1, "succ": { "ac": _2, "co": _2, "edu": _2, "gov": _2, "in": _2, "org": _2, "brendly": { "$": 0, "succ": { "shop": _3 } }, "blogspot": _3, "ua": _3, "ox": _3 } }, "ru": { "$": 1, "succ": { "ac": _3, "edu": _3, "gov": _3, "int": _3, "mil": _3, "test": _3, "eurodir": _3, "adygeya": _3, "bashkiria": _3, "bir": _3, "cbg": _3, "com": _3, "dagestan": _3, "grozny": _3, "kalmykia": _3, "kustanai": _3, "marine": _3, "mordovia": _3, "msk": _3, "mytis": _3, "nalchik": _3, "nov": _3, "pyatigorsk": _3, "spb": _3, "vladikavkaz": _3, "vladimir": _3, "blogspot": _3, "na4u": _3, "mircloud": _3, "regruhosting": _27, "myjino": { "$": 2, "succ": { "hosting": _5, "landing": _5, "spectrum": _5, "vps": _5 } }, "cldmail": { "$": 0, "succ": { "hb": _3 } }, "mcdir": { "$": 2, "succ": { "vps": _3 } }, "mcpre": _3, "net": _3, "org": _3, "pp": _3, "123sait": _3, "lk3": _3, "ras": _3 } }, "rw": { "$": 1, "succ": { "ac": _2, "co": _2, "coop": _2, "gov": _2, "mil": _2, "net": _2, "org": _2 } }, "sa": { "$": 1, "succ": { "com": _2, "net": _2, "org": _2, "gov": _2, "med": _2, "pub": _2, "edu": _2, "sch": _2 } }, "sb": _4, "sc": _4, "sd": { "$": 1, "succ": { "com": _2, "net": _2, "org": _2, "edu": _2, "med": _2, "tv": _2, "gov": _2, "info": _2 } }, "se": { "$": 1, "succ": { "a": _2, "ac": _2, "b": _2, "bd": _2, "brand": _2, "c": _2, "d": _2, "e": _2, "f": _2, "fh": _2, "fhsk": _2, "fhv": _2, "g": _2, "h": _2, "i": _2, "k": _2, "komforb": _2, "kommunalforbund": _2, "komvux": _2, "l": _2, "lanbib": _2, "m": _2, "n": _2, "naturbruksgymn": _2, "o": _2, "org": _2, "p": _2, "parti": _2, "pp": _2, "press": _2, "r": _2, "s": _2, "t": _2, "tm": _2, "u": _2, "w": _2, "x": _2, "y": _2, "z": _2, "com": _3, "blogspot": _3, "conf": _3, "iopsys": _3, "123minsida": _3, "itcouldbewor": _3, "myspreadshop": _3, "paba": { "$": 0, "succ": { "su": _3 } } } }, "sg": { "$": 1, "succ": { "com": _2, "net": _2, "org": _2, "gov": _2, "edu": _2, "per": _2, "blogspot": _3, "enscaled": _3 } }, "sh": { "$": 1, "succ": { "com": _2, "net": _2, "gov": _2, "org": _2, "mil": _2, "bip": _3, "hashbang": _3, "platform": { "$": 0, "succ": { "bc": _3, "ent": _3, "eu": _3, "us": _3 } }, "now": _3, "vxl": _3, "wedeploy": _3 } }, "si": { "$": 1, "succ": { "gitapp": _3, "gitpage": _3, "blogspot": _3 } }, "sj": _2, "sk": _6, "sl": _4, "sm": _2, "sn": { "$": 1, "succ": { "art": _2, "com": _2, "edu": _2, "gouv": _2, "org": _2, "perso": _2, "univ": _2, "blogspot": _3 } }, "so": { "$": 1, "succ": { "com": _2, "edu": _2, "gov": _2, "me": _2, "net": _2, "org": _2, "sch": _3 } }, "sr": _2, "ss": { "$": 1, "succ": { "biz": _2, "com": _2, "edu": _2, "gov": _2, "me": _2, "net": _2, "org": _2, "sch": _2 } }, "st": { "$": 1, "succ": { "co": _2, "com": _2, "consulado": _2, "edu": _2, "embaixada": _2, "mil": _2, "net": _2, "org": _2, "principe": _2, "saotome": _2, "store": _2, "kirara": _3, "noho": _3 } }, "su": { "$": 1, "succ": { "abkhazia": _3, "adygeya": _3, "aktyubinsk": _3, "arkhangelsk": _3, "armenia": _3, "ashgabad": _3, "azerbaijan": _3, "balashov": _3, "bashkiria": _3, "bryansk": _3, "bukhara": _3, "chimkent": _3, "dagestan": _3, "east-kazakhstan": _3, "exnet": _3, "georgia": _3, "grozny": _3, "ivanovo": _3, "jambyl": _3, "kalmykia": _3, "kaluga": _3, "karacol": _3, "karaganda": _3, "karelia": _3, "khakassia": _3, "krasnodar": _3, "kurgan": _3, "kustanai": _3, "lenug": _3, "mangyshlak": _3, "mordovia": _3, "msk": _3, "murmansk": _3, "nalchik": _3, "navoi": _3, "north-kazakhstan": _3, "nov": _3, "obninsk": _3, "penza": _3, "pokrovsk": _3, "sochi": _3, "spb": _3, "tashkent": _3, "termez": _3, "togliatti": _3, "troitsk": _3, "tselinograd": _3, "tula": _3, "tuva": _3, "vladikavkaz": _3, "vladimir": _3, "vologda": _3 } }, "sv": { "$": 1, "succ": { "com": _2, "edu": _2, "gob": _2, "org": _2, "red": _2 } }, "sx": _7, "sy": _32, "sz": { "$": 1, "succ": { "co": _2, "ac": _2, "org": _2 } }, "tc": { "$": 1, "succ": { "ch": _3, "me": _3, "we": _3 } }, "td": _6, "tel": _2, "tf": { "$": 1, "succ": { "sch": _3 } }, "tg": _2, "th": { "$": 1, "succ": { "ac": _2, "co": _2, "go": _2, "in": _2, "mi": _2, "net": _2, "or": _2, "online": _3, "shop": _3 } }, "tj": { "$": 1, "succ": { "ac": _2, "biz": _2, "co": _2, "com": _2, "edu": _2, "go": _2, "gov": _2, "int": _2, "mil": _2, "name": _2, "net": _2, "nic": _2, "org": _2, "test": _2, "web": _2 } }, "tk": _2, "tl": _7, "tm": { "$": 1, "succ": { "com": _2, "co": _2, "org": _2, "net": _2, "nom": _2, "gov": _2, "mil": _2, "edu": _2 } }, "tn": { "$": 1, "succ": { "com": _2, "ens": _2, "fin": _2, "gov": _2, "ind": _2, "info": _2, "intl": _2, "mincom": _2, "nat": _2, "net": _2, "org": _2, "perso": _2, "tourism": _2, "orangecloud": _3 } }, "to": { "$": 1, "succ": { "611": _3, "com": _2, "gov": _2, "net": _2, "org": _2, "edu": _2, "mil": _2, "oya": _3, "rdv": _3, "x0": _3, "vpnplus": _3, "quickconnect": _13, "nyan": _3 } }, "tr": { "$": 1, "succ": { "av": _2, "bbs": _2, "bel": _2, "biz": _2, "com": _6, "dr": _2, "edu": _2, "gen": _2, "gov": _2, "info": _2, "mil": _2, "k12": _2, "kep": _2, "name": _2, "net": _2, "org": _2, "pol": _2, "tel": _2, "tsk": _2, "tv": _2, "web": _2, "nc": _7 } }, "tt": { "$": 1, "succ": { "co": _2, "com": _2, "org": _2, "net": _2, "biz": _2, "info": _2, "pro": _2, "int": _2, "coop": _2, "jobs": _2, "mobi": _2, "travel": _2, "museum": _2, "aero": _2, "name": _2, "gov": _2, "edu": _2 } }, "tv": { "$": 1, "succ": { "dyndns": _3, "better-than": _3, "on-the-web": _3, "worse-than": _3, "from": _3, "sakura": _3 } }, "tw": { "$": 1, "succ": { "edu": _2, "gov": _2, "mil": _2, "com": { "$": 1, "succ": { "mymailer": _3 } }, "net": _2, "org": _2, "idv": _2, "game": _2, "ebiz": _2, "club": _2, "xn--zf0ao64a": _2, "網路": _2, "xn--uc0atv": _2, "組織": _2, "xn--czrw28b": _2, "商業": _2, "url": _3, "blogspot": _3 } }, "tz": { "$": 1, "succ": { "ac": _2, "co": _2, "go": _2, "hotel": _2, "info": _2, "me": _2, "mil": _2, "mobi": _2, "ne": _2, "or": _2, "sc": _2, "tv": _2 } }, "ua": { "$": 1, "succ": { "com": _2, "edu": _2, "gov": _2, "in": _2, "net": _2, "org": _2, "cherkassy": _2, "cherkasy": _2, "chernigov": _2, "chernihiv": _2, "chernivtsi": _2, "chernovtsy": _2, "ck": _2, "cn": _2, "cr": _2, "crimea": _2, "cv": _2, "dn": _2, "dnepropetrovsk": _2, "dnipropetrovsk": _2, "donetsk": _2, "dp": _2, "if": _2, "ivano-frankivsk": _2, "kh": _2, "kharkiv": _2, "kharkov": _2, "kherson": _2, "khmelnitskiy": _2, "khmelnytskyi": _2, "kiev": _2, "kirovograd": _2, "km": _2, "kr": _2, "krym": _2, "ks": _2, "kv": _2, "kyiv": _2, "lg": _2, "lt": _2, "lugansk": _2, "lutsk": _2, "lv": _2, "lviv": _2, "mk": _2, "mykolaiv": _2, "nikolaev": _2, "od": _2, "odesa": _2, "odessa": _2, "pl": _2, "poltava": _2, "rivne": _2, "rovno": _2, "rv": _2, "sb": _2, "sebastopol": _2, "sevastopol": _2, "sm": _2, "sumy": _2, "te": _2, "ternopil": _2, "uz": _2, "uzhgorod": _2, "vinnica": _2, "vinnytsia": _2, "vn": _2, "volyn": _2, "yalta": _2, "zaporizhzhe": _2, "zaporizhzhia": _2, "zhitomir": _2, "zhytomyr": _2, "zp": _2, "zt": _2, "cc": _3, "inf": _3, "ltd": _3, "cx": _3, "ie": _3, "biz": _3, "co": _3, "pp": _3, "v": _3 } }, "ug": { "$": 1, "succ": { "co": _2, "or": _2, "ac": _2, "sc": _2, "go": _2, "ne": _2, "com": _2, "org": _2, "blogspot": _3 } }, "uk": { "$": 1, "succ": { "ac": _2, "co": { "$": 1, "succ": { "bytemark": { "$": 0, "succ": { "dh": _3, "vm": _3 } }, "blogspot": _3, "layershift": _26, "barsy": _3, "barsyonline": _3, "retrosnub": _31, "nh-serv": _3, "no-ip": _3, "wellbeingzone": _3, "adimo": _3, "myspreadshop": _3 } }, "gov": { "$": 1, "succ": { "campaign": _3, "service": _3, "api": _3, "homeoffice": _3 } }, "ltd": _2, "me": _2, "net": _2, "nhs": _2, "org": { "$": 1, "succ": { "glug": _3, "lug": _3, "lugs": _3, "affinitylottery": _3, "raffleentry": _3, "weeklylottery": _3 } }, "plc": _2, "police": _2, "sch": _8, "conn": _3, "copro": _3, "hosp": _3, "independent-commission": _3, "independent-inquest": _3, "independent-inquiry": _3, "independent-panel": _3, "independent-review": _3, "public-inquiry": _3, "royal-commission": _3, "pymnt": _3, "barsy": _3 } }, "us": { "$": 1, "succ": { "dni": _2, "fed": _2, "isa": _2, "kids": _2, "nsn": _2, "ak": _40, "al": _40, "ar": _40, "as": _40, "az": _40, "ca": _40, "co": _40, "ct": _40, "dc": _40, "de": { "$": 1, "succ": { "k12": _2, "cc": _2, "lib": _3 } }, "fl": _40, "ga": _40, "gu": _40, "hi": _41, "ia": _40, "id": _40, "il": _40, "in": _40, "ks": _40, "ky": _40, "la": _40, "ma": { "$": 1, "succ": { "k12": { "$": 1, "succ": { "pvt": _2, "chtr": _2, "paroch": _2 } }, "cc": _2, "lib": _2 } }, "md": _40, "me": _40, "mi": { "$": 1, "succ": { "k12": _2, "cc": _2, "lib": _2, "ann-arbor": _2, "cog": _2, "dst": _2, "eaton": _2, "gen": _2, "mus": _2, "tec": _2, "washtenaw": _2 } }, "mn": _40, "mo": _40, "ms": _40, "mt": _40, "nc": _40, "nd": _41, "ne": _40, "nh": _40, "nj": _40, "nm": _40, "nv": _40, "ny": _40, "oh": _40, "ok": _40, "or": _40, "pa": _40, "pr": _40, "ri": _41, "sc": _40, "sd": _41, "tn": _40, "tx": _40, "ut": _40, "vi": _40, "vt": _40, "va": _40, "wa": _40, "wi": _40, "wv": { "$": 1, "succ": { "cc": _2 } }, "wy": _40, "graphox": _3, "cloudns": _3, "drud": _3, "is-by": _3, "land-4-sale": _3, "stuff-4-sale": _3, "enscaled": { "$": 0, "succ": { "phx": _3 } }, "mircloud": _3, "freeddns": _3, "golffan": _3, "noip": _3, "pointto": _3, "platterp": _3 } }, "uy": { "$": 1, "succ": { "com": _6, "edu": _2, "gub": _2, "mil": _2, "net": _2, "org": _2 } }, "uz": { "$": 1, "succ": { "co": _2, "com": _2, "net": _2, "org": _2 } }, "va": _2, "vc": { "$": 1, "succ": { "com": _2, "net": _2, "org": _2, "gov": _2, "mil": _2, "edu": _2, "gv": { "$": 2, "succ": { "d": _3 } }, "0e": _3 } }, "ve": { "$": 1, "succ": { "arts": _2, "bib": _2, "co": _2, "com": _2, "e12": _2, "edu": _2, "firm": _2, "gob": _2, "gov": _2, "info": _2, "int": _2, "mil": _2, "net": _2, "nom": _2, "org": _2, "rar": _2, "rec": _2, "store": _2, "tec": _2, "web": _2 } }, "vg": { "$": 1, "succ": { "at": _3 } }, "vi": { "$": 1, "succ": { "co": _2, "com": _2, "k12": _2, "net": _2, "org": _2 } }, "vn": { "$": 1, "succ": { "com": _2, "net": _2, "org": _2, "edu": _2, "gov": _2, "int": _2, "ac": _2, "biz": _2, "info": _2, "name": _2, "pro": _2, "health": _2, "blogspot": _3 } }, "vu": { "$": 1, "succ": { "com": _2, "edu": _2, "net": _2, "org": _2, "cn": _3, "blog": _3, "dev": _3, "me": _3 } }, "wf": { "$": 1, "succ": { "biz": _3, "sch": _3 } }, "ws": { "$": 1, "succ": { "com": _2, "net": _2, "org": _2, "gov": _2, "edu": _2, "advisor": _5, "cloud66": _3, "dyndns": _3, "mypets": _3 } }, "yt": { "$": 1, "succ": { "org": _3 } }, "xn--mgbaam7a8h": _2, "امارات": _2, "xn--y9a3aq": _2, "հայ": _2, "xn--54b7fta0cc": _2, "বাংলা": _2, "xn--90ae": _2, "бг": _2, "xn--mgbcpq6gpa1a": _2, "البحرين": _2, "xn--90ais": _2, "бел": _2, "xn--fiqs8s": _2, "中国": _2, "xn--fiqz9s": _2, "中國": _2, "xn--lgbbat1ad8j": _2, "الجزائر": _2, "xn--wgbh1c": _2, "مصر": _2, "xn--e1a4c": _2, "ею": _2, "xn--qxa6a": _2, "ευ": _2, "xn--mgbah1a3hjkrd": _2, "موريتانيا": _2, "xn--node": _2, "გე": _2, "xn--qxam": _2, "ελ": _2, "xn--j6w193g": { "$": 1, "succ": { "xn--55qx5d": _2, "xn--wcvs22d": _2, "xn--mxtq1m": _2, "xn--gmqw5a": _2, "xn--od0alg": _2, "xn--uc0atv": _2 } }, "香港": { "$": 1, "succ": { "公司": _2, "教育": _2, "政府": _2, "個人": _2, "網絡": _2, "組織": _2 } }, "xn--2scrj9c": _2, "ಭಾರತ": _2, "xn--3hcrj9c": _2, "ଭାରତ": _2, "xn--45br5cyl": _2, "ভাৰত": _2, "xn--h2breg3eve": _2, "भारतम्": _2, "xn--h2brj9c8c": _2, "भारोत": _2, "xn--mgbgu82a": _2, "ڀارت": _2, "xn--rvc1e0am3e": _2, "ഭാരതം": _2, "xn--h2brj9c": _2, "भारत": _2, "xn--mgbbh1a": _2, "بارت": _2, "xn--mgbbh1a71e": _2, "بھارت": _2, "xn--fpcrj9c3d": _2, "భారత్": _2, "xn--gecrj9c": _2, "ભારત": _2, "xn--s9brj9c": _2, "ਭਾਰਤ": _2, "xn--45brj9c": _2, "ভারত": _2, "xn--xkc2dl3a5ee0h": _2, "இந்தியா": _2, "xn--mgba3a4f16a": _2, "ایران": _2, "xn--mgba3a4fra": _2, "ايران": _2, "xn--mgbtx2b": _2, "عراق": _2, "xn--mgbayh7gpa": _2, "الاردن": _2, "xn--3e0b707e": _2, "한국": _2, "xn--80ao21a": _2, "қаз": _2, "xn--q7ce6a": _2, "ລາວ": _2, "xn--fzc2c9e2c": _2, "ලංකා": _2, "xn--xkc2al3hye2a": _2, "இலங்கை": _2, "xn--mgbc0a9azcg": _2, "المغرب": _2, "xn--d1alf": _2, "мкд": _2, "xn--l1acc": _2, "мон": _2, "xn--mix891f": _2, "澳門": _2, "xn--mix082f": _2, "澳门": _2, "xn--mgbx4cd0ab": _2, "مليسيا": _2, "xn--mgb9awbf": _2, "عمان": _2, "xn--mgbai9azgqp6j": _2, "پاکستان": _2, "xn--mgbai9a5eva00b": _2, "پاكستان": _2, "xn--ygbi2ammx": _2, "فلسطين": _2, "xn--90a3ac": { "$": 1, "succ": { "xn--o1ac": _2, "xn--c1avg": _2, "xn--90azh": _2, "xn--d1at": _2, "xn--o1ach": _2, "xn--80au": _2 } }, "срб": { "$": 1, "succ": { "пр": _2, "орг": _2, "обр": _2, "од": _2, "упр": _2, "ак": _2 } }, "xn--p1ai": _2, "рф": _2, "xn--wgbl6a": _2, "قطر": _2, "xn--mgberp4a5d4ar": _2, "السعودية": _2, "xn--mgberp4a5d4a87g": _2, "السعودیة": _2, "xn--mgbqly7c0a67fbc": _2, "السعودیۃ": _2, "xn--mgbqly7cvafr": _2, "السعوديه": _2, "xn--mgbpl2fh": _2, "سودان": _2, "xn--yfro4i67o": _2, "新加坡": _2, "xn--clchc0ea0b2g2a9gcd": _2, "சிங்கப்பூர்": _2, "xn--ogbpf8fl": _2, "سورية": _2, "xn--mgbtf8fl": _2, "سوريا": _2, "xn--o3cw4h": { "$": 1, "succ": { "xn--12c1fe0br": _2, "xn--12co0c3b4eva": _2, "xn--h3cuzk1di": _2, "xn--o3cyx2a": _2, "xn--m3ch0j3a": _2, "xn--12cfi8ixb8l": _2 } }, "ไทย": { "$": 1, "succ": { "ศึกษา": _2, "ธุรกิจ": _2, "รัฐบาล": _2, "ทหาร": _2, "เน็ต": _2, "องค์กร": _2 } }, "xn--pgbs0dh": _2, "تونس": _2, "xn--kpry57d": _2, "台灣": _2, "xn--kprw13d": _2, "台湾": _2, "xn--nnx388a": _2, "臺灣": _2, "xn--j1amh": _2, "укр": _2, "xn--mgb2ddes": _2, "اليمن": _2, "xxx": _2, "ye": _32, "za": { "$": 0, "succ": { "ac": _2, "agric": _2, "alt": _2, "co": _6, "edu": _2, "gov": _2, "grondar": _2, "law": _2, "mil": _2, "net": _2, "ngo": _2, "nic": _2, "nis": _2, "nom": _2, "org": _2, "school": _2, "tm": _2, "web": _2 } }, "zm": { "$": 1, "succ": { "ac": _2, "biz": _2, "co": _2, "com": _2, "edu": _2, "gov": _2, "info": _2, "mil": _2, "net": _2, "org": _2, "sch": _2 } }, "zw": { "$": 1, "succ": { "ac": _2, "co": _2, "gov": _2, "mil": _2, "org": _2 } }, "aaa": _2, "aarp": _2, "abarth": _2, "abb": _2, "abbott": _2, "abbvie": _2, "abc": _2, "able": _2, "abogado": _2, "abudhabi": _2, "academy": { "$": 1, "succ": { "official": _3 } }, "accenture": _2, "accountant": _2, "accountants": _2, "aco": _2, "actor": _2, "ads": _2, "adult": _2, "aeg": _2, "aetna": _2, "afl": _2, "africa": _2, "agakhan": _2, "agency": _2, "aig": _2, "airbus": _2, "airforce": _2, "airtel": _2, "akdn": _2, "alfaromeo": _2, "alibaba": _2, "alipay": _2, "allfinanz": _2, "allstate": _2, "ally": _2, "alsace": _2, "alstom": _2, "amazon": _2, "americanexpress": _2, "americanfamily": _2, "amex": _2, "amfam": _2, "amica": _2, "amsterdam": _2, "analytics": _2, "android": _2, "anquan": _2, "anz": _2, "aol": _2, "apartments": _2, "app": { "$": 1, "succ": { "beget": _5, "clerk": _3, "clerkstage": _3, "wnext": _3, "platform0": _3, "deta": _3, "ondigitalocean": _3, "easypanel": _3, "encr": _3, "edgecompute": _3, "fireweb": _3, "onflashdrive": _3, "framer": _3, "run": { "$": 2, "succ": { "a": _3 } }, "web": _3, "hasura": _3, "loginline": _3, "messerli": _3, "netlify": _3, "ngrok": _3, "ngrok-free": _3, "developer": _5, "noop": _3, "northflank": _5, "snowflake": { "$": 2, "succ": { "privatelink": _3 } }, "streamlit": _3, "telebit": _3, "typedream": _3, "vercel": _3, "bookonline": _3 } }, "apple": _2, "aquarelle": _2, "arab": _2, "aramco": _2, "archi": _2, "army": _2, "art": _2, "arte": _2, "asda": _2, "associates": _2, "athleta": _2, "attorney": _2, "auction": _2, "audi": _2, "audible": _2, "audio": _2, "auspost": _2, "author": _2, "auto": _2, "autos": _2, "avianca": _2, "aws": _2, "axa": _2, "azure": _2, "baby": _2, "baidu": _2, "banamex": _2, "bananarepublic": _2, "band": _2, "bank": _2, "bar": _2, "barcelona": _2, "barclaycard": _2, "barclays": _2, "barefoot": _2, "bargains": _2, "baseball": _2, "basketball": { "$": 1, "succ": { "aus": _3, "nz": _3 } }, "bauhaus": _2, "bayern": _2, "bbc": _2, "bbt": _2, "bbva": _2, "bcg": _2, "bcn": _2, "beats": _2, "beauty": _2, "beer": _2, "bentley": _2, "berlin": _2, "best": _2, "bestbuy": _2, "bet": _2, "bharti": _2, "bible": _2, "bid": _2, "bike": _2, "bing": _2, "bingo": _2, "bio": _2, "black": _2, "blackfriday": _2, "blockbuster": _2, "blog": _2, "bloomberg": _2, "blue": _2, "bms": _2, "bmw": _2, "bnpparibas": _2, "boats": _2, "boehringer": _2, "bofa": _2, "bom": _2, "bond": _2, "boo": _2, "book": _2, "booking": _2, "bosch": _2, "bostik": _2, "boston": _2, "bot": _2, "boutique": _2, "box": _2, "bradesco": _2, "bridgestone": _2, "broadway": _2, "broker": _2, "brother": _2, "brussels": _2, "build": _2, "builders": { "$": 1, "succ": { "cloudsite": _3 } }, "business": _10, "buy": _2, "buzz": _2, "bzh": _2, "cab": _2, "cafe": _2, "cal": _2, "call": _2, "calvinklein": _2, "cam": _2, "camera": _2, "camp": _2, "canon": _2, "capetown": _2, "capital": _2, "capitalone": _2, "car": _2, "caravan": _2, "cards": _2, "care": _2, "career": _2, "careers": _2, "cars": _2, "casa": { "$": 1, "succ": { "nabu": { "$": 0, "succ": { "ui": _3 } } } }, "case": _2, "cash": _2, "casino": _2, "catering": _2, "catholic": _2, "cba": _2, "cbn": _2, "cbre": _2, "cbs": _2, "center": _2, "ceo": _2, "cern": _2, "cfa": _2, "cfd": _2, "chanel": _2, "channel": _2, "charity": _2, "chase": _2, "chat": _2, "cheap": _2, "chintai": _2, "christmas": _2, "chrome": _2, "church": _2, "cipriani": _2, "circle": _2, "cisco": _2, "citadel": _2, "citi": _2, "citic": _2, "city": _2, "cityeats": _2, "claims": _2, "cleaning": _2, "click": _2, "clinic": _2, "clinique": _2, "clothing": _2, "cloud": { "$": 1, "succ": { "banzai": _5, "elementor": _3, "encoway": { "$": 0, "succ": { "eu": _3 } }, "statics": _5, "ravendb": _3, "axarnet": { "$": 0, "succ": { "es-1": _3 } }, "diadem": _3, "jelastic": { "$": 0, "succ": { "vip": _3 } }, "jele": _3, "jenv-aruba": { "$": 0, "succ": { "aruba": { "$": 0, "succ": { "eur": { "$": 0, "succ": { "it1": _3 } } } }, "it1": _3 } }, "keliweb": { "$": 2, "succ": { "cs": _3 } }, "oxa": { "$": 2, "succ": { "tn": _3, "uk": _3 } }, "primetel": { "$": 2, "succ": { "uk": _3 } }, "reclaim": { "$": 0, "succ": { "ca": _3, "uk": _3, "us": _3 } }, "trendhosting": { "$": 0, "succ": { "ch": _3, "de": _3 } }, "jotelulu": _3, "kuleuven": _3, "linkyard": _3, "magentosite": _5, "perspecta": _3, "vapor": _3, "on-rancher": _5, "scw": { "$": 0, "succ": { "baremetal": { "$": 0, "succ": { "fr-par-1": _3, "fr-par-2": _3, "nl-ams-1": _3 } }, "fr-par": { "$": 0, "succ": { "fnc": { "$": 2, "succ": { "functions": _3 } }, "k8s": _11, "s3": _3, "s3-website": _3, "whm": _3 } }, "instances": { "$": 0, "succ": { "priv": _3, "pub": _3 } }, "k8s": _3, "nl-ams": { "$": 0, "succ": { "k8s": _11, "s3": _3, "s3-website": _3, "whm": _3 } }, "pl-waw": { "$": 0, "succ": { "k8s": _11, "s3": _3, "s3-website": _3 } }, "scalebook": _3, "smartlabeling": _3 } }, "sensiosite": _5, "trafficplex": _3, "urown": _3, "voorloper": _3 } }, "club": { "$": 1, "succ": { "cloudns": _3, "jele": _3, "barsy": _3 } }, "clubmed": _2, "coach": _2, "codes": { "$": 1, "succ": { "owo": _5 } }, "coffee": _2, "college": _2, "cologne": _2, "comcast": _2, "commbank": _2, "community": { "$": 1, "succ": { "nog": _3, "ravendb": _3, "myforum": _3 } }, "company": _2, "compare": _2, "computer": _2, "comsec": _2, "condos": _2, "construction": _2, "consulting": _2, "contact": _2, "contractors": _2, "cooking": _2, "cookingchannel": _2, "cool": { "$": 1, "succ": { "elementor": _3, "de": _3 } }, "corsica": _2, "country": _2, "coupon": _2, "coupons": _2, "courses": _2, "cpa": _2, "credit": _2, "creditcard": _2, "creditunion": _2, "cricket": _2, "crown": _2, "crs": _2, "cruise": _2, "cruises": _2, "cuisinella": _2, "cymru": _2, "cyou": _2, "dabur": _2, "dad": _2, "dance": _2, "data": _2, "date": _2, "dating": _2, "datsun": _2, "day": _2, "dclk": _2, "dds": _2, "deal": _2, "dealer": _2, "deals": _2, "degree": _2, "delivery": _2, "dell": _2, "deloitte": _2, "delta": _2, "democrat": _2, "dental": _2, "dentist": _2, "desi": _2, "design": { "$": 1, "succ": { "bss": _3 } }, "dev": { "$": 1, "succ": { "autocode": _3, "lcl": _5, "lclstage": _5, "stg": _5, "stgstage": _5, "pages": _3, "r2": _3, "workers": _3, "curv": _3, "deno": _3, "deno-staging": _3, "deta": _3, "fly": _3, "githubpreview": _3, "gateway": _5, "iserv": _3, "localcert": { "$": 0, "succ": { "user": _5 } }, "loginline": _3, "mediatech": _3, "ngrok": _3, "ngrok-free": _3, "platter-app": _3, "shiftcrypto": _3, "vercel": _3, "webhare": _5 } }, "dhl": _2, "diamonds": _2, "diet": _2, "digital": { "$": 1, "succ": { "cloudapps": { "$": 2, "succ": { "london": _3 } } } }, "direct": _2, "directory": _2, "discount": _2, "discover": _2, "dish": _2, "diy": _2, "dnp": _2, "docs": _2, "doctor": _2, "dog": _2, "domains": _2, "dot": _2, "download": _2, "drive": _2, "dtv": _2, "dubai": _2, "dunlop": _2, "dupont": _2, "durban": _2, "dvag": _2, "dvr": _2, "earth": { "$": 1, "succ": { "dapps": { "$": 0, "succ": { "*": _3, "bzz": _5 } } } }, "eat": _2, "eco": _2, "edeka": _2, "education": _10, "email": _2, "emerck": _2, "energy": _2, "engineer": _2, "engineering": _2, "enterprises": _2, "epson": _2, "equipment": _2, "ericsson": _2, "erni": _2, "esq": _2, "estate": { "$": 1, "succ": { "compute": _5 } }, "etisalat": _2, "eurovision": _2, "eus": { "$": 1, "succ": { "party": _28 } }, "events": { "$": 1, "succ": { "koobin": _3, "co": _3 } }, "exchange": _2, "expert": _2, "exposed": _2, "express": _2, "extraspace": _2, "fage": _2, "fail": _2, "fairwinds": _2, "faith": _29, "family": _2, "fan": _2, "fans": _2, "farm": { "$": 1, "succ": { "storj": _3 } }, "farmers": _2, "fashion": _2, "fast": _2, "fedex": _2, "feedback": _2, "ferrari": _2, "ferrero": _2, "fiat": _2, "fidelity": _2, "fido": _2, "film": _2, "final": _2, "finance": _2, "financial": _10, "fire": _2, "firestone": _2, "firmdale": _2, "fish": _2, "fishing": _2, "fit": _2, "fitness": _2, "flickr": _2, "flights": _2, "flir": _2, "florist": _2, "flowers": _2, "fly": _2, "foo": _2, "food": _2, "foodnetwork": _2, "football": _2, "ford": _2, "forex": _2, "forsale": _2, "forum": _2, "foundation": _2, "fox": _2, "free": _2, "fresenius": _2, "frl": _2, "frogans": _2, "frontdoor": _2, "frontier": _2, "ftr": _2, "fujitsu": _2, "fun": _2, "fund": _2, "furniture": _2, "futbol": _2, "fyi": _2, "gal": _2, "gallery": _2, "gallo": _2, "gallup": _2, "game": _2, "games": _2, "gap": _2, "garden": _2, "gay": _2, "gbiz": _2, "gdn": { "$": 1, "succ": { "cnpy": _3 } }, "gea": _2, "gent": _2, "genting": _2, "george": _2, "ggee": _2, "gift": _2, "gifts": _2, "gives": _2, "giving": _2, "glass": _2, "gle": _2, "global": _2, "globo": _2, "gmail": _2, "gmbh": _2, "gmo": _2, "gmx": _2, "godaddy": _2, "gold": _2, "goldpoint": _2, "golf": _2, "goo": _2, "goodyear": _2, "goog": { "$": 1, "succ": { "cloud": _3, "translate": _3, "usercontent": _5 } }, "google": _2, "gop": _2, "got": _2, "grainger": _2, "graphics": _2, "gratis": _2, "green": _2, "gripe": _2, "grocery": _2, "group": { "$": 1, "succ": { "discourse": _3 } }, "guardian": _2, "gucci": _2, "guge": _2, "guide": _2, "guitars": _2, "guru": _2, "hair": _2, "hamburg": _2, "hangout": _2, "haus": _2, "hbo": _2, "hdfc": _2, "hdfcbank": _2, "health": { "$": 1, "succ": { "hra": _3 } }, "healthcare": _2, "help": _2, "helsinki": _2, "here": _2, "hermes": _2, "hgtv": _2, "hiphop": _2, "hisamitsu": _2, "hitachi": _2, "hiv": _2, "hkt": _2, "hockey": _2, "holdings": _2, "holiday": _2, "homedepot": _2, "homegoods": _2, "homes": _2, "homesense": _2, "honda": _2, "horse": _2, "hospital": _2, "host": { "$": 1, "succ": { "cloudaccess": _3, "freesite": _3, "easypanel": _3, "fastvps": _3, "myfast": _3, "tempurl": _3, "wpmudev": _3, "jele": _3, "mircloud": _3, "pcloud": _3, "half": _3 } }, "hosting": { "$": 1, "succ": { "opencraft": _3 } }, "hot": _2, "hoteles": _2, "hotels": _2, "hotmail": _2, "house": _2, "how": _2, "hsbc": _2, "hughes": _2, "hyatt": _2, "hyundai": _2, "ibm": _2, "icbc": _2, "ice": _2, "icu": _2, "ieee": _2, "ifm": _2, "ikano": _2, "imamat": _2, "imdb": _2, "immo": _2, "immobilien": _2, "inc": _2, "industries": _2, "infiniti": _2, "ing": _2, "ink": _2, "institute": _2, "insurance": _2, "insure": _2, "international": _2, "intuit": _2, "investments": _2, "ipiranga": _2, "irish": _2, "ismaili": _2, "ist": _2, "istanbul": _2, "itau": _2, "itv": _2, "jaguar": _2, "java": _2, "jcb": _2, "jeep": _2, "jetzt": _2, "jewelry": _2, "jio": _2, "jll": _2, "jmp": _2, "jnj": _2, "joburg": _2, "jot": _2, "joy": _2, "jpmorgan": _2, "jprs": _2, "juegos": _2, "juniper": _2, "kaufen": _2, "kddi": _2, "kerryhotels": _2, "kerrylogistics": _2, "kerryproperties": _2, "kfh": _2, "kia": _2, "kids": _2, "kim": _2, "kinder": _2, "kindle": _2, "kitchen": _2, "kiwi": _2, "koeln": _2, "komatsu": _2, "kosher": _2, "kpmg": _2, "kpn": _2, "krd": { "$": 1, "succ": { "co": _3, "edu": _3 } }, "kred": _2, "kuokgroup": _2, "kyoto": _2, "lacaixa": _2, "lamborghini": _2, "lamer": _2, "lancaster": _2, "lancia": _2, "land": { "$": 1, "succ": { "static": { "$": 2, "succ": { "dev": _3, "sites": _3 } } } }, "landrover": _2, "lanxess": _2, "lasalle": _2, "lat": _2, "latino": _2, "latrobe": _2, "law": _2, "lawyer": _2, "lds": _2, "lease": _2, "leclerc": _2, "lefrak": _2, "legal": _2, "lego": _2, "lexus": _2, "lgbt": _2, "lidl": _2, "life": _2, "lifeinsurance": _2, "lifestyle": _2, "lighting": _2, "like": _2, "lilly": _2, "limited": _2, "limo": _2, "lincoln": _2, "link": { "$": 1, "succ": { "cyon": _3, "mypep": _3, "dweb": _5 } }, "lipsy": _2, "live": { "$": 1, "succ": { "hlx": _3 } }, "living": _2, "llc": _2, "llp": _2, "loan": _2, "loans": _2, "locker": _2, "locus": _2, "lol": { "$": 1, "succ": { "omg": _3 } }, "london": _2, "lotte": _2, "lotto": _2, "love": _2, "lpl": _2, "lplfinancial": _2, "ltd": _2, "ltda": _2, "lundbeck": _2, "luxe": _2, "luxury": _2, "madrid": _2, "maif": _2, "maison": _2, "makeup": _2, "man": _2, "management": { "$": 1, "succ": { "router": _3 } }, "mango": _2, "map": _2, "market": _2, "marketing": _2, "markets": _2, "marriott": _2, "marshalls": _2, "maserati": _2, "mattel": _2, "mba": _2, "mckinsey": _2, "med": _2, "media": _35, "meet": _2, "melbourne": _2, "meme": _2, "memorial": _2, "men": _2, "menu": _36, "merckmsd": _2, "miami": _2, "microsoft": _2, "mini": _2, "mint": _2, "mit": _2, "mitsubishi": _2, "mlb": _2, "mls": _2, "mma": _2, "mobile": _2, "moda": _2, "moe": _2, "moi": _2, "mom": _2, "monash": _2, "money": _2, "monster": _2, "mormon": _2, "mortgage": _2, "moscow": _2, "moto": _2, "motorcycles": _2, "mov": _2, "movie": _2, "msd": _2, "mtn": _2, "mtr": _2, "music": _2, "mutual": _2, "nab": _2, "nagoya": _2, "natura": _2, "navy": _2, "nba": _2, "nec": _2, "netbank": _2, "netflix": _2, "network": { "$": 1, "succ": { "alces": _5, "co": _3, "arvo": _3, "azimuth": _3, "tlon": _3 } }, "neustar": _2, "new": _2, "news": { "$": 1, "succ": { "noticeable": _3 } }, "next": _2, "nextdirect": _2, "nexus": _2, "nfl": _2, "ngo": _2, "nhk": _2, "nico": _2, "nike": _2, "nikon": _2, "ninja": _2, "nissan": _2, "nissay": _2, "nokia": _2, "northwesternmutual": _2, "norton": _2, "now": _2, "nowruz": _2, "nowtv": _2, "nra": _2, "nrw": _2, "ntt": _2, "nyc": _2, "obi": _2, "observer": _2, "office": _2, "okinawa": _2, "olayan": _2, "olayangroup": _2, "oldnavy": _2, "ollo": _2, "omega": _2, "one": { "$": 1, "succ": { "onred": { "$": 2, "succ": { "staging": _3 } }, "service": _3, "homelink": _3 } }, "ong": _2, "onl": _2, "online": { "$": 1, "succ": { "eero": _3, "eero-stage": _3, "barsy": _3 } }, "ooo": _2, "open": _2, "oracle": _2, "orange": { "$": 1, "succ": { "tech": _3 } }, "organic": _2, "origins": _2, "osaka": _2, "otsuka": _2, "ott": _2, "ovh": { "$": 1, "succ": { "nerdpol": _3 } }, "page": { "$": 1, "succ": { "hlx": _3, "hlx3": _3, "translated": _3, "codeberg": _3, "pdns": _3, "plesk": _3, "prvcy": _3, "rocky": _3, "magnet": _3 } }, "panasonic": _2, "paris": _2, "pars": _2, "partners": _2, "parts": _2, "party": _29, "passagens": _2, "pay": _2, "pccw": _2, "pet": _2, "pfizer": _2, "pharmacy": _2, "phd": _2, "philips": _2, "phone": _2, "photo": _2, "photography": _2, "photos": _35, "physio": _2, "pics": _2, "pictet": _2, "pictures": { "$": 1, "succ": { "1337": _3 } }, "pid": _2, "pin": _2, "ping": _2, "pink": _2, "pioneer": _2, "pizza": { "$": 1, "succ": { "ngrok": _3 } }, "place": _10, "play": _2, "playstation": _2, "plumbing": _2, "plus": _2, "pnc": _2, "pohl": _2, "poker": _2, "politie": _2, "porn": { "$": 1, "succ": { "indie": _3 } }, "pramerica": _2, "praxi": _2, "press": _2, "prime": _2, "prod": _2, "productions": _2, "prof": _2, "progressive": _2, "promo": _2, "properties": _2, "property": _2, "protection": _2, "pru": _2, "prudential": _2, "pub": _36, "pwc": _2, "qpon": _2, "quebec": _2, "quest": _2, "racing": _2, "radio": _2, "read": _2, "realestate": _2, "realtor": _2, "realty": _2, "recipes": _2, "red": _2, "redstone": _2, "redumbrella": _2, "rehab": _2, "reise": _2, "reisen": _2, "reit": _2, "reliance": _2, "ren": _2, "rent": _2, "rentals": _2, "repair": _2, "report": _2, "republican": _2, "rest": _2, "restaurant": _2, "review": _29, "reviews": _2, "rexroth": _2, "rich": _2, "richardli": _2, "ricoh": _2, "ril": _2, "rio": _2, "rip": { "$": 1, "succ": { "clan": _3 } }, "rocher": _2, "rocks": { "$": 1, "succ": { "myddns": _3, "lima-city": _3, "webspace": _3 } }, "rodeo": _2, "rogers": _2, "room": _2, "rsvp": _2, "rugby": _2, "ruhr": _2, "run": { "$": 1, "succ": { "hs": _3, "development": _3, "ravendb": _3, "servers": _3, "build": _5, "code": _5, "database": _5, "migration": _5, "onporter": _3, "repl": _3 } }, "rwe": _2, "ryukyu": _2, "saarland": _2, "safe": _2, "safety": _2, "sakura": _2, "sale": _2, "salon": _2, "samsclub": _2, "samsung": _2, "sandvik": _2, "sandvikcoromant": _2, "sanofi": _2, "sap": _2, "sarl": _2, "sas": _2, "save": _2, "saxo": _2, "sbi": _2, "sbs": _2, "sca": _2, "scb": _2, "schaeffler": _2, "schmidt": _2, "scholarships": _2, "school": _2, "schule": _2, "schwarz": _2, "science": _29, "scot": { "$": 1, "succ": { "edu": _3, "gov": { "$": 2, "succ": { "service": _3 } } } }, "search": _2, "seat": _2, "secure": _2, "security": _2, "seek": _2, "select": _2, "sener": _2, "services": { "$": 1, "succ": { "loginline": _3 } }, "seven": _2, "sew": _2, "sex": _2, "sexy": _2, "sfr": _2, "shangrila": _2, "sharp": _2, "shaw": _2, "shell": _2, "shia": _2, "shiksha": _2, "shoes": _2, "shop": { "$": 1, "succ": { "base": _3, "hoplix": _3, "barsy": _3 } }, "shopping": _2, "shouji": _2, "show": _2, "showtime": _2, "silk": _2, "sina": _2, "singles": _2, "site": { "$": 1, "succ": { "cloudera": _5, "cyon": _3, "fnwk": _3, "folionetwork": _3, "fastvps": _3, "jele": _3, "lelux": _3, "loginline": _3, "barsy": _3, "mintere": _3, "omniwe": _3, "opensocial": _3, "platformsh": _5, "tst": _5, "byen": _3, "srht": _3, "novecore": _3 } }, "ski": _2, "skin": _2, "sky": _2, "skype": _2, "sling": _2, "smart": _2, "smile": _2, "sncf": _2, "soccer": _2, "social": _2, "softbank": _2, "software": _2, "sohu": _2, "solar": _2, "solutions": { "$": 1, "succ": { "diher": _5 } }, "song": _2, "sony": _2, "soy": _2, "spa": _2, "space": { "$": 1, "succ": { "myfast": _3, "uber": _3, "xs4all": _3 } }, "sport": _2, "spot": _2, "srl": _2, "stada": _2, "staples": _2, "star": _2, "statebank": _2, "statefarm": _2, "stc": _2, "stcgroup": _2, "stockholm": _2, "storage": _2, "store": { "$": 1, "succ": { "sellfy": _3, "shopware": _3, "storebase": _3 } }, "stream": _2, "studio": _2, "study": _2, "style": _2, "sucks": _2, "supplies": _2, "supply": _2, "support": _36, "surf": _2, "surgery": _2, "suzuki": _2, "swatch": _2, "swiss": _2, "sydney": _2, "systems": { "$": 1, "succ": { "knightpoint": _3 } }, "tab": _2, "taipei": _2, "talk": _2, "taobao": _2, "target": _2, "tatamotors": _2, "tatar": _2, "tattoo": _2, "tax": _2, "taxi": _2, "tci": _2, "tdk": _2, "team": { "$": 1, "succ": { "discourse": _3, "jelastic": _3 } }, "tech": _2, "technology": _10, "temasek": _2, "tennis": _2, "teva": _2, "thd": _2, "theater": _2, "theatre": _2, "tiaa": _2, "tickets": _2, "tienda": _2, "tiffany": _2, "tips": _2, "tires": _2, "tirol": _2, "tjmaxx": _2, "tjx": _2, "tkmaxx": _2, "tmall": _2, "today": { "$": 1, "succ": { "prequalifyme": _3 } }, "tokyo": _2, "tools": _2, "top": { "$": 1, "succ": { "now-dns": _3, "ntdll": _3 } }, "toray": _2, "toshiba": _2, "total": _2, "tours": _2, "town": _2, "toyota": _2, "toys": _2, "trade": _29, "trading": _2, "training": _2, "travel": _2, "travelchannel": _2, "travelers": _2, "travelersinsurance": _2, "trust": _2, "trv": _2, "tube": _2, "tui": _2, "tunes": _2, "tushu": _2, "tvs": _2, "ubank": _2, "ubs": _2, "unicom": _2, "university": _2, "uno": _2, "uol": _2, "ups": _2, "vacations": _2, "vana": _2, "vanguard": _2, "vegas": _2, "ventures": _2, "verisign": _2, "versicherung": _2, "vet": _2, "viajes": _2, "video": _2, "vig": _2, "viking": _2, "villas": _2, "vin": _2, "vip": _2, "virgin": _2, "visa": _2, "vision": _2, "viva": _2, "vivo": _2, "vlaanderen": _2, "vodka": _2, "volkswagen": _2, "volvo": _2, "vote": _2, "voting": _2, "voto": _2, "voyage": _2, "vuelos": _2, "wales": _2, "walmart": _2, "walter": _2, "wang": _2, "wanggou": _2, "watch": _2, "watches": _2, "weather": _2, "weatherchannel": _2, "webcam": _2, "weber": _2, "website": _35, "wedding": _2, "weibo": _2, "weir": _2, "whoswho": _2, "wien": _2, "wiki": _35, "williamhill": _2, "win": _2, "windows": _2, "wine": _2, "winners": _2, "wme": _2, "wolterskluwer": _2, "woodside": _2, "work": _2, "works": _2, "world": _2, "wow": _2, "wtc": _2, "wtf": _2, "xbox": _2, "xerox": _2, "xfinity": _2, "xihuan": _2, "xin": _2, "xn--11b4c3d": _2, "कॉम": _2, "xn--1ck2e1b": _2, "セール": _2, "xn--1qqw23a": _2, "佛山": _2, "xn--30rr7y": _2, "慈善": _2, "xn--3bst00m": _2, "集团": _2, "xn--3ds443g": _2, "在线": _2, "xn--3pxu8k": _2, "点看": _2, "xn--42c2d9a": _2, "คอม": _2, "xn--45q11c": _2, "八卦": _2, "xn--4gbrim": _2, "موقع": _2, "xn--55qw42g": _2, "公益": _2, "xn--55qx5d": _2, "公司": _2, "xn--5su34j936bgsg": _2, "香格里拉": _2, "xn--5tzm5g": _2, "网站": _2, "xn--6frz82g": _2, "移动": _2, "xn--6qq986b3xl": _2, "我爱你": _2, "xn--80adxhks": _2, "москва": _2, "xn--80aqecdr1a": _2, "католик": _2, "xn--80asehdb": _2, "онлайн": _2, "xn--80aswg": _2, "сайт": _2, "xn--8y0a063a": _2, "联通": _2, "xn--9dbq2a": _2, "קום": _2, "xn--9et52u": _2, "时尚": _2, "xn--9krt00a": _2, "微博": _2, "xn--b4w605ferd": _2, "淡马锡": _2, "xn--bck1b9a5dre4c": _2, "ファッション": _2, "xn--c1avg": _2, "орг": _2, "xn--c2br7g": _2, "नेट": _2, "xn--cck2b3b": _2, "ストア": _2, "xn--cckwcxetd": _2, "アマゾン": _2, "xn--cg4bki": _2, "삼성": _2, "xn--czr694b": _2, "商标": _2, "xn--czrs0t": _2, "商店": _2, "xn--czru2d": _2, "商城": _2, "xn--d1acj3b": _2, "дети": _2, "xn--eckvdtc9d": _2, "ポイント": _2, "xn--efvy88h": _2, "新闻": _2, "xn--fct429k": _2, "家電": _2, "xn--fhbei": _2, "كوم": _2, "xn--fiq228c5hs": _2, "中文网": _2, "xn--fiq64b": _2, "中信": _2, "xn--fjq720a": _2, "娱乐": _2, "xn--flw351e": _2, "谷歌": _2, "xn--fzys8d69uvgm": _2, "電訊盈科": _2, "xn--g2xx48c": _2, "购物": _2, "xn--gckr3f0f": _2, "クラウド": _2, "xn--gk3at1e": _2, "通販": _2, "xn--hxt814e": _2, "网店": _2, "xn--i1b6b1a6a2e": _2, "संगठन": _2, "xn--imr513n": _2, "餐厅": _2, "xn--io0a7i": _2, "网络": _2, "xn--j1aef": _2, "ком": _2, "xn--jlq480n2rg": _2, "亚马逊": _2, "xn--jvr189m": _2, "食品": _2, "xn--kcrx77d1x4a": _2, "飞利浦": _2, "xn--kput3i": _2, "手机": _2, "xn--mgba3a3ejt": _2, "ارامكو": _2, "xn--mgba7c0bbn0a": _2, "العليان": _2, "xn--mgbaakc7dvf": _2, "اتصالات": _2, "xn--mgbab2bd": _2, "بازار": _2, "xn--mgbca7dzdo": _2, "ابوظبي": _2, "xn--mgbi4ecexp": _2, "كاثوليك": _2, "xn--mgbt3dhd": _2, "همراه": _2, "xn--mk1bu44c": _2, "닷컴": _2, "xn--mxtq1m": _2, "政府": _2, "xn--ngbc5azd": _2, "شبكة": _2, "xn--ngbe9e0a": _2, "بيتك": _2, "xn--ngbrx": _2, "عرب": _2, "xn--nqv7f": _2, "机构": _2, "xn--nqv7fs00ema": _2, "组织机构": _2, "xn--nyqy26a": _2, "健康": _2, "xn--otu796d": _2, "招聘": _2, "xn--p1acf": { "$": 1, "succ": { "xn--90amc": _3, "xn--j1aef": _3, "xn--j1ael8b": _3, "xn--h1ahn": _3, "xn--j1adp": _3, "xn--c1avg": _3, "xn--80aaa0cvac": _3, "xn--h1aliz": _3, "xn--90a1af": _3, "xn--41a": _3 } }, "рус": { "$": 1, "succ": { "биз": _3, "ком": _3, "крым": _3, "мир": _3, "мск": _3, "орг": _3, "самара": _3, "сочи": _3, "спб": _3, "я": _3 } }, "xn--pssy2u": _2, "大拿": _2, "xn--q9jyb4c": _2, "みんな": _2, "xn--qcka1pmc": _2, "グーグル": _2, "xn--rhqv96g": _2, "世界": _2, "xn--rovu88b": _2, "書籍": _2, "xn--ses554g": _2, "网址": _2, "xn--t60b56a": _2, "닷넷": _2, "xn--tckwe": _2, "コム": _2, "xn--tiq49xqyj": _2, "天主教": _2, "xn--unup4y": _2, "游戏": _2, "xn--vermgensberater-ctb": _2, "vermögensberater": _2, "xn--vermgensberatung-pwb": _2, "vermögensberatung": _2, "xn--vhquv": _2, "企业": _2, "xn--vuq861b": _2, "信息": _2, "xn--w4r85el8fhu5dnra": _2, "嘉里大酒店": _2, "xn--w4rs40l": _2, "嘉里": _2, "xn--xhq521b": _2, "广东": _2, "xn--zfr164b": _2, "政务": _2, "xyz": { "$": 1, "succ": { "blogsite": _3, "localzone": _3, "crafting": _3, "zapto": _3, "telebit": _5 } }, "yachts": _2, "yahoo": _2, "yamaxun": _2, "yandex": _2, "yodobashi": _2, "yoga": _2, "yokohama": _2, "you": _2, "youtube": _2, "yun": _2, "zappos": _2, "zara": _2, "zero": _2, "zip": _2, "zone": { "$": 1, "succ": { "cloud66": _3, "hs": _3, "triton": _5, "lima": _3 } }, "zuerich": _2 } };
    ;
    return rules;
})();

;// CONCATENATED MODULE: ./node_modules/.pnpm/tldts@5.7.112/node_modules/tldts/dist/es6/src/suffix-trie.js


/**
 * Lookup parts of domain in Trie
 */
function lookupInTrie(parts, trie, index, allowedMask) {
    let result = null;
    let node = trie;
    while (node !== undefined) {
        // We have a match!
        if ((node.$ & allowedMask) !== 0) {
            result = {
                index: index + 1,
                isIcann: node.$ === 1 /* RULE_TYPE.ICANN */,
                isPrivate: node.$ === 2 /* RULE_TYPE.PRIVATE */,
            };
        }
        // No more `parts` to look for
        if (index === -1) {
            break;
        }
        const succ = node.succ;
        node = succ && (succ[parts[index]] || succ['*']);
        index -= 1;
    }
    return result;
}
/**
 * Check if `hostname` has a valid public suffix in `trie`.
 */
function suffix_trie_suffixLookup(hostname, options, out) {
    if ((0,es6/* fastPathLookup */.m5)(hostname, options, out) === true) {
        return;
    }
    const hostnameParts = hostname.split('.');
    const allowedMask = (options.allowPrivateDomains === true ? 2 /* RULE_TYPE.PRIVATE */ : 0) |
        (options.allowIcannDomains === true ? 1 /* RULE_TYPE.ICANN */ : 0);
    // Look for exceptions
    const exceptionMatch = lookupInTrie(hostnameParts, exceptions, hostnameParts.length - 1, allowedMask);
    if (exceptionMatch !== null) {
        out.isIcann = exceptionMatch.isIcann;
        out.isPrivate = exceptionMatch.isPrivate;
        out.publicSuffix = hostnameParts.slice(exceptionMatch.index + 1).join('.');
        return;
    }
    // Look for a match in rules
    const rulesMatch = lookupInTrie(hostnameParts, rules, hostnameParts.length - 1, allowedMask);
    if (rulesMatch !== null) {
        out.isIcann = rulesMatch.isIcann;
        out.isPrivate = rulesMatch.isPrivate;
        out.publicSuffix = hostnameParts.slice(rulesMatch.index).join('.');
        return;
    }
    // No match found...
    // Prevailing rule is '*' so we consider the top-level domain to be the
    // public suffix of `hostname` (e.g.: 'example.org' => 'org').
    out.isIcann = false;
    out.isPrivate = false;
    out.publicSuffix = hostnameParts[hostnameParts.length - 1];
}

;// CONCATENATED MODULE: ./node_modules/.pnpm/tldts@5.7.112/node_modules/tldts/dist/es6/index.js


// For all methods but 'parse', it does not make sense to allocate an object
// every single time to only return the value of a specific attribute. To avoid
// this un-necessary allocation, we use a global object which is re-used.
const RESULT = (0,es6/* getEmptyResult */.e4)();
function parse(url, options = {}) {
    return (0,es6/* parseImpl */.kL)(url, 5 /* FLAG.ALL */, suffix_trie_suffixLookup, options, (0,es6/* getEmptyResult */.e4)());
}
function getHostname(url, options = {}) {
    /*@__INLINE__*/ (0,es6/* resetResult */.a7)(RESULT);
    return (0,es6/* parseImpl */.kL)(url, 0 /* FLAG.HOSTNAME */, suffix_trie_suffixLookup, options, RESULT).hostname;
}
function getPublicSuffix(url, options = {}) {
    /*@__INLINE__*/ resetResult(RESULT);
    return parseImpl(url, 2 /* FLAG.PUBLIC_SUFFIX */, suffixLookup, options, RESULT)
        .publicSuffix;
}
function getDomain(url, options = {}) {
    /*@__INLINE__*/ (0,es6/* resetResult */.a7)(RESULT);
    return (0,es6/* parseImpl */.kL)(url, 3 /* FLAG.DOMAIN */, suffix_trie_suffixLookup, options, RESULT).domain;
}
function getSubdomain(url, options = {}) {
    /*@__INLINE__*/ resetResult(RESULT);
    return parseImpl(url, 4 /* FLAG.SUB_DOMAIN */, suffixLookup, options, RESULT)
        .subdomain;
}
function getDomainWithoutSuffix(url, options = {}) {
    /*@__INLINE__*/ resetResult(RESULT);
    return parseImpl(url, 5 /* FLAG.ALL */, suffixLookup, options, RESULT)
        .domainWithoutSuffix;
}

// EXTERNAL MODULE: ./node_modules/.pnpm/is-ip@3.1.0/node_modules/is-ip/index.js
var is_ip = __webpack_require__(13997);
// EXTERNAL MODULE: ./node_modules/.pnpm/xregexp@5.1.1/node_modules/xregexp/lib/index.js
var lib = __webpack_require__(86378);
// EXTERNAL MODULE: ./node_modules/.pnpm/clone-deep@4.0.1/node_modules/clone-deep/index.js
var clone_deep = __webpack_require__(94332);
// EXTERNAL MODULE: ./node_modules/.pnpm/@adguard+agtree@2.1.2/node_modules/@adguard/agtree/dist/compatibility-table-data.js
var compatibility_table_data = __webpack_require__(23458);
// EXTERNAL MODULE: ./node_modules/.pnpm/zod@3.21.4/node_modules/zod/lib/index.mjs
var zod_lib = __webpack_require__(44945);
;// CONCATENATED MODULE: ./node_modules/.pnpm/@adguard+agtree@2.1.2/node_modules/@adguard/agtree/dist/agtree.mjs
/*
 * AGTree v2.1.2 (build date: Thu, 19 Sep 2024 15:44:40 GMT)
 * (c) 2024 Adguard Software Ltd.
 * Released under the MIT license
 * https://github.com/AdguardTeam/tsurlfilter/tree/master/packages/agtree#readme
 */













/**
 * @file Possible adblock syntaxes are listed here.
 */
/**
 * Possible adblock syntaxes (supported by this library)
 */
var AdblockSyntax;
(function (AdblockSyntax) {
    /**
     * Common syntax, which is supported by more than one adblocker (or by all adblockers).
     *
     * We typically use this syntax when we cannot determine the concrete syntax of the rule,
     * because the syntax is used by more than one adblocker natively.
     *
     * @example
     * - `||example.org^$important` is a common syntax, since it is used by all adblockers natively, and
     * we cannot determine at parsing level whether `important` is a valid option or not, and if it is valid,
     * then which adblocker supports it.
     */
    AdblockSyntax["Common"] = "Common";
    /**
     * Adblock Plus syntax.
     *
     * @example
     * - `example.org#$#abort-on-property-read alert` is an Adblock Plus syntax, since it is not used by any other
     * adblockers directly (probably supported by some on-the-fly conversion, but this is not the native syntax).
     * @see {@link https://adblockplus.org/}
     */
    AdblockSyntax["Abp"] = "AdblockPlus";
    /**
     * uBlock Origin syntax.
     *
     * @example
     * - `example.com##+js(set, atob, noopFunc)` is an uBlock Origin syntax, since it is not used by any other
     * adblockers directly (probably supported by some on-the-fly conversion, but this is not the native syntax).
     * @see {@link https://github.com/gorhill/uBlock}
     */
    AdblockSyntax["Ubo"] = "UblockOrigin";
    /**
     * AdGuard syntax.
     *
     * @example
     * - `example.org#%#//scriptlet("abort-on-property-read", "alert")` is an AdGuard syntax, since it is not used
     * by any other adblockers directly (probably supported by some on-the-fly conversion, but this is not the native
     * syntax).
     * @see {@link https://adguard.com/}
     */
    AdblockSyntax["Adg"] = "AdGuard";
})(AdblockSyntax || (AdblockSyntax = {}));

/**
 * @file Constant values used by all parts of the library
 */
// TODO: remove unused constants
// General
/**
 * Empty string.
 */
const EMPTY = '';
const SPACE = ' ';
const TAB = '\t';
const COLON = ':';
const COMMA = ',';
const DOT = '.';
const SEMICOLON = ';';
const AMPERSAND = '&';
const ASTERISK = '*';
const AT_SIGN = '@';
const CARET = '^';
const DOLLAR_SIGN = '$';
const EQUALS = '=';
const EXCLAMATION_MARK = '!';
const HASHMARK = '#';
const PIPE = '|';
const PLUS = '+';
const QUESTION_MARK = '?';
const SLASH = '/';
const UNDERSCORE = '_';
// Escape characters
const BACKSLASH = '\\';
const ESCAPE_CHARACTER = BACKSLASH;
// Newlines
const CR = '\r';
const FF = '\f';
const LF = '\n';
const CRLF = CR + LF;
const NEWLINE = LF;
// Quotes
const BACKTICK_QUOTE = '`';
const DOUBLE_QUOTE = '"';
const SINGLE_QUOTE = '\'';
// Brackets
const OPEN_PARENTHESIS = '(';
const CLOSE_PARENTHESIS = ')';
const OPEN_SQUARE_BRACKET = '[';
const CLOSE_SQUARE_BRACKET = ']';
const OPEN_CURLY_BRACKET = '{';
const CLOSE_CURLY_BRACKET = '}';
// Letters
const SMALL_LETTER_A = 'a';
const SMALL_LETTER_B = 'b';
const SMALL_LETTER_C = 'c';
const SMALL_LETTER_D = 'd';
const SMALL_LETTER_E = 'e';
const SMALL_LETTER_F = 'f';
const SMALL_LETTER_G = 'g';
const SMALL_LETTER_H = 'h';
const SMALL_LETTER_I = 'i';
const SMALL_LETTER_J = 'j';
const SMALL_LETTER_K = 'k';
const SMALL_LETTER_L = 'l';
const SMALL_LETTER_M = 'm';
const SMALL_LETTER_N = 'n';
const SMALL_LETTER_O = 'o';
const SMALL_LETTER_P = 'p';
const SMALL_LETTER_Q = 'q';
const SMALL_LETTER_R = 'r';
const SMALL_LETTER_S = 's';
const SMALL_LETTER_T = 't';
const SMALL_LETTER_U = 'u';
const SMALL_LETTER_V = 'v';
const SMALL_LETTER_W = 'w';
const SMALL_LETTER_X = 'x';
const SMALL_LETTER_Y = 'y';
const SMALL_LETTER_Z = 'z';
/**
 * Set of all small letters.
 */
const SMALL_LETTERS = new Set([
    SMALL_LETTER_A,
    SMALL_LETTER_B,
    SMALL_LETTER_C,
    SMALL_LETTER_D,
    SMALL_LETTER_E,
    SMALL_LETTER_F,
    SMALL_LETTER_G,
    SMALL_LETTER_H,
    SMALL_LETTER_I,
    SMALL_LETTER_J,
    SMALL_LETTER_K,
    SMALL_LETTER_L,
    SMALL_LETTER_M,
    SMALL_LETTER_N,
    SMALL_LETTER_O,
    SMALL_LETTER_P,
    SMALL_LETTER_Q,
    SMALL_LETTER_R,
    SMALL_LETTER_S,
    SMALL_LETTER_T,
    SMALL_LETTER_U,
    SMALL_LETTER_V,
    SMALL_LETTER_W,
    SMALL_LETTER_X,
    SMALL_LETTER_Y,
    SMALL_LETTER_Z,
]);
// Capital letters
const CAPITAL_LETTER_A = 'A';
const CAPITAL_LETTER_B = 'B';
const CAPITAL_LETTER_C = 'C';
const CAPITAL_LETTER_D = 'D';
const CAPITAL_LETTER_E = 'E';
const CAPITAL_LETTER_F = 'F';
const CAPITAL_LETTER_G = 'G';
const CAPITAL_LETTER_H = 'H';
const CAPITAL_LETTER_I = 'I';
const CAPITAL_LETTER_J = 'J';
const CAPITAL_LETTER_K = 'K';
const CAPITAL_LETTER_L = 'L';
const CAPITAL_LETTER_M = 'M';
const CAPITAL_LETTER_N = 'N';
const CAPITAL_LETTER_O = 'O';
const CAPITAL_LETTER_P = 'P';
const CAPITAL_LETTER_Q = 'Q';
const CAPITAL_LETTER_R = 'R';
const CAPITAL_LETTER_S = 'S';
const CAPITAL_LETTER_T = 'T';
const CAPITAL_LETTER_U = 'U';
const CAPITAL_LETTER_V = 'V';
const CAPITAL_LETTER_W = 'W';
const CAPITAL_LETTER_X = 'X';
const CAPITAL_LETTER_Y = 'Y';
const CAPITAL_LETTER_Z = 'Z';
/**
 * Set of all capital letters.
 */
const CAPITAL_LETTERS = new Set([
    CAPITAL_LETTER_A,
    CAPITAL_LETTER_B,
    CAPITAL_LETTER_C,
    CAPITAL_LETTER_D,
    CAPITAL_LETTER_E,
    CAPITAL_LETTER_F,
    CAPITAL_LETTER_G,
    CAPITAL_LETTER_H,
    CAPITAL_LETTER_I,
    CAPITAL_LETTER_J,
    CAPITAL_LETTER_K,
    CAPITAL_LETTER_L,
    CAPITAL_LETTER_M,
    CAPITAL_LETTER_N,
    CAPITAL_LETTER_O,
    CAPITAL_LETTER_P,
    CAPITAL_LETTER_Q,
    CAPITAL_LETTER_R,
    CAPITAL_LETTER_S,
    CAPITAL_LETTER_T,
    CAPITAL_LETTER_U,
    CAPITAL_LETTER_V,
    CAPITAL_LETTER_W,
    CAPITAL_LETTER_X,
    CAPITAL_LETTER_Y,
    CAPITAL_LETTER_Z,
]);
// Numbers as strings
const NUMBER_0 = '0';
const NUMBER_1 = '1';
const NUMBER_2 = '2';
const NUMBER_3 = '3';
const NUMBER_4 = '4';
const NUMBER_5 = '5';
const NUMBER_6 = '6';
const NUMBER_7 = '7';
const NUMBER_8 = '8';
const NUMBER_9 = '9';
/**
 * Set of all numbers as strings.
 */
const NUMBERS = new Set([
    NUMBER_0,
    NUMBER_1,
    NUMBER_2,
    NUMBER_3,
    NUMBER_4,
    NUMBER_5,
    NUMBER_6,
    NUMBER_7,
    NUMBER_8,
    NUMBER_9,
]);
const REGEX_MARKER = '/';
const ADG_SCRIPTLET_MASK = '//scriptlet';
const UBO_SCRIPTLET_MASK = '+js';
const UBO_SCRIPTLET_MASK_LEGACY = 'script:inject';
const UBO_HTML_MASK = '^';
// Modifiers are separated by ",". For example: "script,domain=example.com"
const MODIFIERS_SEPARATOR = ',';
const MODIFIER_ASSIGN_OPERATOR = '=';
const NEGATION_MARKER = '~';
/**
 * The wildcard symbol — `*`.
 */
const WILDCARD = ASTERISK;
/**
 * Classic domain separator.
 *
 * @example
 * ```adblock
 * ! Domains are separated by ",":
 * example.com,~example.org##.ads
 * ```
 */
const COMMA_DOMAIN_LIST_SEPARATOR = ',';
/**
 * Modifier separator for $app, $denyallow, $domain, $method.
 *
 * @example
 * ```adblock
 * ! Domains are separated by "|":
 * ads.js^$script,domains=example.com|~example.org
 * ```
 */
const PIPE_MODIFIER_SEPARATOR = '|';
const CSS_MEDIA_MARKER = '@media';
const CSS_NOT_PSEUDO = 'not';
const HINT_MARKER = '!+';
const HINT_MARKER_LEN = HINT_MARKER.length;
const NETWORK_RULE_EXCEPTION_MARKER = '@@';
const NETWORK_RULE_EXCEPTION_MARKER_LEN = NETWORK_RULE_EXCEPTION_MARKER.length;
const NETWORK_RULE_SEPARATOR = '$';
const AGLINT_COMMAND_PREFIX = 'aglint';
const AGLINT_CONFIG_COMMENT_MARKER = '--';
const PREPROCESSOR_MARKER = '!#';
const PREPROCESSOR_MARKER_LEN = PREPROCESSOR_MARKER.length;
const PREPROCESSOR_SEPARATOR = ' ';
const SAFARI_CB_AFFINITY = 'safari_cb_affinity';
const IF = 'if';
const INCLUDE = 'include';
const NULL = 0;
const UINT8_MAX = 255;
const UINT16_MAX = 65535;

/**
 * @file Utility functions for string manipulation.
 */
const SINGLE_QUOTE_MARKER = "'";
const DOUBLE_QUOTE_MARKER = '"';
class StringUtils {
    /**
     * Finds the first occurrence of a character that:
     * - isn't preceded by an escape character
     *
     * @param pattern - Source pattern
     * @param searchedCharacter - Searched character
     * @param start - Start index
     * @param escapeCharacter - Escape character, \ by default
     * @returns Index or -1 if the character not found
     */
    static findNextUnescapedCharacter(pattern, searchedCharacter, start = 0, escapeCharacter = ESCAPE_CHARACTER) {
        for (let i = start; i < pattern.length; i += 1) {
            // The searched character cannot be preceded by an escape
            if (pattern[i] === searchedCharacter && pattern[i - 1] !== escapeCharacter) {
                return i;
            }
        }
        return -1;
    }
    /**
     * Finds the first occurrence in backward direction of a character that isn't preceded by an escape character.
     *
     * @param pattern - Source pattern
     * @param searchedCharacter - Searched character
     * @param start - Start index
     * @param escapeCharacter - Escape character, \ by default
     * @returns Index or -1 if the character not found
     */
    static findNextUnescapedCharacterBackwards(pattern, searchedCharacter, start = pattern.length - 1, escapeCharacter = ESCAPE_CHARACTER) {
        for (let i = start; i >= 0; i -= 1) {
            // The searched character cannot be preceded by an escape
            if (pattern[i] === searchedCharacter && pattern[i - 1] !== escapeCharacter) {
                return i;
            }
        }
        return -1;
    }
    /**
     * Finds the last occurrence of a character that:
     * - isn't preceded by an escape character
     *
     * @param pattern - Source pattern
     * @param searchedCharacter - Searched character
     * @param escapeCharacter - Escape character, \ by default
     * @returns Index or -1 if the character not found
     */
    static findLastUnescapedCharacter(pattern, searchedCharacter, escapeCharacter = ESCAPE_CHARACTER) {
        for (let i = pattern.length - 1; i >= 0; i -= 1) {
            // The searched character cannot be preceded by an escape
            if (pattern[i] === searchedCharacter && pattern[i - 1] !== escapeCharacter) {
                return i;
            }
        }
        return -1;
    }
    /**
     * Finds the next occurrence of a character that:
     * - isn't preceded by an escape character
     * - isn't followed by the specified character
     *
     * @param pattern - Source pattern
     * @param start - Start index
     * @param searchedCharacter - Searched character
     * @param notFollowedBy - Searched character not followed by this character
     * @param escapeCharacter - Escape character, \ by default
     * @returns Index or -1 if the character not found
     */
    static findNextUnescapedCharacterThatNotFollowedBy(pattern, start, searchedCharacter, notFollowedBy, escapeCharacter = ESCAPE_CHARACTER) {
        for (let i = start; i < pattern.length; i += 1) {
            // The searched character cannot be preceded by an escape
            if (pattern[i] === searchedCharacter
                && pattern[i + 1] !== notFollowedBy
                && pattern[i - 1] !== escapeCharacter) {
                return i;
            }
        }
        return -1;
    }
    /**
     * Finds the last occurrence of a character that:
     * - isn't preceded by an escape character
     * - isn't followed by the specified character
     *
     * @param pattern - Source pattern
     * @param searchedCharacter - Searched character
     * @param notFollowedBy - Searched character not followed by this character
     * @param escapeCharacter - Escape character, \ by default
     * @returns Index or -1 if the character not found
     */
    static findLastUnescapedCharacterThatNotFollowedBy(pattern, searchedCharacter, notFollowedBy, escapeCharacter = ESCAPE_CHARACTER) {
        for (let i = pattern.length - 1; i >= 0; i -= 1) {
            // The searched character cannot be preceded by an escape
            if (pattern[i] === searchedCharacter
                && pattern[i + 1] !== notFollowedBy
                && pattern[i - 1] !== escapeCharacter) {
                return i;
            }
        }
        return -1;
    }
    /**
     * Finds the next occurrence of a character that:
     * - isn't part of any string literal ('literal' or "literal")
     * - isn't part of any RegExp expression (/regexp/)
     *
     * @param pattern - Source pattern
     * @param searchedCharacter - Searched character
     * @param start - Start index
     * @returns Index or -1 if the character not found
     */
    static findUnescapedNonStringNonRegexChar(pattern, searchedCharacter, start = 0) {
        let open = null;
        for (let i = start; i < pattern.length; i += 1) {
            if ((pattern[i] === SINGLE_QUOTE_MARKER
                || pattern[i] === DOUBLE_QUOTE_MARKER
                || pattern[i] === REGEX_MARKER)
                && pattern[i - 1] !== ESCAPE_CHARACTER) {
                if (open === pattern[i]) {
                    open = null;
                }
                else if (open === null) {
                    open = pattern[i];
                }
            }
            else if (open === null && pattern[i] === searchedCharacter && pattern[i - 1] !== ESCAPE_CHARACTER) {
                return i;
            }
        }
        return -1;
    }
    /**
     * Finds the next occurrence of a character that:
     * - isn't part of any string literal ('literal' or "literal")
     * - isn't preceded by an escape character
     *
     * @param pattern - Source pattern
     * @param searchedCharacter - Searched character
     * @param start - Start index
     * @param escapeCharacter - Escape character, \ by default
     * @returns Index or -1 if the character not found
     */
    static findNextUnquotedUnescapedCharacter(pattern, searchedCharacter, start = 0, escapeCharacter = ESCAPE_CHARACTER) {
        let openQuote = null;
        for (let i = start; i < pattern.length; i += 1) {
            // Unescaped ' or "
            if ((pattern[i] === SINGLE_QUOTE_MARKER || pattern[i] === DOUBLE_QUOTE_MARKER)
                && pattern[i - 1] !== escapeCharacter) {
                if (!openQuote)
                    openQuote = pattern[i];
                else if (openQuote === pattern[i])
                    openQuote = null;
            }
            else if (pattern[i] === searchedCharacter && pattern[i - 1] !== escapeCharacter) {
                // Unescaped character
                if (!openQuote) {
                    return i;
                }
            }
        }
        return -1;
    }
    /**
     * Finds the next occurrence of a character that:
     * - isn't "bracketed"
     * - isn't preceded by an escape character
     *
     * @param pattern - Source pattern
     * @param searchedCharacter - Searched character
     * @param start - Start index
     * @param escapeCharacter - Escape character, \ by default
     * @param openBracket - Open bracket, ( by default
     * @param closeBracket - Close bracket, ( by default
     * @throws If the opening and closing brackets are the same
     * @returns Index or -1 if the character not found
     */
    static findNextNotBracketedUnescapedCharacter(pattern, searchedCharacter, start = 0, escapeCharacter = ESCAPE_CHARACTER, openBracket = '(', closeBracket = ')') {
        if (openBracket === closeBracket) {
            throw new Error('Open and close bracket cannot be the same');
        }
        let depth = 0;
        for (let i = start; i < pattern.length; i += 1) {
            if (pattern[i] === openBracket) {
                depth += 1;
            }
            else if (pattern[i] === closeBracket) {
                depth -= 1;
            }
            else if (depth < 1 && pattern[i] === searchedCharacter && pattern[i - 1] !== escapeCharacter) {
                return i;
            }
        }
        return -1;
    }
    /**
     * Splits the source pattern along characters that:
     * - isn't part of any string literal ('literal' or "literal")
     * - isn't preceded by an escape character
     *
     * @param pattern - Source pattern
     * @param delimeterCharacter - Delimeter character
     * @returns Splitted string
     */
    static splitStringByUnquotedUnescapedCharacter(pattern, delimeterCharacter) {
        const parts = [];
        let delimeterIndex = -1;
        do {
            const prevDelimeterIndex = delimeterIndex;
            delimeterIndex = StringUtils.findNextUnquotedUnescapedCharacter(pattern, delimeterCharacter, delimeterIndex + 1);
            if (delimeterIndex !== -1) {
                parts.push(pattern.substring(prevDelimeterIndex + 1, delimeterIndex));
            }
            else {
                parts.push(pattern.substring(prevDelimeterIndex + 1, pattern.length));
            }
        } while (delimeterIndex !== -1);
        return parts;
    }
    /**
     * Splits the source pattern along characters that:
     * - isn't part of any string literal ('literal' or "literal")
     * - isn't part of any RegExp expression (/regexp/)
     * - isn't preceded by an escape character
     *
     * @param pattern - Source pattern
     * @param delimeterCharacter - Delimeter character
     * @returns Splitted string
     */
    static splitStringByUnescapedNonStringNonRegexChar(pattern, delimeterCharacter) {
        const parts = [];
        let delimeterIndex = -1;
        do {
            const prevDelimeterIndex = delimeterIndex;
            delimeterIndex = StringUtils.findUnescapedNonStringNonRegexChar(pattern, delimeterCharacter, delimeterIndex + 1);
            if (delimeterIndex !== -1) {
                parts.push(pattern.substring(prevDelimeterIndex + 1, delimeterIndex));
            }
            else {
                parts.push(pattern.substring(prevDelimeterIndex + 1, pattern.length));
            }
        } while (delimeterIndex !== -1);
        return parts;
    }
    /**
     * Splits the source pattern along characters that:
     * - isn't preceded by an escape character
     *
     * @param pattern - Source pattern
     * @param delimeterCharacter - Delimeter character
     * @returns Splitted string
     */
    static splitStringByUnescapedCharacter(pattern, delimeterCharacter) {
        const parts = [];
        let delimeterIndex = -1;
        do {
            const prevDelimeterIndex = delimeterIndex;
            delimeterIndex = StringUtils.findNextUnescapedCharacter(pattern, delimeterCharacter, delimeterIndex + 1);
            if (delimeterIndex !== -1) {
                parts.push(pattern.substring(prevDelimeterIndex + 1, delimeterIndex));
            }
            else {
                parts.push(pattern.substring(prevDelimeterIndex + 1, pattern.length));
            }
        } while (delimeterIndex !== -1);
        return parts;
    }
    /**
     * Determines whether the given character is a space or tab character.
     *
     * @param char - The character to check.
     * @returns true if the given character is a space or tab character, false otherwise.
     */
    static isWhitespace(char) {
        return char === SPACE || char === TAB;
    }
    /**
     * Checks if the given character is a digit.
     *
     * @param char The character to check.
     * @returns `true` if the given character is a digit, `false` otherwise.
     */
    static isDigit(char) {
        return char >= NUMBER_0 && char <= NUMBER_9;
    }
    /**
     * Checks if the given character is a small letter.
     *
     * @param char The character to check.
     * @returns `true` if the given character is a small letter, `false` otherwise.
     */
    static isSmallLetter(char) {
        return char >= SMALL_LETTER_A && char <= SMALL_LETTER_Z;
    }
    /**
     * Checks if the given character is a capital letter.
     *
     * @param char The character to check.
     * @returns `true` if the given character is a capital letter, `false` otherwise.
     */
    static isCapitalLetter(char) {
        return char >= CAPITAL_LETTER_A && char <= CAPITAL_LETTER_Z;
    }
    /**
     * Checks if the given character is a letter (small or capital).
     *
     * @param char The character to check.
     * @returns `true` if the given character is a letter, `false` otherwise.
     */
    static isLetter(char) {
        return StringUtils.isSmallLetter(char) || StringUtils.isCapitalLetter(char);
    }
    /**
     * Checks if the given character is a letter or a digit.
     *
     * @param char Character to check
     * @returns `true` if the given character is a letter or a digit, `false` otherwise.
     */
    static isAlphaNumeric(char) {
        return StringUtils.isLetter(char) || StringUtils.isDigit(char);
    }
    /**
     * Searches for the first non-whitespace character in the source pattern.
     *
     * @param pattern - Source pattern
     * @param start - Start index
     * @returns Index or -1 if the character not found
     */
    static findFirstNonWhitespaceCharacter(pattern, start = 0) {
        for (let i = start; i < pattern.length; i += 1) {
            if (!StringUtils.isWhitespace(pattern[i])) {
                return i;
            }
        }
        return -1;
    }
    /**
     * Searches for the last non-whitespace character in the source pattern.
     *
     * @param pattern - Source pattern
     * @returns Index or -1 if the character not found
     */
    static findLastNonWhitespaceCharacter(pattern) {
        for (let i = pattern.length - 1; i >= 0; i -= 1) {
            if (!StringUtils.isWhitespace(pattern[i])) {
                return i;
            }
        }
        return -1;
    }
    /**
     * Finds the next whitespace character in the pattern.
     *
     * @param pattern Pattern to search in
     * @param start Start index
     * @returns Index of the next whitespace character or the length of the pattern if not found
     */
    static findNextWhitespaceCharacter(pattern, start = 0) {
        for (let i = start; i < pattern.length; i += 1) {
            if (StringUtils.isWhitespace(pattern[i])) {
                return i;
            }
        }
        return pattern.length;
    }
    /**
     * Escapes a specified character in the string.
     *
     * @param pattern - Input string
     * @param character - Character to escape
     * @param escapeCharacter - Escape character (optional)
     * @returns Escaped string
     */
    static escapeCharacter(pattern, character, escapeCharacter = ESCAPE_CHARACTER) {
        let result = EMPTY;
        for (let i = 0; i < pattern.length; i += 1) {
            if (pattern[i] === character && pattern[i - 1] !== escapeCharacter) {
                result += escapeCharacter;
            }
            result += pattern[i];
        }
        return result;
    }
    /**
     * Searches for the next non-whitespace character in the source pattern.
     *
     * @param pattern Pattern to search
     * @param start Start index
     * @returns Index of the next non-whitespace character or the length of the pattern
     */
    static skipWS(pattern, start = 0) {
        let i = start;
        while (i < pattern.length && StringUtils.isWhitespace(pattern[i])) {
            i += 1;
        }
        return Math.min(i, pattern.length);
    }
    /**
     * Searches for the previous non-whitespace character in the source pattern.
     *
     * @param pattern Pattern to search
     * @param start Start index
     * @returns Index of the previous non-whitespace character or -1
     */
    static skipWSBack(pattern, start = pattern.length - 1) {
        let i = start;
        while (i >= 0 && StringUtils.isWhitespace(pattern[i])) {
            i -= 1;
        }
        return Math.max(i, -1);
    }
    /**
     * Checks if the given character is a new line character.
     *
     * @param char Character to check
     * @returns `true` if the given character is a new line character, `false` otherwise.
     */
    static isEOL(char) {
        return char === CR || char === LF || char === FF;
    }
    /**
     * Splits a string along newline characters.
     *
     * @param input - Input string
     * @returns Splitted string
     */
    static splitStringByNewLines(input) {
        return input.split(/\r?\n/);
    }
    /**
     * Splits a string by new lines and stores the new line type for each line
     *
     * @param input The input string to be split
     * @returns An array of tuples, where each tuple contains a line of the input string and its
     * corresponding new line type ("lf", "crlf", or "cr")
     */
    static splitStringByNewLinesEx(input) {
        // Array to store the tuples of line and new line type
        const result = [];
        let currentLine = EMPTY;
        let newLineType = null;
        // Iterate over each character in the input string
        for (let i = 0; i < input.length; i += 1) {
            const char = input[i];
            if (char === CR) {
                if (input[i + 1] === LF) {
                    newLineType = 'crlf';
                    i += 1;
                }
                else {
                    newLineType = 'cr';
                }
                result.push([currentLine, newLineType]);
                currentLine = EMPTY;
                newLineType = null;
            }
            else if (char === LF) {
                newLineType = 'lf';
                result.push([currentLine, newLineType]);
                currentLine = EMPTY;
                newLineType = null;
            }
            else {
                currentLine += char;
            }
        }
        if (result.length === 0 || currentLine !== EMPTY) {
            result.push([currentLine, newLineType]);
        }
        return result;
    }
    /**
     * Merges an array of tuples (line, newLineType) into a single string
     *
     * @param input The array of tuples to be merged
     * @returns A single string containing the lines and new line characters from the input array
     */
    static mergeStringByNewLines(input) {
        let result = EMPTY;
        // Iterate over each tuple in the input array
        for (let i = 0; i < input.length; i += 1) {
            const [line, newLineType] = input[i];
            // Add the line to the result string
            result += line;
            // Add the appropriate new line character based on the newLineType
            if (newLineType !== null) {
                if (newLineType === 'crlf') {
                    result += CRLF;
                }
                else if (newLineType === 'cr') {
                    result += CR;
                }
                else {
                    result += LF;
                }
            }
        }
        return result;
    }
    /**
     * Helper method to parse a raw string as a number
     *
     * @param raw Raw string to parse
     * @returns Parsed number
     * @throws If the raw string can't be parsed as a number
     */
    static parseNumber(raw) {
        const result = parseInt(raw, 10);
        if (Number.isNaN(result)) {
            throw new Error('Expected a number');
        }
        return result;
    }
    /**
     * Checks if the given value is a string.
     *
     * @param value Value to check
     * @returns `true` if the value is a string, `false` otherwise
     */
    static isString(value) {
        return typeof value === 'string';
    }
    /**
     * Escapes the given characters in the input string.
     *
     * @param input Input string
     * @param characters Characters to escape (by default, no characters are escaped)
     * @returns Escaped string
     */
    static escapeCharacters(input, characters = new Set()) {
        let result = EMPTY;
        for (let i = 0; i < input.length; i += 1) {
            if (characters.has(input[i])) {
                result += ESCAPE_CHARACTER;
            }
            result += input[i];
        }
        return result;
    }
}

/**
 * Possible operators in the logical expression.
 */
var OperatorValue;
(function (OperatorValue) {
    OperatorValue["Not"] = "!";
    OperatorValue["And"] = "&&";
    OperatorValue["Or"] = "||";
})(OperatorValue || (OperatorValue = {}));
/**
 * Represents the different comment markers that can be used in an adblock rule.
 *
 * @example
 * - If the rule is `! This is just a comment`, then the marker will be `!`.
 * - If the rule is `# This is just a comment`, then the marker will be `#`.
 */
var CommentMarker;
(function (CommentMarker) {
    /**
     * Regular comment marker. It is supported by all ad blockers.
     */
    CommentMarker["Regular"] = "!";
    /**
     * Hashmark comment marker. It is supported by uBlock Origin and AdGuard,
     * and also used in hosts files.
     */
    CommentMarker["Hashmark"] = "#";
})(CommentMarker || (CommentMarker = {}));
/**
 * Represents the main categories that an adblock rule can belong to.
 * Of course, these include additional subcategories.
 */
var RuleCategory;
(function (RuleCategory) {
    /**
     * Empty "rules" that are only containing whitespaces. These rules are handled just for convenience.
     */
    RuleCategory["Empty"] = "Empty";
    /**
     * Syntactically invalid rules (tolerant mode only).
     */
    RuleCategory["Invalid"] = "Invalid";
    /**
     * Comment rules, such as comment rules, metadata rules, preprocessor rules, etc.
     */
    RuleCategory["Comment"] = "Comment";
    /**
     * Cosmetic rules, such as element hiding rules, CSS rules, scriptlet rules, HTML rules, and JS rules.
     */
    RuleCategory["Cosmetic"] = "Cosmetic";
    /**
     * Network rules, such as basic network rules, header remover network rules, redirect network rules,
     * response header filtering rules, etc.
     */
    RuleCategory["Network"] = "Network";
})(RuleCategory || (RuleCategory = {}));
/**
 * Represents similar types of modifiers values
 * which may be separated by a comma `,` (only for DomainList) or a pipe `|`.
 */
var ListNodeType;
(function (ListNodeType) {
    ListNodeType["Unknown"] = "Unknown";
    ListNodeType["AppList"] = "AppList";
    ListNodeType["DomainList"] = "DomainList";
    ListNodeType["MethodList"] = "MethodList";
    ListNodeType["StealthOptionList"] = "StealthOptionList";
})(ListNodeType || (ListNodeType = {}));
/**
 * Represents child items for {@link ListNodeType}.
 */
var ListItemNodeType;
(function (ListItemNodeType) {
    ListItemNodeType["Unknown"] = "Unknown";
    ListItemNodeType["App"] = "App";
    ListItemNodeType["Domain"] = "Domain";
    ListItemNodeType["Method"] = "Method";
    ListItemNodeType["StealthOption"] = "StealthOption";
})(ListItemNodeType || (ListItemNodeType = {}));
/**
 * Represents possible comment types.
 */
var CommentRuleType;
(function (CommentRuleType) {
    CommentRuleType["AgentCommentRule"] = "AgentCommentRule";
    CommentRuleType["CommentRule"] = "CommentRule";
    CommentRuleType["ConfigCommentRule"] = "ConfigCommentRule";
    CommentRuleType["HintCommentRule"] = "HintCommentRule";
    CommentRuleType["MetadataCommentRule"] = "MetadataCommentRule";
    CommentRuleType["PreProcessorCommentRule"] = "PreProcessorCommentRule";
})(CommentRuleType || (CommentRuleType = {}));
/**
 * Represents possible cosmetic rule types.
 */
var CosmeticRuleType;
(function (CosmeticRuleType) {
    CosmeticRuleType["ElementHidingRule"] = "ElementHidingRule";
    CosmeticRuleType["CssInjectionRule"] = "CssInjectionRule";
    CosmeticRuleType["ScriptletInjectionRule"] = "ScriptletInjectionRule";
    CosmeticRuleType["HtmlFilteringRule"] = "HtmlFilteringRule";
    CosmeticRuleType["JsInjectionRule"] = "JsInjectionRule";
})(CosmeticRuleType || (CosmeticRuleType = {}));
/**
 * Represents possible cosmetic rule separators.
 */
var CosmeticRuleSeparator;
(function (CosmeticRuleSeparator) {
    /**
     * @see {@link https://help.eyeo.com/adblockplus/how-to-write-filters#elemhide_basic}
     */
    CosmeticRuleSeparator["ElementHiding"] = "##";
    /**
     * @see {@link https://help.eyeo.com/adblockplus/how-to-write-filters#elemhide_basic}
     */
    CosmeticRuleSeparator["ElementHidingException"] = "#@#";
    /**
     * @see {@link https://help.eyeo.com/adblockplus/how-to-write-filters#elemhide_basic}
     */
    CosmeticRuleSeparator["ExtendedElementHiding"] = "#?#";
    /**
     * @see {@link https://help.eyeo.com/adblockplus/how-to-write-filters#elemhide_basic}
     */
    CosmeticRuleSeparator["ExtendedElementHidingException"] = "#@?#";
    /**
     * @see {@link https://help.eyeo.com/adblockplus/how-to-write-filters#elemhide_basic}
     */
    CosmeticRuleSeparator["AbpSnippet"] = "#$#";
    /**
     * @see {@link https://help.eyeo.com/adblockplus/how-to-write-filters#elemhide_basic}
     */
    CosmeticRuleSeparator["AbpSnippetException"] = "#@$#";
    /**
     * @see {@link https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#cosmetic-css-rules}
     */
    CosmeticRuleSeparator["AdgCssInjection"] = "#$#";
    /**
     * @see {@link https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#cosmetic-css-rules}
     */
    CosmeticRuleSeparator["AdgCssInjectionException"] = "#@$#";
    /**
     * @see {@link https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#cosmetic-css-rules}
     */
    CosmeticRuleSeparator["AdgExtendedCssInjection"] = "#$?#";
    /**
     * @see {@link https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#cosmetic-css-rules}
     */
    CosmeticRuleSeparator["AdgExtendedCssInjectionException"] = "#@$?#";
    /**
     * @see {@link https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#scriptlets}
     */
    CosmeticRuleSeparator["AdgJsInjection"] = "#%#";
    /**
     * @see {@link https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#scriptlets}
     */
    CosmeticRuleSeparator["AdgJsInjectionException"] = "#@%#";
    /**
     * @see {@link https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#html-filtering-rules}
     */
    CosmeticRuleSeparator["AdgHtmlFiltering"] = "$$";
    /**
     * @see {@link https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#html-filtering-rules}
     */
    CosmeticRuleSeparator["AdgHtmlFilteringException"] = "$@$";
})(CosmeticRuleSeparator || (CosmeticRuleSeparator = {}));
/**
 * Type map for binary serialization.
 *
 * @note Values should be fit into 8 bits.
 */
var BinaryTypeMap;
(function (BinaryTypeMap) {
    // Basic types
    BinaryTypeMap[BinaryTypeMap["Null"] = 1] = "Null";
    BinaryTypeMap[BinaryTypeMap["Undefined"] = 2] = "Undefined";
    BinaryTypeMap[BinaryTypeMap["Boolean"] = 3] = "Boolean";
    BinaryTypeMap[BinaryTypeMap["Int"] = 4] = "Int";
    BinaryTypeMap[BinaryTypeMap["Float"] = 5] = "Float";
    BinaryTypeMap[BinaryTypeMap["NotANumber"] = 6] = "NotANumber";
    BinaryTypeMap[BinaryTypeMap["String"] = 7] = "String";
    // AGTree nodes
    BinaryTypeMap[BinaryTypeMap["FilterListNode"] = 8] = "FilterListNode";
    BinaryTypeMap[BinaryTypeMap["EmptyRule"] = 9] = "EmptyRule";
    BinaryTypeMap[BinaryTypeMap["InvalidRule"] = 10] = "InvalidRule";
    BinaryTypeMap[BinaryTypeMap["CommentRuleNode"] = 11] = "CommentRuleNode";
    BinaryTypeMap[BinaryTypeMap["AgentNode"] = 12] = "AgentNode";
    BinaryTypeMap[BinaryTypeMap["AgentRuleNode"] = 13] = "AgentRuleNode";
    BinaryTypeMap[BinaryTypeMap["HintNode"] = 14] = "HintNode";
    BinaryTypeMap[BinaryTypeMap["HintRuleNode"] = 15] = "HintRuleNode";
    BinaryTypeMap[BinaryTypeMap["MetadataCommentRuleNode"] = 16] = "MetadataCommentRuleNode";
    BinaryTypeMap[BinaryTypeMap["ConfigCommentRuleNode"] = 17] = "ConfigCommentRuleNode";
    BinaryTypeMap[BinaryTypeMap["PreProcessorCommentRuleNode"] = 18] = "PreProcessorCommentRuleNode";
    BinaryTypeMap[BinaryTypeMap["ConfigNode"] = 19] = "ConfigNode";
    BinaryTypeMap[BinaryTypeMap["NetworkRuleNode"] = 20] = "NetworkRuleNode";
    BinaryTypeMap[BinaryTypeMap["HostRuleNode"] = 21] = "HostRuleNode";
    BinaryTypeMap[BinaryTypeMap["ElementHidingRule"] = 22] = "ElementHidingRule";
    BinaryTypeMap[BinaryTypeMap["CssInjectionRule"] = 23] = "CssInjectionRule";
    BinaryTypeMap[BinaryTypeMap["ScriptletInjectionRule"] = 24] = "ScriptletInjectionRule";
    BinaryTypeMap[BinaryTypeMap["JsInjectionRule"] = 25] = "JsInjectionRule";
    BinaryTypeMap[BinaryTypeMap["HtmlFilteringRule"] = 26] = "HtmlFilteringRule";
    BinaryTypeMap[BinaryTypeMap["ScriptletInjectionRuleBodyNode"] = 27] = "ScriptletInjectionRuleBodyNode";
    BinaryTypeMap[BinaryTypeMap["ElementHidingRuleBody"] = 28] = "ElementHidingRuleBody";
    BinaryTypeMap[BinaryTypeMap["CssInjectionRuleBody"] = 29] = "CssInjectionRuleBody";
    BinaryTypeMap[BinaryTypeMap["HtmlFilteringRuleBody"] = 30] = "HtmlFilteringRuleBody";
    BinaryTypeMap[BinaryTypeMap["JsInjectionRuleBody"] = 31] = "JsInjectionRuleBody";
    BinaryTypeMap[BinaryTypeMap["ValueNode"] = 32] = "ValueNode";
    BinaryTypeMap[BinaryTypeMap["RawNode"] = 33] = "RawNode";
    BinaryTypeMap[BinaryTypeMap["ModifierNode"] = 34] = "ModifierNode";
    BinaryTypeMap[BinaryTypeMap["ModifierListNode"] = 35] = "ModifierListNode";
    BinaryTypeMap[BinaryTypeMap["ParameterListNode"] = 36] = "ParameterListNode";
    BinaryTypeMap[BinaryTypeMap["DomainListNode"] = 37] = "DomainListNode";
    BinaryTypeMap[BinaryTypeMap["DomainNode"] = 38] = "DomainNode";
    BinaryTypeMap[BinaryTypeMap["MethodListNode"] = 39] = "MethodListNode";
    BinaryTypeMap[BinaryTypeMap["MethodNode"] = 40] = "MethodNode";
    BinaryTypeMap[BinaryTypeMap["StealthOptionListNode"] = 41] = "StealthOptionListNode";
    BinaryTypeMap[BinaryTypeMap["StealthOptionNode"] = 42] = "StealthOptionNode";
    BinaryTypeMap[BinaryTypeMap["AppListNode"] = 43] = "AppListNode";
    BinaryTypeMap[BinaryTypeMap["AppNode"] = 44] = "AppNode";
    BinaryTypeMap[BinaryTypeMap["HostnameListNode"] = 45] = "HostnameListNode";
    BinaryTypeMap[BinaryTypeMap["InvalidRuleErrorNode"] = 46] = "InvalidRuleErrorNode";
    BinaryTypeMap[BinaryTypeMap["ExpressionVariableNode"] = 47] = "ExpressionVariableNode";
    BinaryTypeMap[BinaryTypeMap["ExpressionOperatorNode"] = 48] = "ExpressionOperatorNode";
    BinaryTypeMap[BinaryTypeMap["ExpressionParenthesisNode"] = 49] = "ExpressionParenthesisNode";
})(BinaryTypeMap || (BinaryTypeMap = {}));
/**
 * Value map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent frequently used values.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 */
const SYNTAX_SERIALIZATION_MAP = new Map([
    [AdblockSyntax.Common, 0],
    [AdblockSyntax.Abp, 1],
    [AdblockSyntax.Adg, 2],
    [AdblockSyntax.Ubo, 3],
]);
/**
 * Value map for binary deserialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent frequently used values.
 */
const SYNTAX_DESERIALIZATION_MAP = new Map(Array.from(SYNTAX_SERIALIZATION_MAP, ([key, value]) => [value, key]));
/**
 * Represents the different types of network rules.
 */
var NetworkRuleType;
(function (NetworkRuleType) {
    NetworkRuleType["NetworkRule"] = "NetworkRule";
    NetworkRuleType["HostRule"] = "HostRule";
})(NetworkRuleType || (NetworkRuleType = {}));

/**
 * @file Customized syntax error class for Adblock Filter Parser.
 */
const ERROR_NAME$3 = 'AdblockSyntaxError';
/**
 * Customized syntax error class for Adblock Filter Parser,
 * which contains the location range of the error.
 */
class AdblockSyntaxError extends SyntaxError {
    /**
     * Start offset of the error.
     */
    start;
    /**
     * End offset of the error.
     */
    end;
    /**
     * Constructs a new `AdblockSyntaxError` instance.
     *
     * @param message Error message.
     * @param start Start offset of the error.
     * @param end End offset of the error.
     */
    constructor(message, start, end) {
        super(message);
        this.name = ERROR_NAME$3;
        this.start = start;
        this.end = end;
    }
}

/**
 * @file Customized error class for not implemented features.
 */
const ERROR_NAME$2 = 'NotImplementedError';
const BASE_MESSAGE = 'Not implemented';
/**
 * Customized error class for not implemented features.
 */
class NotImplementedError extends Error {
    /**
     * Constructs a new `NotImplementedError` instance.
     *
     * @param message Additional error message (optional)
     */
    constructor(message = undefined) {
        // Prepare the full error message
        const fullMessage = message
            ? `${BASE_MESSAGE}: ${message}`
            : BASE_MESSAGE;
        super(fullMessage);
        this.name = ERROR_NAME$2;
    }
}

/* eslint-disable @typescript-eslint/no-unused-vars */
/**
 * @file Base parser class.
 */
/**
 * Base class for parsers. Each parser should extend this class.
 */
class ParserBase {
    /**
     * Parses the input string and returns the AST node.
     *
     * @param input Input string to parse.
     * @param options Parser options, see {@link ParserOptions}.
     * @param baseOffset Base offset. Locations in the AST node will be relative to this offset.
     * @param args Additional, parser-specific arguments, if needed.
     */
    static parse(input, options, baseOffset, ...args) {
        throw new NotImplementedError();
    }
    /**
     * Generates a string from the AST node.
     *
     * @param node AST node to generate a string from.
     */
    static generate(node) {
        throw new NotImplementedError();
    }
    /**
     * Serializes the AST node to a byte buffer.
     *
     * @param node AST node to serialize.
     * @param buffer Output byte buffer to write to.
     * @param args Additional, parser-specific arguments, if needed.
     */
    static serialize(node, buffer, ...args) {
        throw new NotImplementedError();
    }
    /**
     * Deserializes the AST node from a byte buffer.
     *
     * @param buffer Input byte buffer to read from.
     * @param node Destination node to write to.
     * @param args Additional, parser-specific arguments, if needed.
     */
    static deserialize(buffer, node, ...args) {
        throw new NotImplementedError();
    }
}

/**
 * @file Common options for all parsers.
 */
/**
 * Default parser options.
 */
const defaultParserOptions = Object.freeze({
    tolerant: false,
    isLocIncluded: true,
    parseAbpSpecificRules: true,
    parseUboSpecificRules: true,
    includeRaws: true,
    ignoreComments: false,
    parseHostRules: false,
});

/**
 * Checks whether the given value is undefined.
 *
 * @param value Value to check.
 *
 * @returns `true` if the value is 'undefined', `false` otherwise.
 */
const isUndefined = (value) => {
    return typeof value === 'undefined';
};
/**
 * Checks whether the given value is null.
 *
 * @param value Value to check.
 *
 * @returns `true` if the value is 'null', `false` otherwise.
 */
const isNull = (value) => {
    return value === null;
};
/**
 * Checks whether the given value is a string.
 *
 * @param value Value to check.
 * @returns `true` if the value is a string, `false` otherwise.
 */
const isString = (value) => {
    return typeof value === 'string';
};
/**
 * Checks whether the given value is an array of Uint8Arrays.
 *
 * @param value Value to check.
 *
 * @returns True if the value type is an array of Uint8Arrays.
 */
const isArrayOfUint8Arrays = (value) => {
    return Array.isArray(value) && value.every((chunk) => chunk instanceof Uint8Array);
};

/* eslint-disable no-param-reassign */
/**
 * Property map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent a property.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 */
var ValueNodeSerializationMap;
(function (ValueNodeSerializationMap) {
    ValueNodeSerializationMap[ValueNodeSerializationMap["Value"] = 1] = "Value";
    ValueNodeSerializationMap[ValueNodeSerializationMap["FrequentValue"] = 2] = "FrequentValue";
    ValueNodeSerializationMap[ValueNodeSerializationMap["Start"] = 3] = "Start";
    ValueNodeSerializationMap[ValueNodeSerializationMap["End"] = 4] = "End";
})(ValueNodeSerializationMap || (ValueNodeSerializationMap = {}));
/**
 * Value parser.
 * This parser is very simple, it just exists to provide a consistent interface for parsing and generating values.
 */
class ValueParser extends ParserBase {
    /**
     * Parses a value.
     *
     * @param raw Raw input to parse.
     * @param options Global parser options.
     * @param baseOffset Starting offset of the input. Node locations are calculated relative to this offset.
     *
     * @returns Value node.
     */
    static parse(raw, options = defaultParserOptions, baseOffset = 0) {
        const result = {
            type: 'Value',
            value: raw,
        };
        if (options.isLocIncluded) {
            result.start = baseOffset;
            result.end = baseOffset + raw.length;
        }
        return result;
    }
    /**
     * Converts a value node to a string.
     *
     * @param node Value node.
     * @returns Raw string.
     */
    static generate(node) {
        return node.value;
    }
    /**
     * Serializes a value node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     * @param frequentValuesMap Optional map of frequent values.
     * @param toLower Whether to lowercase the value before the frequent value match (defaults to `false`).
     */
    static serialize(node, buffer, frequentValuesMap, toLower = false) {
        buffer.writeUint8(BinaryTypeMap.ValueNode);
        const frequentValue = frequentValuesMap?.get(toLower ? node.value.toLowerCase() : node.value);
        // note: do not use just `if (frequentValue)` because it can be 0
        if (!isUndefined(frequentValue)) {
            buffer.writeUint8(ValueNodeSerializationMap.FrequentValue);
            buffer.writeUint8(frequentValue);
        }
        else {
            buffer.writeUint8(ValueNodeSerializationMap.Value);
            buffer.writeString(node.value);
        }
        // note: do not use just `if (node.start)` because it can be 0
        if (!isUndefined(node.start)) {
            buffer.writeUint8(ValueNodeSerializationMap.Start);
            buffer.writeUint32(node.start);
        }
        if (!isUndefined(node.end)) {
            buffer.writeUint8(ValueNodeSerializationMap.End);
            buffer.writeUint32(node.end);
        }
        buffer.writeUint8(NULL);
    }
    /**
     * Deserializes a value node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     * @param frequentValuesMap Optional map of frequent values.
     * @throws If the binary data is malformed.
     */
    static deserialize(buffer, node, frequentValuesMap) {
        buffer.assertUint8(BinaryTypeMap.ValueNode);
        node.type = 'Value';
        let prop = buffer.readUint8();
        while (prop !== NULL) {
            switch (prop) {
                case ValueNodeSerializationMap.Value:
                    node.value = buffer.readString();
                    break;
                case ValueNodeSerializationMap.FrequentValue:
                    node.value = frequentValuesMap?.get(buffer.readUint8()) ?? EMPTY;
                    break;
                case ValueNodeSerializationMap.Start:
                    node.start = buffer.readUint32();
                    break;
                case ValueNodeSerializationMap.End:
                    node.end = buffer.readUint32();
                    break;
                default:
                    throw new Error(`Invalid property: ${prop}`);
            }
            prop = buffer.readUint8();
        }
    }
}

/* eslint-disable no-param-reassign */
/**
 * Property map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent a property.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 */
var AgentNodeSerializationMap;
(function (AgentNodeSerializationMap) {
    AgentNodeSerializationMap[AgentNodeSerializationMap["Adblock"] = 1] = "Adblock";
    AgentNodeSerializationMap[AgentNodeSerializationMap["Version"] = 2] = "Version";
    AgentNodeSerializationMap[AgentNodeSerializationMap["Start"] = 3] = "Start";
    AgentNodeSerializationMap[AgentNodeSerializationMap["End"] = 4] = "End";
})(AgentNodeSerializationMap || (AgentNodeSerializationMap = {}));
/**
 * Possible AdGuard agent markers.
 */
const ADG_NAME_MARKERS = new Set([
    'adguard',
    'adg',
]);
/**
 * Possible uBlock Origin agent markers.
 */
const UBO_NAME_MARKERS = new Set([
    'ublock',
    'ublock origin',
    'ubo',
]);
/**
 * Possible Adblock Plus agent markers.
 */
const ABP_NAME_MARKERS = new Set([
    'adblock',
    'adblock plus',
    'adblockplus',
    'abp',
]);
/**
 * Value map for binary deserialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent frequently used values.
 */
const FREQUENT_AGENTS_DESERIALIZATION_MAP = new Map([
    // AdGuard
    [0, 'AdGuard'],
    [1, 'ADG'],
    // uBlock Origin
    [2, 'uBlock Origin'],
    [3, 'uBlock'],
    [4, 'uBO'],
    // Adblock Plus
    [5, 'Adblock Plus'],
    [6, 'AdblockPlus'],
    [7, 'ABP'],
    [8, 'AdBlock'],
]);
/**
 * Value map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent frequently used values.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 */
const FREQUENT_AGENTS_SERIALIZATION_MAP = new Map(Array.from(FREQUENT_AGENTS_DESERIALIZATION_MAP).map(([key, value]) => [value.toLowerCase(), key]));
/**
 * Returns the adblock syntax based on the adblock name parsed from the agent type comment.
 * Needed for modifiers validation of network rules by AGLint.
 *
 * @param name Adblock name.
 *
 * @returns Adblock syntax.
 */
const getAdblockSyntax = (name) => {
    let syntax = AdblockSyntax.Common;
    const lowerCaseName = name.toLowerCase();
    if (ADG_NAME_MARKERS.has(lowerCaseName)) {
        syntax = AdblockSyntax.Adg;
    }
    else if (UBO_NAME_MARKERS.has(lowerCaseName)) {
        syntax = AdblockSyntax.Ubo;
    }
    else if (ABP_NAME_MARKERS.has(lowerCaseName)) {
        syntax = AdblockSyntax.Abp;
    }
    return syntax;
};
/**
 * `AgentParser` is responsible for parsing single adblock agent elements.
 *
 * @example
 * If the adblock agent rule is
 * ```adblock
 * [Adblock Plus 2.0; AdGuard]
 * ```
 * then the adblock agents are `Adblock Plus 2.0` and `AdGuard`, and this
 * class is responsible for parsing them. The rule itself is parsed by
 * `AgentCommentRuleParser`, which uses this class to parse single agents.
 */
class AgentParser extends ParserBase {
    /**
     * Checks if the string is a valid version.
     *
     * @param str String to check
     * @returns `true` if the string is a valid version, `false` otherwise
     */
    static isValidVersion(str) {
        return valid(coerce(str)) !== null;
    }
    /**
     * Parses a raw rule as an adblock agent comment.
     *
     * @param raw Raw input to parse.
     * @param options Global parser options.
     * @param baseOffset Starting offset of the input. Node locations are calculated relative to this offset.
     * @returns Agent rule AST
     * @throws {AdblockSyntaxError} If the raw rule cannot be parsed as an adblock agent
     */
    static parse(raw, options = defaultParserOptions, baseOffset = 0) {
        let offset = 0;
        // Save name start position
        const nameStartIndex = offset;
        let nameEndIndex = offset;
        // Prepare variables for name and version
        let name;
        let version;
        // default value for the syntax
        let syntax = AdblockSyntax.Common;
        // Get agent parts by splitting it by spaces. The last part may be a version.
        // Example: "Adblock Plus 2.0"
        while (offset < raw.length) {
            // Skip whitespace before the part
            offset = StringUtils.skipWS(raw, offset);
            const partEnd = StringUtils.findNextWhitespaceCharacter(raw, offset);
            const part = raw.slice(offset, partEnd);
            if (AgentParser.isValidVersion(part)) {
                if (!isUndefined(version)) {
                    throw new AdblockSyntaxError('Duplicated versions are not allowed', baseOffset + offset, baseOffset + partEnd);
                }
                const parsedNamePart = raw.slice(nameStartIndex, nameEndIndex);
                name = ValueParser.parse(parsedNamePart, options, baseOffset + nameStartIndex);
                version = ValueParser.parse(part, options, baseOffset + offset);
                syntax = getAdblockSyntax(parsedNamePart);
            }
            else {
                nameEndIndex = partEnd;
            }
            // Skip whitespace after the part
            offset = StringUtils.skipWS(raw, partEnd);
        }
        // If we didn't find a version, the whole string is the name
        if (isUndefined(name)) {
            const parsedNamePart = raw.slice(nameStartIndex, nameEndIndex);
            name = ValueParser.parse(parsedNamePart, options, baseOffset + nameStartIndex);
            syntax = getAdblockSyntax(parsedNamePart);
        }
        // Agent name cannot be empty
        if (name.value.length === 0) {
            throw new AdblockSyntaxError('Agent name cannot be empty', baseOffset, baseOffset + raw.length);
        }
        const result = {
            type: 'Agent',
            adblock: name,
            syntax,
        };
        // only add version if it's present
        if (version) {
            result.version = version;
        }
        if (options.isLocIncluded) {
            result.start = baseOffset;
            result.end = baseOffset + raw.length;
        }
        return result;
    }
    /**
     * Converts an adblock agent node to a string.
     *
     * @param value Agent node
     * @returns Raw string
     */
    static generate(value) {
        let result = EMPTY;
        // Agent adblock name
        result += value.adblock.value;
        // Agent adblock version (if present)
        if (!isUndefined(value.version)) {
            // Add a space between the name and the version
            result += SPACE;
            result += value.version.value;
        }
        return result;
    }
    /**
     * Serializes an agent node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     */
    static serialize(node, buffer) {
        buffer.writeUint8(BinaryTypeMap.AgentNode);
        buffer.writeUint8(AgentNodeSerializationMap.Adblock);
        ValueParser.serialize(node.adblock, buffer, FREQUENT_AGENTS_SERIALIZATION_MAP, true);
        if (!isUndefined(node.version)) {
            buffer.writeUint8(AgentNodeSerializationMap.Version);
            ValueParser.serialize(node.version, buffer);
        }
        if (!isUndefined(node.start)) {
            buffer.writeUint8(AgentNodeSerializationMap.Start);
            buffer.writeUint32(node.start);
        }
        if (!isUndefined(node.end)) {
            buffer.writeUint8(AgentNodeSerializationMap.End);
            buffer.writeUint32(node.end);
        }
        buffer.writeUint8(NULL);
    }
    /**
     * Deserializes an agent node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     * @throws If the binary data is malformed.
     */
    static deserialize(buffer, node) {
        buffer.assertUint8(BinaryTypeMap.AgentNode);
        node.type = 'Agent';
        let prop = buffer.readUint8();
        while (prop !== NULL) {
            switch (prop) {
                case AgentNodeSerializationMap.Adblock:
                    ValueParser.deserialize(buffer, node.adblock = {}, FREQUENT_AGENTS_DESERIALIZATION_MAP);
                    if (node.adblock) {
                        node.syntax = getAdblockSyntax(node.adblock.value);
                    }
                    break;
                case AgentNodeSerializationMap.Version:
                    ValueParser.deserialize(buffer, node.version = {});
                    break;
                case AgentNodeSerializationMap.Start:
                    node.start = buffer.readUint32();
                    break;
                case AgentNodeSerializationMap.End:
                    node.end = buffer.readUint32();
                    break;
                default:
                    throw new Error(`Invalid property: ${prop}`);
            }
            prop = buffer.readUint8();
        }
    }
}

/**
 * @file Cosmetic rule separator finder and categorizer
 */
/**
 * Utility class for cosmetic rule separators.
 */
class CosmeticRuleSeparatorUtils {
    /**
     * Checks whether the specified separator is an exception.
     *
     * @param separator Separator to check
     * @returns `true` if the separator is an exception, `false` otherwise
     */
    static isException(separator) {
        // Simply check the second character
        return separator[1] === AT_SIGN;
    }
    /**
     * Checks whether the specified separator is marks an Extended CSS cosmetic rule.
     *
     * @param separator Separator to check
     * @returns `true` if the separator is marks an Extended CSS cosmetic rule, `false` otherwise
     */
    static isExtendedCssMarker(separator) {
        return (separator === CosmeticRuleSeparator.ExtendedElementHiding
            || separator === CosmeticRuleSeparator.ExtendedElementHidingException
            || separator === CosmeticRuleSeparator.AdgExtendedCssInjection
            || separator === CosmeticRuleSeparator.AdgExtendedCssInjectionException);
    }
    /**
     * Looks for the cosmetic rule separator in the rule. This is a simplified version that
     * masks the recursive function.
     *
     * @param rule Raw rule
     * @returns Separator result or null if no separator was found
     */
    static find(rule) {
        /**
         * Helper function to create results of the `find` method.
         *
         * @param start Start position
         * @param separator Separator type
         * @returns Cosmetic rule separator node
         */
        // eslint-disable-next-line max-len
        function createResult(start, separator) {
            return {
                separator,
                start,
                end: start + separator.length,
            };
        }
        for (let i = 0; i < rule.length; i += 1) {
            if (rule[i] === '#') {
                if (rule[i + 1] === '#' && rule[i - 1] !== SPACE) {
                    // ##
                    return createResult(i, CosmeticRuleSeparator.ElementHiding);
                }
                if (rule[i + 1] === '?' && rule[i + 2] === '#') {
                    // #?#
                    return createResult(i, CosmeticRuleSeparator.ExtendedElementHiding);
                }
                if (rule[i + 1] === '%' && rule[i + 2] === '#') {
                    // #%#
                    return createResult(i, CosmeticRuleSeparator.AdgJsInjection);
                }
                if (rule[i + 1] === '$') {
                    if (rule[i + 2] === '#') {
                        // #$#
                        return createResult(i, CosmeticRuleSeparator.AdgCssInjection);
                    }
                    if (rule[i + 2] === '?' && rule[i + 3] === '#') {
                        // #$?#
                        return createResult(i, CosmeticRuleSeparator.AdgExtendedCssInjection);
                    }
                }
                // Exceptions
                if (rule[i + 1] === '@') {
                    if (rule[i + 2] === '#' && rule[i - 1] !== SPACE) {
                        // #@#
                        return createResult(i, CosmeticRuleSeparator.ElementHidingException);
                    }
                    if (rule[i + 2] === '?' && rule[i + 3] === '#') {
                        // #@?#
                        return createResult(i, CosmeticRuleSeparator.ExtendedElementHidingException);
                    }
                    if (rule[i + 2] === '%' && rule[i + 3] === '#') {
                        // #@%#
                        return createResult(i, CosmeticRuleSeparator.AdgJsInjectionException);
                    }
                    if (rule[i + 2] === '$') {
                        if (rule[i + 3] === '#') {
                            // #@$#
                            return createResult(i, CosmeticRuleSeparator.AdgCssInjectionException);
                        }
                        if (rule[i + 3] === '?' && rule[i + 4] === '#') {
                            // #@$?#
                            return createResult(i, CosmeticRuleSeparator.AdgExtendedCssInjectionException);
                        }
                    }
                }
            }
            if (rule[i] === '$') {
                if (rule[i + 1] === '$') {
                    // $$
                    return createResult(i, CosmeticRuleSeparator.AdgHtmlFiltering);
                }
                if (rule[i + 1] === '@' && rule[i + 2] === '$') {
                    // $@$
                    return createResult(i, CosmeticRuleSeparator.AdgHtmlFilteringException);
                }
            }
        }
        return null;
    }
}

/* eslint-disable no-param-reassign */
/**
 * Property map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent a property.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 */
var AgentRuleSerializationMap;
(function (AgentRuleSerializationMap) {
    AgentRuleSerializationMap[AgentRuleSerializationMap["Children"] = 1] = "Children";
    AgentRuleSerializationMap[AgentRuleSerializationMap["Start"] = 2] = "Start";
    AgentRuleSerializationMap[AgentRuleSerializationMap["End"] = 3] = "End";
})(AgentRuleSerializationMap || (AgentRuleSerializationMap = {}));
/**
 * `AgentParser` is responsible for parsing an Adblock agent rules.
 * Adblock agent comment marks that the filter list is supposed to
 * be used by the specified ad blockers.
 *
 * @example
 *  - ```adblock
 *    [AdGuard]
 *    ```
 *  - ```adblock
 *    [Adblock Plus 2.0]
 *    ```
 *  - ```adblock
 *    [uBlock Origin]
 *    ```
 *  - ```adblock
 *    [uBlock Origin 1.45.3]
 *    ```
 *  - ```adblock
 *    [Adblock Plus 2.0; AdGuard]
 *    ```
 */
class AgentCommentRuleParser extends ParserBase {
    /**
     * Checks if the raw rule is an adblock agent comment.
     *
     * @param raw Raw rule
     * @returns `true` if the rule is an adblock agent, `false` otherwise
     */
    static isAgentRule(raw) {
        const rawTrimmed = raw.trim();
        if (rawTrimmed.startsWith(OPEN_SQUARE_BRACKET) && rawTrimmed.endsWith(CLOSE_SQUARE_BRACKET)) {
            // Avoid this case: [$adg-modifier]##[class^="adg-"]
            return isNull(CosmeticRuleSeparatorUtils.find(rawTrimmed));
        }
        return false;
    }
    /**
     * Parses a raw rule as an adblock agent comment.
     *
     * @param raw Raw input to parse.
     * @param options Global parser options.
     * @param baseOffset Starting offset of the input. Node locations are calculated relative to this offset.
     * @returns Agent rule AST or null (if the raw rule cannot be parsed as an adblock agent comment)
     */
    static parse(raw, options = defaultParserOptions, baseOffset = 0) {
        // Ignore non-agent rules
        if (!AgentCommentRuleParser.isAgentRule(raw)) {
            return null;
        }
        let offset = 0;
        // Skip whitespace characters before the rule
        offset = StringUtils.skipWS(raw, offset);
        // Skip opening bracket
        offset += 1;
        // last character should be a closing bracket
        const closingBracketIndex = StringUtils.skipWSBack(raw, raw.length - 1);
        if (closingBracketIndex === -1 || raw[closingBracketIndex] !== CLOSE_SQUARE_BRACKET) {
            throw new AdblockSyntaxError('Missing closing bracket', offset, offset + raw.length);
        }
        // Initialize the agent list
        const result = {
            type: CommentRuleType.AgentCommentRule,
            syntax: AdblockSyntax.Common,
            category: RuleCategory.Comment,
            children: [],
        };
        if (options.includeRaws) {
            result.raws = {
                text: raw,
            };
        }
        if (options.isLocIncluded) {
            result.start = baseOffset;
            result.end = baseOffset + raw.length;
        }
        while (offset < closingBracketIndex) {
            // Skip whitespace characters before the agent
            offset = StringUtils.skipWS(raw, offset);
            // Find the separator or the closing bracket
            let separatorIndex = raw.indexOf(SEMICOLON, offset);
            if (separatorIndex === -1) {
                separatorIndex = closingBracketIndex;
            }
            // Find the last non-whitespace character of the agent
            // [AdGuard  ; Adblock Plus 2.0]
            //        ^
            // (if we have spaces between the agent name and the separator)
            const agentEndIndex = StringUtils.findLastNonWhitespaceCharacter(raw.slice(offset, separatorIndex)) + offset + 1;
            // Collect the agent
            result.children.push(AgentParser.parse(raw.slice(offset, agentEndIndex), options, baseOffset + offset));
            // Set the offset to the next agent or the end of the rule
            offset = separatorIndex + 1;
        }
        if (result.children.length === 0) {
            throw new AdblockSyntaxError('Empty agent list', baseOffset, baseOffset + raw.length);
        }
        return result;
    }
    /**
     * Converts an adblock agent AST to a string.
     *
     * @param ast Agent rule AST
     * @returns Raw string
     */
    static generate(ast) {
        let result = OPEN_SQUARE_BRACKET;
        result += ast.children
            .map(AgentParser.generate)
            .join(SEMICOLON + SPACE);
        result += CLOSE_SQUARE_BRACKET;
        return result;
    }
    /**
     * Serializes an adblock agent list node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     */
    // TODO: add support for raws, if ever needed
    static serialize(node, buffer) {
        buffer.writeUint8(BinaryTypeMap.AgentRuleNode);
        const count = node.children.length;
        if (count) {
            buffer.writeUint8(AgentRuleSerializationMap.Children);
            // note: we store the count, because re-construction of the array is faster if we know the length
            // 8 bits is more than enough here
            if (count > UINT8_MAX) {
                throw new Error(`Too many children: ${count}, the limit is ${UINT8_MAX}`);
            }
            buffer.writeUint8(count);
            for (let i = 0; i < count; i += 1) {
                AgentParser.serialize(node.children[i], buffer);
            }
        }
        if (!isUndefined(node.start)) {
            buffer.writeUint8(AgentRuleSerializationMap.Start);
            buffer.writeUint32(node.start);
        }
        if (!isUndefined(node.end)) {
            buffer.writeUint8(AgentRuleSerializationMap.End);
            buffer.writeUint32(node.end);
        }
        buffer.writeUint8(NULL);
    }
    /**
     * Deserializes an agent list node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     */
    static deserialize(buffer, node) {
        buffer.assertUint8(BinaryTypeMap.AgentRuleNode);
        node.type = CommentRuleType.AgentCommentRule;
        node.syntax = AdblockSyntax.Common;
        node.category = RuleCategory.Comment;
        let prop = buffer.readUint8();
        while (prop !== NULL) {
            switch (prop) {
                case AgentRuleSerializationMap.Children:
                    node.children = new Array(buffer.readUint8());
                    // read children
                    for (let i = 0; i < node.children.length; i += 1) {
                        AgentParser.deserialize(buffer, node.children[i] = {});
                    }
                    break;
                case AgentRuleSerializationMap.Start:
                    node.start = buffer.readUint32();
                    break;
                case AgentRuleSerializationMap.End:
                    node.end = buffer.readUint32();
                    break;
                default:
                    throw new Error(`Invalid property: ${prop}`);
            }
            prop = buffer.readUint8();
        }
    }
}

/* eslint-disable no-param-reassign */
/**
 * Property map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent a property.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 */
var ParameterListNodeSerializationMap;
(function (ParameterListNodeSerializationMap) {
    ParameterListNodeSerializationMap[ParameterListNodeSerializationMap["Children"] = 1] = "Children";
    ParameterListNodeSerializationMap[ParameterListNodeSerializationMap["Start"] = 2] = "Start";
    ParameterListNodeSerializationMap[ParameterListNodeSerializationMap["End"] = 3] = "End";
})(ParameterListNodeSerializationMap || (ParameterListNodeSerializationMap = {}));
class ParameterListParser extends ParserBase {
    /**
     * Parses a raw parameter list.
     *
     * @param raw Raw input to parse.
     * @param options Global parser options.
     * @param baseOffset Starting offset of the input. Node locations are calculated relative to this offset.
     * @param separator Separator character (default: comma)
     * @returns Parameter list AST
     */
    static parse(raw, options = defaultParserOptions, baseOffset = 0, separator = COMMA) {
        // Prepare the parameter list node
        const params = {
            type: 'ParameterList',
            children: [],
        };
        const { length } = raw;
        if (options.isLocIncluded) {
            params.start = baseOffset;
            params.end = baseOffset + length;
        }
        let offset = 0;
        // Parse parameters: skip whitespace before and after each parameter, and
        // split parameters by the separator character.
        while (offset < length) {
            // Skip whitespace before parameter
            offset = StringUtils.skipWS(raw, offset);
            // Parameter may only contain whitespace
            // In this case, we reached the end of the parameter list
            if (raw[offset] === separator || offset === length) {
                // Add a null for empty parameter
                params.children.push(null);
                // Skip separator
                offset += 1;
            }
            else {
                // Get parameter start position
                const paramStart = offset;
                // Get next unescaped separator position
                const nextSeparator = StringUtils.findUnescapedNonStringNonRegexChar(raw, separator, offset);
                // Get parameter end position
                const paramEnd = nextSeparator !== -1
                    ? StringUtils.skipWSBack(raw, nextSeparator - 1)
                    : StringUtils.skipWSBack(raw);
                // Add parameter to the list
                const param = ValueParser.parse(raw.slice(paramStart, paramEnd + 1), options, baseOffset + paramStart);
                params.children.push(param);
                // Set offset to the next separator position + 1
                offset = nextSeparator !== -1 ? nextSeparator + 1 : length;
            }
        }
        // If the last character was a separator, add an additional null parameter
        if (raw[length - 1] === separator) {
            params.children.push(null);
        }
        return params;
    }
    /**
     * Converts a parameter list AST to a string.
     *
     * @param params Parameter list AST
     * @param separator Separator character (default: comma)
     * @returns String representation of the parameter list
     */
    static generate(params, separator = COMMA) {
        const collection = [];
        // add parameters
        let i = 0;
        for (; i < params.children.length; i += 1) {
            const param = params.children[i];
            if (param === null) {
                collection.push(EMPTY);
            }
            else {
                collection.push(ValueParser.generate(param));
            }
        }
        // join parameters with separator
        // if the separator is a space, join with a single space
        const result = collection.join(separator === SPACE ? separator : `${separator}${SPACE}`);
        return result;
    }
    /**
     * Serializes a parameter list node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     * @param frequentValuesMap Optional map of frequent values.
     * @param toLower Whether to lowercase the value before the frequent value match (defaults to `false`).
     */
    static serialize(node, buffer, frequentValuesMap, toLower = false) {
        buffer.writeUint8(BinaryTypeMap.ParameterListNode);
        const count = node.children.length;
        buffer.writeUint8(ParameterListNodeSerializationMap.Children);
        // note: we store the count, because re-construction of the array is faster if we know the length
        buffer.writeUint32(count);
        for (let i = 0; i < count; i += 1) {
            const child = node.children[i];
            if (isNull(child)) {
                buffer.writeUint8(BinaryTypeMap.Null);
                continue;
            }
            ValueParser.serialize(child, buffer, frequentValuesMap, toLower);
        }
        if (!isUndefined(node.start)) {
            buffer.writeUint8(ParameterListNodeSerializationMap.Start);
            buffer.writeUint32(node.start);
        }
        if (!isUndefined(node.end)) {
            buffer.writeUint8(ParameterListNodeSerializationMap.End);
            buffer.writeUint32(node.end);
        }
        buffer.writeUint8(NULL);
    }
    /**
     * Deserializes a parameter list node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     * @param frequentValuesMap Optional map of frequent values.
     * @throws If the binary data is malformed.
     */
    static deserialize(buffer, node, frequentValuesMap) {
        buffer.assertUint8(BinaryTypeMap.ParameterListNode);
        node.type = 'ParameterList';
        let prop = buffer.readUint8();
        while (prop !== NULL) {
            switch (prop) {
                case ParameterListNodeSerializationMap.Children:
                    node.children = new Array(buffer.readUint32());
                    // read children
                    for (let i = 0; i < node.children.length; i += 1) {
                        switch (buffer.peekUint8()) {
                            case BinaryTypeMap.Null:
                                buffer.readUint8();
                                node.children[i] = null;
                                break;
                            case BinaryTypeMap.ValueNode:
                                ValueParser.deserialize(buffer, node.children[i] = {}, frequentValuesMap);
                                break;
                            default:
                                throw new Error(`Invalid child type: ${buffer.peekUint8()}`);
                        }
                    }
                    break;
                case ParameterListNodeSerializationMap.Start:
                    node.start = buffer.readUint32();
                    break;
                case ParameterListNodeSerializationMap.End:
                    node.end = buffer.readUint32();
                    break;
                default:
                    throw new Error(`Invalid property: ${prop}`);
            }
            prop = buffer.readUint8();
        }
    }
}

/* eslint-disable no-param-reassign */
/**
 * @file AGLint configuration comments. Inspired by ESLint inline configuration comments.
 * @see {@link https://eslint.org/docs/latest/user-guide/configuring/rules#using-configuration-comments}
 */
/**
 * Property map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent a property.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 */
var ConfigCommentRuleSerializationMap;
(function (ConfigCommentRuleSerializationMap) {
    ConfigCommentRuleSerializationMap[ConfigCommentRuleSerializationMap["Marker"] = 1] = "Marker";
    ConfigCommentRuleSerializationMap[ConfigCommentRuleSerializationMap["Command"] = 2] = "Command";
    ConfigCommentRuleSerializationMap[ConfigCommentRuleSerializationMap["Params"] = 3] = "Params";
    ConfigCommentRuleSerializationMap[ConfigCommentRuleSerializationMap["Comment"] = 4] = "Comment";
    ConfigCommentRuleSerializationMap[ConfigCommentRuleSerializationMap["Start"] = 5] = "Start";
    ConfigCommentRuleSerializationMap[ConfigCommentRuleSerializationMap["End"] = 6] = "End";
})(ConfigCommentRuleSerializationMap || (ConfigCommentRuleSerializationMap = {}));
/**
 * Property map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent a property.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 */
var ConfigNodeSerializationMap;
(function (ConfigNodeSerializationMap) {
    ConfigNodeSerializationMap[ConfigNodeSerializationMap["Value"] = 1] = "Value";
    ConfigNodeSerializationMap[ConfigNodeSerializationMap["Start"] = 2] = "Start";
    ConfigNodeSerializationMap[ConfigNodeSerializationMap["End"] = 3] = "End";
})(ConfigNodeSerializationMap || (ConfigNodeSerializationMap = {}));
/**
 * Value map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent frequently used values.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 *
 * @see {@link https://github.com/AdguardTeam/AGLint/blob/master/src/linter/inline-config.ts}
 */
const FREQUENT_COMMANDS_SERIALIZATION_MAP = new Map([
    ['aglint', 0],
    ['aglint-disable', 1],
    ['aglint-enable', 2],
    ['aglint-disable-next-line', 3],
    ['aglint-enable-next-line', 4],
]);
/**
 * Value map for binary deserialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent frequently used values.
 */
const FREQUENT_COMMANDS_DESERIALIZATION_MAP = new Map(Array.from(FREQUENT_COMMANDS_SERIALIZATION_MAP).map(([key, value]) => [value, key]));
/**
 * `ConfigCommentParser` is responsible for parsing inline AGLint configuration rules.
 * Generally, the idea is inspired by ESLint inline configuration comments.
 *
 * @see {@link https://eslint.org/docs/latest/user-guide/configuring/rules#using-configuration-comments}
 */
class ConfigCommentRuleParser extends ParserBase {
    /**
     * Checks if the raw rule is an inline configuration comment rule.
     *
     * @param raw Raw rule
     * @returns `true` if the rule is an inline configuration comment rule, otherwise `false`.
     */
    static isConfigComment(raw) {
        const trimmed = raw.trim();
        if (trimmed[0] === CommentMarker.Regular || trimmed[0] === CommentMarker.Hashmark) {
            // Skip comment marker and trim comment text (it is necessary because of "!     something")
            const text = raw.slice(1).trim();
            // The code below is "not pretty", but it runs fast, which is necessary, since it will run on EVERY comment
            // The essence of the indicator is that the control comment always starts with the "aglint" prefix
            return ((text[0] === 'a' || text[0] === 'A')
                && (text[1] === 'g' || text[1] === 'G')
                && (text[2] === 'l' || text[2] === 'L')
                && (text[3] === 'i' || text[3] === 'I')
                && (text[4] === 'n' || text[4] === 'N')
                && (text[5] === 't' || text[5] === 'T'));
        }
        return false;
    }
    /**
     * Parses a raw rule as an inline configuration comment.
     *
     * @param raw Raw input to parse.
     * @param options Global parser options.
     * @param baseOffset Starting offset of the input. Node locations are calculated relative to this offset.
     * @returns
     * Inline configuration comment AST or null (if the raw rule cannot be parsed as configuration comment)
     */
    static parse(raw, options = defaultParserOptions, baseOffset = 0) {
        if (!ConfigCommentRuleParser.isConfigComment(raw)) {
            return null;
        }
        let offset = 0;
        // Skip leading whitespace (if any)
        offset = StringUtils.skipWS(raw, offset);
        // Get comment marker
        const marker = ValueParser.parse(raw[offset], options, baseOffset + offset);
        // Skip marker
        offset += 1;
        // Skip whitespace (if any)
        offset = StringUtils.skipWS(raw, offset);
        // Save the command start position
        const commandStart = offset;
        // Get comment text, for example: "aglint-disable-next-line"
        offset = StringUtils.findNextWhitespaceCharacter(raw, offset);
        const command = ValueParser.parse(raw.slice(commandStart, offset), options, baseOffset + commandStart);
        // Skip whitespace after command
        offset = StringUtils.skipWS(raw, offset);
        // Get comment (if any)
        const commentStart = raw.indexOf(AGLINT_CONFIG_COMMENT_MARKER, offset);
        const commentEnd = commentStart !== -1 ? StringUtils.skipWSBack(raw) + 1 : -1;
        let comment;
        // Check if there is a comment
        if (commentStart !== -1) {
            comment = ValueParser.parse(raw.slice(commentStart, commentEnd), options, baseOffset + commentStart);
        }
        // Get parameter
        const paramsStart = offset;
        const paramsEnd = commentStart !== -1
            ? StringUtils.skipWSBack(raw, commentStart - 1) + 1
            : StringUtils.skipWSBack(raw) + 1;
        let params;
        // `! aglint ...` config comment
        if (command.value === AGLINT_COMMAND_PREFIX) {
            params = {
                type: 'ConfigNode',
                // It is necessary to use JSON5.parse instead of JSON.parse because JSON5 allows unquoted keys.
                // But don't forget to add { } to the beginning and end of the string,
                // otherwise JSON5 will not be able to parse it.
                // TODO: Better solution? ESLint uses "levn" package for parsing these comments.
                value: dist.parse(`{${raw.slice(paramsStart, paramsEnd)}}`),
            };
            if (options.isLocIncluded) {
                params.start = paramsStart;
                params.end = paramsEnd;
            }
            // Throw error for empty config
            if (Object.keys(params.value).length === 0) {
                throw new Error('Empty AGLint config');
            }
        }
        else if (paramsStart < paramsEnd) {
            params = ParameterListParser.parse(raw.slice(paramsStart, paramsEnd), options, baseOffset + paramsStart, COMMA);
        }
        const result = {
            type: CommentRuleType.ConfigCommentRule,
            category: RuleCategory.Comment,
            syntax: AdblockSyntax.Common,
            marker,
            command,
            params,
            comment,
        };
        if (options.includeRaws) {
            result.raws = {
                text: raw,
            };
        }
        if (options.isLocIncluded) {
            result.start = baseOffset;
            result.end = baseOffset + raw.length;
        }
        return result;
    }
    /**
     * Converts an inline configuration comment node to a string.
     *
     * @param node Inline configuration comment node
     * @returns Raw string
     */
    static generate(node) {
        let result = EMPTY;
        result += node.marker.value;
        result += SPACE;
        result += node.command.value;
        if (node.params) {
            result += SPACE;
            if (node.params.type === 'ParameterList') {
                result += ParameterListParser.generate(node.params, COMMA);
            }
            else {
                // Trim JSON boundaries
                result += JSON.stringify(node.params.value).slice(1, -1).trim();
            }
        }
        // Add comment within the config comment
        if (node.comment) {
            result += SPACE;
            result += node.comment.value;
        }
        return result;
    }
    /**
     * Serializes a config node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     */
    static serializeConfigNode(node, buffer) {
        buffer.writeUint8(BinaryTypeMap.ConfigNode);
        buffer.writeUint8(ConfigNodeSerializationMap.Value);
        // note: we don't support serializing generic objects, only AGTree nodes
        // this is a very special case, so we just stringify the configuration object
        buffer.writeString(JSON.stringify(node.value));
        if (!isUndefined(node.start)) {
            buffer.writeUint8(ConfigNodeSerializationMap.Start);
            buffer.writeUint32(node.start);
        }
        if (!isUndefined(node.end)) {
            buffer.writeUint8(ConfigNodeSerializationMap.End);
            buffer.writeUint32(node.end);
        }
        buffer.writeUint8(NULL);
    }
    /**
     * Deserializes a metadata comment node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     * @throws If the binary data is malformed.
     */
    static deserializeConfigNode(buffer, node) {
        buffer.assertUint8(BinaryTypeMap.ConfigNode);
        node.type = 'ConfigNode';
        let prop = buffer.readUint8();
        while (prop !== NULL) {
            switch (prop) {
                case ConfigNodeSerializationMap.Value:
                    // note: it is safe to use JSON.parse here, because we serialized it with JSON.stringify
                    node.value = JSON.parse(buffer.readString());
                    break;
                case ConfigNodeSerializationMap.Start:
                    node.start = buffer.readUint32();
                    break;
                case ConfigNodeSerializationMap.End:
                    node.end = buffer.readUint32();
                    break;
                default:
                    throw new Error(`Invalid property: ${prop}.`);
            }
            prop = buffer.readUint8();
        }
    }
    /**
     * Serializes a metadata comment node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     */
    // TODO: add support for raws, if ever needed
    static serialize(node, buffer) {
        buffer.writeUint8(BinaryTypeMap.ConfigCommentRuleNode);
        buffer.writeUint8(ConfigCommentRuleSerializationMap.Marker);
        ValueParser.serialize(node.marker, buffer);
        buffer.writeUint8(ConfigCommentRuleSerializationMap.Command);
        ValueParser.serialize(node.command, buffer, FREQUENT_COMMANDS_SERIALIZATION_MAP, true);
        if (!isUndefined(node.params)) {
            buffer.writeUint8(ConfigCommentRuleSerializationMap.Params);
            if (node.params.type === 'ParameterList') {
                ParameterListParser.serialize(node.params, buffer);
            }
            else {
                ConfigCommentRuleParser.serializeConfigNode(node.params, buffer);
            }
        }
        if (!isUndefined(node.comment)) {
            buffer.writeUint8(ConfigCommentRuleSerializationMap.Comment);
            ValueParser.serialize(node.comment, buffer);
        }
        if (!isUndefined(node.start)) {
            buffer.writeUint8(ConfigCommentRuleSerializationMap.Start);
            buffer.writeUint32(node.start);
        }
        if (!isUndefined(node.end)) {
            buffer.writeUint8(ConfigCommentRuleSerializationMap.End);
            buffer.writeUint32(node.end);
        }
        buffer.writeUint8(NULL);
    }
    /**
     * Deserializes a metadata comment node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     * @throws If the binary data is malformed.
     */
    static deserialize(buffer, node) {
        buffer.assertUint8(BinaryTypeMap.ConfigCommentRuleNode);
        node.type = CommentRuleType.ConfigCommentRule;
        node.category = RuleCategory.Comment;
        node.syntax = AdblockSyntax.Common;
        let prop = buffer.readUint8();
        while (prop !== NULL) {
            switch (prop) {
                case ConfigCommentRuleSerializationMap.Marker:
                    ValueParser.deserialize(buffer, node.marker = {});
                    break;
                case ConfigCommentRuleSerializationMap.Command:
                    ValueParser.deserialize(buffer, node.command = {}, FREQUENT_COMMANDS_DESERIALIZATION_MAP);
                    break;
                case ConfigCommentRuleSerializationMap.Params:
                    if (buffer.peekUint8() === BinaryTypeMap.ConfigNode) {
                        ConfigCommentRuleParser.deserializeConfigNode(buffer, node.params = {});
                    }
                    else {
                        ParameterListParser.deserialize(buffer, node.params = {});
                    }
                    break;
                case ConfigCommentRuleSerializationMap.Comment:
                    ValueParser.deserialize(buffer, node.comment = {});
                    break;
                case ConfigCommentRuleSerializationMap.Start:
                    node.start = buffer.readUint32();
                    break;
                case ConfigCommentRuleSerializationMap.End:
                    node.end = buffer.readUint32();
                    break;
                default:
                    throw new Error(`Invalid property: ${prop}`);
            }
            prop = buffer.readUint8();
        }
    }
}

/* eslint-disable no-param-reassign */
/**
 * @file AdGuard Hints
 * @see {@link https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#hints}
 */
/**
 * Property map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent a property.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 */
var HintNodeSerializationMap;
(function (HintNodeSerializationMap) {
    HintNodeSerializationMap[HintNodeSerializationMap["Name"] = 1] = "Name";
    HintNodeSerializationMap[HintNodeSerializationMap["Params"] = 2] = "Params";
    HintNodeSerializationMap[HintNodeSerializationMap["Start"] = 3] = "Start";
    HintNodeSerializationMap[HintNodeSerializationMap["End"] = 4] = "End";
})(HintNodeSerializationMap || (HintNodeSerializationMap = {}));
/**
 * Value map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent frequently used values.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 */
const FREQUENT_HINTS_SERIALIZATION_MAP = new Map([
    ['NOT_OPTIMIZED', 0],
    ['PLATFORM', 1],
    ['NOT_PLATFORM', 2],
]);
/**
 * Value map for binary deserialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent frequently used values.
 */
const FREQUENT_HINTS_DESERIALIZATION_MAP = new Map(Array.from(FREQUENT_HINTS_SERIALIZATION_MAP).map(([key, value]) => [value, key]));
/**
 * Value map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent frequently used values.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 */
const FREQUENT_PLATFORMS_SERIALIZATION_MAP = new Map([
    ['windows', 0],
    ['mac', 1],
    ['android', 2],
    ['ios', 3],
    ['ext_chromium', 4],
    ['ext_ff', 5],
    ['ext_edge', 6],
    ['ext_opera', 7],
    ['ext_safari', 8],
    ['ext_android_cb', 9],
    ['ext_ublock', 10],
]);
/**
 * Value map for binary deserialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent frequently used values.
 */
const FREQUENT_PLATFORMS_DESERIALIZATION_MAP = new Map(Array.from(FREQUENT_PLATFORMS_SERIALIZATION_MAP).map(([key, value]) => [value, key]));
/**
 * `HintParser` is responsible for parsing AdGuard hints.
 *
 * @example
 * If the hint rule is
 * ```adblock
 * !+ NOT_OPTIMIZED PLATFORM(windows)
 * ```
 * then the hints are `NOT_OPTIMIZED` and `PLATFORM(windows)`, and this
 * class is responsible for parsing them. The rule itself is parsed by
 * the `HintRuleParser`, which uses this class to parse single hints.
 */
class HintParser extends ParserBase {
    /**
     * Parses a raw rule as a hint.
     *
     * @param raw Raw input to parse.
     * @param options Global parser options.
     * @param baseOffset Starting offset of the input. Node locations are calculated relative to this offset.
     * @returns Hint rule AST or null
     * @throws If the syntax is invalid
     */
    static parse(raw, options = defaultParserOptions, baseOffset = 0) {
        let offset = 0;
        // Skip whitespace characters before the hint
        offset = StringUtils.skipWS(raw);
        // Hint should start with the hint name in every case
        // Save the start offset of the hint name
        const nameStartIndex = offset;
        // Parse the hint name
        for (; offset < raw.length; offset += 1) {
            const char = raw[offset];
            // Abort consuming the hint name if we encounter a whitespace character
            // or an opening parenthesis, which means 'HIT_NAME(' case
            if (char === OPEN_PARENTHESIS || char === SPACE) {
                break;
            }
            // Hint name should only contain letters, digits, and underscores
            if (!StringUtils.isAlphaNumeric(char) && char !== UNDERSCORE) {
                throw new AdblockSyntaxError(`Invalid character "${char}" in hint name: "${char}"`, baseOffset + nameStartIndex, baseOffset + offset);
            }
        }
        // Save the end offset of the hint name
        const nameEndIndex = offset;
        // Save the hint name token
        const name = raw.slice(nameStartIndex, nameEndIndex);
        // Hint name cannot be empty
        if (name === EMPTY) {
            throw new AdblockSyntaxError('Empty hint name', baseOffset, baseOffset + nameEndIndex);
        }
        // Now we have two case:
        //  1. We have HINT_NAME and should return it
        //  2. We have HINT_NAME(PARAMS) and should continue parsing
        // Skip whitespace characters after the hint name
        offset = StringUtils.skipWS(raw, offset);
        // Throw error for 'HINT_NAME (' case
        if (offset > nameEndIndex && raw[offset] === OPEN_PARENTHESIS) {
            throw new AdblockSyntaxError('Unexpected whitespace(s) between hint name and opening parenthesis', baseOffset + nameEndIndex, baseOffset + offset);
        }
        // Create the hint name node (we can reuse it in the 'HINT_NAME' case, if needed)
        const nameNode = ValueParser.parse(name, options, baseOffset + nameStartIndex);
        // Just return the hint name if we have 'HINT_NAME' case (no params)
        if (raw[offset] !== OPEN_PARENTHESIS) {
            const result = {
                type: 'Hint',
                name: nameNode,
            };
            if (options.isLocIncluded) {
                result.start = baseOffset;
                result.end = baseOffset + offset;
            }
            return result;
        }
        // Skip the opening parenthesis
        offset += 1;
        // Find closing parenthesis
        const closeParenthesisIndex = raw.lastIndexOf(CLOSE_PARENTHESIS);
        // Throw error if we don't have closing parenthesis
        if (closeParenthesisIndex === -1) {
            throw new AdblockSyntaxError(`Missing closing parenthesis for hint "${name}"`, baseOffset + nameStartIndex, baseOffset + raw.length);
        }
        // Save the start and end index of the params
        const paramsStartIndex = offset;
        const paramsEndIndex = closeParenthesisIndex;
        // Parse the params
        const params = ParameterListParser.parse(raw.slice(paramsStartIndex, paramsEndIndex), options, baseOffset + paramsStartIndex, COMMA);
        offset = closeParenthesisIndex + 1;
        // Skip whitespace characters after the closing parenthesis
        offset = StringUtils.skipWS(raw, offset);
        // Throw error if we don't reach the end of the input
        if (offset !== raw.length) {
            throw new AdblockSyntaxError(
            // eslint-disable-next-line max-len
            `Unexpected input after closing parenthesis for hint "${name}": "${raw.slice(closeParenthesisIndex + 1, offset + 1)}"`, baseOffset + closeParenthesisIndex + 1, baseOffset + offset + 1);
        }
        // Return the HINT_NAME(PARAMS) case AST
        const result = {
            type: 'Hint',
            name: nameNode,
            params,
        };
        if (options.isLocIncluded) {
            result.start = baseOffset;
            result.end = baseOffset + offset;
        }
        return result;
    }
    /**
     * Converts a single hint AST to a string.
     *
     * @param hint Hint AST
     * @returns Hint string
     */
    static generate(hint) {
        let result = EMPTY;
        result += hint.name.value;
        if (hint.params && hint.params.children.length > 0) {
            result += OPEN_PARENTHESIS;
            result += ParameterListParser.generate(hint.params, COMMA);
            result += CLOSE_PARENTHESIS;
        }
        return result;
    }
    /**
     * Serializes a hint node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     */
    static serialize(node, buffer) {
        buffer.writeUint8(BinaryTypeMap.HintNode);
        buffer.writeUint8(HintNodeSerializationMap.Name);
        ValueParser.serialize(node.name, buffer, FREQUENT_HINTS_SERIALIZATION_MAP);
        if (!isUndefined(node.params)) {
            buffer.writeUint8(HintNodeSerializationMap.Params);
            ParameterListParser.serialize(node.params, buffer, FREQUENT_PLATFORMS_SERIALIZATION_MAP);
        }
        if (!isUndefined(node.start)) {
            buffer.writeUint8(HintNodeSerializationMap.Start);
            buffer.writeUint32(node.start);
        }
        if (!isUndefined(node.end)) {
            buffer.writeUint8(HintNodeSerializationMap.End);
            buffer.writeUint32(node.end);
        }
        buffer.writeUint8(NULL);
    }
    /**
     * Deserializes a hint node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     * @throws If the binary data is malformed.
     */
    static deserialize(buffer, node) {
        buffer.assertUint8(BinaryTypeMap.HintNode);
        node.type = 'Hint';
        let prop = buffer.readUint8();
        while (prop !== NULL) {
            switch (prop) {
                case HintNodeSerializationMap.Name:
                    ValueParser.deserialize(buffer, node.name = {}, FREQUENT_HINTS_DESERIALIZATION_MAP);
                    break;
                case HintNodeSerializationMap.Params:
                    // eslint-disable-next-line max-len
                    ParameterListParser.deserialize(buffer, node.params = {}, FREQUENT_PLATFORMS_DESERIALIZATION_MAP);
                    break;
                case HintNodeSerializationMap.Start:
                    node.start = buffer.readUint32();
                    break;
                case HintNodeSerializationMap.End:
                    node.end = buffer.readUint32();
                    break;
                default:
                    throw new Error(`Invalid property: ${prop}`);
            }
            prop = buffer.readUint8();
        }
    }
}

/* eslint-disable no-param-reassign */
/**
 * Property map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent a property.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 */
var HintRuleSerializationMap;
(function (HintRuleSerializationMap) {
    HintRuleSerializationMap[HintRuleSerializationMap["Syntax"] = 1] = "Syntax";
    HintRuleSerializationMap[HintRuleSerializationMap["Children"] = 2] = "Children";
    HintRuleSerializationMap[HintRuleSerializationMap["Start"] = 3] = "Start";
    HintRuleSerializationMap[HintRuleSerializationMap["End"] = 4] = "End";
})(HintRuleSerializationMap || (HintRuleSerializationMap = {}));
/**
 * `HintRuleParser` is responsible for parsing AdGuard hint rules.
 *
 * @example
 * The following hint rule
 * ```adblock
 * !+ NOT_OPTIMIZED PLATFORM(windows)
 * ```
 * contains two hints: `NOT_OPTIMIZED` and `PLATFORM`.
 * @see {@link https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#hints}
 */
class HintCommentRuleParser extends ParserBase {
    /**
     * Checks if the raw rule is a hint rule.
     *
     * @param raw Raw rule
     * @returns `true` if the rule is a hint rule, `false` otherwise
     */
    static isHintRule(raw) {
        return raw.trim().startsWith(HINT_MARKER);
    }
    /**
     * Parses a raw rule as a hint comment.
     *
     * @param raw Raw input to parse.
     * @param options Global parser options.
     * @param baseOffset Starting offset of the input. Node locations are calculated relative to this offset.
     * @returns Hint AST or null (if the raw rule cannot be parsed as a hint comment)
     * @throws If the input matches the HINT pattern but syntactically invalid
     * @see {@link https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#hints-1}
     */
    static parse(raw, options = defaultParserOptions, baseOffset = 0) {
        // Ignore non-hint rules
        if (!HintCommentRuleParser.isHintRule(raw)) {
            return null;
        }
        let offset = 0;
        // Skip whitespace characters before the rule
        offset = StringUtils.skipWS(raw);
        // Skip hint marker
        offset += HINT_MARKER_LEN;
        const hints = [];
        // Collect hints. Each hint is a string, optionally followed by a parameter list,
        // enclosed in parentheses. One rule can contain multiple hints.
        while (offset < raw.length) {
            // Split rule into raw hints (e.g. 'HINT_NAME' or 'HINT_NAME(PARAMS)')
            // Hints are separated by whitespace characters, but we should ignore
            // whitespace characters inside the parameter list
            // Ignore whitespace characters before the hint
            offset = StringUtils.skipWS(raw, offset);
            // Save the start index of the hint
            const hintStartIndex = offset;
            // Find the end of the hint
            let hintEndIndex = offset;
            let balance = 0;
            while (hintEndIndex < raw.length) {
                if (raw[hintEndIndex] === OPEN_PARENTHESIS && raw[hintEndIndex - 1] !== BACKSLASH) {
                    balance += 1;
                    // Throw error for nesting
                    if (balance > 1) {
                        throw new AdblockSyntaxError('Invalid hint: nested parentheses are not allowed', baseOffset + hintStartIndex, baseOffset + hintEndIndex);
                    }
                }
                else if (raw[hintEndIndex] === CLOSE_PARENTHESIS && raw[hintEndIndex - 1] !== BACKSLASH) {
                    balance -= 1;
                }
                else if (StringUtils.isWhitespace(raw[hintEndIndex]) && balance === 0) {
                    break;
                }
                hintEndIndex += 1;
            }
            offset = hintEndIndex;
            // Skip whitespace characters after the hint
            offset = StringUtils.skipWS(raw, offset);
            // Parse the hint
            const hint = HintParser.parse(raw.slice(hintStartIndex, hintEndIndex), options, baseOffset + hintStartIndex);
            hints.push(hint);
        }
        // Throw error if no hints were found
        if (hints.length === 0) {
            throw new AdblockSyntaxError('Empty hint rule', baseOffset, baseOffset + offset);
        }
        const result = {
            type: CommentRuleType.HintCommentRule,
            category: RuleCategory.Comment,
            syntax: AdblockSyntax.Adg,
            children: hints,
        };
        if (options.includeRaws) {
            result.raws = {
                text: raw,
            };
        }
        if (options.isLocIncluded) {
            result.start = baseOffset;
            result.end = baseOffset + offset;
        }
        return result;
    }
    /**
     * Converts a hint rule node to a raw string.
     *
     * @param node Hint rule node
     * @returns Raw string
     */
    static generate(node) {
        let result = HINT_MARKER + SPACE;
        result += node.children.map(HintParser.generate).join(SPACE);
        return result;
    }
    /**
     * Serializes a hint rule node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     */
    // TODO: add support for raws, if ever needed
    static serialize(node, buffer) {
        buffer.writeUint8(BinaryTypeMap.HintRuleNode);
        if (node.syntax === AdblockSyntax.Adg) {
            buffer.writeUint8(HintRuleSerializationMap.Syntax);
            buffer.writeUint8(SYNTAX_SERIALIZATION_MAP.get(AdblockSyntax.Adg) ?? 0);
        }
        const count = node.children.length;
        if (count) {
            buffer.writeUint8(HintRuleSerializationMap.Children);
            // note: we store the count, because re-construction of the array is faster if we know the length
            buffer.writeUint8(count);
            for (let i = 0; i < count; i += 1) {
                HintParser.serialize(node.children[i], buffer);
            }
        }
        if (!isUndefined(node.start)) {
            buffer.writeUint8(HintRuleSerializationMap.Start);
            buffer.writeUint32(node.start);
        }
        if (!isUndefined(node.end)) {
            buffer.writeUint8(HintRuleSerializationMap.End);
            buffer.writeUint32(node.end);
        }
        buffer.writeUint8(NULL);
    }
    /**
     * Deserializes a hint rule node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     * @throws If the binary data is malformed.
     */
    static deserialize(buffer, node) {
        buffer.assertUint8(BinaryTypeMap.HintRuleNode);
        node.category = RuleCategory.Comment;
        node.type = CommentRuleType.HintCommentRule;
        let prop = buffer.readUint8();
        while (prop !== NULL) {
            switch (prop) {
                case HintRuleSerializationMap.Syntax:
                    node.syntax = SYNTAX_DESERIALIZATION_MAP.get(buffer.readUint8()) ?? AdblockSyntax.Common;
                    break;
                case HintRuleSerializationMap.Children:
                    node.children = new Array(buffer.readUint8());
                    // read children
                    for (let i = 0; i < node.children.length; i += 1) {
                        HintParser.deserialize(buffer, node.children[i] = {});
                    }
                    break;
                case HintRuleSerializationMap.Start:
                    node.start = buffer.readUint32();
                    break;
                case HintRuleSerializationMap.End:
                    node.end = buffer.readUint32();
                    break;
                default:
                    throw new Error(`Invalid property: ${prop}`);
            }
            prop = buffer.readUint8();
        }
    }
}

/* eslint-disable no-param-reassign */
/**
 * @file Metadata comments
 */
/**
 * Property map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent a property.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 */
var MetadataCommentRuleSerializationMap;
(function (MetadataCommentRuleSerializationMap) {
    MetadataCommentRuleSerializationMap[MetadataCommentRuleSerializationMap["Marker"] = 1] = "Marker";
    MetadataCommentRuleSerializationMap[MetadataCommentRuleSerializationMap["Header"] = 2] = "Header";
    MetadataCommentRuleSerializationMap[MetadataCommentRuleSerializationMap["Value"] = 3] = "Value";
    MetadataCommentRuleSerializationMap[MetadataCommentRuleSerializationMap["Start"] = 4] = "Start";
    MetadataCommentRuleSerializationMap[MetadataCommentRuleSerializationMap["End"] = 5] = "End";
})(MetadataCommentRuleSerializationMap || (MetadataCommentRuleSerializationMap = {}));
/**
 * Value map for binary deserialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent frequently used values.
 */
const FREQUENT_HEADERS_DESERIALIZATION_MAP = new Map([
    [1, 'Checksum'],
    [2, 'Description'],
    [3, 'Expires'],
    [4, 'Homepage'],
    [5, 'Last Modified'],
    [6, 'LastModified'],
    [7, 'Licence'],
    [8, 'License'],
    [9, 'Time Updated'],
    [10, 'TimeUpdated'],
    [11, 'Version'],
    [12, 'Title'],
]);
/**
 * Value map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent frequently used values.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 * @note This map is generated from `FREQUENT_HEADERS_DESERIALIZATION_MAP` to keep uppercase characters
 * while deserializing.
 */
const FREQUENT_HEADERS_SERIALIZATION_MAP = new Map(Array.from(FREQUENT_HEADERS_DESERIALIZATION_MAP.entries()).map(([key, value]) => [value.toLowerCase(), key]));
/**
 * Known metadata headers.
 */
const KNOWN_METADATA_HEADERS = Array.from(FREQUENT_HEADERS_SERIALIZATION_MAP.keys());
/**
 * `MetadataParser` is responsible for parsing metadata comments.
 * Metadata comments are special comments that specify some properties of the list.
 *
 * @example
 * For example, in the case of
 * ```adblock
 * ! Title: My List
 * ```
 * the name of the header is `Title`, and the value is `My List`, which means that
 * the list title is `My List`, and it can be used in the adblocker UI.
 * @see {@link https://help.eyeo.com/adblockplus/how-to-write-filters#special-comments}
 */
class MetadataCommentRuleParser extends ParserBase {
    /**
     * Parses a raw rule as a metadata comment.
     *
     * @param raw Raw input to parse.
     * @param options Global parser options.
     * @param baseOffset Starting offset of the input. Node locations are calculated relative to this offset.
     * @returns Metadata comment AST or null (if the raw rule cannot be parsed as a metadata comment)
     */
    static parse(raw, options = defaultParserOptions, baseOffset = 0) {
        // Fast check to avoid unnecessary work
        if (raw.indexOf(COLON) === -1) {
            return null;
        }
        let offset = 0;
        // Skip leading spaces before the comment marker
        offset = StringUtils.skipWS(raw, offset);
        // Check if the rule starts with a comment marker (first non-space sequence)
        if (raw[offset] !== CommentMarker.Regular && raw[offset] !== CommentMarker.Hashmark) {
            return null;
        }
        // Consume the comment marker
        const marker = ValueParser.parse(raw[offset], options, baseOffset + offset);
        offset += 1;
        // Skip spaces
        offset = StringUtils.skipWS(raw, offset);
        // Save header start position
        const headerStart = offset;
        // Check if the comment text starts with a known header
        const text = raw.slice(offset);
        for (let i = 0; i < KNOWN_METADATA_HEADERS.length; i += 1) {
            // Check if the comment text starts with the header (case-insensitive)
            if (text.toLocaleLowerCase().startsWith(KNOWN_METADATA_HEADERS[i].toLocaleLowerCase())) {
                // Skip the header
                offset += KNOWN_METADATA_HEADERS[i].length;
                // Save header
                const header = ValueParser.parse(raw.slice(headerStart, offset), options, baseOffset + headerStart);
                // Skip spaces after the header
                offset = StringUtils.skipWS(raw, offset);
                // Check if the rule contains a separator after the header
                if (raw[offset] !== COLON) {
                    return null;
                }
                // Skip the separator
                offset += 1;
                // Skip spaces after the separator
                offset = StringUtils.skipWS(raw, offset);
                // Save the value start position
                const valueStart = offset;
                // Check if the rule contains a value
                if (offset >= raw.length) {
                    return null;
                }
                const valueEnd = StringUtils.skipWSBack(raw, raw.length - 1) + 1;
                // Save the value
                const value = ValueParser.parse(raw.slice(valueStart, valueEnd), options, baseOffset + valueStart);
                const result = {
                    type: CommentRuleType.MetadataCommentRule,
                    category: RuleCategory.Comment,
                    syntax: AdblockSyntax.Common,
                    marker,
                    header,
                    value,
                };
                if (options.includeRaws) {
                    result.raws = {
                        text: raw,
                    };
                }
                if (options.isLocIncluded) {
                    result.start = baseOffset;
                    result.end = baseOffset + raw.length;
                }
                return result;
            }
        }
        return null;
    }
    /**
     * Converts a metadata comment rule node to a string.
     *
     * @param node Metadata comment rule node.
     * @returns Raw string.
     */
    static generate(node) {
        let result = EMPTY;
        result += ValueParser.generate(node.marker);
        result += SPACE;
        result += ValueParser.generate(node.header);
        result += COLON;
        result += SPACE;
        result += ValueParser.generate(node.value);
        return result;
    }
    /**
     * Serializes a metadata comment node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     */
    // TODO: add support for raws, if ever needed
    static serialize(node, buffer) {
        buffer.writeUint8(BinaryTypeMap.MetadataCommentRuleNode);
        buffer.writeUint8(MetadataCommentRuleSerializationMap.Marker);
        ValueParser.serialize(node.marker, buffer);
        buffer.writeUint8(MetadataCommentRuleSerializationMap.Header);
        ValueParser.serialize(node.header, buffer, FREQUENT_HEADERS_SERIALIZATION_MAP, true);
        buffer.writeUint8(MetadataCommentRuleSerializationMap.Value);
        ValueParser.serialize(node.value, buffer);
        if (!isUndefined(node.start)) {
            buffer.writeUint8(MetadataCommentRuleSerializationMap.Start);
            buffer.writeUint32(node.start);
        }
        if (!isUndefined(node.end)) {
            buffer.writeUint8(MetadataCommentRuleSerializationMap.End);
            buffer.writeUint32(node.end);
        }
        buffer.writeUint8(NULL);
    }
    /**
     * Deserializes a metadata comment node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     * @throws If the binary data is malformed.
     */
    static deserialize(buffer, node) {
        buffer.assertUint8(BinaryTypeMap.MetadataCommentRuleNode);
        node.type = CommentRuleType.MetadataCommentRule;
        node.category = RuleCategory.Comment;
        node.syntax = AdblockSyntax.Common;
        let prop = buffer.readUint8();
        while (prop !== NULL) {
            switch (prop) {
                case MetadataCommentRuleSerializationMap.Marker:
                    ValueParser.deserialize(buffer, node.marker = {});
                    break;
                case MetadataCommentRuleSerializationMap.Header:
                    ValueParser.deserialize(buffer, node.header = {}, FREQUENT_HEADERS_DESERIALIZATION_MAP);
                    break;
                case MetadataCommentRuleSerializationMap.Value:
                    ValueParser.deserialize(buffer, node.value = {});
                    break;
                case MetadataCommentRuleSerializationMap.Start:
                    node.start = buffer.readUint32();
                    break;
                case MetadataCommentRuleSerializationMap.End:
                    node.end = buffer.readUint32();
                    break;
                default:
                    throw new Error(`Invalid property: ${prop}`);
            }
            prop = buffer.readUint8();
        }
    }
}

/* eslint-disable no-param-reassign */
/* eslint-disable max-classes-per-file */
/**
 * Property map for binary serialization.
 */
var VariableNodeBinaryPropMap;
(function (VariableNodeBinaryPropMap) {
    VariableNodeBinaryPropMap[VariableNodeBinaryPropMap["Name"] = 1] = "Name";
    VariableNodeBinaryPropMap[VariableNodeBinaryPropMap["FrequentName"] = 2] = "FrequentName";
    VariableNodeBinaryPropMap[VariableNodeBinaryPropMap["Start"] = 3] = "Start";
    VariableNodeBinaryPropMap[VariableNodeBinaryPropMap["End"] = 4] = "End";
})(VariableNodeBinaryPropMap || (VariableNodeBinaryPropMap = {}));
/**
 * Property map for binary serialization.
 */
var OperatorNodeBinaryPropMap;
(function (OperatorNodeBinaryPropMap) {
    OperatorNodeBinaryPropMap[OperatorNodeBinaryPropMap["Operator"] = 1] = "Operator";
    OperatorNodeBinaryPropMap[OperatorNodeBinaryPropMap["Left"] = 2] = "Left";
    OperatorNodeBinaryPropMap[OperatorNodeBinaryPropMap["Right"] = 3] = "Right";
    OperatorNodeBinaryPropMap[OperatorNodeBinaryPropMap["Start"] = 4] = "Start";
    OperatorNodeBinaryPropMap[OperatorNodeBinaryPropMap["End"] = 5] = "End";
})(OperatorNodeBinaryPropMap || (OperatorNodeBinaryPropMap = {}));
/**
 * Property map for binary serialization.
 */
var ParenthesisNodeBinaryPropMap;
(function (ParenthesisNodeBinaryPropMap) {
    ParenthesisNodeBinaryPropMap[ParenthesisNodeBinaryPropMap["Expression"] = 1] = "Expression";
    ParenthesisNodeBinaryPropMap[ParenthesisNodeBinaryPropMap["Start"] = 2] = "Start";
    ParenthesisNodeBinaryPropMap[ParenthesisNodeBinaryPropMap["End"] = 3] = "End";
})(ParenthesisNodeBinaryPropMap || (ParenthesisNodeBinaryPropMap = {}));
/**
 * Possible token types in the logical expression.
 */
var TokenType;
(function (TokenType) {
    TokenType[TokenType["Variable"] = 0] = "Variable";
    TokenType[TokenType["Operator"] = 1] = "Operator";
    TokenType[TokenType["Parenthesis"] = 2] = "Parenthesis";
})(TokenType || (TokenType = {}));
/**
 * Possible node types in the logical expression.
 */
var NodeType;
(function (NodeType) {
    NodeType["Variable"] = "Variable";
    NodeType["Operator"] = "Operator";
    NodeType["Parenthesis"] = "Parenthesis";
})(NodeType || (NodeType = {}));
/**
 * Precedence of the operators, larger number means higher precedence.
 */
const OPERATOR_PRECEDENCE = {
    [OperatorValue.Not]: 3,
    [OperatorValue.And]: 2,
    [OperatorValue.Or]: 1,
};
const OPERATOR_BINARY_MAP = new Map([
    [OperatorValue.Not, 0],
    [OperatorValue.And, 1],
    [OperatorValue.Or, 2],
]);
const OPERATOR_BINARY_MAP_REVERSE = new Map(Array.from(OPERATOR_BINARY_MAP).map(([key, value]) => [value, key]));
/**
 * Gets the string representation of the operator from the binary representation.
 *
 * @param binary Binary representation of the operator
 * @returns String representation of the operator
 * @throws If the operator is unknown
 */
const getOperatorOrFail = (binary) => {
    const operator = OPERATOR_BINARY_MAP_REVERSE.get(binary);
    if (isUndefined(operator)) {
        throw new Error(`Unknown operator: ${binary}`);
    }
    return operator;
};
/**
 * Serialization map for known variables.
 */
const KNOWN_VARIABLES_MAP = new Map([
    ['ext_abp', 0],
    ['ext_ublock', 1],
    ['ext_ubol', 2],
    ['ext_devbuild', 3],
    ['env_chromium', 4],
    ['env_edge', 5],
    ['env_firefox', 6],
    ['env_mobile', 7],
    ['env_safari', 8],
    ['env_mv3', 9],
    ['false', 10],
    ['cap_html_filtering', 11],
    ['cap_user_stylesheet', 12],
    ['adguard', 13],
    ['adguard_app_windows', 14],
    ['adguard_app_mac', 15],
    ['adguard_app_android', 16],
    ['adguard_app_ios', 17],
    ['adguard_ext_safari', 18],
    ['adguard_ext_chromium', 19],
    ['adguard_ext_firefox', 20],
    ['adguard_ext_edge', 21],
    ['adguard_ext_opera', 22],
    ['adguard_ext_android_cb', 23],
    // TODO: Add 'adguard_ext_chromium_mv3' to the list
]);
/**
 * Deserialization map for known variables.
 */
const KNOWN_VARIABLES_MAP_REVERSE = new Map(Array.from(KNOWN_VARIABLES_MAP).map(([key, value]) => [value, key]));
/**
 * Gets the frequent name of the variable from the binary representation.
 *
 * @param binary Binary representation of the variable
 * @returns Frequent name of the variable
 * @throws If the variable is unknown
 */
const getFrequentNameOrFail = (binary) => {
    const name = KNOWN_VARIABLES_MAP_REVERSE.get(binary);
    if (isUndefined(name)) {
        throw new Error(`Unknown frequent name: ${binary}`);
    }
    return name;
};
/**
 * `LogicalExpressionParser` is responsible for parsing logical expressions.
 *
 * @example
 * From the following rule:
 * ```adblock
 * !#if (adguard_ext_android_cb || adguard_ext_safari)
 * ```
 * this parser will parse the expression `(adguard_ext_android_cb || adguard_ext_safari)`.
 */
// TODO: Refactor this class
class LogicalExpressionParser extends ParserBase {
    /**
     * Split the expression into tokens.
     *
     * @param raw Source code of the expression
     * @param baseOffset Starting offset of the input. Node locations are calculated relative to this offset.
     * @returns Token list
     * @throws {AdblockSyntaxError} If the expression is invalid
     */
    static tokenize(raw, baseOffset = 0) {
        const tokens = [];
        let offset = 0;
        while (offset < raw.length) {
            const char = raw[offset];
            if (StringUtils.isWhitespace(char)) {
                // Ignore whitespace
                offset += 1;
            }
            else if (StringUtils.isLetter(char)) {
                // Save the start offset of the variable name
                const nameStart = offset;
                // Variable name shouldn't start with a number or underscore,
                // but can contain them
                while (offset + 1 < raw.length
                    && (StringUtils.isAlphaNumeric(raw[offset + 1]) || raw[offset + 1] === UNDERSCORE)) {
                    offset += 1;
                }
                tokens.push({
                    type: TokenType.Variable,
                    start: nameStart,
                    end: offset + 1,
                });
                offset += 1;
            }
            else if (char === OPEN_PARENTHESIS || char === CLOSE_PARENTHESIS) {
                // Parenthesis
                tokens.push({
                    type: TokenType.Parenthesis,
                    start: offset,
                    end: offset + 1,
                });
                offset += 1;
            }
            else if (char === AMPERSAND || char === PIPE) {
                // Parse operator
                if (offset + 1 < raw.length && raw[offset + 1] === char) {
                    tokens.push({
                        type: TokenType.Operator,
                        start: offset,
                        end: offset + 2,
                    });
                    offset += 2;
                }
                else {
                    throw new AdblockSyntaxError(`Unexpected character "${char}"`, baseOffset + offset, baseOffset + offset + 1);
                }
            }
            else if (char === EXCLAMATION_MARK) {
                tokens.push({
                    type: TokenType.Operator,
                    start: offset,
                    end: offset + 1,
                });
                offset += 1;
            }
            else {
                throw new AdblockSyntaxError(`Unexpected character "${char}"`, baseOffset + offset, baseOffset + offset + 1);
            }
        }
        return tokens;
    }
    /**
     * Parses a logical expression.
     *
     * @param raw Raw input to parse.
     * @param options Global parser options.
     * @param baseOffset Starting offset of the input. Node locations are calculated relative to this offset.
     * @returns Parsed expression
     * @throws {AdblockSyntaxError} If the expression is invalid
     */
    // TODO: Create a separate TokenStream class
    static parse(raw, options = defaultParserOptions, baseOffset = 0) {
        // Tokenize the source (produces an array of tokens)
        const tokens = LogicalExpressionParser.tokenize(raw, baseOffset);
        // Current token index
        let tokenIndex = 0;
        /**
         * Consumes a token of the expected type.
         *
         * @param type Expected token type
         * @returns The consumed token
         */
        function consume(type) {
            const token = tokens[tokenIndex];
            if (!token) {
                throw new AdblockSyntaxError(`Expected token of type "${type}", but reached end of input`, baseOffset, baseOffset + raw.length);
            }
            // We only use this function internally, so we can safely ignore this
            // from the coverage report
            // istanbul ignore next
            if (token.type !== type) {
                throw new AdblockSyntaxError(`Expected token of type "${type}", but got "${token.type}"`, baseOffset + token.start, baseOffset + token.end);
            }
            tokenIndex += 1;
            return token;
        }
        /**
         * Parses a variable.
         *
         * @returns Variable node
         */
        function parseVariable() {
            const token = consume(TokenType.Variable);
            const result = {
                type: NodeType.Variable,
                name: raw.slice(token.start, token.end),
            };
            if (options.isLocIncluded) {
                result.start = baseOffset + token.start;
                result.end = baseOffset + token.end;
            }
            return result;
        }
        /**
         * Parses a binary expression.
         *
         * @param left Left-hand side of the expression
         * @param minPrecedence Minimum precedence of the operator
         * @returns Binary expression node
         */
        function parseBinaryExpression(left, minPrecedence = 0) {
            let node = left;
            let operatorToken;
            while (tokens[tokenIndex]) {
                operatorToken = tokens[tokenIndex];
                if (!operatorToken || operatorToken.type !== TokenType.Operator) {
                    break;
                }
                // It is safe to cast here, because we already checked the type
                const operator = raw.slice(operatorToken.start, operatorToken.end);
                const precedence = OPERATOR_PRECEDENCE[operator];
                if (precedence < minPrecedence) {
                    break;
                }
                tokenIndex += 1;
                // eslint-disable-next-line @typescript-eslint/no-use-before-define
                const right = parseExpression(precedence + 1);
                const newNode = {
                    type: NodeType.Operator,
                    operator,
                    left: node,
                    right,
                };
                if (options.isLocIncluded) {
                    newNode.start = node.start ?? baseOffset + operatorToken.start;
                    newNode.end = right.end ?? baseOffset + operatorToken.end;
                }
                node = newNode;
            }
            return node;
        }
        /**
         * Parses a parenthesized expression.
         *
         * @returns Parenthesized expression node
         */
        function parseParenthesizedExpression() {
            consume(TokenType.Parenthesis);
            // eslint-disable-next-line @typescript-eslint/no-use-before-define
            const expression = parseExpression();
            consume(TokenType.Parenthesis);
            const result = {
                type: NodeType.Parenthesis,
                expression,
            };
            if (options.isLocIncluded) {
                result.start = expression.start;
                result.end = expression.end;
            }
            return result;
        }
        /**
         * Parses an expression.
         *
         * @param minPrecedence Minimum precedence of the operator
         * @returns Expression node
         */
        function parseExpression(minPrecedence = 0) {
            let node;
            const token = tokens[tokenIndex];
            const value = raw.slice(token.start, token.end);
            if (token.type === TokenType.Variable) {
                node = parseVariable();
            }
            else if (token.type === TokenType.Operator && value === OperatorValue.Not) {
                tokenIndex += 1;
                const expression = parseExpression(OPERATOR_PRECEDENCE[OperatorValue.Not]);
                node = {
                    type: NodeType.Operator,
                    operator: OperatorValue.Not,
                    left: expression,
                };
                if (options.isLocIncluded) {
                    if (expression.end) {
                        node.start = baseOffset + token.start;
                        // no need to shift the node location, because it's already shifted
                        node.end = expression.end;
                    }
                    else {
                        node.start = baseOffset + token.start;
                        node.end = baseOffset + token.end;
                    }
                }
            }
            else if (token.type === TokenType.Parenthesis && value === OPEN_PARENTHESIS) {
                node = parseParenthesizedExpression();
            }
            else {
                throw new AdblockSyntaxError(`Unexpected token "${value}"`, baseOffset + token.start, baseOffset + token.end);
            }
            return parseBinaryExpression(node, minPrecedence);
        }
        const expression = parseExpression();
        if (tokenIndex !== tokens.length) {
            throw new AdblockSyntaxError(`Unexpected token "${tokens[tokenIndex].type}"`, baseOffset + tokens[tokenIndex].start, baseOffset + tokens[tokenIndex].end);
        }
        return expression;
    }
    /**
     * Generates a string representation of the logical expression (serialization).
     *
     * @param node Expression node
     * @returns String representation of the logical expression
     */
    static generate(node) {
        if (node.type === NodeType.Variable) {
            return node.name;
        }
        if (node.type === NodeType.Operator) {
            const left = LogicalExpressionParser.generate(node.left);
            const right = node.right ? LogicalExpressionParser.generate(node.right) : undefined;
            const { operator } = node;
            // Special case for NOT operator
            if (operator === OperatorValue.Not) {
                return `${operator}${left}`;
            }
            // Right operand is required for AND and OR operators
            if (!right) {
                throw new Error('Expected right operand');
            }
            return `${left} ${operator} ${right}`;
        }
        if (node.type === NodeType.Parenthesis) {
            const expressionString = LogicalExpressionParser.generate(node.expression);
            return `(${expressionString})`;
        }
        // Theoretically, this shouldn't happen if the library is used correctly
        throw new Error('Unexpected node type');
    }
    /**
     * Serializes a variable node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     */
    // TODO: create a common serialize / deserialize interface for such nodes (Variable, Value, Parameter, etc.)
    static serializeVariableNode(node, buffer) {
        buffer.writeUint8(BinaryTypeMap.ExpressionVariableNode);
        const frequentName = KNOWN_VARIABLES_MAP.get(node.name);
        if (!isUndefined(frequentName)) {
            buffer.writeUint8(VariableNodeBinaryPropMap.FrequentName);
            buffer.writeUint8(frequentName);
        }
        else {
            buffer.writeUint8(VariableNodeBinaryPropMap.Name);
            buffer.writeString(node.name);
        }
        if (!isUndefined(node.start)) {
            buffer.writeUint8(VariableNodeBinaryPropMap.Start);
            buffer.writeUint32(node.start);
        }
        if (!isUndefined(node.end)) {
            buffer.writeUint8(VariableNodeBinaryPropMap.End);
            buffer.writeUint32(node.end);
        }
        buffer.writeUint8(NULL);
    }
    /**
     * Serializes a parenthesis node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     */
    static serializeParenthesisNode(node, buffer) {
        buffer.writeUint8(BinaryTypeMap.ExpressionParenthesisNode);
        buffer.writeUint8(ParenthesisNodeBinaryPropMap.Expression);
        LogicalExpressionParser.serialize(node.expression, buffer);
        if (!isUndefined(node.start)) {
            buffer.writeUint8(ParenthesisNodeBinaryPropMap.Start);
            buffer.writeUint32(node.start);
        }
        if (!isUndefined(node.end)) {
            buffer.writeUint8(ParenthesisNodeBinaryPropMap.End);
            buffer.writeUint32(node.end);
        }
        buffer.writeUint8(NULL);
    }
    /**
     * Serializes an operator node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     */
    static serializeOperatorNode(node, buffer) {
        buffer.writeUint8(BinaryTypeMap.ExpressionOperatorNode);
        buffer.writeUint8(OperatorNodeBinaryPropMap.Operator);
        const operatorBinary = OPERATOR_BINARY_MAP.get(node.operator);
        if (isUndefined(operatorBinary)) {
            throw new Error(`Unknown operator: ${node.operator}`);
        }
        buffer.writeUint8(operatorBinary);
        buffer.writeUint8(OperatorNodeBinaryPropMap.Left);
        LogicalExpressionParser.serialize(node.left, buffer);
        if (node.right) {
            buffer.writeUint8(OperatorNodeBinaryPropMap.Right);
            LogicalExpressionParser.serialize(node.right, buffer);
        }
        if (!isUndefined(node.start)) {
            buffer.writeUint8(OperatorNodeBinaryPropMap.Start);
            buffer.writeUint32(node.start);
        }
        if (!isUndefined(node.end)) {
            buffer.writeUint8(OperatorNodeBinaryPropMap.End);
            buffer.writeUint32(node.end);
        }
        buffer.writeUint8(NULL);
    }
    /**
     * Serializes a logical expression node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     */
    static serialize(node, buffer) {
        switch (node.type) {
            case NodeType.Variable:
                LogicalExpressionParser.serializeVariableNode(node, buffer);
                break;
            case NodeType.Operator:
                LogicalExpressionParser.serializeOperatorNode(node, buffer);
                break;
            case NodeType.Parenthesis:
                LogicalExpressionParser.serializeParenthesisNode(node, buffer);
                break;
            default:
                throw new Error(`Unexpected node type: ${node.type}`);
        }
        buffer.writeUint8(NULL);
    }
    /**
     * Deserializes a variable node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     * @throws If the binary data is malformed.
     */
    static deserializeVariableNode(buffer, node) {
        buffer.assertUint8(BinaryTypeMap.ExpressionVariableNode);
        node.type = NodeType.Variable;
        let prop = buffer.readUint8();
        while (prop !== NULL) {
            switch (prop) {
                case VariableNodeBinaryPropMap.Name:
                    node.name = buffer.readString();
                    break;
                case VariableNodeBinaryPropMap.FrequentName:
                    node.name = getFrequentNameOrFail(buffer.readUint8());
                    break;
                case VariableNodeBinaryPropMap.Start:
                    node.start = buffer.readUint32();
                    break;
                case VariableNodeBinaryPropMap.End:
                    node.end = buffer.readUint32();
                    break;
                default:
                    throw new Error(`Invalid property: ${prop}`);
            }
            prop = buffer.readUint8();
        }
    }
    /**
     * Deserializes a parenthesis node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     * @throws If the binary data is malformed.
     */
    static deserializeParenthesisNode(buffer, node) {
        buffer.assertUint8(BinaryTypeMap.ExpressionParenthesisNode);
        node.type = NodeType.Parenthesis;
        let prop = buffer.readUint8();
        while (prop !== NULL) {
            switch (prop) {
                case ParenthesisNodeBinaryPropMap.Expression:
                    LogicalExpressionParser.deserialize(buffer, node.expression = {});
                    break;
                case ParenthesisNodeBinaryPropMap.Start:
                    node.start = buffer.readUint32();
                    break;
                case ParenthesisNodeBinaryPropMap.End:
                    node.end = buffer.readUint32();
                    break;
                default:
                    throw new Error(`Invalid property: ${prop}`);
            }
            prop = buffer.readUint8();
        }
    }
    /**
     * Deserializes an operator node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     * @throws If the binary data is malformed.
     */
    static deserializeOperatorNode(buffer, node) {
        buffer.assertUint8(BinaryTypeMap.ExpressionOperatorNode);
        node.type = NodeType.Operator;
        let prop = buffer.readUint8();
        while (prop !== NULL) {
            switch (prop) {
                case OperatorNodeBinaryPropMap.Operator:
                    node.operator = getOperatorOrFail(buffer.readUint8());
                    break;
                case OperatorNodeBinaryPropMap.Left:
                    LogicalExpressionParser.deserialize(buffer, node.left = {});
                    break;
                case OperatorNodeBinaryPropMap.Right:
                    LogicalExpressionParser.deserialize(buffer, node.right = {});
                    break;
                case OperatorNodeBinaryPropMap.Start:
                    node.start = buffer.readUint32();
                    break;
                case OperatorNodeBinaryPropMap.End:
                    node.end = buffer.readUint32();
                    break;
                default:
                    throw new Error(`Invalid property: ${prop}`);
            }
            prop = buffer.readUint8();
        }
    }
    /**
     * Deserializes a logical expression node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     * @throws If the binary data is malformed.
     */
    static deserialize(buffer, node) {
        // note: we just do a simple lookahead here, because advancing the buffer is done in the
        // 'sub-deserialize' methods
        let type = buffer.peekUint8();
        while (type !== NULL) {
            switch (type) {
                case BinaryTypeMap.ExpressionVariableNode:
                    LogicalExpressionParser.deserializeVariableNode(buffer, node);
                    break;
                case BinaryTypeMap.ExpressionOperatorNode:
                    LogicalExpressionParser.deserializeOperatorNode(buffer, node);
                    break;
                case BinaryTypeMap.ExpressionParenthesisNode:
                    // eslint-disable-next-line max-len
                    LogicalExpressionParser.deserializeParenthesisNode(buffer, node);
                    break;
                default:
                    throw new Error(`Unexpected node type: ${type}`);
            }
            type = buffer.peekUint8();
        }
        // consume NULL
        buffer.readUint8();
    }
}

/* eslint-disable no-param-reassign */
/**
 * Pre-processor directives
 *
 * @see {@link https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#pre-processor-directives}
 * @see {@link https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#pre-parsing-directives}
 */
/**
 * Property map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent a property.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 */
var PreProcessorRuleSerializationMap;
(function (PreProcessorRuleSerializationMap) {
    PreProcessorRuleSerializationMap[PreProcessorRuleSerializationMap["Name"] = 1] = "Name";
    PreProcessorRuleSerializationMap[PreProcessorRuleSerializationMap["Params"] = 2] = "Params";
    PreProcessorRuleSerializationMap[PreProcessorRuleSerializationMap["Syntax"] = 3] = "Syntax";
    PreProcessorRuleSerializationMap[PreProcessorRuleSerializationMap["Start"] = 4] = "Start";
    PreProcessorRuleSerializationMap[PreProcessorRuleSerializationMap["End"] = 5] = "End";
})(PreProcessorRuleSerializationMap || (PreProcessorRuleSerializationMap = {}));
/**
 * Value map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent frequently used values.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 *
 * @see {@link https://adguard.com/kb/general/ad-filtering/create-own-filters/#preprocessor-directives}
 * @see {@link https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#pre-parsing-directives}
 */
const FREQUENT_DIRECTIVES_SERIALIZATION_MAP = new Map([
    ['if', 0],
    ['else', 1],
    ['endif', 2],
    ['include', 3],
    ['safari_cb_affinity', 4],
]);
/**
 * Value map for binary deserialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent frequently used values.
 */
const FREQUENT_DIRECTIVES_DESERIALIZATION_MAP = new Map(Array.from(FREQUENT_DIRECTIVES_SERIALIZATION_MAP).map(([key, value]) => [value, key]));
/**
 * Value map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent frequently used values.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 */
const FREQUENT_PARAMS_SERIALIZATION_MAP = new Map([
    // safari_cb_affinity parameters
    ['general', 0],
    ['privacy', 1],
    ['social', 2],
    ['security', 3],
    ['other', 4],
    ['custom', 5],
    ['all', 6],
]);
/**
 * Value map for binary deserialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent frequently used values.
 */
const FREQUENT_PARAMS_DESERIALIZATION_MAP = new Map(Array.from(FREQUENT_PARAMS_SERIALIZATION_MAP).map(([key, value]) => [value, key]));
/**
 * `PreProcessorParser` is responsible for parsing preprocessor rules.
 * Pre-processor comments are special comments that are used to control the behavior of the filter list processor.
 * Please note that this parser only handles general syntax for now, and does not validate the parameters at
 * the parsing stage.
 *
 * @example
 * If your rule is
 * ```adblock
 * !#if (adguard)
 * ```
 * then the directive's name is `if` and its value is `(adguard)`, but the parameter list
 * is not parsed / validated further.
 * @see {@link https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#pre-processor-directives}
 * @see {@link https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#pre-parsing-directives}
 */
class PreProcessorCommentRuleParser extends ParserBase {
    /**
     * Determines whether the rule is a pre-processor rule.
     *
     * @param raw Raw rule
     * @returns `true` if the rule is a pre-processor rule, `false` otherwise
     */
    static isPreProcessorRule(raw) {
        const trimmed = raw.trim();
        // Avoid this case: !##... (commonly used in AdGuard filters)
        return trimmed.startsWith(PREPROCESSOR_MARKER) && trimmed[PREPROCESSOR_MARKER_LEN] !== HASHMARK;
    }
    /**
     * Parses a raw rule as a pre-processor comment.
     *
     * @param raw Raw input to parse.
     * @param options Global parser options.
     * @param baseOffset Starting offset of the input. Node locations are calculated relative to this offset.
     * @returns
     * Pre-processor comment AST or null (if the raw rule cannot be parsed as a pre-processor comment)
     */
    static parse(raw, options = defaultParserOptions, baseOffset = 0) {
        // Ignore non-pre-processor rules
        if (!PreProcessorCommentRuleParser.isPreProcessorRule(raw)) {
            return null;
        }
        let offset = 0;
        // Ignore whitespace characters before the rule (if any)
        offset = StringUtils.skipWS(raw, offset);
        // Ignore the pre-processor marker
        offset += PREPROCESSOR_MARKER_LEN;
        // Ignore whitespace characters after the pre-processor marker (if any)
        // Note: this is incorrect according to the spec, but we do it for tolerance
        offset = StringUtils.skipWS(raw, offset);
        // Directive name should start at this offset, so we save this offset now
        const nameStart = offset;
        // Consume directive name, so parse the sequence until the first
        // whitespace / opening parenthesis / end of string
        while (offset < raw.length) {
            const ch = raw[offset];
            if (ch === PREPROCESSOR_SEPARATOR || ch === OPEN_PARENTHESIS) {
                break;
            }
            offset += 1;
        }
        // Save name end offset
        const nameEnd = offset;
        // Create name node
        const name = ValueParser.parse(raw.slice(nameStart, nameEnd), options, baseOffset + nameStart);
        // Ignore whitespace characters after the directive name (if any)
        // Note: this may incorrect according to the spec, but we do it for tolerance
        offset = StringUtils.skipWS(raw, offset);
        // If the directive name is "safari_cb_affinity", then we have a special case
        if (name.value === SAFARI_CB_AFFINITY) {
            // Throw error if there are spaces after the directive name
            if (offset > nameEnd) {
                throw new AdblockSyntaxError(`Unexpected whitespace after "${SAFARI_CB_AFFINITY}" directive name`, baseOffset + nameEnd, baseOffset + offset);
            }
            // safari_cb_affinity directive optionally accepts a parameter list
            // So at this point we should check if there are parameters or not
            // (cb_affinity directive followed by an opening parenthesis or if we
            // skip the whitespace we reach the end of the string)
            if (StringUtils.skipWS(raw, offset) !== raw.length) {
                if (raw[offset] !== OPEN_PARENTHESIS) {
                    throw new AdblockSyntaxError(`Unexpected character '${raw[offset]}' after '${SAFARI_CB_AFFINITY}' directive name`, baseOffset + offset, baseOffset + offset + 1);
                }
                // If we have parameters, then we should parse them
                // Note: we don't validate the parameters at this stage
                // Ignore opening parenthesis
                offset += 1;
                // Save parameter list start offset
                const parameterListStart = offset;
                // Check for closing parenthesis
                const closingParenthesesIndex = StringUtils.skipWSBack(raw);
                if (closingParenthesesIndex === -1 || raw[closingParenthesesIndex] !== CLOSE_PARENTHESIS) {
                    throw new AdblockSyntaxError(`Missing closing parenthesis for '${SAFARI_CB_AFFINITY}' directive`, baseOffset + offset, baseOffset + raw.length);
                }
                // Save parameter list end offset
                const parameterListEnd = closingParenthesesIndex;
                // Parse parameters between the opening and closing parentheses
                const result = {
                    type: CommentRuleType.PreProcessorCommentRule,
                    category: RuleCategory.Comment,
                    syntax: AdblockSyntax.Adg,
                    name,
                    // comma separated list of parameters
                    params: ParameterListParser.parse(raw.slice(parameterListStart, parameterListEnd), options, baseOffset + parameterListStart, COMMA),
                };
                if (options.includeRaws) {
                    result.raws = {
                        text: raw,
                    };
                }
                if (options.isLocIncluded) {
                    result.start = baseOffset;
                    result.end = baseOffset + raw.length;
                }
                return result;
            }
        }
        // If we reached the end of the string, then we have a directive without parameters
        // (e.g. "!#safari_cb_affinity" or "!#endif")
        // No need to continue parsing in this case.
        if (offset === raw.length) {
            // Throw error if the directive name is "if" or "include", because these directives
            // should have parameters
            if (name.value === IF || name.value === INCLUDE) {
                throw new AdblockSyntaxError(`Directive "${name.value}" requires parameters`, baseOffset, baseOffset + raw.length);
            }
            const result = {
                type: CommentRuleType.PreProcessorCommentRule,
                category: RuleCategory.Comment,
                syntax: AdblockSyntax.Common,
                name,
            };
            if (options.includeRaws) {
                result.raws = {
                    text: raw,
                };
            }
            if (options.isLocIncluded) {
                result.start = baseOffset;
                result.end = baseOffset + raw.length;
            }
            return result;
        }
        // Get start and end offsets of the directive parameters
        const paramsStart = offset;
        const paramsEnd = StringUtils.skipWSBack(raw) + 1;
        // Prepare parameters node
        let params;
        // Parse parameters. Handle "if" and "safari_cb_affinity" directives
        // separately.
        if (name.value === IF) {
            params = LogicalExpressionParser.parse(raw.slice(paramsStart, paramsEnd), options, baseOffset + paramsStart);
        }
        else {
            params = ValueParser.parse(raw.slice(paramsStart, paramsEnd), options, baseOffset + paramsStart);
        }
        const result = {
            type: CommentRuleType.PreProcessorCommentRule,
            category: RuleCategory.Comment,
            syntax: AdblockSyntax.Common,
            name,
            params,
        };
        if (options.includeRaws) {
            result.raws = {
                text: raw,
            };
        }
        if (options.isLocIncluded) {
            result.start = baseOffset;
            result.end = baseOffset + raw.length;
        }
        return result;
    }
    /**
     * Converts a pre-processor comment node to a string.
     *
     * @param node Pre-processor comment node
     * @returns Raw string
     */
    static generate(node) {
        let result = EMPTY;
        result += PREPROCESSOR_MARKER;
        result += node.name.value;
        if (node.params) {
            // Space is not allowed after "safari_cb_affinity" directive, so we need to handle it separately.
            if (node.name.value !== SAFARI_CB_AFFINITY) {
                result += SPACE;
            }
            if (node.params.type === 'Value') {
                result += ValueParser.generate(node.params);
            }
            else if (node.params.type === 'ParameterList') {
                result += OPEN_PARENTHESIS;
                result += ParameterListParser.generate(node.params);
                result += CLOSE_PARENTHESIS;
            }
            else {
                result += LogicalExpressionParser.generate(node.params);
            }
        }
        return result;
    }
    /**
     * Serializes a pre-processor comment node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     */
    // TODO: add support for raws, if ever needed
    static serialize(node, buffer) {
        buffer.writeUint8(BinaryTypeMap.PreProcessorCommentRuleNode);
        buffer.writeUint8(PreProcessorRuleSerializationMap.Name);
        ValueParser.serialize(node.name, buffer, FREQUENT_DIRECTIVES_SERIALIZATION_MAP);
        buffer.writeUint8(PreProcessorRuleSerializationMap.Syntax);
        buffer.writeUint8(SYNTAX_SERIALIZATION_MAP.get(node.syntax) ?? 0);
        if (!isUndefined(node.params)) {
            buffer.writeUint8(PreProcessorRuleSerializationMap.Params);
            if (node.params.type === 'Value') {
                ValueParser.serialize(node.params, buffer);
            }
            else if (node.params.type === 'ParameterList') {
                ParameterListParser.serialize(node.params, buffer, FREQUENT_PARAMS_SERIALIZATION_MAP, true);
            }
            else {
                LogicalExpressionParser.serialize(node.params, buffer);
            }
        }
        if (!isUndefined(node.start)) {
            buffer.writeUint8(PreProcessorRuleSerializationMap.Start);
            buffer.writeUint32(node.start);
        }
        if (!isUndefined(node.end)) {
            buffer.writeUint8(PreProcessorRuleSerializationMap.End);
            buffer.writeUint32(node.end);
        }
        buffer.writeUint8(NULL);
    }
    /**
     * Deserializes a pre-processor comment node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     * @throws If the binary data is malformed.
     */
    static deserialize(buffer, node) {
        buffer.assertUint8(BinaryTypeMap.PreProcessorCommentRuleNode);
        node.type = CommentRuleType.PreProcessorCommentRule;
        node.category = RuleCategory.Comment;
        node.syntax = AdblockSyntax.Common;
        let prop = buffer.readUint8();
        while (prop !== NULL) {
            switch (prop) {
                case PreProcessorRuleSerializationMap.Name:
                    ValueParser.deserialize(buffer, node.name = {}, FREQUENT_DIRECTIVES_DESERIALIZATION_MAP);
                    break;
                case PreProcessorRuleSerializationMap.Syntax:
                    node.syntax = SYNTAX_DESERIALIZATION_MAP.get(buffer.readUint8()) ?? AdblockSyntax.Common;
                    break;
                case PreProcessorRuleSerializationMap.Params:
                    switch (buffer.peekUint8()) {
                        case BinaryTypeMap.ValueNode:
                            ValueParser.deserialize(buffer, node.params = {});
                            break;
                        case BinaryTypeMap.ParameterListNode:
                            // eslint-disable-next-line max-len
                            ParameterListParser.deserialize(buffer, node.params = {}, FREQUENT_PARAMS_DESERIALIZATION_MAP);
                            break;
                        case BinaryTypeMap.ExpressionOperatorNode:
                        case BinaryTypeMap.ExpressionParenthesisNode:
                        case BinaryTypeMap.ExpressionVariableNode:
                            LogicalExpressionParser.deserialize(buffer, node.params = {});
                            break;
                        default:
                            throw new Error(`Invalid binary type: ${prop}`);
                    }
                    break;
                case PreProcessorRuleSerializationMap.Start:
                    node.start = buffer.readUint32();
                    break;
                case PreProcessorRuleSerializationMap.End:
                    node.end = buffer.readUint32();
                    break;
                default:
                    throw new Error(`Invalid property: ${prop}`);
            }
            prop = buffer.readUint8();
        }
    }
}

/* eslint-disable no-param-reassign */
/**
 * Property map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent a property.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 */
var SimpleCommentRuleSerializationMap;
(function (SimpleCommentRuleSerializationMap) {
    SimpleCommentRuleSerializationMap[SimpleCommentRuleSerializationMap["Marker"] = 1] = "Marker";
    SimpleCommentRuleSerializationMap[SimpleCommentRuleSerializationMap["Text"] = 2] = "Text";
    SimpleCommentRuleSerializationMap[SimpleCommentRuleSerializationMap["Start"] = 3] = "Start";
    SimpleCommentRuleSerializationMap[SimpleCommentRuleSerializationMap["End"] = 4] = "End";
})(SimpleCommentRuleSerializationMap || (SimpleCommentRuleSerializationMap = {}));
/**
 * `SimpleCommentParser` is responsible for parsing simple comments.
 * Some comments have a special meaning in adblock syntax, like agent comments or hints,
 * but this parser is only responsible for parsing regular comments,
 * whose only purpose is to provide some human-readable information.
 *
 * @example
 * ```adblock
 * ! This is a simple comment
 * # This is a simple comment, but in host-like syntax
 * ```
 */
class SimpleCommentParser extends ParserBase {
    /**
     * Checks if the raw rule is a simple comment.
     *
     * @param raw Raw input to check.
     * @returns `true` if the input is a simple comment, `false` otherwise.
     * @note This method does not check for adblock agent comments.
     */
    static isSimpleComment(raw) {
        const trimmed = raw.trim();
        // Exclamation mark based comments
        if (trimmed.startsWith(CommentMarker.Regular)) {
            return true;
        }
        // Hashmark based comments
        // Note: in this case, we must be sure that we do not mistakenly parse a cosmetic rule as a #-like comment,
        // since most cosmetic rule separators also start with #
        if (trimmed.startsWith(CommentMarker.Hashmark)) {
            const result = CosmeticRuleSeparatorUtils.find(trimmed);
            // If we cannot find a separator, it means that the rule is definitely a comment
            if (result === null) {
                return true;
            }
            // Otherwise, we must check if the separator is followed by a valid selector
            const { end } = result;
            // No valid selector
            if (!trimmed[end + 1]
                || StringUtils.isWhitespace(trimmed[end + 1])
                || (trimmed[end + 1] === CommentMarker.Hashmark && trimmed[end + 2] === CommentMarker.Hashmark)) {
                return true;
            }
        }
        return false;
    }
    /**
     * Parses a raw rule as a simple comment.
     *
     * @param raw Raw input to parse.
     * @param options Global parser options.
     * @param baseOffset Starting offset of the input. Node locations are calculated relative to this offset.
     * @returns Comment rule node or null (if the raw rule cannot be parsed as a simple comment).
     */
    static parse(raw, options = defaultParserOptions, baseOffset = 0) {
        // Ignore non-comment rules
        if (!this.isSimpleComment(raw)) {
            return null;
        }
        // If we are here, it means that the rule is a regular comment
        let offset = 0;
        // Skip leading whitespace (if any)
        offset = StringUtils.skipWS(raw, offset);
        // Get comment marker
        const marker = ValueParser.parse(raw[offset], options, baseOffset + offset);
        // Skip marker
        offset += 1;
        // Get comment text
        const text = ValueParser.parse(raw.slice(offset), options, baseOffset + offset);
        // Regular comment rule
        const result = {
            category: RuleCategory.Comment,
            type: CommentRuleType.CommentRule,
            // TODO: Change syntax when hashmark is used
            syntax: AdblockSyntax.Common,
            marker,
            text,
        };
        if (options.includeRaws) {
            result.raws = {
                text: raw,
            };
        }
        if (options.isLocIncluded) {
            result.start = baseOffset;
            result.end = baseOffset + raw.length;
        }
        return result;
    }
    /**
     * Converts a comment rule node to a string.
     *
     * @param node Comment rule node.
     * @returns Raw string.
     */
    static generate(node) {
        let result = EMPTY;
        result += ValueParser.generate(node.marker);
        result += ValueParser.generate(node.text);
        return result;
    }
    /**
     * Serializes a simple comment rule node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     */
    // TODO: add support for raws, if ever needed
    static serialize(node, buffer) {
        buffer.writeUint8(BinaryTypeMap.CommentRuleNode);
        buffer.writeUint8(SimpleCommentRuleSerializationMap.Marker);
        ValueParser.serialize(node.marker, buffer);
        buffer.writeUint8(SimpleCommentRuleSerializationMap.Text);
        ValueParser.serialize(node.text, buffer);
        if (!isUndefined(node.start)) {
            buffer.writeUint8(SimpleCommentRuleSerializationMap.Start);
            buffer.writeUint32(node.start);
        }
        if (!isUndefined(node.end)) {
            buffer.writeUint8(SimpleCommentRuleSerializationMap.End);
            buffer.writeUint32(node.end);
        }
        buffer.writeUint8(NULL);
    }
    /**
     * Deserializes a simple comment node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     * @throws If the binary data is malformed.
     */
    static deserialize(buffer, node) {
        buffer.assertUint8(BinaryTypeMap.CommentRuleNode);
        node.type = CommentRuleType.CommentRule;
        node.category = RuleCategory.Comment;
        node.syntax = AdblockSyntax.Common;
        let prop = buffer.readUint8();
        while (prop !== NULL) {
            switch (prop) {
                case SimpleCommentRuleSerializationMap.Marker:
                    ValueParser.deserialize(buffer, node.marker = {});
                    break;
                case SimpleCommentRuleSerializationMap.Text:
                    ValueParser.deserialize(buffer, node.text = {});
                    break;
                case SimpleCommentRuleSerializationMap.Start:
                    node.start = buffer.readUint32();
                    break;
                case SimpleCommentRuleSerializationMap.End:
                    node.end = buffer.readUint32();
                    break;
                default:
                    throw new Error(`Invalid property: ${prop}`);
            }
            prop = buffer.readUint8();
        }
    }
}

/* eslint-disable no-param-reassign */
/**
 * `CommentParser` is responsible for parsing any comment-like adblock rules.
 *
 * @example
 * Example rules:
 *  - Adblock agent rules:
 *      - ```adblock
 *        [AdGuard]
 *        ```
 *      - ```adblock
 *        [Adblock Plus 2.0]
 *        ```
 *      - etc.
 *  - AdGuard hint rules:
 *      - ```adblock
 *        !+ NOT_OPTIMIZED
 *        ```
 *      - ```adblock
 *        !+ NOT_OPTIMIZED PLATFORM(windows)
 *        ```
 *      - etc.
 *  - Pre-processor rules:
 *      - ```adblock
 *        !#if (adguard)
 *        ```
 *      - ```adblock
 *        !#endif
 *        ```
 *      - etc.
 *  - Metadata rules:
 *      - ```adblock
 *        ! Title: My List
 *        ```
 *      - ```adblock
 *        ! Version: 2.0.150
 *        ```
 *      - etc.
 *  - AGLint inline config rules:
 *      - ```adblock
 *        ! aglint-enable some-rule
 *        ```
 *      - ```adblock
 *        ! aglint-disable some-rule
 *        ```
 *      - etc.
 *  - Simple comments:
 *      - Regular version:
 *        ```adblock
 *        ! This is just a comment
 *        ```
 *      - uBlock Origin / "hostlist" version:
 *        ```adblock
 *        # This is just a comment
 *        ```
 *      - etc.
 */
class CommentRuleParser extends ParserBase {
    /**
     * Checks whether a rule is a comment.
     *
     * @param raw Raw rule
     * @returns `true` if the rule is a comment, `false` otherwise
     */
    static isCommentRule(raw) {
        const trimmed = raw.trim();
        return SimpleCommentParser.isSimpleComment(trimmed) || AgentCommentRuleParser.isAgentRule(trimmed);
    }
    /**
     * Parses a raw rule as comment.
     *
     * @param raw Raw input to parse.
     * @param options Global parser options.
     * @param baseOffset Starting offset of the input. Node locations are calculated relative to this offset.
     * @returns Comment AST or null (if the raw rule cannot be parsed as comment)
     */
    static parse(raw, options = defaultParserOptions, baseOffset = 0) {
        // Ignore non-comment rules
        if (!CommentRuleParser.isCommentRule(raw)) {
            return null;
        }
        // Note: we parse non-functional comments at the end,
        // if the input does not match any of the previous, more specific comment patterns
        return AgentCommentRuleParser.parse(raw, options, baseOffset)
            || HintCommentRuleParser.parse(raw, options, baseOffset)
            || PreProcessorCommentRuleParser.parse(raw, options, baseOffset)
            || MetadataCommentRuleParser.parse(raw, options, baseOffset)
            || ConfigCommentRuleParser.parse(raw, options, baseOffset)
            || SimpleCommentParser.parse(raw, options, baseOffset);
    }
    /**
     * Converts a comment rule node to a string.
     *
     * @param node Comment rule node
     * @returns Raw string
     */
    static generate(node) {
        switch (node.type) {
            case CommentRuleType.AgentCommentRule:
                return AgentCommentRuleParser.generate(node);
            case CommentRuleType.HintCommentRule:
                return HintCommentRuleParser.generate(node);
            case CommentRuleType.PreProcessorCommentRule:
                return PreProcessorCommentRuleParser.generate(node);
            case CommentRuleType.MetadataCommentRule:
                return MetadataCommentRuleParser.generate(node);
            case CommentRuleType.ConfigCommentRule:
                return ConfigCommentRuleParser.generate(node);
            case CommentRuleType.CommentRule:
                return SimpleCommentParser.generate(node);
            default:
                throw new Error('Unknown comment rule type');
        }
    }
    /**
     * Serializes a comment rule node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     */
    static serialize(node, buffer) {
        switch (node.type) {
            case CommentRuleType.AgentCommentRule:
                AgentCommentRuleParser.serialize(node, buffer);
                return;
            case CommentRuleType.HintCommentRule:
                HintCommentRuleParser.serialize(node, buffer);
                return;
            case CommentRuleType.PreProcessorCommentRule:
                PreProcessorCommentRuleParser.serialize(node, buffer);
                return;
            case CommentRuleType.MetadataCommentRule:
                MetadataCommentRuleParser.serialize(node, buffer);
                return;
            case CommentRuleType.ConfigCommentRule:
                ConfigCommentRuleParser.serialize(node, buffer);
                return;
            case CommentRuleType.CommentRule:
                SimpleCommentParser.serialize(node, buffer);
                break;
            default:
                throw new Error('Unknown comment rule type');
        }
    }
    /**
     * Deserializes a comment rule node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     * @throws If the binary data is malformed.
     */
    static deserialize(buffer, node) {
        const type = buffer.peekUint8();
        switch (type) {
            case BinaryTypeMap.AgentRuleNode:
                AgentCommentRuleParser.deserialize(buffer, node);
                return;
            case BinaryTypeMap.HintRuleNode:
                HintCommentRuleParser.deserialize(buffer, node);
                return;
            case BinaryTypeMap.PreProcessorCommentRuleNode:
                PreProcessorCommentRuleParser.deserialize(buffer, node);
                return;
            case BinaryTypeMap.MetadataCommentRuleNode:
                MetadataCommentRuleParser.deserialize(buffer, node);
                return;
            case BinaryTypeMap.ConfigCommentRuleNode:
                ConfigCommentRuleParser.deserialize(buffer, node);
                return;
            case BinaryTypeMap.CommentRuleNode:
                SimpleCommentParser.deserialize(buffer, node);
                return;
            default:
                throw new Error(`Unknown comment rule type: ${type}`);
        }
    }
}

/* eslint-disable no-param-reassign */
/**
 * Property map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent a property.
 *
 * ! IMPORTANT: If you change values here, please update the binary schema version
 *
 * @note Only 256 values can be represented this way.
 */
var ListItemSerializationMap;
(function (ListItemSerializationMap) {
    ListItemSerializationMap[ListItemSerializationMap["Exception"] = 1] = "Exception";
    ListItemSerializationMap[ListItemSerializationMap["Value"] = 2] = "Value";
    ListItemSerializationMap[ListItemSerializationMap["Start"] = 3] = "Start";
    ListItemSerializationMap[ListItemSerializationMap["End"] = 4] = "End";
})(ListItemSerializationMap || (ListItemSerializationMap = {}));
/**
 * Prefixes for error messages which are used for parsing of value lists.
 */
const LIST_PARSE_ERROR_PREFIX = {
    EMPTY_ITEM: 'Empty value specified in the list',
    NO_MULTIPLE_NEGATION: 'Exception marker cannot be followed by another exception marker',
    NO_SEPARATOR_AFTER_NEGATION: 'Exception marker cannot be followed by a separator',
    NO_SEPARATOR_AT_THE_BEGINNING: 'Value list cannot start with a separator',
    NO_SEPARATOR_AT_THE_END: 'Value list cannot end with a separator',
    NO_WHITESPACE_AFTER_NEGATION: 'Exception marker cannot be followed by whitespace',
};
/**
 * Parses a `raw` modifier value which may be represented as a list of items separated by `separator`.
 * Needed for $app, $denyallow, $domain, $method.
 *
 * @param raw Raw input to parse.
 * @param options Global parser options.
 * @param baseOffset Starting offset of the input. Node locations are calculated relative to this offset.
 * @param separator Separator character (default: comma)
 * @param type Type of the list items (default: {@link ListItemNodeType.Domain}).
 * @template T Type of the list items.
 *
 * @returns List of parsed items.
 * @throws An {@link AdblockSyntaxError} if the list is syntactically invalid
 *
 * @example
 * - parses an app list — `com.example.app|Example.exe`
 * - parses a domain list — `example.com,example.org,~example.org` or `example.com|~example.org`
 * - parses a method list — `~post|~put`
 */
const parseListItems = (raw, options = defaultParserOptions, baseOffset = 0, separator = COMMA, type = ListItemNodeType.Unknown) => {
    // Function body here
    const rawListItems = [];
    let offset = 0;
    // Skip whitespace before the list
    offset = StringUtils.skipWS(raw, offset);
    // If the first character is a separator, then the list is invalid
    // and no need to continue parsing
    if (raw[offset] === separator) {
        throw new AdblockSyntaxError(LIST_PARSE_ERROR_PREFIX.NO_SEPARATOR_AT_THE_BEGINNING, baseOffset + offset, baseOffset + raw.length);
    }
    // If the last character is a separator, then the list item is invalid
    // and no need to continue parsing
    const realEndIndex = StringUtils.skipWSBack(raw);
    if (raw[realEndIndex] === separator) {
        throw new AdblockSyntaxError(LIST_PARSE_ERROR_PREFIX.NO_SEPARATOR_AT_THE_END, baseOffset + realEndIndex, baseOffset + realEndIndex + 1);
    }
    // Split list items by unescaped separators
    while (offset < raw.length) {
        // Skip whitespace before the list item
        offset = StringUtils.skipWS(raw, offset);
        let itemStart = offset;
        // Find the index of the first unescaped separator character
        const separatorStartIndex = StringUtils.findNextUnescapedCharacter(raw, separator, offset);
        const itemEnd = separatorStartIndex === -1
            ? StringUtils.skipWSBack(raw) + 1
            : StringUtils.skipWSBack(raw, separatorStartIndex - 1) + 1;
        const exception = raw[itemStart] === NEGATION_MARKER;
        // Skip the exception marker
        if (exception) {
            itemStart += 1;
            const item = raw[itemStart];
            // Exception marker cannot be followed by another exception marker
            if (item === NEGATION_MARKER) {
                throw new AdblockSyntaxError(LIST_PARSE_ERROR_PREFIX.NO_MULTIPLE_NEGATION, baseOffset + itemStart, baseOffset + itemStart + 1);
            }
            // Exception marker cannot be followed by a separator
            if (item === separator) {
                throw new AdblockSyntaxError(LIST_PARSE_ERROR_PREFIX.NO_SEPARATOR_AFTER_NEGATION, baseOffset + itemStart, baseOffset + itemStart + 1);
            }
            // Exception marker cannot be followed by whitespace
            if (StringUtils.isWhitespace(item)) {
                throw new AdblockSyntaxError(LIST_PARSE_ERROR_PREFIX.NO_WHITESPACE_AFTER_NEGATION, baseOffset + itemStart, baseOffset + itemStart + 1);
            }
        }
        // List item can't be empty
        // Note we use '<=' instead of '===' because we have bidirectional trim
        // This is needed to handle cases like 'example.com, ,example.org'
        if (itemEnd <= itemStart) {
            throw new AdblockSyntaxError(LIST_PARSE_ERROR_PREFIX.EMPTY_ITEM, baseOffset + itemStart, baseOffset + raw.length);
        }
        const listItem = {
            type,
            value: raw.slice(itemStart, itemEnd),
            exception,
        };
        if (options.isLocIncluded) {
            listItem.start = baseOffset + itemStart;
            listItem.end = baseOffset + itemEnd;
        }
        // Collect list item
        rawListItems.push(listItem);
        // Increment the offset to the next list item (or the end of the string)
        offset = separatorStartIndex === -1 ? raw.length : separatorStartIndex + 1;
    }
    return rawListItems;
};
/**
 * Generates a string representation of a list item.
 *
 * @param item List item to generate.
 * @template T Type of the list item.
 *
 * @returns String representation of the list item.
 */
const generateListItem = (item) => {
    return `${item.exception ? NEGATION_MARKER : EMPTY}${item.value}`;
};
/**
 * Generates a string representation of a list of items.
 *
 * @param items List of items to generate.
 * @param separator Separator character.
 * @template T Type of the list items.
 *
 * @returns String representation of the list of items.
 */
const generateListItems = (items, separator) => {
    return items.map(generateListItem).join(separator);
};
/**
 * Serializes a list item to binary format.
 *
 * @param item List item to serialize.
 * @param buffer Output byte buffer.
 * @template T Type of the list item.
 */
const serializeListItem = (item, buffer) => {
    switch (item.type) {
        case ListItemNodeType.App:
            buffer.writeUint8(BinaryTypeMap.AppNode);
            break;
        case ListItemNodeType.Domain:
            buffer.writeUint8(BinaryTypeMap.DomainNode);
            break;
        case ListItemNodeType.Method:
            buffer.writeUint8(BinaryTypeMap.MethodNode);
            break;
        case ListItemNodeType.StealthOption:
            buffer.writeUint8(BinaryTypeMap.StealthOptionNode);
            break;
        default:
            throw new Error(`Invalid list item type: ${item.type}`);
    }
    buffer.writeUint8(ListItemSerializationMap.Exception);
    buffer.writeUint8(item.exception ? 1 : 0);
    buffer.writeUint8(ListItemSerializationMap.Value);
    buffer.writeString(item.value);
    if (!isUndefined(item.start)) {
        buffer.writeUint8(ListItemSerializationMap.Start);
        buffer.writeUint32(item.start);
    }
    if (!isUndefined(item.end)) {
        buffer.writeUint8(ListItemSerializationMap.End);
        buffer.writeUint32(item.end);
    }
    buffer.writeUint8(NULL);
};
/**
 * Deserializes a list item from binary format.
 *
 * @param buffer Input byte buffer.
 * @param node Partial list item to deserialize.
 * @template T Type of the list item.
 */
const deserializeListItem = (buffer, node) => {
    const type = buffer.readUint8();
    switch (type) {
        case BinaryTypeMap.AppNode:
            node.type = ListItemNodeType.App;
            break;
        case BinaryTypeMap.DomainNode:
            node.type = ListItemNodeType.Domain;
            break;
        case BinaryTypeMap.MethodNode:
            node.type = ListItemNodeType.Method;
            break;
        case BinaryTypeMap.StealthOptionNode:
            node.type = ListItemNodeType.StealthOption;
            break;
        default:
            throw new Error(`Invalid list item type: ${type}`);
    }
    let prop = buffer.readUint8();
    while (prop !== NULL) {
        switch (prop) {
            case ListItemSerializationMap.Exception:
                node.exception = buffer.readUint8() === 1;
                break;
            case ListItemSerializationMap.Value:
                node.value = buffer.readString();
                break;
            case ListItemSerializationMap.Start:
                node.start = buffer.readUint32();
                break;
            case ListItemSerializationMap.End:
                node.end = buffer.readUint32();
                break;
            default:
                throw new Error(`Invalid property: ${type}`);
        }
        prop = buffer.readUint8();
    }
};
/**
 * Serializes a list of items to binary format.
 *
 * @param items List of items to serialize.
 * @param buffer Output byte buffer.
 * @template T Type of the list items.
 */
const serializeListItems = (items, buffer) => {
    const { length } = items;
    buffer.writeUint16(length);
    for (let i = 0; i < length; i += 1) {
        serializeListItem(items[i], buffer);
    }
};
/**
 * Deserializes a list of items from binary format.
 *
 * @param buffer Input byte buffer.
 * @param items Partial list of items to deserialize.
 * @template T Type of the list items.
 */
const deserializeListItems = (buffer, items) => {
    const length = buffer.readUint16();
    items.length = length;
    for (let i = 0; i < length; i += 1) {
        deserializeListItem(buffer, items[i] = {});
    }
};

/* eslint-disable no-param-reassign */
/**
 * Property map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent a property.
 *
 * ! IMPORTANT: If you change values here, please update the binary schema version
 *
 * @note Only 256 values can be represented this way.
 */
var DomainListSerializationMap;
(function (DomainListSerializationMap) {
    DomainListSerializationMap[DomainListSerializationMap["Separator"] = 1] = "Separator";
    DomainListSerializationMap[DomainListSerializationMap["Children"] = 2] = "Children";
    DomainListSerializationMap[DomainListSerializationMap["Start"] = 3] = "Start";
    DomainListSerializationMap[DomainListSerializationMap["End"] = 4] = "End";
})(DomainListSerializationMap || (DomainListSerializationMap = {}));
/**
 * Value map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent frequently used values.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 */
const SEPARATOR_SERIALIZATION_MAP$1 = new Map([
    [COMMA, 0],
    [PIPE, 1],
]);
/**
 * Value map for binary deserialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent frequently used values.
 */
const SEPARATOR_DESERIALIZATION_MAP$1 = new Map(Array.from(SEPARATOR_SERIALIZATION_MAP$1).map(([key, value]) => [value, key]));
/**
 * `DomainListParser` is responsible for parsing a domain list.
 *
 * @example
 * - If the rule is `example.com,~example.net##.ads`, the domain list is `example.com,~example.net`.
 * - If the rule is `ads.js^$script,domains=example.com|~example.org`, the domain list is `example.com|~example.org`.
 * This parser is responsible for parsing these domain lists.
 * @see {@link https://help.eyeo.com/adblockplus/how-to-write-filters#elemhide_domains}
 */
class DomainListParser extends ParserBase {
    /**
     * Parses a domain list, eg. `example.com,example.org,~example.org`
     *
     * @param raw Raw input to parse.
     * @param options Global parser options.
     * @param baseOffset Starting offset of the input. Node locations are calculated relative to this offset.
     * @param separator Separator character (default: comma)
     *
     * @returns Domain list AST.
     * @throws An {@link AdblockSyntaxError} if the domain list is syntactically invalid.
     * @throws An {@link Error} if the options are invalid.
     */
    static parse(raw, options = defaultParserOptions, baseOffset = 0, separator = COMMA) {
        if (separator !== COMMA && separator !== PIPE) {
            throw new Error(`Invalid separator: ${separator}`);
        }
        const result = {
            type: ListNodeType.DomainList,
            separator,
            children: parseListItems(raw, options, baseOffset, separator, ListItemNodeType.Domain),
        };
        if (options.isLocIncluded) {
            result.start = baseOffset;
            result.end = baseOffset + raw.length;
        }
        return result;
    }
    /**
     * Converts a domain list node to a string.
     *
     * @param node Domain list node.
     *
     * @returns Raw string.
     */
    static generate(node) {
        return generateListItems(node.children, node.separator);
    }
    /**
     * Serializes a domain list node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     */
    static serialize(node, buffer) {
        buffer.writeUint8(BinaryTypeMap.DomainListNode);
        const separator = SEPARATOR_SERIALIZATION_MAP$1.get(node.separator);
        if (isUndefined(separator)) {
            throw new Error(`Invalid separator: ${node.separator}`);
        }
        buffer.writeUint8(DomainListSerializationMap.Separator);
        buffer.writeUint8(separator);
        buffer.writeUint8(DomainListSerializationMap.Children);
        serializeListItems(node.children, buffer);
        if (!isUndefined(node.start)) {
            buffer.writeUint8(DomainListSerializationMap.Start);
            buffer.writeUint32(node.start);
        }
        if (!isUndefined(node.end)) {
            buffer.writeUint8(DomainListSerializationMap.End);
            buffer.writeUint32(node.end);
        }
        buffer.writeUint8(NULL);
    }
    /**
     * Deserializes a modifier list node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     */
    static deserialize(buffer, node) {
        buffer.assertUint8(BinaryTypeMap.DomainListNode);
        node.type = ListNodeType.DomainList;
        let prop = buffer.readUint8();
        while (prop !== NULL) {
            switch (prop) {
                case DomainListSerializationMap.Separator:
                    // eslint-disable-next-line max-len
                    node.separator = (SEPARATOR_DESERIALIZATION_MAP$1.get(buffer.readUint8()) ?? COMMA);
                    break;
                case DomainListSerializationMap.Children:
                    deserializeListItems(buffer, node.children = []);
                    break;
                case DomainListSerializationMap.Start:
                    node.start = buffer.readUint32();
                    break;
                case DomainListSerializationMap.End:
                    node.end = buffer.readUint32();
                    break;
                default:
                    throw new Error(`Invalid property: ${prop}.`);
            }
            prop = buffer.readUint8();
        }
    }
}

/* eslint-disable no-param-reassign */
/**
 * Property map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent a property.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 */
var ModifierNodeSerializationMap;
(function (ModifierNodeSerializationMap) {
    ModifierNodeSerializationMap[ModifierNodeSerializationMap["Name"] = 1] = "Name";
    ModifierNodeSerializationMap[ModifierNodeSerializationMap["Value"] = 2] = "Value";
    ModifierNodeSerializationMap[ModifierNodeSerializationMap["Exception"] = 3] = "Exception";
    ModifierNodeSerializationMap[ModifierNodeSerializationMap["Start"] = 4] = "Start";
    ModifierNodeSerializationMap[ModifierNodeSerializationMap["End"] = 5] = "End";
})(ModifierNodeSerializationMap || (ModifierNodeSerializationMap = {}));
/**
 * Value map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent frequently used values.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 */
const FREQUENT_MODIFIERS_SERIALIZATION_MAP = new Map([
    ['_', 0],
    ['all', 1],
    ['app', 2],
    ['badfilter', 3],
    ['cname', 4],
    ['content', 5],
    ['cookie', 6],
    ['csp', 7],
    ['denyallow', 8],
    ['document', 9],
    ['doc', 10],
    ['domain', 11],
    ['from', 12],
    ['elemhide', 13],
    ['ehide', 14],
    ['empty', 15],
    ['first-party', 16],
    ['1p', 17],
    ['extension', 18],
    ['font', 19],
    ['genericblock', 20],
    ['generichide', 21],
    ['ghide', 22],
    ['header', 23],
    ['hls', 24],
    ['image', 25],
    ['important', 26],
    ['inline-font', 27],
    ['inline-script', 28],
    ['jsinject', 29],
    ['jsonprune', 30],
    ['match-case', 31],
    ['media', 32],
    ['method', 33],
    ['mp4', 34],
    ['network', 35],
    ['object-subrequest', 36],
    ['object', 37],
    ['other', 38],
    ['permissions', 39],
    ['ping', 40],
    ['popunder', 41],
    ['popup', 42],
    ['redirect-rule', 43],
    ['redirect', 44],
    ['rewrite', 45],
    ['referrerpolicy', 46],
    ['removeheader', 47],
    ['removeparam', 48],
    ['replace', 49],
    ['script', 50],
    ['specifichide', 51],
    ['shide', 52],
    ['stealth', 53],
    ['strict1p', 54],
    ['strict3p', 55],
    ['stylesheet', 56],
    ['css', 57],
    ['subdocument', 58],
    ['frame', 59],
    ['third-party', 60],
    ['3p', 61],
    ['to', 62],
    ['urlblock', 63],
    ['webrtc', 64],
    ['websocket', 65],
    ['xmlhttprequest', 66],
    ['xhr', 67],
    // TODO: add new modifiers here
]);
/**
 * Value map for binary deserialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent frequently used values.
 *
 * @note Only 256 values can be represented this way.
 */
const FREQUENT_MODIFIERS_DESERIALIZATION_MAP = new Map(Array.from(FREQUENT_MODIFIERS_SERIALIZATION_MAP, ([key, value]) => [value, key]));
/**
 * Value map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent frequently used values.
 *
 * ! IMPORTANT: If you change values here, please update the binary schema version
 *
 * @note Only 256 values can be represented this way.
 */
const FREQUENT_REDIRECT_VALUES_SERIALIZATION_MAP = new Map([
    // AdGuard
    ['1x1-transparent.gif', 0],
    ['2x2-transparent.png', 1],
    ['3x2-transparent.png', 2],
    ['32x32-transparent.png', 3],
    ['amazon-apstag', 4],
    ['ati-smarttag', 5],
    ['didomi-loader', 6],
    ['click2load.html', 7],
    ['fingerprintjs2', 8],
    ['fingerprintjs3', 9],
    ['google-analytics', 10],
    ['google-analytics-ga', 11],
    ['googlesyndication-adsbygoogle', 12],
    ['googlesyndication-adsbygoogle', 13],
    ['googletagmanager-gtm', 14],
    ['googletagmanager-gtm', 15],
    ['googletagservices-gpt', 16],
    ['google-ima3', 17],
    ['gemius', 18],
    ['matomo', 19],
    ['metrika-yandex-watch', 20],
    ['metrika-yandex-tag', 21],
    ['naver-wcslog', 22],
    ['noeval', 23],
    ['noopcss', 24],
    ['noopframe', 25],
    ['noopjs', 26],
    ['noopjson', 27],
    ['nooptext', 28],
    ['noopmp3-0.1s', 29],
    ['noopmp4-1s', 30],
    ['noopvmap-1.0', 31],
    ['noopvast-2.0', 32],
    ['noopvast-3.0', 33],
    ['noopvast-4.0', 34],
    ['prebid', 35],
    ['pardot-1.0', 36],
    ['prevent-bab', 37],
    ['prevent-bab2', 38],
    ['prevent-fab-3.2.0', 39],
    ['prevent-fab-3.2.0', 40],
    ['prevent-popads-net', 41],
    ['scorecardresearch-beacon', 42],
    ['set-popads-dummy', 43],
    ['empty', 44],
    ['prebid-ads', 45],
    // empty slots for future use
    // uBlock Origin
    ['1x1.gif', 60],
    ['2x2.png', 61],
    ['3x2.png', 62],
    ['32x32.png', 63],
    ['amazon_apstag.js', 64],
    ['click2load.html', 65],
    ['fingerprint2.js', 66],
    ['fingerprint3.js', 67],
    ['google-analytics_analytics.js', 68],
    ['google-analytics_ga.js', 69],
    ['googlesyndication_adsbygoogle.js', 70],
    ['googlesyndication.com/adsbygoogle.js', 71],
    ['google-analytics_ga.js', 72],
    ['googletagmanager_gtm.js', 73],
    ['googletagservices_gpt.js', 74],
    ['google-ima.js', 75],
    ['noeval-silent.js', 76],
    ['noop.css', 77],
    ['noop.html', 78],
    ['noop.js', 79],
    ['noop.json', 80],
    ['noop.txt', 81],
    ['noop-0.1s.mp3', 82],
    ['noop-1s.mp4', 83],
    ['noop-vmap1.0.xml', 84],
    ['nobab.js', 85],
    ['nobab2.js', 86],
    ['nofab.js', 87],
    ['fuckadblock.js-3.2.0', 88],
    ['popads.js', 89],
    ['scorecardresearch_beacon.js', 90],
    ['popads-dummy.js', 91],
    ['empty', 92],
    ['prebid-ads.js', 93],
    // empty slots for future use
    // Adblock Plus
    ['1x1-transparent-gif', 105],
    ['2x2-transparent-png', 106],
    ['3x2-transparent-png', 107],
    ['32x32-transparent-png', 108],
    ['blank-css', 109],
    ['blank-html', 110],
    ['blank-js', 111],
    ['blank-text', 112],
    ['blank-mp3', 113],
    ['blank-mp4', 114],
    // empty slots for future use
    ['abp-resource:1x1-transparent-gif', 120],
    ['abp-resource:2x2-transparent-png', 121],
    ['abp-resource:3x2-transparent-png', 122],
    ['abp-resource:32x32-transparent-png', 123],
    ['abp-resource:blank-css', 124],
    ['abp-resource:blank-html', 125],
    ['abp-resource:blank-js', 126],
    ['abp-resource:blank-text', 127],
    ['abp-resource:blank-mp3', 128],
    ['abp-resource:blank-mp4', 129],
    // TODO: add other common values
]);
/**
 * Value map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent frequently used values.
 *
 * @note This is a special map which allows us to use different value maps for different modifiers.
 */
const FREQUENT_VALUES_SERIALIZATION_MAPS = new Map([
    ['redirect', FREQUENT_REDIRECT_VALUES_SERIALIZATION_MAP],
    ['redirect-rule', FREQUENT_REDIRECT_VALUES_SERIALIZATION_MAP],
    ['rewrite', FREQUENT_REDIRECT_VALUES_SERIALIZATION_MAP],
    // TODO: Add other modifiers here
]);
/**
 * Value map for binary deserialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent frequently used values.
 */
const FREQUENT_VALUES_DESERIALIZATION_MAPS = new Map(Array.from(FREQUENT_VALUES_SERIALIZATION_MAPS, ([modifier, valueMap]) => [modifier, new Map(Array.from(valueMap, ([key, value]) => [value, key]))]));
/**
 * `ModifierParser` is responsible for parsing modifiers.
 *
 * @example
 * `match-case`, `~third-party`, `domain=example.com|~example.org`
 */
class ModifierParser extends ParserBase {
    /**
     * Parses a modifier.
     *
     * @param raw Raw input to parse.
     * @param options Global parser options.
     * @param baseOffset Starting offset of the input. Node locations are calculated relative to this offset.
     *
     * @returns Parsed modifier
     * @throws An error if modifier name or value is empty.
     */
    static parse(raw, options = defaultParserOptions, baseOffset = 0) {
        let offset = 0;
        // Skip leading whitespace
        offset = StringUtils.skipWS(raw, offset);
        // Save the offset of the first character of the modifier (whole modifier)
        const modifierStart = offset;
        // Check if the modifier is an exception
        let exception = false;
        if (raw[offset] === NEGATION_MARKER) {
            offset += NEGATION_MARKER.length;
            exception = true;
        }
        // Skip whitespace after the exception marker (if any)
        offset = StringUtils.skipWS(raw, offset);
        // Save the offset of the first character of the modifier name
        const modifierNameStart = offset;
        // Find assignment operator
        const assignmentIndex = StringUtils.findNextUnescapedCharacter(raw, MODIFIER_ASSIGN_OPERATOR);
        // Find the end of the modifier
        const modifierEnd = Math.max(StringUtils.skipWSBack(raw) + 1, modifierNameStart);
        // Modifier name can't be empty
        if (modifierNameStart === modifierEnd) {
            throw new AdblockSyntaxError('Modifier name cannot be empty', baseOffset, baseOffset + raw.length);
        }
        let modifier;
        let value;
        // If there is no assignment operator, the whole modifier is the name
        // without a value
        if (assignmentIndex === -1) {
            modifier = ValueParser.parse(raw.slice(modifierNameStart, modifierEnd), options, baseOffset + modifierNameStart);
        }
        else {
            // If there is an assignment operator, first we need to find the
            // end of the modifier name, then we can parse the value
            const modifierNameEnd = StringUtils.skipWSBack(raw, assignmentIndex - 1) + 1;
            modifier = ValueParser.parse(raw.slice(modifierNameStart, modifierNameEnd), options, baseOffset + modifierNameStart);
            // Value can't be empty
            if (assignmentIndex + 1 === modifierEnd) {
                throw new AdblockSyntaxError('Modifier value cannot be empty', baseOffset, baseOffset + raw.length);
            }
            // Skip whitespace after the assignment operator
            const valueStart = StringUtils.skipWS(raw, assignmentIndex + MODIFIER_ASSIGN_OPERATOR.length);
            value = ValueParser.parse(raw.slice(valueStart, modifierEnd), options, baseOffset + valueStart);
        }
        const result = {
            type: 'Modifier',
            name: modifier,
            value,
            exception,
        };
        if (options.isLocIncluded) {
            result.start = baseOffset + modifierStart;
            result.end = baseOffset + modifierEnd;
        }
        return result;
    }
    /**
     * Generates a string from a modifier (serializes it).
     *
     * @param modifier Modifier to generate string from
     * @returns String representation of the modifier
     */
    static generate(modifier) {
        let result = EMPTY;
        if (modifier.exception) {
            result += NEGATION_MARKER;
        }
        result += modifier.name.value;
        if (modifier.value !== undefined) {
            result += MODIFIER_ASSIGN_OPERATOR;
            result += modifier.value.value;
        }
        return result;
    }
    /**
     * Serializes a modifier node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     */
    static serialize(node, buffer) {
        buffer.writeUint8(BinaryTypeMap.ModifierNode);
        buffer.writeUint8(ModifierNodeSerializationMap.Name);
        ValueParser.serialize(node.name, buffer, FREQUENT_MODIFIERS_SERIALIZATION_MAP);
        if (!isUndefined(node.value)) {
            buffer.writeUint8(ModifierNodeSerializationMap.Value);
            ValueParser.serialize(node.value, buffer, FREQUENT_VALUES_SERIALIZATION_MAPS.get(node.name.value));
        }
        buffer.writeUint8(ModifierNodeSerializationMap.Exception);
        buffer.writeUint8(node.exception ? 1 : 0);
        if (!isUndefined(node.start)) {
            buffer.writeUint8(ModifierNodeSerializationMap.Start);
            buffer.writeUint32(node.start);
        }
        if (!isUndefined(node.end)) {
            buffer.writeUint8(ModifierNodeSerializationMap.End);
            buffer.writeUint32(node.end);
        }
        buffer.writeUint8(NULL);
    }
    /**
     * Deserializes a modifier node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     */
    static deserialize(buffer, node) {
        buffer.assertUint8(BinaryTypeMap.ModifierNode);
        node.type = 'Modifier';
        let prop = buffer.readUint8();
        while (prop !== NULL) {
            switch (prop) {
                case ModifierNodeSerializationMap.Name:
                    ValueParser.deserialize(buffer, node.name = {}, FREQUENT_MODIFIERS_DESERIALIZATION_MAP);
                    break;
                case ModifierNodeSerializationMap.Value:
                    if (node.name) {
                        // eslint-disable-next-line max-len
                        ValueParser.deserialize(buffer, node.value = {}, FREQUENT_VALUES_DESERIALIZATION_MAPS.get(node.name.value));
                    }
                    else {
                        ValueParser.deserialize(buffer, node.value = {});
                    }
                    break;
                case ModifierNodeSerializationMap.Exception:
                    node.exception = buffer.readUint8() === 1;
                    break;
                case ModifierNodeSerializationMap.Start:
                    node.start = buffer.readUint32();
                    break;
                case ModifierNodeSerializationMap.End:
                    node.end = buffer.readUint32();
                    break;
                default:
                    throw new Error(`Invalid property: ${prop}.`);
            }
            prop = buffer.readUint8();
        }
    }
}

/* eslint-disable no-param-reassign */
/**
 * Property map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent a property.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 */
var ModifierListNodeSerializationMap;
(function (ModifierListNodeSerializationMap) {
    ModifierListNodeSerializationMap[ModifierListNodeSerializationMap["Children"] = 1] = "Children";
    ModifierListNodeSerializationMap[ModifierListNodeSerializationMap["Start"] = 2] = "Start";
    ModifierListNodeSerializationMap[ModifierListNodeSerializationMap["End"] = 3] = "End";
})(ModifierListNodeSerializationMap || (ModifierListNodeSerializationMap = {}));
/**
 * `ModifierListParser` is responsible for parsing modifier lists. Please note that the name is not
 * uniform, "modifiers" are also known as "options".
 *
 * @see {@link https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#basic-rules-modifiers}
 * @see {@link https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#non-basic-rules-modifiers}
 * @see {@link https://help.eyeo.com/adblockplus/how-to-write-filters#options}
 */
class ModifierListParser extends ParserBase {
    /**
     * Parses the cosmetic rule modifiers, eg. `third-party,domain=example.com|~example.org`.
     *
     * _Note:_ you should remove `$` separator before passing the raw modifiers to this function,
     *  or it will be parsed in the first modifier.
     *
     * @param raw Raw input to parse.
     * @param options Global parser options.
     * @param baseOffset Starting offset of the input. Node locations are calculated relative to this offset.
     * @returns Parsed modifiers interface
     */
    static parse(raw, options = defaultParserOptions, baseOffset = 0) {
        const result = {
            type: 'ModifierList',
            children: [],
        };
        if (options.isLocIncluded) {
            result.start = baseOffset;
            result.end = baseOffset + raw.length;
        }
        let offset = StringUtils.skipWS(raw);
        let separatorIndex = -1;
        // Split modifiers by unescaped commas
        while (offset < raw.length) {
            // Skip whitespace before the modifier
            offset = StringUtils.skipWS(raw, offset);
            const modifierStart = offset;
            // Find the index of the first unescaped comma
            separatorIndex = StringUtils.findNextUnescapedCharacter(raw, MODIFIERS_SEPARATOR, offset);
            const modifierEnd = separatorIndex === -1
                ? raw.length
                : StringUtils.skipWSBack(raw, separatorIndex - 1) + 1;
            // Parse the modifier
            const modifier = ModifierParser.parse(raw.slice(modifierStart, modifierEnd), options, baseOffset + modifierStart);
            result.children.push(modifier);
            // Increment the offset to the next modifier (or the end of the string)
            offset = separatorIndex === -1 ? raw.length : separatorIndex + 1;
        }
        // Check if there are any modifiers after the last separator
        if (separatorIndex !== -1) {
            const modifierStart = StringUtils.skipWS(raw, separatorIndex + 1);
            result.children.push(ModifierParser.parse(raw.slice(modifierStart, raw.length), options, baseOffset + modifierStart));
        }
        return result;
    }
    /**
     * Converts a modifier list AST to a string.
     *
     * @param ast Modifier list AST
     * @returns Raw string
     */
    static generate(ast) {
        const result = ast.children
            .map(ModifierParser.generate)
            .join(MODIFIERS_SEPARATOR);
        return result;
    }
    /**
     * Serializes a modifier list node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     */
    static serialize(node, buffer) {
        buffer.writeUint8(BinaryTypeMap.ModifierListNode);
        const count = node.children.length;
        if (count) {
            buffer.writeUint8(ModifierListNodeSerializationMap.Children);
            // note: we store the count, because re-construction of the array is faster if we know the length
            if (count > UINT16_MAX) {
                throw new Error(`Too many modifiers: ${count}, the limit is ${UINT16_MAX}`);
            }
            buffer.writeUint16(count);
            for (let i = 0; i < count; i += 1) {
                ModifierParser.serialize(node.children[i], buffer);
            }
        }
        if (!isUndefined(node.start)) {
            buffer.writeUint8(ModifierListNodeSerializationMap.Start);
            buffer.writeUint32(node.start);
        }
        if (!isUndefined(node.end)) {
            buffer.writeUint8(ModifierListNodeSerializationMap.End);
            buffer.writeUint32(node.end);
        }
        buffer.writeUint8(NULL);
    }
    /**
     * Deserializes a modifier list node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     */
    static deserialize(buffer, node) {
        buffer.assertUint8(BinaryTypeMap.ModifierListNode);
        node.type = 'ModifierList';
        let prop = buffer.readUint8();
        while (prop !== NULL) {
            switch (prop) {
                case ModifierListNodeSerializationMap.Children:
                    node.children = new Array(buffer.readUint16());
                    // read children
                    for (let i = 0; i < node.children.length; i += 1) {
                        ModifierParser.deserialize(buffer, node.children[i] = {});
                    }
                    break;
                case ModifierListNodeSerializationMap.Start:
                    node.start = buffer.readUint32();
                    break;
                case ModifierListNodeSerializationMap.End:
                    node.end = buffer.readUint32();
                    break;
                default:
                    throw new Error(`Invalid property: ${prop}.`);
            }
            prop = buffer.readUint8();
        }
    }
}

/**
 * @file Error messages for CSS token stream and balancer.
 */
const END_OF_INPUT = 'end of input';
const ERROR_MESSAGES$6 = {
    EXPECTED_ANY_TOKEN_BUT_GOT: "Expected a token, but got '%s'",
    EXPECTED_TOKEN_BUT_GOT: "Expected '%s', but got '%s'",
    EXPECTED_TOKEN_WITH_BALANCE_BUT_GOT: "Expected '%s' with balance '%d', but got '%d'",
    EXPECTED_TOKEN_WITH_VALUE_BUT_GOT: "Expected '%s' with value '%s', but got '%s'",
};

/**
 * @file Tokenizer helpers for balanced pairs.
 */
/**
 * Map of opening tokens to their corresponding closing tokens.
 */
const standardTokenPairs = new Map([
    [csstokenizer/* TokenType.Function */.iv.Function, csstokenizer/* TokenType.CloseParenthesis */.iv.CloseParenthesis],
    [csstokenizer/* TokenType.OpenParenthesis */.iv.OpenParenthesis, csstokenizer/* TokenType.CloseParenthesis */.iv.CloseParenthesis],
    [csstokenizer/* TokenType.OpenSquareBracket */.iv.OpenSquareBracket, csstokenizer/* TokenType.CloseSquareBracket */.iv.CloseSquareBracket],
    [csstokenizer/* TokenType.OpenCurlyBracket */.iv.OpenCurlyBracket, csstokenizer/* TokenType.CloseCurlyBracket */.iv.CloseCurlyBracket],
]);
/**
 * Map of opening tokens to their corresponding closing tokens just for function calls. This makes possible a more
 * lightweight and tolerant check for balanced pairs in some cases.
 */
const functionTokenPairs = new Map([
    [csstokenizer/* TokenType.Function */.iv.Function, csstokenizer/* TokenType.CloseParenthesis */.iv.CloseParenthesis],
    [csstokenizer/* TokenType.OpenParenthesis */.iv.OpenParenthesis, csstokenizer/* TokenType.CloseParenthesis */.iv.CloseParenthesis],
]);
/**
 * Helper function to tokenize and ensure balanced pairs.
 *
 * @param raw Raw CSS string to tokenize
 * @param onToken Callback which will be invoked for each token, extended with a `balance` parameter
 * @param onError Error callback which is called when a parsing error is found (optional)
 * @param functionHandlers Custom function handlers (optional)
 * @param tokenPairs Map of opening tokens to their corresponding closing tokens
 * @throws If the input is not balanced
 * @todo Consider adding a `tolerant` flag if error throwing seems too aggressive in the future
 */
const tokenizeWithBalancedPairs = (raw, onToken, onError = () => { }, functionHandlers, tokenPairs = standardTokenPairs) => {
    const stack = [];
    const values = new Set(tokenPairs.values());
    (0,csstokenizer/* tokenizeExtended */.lL)(raw, (type, start, end, props) => {
        if (tokenPairs.has(type)) {
            // If the token is an opening token, push its corresponding closing token to the stack.
            // It is safe to use non-null assertion here, because we have checked that the token exists in the map.
            // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
            stack.push(tokenPairs.get(type));
        }
        else if (values.has(type)) {
            // If the token is a closing token, check if it matches the last opening token, and if so, pop it.
            if (stack[stack.length - 1] === type) {
                stack.pop();
            }
            else {
                throw new AdblockSyntaxError((0,sprintf.sprintf)(ERROR_MESSAGES$6.EXPECTED_TOKEN_BUT_GOT, (0,csstokenizer/* getFormattedTokenName */.PE)(stack[stack.length - 1]), (0,csstokenizer/* getFormattedTokenName */.PE)(type)), start, raw.length);
            }
        }
        onToken(type, start, end, props, stack.length);
    }, onError, functionHandlers);
    // If the stack is not empty, then there are some opening tokens that were not closed.
    if (stack.length > 0) {
        throw new AdblockSyntaxError((0,sprintf.sprintf)(ERROR_MESSAGES$6.EXPECTED_TOKEN_BUT_GOT, (0,csstokenizer/* getFormattedTokenName */.PE)(stack[stack.length - 1]), END_OF_INPUT), raw.length - 1, raw.length);
    }
};
/**
 * Tokenize and ensure balanced pairs for standard CSS.
 *
 * @param raw Raw CSS string to tokenize
 * @param onToken Callback which will be invoked for each token, extended with a `balance` parameter
 * @param onError Error callback which is called when a parsing error is found (optional)
 * @param functionHandlers Custom function handlers (optional)
 * @throws If the input is not balanced
 */
const tokenizeBalanced = (raw, onToken, onError = () => { }, functionHandlers) => {
    tokenizeWithBalancedPairs(raw, onToken, onError, functionHandlers);
};
/**
 * Tokenize and ensure balanced pairs for function calls.
 *
 * @param raw Raw CSS string to tokenize
 * @param onToken Callback which will be invoked for each token, extended with a `balance` parameter
 * @param onError Error callback which is called when a parsing error is found (optional)
 * @param functionHandlers Custom function handlers (optional)
 * @throws If the input is not balanced
 */
const tokenizeFnBalanced = (raw, onToken, onError = () => { }, functionHandlers) => {
    tokenizeWithBalancedPairs(raw, onToken, onError, functionHandlers, functionTokenPairs);
};

/**
 * @file Parser for special uBO selectors.
 */
/**
 * Possible error messages for uBO selectors. Formatted with {@link sprintf}.
 */
const ERROR_MESSAGES$5 = {
    DUPLICATED_UBO_MODIFIER: "uBO modifier '%s' cannot be used more than once",
    EXPECTED_BUT_GOT_BEFORE: "Expected '%s' but got '%s' before '%s'",
    // eslint-disable-next-line max-len
    NEGATED_UBO_MODIFIER_CANNOT_BE_FOLLOWED_BY: "Negated uBO modifier '%s' cannot be followed by anything else than a closing parenthesis or a whitespace",
    NEGATED_UBO_MODIFIER_CANNOT_BE_PRECEDED_BY: "Negated uBO modifier '%s' cannot be preceded by '%s'",
    PSEUDO_CANNOT_BE_NESTED: "uBO modifier '%s' cannot be nested inside '%s', only '%s' is allowed as a wrapper",
    UBO_MODIFIER_CANNOT_BE_NESTED: "uBO modifier '%s' cannot be nested",
    UBO_STYLE_CANNOT_BE_FOLLOWED: 'uBO style injection cannot be followed by anything else than a whitespace',
};
/**
 * Dummy parameter for uBO modifiers in error messages.
 */
const DUMMY_PARAM = '...';
/**
 * Known uBO modifiers.
 */
var UboPseudoName;
(function (UboPseudoName) {
    UboPseudoName["MatchesMedia"] = "matches-media";
    UboPseudoName["MatchesPath"] = "matches-path";
    UboPseudoName["Remove"] = "remove";
    UboPseudoName["Style"] = "style";
})(UboPseudoName || (UboPseudoName = {}));
/**
 * Set of known uBO modifiers.
 *
 * @note We use `string` instead of `UboPseudoName` because we use this set for checking if a modifier is a known uBO,
 * and an unknown sequence is just a string.
 */
const KNOWN_UBO_MODIFIERS = new Set([
    UboPseudoName.MatchesMedia,
    UboPseudoName.MatchesPath,
    UboPseudoName.Remove,
    UboPseudoName.Style,
]);
/**
 * Helper function to check if the given selector has any uBO modifier. This function should be fast, because it's used
 * in the hot path of the parser.
 *
 * @param raw Raw selector string.
 * @returns `true` if the selector has any uBO modifier, `false` otherwise.
 */
const hasAnyUboModifier = (raw) => {
    // Find the first colon
    let colonIndex = raw.indexOf(COLON);
    while (colonIndex !== -1) {
        // Find next opening parenthesis
        const openingParenthesisIndex = raw.indexOf(OPEN_PARENTHESIS, colonIndex + 1);
        // If there is no opening parenthesis, then the selector doesn't contain any uBO modifier
        if (openingParenthesisIndex === -1) {
            return false;
        }
        // Check if the modifier is a known uBO modifier
        if (KNOWN_UBO_MODIFIERS.has(raw.slice(colonIndex + 1, openingParenthesisIndex))) {
            return true;
        }
        // Find next colon
        colonIndex = raw.indexOf(COLON, openingParenthesisIndex + 1);
    }
    return false;
};
/**
 * A simple helper function to format a pseudo name for error messages.
 *
 * @param name Pseudo name.
 * @param wrapper Wrapper pseudo name (eg. `not`) (optional, defaults to `undefined`).
 * @returns Formatted pseudo name.
 * @example
 * ```ts
 * formatPseudoName('matches-path', 'not'); // => ':not(:matches-path(...))'
 * formatPseudoName('matches-media'); // => ':matches-media(...)'
 * ```
 */
const formatPseudoName = (name, wrapper) => {
    const result = [];
    if (wrapper) {
        result.push(COLON, wrapper, OPEN_PARENTHESIS);
    }
    result.push(COLON, name, OPEN_PARENTHESIS, DUMMY_PARAM, CLOSE_PARENTHESIS);
    if (wrapper) {
        result.push(CLOSE_PARENTHESIS);
    }
    return result.join(EMPTY);
};
/**
 * Parser for uBO selectors.
 */
class UboSelectorParser extends ParserBase {
    /**
     * Parses a uBO selector list, eg. `div:matches-path(/path)`.
     *
     * @param raw Raw input to parse.
     * @param options Global parser options.
     * @param baseOffset Starting offset of the input. Node locations are calculated relative to this offset.
     *
     * @returns Parsed uBO selector {@link UboSelector}.
     * @throws An {@link AdblockSyntaxError} if the selector list is syntactically invalid.
     */
    static parse(raw, options = defaultParserOptions, baseOffset = 0) {
        // Prepare helper variables
        const modifiers = {
            type: 'ModifierList',
            children: [],
        };
        if (options.isLocIncluded) {
            modifiers.start = baseOffset;
            modifiers.end = baseOffset + raw.length;
        }
        // Do not perform any parsing if the selector doesn't contain any uBO modifier
        // Parsing is a relatively expensive operation, but this check is cheap, so we can avoid unnecessary work
        // TODO: Move this check to the cosmetic parser (adjustable syntaxes - if uBO syntax is disabled, then we don't
        // need to check for uBO modifiers)
        if (!hasAnyUboModifier(raw)) {
            const selector = {
                type: 'Value',
                value: raw,
            };
            if (options.isLocIncluded) {
                selector.start = baseOffset;
                selector.end = baseOffset + raw.length;
            }
            const result = {
                type: 'UboSelector',
                selector,
                modifiers,
            };
            if (options.isLocIncluded) {
                result.start = baseOffset;
                result.end = baseOffset + raw.length;
            }
            return result;
        }
        // Simple way to check if a modifier is already processed to avoid duplicate modifiers
        const processedModifiers = new Set();
        // We need to keep track of the tokens for handling negations properly
        const tokens = [];
        // This array is used to mark the character slots in the selector string that are occupied by uBO modifiers
        const uboIndexes = new Array(raw.length);
        const uboModifierStack = [];
        let i = 0;
        // Helper function to stack a uBO modifier
        const stackModifier = (modifier) => {
            if (processedModifiers.has(modifier.name)) {
                throw new AdblockSyntaxError((0,sprintf.sprintf)(ERROR_MESSAGES$5.DUPLICATED_UBO_MODIFIER, formatPseudoName(modifier.name)), baseOffset + modifier.modifierStart, baseOffset + raw.length);
            }
            uboModifierStack.push(modifier);
        };
        // Tokenize the selector, calculate the balance
        tokenizeFnBalanced(raw, (type, start, end, _, balance) => {
            // Special case: style injection (`:style(...)` and `:remove()`) can only be used at the end of the
            // selector, like
            //  - `div:style(...)`,
            //  - `div:matches-media(...):style(...)`,
            //  - `div:remove()`,
            // etc.
            //
            // But not like
            //  - `:style(...) div`,
            //  - `:matches-media(...):style(...) div`,
            //  - `:remove() div`,
            // etc.
            //
            // The one exception is whitespace, which is allowed after style injection, like
            //  - `div:style(...) `,
            //  - `div:matches-media(...):style(...) `,
            //  - `div:remove() `,
            // etc.
            if ((processedModifiers.has(UboPseudoName.Style)
                || processedModifiers.has(UboPseudoName.Remove))
                && type !== csstokenizer/* TokenType.Whitespace */.iv.Whitespace) {
                throw new AdblockSyntaxError(ERROR_MESSAGES$5.UBO_STYLE_CANNOT_BE_FOLLOWED, baseOffset + start, baseOffset + raw.length);
            }
            // Check for pseudo classes (colon followed by a function)
            if (tokens[i - 1]?.type === csstokenizer/* TokenType.Colon */.iv.Colon && type === csstokenizer/* TokenType.Function */.iv.Function) {
                // Since closing parenthesis is always included in the function token, but we only need the function
                // name, we need to cut off the last character, this is why we use `end - 1` here
                const fn = raw.slice(start, end - 1);
                // Check if the pseudo class is a known uBO modifier
                if (KNOWN_UBO_MODIFIERS.has(fn)) {
                    // Generally, uBO modifiers cannot be nested, like
                    //  - `:any(:matches-media(...))`,
                    //  - `:matches-media(:matches-media(...))`,
                    //  - `:not(style(...))`,
                    //  etc.
                    if (balance > 1) {
                        // However, we have one exception: `:matches-path()` can be nested inside `:not()`s, like:
                        //  - `:not(:matches-path(...))`,
                        //  - `:not(:not(:matches-path(...)))`,
                        //  etc.
                        //
                        // But it can't be nested inside any other pseudo class, like:
                        //  - `:anything(:matches-path(...))`,
                        //  etc.
                        //
                        // Moreover, :not() can't contain any other data, like
                        //  - `:not(div:matches-path(...))`,
                        //  - `:not(:matches-path(...):matches-path(...))`,
                        //  - `:not(:matches-path(...) div)`,
                        // etc.
                        if (fn === UboPseudoName.MatchesPath) {
                            if (uboModifierStack.length > 0) {
                                throw new AdblockSyntaxError((0,sprintf.sprintf)(ERROR_MESSAGES$5.PSEUDO_CANNOT_BE_NESTED, formatPseudoName(UboPseudoName.MatchesPath), formatPseudoName(uboModifierStack[uboModifierStack.length - 1].name), formatPseudoName(CSS_NOT_PSEUDO)), baseOffset + start - 1, baseOffset + raw.length);
                            }
                            let isException = false;
                            let modifierBalance = balance;
                            let modifierStart = start;
                            for (let j = i - 1; j >= 0; j -= 1) {
                                // If we have reached the root level, then we should check if the `not` function is
                                // preceded by a colon (which means that it's a pseudo class)
                                if (tokens[j].balance === 0) {
                                    modifierStart = tokens[j].start;
                                    modifierBalance = tokens[j].balance;
                                    break;
                                }
                                else if (tokens[j].type === csstokenizer/* TokenType.Colon */.iv.Colon
                                    || tokens[j].type === csstokenizer/* TokenType.Whitespace */.iv.Whitespace) {
                                    continue;
                                }
                                else if (tokens[j].type === csstokenizer/* TokenType.Function */.iv.Function) {
                                    const wrapperFnName = raw.slice(tokens[j].start, tokens[j].end - 1);
                                    if (wrapperFnName !== CSS_NOT_PSEUDO) {
                                        throw new AdblockSyntaxError((0,sprintf.sprintf)(ERROR_MESSAGES$5.PSEUDO_CANNOT_BE_NESTED, formatPseudoName(UboPseudoName.MatchesPath), formatPseudoName(wrapperFnName), formatPseudoName(CSS_NOT_PSEUDO)), baseOffset + tokens[j].start - 1, baseOffset + raw.length);
                                    }
                                    if (tokens[j - 1]?.type !== csstokenizer/* TokenType.Colon */.iv.Colon) {
                                        const got = tokens[j - 1]?.type
                                            ? (0,csstokenizer/* getFormattedTokenName */.PE)(tokens[j - 1]?.type)
                                            : 'nothing';
                                        throw new AdblockSyntaxError((0,sprintf.sprintf)(ERROR_MESSAGES$5.EXPECTED_BUT_GOT_BEFORE, (0,csstokenizer/* getFormattedTokenName */.PE)(csstokenizer/* TokenType.Colon */.iv.Colon), got, formatPseudoName(UboPseudoName.MatchesPath, CSS_NOT_PSEUDO)), 
                                        // eslint-disable-next-line no-unsafe-optional-chaining
                                        baseOffset + tokens[j - 1]?.start || 0, baseOffset + raw.length);
                                    }
                                    isException = !isException;
                                    continue;
                                }
                                else {
                                    throw new AdblockSyntaxError((0,sprintf.sprintf)(ERROR_MESSAGES$5.NEGATED_UBO_MODIFIER_CANNOT_BE_PRECEDED_BY, formatPseudoName(UboPseudoName.MatchesPath), (0,csstokenizer/* getFormattedTokenName */.PE)(tokens[j].type)), baseOffset + tokens[j].start, baseOffset + raw.length);
                                }
                            }
                            stackModifier({
                                name: fn,
                                modifierStart,
                                modifierBalance,
                                nameStart: start,
                                nameEnd: end - 1, // ignore opening parenthesis
                                valueStart: end,
                                valueBalance: balance,
                                isException,
                            });
                        }
                        else {
                            throw new AdblockSyntaxError((0,sprintf.sprintf)(ERROR_MESSAGES$5.UBO_MODIFIER_CANNOT_BE_NESTED, formatPseudoName(fn)), baseOffset + start - 1, baseOffset + raw.length);
                        }
                    }
                    else {
                        stackModifier({
                            name: fn,
                            modifierStart: start - 1, // Include the colon
                            modifierBalance: balance,
                            nameStart: start,
                            nameEnd: end - 1, // ignore opening parenthesis
                            valueStart: end,
                            valueBalance: balance,
                            isException: false,
                        });
                    }
                }
            }
            else {
                // Get the last stacked modifier
                const lastStackedModifier = uboModifierStack[uboModifierStack.length - 1];
                // Do not allow any other token after `:matches-path(...)` inside `:not(...)`
                if (lastStackedModifier?.name === UboPseudoName.MatchesPath && lastStackedModifier?.isException) {
                    if (!(type === csstokenizer/* TokenType.CloseParenthesis */.iv.CloseParenthesis || type === csstokenizer/* TokenType.Whitespace */.iv.Whitespace)
                        && balance < lastStackedModifier.valueBalance) {
                        throw new AdblockSyntaxError((0,sprintf.sprintf)(ERROR_MESSAGES$5.NEGATED_UBO_MODIFIER_CANNOT_BE_FOLLOWED_BY, formatPseudoName(UboPseudoName.MatchesPath), (0,csstokenizer/* getFormattedTokenName */.PE)(type)), baseOffset + start, baseOffset + raw.length);
                    }
                }
                // If we have reached a closing parenthesis, then we should check if it closes the last stacked modifier
                // and if so, pop it from the stack
                if (type === csstokenizer/* TokenType.CloseParenthesis */.iv.CloseParenthesis && lastStackedModifier) {
                    if (balance === Math.max(0, lastStackedModifier.valueBalance - 1)) {
                        lastStackedModifier.valueEnd = start;
                    }
                    if (balance === Math.max(0, lastStackedModifier.modifierBalance - 1)) {
                        const modifierName = {
                            type: 'Value',
                            value: lastStackedModifier.name,
                        };
                        if (options.isLocIncluded) {
                            // TODO: Refactor
                            modifierName.start = baseOffset + lastStackedModifier.nameStart;
                            modifierName.end = baseOffset + lastStackedModifier.nameEnd;
                        }
                        const value = {
                            type: 'Value',
                            value: raw.slice(lastStackedModifier.valueStart, lastStackedModifier.valueEnd),
                        };
                        if (options.isLocIncluded) {
                            value.start = baseOffset + lastStackedModifier.valueStart;
                            // It's safe to use `!` here, because we determined the value end index in the
                            // previous `if` statement
                            // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
                            value.end = baseOffset + lastStackedModifier.valueEnd;
                        }
                        const modifier = {
                            type: 'Modifier',
                            name: modifierName,
                            value,
                            exception: lastStackedModifier.isException,
                        };
                        if (options.isLocIncluded) {
                            modifier.start = baseOffset + lastStackedModifier.modifierStart;
                            modifier.end = baseOffset + end;
                        }
                        modifiers.children.push(modifier);
                        processedModifiers.add(lastStackedModifier.name);
                        uboModifierStack.pop();
                        // Mark the character slots in the selector string that are occupied by uBO modifiers
                        uboIndexes.fill(true, lastStackedModifier.modifierStart, end);
                    }
                }
            }
            // Save the token to the history and increase the index
            tokens.push({
                type,
                start,
                end,
                balance,
            });
            i += 1;
        });
        const selector = {
            type: 'Value',
            value: raw
                .split(EMPTY)
                .map((char, p) => (uboIndexes[p] ? EMPTY : char))
                .join(EMPTY)
                .trim(),
        };
        if (options.isLocIncluded) {
            selector.start = baseOffset;
            selector.end = baseOffset + raw.length;
        }
        const result = {
            type: 'UboSelector',
            selector,
            modifiers,
        };
        if (options.isLocIncluded) {
            result.start = baseOffset;
            result.end = baseOffset + raw.length;
        }
        return result;
    }
    /**
     * Serializes a uBO selector node to a string.
     *
     * @param node UBO selector node
     * @returns Raw string
     */
    static generate(node) {
        const prefix = []; // List of leading modifiers
        const suffix = []; // List of trailing modifiers, typically style injection
        if (node.modifiers) {
            for (const modifier of node.modifiers.children) {
                switch (modifier.name.value) {
                    case UboPseudoName.Remove:
                    case UboPseudoName.Style:
                        // eslint-disable-next-line max-len
                        suffix.push(COLON, modifier.name.value, OPEN_PARENTHESIS, modifier.value?.value || EMPTY, CLOSE_PARENTHESIS);
                        break;
                    default:
                        // Wrap exceptions in `:not()`
                        if (modifier.exception) {
                            prefix.push(COLON, CSS_NOT_PSEUDO, OPEN_PARENTHESIS);
                        }
                        // :modifier-name(value)
                        // eslint-disable-next-line max-len
                        prefix.push(COLON, modifier.name.value, OPEN_PARENTHESIS, modifier.value?.value || EMPTY, CLOSE_PARENTHESIS);
                        // Close the `:not()` if we are in an exception
                        if (modifier.exception) {
                            prefix.push(CLOSE_PARENTHESIS);
                        }
                        break;
                }
            }
        }
        // Prepare the result
        let result = EMPTY;
        if (prefix.length > 0) {
            result += prefix.join(EMPTY);
            // Add a space between the selector and the leading modifier(s)
            if (node.selector?.value) {
                result += SPACE;
            }
        }
        result += node.selector?.value || EMPTY;
        result += suffix.join(EMPTY);
        return result;
    }
}

/**
 * @file Known CSS elements and attributes.
 * TODO: Implement a compatibility table for Extended CSS
 */
/**
 * Legacy Extended CSS attribute prefix.
 *
 * @example
 * ```css
 * [-ext-<name>=...]
 * ```
 */
const LEGACY_EXT_CSS_ATTRIBUTE_PREFIX = '-ext-';
/**
 * ABP Extended CSS prefix.
 *
 * @example
 * ```css
 * [-abp-<name>=...]
 * -abp-<name>(...)
 * ```
 */
const ABP_EXT_CSS_PREFIX = '-abp';
/**
 * Known _strict_ Extended CSS pseudo-classes. Please, keep this list sorted.
 * Strict means that these pseudo-classes are not supported by any browser natively,
 * and they always require Extended CSS libraries to work.
 */
const EXT_CSS_PSEUDO_CLASSES_STRICT = new Set([
    // AdGuard
    // https://github.com/AdguardTeam/ExtendedCss
    'contains',
    'if-not',
    'matches-attr',
    'matches-css',
    'matches-property',
    'nth-ancestor',
    'remove',
    'upward',
    'xpath',
    // uBlock Origin
    // https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#procedural-cosmetic-filters
    'has-text',
    'matches-css-after',
    'matches-css-before',
    'matches-path',
    'min-text-length',
    'watch-attr',
    // Adblock Plus
    // https://help.eyeo.com/adblockplus/how-to-write-filters#elemhide-emulation
    '-abp-contains',
    '-abp-has',
    '-abp-properties',
]);
/**
 * _ALL_ known Extended CSS pseudo-classes. Please, keep this list sorted.
 * It includes strict pseudo-classes and additional pseudo-classes that may be
 * supported by some browsers natively.
 */
const EXT_CSS_PSEUDO_CLASSES = new Set([
    ...EXT_CSS_PSEUDO_CLASSES_STRICT,
    /**
     * https://developer.mozilla.org/en-US/docs/Web/CSS/:has
     */
    'has',
    /**
     * https://developer.mozilla.org/en-US/docs/Web/CSS/:is
     */
    'is',
]);
/**
 * Known legacy Extended CSS attributes. These attributes are deprecated and
 * should be replaced with the corresponding pseudo-classes. In a long term,
 * these attributes will be COMPLETELY removed from the Extended CSS syntax.
 *
 * Please, keep this list sorted.
 */
const EXT_CSS_LEGACY_ATTRIBUTES = new Set([
    // AdGuard
    '-ext-contains',
    '-ext-has',
    '-ext-if-not',
    '-ext-is',
    '-ext-matches-attr',
    '-ext-matches-css',
    '-ext-matches-property',
    '-ext-nth-ancestor',
    '-ext-remove',
    '-ext-upward',
    '-ext-xpath',
    // uBlock Origin
    '-ext-has-text',
    '-ext-matches-css-after',
    '-ext-matches-css-before',
    '-ext-matches-path',
    '-ext-min-text-length',
    '-ext-watch-attr',
    // Adblock Plus
    '-ext-abp-contains',
    '-ext-abp-has',
    '-ext-abp-properties',
]);
/**
 * Known CSS functions that aren't allowed in CSS injection rules, because they
 * able to load external resources. Please, keep this list sorted.
 */
const FORBIDDEN_CSS_FUNCTIONS = new Set([
    // https://developer.mozilla.org/en-US/docs/Web/CSS/cross-fade
    '-webkit-cross-fade',
    'cross-fade',
    // https://developer.mozilla.org/en-US/docs/Web/CSS/image
    'image',
    // https://developer.mozilla.org/en-US/docs/Web/CSS/image-set
    '-webkit-image-set',
    'image-set',
    // https://developer.mozilla.org/en-US/docs/Web/CSS/url
    'url',
]);

/**
 * @file CSS token stream.
 */
/**
 * Represents a stream of CSS tokens.
 */
class CssTokenStream {
    /**
     * The tokens in the stream.
     */
    tokens = [];
    /**
     * The source string.
     */
    source = EMPTY;
    /**
     * The current index in the stream.
     */
    index = 0;
    /**
     * The base offset of the source string.
     */
    baseOffset;
    /**
     * Initializes a new instance of the TokenStream class.
     *
     * @param source The source string to tokenize.
     * @param baseOffset The base offset of the source string.
     */
    constructor(source, baseOffset = 0) {
        this.source = source;
        // Tokenize the source string with the CSS tokenizer and add balance level to each token.
        // 'onToken' callback is invoked when a token is found in the source string.
        // Passed parameters:
        // - type: type of the token
        // - start: start index of the token
        // - end: end index of the token
        // - props: additional properties of the token, if any (we don't use it here, this is why we use underscore)
        // - balance: balance level of the token
        tokenizeBalanced(source, (type, start, end, _, balance) => {
            this.tokens.push({
                type,
                start,
                end,
                balance,
            });
        });
        this.index = 0;
        this.baseOffset = baseOffset;
    }
    /**
     * Gets the number of tokens in the stream.
     *
     * @returns The number of tokens in the stream.
     */
    get length() {
        return this.tokens.length;
    }
    /**
     * Checks if the end of the token stream is reached.
     *
     * @returns True if the end of the stream is reached, otherwise false.
     */
    isEof() {
        return this.index >= this.tokens.length;
    }
    /**
     * Gets the token at the specified index.
     *
     * @param index The index of the token to retrieve.
     * @returns The token at the specified index or undefined if the index is out of bounds.
     */
    get(index = this.index) {
        return this.tokens[index];
    }
    /**
     * Gets the token at the specified index or throws if no token is found at the specified index.
     *
     * @param index The index of the token to retrieve.
     * @returns The token at the specified index or undefined if the index is out of bounds.
     * @throws If no token is found at the specified index.
     */
    getOrFail(index = this.index) {
        const token = this.get(index);
        if (!token) {
            throw new AdblockSyntaxError((0,sprintf.sprintf)(ERROR_MESSAGES$6.EXPECTED_ANY_TOKEN_BUT_GOT, END_OF_INPUT), this.baseOffset + this.source.length - 1, this.baseOffset + this.source.length);
        }
        return token;
    }
    /**
     * Gets the source fragment of the token at the specified index.
     *
     * @param index The index of the token to retrieve the fragment for.
     * @returns The source fragment of the token or an empty string if the index is out of bounds.
     */
    fragment(index = this.index) {
        const token = this.get(index);
        if (token) {
            return this.source.slice(token.start, token.end);
        }
        return EMPTY;
    }
    /**
     * Moves the index to the next token and returns it.
     *
     * @returns The next token or undefined if the end of the stream is reached.
     */
    advance() {
        if (this.isEof()) {
            return undefined;
        }
        this.index += 1;
        return this.tokens[this.index];
    }
    /**
     * Looks ahead in the stream without changing the index.
     *
     * @param index The relative index to look ahead to, starting from the current index.
     * @returns The next token or undefined if the end of the stream is reached.
     */
    lookahead(index = 1) {
        return this.tokens[this.index + Math.max(1, index)];
    }
    /**
     * Looks behind in the stream without changing the index.
     *
     * @param index The relative index to look behind to, starting from the current index.
     * @returns The previous token or undefined if the current token is the first in the stream.
     */
    lookbehind(index = 1) {
        if (this.index === 0) {
            return undefined;
        }
        return this.tokens[this.index - Math.max(1, index)];
    }
    /**
     * Looks behind in the stream for the previous non-whitespace token without changing the index.
     *
     * @returns The previous non-whitespace token or undefined if it could not be found.
     */
    lookbehindForNonWs() {
        for (let i = this.index - 1; i >= 0; i -= 1) {
            if (this.tokens[i].type !== csstokenizer/* TokenType.Whitespace */.iv.Whitespace) {
                return this.tokens[i];
            }
        }
        return undefined;
    }
    /**
     * Skips whitespace tokens in the stream.
     */
    skipWhitespace() {
        while (this.get()?.type === csstokenizer/* TokenType.Whitespace */.iv.Whitespace) {
            this.index += 1;
        }
    }
    /**
     * Skips tokens until the current balance level is reached.
     *
     * @returns The number of tokens skipped.
     */
    skipUntilBalanced() {
        if (this.isEof()) {
            return 0;
        }
        // It is safe to use ! here, because we check for EOF above
        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
        const currentBalance = this.get().balance;
        // If the current balance is 0, do nothing
        if (currentBalance === 0) {
            return 0;
        }
        // Otherwise, skip tokens until the balance is the current balance - 1
        let skipped = 0;
        while (!this.isEof() && this.get()?.balance !== currentBalance - 1) {
            this.index += 1;
            skipped += 1;
        }
        return skipped;
    }
    /**
     * Skips tokens until a token with the specified type or the end of the stream is reached.
     *
     * @param type The type of token to skip until.
     * @param balance The balance level of the token to skip until.
     * @returns The number of tokens skipped.
     */
    skipUntil(type, balance) {
        let skipped = 0;
        while (!this.isEof()
            && (this.get()?.type !== type || (balance !== undefined && this.get()?.balance !== balance))) {
            this.index += 1;
            skipped += 1;
        }
        return skipped;
    }
    /**
     * Skips tokens until a token with the specified type or the end of the stream is reached. This is an extended
     * version of skipUntil that also returns the number of tokens skipped without calculating leading and trailing
     * whitespace tokens.
     *
     * @param type The type of token to skip until.
     * @param balance The balance level of the token to skip until.
     * @returns An array containing the number of tokens skipped and the number of tokens skipped without leading and
     * trailing whitespace tokens.
     */
    skipUntilExt(type, balance) {
        let i = this.index;
        let firstNonWsToken = -1; // -1 means no non-whitespace token found yet
        let lastNonWsToken = -1; // -1 means no non-whitespace token found yet
        while (i < this.tokens.length) {
            const currentToken = this.tokens[i];
            if (currentToken.type === csstokenizer/* TokenType.Whitespace */.iv.Whitespace) {
                i += 1;
                continue;
            }
            else if (currentToken.type === type && currentToken.balance === balance) {
                break;
            }
            if (firstNonWsToken === -1) {
                firstNonWsToken = i;
            }
            lastNonWsToken = i;
            i += 1;
        }
        const skipped = i - this.index;
        this.index = i;
        return {
            skipped,
            // if firstNonWsToken is -1, then lastNonWsToken is also -1
            skippedTrimmed: firstNonWsToken === -1 ? 0 : lastNonWsToken - firstNonWsToken + 1,
        };
    }
    /**
     * Expects that the end of the stream is not reached.
     */
    expectNotEof() {
        if (this.isEof()) {
            throw new AdblockSyntaxError('Unexpected end of input', this.baseOffset + this.source.length - 1, this.baseOffset + this.source.length);
        }
    }
    /**
     * Expects the current token to have a specific type and optional value and balance level.
     *
     * @param type The expected token type.
     * @param data Optional expectation data.
     * @throws If the end of the stream is reached or if the token type or expectation data does not match.
     */
    expect(type, data) {
        const token = this.get();
        if (!token) {
            throw new AdblockSyntaxError((0,sprintf.sprintf)(ERROR_MESSAGES$6.EXPECTED_TOKEN_BUT_GOT, (0,csstokenizer/* getFormattedTokenName */.PE)(type), END_OF_INPUT), this.baseOffset + this.source.length - 1, this.baseOffset + this.source.length);
        }
        if (token.type !== type) {
            throw new AdblockSyntaxError((0,sprintf.sprintf)(ERROR_MESSAGES$6.EXPECTED_TOKEN_BUT_GOT, (0,csstokenizer/* getFormattedTokenName */.PE)(type), (0,csstokenizer/* getFormattedTokenName */.PE)(token.type)), this.baseOffset + token.start, this.baseOffset + token.end);
        }
        if (data?.balance !== undefined && token.balance !== data.balance) {
            throw new AdblockSyntaxError((0,sprintf.sprintf)(ERROR_MESSAGES$6.EXPECTED_TOKEN_WITH_BALANCE_BUT_GOT, (0,csstokenizer/* getFormattedTokenName */.PE)(type), data.balance, token.balance), this.baseOffset + token.start, this.baseOffset + token.end);
        }
        if (data?.value && this.fragment() !== data.value) {
            throw new AdblockSyntaxError((0,sprintf.sprintf)(ERROR_MESSAGES$6.EXPECTED_TOKEN_WITH_VALUE_BUT_GOT, (0,csstokenizer/* getFormattedTokenName */.PE)(type), data.value, this.fragment()), this.baseOffset + token.start, this.baseOffset + token.end);
        }
    }
    /**
     * Gets the balance level of the token at the specified index.
     *
     * @param index The index of the token to retrieve the balance level for.
     * @returns The balance level of the token or 0 if the index is out of bounds.
     */
    getBalance(index = this.index) {
        return this.tokens[index]?.balance || 0;
    }
    /**
     * Checks whether the token stream contains any Extended CSS elements, such as `:contains()`, etc.
     *
     * @returns `true` if the stream contains any Extended CSS elements, otherwise `false`.
     */
    hasAnySelectorExtendedCssNode() {
        return this.hasAnySelectorExtendedCssNodeInternal(EXT_CSS_PSEUDO_CLASSES);
    }
    /**
     * Strictly checks whether the token stream contains any Extended CSS elements, such as `:contains()`.
     * Some Extended CSS elements are natively supported by browsers, like `:has()`.
     * This method is used to check for Extended CSS elements that are not natively supported by browsers,
     * this is why it called "strict", because it strictly checks for Extended CSS elements.
     *
     * @returns `true` if the stream contains any Extended CSS elements, otherwise `false`.
     */
    hasAnySelectorExtendedCssNodeStrict() {
        return this.hasAnySelectorExtendedCssNodeInternal(EXT_CSS_PSEUDO_CLASSES_STRICT);
    }
    /**
     * Checks whether the token stream contains any Extended CSS elements, such as `:has()`, `:contains()`, etc.
     *
     * @param pseudos Set of pseudo-classes to check for.
     *
     * @returns `true` if the stream contains any Extended CSS elements, otherwise `false`.
     */
    hasAnySelectorExtendedCssNodeInternal(pseudos) {
        for (let i = 0; i < this.tokens.length; i += 1) {
            const token = this.tokens[i];
            if (token.type === csstokenizer/* TokenType.Function */.iv.Function) {
                const name = this.source.slice(token.start, token.end - 1); // omit the last parenthesis
                if (pseudos.has(name)) {
                    return true;
                }
            }
            else if (token.type === csstokenizer/* TokenType.OpenSquareBracket */.iv.OpenSquareBracket) {
                let j = i + 1;
                // skip whitespace
                while (j < this.tokens.length && this.tokens[j].type === csstokenizer/* TokenType.Whitespace */.iv.Whitespace) {
                    j += 1;
                }
                if (j < this.tokens.length && this.tokens[j].type === csstokenizer/* TokenType.Ident */.iv.Ident) {
                    const attr = this.source.slice(this.tokens[j].start, this.tokens[j].end);
                    // [-ext-<name>=...] or [-abp-<name>=...]
                    if (attr.startsWith(LEGACY_EXT_CSS_ATTRIBUTE_PREFIX) || attr.startsWith(ABP_EXT_CSS_PREFIX)) {
                        return true;
                    }
                }
                // do not check these tokens again
                i = j;
            }
        }
        return false;
    }
}

/**
 * @file Parser for AdGuard CSS injections.
 */
const REMOVE_PROPERTY = 'remove';
const REMOVE_VALUE = 'true';
const removeDeclaration = `${REMOVE_PROPERTY}${COLON}${SPACE}${REMOVE_VALUE}${SEMICOLON}`;
const ERROR_MESSAGES$4 = {
    MEDIA_QUERY_LIST_IS_EMPTY: 'Media query list is empty',
    SELECTOR_LIST_IS_EMPTY: 'Selector list is empty',
    DECLARATION_LIST_IS_EMPTY: 'Declaration list is empty',
};
/**
 * Parser for AdGuard CSS injection.
 */
class AdgCssInjectionParser extends ParserBase {
    /**
     * Parses an AdGuard CSS injection.
     *
     * @param raw Raw input to parse.
     * @param options Global parser options.
     * @param baseOffset Starting offset of the input. Node locations are calculated relative to this offset.
     *
     * @returns Parsed AdGuard CSS injection {@link CssInjectionRuleBody}.
     * @throws An {@link AdblockSyntaxError} if the selector list is syntactically invalid.
     */
    static parse(raw, options = defaultParserOptions, baseOffset = 0) {
        let mediaQueryList;
        const selectorList = { type: 'Value', value: EMPTY };
        const declarationList = { type: 'Value', value: EMPTY };
        const stream = new CssTokenStream(raw, baseOffset);
        // Skip leading whitespace characters
        stream.skipWhitespace();
        // We have two possible CSS injection formats:
        // 1. @media (media-query-list) { selector list { declarations separated by semicolons } }
        // 2. selector list { declarations separated by semicolons }
        // Handle '@media' case:
        let balanceShift = 0;
        if (stream.getOrFail().type === csstokenizer/* TokenType.AtKeyword */.iv.AtKeyword) {
            // Currently only '@media' is supported, we should throw an error if we encounter anything else,
            // like '@supports' or '@charset', etc.
            stream.expect(csstokenizer/* TokenType.AtKeyword */.iv.AtKeyword, { value: CSS_MEDIA_MARKER, balance: 0 });
            stream.advance();
            // Skip whitespace characters after @media keyword, if any
            // @media (media-query-list) { ...
            //       ↑
            //       └ this one (if any)
            stream.skipWhitespace();
            const mediaQueryListStart = stream.getOrFail().start;
            // Skip everything until we found the opening curly bracket of the declaration block
            // @media media-query-list { ...
            //                         ↑
            //                         └ this one
            let lastNonWsIndex = -1;
            while (!stream.isEof()) {
                const token = stream.getOrFail();
                if (token.type === csstokenizer/* TokenType.OpenCurlyBracket */.iv.OpenCurlyBracket && token.balance === 1) {
                    break;
                }
                if (token.type !== csstokenizer/* TokenType.Whitespace */.iv.Whitespace) {
                    lastNonWsIndex = token.end;
                }
                stream.advance();
            }
            // If the skipped tokens count is 0 without leading and trailing whitespace characters, then the media query
            // list is empty
            if (lastNonWsIndex === -1) {
                throw new AdblockSyntaxError(ERROR_MESSAGES$4.MEDIA_QUERY_LIST_IS_EMPTY, baseOffset + mediaQueryListStart, baseOffset + raw.length);
            }
            // It is safe to use non-null assertion here, because we have already checked previous tokens.
            // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
            const mediaQueryListEnd = lastNonWsIndex;
            mediaQueryList = {
                type: 'Value',
                value: raw.slice(mediaQueryListStart, mediaQueryListEnd),
            };
            if (options.isLocIncluded) {
                mediaQueryList.start = baseOffset + mediaQueryListStart;
                mediaQueryList.end = baseOffset + mediaQueryListEnd;
            }
            // Next token should be an open curly bracket
            // @media (media-query-list) { ...
            //                           ↑
            //                           └ this one
            stream.expect(csstokenizer/* TokenType.OpenCurlyBracket */.iv.OpenCurlyBracket);
            stream.advance();
            // '@media' at-rule wrap increases the balance level by 1 for the rule within the at-rule, because it
            // has its own { ... } block
            balanceShift = 1;
        }
        // Skip leading whitespace before the rule, if any
        // Note: rule = selector list { declarations separated by semicolons }
        stream.skipWhitespace();
        const selectorStart = stream.getOrFail().start;
        // Jump to the opening curly bracket of the declaration block, based on the balance level
        // .selector { padding-top: 10px; padding-bottom: 10px; }
        //           ↑
        //           └ this one
        const { skippedTrimmed: selectorTokensLength } = stream.skipUntilExt(csstokenizer/* TokenType.OpenCurlyBracket */.iv.OpenCurlyBracket, balanceShift + 1);
        stream.expect(csstokenizer/* TokenType.OpenCurlyBracket */.iv.OpenCurlyBracket);
        // If the skipped tokens count is 0 without leading and trailing whitespace characters, then the selector list
        // is empty
        if (selectorTokensLength === 0) {
            throw new AdblockSyntaxError(ERROR_MESSAGES$4.SELECTOR_LIST_IS_EMPTY, baseOffset + selectorStart, baseOffset + raw.length);
        }
        // It is safe to use non-null assertion here, because we have already checked previous tokens.
        // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
        const selectorEnd = stream.lookbehindForNonWs().end;
        selectorList.value = raw.slice(selectorStart, selectorEnd);
        if (options.isLocIncluded) {
            selectorList.start = baseOffset + selectorStart;
            selectorList.end = baseOffset + selectorEnd;
        }
        // Jump to the next token after the opening curly bracket of the declaration block
        // .selector { padding-top: 10px; padding-bottom: 10px; }
        //            ↑
        //            └ this one
        stream.advance();
        // Skip whitespace characters after the opening curly bracket of the declaration block, if any
        stream.skipWhitespace();
        // Jump to the closing curly bracket of the declaration block, based on the balance level
        // .selector { padding-top: 10px; padding-bottom: 10px; }
        //                                                      ↑
        //                                                      └ this one
        const declarationsStart = stream.getOrFail().start;
        const declarations = new Set();
        let declarationsEnd = -1;
        let remove = false;
        let lastNonWsIndex = -1;
        while (!stream.isEof()) {
            const token = stream.getOrFail();
            if (token.type === csstokenizer/* TokenType.CloseCurlyBracket */.iv.CloseCurlyBracket && stream.getBalance() === balanceShift) {
                declarationsEnd = lastNonWsIndex;
                break;
            }
            if (token.type !== csstokenizer/* TokenType.Whitespace */.iv.Whitespace) {
                lastNonWsIndex = token.end;
            }
            if (token.type === csstokenizer/* TokenType.Ident */.iv.Ident && stream.lookahead()?.type === csstokenizer/* TokenType.Colon */.iv.Colon) {
                const ident = raw.slice(token.start, token.end);
                declarations.add(ident);
                // Consume ident and colon
                stream.advance();
                stream.advance();
                // only 'remove: true' is allowed
                if (ident === REMOVE_PROPERTY) {
                    // Skip whitespace after colon, if any
                    stream.skipWhitespace();
                    // Next token should be an ident, with value 'true'
                    stream.expect(csstokenizer/* TokenType.Ident */.iv.Ident, { value: REMOVE_VALUE });
                    stream.advance();
                    remove = true;
                }
            }
            else {
                stream.advance();
            }
        }
        if (declarationsEnd === -1) {
            throw new AdblockSyntaxError(ERROR_MESSAGES$4.DECLARATION_LIST_IS_EMPTY, baseOffset + declarationsStart, baseOffset + raw.length);
        }
        declarationList.value = raw.slice(declarationsStart, declarationsEnd);
        if (options.isLocIncluded) {
            declarationList.start = baseOffset + declarationsStart;
            declarationList.end = baseOffset + declarationsEnd;
        }
        // Eat the close curly bracket of the declaration block
        // .selector { padding-top: 10px; padding-bottom: 10px; }
        //                                                      ↑
        //                                                      └ this one
        stream.expect(csstokenizer/* TokenType.CloseCurlyBracket */.iv.CloseCurlyBracket);
        stream.advance();
        // Skip whitespace after the rule, if any
        stream.skipWhitespace();
        // If we have a media query, we should have an extra close curly bracket
        if (balanceShift === 1) {
            stream.expect(csstokenizer/* TokenType.CloseCurlyBracket */.iv.CloseCurlyBracket);
            stream.advance();
        }
        const result = {
            type: 'CssInjectionRuleBody',
            selectorList,
            declarationList,
            remove,
        };
        if (options.isLocIncluded) {
            result.start = baseOffset;
            result.end = baseOffset + raw.length;
        }
        if (mediaQueryList) {
            result.mediaQueryList = mediaQueryList;
        }
        return result;
    }
    /**
     * Serializes an AdGuard CSS injection node into a raw string.
     *
     * @param node Node to serialize.
     * @returns Raw string.
     */
    static generate(node) {
        const result = [];
        if (node.mediaQueryList) {
            result.push(CSS_MEDIA_MARKER, SPACE, node.mediaQueryList.value, SPACE, OPEN_CURLY_BRACKET, SPACE);
        }
        result.push(node.selectorList.value, SPACE, OPEN_CURLY_BRACKET, SPACE);
        if (node.remove) {
            result.push(removeDeclaration);
        }
        else if (node.declarationList?.value) {
            result.push(node.declarationList.value);
        }
        result.push(SPACE, CLOSE_CURLY_BRACKET);
        if (node.mediaQueryList) {
            result.push(SPACE, CLOSE_CURLY_BRACKET);
        }
        return result.join(EMPTY);
    }
}

/* eslint-disable no-param-reassign */
/**
 * @file Helpers for serializing scriptlet injection body nodes to binary format.
 * We keep the core logic here, because it can be reused for each scriptlet body parser.
 */
/**
 * Property map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent a property.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 */
var AbpSnippetBodySerializationMap;
(function (AbpSnippetBodySerializationMap) {
    AbpSnippetBodySerializationMap[AbpSnippetBodySerializationMap["Children"] = 1] = "Children";
    AbpSnippetBodySerializationMap[AbpSnippetBodySerializationMap["Start"] = 2] = "Start";
    AbpSnippetBodySerializationMap[AbpSnippetBodySerializationMap["End"] = 3] = "End";
})(AbpSnippetBodySerializationMap || (AbpSnippetBodySerializationMap = {}));
/**
 * Serializes a hint rule node to binary format.
 *
 * @param node Node to serialize.
 * @param buffer ByteBuffer for writing binary data.
 * @param frequentScriptletArgs Map of frequently used scriptlet names / arguments
 * and their serialization index (optional).
 */
const serializeScriptletBody = (node, buffer, frequentScriptletArgs) => {
    buffer.writeUint8(BinaryTypeMap.ScriptletInjectionRuleBodyNode);
    const { length } = node.children;
    buffer.writeUint8(AbpSnippetBodySerializationMap.Children);
    // note: we store the count, because re-construction of the array is faster if we know the length
    if (length > UINT8_MAX) {
        throw new Error(`Too many scriptlet children: ${length}, the limit is ${UINT8_MAX}`);
    }
    buffer.writeUint8(length);
    for (let i = 0; i < length; i += 1) {
        ParameterListParser.serialize(node.children[i], buffer, frequentScriptletArgs);
    }
    if (!isUndefined(node.start)) {
        buffer.writeUint8(AbpSnippetBodySerializationMap.Start);
        buffer.writeUint32(node.start);
    }
    if (!isUndefined(node.end)) {
        buffer.writeUint8(AbpSnippetBodySerializationMap.End);
        buffer.writeUint32(node.end);
    }
    buffer.writeUint8(NULL);
};
/**
 * Deserializes a hint rule node from binary format.
 *
 * @param buffer ByteBuffer for reading binary data.
 * @param node Destination node.
 * @param frequentScriptletArgs Map of frequently used scriptlet names / arguments
 * and their serialization index (optional).
 * @throws If the binary data is malformed.
 */
const deserializeScriptletBody = (buffer, node, frequentScriptletArgs) => {
    buffer.assertUint8(BinaryTypeMap.ScriptletInjectionRuleBodyNode);
    node.type = 'ScriptletInjectionRuleBody';
    let prop = buffer.readUint8();
    while (prop !== NULL) {
        switch (prop) {
            case AbpSnippetBodySerializationMap.Children:
                node.children = new Array(buffer.readUint8());
                // read children
                for (let i = 0; i < node.children.length; i += 1) {
                    // eslint-disable-next-line max-len
                    ParameterListParser.deserialize(buffer, node.children[i] = {}, frequentScriptletArgs);
                }
                break;
            case AbpSnippetBodySerializationMap.Start:
                node.start = buffer.readUint32();
                break;
            case AbpSnippetBodySerializationMap.End:
                node.end = buffer.readUint32();
                break;
            default:
                throw new Error(`Invalid property: ${prop}`);
        }
        prop = buffer.readUint8();
    }
};

/**
 * @file uBlock scriptlet injection body parser
 */
/**
 * `AbpSnippetInjectionBodyParser` is responsible for parsing the body of an Adblock Plus-style snippet rule.
 *
 * Please note that the parser will parse any scriptlet rule if it is syntactically correct.
 * For example, it will parse this:
 * ```adblock
 * example.com#$#snippet0 arg0
 * ```
 *
 * but it didn't check if the scriptlet `snippet0` actually supported by any adblocker.
 *
 * @see {@link https://help.eyeo.com/adblockplus/snippet-filters-tutorial}
 */
class AbpSnippetInjectionBodyParser extends ParserBase {
    /**
     * Error messages used by the parser.
     */
    static ERROR_MESSAGES = {
        EMPTY_SCRIPTLET_CALL: 'Empty ABP snippet call',
    };
    /**
     * Value map for binary serialization. This helps to reduce the size of the serialized data,
     * as it allows us to use a single byte to represent frequently used values.
     *
     * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
     *
     * @note Only 256 values can be represented this way.
     */
    // TODO: Update this map with the actual values
    static FREQUENT_ARGS_SERIALIZATION_MAP = new Map([
        ['abort-current-inline-script', 0],
        ['abort-on-property-read', 1],
        ['abort-on-property-write', 2],
        ['json-prune', 3],
        ['log', 4],
        ['prevent-listener', 5],
        ['cookie-remover', 6],
        ['override-property-read', 7],
        ['abort-on-iframe-property-read', 8],
        ['abort-on-iframe-property-write', 9],
        ['freeze-element', 10],
        ['json-override', 11],
        ['simulate-mouse-event', 12],
        ['strip-fetch-query-parameter', 13],
        ['hide-if-contains', 14],
        ['hide-if-contains-image', 15],
        ['hide-if-contains-image-hash', 16],
        ['hide-if-contains-similar-text', 17],
        ['hide-if-contains-visible-text', 18],
        ['hide-if-contains-and-matches-style', 19],
        ['hide-if-graph-matches', 20],
        ['hide-if-has-and-matches-style', 21],
        ['hide-if-labelled-by', 22],
        ['hide-if-matches-xpath', 23],
        ['hide-if-matches-computed-xpath', 24],
        ['hide-if-shadow-contains', 25],
        ['debug', 26],
        ['trace', 27],
        ['race', 28],
    ]);
    /**
     * Value map for binary deserialization. This helps to reduce the size of the serialized data,
     * as it allows us to use a single byte to represent frequently used values.
     */
    static FREQUENT_ARGS_DESERIALIZATION_MAP = new Map(Array.from(this.FREQUENT_ARGS_SERIALIZATION_MAP).map(([key, value]) => [value, key]));
    /**
     * Parses the body of an Adblock Plus-style snippet rule.
     *
     * @param raw Raw input to parse.
     * @param options Global parser options.
     * @param baseOffset Starting offset of the input. Node locations are calculated relative to this offset.
     * @returns Node of the parsed scriptlet call body
     * @throws If the body is syntactically incorrect
     * @example
     * ```
     * #$#snippet0 arg0
     * ```
     */
    static parse(raw, options = defaultParserOptions, baseOffset = 0) {
        const result = {
            type: 'ScriptletInjectionRuleBody',
            children: [],
        };
        if (options.isLocIncluded) {
            result.start = baseOffset;
            result.end = baseOffset + raw.length;
        }
        let offset = 0;
        // Skip leading spaces
        offset = StringUtils.skipWS(raw, offset);
        while (offset < raw.length) {
            offset = StringUtils.skipWS(raw, offset);
            const scriptletCallStart = offset;
            // Find the next semicolon or the end of the string
            let semicolonIndex = StringUtils.findUnescapedNonStringNonRegexChar(raw, SEMICOLON, offset);
            if (semicolonIndex === -1) {
                semicolonIndex = raw.length;
            }
            const scriptletCallEnd = Math.max(StringUtils.skipWSBack(raw, semicolonIndex - 1) + 1, scriptletCallStart);
            const params = ParameterListParser.parse(raw.slice(scriptletCallStart, scriptletCallEnd), options, baseOffset + scriptletCallStart, SPACE);
            // Parse the scriptlet call
            result.children.push(params);
            // Skip the semicolon
            offset = semicolonIndex + 1;
        }
        if (result.children.length === 0) {
            throw new AdblockSyntaxError(this.ERROR_MESSAGES.EMPTY_SCRIPTLET_CALL, baseOffset, baseOffset + raw.length);
        }
        return result;
    }
    /**
     * Generates a string representation of the Adblock Plus-style snippet call body.
     *
     * @param node Scriptlet injection rule body
     * @returns String representation of the rule body
     */
    static generate(node) {
        const result = [];
        if (node.children.length === 0) {
            throw new Error(this.ERROR_MESSAGES.EMPTY_SCRIPTLET_CALL);
        }
        for (const scriptletCall of node.children) {
            if (scriptletCall.children.length === 0) {
                throw new Error(this.ERROR_MESSAGES.EMPTY_SCRIPTLET_CALL);
            }
            result.push(ParameterListParser.generate(scriptletCall, SPACE));
        }
        return result.join(SEMICOLON + SPACE);
    }
    /**
     * Serializes a scriptlet call body node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     */
    static serialize(node, buffer) {
        serializeScriptletBody(node, buffer, this.FREQUENT_ARGS_SERIALIZATION_MAP);
    }
    /**
     * Deserializes a scriptlet call body node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     * @throws If the binary data is malformed.
     */
    static deserialize(buffer, node) {
        deserializeScriptletBody(buffer, node, this.FREQUENT_ARGS_DESERIALIZATION_MAP);
    }
}

/**
 * @file Utility functions for working with quotes
 */
/**
 * Set of all possible quote characters supported by the library
 */
const QUOTE_SET = new Set([
    SINGLE_QUOTE,
    DOUBLE_QUOTE,
    BACKTICK_QUOTE,
]);
/**
 * Possible quote types for scriptlet parameters
 */
var QuoteType;
(function (QuoteType) {
    /**
     * No quotes at all
     */
    QuoteType["None"] = "none";
    /**
     * Single quotes (`'`)
     */
    QuoteType["Single"] = "single";
    /**
     * Double quotes (`"`)
     */
    QuoteType["Double"] = "double";
    /**
     * Backtick quotes (`` ` ``)
     */
    QuoteType["Backtick"] = "backtick";
})(QuoteType || (QuoteType = {}));
/**
 * Utility functions for working with quotes
 */
class QuoteUtils {
    /**
     * Escape all unescaped occurrences of the character
     *
     * @param string String to escape
     * @param char Character to escape
     * @returns Escaped string
     */
    static escapeUnescapedOccurrences(string, char) {
        let result = EMPTY;
        for (let i = 0; i < string.length; i += 1) {
            if (string[i] === char && (i === 0 || string[i - 1] !== ESCAPE_CHARACTER)) {
                result += ESCAPE_CHARACTER;
            }
            result += string[i];
        }
        return result;
    }
    /**
     * Unescape all single escaped occurrences of the character
     *
     * @param string String to unescape
     * @param char Character to unescape
     * @returns Unescaped string
     */
    static unescapeSingleEscapedOccurrences(string, char) {
        let result = EMPTY;
        for (let i = 0; i < string.length; i += 1) {
            if (string[i] === char
                && string[i - 1] === ESCAPE_CHARACTER
                && (i === 1 || string[i - 2] !== ESCAPE_CHARACTER)) {
                result = result.slice(0, -1);
            }
            result += string[i];
        }
        return result;
    }
    /**
     * Get quote type of the string
     *
     * @param string String to check
     * @returns Quote type of the string
     */
    static getStringQuoteType(string) {
        // Don't check 1-character strings to avoid false positives
        if (string.length > 1) {
            if (string.startsWith(SINGLE_QUOTE) && string.endsWith(SINGLE_QUOTE)) {
                return QuoteType.Single;
            }
            if (string.startsWith(DOUBLE_QUOTE) && string.endsWith(DOUBLE_QUOTE)) {
                return QuoteType.Double;
            }
            if (string.startsWith(BACKTICK_QUOTE) && string.endsWith(BACKTICK_QUOTE)) {
                return QuoteType.Backtick;
            }
        }
        return QuoteType.None;
    }
    /**
     * Set quote type of the string
     *
     * @param string String to set quote type of
     * @param quoteType Quote type to set
     * @returns String with the specified quote type
     */
    static setStringQuoteType(string, quoteType) {
        const actualQuoteType = QuoteUtils.getStringQuoteType(string);
        switch (quoteType) {
            case QuoteType.None:
                if (actualQuoteType === QuoteType.Single) {
                    return QuoteUtils.escapeUnescapedOccurrences(string.slice(1, -1), SINGLE_QUOTE);
                }
                if (actualQuoteType === QuoteType.Double) {
                    return QuoteUtils.escapeUnescapedOccurrences(string.slice(1, -1), DOUBLE_QUOTE);
                }
                if (actualQuoteType === QuoteType.Backtick) {
                    return QuoteUtils.escapeUnescapedOccurrences(string.slice(1, -1), BACKTICK_QUOTE);
                }
                return string;
            case QuoteType.Single:
                if (actualQuoteType === QuoteType.None) {
                    return SINGLE_QUOTE + QuoteUtils.escapeUnescapedOccurrences(string, SINGLE_QUOTE) + SINGLE_QUOTE;
                }
                if (actualQuoteType === QuoteType.Double) {
                    return SINGLE_QUOTE
                        + QuoteUtils.escapeUnescapedOccurrences(QuoteUtils.unescapeSingleEscapedOccurrences(string.slice(1, -1), DOUBLE_QUOTE), SINGLE_QUOTE) + SINGLE_QUOTE;
                }
                if (actualQuoteType === QuoteType.Backtick) {
                    return SINGLE_QUOTE
                        + QuoteUtils.escapeUnescapedOccurrences(QuoteUtils.unescapeSingleEscapedOccurrences(string.slice(1, -1), BACKTICK_QUOTE), SINGLE_QUOTE) + SINGLE_QUOTE;
                }
                return string;
            case QuoteType.Double:
                if (actualQuoteType === QuoteType.None) {
                    return DOUBLE_QUOTE + QuoteUtils.escapeUnescapedOccurrences(string, DOUBLE_QUOTE) + DOUBLE_QUOTE;
                }
                if (actualQuoteType !== QuoteType.Double) {
                    // eslint-disable-next-line max-len
                    return DOUBLE_QUOTE
                        + QuoteUtils.escapeUnescapedOccurrences(QuoteUtils.unescapeSingleEscapedOccurrences(string.slice(1, -1), SINGLE_QUOTE), DOUBLE_QUOTE) + DOUBLE_QUOTE;
                }
                return string;
            case QuoteType.Backtick:
                if (actualQuoteType === QuoteType.None) {
                    // eslint-disable-next-line max-len
                    return BACKTICK_QUOTE + QuoteUtils.escapeUnescapedOccurrences(string, BACKTICK_QUOTE) + BACKTICK_QUOTE;
                }
                if (actualQuoteType !== QuoteType.Backtick) {
                    // eslint-disable-next-line max-len
                    return BACKTICK_QUOTE
                        + QuoteUtils.escapeUnescapedOccurrences(QuoteUtils.unescapeSingleEscapedOccurrences(string.slice(1, -1), SINGLE_QUOTE), BACKTICK_QUOTE) + BACKTICK_QUOTE;
                }
                return string;
            default:
                return string;
        }
    }
    /**
     * Removes bounding quotes from a string, if any
     *
     * @param string Input string
     * @returns String without quotes
     */
    static removeQuotes(string) {
        if (
        // We should check for string length to avoid false positives
        string.length > 1
            && (string[0] === SINGLE_QUOTE || string[0] === DOUBLE_QUOTE || string[0] === BACKTICK_QUOTE)
            && string[0] === string[string.length - 1]) {
            return string.slice(1, -1);
        }
        return string;
    }
    /**
     * Removes bounding quotes from a string, if any, and unescapes the escaped quotes,
     * like transforming `'abc\'def'` to `abc'def`.
     *
     * @param string Input string
     * @returns String without quotes
     */
    static removeQuotesAndUnescape(string) {
        if (
        // We should check for string length to avoid false positives
        string.length > 1
            && (string[0] === SINGLE_QUOTE || string[0] === DOUBLE_QUOTE || string[0] === BACKTICK_QUOTE)
            && string[0] === string[string.length - 1]) {
            return QuoteUtils.unescapeSingleEscapedOccurrences(string.slice(1, -1), string[0]);
        }
        return string;
    }
    /**
     * Wraps given `strings` with `quote` (defaults to single quote `'`)
     * and joins them with `separator` (defaults to comma+space `, `).
     *
     * @param strings Strings to quote and join.
     * @param quoteType Quote to use.
     * @param separator Separator to use.
     *
     * @returns String with joined items.
     *
     * @example
     * ['abc', 'def']: strings[]  ->  "'abc', 'def'": string
     */
    static quoteAndJoinStrings(strings, quoteType = QuoteType.Single, separator = `${COMMA}${SPACE}`) {
        return strings
            .map((s) => QuoteUtils.setStringQuoteType(s, quoteType))
            .join(separator);
    }
}

/* eslint-disable no-param-reassign */
class UboParameterListParser extends ParameterListParser {
    /**
     * Parses an "uBO-specific parameter list".
     *
     * @param raw Raw input to parse.
     * @param options Global parser options.
     * @param baseOffset Starting offset of the input. Node locations are calculated relative to this offset.
     * @param separator Separator character (default: comma).
     * @param requireQuotes Whether to require quotes around the parameter values (default: false).
     * @param supportedQuotes Set of accepted quotes (default: {@link QUOTE_SET}).
     * @returns Parameter list node.
     *
     * @note Based on {@link https://github.com/gorhill/uBlock/blob/f9ab4b75041815e6e5690d80851189ae3dc660d0/src/js/static-filtering-parser.js#L607-L699} to provide consistency.
     */
    static parse(raw, options = defaultParserOptions, baseOffset = 0, separator = COMMA, requireQuotes = false, supportedQuotes = QUOTE_SET) {
        // Prepare the parameter list node
        const params = {
            type: 'ParameterList',
            children: [],
        };
        const { length } = raw;
        if (options.isLocIncluded) {
            params.start = baseOffset;
            params.end = baseOffset + length;
        }
        let offset = 0;
        // TODO: Eliminate the need for extraNull
        let extraNull = false;
        while (offset < length) {
            offset = StringUtils.skipWS(raw, offset);
            const paramStart = offset;
            let paramEnd = offset;
            if (supportedQuotes.has(raw[offset])) {
                // Find the closing quote
                const possibleClosingQuoteIndex = StringUtils.findNextUnescapedCharacter(raw, raw[offset], offset + 1);
                if (possibleClosingQuoteIndex !== -1) {
                    // Next non-whitespace character after the closing quote should be the separator
                    const nextSeparatorIndex = StringUtils.skipWS(raw, possibleClosingQuoteIndex + 1);
                    if (nextSeparatorIndex === length) {
                        if (requireQuotes) {
                            throw new AdblockSyntaxError('Expected separator, got end of string', baseOffset + nextSeparatorIndex, baseOffset + length);
                        }
                        // If the separator is not found, the param end is the end of the string
                        paramEnd = StringUtils.skipWSBack(raw, length - 1) + 1;
                        offset = length;
                    }
                    else if (raw[nextSeparatorIndex] === separator) {
                        // If the quote is followed by a separator, we can use it as a closing quote
                        paramEnd = possibleClosingQuoteIndex + 1;
                        offset = nextSeparatorIndex + 1;
                    }
                    else {
                        if (requireQuotes) {
                            throw new AdblockSyntaxError(`Expected separator, got: '${raw[nextSeparatorIndex]}'`, baseOffset + nextSeparatorIndex, baseOffset + length);
                        }
                        // Param end should be the last separator before the quote
                        offset = StringUtils.findNextUnescapedCharacterBackwards(raw, separator, possibleClosingQuoteIndex) + 1;
                        paramEnd = StringUtils.skipWSBack(raw, offset - 2) + 1;
                    }
                }
                else {
                    if (requireQuotes) {
                        throw new AdblockSyntaxError('Expected closing quote, got end of string', baseOffset + offset, baseOffset + length);
                    }
                    // If the closing quote is not found, the param end is the end of the string
                    paramEnd = StringUtils.skipWSBack(raw, length - 1) + 1;
                    offset = length;
                }
            }
            else {
                if (requireQuotes) {
                    throw new AdblockSyntaxError(`Expected quote, got: '${raw[offset]}'`, baseOffset + offset, baseOffset + length);
                }
                const nextSeparator = StringUtils.findNextUnescapedCharacter(raw, separator, offset);
                if (nextSeparator === -1) {
                    // If the separator is not found, the param end is the end of the string
                    paramEnd = StringUtils.skipWSBack(raw, length - 1) + 1;
                    offset = length;
                }
                else {
                    // Param end should be the last non-whitespace character before the separator
                    paramEnd = StringUtils.skipWSBack(raw, nextSeparator - 1) + 1;
                    offset = nextSeparator + 1;
                    if (StringUtils.skipWS(raw, length - 1) === nextSeparator) {
                        extraNull = true;
                    }
                }
            }
            if (paramStart < paramEnd) {
                params.children.push(ValueParser.parse(raw.slice(paramStart, paramEnd), options, baseOffset + paramStart));
            }
            else {
                params.children.push(null);
            }
        }
        if (extraNull) {
            params.children.push(null);
        }
        return params;
    }
}

/**
 * @file uBlock scriptlet injection body parser
 */
/**
 * `UboScriptletInjectionBodyParser` is responsible for parsing the body of a uBlock-style scriptlet rule.
 *
 * Please note that the parser will parse any scriptlet rule if it is syntactically correct.
 * For example, it will parse this:
 * ```adblock
 * example.com##+js(scriptlet0, arg0)
 * ```
 *
 * but it didn't check if the scriptlet `scriptlet0` actually supported by any adblocker.
 *
 * @see {@link https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#scriptlet-injection}
 */
class UboScriptletInjectionBodyParser extends ParserBase {
    /**
     * Error messages used by the parser.
     */
    static ERROR_MESSAGES = {
        NO_SCRIPTLET_MASK: `Invalid uBO scriptlet call, no scriptlet call mask '${UBO_SCRIPTLET_MASK}' found`,
        NO_OPENING_PARENTHESIS: `Invalid uBO scriptlet call, no opening parentheses '${OPEN_PARENTHESIS}' found`,
        NO_CLOSING_PARENTHESIS: `Invalid uBO scriptlet call, no closing parentheses '${CLOSE_PARENTHESIS}' found`,
        NO_SCRIPTLET_NAME: 'Invalid uBO scriptlet call, no scriptlet name specified',
        WHITESPACE_AFTER_MASK: 'Invalid uBO scriptlet call, whitespace is not allowed after the scriptlet call mask',
        NO_MULTIPLE_SCRIPTLET_CALLS: 'uBO syntaxes does not support multiple scriptlet calls within one single rule',
    };
    /**
     * Value map for binary serialization. This helps to reduce the size of the serialized data,
     * as it allows us to use a single byte to represent frequently used values.
     *
     * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
     *
     * @note Only 256 values can be represented this way.
     */
    // TODO: Update this map with the actual values
    static FREQUENT_ARGS_SERIALIZATION_MAP = new Map([
        ['abort-current-script.js', 0],
        ['acs.js', 1],
        ['abort-current-inline-script.js', 2],
        ['acis.js', 3],
        ['abort-on-property-read.js', 4],
        ['aopr.js', 5],
        ['abort-on-property-write.js', 6],
        ['aopw.js', 7],
        ['abort-on-stack-trace.js', 8],
        ['aost.js', 9],
        ['adjust-setInterval.js', 10],
        ['nano-setInterval-booster.js', 11],
        ['nano-sib.js', 12],
        ['adjust-setTimeout.js', 13],
        ['nano-setTimeout-booster.js', 14],
        ['nano-stb.js', 15],
        ['close-window.js', 16],
        ['window-close-if.js', 17],
        ['disable-newtab-links.js', 18],
        ['evaldata-prune.js', 19],
        ['json-prune.js', 20],
        ['addEventListener-logger.js', 21],
        ['aell.js', 22],
        ['m3u-prune.js', 23],
        ['nowebrtc.js', 24],
        ['addEventListener-defuser.js', 25],
        ['aeld.js', 26],
        ['prevent-addEventListener.js', 27],
        ['adfly-defuser.js', 28],
        ['noeval-if.js', 29],
        ['prevent-eval-if.js', 30],
        ['no-fetch-if.js', 31],
        ['prevent-fetch.js', 32],
        ['no-xhr-if.js', 33],
        ['prevent-xhr.js', 34],
        ['prevent-refresh.js', 35],
        ['refresh-defuser.js', 36],
        ['no-requestAnimationFrame-if.js', 37],
        ['norafif.js', 38],
        ['prevent-requestAnimationFrame.js', 39],
        ['no-setInterval-if.js', 40],
        ['nosiif.js', 41],
        ['prevent-setInterval.js', 42],
        ['setInterval-defuser.js', 43],
        ['no-setTimeout-if.js', 44],
        ['nostif.js', 45],
        ['prevent-setTimeout.js', 46],
        ['setTimeout-defuser.js', 47],
        ['no-window-open-if.js', 48],
        ['nowoif.js', 49],
        ['prevent-window-open.js', 50],
        ['window.open-defuser.js', 51],
        ['remove-attr.js', 52],
        ['ra.js', 53],
        ['remove-class.js', 54],
        ['rc.js', 55],
        ['remove-cookie.js', 56],
        ['cookie-remover.js', 57],
        ['remove-node-text.js', 58],
        ['rmnt.js', 59],
        ['set-attr.js', 60],
        ['set-constant.js', 61],
        ['set.js', 62],
        ['set-cookie.js', 63],
        ['set-local-storage-item.js', 64],
        ['set-session-storage-item.js', 65],
        ['xml-prune.js', 66],
        ['webrtc-if.js', 67],
        ['overlay-buster.js', 68],
        ['alert-buster.js', 69],
        ['golem.de.js', 70],
        ['href-sanitizer.js', 71],
        ['call-nothrow.js', 72],
        ['window.name-defuser.js', 73],
        ['spoof-css.js', 74],
        ['trusted-set-constant.js', 75],
        ['trusted-set.js', 76],
        ['trusted-set-cookie.js', 77],
        ['trusted-set-local-storage-item.js', 78],
        ['trusted-replace-fetch-response.js', 79],
        ['json-prune-fetch-response.js', 80],
        ['json-prune-xhr-response.js', 81],
        ['trusted-replace-xhr-response.js', 82],
        ['multiup.js', 83],
        ['prevent-canvas.js', 84],
        ['set-cookie-reload.js', 85],
        ['trusted-set-cookie-reload.js', 86],
        ['trusted-click-element.js', 87],
        ['trusted-prune-inbound-object.js', 88],
        ['trusted-prune-outbound-object.js', 89],
        ['trusted-set-session-storage-item.js', 90],
        ['trusted-replace-node-text.js', 91],
        ['trusted-rpnt.js', 92],
        ['replace-node-text.js', 93],
        ['rpnt.js', 94],
    ]);
    /**
     * Value map for binary deserialization. This helps to reduce the size of the serialized data,
     * as it allows us to use a single byte to represent frequently used values.
     */
    static FREQUENT_ARGS_DESERIALIZATION_MAP = new Map(Array.from(this.FREQUENT_ARGS_SERIALIZATION_MAP).map(([key, value]) => [value, key]));
    /**
     * Parses the body of a uBlock-style scriptlet rule.
     *
     * @param raw Raw input to parse.
     * @param options Global parser options.
     * @param baseOffset Starting offset of the input. Node locations are calculated relative to this offset.
     * @returns Node of the parsed scriptlet call body
     * @throws If the body is syntactically incorrect
     * @example
     * ```
     * ##+js(scriptlet0, arg0)
     * ```
     */
    static parse(raw, options = defaultParserOptions, baseOffset = 0) {
        let offset = 0;
        // Skip leading spaces
        offset = StringUtils.skipWS(raw, offset);
        let scriptletMaskLength = 0;
        if (raw.startsWith(UBO_SCRIPTLET_MASK, offset)) {
            scriptletMaskLength = UBO_SCRIPTLET_MASK.length;
        }
        else if (raw.startsWith(UBO_SCRIPTLET_MASK_LEGACY, offset)) {
            scriptletMaskLength = UBO_SCRIPTLET_MASK_LEGACY.length;
        }
        // Scriptlet call should start with "+js"
        if (!scriptletMaskLength) {
            throw new AdblockSyntaxError(this.ERROR_MESSAGES.NO_SCRIPTLET_MASK, baseOffset + offset, baseOffset + raw.length);
        }
        offset += scriptletMaskLength;
        // Whitespace is not allowed after the mask
        if (raw[offset] === SPACE) {
            throw new AdblockSyntaxError(this.ERROR_MESSAGES.WHITESPACE_AFTER_MASK, baseOffset + offset, baseOffset + raw.length);
        }
        // Parameter list should be wrapped in parentheses
        if (raw[offset] !== OPEN_PARENTHESIS) {
            throw new AdblockSyntaxError(this.ERROR_MESSAGES.NO_OPENING_PARENTHESIS, baseOffset + offset, baseOffset + raw.length);
        }
        // Save the offset of the opening parentheses
        const openingParenthesesIndex = offset;
        // Skip whitespace from the end
        const closingParenthesesIndex = StringUtils.skipWSBack(raw, raw.length - 1);
        // Closing parentheses should be present
        if (raw[closingParenthesesIndex] !== CLOSE_PARENTHESIS
            || raw[closingParenthesesIndex - 1] === ESCAPE_CHARACTER) {
            throw new AdblockSyntaxError(this.ERROR_MESSAGES.NO_CLOSING_PARENTHESIS, baseOffset + offset, baseOffset + raw.length);
        }
        const result = {
            type: 'ScriptletInjectionRuleBody',
            children: [],
        };
        if (options.isLocIncluded) {
            result.start = baseOffset;
            result.end = baseOffset + raw.length;
        }
        // Special case: empty scriptlet call, like +js(), +js( ), etc.
        if (StringUtils.skipWS(raw, openingParenthesesIndex + 1) === closingParenthesesIndex) {
            return result;
        }
        // Parse parameter list
        const params = UboParameterListParser.parse(raw.slice(openingParenthesesIndex + 1, closingParenthesesIndex), options, baseOffset + openingParenthesesIndex + 1, COMMA);
        // Do not allow parameters without scriptlet: +js(, arg0, arg1)
        if (params.children.length > 0 && params.children[0] === null) {
            throw new AdblockSyntaxError(this.ERROR_MESSAGES.NO_SCRIPTLET_NAME, baseOffset + offset, baseOffset + raw.length);
        }
        result.children.push(params);
        return result;
    }
    /**
     * Generates a string representation of the uBlock scriptlet call body.
     *
     * @param node Scriptlet injection rule body
     * @returns String representation of the rule body
     */
    static generate(node) {
        const result = [];
        if (node.children.length > 1) {
            throw new Error(this.ERROR_MESSAGES.NO_MULTIPLE_SCRIPTLET_CALLS);
        }
        // During generation, we only support the modern scriptlet mask
        result.push(UBO_SCRIPTLET_MASK);
        result.push(OPEN_PARENTHESIS);
        if (node.children.length > 0) {
            const [parameterListNode] = node.children;
            result.push(ParameterListParser.generate(parameterListNode));
        }
        result.push(CLOSE_PARENTHESIS);
        return result.join(EMPTY);
    }
    /**
     * Serializes a scriptlet call body node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     */
    static serialize(node, buffer) {
        serializeScriptletBody(node, buffer, this.FREQUENT_ARGS_SERIALIZATION_MAP);
    }
    /**
     * Deserializes a scriptlet call body node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     * @throws If the binary data is malformed.
     */
    static deserialize(buffer, node) {
        deserializeScriptletBody(buffer, node, this.FREQUENT_ARGS_DESERIALIZATION_MAP);
    }
}

/**
 * @file AdGuard scriptlet injection body parser
 */
/**
 * `AdgScriptletInjectionBodyParser` is responsible for parsing the body of an AdGuard-style scriptlet rule.
 *
 * Please note that the parser will parse any scriptlet rule if it is syntactically correct.
 * For example, it will parse this:
 * ```adblock
 * example.com#%#//scriptlet('scriptlet0', 'arg0')
 * ```
 *
 * but it didn't check if the scriptlet `scriptlet0` actually supported by any adblocker.
 *
 * @see {@link https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#scriptlets}
 */
class AdgScriptletInjectionBodyParser extends ParserBase {
    /**
     * Error messages used by the parser.
     */
    static ERROR_MESSAGES = {
        NO_SCRIPTLET_MASK: `Invalid ADG scriptlet call, no scriptlet call mask '${ADG_SCRIPTLET_MASK}' found`,
        NO_OPENING_PARENTHESIS: `Invalid ADG scriptlet call, no opening parentheses '${OPEN_PARENTHESIS}' found`,
        NO_CLOSING_PARENTHESIS: `Invalid ADG scriptlet call, no closing parentheses '${CLOSE_PARENTHESIS}' found`,
        WHITESPACE_AFTER_MASK: 'Invalid ADG scriptlet call, whitespace is not allowed after the scriptlet call mask',
        NO_MULTIPLE_SCRIPTLET_CALLS: 'ADG syntaxes does not support multiple scriptlet calls within one single rule',
        NO_INCONSISTENT_QUOTES: 'Invalid ADG scriptlet call, inconsistent quotes',
        NO_UNCLOSED_PARAMETER: 'Invalid ADG scriptlet call, unclosed parameter',
        EXPECTED_QUOTE: "Invalid ADG scriptlet call, expected quote, got '%s'",
        EXPECTED_COMMA: "Invalid ADG scriptlet call, expected comma, got '%s'",
    };
    /**
     * Value map for binary serialization. This helps to reduce the size of the serialized data,
     * as it allows us to use a single byte to represent frequently used values.
     *
     * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
     *
     * @note Only 256 values can be represented this way.
     */
    // TODO: Update this map with the actual values
    static FREQUENT_ARGS_SERIALIZATION_MAP = new Map([
        ['abort-current-inline-script', 0],
        ['abort-on-property-read', 1],
        ['abort-on-property-write', 2],
        ['abort-on-stack-trace', 3],
        ['adjust-setInterval', 4],
        ['adjust-setTimeout', 5],
        ['close-window', 6],
        ['debug-current-inline-script', 7],
        ['debug-on-property-read', 8],
        ['debug-on-property-write', 9],
        ['dir-string', 10],
        ['disable-newtab-links', 11],
        ['evaldata-prune', 12],
        ['json-prune', 13],
        ['log', 14],
        ['log-addEventListener', 15],
        ['log-eval', 16],
        ['log-on-stack-trace', 17],
        ['m3u-prune', 18],
        ['noeval', 19],
        ['nowebrtc', 20],
        ['no-topics', 21],
        ['prevent-addEventListener', 22],
        ['prevent-adfly', 23],
        ['prevent-bab', 24],
        ['prevent-eval-if', 25],
        ['prevent-fab-3.2.0', 26],
        ['prevent-fetch', 27],
        ['prevent-xhr', 28],
        ['prevent-popads-net', 29],
        ['prevent-refresh', 30],
        ['prevent-requestAnimationFrame', 31],
        ['prevent-setInterval', 32],
        ['prevent-setTimeout', 33],
        ['prevent-window-open', 34],
        ['remove-attr', 35],
        ['remove-class', 36],
        ['remove-cookie', 37],
        ['remove-node-text', 38],
        ['set-attr', 39],
        ['set-constant', 40],
        ['set-cookie', 41],
        ['set-cookie-reload', 42],
        ['set-local-storage-item', 43],
        ['set-popads-dummy', 44],
        ['set-session-storage-item', 45],
        ['xml-prune', 46],
    ]);
    /**
     * Value map for binary deserialization. This helps to reduce the size of the serialized data,
     * as it allows us to use a single byte to represent frequently used values.
     */
    static FREQUENT_ARGS_DESERIALIZATION_MAP = new Map(Array.from(this.FREQUENT_ARGS_SERIALIZATION_MAP).map(([key, value]) => [value, key]));
    /**
     * Parses the body of an AdGuard-style scriptlet rule.
     *
     * @param raw Raw input to parse.
     * @param options Global parser options.
     * @param baseOffset Starting offset of the input. Node locations are calculated relative to this offset.
     * @returns Node of the parsed scriptlet call body
     * @throws If the body is syntactically incorrect
     * @example
     * ```
     * //scriptlet('scriptlet0', 'arg0')
     * ```
     */
    static parse(raw, options = defaultParserOptions, baseOffset = 0) {
        let offset = 0;
        // Skip leading spaces
        offset = StringUtils.skipWS(raw, offset);
        // Scriptlet call should start with "//scriptlet"
        if (!raw.startsWith(ADG_SCRIPTLET_MASK, offset)) {
            throw new AdblockSyntaxError(this.ERROR_MESSAGES.NO_SCRIPTLET_MASK, baseOffset + offset, baseOffset + raw.length);
        }
        offset += ADG_SCRIPTLET_MASK.length;
        // Whitespace is not allowed after the mask
        if (raw[offset] === SPACE) {
            throw new AdblockSyntaxError(this.ERROR_MESSAGES.WHITESPACE_AFTER_MASK, baseOffset + offset, baseOffset + raw.length);
        }
        // Parameter list should be wrapped in parentheses
        if (raw[offset] !== OPEN_PARENTHESIS) {
            throw new AdblockSyntaxError(this.ERROR_MESSAGES.NO_OPENING_PARENTHESIS, baseOffset + offset, baseOffset + raw.length);
        }
        // Save the offset of the opening parentheses
        const openingParenthesesIndex = offset;
        // Skip whitespace from the end
        const closingParenthesesIndex = StringUtils.skipWSBack(raw, raw.length - 1);
        // Closing parentheses should be present
        if (raw[closingParenthesesIndex] !== CLOSE_PARENTHESIS
            || raw[closingParenthesesIndex - 1] === ESCAPE_CHARACTER) {
            throw new AdblockSyntaxError(this.ERROR_MESSAGES.NO_CLOSING_PARENTHESIS, baseOffset + offset, baseOffset + raw.length);
        }
        // Skip space, if any
        offset = StringUtils.skipWS(raw, offset + 1);
        const result = {
            type: 'ScriptletInjectionRuleBody',
            children: [],
        };
        if (options.isLocIncluded) {
            result.start = baseOffset;
            result.end = baseOffset + raw.length;
        }
        // Special case: empty scriptlet call, like `//scriptlet()`, `//scriptlet( )` etc.
        if (StringUtils.skipWS(raw, openingParenthesesIndex + 1) === closingParenthesesIndex) {
            return result;
        }
        let detectedQuote = null;
        const parameterList = {
            type: 'ParameterList',
            children: [],
        };
        if (options.isLocIncluded) {
            parameterList.start = baseOffset + openingParenthesesIndex + 1;
            parameterList.end = baseOffset + closingParenthesesIndex;
        }
        while (offset < closingParenthesesIndex) {
            // Skip whitespace
            offset = StringUtils.skipWS(raw, offset);
            // Expect comma if not first parameter
            if (parameterList.children.length > 0) {
                if (raw[offset] !== COMMA) {
                    throw new AdblockSyntaxError((0,sprintf.sprintf)(AdgScriptletInjectionBodyParser.ERROR_MESSAGES.EXPECTED_COMMA, raw[offset]), baseOffset + offset, baseOffset + raw.length);
                }
                // Eat the comma
                offset += 1;
                // Skip whitespace
                offset = StringUtils.skipWS(raw, offset);
            }
            // Next character should be a quote
            if (raw[offset] === SINGLE_QUOTE || raw[offset] === DOUBLE_QUOTE) {
                if (isNull(detectedQuote)) {
                    detectedQuote = raw[offset];
                }
                else if (detectedQuote !== raw[offset]) {
                    throw new AdblockSyntaxError(AdgScriptletInjectionBodyParser.ERROR_MESSAGES.NO_INCONSISTENT_QUOTES, baseOffset + offset, baseOffset + raw.length);
                }
                // Find next unescaped same quote
                const closingQuoteIndex = StringUtils.findNextUnescapedCharacter(raw, detectedQuote, offset + 1);
                if (closingQuoteIndex === -1) {
                    throw new AdblockSyntaxError(AdgScriptletInjectionBodyParser.ERROR_MESSAGES.NO_UNCLOSED_PARAMETER, baseOffset + offset, baseOffset + raw.length);
                }
                // Save the parameter
                const parameter = ValueParser.parse(raw.slice(offset, closingQuoteIndex + 1), options, baseOffset + offset);
                parameterList.children.push(parameter);
                // Move after the closing quote
                offset = StringUtils.skipWS(raw, closingQuoteIndex + 1);
            }
            else {
                throw new AdblockSyntaxError((0,sprintf.sprintf)(AdgScriptletInjectionBodyParser.ERROR_MESSAGES.EXPECTED_QUOTE, raw[offset]), baseOffset + offset, baseOffset + raw.length);
            }
        }
        result.children.push(parameterList);
        return result;
    }
    /**
     * Generates a string representation of the AdGuard scriptlet call body.
     *
     * @param node Scriptlet injection rule body
     * @returns String representation of the rule body
     */
    static generate(node) {
        const result = [];
        if (node.children.length > 1) {
            throw new Error(this.ERROR_MESSAGES.NO_MULTIPLE_SCRIPTLET_CALLS);
        }
        result.push(ADG_SCRIPTLET_MASK);
        result.push(OPEN_PARENTHESIS);
        if (node.children.length > 0) {
            result.push(ParameterListParser.generate(node.children[0]));
        }
        result.push(CLOSE_PARENTHESIS);
        return result.join(EMPTY);
    }
    /**
     * Serializes a scriptlet call body node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     */
    static serialize(node, buffer) {
        serializeScriptletBody(node, buffer, this.FREQUENT_ARGS_SERIALIZATION_MAP);
    }
    /**
     * Deserializes a scriptlet call body node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     * @throws If the binary data is malformed.
     */
    static deserialize(buffer, node) {
        deserializeScriptletBody(buffer, node, this.FREQUENT_ARGS_DESERIALIZATION_MAP);
    }
}

/* eslint-disable no-param-reassign */
/**
 * Value map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent frequently used values.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 */
const SEPARATOR_SERIALIZATION_MAP = new Map([
    ['##', 0],
    ['#@#', 1],
    ['#?#', 2],
    ['#@?#', 3],
    ['#$#', 4],
    ['#$?#', 5],
    ['#@$#', 6],
    ['#@$?#', 7],
    ['#%#', 8],
    ['#@%#', 9],
    ['$$', 10],
    ['$@$', 11],
]);
/**
 * Value map for binary deserialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent frequently used values.
 */
const SEPARATOR_DESERIALIZATION_MAP = new Map(Array.from(SEPARATOR_SERIALIZATION_MAP).map(([key, value]) => [value, key]));
/**
 * Value map for binary deserialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent frequently used values.
 */
const COSMETIC_RULE_TYPE_DESERIALIZATION_MAP = new Map([
    [BinaryTypeMap.ElementHidingRule, CosmeticRuleType.ElementHidingRule],
    [BinaryTypeMap.CssInjectionRule, CosmeticRuleType.CssInjectionRule],
    [BinaryTypeMap.ScriptletInjectionRule, CosmeticRuleType.ScriptletInjectionRule],
    [BinaryTypeMap.JsInjectionRule, CosmeticRuleType.JsInjectionRule],
    [BinaryTypeMap.HtmlFilteringRule, CosmeticRuleType.HtmlFilteringRule],
]);
/**
 * Property map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent a property.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 */
var ElementHidingRuleSerializationMap;
(function (ElementHidingRuleSerializationMap) {
    ElementHidingRuleSerializationMap[ElementHidingRuleSerializationMap["SelectorList"] = 1] = "SelectorList";
    ElementHidingRuleSerializationMap[ElementHidingRuleSerializationMap["Start"] = 2] = "Start";
    ElementHidingRuleSerializationMap[ElementHidingRuleSerializationMap["End"] = 3] = "End";
})(ElementHidingRuleSerializationMap || (ElementHidingRuleSerializationMap = {}));
/**
 * Property map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent a property.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 */
var CssInjectionRuleSerializationMap;
(function (CssInjectionRuleSerializationMap) {
    CssInjectionRuleSerializationMap[CssInjectionRuleSerializationMap["SelectorList"] = 1] = "SelectorList";
    CssInjectionRuleSerializationMap[CssInjectionRuleSerializationMap["DeclarationList"] = 2] = "DeclarationList";
    CssInjectionRuleSerializationMap[CssInjectionRuleSerializationMap["MediaQueryList"] = 3] = "MediaQueryList";
    CssInjectionRuleSerializationMap[CssInjectionRuleSerializationMap["Remove"] = 4] = "Remove";
    CssInjectionRuleSerializationMap[CssInjectionRuleSerializationMap["Start"] = 5] = "Start";
    CssInjectionRuleSerializationMap[CssInjectionRuleSerializationMap["End"] = 6] = "End";
})(CssInjectionRuleSerializationMap || (CssInjectionRuleSerializationMap = {}));
/**
 * Property map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent a property.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 */
var CosmeticRuleSerializationMap;
(function (CosmeticRuleSerializationMap) {
    CosmeticRuleSerializationMap[CosmeticRuleSerializationMap["Syntax"] = 1] = "Syntax";
    CosmeticRuleSerializationMap[CosmeticRuleSerializationMap["Exception"] = 2] = "Exception";
    CosmeticRuleSerializationMap[CosmeticRuleSerializationMap["Separator"] = 3] = "Separator";
    CosmeticRuleSerializationMap[CosmeticRuleSerializationMap["Modifiers"] = 4] = "Modifiers";
    CosmeticRuleSerializationMap[CosmeticRuleSerializationMap["Domains"] = 5] = "Domains";
    CosmeticRuleSerializationMap[CosmeticRuleSerializationMap["Body"] = 6] = "Body";
    CosmeticRuleSerializationMap[CosmeticRuleSerializationMap["Start"] = 7] = "Start";
    CosmeticRuleSerializationMap[CosmeticRuleSerializationMap["End"] = 8] = "End";
})(CosmeticRuleSerializationMap || (CosmeticRuleSerializationMap = {}));
/**
 * Possible error messages for uBO selectors. Formatted with {@link sprintf}.
 */
const ERROR_MESSAGES$3 = {
    EMPTY_RULE_BODY: 'Empty rule body',
    INVALID_BODY_FOR_SEPARATOR: "Body '%s' is not valid for the '%s' cosmetic rule separator",
    MISSING_ADGUARD_MODIFIER_LIST_END: "Missing '%s' at the end of the AdGuard modifier list in pattern '%s'",
    MISSING_ADGUARD_MODIFIER_LIST_MARKER: "Missing '%s' at the beginning of the AdGuard modifier list in pattern '%s'",
    SYNTAXES_CANNOT_BE_MIXED: "'%s' syntax cannot be mixed with '%s' syntax",
    SYNTAX_DISABLED: "Parsing '%s' syntax is disabled, but the rule uses it",
};
const ADG_CSS_INJECTION_PATTERN = /^(?:.+){(?:.+)}$/;
/**
 * `CosmeticRuleParser` is responsible for parsing cosmetic rules.
 *
 * Where possible, it automatically detects the difference between supported syntaxes:
 *  - AdGuard
 *  - uBlock Origin
 *  - Adblock Plus
 *
 * If the syntax is common / cannot be determined, the parser gives `Common` syntax.
 *
 * Please note that syntactically correct rules are parsed even if they are not actually
 * compatible with the given adblocker. This is a completely natural behavior, meaningful
 * checking of compatibility is not done at the parser level.
 */
// TODO: Make raw body parsing optional
// TODO: Split into smaller sections
class CosmeticRuleParser extends ParserBase {
    /**
     * Determines whether a rule is a cosmetic rule. The rule is considered cosmetic if it
     * contains a cosmetic rule separator.
     *
     * @param raw Raw rule
     * @returns `true` if the rule is a cosmetic rule, `false` otherwise
     */
    static isCosmeticRule(raw) {
        const trimmed = raw.trim();
        if (CommentRuleParser.isCommentRule(trimmed)) {
            return false;
        }
        return CosmeticRuleSeparatorUtils.find(trimmed) !== null;
    }
    /**
     * Parses a cosmetic rule. The structure of the cosmetic rules:
     *  - pattern (AdGuard pattern can have modifiers, other syntaxes don't)
     *  - separator
     *  - body
     *
     * @param raw Raw input to parse.
     * @param options Global parser options.
     * @param baseOffset Starting offset of the input. Node locations are calculated relative to this offset.
     * @returns
     * Parsed cosmetic rule AST or null if it failed to parse based on the known cosmetic rules
     * @throws If the input matches the cosmetic rule pattern but syntactically invalid
     */
    // TODO: Split to smaller functions
    static parse(raw, options = defaultParserOptions, baseOffset = 0) {
        // Find cosmetic rule separator - each cosmetic rule must have it, otherwise it is not a cosmetic rule
        const separatorResult = CosmeticRuleSeparatorUtils.find(raw);
        if (!separatorResult) {
            return null;
        }
        let syntax = AdblockSyntax.Common;
        let modifiers;
        const patternStart = StringUtils.skipWS(raw);
        const patternEnd = StringUtils.skipWSBack(raw, separatorResult.start - 1) + 1;
        const bodyStart = StringUtils.skipWS(raw, separatorResult.end);
        const bodyEnd = StringUtils.skipWSBack(raw) + 1;
        // Note we use '<=' instead of '===' because we have bidirectional trim
        if (bodyEnd <= bodyStart) {
            throw new AdblockSyntaxError(ERROR_MESSAGES$3.EMPTY_RULE_BODY, baseOffset, baseOffset + raw.length);
        }
        // Step 1. Parse the pattern: it can be a domain list or a domain list with modifiers (AdGuard)
        const rawPattern = raw.slice(patternStart, patternEnd);
        let patternOffset = patternStart;
        if (rawPattern[patternOffset] === OPEN_SQUARE_BRACKET) {
            // Save offset to the beginning of the modifier list for later
            const modifierListStart = patternOffset;
            // Consume opening square bracket
            patternOffset += 1;
            // Skip whitespace after opening square bracket
            patternOffset = StringUtils.skipWS(rawPattern, patternOffset);
            // Open square bracket should be followed by a modifier separator: [$
            if (rawPattern[patternOffset] !== DOLLAR_SIGN) {
                throw new AdblockSyntaxError((0,sprintf.sprintf)(ERROR_MESSAGES$3.MISSING_ADGUARD_MODIFIER_LIST_MARKER, DOLLAR_SIGN, rawPattern), baseOffset + patternOffset, baseOffset + rawPattern.length);
            }
            // Consume modifier separator
            patternOffset += 1;
            // Skip whitespace after modifier separator
            patternOffset = StringUtils.skipWS(rawPattern, patternOffset);
            // Modifier list ends with the last unescaped square bracket
            // We search for the last unescaped square bracket, because some modifiers can contain square brackets,
            // e.g. [$domain=/example[0-9]\.(com|org)/]##.ad
            const modifierListEnd = StringUtils.findLastUnescapedCharacter(rawPattern, CLOSE_SQUARE_BRACKET);
            if (modifierListEnd === -1) {
                throw new AdblockSyntaxError((0,sprintf.sprintf)(ERROR_MESSAGES$3.MISSING_ADGUARD_MODIFIER_LIST_END, CLOSE_SQUARE_BRACKET, rawPattern), baseOffset + patternOffset, baseOffset + rawPattern.length);
            }
            // Parse modifier list
            modifiers = ModifierListParser.parse(raw.slice(patternOffset, modifierListEnd), options, baseOffset + patternOffset);
            // Expand modifier list location to include the opening and closing square brackets
            if (options.isLocIncluded) {
                modifiers.start = baseOffset + modifierListStart;
                modifiers.end = baseOffset + modifierListEnd + 1;
            }
            // Consume modifier list
            patternOffset = modifierListEnd + 1;
            // Change the syntax to ADG
            syntax = AdblockSyntax.Adg;
        }
        // Skip whitespace after modifier list
        patternOffset = StringUtils.skipWS(rawPattern, patternOffset);
        // Parse domains
        const domains = DomainListParser.parse(rawPattern.slice(patternOffset), options, baseOffset + patternOffset);
        // Step 2. Parse the separator
        const separator = {
            type: 'Value',
            value: separatorResult.separator,
        };
        if (options.isLocIncluded) {
            separator.start = baseOffset + separatorResult.start;
            separator.end = baseOffset + separatorResult.end;
        }
        const exception = CosmeticRuleSeparatorUtils.isException(separatorResult.separator);
        // Step 3. Parse the rule body
        let rawBody = raw.slice(bodyStart, bodyEnd);
        /**
         * Ensures that the rule syntax is common or the expected one. This function is used to prevent mixing
         * different syntaxes in the same rule.
         *
         * @example
         * The following rule mixes AdGuard and uBO syntaxes, because it uses AdGuard modifier list and uBO
         * CSS injection:
         * ```adblock
         * [$path=/something]example.com##.foo:style(color: red)
         * ```
         * In this case, parser sets syntax to AdGuard, because it detects the AdGuard modifier list, but
         * when parsing the rule body, it detects uBO CSS injection, which is not compatible with AdGuard.
         *
         * @param expectedSyntax Expected syntax
         * @throws If the rule syntax is not common or the expected one
         */
        const expectCommonOrSpecificSyntax = (expectedSyntax) => {
            if (syntax !== AdblockSyntax.Common && syntax !== expectedSyntax) {
                throw new AdblockSyntaxError((0,sprintf.sprintf)(ERROR_MESSAGES$3.SYNTAXES_CANNOT_BE_MIXED, expectedSyntax, syntax), baseOffset + patternStart, baseOffset + bodyEnd);
            }
        };
        let uboSelector;
        // Parse UBO rule modifiers
        if (options.parseUboSpecificRules) {
            uboSelector = UboSelectorParser.parse(rawBody, options, baseOffset + bodyStart);
            rawBody = uboSelector.selector.value;
            // Do not allow ADG modifiers and UBO modifiers in the same rule
            if (uboSelector.modifiers && uboSelector.modifiers.children.length > 0) {
                // If modifiers are present, that means that the ADG modifier list was parsed
                expectCommonOrSpecificSyntax(AdblockSyntax.Ubo);
                // Change the syntax to uBO
                syntax = AdblockSyntax.Ubo;
                // Store the rule modifiers
                // Please note that not each special uBO modifier is a rule modifier, some of them are
                // used for CSS injection, for example `:style()` and `:remove()`
                for (const modifier of uboSelector.modifiers.children) {
                    // TODO: Add support for matches-media and element hiding rules
                    // TODO: Improve this condition if new uBO modifiers are added
                    if (modifier.name.value === UboPseudoName.MatchesPath) {
                        // Prepare the modifier list if it does not exist yet
                        if (!modifiers) {
                            modifiers = {
                                type: 'ModifierList',
                                children: [],
                            };
                            if (options.isLocIncluded) {
                                modifiers.start = baseOffset + bodyStart;
                                modifiers.end = baseOffset + bodyEnd;
                            }
                        }
                        modifiers.children.push(modifier);
                    }
                }
            }
        }
        const raws = {
            text: raw,
        };
        const baseRule = {
            category: RuleCategory.Cosmetic,
            exception,
            modifiers,
            domains,
            separator,
        };
        if (options.includeRaws) {
            baseRule.raws = raws;
        }
        if (options.isLocIncluded) {
            baseRule.start = baseOffset;
            baseRule.end = baseOffset + raw.length;
        }
        const parseUboCssInjection = () => {
            if (!uboSelector || !uboSelector.modifiers || uboSelector.modifiers.children?.length < 1) {
                return null;
            }
            expectCommonOrSpecificSyntax(AdblockSyntax.Ubo);
            const selectorList = uboSelector.selector;
            let declarationList;
            let mediaQueryList;
            let remove = false;
            for (const modifier of uboSelector.modifiers.children) {
                switch (modifier.name.value) {
                    case UboPseudoName.Style:
                        declarationList = modifier.value;
                        break;
                    case UboPseudoName.Remove:
                        declarationList = {
                            type: 'Value',
                            value: '',
                        };
                        remove = true;
                        break;
                    case UboPseudoName.MatchesMedia:
                        mediaQueryList = modifier.value;
                        break;
                }
            }
            // If neither `:style()` nor `:remove()` is present
            if (!declarationList) {
                return null;
            }
            const body = {
                type: 'CssInjectionRuleBody',
                selectorList,
                declarationList,
                mediaQueryList,
                remove,
            };
            if (options.isLocIncluded) {
                body.start = baseOffset + bodyStart;
                body.end = baseOffset + bodyEnd;
            }
            return {
                syntax: AdblockSyntax.Ubo,
                type: CosmeticRuleType.CssInjectionRule,
                body,
            };
        };
        const parseElementHiding = () => {
            const selectorList = {
                type: 'Value',
                value: rawBody,
            };
            if (options.isLocIncluded) {
                selectorList.start = baseOffset + bodyStart;
                selectorList.end = baseOffset + bodyEnd;
            }
            const body = {
                type: 'ElementHidingRuleBody',
                selectorList,
            };
            if (options.isLocIncluded) {
                body.start = baseOffset + bodyStart;
                body.end = baseOffset + bodyEnd;
            }
            return {
                syntax,
                type: CosmeticRuleType.ElementHidingRule,
                body,
            };
        };
        const parseAdgCssInjection = () => {
            // TODO: Improve this detection. Need to cover the following cases:
            // #$#body { color: red;
            // #$#@media (min-width: 100px) { body { color: red; }
            // ADG CSS injection
            if (!ADG_CSS_INJECTION_PATTERN.test(rawBody)) {
                return null;
            }
            expectCommonOrSpecificSyntax(AdblockSyntax.Adg);
            return {
                syntax: AdblockSyntax.Adg,
                type: CosmeticRuleType.CssInjectionRule,
                body: AdgCssInjectionParser.parse(rawBody, options, baseOffset + bodyStart),
            };
        };
        const parseAbpSnippetInjection = () => {
            if (!options.parseAbpSpecificRules) {
                throw new AdblockSyntaxError((0,sprintf.sprintf)(ERROR_MESSAGES$3.SYNTAX_DISABLED, AdblockSyntax.Abp), baseOffset + bodyStart, baseOffset + bodyEnd);
            }
            expectCommonOrSpecificSyntax(AdblockSyntax.Abp);
            const body = AbpSnippetInjectionBodyParser.parse(rawBody, options, baseOffset + bodyStart);
            if (options.isLocIncluded) {
                body.start = baseOffset + bodyStart;
                body.end = baseOffset + bodyEnd;
            }
            return {
                syntax: AdblockSyntax.Abp,
                type: CosmeticRuleType.ScriptletInjectionRule,
                body,
            };
        };
        const parseUboScriptletInjection = () => {
            if (!rawBody.startsWith(UBO_SCRIPTLET_MASK) && !rawBody.startsWith(UBO_SCRIPTLET_MASK_LEGACY)) {
                return null;
            }
            if (!options.parseUboSpecificRules) {
                throw new AdblockSyntaxError((0,sprintf.sprintf)(ERROR_MESSAGES$3.SYNTAX_DISABLED, AdblockSyntax.Ubo), baseOffset + bodyStart, baseOffset + bodyEnd);
            }
            expectCommonOrSpecificSyntax(AdblockSyntax.Ubo);
            const body = UboScriptletInjectionBodyParser.parse(rawBody, options, baseOffset + bodyStart);
            if (options.isLocIncluded) {
                body.start = baseOffset + bodyStart;
                body.end = baseOffset + bodyEnd;
            }
            return {
                syntax: AdblockSyntax.Ubo,
                type: CosmeticRuleType.ScriptletInjectionRule,
                body,
            };
        };
        const parseAdgScriptletInjection = () => {
            // ADG scriptlet injection
            if (!rawBody.startsWith(ADG_SCRIPTLET_MASK)) {
                return null;
            }
            expectCommonOrSpecificSyntax(AdblockSyntax.Adg);
            const body = AdgScriptletInjectionBodyParser.parse(rawBody, options, baseOffset + bodyStart);
            if (options.isLocIncluded) {
                body.start = baseOffset + bodyStart;
                body.end = baseOffset + bodyEnd;
            }
            return {
                syntax: AdblockSyntax.Adg,
                type: CosmeticRuleType.ScriptletInjectionRule,
                body,
            };
        };
        const parseAdgJsInjection = () => {
            expectCommonOrSpecificSyntax(AdblockSyntax.Adg);
            const body = {
                type: 'Value',
                value: rawBody,
            };
            if (options.isLocIncluded) {
                body.start = baseOffset + bodyStart;
                body.end = baseOffset + bodyEnd;
            }
            return {
                syntax: AdblockSyntax.Adg,
                type: CosmeticRuleType.JsInjectionRule,
                body,
            };
        };
        const parseUboHtmlFiltering = () => {
            if (!rawBody.startsWith(UBO_HTML_MASK)) {
                return null;
            }
            if (!options.parseUboSpecificRules) {
                throw new AdblockSyntaxError((0,sprintf.sprintf)(ERROR_MESSAGES$3.SYNTAX_DISABLED, AdblockSyntax.Ubo), baseOffset + bodyStart, baseOffset + bodyEnd);
            }
            expectCommonOrSpecificSyntax(AdblockSyntax.Ubo);
            const body = {
                type: 'Value',
                value: rawBody,
            };
            if (options.isLocIncluded) {
                body.start = baseOffset + bodyStart;
                body.end = baseOffset + bodyEnd;
            }
            return {
                syntax: AdblockSyntax.Ubo,
                type: CosmeticRuleType.HtmlFilteringRule,
                body,
            };
        };
        const parseAdgHtmlFiltering = () => {
            expectCommonOrSpecificSyntax(AdblockSyntax.Adg);
            const body = {
                type: 'Value',
                value: rawBody,
            };
            if (options.isLocIncluded) {
                body.start = baseOffset + bodyStart;
                body.end = baseOffset + bodyEnd;
            }
            return {
                syntax: AdblockSyntax.Adg,
                type: CosmeticRuleType.HtmlFilteringRule,
                body,
            };
        };
        // Create a fast lookup table for cosmetic rule separators and their parsing functions.
        // One separator can have multiple parsing functions. If the first function returns null,
        // the next function is called, and so on.
        // If all functions return null, an error should be thrown.
        const separatorMap = {
            '##': [parseUboHtmlFiltering, parseUboScriptletInjection, parseUboCssInjection, parseElementHiding],
            '#@#': [parseUboHtmlFiltering, parseUboScriptletInjection, parseUboCssInjection, parseElementHiding],
            '#?#': [parseUboCssInjection, parseElementHiding],
            '#@?#': [parseUboCssInjection, parseElementHiding],
            '#$#': [parseAdgCssInjection, parseAbpSnippetInjection],
            '#@$#': [parseAdgCssInjection, parseAbpSnippetInjection],
            '#$?#': [parseAdgCssInjection],
            '#@$?#': [parseAdgCssInjection],
            '#%#': [parseAdgScriptletInjection, parseAdgJsInjection],
            '#@%#': [parseAdgScriptletInjection, parseAdgJsInjection],
            $$: [parseAdgHtmlFiltering],
            '$@$': [parseAdgHtmlFiltering],
        };
        const parseFunctions = separatorMap[separatorResult.separator];
        let restProps;
        for (const parseFunction of parseFunctions) {
            restProps = parseFunction();
            if (restProps) {
                break;
            }
        }
        // If none of the parsing functions returned a result, it means that the rule is unknown / invalid.
        if (!restProps) {
            throw new AdblockSyntaxError((0,sprintf.sprintf)(ERROR_MESSAGES$3.INVALID_BODY_FOR_SEPARATOR, rawBody, separatorResult.separator), baseOffset + bodyStart, baseOffset + bodyEnd);
        }
        // Combine the base rule with the rest of the properties.
        return {
            ...baseRule,
            ...restProps,
        };
    }
    /**
     * Generates the rule pattern from the AST.
     *
     * @param node Cosmetic rule node
     * @returns Raw rule pattern
     * @example
     * - '##.foo' → ''
     * - 'example.com,example.org##.foo' → 'example.com,example.org'
     * - '[$path=/foo/bar]example.com##.foo' → '[$path=/foo/bar]example.com'
     */
    static generatePattern(node) {
        let result = EMPTY;
        // AdGuard modifiers (if any)
        if (node.syntax === AdblockSyntax.Adg && node.modifiers && node.modifiers.children.length > 0) {
            result += OPEN_SQUARE_BRACKET;
            result += DOLLAR_SIGN;
            result += ModifierListParser.generate(node.modifiers);
            result += CLOSE_SQUARE_BRACKET;
        }
        // Domain list (if any)
        result += DomainListParser.generate(node.domains);
        return result;
    }
    /**
     * Generates the rule body from the node.
     *
     * @param node Cosmetic rule node
     * @returns Raw rule body
     * @example
     * - '##.foo' → '.foo'
     * - 'example.com,example.org##.foo' → '.foo'
     * - 'example.com#%#//scriptlet('foo')' → '//scriptlet('foo')'
     */
    static generateBody(node) {
        let result = EMPTY;
        // Body
        switch (node.type) {
            case CosmeticRuleType.ElementHidingRule:
                result = node.body.selectorList.value;
                break;
            case CosmeticRuleType.CssInjectionRule:
                if (node.syntax === AdblockSyntax.Adg) {
                    result = AdgCssInjectionParser.generate(node.body);
                }
                else if (node.syntax === AdblockSyntax.Ubo) {
                    if (node.body.mediaQueryList) {
                        result += COLON;
                        result += UboPseudoName.MatchesMedia;
                        result += OPEN_PARENTHESIS;
                        result += node.body.mediaQueryList.value;
                        result += CLOSE_PARENTHESIS;
                        result += SPACE;
                    }
                    result += node.body.selectorList.value;
                    if (node.body.remove) {
                        result += COLON;
                        result += UboPseudoName.Remove;
                        result += OPEN_PARENTHESIS;
                        result += CLOSE_PARENTHESIS;
                    }
                    else if (node.body.declarationList) {
                        result += COLON;
                        result += UboPseudoName.Style;
                        result += OPEN_PARENTHESIS;
                        result += node.body.declarationList.value;
                        result += CLOSE_PARENTHESIS;
                    }
                }
                break;
            case CosmeticRuleType.HtmlFilteringRule:
            case CosmeticRuleType.JsInjectionRule:
                result = node.body.value;
                break;
            case CosmeticRuleType.ScriptletInjectionRule:
                switch (node.syntax) {
                    case AdblockSyntax.Adg:
                        result = AdgScriptletInjectionBodyParser.generate(node.body);
                        break;
                    case AdblockSyntax.Abp:
                        result = AbpSnippetInjectionBodyParser.generate(node.body);
                        break;
                    case AdblockSyntax.Ubo:
                        result = UboScriptletInjectionBodyParser.generate(node.body);
                        break;
                    default:
                        throw new Error('Scriptlet rule should have an explicit syntax');
                }
                break;
            default:
                throw new Error('Unknown cosmetic rule type');
        }
        return result;
    }
    /**
     * Converts a cosmetic rule AST into a string.
     *
     * @param node Cosmetic rule AST
     * @returns Raw string
     */
    static generate(node) {
        let result = EMPTY;
        // Pattern
        result += CosmeticRuleParser.generatePattern(node);
        // Separator
        result += node.separator.value;
        // uBO rule modifiers
        if (node.syntax === AdblockSyntax.Ubo && node.modifiers) {
            node.modifiers.children.forEach((modifier) => {
                result += COLON;
                result += modifier.name.value;
                if (modifier.value) {
                    result += OPEN_PARENTHESIS;
                    result += modifier.value.value;
                    result += CLOSE_PARENTHESIS;
                }
            });
            // If there are at least one modifier, add a space
            if (node.modifiers.children.length) {
                result += SPACE;
            }
        }
        // Body
        result += CosmeticRuleParser.generateBody(node);
        return result;
    }
    /**
     * Serializes an element hiding rule body node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     */
    static serializeElementHidingBody(node, buffer) {
        buffer.writeUint8(BinaryTypeMap.ElementHidingRuleBody);
        buffer.writeUint8(ElementHidingRuleSerializationMap.SelectorList);
        ValueParser.serialize(node.selectorList, buffer);
        if (!isUndefined(node.start)) {
            buffer.writeUint8(ElementHidingRuleSerializationMap.Start);
            buffer.writeUint32(node.start);
        }
        if (!isUndefined(node.end)) {
            buffer.writeUint8(ElementHidingRuleSerializationMap.End);
            buffer.writeUint32(node.end);
        }
        buffer.writeUint8(NULL);
    }
    /**
     * Deserializes an element hiding rule body node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     */
    static deserializeElementHidingBody(buffer, node) {
        buffer.assertUint8(BinaryTypeMap.ElementHidingRuleBody);
        node.type = 'ElementHidingRuleBody';
        let prop = buffer.readUint8();
        while (prop !== NULL) {
            switch (prop) {
                case ElementHidingRuleSerializationMap.SelectorList:
                    ValueParser.deserialize(buffer, node.selectorList = {});
                    break;
                case ElementHidingRuleSerializationMap.Start:
                    node.start = buffer.readUint32();
                    break;
                case ElementHidingRuleSerializationMap.End:
                    node.end = buffer.readUint32();
                    break;
                default:
                    throw new Error(`Unknown property: ${prop}`);
            }
            prop = buffer.readUint8();
        }
    }
    /**
     * Serializes a CSS injection rule body node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     */
    static serializeCssInjectionBody(node, buffer) {
        buffer.writeUint8(BinaryTypeMap.CssInjectionRuleBody);
        if (node.mediaQueryList) {
            buffer.writeUint8(CssInjectionRuleSerializationMap.MediaQueryList);
            ValueParser.serialize(node.mediaQueryList, buffer);
        }
        buffer.writeUint8(CssInjectionRuleSerializationMap.SelectorList);
        ValueParser.serialize(node.selectorList, buffer);
        if (node.declarationList) {
            buffer.writeUint8(CssInjectionRuleSerializationMap.DeclarationList);
            ValueParser.serialize(node.declarationList, buffer);
        }
        if (node.remove) {
            buffer.writeUint8(CssInjectionRuleSerializationMap.Remove);
        }
        if (!isUndefined(node.start)) {
            buffer.writeUint8(CssInjectionRuleSerializationMap.Start);
            buffer.writeUint32(node.start);
        }
        if (!isUndefined(node.end)) {
            buffer.writeUint8(CssInjectionRuleSerializationMap.End);
            buffer.writeUint32(node.end);
        }
        buffer.writeUint8(NULL);
    }
    /**
     * Deserializes CSS injection rule body node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     */
    static deserializeCssInjectionBody(buffer, node) {
        buffer.assertUint8(BinaryTypeMap.CssInjectionRuleBody);
        node.type = 'CssInjectionRuleBody';
        node.remove = false;
        let prop = buffer.readUint8();
        while (prop !== NULL) {
            switch (prop) {
                case CssInjectionRuleSerializationMap.MediaQueryList:
                    ValueParser.deserialize(buffer, node.mediaQueryList = {});
                    break;
                case CssInjectionRuleSerializationMap.SelectorList:
                    ValueParser.deserialize(buffer, node.selectorList = {});
                    break;
                case CssInjectionRuleSerializationMap.DeclarationList:
                    ValueParser.deserialize(buffer, node.declarationList = {});
                    break;
                case CssInjectionRuleSerializationMap.Remove:
                    node.remove = true;
                    break;
                case CssInjectionRuleSerializationMap.Start:
                    node.start = buffer.readUint32();
                    break;
                case CssInjectionRuleSerializationMap.End:
                    node.end = buffer.readUint32();
                    break;
                default:
                    throw new Error(`Unknown property: ${prop}`);
            }
            prop = buffer.readUint8();
        }
    }
    /**
     * Serializes a cosmetic rule node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     */
    // TODO: add support for raws, if ever needed
    static serialize(node, buffer) {
        // specific properties
        switch (node.type) {
            case CosmeticRuleType.ElementHidingRule:
                // rule type
                buffer.writeUint8(BinaryTypeMap.ElementHidingRule);
                // syntax
                buffer.writeUint8(SYNTAX_SERIALIZATION_MAP.get(node.syntax) ?? 0);
                // rule body
                CosmeticRuleParser.serializeElementHidingBody(node.body, buffer);
                break;
            case CosmeticRuleType.CssInjectionRule:
                // rule type
                buffer.writeUint8(BinaryTypeMap.CssInjectionRule);
                // syntax
                buffer.writeUint8(SYNTAX_SERIALIZATION_MAP.get(node.syntax) ?? 0);
                // rule body
                CosmeticRuleParser.serializeCssInjectionBody(node.body, buffer);
                break;
            case CosmeticRuleType.JsInjectionRule:
                // rule type
                buffer.writeUint8(BinaryTypeMap.JsInjectionRule);
                // syntax
                buffer.writeUint8(SYNTAX_SERIALIZATION_MAP.get(node.syntax) ?? 0);
                // rule body
                ValueParser.serialize(node.body, buffer);
                break;
            case CosmeticRuleType.HtmlFilteringRule:
                // rule type
                buffer.writeUint8(BinaryTypeMap.HtmlFilteringRule);
                // syntax
                buffer.writeUint8(SYNTAX_SERIALIZATION_MAP.get(node.syntax) ?? 0);
                // rule body
                ValueParser.serialize(node.body, buffer);
                break;
            case CosmeticRuleType.ScriptletInjectionRule:
                // rule type
                buffer.writeUint8(BinaryTypeMap.ScriptletInjectionRule);
                // syntax
                buffer.writeUint8(SYNTAX_SERIALIZATION_MAP.get(node.syntax) ?? 0);
                // rule body
                switch (node.syntax) {
                    case AdblockSyntax.Adg:
                        AdgScriptletInjectionBodyParser.serialize(node.body, buffer);
                        break;
                    case AdblockSyntax.Abp:
                        AbpSnippetInjectionBodyParser.serialize(node.body, buffer);
                        break;
                    case AdblockSyntax.Ubo:
                        UboScriptletInjectionBodyParser.serialize(node.body, buffer);
                        break;
                    default:
                        throw new Error('Scriptlet rule should have an explicit syntax');
                }
                break;
            default:
                throw new Error('Unknown cosmetic rule type');
        }
        // common properties
        buffer.writeUint8(CosmeticRuleSerializationMap.Exception);
        buffer.writeUint8(node.exception ? 1 : 0);
        buffer.writeUint8(CosmeticRuleSerializationMap.Separator);
        ValueParser.serialize(node.separator, buffer, SEPARATOR_SERIALIZATION_MAP);
        if (node.modifiers) {
            buffer.writeUint8(CosmeticRuleSerializationMap.Modifiers);
            ModifierListParser.serialize(node.modifiers, buffer);
        }
        buffer.writeUint8(CosmeticRuleSerializationMap.Domains);
        DomainListParser.serialize(node.domains, buffer);
        if (!isUndefined(node.start)) {
            buffer.writeUint8(CosmeticRuleSerializationMap.Start);
            buffer.writeUint32(node.start);
        }
        if (!isUndefined(node.end)) {
            buffer.writeUint8(CosmeticRuleSerializationMap.End);
            buffer.writeUint32(node.end);
        }
        buffer.writeUint8(NULL);
    }
    /**
     * Deserializes a cosmetic rule node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     */
    static deserialize(buffer, node) {
        const type = COSMETIC_RULE_TYPE_DESERIALIZATION_MAP.get(buffer.readUint8());
        if (isUndefined(type)) {
            throw new Error(`Unknown rule type: ${type}`);
        }
        node.type = type;
        node.category = RuleCategory.Cosmetic;
        const syntax = SYNTAX_DESERIALIZATION_MAP.get(buffer.readUint8()) ?? AdblockSyntax.Common;
        node.syntax = syntax;
        node.modifiers = undefined;
        switch (type) {
            case CosmeticRuleType.ElementHidingRule:
                CosmeticRuleParser.deserializeElementHidingBody(buffer, node.body = {});
                break;
            case CosmeticRuleType.CssInjectionRule:
                CosmeticRuleParser.deserializeCssInjectionBody(buffer, node.body = {});
                break;
            case CosmeticRuleType.JsInjectionRule:
                ValueParser.deserialize(buffer, node.body = {});
                break;
            case CosmeticRuleType.HtmlFilteringRule:
                ValueParser.deserialize(buffer, node.body = {});
                break;
            case CosmeticRuleType.ScriptletInjectionRule:
                switch (syntax) {
                    case AdblockSyntax.Adg:
                        // eslint-disable-next-line max-len
                        AdgScriptletInjectionBodyParser.deserialize(buffer, node.body = {});
                        break;
                    case AdblockSyntax.Abp:
                        AbpSnippetInjectionBodyParser.deserialize(buffer, node.body = {});
                        break;
                    case AdblockSyntax.Ubo:
                        // eslint-disable-next-line max-len
                        UboScriptletInjectionBodyParser.deserialize(buffer, node.body = {});
                        break;
                    default:
                        throw new Error('Scriptlet rule should have an explicit syntax');
                }
                break;
            default:
                throw new Error('Unknown cosmetic rule type');
        }
        let prop = buffer.readUint8();
        while (prop !== NULL) {
            switch (prop) {
                case CosmeticRuleSerializationMap.Exception:
                    node.exception = buffer.readUint8() === 1;
                    break;
                case CosmeticRuleSerializationMap.Separator:
                    ValueParser.deserialize(buffer, node.separator = {}, SEPARATOR_DESERIALIZATION_MAP);
                    break;
                case CosmeticRuleSerializationMap.Modifiers:
                    node.modifiers = {};
                    ModifierListParser.deserialize(buffer, node.modifiers);
                    break;
                case CosmeticRuleSerializationMap.Domains:
                    DomainListParser.deserialize(buffer, node.domains = {});
                    break;
                case CosmeticRuleSerializationMap.Start:
                    node.start = buffer.readUint32();
                    break;
                case CosmeticRuleSerializationMap.End:
                    node.end = buffer.readUint32();
                    break;
                default:
                    throw new Error(`Unknown property: ${prop}`);
            }
            prop = buffer.readUint8();
        }
    }
}

/* eslint-disable no-param-reassign */
/**
 * Property map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent a property.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 */
var NetworkRuleSerializationMap;
(function (NetworkRuleSerializationMap) {
    NetworkRuleSerializationMap[NetworkRuleSerializationMap["Syntax"] = 1] = "Syntax";
    NetworkRuleSerializationMap[NetworkRuleSerializationMap["Raws"] = 2] = "Raws";
    NetworkRuleSerializationMap[NetworkRuleSerializationMap["Exception"] = 3] = "Exception";
    NetworkRuleSerializationMap[NetworkRuleSerializationMap["Pattern"] = 4] = "Pattern";
    NetworkRuleSerializationMap[NetworkRuleSerializationMap["ModifierList"] = 5] = "ModifierList";
    NetworkRuleSerializationMap[NetworkRuleSerializationMap["Start"] = 6] = "Start";
    NetworkRuleSerializationMap[NetworkRuleSerializationMap["End"] = 7] = "End";
})(NetworkRuleSerializationMap || (NetworkRuleSerializationMap = {}));
/**
 * `NetworkRuleParser` is responsible for parsing network rules.
 *
 * Please note that this will parse all syntactically correct network rules.
 * Modifier compatibility is not checked at the parser level.
 *
 * @see {@link https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#basic-rules}
 * @see {@link https://help.eyeo.com/adblockplus/how-to-write-filters#basic}
 */
class NetworkRuleParser extends ParserBase {
    /**
     * Parses a network rule (also known as basic rule).
     *
     * @param raw Raw input to parse.
     * @param options Global parser options.
     * @param baseOffset Starting offset of the input. Node locations are calculated relative to this offset.
     * @returns Network rule AST
     *
     * @throws If the rule is syntactically incorrect.
     */
    static parse(raw, options = defaultParserOptions, baseOffset = 0) {
        let offset = 0;
        // Skip leading whitespace
        offset = StringUtils.skipWS(raw, offset);
        // Handle exception rules
        let exception = false;
        // Rule starts with exception marker, eg @@||example.com,
        // where @@ is the exception marker
        if (raw.startsWith(NETWORK_RULE_EXCEPTION_MARKER, offset)) {
            offset += NETWORK_RULE_EXCEPTION_MARKER_LEN;
            exception = true;
        }
        // Save the start of the pattern
        const patternStart = offset;
        // Find corresponding (last) separator ($) character (if any)
        const separatorIndex = NetworkRuleParser.findNetworkRuleSeparatorIndex(raw);
        // Save the end of the pattern
        const patternEnd = separatorIndex === -1
            ? StringUtils.skipWSBack(raw) + 1
            : StringUtils.skipWSBack(raw, separatorIndex - 1) + 1;
        // Parse pattern
        const pattern = ValueParser.parse(raw.slice(patternStart, patternEnd), options, baseOffset + patternStart);
        // Parse modifiers (if any)
        let modifiers;
        // Find start and end index of the modifiers
        const modifiersStart = separatorIndex + 1;
        const modifiersEnd = StringUtils.skipWSBack(raw) + 1;
        if (separatorIndex !== -1) {
            modifiers = ModifierListParser.parse(raw.slice(modifiersStart, modifiersEnd), options, baseOffset + modifiersStart);
        }
        // Throw error if there is no pattern and no modifiers
        if (pattern.value.length === 0 && (modifiers === undefined || modifiers.children.length === 0)) {
            throw new AdblockSyntaxError('Network rule must have a pattern or modifiers', baseOffset, baseOffset + raw.length);
        }
        const result = {
            type: NetworkRuleType.NetworkRule,
            category: RuleCategory.Network,
            syntax: AdblockSyntax.Common,
            exception,
            pattern,
            modifiers,
        };
        if (options.includeRaws) {
            result.raws = {
                text: raw,
            };
        }
        if (options.isLocIncluded) {
            result.start = baseOffset;
            result.end = baseOffset + raw.length;
        }
        return result;
    }
    /**
     * Finds the index of the separator character in a network rule.
     *
     * @param rule Network rule to check
     * @returns The index of the separator character, or -1 if there is no separator
     */
    static findNetworkRuleSeparatorIndex(rule) {
        // As we are looking for the last separator, we start from the end of the string
        for (let i = rule.length - 1; i >= 0; i -= 1) {
            // If we find a potential separator, we should check
            // - if it's not escaped
            // - if it's not followed by a regex marker, for example: `example.org^$removeparam=/regex$/`
            // eslint-disable-next-line max-len
            if (rule[i] === NETWORK_RULE_SEPARATOR && rule[i + 1] !== REGEX_MARKER && rule[i - 1] !== ESCAPE_CHARACTER) {
                return i;
            }
        }
        return -1;
    }
    /**
     * Converts a network rule (basic rule) AST to a string.
     *
     * @param node Network rule node
     * @returns Raw string
     */
    static generate(node) {
        let result = EMPTY;
        // If the rule is an exception, add the exception marker: `@@||example.org`
        if (node.exception) {
            result += NETWORK_RULE_EXCEPTION_MARKER;
        }
        // Add the pattern: `||example.org`
        result += node.pattern.value;
        // If there are modifiers, add a separator and the modifiers: `||example.org$important`
        if (node.modifiers && node.modifiers.children.length > 0) {
            result += NETWORK_RULE_SEPARATOR;
            result += ModifierListParser.generate(node.modifiers);
        }
        return result;
    }
    /**
     * Serializes a network rule node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     */
    // TODO: add support for raws, if ever needed
    static serialize(node, buffer) {
        buffer.writeUint8(BinaryTypeMap.NetworkRuleNode);
        buffer.writeUint8(NetworkRuleSerializationMap.Syntax);
        buffer.writeUint8(SYNTAX_SERIALIZATION_MAP.get(node.syntax) ?? 0);
        buffer.writeUint8(NetworkRuleSerializationMap.Exception);
        buffer.writeUint8(node.exception ? 1 : 0);
        buffer.writeUint8(NetworkRuleSerializationMap.Pattern);
        ValueParser.serialize(node.pattern, buffer);
        if (!isUndefined(node.modifiers)) {
            buffer.writeUint8(NetworkRuleSerializationMap.ModifierList);
            ModifierListParser.serialize(node.modifiers, buffer);
        }
        if (!isUndefined(node.start)) {
            buffer.writeUint8(NetworkRuleSerializationMap.Start);
            buffer.writeUint32(node.start);
        }
        if (!isUndefined(node.end)) {
            buffer.writeUint8(NetworkRuleSerializationMap.End);
            buffer.writeUint32(node.end);
        }
        buffer.writeUint8(NULL);
    }
    /**
     * Deserializes a modifier node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     */
    static deserialize(buffer, node) {
        buffer.assertUint8(BinaryTypeMap.NetworkRuleNode);
        node.type = NetworkRuleType.NetworkRule;
        node.category = RuleCategory.Network;
        node.modifiers = undefined;
        let prop = buffer.readUint8();
        while (prop !== NULL) {
            switch (prop) {
                case NetworkRuleSerializationMap.Syntax:
                    node.syntax = SYNTAX_DESERIALIZATION_MAP.get(buffer.readUint8()) ?? AdblockSyntax.Common;
                    break;
                case NetworkRuleSerializationMap.Exception:
                    node.exception = buffer.readUint8() === 1;
                    break;
                case NetworkRuleSerializationMap.Pattern:
                    ValueParser.deserialize(buffer, node.pattern = {});
                    break;
                case NetworkRuleSerializationMap.ModifierList:
                    ModifierListParser.deserialize(buffer, node.modifiers = {});
                    break;
                case NetworkRuleSerializationMap.Start:
                    node.start = buffer.readUint32();
                    break;
                case NetworkRuleSerializationMap.End:
                    node.end = buffer.readUint32();
                    break;
                default:
                    throw new Error(`Invalid property: ${prop}.`);
            }
            prop = buffer.readUint8();
        }
    }
}

/* eslint-disable no-param-reassign */
/**
 * Property map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent a property.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 */
var HostRuleSerializationMap;
(function (HostRuleSerializationMap) {
    HostRuleSerializationMap[HostRuleSerializationMap["Syntax"] = 1] = "Syntax";
    HostRuleSerializationMap[HostRuleSerializationMap["Raws"] = 2] = "Raws";
    HostRuleSerializationMap[HostRuleSerializationMap["Ip"] = 3] = "Ip";
    HostRuleSerializationMap[HostRuleSerializationMap["HostnameList"] = 4] = "HostnameList";
    HostRuleSerializationMap[HostRuleSerializationMap["Comment"] = 5] = "Comment";
    HostRuleSerializationMap[HostRuleSerializationMap["Start"] = 6] = "Start";
    HostRuleSerializationMap[HostRuleSerializationMap["End"] = 7] = "End";
})(HostRuleSerializationMap || (HostRuleSerializationMap = {}));
/**
 * Property map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent a property.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 */
var HostnameListNodeSerializationMap;
(function (HostnameListNodeSerializationMap) {
    HostnameListNodeSerializationMap[HostnameListNodeSerializationMap["Children"] = 1] = "Children";
    HostnameListNodeSerializationMap[HostnameListNodeSerializationMap["Start"] = 2] = "Start";
    HostnameListNodeSerializationMap[HostnameListNodeSerializationMap["End"] = 3] = "End";
})(HostnameListNodeSerializationMap || (HostnameListNodeSerializationMap = {}));
/**
 * `HostRuleParser` is responsible for parsing hosts-like rules.
 *
 * HostRule is a structure for simple host-level rules (i.e. /etc/hosts syntax).
 * It also supports "just domain" syntax. In this case, the IP will be set to 0.0.0.0.
 *
 * Rules syntax looks like this:
 * ```text
 * IP_address canonical_hostname [aliases...]
 * ```
 *
 * @example
 * `192.168.1.13 bar.mydomain.org bar` -- ipv4
 * `ff02::1 ip6-allnodes` -- ipv6
 * `::1 localhost ip6-localhost ip6-loopback` -- ipv6 aliases
 * `example.org` -- "just domain" syntax
 * @see {@link http://man7.org/linux/man-pages/man5/hosts.5.html}
 */
class HostRuleParser extends ParserBase {
    static NULL_IP = '0.0.0.0';
    static COMMENT_MARKER = '#';
    /**
     * Parses an etc/hosts-like rule.
     *
     * @param raw Raw input to parse.
     * @param options Global parser options.
     * @param baseOffset Starting offset of the input. Node locations are calculated relative to this offset.
     * @returns Host rule node.
     *
     * @throws If the input contains invalid data.
     */
    static parse(raw, options = defaultParserOptions, baseOffset = 0) {
        let offset = StringUtils.skipWS(raw, 0);
        const parts = [];
        let lastPartStartIndex = offset;
        let comment = null;
        const rawLength = raw.length;
        const parsePartIfNeeded = (startIndex, endIndex) => {
            if (startIndex < endIndex) {
                parts.push(ValueParser.parse(raw.slice(startIndex, endIndex), options, baseOffset + startIndex));
            }
        };
        while (offset < rawLength) {
            if (StringUtils.isWhitespace(raw[offset])) {
                parsePartIfNeeded(lastPartStartIndex, offset);
                offset = StringUtils.skipWS(raw, offset);
                lastPartStartIndex = offset;
            }
            else if (raw[offset] === HostRuleParser.COMMENT_MARKER) {
                const commentStart = offset;
                offset = StringUtils.skipWS(raw, offset + 1);
                comment = ValueParser.parse(raw.slice(offset), options, baseOffset + commentStart);
                offset = rawLength;
                lastPartStartIndex = offset;
            }
            else {
                offset += 1;
            }
        }
        parsePartIfNeeded(lastPartStartIndex, offset);
        const partsLength = parts.length;
        if (partsLength < 1) {
            throw new Error('Host rule must have at least one domain name or an IP address and a domain name');
        }
        const result = {
            category: RuleCategory.Network,
            type: NetworkRuleType.HostRule,
            syntax: AdblockSyntax.Common,
        };
        if (partsLength === 1) {
            // "Just domain" syntax, e.g. `example.org`
            // In this case, domain should be valid and IP will be set to 0.0.0.0 by default
            if (getDomain(parts[0].value) !== parts[0].value) {
                throw new Error(`Not a valid domain: ${parts[0].value}`);
            }
            result.ip = {
                type: 'Value',
                value: HostRuleParser.NULL_IP,
            };
            result.hostnames = {
                type: 'HostnameList',
                children: parts,
            };
        }
        else if (partsLength > 1) {
            // IP + domain list syntax
            const [ip, ...hostnames] = parts;
            if (!is_ip(ip.value)) {
                throw new Error(`Invalid IP address: ${ip.value}`);
            }
            for (const { value } of hostnames) {
                if (getHostname(value) !== value) {
                    throw new Error(`Not a valid hostname: ${value}`);
                }
            }
            result.ip = ip;
            result.hostnames = {
                type: 'HostnameList',
                children: hostnames,
            };
        }
        if (comment) {
            result.comment = comment;
        }
        if (options.includeRaws) {
            result.raws = {
                text: raw,
            };
        }
        return result;
    }
    /**
     * Converts a host rule node to a raw string.
     *
     * @param node Host rule node.
     * @returns Raw string.
     */
    static generate(node) {
        const result = [];
        if (node.ip) {
            result.push(node.ip.value);
        }
        if (node.hostnames) {
            result.push(SPACE);
            result.push(node.hostnames.children.map(({ value }) => value).join(SPACE));
        }
        if (node.comment) {
            result.push(SPACE);
            result.push(HostRuleParser.COMMENT_MARKER);
            result.push(SPACE);
            result.push(node.comment.value);
        }
        return result.join(EMPTY);
    }
    /**
     * Serializes a hostname list node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     */
    static serializeHostnameList(node, buffer) {
        buffer.writeUint8(BinaryTypeMap.HostnameListNode);
        if (!isUndefined(node.start)) {
            buffer.writeUint8(HostnameListNodeSerializationMap.Start);
            buffer.writeUint32(node.start);
        }
        if (!isUndefined(node.end)) {
            buffer.writeUint8(HostnameListNodeSerializationMap.End);
            buffer.writeUint32(node.end);
        }
        const count = node.children.length;
        if (count) {
            // note: we store the count, because re-construction of the array is faster if we know the length
            if (count > UINT16_MAX) {
                throw new Error(`Too many children: ${count}, the limit is ${UINT16_MAX}`);
            }
            buffer.writeUint8(HostnameListNodeSerializationMap.Children);
            buffer.writeUint16(count);
            for (let i = 0; i < count; i += 1) {
                ValueParser.serialize(node.children[i], buffer);
            }
        }
        buffer.writeUint8(NULL);
    }
    /**
     * Deserializes a hostname list node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     */
    static deserializeHostnameList(buffer, node) {
        buffer.assertUint8(BinaryTypeMap.HostnameListNode);
        node.type = 'HostnameList';
        let prop = buffer.readUint8();
        while (prop !== NULL) {
            switch (prop) {
                case HostnameListNodeSerializationMap.Children:
                    node.children = new Array(buffer.readUint16());
                    // read children
                    for (let i = 0; i < node.children.length; i += 1) {
                        ValueParser.deserialize(buffer, node.children[i] = {});
                    }
                    break;
                case HostnameListNodeSerializationMap.Start:
                    node.start = buffer.readUint32();
                    break;
                case HostnameListNodeSerializationMap.End:
                    node.end = buffer.readUint32();
                    break;
                default:
                    throw new Error(`Unknown property: ${prop}`);
            }
            prop = buffer.readUint8();
        }
    }
    /**
     * Serializes a host rule node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     */
    // TODO: add support for raws, if ever needed
    static serialize(node, buffer) {
        buffer.writeUint8(BinaryTypeMap.HostRuleNode);
        buffer.writeUint8(HostRuleSerializationMap.Syntax);
        buffer.writeUint8(SYNTAX_SERIALIZATION_MAP.get(node.syntax) ?? 0);
        if (node.ip) {
            buffer.writeUint8(HostRuleSerializationMap.Ip);
            ValueParser.serialize(node.ip, buffer);
        }
        if (node.hostnames) {
            buffer.writeUint8(HostRuleSerializationMap.HostnameList);
            HostRuleParser.serializeHostnameList(node.hostnames, buffer);
        }
        if (node.comment) {
            buffer.writeUint8(HostRuleSerializationMap.Comment);
            ValueParser.serialize(node.comment, buffer);
        }
        if (!isUndefined(node.start)) {
            buffer.writeUint8(HostRuleSerializationMap.Start);
            buffer.writeUint32(node.start);
        }
        if (!isUndefined(node.end)) {
            buffer.writeUint8(HostRuleSerializationMap.End);
            buffer.writeUint32(node.end);
        }
        buffer.writeUint8(NULL);
    }
    /**
     * Deserializes a modifier node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     */
    static deserialize(buffer, node) {
        buffer.assertUint8(BinaryTypeMap.HostRuleNode);
        node.category = RuleCategory.Network;
        node.type = NetworkRuleType.HostRule;
        let prop = buffer.readUint8();
        while (prop !== NULL) {
            switch (prop) {
                case HostRuleSerializationMap.Syntax:
                    node.syntax = SYNTAX_DESERIALIZATION_MAP.get(buffer.readUint8()) ?? AdblockSyntax.Common;
                    break;
                case HostRuleSerializationMap.Ip:
                    node.ip = {};
                    ValueParser.deserialize(buffer, node.ip);
                    break;
                case HostRuleSerializationMap.HostnameList:
                    node.hostnames = {};
                    HostRuleParser.deserializeHostnameList(buffer, node.hostnames);
                    break;
                case HostRuleSerializationMap.Comment:
                    node.comment = {};
                    ValueParser.deserialize(buffer, node.comment);
                    break;
                case HostRuleSerializationMap.Start:
                    node.start = buffer.readUint32();
                    break;
                case HostRuleSerializationMap.End:
                    node.end = buffer.readUint32();
                    break;
                default:
                    throw new Error(`Invalid property: ${prop}.`);
            }
            prop = buffer.readUint8();
        }
    }
}

/* eslint-disable no-param-reassign */
/**
 * Property map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent a property.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 */
var EmptyRuleSerializationMap;
(function (EmptyRuleSerializationMap) {
    EmptyRuleSerializationMap[EmptyRuleSerializationMap["Start"] = 1] = "Start";
    EmptyRuleSerializationMap[EmptyRuleSerializationMap["End"] = 2] = "End";
})(EmptyRuleSerializationMap || (EmptyRuleSerializationMap = {}));
/**
 * Property map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent a property.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 */
var InvalidRuleErrorNodeSerializationMap;
(function (InvalidRuleErrorNodeSerializationMap) {
    InvalidRuleErrorNodeSerializationMap[InvalidRuleErrorNodeSerializationMap["Name"] = 1] = "Name";
    InvalidRuleErrorNodeSerializationMap[InvalidRuleErrorNodeSerializationMap["Message"] = 2] = "Message";
    InvalidRuleErrorNodeSerializationMap[InvalidRuleErrorNodeSerializationMap["Start"] = 3] = "Start";
    InvalidRuleErrorNodeSerializationMap[InvalidRuleErrorNodeSerializationMap["End"] = 4] = "End";
})(InvalidRuleErrorNodeSerializationMap || (InvalidRuleErrorNodeSerializationMap = {}));
/**
 * Property map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent a property.
 *
 * ! IMPORTANT: If you change values here, please update the binary schema version.!
 *
 * @note Only 256 values can be represented this way.
 */
var InvalidRuleSerializationMap;
(function (InvalidRuleSerializationMap) {
    InvalidRuleSerializationMap[InvalidRuleSerializationMap["Error"] = 1] = "Error";
    InvalidRuleSerializationMap[InvalidRuleSerializationMap["Start"] = 2] = "Start";
    InvalidRuleSerializationMap[InvalidRuleSerializationMap["End"] = 3] = "End";
})(InvalidRuleSerializationMap || (InvalidRuleSerializationMap = {}));
/**
 * `RuleParser` is responsible for parsing the rules.
 *
 * It automatically determines the category and syntax of the rule, so you can pass any kind of rule to it.
 */
class RuleParser extends ParserBase {
    /**
     * Helper method to parse host rules if the `parseHostRules` option is enabled, otherwise it will
     * parse network rules.
     *
     * @param raw Raw input to parse.
     * @param options Global parser options.
     * @param baseOffset Starting offset of the input. Node locations are calculated relative to this offset.
     * @returns Host rule or network rule node.
     */
    static parseHostOrNetworkRule(raw, options, baseOffset) {
        if (options.parseHostRules) {
            try {
                return HostRuleParser.parse(raw, options, baseOffset);
            }
            catch (error) {
                // Ignore the error, and fall back to network rule parser
            }
        }
        return NetworkRuleParser.parse(raw, options, baseOffset);
    }
    /**
     * Parse an adblock rule. You can pass any kind of rule to this method, since it will automatically determine
     * the category and syntax. If the rule is syntactically invalid, then an error will be thrown. If the
     * syntax / compatibility cannot be determined clearly, then the value of the `syntax` property will be
     * `Common`.
     *
     * For example, let's have this network rule:
     * ```adblock
     * ||example.org^$important
     * ```
     * The `syntax` property will be `Common`, since the rule is syntactically correct in every adblockers, but we
     * cannot determine at parsing level whether `important` is an existing option or not, nor if it exists, then
     * which adblocker supports it. This is why the `syntax` property is simply `Common` at this point.
     * The concrete COMPATIBILITY of the rule will be determined later, in a different, higher-level layer, called
     * "Compatibility table".
     *
     * But we can determinate the concrete syntax of this rule:
     * ```adblock
     * example.org#%#//scriptlet("scriptlet0", "arg0")
     * ```
     * since it is clearly an AdGuard-specific rule and no other adblockers uses this syntax natively. However, we also
     * cannot determine the COMPATIBILITY of this rule, as it is not clear at this point whether the `scriptlet0`
     * scriptlet is supported by AdGuard or not. This is also the task of the "Compatibility table". Here, we simply
     * mark the rule with the `AdGuard` syntax in this case.
     *
     * @param raw Raw input to parse.
     * @param options Global parser options.
     * @param baseOffset Starting offset of the input. Node locations are calculated relative to this offset.
     * @returns Adblock rule node
     * @throws If the input matches a pattern but syntactically invalid
     * @example
     * Take a look at the following example:
     * ```js
     * // Parse a network rule
     * const ast1 = RuleParser.parse("||example.org^$important");
     *
     * // Parse another network rule
     * const ast2 = RuleParser.parse("/ads.js^$important,third-party,domain=example.org|~example.com");
     *
     * // Parse a cosmetic rule
     * const ast2 = RuleParser.parse("example.org##.banner");
     *
     * // Parse another cosmetic rule
     * const ast3 = RuleParser.parse("example.org#?#.banner:-abp-has(.ad)");
     *
     * // Parse a comment rule
     * const ast4 = RuleParser.parse("! Comment");
     *
     * // Parse an empty rule
     * const ast5 = RuleParser.parse("");
     *
     * // Parse a comment rule (with metadata)
     * const ast6 = RuleParser.parse("! Title: Example");
     *
     * // Parse a pre-processor rule
     * const ast7 = RuleParser.parse("!#if (adguard)");
     * ```
     */
    static parse(raw, options = defaultParserOptions, baseOffset = 0) {
        try {
            // Empty lines / rules (handle it just for convenience)
            if (raw.trim().length === 0) {
                const result = {
                    type: 'EmptyRule',
                    category: RuleCategory.Empty,
                    syntax: AdblockSyntax.Common,
                };
                if (options.includeRaws) {
                    result.raws = {
                        text: raw,
                    };
                }
                if (options.isLocIncluded) {
                    result.start = baseOffset;
                    result.end = baseOffset + raw.length;
                }
                return result;
            }
            // Try to parse the rule with all sub-parsers. If a rule doesn't match
            // the pattern of a parser, then it will return `null`. For example, a
            // network rule will not match the pattern of a comment rule, since it
            // doesn't start with comment marker. But if the rule matches the
            // pattern of a parser, then it will return the AST of the rule, or
            // throw an error if the rule is syntactically invalid.
            if (options.ignoreComments) {
                if (CommentRuleParser.isCommentRule(raw)) {
                    const result = {
                        type: 'EmptyRule',
                        category: RuleCategory.Empty,
                        syntax: AdblockSyntax.Common,
                    };
                    if (options.includeRaws) {
                        result.raws = {
                            text: raw,
                        };
                    }
                    if (options.isLocIncluded) {
                        result.start = baseOffset;
                        result.end = baseOffset + raw.length;
                    }
                    return result;
                }
                return CosmeticRuleParser.parse(raw, options, baseOffset)
                    || RuleParser.parseHostOrNetworkRule(raw, options, baseOffset);
            }
            return CommentRuleParser.parse(raw, options, baseOffset)
                || CosmeticRuleParser.parse(raw, options, baseOffset)
                || RuleParser.parseHostOrNetworkRule(raw, options, baseOffset);
        }
        catch (error) {
            // If tolerant mode is disabled or the error is not known, then simply
            // re-throw the error
            if (!options.tolerant || !(error instanceof Error)) {
                throw error;
            }
            const errorNode = {
                type: 'InvalidRuleError',
                name: error.name,
                message: error.message,
            };
            // If the error is an AdblockSyntaxError, then we can add the
            // location of the error to the result
            if (error instanceof AdblockSyntaxError) {
                errorNode.start = error.start;
                errorNode.end = error.end;
            }
            // Otherwise, return an invalid rule (tolerant mode)
            const result = {
                type: 'InvalidRule',
                category: RuleCategory.Invalid,
                syntax: AdblockSyntax.Common,
                raw,
                error: errorNode,
            };
            if (options.includeRaws) {
                result.raws = {
                    text: raw,
                };
            }
            if (options.isLocIncluded) {
                result.start = baseOffset;
                result.end = baseOffset + raw.length;
            }
            return result;
        }
    }
    /**
     * Converts a rule AST to a string.
     *
     * @param ast - Adblock rule AST
     * @returns Raw string
     * @example
     * Take a look at the following example:
     * ```js
     * // Parse the rule to the AST
     * const ast = RuleParser.parse("example.org##.banner");
     * // Generate the rule from the AST
     * const raw = RuleParser.generate(ast);
     * // Print the generated rule
     * console.log(raw); // "example.org##.banner"
     * ```
     */
    static generate(ast) {
        switch (ast.category) {
            // Empty lines
            case RuleCategory.Empty:
                return EMPTY;
            // Invalid rules
            case RuleCategory.Invalid:
                return ast.raw;
            // Comment rules
            case RuleCategory.Comment:
                return CommentRuleParser.generate(ast);
            // Cosmetic / non-basic rules
            case RuleCategory.Cosmetic:
                return CosmeticRuleParser.generate(ast);
            // Network / basic rules
            case RuleCategory.Network:
                switch (ast.type) {
                    case NetworkRuleType.HostRule:
                        return HostRuleParser.generate(ast);
                    case NetworkRuleType.NetworkRule:
                        return NetworkRuleParser.generate(ast);
                    default:
                        throw new Error('Unknown network rule type');
                }
            default:
                throw new Error('Unknown rule category');
        }
    }
    /**
     * Serializes an empty rule node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     */
    static serializeEmptyRule(node, buffer) {
        buffer.writeUint8(BinaryTypeMap.EmptyRule);
        if (!isUndefined(node.start)) {
            buffer.writeUint8(EmptyRuleSerializationMap.Start);
            buffer.writeUint32(node.start);
        }
        if (!isUndefined(node.end)) {
            buffer.writeUint8(EmptyRuleSerializationMap.End);
            buffer.writeUint32(node.end);
        }
        buffer.writeUint8(NULL);
    }
    /**
     * Deserializes an empty rule node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     */
    static deserializeEmptyRule(buffer, node) {
        buffer.assertUint8(BinaryTypeMap.EmptyRule);
        node.type = 'EmptyRule';
        node.category = RuleCategory.Empty;
        node.syntax = AdblockSyntax.Common;
        let prop = buffer.readUint8();
        while (prop !== NULL) {
            switch (prop) {
                case EmptyRuleSerializationMap.Start:
                    node.start = buffer.readUint32();
                    break;
                case EmptyRuleSerializationMap.End:
                    node.end = buffer.readUint32();
                    break;
                default:
                    throw new Error(`Invalid property: ${prop}.`);
            }
            prop = buffer.readUint8();
        }
    }
    /**
     * Serializes an invalid rule error node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     */
    static serializeInvalidRuleErrorNode(node, buffer) {
        buffer.writeUint8(BinaryTypeMap.InvalidRuleErrorNode);
        buffer.writeUint8(InvalidRuleErrorNodeSerializationMap.Name);
        buffer.writeString(node.name);
        buffer.writeUint8(InvalidRuleErrorNodeSerializationMap.Message);
        buffer.writeString(node.message);
        if (!isUndefined(node.start)) {
            buffer.writeUint8(InvalidRuleErrorNodeSerializationMap.Start);
            buffer.writeUint32(node.start);
        }
        if (!isUndefined(node.end)) {
            buffer.writeUint8(InvalidRuleErrorNodeSerializationMap.End);
            buffer.writeUint32(node.end);
        }
        buffer.writeUint8(NULL);
    }
    /**
     * Deserializes an invalid rule error node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     */
    static deserializeInvalidRuleErrorNode(buffer, node) {
        buffer.assertUint8(BinaryTypeMap.InvalidRuleErrorNode);
        node.type = 'InvalidRuleError';
        let prop = buffer.readUint8();
        while (prop !== NULL) {
            switch (prop) {
                case InvalidRuleErrorNodeSerializationMap.Name:
                    node.name = buffer.readString();
                    break;
                case InvalidRuleErrorNodeSerializationMap.Message:
                    node.message = buffer.readString();
                    break;
                case InvalidRuleErrorNodeSerializationMap.Start:
                    node.start = buffer.readUint32();
                    break;
                case InvalidRuleErrorNodeSerializationMap.End:
                    node.end = buffer.readUint32();
                    break;
                default:
                    throw new Error(`Invalid property: ${prop}.`);
            }
            prop = buffer.readUint8();
        }
    }
    /**
     * Serializes an invalid rule node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     */
    static serializeInvalidRule(node, buffer) {
        buffer.writeUint8(BinaryTypeMap.InvalidRule);
        buffer.writeUint8(InvalidRuleSerializationMap.Error);
        RuleParser.serializeInvalidRuleErrorNode(node.error, buffer);
        if (!isUndefined(node.start)) {
            buffer.writeUint8(InvalidRuleSerializationMap.Start);
            buffer.writeUint32(node.start);
        }
        if (!isUndefined(node.end)) {
            buffer.writeUint8(InvalidRuleSerializationMap.End);
            buffer.writeUint32(node.end);
        }
        buffer.writeUint8(NULL);
    }
    /**
     * Deserializes an invalid rule node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     */
    static deserializeInvalidRule(buffer, node) {
        buffer.assertUint8(BinaryTypeMap.InvalidRule);
        node.type = 'InvalidRule';
        node.category = RuleCategory.Invalid;
        let prop = buffer.readUint8();
        while (prop !== NULL) {
            switch (prop) {
                case InvalidRuleSerializationMap.Error:
                    RuleParser.deserializeInvalidRuleErrorNode(buffer, node.error = {});
                    break;
                case InvalidRuleSerializationMap.Start:
                    node.start = buffer.readUint32();
                    break;
                case InvalidRuleSerializationMap.End:
                    node.end = buffer.readUint32();
                    break;
                default:
                    throw new Error(`Invalid property: ${prop}.`);
            }
            prop = buffer.readUint8();
        }
    }
    /**
     * Serializes a rule node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     */
    // TODO: add support for raws, if ever needed
    static serialize(node, buffer) {
        switch (node.category) {
            case RuleCategory.Comment:
                CommentRuleParser.serialize(node, buffer);
                break;
            case RuleCategory.Cosmetic:
                CosmeticRuleParser.serialize(node, buffer);
                break;
            case RuleCategory.Network:
                switch (node.type) {
                    case NetworkRuleType.HostRule:
                        HostRuleParser.serialize(node, buffer);
                        break;
                    case NetworkRuleType.NetworkRule:
                        NetworkRuleParser.serialize(node, buffer);
                        break;
                    default:
                        throw new Error('Unknown network rule type');
                }
                break;
            case RuleCategory.Empty:
                RuleParser.serializeEmptyRule(node, buffer);
                break;
            case RuleCategory.Invalid:
                RuleParser.serializeInvalidRule(node, buffer);
                break;
            default:
                throw new Error('Unknown rule category');
        }
    }
    /**
     * Deserializes a rule node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     */
    static deserialize(buffer, node) {
        // lookup instead of storing +1 byte
        const type = buffer.peekUint8();
        switch (type) {
            case BinaryTypeMap.AgentRuleNode:
            case BinaryTypeMap.HintRuleNode:
            case BinaryTypeMap.PreProcessorCommentRuleNode:
            case BinaryTypeMap.MetadataCommentRuleNode:
            case BinaryTypeMap.ConfigCommentRuleNode:
            case BinaryTypeMap.CommentRuleNode:
                CommentRuleParser.deserialize(buffer, node);
                break;
            case BinaryTypeMap.ElementHidingRule:
            case BinaryTypeMap.CssInjectionRule:
            case BinaryTypeMap.ScriptletInjectionRule:
            case BinaryTypeMap.HtmlFilteringRule:
            case BinaryTypeMap.JsInjectionRule:
                CosmeticRuleParser.deserialize(buffer, node);
                break;
            case BinaryTypeMap.NetworkRuleNode:
                NetworkRuleParser.deserialize(buffer, node);
                break;
            case BinaryTypeMap.HostRuleNode:
                HostRuleParser.deserialize(buffer, node);
                break;
            case BinaryTypeMap.EmptyRule:
                RuleParser.deserializeEmptyRule(buffer, node);
                break;
            case BinaryTypeMap.InvalidRule:
                RuleParser.deserializeInvalidRule(buffer, node);
                break;
            default:
                throw new Error('Unknown rule category');
        }
    }
}

const APP_LIST_SEPARATOR = PIPE;
/**
 * `AppListParser` is responsible for parsing an app list.
 *
 * @see {@link https://adguard.app/kb/general/ad-filtering/create-own-filters/#app-modifier}
 */
class AppListParser extends ParserBase {
    /**
     * Parses an app list which items are separated by `|`,
     * e.g. `Example.exe|com.example.osx`.
     *
     * @param raw Raw input to parse.
     * @param options Global parser options.
     * @param baseOffset Starting offset of the input. Node locations are calculated relative to this offset.
     *
     * @returns App list AST.
     * @throws An {@link AdblockSyntaxError} if the app list is syntactically invalid.
     * @throws An {@link Error} if the options are invalid.
     */
    static parse(raw, options = defaultParserOptions, baseOffset = 0) {
        const result = {
            type: ListNodeType.AppList,
            separator: APP_LIST_SEPARATOR,
            children: parseListItems(raw, options, baseOffset, APP_LIST_SEPARATOR, ListItemNodeType.App),
        };
        if (options.isLocIncluded) {
            result.start = baseOffset;
            result.end = baseOffset + raw.length;
        }
        return result;
    }
}

const METHOD_LIST_SEPARATOR = PIPE;
/**
 * `MethodListParser` is responsible for parsing a method list.
 *
 * @see {@link https://adguard.app/kb/general/ad-filtering/create-own-filters/#method-modifier}
 */
class MethodListParser extends ParserBase {
    /**
     * Parses a method list which items are separated by `|`,
     * e.g. `get|post|put`.
     *
     * @param raw Raw input to parse.
     * @param options Global parser options.
     * @param baseOffset Starting offset of the input. Node locations are calculated relative to this offset.
     *
     * @returns Method list AST.
     * @throws An {@link AdblockSyntaxError} if the method list is syntactically invalid.
     * @throws An {@link Error} if the options are invalid.
     */
    static parse(raw, options = defaultParserOptions, baseOffset = 0) {
        const result = {
            type: ListNodeType.MethodList,
            separator: METHOD_LIST_SEPARATOR,
            children: parseListItems(raw, options, baseOffset, METHOD_LIST_SEPARATOR, ListItemNodeType.Method),
        };
        if (options.isLocIncluded) {
            result.start = baseOffset;
            result.end = baseOffset + raw.length;
        }
        return result;
    }
}

const STEALTH_OPTION_LIST_SEPARATOR = PIPE;
/**
 * `StealthOptionListParser` is responsible for parsing a list of stealth options.
 *
 * @see {@link https://adguard.app/kb/general/ad-filtering/create-own-filters/#stealth-modifier}
 */
class StealthOptionListParser extends ParserBase {
    /**
     * Parses a stealth option list which items are separated by `|`,
     * e.g. `dpi|ip`.
     *
     * @param raw Raw input to parse.
     * @param options Global parser options.
     * @param baseOffset Starting offset of the input. Node locations are calculated relative to this offset.
     *
     * @returns Stealth option list AST.
     * @throws An {@link AdblockSyntaxError} if the stealth option list is syntactically invalid.
     * @throws An {@link Error} if the options are invalid.
     */
    static parse(raw, options = defaultParserOptions, baseOffset = 0) {
        const result = {
            type: ListNodeType.StealthOptionList,
            separator: STEALTH_OPTION_LIST_SEPARATOR,
            // eslint-disable-next-line max-len
            children: parseListItems(raw, options, baseOffset, STEALTH_OPTION_LIST_SEPARATOR, ListItemNodeType.StealthOption),
        };
        if (options.isLocIncluded) {
            result.start = baseOffset;
            result.end = baseOffset + raw.length;
        }
        return result;
    }
}

/* eslint-disable no-param-reassign */
/**
 * Property map for binary serialization. This helps to reduce the size of the serialized data,
 * as it allows us to use a single byte to represent a property.
 *
 * ! IMPORTANT: If you change values here, please update the {@link BINARY_SCHEMA_VERSION}!
 *
 * @note Only 256 values can be represented this way.
 */
var FilterListNodeSerializationMap;
(function (FilterListNodeSerializationMap) {
    FilterListNodeSerializationMap[FilterListNodeSerializationMap["Children"] = 1] = "Children";
    FilterListNodeSerializationMap[FilterListNodeSerializationMap["Start"] = 2] = "Start";
    FilterListNodeSerializationMap[FilterListNodeSerializationMap["End"] = 3] = "End";
})(FilterListNodeSerializationMap || (FilterListNodeSerializationMap = {}));
/**
 * `FilterListParser` is responsible for parsing a whole adblock filter list (list of rules).
 * It is a wrapper around `RuleParser` which parses each line separately.
 */
class FilterListParser extends (/* unused pure expression or super */ null && (ParserBase)) {
    /**
     * Parses a whole adblock filter list (list of rules).
     *
     * @param raw Raw input to parse.
     * @param options Global parser options.
     * @param baseOffset Starting offset of the input. Node locations are calculated relative to this offset.
     * @returns AST of the source code (list of rules)
     * @example
     * ```js
     * import { readFileSync } from 'fs';
     * import { FilterListParser } from '@adguard/agtree';
     *
     * // Read filter list content from file
     * const content = readFileSync('your-adblock-filter-list.txt', 'utf-8');
     *
     * // Parse the filter list content, then do something with the AST
     * const ast = FilterListParser.parse(content);
     * ```
     * @throws If one of the rules is syntactically invalid (if `tolerant` is `false`)
     */
    static parse(raw, options = defaultParserOptions, baseOffset = 0) {
        // Actual position in the source code
        let offset = 0;
        // Collect adblock rules here
        const rules = [];
        // Start offset of the current line (initially it's 0)
        let lineStartOffset = offset;
        while (offset < raw.length) {
            // Check if we found a new line
            if (StringUtils.isEOL(raw[offset])) {
                // Rule text
                const text = raw.slice(lineStartOffset, offset);
                // Parse the rule
                const rule = RuleParser.parse(text, options, lineStartOffset);
                // Get newline type (possible values: 'crlf', 'lf', 'cr' or undefined if no newline found)
                let nl;
                if (raw[offset] === CR) {
                    if (raw[offset + 1] === LF) {
                        nl = 'crlf';
                    }
                    else {
                        nl = 'cr';
                    }
                }
                else if (raw[offset] === LF) {
                    nl = 'lf';
                }
                // Add newline type to the rule (rule parser already added raws.text)
                if (!rule.raws) {
                    rule.raws = {
                        text,
                        nl,
                    };
                }
                else {
                    rule.raws.nl = nl;
                }
                // Add the rule to the list
                rules.push(rule);
                // Update offset: add 2 if we found CRLF, otherwise add 1
                offset += nl === 'crlf' ? 2 : 1;
                // Update line start offset
                lineStartOffset = offset;
            }
            else {
                // No new line found, just increase offset
                offset += 1;
            }
        }
        // Parse the last rule (it doesn't end with a new line)
        rules.push(RuleParser.parse(raw.slice(lineStartOffset, offset), options, baseOffset + lineStartOffset));
        // Return the list of rules (FilterList node)
        const result = {
            type: 'FilterList',
            children: rules,
        };
        if (options.isLocIncluded) {
            result.start = baseOffset;
            result.end = baseOffset + raw.length;
        }
        return result;
    }
    /**
     * Serializes a whole adblock filter list (list of rules).
     *
     * @param ast AST to generate
     * @param preferRaw If `true`, then the parser will use `raws.text` property of each rule
     * if it is available. Default is `false`.
     * @returns Serialized filter list
     */
    static generate(ast, preferRaw = false) {
        let result = EMPTY;
        for (let i = 0; i < ast.children.length; i += 1) {
            const rule = ast.children[i];
            if (preferRaw && rule.raws?.text) {
                result += rule.raws.text;
            }
            else {
                result += RuleParser.generate(rule);
            }
            switch (rule.raws?.nl) {
                case 'crlf':
                    result += CRLF;
                    break;
                case 'cr':
                    result += CR;
                    break;
                case 'lf':
                    result += LF;
                    break;
                default:
                    if (i !== ast.children.length - 1) {
                        result += LF;
                    }
                    break;
            }
        }
        return result;
    }
    /**
     * Serializes a filter list node to binary format.
     *
     * @param node Node to serialize.
     * @param buffer ByteBuffer for writing binary data.
     */
    // TODO: add support for raws, if ever needed
    static serialize(node, buffer) {
        buffer.writeUint8(BinaryTypeMap.FilterListNode);
        buffer.writeUint8(FilterListNodeSerializationMap.Children);
        const count = node.children.length;
        buffer.writeUint32(count);
        for (let i = 0; i < count; i += 1) {
            RuleParser.serialize(node.children[i], buffer);
        }
        if (!isUndefined(node.start)) {
            buffer.writeUint8(FilterListNodeSerializationMap.Start);
            buffer.writeUint32(node.start);
        }
        if (!isUndefined(node.end)) {
            buffer.writeUint8(FilterListNodeSerializationMap.End);
            buffer.writeUint32(node.end);
        }
        buffer.writeUint8(NULL);
    }
    /**
     * Deserializes a filter list node from binary format.
     *
     * @param buffer ByteBuffer for reading binary data.
     * @param node Destination node.
     */
    static deserialize(buffer, node) {
        buffer.assertUint8(BinaryTypeMap.FilterListNode);
        node.type = 'FilterList';
        let prop = buffer.readUint8();
        while (prop !== NULL) {
            switch (prop) {
                case FilterListNodeSerializationMap.Children:
                    node.children = new Array(buffer.readUint32());
                    for (let i = 0; i < node.children.length; i += 1) {
                        RuleParser.deserialize(buffer, node.children[i] = {});
                    }
                    break;
                case FilterListNodeSerializationMap.Start:
                    node.start = buffer.readUint32();
                    break;
                case FilterListNodeSerializationMap.End:
                    node.end = buffer.readUint32();
                    break;
                default:
                    throw new Error(`Invalid property: ${prop}.`);
            }
            prop = buffer.readUint8();
        }
    }
    /**
     * Helper method to jump to the children of the filter list node.
     *
     * Filter lists serialized in binary format are structured as follows:
     * - `FilterListNode` filter list node indicator (1 byte)
     * - Properties:
     *      - `Children` (1 byte) - children count, followed by children nodes
     *      - `Start` (1 byte) - start offset, if present, followed by the value
     *      - `End` (1 byte) - end offset, if present, followed by the value
     *      - `NULL` (1 byte) - closing indicator
     *
     * This method skips indicators, reads the children count and returns it.
     * This way the buffer is positioned at the beginning of the children nodes.
     *
     * @param buffer Reference to the input byte buffer.
     * @returns Number of children nodes.
     */
    static jumpToChildren(buffer) {
        buffer.assertUint8(BinaryTypeMap.FilterListNode); // filter list indicator
        let prop = buffer.readUint8();
        while (prop) {
            switch (prop) {
                case FilterListNodeSerializationMap.Children:
                    return buffer.readUint32();
                case FilterListNodeSerializationMap.Start:
                case FilterListNodeSerializationMap.End:
                    buffer.readUint32(); // ignore value
                    break;
                default:
                    throw new Error(`Invalid property: ${prop}.`);
            }
            prop = buffer.readUint8();
        }
        return 0;
    }
}

/**
 * @file Customized error class for conversion errors.
 */
const ERROR_NAME$1 = 'RuleConversionError';
/**
 * Customized error class for conversion errors.
 */
class RuleConversionError extends Error {
    /**
     * Constructs a new `RuleConversionError` instance.
     *
     * @param message Error message
     */
    constructor(message) {
        super(message);
        this.name = ERROR_NAME$1;
    }
}

/**
 * @file Customized error for binary schema mismatch.
 */
const ERROR_NAME = 'BinarySchemaMismatchError';
/**
 * Customized error for binary schema mismatch.
 */
class BinarySchemaMismatchError extends Error {
    /**
     * Expected schema version.
     */
    expectedVersion;
    /**
     * Actual schema version.
     */
    actualVersion;
    /**
     * Constructs a new `BinarySchemaMismatchError` instance.
     *
     * @param expectedVersion Expected schema version.
     * @param actualVersion Actual schema version.
     */
    constructor(expectedVersion, actualVersion) {
        super(`Expected schema version ${expectedVersion}, but got ${actualVersion}`);
        this.name = ERROR_NAME;
        this.expectedVersion = expectedVersion;
        this.actualVersion = actualVersion;
    }
}

/**
 * Prefixes for different adblockers to describe the platform-specific modifiers data
 * stored in the yaml files.
 */
const BLOCKER_PREFIX = {
    [AdblockSyntax.Adg]: 'adg_',
    [AdblockSyntax.Ubo]: 'ubo_',
    [AdblockSyntax.Abp]: 'abp_',
};
/**
 * Set of all allowed characters for app name except the dot `.`.
 */
const APP_NAME_ALLOWED_CHARS = new Set([
    ...CAPITAL_LETTERS,
    ...SMALL_LETTERS,
    ...NUMBERS,
    UNDERSCORE,
]);
/**
 * Allowed methods for $method modifier.
 *
 * @see {@link https://adguard.app/kb/general/ad-filtering/create-own-filters/#method-modifier}
 */
const ALLOWED_METHODS = new Set([
    'connect',
    'delete',
    'get',
    'head',
    'options',
    'patch',
    'post',
    'put',
    'trace',
]);
/**
 * Allowed stealth options for $stealth modifier.
 *
 * @see {@link https://adguard.app/kb/general/ad-filtering/create-own-filters/#stealth-modifier}
 */
const ALLOWED_STEALTH_OPTIONS = new Set([
    'searchqueries',
    'donottrack',
    '3p-cookie',
    '1p-cookie',
    '3p-cache',
    '3p-auth',
    'webrtc',
    'push',
    'location',
    'flash',
    'java',
    'referrer',
    'useragent',
    'ip',
    'xclientdata',
    'dpi',
]);
/**
 * Allowed CSP directives for $csp modifier.
 *
 * @see {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy#directives}
 */
const ALLOWED_CSP_DIRECTIVES = new Set([
    'base-uri',
    'child-src',
    'connect-src',
    'default-src',
    'fenced-frame-src',
    'font-src',
    'form-action',
    'frame-ancestors',
    'frame-src',
    'img-src',
    'manifest-src',
    'media-src',
    'navigate-to',
    'object-src',
    'plugin-types',
    'prefetch-src',
    'referrer',
    'report-to',
    'report-uri',
    'require-trusted-types-for',
    'sandbox',
    'script-src',
    'script-src-attr',
    'script-src-elem',
    'style-src',
    'style-src-attr',
    'style-src-elem',
    'trusted-types',
    'upgrade-insecure-requests',
    'worker-src',
]);
/**
 * Allowed directives for $permissions modifier.
 *
 * @see {@link https://adguard.app/kb/general/ad-filtering/create-own-filters/#permissions-modifier}
 */
const ALLOWED_PERMISSION_DIRECTIVES = new Set([
    'accelerometer',
    'ambient-light-sensor',
    'autoplay',
    'battery',
    'browsing-topics',
    'camera',
    'display-capture',
    'document-domain',
    'encrypted-media',
    'execution-while-not-rendered',
    'execution-while-out-of-viewport',
    'fullscreen',
    'gamepad',
    'geolocation',
    'gyroscope',
    'hid',
    'identity-credentials-get',
    'idle-detection',
    'join-ad-interest-group',
    'local-fonts',
    'magnetometer',
    'microphone',
    'midi',
    'payment',
    'picture-in-picture',
    'publickey-credentials-create',
    'publickey-credentials-get',
    'run-ad-auction',
    'screen-wake-lock',
    'serial',
    'speaker-selection',
    'storage-access',
    'usb',
    'web-share',
    'xr-spatial-tracking',
]);
/**
 * One of available tokens for $permission modifier value.
 *
 * @see {@link https://w3c.github.io/webappsec-permissions-policy/#structured-header-serialization}
 */
const PERMISSIONS_TOKEN_SELF = 'self';
/**
 * One of allowlist values for $permissions modifier.
 *
 * @see {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/Permissions_Policy#allowlists}
 */
const EMPTY_PERMISSIONS_ALLOWLIST = `${OPEN_PARENTHESIS}${CLOSE_PARENTHESIS}`;
/**
 * Allowed directives for $referrerpolicy modifier.
 *
 * @see {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy}
 */
const REFERRER_POLICY_DIRECTIVES = new Set([
    'no-referrer',
    'no-referrer-when-downgrade',
    'origin',
    'origin-when-cross-origin',
    'same-origin',
    'strict-origin',
    'strict-origin-when-cross-origin',
    'unsafe-url',
]);
/**
 * Prefixes for error messages used in modifier validation.
 */
const VALIDATION_ERROR_PREFIX = {
    BLOCK_ONLY: 'Only blocking rules may contain the modifier',
    EXCEPTION_ONLY: 'Only exception rules may contain the modifier',
    INVALID_CSP_DIRECTIVES: 'Invalid CSP directives for the modifier',
    INVALID_LIST_VALUES: 'Invalid values for the modifier',
    INVALID_NOOP: 'Invalid noop modifier',
    INVALID_PERMISSION_DIRECTIVE: 'Invalid Permissions-Policy directive for the modifier',
    INVALID_PERMISSION_ORIGINS: 'Origins in the value is invalid for the modifier and the directive',
    INVALID_PERMISSION_ORIGIN_QUOTES: 'Double quotes should be used for origins in the value of the modifier',
    INVALID_REFERRER_POLICY_DIRECTIVE: 'Invalid Referrer-Policy directive for the modifier',
    MIXED_NEGATIONS: 'Simultaneous usage of negated and not negated values is forbidden for the modifier',
    NO_CSP_VALUE: 'No CSP value for the modifier and the directive',
    NO_CSP_DIRECTIVE_QUOTE: 'CSP directives should no be quoted for the modifier',
    NO_UNESCAPED_PERMISSION_COMMA: 'Unescaped comma in the value is not allowed for the modifier',
    // TODO: implement later for $scp and $permissions
    // NO_VALUE_ONLY_FOR_EXCEPTION: 'Modifier without value can be used only in exception rules',
    NOT_EXISTENT: 'Non-existent modifier',
    NOT_NEGATABLE_MODIFIER: 'Non-negatable modifier',
    NOT_NEGATABLE_VALUE: 'Values cannot be negated for the modifier',
    NOT_SUPPORTED: 'The adblocker does not support the modifier',
    REMOVED: 'Removed and no longer supported modifier',
    VALUE_FORBIDDEN: 'Value is not allowed for the modifier',
    VALUE_INVALID: 'Value is invalid for the modifier',
    VALUE_REQUIRED: 'Value is required for the modifier',
};
/**
 * Prefixes for error messages related to issues in the source YAML files' data.
 */
const SOURCE_DATA_ERROR_PREFIX = {
    INVALID_VALUE_FORMAT_REGEXP: "Invalid regular expression in 'value_format' for the modifier",
    NO_DEPRECATION_MESSAGE: "Property 'deprecation_message' is required for the 'deprecated' modifier",
    NO_VALUE_FORMAT_FOR_ASSIGNABLE: "Property 'value_format' should be specified for the assignable modifier",
};

/**
 * Validates the noop modifier (i.e. only underscores).
 *
 * @param value Value of the modifier.
 *
 * @returns True if the modifier is valid, false otherwise.
 */
const isValidNoopModifier = (value) => {
    return value.split('').every((char) => char === UNDERSCORE);
};
/**
 * Returns invalid validation result with given error message.
 *
 * @param error Error message.
 *
 * @returns Validation result `{ valid: false, error }`.
 */
const getInvalidValidationResult = (error) => {
    return {
        valid: false,
        error,
    };
};
/**
 * Returns invalid validation result which uses {@link VALIDATION_ERROR_PREFIX.VALUE_REQUIRED} as prefix
 * and specifies the given `modifierName` in the error message.
 *
 * @param modifierName Modifier name.
 *
 * @returns Validation result `{ valid: false, error }`.
 */
const getValueRequiredValidationResult = (modifierName) => {
    return getInvalidValidationResult(`${VALIDATION_ERROR_PREFIX.VALUE_REQUIRED}: '${modifierName}'`);
};

/**
 * @file Utility functions for domain and hostname validation.
 */
/**
 * Marker for a wildcard top-level domain — `.*`.
 *
 * @example
 * `example.*` — matches with any TLD, e.g. `example.org`, `example.com`, etc.
 */
const WILDCARD_TLD = DOT + WILDCARD;
/**
 * Marker for a wildcard subdomain — `*.`.
 *
 * @example
 * `*.example.org` — matches with any subdomain, e.g. `foo.example.org` or `bar.example.org`
 */
const WILDCARD_SUBDOMAIN = WILDCARD + DOT;
class DomainUtils {
    /**
     * Check if the input is a valid domain or hostname.
     *
     * @param domain Domain to check
     * @returns `true` if the domain is valid, `false` otherwise
     */
    static isValidDomainOrHostname(domain) {
        let domainToCheck = domain;
        // Wildcard-only domain, typically a generic rule
        if (domainToCheck === WILDCARD) {
            return true;
        }
        // https://adguard.com/kb/general/ad-filtering/create-own-filters/#wildcard-for-tld
        if (domainToCheck.endsWith(WILDCARD_TLD)) {
            // Remove the wildcard TLD
            domainToCheck = domainToCheck.substring(0, domainToCheck.length - WILDCARD_TLD.length);
        }
        if (domainToCheck.startsWith(WILDCARD_SUBDOMAIN)) {
            // Remove the wildcard subdomain
            domainToCheck = domainToCheck.substring(WILDCARD_SUBDOMAIN.length);
        }
        // Parse the domain with tldts
        const tldtsResult = parse(domainToCheck);
        // Check if the domain is valid
        return domainToCheck === tldtsResult.domain || domainToCheck === tldtsResult.hostname;
    }
}

/**
 * Pre-defined available validators for modifiers with custom `value_format`.
 */
var CustomValueFormatValidatorName;
(function (CustomValueFormatValidatorName) {
    CustomValueFormatValidatorName["App"] = "pipe_separated_apps";
    CustomValueFormatValidatorName["Csp"] = "csp_value";
    // there are some differences between $domain and $denyallow
    CustomValueFormatValidatorName["DenyAllow"] = "pipe_separated_denyallow_domains";
    CustomValueFormatValidatorName["Domain"] = "pipe_separated_domains";
    CustomValueFormatValidatorName["Method"] = "pipe_separated_methods";
    CustomValueFormatValidatorName["Permissions"] = "permissions_value";
    CustomValueFormatValidatorName["ReferrerPolicy"] = "referrerpolicy_value";
    CustomValueFormatValidatorName["StealthOption"] = "pipe_separated_stealth_options";
})(CustomValueFormatValidatorName || (CustomValueFormatValidatorName = {}));
/**
 * Checks whether the `chunk` of app name (which if splitted by dot `.`) is valid.
 * Only letters, numbers, and underscore `_` are allowed.
 *
 * @param chunk Chunk of app name to check.
 *
 * @returns True if the `chunk` is valid part of app name, false otherwise.
 */
const isValidAppNameChunk = (chunk) => {
    // e.g. 'Example..exe'
    if (chunk.length === 0) {
        return false;
    }
    for (let i = 0; i < chunk.length; i += 1) {
        const char = chunk[i];
        if (!APP_NAME_ALLOWED_CHARS.has(char)) {
            return false;
        }
    }
    return true;
};
/**
 * Checks whether the given `value` is valid app name as $app modifier value.
 *
 * @param value App name to check.
 *
 * @returns True if the `value` is valid app name, false otherwise.
 */
const isValidAppModifierValue = (value) => {
    // $app modifier does not support wildcard tld
    // https://adguard.app/kb/general/ad-filtering/create-own-filters/#app-modifier
    if (value.includes(WILDCARD)) {
        return false;
    }
    return value
        .split(DOT)
        .every((chunk) => isValidAppNameChunk(chunk));
};
/**
 * Checks whether the given `value` is valid HTTP method as $method modifier value.
 *
 * @param value Method to check.
 *
 * @returns True if the `value` is valid HTTP method, false otherwise.
 */
const isValidMethodModifierValue = (value) => {
    return ALLOWED_METHODS.has(value);
};
/**
 * Checks whether the given `value` is valid option as $stealth modifier value.
 *
 * @param value Stealth option to check.
 *
 * @returns True if the `value` is valid stealth option, false otherwise.
 */
const isValidStealthModifierValue = (value) => {
    return ALLOWED_STEALTH_OPTIONS.has(value);
};
/**
 * Checks whether the given `rawOrigin` is valid as Permissions Allowlist origin.
 *
 * @see {@link https://w3c.github.io/webappsec-permissions-policy/#allowlists}
 *
 * @param rawOrigin The raw origin.
 *
 * @returns True if the origin is valid, false otherwise.
 */
const isValidPermissionsOrigin = (rawOrigin) => {
    // origins should be quoted by double quote
    const actualQuoteType = QuoteUtils.getStringQuoteType(rawOrigin);
    if (actualQuoteType !== QuoteType.Double) {
        return false;
    }
    const origin = QuoteUtils.removeQuotes(rawOrigin);
    try {
        // validate the origin by URL constructor
        // https://w3c.github.io/webappsec-permissions-policy/#algo-parse-policy-directive
        new URL(origin);
    }
    catch (e) {
        return false;
    }
    return true;
};
/**
 * Checks whether the given `value` is valid domain as $denyallow modifier value.
 * Important: wildcard tld are not supported, compared to $domain.
 *
 * @param value Value to check.
 *
 * @returns True if the `value` is valid domain and does not contain wildcard `*`, false otherwise.
 */
const isValidDenyAllowModifierValue = (value) => {
    // $denyallow modifier does not support wildcard tld
    // https://adguard.app/kb/general/ad-filtering/create-own-filters/#denyallow-modifier
    // but here we are simply checking whether the value contains wildcard `*`, not ends with `.*`
    if (value.includes(WILDCARD)) {
        return false;
    }
    // TODO: add cache for domains validation
    return DomainUtils.isValidDomainOrHostname(value);
};
/**
 * Checks whether the given `value` is valid domain as $domain modifier value.
 *
 * @param value Value to check.
 *
 * @returns True if the `value` is valid domain, false otherwise.
 */
const isValidDomainModifierValue = (value) => {
    // TODO: add cache for domains validation
    return DomainUtils.isValidDomainOrHostname(value);
};
/**
 * Checks whether the all list items' exceptions are `false`.
 * Those items which `exception` is `true` is to be specified in the validation result error message.
 *
 * @param modifierName Modifier name.
 * @param listItems List items to check.
 *
 * @returns Validation result.
 */
const customNoNegatedListItemsValidator = (modifierName, listItems) => {
    const negatedValues = [];
    listItems.forEach((listItem) => {
        if (listItem.exception) {
            negatedValues.push(listItem.value);
        }
    });
    if (negatedValues.length > 0) {
        const valuesToStr = QuoteUtils.quoteAndJoinStrings(negatedValues);
        return getInvalidValidationResult(`${VALIDATION_ERROR_PREFIX.NOT_NEGATABLE_VALUE}: '${modifierName}': ${valuesToStr}`);
    }
    return { valid: true };
};
/**
 * Checks whether the all list items' exceptions are consistent,
 * i.e. all items are either negated or not negated.
 *
 * The `exception` value of the first item is used as a reference, and all other items are checked against it.
 * Those items which `exception` is not consistent with the first item
 * is to be specified in the validation result error message.
 *
 * @see {@link https://adguard.com/kb/general/ad-filtering/create-own-filters/#method-modifier}
 *
 * @param modifierName Modifier name.
 * @param listItems List items to check.
 *
 * @returns Validation result.
 */
const customConsistentExceptionsValidator = (modifierName, listItems) => {
    const firstException = listItems[0].exception;
    const nonConsistentItemValues = [];
    listItems.forEach((listItem) => {
        if (listItem.exception !== firstException) {
            nonConsistentItemValues.push(listItem.value);
        }
    });
    if (nonConsistentItemValues.length > 0) {
        const valuesToStr = QuoteUtils.quoteAndJoinStrings(nonConsistentItemValues);
        return getInvalidValidationResult(`${VALIDATION_ERROR_PREFIX.MIXED_NEGATIONS}: '${modifierName}': ${valuesToStr}`);
    }
    return { valid: true };
};
/**
 * Checks whether the given `modifier` value is valid.
 * Supposed to validate the value of modifiers which values are lists separated by pipe `|` —
 * $app, $domain, $denyallow, $method.
 *
 * @param modifier Modifier AST node.
 * @param listParser Parser function for parsing modifier value
 * which is supposed to be a list separated by pipe `|`.
 * @param isValidListItem Predicate function for checking of modifier's list item validity,
 * e.g. $denyallow modifier does not support wildcard tld, but $domain does.
 * @param customListValidator Optional; custom validator for specific modifier,
 * e.g. $denyallow modifier does not support negated domains.
 *
 * @returns Result of modifier domains validation.
 */
const validateListItemsModifier = (modifier, listParser, isValidListItem, customListValidator) => {
    const modifierName = modifier.name.value;
    const defaultInvalidValueResult = getValueRequiredValidationResult(modifierName);
    if (!modifier.value?.value) {
        return defaultInvalidValueResult;
    }
    let theList;
    try {
        theList = listParser(modifier.value.value, defaultParserOptions, 0, PIPE);
    }
    catch (e) {
        if (e instanceof AdblockSyntaxError) {
            return {
                valid: false,
                error: e.message,
            };
        }
        return defaultInvalidValueResult;
    }
    const invalidListItems = [];
    theList.children.forEach((item) => {
        // different validators are used for $denyallow and $domain modifiers
        // because of different requirements and restrictions
        if (!isValidListItem(item.value)) {
            invalidListItems.push(item.value);
        }
    });
    if (invalidListItems.length > 0) {
        const itemsToStr = QuoteUtils.quoteAndJoinStrings(invalidListItems);
        return getInvalidValidationResult(`${VALIDATION_ERROR_PREFIX.INVALID_LIST_VALUES}: '${modifierName}': ${itemsToStr}`);
    }
    // IMPORTANT: run custom validator after all other checks
    // Some lists should be fully checked, not just the list items:
    // e.g. Safari does not support allowed and disallowed domains for $domain in the same list
    // or   domains cannot be negated for $denyallow modifier
    if (customListValidator) {
        return customListValidator(modifierName, theList.children);
    }
    return { valid: true };
};
/**
 * Validates 'pipe_separated_apps' custom value format.
 * Used for $app modifier.
 *
 * @param modifier Modifier AST node.
 *
 * @returns Validation result.
 */
const validatePipeSeparatedApps = (modifier) => {
    return validateListItemsModifier(modifier, (raw) => AppListParser.parse(raw), isValidAppModifierValue);
};
/**
 * Validates 'pipe_separated_denyallow_domains' custom value format.
 * Used for $denyallow modifier.
 *
 * @param modifier Modifier AST node.
 *
 * @returns Validation result.
 */
const validatePipeSeparatedDenyAllowDomains = (modifier) => {
    return validateListItemsModifier(modifier, DomainListParser.parse, isValidDenyAllowModifierValue, customNoNegatedListItemsValidator);
};
/**
 * Validates 'pipe_separated_domains' custom value format.
 * Used for $domains modifier.
 *
 * @param modifier Modifier AST node.
 *
 * @returns Validation result.
 */
const validatePipeSeparatedDomains = (modifier) => {
    return validateListItemsModifier(modifier, DomainListParser.parse, isValidDomainModifierValue);
};
/**
 * Validates 'pipe_separated_methods' custom value format.
 * Used for $method modifier.
 *
 * @param modifier Modifier AST node.
 *
 * @returns Validation result.
 */
const validatePipeSeparatedMethods = (modifier) => {
    return validateListItemsModifier(modifier, (raw) => MethodListParser.parse(raw), isValidMethodModifierValue, customConsistentExceptionsValidator);
};
/**
 * Validates 'pipe_separated_stealth_options' custom value format.
 * Used for $stealth modifier.
 *
 * @param modifier Modifier AST node.
 *
 * @returns Validation result.
 */
const validatePipeSeparatedStealthOptions = (modifier) => {
    return validateListItemsModifier(modifier, (raw) => StealthOptionListParser.parse(raw), isValidStealthModifierValue, customNoNegatedListItemsValidator);
};
/**
 * Validates `csp_value` custom value format.
 * Used for $csp modifier.
 *
 * @param modifier Modifier AST node.
 *
 * @returns Validation result.
 */
const validateCspValue = (modifier) => {
    const modifierName = modifier.name.value;
    if (!modifier.value?.value) {
        return getValueRequiredValidationResult(modifierName);
    }
    // $csp modifier value may contain multiple directives
    // e.g. "csp=child-src 'none'; frame-src 'self' *; worker-src 'none'"
    const policyDirectives = modifier.value.value
        .split(SEMICOLON)
        // rule with $csp modifier may end with semicolon
        // e.g. "$csp=sandbox allow-same-origin;"
        // TODO: add predicate helper for `(i) => !!i`
        .filter((i) => !!i);
    const invalidValueValidationResult = getInvalidValidationResult(`${VALIDATION_ERROR_PREFIX.VALUE_INVALID}: '${modifierName}': "${modifier.value.value}"`);
    if (policyDirectives.length === 0) {
        return invalidValueValidationResult;
    }
    const invalidDirectives = [];
    for (let i = 0; i < policyDirectives.length; i += 1) {
        const policyDirective = policyDirectives[i].trim();
        if (!policyDirective) {
            return invalidValueValidationResult;
        }
        const chunks = policyDirective.split(SPACE);
        const [directive, ...valueChunks] = chunks;
        // e.g. "csp=child-src 'none'; ; worker-src 'none'"
        // validator it here          ↑
        if (!directive) {
            return invalidValueValidationResult;
        }
        if (!ALLOWED_CSP_DIRECTIVES.has(directive)) {
            // e.g. "csp='child-src' 'none'"
            if (ALLOWED_CSP_DIRECTIVES.has(QuoteUtils.removeQuotes(directive))) {
                return getInvalidValidationResult(`${VALIDATION_ERROR_PREFIX.NO_CSP_DIRECTIVE_QUOTE}: '${modifierName}': ${directive}`);
            }
            invalidDirectives.push(directive);
            continue;
        }
        if (valueChunks.length === 0) {
            return getInvalidValidationResult(`${VALIDATION_ERROR_PREFIX.NO_CSP_VALUE}: '${modifierName}': '${directive}'`);
        }
    }
    if (invalidDirectives.length > 0) {
        const directivesToStr = QuoteUtils.quoteAndJoinStrings(invalidDirectives, QuoteType.Double);
        return getInvalidValidationResult(`${VALIDATION_ERROR_PREFIX.INVALID_CSP_DIRECTIVES}: '${modifierName}': ${directivesToStr}`);
    }
    return { valid: true };
};
/**
 * Validates permission allowlist origins in the value of $permissions modifier.
 *
 * @see {@link https://w3c.github.io/webappsec-permissions-policy/#allowlists}
 *
 * @param allowlistChunks Array of allowlist chunks.
 * @param directive Permission directive name.
 * @param modifierName Modifier name.
 *
 * @returns Validation result.
 */
const validatePermissionAllowlistOrigins = (allowlistChunks, directive, modifierName) => {
    const invalidOrigins = [];
    for (let i = 0; i < allowlistChunks.length; i += 1) {
        const chunk = allowlistChunks[i].trim();
        // skip few spaces between origins (they were splitted by space)
        // e.g. 'geolocation=("https://example.com"  "https://*.example.com")'
        if (chunk.length === 0) {
            continue;
        }
        /**
         * 'self' should be checked case-insensitively
         *
         * @see {@link https://w3c.github.io/webappsec-permissions-policy/#algo-parse-policy-directive}
         *
         * @example 'geolocation=(self)'
         */
        if (chunk.toLowerCase() === PERMISSIONS_TOKEN_SELF) {
            continue;
        }
        if (QuoteUtils.getStringQuoteType(chunk) !== QuoteType.Double) {
            return getInvalidValidationResult(
            // eslint-disable-next-line max-len
            `${VALIDATION_ERROR_PREFIX.INVALID_PERMISSION_ORIGIN_QUOTES}: '${modifierName}': '${directive}': '${QuoteUtils.removeQuotes(chunk)}'`);
        }
        if (!isValidPermissionsOrigin(chunk)) {
            invalidOrigins.push(chunk);
        }
    }
    if (invalidOrigins.length > 0) {
        const originsToStr = QuoteUtils.quoteAndJoinStrings(invalidOrigins);
        return getInvalidValidationResult(
        // eslint-disable-next-line max-len
        `${VALIDATION_ERROR_PREFIX.INVALID_PERMISSION_ORIGINS}: '${modifierName}': '${directive}': ${originsToStr}`);
    }
    return { valid: true };
};
/**
 * Validates permission allowlist in the modifier value.
 *
 * @see {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/Permissions_Policy#allowlists}
 * @see {@link https://w3c.github.io/webappsec-permissions-policy/#allowlists}
 *
 * @param allowlist Allowlist value.
 * @param directive Permission directive name.
 * @param modifierName Modifier name.
 *
 * @returns Validation result.
 */
const validatePermissionAllowlist = (allowlist, directive, modifierName) => {
    // `*` is one of available permissions tokens
    // e.g. 'fullscreen=*'
    // https://w3c.github.io/webappsec-permissions-policy/#structured-header-serialization
    if (allowlist === WILDCARD
        // e.g. 'autoplay=()'
        || allowlist === EMPTY_PERMISSIONS_ALLOWLIST) {
        return { valid: true };
    }
    if (!(allowlist.startsWith(OPEN_PARENTHESIS) && allowlist.endsWith(CLOSE_PARENTHESIS))) {
        return getInvalidValidationResult(`${VALIDATION_ERROR_PREFIX.VALUE_INVALID}: '${modifierName}'`);
    }
    const allowlistChunks = allowlist.slice(1, -1).split(SPACE);
    return validatePermissionAllowlistOrigins(allowlistChunks, directive, modifierName);
};
/**
 * Validates single permission in the modifier value.
 *
 * @param permission Single permission value.
 * @param modifierName Modifier name.
 * @param modifierValue Modifier value.
 *
 * @returns Validation result.
 */
const validateSinglePermission = (permission, modifierName, modifierValue) => {
    // empty permission in the rule
    // e.g. 'permissions=storage-access=()\\, \\, camera=()'
    // the validator is here                 ↑
    if (!permission) {
        return getInvalidValidationResult(`${VALIDATION_ERROR_PREFIX.VALUE_INVALID}: '${modifierName}'`);
    }
    if (permission.includes(COMMA)) {
        return getInvalidValidationResult(`${VALIDATION_ERROR_PREFIX.NO_UNESCAPED_PERMISSION_COMMA}: '${modifierName}': '${modifierValue}'`);
    }
    const [directive, allowlist] = permission.split(EQUALS);
    if (!ALLOWED_PERMISSION_DIRECTIVES.has(directive)) {
        return getInvalidValidationResult(`${VALIDATION_ERROR_PREFIX.INVALID_PERMISSION_DIRECTIVE}: '${modifierName}': '${directive}'`);
    }
    return validatePermissionAllowlist(allowlist, directive, modifierName);
};
/**
 * Validates `permissions_value` custom value format.
 * Used for $permissions modifier.
 *
 * @param modifier Modifier AST node.
 *
 * @returns Validation result.
 */
const validatePermissions = (modifier) => {
    if (!modifier.value?.value) {
        return getValueRequiredValidationResult(modifier.name.value);
    }
    const modifierName = modifier.name.value;
    const modifierValue = modifier.value.value;
    // multiple permissions may be separated by escaped commas
    const permissions = modifier.value.value.split(`${BACKSLASH}${COMMA}`);
    for (let i = 0; i < permissions.length; i += 1) {
        const permission = permissions[i].trim();
        const singlePermissionValidationResult = validateSinglePermission(permission, modifierName, modifierValue);
        if (!singlePermissionValidationResult.valid) {
            return singlePermissionValidationResult;
        }
    }
    return { valid: true };
};
/**
 * Validates `referrerpolicy_value` custom value format.
 * Used for $referrerpolicy modifier.
 *
 * @param modifier Modifier AST node.
 *
 * @returns Validation result.
 */
const validateReferrerPolicy = (modifier) => {
    if (!modifier.value?.value) {
        return getValueRequiredValidationResult(modifier.name.value);
    }
    const modifierName = modifier.name.value;
    const modifierValue = modifier.value.value;
    if (!REFERRER_POLICY_DIRECTIVES.has(modifierValue)) {
        // eslint-disable-next-line max-len
        return getInvalidValidationResult(`${VALIDATION_ERROR_PREFIX.INVALID_REFERRER_POLICY_DIRECTIVE}: '${modifierName}': '${modifierValue}'`);
    }
    return { valid: true };
};
/**
 * Map of all available pre-defined validators for modifiers with custom `value_format`.
 */
const CUSTOM_VALUE_FORMAT_MAP = {
    [CustomValueFormatValidatorName.App]: validatePipeSeparatedApps,
    [CustomValueFormatValidatorName.Csp]: validateCspValue,
    [CustomValueFormatValidatorName.DenyAllow]: validatePipeSeparatedDenyAllowDomains,
    [CustomValueFormatValidatorName.Domain]: validatePipeSeparatedDomains,
    [CustomValueFormatValidatorName.Method]: validatePipeSeparatedMethods,
    [CustomValueFormatValidatorName.Permissions]: validatePermissions,
    [CustomValueFormatValidatorName.ReferrerPolicy]: validateReferrerPolicy,
    [CustomValueFormatValidatorName.StealthOption]: validatePipeSeparatedStealthOptions,
};
/**
 * Returns whether the given `valueFormat` is a valid custom value format validator name.
 *
 * @param valueFormat Value format for the modifier.
 *
 * @returns True if `valueFormat` is a supported pre-defined value format validator name, false otherwise.
 */
const isCustomValueFormatValidator = (valueFormat) => {
    return Object.keys(CUSTOM_VALUE_FORMAT_MAP).includes(valueFormat);
};
/**
 * Checks whether the value for given `modifier` is valid.
 *
 * @param modifier Modifier AST node.
 * @param valueFormat Value format for the modifier.
 *
 * @returns Validation result.
 */
const validateValue = (modifier, valueFormat) => {
    if (isCustomValueFormatValidator(valueFormat)) {
        const validator = CUSTOM_VALUE_FORMAT_MAP[valueFormat];
        return validator(modifier);
    }
    const modifierName = modifier.name.value;
    if (!modifier.value?.value) {
        return getValueRequiredValidationResult(modifierName);
    }
    let xRegExp;
    try {
        xRegExp = lib(valueFormat);
    }
    catch (e) {
        throw new Error(`${SOURCE_DATA_ERROR_PREFIX.INVALID_VALUE_FORMAT_REGEXP}: '${modifierName}'`);
    }
    const isValid = xRegExp.test(modifier.value?.value);
    if (!isValid) {
        return getInvalidValidationResult(`${VALIDATION_ERROR_PREFIX.VALUE_INVALID}: '${modifierName}'`);
    }
    return { valid: true };
};

/**
 * @file Clone related utilities
 *
 * We should keep clone related functions in this file. Thus, we just provide
 * a simple interface for cloning values, we use it across the AGTree project,
 * and the implementation "under the hood" can be improved later, if needed.
 */
/**
 * Clones an input value to avoid side effects. Use it only in justified cases,
 * because it can impact performance negatively.
 *
 * @param value Value to clone
 * @returns Cloned value
 */
function clone(value) {
    // TODO: Replace cloneDeep with a more efficient implementation
    return clone_deep(value);
}

/* eslint-disable no-bitwise */
/**
 * @file Provides platform enums.
 * The difference between specific and generic platforms is that specific platforms are individual platforms
 * (e.g. AdGuard for Windows, AdGuard for Android, etc.),
 * while generic platforms are groups of specific platforms
 * (e.g. AdGuard for any OS, AdGuard for any Chromium-based extension, etc.).
 */
/**
 * List of specific platforms.
 */
var SpecificPlatform;
(function (SpecificPlatform) {
    SpecificPlatform[SpecificPlatform["AdgOsWindows"] = 1] = "AdgOsWindows";
    SpecificPlatform[SpecificPlatform["AdgOsMac"] = 2] = "AdgOsMac";
    SpecificPlatform[SpecificPlatform["AdgOsAndroid"] = 4] = "AdgOsAndroid";
    SpecificPlatform[SpecificPlatform["AdgExtChrome"] = 8] = "AdgExtChrome";
    SpecificPlatform[SpecificPlatform["AdgExtOpera"] = 16] = "AdgExtOpera";
    SpecificPlatform[SpecificPlatform["AdgExtEdge"] = 32] = "AdgExtEdge";
    SpecificPlatform[SpecificPlatform["AdgExtFirefox"] = 64] = "AdgExtFirefox";
    SpecificPlatform[SpecificPlatform["AdgCbAndroid"] = 128] = "AdgCbAndroid";
    SpecificPlatform[SpecificPlatform["AdgCbIos"] = 256] = "AdgCbIos";
    SpecificPlatform[SpecificPlatform["AdgCbSafari"] = 512] = "AdgCbSafari";
    SpecificPlatform[SpecificPlatform["UboExtChrome"] = 1024] = "UboExtChrome";
    SpecificPlatform[SpecificPlatform["UboExtOpera"] = 2048] = "UboExtOpera";
    SpecificPlatform[SpecificPlatform["UboExtEdge"] = 4096] = "UboExtEdge";
    SpecificPlatform[SpecificPlatform["UboExtFirefox"] = 8192] = "UboExtFirefox";
    SpecificPlatform[SpecificPlatform["AbpExtChrome"] = 16384] = "AbpExtChrome";
    SpecificPlatform[SpecificPlatform["AbpExtOpera"] = 32768] = "AbpExtOpera";
    SpecificPlatform[SpecificPlatform["AbpExtEdge"] = 65536] = "AbpExtEdge";
    SpecificPlatform[SpecificPlatform["AbpExtFirefox"] = 131072] = "AbpExtFirefox";
})(SpecificPlatform || (SpecificPlatform = {}));
/**
 * List of generic platforms (combinations of specific platforms).
 */
var GenericPlatform;
(function (GenericPlatform) {
    GenericPlatform[GenericPlatform["AdgOsAny"] = 7] = "AdgOsAny";
    GenericPlatform[GenericPlatform["AdgSafariAny"] = 768] = "AdgSafariAny";
    GenericPlatform[GenericPlatform["AdgExtChromium"] = 56] = "AdgExtChromium";
    GenericPlatform[GenericPlatform["AdgExtAny"] = 120] = "AdgExtAny";
    GenericPlatform[GenericPlatform["AdgAny"] = 1023] = "AdgAny";
    GenericPlatform[GenericPlatform["UboExtChromium"] = 7168] = "UboExtChromium";
    GenericPlatform[GenericPlatform["UboExtAny"] = 15360] = "UboExtAny";
    GenericPlatform[GenericPlatform["UboAny"] = 15360] = "UboAny";
    GenericPlatform[GenericPlatform["AbpExtChromium"] = 114688] = "AbpExtChromium";
    GenericPlatform[GenericPlatform["AbpExtAny"] = 245760] = "AbpExtAny";
    GenericPlatform[GenericPlatform["AbpAny"] = 245760] = "AbpAny";
    GenericPlatform[GenericPlatform["Any"] = 262143] = "Any";
})(GenericPlatform || (GenericPlatform = {}));

/* eslint-disable no-bitwise */
/**
 * @file Provides platform mapping and helper functions.
 */
/**
 * Map of specific platforms string names to their corresponding enum values.
 */
const SPECIFIC_PLATFORM_MAP = new Map([
    ['adg_os_windows', SpecificPlatform.AdgOsWindows],
    ['adg_os_mac', SpecificPlatform.AdgOsMac],
    ['adg_os_android', SpecificPlatform.AdgOsAndroid],
    ['adg_ext_chrome', SpecificPlatform.AdgExtChrome],
    ['adg_ext_opera', SpecificPlatform.AdgExtOpera],
    ['adg_ext_edge', SpecificPlatform.AdgExtEdge],
    ['adg_ext_firefox', SpecificPlatform.AdgExtFirefox],
    ['adg_cb_android', SpecificPlatform.AdgCbAndroid],
    ['adg_cb_ios', SpecificPlatform.AdgCbIos],
    ['adg_cb_safari', SpecificPlatform.AdgCbSafari],
    ['ubo_ext_chrome', SpecificPlatform.UboExtChrome],
    ['ubo_ext_opera', SpecificPlatform.UboExtOpera],
    ['ubo_ext_edge', SpecificPlatform.UboExtEdge],
    ['ubo_ext_firefox', SpecificPlatform.UboExtFirefox],
    ['abp_ext_chrome', SpecificPlatform.AbpExtChrome],
    ['abp_ext_opera', SpecificPlatform.AbpExtOpera],
    ['abp_ext_edge', SpecificPlatform.AbpExtEdge],
    ['abp_ext_firefox', SpecificPlatform.AbpExtFirefox],
]);
/**
 * Map of specific platforms enum values to their corresponding string names.
 *
 * @note Reverse of {@link SPECIFIC_PLATFORM_MAP}.
 */
const SPECIFIC_PLATFORM_MAP_REVERSE = new Map([...SPECIFIC_PLATFORM_MAP].map(([key, value]) => [value, key]));
/**
 * Map of generic platforms string names to their corresponding enum values.
 */
const GENERIC_PLATFORM_MAP = new Map([
    ['adg_os_any', GenericPlatform.AdgOsAny],
    ['adg_safari_any', GenericPlatform.AdgSafariAny],
    ['adg_ext_chromium', GenericPlatform.AdgExtChromium],
    ['adg_ext_any', GenericPlatform.AdgExtAny],
    ['adg_any', GenericPlatform.AdgAny],
    ['ubo_ext_chromium', GenericPlatform.UboExtChromium],
    ['ubo_ext_any', GenericPlatform.UboExtAny],
    ['ubo_any', GenericPlatform.UboAny],
    ['abp_ext_chromium', GenericPlatform.AbpExtChromium],
    ['abp_ext_any', GenericPlatform.AbpExtAny],
    ['abp_any', GenericPlatform.AbpAny],
    ['any', GenericPlatform.Any],
]);
/**
 * Check if the platform is a generic platform.
 *
 * @param platform Platform to check.
 *
 * @returns True if the platform is a generic platform, false otherwise.
 */
const isGenericPlatform = (platform) => {
    // if more than one bit is set, it's a generic platform
    return !!(platform & (platform - 1));
};
/**
 * Returns the platform enum value for the given platform string name.
 *
 * @param platform Platform string name, e.g., 'adg_os_windows'.
 *
 * @returns Specific or generic platform enum value.
 * @throws Error if the platform is unknown.
 */
const getPlatformId = (platform) => {
    const specificPlatform = SPECIFIC_PLATFORM_MAP.get(platform);
    if (specificPlatform) {
        return specificPlatform;
    }
    const genericPlatform = GENERIC_PLATFORM_MAP.get(platform);
    if (genericPlatform) {
        return genericPlatform;
    }
    throw new Error(`Unknown platform: ${platform}`);
};
/**
 * Returns the specific platform string name for the given platform enum value.
 *
 * @param platform Specific platform enum value.
 *
 * @returns Specific platform string name, e.g., 'adg_os_windows'.
 * @throws Error if the platform is unknown.
 */
const getSpecificPlatformName = (platform) => {
    const specificPlatform = SPECIFIC_PLATFORM_MAP_REVERSE.get(platform);
    if (!specificPlatform) {
        throw new Error(`Unknown platform: ${platform}`);
    }
    return specificPlatform;
};

/* eslint-disable no-bitwise */
/**
 * @file Provides common compatibility table methods.
 */
/**
 * Base compatibility table class which provides common methods to work with compatibility data.
 *
 * @template T Compatibility data schema.
 */
class CompatibilityTableBase {
    /**
     * Compatibility table data.
     */
    data;
    /**
     * Optional name transformer function. If provided,
     * it will be called in all methods before processing compatibility data names.
     */
    nameTransformer;
    /**
     * Creates a new instance of the common compatibility table.
     *
     * @param data Compatibility table data.
     * @param nameTransformer Optional name transformer function.
     */
    constructor(data, nameTransformer = null) {
        this.data = data;
        this.nameTransformer = nameTransformer;
    }
    /**
     * Helper method to get a 'row' from the compatibility table data by name.
     *
     * @param name Compatibility data name.
     * @returns Compatibility table row storage or `null` if not found.
     */
    getRowStorage(name) {
        const idx = this.data.map[name];
        if (isUndefined(idx)) {
            return null;
        }
        return this.data.shared[idx];
    }
    /**
     * Checks whether a compatibility data `name` exists for any platform.
     *
     * @note Technically, do the same as `exists()` method with generic platform _any_
     * but it is faster because it does not apply complex logic.
     *
     * @param name Compatibility data name.
     *
     * @returns True if the compatibility data exists, false otherwise.
     */
    existsAny(name) {
        const normalizedName = this.nameTransformer ? this.nameTransformer(name) : name;
        return !isUndefined(this.data.map[normalizedName]);
    }
    /**
     * Checks whether a compatibility data `name` exists for a specified platform.
     *
     * @param name Compatibility data name.
     * @param platform Specific or generic platform.
     *
     * @returns True if the compatibility data exists, false otherwise.
     */
    exists(name, platform) {
        const normalizedName = this.nameTransformer ? this.nameTransformer(name) : name;
        const data = this.getRowStorage(normalizedName);
        if (!data) {
            return false;
        }
        const isMatch = (idx) => {
            const el = data.shared[idx];
            return !isUndefined(el) && (el.name === normalizedName || !!el.aliases?.includes(normalizedName));
        };
        if (isGenericPlatform(platform)) {
            // Since indexes are specific platforms in the compatibility table data,
            // we can't index them directly if the platform is generic (union of specific platforms).
            // In this case, we need to iterate over the keys and return true on the first match.
            const keys = Object.keys(data.map);
            for (let i = 0; i < keys.length; i += 1) {
                const key = Number(keys[i]);
                if (platform & key) {
                    const idx = data.map[key];
                    if (isMatch(idx)) {
                        return true;
                    }
                }
            }
            return false;
        }
        const idx = data.map[platform];
        return isMatch(idx);
    }
    /**
     * Returns a compatibility data by name and specific platform.
     *
     * @param name The name of the compatibility data.
     * @param platform The specific platform.
     *
     * @returns A single compatibility data or `null` if not found.
     */
    getSingle(name, platform) {
        const normalizedName = this.nameTransformer ? this.nameTransformer(name) : name;
        const data = this.getRowStorage(normalizedName);
        if (!data) {
            return null;
        }
        const idx = data.map[platform];
        return isUndefined(idx) ? null : data.shared[idx];
    }
    /**
     * Returns all compatibility data records for name and specified platform.
     *
     * @param name Compatibility data name.
     * @param platform Specific or generic platform.
     *
     * @returns Multiple records grouped by platforms.
     * Technically, it is an object where keys are platform enums values and values are compatibility data records.
     *
     * @note Platform enum values can be converted to string names using {@link getSpecificPlatformName} on demand.
     */
    getMultiple(name, platform) {
        const normalizedName = this.nameTransformer ? this.nameTransformer(name) : name;
        const data = this.getRowStorage(normalizedName);
        if (!data) {
            return null;
        }
        if (isGenericPlatform(platform)) {
            const result = {};
            const keys = Object.keys(data.map);
            for (let i = 0; i < keys.length; i += 1) {
                const key = Number(keys[i]);
                if (platform & key) {
                    const idx = data.map[key];
                    if (!isUndefined(idx)) {
                        result[key] = data.shared[idx];
                    }
                }
            }
            return result;
        }
        const idx = data.map[platform];
        if (isUndefined(idx)) {
            return null;
        }
        return { key: data.shared[idx] };
    }
    /**
     * Returns all compatibility data records for the specified platform.
     *
     * @param platform Specific or generic platform.
     *
     * @returns Array of multiple records grouped by platforms.
     */
    getAllMultiple(platform) {
        const result = [];
        for (let i = 0; i < this.data.shared.length; i += 1) {
            const data = this.data.shared[i];
            const names = new Set(data.shared.map(({ name }) => name));
            names.forEach((name) => {
                const multipleRecords = this.getMultiple(name, platform);
                if (multipleRecords) {
                    result.push(multipleRecords);
                }
            });
        }
        return result;
    }
    /**
     * Returns the first compatibility data record for name and specified platform.
     *
     * @param name Compatibility data name.
     * @param platform Specific or generic platform.
     *
     * @returns First found compatibility data record or `null` if not found.
     */
    getFirst(name, platform) {
        const normalizedName = this.nameTransformer ? this.nameTransformer(name) : name;
        const data = this.getRowStorage(normalizedName);
        if (!data) {
            return null;
        }
        if (isGenericPlatform(platform)) {
            const keys = Object.keys(data.map);
            for (let i = 0; i < keys.length; i += 1) {
                const key = Number(keys[i]);
                if (platform & key) {
                    const idx = data.map[key];
                    if (!isUndefined(idx)) {
                        // return the first found record
                        return data.shared[idx];
                    }
                }
            }
            return null;
        }
        const idx = data.map[platform];
        if (isUndefined(idx)) {
            return null;
        }
        return data.shared[idx];
    }
    /**
     * Returns all compatibility data records for the specified name.
     *
     * @param name Compatibility data name.
     *
     * @returns Array of multiple records grouped by platforms.
     */
    getRow(name) {
        const normalizedName = this.nameTransformer ? this.nameTransformer(name) : name;
        const data = this.getRowStorage(normalizedName);
        if (!data) {
            return [];
        }
        return data.shared;
    }
    /**
     * Returns all compatibility data grouped by products.
     *
     * @returns Array of multiple records grouped by products.
     */
    getRowsByProduct() {
        const result = [];
        for (let i = 0; i < this.data.shared.length; i += 1) {
            const data = this.data.shared[i];
            const keys = Object.keys(data.map);
            const row = {
                [AdblockSyntax.Adg]: {},
                [AdblockSyntax.Ubo]: {},
                [AdblockSyntax.Abp]: {},
            };
            for (let j = 0; j < keys.length; j += 1) {
                const key = Number(keys[j]);
                if (key & GenericPlatform.AdgAny) {
                    row[AdblockSyntax.Adg][key] = data.shared[data.map[key]];
                }
                else if (key & GenericPlatform.UboAny) {
                    row[AdblockSyntax.Ubo][key] = data.shared[data.map[key]];
                }
                else if (key & GenericPlatform.AbpAny) {
                    row[AdblockSyntax.Abp][key] = data.shared[data.map[key]];
                }
            }
            result.push(row);
        }
        return result;
    }
}

/**
 * Simple deep freeze implementation.
 * It freezes the object and all its properties recursively.
 *
 * @param object Object to freeze.
 *
 * @returns Frozen object.
 *
 * @template T Type of the object to freeze.
 *
 * @see {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#deep_freezing}
 */
const deepFreeze = (object) => {
    // Retrieve the property names defined on object
    const propNames = Reflect.ownKeys(object);
    // Freeze properties before freezing self
    for (const name of propNames) {
        const value = object[name];
        if ((value && typeof value === 'object') || typeof value === 'function') {
            deepFreeze(value);
        }
    }
    return Object.freeze(object);
};

/**
 * @file Compatibility tables for modifiers.
 */
/**
 * Transforms the name of the modifier to a normalized form.
 * This is a special case: the noop modifier normally '_', but it can consist of any number of characters,
 * e.g. '____' is also valid. In this case, we need to normalize the name to '_'.
 *
 * @param name Modifier name to normalize.
 * @returns Normalized modifier name.
 */
const noopModifierNameNormalizer = (name) => {
    if (name.startsWith(UNDERSCORE)) {
        if (name.split(EMPTY).every((char) => char === UNDERSCORE)) {
            // in compatibility tables, we just store '_', so we need to reduce the number of underscores to 1
            // before checking the existence of the noop modifier
            return UNDERSCORE;
        }
    }
    return name;
};
/**
 * Compatibility table for modifiers.
 */
class ModifiersCompatibilityTable extends CompatibilityTableBase {
    /**
     * Creates a new instance of the compatibility table for modifiers.
     *
     * @param data Compatibility table data.
     */
    constructor(data) {
        super(data, noopModifierNameNormalizer);
    }
}
/**
 * Deep freeze the compatibility table data to avoid accidental modifications.
 */
deepFreeze(compatibility_table_data/* modifiersCompatibilityTableData */.aB);
/**
 * Compatibility table instance for modifiers.
 */
const modifiersCompatibilityTable = new ModifiersCompatibilityTable(compatibility_table_data/* modifiersCompatibilityTableData */.aB);

/**
 * @file Validator for modifiers.
 */
const convertSyntaxToGenericPlatform = (syntax) => {
    switch (syntax) {
        case AdblockSyntax.Adg:
            return GenericPlatform.AdgAny;
        case AdblockSyntax.Ubo:
            return GenericPlatform.UboAny;
        case AdblockSyntax.Abp:
            return GenericPlatform.AbpAny;
        default:
            throw new Error(`Unknown syntax: ${syntax}`);
    }
};
/**
 * Fully checks whether the given `modifier` valid for given blocker `syntax`:
 * is it supported by the blocker, deprecated, assignable, negatable, etc.
 *
 * @param syntax Adblock syntax to check the modifier for.
 * 'Common' is not supported, it should be specific — 'AdGuard', 'uBlockOrigin', or 'AdblockPlus'.
 * @param modifier Parsed modifier AST node.
 * @param isException Whether the modifier is used in exception rule.
 * Needed to check whether the modifier is allowed only in blocking or exception rules.
 *
 * @returns Result of modifier validation.
 */
const validateForSpecificSyntax = (syntax, modifier, isException) => {
    if (syntax === AdblockSyntax.Common) {
        throw new Error(`Syntax should be specific, '${AdblockSyntax.Common}' is not supported`);
    }
    const modifierName = modifier.name.value;
    const blockerPrefix = BLOCKER_PREFIX[syntax];
    if (!blockerPrefix) {
        throw new Error(`Unknown syntax: ${syntax}`);
    }
    // needed for validation of negation, assignment, etc.
    const specificBlockerData = modifiersCompatibilityTable.getFirst(modifierName, convertSyntaxToGenericPlatform(syntax));
    // if no specific blocker data is found
    if (!specificBlockerData) {
        return getInvalidValidationResult(`${VALIDATION_ERROR_PREFIX.NOT_SUPPORTED}: '${modifierName}'`);
    }
    // e.g. 'object-subrequest'
    if (specificBlockerData.removed) {
        return getInvalidValidationResult(`${VALIDATION_ERROR_PREFIX.REMOVED}: '${modifierName}'`);
    }
    if (specificBlockerData.deprecated) {
        if (!specificBlockerData.deprecationMessage) {
            throw new Error(`${SOURCE_DATA_ERROR_PREFIX.NO_DEPRECATION_MESSAGE}: '${modifierName}'`);
        }
        // prepare the message which is multiline in the yaml file
        const warn = specificBlockerData.deprecationMessage.replace(NEWLINE, SPACE);
        return {
            valid: true,
            warn,
        };
    }
    if (specificBlockerData.blockOnly && isException) {
        return getInvalidValidationResult(`${VALIDATION_ERROR_PREFIX.BLOCK_ONLY}: '${modifierName}'`);
    }
    if (specificBlockerData.exceptionOnly && !isException) {
        return getInvalidValidationResult(`${VALIDATION_ERROR_PREFIX.EXCEPTION_ONLY}: '${modifierName}'`);
    }
    // e.g. '~domain=example.com'
    if (!specificBlockerData.negatable && modifier.exception) {
        return getInvalidValidationResult(`${VALIDATION_ERROR_PREFIX.NOT_NEGATABLE_MODIFIER}: '${modifierName}'`);
    }
    // e.g. 'domain'
    if (specificBlockerData.assignable) {
        if (!modifier.value) {
            // TODO: ditch value_optional after custom validators are implemented for value_format for all modifiers.
            // This checking should be done in each separate custom validator,
            // because $csp and $permissions without value can be used only in extension rules,
            // but $cookie with no value can be used in both blocking and exception rules.
            /**
             * Some assignable modifiers can be used without a value,
             * e.g. '@@||example.com^$cookie'.
             */
            if (specificBlockerData.valueOptional) {
                return { valid: true };
            }
            // for other assignable modifiers the value is required
            return getValueRequiredValidationResult(modifierName);
        }
        /**
         * TODO: consider to return `{ valid: true, warn: 'Modifier value may be specified' }` (???)
         * for $stealth modifier without a value
         * but only after the extension will support value for $stealth:
         * https://github.com/AdguardTeam/AdguardBrowserExtension/issues/2107
         */
        if (!specificBlockerData.valueFormat) {
            throw new Error(`${SOURCE_DATA_ERROR_PREFIX.NO_VALUE_FORMAT_FOR_ASSIGNABLE}: '${modifierName}'`);
        }
        return validateValue(modifier, specificBlockerData.valueFormat);
    }
    if (modifier?.value) {
        // e.g. 'third-party=true'
        return getInvalidValidationResult(`${VALIDATION_ERROR_PREFIX.VALUE_FORBIDDEN}: '${modifierName}'`);
    }
    return { valid: true };
};
// TODO: move to modifier.ts and use index.ts only for exporting
/**
 * Modifier validator class.
 */
class ModifierValidator {
    /**
     * Simply checks whether the modifier exists in any adblocker.
     *
     * **Deprecated** and **removed** modifiers are considered as **existent**.
     *
     * @param modifier Already parsed modifier AST node.
     *
     * @returns True if modifier exists, false otherwise.
     */
    // eslint-disable-next-line class-methods-use-this
    exists = (modifier) => {
        return modifiersCompatibilityTable.existsAny(modifier.name.value);
    };
    /**
     * Checks whether the given `modifier` is valid for specified `syntax`.
     *
     * For `Common` syntax it simply checks whether the modifier exists.
     * For specific syntax the validation is more complex —
     * deprecated, assignable, negatable and other requirements are checked.
     *
     * @param syntax Adblock syntax to check the modifier for.
     * @param rawModifier Modifier AST node.
     * @param isException Whether the modifier is used in exception rule, default to false.
     * Needed to check whether the modifier is allowed only in blocking or exception rules.
     *
     * @returns Result of modifier validation.
     */
    validate = (syntax, rawModifier, isException = false) => {
        const modifier = clone(rawModifier);
        // special case: handle noop modifier which may be used as multiple underscores (not just one)
        // https://adguard.com/kb/general/ad-filtering/create-own-filters/#noop-modifier
        if (modifier.name.value.startsWith(UNDERSCORE)) {
            // check whether the modifier value contains something else besides underscores
            if (!isValidNoopModifier(modifier.name.value)) {
                return getInvalidValidationResult(`${VALIDATION_ERROR_PREFIX.INVALID_NOOP}: '${modifier.name.value}'`);
            }
            // otherwise, replace the modifier value with single underscore.
            // it is needed to check whether the modifier is supported by specific adblocker due to the syntax
            modifier.name.value = UNDERSCORE;
        }
        if (!this.exists(modifier)) {
            return getInvalidValidationResult(`${VALIDATION_ERROR_PREFIX.NOT_EXISTENT}: '${modifier.name.value}'`);
        }
        // for 'Common' syntax we cannot check something more
        if (syntax === AdblockSyntax.Common) {
            return { valid: true };
        }
        return validateForSpecificSyntax(syntax, modifier, isException);
    };
}
const modifierValidator = new ModifierValidator();

/**
 * @file Base class for converters
 *
 * TS doesn't support abstract static methods, so we should use
 * a workaround and extend this class instead of implementing it
 */
/* eslint-disable jsdoc/require-returns-check */
/* eslint-disable @typescript-eslint/no-unused-vars */
/**
 * Basic class for rule converters
 */
class ConverterBase {
    /**
     * Converts some data to AdGuard format
     *
     * @param data Data to convert
     * @returns An object which follows the {@link ConversionResult} interface. Its `result` property contains
     * the converted node, and its `isConverted` flag indicates whether the original node was converted.
     * If the node was not converted, the result will contain the original node with the same object reference
     * @throws If the data is invalid or incompatible
     */
    static convertToAdg(data) {
        throw new NotImplementedError();
    }
    /**
     * Converts some data to Adblock Plus format
     *
     * @param data Data to convert
     * @returns An object which follows the {@link ConversionResult} interface. Its `result` property contains
     * the converted node, and its `isConverted` flag indicates whether the original node was converted.
     * If the node was not converted, the result will contain the original node with the same object reference
     * @throws If the data is invalid or incompatible
     */
    static convertToAbp(data) {
        throw new NotImplementedError();
    }
    /**
     * Converts some data to uBlock Origin format
     *
     * @param data Data to convert
     * @returns An object which follows the {@link ConversionResult} interface. Its `result` property contains
     * the converted node, and its `isConverted` flag indicates whether the original node was converted.
     * If the node was not converted, the result will contain the original node with the same object reference
     * @throws If the data is invalid or incompatible
     */
    static convertToUbo(data) {
        throw new NotImplementedError();
    }
}

/**
 * @file Base class for rule converters
 *
 * TS doesn't support abstract static methods, so we should use
 * a workaround and extend this class instead of implementing it
 */
/* eslint-disable jsdoc/require-returns-check */
/* eslint-disable @typescript-eslint/no-unused-vars */
/**
 * Basic class for rule converters
 */
class RuleConverterBase extends ConverterBase {
    /**
     * Converts an adblock filtering rule to AdGuard format, if possible.
     *
     * @param rule Rule node to convert
     * @returns An object which follows the {@link NodeConversionResult} interface. Its `result` property contains
     * the array of converted rule nodes, and its `isConverted` flag indicates whether the original rule was converted.
     * If the rule was not converted, the result array will contain the original node with the same object reference
     * @throws If the rule is invalid or cannot be converted
     */
    static convertToAdg(rule) {
        throw new NotImplementedError();
    }
    /**
     * Converts an adblock filtering rule to Adblock Plus format, if possible.
     *
     * @param rule Rule node to convert
     * @returns An object which follows the {@link NodeConversionResult} interface. Its `result` property contains
     * the array of converted rule nodes, and its `isConverted` flag indicates whether the original rule was converted.
     * If the rule was not converted, the result array will contain the original node with the same object reference
     * @throws If the rule is invalid or cannot be converted
     */
    static convertToAbp(rule) {
        throw new NotImplementedError();
    }
    /**
     * Converts an adblock filtering rule to uBlock Origin format, if possible.
     *
     * @param rule Rule node to convert
     * @returns An object which follows the {@link NodeConversionResult} interface. Its `result` property contains
     * the array of converted rule nodes, and its `isConverted` flag indicates whether the original rule was converted.
     * If the rule was not converted, the result array will contain the original node with the same object reference
     * @throws If the rule is invalid or cannot be converted
     */
    static convertToUbo(rule) {
        throw new NotImplementedError();
    }
}

/**
 * @file Conversion result interface and helper functions
 */
/**
 * Helper function to create a generic conversion result.
 *
 * @param result Conversion result
 * @param isConverted Indicates whether the input item was converted
 * @template T Type of the item to convert
 * @template U Type of the conversion result (defaults to `T`, but can be `T[]` as well)
 * @returns Generic conversion result
 */
// eslint-disable-next-line max-len
function createConversionResult(result, isConverted) {
    return {
        result,
        isConverted,
    };
}
/**
 * Helper function to create a node conversion result.
 *
 * @param nodes Array of nodes
 * @param isConverted Indicates whether the input item was converted
 * @template T Type of the node (extends `Node`)
 * @returns Node conversion result
 */
function createNodeConversionResult(nodes, isConverted) {
    return createConversionResult(nodes, isConverted);
}

/**
 * @file Comment rule converter
 */
/**
 * Comment rule converter class
 *
 * @todo Implement `convertToUbo` and `convertToAbp`
 */
class CommentRuleConverter extends RuleConverterBase {
    /**
     * Converts a comment rule to AdGuard format, if possible.
     *
     * @param rule Rule node to convert
     * @returns An object which follows the {@link NodeConversionResult} interface. Its `result` property contains
     * the array of converted rule nodes, and its `isConverted` flag indicates whether the original rule was converted.
     * If the rule was not converted, the result array will contain the original node with the same object reference
     * @throws If the rule is invalid or cannot be converted
     */
    static convertToAdg(rule) {
        // TODO: Add support for other comment types, if needed
        // Main task is # -> ! conversion
        switch (rule.type) {
            case CommentRuleType.CommentRule:
                // Check if the rule needs to be converted
                if (rule.type === CommentRuleType.CommentRule && rule.marker.value === CommentMarker.Hashmark) {
                    // Add a ! to the beginning of the comment
                    // TODO: Replace with custom clone method
                    const ruleClone = clone(rule);
                    ruleClone.marker.value = CommentMarker.Regular;
                    // Add the hashmark to the beginning of the comment text
                    ruleClone.text.value = `${SPACE}${CommentMarker.Hashmark}${ruleClone.text.value}`;
                    return createNodeConversionResult([ruleClone], true);
                }
                return createNodeConversionResult([rule], false);
            // Leave any other comment rule as is
            default:
                return createNodeConversionResult([rule], false);
        }
    }
}

/**
 * @file Regular expression utilities
 */
// Special RegExp constants
const REGEX_START = CARET; // '^'
const REGEX_END = DOLLAR_SIGN; // '$'
const REGEX_ANY_CHARACTERS = DOT + ASTERISK; // '.*'
// Special adblock pattern symbols and their RegExp equivalents
const ADBLOCK_URL_START = PIPE + PIPE; // '||'
const ADBLOCK_URL_START_REGEX = '^(http|https|ws|wss)://([a-z0-9-_.]+\\.)?';
const ADBLOCK_URL_SEPARATOR = CARET; // '^'
const ADBLOCK_URL_SEPARATOR_REGEX = '([^ a-zA-Z0-9.%_-]|$)';
const ADBLOCK_WILDCARD = ASTERISK; // '*'
const ADBLOCK_WILDCARD_REGEX = REGEX_ANY_CHARACTERS;
// Negation wrapper for RegExp patterns
const REGEX_NEGATION_PREFIX = '^((?!';
const REGEX_NEGATION_SUFFIX = ').)*$';
/**
 * Special RegExp symbols
 *
 * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#special-escape
 */
const SPECIAL_REGEX_SYMBOLS = new Set([
    ASTERISK,
    CARET,
    CLOSE_CURLY_BRACKET,
    CLOSE_PARENTHESIS,
    CLOSE_SQUARE_BRACKET,
    DOLLAR_SIGN,
    DOT,
    ESCAPE_CHARACTER,
    OPEN_CURLY_BRACKET,
    OPEN_PARENTHESIS,
    OPEN_SQUARE_BRACKET,
    PIPE,
    PLUS,
    QUESTION_MARK,
    SLASH,
]);
/**
 * Utility functions for working with RegExp patterns
 */
class RegExpUtils {
    /**
     * Checks whether a string possibly is a RegExp pattern.
     * Flags are not supported.
     *
     * Note: it does not perform a full validation of the pattern,
     * it just checks if the string starts and ends with a slash.
     *
     * @param pattern - Pattern to check
     * @returns `true` if the string is a RegExp pattern, `false` otherwise
     */
    static isRegexPattern(pattern) {
        const trimmedPattern = pattern.trim();
        // Avoid false positives
        return trimmedPattern.length > REGEX_MARKER.length * 2
            && trimmedPattern.startsWith(REGEX_MARKER)
            && trimmedPattern.endsWith(REGEX_MARKER)
            && trimmedPattern[REGEX_MARKER.length - 2] !== ESCAPE_CHARACTER;
    }
    /**
     * Negates a RegExp pattern. Technically, this method wraps the pattern in `^((?!` and `).)*$`.
     *
     * RegExp modifiers are not supported.
     *
     * @param pattern Pattern to negate (can be wrapped in slashes or not)
     * @returns Negated RegExp pattern
     */
    static negateRegexPattern(pattern) {
        let result = pattern.trim();
        let slashes = false;
        // Remove the leading and trailing slashes (/)
        if (RegExpUtils.isRegexPattern(result)) {
            result = result.substring(REGEX_MARKER.length, result.length - REGEX_MARKER.length);
            slashes = true;
        }
        // Only negate the pattern if it's not already negated
        if (!(result.startsWith(REGEX_NEGATION_PREFIX) && result.endsWith(REGEX_NEGATION_SUFFIX))) {
            // Remove leading caret (^)
            if (result.startsWith(REGEX_START)) {
                result = result.substring(REGEX_START.length);
            }
            // Remove trailing dollar sign ($)
            if (result.endsWith(REGEX_END)) {
                result = result.substring(0, result.length - REGEX_END.length);
            }
            // Wrap the pattern in the negation
            result = `${REGEX_NEGATION_PREFIX}${result}${REGEX_NEGATION_SUFFIX}`;
        }
        // Add the leading and trailing slashes back if they were there
        if (slashes) {
            result = `${REGEX_MARKER}${result}${REGEX_MARKER}`;
        }
        return result;
    }
    /**
     * Converts a basic adblock rule pattern to a RegExp pattern. Based on
     * https://github.com/AdguardTeam/tsurlfilter/blob/9b26e0b4a0e30b87690bc60f7cf377d112c3085c/packages/tsurlfilter/src/rules/simple-regex.ts#L219
     *
     * @param pattern Pattern to convert
     * @returns RegExp equivalent of the pattern
     * @see {@link https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#basic-rules}
     */
    static patternToRegexp(pattern) {
        const trimmed = pattern.trim();
        // Return regex for any character sequence if the pattern is just |, ||, * or empty
        if (trimmed === ADBLOCK_URL_START
            || trimmed === PIPE
            || trimmed === ADBLOCK_WILDCARD
            || trimmed === EMPTY) {
            return REGEX_ANY_CHARACTERS;
        }
        // If the pattern is already a RegExp, just return it, but remove the leading and trailing slashes
        if (RegExpUtils.isRegexPattern(pattern)) {
            return pattern.substring(REGEX_MARKER.length, pattern.length - REGEX_MARKER.length);
        }
        let result = EMPTY;
        let offset = 0;
        let len = trimmed.length;
        // Handle leading pipes
        if (trimmed[0] === PIPE) {
            if (trimmed[1] === PIPE) {
                // Replace adblock url start (||) with its RegExp equivalent
                result += ADBLOCK_URL_START_REGEX;
                offset = ADBLOCK_URL_START.length;
            }
            else {
                // Replace single pipe (|) with the RegExp start symbol (^)
                result += REGEX_START;
                offset = REGEX_START.length;
            }
        }
        // Handle trailing pipes
        let trailingPipe = false;
        if (trimmed.endsWith(PIPE)) {
            trailingPipe = true;
            len -= PIPE.length;
        }
        // Handle the rest of the pattern, if any
        for (; offset < len; offset += 1) {
            if (trimmed[offset] === ADBLOCK_WILDCARD) {
                // Replace adblock wildcard (*) with its RegExp equivalent
                result += ADBLOCK_WILDCARD_REGEX;
            }
            else if (trimmed[offset] === ADBLOCK_URL_SEPARATOR) {
                // Replace adblock url separator (^) with its RegExp equivalent
                result += ADBLOCK_URL_SEPARATOR_REGEX;
            }
            else if (SPECIAL_REGEX_SYMBOLS.has(trimmed[offset])) {
                // Escape special RegExp symbols (we handled pipe (|) and asterisk (*) already)
                result += ESCAPE_CHARACTER + trimmed[offset];
            }
            else {
                // Just add any other character
                result += trimmed[offset];
            }
        }
        // Handle trailing pipes
        if (trailingPipe) {
            // Replace trailing pipe (|) with the RegExp end symbol ($)
            result += REGEX_END;
        }
        return result;
    }
}

/**
 * @file Custom clone functions for AST nodes, this is probably the most efficient way to clone AST nodes.
 * @todo Maybe move them to parser classes as 'clone' methods
 */
/**
 * Clones a scriptlet rule node.
 *
 * @param node Node to clone
 * @returns Cloned node
 */
function cloneScriptletRuleNode(node) {
    return {
        type: node.type,
        children: node.children.map((child) => (isNull(child) ? null : { ...child })),
    };
}
/**
 * Clones a domain list node.
 *
 * @param node Node to clone
 * @returns Cloned node
 */
function cloneDomainListNode(node) {
    return {
        type: node.type,
        separator: node.separator,
        children: node.children.map((domain) => ({ ...domain })),
    };
}
/**
 * Clones a modifier list node.
 *
 * @param node Node to clone
 * @returns Cloned node
 */
function cloneModifierListNode(node) {
    return {
        type: node.type,
        children: node.children.map((modifier) => {
            const res = {
                type: modifier.type,
                exception: modifier.exception,
                name: { ...modifier.name },
            };
            if (modifier.value) {
                res.value = { ...modifier.value };
            }
            return res;
        }),
    };
}

/**
 * @file HTML filtering rule converter
 */
/**
 * From the AdGuard docs:
 * Specifies the maximum length for content of HTML element. If this parameter is
 * set and the content length exceeds the value, a rule does not apply to the element.
 * If this parameter is not specified, the max-length is considered to be 8192 (8 KB).
 * When converting from other formats, we set the max-length to 262144 (256 KB).
 *
 * @see {@link https://adguard.com/kb/general/ad-filtering/create-own-filters/#html-filtering-rules}
 */
const ADG_HTML_DEFAULT_MAX_LENGTH = 8192;
const ADG_HTML_CONVERSION_MAX_LENGTH = ADG_HTML_DEFAULT_MAX_LENGTH * 32;
const NOT_SPECIFIED = -1;
var PseudoClasses$1;
(function (PseudoClasses) {
    PseudoClasses["Contains"] = "contains";
    PseudoClasses["HasText"] = "has-text";
    PseudoClasses["MinTextLength"] = "min-text-length";
})(PseudoClasses$1 || (PseudoClasses$1 = {}));
var AttributeSelectors;
(function (AttributeSelectors) {
    AttributeSelectors["MaxLength"] = "max-length";
    AttributeSelectors["MinLength"] = "min-length";
    AttributeSelectors["TagContent"] = "tag-content";
    AttributeSelectors["Wildcard"] = "wildcard";
})(AttributeSelectors || (AttributeSelectors = {}));
const SUPPORTED_UBO_PSEUDO_CLASSES = new Set([
    PseudoClasses$1.Contains,
    PseudoClasses$1.HasText,
    PseudoClasses$1.MinTextLength,
]);
const ERROR_MESSAGES$2 = {
    ABP_NOT_SUPPORTED: 'Invalid rule, ABP does not support HTML filtering rules',
    TAG_SHOULD_BE_FIRST_CHILD: "Unexpected token '%s' with value '%s', tag selector should be the first child",
    EXPECTED_BUT_GOT_WITH_VALUE: "Expected '%s', but got '%s' with value '%s'",
    INVALID_ATTRIBUTE_NAME: "Attribute name should be an identifier, but got '%s' with value '%s'",
    // eslint-disable-next-line max-len
    INVALID_ATTRIBUTE_VALUE: `Expected '${(0,csstokenizer/* getFormattedTokenName */.PE)(csstokenizer/* TokenType.Ident */.iv.Ident)}' or '${(0,csstokenizer/* getFormattedTokenName */.PE)(csstokenizer/* TokenType.String */.iv.String)}' as attribute value, but got '%s' with value '%s`,
    INVALID_FLAG: "Unsupported attribute selector flag '%s'",
    INVALID_OPERATOR_FOR_ATTR: "Unsupported operator '%s' for '%s' attribute",
    VALUE_FOR_ATTR_SHOULD_BE_INT: "Value for '%s' attribute should be an integer, but got '%s'",
    INVALID_PSEUDO_CLASS: "Unsupported pseudo class '%s'",
    VALUE_FOR_PSEUDO_CLASS_SHOULD_BE_INT: "Value for '%s' pseudo class should be an integer, but got '%s'",
    // eslint-disable-next-line max-len
    REGEXP_NOT_SUPPORTED: "Cannot convert RegExp parameter '%s' from '%s' pseudo class, because converting RegExp patterns are not supported yet",
    ATTRIBUTE_SELECTOR_REQUIRES_VALUE: "Attribute selector '%s' requires a value",
    INVALID_ATTRIBUTE_SELECTOR_OPERATOR: "Unsupported attribute selector operator '%s'",
    VALUE_SHOULD_BE_SPECIFIED: 'Value should be specified if operator is specified',
    OPERATOR_SHOULD_BE_SPECIFIED: 'Operator should be specified if value is specified',
    UNEXPECTED_TOKEN_WITH_VALUE: "Unexpected token '%s' with value '%s'",
    FLAGS_NOT_SUPPORTED: 'Flags are not supported for attribute selectors',
};
/**
 * Convert `""` to `\"` within strings, because it does not compatible with the standard CSS syntax.
 *
 * @param selector CSS selector string
 * @returns Escaped CSS selector
 * @note In the legacy syntax, `""` is used to escape double quotes, but it cannot be used in the standard CSS syntax,
 * so we use conversion functions to handle this.
 * @see {@link https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#tag-content}
 */
function escapeDoubleQuotes(selector) {
    let withinString = false;
    const buffer = [];
    for (let i = 0; i < selector.length; i += 1) {
        if (!withinString && selector[i] === DOUBLE_QUOTE_MARKER) {
            withinString = true;
            buffer.push(selector[i]);
        }
        else if (withinString && selector[i] === DOUBLE_QUOTE_MARKER && selector[i + 1] === DOUBLE_QUOTE_MARKER) {
            buffer.push(ESCAPE_CHARACTER);
            buffer.push(DOUBLE_QUOTE_MARKER);
            i += 1;
        }
        else if (withinString && selector[i] === DOUBLE_QUOTE_MARKER && selector[i + 1] !== DOUBLE_QUOTE_MARKER) {
            buffer.push(DOUBLE_QUOTE_MARKER);
            withinString = false;
        }
        else {
            buffer.push(selector[i]);
        }
    }
    return buffer.join(EMPTY);
}
/**
 * Convert escaped double quotes `\"` to `""` within strings.
 *
 * @param selector CSS selector string
 * @returns Unescaped CSS selector
 * @note In the legacy syntax, `""` is used to escape double quotes, but it cannot be used in the standard CSS syntax,
 * so we use conversion functions to handle this.
 * @see {@link https://kb.adguard.com/en/general/how-to-create-your-own-ad-filters#tag-content}
 */
function unescapeDoubleQuotes(selector) {
    let withinString = false;
    const buffer = [];
    for (let i = 0; i < selector.length; i += 1) {
        if (selector[i] === DOUBLE_QUOTE_MARKER && selector[i - 1] !== ESCAPE_CHARACTER) {
            withinString = !withinString;
            buffer.push(selector[i]);
        }
        else if (withinString && selector[i] === ESCAPE_CHARACTER && selector[i + 1] === DOUBLE_QUOTE_MARKER) {
            buffer.push(DOUBLE_QUOTE_MARKER);
        }
        else {
            buffer.push(selector[i]);
        }
    }
    return buffer.join(EMPTY);
}
/**
 * Helper function to render an attribute selector
 *
 * @param attr Attribute name
 * @param op Operator (optional)
 * @param value Attribute value (optional)
 * @param flags Attribute flags (optional)
 * @returns Rendered attribute selector string
 */
function renderAttrSelector(attr, op, value, flags) {
    const result = [];
    result.push(OPEN_SQUARE_BRACKET);
    result.push(attr);
    if (op !== undefined) {
        if (value === undefined) {
            throw new Error(ERROR_MESSAGES$2.VALUE_SHOULD_BE_SPECIFIED);
        }
        result.push(op);
    }
    if (value !== undefined) {
        if (!op) {
            throw new Error(ERROR_MESSAGES$2.OPERATOR_SHOULD_BE_SPECIFIED);
        }
        result.push(DOUBLE_QUOTE_MARKER);
        result.push(value);
        result.push(DOUBLE_QUOTE_MARKER);
    }
    if (flags !== undefined) {
        result.push(SPACE);
        result.push(flags);
    }
    result.push(CLOSE_SQUARE_BRACKET);
    return result.join(EMPTY);
}
/**
 * HTML filtering rule converter class
 *
 * @todo Implement `convertToUbo` (ABP currently doesn't support HTML filtering rules)
 */
class HtmlRuleConverter extends RuleConverterBase {
    /**
     * Converts a HTML rule to AdGuard syntax, if possible. Also can be used to convert
     * AdGuard rules to AdGuard syntax to validate them.
     *
     * _Note:_ uBlock Origin supports multiple selectors within a single rule, but AdGuard doesn't,
     * so the following rule
     * ```
     * example.com##^div[attr1="value1"][attr2="value2"], script:has-text(value)
     * ```
     * will be converted to multiple AdGuard rules:
     * ```
     * example.com$$div[attr1="value1"][attr2="value2"][max-length="262144"]
     * example.com$$script[tag-content="value"][max-length="262144"]
     * ```
     *
     * @param rule Rule node to convert
     * @returns An object which follows the {@link NodeConversionResult} interface. Its `result` property contains
     * the array of converted rule nodes, and its `isConverted` flag indicates whether the original rule was converted.
     * If the rule was not converted, the result array will contain the original node with the same object reference
     * @throws If the rule is invalid or cannot be converted
     */
    static convertToAdg(rule) {
        // Ignore AdGuard rules
        if (rule.syntax === AdblockSyntax.Adg) {
            return createNodeConversionResult([rule], false);
        }
        if (rule.syntax === AdblockSyntax.Abp) {
            throw new RuleConversionError(ERROR_MESSAGES$2.ABP_NOT_SUPPORTED);
        }
        const source = escapeDoubleQuotes(rule.body.value);
        const stream = new CssTokenStream(source);
        const convertedSelector = [];
        const convertedSelectorList = [];
        let minLen = NOT_SPECIFIED;
        let maxLen = NOT_SPECIFIED;
        // Skip leading whitespace
        stream.skipWhitespace();
        // Skip ^
        stream.expect(csstokenizer/* TokenType.Delim */.iv.Delim, { value: UBO_HTML_MASK });
        stream.advance();
        while (!stream.isEof()) {
            const token = stream.getOrFail();
            if (token.type === csstokenizer/* TokenType.Ident */.iv.Ident) {
                // Tag selector should be the first child, if present, but whitespace is allowed before it
                if (convertedSelector.length !== 0 && stream.lookbehindForNonWs() !== undefined) {
                    throw new RuleConversionError((0,sprintf.sprintf)(ERROR_MESSAGES$2.TAG_SHOULD_BE_FIRST_CHILD, (0,csstokenizer/* getFormattedTokenName */.PE)(token.type), source.slice(token.start, token.end)));
                }
                convertedSelector.push(source.slice(token.start, token.end));
                stream.advance();
            }
            else if (token.type === csstokenizer/* TokenType.OpenSquareBracket */.iv.OpenSquareBracket) {
                // Attribute selectors: https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors#syntax
                const { start } = token;
                let tempToken;
                // Advance opening square bracket
                stream.advance();
                // Skip optional whitespace after the opening square bracket
                stream.skipWhitespace();
                // Parse attribute name
                tempToken = stream.getOrFail();
                if (tempToken.type !== csstokenizer/* TokenType.Ident */.iv.Ident) {
                    throw new RuleConversionError((0,sprintf.sprintf)(ERROR_MESSAGES$2.INVALID_ATTRIBUTE_NAME, (0,csstokenizer/* getFormattedTokenName */.PE)(tempToken.type), source.slice(tempToken.start, tempToken.end)));
                }
                const attr = source.slice(tempToken.start, tempToken.end);
                stream.advance();
                // Skip optional whitespace after the attribute name
                stream.skipWhitespace();
                // Maybe attribute selector ends here, because value is not required, like in '[disabled]'
                tempToken = stream.getOrFail();
                // So check if the next non whitespace token is a closing square bracket
                if (tempToken.type === csstokenizer/* TokenType.CloseSquareBracket */.iv.CloseSquareBracket) {
                    const { end } = tempToken;
                    stream.advance();
                    // Special case for min-length and max-length attributes
                    if (attr === AttributeSelectors.MinLength || attr === AttributeSelectors.MaxLength) {
                        throw new RuleConversionError((0,sprintf.sprintf)(ERROR_MESSAGES$2.ATTRIBUTE_SELECTOR_REQUIRES_VALUE, attr));
                    }
                    convertedSelector.push(source.slice(start, end));
                    continue;
                }
                // Next token should be a valid attribute selector operator
                // Only '=' operator is supported
                stream.expect(csstokenizer/* TokenType.Delim */.iv.Delim, { value: EQUALS });
                // Advance the operator
                stream.advance();
                // Skip optional whitespace after the operator
                stream.skipWhitespace();
                // Parse attribute value
                tempToken = stream.getOrFail();
                // According to the spec, attribute value should be an identifier or a string
                if (tempToken.type !== csstokenizer/* TokenType.Ident */.iv.Ident && tempToken.type !== csstokenizer/* TokenType.String */.iv.String) {
                    throw new RuleConversionError((0,sprintf.sprintf)(ERROR_MESSAGES$2.INVALID_ATTRIBUTE_VALUE, (0,csstokenizer/* getFormattedTokenName */.PE)(tempToken.type), source.slice(tempToken.start, tempToken.end)));
                }
                const value = source.slice(tempToken.start, tempToken.end);
                // Advance the attribute value
                stream.advance();
                // Skip optional whitespace after the attribute value
                stream.skipWhitespace();
                // Attribute selector may have flags - but AdGuard HTML filtering does not support them
                tempToken = stream.getOrFail();
                if (tempToken.type === csstokenizer/* TokenType.Ident */.iv.Ident) {
                    throw new RuleConversionError((0,sprintf.sprintf)(ERROR_MESSAGES$2.FLAGS_NOT_SUPPORTED));
                }
                // Next token should be a closing square bracket
                stream.expect(csstokenizer/* TokenType.CloseSquareBracket */.iv.CloseSquareBracket);
                const { end } = stream.getOrFail();
                stream.advance();
                if (attr === AttributeSelectors.MinLength) {
                    // Min length attribute
                    const parsed = parseInt(value, 10);
                    if (Number.isNaN(parsed)) {
                        throw new RuleConversionError((0,sprintf.sprintf)(ERROR_MESSAGES$2.VALUE_FOR_ATTR_SHOULD_BE_INT, attr, value));
                    }
                    minLen = parsed;
                }
                else if (attr === AttributeSelectors.MaxLength) {
                    // Max length attribute
                    const parsed = parseInt(value, 10);
                    if (Number.isNaN(parsed)) {
                        throw new RuleConversionError((0,sprintf.sprintf)(ERROR_MESSAGES$2.VALUE_FOR_ATTR_SHOULD_BE_INT, attr, value));
                    }
                    maxLen = parsed;
                }
                else {
                    convertedSelector.push(source.slice(start, end));
                }
            }
            else if (token.type === csstokenizer/* TokenType.Colon */.iv.Colon) {
                let tempToken;
                // Pseudo classes: https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes#syntax
                stream.advance();
                // Next token should be a pseudo class name
                stream.expect(csstokenizer/* TokenType.Function */.iv.Function);
                tempToken = stream.getOrFail();
                const fn = source.slice(tempToken.start, tempToken.end - 1); // do not include '('
                // Pseudo class should be supported
                if (!SUPPORTED_UBO_PSEUDO_CLASSES.has(fn)) {
                    throw new RuleConversionError((0,sprintf.sprintf)(ERROR_MESSAGES$2.INVALID_PSEUDO_CLASS, fn));
                }
                const paramStart = tempToken.end;
                // Find the closing paren
                stream.skipUntilBalanced();
                tempToken = stream.getOrFail();
                const paramEnd = tempToken.end;
                // Get the parameter
                const param = source.slice(paramStart, paramEnd - 1);
                if (fn === PseudoClasses$1.MinTextLength) {
                    // Min text length pseudo class
                    // Parameter should be parsed as an integer
                    const parsed = parseInt(param, 10);
                    if (Number.isNaN(parsed)) {
                        throw new RuleConversionError((0,sprintf.sprintf)(ERROR_MESSAGES$2.VALUE_FOR_PSEUDO_CLASS_SHOULD_BE_INT, fn, param));
                    }
                    minLen = parsed;
                }
                else if (fn === PseudoClasses$1.Contains || fn === PseudoClasses$1.HasText) {
                    // Contains and has-text pseudo classes
                    // Check if the argument is a RegExp
                    if (RegExpUtils.isRegexPattern(param)) {
                        // TODO: Add some support for RegExp patterns later
                        // Need to find a way to convert some RegExp patterns to glob patterns
                        throw new RuleConversionError((0,sprintf.sprintf)(ERROR_MESSAGES$2.REGEXP_NOT_SUPPORTED, param, fn));
                    }
                    // Escape unescaped double quotes in the parameter
                    const paramEscaped = StringUtils.escapeCharacter(param, DOUBLE_QUOTE_MARKER);
                    convertedSelector.push(renderAttrSelector(AttributeSelectors.TagContent, EQUALS, paramEscaped));
                }
                stream.advance();
            }
            else if (token.type === csstokenizer/* TokenType.Comma */.iv.Comma && token.balance === 0) {
                if (minLen !== NOT_SPECIFIED) {
                    convertedSelector.push(renderAttrSelector(AttributeSelectors.MinLength, EQUALS, minLen.toString()));
                }
                convertedSelector.push(renderAttrSelector(AttributeSelectors.MaxLength, EQUALS, maxLen !== NOT_SPECIFIED ? maxLen.toString() : ADG_HTML_CONVERSION_MAX_LENGTH.toString()));
                convertedSelectorList.push(convertedSelector.join(EMPTY));
                convertedSelector.length = 0;
                stream.advance();
            }
            else if (token.type === csstokenizer/* TokenType.Whitespace */.iv.Whitespace) {
                stream.advance();
            }
            else {
                throw new RuleConversionError((0,sprintf.sprintf)(ERROR_MESSAGES$2.UNEXPECTED_TOKEN_WITH_VALUE, (0,csstokenizer/* getFormattedTokenName */.PE)(token.type), source.slice(token.start, token.end)));
            }
        }
        if (convertedSelector.length !== 0) {
            if (minLen !== NOT_SPECIFIED) {
                convertedSelector.push(renderAttrSelector(AttributeSelectors.MinLength, EQUALS, minLen.toString()));
            }
            convertedSelector.push(renderAttrSelector(AttributeSelectors.MaxLength, EQUALS, maxLen !== NOT_SPECIFIED ? maxLen.toString() : ADG_HTML_CONVERSION_MAX_LENGTH.toString()));
            convertedSelectorList.push(convertedSelector.join(EMPTY));
        }
        return createNodeConversionResult(
        // Since AdGuard HTML filtering rules do not support multiple selectors, we need to split each selector
        // into a separate rule node.
        convertedSelectorList.map((selector) => ({
            category: RuleCategory.Cosmetic,
            type: CosmeticRuleType.HtmlFilteringRule,
            syntax: AdblockSyntax.Adg,
            exception: rule.exception,
            domains: cloneDomainListNode(rule.domains),
            // Convert the separator based on the exception status
            separator: {
                type: 'Value',
                value: rule.exception
                    ? CosmeticRuleSeparator.AdgHtmlFilteringException
                    : CosmeticRuleSeparator.AdgHtmlFiltering,
            },
            body: {
                type: 'Value',
                value: unescapeDoubleQuotes(selector),
            },
        })), true);
    }
}

/**
 * @file Utility functions for working with scriptlet nodes
 */
/**
 * Get name of the scriptlet from the scriptlet node
 *
 * @param scriptletNode Scriptlet node to get name of
 * @returns Name of the scriptlet
 * @throws If the scriptlet is empty
 */
function getScriptletName(scriptletNode) {
    if (scriptletNode.children.length === 0) {
        throw new Error('Empty scriptlet');
    }
    return scriptletNode.children[0]?.value ?? EMPTY;
}
/**
 * Transform the nth argument of the scriptlet node
 *
 * @param scriptletNode Scriptlet node to transform argument of
 * @param index Index of the argument to transform (index 0 is the scriptlet name)
 * @param transform Function to transform the argument
 */
function transformNthScriptletArgument(scriptletNode, index, transform) {
    const child = scriptletNode.children[index];
    if (!isUndefined(child)) {
        const transformed = transform(child?.value ?? null);
        if (isNull(transformed)) {
            // eslint-disable-next-line no-param-reassign
            scriptletNode.children[index] = null;
            return;
        }
        if (isNull(child)) {
            // eslint-disable-next-line no-param-reassign
            scriptletNode.children[index] = {
                type: 'Value',
                value: transformed,
            };
            return;
        }
        child.value = transformed;
    }
}
/**
 * Transform all arguments of the scriptlet node
 *
 * @param scriptletNode Scriptlet node to transform arguments of
 * @param transform Function to transform the arguments
 */
function transformAllScriptletArguments(scriptletNode, transform) {
    for (let i = 0; i < scriptletNode.children.length; i += 1) {
        transformNthScriptletArgument(scriptletNode, i, transform);
    }
}
/**
 * Set name of the scriptlet.
 * Modifies input `scriptletNode` if needed.
 *
 * @param scriptletNode Scriptlet node to set name of
 * @param name Name to set
 */
function setScriptletName(scriptletNode, name) {
    transformNthScriptletArgument(scriptletNode, 0, () => name);
}
/**
 * Set quote type of the scriptlet parameters
 *
 * @param scriptletNode Scriptlet node to set quote type of
 * @param quoteType Preferred quote type
 */
function setScriptletQuoteType(scriptletNode, quoteType) {
    // null is a special value that means "no value", but we can't change its quote type,
    // so we need to convert it to empty string
    transformAllScriptletArguments(scriptletNode, (value) => QuoteUtils.setStringQuoteType(value ?? EMPTY, quoteType));
}

/**
 * @file Resource type schema.
 */
/**
 * Resource type.
 *
 * @see {@link https://developer.chrome.com/docs/extensions/reference/declarativeNetRequest/#type-ResourceType}
 */
var ResourceType;
(function (ResourceType) {
    ResourceType["MainFrame"] = "main_frame";
    ResourceType["SubFrame"] = "sub_frame";
    ResourceType["Stylesheet"] = "stylesheet";
    ResourceType["Script"] = "script";
    ResourceType["Image"] = "image";
    ResourceType["Font"] = "font";
    ResourceType["Object"] = "object";
    ResourceType["XmlHttpRequest"] = "xmlhttprequest";
    ResourceType["Ping"] = "ping";
    ResourceType["Media"] = "media";
    ResourceType["WebSocket"] = "websocket";
    ResourceType["Other"] = "other";
})(ResourceType || (ResourceType = {}));
/**
 * Resource type schema.
 */
const resourceTypeSchema = zod_lib/* default.nativeEnum */.ZP.nativeEnum(ResourceType);

/**
 * Map of resource types to their corresponding adblock modifier names.
 *
 * @note Record type is used to ensure that all resource types are present in the map.
 */
const RESOURCE_TYPE_MODIFIER_MAP = Object.freeze({
    [ResourceType.MainFrame]: 'document',
    [ResourceType.SubFrame]: 'subdocument',
    [ResourceType.Stylesheet]: 'stylesheet',
    [ResourceType.Script]: 'script',
    [ResourceType.Image]: 'image',
    [ResourceType.Font]: 'font',
    [ResourceType.Object]: 'object',
    [ResourceType.XmlHttpRequest]: 'xmlhttprequest',
    [ResourceType.Ping]: 'ping',
    [ResourceType.Media]: 'media',
    [ResourceType.WebSocket]: 'websocket',
    [ResourceType.Other]: 'other',
});
/**
 * Gets the adblock modifier name for the given resource type.
 *
 * @param resourceType Resource type to get the modifier name for.
 * @param platform Platform to get the modifier for.
 *
 * @returns A string containing the adblock modifier name for the given resource type
 * or `null` if the modifier could not be found.
 */
const getResourceTypeModifier = (resourceType, platform) => {
    const modifierName = RESOURCE_TYPE_MODIFIER_MAP[resourceType];
    if (!modifierName) {
        return null;
    }
    const modifierData = modifiersCompatibilityTable.getFirst(modifierName, platform);
    if (isNull(modifierData)) {
        return null;
    }
    return modifierData.name;
};
/**
 * Checks if the given resource type is valid.
 *
 * @param resourceType Resource type to check.
 *
 * @returns `true` if the resource type is valid, `false` otherwise.
 */
const isValidResourceType = (resourceType) => {
    return Object.values(ResourceType).includes(resourceType);
};

/**
 * @file Compatibility tables for redirects.
 */
/**
 * Prefix for resource redirection names.
 */
const ABP_RESOURCE_PREFIX = 'abp-resource:';
const ABP_RESOURCE_PREFIX_LENGTH = ABP_RESOURCE_PREFIX.length;
/**
 * Normalizes the redirect name.
 *
 * @param name Redirect name to normalize.
 *
 * @returns Normalized redirect name.
 *
 * @example
 * redirectNameNormalizer('abp-resource:my-resource') // => 'my-resource'
 * redirectNameNormalizer('noop.js:99') // => 'noop.js'
 */
const redirectNameNormalizer = (name) => {
    // Remove ABP resource prefix, if present
    if (name.startsWith(ABP_RESOURCE_PREFIX)) {
        return name.slice(ABP_RESOURCE_PREFIX_LENGTH);
    }
    // Remove :[integer] priority suffix from the name, if present
    // See:
    // - https://github.com/AdguardTeam/tsurlfilter/issues/59
    // - https://github.com/gorhill/uBlock/wiki/Static-filter-syntax#redirect
    const colonIndex = name.lastIndexOf(COLON);
    if (colonIndex !== -1 && /^\d+$/.test(name.slice(colonIndex + 1))) {
        return name.slice(0, colonIndex);
    }
    return name;
};
/**
 * Compatibility table for redirects.
 */
class RedirectsCompatibilityTable extends CompatibilityTableBase {
    /**
     * Creates a new instance of the compatibility table for redirects.
     *
     * @param data Compatibility table data.
     */
    constructor(data) {
        super(data, redirectNameNormalizer);
    }
    /**
     * Gets the resource type adblock modifiers for the redirect for the given platform
     * based on the `resourceTypes` field.
     *
     * @param redirect Redirect name or redirect data.
     * @param platform Platform to get the modifiers for.
     *
     * @returns Set of resource type modifiers or an empty set if the redirect is not found or has no resource types.
     */
    getResourceTypeModifiers(redirect, platform) {
        let redirectData = null;
        if (isString(redirect)) {
            redirectData = this.getFirst(redirect, platform);
        }
        else {
            redirectData = redirect;
        }
        const modifierNames = new Set();
        if (isNull(redirectData) || isUndefined(redirectData.resourceTypes)) {
            return modifierNames;
        }
        for (const resourceType of redirectData.resourceTypes) {
            const modifierName = getResourceTypeModifier(resourceType, platform);
            if (isNull(modifierName)) {
                continue;
            }
            modifierNames.add(modifierName);
        }
        return modifierNames;
    }
}
/**
 * Deep freeze the compatibility table data to avoid accidental modifications.
 */
deepFreeze(compatibility_table_data/* redirectsCompatibilityTableData */.HL);
/**
 * Compatibility table instance for redirects.
 */
const redirectsCompatibilityTable = new RedirectsCompatibilityTable(compatibility_table_data/* redirectsCompatibilityTableData */.HL);

/**
 * @file Compatibility tables for scriptlets.
 */
/**
 * Compatibility table for scriptlets.
 */
class ScriptletsCompatibilityTable extends CompatibilityTableBase {
}
/**
 * Deep freeze the compatibility table data to avoid accidental modifications.
 */
deepFreeze(compatibility_table_data/* scriptletsCompatibilityTableData */.Rp);
/**
 * Compatibility table instance for scriptlets.
 */
const scriptletsCompatibilityTable = new ScriptletsCompatibilityTable(compatibility_table_data/* scriptletsCompatibilityTableData */.Rp);

/* eslint-disable no-bitwise */
/**
 * @file Platform schema.
 */
/**
 * Platform separator, e.g. 'adg_os_any|adg_safari_any' means any AdGuard OS platform and
 * any AdGuard Safari content blocker platform.
 */
const PLATFORM_SEPARATOR = '|';
/**
 * Platform negation character, e.g. 'adg_any|~adg_safari_any' means any AdGuard product except
 * Safari content blockers.
 */
const PLATFORM_NEGATION = '~';
/**
 * Parses a raw platform string into a platform bitmask.
 *
 * @param rawPlatforms Raw platform string, e.g. 'adg_safari_any|adg_os_any'.
 *
 * @returns Platform bitmask.
 */
const parseRawPlatforms = (rawPlatforms) => {
    // e.g. 'adg_safari_any|adg_os_any'
    const rawPlatformList = rawPlatforms
        .split(PLATFORM_SEPARATOR)
        .map((rawPlatform) => rawPlatform.trim());
    let result = 0;
    for (let rawPlatform of rawPlatformList) {
        // negation, e.g. 'adg_any|~adg_safari_any' means any AdGuard product except Safari content blockers
        let negated = false;
        if (rawPlatform.startsWith(PLATFORM_NEGATION)) {
            negated = true;
            rawPlatform = rawPlatform.slice(1).trim();
        }
        const platform = SPECIFIC_PLATFORM_MAP.get(rawPlatform) ?? GENERIC_PLATFORM_MAP.get(rawPlatform);
        if (isUndefined(platform)) {
            throw new Error(`Unknown platform: ${rawPlatform}`);
        }
        if (negated) {
            result &= ~platform;
        }
        else {
            result |= platform;
        }
    }
    if (result === 0) {
        throw new Error('No platforms specified');
    }
    return result;
};
/**
 * Platform schema.
 */
zod_lib/* default.string */.ZP.string()
    .min(1)
    .transform((value) => parseRawPlatforms(value));

function getDefaultExportFromCjs (x) {
	return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
}

var mapObj$1 = {exports: {}};

const isObject$1 = value => typeof value === 'object' && value !== null;
const mapObjectSkip = Symbol('skip');

// Customized for this use-case
const isObjectCustom = value =>
	isObject$1(value) &&
	!(value instanceof RegExp) &&
	!(value instanceof Error) &&
	!(value instanceof Date);

const mapObject = (object, mapper, options, isSeen = new WeakMap()) => {
	options = {
		deep: false,
		target: {},
		...options
	};

	if (isSeen.has(object)) {
		return isSeen.get(object);
	}

	isSeen.set(object, options.target);

	const {target} = options;
	delete options.target;

	const mapArray = array => array.map(element => isObjectCustom(element) ? mapObject(element, mapper, options, isSeen) : element);
	if (Array.isArray(object)) {
		return mapArray(object);
	}

	for (const [key, value] of Object.entries(object)) {
		const mapResult = mapper(key, value, object);

		if (mapResult === mapObjectSkip) {
			continue;
		}

		let [newKey, newValue, {shouldRecurse = true} = {}] = mapResult;

		// Drop `__proto__` keys.
		if (newKey === '__proto__') {
			continue;
		}

		if (options.deep && shouldRecurse && isObjectCustom(newValue)) {
			newValue = Array.isArray(newValue) ?
				mapArray(newValue) :
				mapObject(newValue, mapper, options, isSeen);
		}

		target[newKey] = newValue;
	}

	return target;
};

mapObj$1.exports = (object, mapper, options) => {
	if (!isObject$1(object)) {
		throw new TypeError(`Expected an object, got \`${object}\` (${typeof object})`);
	}

	return mapObject(object, mapper, options);
};

mapObj$1.exports.mapObjectSkip = mapObjectSkip;

var mapObjExports = mapObj$1.exports;

var camelcase = {exports: {}};

const UPPERCASE = /[\p{Lu}]/u;
const LOWERCASE = /[\p{Ll}]/u;
const LEADING_CAPITAL = /^[\p{Lu}](?![\p{Lu}])/gu;
const IDENTIFIER = /([\p{Alpha}\p{N}_]|$)/u;
const SEPARATORS = /[_.\- ]+/;

const LEADING_SEPARATORS = new RegExp('^' + SEPARATORS.source);
const SEPARATORS_AND_IDENTIFIER = new RegExp(SEPARATORS.source + IDENTIFIER.source, 'gu');
const NUMBERS_AND_IDENTIFIER = new RegExp('\\d+' + IDENTIFIER.source, 'gu');

const preserveCamelCase = (string, toLowerCase, toUpperCase) => {
	let isLastCharLower = false;
	let isLastCharUpper = false;
	let isLastLastCharUpper = false;

	for (let i = 0; i < string.length; i++) {
		const character = string[i];

		if (isLastCharLower && UPPERCASE.test(character)) {
			string = string.slice(0, i) + '-' + string.slice(i);
			isLastCharLower = false;
			isLastLastCharUpper = isLastCharUpper;
			isLastCharUpper = true;
			i++;
		} else if (isLastCharUpper && isLastLastCharUpper && LOWERCASE.test(character)) {
			string = string.slice(0, i - 1) + '-' + string.slice(i - 1);
			isLastLastCharUpper = isLastCharUpper;
			isLastCharUpper = false;
			isLastCharLower = true;
		} else {
			isLastCharLower = toLowerCase(character) === character && toUpperCase(character) !== character;
			isLastLastCharUpper = isLastCharUpper;
			isLastCharUpper = toUpperCase(character) === character && toLowerCase(character) !== character;
		}
	}

	return string;
};

const preserveConsecutiveUppercase = (input, toLowerCase) => {
	LEADING_CAPITAL.lastIndex = 0;

	return input.replace(LEADING_CAPITAL, m1 => toLowerCase(m1));
};

const postProcess = (input, toUpperCase) => {
	SEPARATORS_AND_IDENTIFIER.lastIndex = 0;
	NUMBERS_AND_IDENTIFIER.lastIndex = 0;

	return input.replace(SEPARATORS_AND_IDENTIFIER, (_, identifier) => toUpperCase(identifier))
		.replace(NUMBERS_AND_IDENTIFIER, m => toUpperCase(m));
};

const camelCase$1 = (input, options) => {
	if (!(typeof input === 'string' || Array.isArray(input))) {
		throw new TypeError('Expected the input to be `string | string[]`');
	}

	options = {
		pascalCase: false,
		preserveConsecutiveUppercase: false,
		...options
	};

	if (Array.isArray(input)) {
		input = input.map(x => x.trim())
			.filter(x => x.length)
			.join('-');
	} else {
		input = input.trim();
	}

	if (input.length === 0) {
		return '';
	}

	const toLowerCase = options.locale === false ?
		string => string.toLowerCase() :
		string => string.toLocaleLowerCase(options.locale);
	const toUpperCase = options.locale === false ?
		string => string.toUpperCase() :
		string => string.toLocaleUpperCase(options.locale);

	if (input.length === 1) {
		return options.pascalCase ? toUpperCase(input) : toLowerCase(input);
	}

	const hasUpperCase = input !== toLowerCase(input);

	if (hasUpperCase) {
		input = preserveCamelCase(input, toLowerCase, toUpperCase);
	}

	input = input.replace(LEADING_SEPARATORS, '');

	if (options.preserveConsecutiveUppercase) {
		input = preserveConsecutiveUppercase(input, toLowerCase);
	} else {
		input = toLowerCase(input);
	}

	if (options.pascalCase) {
		input = toUpperCase(input.charAt(0)) + input.slice(1);
	}

	return postProcess(input, toUpperCase);
};

camelcase.exports = camelCase$1;
// TODO: Remove this for the next major release
camelcase.exports.default = camelCase$1;

var camelcaseExports = camelcase.exports;

class QuickLRU {
	constructor(options = {}) {
		if (!(options.maxSize && options.maxSize > 0)) {
			throw new TypeError('`maxSize` must be a number greater than 0');
		}

		this.maxSize = options.maxSize;
		this.onEviction = options.onEviction;
		this.cache = new Map();
		this.oldCache = new Map();
		this._size = 0;
	}

	_set(key, value) {
		this.cache.set(key, value);
		this._size++;

		if (this._size >= this.maxSize) {
			this._size = 0;

			if (typeof this.onEviction === 'function') {
				for (const [key, value] of this.oldCache.entries()) {
					this.onEviction(key, value);
				}
			}

			this.oldCache = this.cache;
			this.cache = new Map();
		}
	}

	get(key) {
		if (this.cache.has(key)) {
			return this.cache.get(key);
		}

		if (this.oldCache.has(key)) {
			const value = this.oldCache.get(key);
			this.oldCache.delete(key);
			this._set(key, value);
			return value;
		}
	}

	set(key, value) {
		if (this.cache.has(key)) {
			this.cache.set(key, value);
		} else {
			this._set(key, value);
		}

		return this;
	}

	has(key) {
		return this.cache.has(key) || this.oldCache.has(key);
	}

	peek(key) {
		if (this.cache.has(key)) {
			return this.cache.get(key);
		}

		if (this.oldCache.has(key)) {
			return this.oldCache.get(key);
		}
	}

	delete(key) {
		const deleted = this.cache.delete(key);
		if (deleted) {
			this._size--;
		}

		return this.oldCache.delete(key) || deleted;
	}

	clear() {
		this.cache.clear();
		this.oldCache.clear();
		this._size = 0;
	}

	* keys() {
		for (const [key] of this) {
			yield key;
		}
	}

	* values() {
		for (const [, value] of this) {
			yield value;
		}
	}

	* [Symbol.iterator]() {
		for (const item of this.cache) {
			yield item;
		}

		for (const item of this.oldCache) {
			const [key] = item;
			if (!this.cache.has(key)) {
				yield item;
			}
		}
	}

	get size() {
		let oldCacheSize = 0;
		for (const key of this.oldCache.keys()) {
			if (!this.cache.has(key)) {
				oldCacheSize++;
			}
		}

		return Math.min(this._size + oldCacheSize, this.maxSize);
	}
}

var quickLru = QuickLRU;

const mapObj = mapObjExports;
const camelCase = camelcaseExports;
const QuickLru = quickLru;

const has = (array, key) => array.some(x => {
	if (typeof x === 'string') {
		return x === key;
	}

	x.lastIndex = 0;
	return x.test(key);
});

const cache = new QuickLru({maxSize: 100000});

// Reproduces behavior from `map-obj`
const isObject = value =>
	typeof value === 'object' &&
	value !== null &&
	!(value instanceof RegExp) &&
	!(value instanceof Error) &&
	!(value instanceof Date);

const camelCaseConvert = (input, options) => {
	if (!isObject(input)) {
		return input;
	}

	options = {
		deep: false,
		pascalCase: false,
		...options
	};

	const {exclude, pascalCase, stopPaths, deep} = options;

	const stopPathsSet = new Set(stopPaths);

	const makeMapper = parentPath => (key, value) => {
		if (deep && isObject(value)) {
			const path = parentPath === undefined ? key : `${parentPath}.${key}`;

			if (!stopPathsSet.has(path)) {
				value = mapObj(value, makeMapper(path));
			}
		}

		if (!(exclude && has(exclude, key))) {
			const cacheKey = pascalCase ? `${key}_` : key;

			if (cache.has(cacheKey)) {
				key = cache.get(cacheKey);
			} else {
				const returnValue = camelCase(key, {pascalCase, locale: false});

				if (key.length < 100) { // Prevent abuse
					cache.set(cacheKey, returnValue);
				}

				key = returnValue;
			}
		}

		return [key, value];
	};

	return mapObj(input, makeMapper(undefined));
};

var camelcaseKeys = (input, options) => {
	if (Array.isArray(input)) {
		return Object.keys(input).map(key => camelCaseConvert(input[key], options));
	}

	return camelCaseConvert(input, options);
};

var camelCaseKeys = /*@__PURE__*/getDefaultExportFromCjs(camelcaseKeys);

/**
 * @file Zod camelCase utility.
 */
// eslint-disable-next-line import/no-extraneous-dependencies
/**
 * Transforms Zod schema to camelCase.
 *
 * @param zod Zod schema.
 *
 * @returns Zod schema with camelCase properties.
 *
 * @see {@link https://github.com/colinhacks/zod/issues/486#issuecomment-1501097361}
 */
const zodToCamelCase = (zod) => {
    return zod.transform((val) => camelCaseKeys(val));
};

/**
 * @file Base compatibility data schema, which is commonly used in compatibility tables.
 */
/**
 * Zod schema for boolean values. Accepts both boolean and string values.
 */
const booleanSchema = zod_lib/* default.union */.ZP.union([
    zod_lib/* default.string */.ZP.string().transform((val) => val.trim().toLowerCase() === 'true'),
    zod_lib/* default.boolean */.ZP.boolean(),
]);
/**
 * Zod schema for non-empty string values.
 */
const nonEmptyStringSchema = zod_lib/* default.string */.ZP.string()
    .transform((val) => val.trim())
    .pipe(zod_lib/* default.string */.ZP.string().min(1));
/**
 * Zod schema for base compatibility data.
 * Here we use snake_case properties because the compatibility data is stored in YAML files.
 */
const baseCompatibilityDataSchema = zod_lib/* default.object */.ZP.object({
    /**
     * Name of the actual entity.
     */
    name: nonEmptyStringSchema,
    /**
     * List of aliases for the entity (if any).
     */
    aliases: zod_lib/* default.array */.ZP.array(nonEmptyStringSchema).nullable().default(null),
    /**
     * Short description of the actual entity.
     * If not specified or it's value is `null`, then the description is not available.
     */
    description: nonEmptyStringSchema.nullable().default(null),
    /**
     * Link to the documentation. If not specified or it's value is `null`, then the documentation is not available.
     */
    docs: nonEmptyStringSchema.nullable().default(null),
    /**
     * The version of the adblocker in which the entity was added.
     * For AdGuard resources, the version of the library is specified.
     */
    version_added: nonEmptyStringSchema.nullable().default(null),
    /**
     * The version of the adblocker when the entity was removed.
     */
    version_removed: nonEmptyStringSchema.nullable().default(null),
    /**
     * Describes whether the entity is deprecated.
     */
    deprecated: booleanSchema.default(false),
    /**
     * Message that describes why the entity is deprecated.
     * If not specified or it's value is `null`, then the message is not available.
     * It's value is omitted if the entity is not marked as deprecated.
     */
    deprecation_message: nonEmptyStringSchema.nullable().default(null),
    /**
     * Describes whether the entity is removed; for *already removed* features.
     */
    removed: booleanSchema.default(false),
    /**
     * Message that describes why the entity is removed.
     * If not specified or it's value is `null`, then the message is not available.
     * It's value is omitted if the entity is not marked as deprecated.
     */
    removal_message: nonEmptyStringSchema.nullable().default(null),
});
/**
 * Zod schema for base compatibility data with camelCase properties.
 */
zodToCamelCase(baseCompatibilityDataSchema);
/**
 * Refinement logic for base compatibility data.
 *
 * @param data Base compatibility data.
 * @param ctx Refinement context.
 */
const baseRefineLogic = (data, ctx) => {
    if (data.deprecated && !data.deprecation_message) {
        ctx.addIssue({
            code: zod_lib/* default.ZodIssueCode.custom */.ZP.ZodIssueCode.custom,
            message: 'deprecation_message is required for deprecated modifiers',
        });
    }
    if (!data.deprecated && data.deprecation_message) {
        ctx.addIssue({
            code: zod_lib/* default.ZodIssueCode.custom */.ZP.ZodIssueCode.custom,
            message: 'deprecation_message is only allowed for deprecated modifiers',
        });
    }
    if (data.aliases && data.aliases.length !== new Set(data.aliases).size) {
        ctx.addIssue({
            code: zod_lib/* default.ZodIssueCode.custom */.ZP.ZodIssueCode.custom,
            message: 'Aliases must be unique',
        });
    }
};

/**
 * Checks if error has message.
 *
 * @param error Error object.
 * @returns If param is error.
 */
function isErrorWithMessage(error) {
    return (typeof error === 'object'
        && error !== null
        && 'message' in error
        && typeof error.message === 'string');
}
/**
 * Converts error to the error with message.
 *
 * @param maybeError Possible error.
 * @returns Error with message.
 */
function toErrorWithMessage(maybeError) {
    if (isErrorWithMessage(maybeError)) {
        return maybeError;
    }
    try {
        return new Error(JSON.stringify(maybeError));
    }
    catch {
        // fallback in case there's an error stringifying the maybeError
        // like with circular references for example.
        return new Error(String(maybeError));
    }
}
/**
 * Converts error object to error with message. This method might be helpful to handle thrown errors.
 *
 * @param error Error object.
 *
 * @returns Message of the error.
 */
function getErrorMessage(error) {
    return toErrorWithMessage(error).message;
}

/**
 * @file Schema for modifier data.
 */
/**
 * Known validators that don't need to be validated as regex.
 */
const KNOWN_VALIDATORS = new Set([
    'domain',
    'pipe_separated_domains',
    'regexp',
    'url',
]);
/**
 * Zod schema for modifier data.
 */
zodToCamelCase(baseCompatibilityDataSchema.extend({
    /**
     * List of modifiers that are incompatible with the actual one.
     */
    conflicts: zod_lib/* default.array */.ZP.array(nonEmptyStringSchema).nullable().default(null),
    /**
     * The actual modifier is incompatible with all other modifiers, except the ones listed in `conflicts`.
     */
    inverse_conflicts: booleanSchema.default(false),
    /**
     * Describes whether the actual modifier supports value assignment. For example, `$domain` is assignable,
     * so it can be used like this: `$domain=domain.com\|~subdomain.domain.com`, where `=` is the assignment operator
     * and `domain.com\|~subdomain.domain.com` is the value.
     */
    assignable: booleanSchema.default(false),
    /**
     * Describes whether the actual modifier can be negated. For example, `$third-party` is negatable,
     * so it can be used like this: `$~third-party`.
     */
    negatable: booleanSchema.default(true),
    /**
     * The actual modifier can only be used in blocking rules, it cannot be used in exceptions.
     * If it's value is `true`, then the modifier can be used only in blocking rules.
     * `exception_only` and `block_only` cannot be used together (they are mutually exclusive).
     */
    block_only: booleanSchema.default(false),
    /**
     * The actual modifier can only be used in exceptions, it cannot be used in blocking rules.
     * If it's value is `true`, then the modifier can be used only in exceptions.
     * `exception_only` and `block_only` cannot be used together (they are mutually exclusive).
     */
    exception_only: booleanSchema.default(false),
    /**
     * Describes whether the *assignable* modifier value is required.
     * For example, `$cookie` is assignable but it can be used without a value in exception rules:
     * `@@\|\|example.com^$cookie`.
     * If `false`, the `value_format` is required, e.g. the value of `$app` should always be specified
     */
    value_optional: booleanSchema.default(false),
    /**
     * Describes the format of the value for the *assignable* modifier.
     * Its value can be a regex pattern or a known validator name (e.g. `domain`, `pipe_separated_domains`, etc.).
     */
    value_format: nonEmptyStringSchema.nullable().default(null),
}).superRefine((data, ctx) => {
    // TODO: find something better, for now we can't add refine logic to the base schema:
    // https://github.com/colinhacks/zod/issues/454#issuecomment-848370721
    baseRefineLogic(data, ctx);
    if (data.block_only && data.exception_only) {
        ctx.addIssue({
            code: zod_lib/* default.ZodIssueCode.custom */.ZP.ZodIssueCode.custom,
            message: 'block_only and exception_only are mutually exclusive',
        });
    }
    if (data.assignable && !data.value_format) {
        ctx.addIssue({
            code: zod_lib/* default.ZodIssueCode.custom */.ZP.ZodIssueCode.custom,
            message: 'value_format is required for assignable modifiers',
        });
    }
    if (data.value_format) {
        const valueFormat = data.value_format.trim();
        // if it is a known validator, we don't need to validate it further
        if (KNOWN_VALIDATORS.has(valueFormat)) {
            return;
        }
        // otherwise, we need to validate it as a regex
        try {
            lib(valueFormat);
        }
        catch (error) {
            ctx.addIssue({
                code: zod_lib/* default.ZodIssueCode.custom */.ZP.ZodIssueCode.custom,
                message: getErrorMessage(error),
            });
        }
    }
}));

/**
 * @file Schema for redirect data.
 */
/**
 * Zod schema for redirect data.
 */
zodToCamelCase(baseCompatibilityDataSchema.extend({
    /**
     * Whether the redirect is blocking.
     */
    is_blocking: booleanSchema.default(false),
    /**
     * Resource type(s) belonging to the redirect.
     *
     * @see {@link https://developer.chrome.com/docs/extensions/reference/declarativeNetRequest/#type-ResourceType}
     */
    resource_types: zod_lib/* default.array */.ZP.array(resourceTypeSchema).default([]),
}).superRefine(baseRefineLogic));

/**
 * @file Schema for scriptlet data.
 */
/**
 * Zod schema for scriptlet parameter data.
 */
const scriptletParameterSchema = zod_lib/* default.object */.ZP.object({
    /**
     * Name of the actual parameter.
     */
    name: nonEmptyStringSchema,
    /**
     * Describes whether the parameter is required. Empty parameters are not allowed.
     */
    required: booleanSchema,
    /**
     * Short description of the parameter.
     * If not specified or it's value is `null`,then the description is not available.
     */
    description: nonEmptyStringSchema.nullable().default(null),
    /**
     * Regular expression that matches the value of the parameter.
     * If it's value is `null`, then the parameter value is not checked.
     */
    pattern: nonEmptyStringSchema.nullable().default(null),
    /**
     * Default value of the parameter (if any).
     */
    default: nonEmptyStringSchema.nullable().default(null),
    /**
     * Describes whether the parameter is used only for debugging purposes.
     */
    debug: booleanSchema.default(false),
});
/**
 * Zod schema for scriptlet parameters.
 */
const scriptletParametersSchema = zod_lib/* default.array */.ZP.array(scriptletParameterSchema);
/**
 * Zod schema for scriptlet data.
 */
zodToCamelCase(baseCompatibilityDataSchema.extend({
    /**
     * List of parameters that the scriptlet accepts.
     * **Every** parameter should be listed here, because we check that the scriptlet is used correctly
     * (e.g. that the number of parameters is correct).
     */
    parameters: scriptletParametersSchema.optional(),
}).superRefine((data, ctx) => {
    // TODO: find something better, for now we can't add refine logic to the base schema:
    // https://github.com/colinhacks/zod/issues/454#issuecomment-848370721
    baseRefineLogic(data, ctx);
    // we don't allow required parameters after optional ones
    if (!data.parameters) {
        return;
    }
    let optionalFound = false;
    for (const parameter of data.parameters) {
        if (optionalFound && parameter.required) {
            ctx.addIssue({
                code: zod_lib/* default.ZodIssueCode.custom */.ZP.ZodIssueCode.custom,
                message: 'Required parameters must be before optional ones',
            });
        }
        if (!parameter.required) {
            optionalFound = true;
        }
    }
}));

/**
 * @file Scriptlet injection rule converter
 */
const ABP_SCRIPTLET_PREFIX = 'abp-';
const UBO_SCRIPTLET_PREFIX = 'ubo-';
const UBO_SCRIPTLET_PREFIX_LENGTH = UBO_SCRIPTLET_PREFIX.length;
const UBO_SCRIPTLET_JS_SUFFIX = '.js';
const UBO_SCRIPTLET_JS_SUFFIX_LENGTH = UBO_SCRIPTLET_JS_SUFFIX.length;
const COMMA_SEPARATOR = ',';
const ADG_SET_CONSTANT_NAME = 'set-constant';
const ADG_SET_CONSTANT_EMPTY_STRING = '';
const ADG_SET_CONSTANT_EMPTY_ARRAY = 'emptyArr';
const ADG_SET_CONSTANT_EMPTY_OBJECT = 'emptyObj';
const UBO_SET_CONSTANT_EMPTY_STRING = '\'\'';
const UBO_SET_CONSTANT_EMPTY_ARRAY = '[]';
const UBO_SET_CONSTANT_EMPTY_OBJECT = '{}';
const ADG_PREVENT_FETCH_NAME = 'prevent-fetch';
const ADG_PREVENT_FETCH_EMPTY_STRING = '';
const ADG_PREVENT_FETCH_WILDCARD = '*';
const UBO_NO_FETCH_IF_WILDCARD = '/^/';
const UBO_REMOVE_CLASS_NAME = 'remove-class.js';
const UBO_REMOVE_ATTR_NAME = 'remove-attr.js';
const setConstantAdgToUboMap = {
    [ADG_SET_CONSTANT_EMPTY_STRING]: UBO_SET_CONSTANT_EMPTY_STRING,
    [ADG_SET_CONSTANT_EMPTY_ARRAY]: UBO_SET_CONSTANT_EMPTY_ARRAY,
    [ADG_SET_CONSTANT_EMPTY_OBJECT]: UBO_SET_CONSTANT_EMPTY_OBJECT,
};
const REMOVE_ATTR_CLASS_APPLYING = new Set([
    'asap',
    'stay',
    'complete',
]);
/**
 * Scriptlet injection rule converter class
 *
 * @todo Implement `convertToUbo` and `convertToAbp`
 */
class ScriptletRuleConverter extends RuleConverterBase {
    /**
     * Converts a scriptlet injection rule to AdGuard format, if possible.
     *
     * @param rule Rule node to convert
     * @returns An object which follows the {@link NodeConversionResult} interface. Its `result` property contains
     * the array of converted rule nodes, and its `isConverted` flag indicates whether the original rule was converted.
     * If the rule was not converted, the result array will contain the original node with the same object reference
     * @throws If the rule is invalid or cannot be converted
     */
    static convertToAdg(rule) {
        // Ignore AdGuard rules
        if (rule.syntax === AdblockSyntax.Adg) {
            return createNodeConversionResult([rule], false);
        }
        const separator = rule.separator.value;
        let convertedSeparator = separator;
        convertedSeparator = rule.exception
            ? CosmeticRuleSeparator.AdgJsInjectionException
            : CosmeticRuleSeparator.AdgJsInjection;
        const convertedScriptlets = [];
        for (const scriptlet of rule.body.children) {
            // Clone the node to avoid any side effects
            const scriptletClone = cloneScriptletRuleNode(scriptlet);
            // Remove possible quotes just to make it easier to work with the scriptlet name
            const scriptletName = QuoteUtils.setStringQuoteType(getScriptletName(scriptletClone), QuoteType.None);
            // Add prefix if it's not already there
            let prefix;
            // In uBO / ABP syntax, if a parameter contains the separator character, it should be escaped,
            // but during the conversion, we need to unescape them, because AdGuard syntax uses quotes to
            // distinguish between parameters.
            let charToUnescape;
            switch (rule.syntax) {
                case AdblockSyntax.Abp:
                    prefix = ABP_SCRIPTLET_PREFIX;
                    charToUnescape = SPACE;
                    break;
                case AdblockSyntax.Ubo:
                    prefix = UBO_SCRIPTLET_PREFIX;
                    charToUnescape = COMMA_SEPARATOR;
                    break;
                default:
                    prefix = EMPTY;
            }
            if (!scriptletName.startsWith(prefix)) {
                setScriptletName(scriptletClone, `${prefix}${scriptletName}`);
            }
            if (!isUndefined(charToUnescape)) {
                transformAllScriptletArguments(scriptletClone, (value) => {
                    if (!isNull(value)) {
                        return QuoteUtils.unescapeSingleEscapedOccurrences(value, charToUnescape);
                    }
                    return value;
                });
            }
            if (rule.syntax === AdblockSyntax.Ubo) {
                const scriptletData = scriptletsCompatibilityTable.getFirst(scriptletName, GenericPlatform.UboAny);
                // Some scriptlets have special values that need to be converted
                if (scriptletData
                    && (scriptletData.name === UBO_REMOVE_CLASS_NAME
                        || scriptletData.name === UBO_REMOVE_ATTR_NAME)
                    && scriptletClone.children.length > 2) {
                    const selectors = [];
                    let applying = null;
                    let lastArg = scriptletClone.children.pop();
                    // The very last argument might be the 'applying' parameter
                    if (lastArg) {
                        if (REMOVE_ATTR_CLASS_APPLYING.has(lastArg.value)) {
                            applying = lastArg.value;
                        }
                        else {
                            selectors.push(lastArg.value);
                        }
                    }
                    while (scriptletClone.children.length > 2) {
                        lastArg = scriptletClone.children.pop();
                        if (lastArg) {
                            selectors.push(lastArg.value.trim());
                        }
                    }
                    // Set last arg to be the combined selectors (in reverse order, because we popped them)
                    if (selectors.length > 0) {
                        scriptletClone.children.push({
                            type: 'Value',
                            value: selectors.reverse().join(', '),
                        });
                    }
                    // Push back the 'applying' parameter if it was found previously
                    if (!isNull(applying)) {
                        // If we don't have any selectors,
                        // we need to add an empty parameter before the 'applying' one
                        if (selectors.length === 0) {
                            scriptletClone.children.push({
                                type: 'Value',
                                value: EMPTY,
                            });
                        }
                        scriptletClone.children.push({
                            type: 'Value',
                            value: applying,
                        });
                    }
                }
            }
            // ADG scriptlet parameters should be quoted, and single quoted are preferred
            setScriptletQuoteType(scriptletClone, QuoteType.Single);
            convertedScriptlets.push(scriptletClone);
        }
        if (rule.body.children.length === 0) {
            const convertedScriptletNode = {
                category: rule.category,
                type: rule.type,
                syntax: AdblockSyntax.Adg,
                exception: rule.exception,
                domains: cloneDomainListNode(rule.domains),
                separator: {
                    type: 'Value',
                    value: convertedSeparator,
                },
                body: {
                    type: rule.body.type,
                    children: [],
                },
            };
            if (rule.modifiers) {
                convertedScriptletNode.modifiers = cloneModifierListNode(rule.modifiers);
            }
            return createNodeConversionResult([convertedScriptletNode], true);
        }
        return createNodeConversionResult(convertedScriptlets.map((scriptlet) => {
            const res = {
                category: rule.category,
                type: rule.type,
                syntax: AdblockSyntax.Adg,
                exception: rule.exception,
                domains: cloneDomainListNode(rule.domains),
                separator: {
                    type: 'Value',
                    value: convertedSeparator,
                },
                body: {
                    type: rule.body.type,
                    children: [scriptlet],
                },
            };
            if (rule.modifiers) {
                res.modifiers = cloneModifierListNode(rule.modifiers);
            }
            return res;
        }), true);
    }
    /**
     * Converts a scriptlet injection rule to uBlock format, if possible.
     *
     * @param rule Rule node to convert
     * @returns An object which follows the {@link NodeConversionResult} interface. Its `result` property contains
     * the array of converted rule nodes, and its `isConverted` flag indicates whether the original rule was converted.
     * If the rule was not converted, the result array will contain the original node with the same object reference
     * @throws If the rule is invalid or cannot be converted
     */
    static convertToUbo(rule) {
        // Ignore uBlock rules
        if (rule.syntax === AdblockSyntax.Ubo) {
            return createNodeConversionResult([rule], false);
        }
        const separator = rule.separator.value;
        let convertedSeparator = separator;
        convertedSeparator = rule.exception
            ? CosmeticRuleSeparator.ElementHidingException
            : CosmeticRuleSeparator.ElementHiding;
        const convertedScriptlets = [];
        for (const scriptlet of rule.body.children) {
            // Clone the node to avoid any side effects
            const scriptletClone = cloneScriptletRuleNode(scriptlet);
            // Remove possible quotes just to make it easier to work with the scriptlet name
            const scriptletName = QuoteUtils.setStringQuoteType(getScriptletName(scriptletClone), QuoteType.None);
            let uboScriptletName;
            if (rule.syntax === AdblockSyntax.Adg && scriptletName.startsWith(UBO_SCRIPTLET_PREFIX)) {
                // Special case: AdGuard syntax 'preserves' the original scriptlet name,
                // so we need to convert it back by removing the uBO prefix
                uboScriptletName = scriptletName.slice(UBO_SCRIPTLET_PREFIX_LENGTH);
            }
            else {
                // Otherwise, try to find the corresponding uBO scriptlet name, or use the original one if not found
                const uboScriptlet = scriptletsCompatibilityTable.getFirst(scriptletName, GenericPlatform.UboAny);
                uboScriptletName = uboScriptlet?.name ?? scriptletName;
            }
            // Remove the '.js' suffix if it's there - its presence is not mandatory
            if (uboScriptletName.endsWith(UBO_SCRIPTLET_JS_SUFFIX)) {
                uboScriptletName = uboScriptletName.slice(0, -UBO_SCRIPTLET_JS_SUFFIX_LENGTH);
            }
            setScriptletName(scriptletClone, uboScriptletName);
            setScriptletQuoteType(scriptletClone, QuoteType.None);
            // Escape unescaped commas in parameters, because uBlock Origin uses them as separators.
            // For example, the following AdGuard rule:
            //
            // example.com#%#//scriptlet('spoof-css', '.adsbygoogle, #ads', 'visibility', 'visible')
            //
            //      ↓↓ should be converted to ↓↓
            //
            // example.com##+js(spoof-css.js, .adsbygoogle\, #ads, visibility, visible)
            //                  ------------  -------------------  ----------  -------
            //                    arg 0              arg 1           arg 2      arg 3
            //
            // and we need to escape the comma in the second argument to prevent it from being treated
            // as two separate arguments.
            transformAllScriptletArguments(scriptletClone, (value) => {
                if (!isNull(value)) {
                    return QuoteUtils.escapeUnescapedOccurrences(value, COMMA_SEPARATOR);
                }
                return value;
            });
            // Unescape spaces in parameters, because uBlock Origin doesn't treat them as separators.
            if (rule.syntax === AdblockSyntax.Abp) {
                transformAllScriptletArguments(scriptletClone, (value) => {
                    if (!isNull(value)) {
                        return QuoteUtils.unescapeSingleEscapedOccurrences(value, SPACE);
                    }
                    return value;
                });
            }
            // Some scriptlets have special values that need to be converted
            switch (scriptletName) {
                case ADG_SET_CONSTANT_NAME:
                    transformNthScriptletArgument(scriptletClone, 2, (value) => {
                        if (!isNull(value)) {
                            return setConstantAdgToUboMap[value] ?? value;
                        }
                        return value;
                    });
                    break;
                case ADG_PREVENT_FETCH_NAME:
                    transformNthScriptletArgument(scriptletClone, 1, (value) => {
                        if (value === ADG_PREVENT_FETCH_EMPTY_STRING || value === ADG_PREVENT_FETCH_WILDCARD) {
                            return UBO_NO_FETCH_IF_WILDCARD;
                        }
                        return value;
                    });
                    break;
            }
            convertedScriptlets.push(scriptletClone);
        }
        // TODO: Refactor redundant code
        if (rule.body.children.length === 0) {
            const convertedScriptletNode = {
                category: rule.category,
                type: rule.type,
                syntax: AdblockSyntax.Ubo,
                exception: rule.exception,
                domains: cloneDomainListNode(rule.domains),
                separator: {
                    type: 'Value',
                    value: convertedSeparator,
                },
                body: {
                    type: rule.body.type,
                    children: [],
                },
            };
            if (rule.modifiers) {
                convertedScriptletNode.modifiers = cloneModifierListNode(rule.modifiers);
            }
            return createNodeConversionResult([convertedScriptletNode], true);
        }
        return createNodeConversionResult(convertedScriptlets.map((scriptlet) => {
            const res = {
                category: rule.category,
                type: rule.type,
                syntax: AdblockSyntax.Ubo,
                exception: rule.exception,
                domains: cloneDomainListNode(rule.domains),
                separator: {
                    type: 'Value',
                    value: convertedSeparator,
                },
                body: {
                    type: rule.body.type,
                    children: [scriptlet],
                },
            };
            if (rule.modifiers) {
                res.modifiers = cloneModifierListNode(rule.modifiers);
            }
            return res;
        }), true);
    }
}

/**
 * @file Utility functions for working with modifier nodes
 */
/**
 * Creates a modifier node
 *
 * @param name Name of the modifier
 * @param value Value of the modifier
 * @param exception Whether the modifier is an exception
 * @returns Modifier node
 */
function createModifierNode(name, value = undefined, exception = false) {
    const result = {
        type: 'Modifier',
        exception,
        name: {
            type: 'Value',
            value: name,
        },
    };
    if (!isUndefined(value)) {
        result.value = {
            type: 'Value',
            value,
        };
    }
    return result;
}
/**
 * Creates a modifier list node
 *
 * @param modifiers Modifiers to put in the list (optional, defaults to an empty list)
 * @returns Modifier list node
 */
function createModifierListNode(modifiers = []) {
    const result = {
        type: 'ModifierList',
        // We need to clone the modifiers to avoid side effects
        children: modifiers.length ? clone(modifiers) : [],
    };
    return result;
}

/**
 * A very simple map extension that allows to store multiple values for the same key
 * by storing them in an array.
 *
 * @todo Add more methods if needed
 */
class MultiValueMap extends Map {
    /**
     * Adds a value to the map. If the key already exists, the value will be appended to the existing array,
     * otherwise a new array will be created for the key.
     *
     * @param key Key to add
     * @param values Value(s) to add
     */
    add(key, ...values) {
        let currentValues = super.get(key);
        if (isUndefined(currentValues)) {
            currentValues = [];
            super.set(key, values);
        }
        currentValues.push(...values);
    }
}

/**
 * @file Cosmetic rule modifier converter from uBO to ADG
 */
const UBO_MATCHES_PATH_OPERATOR = 'matches-path';
const ADG_PATH_MODIFIER = 'path';
/**
 * Special characters in modifier regexps that should be escaped
 */
const SPECIAL_MODIFIER_REGEX_CHARS = new Set([
    OPEN_SQUARE_BRACKET,
    CLOSE_SQUARE_BRACKET,
    COMMA,
    ESCAPE_CHARACTER,
]);
/**
 * Helper class for converting cosmetic rule modifiers from uBO to ADG
 */
class AdgCosmeticRuleModifierConverter {
    /**
     * Converts a uBO cosmetic rule modifier list to ADG, if possible.
     *
     * @param modifierList Cosmetic rule modifier list node to convert
     * @returns An object which follows the {@link ConversionResult} interface. Its `result` property contains
     * the converted node, and its `isConverted` flag indicates whether the original node was converted.
     * If the node was not converted, the result will contain the original node with the same object reference
     * @throws If the modifier list cannot be converted
     * @see {@link https://github.com/gorhill/uBlock/wiki/Procedural-cosmetic-filters#cosmetic-filter-operators}
     */
    static convertFromUbo(modifierList) {
        const conversionMap = new MultiValueMap();
        modifierList.children.forEach((modifier, index) => {
            // :matches-path
            if (modifier.name.value === UBO_MATCHES_PATH_OPERATOR) {
                if (!modifier.value) {
                    throw new RuleConversionError(`'${UBO_MATCHES_PATH_OPERATOR}' operator requires a value`);
                }
                const value = RegExpUtils.isRegexPattern(modifier.value.value)
                    ? StringUtils.escapeCharacters(modifier.value.value, SPECIAL_MODIFIER_REGEX_CHARS)
                    : modifier.value.value;
                // Convert uBO's `:matches-path(...)` operator to ADG's `$path=...` modifier
                conversionMap.add(index, createModifierNode(ADG_PATH_MODIFIER, 
                // We should negate the regexp if the modifier is an exception
                modifier.exception
                    // eslint-disable-next-line max-len
                    ? `${REGEX_MARKER}${RegExpUtils.negateRegexPattern(RegExpUtils.patternToRegexp(value))}${REGEX_MARKER}`
                    : value));
            }
        });
        // Check if we have any converted modifiers
        if (conversionMap.size) {
            const modifierListClone = clone(modifierList);
            // Replace the original modifiers with the converted ones
            modifierListClone.children = modifierListClone.children.map((modifier, index) => {
                const convertedModifier = conversionMap.get(index);
                return convertedModifier ?? modifier;
            }).flat();
            return createConversionResult(modifierListClone, true);
        }
        // Otherwise, just return the original modifier list
        return createConversionResult(modifierList, false);
    }
}

const ERROR_MESSAGES$1 = {
    // eslint-disable-next-line max-len
    INVALID_ATTRIBUTE_VALUE: `Expected '${(0,csstokenizer/* getFormattedTokenName */.PE)(csstokenizer/* TokenType.Ident */.iv.Ident)}' or '${(0,csstokenizer/* getFormattedTokenName */.PE)(csstokenizer/* TokenType.String */.iv.String)}' as attribute value, but got '%s' with value '%s`,
};
var PseudoClasses;
(function (PseudoClasses) {
    PseudoClasses["AbpContains"] = "-abp-contains";
    PseudoClasses["AbpHas"] = "-abp-has";
    PseudoClasses["Contains"] = "contains";
    PseudoClasses["Has"] = "has";
    PseudoClasses["HasText"] = "has-text";
    PseudoClasses["MatchesCss"] = "matches-css";
    PseudoClasses["MatchesCssAfter"] = "matches-css-after";
    PseudoClasses["MatchesCssBefore"] = "matches-css-before";
    PseudoClasses["Not"] = "not";
})(PseudoClasses || (PseudoClasses = {}));
var PseudoElements;
(function (PseudoElements) {
    PseudoElements["After"] = "after";
    PseudoElements["Before"] = "before";
})(PseudoElements || (PseudoElements = {}));
const PSEUDO_ELEMENT_NAMES = new Set([
    PseudoElements.After,
    PseudoElements.Before,
]);
/**
 * CSS selector converter
 *
 * @todo Implement `convertToUbo` and `convertToAbp`
 */
class CssSelectorConverter extends ConverterBase {
    /**
     * Converts Extended CSS elements to AdGuard-compatible ones
     *
     * @param selectorList Selector list to convert
     * @returns An object which follows the {@link ConversionResult} interface. Its `result` property contains
     * the converted node, and its `isConverted` flag indicates whether the original node was converted.
     * If the node was not converted, the result will contain the original node with the same object reference
     * @throws If the rule is invalid or incompatible
     */
    static convertToAdg(selectorList) {
        const stream = selectorList instanceof CssTokenStream
            ? selectorList
            : new CssTokenStream(selectorList);
        const converted = [];
        const convertAndPushPseudo = (pseudo) => {
            switch (pseudo) {
                case PseudoClasses.AbpContains:
                case PseudoClasses.HasText:
                    converted.push(PseudoClasses.Contains);
                    converted.push(OPEN_PARENTHESIS);
                    break;
                case PseudoClasses.AbpHas:
                    converted.push(PseudoClasses.Has);
                    converted.push(OPEN_PARENTHESIS);
                    break;
                // a bit special case:
                // - `:matches-css-before(...)` → `:matches-css(before, ...)`
                // - `:matches-css-after(...)`  → `:matches-css(after, ...)`
                case PseudoClasses.MatchesCssBefore:
                case PseudoClasses.MatchesCssAfter:
                    converted.push(PseudoClasses.MatchesCss);
                    converted.push(OPEN_PARENTHESIS);
                    converted.push(pseudo.substring(PseudoClasses.MatchesCss.length + 1));
                    converted.push(COMMA);
                    break;
                default:
                    converted.push(pseudo);
                    converted.push(OPEN_PARENTHESIS);
                    break;
            }
        };
        while (!stream.isEof()) {
            const token = stream.getOrFail();
            if (token.type === csstokenizer/* TokenType.Colon */.iv.Colon) {
                // Advance colon
                stream.advance();
                converted.push(COLON);
                const tempToken = stream.getOrFail();
                // Double colon is a pseudo-element
                if (tempToken.type === csstokenizer/* TokenType.Colon */.iv.Colon) {
                    stream.advance();
                    converted.push(COLON);
                    continue;
                }
                if (tempToken.type === csstokenizer/* TokenType.Ident */.iv.Ident) {
                    const name = stream.source.slice(tempToken.start, tempToken.end);
                    if (PSEUDO_ELEMENT_NAMES.has(name)) {
                        // Add an extra colon to the name
                        converted.push(COLON);
                        converted.push(name);
                    }
                    else {
                        // Add the name as is
                        converted.push(name);
                    }
                    // Advance the names
                    stream.advance();
                }
                else if (tempToken.type === csstokenizer/* TokenType.Function */.iv.Function) {
                    const name = stream.source.slice(tempToken.start, tempToken.end - 1); // omit the last parenthesis
                    // :-abp-contains(...) → :contains(...)
                    // :has-text(...)      → :contains(...)
                    // :-abp-has(...)      → :has(...)
                    convertAndPushPseudo(name);
                    // Advance the function name
                    stream.advance();
                }
            }
            else if (token.type === csstokenizer/* TokenType.OpenSquareBracket */.iv.OpenSquareBracket) {
                let tempToken;
                const { start } = token;
                stream.advance();
                // Converts legacy Extended CSS selectors to the modern Extended CSS syntax.
                // For example:
                // - `[-ext-has=...]`                  → `:has(...)`
                // - `[-ext-contains=...]`             → `:contains(...)`
                // - `[-ext-matches-css-before=...]`   → `:matches-css(before, ...)`
                stream.skipWhitespace();
                stream.expect(csstokenizer/* TokenType.Ident */.iv.Ident);
                tempToken = stream.getOrFail();
                let attr = stream.source.slice(tempToken.start, tempToken.end);
                // Skip if the attribute name is not a legacy Extended CSS one
                if (!(attr.startsWith(LEGACY_EXT_CSS_ATTRIBUTE_PREFIX) || attr.startsWith(ABP_EXT_CSS_PREFIX))) {
                    converted.push(stream.source.slice(start, tempToken.end));
                    stream.advance();
                    continue;
                }
                if (attr.startsWith(LEGACY_EXT_CSS_ATTRIBUTE_PREFIX)) {
                    attr = attr.slice(LEGACY_EXT_CSS_ATTRIBUTE_PREFIX.length);
                }
                stream.advance();
                stream.skipWhitespace();
                // Next token should be an equality operator (=), because Extended CSS attribute selectors
                // do not support other operators
                stream.expect(csstokenizer/* TokenType.Delim */.iv.Delim, { value: EQUALS });
                stream.advance();
                // Skip optional whitespace after the operator
                stream.skipWhitespace();
                // Parse attribute value
                tempToken = stream.getOrFail();
                // According to the spec, attribute value should be an identifier or a string
                if (tempToken.type !== csstokenizer/* TokenType.Ident */.iv.Ident && tempToken.type !== csstokenizer/* TokenType.String */.iv.String) {
                    throw new Error((0,sprintf.sprintf)(ERROR_MESSAGES$1.INVALID_ATTRIBUTE_VALUE, (0,csstokenizer/* getFormattedTokenName */.PE)(tempToken.type), stream.source.slice(tempToken.start, tempToken.end)));
                }
                const value = stream.source.slice(tempToken.start, tempToken.end);
                // Advance the attribute value
                stream.advance();
                // Skip optional whitespace after the attribute value
                stream.skipWhitespace();
                // Next character should be a closing square bracket
                // We don't allow flags for Extended CSS attribute selectors
                stream.expect(csstokenizer/* TokenType.CloseSquareBracket */.iv.CloseSquareBracket);
                stream.advance();
                converted.push(COLON);
                convertAndPushPseudo(attr);
                let processedValue = value.slice(1, -1); // omit the quotes
                if (attr === PseudoClasses.Has) {
                    // TODO: Optimize this to avoid double tokenization
                    processedValue = CssSelectorConverter.convertToAdg(processedValue).result;
                }
                converted.push(processedValue);
                converted.push(CLOSE_PARENTHESIS);
            }
            else {
                converted.push(stream.source.slice(token.start, token.end));
                // Advance the token
                stream.advance();
            }
        }
        const convertedSelectorList = converted.join(EMPTY);
        return createConversionResult(convertedSelectorList, stream.source !== convertedSelectorList);
    }
}

/**
 * @file CSS injection rule converter
 */
/**
 * CSS injection rule converter class
 *
 * @todo Implement `convertToUbo` and `convertToAbp`
 */
class CssInjectionRuleConverter extends RuleConverterBase {
    /**
     * Converts a CSS injection rule to AdGuard format, if possible.
     *
     * @param rule Rule node to convert
     * @returns An object which follows the {@link NodeConversionResult} interface. Its `result` property contains
     * the array of converted rule nodes, and its `isConverted` flag indicates whether the original rule was converted.
     * If the rule was not converted, the result array will contain the original node with the same object reference
     * @throws If the rule is invalid or cannot be converted
     */
    static convertToAdg(rule) {
        const separator = rule.separator.value;
        let convertedSeparator = separator;
        const stream = new CssTokenStream(rule.body.selectorList.value);
        const convertedSelectorList = CssSelectorConverter.convertToAdg(stream);
        // Change the separator if the rule contains ExtendedCSS elements,
        // but do not force non-extended CSS separator if the rule does not contain any ExtendedCSS selectors,
        // because sometimes we use it to force executing ExtendedCSS library.
        if (stream.hasAnySelectorExtendedCssNodeStrict() || rule.body.remove) {
            convertedSeparator = rule.exception
                ? CosmeticRuleSeparator.AdgExtendedCssInjectionException
                : CosmeticRuleSeparator.AdgExtendedCssInjection;
        }
        else if (rule.syntax !== AdblockSyntax.Adg) {
            // If the original rule syntax is not AdGuard, use the default separator
            // e.g. if the input rule is from uBO, we need to convert ## to #$#.
            convertedSeparator = rule.exception
                ? CosmeticRuleSeparator.AdgCssInjectionException
                : CosmeticRuleSeparator.AdgCssInjection;
        }
        // Check if the rule needs to be converted
        if (!(rule.syntax === AdblockSyntax.Common || rule.syntax === AdblockSyntax.Adg)
            || separator !== convertedSeparator
            || convertedSelectorList.isConverted) {
            // TODO: Replace with custom clone method
            const ruleClone = clone(rule);
            ruleClone.syntax = AdblockSyntax.Adg;
            ruleClone.separator.value = convertedSeparator;
            ruleClone.body.selectorList.value = convertedSelectorList.result;
            return createNodeConversionResult([ruleClone], true);
        }
        // Otherwise, return the original rule
        return createNodeConversionResult([rule], false);
    }
}

/**
 * @file Element hiding rule converter
 */
/**
 * Element hiding rule converter class
 *
 * @todo Implement `convertToUbo` and `convertToAbp`
 */
class ElementHidingRuleConverter extends RuleConverterBase {
    /**
     * Converts an element hiding rule to AdGuard format, if possible.
     *
     * @param rule Rule node to convert
     * @returns An object which follows the {@link NodeConversionResult} interface. Its `result` property contains
     * the array of converted rule nodes, and its `isConverted` flag indicates whether the original rule was converted.
     * If the rule was not converted, the result array will contain the original node with the same object reference
     * @throws If the rule is invalid or cannot be converted
     */
    static convertToAdg(rule) {
        const separator = rule.separator.value;
        let convertedSeparator = separator;
        const stream = new CssTokenStream(rule.body.selectorList.value);
        const convertedSelectorList = CssSelectorConverter.convertToAdg(stream);
        // Change the separator if the rule contains ExtendedCSS elements,
        // but do not force non-extended CSS separator if the rule does not contain any ExtendedCSS selectors,
        // because sometimes we use it to force executing ExtendedCSS library.
        if (stream.hasAnySelectorExtendedCssNodeStrict()) {
            convertedSeparator = rule.exception
                ? CosmeticRuleSeparator.ExtendedElementHidingException
                : CosmeticRuleSeparator.ExtendedElementHiding;
        }
        // Check if the rule needs to be converted
        if (!(rule.syntax === AdblockSyntax.Common || rule.syntax === AdblockSyntax.Adg)
            || separator !== convertedSeparator
            || convertedSelectorList.isConverted) {
            // TODO: Replace with custom clone method
            const ruleClone = clone(rule);
            ruleClone.syntax = AdblockSyntax.Adg;
            ruleClone.separator.value = convertedSeparator;
            ruleClone.body.selectorList.value = convertedSelectorList.result;
            return createNodeConversionResult([ruleClone], true);
        }
        // Otherwise, return the original rule
        return createNodeConversionResult([rule], false);
    }
}

/**
 * @file Utility functions for working with network rule nodes
 */
/**
 * Creates a network rule node
 *
 * @param pattern Rule pattern
 * @param modifiers Rule modifiers (optional, default: undefined)
 * @param exception Exception rule flag (optional, default: false)
 * @param syntax Adblock syntax (optional, default: Common)
 * @returns Network rule node
 */
function createNetworkRuleNode(pattern, modifiers = undefined, exception = false, syntax = AdblockSyntax.Common) {
    const result = {
        category: RuleCategory.Network,
        type: NetworkRuleType.NetworkRule,
        syntax,
        exception,
        pattern: {
            type: 'Value',
            value: pattern,
        },
    };
    if (!isUndefined(modifiers)) {
        result.modifiers = clone(modifiers);
    }
    return result;
}

/**
 * @file Converter for request header removal rules
 */
const UBO_RESPONSEHEADER_FN = 'responseheader';
const ADG_REMOVEHEADER_MODIFIER = 'removeheader';
const ERROR_MESSAGES = {
    EMPTY_PARAMETER: `Empty parameter for '${UBO_RESPONSEHEADER_FN}' function`,
    EXPECTED_END_OF_RULE: "Expected end of rule, but got '%s'",
    MULTIPLE_DOMAINS_NOT_SUPPORTED: 'Multiple domains are not supported yet',
};
/**
 * Converter for request header removal rules
 *
 * @todo Implement `convertToUbo` (ABP currently doesn't support header removal rules)
 */
class HeaderRemovalRuleConverter extends RuleConverterBase {
    /**
     * Converts a header removal rule to AdGuard syntax, if possible.
     *
     * @param rule Rule node to convert
     * @returns An object which follows the {@link NodeConversionResult} interface. Its `result` property contains
     * the array of converted rule nodes, and its `isConverted` flag indicates whether the original rule was converted.
     * If the rule was not converted, the result array will contain the original node with the same object reference
     * @throws If the rule is invalid or cannot be converted
     * @example
     * If the input rule is:
     * ```adblock
     * example.com##^responseheader(header-name)
     * ```
     * The output will be:
     * ```adblock
     * ||example.com^$removeheader=header-name
     * ```
     */
    static convertToAdg(rule) {
        // TODO: Add support for ABP syntax once it starts supporting header removal rules
        // Leave the rule as is if it's not a header removal rule
        if (rule.category !== RuleCategory.Cosmetic || rule.type !== CosmeticRuleType.HtmlFilteringRule) {
            return createNodeConversionResult([rule], false);
        }
        const stream = new CssTokenStream(rule.body.value);
        let token;
        // Skip leading whitespace
        stream.skipWhitespace();
        // Next token should be the `^` followed by a `responseheader` function
        token = stream.get();
        if (!token || token.type !== csstokenizer/* TokenType.Delim */.iv.Delim || rule.body.value[token.start] !== UBO_HTML_MASK) {
            return createNodeConversionResult([rule], false);
        }
        stream.advance();
        token = stream.get();
        if (!token) {
            return createNodeConversionResult([rule], false);
        }
        const functionName = rule.body.value.slice(token.start, token.end - 1);
        if (functionName !== UBO_RESPONSEHEADER_FN) {
            return createNodeConversionResult([rule], false);
        }
        // Parse the parameter
        const paramStart = token.end;
        stream.skipUntilBalanced();
        const paramEnd = stream.getOrFail().end;
        const param = rule.body.value.slice(paramStart, paramEnd - 1).trim();
        // Do not allow empty parameter
        if (param.length === 0) {
            throw new RuleConversionError(ERROR_MESSAGES.EMPTY_PARAMETER);
        }
        stream.expect(csstokenizer/* TokenType.CloseParenthesis */.iv.CloseParenthesis);
        stream.advance();
        // Skip trailing whitespace after the function call
        stream.skipWhitespace();
        // Expect the end of the rule - so nothing should be left in the stream
        if (!stream.isEof()) {
            token = stream.getOrFail();
            throw new RuleConversionError((0,sprintf.sprintf)(ERROR_MESSAGES.EXPECTED_END_OF_RULE, (0,csstokenizer/* getFormattedTokenName */.PE)(token.type)));
        }
        // Prepare network rule pattern
        const pattern = [];
        if (rule.domains.children.length === 1) {
            // If the rule has only one domain, we can use a simple network rule pattern:
            // ||single-domain-from-the-rule^
            pattern.push(ADBLOCK_URL_START, rule.domains.children[0].value, ADBLOCK_URL_SEPARATOR);
        }
        else if (rule.domains.children.length > 1) {
            // TODO: Add support for multiple domains, for example:
            // example.com,example.org,example.net##^responseheader(header-name)
            // We should consider allowing $domain with $removeheader modifier,
            // for example:
            // $removeheader=header-name,domain=example.com|example.org|example.net
            throw new RuleConversionError(ERROR_MESSAGES.MULTIPLE_DOMAINS_NOT_SUPPORTED);
        }
        // Prepare network rule modifiers
        const modifiers = createModifierListNode();
        modifiers.children.push(createModifierNode(ADG_REMOVEHEADER_MODIFIER, param));
        // Construct the network rule
        return createNodeConversionResult([
            createNetworkRuleNode(pattern.join(EMPTY), modifiers, 
            // Copy the exception flag
            rule.exception, AdblockSyntax.Adg),
        ], true);
    }
}

/**
 * @file Cosmetic rule converter
 */
/**
 * Cosmetic rule converter class (also known as "non-basic rule converter")
 *
 * @todo Implement `convertToUbo` and `convertToAbp`
 */
class CosmeticRuleConverter extends RuleConverterBase {
    /**
     * Converts a cosmetic rule to AdGuard syntax, if possible.
     *
     * @param rule Rule node to convert
     * @returns An object which follows the {@link NodeConversionResult} interface. Its `result` property contains
     * the array of converted rule nodes, and its `isConverted` flag indicates whether the original rule was converted.
     * If the rule was not converted, the result array will contain the original node with the same object reference
     * @throws If the rule is invalid or cannot be converted
     */
    static convertToAdg(rule) {
        let subconverterResult;
        // Convert cosmetic rule based on its type
        switch (rule.type) {
            case CosmeticRuleType.ElementHidingRule:
                subconverterResult = ElementHidingRuleConverter.convertToAdg(rule);
                break;
            case CosmeticRuleType.ScriptletInjectionRule:
                subconverterResult = ScriptletRuleConverter.convertToAdg(rule);
                break;
            case CosmeticRuleType.CssInjectionRule:
                subconverterResult = CssInjectionRuleConverter.convertToAdg(rule);
                break;
            case CosmeticRuleType.HtmlFilteringRule:
                // Handle special case: uBO response header filtering rule
                // TODO: Optimize double CSS tokenization here
                subconverterResult = HeaderRemovalRuleConverter.convertToAdg(rule);
                if (subconverterResult.isConverted) {
                    break;
                }
                subconverterResult = HtmlRuleConverter.convertToAdg(rule);
                break;
            // Note: Currently, only ADG supports JS injection rules, so we don't need to convert them
            case CosmeticRuleType.JsInjectionRule:
                subconverterResult = createNodeConversionResult([rule], false);
                break;
            default:
                throw new RuleConversionError('Unsupported cosmetic rule type');
        }
        let convertedModifiers;
        // Convert cosmetic rule modifiers, if any
        if (rule.modifiers) {
            if (rule.syntax === AdblockSyntax.Ubo) {
                // uBO doesn't support this rule:
                // example.com##+js(set-constant.js, foo, bar):matches-path(/baz)
                if (rule.type === CosmeticRuleType.ScriptletInjectionRule) {
                    throw new RuleConversionError('uBO scriptlet injection rules don\'t support cosmetic rule modifiers');
                }
                convertedModifiers = AdgCosmeticRuleModifierConverter.convertFromUbo(rule.modifiers);
            }
            else if (rule.syntax === AdblockSyntax.Abp) {
                // TODO: Implement once ABP starts supporting cosmetic rule modifiers
                throw new RuleConversionError('ABP don\'t support cosmetic rule modifiers');
            }
        }
        if ((subconverterResult.result.length > 1 || subconverterResult.isConverted)
            || (convertedModifiers && convertedModifiers.isConverted)) {
            // Add modifier list to the subconverter result rules
            subconverterResult.result.forEach((subconverterRule) => {
                if (convertedModifiers && subconverterRule.category === RuleCategory.Cosmetic) {
                    // eslint-disable-next-line no-param-reassign
                    subconverterRule.modifiers = convertedModifiers.result;
                }
            });
            return subconverterResult;
        }
        return createNodeConversionResult([rule], false);
    }
    /**
     * Converts a cosmetic rule to uBlock Origin syntax, if possible.
     *
     * @param rule Rule node to convert
     * @returns An object which follows the {@link NodeConversionResult} interface. Its `result` property contains
     * the array of converted rule nodes, and its `isConverted` flag indicates whether the original rule was converted.
     * If the rule was not converted, the result array will contain the original node with the same object reference
     * @throws If the rule is invalid or cannot be converted
     */
    // TODO: Add support for other cosmetic rule types
    static convertToUbo(rule) {
        // Convert cosmetic rule based on its type
        if (rule.type === CosmeticRuleType.ScriptletInjectionRule) {
            if (rule.syntax === AdblockSyntax.Adg && rule.modifiers?.children.length) {
                // e.g. example.com##+js(set-constant.js, foo, bar):matches-path(/baz)
                throw new RuleConversionError('uBO scriptlet injection rules do not support cosmetic rule modifiers');
            }
            return ScriptletRuleConverter.convertToUbo(rule);
        }
        return createNodeConversionResult([rule], false);
    }
}

/**
 * @file Network rule modifier list converter.
 */
/**
 * @see {@link https://adguard.com/kb/general/ad-filtering/create-own-filters/#csp-modifier}
 */
const CSP_MODIFIER = 'csp';
const CSP_SEPARATOR = SEMICOLON + SPACE;
/**
 * @see {@link https://adguard.com/kb/general/ad-filtering/create-own-filters/#csp-modifier}
 * @see {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy}
 */
const COMMON_CSP_PARAMS = '\'self\' \'unsafe-eval\' http: https: data: blob: mediastream: filesystem:';
/**
 * @see {@link https://help.adblockplus.org/hc/en-us/articles/360062733293#rewrite}
 */
const ABP_REWRITE_MODIFIER = 'rewrite';
/**
 * @see {@link https://adguard.com/kb/general/ad-filtering/create-own-filters/#redirect-modifier}
 */
const REDIRECT_MODIFIER = 'redirect';
/**
 * @see {@link https://adguard.com/kb/general/ad-filtering/create-own-filters/#redirect-rule-modifier}
 */
const REDIRECT_RULE_MODIFIER = 'redirect-rule';
/**
 * @see {@link https://github.com/gorhill/uBlock/wiki/Resources-Library#empty-redirect-resources}
 */
const UBO_NOOP_TEXT_RESOURCE = 'noop.txt';
/**
 * Redirect-related modifiers.
 */
const REDIRECT_MODIFIERS = new Set([
    ABP_REWRITE_MODIFIER,
    REDIRECT_MODIFIER,
    REDIRECT_RULE_MODIFIER,
]);
/**
 * Conversion map for ADG network rule modifiers.
 */
const ADG_CONVERSION_MAP = new Map([
    ['1p', [{ name: () => 'third-party', exception: (actual) => !actual }]],
    ['3p', [{ name: () => 'third-party' }]],
    ['css', [{ name: () => 'stylesheet' }]],
    ['doc', [{ name: () => 'document' }]],
    ['ehide', [{ name: () => 'elemhide' }]],
    ['empty', [{ name: () => 'redirect', value: () => 'nooptext' }]],
    ['first-party', [{ name: () => 'third-party', exception: (actual) => !actual }]],
    ['frame', [{ name: () => 'subdocument' }]],
    ['ghide', [{ name: () => 'generichide' }]],
    ['inline-font', [{ name: () => CSP_MODIFIER, value: () => `font-src ${COMMON_CSP_PARAMS}` }]],
    ['inline-script', [{ name: () => CSP_MODIFIER, value: () => `script-src ${COMMON_CSP_PARAMS}` }]],
    ['mp4', [{ name: () => 'redirect', value: () => 'noopmp4-1s' }, { name: () => 'media', value: () => undefined }]],
    ['queryprune', [{ name: () => 'removeparam' }]],
    ['shide', [{ name: () => 'specifichide' }]],
    ['xhr', [{ name: () => 'xmlhttprequest' }]],
]);
/**
 * Helper class for converting network rule modifier lists.
 *
 * @todo Implement `convertToUbo` and `convertToAbp`
 */
class NetworkRuleModifierListConverter extends ConverterBase {
    /**
     * Converts a network rule modifier list to AdGuard format, if possible.
     *
     * @param modifierList Network rule modifier list node to convert
     * @param isException If `true`, the rule is an exception rule
     * @returns An object which follows the {@link ConversionResult} interface. Its `result` property contains
     * the converted node, and its `isConverted` flag indicates whether the original node was converted.
     * If the node was not converted, the result will contain the original node with the same object reference
     * @throws If the conversion is not possible
     */
    static convertToAdg(modifierList, isException = false) {
        const conversionMap = new MultiValueMap();
        // Special case: $csp modifier
        let cspCount = 0;
        modifierList.children.forEach((modifierNode, index) => {
            const modifierConversions = ADG_CONVERSION_MAP.get(modifierNode.name.value);
            if (modifierConversions) {
                for (const modifierConversion of modifierConversions) {
                    const name = modifierConversion.name(modifierNode.name.value);
                    const exception = modifierConversion.exception
                        // If the exception value is undefined in the original modifier, it
                        // means that the modifier isn't negated
                        ? modifierConversion.exception(modifierNode.exception || false)
                        : modifierNode.exception;
                    const value = modifierConversion.value
                        ? modifierConversion.value(modifierNode.value?.value)
                        : modifierNode.value?.value;
                    // Check if the name or the value is different from the original modifier
                    // If so, add the converted modifier to the list
                    if (name !== modifierNode.name.value || value !== modifierNode.value?.value) {
                        conversionMap.add(index, createModifierNode(name, value, exception));
                    }
                    // Special case: $csp modifier
                    if (name === CSP_MODIFIER) {
                        cspCount += 1;
                    }
                }
                return;
            }
            // Handle special case: resource redirection modifiers
            if (REDIRECT_MODIFIERS.has(modifierNode.name.value)) {
                // Redirect modifiers can't be negated
                if (modifierNode.exception === true) {
                    throw new RuleConversionError(`Modifier '${modifierNode.name.value}' cannot be negated`);
                }
                // Convert the redirect resource name to ADG format
                const redirectResource = modifierNode.value?.value;
                // Special case: for exception rules, $redirect without value is allowed,
                // and in this case it means an exception for all redirects
                if (!redirectResource && !isException) {
                    throw new RuleConversionError(`No redirect resource specified for '${modifierNode.name.value}' modifier`);
                }
                // Leave $redirect and $redirect-rule modifiers as is, but convert $rewrite to $redirect
                const modifierName = modifierNode.name.value === ABP_REWRITE_MODIFIER
                    ? REDIRECT_MODIFIER
                    : modifierNode.name.value;
                const convertedRedirectResource = redirectResource
                    ? redirectsCompatibilityTable.getFirst(redirectResource, GenericPlatform.AdgAny)?.name
                    : undefined;
                // Check if the modifier name or the redirect resource name is different from the original modifier.
                // If so, add the converted modifier to the list
                if (modifierName !== modifierNode.name.value
                    || (convertedRedirectResource !== undefined && convertedRedirectResource !== redirectResource)) {
                    conversionMap.add(index, createModifierNode(modifierName, 
                    // If the redirect resource name is unknown, fall back to the original one
                    // Later, the validator will throw an error if the resource name is invalid
                    convertedRedirectResource || redirectResource, modifierNode.exception));
                }
            }
        });
        // Prepare the result if there are any converted modifiers or $csp modifiers
        if (conversionMap.size || cspCount) {
            const modifierListClone = cloneModifierListNode(modifierList);
            // Replace the original modifiers with the converted ones
            // One modifier may be replaced with multiple modifiers, so we need to flatten the array
            modifierListClone.children = modifierListClone.children.map((modifierNode, index) => {
                const conversionRecord = conversionMap.get(index);
                if (conversionRecord) {
                    return conversionRecord;
                }
                return modifierNode;
            }).flat();
            // Special case: $csp modifier: merge multiple $csp modifiers into one
            // and put it at the end of the modifier list
            if (cspCount) {
                const cspValues = [];
                modifierListClone.children = modifierListClone.children.filter((modifierNode) => {
                    if (modifierNode.name.value === CSP_MODIFIER) {
                        if (!modifierNode.value?.value) {
                            throw new RuleConversionError('$csp modifier value is missing');
                        }
                        cspValues.push(modifierNode.value?.value);
                        return false;
                    }
                    return true;
                });
                modifierListClone.children.push(createModifierNode(CSP_MODIFIER, cspValues.join(CSP_SEPARATOR)));
            }
            // Before returning the result, remove duplicated modifiers
            modifierListClone.children = modifierListClone.children.filter((modifierNode, index, self) => self.findIndex((m) => m.name.value === modifierNode.name.value
                && m.exception === modifierNode.exception
                && m.value?.value === modifierNode.value?.value) === index);
            return createConversionResult(modifierListClone, true);
        }
        return createConversionResult(modifierList, false);
    }
    /**
     * Converts a network rule modifier list to uBlock format, if possible.
     *
     * @param modifierList Network rule modifier list node to convert
     * @param isException If `true`, the rule is an exception rule
     * @returns An object which follows the {@link ConversionResult} interface. Its `result` property contains
     * the converted node, and its `isConverted` flag indicates whether the original node was converted.
     * If the node was not converted, the result will contain the original node with the same object reference
     * @throws If the conversion is not possible
     */
    // TODO: Optimize
    static convertToUbo(modifierList, isException = false) {
        const conversionMap = new MultiValueMap();
        const resourceTypeModifiersToAdd = new Set();
        modifierList.children.forEach((modifierNode, index) => {
            const originalModifierName = modifierNode.name.value;
            const modifierData = modifiersCompatibilityTable.getFirst(originalModifierName, GenericPlatform.UboAny);
            // Handle special case: resource redirection modifiers
            if (REDIRECT_MODIFIERS.has(originalModifierName)) {
                // Redirect modifiers cannot be negated
                if (modifierNode.exception === true) {
                    throw new RuleConversionError(`Modifier '${modifierNode.name.value}' cannot be negated`);
                }
                // Convert the redirect resource name to uBO format
                const redirectResourceName = modifierNode.value?.value;
                // Special case: for exception rules, $redirect without value is allowed,
                // and in this case it means an exception for all redirects
                if (!redirectResourceName && !isException) {
                    throw new RuleConversionError(`No redirect resource specified for '${modifierNode.name.value}' modifier`);
                }
                if (!redirectResourceName) {
                    // Jump to the next modifier if the redirect resource is not specified
                    return;
                }
                // Leave $redirect and $redirect-rule modifiers as is, but convert $rewrite to $redirect
                const modifierName = modifierNode.name.value === ABP_REWRITE_MODIFIER
                    ? REDIRECT_MODIFIER
                    : modifierNode.name.value;
                const convertedRedirectResourceData = redirectsCompatibilityTable.getFirst(redirectResourceName, GenericPlatform.UboAny);
                const convertedRedirectResourceName = convertedRedirectResourceData?.name ?? redirectResourceName;
                // uBlock requires the $redirect modifier to have a resource type
                // https://github.com/AdguardTeam/Scriptlets/issues/101
                if (convertedRedirectResourceData?.resourceTypes?.length) {
                    // Convert the resource types to uBO modifiers
                    const uboResourceTypeModifiers = redirectsCompatibilityTable.getResourceTypeModifiers(convertedRedirectResourceData, GenericPlatform.UboAny);
                    // Special case: noop text resource
                    // If any of resource type is already present, we don't need to add other resource types,
                    // otherwise, add all resource types
                    // TODO: Optimize this logic
                    // Check if the current resource is the noop text resource
                    const isNoopTextResource = convertedRedirectResourceName === UBO_NOOP_TEXT_RESOURCE;
                    // Determine if there are any valid resource types already present
                    const hasValidResourceType = modifierList.children.some((modifier) => {
                        const name = modifier.name.value;
                        if (!isValidResourceType(name)) {
                            return false;
                        }
                        const convertedModifierData = modifiersCompatibilityTable.getFirst(name, GenericPlatform.UboAny);
                        return uboResourceTypeModifiers.has(convertedModifierData?.name ?? name);
                    });
                    // If it's not the noop text resource or if no valid resource types are present
                    if (!isNoopTextResource || !hasValidResourceType) {
                        uboResourceTypeModifiers.forEach((resourceType) => {
                            resourceTypeModifiersToAdd.add(resourceType);
                        });
                    }
                }
                // Check if the modifier name or the redirect resource name is different from the original modifier.
                // If so, add the converted modifier to the list
                if (modifierName !== originalModifierName
                    || (!isUndefined(convertedRedirectResourceName)
                        && convertedRedirectResourceName !== redirectResourceName)) {
                    conversionMap.add(index, createModifierNode(modifierName, 
                    // If the redirect resource name is unknown, fall back to the original one
                    // Later, the validator will throw an error if the resource name is invalid
                    convertedRedirectResourceName || redirectResourceName, modifierNode.exception));
                }
                return;
            }
            // Generic modifier conversion
            if (modifierData && modifierData.name !== originalModifierName) {
                conversionMap.add(index, createModifierNode(modifierData.name, modifierNode.value?.value, modifierNode.exception));
            }
        });
        // Prepare the result if there are any converted modifiers or $csp modifiers
        if (conversionMap.size || resourceTypeModifiersToAdd.size) {
            const modifierListClone = cloneModifierListNode(modifierList);
            // Replace the original modifiers with the converted ones
            // One modifier may be replaced with multiple modifiers, so we need to flatten the array
            modifierListClone.children = modifierListClone.children.map((modifierNode, index) => {
                const conversionRecord = conversionMap.get(index);
                if (conversionRecord) {
                    return conversionRecord;
                }
                return modifierNode;
            }).flat();
            // Before returning the result, remove duplicated modifiers
            modifierListClone.children = modifierListClone.children.filter((modifierNode, index, self) => self.findIndex((m) => m.name.value === modifierNode.name.value
                && m.exception === modifierNode.exception
                && m.value?.value === modifierNode.value?.value) === index);
            if (resourceTypeModifiersToAdd.size) {
                const modifierNameSet = new Set(modifierList.children.map((m) => m.name.value));
                resourceTypeModifiersToAdd.forEach((resourceType) => {
                    if (!modifierNameSet.has(resourceType)) {
                        modifierListClone.children.push(createModifierNode(resourceType));
                    }
                });
            }
            return createConversionResult(modifierListClone, true);
        }
        return createConversionResult(modifierList, false);
    }
}

/**
 * @file Network rule converter
 */
/**
 * Network rule converter class (also known as "basic rule converter")
 *
 * @todo Implement `convertToUbo` and `convertToAbp`
 */
class NetworkRuleConverter extends RuleConverterBase {
    /**
     * Converts a network rule to AdGuard format, if possible.
     *
     * @param rule Rule node to convert
     * @returns An object which follows the {@link NodeConversionResult} interface. Its `result` property contains
     * the array of converted rule nodes, and its `isConverted` flag indicates whether the original rule was converted.
     * If the rule was not converted, the result array will contain the original node with the same object reference
     * @throws If the rule is invalid or cannot be converted
     */
    static convertToAdg(rule) {
        // TODO: add support for host rules
        if (rule.type !== NetworkRuleType.NetworkRule) {
            throw new Error(`Invalid rule type: ${rule.type}`);
        }
        if (rule.modifiers) {
            const modifiers = NetworkRuleModifierListConverter.convertToAdg(rule.modifiers, rule.exception);
            // If the object reference is different, it means that the modifiers were converted
            // In this case, we should clone the entire rule and replace the modifiers with the converted ones
            if (modifiers.isConverted) {
                return {
                    result: [{
                            category: RuleCategory.Network,
                            type: NetworkRuleType.NetworkRule,
                            syntax: rule.syntax,
                            exception: rule.exception,
                            pattern: {
                                type: 'Value',
                                value: rule.pattern.value,
                            },
                            modifiers: modifiers.result,
                        }],
                    isConverted: true,
                };
            }
        }
        // If the modifiers were not converted, return the original rule
        return createNodeConversionResult([rule], false);
    }
    /**
     * Converts a network rule to uBlock format, if possible.
     *
     * @param rule Rule node to convert
     * @returns An object which follows the {@link NodeConversionResult} interface. Its `result` property contains
     * the array of converted rule nodes, and its `isConverted` flag indicates whether the original rule was converted.
     * If the rule was not converted, the result array will contain the original node with the same object reference
     * @throws If the rule is invalid or cannot be converted
     */
    static convertToUbo(rule) {
        // TODO: add support for host rules
        if (rule.type !== NetworkRuleType.NetworkRule) {
            throw new Error(`Invalid rule type: ${rule.type}`);
        }
        if (rule.modifiers) {
            const modifiers = NetworkRuleModifierListConverter.convertToUbo(rule.modifiers, rule.exception);
            // If the object reference is different, it means that the modifiers were converted
            // In this case, we should clone the entire rule and replace the modifiers with the converted ones
            if (modifiers.isConverted) {
                return {
                    result: [{
                            category: RuleCategory.Network,
                            type: NetworkRuleType.NetworkRule,
                            syntax: rule.syntax,
                            exception: rule.exception,
                            pattern: {
                                type: 'Value',
                                value: rule.pattern.value,
                            },
                            modifiers: modifiers.result,
                        }],
                    isConverted: true,
                };
            }
        }
        // If the modifiers were not converted, return the original rule
        return createNodeConversionResult([rule], false);
    }
}

/**
 * @file Adblock rule converter
 *
 * This file is the entry point for all rule converters
 * which automatically detects the rule type and calls
 * the corresponding "sub-converter".
 */
/**
 * Adblock filtering rule converter class
 *
 * @todo Implement `convertToUbo` and `convertToAbp`
 */
class RuleConverter extends RuleConverterBase {
    /**
     * Converts an adblock filtering rule to AdGuard format, if possible.
     *
     * @param rule Rule node to convert
     * @returns An object which follows the {@link NodeConversionResult} interface. Its `result` property contains
     * the array of converted rule nodes, and its `isConverted` flag indicates whether the original rule was converted.
     * If the rule was not converted, the result array will contain the original node with the same object reference
     * @throws If the rule is invalid or cannot be converted
     */
    static convertToAdg(rule) {
        // Delegate conversion to the corresponding sub-converter
        // based on the rule category
        switch (rule.category) {
            case RuleCategory.Comment:
                return CommentRuleConverter.convertToAdg(rule);
            case RuleCategory.Cosmetic:
                return CosmeticRuleConverter.convertToAdg(rule);
            case RuleCategory.Network:
                // TODO: Handle hosts rules later
                if (rule.type === NetworkRuleType.HostRule) {
                    return createConversionResult([rule], false);
                }
                return NetworkRuleConverter.convertToAdg(rule);
            case RuleCategory.Invalid:
            case RuleCategory.Empty:
                // Just forward the rule as is
                return createConversionResult([rule], false);
            default:
                // Never happens during normal operation
                throw new RuleConversionError('Unknown rule category');
        }
    }
    /**
     * Converts an adblock filtering rule to uBlock Origin format, if possible.
     *
     * @param rule Rule node to convert
     * @returns An object which follows the {@link NodeConversionResult} interface. Its `result` property contains
     * the array of converted rule nodes, and its `isConverted` flag indicates whether the original rule was converted.
     * If the rule was not converted, the result array will contain the original node with the same object reference
     * @throws If the rule is invalid or cannot be converted
     */
    // TODO: Add support for other rule types
    static convertToUbo(rule) {
        if (rule.category === RuleCategory.Cosmetic) {
            return CosmeticRuleConverter.convertToUbo(rule);
        }
        if (rule.category === RuleCategory.Network) {
            return NetworkRuleConverter.convertToUbo(rule);
        }
        return createConversionResult([rule], false);
    }
}

/**
 * @file Adblock filter list converter
 */
/**
 * Adblock filter list converter class
 *
 * This class just provides an extra layer on top of the {@link RuleConverter}
 * and can be used to convert entire filter lists.
 *
 * @todo Implement `convertToUbo` and `convertToAbp`
 * @todo Implement tolerant mode, which will allow to convert a filter list
 * even if some of its rules are invalid
 */
class FilterListConverter extends (/* unused pure expression or super */ null && (ConverterBase)) {
    /**
     * Converts an adblock filter list to AdGuard format, if possible.
     *
     * @param filterListNode Filter list node to convert
     * @param tolerant Indicates whether the converter should be tolerant to invalid rules. If enabled and a rule is
     * invalid, it will be left as is. If disabled and a rule is invalid, the whole filter list will be failed.
     * Defaults to `true`.
     * @returns An object which follows the {@link ConversionResult} interface. Its `result` property contains
     * the converted node, and its `isConverted` flag indicates whether the original node was converted.
     * If the node was not converted, the result will contain the original node with the same object reference
     * @throws If the filter list is invalid or cannot be converted (if the tolerant mode is disabled)
     */
    static convertToAdg(filterListNode, tolerant = true) {
        // Prepare a map to store the converted rules by their index in the filter list
        const conversionMap = new MultiValueMap();
        // Iterate over the filtering rules and convert them one by one, then add them to the result (one conversion may
        // result in multiple rules)
        for (let i = 0; i < filterListNode.children.length; i += 1) {
            try {
                const convertedRules = RuleConverter.convertToAdg(filterListNode.children[i]);
                // Add the converted rules to the map if they were converted
                if (convertedRules.isConverted) {
                    conversionMap.add(i, ...convertedRules.result);
                }
            }
            catch (error) {
                // If the tolerant mode is disabled, we should throw an error, this will fail the whole filter list
                // conversion.
                // Otherwise, we just ignore the error and leave the rule as is
                if (!tolerant) {
                    throw error;
                }
            }
        }
        // If the conversion map is empty, it means that no rules were converted, so we can return the original filter
        // list
        if (conversionMap.size === 0) {
            return createConversionResult(filterListNode, false);
        }
        // Otherwise, create a new filter list node with the converted rules
        const convertedFilterList = {
            type: 'FilterList',
            children: [],
        };
        // Iterate over the original rules again and add them to the converted filter list, replacing the converted
        // rules with the new ones at the specified indexes
        for (let i = 0; i < filterListNode.children.length; i += 1) {
            const rules = conversionMap.get(i);
            if (rules) {
                convertedFilterList.children.push(...rules);
            }
            else {
                // We clone the unconverted rules to avoid mutating the original filter list if we return the converted
                // one
                convertedFilterList.children.push(clone(filterListNode.children[i]));
            }
        }
        return createConversionResult(convertedFilterList, true);
    }
}

/**
 * @file Filter list converter for raw filter lists
 *
 * Technically, this is a wrapper around `FilterListConverter` that works with nodes instead of strings.
 */
/**
 * Adblock filter list converter class.
 *
 * You can use this class to convert string-based filter lists, since most of the converters work with nodes.
 * This class just provides an extra layer on top of the {@link FilterListConverter} and calls the parser/serializer
 * before/after the conversion internally.
 *
 * @todo Implement `convertToUbo` and `convertToAbp`
 */
class RawFilterListConverter extends (/* unused pure expression or super */ null && (ConverterBase)) {
    /**
     * Converts an adblock filter list text to AdGuard format, if possible.
     *
     * @param rawFilterList Raw filter list text to convert
     * @param tolerant Indicates whether the converter should be tolerant to invalid rules. If enabled and a rule is
     * invalid, it will be left as is. If disabled and a rule is invalid, the whole filter list will be failed.
     * Defaults to `true`.
     * @returns An object which follows the {@link ConversionResult} interface. Its `result` property contains
     * the array of converted filter list text, and its `isConverted` flag indicates whether the original rule was
     * converted. If the rule was not converted, the original filter list text will be returned
     * @throws If the filter list is invalid or cannot be converted (if the tolerant mode is disabled)
     */
    static convertToAdg(rawFilterList, tolerant = true) {
        const conversionResult = FilterListConverter.convertToAdg(FilterListParser.parse(rawFilterList, {
            ...defaultParserOptions,
            isLocIncluded: false,
            tolerant,
        }), tolerant);
        // If the filter list was not converted, return the original text
        if (!conversionResult.isConverted) {
            return createConversionResult(rawFilterList, false);
        }
        // Otherwise, serialize the filter list and return the result
        return createConversionResult(FilterListParser.generate(conversionResult.result), true);
    }
}

/**
 * @file Rule converter for raw rules
 *
 * Technically, this is a wrapper around `RuleConverter` that works with nodes instead of strings.
 */
/**
 * Adblock filtering rule converter class.
 *
 * You can use this class to convert string-based adblock rules, since most of the converters work with nodes.
 * This class just provides an extra layer on top of the {@link RuleConverter} and calls the parser/serializer
 * before/after the conversion internally.
 *
 * @todo Implement `convertToUbo` and `convertToAbp`
 */
class RawRuleConverter extends (/* unused pure expression or super */ null && (ConverterBase)) {
    /**
     * Converts an adblock filtering rule to AdGuard format, if possible.
     *
     * @param rawRule Raw rule text to convert
     * @returns An object which follows the {@link ConversionResult} interface. Its `result` property contains
     * the array of converted rule texts, and its `isConverted` flag indicates whether the original rule was converted.
     * If the rule was not converted, the original rule text will be returned
     * @throws If the rule is invalid or cannot be converted
     */
    static convertToAdg(rawRule) {
        const conversionResult = RuleConverter.convertToAdg(RuleParser.parse(rawRule));
        // If the rule was not converted, return the original rule text
        if (!conversionResult.isConverted) {
            return createConversionResult([rawRule], false);
        }
        // Otherwise, serialize the converted rule nodes
        return createConversionResult(conversionResult.result.map(RuleParser.generate), true);
    }
}

/**
 * @file Binary schema version.
 */
/**
 * Binary schema version.
 * This version number is used to ensure that the binary format is compatible with the current library version.
 * We increment this number if the serialized format changes in a way that is not backwards-compatible.
 */
const BINARY_SCHEMA_VERSION = 1;

/**
 * @file Utility functions for logical expression node.
 */
const ERROR_PREFIX = {
    UNEXPECTED_NODE_TYPE: 'Unexpected node type',
    UNEXPECTED_OPERATOR: 'Unexpected operator',
};
/**
 * Utility functions for logical expression node.
 */
class LogicalExpressionUtils {
    /**
     * Get all variables in the expression.
     *
     * @param node Logical expression node
     * @returns List of variables in the expression (nodes)
     * @example
     * If the expression is `a && b || c`, the returned list will be
     * nodes for `a`, `b`, and `c`.
     */
    static getVariables(node) {
        if (node.type === NodeType.Variable) {
            return [node];
        }
        if (node.type === NodeType.Operator) {
            const leftVars = LogicalExpressionUtils.getVariables(node.left);
            const rightVars = node.right ? LogicalExpressionUtils.getVariables(node.right) : [];
            return [...leftVars, ...rightVars];
        }
        if (node.type === NodeType.Parenthesis) {
            return LogicalExpressionUtils.getVariables(node.expression);
        }
        throw new Error(ERROR_PREFIX.UNEXPECTED_NODE_TYPE);
    }
    /**
     * Evaluate the parsed logical expression. You'll need to provide a
     * variable table.
     *
     * @param node Logical expression node
     * @param table Variable table (key: variable name, value: boolean)
     * @returns Evaluation result
     * @example
     * If the expression is `a && b`, and the variable table is
     * `{ a: true, b: false }`, the result will be `false`.
     *
     * Example code:
     * ```js
     * LogicalExpressionUtils.evaluate(
     *     LogicalExpressionParser.parse('a && b'),
     *     { a: true, b: false }
     * );
     * ```
     */
    static evaluate(node, table) {
        if (node.type === NodeType.Variable) {
            return !!table[node.name];
        }
        if (node.type === NodeType.Operator) {
            if (node.operator === OperatorValue.And || node.operator === OperatorValue.Or) {
                if (!node.right) {
                    throw new Error(`${ERROR_PREFIX.UNEXPECTED_OPERATOR} '${node.operator}'`);
                }
                if (node.operator === OperatorValue.And) {
                    // eslint-disable-next-line max-len
                    return LogicalExpressionUtils.evaluate(node.left, table) && LogicalExpressionUtils.evaluate(node.right, table);
                }
                if (node.operator === OperatorValue.Or) {
                    // eslint-disable-next-line max-len
                    return LogicalExpressionUtils.evaluate(node.left, table) || LogicalExpressionUtils.evaluate(node.right, table);
                }
            }
            else if (node.operator === OperatorValue.Not) {
                return !LogicalExpressionUtils.evaluate(node.left, table);
            }
        }
        else if (node.type === NodeType.Parenthesis) {
            return LogicalExpressionUtils.evaluate(node.expression, table);
        }
        throw new Error(`${ERROR_PREFIX.UNEXPECTED_NODE_TYPE} '${node.type}'`);
    }
}

/**
 * @file Position provider class.
 */
/**
 * Class responsible for converting a character offset in source code into a line and column position.
 * This conversion is particularly needed in linters and VSCode extensions,
 * where line and column numbers are more human-friendly and intuitive than character offsets.
 * Moreover, the VSCode diagnostics API does not directly support character offsets,
 * it also requires line and column numbers.
 */
class PositionProvider {
    /**
     * Maps a character offset to a line number.
     */
    offsetToLine;
    /**
     * Maps a line number to the starting character offset of that line.
     */
    lineStartOffsets;
    /**
     * Constructs a new PositionProvider instance.
     *
     * @param sourceCode The source code as a string.
     */
    constructor(sourceCode) {
        this.offsetToLine = [];
        this.lineStartOffsets = [0];
        let currentLine = 0;
        for (let i = 0; i < sourceCode.length; i += 1) {
            this.offsetToLine[i] = currentLine;
            // Handle different types of line breaks: LF, FF, and CR
            if (sourceCode[i] === LF || sourceCode[i] === FF || sourceCode[i] === CR) {
                currentLine += 1;
                this.lineStartOffsets[currentLine] = (sourceCode[i] === CR && sourceCode[i + 1] === LF)
                    ? i + 2
                    : i + 1;
                if (sourceCode[i] === CR && sourceCode[i + 1] === LF) {
                    // Skip the '\n' in a '\r\n' sequence
                    i += 1;
                }
            }
        }
        // Handle the case where the last offset is at the end of the source code
        this.offsetToLine[sourceCode.length] = currentLine;
    }
    /**
     * Converts a character offset to a line and column position.
     *
     * @param offset The zero-based character offset in the source code.
     * @returns A Position object containing the 1-based line and column number, or null if the offset is out of range.
     */
    convertOffsetToPosition(offset) {
        if (offset < 0 || offset > this.offsetToLine.length - 1) {
            return null;
        }
        const line = this.offsetToLine[offset];
        const lineStartOffset = this.lineStartOffsets[line];
        return {
            line: line + 1,
            column: offset - lineStartOffset + 1,
        };
    }
}

/* eslint-disable no-bitwise */
/**
 * @file Core ByteBuffer implementation for handling binary data in chunks.
 */
/**
 * Core ByteBuffer implementation for handling binary data in chunks.
 * This class allows for efficient byte storage and manipulation by organizing data into chunks
 * and providing methods to read and write bytes.
 */
class ByteBuffer {
    /**
     * The size of each chunk in bytes (32 KB).
     */
    // ! IMPORTANT: If you ever change this value, make sure to update optimized bitwise operations in the code.
    static CHUNK_SIZE = 32768; // 32 * 1024
    /**
     * An array of Uint8Array chunks that make up the buffer.
     */
    chunks;
    /**
     * The total number of chunks in the buffer.
     */
    chunksLength;
    /**
     * Constructs a new ByteBuffer instance.
     *
     * @param chunks Optional array of chunks to initialize the ByteBuffer with.
     * @param cloneChunks Flag indicating if the chunks should be cloned. For performance reasons,
     * its default value is `false`. If the original chunks are guaranteed not to change,
     * leave this flag as `false` to avoid unnecessary copying.
     */
    constructor(chunks, cloneChunks = false) {
        const chunksToUse = chunks ?? [];
        this.chunks = cloneChunks ? chunksToUse.map((chunk) => new Uint8Array(chunk)) : chunksToUse;
        this.chunksLength = chunks?.length ?? 0;
    }
    /**
     * Ensures that the buffer has enough capacity to accommodate a given position.
     * This method adjusts the `chunks` array size to ensure it can hold the specified position.
     *
     * @param position The position to ensure capacity for.
     */
    ensureCapacity(position) {
        // same as Math.floor(position / chunk size), just optimized for the 32 KB chunk size
        const requiredChunkIndex = position >>> 0x000F;
        for (let i = this.chunksLength; i <= requiredChunkIndex; i += 1) {
            this.chunks.push(new Uint8Array(ByteBuffer.CHUNK_SIZE));
            this.chunksLength += 1;
        }
    }
    /**
     * Writes a byte to the buffer at the specified position.
     * If the position is outside of the buffer's current size, the buffer is resized to accommodate it.
     *
     * @param position The position at which to write the byte.
     * @param value The byte value to write (0-255).
     */
    writeByte(position, value) {
        // same as Math.floor(position / chunk size), just optimized for the 32 KB chunk size
        const chunkIndex = position >>> 0x000F;
        // same as position % chunk size, just optimized for the 32 KB chunk size
        const chunkOffset = position & 0x7FFF;
        if (chunkIndex >= this.chunksLength) {
            this.ensureCapacity(position);
        }
        this.chunks[chunkIndex][chunkOffset] = value;
    }
    /**
     * Reads a byte from the specified position in the buffer.
     * Returns `undefined` if the position is outside of the buffer's current size.
     *
     * @param position The position from which to read the byte.
     * @returns The read byte value, or `undefined` if the position is out of bounds.
     */
    readByte(position) {
        const chunkIndex = position >>> 0x000F;
        const chunkOffset = position & 0x7FFF;
        if (chunkIndex >= this.chunksLength) {
            return undefined;
        }
        return this.chunks[chunkIndex][chunkOffset];
    }
}

/**
 * A simple function to check if the current browser is Chromium-based.
 *
 * @returns `true` if the current browser is Chromium-based, `false` otherwise.
 * @see {@link https://stackoverflow.com/a/62797156}
 */
const isChromium = () => {
    return typeof window !== 'undefined'
        && (Object.prototype.hasOwnProperty.call(window, 'chrome')
            || (typeof window.navigator !== 'undefined'
                && /chrome/i.test(window.navigator.userAgent)));
};

/* eslint-disable no-param-reassign */
/* eslint-disable no-bitwise */
/**
 * @file Utility for encoding strings to byte sequences.
 */
/**
 * Checks if the given code point is an ASCII code point.
 *
 * @param codePoint Code point to check.
 * @returns `true` if the given code point is an ASCII code point, `false` otherwise.
 * @see {@link https://infra.spec.whatwg.org/#ascii-code-point}
 */
const isAsciiCodePoint = (codePoint) => {
    return codePoint >= 0x0000 && codePoint <= 0x007F;
};
const OFFSETS = [0xC0, 0xE0, 0xF0];
/**
 * Encodes an UTF-8 string into a byte sequence according to the WHATWG spec.
 *
 * @param str String to encode.
 * @param buffer Buffer to write the encoded bytes to.
 * @returns Number of bytes written to the buffer.
 * @see {@link https://encoding.spec.whatwg.org/#utf-8-encoder}
 * @note Bytes written maybe larger than the string length, but never smaller.
 * For example, the string '你好' has a length of 2, but its byte representation has a length of 6.
 */
const encodeIntoPolyfill = (str, buffer) => {
    const { length } = buffer;
    let read = 0;
    let written = 0;
    for (let i = 0; i < str.length;) {
        const codePoint = str.codePointAt(i) || 0;
        let bytesNeeded = 1;
        if (isAsciiCodePoint(codePoint)) {
            if (written >= length)
                break; // Stop if no space in buffer
            buffer[written] = codePoint;
            written += 1;
            read += 1; // Increment read for ASCII
            i += 1;
        }
        else {
            if (codePoint >= 0x0080 && codePoint <= 0x07FF) {
                bytesNeeded = 2;
            }
            else if (codePoint >= 0x0800 && codePoint <= 0xFFFF) {
                bytesNeeded = 3;
            }
            else if (codePoint >= 0x10000 && codePoint <= 0x10FFFF) {
                bytesNeeded = 4;
            }
            if (written + bytesNeeded - 1 >= length) {
                // Stop if no space for the whole encoding
                break;
            }
            let count = bytesNeeded - 1;
            const offset = OFFSETS[bytesNeeded - 2];
            buffer[written] = (codePoint >> (6 * count)) + offset;
            written += 1;
            while (count > 0) {
                buffer[written] = 0x80 | ((codePoint >> (6 * (count - 1))) & 0x3F);
                written += 1;
                count -= 1;
            }
            read += codePoint >= 0x10000 ? 2 : 1; // Increment read by 1 or 2 depending on code point
            i += codePoint >= 0x10000 ? 2 : 1; // Move i by 1 or 2
        }
    }
    return { read, written };
};

/* eslint-disable no-plusplus */
/* eslint-disable no-bitwise */
/**
 * @file Output byte buffer for writing binary data.
 */
/**
 * Output byte buffer for writing binary data.
 *
 * @note Internally, this class uses a {@link ByteBuffer} instance, just providing a convenient API for reading data.
 */
class OutputByteBuffer extends ByteBuffer {
    /**
     * Current offset in the buffer for writing.
     */
    offset;
    /**
     * Size of the shared buffer for encoding strings in bytes.
     * This is a divisor of ByteBuffer.CHUNK_SIZE and experience shows that this value works optimally.
     * This is sufficient for most strings that occur in filter lists (we checked average string length in popular
     * filter lists).
     */
    static ENCODER_BUFFER_SIZE = 8192;
    /**
     * Length threshold for using a shared buffer for encoding strings.
     * This temp buffer is needed because we write the short strings in it
     * (so there is no need to constantly allocate a new buffer).
     * The reason for dividing ENCODER_BUFFER_SIZE by 4 is to ensure that the encoded string fits in the buffer,
     * if we also take into account the worst possible case (each character is encoded with 4 bytes).
     */
    static SHORT_STRING_THRESHOLD = 2048; // 8192 / 4
    /**
     * Represents the maximum value that can be written as a 'storage optimized' unsigned integer.
     * 0x1FFFFFFF means 29 bits — 32 bits minus 3 bits — because the last bit in each byte is a flag indicating
     * if there are more bytes (except for the last byte).
     */
    static MAX_OPTIMIZED_UINT = 0x1FFFFFFF;
    /**
     * Shared buffer for encoding strings.
     */
    sharedBuffer;
    /**
     * Shared native encoder for encoding strings.
     */
    sharedNativeEncoder;
    /**
     * Flag indicating if the current environment is Chromium.
     * This is used for performance optimizations, because Chromium's TextEncoder/TextDecoder has a relatively
     * large marshalling overhead for small strings.
     */
    isChromium;
    /**
     * Constructs a new OutputByteBuffer instance.
     */
    // TODO: add chunks as a parameter, if ever needed
    constructor() {
        super();
        this.sharedBuffer = new Uint8Array(OutputByteBuffer.ENCODER_BUFFER_SIZE);
        this.sharedNativeEncoder = new TextEncoder();
        this.isChromium = isChromium();
        // write the schema version at the beginning of the buffer
        this.writeUint32ToIndex(BINARY_SCHEMA_VERSION, 0);
        this.offset = 4; // schema version is already written
    }
    /**
     * Writes a 8-bit unsigned integer to the buffer.
     *
     * @param value Value to write.
     * @returns Number of bytes written to the buffer.
     */
    writeUint8(value) {
        this.writeByte(this.offset++, value);
        return 1;
    }
    /**
     * Writes a 16-bit unsigned integer to the buffer.
     *
     * @param value Value to write.
     * @returns Number of bytes written to the buffer.
     */
    writeUint16(value) {
        this.writeByte(this.offset++, value >> 8);
        this.writeByte(this.offset++, value);
        return 2;
    }
    /**
     * Writes a 32-bit unsigned integer to the buffer at a specific index.
     *
     * @param value Value to write.
     * @param index Index to write the value to.
     * @returns Number of bytes written to the buffer.
     */
    writeUint32ToIndex(value, index) {
        this.writeByte(index, value >> 24);
        this.writeByte(index + 1, value >> 16);
        this.writeByte(index + 2, value >> 8);
        this.writeByte(index + 3, value);
        return 4;
    }
    /**
     * Writes a 32-bit unsigned integer to the buffer.
     *
     * @param value Value to write.
     * @returns Number of bytes written to the buffer.
     */
    writeUint32(value) {
        this.writeUint32ToIndex(value, this.offset);
        this.offset += 4;
        return 4;
    }
    /**
     * Writes a 32-bit signed integer to the buffer.
     *
     * @param value Value to write.
     * @returns Number of bytes written to the buffer.
     */
    writeInt32(value) {
        return this.writeUint32(value ? value >>> 0 : 0);
    }
    /**
     * Writes a Uint8Array to the byte buffer.
     *
     * @param buffer Buffer to write.
     */
    writeBuffer(buffer) {
        const { length } = buffer;
        this.ensureCapacity(this.offset + length);
        let chunkIndex = this.offset >>> 0x000F;
        let chunkOffset = this.offset & 0x7FFF;
        let remainingBytes = length;
        while (remainingBytes) {
            const leftInChunk = ByteBuffer.CHUNK_SIZE - chunkOffset;
            const bytesToWrite = Math.min(remainingBytes, leftInChunk);
            this.chunks[chunkIndex].set(buffer.subarray(length - remainingBytes, length - remainingBytes + bytesToWrite), chunkOffset);
            remainingBytes -= bytesToWrite;
            chunkIndex += 1;
            chunkOffset = 0;
        }
    }
    /**
     * Writes a string to the buffer.
     *
     * @param value Value to write.
     * @returns Number of bytes written to the buffer.
     */
    writeString(value) {
        const start = this.offset;
        if (value.length <= OutputByteBuffer.SHORT_STRING_THRESHOLD) {
            let bytesWritten;
            if (this.isChromium) {
                bytesWritten = encodeIntoPolyfill(value, this.sharedBuffer).written ?? 0;
            }
            else {
                bytesWritten = this.sharedNativeEncoder.encodeInto(value, this.sharedBuffer).written ?? 0;
            }
            this.writeOptimizedUint(bytesWritten);
            this.writeBuffer(this.sharedBuffer.subarray(0, bytesWritten));
            this.offset += bytesWritten;
            return this.offset - start;
        }
        // TODO: Optimize for long strings, if needed. Not a common case for our use case
        const buffer = this.sharedNativeEncoder.encode(value);
        const bytesWritten = buffer.length;
        this.writeOptimizedUint(bytesWritten);
        this.writeBuffer(buffer);
        this.offset += bytesWritten;
        return this.offset - start;
    }
    /**
     * Writes chunks to the storage.
     *
     * @param storage Storage to write the chunks to.
     * @param key Key to write the chunks to.
     * @note For performance reasons, chunks are passed by reference and not copied.
     * @throws If the storage write operation throws.
     */
    async writeChunksToStorage(storage, key) {
        await storage.set(key, this.chunks);
    }
    /**
     * Writes an 'optimized' unsigned integer to the buffer.
     * 'Optimized' means smaller storage usage for smaller numbers.
     * Except for the last byte, each byte's most significant bit is a flag indicating if there are more bytes.
     *
     * @param value Value to write.
     * @returns Number of bytes written to the buffer.
     * @throws If the value exceeds the 29-bit limit.
     */
    writeOptimizedUint(value) {
        if (value < 0 || value > OutputByteBuffer.MAX_OPTIMIZED_UINT) {
            throw new Error('Value exceeds 29-bit limit');
        }
        let remainingValue = value;
        const startOffset = this.offset;
        while (remainingValue >= 0x80) {
            const byteValue = remainingValue & 0x7F;
            remainingValue >>>= 7;
            this.writeByte(this.offset++, byteValue | 0x80);
        }
        this.writeByte(this.offset++, remainingValue);
        return this.offset - startOffset;
    }
    /**
     * Gets the current offset in the buffer for writing.
     *
     * @returns Current offset in the buffer for writing.
     */
    get currentOffset() {
        return this.offset;
    }
}

/* eslint-disable no-plusplus */
/* eslint-disable no-bitwise */
/**
 * @file Optimized utility for decoding strings from byte sequences.
 */
const REPLACEMENT_CHAR = String.fromCodePoint(0xFFFD);
/**
 * Decodes a byte sequence into an UTF-8 string according to the WHATWG spec.
 * Optimized for performance.
 *
 * @param buffer Buffer to read the bytes from.
 * @param start Start offset in the buffer.
 * @param end End offset in the buffer.
 * @returns Decoded string.
 * @see {@link https://encoding.spec.whatwg.org/#utf-8-decoder}
 */
const decodeTextPolyfill = (buffer, start = 0, end = -1) => {
    let codePoint = 0;
    let bytesSeen = 0;
    let bytesNeeded = 0;
    let lowerBoundary = 0x0080;
    let upperBoundary = 0x00BF;
    let i = start;
    const { length } = buffer;
    const realEnd = end === -1 ? length : Math.min(end, length);
    const result = new Array(realEnd - start);
    let resIdx = 0;
    for (; i < realEnd; i += 1) {
        const byte = buffer[i];
        if (bytesNeeded === 0) {
            if (byte <= 0x007F) {
                codePoint = byte & 0x00FF;
            }
            else if (byte >= 0x00C2 && byte <= 0x00DF) {
                bytesNeeded = 1;
                codePoint = byte & 0x001F;
            }
            else if (byte >= 0x00E0 && byte <= 0x00EF) {
                bytesNeeded = 2;
                codePoint = byte & 0x000F;
                if (byte === 0x00E0) {
                    // Adjust lower boundary for exclusion of overlong sequences
                    lowerBoundary = 0x00A0;
                }
                else if (byte === 0x00ED) {
                    // Adjust upper boundary to exclude surrogates
                    upperBoundary = 0x009F;
                }
            }
            else if (byte >= 0x00F0 && byte <= 0x00F4) {
                bytesNeeded = 3;
                codePoint = byte & 0x0007;
                if (byte === 0x00F0) {
                    // Adjust lower boundary for exclusion of overlong sequences
                    lowerBoundary = 0x0090;
                }
                else if (byte === 0x00F4) {
                    // Adjust upper boundary to limit to valid Unicode range
                    upperBoundary = 0x008F;
                }
            }
            else {
                // For bytes that are not valid initial bytes of UTF-8 sequences, add replacement character
                result[resIdx++] = REPLACEMENT_CHAR;
                continue;
            }
        }
        else {
            // For subsequent bytes in a multibyte sequence, check if the byte is in the expected range
            if (!(byte >= lowerBoundary && byte <= upperBoundary)) {
                // Reset the state for illegal sequences and add replacement character
                bytesNeeded = 0;
                bytesSeen = 0;
                lowerBoundary = 0x0080;
                upperBoundary = 0x00BF;
                result[resIdx++] = REPLACEMENT_CHAR;
                // Decrement `i` to re-evaluate this byte as the start of a new sequence
                i -= 1;
                continue;
            }
            codePoint = (codePoint << 6) | (byte & 0x003F);
            // Reset boundaries for next bytes
            lowerBoundary = 0x0080;
            upperBoundary = 0x00BF;
            bytesSeen += 1;
        }
        if (bytesSeen === bytesNeeded) {
            // Complete the code point assembly and add it to the result
            result[resIdx++] = String.fromCodePoint(codePoint);
            // Reset for the next character
            bytesNeeded = 0;
            bytesSeen = 0;
            codePoint = 0;
        }
    }
    return result.join(EMPTY);
};

/* eslint-disable max-len */
/* eslint-disable no-plusplus */
/* eslint-disable no-bitwise */
/**
 * @file Input byte buffer for reading binary data.
 */
/**
 * Input byte buffer for reading binary data.
 *
 * @note Internally, this class uses a {@link ByteBuffer} instance, just providing a convenient API for reading data.
 */
class InputByteBuffer extends ByteBuffer {
    /**
     * Current offset in the buffer for reading.
     */
    offset;
    /**
     * Shared native decoder for decoding strings.
     */
    sharedNativeDecoder;
    /**
     * Flag indicating if the current environment is Chromium.
     * This is used for performance optimizations, because Chromium's TextEncoder/TextDecoder has a relatively
     * large marshalling overhead for small strings.
     */
    isChromium;
    /**
     * Constructs a new `InputByteBuffer` instance.
     *
     * @param chunks Array of chunks to initialize the ByteBuffer with.
     * @param cloneChunks Flag indicating if the chunks should be cloned. For performance reasons,
     * its default value is `false`. If the original chunks are guaranteed not to change,
     * leave this flag as `false` to avoid unnecessary copying.
     * @param initialOffset Initial offset in the buffer for reading.
     *
     * @throws If the specified chunks array is empty.
     * @throws If the binary schema version in the buffer is not equal to the expected version.
     * @throws If the initial offset is out of bounds.
     */
    constructor(chunks, cloneChunks = false, initialOffset = 0) {
        super(chunks, cloneChunks);
        // Check binary schema version
        if (chunks.length === 0) {
            throw new Error('No data in the buffer');
        }
        const actualVersion = this.readSchemaVersion();
        if (actualVersion !== BINARY_SCHEMA_VERSION) {
            throw new BinarySchemaMismatchError(BINARY_SCHEMA_VERSION, actualVersion);
        }
        // Throw an error if the initial offset is out of bounds
        if (initialOffset < 0 || initialOffset > this.chunks.length * ByteBuffer.CHUNK_SIZE) {
            throw new Error(`Invalid offset: ${initialOffset}`);
        }
        // Schema version is always stored at the beginning of the buffer - skip it, because it is already processed
        this.offset = Math.max(4, initialOffset);
        this.sharedNativeDecoder = new TextDecoder();
        this.isChromium = isChromium();
    }
    /**
     * Creates a new InputByteBuffer instance from a Storage instance by reading chunks from the storage.
     *
     * @param storage Storage instance.
     * @param key Key to read from the storage.
     * @returns New InputByteBuffer instance.
     * @note For performance reasons, chunks are passed by reference and not copied.
     */
    static async createFromStorage(storage, key) {
        const chunks = await storage.get(key);
        if (!isArrayOfUint8Arrays(chunks)) {
            throw new Error('The data from storage is not an array of Uint8Arrays');
        }
        return new InputByteBuffer(chunks);
    }
    /**
     * Reads a 8-bit unsigned integer from the buffer.
     *
     * @returns 8-bit unsigned integer from the buffer.
     */
    readUint8() {
        const result = this.readByte(this.offset++) ?? 0;
        return result;
    }
    /**
     * Reads a 16-bit unsigned integer from the buffer.
     *
     * @returns 16-bit unsigned integer from the buffer.
     */
    readUint16() {
        const result = (((this.readByte(this.offset++) ?? 0) << 8)
            | ((this.readByte(this.offset++) ?? 0))) >>> 0;
        return result;
    }
    /**
     * Reads a 32-bit unsigned integer from the buffer at the specified index.
     *
     * @param index Index to read the 32-bit unsigned integer from.
     *
     * @returns 32-bit unsigned integer from the buffer.
     */
    readUint32FromIndex(index) {
        const result = (((this.readByte(index) ?? 0) << 24)
            | ((this.readByte(index + 1) ?? 0) << 16)
            | ((this.readByte(index + 2) ?? 0) << 8)
            | ((this.readByte(index + 3) ?? 0))) >>> 0;
        return result;
    }
    /**
     * Reads a 32-bit unsigned integer from the buffer.
     *
     * @returns 32-bit unsigned integer from the buffer.
     */
    readUint32() {
        const result = this.readUint32FromIndex(this.offset);
        this.offset += 4;
        return result;
    }
    /**
     * Reads schema version from the buffer.
     *
     * @returns 32-bit unsigned integer from the buffer.
     * @note Schema version is always stored at the beginning of the buffer.
     */
    readSchemaVersion() {
        return this.readUint32FromIndex(0);
    }
    /**
     * Reads a 32-bit signed integer from the buffer.
     *
     * @returns 32-bit signed integer from the buffer.
     */
    readInt32() {
        const result = this.readUint32();
        return result > 0x7fffffff ? result - 0x100000000 : result;
    }
    /**
     * Reads an optimized unsigned integer from the buffer.
     * 'Optimized' means that the integer is stored in a variable number of bytes, depending on its value,
     * so that smaller numbers occupy less space.
     *
     * @returns Decoded unsigned integer from the buffer.
     */
    readOptimizedUint() {
        let result = 0;
        let shift = 0;
        while (shift <= 28) {
            const byteValue = this.readByte(this.offset++) ?? 0;
            result |= (byteValue & 0x7F) << shift;
            shift += 7;
            if ((byteValue & 0x80) === 0) {
                break;
            }
        }
        return result;
    }
    /**
     * Reads a string from the buffer.
     *
     * @returns Decoded string from the buffer.
     */
    readString() {
        const length = this.readOptimizedUint();
        let chunkIndex = this.offset >>> 0x000F;
        const chunkOffset = this.offset & 0x7FFF; // offset is only relevant for the first chunk
        const endOffset = chunkOffset + length;
        // In most cases, the string is stored in the current chunk
        if (endOffset < ByteBuffer.CHUNK_SIZE) {
            this.offset += length;
            if (this.isChromium) {
                return decodeTextPolyfill(this.chunks[chunkIndex], chunkOffset, endOffset);
            }
            return this.sharedNativeDecoder.decode(this.chunks[chunkIndex].subarray(chunkOffset, endOffset));
        }
        const result = [];
        result.push(this.sharedNativeDecoder.decode(this.chunks[chunkIndex++].subarray(chunkOffset), { stream: true }));
        let remaining = length - (ByteBuffer.CHUNK_SIZE - chunkOffset);
        while (remaining) {
            const chunk = this.chunks[chunkIndex];
            if (!chunk) {
                break;
            }
            const toRead = Math.min(remaining, ByteBuffer.CHUNK_SIZE);
            result.push(this.sharedNativeDecoder.decode(chunk.subarray(0, toRead), { stream: true }));
            remaining -= toRead;
            chunkIndex += 1;
        }
        // Finish decoding, if something is left
        result.push(this.sharedNativeDecoder.decode());
        this.offset += length;
        return result.join('');
    }
    /**
     * Reads a 8-bit unsigned integer from the buffer without advancing the offset.
     *
     * @returns 8-bit unsigned integer from the buffer.
     */
    peekUint8() {
        return this.readByte(this.offset) ?? 0;
    }
    /**
     * Helper method for asserting the next 8-bit unsigned integer in the buffer.
     *
     * @param value Expected value.
     * @throws If the next value in the buffer is not equal to the expected value.
     */
    assertUint8(value) {
        const result = this.readUint8();
        if (result !== value) {
            throw new Error(`Expected ${value}, but got ${result}`);
        }
    }
    /**
     * Creates a new `InputByteBuffer` instance with the given initial offset.
     *
     * @param initialOffset Initial offset for the new buffer.
     * @param cloneChunks Flag indicating if the chunks should be cloned. For performance reasons,
     * its default value is `false`. If the original chunks are guaranteed not to change,
     * leave this flag as `false` to avoid unnecessary copying.
     *
     * @returns New `InputByteBuffer` instance with the given initial offset.
     *
     * @note This method is useful if you want to read some data from a specific index.
     */
    createCopyWithOffset(initialOffset, cloneChunks = false) {
        return new InputByteBuffer(this.chunks, cloneChunks, initialOffset);
    }
    /**
     * Gets the current offset in the buffer for reading.
     *
     * @returns Current offset in the buffer for reading.
     */
    get currentOffset() {
        return this.offset;
    }
    /**
     * Gets the capacity of the buffer.
     *
     * @returns Capacity of the buffer.
     */
    get capacity() {
        return this.chunks.length * ByteBuffer.CHUNK_SIZE;
    }
}

/**
 * Utility functions for categorizing rules.
 */
// TODO: Optimize functions to avoid produce unnecessary data (currently, most of node data is not used).
// TODO: Add support for other rule categories, like network rules (when needed).
class RuleCategorizer {
    /**
     * Determines the type of a given raw cosmetic rule.
     *
     * @param rawRule Raw rule to check.
     *
     * @returns Type of the cosmetic rule or `null` if the rule is cannot be parsed as a cosmetic rule.
     */
    static getCosmeticRuleType(rawRule) {
        try {
            const node = CosmeticRuleParser.parse(rawRule, {
                ...defaultParserOptions,
                isLocIncluded: false,
                includeRaws: false,
            });
            // If rule cannot be recognized as a cosmetic rule, return null.
            if (isNull(node)) {
                return null;
            }
            return node.type;
        }
        catch {
            // Be tolerant to parsing errors and simply return null.
            return null;
        }
    }
}

const version = "2.1.2";

/**
 * @file AGTree version
 */
// ! Notice:
// Don't export version from package.json directly, because if you run
// `tsc` in the root directory, it will generate `dist/types/src/version.d.ts`
// with wrong relative path to `package.json`. So we need this little "hack"
const AGTREE_VERSION = (/* unused pure expression or super */ null && (version));




/***/ }),

/***/ 97094:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "PE": () => (/* binding */ getFormattedTokenName),
/* harmony export */   "iv": () => (/* binding */ TokenType),
/* harmony export */   "lL": () => (/* binding */ tokenizeExtended),
/* harmony export */   "pV": () => (/* binding */ decodeIdent)
/* harmony export */ });
/* unused harmony exports CSS_TOKENIZER_VERSION, TokenizerContext, getBaseTokenName, tokenize */
/*
 * CSSTokenizer v1.1.1 (build date: Thu, 19 Sep 2024 13:23:31 GMT)
 * (c) 2024 Adguard Software Ltd.
 * Released under the MIT license
 * https://github.com/AdguardTeam/tsurlfilter/tree/master/packages/css-tokenizer#readme
 */
/**
 * @file Implementation of CSS Syntax Module Level 3 tokenizer definitions (§ 4.2.)
 *
 * @see {@link https://www.w3.org/TR/css-syntax-3/#tokenizer-definitions}
 */
/**
 * Check if code point code is between two code points
 *
 * @param code Code point to check
 * @param min Minimum code point
 * @param max Maximum code point
 * @returns `true` if code point is between `min` and `max`, `false` otherwise
 * @note Boundaries are inclusive
 * @note This function is used instead of `code >= min && code <= max` because TypeScript doesn't allow to compare
 * `number | undefined` with `number` (even though it's perfectly valid in JavaScript)
 */
function isBetween(code, min, max) {
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-ignore 18048
    return code >= min && code <= max;
}
/**
 * Check if code point code is greater than other code point
 *
 * @param code Code point to check
 * @param min Minimum code point
 * @returns `true` if code point is greater than `min`, `false` otherwise
 * @note This function is used instead of `code > min` because TypeScript doesn't allow to compare
 * `number | undefined` with `number` (even though it's perfectly valid in JavaScript)
 */
function isGreaterThan(code, min) {
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-ignore 18048
    return code > min;
}
/**
 * Check if code point code is greater than or equal to other code point
 *
 * @param code Code point to check
 * @param min Minimum code point
 * @returns `true` if code point is greater than or equal to `min`, `false` otherwise
 * @note This function is used instead of `code >= min` because TypeScript doesn't allow to compare
 * `number | undefined` with `number` (even though it's perfectly valid in JavaScript)
 */
function isGreaterThanOrEqual(code, min) {
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-ignore 18048
    return code >= min;
}
/**
 * Check if character code is a digit
 *
 * @param code Character code
 * @returns `true` if character code is a digit, `false` otherwise
 * @see {@link https://www.w3.org/TR/css-syntax-3/#digit}
 */
function isDigit(code) {
    // A code point between U+0030 DIGIT ZERO (0) and U+0039 DIGIT NINE (9) inclusive.
    return isBetween(code, 48 /* CodePoint.DigitZero */, 57 /* CodePoint.DigitNine */);
}
/**
 * Check if character code is a hex digit
 *
 * @param code Character code
 * @returns `true` if character code is a hex digit, `false` otherwise
 * @see {@link https://www.w3.org/TR/css-syntax-3/#hex-digit}
 */
function isHexDigit(code) {
    // A digit, or a code point between U+0041 LATIN CAPITAL LETTER A (A) and U+0046 LATIN CAPITAL LETTER F (F)
    // inclusive, or a code point between U+0061 LATIN SMALL LETTER A (a) and U+0066 LATIN SMALL LETTER F (f) inclusive.
    return isDigit(code) // 0-9
        || isBetween(code, 65 /* CodePoint.LatinCapitalLetterA */, 70 /* CodePoint.LatinCapitalLetterF */) // A-F
        || isBetween(code, 97 /* CodePoint.LatinSmallLetterA */, 102 /* CodePoint.LatinSmallLetterF */); // a-f
}
/**
 * Check if character code is an uppercase letter
 *
 * @param code Character code
 * @returns `true` if character code is an uppercase letter, `false` otherwise
 * @see {@link https://www.w3.org/TR/css-syntax-3/#uppercase-letter}
 */
function isUppercaseLetter(code) {
    // A code point between U+0041 LATIN CAPITAL LETTER A (A) and U+005A LATIN CAPITAL LETTER Z (Z) inclusive.
    return isBetween(code, 65 /* CodePoint.LatinCapitalLetterA */, 90 /* CodePoint.LatinCapitalLetterZ */); // A-Z
}
/**
 * Check if character code is a lowercase letter
 *
 * @param code Character code
 * @returns `true` if character code is a lowercase letter, `false` otherwise
 * @see {@link https://www.w3.org/TR/css-syntax-3/#lowercase-letter}
 */
function isLowercaseLetter(code) {
    // A code point between U+0061 LATIN SMALL LETTER A (a) and U+007A LATIN SMALL LETTER Z (z) inclusive.
    return isBetween(code, 97 /* CodePoint.LatinSmallLetterA */, 122 /* CodePoint.LatinSmallLetterZ */); // a-z
}
/**
 * Check if character code is a letter
 *
 * @param code Character code
 * @returns `true` if character code is a letter, `false` otherwise
 * @see {@link https://www.w3.org/TR/css-syntax-3/#letter}
 */
function isLetter(code) {
    // An uppercase letter or a lowercase letter.
    return isUppercaseLetter(code) || isLowercaseLetter(code); // A-Z or a-z
}
/**
 * Check if character code is a non-ASCII code point
 *
 * @param code Character code
 * @returns `true` if character code is a non-ASCII code point, `false` otherwise
 * @see {@link https://www.w3.org/TR/css-syntax-3/#non-ascii-code-point}
 */
function isNonAsciiCodePoint(code) {
    // A code point with a value equal to or greater than U+0080 <control>.
    return isGreaterThanOrEqual(code, 128 /* CodePoint.ControlCharacterStart */);
}
/**
 * Check if character code is a name code point
 *
 * @param code Character code
 * @returns `true` if character code is a name start code point, `false` otherwise
 * @see {@link https://www.w3.org/TR/css-syntax-3/#ident-start-code-point}
 */
function isIdentStartCodePoint(code) {
    // A letter, a non-ASCII code point, or U+005F LOW LINE (_).
    return isLetter(code) || isNonAsciiCodePoint(code) || code === 95 /* CodePoint.LowLine */;
}
/**
 * Check if character code is a name code point
 *
 * @param code Character code
 * @returns `true` if character code is a name code point, `false` otherwise
 * @see {@link https://www.w3.org/TR/css-syntax-3/#ident-code-point}
 */
function isIdentCodePoint(code) {
    // An ident-start code point, a digit, or U+002D HYPHEN-MINUS (-).
    return isIdentStartCodePoint(code) || isDigit(code) || code === 45 /* CodePoint.HyphenMinus */;
}
/**
 * Check if character code is a non-printable code point
 *
 * @param code Character code
 * @returns `true` if character code is a non-printable code point, `false` otherwise
 * @see {@link https://www.w3.org/TR/css-syntax-3/#non-printable-code-point}
 */
function isNonPrintableCodePoint(code) {
    // A code point between U+0000 NULL and U+0008 BACKSPACE inclusive, or U+000B LINE TABULATION, or a code point
    // between U+000E SHIFT OUT and U+001F INFORMATION SEPARATOR ONE inclusive, or U+007F DELETE.
    return isBetween(code, 0 /* CodePoint.Null */, 8 /* CodePoint.Backspace */)
        || code === 11 /* CodePoint.LineTabulation */
        || isBetween(code, 14 /* CodePoint.ShiftOut */, 31 /* CodePoint.InformationSeparatorOne */)
        || code === 127 /* CodePoint.Delete */;
}
/**
 * Check if character code is a newline
 *
 * @param code Character code
 * @returns `true` if character code is a newline, `false` otherwise
 * @see {@link https://www.w3.org/TR/css-syntax-3/#newline}
 */
function isNewline(code) {
    // U+000A LINE FEED. Note that U+000D CARRIAGE RETURN and U+000C FORM FEED are not included in this definition, as
    // they are converted to U+000A LINE FEED during preprocessing.
    return code === 10 /* CodePoint.LineFeed */ || code === 13 /* CodePoint.CarriageReturn */ || code === 12 /* CodePoint.FormFeed */;
}
/**
 * Check if character code is a whitespace
 *
 * @param code Character code
 * @returns `true` if character code is a whitespace, `false` otherwise
 * @see {@link https://www.w3.org/TR/css-syntax-3/#whitespace}
 */
function isWhitespace(code) {
    // A newline, U+0009 CHARACTER TABULATION, or U+0020 SPACE.
    return isNewline(code) || code === 9 /* CodePoint.CharacterTabulation */ || code === 32 /* CodePoint.Space */;
}
/**
 * Check if character code is a leading surrogate
 *
 * @param code Character code
 * @returns `true` if character code is a leading surrogate, `false` otherwise
 * @see {@link https://infra.spec.whatwg.org/#surrogate}
 */
function isLeadingSurrogate(code) {
    return isBetween(code, 55296 /* CodePoint.LeadingSurrogateStart */, 56319 /* CodePoint.LeadingSurrogateEnd */);
}
/**
 * Check if character code is a trailing surrogate
 *
 * @param code Character code
 * @returns `true` if character code is a trailing surrogate, `false` otherwise
 * @see {@link https://infra.spec.whatwg.org/#surrogate}
 */
function isTrailingSurrogate(code) {
    return isBetween(code, 56320 /* CodePoint.TrailingSurrogateStart */, 57343 /* CodePoint.TrailingSurrogateEnd */);
}
/**
 * Check if character code is a surrogate
 *
 * @param code Character code
 * @returns `true` if character code is a surrogate, `false` otherwise
 * @see {@link https://infra.spec.whatwg.org/#surrogate}
 */
function isSurrogate(code) {
    return isLeadingSurrogate(code) || isTrailingSurrogate(code);
}
/**
 * Check if character code is greater than maximum allowed code point
 *
 * @param code Character code
 * @returns `true` if character code is greater than maximum allowed code point, `false` otherwise
 * @see {@link https://www.w3.org/TR/css-syntax-3/#maximum-allowed-code-point}
 */
function isGreaterThanMaxAllowedCodePoint(code) {
    return isGreaterThan(code, 1114111 /* CodePoint.MaxCodePoint */);
}
// TODO: Uncomment when needed, maybe useful in the future
// /**
//  * Check if character code is a valid identifier sequence code point
//  *
//  * @param code Character code
//  * @returns `true` if character code is a valid identifier sequence code point, `false` otherwise
//  * @see {@link https://www.w3.org/TR/css-syntax-3/#ident-sequence}
//  * @note The part of an <at-keyword-token> after the "@", the part of a <hash-token> (with the "id" type flag) after
//  * the "#", the part of a <function-token> before the "(", and the unit of a <dimension-token> are all ident
//  * sequences.
//  */
// export function isIdentSequence(code: number): boolean {
//     // A sequence of code points that has the same syntax as an <ident-token>.
// eslint-disable-next-line max-len
//     return isIdentStartCodePoint(code) || isDigit(code) || code === CodePoint.HyphenMinus || code === CodePoint.LowLine;
// }
/**
 * Check if character code is a BOM (Byte Order Mark)
 *
 * @param code Character code to check
 * @returns `true` if character code is a BOM, `false` otherwise
 */
function isBOM(code) {
    return code === 65279 /* CodePoint.Utf16BeBom */ || code === 65534 /* CodePoint.Utf16LeBom */;
}
/**
 * § 4.3.8. Check if two code points are a valid escape
 *
 * @param a First code point
 * @param b Second code point
 * @returns `true` if the code points are a valid escape, `false` otherwise
 * @see {@link https://www.w3.org/TR/css-syntax-3/#starts-with-a-valid-escape}
 * @note This algorithm will not consume any additional code point.
 */
const checkForValidEscape = (a, b) => {
    // If the first code point is not U+005C REVERSE SOLIDUS (\), return false.
    if (a !== 92 /* CodePoint.ReverseSolidus */) {
        return false;
    }
    // Otherwise, if the second code point is a newline, return false.
    // Otherwise, return true.
    return !isNewline(b);
};
/**
 * § 4.3.9. Check if three code points would start an ident sequence
 *
 * @param a First code point
 * @param b Second code point
 * @param c Third code point
 * @returns `true` if the next code points would start an identifier, `false` otherwise
 * @see {@link https://www.w3.org/TR/css-syntax-3/#would-start-an-identifier}
 * @note This algorithm will not consume any additional code points.
 */
const checkForIdentStart = (a, b, c) => {
    // Look at the first code point:
    // U+002D HYPHEN-MINUS
    if (a === 45 /* CodePoint.HyphenMinus */) {
        // If the second code point is an ident-start code point or a U+002D HYPHEN-MINUS,
        // or the second and third code points are a valid escape, return true. Otherwise, return false.
        return isIdentStartCodePoint(b) || b === 45 /* CodePoint.HyphenMinus */ || checkForValidEscape(b, c);
    }
    // ident-start code point
    if (isIdentStartCodePoint(a)) {
        // Return true.
        return true;
    }
    // U+005C REVERSE SOLIDUS (\)
    if (a === 92 /* CodePoint.ReverseSolidus */) {
        // If the first and second code points are a valid escape, return true. Otherwise, return false.
        return checkForValidEscape(a, b);
    }
    // anything else
    // Return false.
    return false;
};
/**
 * § 4.3.10. Check if three code points would start a number
 *
 * @param a First code point
 * @param b Second code point
 * @param c Third code point
 * @returns `true` if the next code points would start a number, `false` otherwise
 * @see {@link https://www.w3.org/TR/css-syntax-3/#starts-with-a-number}
 * @note This algorithm will not consume any additional code points.
 */
const checkForNumberStart = (a, b, c) => {
    // Look at the first code point:
    // U+002B PLUS SIGN (+)
    // U+002D HYPHEN-MINUS (-)
    if (a === 43 /* CodePoint.PlusSign */ || a === 45 /* CodePoint.HyphenMinus */) {
        // If the second code point is a digit, return true.
        if (isDigit(b)) {
            return true;
        }
        // Otherwise, if the second code point is a U+002E FULL STOP (.) and the third code point is a digit, return
        // true.
        // Otherwise, return false.
        return b === 46 /* CodePoint.FullStop */ && isDigit(c);
    }
    // U+002E FULL STOP (.)
    if (a === 46 /* CodePoint.FullStop */) {
        // If the second code point is a digit, return true. Otherwise, return false.
        return isDigit(b);
    }
    // digit
    // Return true.
    // anything else
    // Return false.
    return isDigit(a);
};

/* eslint-disable no-bitwise */
/**
 * @file Hashing functions based on the djb2 algorithm
 *
 * @see {@link http://www.cse.yorku.ca/~oz/hash.html}
 * @see {@link https://gist.github.com/eplawless/52813b1d8ad9af510d85?permalink_comment_id=3367765#gistcomment-3367765}
 * @todo If we need it, we can create case-sensitive versions of these functions
 */
/**
 * Make a unique hash from the given array of code points
 *
 * @param arr Reference to the array of code points
 * @param start Start index
 * @param end End index
 * @returns Hash of the given array of code points
 * @note Case-insensitive (we use it just for function names which are case-insensitive)
 */
function getCodePointsArrayHash(arr, start, end) {
    let hash = 5381;
    for (let i = start; i < end; i += 1) {
        hash = hash * 33 ^ (arr[i] | 0x20);
    }
    return hash >>> 0;
}

/**
 * @file Tokenizer context
 */
/**
 * Context of the tokenizer which is shared between all the functions
 */
class TokenizerContext {
    /**
     * Cached source length
     */
    length;
    /**
     * Reference to the `onToken` callback function
     */
    onToken;
    /**
     * Reference to the `onError` callback function
     */
    onError;
    /**
     * Unicode code points of the source string
     *
     * @note The last code point is always EOF ("imaginary" code point)
     * @note Using `!` is safe here because the `preprocess` function always sets the codes in the constructor
     * @note We need a signed 32-bit integer array, because the code points are 21-bit integers + imaginary code points
     * are negative numbers
     */
    codes;
    /**
     * Actual position in the source string
     */
    cursor;
    /**
     * Custom function handlers to handle special functions, like Extended CSS's pseudo selectors
     */
    customFunctionHandlers;
    /**
     * Constructs a new tokenizer context instance
     *
     * @param source Source string
     * @param onToken Callback function to call when a token is found
     * @param onError Callback function to call when a parsing error occurs
     * @param functionHandlers Custom function handlers to handle special functions, like Extended CSS's pseudo
     * selectors
     */
    constructor(source, onToken, onError, functionHandlers) {
        // Set the source and offset
        // this.source = source;
        this.length = source.length;
        this.preprocess(source);
        // Ignore BOM character if present
        this.cursor = isBOM(this.codes[0]) ? 1 : 0;
        // Set the callback functions
        this.onToken = onToken;
        this.onError = onError;
        // Register custom function handlers, if any
        if (functionHandlers) {
            this.customFunctionHandlers = new Map();
            for (const [hash, handler] of functionHandlers) {
                this.customFunctionHandlers.set(hash, handler);
            }
        }
    }
    /**
     * § 3.3. Preprocessing the input stream
     *
     * @param source Source string to preprocess
     * @see {@link https://www.w3.org/TR/css-syntax-3/#input-preprocessing}
     */
    preprocess(source) {
        const len = source.length;
        this.codes = new Int32Array(len + 1); // add +1 slot for the EOF "code point"
        // TODO: Uncomment when needed - actually, we don't convert the CRLF to LF to keep the original source positions
        // // The input stream consists of the filtered code points pushed into it as the input byte stream is decoded.
        // for (let i = 0; i < len; i += 1) {
        //     const code = source.charCodeAt(i);
        //     // To filter code points from a stream of (unfiltered) code points input:
        //     switch (code) {
        //         // Replace any U+000D CARRIAGE RETURN (CR) code points, U+000C FORM FEED (FF) code points, or pairs
        //         // of U+000D CARRIAGE RETURN (CR) followed by U+000A LINE FEED (LF) in input by a single
        //         // U+000A LINE FEED (LF) code point.
        //         case CodePoint.CarriageReturn:
        //             if (source.charCodeAt(i + 1) === CodePoint.LineFeed) {
        //                 this.codes[i] = CodePoint.LineFeed;
        //                 // Skip the next code point
        //                 i += 1;
        //                 break;
        //             }
        //             this.codes[i] = CodePoint.LineFeed;
        //             break;
        //         case CodePoint.FormFeed:
        //             this.codes[i] = CodePoint.LineFeed;
        //             break;
        //         // Replace any U+0000 NULL or surrogate code points in input with U+FFFD REPLACEMENT CHARACTER (�).
        //         case CodePoint.Null:
        //             this.codes[i] = CodePoint.ReplacementCharacter;
        //             break;
        //         default:
        //             this.codes[i] = code;
        //             break;
        //     }
        // }
        // Everything what we need here is to transform the ASCII source to Unicode code points as fast as possible
        for (let i = 0; i < len; i += 1) {
            this.codes[i] = source.charCodeAt(i);
        }
        // Set last code point to EOF (this way we can use it in switch-case statements, which are faster than if-else
        // or classic lookup tables)
        // See https://stackoverflow.com/a/37955539
        this.codes[len] = -1 /* ImaginaryCodePoint.Eof */;
    }
    /**
     * Gets the corresponding custom function handler for the given function name hash
     *
     * @param hash Function name hash
     * @returns Corresponding custom function handler or `undefined` if not found
     */
    getFunctionHandler(hash) {
        return this.customFunctionHandlers?.get(hash);
    }
    /**
     * Checks if the custom function handler is registered for the given function name hash
     *
     * @param hash Custom function name hash
     * @returns `true` if the custom function handler is registered, `false` otherwise
     */
    hasFunctionHandler(hash) {
        return this.customFunctionHandlers?.has(hash) ?? false;
    }
    /**
     * Returns the current offset
     *
     * @returns Current offset
     */
    get offset() {
        return this.cursor;
    }
    /**
     * Returns the code point at the current offset
     *
     * @returns Code point at the current offset
     */
    get code() {
        return this.codes[this.offset];
    }
    /**
     * Returns the code point at the previous offset
     *
     * @returns Code point at the previous offset or `undefined` if the offset is out of bounds
     */
    get prevCode() {
        return this.codes[this.offset - 1];
    }
    /**
     * Returns the code point at the next offset
     *
     * @returns Code point at the next offset or `undefined` if the offset is out of bounds
     */
    get nextCode() {
        return this.codes[this.offset + 1];
    }
    /**
     * Returns the code point at the given relative offset
     *
     * @param relativeOffset Relative offset
     * @returns Code point at the relative offset or `undefined` if the offset is out of bounds
     * @note Relative offset compared to the current offset. 1 means the next code point, -1 means the previous code
     * point, 2 means the code point after the next code point, etc.
     */
    getRelativeCode(relativeOffset) {
        return this.codes[this.offset + relativeOffset];
    }
    /**
     * Check if the current offset is at the end of the source (or past it)
     *
     * @returns `true` if the current offset is at the end of the source, `false` otherwise
     */
    isEof() {
        return this.offset >= this.length;
    }
    /**
     * Check if the next code point is EOF
     *
     * @returns `true` if the next code point is EOF, `false` otherwise
     */
    isNextEof() {
        return this.cursor + 1 === this.length;
    }
    /**
     * Check if the current offset is less than or equal to the end of the source
     *
     * @returns `true` if the current offset is less than or equal to the end of the source, `false` otherwise
     */
    isLessThanEqualToEof() {
        return this.offset <= this.length;
    }
    /**
     * Consumes the given number of code points
     *
     * @param n Number of code points to consume (default: 1)
     * @note Negative numbers are allowed (they will move the cursor backwards)
     * @note No protection against out of bounds for performance reasons
     */
    consumeCodePoint(n = 1) {
        this.cursor += n;
    }
    /**
     * Finds the next non-whitespace code point and returns it
     *
     * @returns Next non-whitespace code point or EOF imaginary code point if the rest of the source is whitespace
     */
    getNextNonWsCode() {
        let i = this.cursor;
        while (i < this.length && isWhitespace(this.codes[i])) {
            i += 1;
        }
        return this.codes[i];
    }
    /**
     * Consumes the whitespace code points
     */
    consumeWhitespace() {
        while (this.code && isWhitespace(this.code)) {
            this.consumeCodePoint();
        }
    }
    /**
     * Consumes a single whitespace code point, if the current code point is a whitespace
     */
    consumeSingleWhitespace() {
        if (isWhitespace(this.code)) {
            // special case: consume CRLF as a single whitespace
            this.cursor += this.code === 13 /* CodePoint.CarriageReturn */ && this.nextCode === 10 /* CodePoint.LineFeed */ ? 2 : 1;
        }
    }
    /**
     * Consumes everything until the end of the comment (or the end of the source)
     */
    consumeUntilCommentEnd() {
        // search for the end of the comment or reach the end of the source
        while (this.cursor < this.length) {
            // check if the current code point is a *
            if (this.code === 42 /* CodePoint.Asterisk */ && this.nextCode === 47 /* CodePoint.Solidus */) {
                // consume '*/' and exit the loop
                this.cursor += 2;
                break;
            }
            // consume the current code point, it seems it's a part of the comment
            this.cursor += 1;
        }
    }
    /**
     * Consumes a single-character token (trivial token) and reports it via the `onToken` callback
     *
     * @param tokenType Token type to report
     */
    consumeTrivialToken(tokenType) {
        // eslint-disable-next-line no-plusplus
        this.onToken(tokenType, this.cursor, ++this.cursor);
    }
    /**
     * Calculates the hash of the fragment from the given start offset to the current offset. This is useful to
     * fast-check function names.
     *
     * @param start Start offset
     * @returns Calculated hash
     */
    getHashFrom(start) {
        return getCodePointsArrayHash(this.codes, start, this.cursor);
    }
}

/**
 * @file Possible CSS token types, as defined in the CSS Syntax Module Level 3.
 *
 * ! Strictly follows the spec.
 *
 * @see {@link https://www.w3.org/TR/css-syntax-3/#tokenization}
 */
var TokenType;
(function (TokenType) {
    TokenType[TokenType["Eof"] = 0] = "Eof";
    TokenType[TokenType["Ident"] = 1] = "Ident";
    TokenType[TokenType["Function"] = 2] = "Function";
    TokenType[TokenType["AtKeyword"] = 3] = "AtKeyword";
    TokenType[TokenType["Hash"] = 4] = "Hash";
    TokenType[TokenType["String"] = 5] = "String";
    TokenType[TokenType["BadString"] = 6] = "BadString";
    TokenType[TokenType["Url"] = 7] = "Url";
    TokenType[TokenType["BadUrl"] = 8] = "BadUrl";
    TokenType[TokenType["Delim"] = 9] = "Delim";
    TokenType[TokenType["Number"] = 10] = "Number";
    TokenType[TokenType["Percentage"] = 11] = "Percentage";
    TokenType[TokenType["Dimension"] = 12] = "Dimension";
    TokenType[TokenType["Whitespace"] = 13] = "Whitespace";
    TokenType[TokenType["Cdo"] = 14] = "Cdo";
    TokenType[TokenType["Cdc"] = 15] = "Cdc";
    TokenType[TokenType["Colon"] = 16] = "Colon";
    TokenType[TokenType["Semicolon"] = 17] = "Semicolon";
    TokenType[TokenType["Comma"] = 18] = "Comma";
    TokenType[TokenType["OpenSquareBracket"] = 19] = "OpenSquareBracket";
    TokenType[TokenType["CloseSquareBracket"] = 20] = "CloseSquareBracket";
    TokenType[TokenType["OpenParenthesis"] = 21] = "OpenParenthesis";
    TokenType[TokenType["CloseParenthesis"] = 22] = "CloseParenthesis";
    TokenType[TokenType["OpenCurlyBracket"] = 23] = "OpenCurlyBracket";
    TokenType[TokenType["CloseCurlyBracket"] = 24] = "CloseCurlyBracket";
    TokenType[TokenType["Comment"] = 25] = "Comment";
})(TokenType || (TokenType = {}));

/**
 * @file CSS token names
 */
const UNKNOWN_TOKEN_NAME = 'unknown';
/**
 * Pairs of token types and their base names
 */
const TOKEN_NAMES = Object.freeze({
    [TokenType.Eof]: 'eof',
    [TokenType.Ident]: 'ident',
    [TokenType.Function]: 'function',
    [TokenType.AtKeyword]: 'at-keyword',
    [TokenType.Hash]: 'hash',
    [TokenType.String]: 'string',
    [TokenType.BadString]: 'bad-string',
    [TokenType.Url]: 'url',
    [TokenType.BadUrl]: 'bad-url',
    [TokenType.Delim]: 'delim',
    [TokenType.Number]: 'number',
    [TokenType.Percentage]: 'percentage',
    [TokenType.Dimension]: 'dimension',
    [TokenType.Whitespace]: 'whitespace',
    [TokenType.Cdo]: 'CDO',
    [TokenType.Cdc]: 'CDC',
    [TokenType.Colon]: 'colon',
    [TokenType.Semicolon]: 'semicolon',
    [TokenType.Comma]: 'comma',
    [TokenType.OpenSquareBracket]: '[',
    [TokenType.CloseSquareBracket]: ']',
    [TokenType.OpenParenthesis]: '(',
    [TokenType.CloseParenthesis]: ')',
    [TokenType.OpenCurlyBracket]: '{',
    [TokenType.CloseCurlyBracket]: '}',
    [TokenType.Comment]: 'comment',
});
/**
 * Get base token name by token type
 *
 * @param type Token type
 *
 * @example
 * ```ts
 * getBaseTokenName(TokenType.Ident); // 'ident'
 * getBaseTokenName(-1); // 'unknown'
 * ```
 *
 * @returns Base token name or 'unknown' if token type is unknown
 */
const getBaseTokenName = (type) => {
    return TOKEN_NAMES[type] ?? UNKNOWN_TOKEN_NAME;
};
/**
 * Get formatted token name by token type
 *
 * @param type Token type
 *
 * @example
 * ```ts
 * getFormattedTokenName(TokenType.Ident); // '<ident-token>'
 * getFormattedTokenName(-1); // '<unknown-token>'
 * ```
 *
 * @returns Formatted token name or `'<unknown-token>'` if token type is unknown
 */
const getFormattedTokenName = (type) => {
    return `<${getBaseTokenName(type)}-token>`;
};

/**
 * @file Tokenizing logic for escaped code points
 */
const MAX_HEX_DIGITS = 6;
/**
 * § 4.3.7. Consume an escaped code point
 *
 * @param context Reference to the tokenizer context instance
 * @see {@link https://www.w3.org/TR/css-syntax-3/#consume-escaped-code-point}
 */
const consumeEscapedCodePoint = (context) => {
    // It assumes that the U+005C REVERSE SOLIDUS (\) has already been consumed and that the next input code point has
    // already been verified to be part of a valid escape.
    // Consume the next input code point.
    context.consumeCodePoint();
    // hex digit
    if (isHexDigit(context.code)) {
        // Consume as many hex digits as possible, but no more than 5. Note that this means 1-6 hex digits have been
        // consumed in total. If the next input code point is whitespace, consume it as well. Interpret the hex digits
        // as a hexadecimal number.
        let consumedHexDigits = 0;
        while (isHexDigit(context.code) && consumedHexDigits <= MAX_HEX_DIGITS) {
            context.consumeCodePoint();
            consumedHexDigits += 1;
        }
        // If the next input code point is whitespace, consume it as well.
        context.consumeSingleWhitespace();
        // If this number is zero, or is for a surrogate, or is greater than the maximum allowed code point,
        // return U+FFFD REPLACEMENT CHARACTER (�).
        // Otherwise, return the code point with that value.
        // TODO: Implement surrogate check
    }
    // EOF
    // This is a parse error. Return U+FFFD REPLACEMENT CHARACTER (�).
    if (context.isEof()) {
        context.onError("Unexpected end of file while parsing escaped code point." /* ErrorMessage.UnexpectedEofInEscaped */, context.offset, context.offset);
    }
    // anything else
    // Return the current input code point.
};

/**
 * @file Tokenizing logic for ident sequences
 */
/**
 * § 4.3.11. Consume an ident sequence
 *
 * Consume an ident sequence from a stream of code points. It returns a string containing the largest name that can be
 * formed from adjacent code points in the stream, starting from the first.
 *
 * @param context Reference to the tokenizer context instance
 * @see {@link https://www.w3.org/TR/css-syntax-3/#consume-name}
 * @note This algorithm does not do the verification of the first few code points that are necessary to ensure the
 * returned code points would constitute an <ident-token>. If that is the intended use, ensure that the stream
 * starts with an ident sequence before calling this algorithm.
 */
const consumeIndentSequence = (context) => {
    // Let result initially be an empty string.
    // Repeatedly consume the next input code point from the stream:
    while (!context.isEof()) {
        // ident code point
        if (isIdentCodePoint(context.code)) {
            // Append the code point to result.
            context.consumeCodePoint();
            continue;
        }
        // the stream starts with a valid escape
        if (checkForValidEscape(context.code, context.nextCode)) {
            // Consume an escaped code point. Append the returned code point to result.
            context.consumeCodePoint();
            consumeEscapedCodePoint(context);
            continue;
        }
        // anything else
        // Reconsume the current input code point. Return result.
        return;
    }
};

/**
 * @file Tokenizing logic for URLs
 */
/**
 * § 4.3.14. Consume the remnants of a bad url
 *
 * Consume the remnants of a bad url from a stream of code points, "cleaning up" after the tokenizer realizes that it’s
 * in the middle of a <bad-url-token> rather than a <url-token>. It returns nothing; its sole use is to consume enough
 * of the input stream to reach a recovery point where normal tokenizing can resume.
 *
 * @param context Tokenizer context
 * @see {@link https://www.w3.org/TR/css-syntax-3/#consume-remnants-of-bad-url}
 */
function consumeBadUrlRemnants(context) {
    // Repeatedly consume the next input code point from the stream:
    // eslint-disable-next-line no-constant-condition
    for (; !context.isEof(); context.consumeCodePoint()) {
        // U+0029 RIGHT PARENTHESIS ())
        if (context.code === 41 /* CodePoint.RightParenthesis */) {
            // Don’t forget to consume it.
            context.consumeCodePoint();
            return;
        }
        // the input stream starts with a valid escape
        if (checkForValidEscape(context.getRelativeCode(1), context.getRelativeCode(2))) {
            // Consume an escaped code point. This allows an escaped right parenthesis ("\)") to be encountered
            // without ending the <bad-url-token>. This is otherwise identical to the "anything else" clause.
            context.consumeCodePoint();
            consumeEscapedCodePoint(context);
            continue;
        }
        // anything else
        // Do nothing.
    }
}
/**
 * Helper function for consuming a bad url token.
 *
 * @param context Tokenizer context
 * @param start Token start offset
 * @see {@link https://www.w3.org/TR/css-syntax-3/#consume-remnants-of-bad-url}
 */
function consumeBadUrlToken(context, start) {
    consumeBadUrlRemnants(context);
    context.onToken(TokenType.BadUrl, start, context.offset);
}
/**
 * § 4.3.6. Consume a url token
 *
 * Consume a url token from a stream of code points. It returns either a <url-token> or a <bad-url-token>.
 *
 * @param context Reference to the tokenizer context instance
 * @param start Token start offset
 * @see {@link https://www.w3.org/TR/css-syntax-3/#consume-url-token}
 * @note This algorithm assumes that the initial "url(" has already been consumed. This algorithm also assumes that
 * it’s being called to consume an "unquoted" value, like url(foo). A quoted value, like url("foo"), is parsed as a
 * <function-token>. Consume an ident-like token automatically handles this distinction; this algorithm shouldn’t be
 * called directly otherwise.
 */
const consumeUrlToken = (context, start) => {
    // Initially create a <url-token> with its value set to the empty string.
    // Consume as much whitespace as possible.
    while (isWhitespace(context.code)) {
        context.consumeCodePoint();
    }
    // Repeatedly consume the next input code point from the stream:
    // eslint-disable-next-line no-constant-condition
    while (context.offset <= context.length) {
        // TODO: Use switch-case here, but need to resolve non-printable code points first
        // U+0029 RIGHT PARENTHESIS ())
        if (context.code === 41 /* CodePoint.RightParenthesis */) {
            // Consume it.
            context.consumeCodePoint();
            // Return the <url-token>.
            context.onToken(TokenType.Url, start, context.offset);
            return;
        }
        // EOF
        if (context.isEof()) {
            // This is a parse error. Return the <url-token>.
            context.onToken(TokenType.Url, start, context.offset);
            context.onError("Unexpected end of file while parsing URL." /* ErrorMessage.UnexpectedEofInUrl */, start, context.offset);
            return;
        }
        // whitespace
        if (isWhitespace(context.code)) {
            // Consume as much whitespace as possible. If the next input code point is U+0029 RIGHT PARENTHESIS ())
            // or EOF, consume it and return the <url-token> (if EOF was encountered, this is a parse error);
            // otherwise, consume the remnants of a bad url, create a <bad-url-token>, and return it.
            while (isWhitespace(context.code)) {
                context.consumeCodePoint();
            }
            if (context.code === 41 /* CodePoint.RightParenthesis */ || context.isEof()) {
                context.consumeCodePoint();
                context.onToken(TokenType.Url, start, context.offset);
                context.onError("Unexpected end of file while parsing URL." /* ErrorMessage.UnexpectedEofInUrl */, start, context.offset);
                return;
            }
            context.onError("Unexpected character in URL." /* ErrorMessage.UnexpectedCharInUrl */, start, context.offset);
            consumeBadUrlToken(context, start);
            return;
        }
        // U+0022 QUOTATION MARK (")
        // U+0027 APOSTROPHE (')
        // U+0028 LEFT PARENTHESIS (()
        // non-printable code point
        if (context.code === 34 /* CodePoint.QuotationMark */
            || context.code === 39 /* CodePoint.Apostrophe */
            || context.code === 40 /* CodePoint.LeftParenthesis */
            || isNonPrintableCodePoint(context.code)) {
            // This is a parse error. Consume the remnants of a bad url, create a <bad-url-token>, and return it.
            context.onError("Unexpected character in URL." /* ErrorMessage.UnexpectedCharInUrl */, start, context.offset);
            consumeBadUrlToken(context, start);
            return;
        }
        // U+005C REVERSE SOLIDUS (\)
        if (context.code === 92 /* CodePoint.ReverseSolidus */) {
            // If the stream starts with a valid escape, consume an escaped code point and append the returned code
            // point to the <url-token>’s value.
            if (checkForValidEscape(context.code, context.nextCode)) {
                // Consume reversed solidus, then consume escaped code point
                context.consumeCodePoint();
                consumeEscapedCodePoint(context);
                continue;
            }
            // Otherwise, this is a parse error. Consume the remnants of a bad url, create a <bad-url-token>, and
            // return it.
            context.onError("Unexpected character in URL." /* ErrorMessage.UnexpectedCharInUrl */, start, context.offset);
            consumeBadUrlToken(context, start);
            return;
        }
        // anything else
        // Append the current input code point to the <url-token>’s value.
        context.consumeCodePoint();
    }
};

/**
 * @file Tokenizing logic for ident-like tokens
 */
const URL_FUNCTION_HASH = 193422222; // getStringHash('url')
/**
 * § 4.3.4. Consume an ident-like token
 *
 * Consume an ident-like token from a stream of code points. It returns an <ident-token>, <function-token>, <url-token>,
 * or <bad-url-token>.
 *
 * @param context Reference to the tokenizer context instance
 * @see {@link https://www.w3.org/TR/css-syntax-3/#consume-an-ident-like-token}
 * @note We extended the algorithm to allow custom function handlers, but the tokenizer still strictly follows the spec.
 */
const consumeIdentLikeToken = (context) => {
    // Consume an ident sequence, and let string be the result.
    const start = context.offset;
    consumeIndentSequence(context);
    // If the ident sequence is followed by U+0028 LEFT PARENTHESIS ((), consume it as a function:
    if (context.code === 40 /* CodePoint.LeftParenthesis */) {
        // First, store the function’s name hash
        const fnHash = context.getHashFrom(start);
        // Consume the opening parenthesis.
        context.consumeCodePoint();
        // URL
        if (fnHash === URL_FUNCTION_HASH) {
            // While the next two input code points are whitespace, consume the next input code point
            // If the next one or two input code points are U+0022 QUOTATION MARK ("), U+0027 APOSTROPHE ('), or
            // whitespace followed by U+0022 QUOTATION MARK (") or U+0027 APOSTROPHE ('), then create a <function-token>
            // with its value set to string and return it.
            // ! Different from the spec, but technically it is enough to check the next non-whitespace code point
            const nextNonWsCode = context.getNextNonWsCode();
            if (nextNonWsCode === 34 /* CodePoint.QuotationMark */ || nextNonWsCode === 39 /* CodePoint.Apostrophe */) {
                context.onToken(TokenType.Function, start, context.offset);
                return;
            }
            // Otherwise, consume a url token, and return it.
            consumeUrlToken(context, start);
            return;
        }
        // This is a good time to call custom function handlers, if any.
        // ! This is not part of the spec, but it's a good way to extend the tokenizer and if you didn't added any
        // ! custom function handler, it will not affect the tokenizer in any way, it still strictly follows the spec.
        // For performance reasons, we use `has` and `get` separately to avoid declaring a new variable every time here
        if (context.hasFunctionHandler(fnHash)) {
            // Return the <function-token>.
            context.onToken(TokenType.Function, start, context.offset);
            // Consume the function body
            // It's safe to call the handler directly because we already checked if it exists
            // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
            context.getFunctionHandler(fnHash)(context);
            return;
        }
        // Otherwise, if the next input code point is U+0028 LEFT PARENTHESIS ((), consume it. Create a <function-token>
        // with its value set to string and return it.
        context.onToken(TokenType.Function, start, context.offset);
        return;
    }
    // Otherwise, create an <ident-token> with its value set to string and return it.
    context.onToken(TokenType.Ident, start, context.offset);
};

/**
 * @file Tokenizing logic for numbers
 */
/**
 * § 4.3.12. Consume a number
 *
 * Consume a number from a stream of code points. It returns a numeric value, and a type which is either "integer" or
 * "number".
 *
 * @param context Reference to the tokenizer context instance
 * @note This algorithm does not do the verification of the first few code points that are necessary to ensure a number
 * can be obtained from the stream. Ensure that the stream starts with a number before calling this algorithm.
 * @see {@link https://www.w3.org/TR/css-syntax-3/#consume-number}
 * @todo Uncomment type/repr handling if needed - currently we don't need them, and they're not used for performance
 * reasons
 */
const consumeNumber = (context) => {
    // Execute the following steps in order:
    // 1. Initially set type to "integer". Let repr be the empty string.
    // TODO: Uncomment type/repr handling if needed
    // let type = NumberType.Integer;
    // const repr: string[] = [];
    // 2. If the next input code point is U+002B PLUS SIGN (+) or U+002D HYPHEN-MINUS (-), consume it and append it
    // to repr.
    if (context.code === 43 /* CodePoint.PlusSign */ || context.code === 45 /* CodePoint.HyphenMinus */) {
        context.consumeCodePoint();
        // TODO: Append to repr
    }
    // 3. While the next input code point is a digit, consume it and append it to repr.
    while (isDigit(context.code)) {
        context.consumeCodePoint();
        // TODO: Append to repr
    }
    // 4. If the next 2 input code points are U+002E FULL STOP (.) followed by a digit, then:
    if (context.code === 46 /* CodePoint.FullStop */ && isDigit(context.nextCode)) {
        // 1. Consume them.
        context.consumeCodePoint(2);
        // 2.Append them to repr
        // TODO: Append to repr
        // 3. Set type to "number".
        // type = NumberType.Number;
        // 4. While the next input code point is a digit, consume it and append it to repr.
        while (isDigit(context.code)) {
            context.consumeCodePoint();
            // TODO: Append to repr
        }
    }
    // 5. If the next 2 or 3 input code points are U+0045 LATIN CAPITAL LETTER E (E) or U+0065 LATIN SMALL LETTER E
    // (e) ...
    if ((context.code === 69 /* CodePoint.LatinCapitalLetterE */ || context.code === 101 /* CodePoint.LatinSmallLetterE */)) {
        // ... optionally followed by U+002D HYPHEN-MINUS (-) or U+002B PLUS SIGN (+)
        // Note: we split this into two if statements to avoid declaring a shift variable for the sign
        if ((context.nextCode === 45 /* CodePoint.HyphenMinus */ || context.nextCode === 43 /* CodePoint.PlusSign */)
            && isDigit(context.getRelativeCode(2))) {
            // 1. Consume them.
            context.consumeCodePoint(3); // e, sign, digit
            // 2. Append them to repr.
            // TODO: Append to repr
            // 3. Set type to "number".
            // TODO: Set type
            // 4. While the next input code point is a digit, consume it and append it to repr.
            while (isDigit(context.code)) {
                context.consumeCodePoint();
                // TODO: Append to repr
            }
        }
        else if (isDigit(context.nextCode)) {
            // ... followed by a digit, then:
            // 1. Consume them.
            context.consumeCodePoint(2); // e, digit
            // 2. Append them to repr.
            // TODO: Append to repr
            // 3. Set type to "number".
            // TODO: Set type
            // 4. While the next input code point is a digit, consume it and append it to repr.
            while (isDigit(context.code)) {
                context.consumeCodePoint();
                // TODO: Append to repr
            }
        }
    }
    // 6. Convert repr to a number, and set the value to the returned value.
    // TODO: Convert repr to a number
    // const value = Number(repr.join(''));
    // 7. Return value and type.
    // TODO: Uncomment type handling if needed
    // return [value, type];
};

/**
 * @file Tokenizing logic for numeric tokens
 */
/**
 * § 4.3.3. Consume a numeric token
 *
 * Consume a numeric token from a stream of code points. It returns either a <number-token>, <percentage-token>, or
 * <dimension-token>.
 *
 * @param context Reference to the tokenizer context instance
 * @see {@link https://www.w3.org/TR/css-syntax-3/#consume-numeric-token}
 */
const consumeNumericToken = (context) => {
    const start = context.offset;
    // Consume a number and let number be the result.
    consumeNumber(context);
    // If the next 3 input code points would start an ident sequence, then:
    if (checkForIdentStart(context.code, context.nextCode, context.getRelativeCode(2))) {
        // 1. Create a <dimension-token> with the same value and type flag as number, and a unit set initially to
        // the empty string.
        // 2. Consume an ident sequence. Set the <dimension-token>’s unit to the returned value.
        consumeIndentSequence(context);
        // 3. Return the <dimension-token>.
        context.onToken(TokenType.Dimension, start, context.offset);
        return;
    }
    // Otherwise, if the next input code point is U+0025 PERCENTAGE SIGN (%), consume it. Create a
    // <percentage-token> with the same value as number, and return it.
    if (context.code === 37 /* CodePoint.PercentageSign */) {
        context.consumeCodePoint();
        context.onToken(TokenType.Percentage, start, context.offset);
        return;
    }
    // Otherwise, create a <number-token> with the same value and type flag as number, and return it.
    context.onToken(TokenType.Number, start, context.offset);
};

/**
 * @file Tokenizing logic for strings
 */
/**
 * § 4.3.5. Consume a string token
 *
 * Consume a string token from a stream of code points. It returns either a <string-token> or <bad-string-token>.
 *
 * @param context Reference to the tokenizer context instance
 * @see {@link https://www.w3.org/TR/css-syntax-3/#consume-string-token}
 */
const consumeStringToken = (context) => {
    // This algorithm may be called with an ending code point, which denotes the code point that ends the string.
    // If an ending code point is not specified, the current input code point is used.
    const endingCodePoint = context.code;
    // Initially create a <string-token> with its value set to the empty string.
    const start = context.offset;
    // Consume opening character
    context.consumeCodePoint();
    // Repeatedly consume the next input code point from the stream:
    // eslint-disable-next-line no-constant-condition
    while (context.isLessThanEqualToEof()) {
        switch (context.code) {
            // ending code point
            case endingCodePoint:
                // Consume it
                context.consumeCodePoint();
                // Return the <string-token>.
                context.onToken(TokenType.String, start, context.offset);
                return;
            // EOF
            case -1 /* ImaginaryCodePoint.Eof */:
                // This is a parse error. Return the <string-token>.
                context.onToken(TokenType.String, start, context.offset);
                context.onError("Unexpected end of file while parsing string token." /* ErrorMessage.UnexpectedEofInString */, start, context.offset);
                return;
            // newline
            case 13 /* CodePoint.CarriageReturn */:
            case 10 /* CodePoint.LineFeed */:
            case 12 /* CodePoint.FormFeed */:
                // Special case: CRLF is 2 code points
                if (context.code === 13 /* CodePoint.CarriageReturn */ && context.nextCode === 10 /* CodePoint.LineFeed */) {
                    // Do an extra consume
                    context.consumeCodePoint(1);
                }
                context.consumeCodePoint(1);
                // This is a parse error. Reconsume the current input code point, create a <bad-string-token>, and
                // return it.
                context.onToken(TokenType.BadString, start, context.offset);
                context.onError("Unexpected newline while parsing string token." /* ErrorMessage.UnexpectedNewlineInString */, start, context.offset);
                return;
            // U+005C REVERSE SOLIDUS (\)
            case 92 /* CodePoint.ReverseSolidus */:
                // If the next input code point is EOF, do nothing.
                if (context.isNextEof()) {
                    context.consumeCodePoint();
                    context.onToken(TokenType.String, start, context.offset);
                    context.onError("Unexpected end of file while parsing string token." /* ErrorMessage.UnexpectedEofInString */, start, context.offset);
                    return;
                }
                // Otherwise, if the next input code point is a newline, consume it.
                if (isNewline(context.nextCode)) {
                    context.consumeCodePoint(2);
                    break;
                }
                // Otherwise, (the stream starts with a valid escape) consume an escaped code point and append the
                // returned code point to the <string-token>’s value.
                if (checkForValidEscape(context.code, context.nextCode)) {
                    context.consumeCodePoint();
                    consumeEscapedCodePoint(context);
                }
                break;
            // anything else
            default:
                // Append the current input code point to the <string-token>’s value.
                context.consumeCodePoint();
        }
    }
};

/**
 * @file Tokenizing logic for whitespace
 */
/**
 * § 4.3.1. Consume a token (whitespace)
 *
 * @see {@link https://www.w3.org/TR/css-syntax-3/#consume-token}
 * @param context Reference to the tokenizer context instance
 */
const consumeWhitespaceToken = (context) => {
    // Consume as much whitespace as possible. Return a <whitespace-token>.
    const start = context.offset;
    context.consumeWhitespace();
    context.onToken(TokenType.Whitespace, start, context.offset);
};

/**
 * @file CSS tokenizer that strictly follows the CSS Syntax Module Level 3 specification
 *
 * @see {@link https://www.w3.org/TR/css-syntax-3/#tokenization}
 */
/**
 * CSS tokenizer function
 *
 * @param source Source code to tokenize
 * @param onToken Tokenizer callback which is called for each token found in source code
 * @param onError Error callback which is called when a parsing error is found (optional)
 * @param functionHandlers Custom function handlers (optional)
 */
const tokenize = (source, onToken, onError = () => { }, functionHandlers) => {
    // Create tokenizer context
    const context = new TokenizerContext(source, onToken, onError, functionHandlers);
    // Repeatedly consume the next input code point from the stream:
    while (!context.isEof()) {
        switch (context.code) {
            // According to the spec, these are all whitespace code points:
            case 9 /* CodePoint.CharacterTabulation */:
            case 32 /* CodePoint.Space */:
            case 10 /* CodePoint.LineFeed */:
            case 12 /* CodePoint.FormFeed */:
            case 13 /* CodePoint.CarriageReturn */:
                // Consume as much whitespace as possible. Return a <whitespace-token>.
                consumeWhitespaceToken(context);
                break;
            // Digit
            case 48 /* CodePoint.DigitZero */:
            case 49 /* CodePoint.DigitOne */:
            case 50 /* CodePoint.DigitTwo */:
            case 51 /* CodePoint.DigitThree */:
            case 52 /* CodePoint.DigitFour */:
            case 53 /* CodePoint.DigitFive */:
            case 54 /* CodePoint.DigitSix */:
            case 55 /* CodePoint.DigitSeven */:
            case 56 /* CodePoint.DigitEight */:
            case 57 /* CodePoint.DigitNine */:
                consumeNumericToken(context);
                break;
            case 40 /* CodePoint.LeftParenthesis */:
                context.consumeTrivialToken(TokenType.OpenParenthesis);
                break;
            case 41 /* CodePoint.RightParenthesis */:
                context.consumeTrivialToken(TokenType.CloseParenthesis);
                break;
            case 44 /* CodePoint.Comma */:
                context.consumeTrivialToken(TokenType.Comma);
                break;
            case 58 /* CodePoint.Colon */:
                context.consumeTrivialToken(TokenType.Colon);
                break;
            case 59 /* CodePoint.SemiColon */:
                context.consumeTrivialToken(TokenType.Semicolon);
                break;
            case 91 /* CodePoint.LeftSquareBracket */:
                context.consumeTrivialToken(TokenType.OpenSquareBracket);
                break;
            case 93 /* CodePoint.RightSquareBracket */:
                context.consumeTrivialToken(TokenType.CloseSquareBracket);
                break;
            case 123 /* CodePoint.LeftCurlyBracket */:
                context.consumeTrivialToken(TokenType.OpenCurlyBracket);
                break;
            case 125 /* CodePoint.RightCurlyBracket */:
                context.consumeTrivialToken(TokenType.CloseCurlyBracket);
                break;
            case 39 /* CodePoint.Apostrophe */:
            case 34 /* CodePoint.QuotationMark */:
                // Consume a string token and return it.
                consumeStringToken(context);
                break;
            case 35 /* CodePoint.NumberSign */:
                // If the next input code point is an ident code point or the next two input code points are a
                // valid escape, then:
                if (isIdentCodePoint(context.getRelativeCode(1))
                    || checkForValidEscape(context.getRelativeCode(1), context.getRelativeCode(2))) {
                    const start = context.offset;
                    // 1. Create a <hash-token>.
                    // 2. If the next 3 input code points would start an ident sequence, set the <hash-token>’s
                    // type flag to "id".
                    // TODO: Uncomment when needed
                    // const props = {
                    //     typeFlag: checkForIdentStart(
                    //         context.getRelativeCode(1),
                    //         context.getRelativeCode(2),
                    //         context.getRelativeCode(3),
                    //     ) ? 'id' : 'unrestricted',
                    // };
                    // Consume an ident sequence, and set the <hash-token>’s value to the returned string.
                    context.consumeCodePoint();
                    consumeIndentSequence(context);
                    // 4. Return the <hash-token>.
                    // TODO: Uncomment when needed
                    // context.onToken(TokenType.Hash, start, context.offset, props);
                    context.onToken(TokenType.Hash, start, context.offset);
                    break;
                }
                // Otherwise, return a <delim-token> with its value set to the current input code point.
                context.consumeTrivialToken(TokenType.Delim);
                break;
            case 43 /* CodePoint.PlusSign */:
                // If the input stream starts with a number, reconsume the current input code point, consume a
                // numeric token, and return it.
                if (checkForNumberStart(context.code, context.getRelativeCode(1), context.getRelativeCode(2))) {
                    consumeNumericToken(context);
                    break;
                }
                // Otherwise, return a <delim-token> with its value set to the current input code point.
                context.consumeTrivialToken(TokenType.Delim);
                break;
            case 45 /* CodePoint.HyphenMinus */:
                // If the input stream starts with a number, reconsume the current input code point, consume a
                // numeric token, and return it.
                if (checkForNumberStart(context.code, context.getRelativeCode(1), context.getRelativeCode(2))) {
                    consumeNumericToken(context);
                    break;
                }
                // Otherwise, if the next 2 input code points are U+002D HYPHEN-MINUS U+003E GREATER-THAN SIGN
                // (>), consume them and return a <CDC-token>.
                if (context.getRelativeCode(1) === 45 /* CodePoint.HyphenMinus */
                    && context.getRelativeCode(2) === 62 /* CodePoint.GreaterThanSign */) {
                    context.consumeCodePoint(3);
                    context.onToken(TokenType.Cdc, context.offset - 3, context.offset);
                    break;
                }
                // Otherwise, if the input stream starts with an ident sequence, reconsume the current input
                // code point, consume an ident-like token, and return it.
                if (checkForIdentStart(context.code, context.getRelativeCode(1), context.getRelativeCode(2))) {
                    consumeIdentLikeToken(context);
                    break;
                }
                // Otherwise, return a <delim-token> with its value set to the current input code point.
                context.consumeTrivialToken(TokenType.Delim);
                break;
            case 46 /* CodePoint.FullStop */:
                // If the input stream starts with a number, reconsume the current input code point, consume a
                // numeric token, and return it.
                if (checkForNumberStart(context.code, context.getRelativeCode(1), context.getRelativeCode(2))) {
                    consumeNumericToken(context);
                    break;
                }
                // Otherwise, return a <delim-token> with its value set to the current input code point.
                context.consumeTrivialToken(TokenType.Delim);
                break;
            case 60 /* CodePoint.LessThanSign */:
                // If the next 3 input code points are U+0021 EXCLAMATION MARK U+002D HYPHEN-MINUS U+002D
                // HYPHEN-MINUS (!--), consume them and return a <CDO-token>.
                if (context.getRelativeCode(1) === 33 /* CodePoint.ExclamationMark */
                    && context.getRelativeCode(2) === 45 /* CodePoint.HyphenMinus */
                    && context.getRelativeCode(3) === 45 /* CodePoint.HyphenMinus */) {
                    context.consumeCodePoint(4);
                    context.onToken(TokenType.Cdo, context.offset - 4, context.offset);
                    break;
                }
                // Otherwise, return a <delim-token> with its value set to the current input code point.
                context.consumeTrivialToken(TokenType.Delim);
                break;
            case 64 /* CodePoint.CommercialAt */:
                // If the next 3 input code points would start an ident sequence, consume an ident sequence,
                // create an <at-keyword-token> with its value set to the returned value, and return it.
                if (checkForIdentStart(context.getRelativeCode(1), context.getRelativeCode(2), context.getRelativeCode(3))) {
                    const start = context.offset;
                    // Consume commercial at character
                    context.consumeCodePoint();
                    // Consume ident sequence after commercial at character
                    consumeIndentSequence(context);
                    context.onToken(TokenType.AtKeyword, start, context.offset);
                    break;
                }
                // Otherwise, return a <delim-token> with its value set to the current input code point.
                context.consumeTrivialToken(TokenType.Delim);
                break;
            case 92 /* CodePoint.ReverseSolidus */:
                // If the input stream starts with a valid escape, reconsume the current input code point,
                // consume an ident-like token, and return it.
                if (checkForValidEscape(context.code, context.getRelativeCode(1))) {
                    consumeIdentLikeToken(context);
                    break;
                }
                // Otherwise, this is a parse error. Return a <delim-token> with its value set to the current
                // input code point.
                context.consumeTrivialToken(TokenType.Delim);
                context.onError("Invalid escape sequence." /* ErrorMessage.InvalidEscapeSequence */, context.offset - 1, context.offset);
                break;
            case 47 /* CodePoint.Solidus */:
                // If the next two input code point are U+002F SOLIDUS (/) followed by a U+002A ASTERISK (*),
                // If the preceding paragraph ended by consuming an EOF code point, this is a parse error.
                if (context.getRelativeCode(1) === 42 /* CodePoint.Asterisk */) {
                    const start = context.offset;
                    // Consume U+002F SOLIDUS (/) and U+002A ASTERISK (*)
                    context.consumeCodePoint(2);
                    // consume them and all following code points up to and including the first U+002A ASTERISK
                    // (*) followed by a U+002F SOLIDUS (/), or up to an EOF code point. Return to the start of
                    // this step.
                    context.consumeUntilCommentEnd();
                    if (context.isEof()) {
                        context.onError("Unterminated comment." /* ErrorMessage.UnterminatedComment */, start, context.length - 2);
                    }
                    context.onToken(TokenType.Comment, start, context.offset);
                    break;
                }
                // Otherwise, return a <delim-token> with its value set to the current input code point.
                context.consumeTrivialToken(TokenType.Delim);
                break;
            // anything else
            default:
                // Can't be optimized because of the control threshold
                if (isIdentStartCodePoint(context.code)) {
                    // Reconsume the current input code point, consume an ident-like token, and return it.
                    consumeIdentLikeToken(context);
                    break;
                }
                // Return a <delim-token> with its value set to the current input code point.
                context.consumeTrivialToken(TokenType.Delim);
        }
    }
};

/**
 * @file Custom tokenizing logic for Extended CSS's pseudo-classes
 */
/**
 * Generic handler for the Extended CSS's pseudo-classes
 *
 * @param context Reference to the tokenizer context instance
 */
const handleRegularExtendedCssPseudo = (context) => {
    // Save the current offset, because we will need it later
    const start = context.offset;
    // Consume as much whitespace as possible
    context.consumeWhitespace();
    // If the first non-whitespace code point is an apostrophe or a quotation mark, it means that we are dealing
    // with a string parameter.
    // In this case, we simply abort the custom handler here, and let the standard tokenizer handle the string and
    // everything that comes after it as specified in the spec.
    // This behavior is similar to the standard CSS's url() function, it is also handled differently if its parameter
    // is a string.
    if (context.code === 39 /* CodePoint.Apostrophe */ || context.code === 34 /* CodePoint.QuotationMark */) {
        // Report whitespace tokens (if any)
        // It is important to report them, because we already consumed them - and the report is faster here than
        // a re-consume
        if (context.offset > start) {
            context.onToken(TokenType.Whitespace, start, context.offset);
        }
        // We simply abort the custom handler
        return;
    }
    // Otherwise, we need to find the closing parenthesis based on the parenthesis balance
    // Parenthesis balance: 1, because we start after the opening parenthesis:
    // :contains(param)
    //           ^ we starts from here, so we already have 1 open parenthesis
    let balance = 1;
    // Don't forget to report already consumed whitespace chars as delim-tokens (if any)
    // Note: we handle the parameter characters as delim-tokens, this is why we don't need to report them here
    // as whitespace-tokens
    for (let i = start; i < context.offset; i += 1) {
        context.onToken(TokenType.Delim, i, i + 1);
    }
    // Consume until we find the closing parenthesis or we reach the end of the source
    while (!context.isEof()) {
        if (context.code === 40 /* CodePoint.LeftParenthesis */ && context.prevCode !== 92 /* CodePoint.ReverseSolidus */) {
            // If we find an unescaped opening parenthesis, we increase the balance
            balance += 1;
        }
        else if (context.code === 41 /* CodePoint.RightParenthesis */ && context.prevCode !== 92 /* CodePoint.ReverseSolidus */) {
            // If we find an unescaped closing parenthesis, we decrease the balance
            balance -= 1;
            // If the balance is 0, it means that we found the closing parenthesis
            if (balance === 0) {
                break;
            }
        }
        // Consume the current character as a delim-token
        context.consumeTrivialToken(TokenType.Delim);
    }
};

/**
 * @file Custom tokenizing logic for Extended CSS's `:xpath()` pseudo-class
 * @note `:xpath()` is a bit tricky, because it can contain unescaped parentheses inside strings in the XPath
 * expression.
 */
/**
 * Handler for the Extended CSS's `:xpath()` pseudo-class
 *
 * @param context Reference to the tokenizer context instance
 */
const handleXpathExtendedCssPseudo = (context) => {
    // Save the current offset, because we will need it later
    const start = context.offset;
    // Consume as much whitespace as possible
    context.consumeWhitespace();
    // If the first non-whitespace code point is an apostrophe or a quotation mark, it means that we are dealing
    // with a string parameter.
    // In this case, we simply abort the custom handler here, and let the standard tokenizer handle the string and
    // everything that comes after it as specified in the spec.
    // This behavior is similar to the standard CSS's url() function, it is also handled differently if its parameter
    // is a string.
    if (context.code === 39 /* CodePoint.Apostrophe */ || context.code === 34 /* CodePoint.QuotationMark */) {
        // Report whitespace tokens (if any)
        // It is important to report them, because we already consumed them - and the report is faster here than
        // a re-consume
        if (context.offset > start) {
            context.onToken(TokenType.Whitespace, start, context.offset);
        }
        // We simply abort the custom handler
        return;
    }
    // Otherwise, we need to find the closing parenthesis based on the parenthesis balance
    // Parenthesis balance: 1, because we start after the opening parenthesis:
    // :xpath(param)
    //        ^ we starts from here, so we already have 1 open parenthesis
    let balance = 1;
    // Don't forget to report already consumed whitespace chars as delim-tokens (if any)
    // Note: we handle the parameter characters as delim-tokens, this is why we don't need to report them here
    // as whitespace-tokens
    for (let i = start; i < context.offset; i += 1) {
        context.onToken(TokenType.Delim, i, i + 1);
    }
    // :xpath() is a bit tricky, because it can contain unescaped parentheses inside strings in the XPath expression,
    // like this:
    // :xpath(//div[@class="foo(bar)"])
    // but in this case, not required the whole XPath expression to be a string
    let inString = false;
    // Consume until we find the closing parenthesis or we reach the end of the source
    while (!context.isEof()) {
        // If we find an unescaped quote mark, we toggle the "inString" flag
        // It is important, because we should omit parentheses inside strings.
        if (context.code === 34 /* CodePoint.QuotationMark */ && context.prevCode !== 92 /* CodePoint.ReverseSolidus */) {
            inString = !inString;
        }
        // If we are not inside a string, we should check parentheses balance
        if (!inString) {
            if (context.code === 40 /* CodePoint.LeftParenthesis */ && context.prevCode !== 92 /* CodePoint.ReverseSolidus */) {
                // If we find an unescaped opening parenthesis, we increase the balance
                balance += 1;
            }
            else if (context.code === 41 /* CodePoint.RightParenthesis */ && context.prevCode !== 92 /* CodePoint.ReverseSolidus */) {
                // If we find an unescaped closing parenthesis, we decrease the balance
                balance -= 1;
                // If the balance is 0, it means that we found the closing parenthesis of the
                // pseudo-class
                if (balance === 0) {
                    break;
                }
            }
        }
        // Consume the current character as a delim-token
        context.consumeTrivialToken(TokenType.Delim);
    }
};

/**
 * @file Map utility functions
 */
/**
 * Simple utility function to merge two maps.
 *
 * @param map1 First map
 * @param map2 Second map
 * @returns Merged map
 * @note If a key is present in both maps, the value from the second map will be used
 * @note This function does not modify the original maps, it returns a new map
 */
function mergeMaps(map1, map2) {
    const result = new Map();
    for (const [key, value] of map1) {
        result.set(key, value);
    }
    for (const [key, value] of map2) {
        result.set(key, value);
    }
    return result;
}

/**
 * @file Extended CSS tokenizer that extends the core CSS tokenizer
 *
 * This library supports various Extended CSS language elements from
 * - AdGuard,
 * - uBlock Origin and
 * - Adblock Plus.
 *
 * @see {@link https://github.com/AdguardTeam/ExtendedCss}
 * @see {@link https://github.com/gorhill/uBlock/wiki/Procedural-cosmetic-filters}
 * @see {@link https://help.adblockplus.org/hc/en-us/articles/360062733293#elemhide-emulation}
 */
const ABP_CONTAINS_HASH = 1989084725; // getStringHash('-abp-contains')
const CONTAINS_HASH = 2399470598; // getStringHash('contains')
const HAS_TEXT_HASH = 1221663855; // getStringHash('has-text')
const MATCHES_CSS_HASH = 102304302; // getStringHash('matches-css')
const MATCHES_CSS_AFTER_HASH = 2923888231; // getStringHash('matches-css-after')
const MATCHES_CSS_BEFORE_HASH = 1739713050; // getStringHash('matches-css-before')
const MATCHES_PROPERTY_HASH = 1860790666; // getStringHash('matches-property')
const MATCHES_ATTR_HASH = 3376104318; // getStringHash('matches-attr')
const XPATH_HASH = 196571984; // getStringHash('xpath')
/**
 * Map of Extended CSS's pseudo-classes and their respective handler functions
 */
const EXT_CSS_PSEUDO_HANDLERS = new Map([
    // Note: alternatively, you can use `getStringHash` to get the hash of the pseudo-class name, but we use
    // pre-calculated hashes here for performance reasons
    [ABP_CONTAINS_HASH, handleRegularExtendedCssPseudo],
    [CONTAINS_HASH, handleRegularExtendedCssPseudo],
    [HAS_TEXT_HASH, handleRegularExtendedCssPseudo],
    [MATCHES_CSS_HASH, handleRegularExtendedCssPseudo],
    [MATCHES_CSS_AFTER_HASH, handleRegularExtendedCssPseudo],
    [MATCHES_CSS_BEFORE_HASH, handleRegularExtendedCssPseudo],
    [MATCHES_PROPERTY_HASH, handleRegularExtendedCssPseudo],
    [MATCHES_ATTR_HASH, handleRegularExtendedCssPseudo],
    [XPATH_HASH, handleXpathExtendedCssPseudo],
]);
/**
 * Extended CSS tokenizer function
 *
 * @param source Source code to tokenize
 * @param onToken Tokenizer callback which is called for each token found in source code
 * @param onError Error callback which is called when a parsing error is found (optional)
 * @param functionHandlers Custom function handlers (optional)
 * @note If you specify custom function handlers, they will be merged with the default function handlers. If you
 * duplicate a function handler, the custom one will be used instead of the default one, so you can override the default
 * function handlers this way, if you want to.
 */
function tokenizeExtended(source, onToken, onError = () => { }, functionHandlers = new Map()) {
    tokenize(source, onToken, onError, 
    // Register custom function handlers for Extended CSS's pseudo-classes, but do not call mergeMaps if there are
    // no custom function handlers are provided
    functionHandlers.size > 0
        ? mergeMaps(EXT_CSS_PSEUDO_HANDLERS, functionHandlers)
        : EXT_CSS_PSEUDO_HANDLERS);
}

/**
 * @file CSS identifier decoder.
 */
const EMPTY_STRING = '';
/**
 * Decodes a CSS identifier according to the CSS Syntax Module Level 3 specification.
 *
 * @param ident CSS identifier to decode.
 *
 * @example
 * ```ts
 * decodeIdent(String.raw`\00075\00072\0006C`); // 'url'
 * decodeIdent('url'); // 'url'
 * ```
 *
 * @returns Decoded CSS identifier.
 */
const decodeIdent = (ident) => {
    const decodedIdent = [];
    for (let i = 0; i < ident.length; i += 1) {
        const codePoint = ident.charCodeAt(i);
        // 4.3.7. Consume an escaped code point
        // https://www.w3.org/TR/css-syntax-3/#consume-an-escaped-code-point
        if (codePoint === 92 /* CodePoint.ReverseSolidus */) {
            // hex digit
            if (isHexDigit(ident.charCodeAt(i + 1))) {
                // Consume as many hex digits as possible, but no more than 5.
                // Note that this means 1-6 hex digits have been consumed in total.
                let n = 0;
                let j = 0; // consumed hex digits
                while (j < MAX_HEX_DIGITS && isHexDigit(ident.charCodeAt(i + j + 1))) {
                    // Interpret the hex digits as a hexadecimal number.
                    n = n * 16 + parseInt(ident[i + j + 1], 16);
                    j += 1;
                }
                decodedIdent.push(
                // If this number is zero, or is for a surrogate, or is greater than the maximum allowed code
                // point, return U+FFFD REPLACEMENT CHARACTER (�).
                // Otherwise, return the code point with that value.
                String.fromCodePoint(n === 0 || isSurrogate(n) || isGreaterThanMaxAllowedCodePoint(n)
                    ? 65533 /* CodePoint.ReplacementCharacter */
                    : n));
                i += j;
                // If the next input code point is whitespace, consume it as well.
                const nextCodePoint = ident.charCodeAt(i + 1);
                if (isWhitespace(nextCodePoint)) {
                    // Consume whitespace character
                    i += 1;
                    // Special case: consume +1 character if the sequence is CR LF
                    if (nextCodePoint === 13 /* CodePoint.CarriageReturn */ && ident.charCodeAt(i + 1) === 10 /* CodePoint.LineFeed */) {
                        i += 1;
                    }
                }
            }
            // do nothing for EOF
        }
        else {
            // anything else
            // Return the current input code point.
            decodedIdent.push(ident[i]);
        }
    }
    return decodedIdent.join(EMPTY_STRING);
};

const version = "1.1.1";

/**
 * @file Package version
 */
// ! Notice:
// Don't export version from package.json directly, because if you run `tsc` in the root directory, it will generate
// `dist/types/src/version.d.ts` with wrong relative path to `package.json`. So we need this little "hack"
const CSS_TOKENIZER_VERSION = (/* unused pure expression or super */ null && (version));




/***/ }),

/***/ 21289:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";

// EXPORTS
__webpack_require__.d(__webpack_exports__, {
  "r3": () => (/* binding */ contains)
});

// UNUSED EXPORTS: default, exclude, expand, isIP, merge, normalize, overlap, parse

;// CONCATENATED MODULE: ./node_modules/.pnpm/ip-regex@5.0.0/node_modules/ip-regex/index.js
const word = '[a-fA-F\\d:]';

const boundry = options => options && options.includeBoundaries
	? `(?:(?<=\\s|^)(?=${word})|(?<=${word})(?=\\s|$))`
	: '';

const v4 = '(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)(?:\\.(?:25[0-5]|2[0-4]\\d|1\\d\\d|[1-9]\\d|\\d)){3}';

const v6segment = '[a-fA-F\\d]{1,4}';

const v6 = `
(?:
(?:${v6segment}:){7}(?:${v6segment}|:)|                                    // 1:2:3:4:5:6:7::  1:2:3:4:5:6:7:8
(?:${v6segment}:){6}(?:${v4}|:${v6segment}|:)|                             // 1:2:3:4:5:6::    1:2:3:4:5:6::8   1:2:3:4:5:6::8  1:2:3:4:5:6::1.2.3.4
(?:${v6segment}:){5}(?::${v4}|(?::${v6segment}){1,2}|:)|                   // 1:2:3:4:5::      1:2:3:4:5::7:8   1:2:3:4:5::8    1:2:3:4:5::7:1.2.3.4
(?:${v6segment}:){4}(?:(?::${v6segment}){0,1}:${v4}|(?::${v6segment}){1,3}|:)| // 1:2:3:4::        1:2:3:4::6:7:8   1:2:3:4::8      1:2:3:4::6:7:1.2.3.4
(?:${v6segment}:){3}(?:(?::${v6segment}){0,2}:${v4}|(?::${v6segment}){1,4}|:)| // 1:2:3::          1:2:3::5:6:7:8   1:2:3::8        1:2:3::5:6:7:1.2.3.4
(?:${v6segment}:){2}(?:(?::${v6segment}){0,3}:${v4}|(?::${v6segment}){1,5}|:)| // 1:2::            1:2::4:5:6:7:8   1:2::8          1:2::4:5:6:7:1.2.3.4
(?:${v6segment}:){1}(?:(?::${v6segment}){0,4}:${v4}|(?::${v6segment}){1,6}|:)| // 1::              1::3:4:5:6:7:8   1::8            1::3:4:5:6:7:1.2.3.4
(?::(?:(?::${v6segment}){0,5}:${v4}|(?::${v6segment}){1,7}|:))             // ::2:3:4:5:6:7:8  ::2:3:4:5:6:7:8  ::8             ::1.2.3.4
)(?:%[0-9a-zA-Z]{1,})?                                             // %eth0            %1
`.replace(/\s*\/\/.*$/gm, '').replace(/\n/g, '').trim();

// Pre-compile only the exact regexes because adding a global flag make regexes stateful
const v46Exact = new RegExp(`(?:^${v4}$)|(?:^${v6}$)`);
const v4exact = new RegExp(`^${v4}$`);
const v6exact = new RegExp(`^${v6}$`);

const ipRegex = options => options && options.exact
	? v46Exact
	: new RegExp(`(?:${boundry(options)}${v4}${boundry(options)})|(?:${boundry(options)}${v6}${boundry(options)})`, 'g');

ipRegex.v4 = options => options && options.exact ? v4exact : new RegExp(`${boundry(options)}${v4}${boundry(options)}`, 'g');
ipRegex.v6 = options => options && options.exact ? v6exact : new RegExp(`${boundry(options)}${v6}${boundry(options)}`, 'g');

/* harmony default export */ const ip_regex = (ipRegex);

;// CONCATENATED MODULE: ./node_modules/.pnpm/cidr-regex@4.0.3/node_modules/cidr-regex/index.js


const defaultOpts = {exact: false};
const v4str = `${ip_regex.v4().source}\\/(3[0-2]|[12]?[0-9])`;
const v6str = `${ip_regex.v6().source}\\/(12[0-8]|1[01][0-9]|[1-9]?[0-9])`;

// pre-compile only the exact regexes as global flag makes regex objects stateful
const cidr_regex_v4exact = new RegExp(`^${v4str}$`);
const cidr_regex_v6exact = new RegExp(`^${v6str}$`);
const v46exact = new RegExp(`(?:^${v4str}$)|(?:^${v6str}$)`);

const cidrRegex = ({exact} = defaultOpts) => exact ? v46exact : new RegExp(`(?:${v4str})|(?:${v6str})`, "g");
const cidr_regex_v4 = cidrRegex.v4 = ({exact} = defaultOpts) => exact ? cidr_regex_v4exact : new RegExp(v4str, "g");
const cidr_regex_v6 = cidrRegex.v6 = ({exact} = defaultOpts) => exact ? cidr_regex_v6exact : new RegExp(v6str, "g");
/* harmony default export */ const cidr_regex = (cidrRegex);

// EXTERNAL MODULE: ./node_modules/.pnpm/string-natural-compare@3.0.1/node_modules/string-natural-compare/natural-compare.js
var natural_compare = __webpack_require__(86730);
;// CONCATENATED MODULE: ./node_modules/.pnpm/ip-bigint@7.2.1/node_modules/ip-bigint/index.js
const max4 = 2n ** 32n - 1n;
const max6 = 2n ** 128n - 1n;

function parseIp(ip) {
  const version = ip.includes(":") ? 6 : ip.includes(".") ? 4 : 0;
  if (!version) throw new Error(`Invalid IP address: ${ip}`);

  let number = 0n;
  let exp = 0n;
  const res = Object.create(null);

  if (version === 4) {
    for (const n of ip.split(".").map(BigInt).reverse()) {
      number += n * (2n ** exp);
      exp += 8n;
    }
  } else {
    if (ip.includes(".")) {
      res.ipv4mapped = true;
      ip = ip.split(":").map(part => {
        if (part.includes(".")) {
          const digits = part.split(".").map(str => Number(str).toString(16).padStart(2, "0"));
          return `${digits[0]}${digits[1]}:${digits[2]}${digits[3]}`;
        } else {
          return part;
        }
      }).join(":");
    }

    if (ip.includes("%")) {
      let scopeid;
      [, ip, scopeid] = /(.+)%(.+)/.exec(ip);
      res.scopeid = scopeid;
    }

    const parts = ip.split(":");
    const index = parts.indexOf("");

    if (index !== -1) {
      while (parts.length < 8) {
        parts.splice(index, 0, "");
      }
    }

    for (const n of parts.map(part => BigInt(parseInt(part || 0, 16))).reverse()) {
      number += n * (2n ** exp);
      exp += 16n;
    }
  }

  res.number = number;
  res.version = version;
  return res;
}

function stringifyIp({number, version, ipv4mapped, scopeid} = {}, {compress = true, hexify = false} = {}) {
  if (typeof number !== "bigint") throw new Error(`Expected a BigInt`);
  if (![4, 6].includes(version)) throw new Error(`Invalid version: ${version}`);
  if (number < 0n || number > (version === 4 ? max4 : max6)) throw new Error(`Invalid number: ${number}`);

  let step = version === 4 ? 24n : 112n;
  const stepReduction = version === 4 ? 8n : 16n;
  let remain = number;
  const parts = [];

  while (step > 0n) {
    const divisor = 2n ** step;
    parts.push(remain / divisor);
    remain = number % divisor;
    step -= stepReduction;
  }
  parts.push(remain);

  if (version === 4) {
    return parts.join(".");
  } else {
    let ip = "";
    if (ipv4mapped && !hexify) {
      for (const [index, num] of parts.entries()) {
        if (index < 6) {
          ip += `${num.toString(16)}:`;
        } else {
          ip += `${String(num >> 8n)}.${String(num & 255n)}${index === 6 ? "." : ""}`;
        }
      }
      if (compress) {
        ip = compressIPv6(ip.split(":"));
      }
    } else {
      if (compress) {
        ip = compressIPv6(parts.map(n => n.toString(16)));
      } else {
        ip = parts.map(n => n.toString(16)).join(":");
      }
    }

    if (scopeid) {
      ip = `${ip}%${scopeid}`;
    }

    return ip;
  }
}

function normalizeIp(ip, {compress = true, hexify = false} = {}) {
  return stringifyIp(parseIp(ip), {compress, hexify});
}

// take the longest or first sequence of "0" segments and replace it with "::"
function compressIPv6(parts) {
  let longest, current;
  for (const [index, part] of parts.entries()) {
    if (part === "0") {
      if (!current) {
        current = new Set([index]);
      } else {
        current.add(index);
      }
    } else {
      if (current) {
        if (!longest) {
          longest = current;
        } else if (current.size > longest.size) {
          longest = current;
        }
        current = null;
      }
    }
  }
  if ((!longest && current) || (current && current.size > longest.size)) {
    longest = current;
  }

  for (const index of longest || []) {
    parts[index] = ":";
  }

  return parts.filter(Boolean).join(":").replace(/:{2,}/, "::");
}

;// CONCATENATED MODULE: ./node_modules/.pnpm/cidr-tools@6.4.1/node_modules/cidr-tools/index.js





const bits = {
  "v4": 32,
  "v6": 128,
};

const uniq = arr => Array.from(new Set(arr));

function isIP(ip) {
  if (ip_regex.v4({exact: true}).test(ip)) return 4;
  if (ip_regex.v6({exact: true}).test(ip)) return 6;
  return 0;
}

function isCidr(ip) {
  if (cidr_regex.v4({exact: true}).test(ip)) return 4;
  if (cidr_regex.v6({exact: true}).test(ip)) return 6;
  return 0;
}

function doNormalize(cidr, {compress = true, hexify = false} = {}) {
  const {start, prefix, single, version} = parse(cidr);
  if (!single) { // cidr
    // set network address to first address
    const ip = normalizeIp(stringifyIp({number: start, version}), {compress, hexify});
    return `${ip}/${prefix}`;
  } else { // single ip
    return normalizeIp(cidr, {compress, hexify});
  }
}

function normalize(cidr, {compress = true, hexify = false} = {}) {
  if (Array.isArray(cidr)) {
    return cidr.map(entry => normalize(entry, {compress, hexify}));
  } else {
    return doNormalize(cidr, {compress, hexify});
  }
}

function parse(str) {
  const cidrVersion = isCidr(str);
  const parsed = Object.create(null);
  parsed.single = false;

  if (cidrVersion) {
    parsed.cidr = str;
    parsed.version = cidrVersion;
  } else {
    const version = isIP(str);
    if (version) {
      parsed.cidr = `${str}/${bits[`v${version}`]}`;
      parsed.version = version;
      parsed.single = true;
    } else {
      throw new Error(`Network is not a CIDR or IP: ${str}`);
    }
  }

  const [ip, prefix] = parsed.cidr.split("/");
  parsed.prefix = prefix;
  const {number, version} = parseIp(ip);
  const numBits = bits[`v${version}`];
  const ipBits = number.toString(2).padStart(numBits, "0");
  const prefixLen = Number(numBits - prefix);
  const startBits = ipBits.substring(0, numBits - prefixLen);
  parsed.start = BigInt(`0b${startBits}${"0".repeat(prefixLen)}`);
  parsed.end = BigInt(`0b${startBits}${"1".repeat(prefixLen)}`);
  return parsed;
}

// returns whether networks fully or partially overlap
function doNetsOverlap(a, b) {
  //    aaa
  // bbb
  if (a.start > b.end) return false; // a starts after b

  // aaa
  //    bbb
  if (b.start > a.end) return false; // b starts after a

  return true;
}

// returns whether network a fully contains network b;
function netContains(a, b) {
  //  aaa
  // bbbb
  if (b.start < a.start) return false; // a starts after b

  // aaa
  // bbbb
  if (b.end > a.end) return false; // b starts after a

  return true;
}

// exclude b from a and return remainder cidrs
function excludeNets(a, b, v) {
  const parts = [];

  // compareTo returns negative if left is less than right

  //       aaa
  //   bbb
  //   aaa
  //       bbb
  if (a.start > b.end || a.end < b.start) {
    return [a.cidr];
  }

  //   aaa
  //   bbb
  if (a.start === b.start && a.end === b.end) {
    return [];
  }

  //   aa
  //  bbbb
  if (a.start > b.start && a.end < b.end) {
    return [];
  }

  // aaaa
  //   bbbb
  // aaaa
  //   bb
  if (a.start < b.start && a.end <= b.end) {
    parts.push({start: a.start, end: b.start - 1n});
  }

  //    aaa
  //   bbb
  //   aaaa
  //   bbb
  if (a.start >= b.start && a.end > b.end) {
    parts.push({start: b.end + 1n, end: a.end});
  }

  //  aaaa
  //   bb
  if (a.start < b.start && a.end > b.end) {
    parts.push(
      {start: a.start, end: b.start - 1n},
      {start: b.end + 1n, end: a.end},
    );
  }

  const remaining = [];
  for (const part of parts) {
    for (const subpart of subparts(part)) {
      remaining.push(formatPart(subpart, v));
    }
  }

  return merge(remaining);
}

function biggestPowerOfTwo(num) {
  if (num === 0n) return 0n;
  return 2n ** BigInt(String(num.toString(2).length - 1));
}

function subparts(part) {
  // special case for when part is length 1
  if ((part.end - part.start) === 1n) {
    if (part.end % 2n === 0n) {
      return [{start: part.start, end: part.start}, {start: part.end, end: part.end}];
    } else {
      return [{start: part.start, end: part.end}];
    }
  }

  const size = diff(part.end, part.start);
  let biggest = biggestPowerOfTwo(size);

  let start, end;
  if (size === biggest && part.start + size === part.end) {
    return [part];
  } else if (part.start % biggest === 0n) {
    // start is matching on the size-defined boundary - ex: 0-12, use 0-8
    start = part.start;
    end = start + biggest - 1n;
  } else {
    start = (part.end / biggest) * biggest;

    // start is not matching on the size-defined boundary - 4-16, use 8-16
    if ((start + biggest - 1n) > part.end) {
      // divide will floor to nearest integer
      start = ((part.end / biggest) - 1n) * biggest;

      while (start < part.start) {
        biggest /= 2n;
        start = ((part.end / biggest) - 1n) * biggest;
      }

      end = start + biggest - 1n;
    } else {
      start = (part.end / biggest) * biggest;
      end = start + biggest - 1n;
    }
  }

  let parts = [{start, end}];

  // additional subnets on left side
  if (start !== part.start) {
    parts = parts.concat(subparts({start: part.start, end: start - 1n}));
  }

  // additional subnets on right side
  if (end !== part.end) {
    parts = parts.concat(subparts({start: end + 1n, end: part.end}));
  }

  return parts;
}

function diff(a, b) {
  if (typeof a !== "bigint") a = BigInt(a);
  if (typeof b !== "bigint") b = BigInt(b);
  a += 1n;
  return a - b;
}

function formatPart(part, v) {
  const ip = normalize(stringifyIp({
    number: BigInt(part.start.toString()),
    version: Number(v.substring(1)),
  }));
  const zeroes = diff(part.end, part.start).toString(2);
  const prefix = bits[v] - (zeroes.match(/0/g) || []).length;
  return `${ip}/${prefix}`;
}

function mapNets(nets) {
  const maps = {v4: {}, v6: {}};
  for (const {start, end, version} of nets) {
    const v = `v${version}`;

    if (!maps[v][start]) maps[v][start] = {};
    if (!maps[v][end]) maps[v][end] = {};

    if (maps[v][start].start) {
      maps[v][start].start += 1;
    } else {
      maps[v][start].start = 1;
    }

    if (maps[v][end].end) {
      maps[v][end].end += 1;
    } else {
      maps[v][end].end = 1;
    }
  }
  return maps;
}

function merge(nets) {
  nets = uniq((Array.isArray(nets) ? nets : [nets]).map(parse));
  const maps = mapNets(nets);

  const merged = {v4: [], v6: []};
  const start = {v4: null, v6: null};
  const end = {v4: null, v6: null};

  for (const v of ["v4", "v6"]) {
    const numbers = Object.keys(maps[v]).sort(natural_compare);
    let depth = 0;

    for (const [index, number] of numbers.entries()) {
      const marker = maps[v][number];

      if (start[v] === null && marker.start) {
        start[v] = BigInt(number);
      }
      if (marker.end) {
        end[v] = BigInt(number);
      }

      if (marker.start) depth += marker.start;
      if (marker.end) depth -= marker.end;

      if (marker.end && depth === 0 && ((numbers[index + 1] - numbers[index]) > 1)) {
        for (const sub of subparts({start: start[v], end: end[v]})) {
          merged[v].push(formatPart(sub, v));
        }
        start[v] = null;
        end[v] = null;
      } else if (index === (numbers.length - 1)) {
        for (const sub of subparts({start: start[v], end: end[v]})) {
          merged[v].push(formatPart(sub, v));
        }
      }
    }
  }

  return [...merged.v4.sort(natural_compare), ...merged.v6.sort(natural_compare)];
}

function exclude(basenets, exclnets) {
  basenets = uniq(Array.isArray(basenets) ? basenets : [basenets]);
  exclnets = uniq(Array.isArray(exclnets) ? exclnets : [exclnets]);

  basenets = merge(basenets);
  exclnets = merge(exclnets);

  const bases = {v4: [], v6: []};
  const excls = {v4: [], v6: []};

  for (const basenet of basenets) {
    bases[`v${isCidr(basenet)}`].push(basenet);
  }

  for (const exclnet of exclnets) {
    excls[`v${isCidr(exclnet)}`].push(exclnet);
  }

  for (const v of ["v4", "v6"]) {
    for (const exclcidr of excls[v]) {
      for (const [index, basecidr] of bases[v].entries()) {
        const base = parse(basecidr);
        const excl = parse(exclcidr);
        const remainders = excludeNets(base, excl, v);
        if (base.cidr !== remainders.toString()) {
          bases[v] = bases[v].concat(remainders);
          bases[v].splice(index, 1);
        }
      }
    }
  }

  return bases.v4.concat(bases.v6);
}

function expand(nets) {
  nets = uniq(Array.isArray(nets) ? nets : [nets]);

  const ips = [];
  for (const net of merge(nets)) {
    const {start, end, version} = parse(net);
    for (let number = start; number <= end; number++) {
      ips.push(stringifyIp({number, version}));
    }
  }
  return ips.map(normalize);
}

function overlap(a, b) {
  const aNets = uniq(Array.isArray(a) ? a : [a]);
  const bNets = uniq(Array.isArray(b) ? b : [b]);

  for (const a of aNets) {
    const aParsed = parse(a);
    for (const b of bNets) {
      const bParsed = parse(b);

      // version mismatch
      if (aParsed.version !== bParsed.version) {
        continue;
      }

      if (doNetsOverlap(aParsed, bParsed)) {
        return true;
      }
    }
  }

  return false;
}

function contains(a, b) {
  const aNets = uniq(Array.isArray(a) ? a : [a]);
  const bNets = uniq(Array.isArray(b) ? b : [b]);

  const numExpected = bNets.length;
  let numFound = 0;
  for (const a of aNets) {
    const aParsed = parse(a);
    for (const b of bNets) {
      const bParsed = parse(b);

      // version mismatch
      if (aParsed.version !== bParsed.version) {
        continue;
      }

      if (netContains(aParsed, bParsed)) {
        numFound++;
        continue;
      }
    }
  }

  return numFound === numExpected;
}

/* harmony default export */ const cidr_tools = ({
  merge,
  exclude,
  expand,
  overlap,
  contains,
  normalize,
  parse,
});


/***/ }),

/***/ 44945:
/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => {

"use strict";
/* harmony export */ __webpack_require__.d(__webpack_exports__, {
/* harmony export */   "ZP": () => (/* binding */ z),
/* harmony export */   "z": () => (/* binding */ z)
/* harmony export */ });
/* unused harmony exports BRAND, DIRTY, EMPTY_PATH, INVALID, NEVER, OK, ParseStatus, Schema, ZodAny, ZodArray, ZodBigInt, ZodBoolean, ZodBranded, ZodCatch, ZodDate, ZodDefault, ZodDiscriminatedUnion, ZodEffects, ZodEnum, ZodError, ZodFirstPartyTypeKind, ZodFunction, ZodIntersection, ZodIssueCode, ZodLazy, ZodLiteral, ZodMap, ZodNaN, ZodNativeEnum, ZodNever, ZodNull, ZodNullable, ZodNumber, ZodObject, ZodOptional, ZodParsedType, ZodPipeline, ZodPromise, ZodRecord, ZodSchema, ZodSet, ZodString, ZodSymbol, ZodTransformer, ZodTuple, ZodType, ZodUndefined, ZodUnion, ZodUnknown, ZodVoid, addIssueToContext, any, array, bigint, boolean, coerce, custom, date, defaultErrorMap, discriminatedUnion, effect, enum, function, getErrorMap, getParsedType, instanceof, intersection, isAborted, isAsync, isDirty, isValid, late, lazy, literal, makeIssue, map, nan, nativeEnum, never, null, nullable, number, object, objectUtil, oboolean, onumber, optional, ostring, pipeline, preprocess, promise, quotelessJson, record, set, setErrorMap, strictObject, string, symbol, transformer, tuple, undefined, union, unknown, util, void */
var util;
(function (util) {
    util.assertEqual = (val) => val;
    function assertIs(_arg) { }
    util.assertIs = assertIs;
    function assertNever(_x) {
        throw new Error();
    }
    util.assertNever = assertNever;
    util.arrayToEnum = (items) => {
        const obj = {};
        for (const item of items) {
            obj[item] = item;
        }
        return obj;
    };
    util.getValidEnumValues = (obj) => {
        const validKeys = util.objectKeys(obj).filter((k) => typeof obj[obj[k]] !== "number");
        const filtered = {};
        for (const k of validKeys) {
            filtered[k] = obj[k];
        }
        return util.objectValues(filtered);
    };
    util.objectValues = (obj) => {
        return util.objectKeys(obj).map(function (e) {
            return obj[e];
        });
    };
    util.objectKeys = typeof Object.keys === "function" // eslint-disable-line ban/ban
        ? (obj) => Object.keys(obj) // eslint-disable-line ban/ban
        : (object) => {
            const keys = [];
            for (const key in object) {
                if (Object.prototype.hasOwnProperty.call(object, key)) {
                    keys.push(key);
                }
            }
            return keys;
        };
    util.find = (arr, checker) => {
        for (const item of arr) {
            if (checker(item))
                return item;
        }
        return undefined;
    };
    util.isInteger = typeof Number.isInteger === "function"
        ? (val) => Number.isInteger(val) // eslint-disable-line ban/ban
        : (val) => typeof val === "number" && isFinite(val) && Math.floor(val) === val;
    function joinValues(array, separator = " | ") {
        return array
            .map((val) => (typeof val === "string" ? `'${val}'` : val))
            .join(separator);
    }
    util.joinValues = joinValues;
    util.jsonStringifyReplacer = (_, value) => {
        if (typeof value === "bigint") {
            return value.toString();
        }
        return value;
    };
})(util || (util = {}));
var objectUtil;
(function (objectUtil) {
    objectUtil.mergeShapes = (first, second) => {
        return {
            ...first,
            ...second, // second overwrites first
        };
    };
})(objectUtil || (objectUtil = {}));
const ZodParsedType = util.arrayToEnum([
    "string",
    "nan",
    "number",
    "integer",
    "float",
    "boolean",
    "date",
    "bigint",
    "symbol",
    "function",
    "undefined",
    "null",
    "array",
    "object",
    "unknown",
    "promise",
    "void",
    "never",
    "map",
    "set",
]);
const getParsedType = (data) => {
    const t = typeof data;
    switch (t) {
        case "undefined":
            return ZodParsedType.undefined;
        case "string":
            return ZodParsedType.string;
        case "number":
            return isNaN(data) ? ZodParsedType.nan : ZodParsedType.number;
        case "boolean":
            return ZodParsedType.boolean;
        case "function":
            return ZodParsedType.function;
        case "bigint":
            return ZodParsedType.bigint;
        case "symbol":
            return ZodParsedType.symbol;
        case "object":
            if (Array.isArray(data)) {
                return ZodParsedType.array;
            }
            if (data === null) {
                return ZodParsedType.null;
            }
            if (data.then &&
                typeof data.then === "function" &&
                data.catch &&
                typeof data.catch === "function") {
                return ZodParsedType.promise;
            }
            if (typeof Map !== "undefined" && data instanceof Map) {
                return ZodParsedType.map;
            }
            if (typeof Set !== "undefined" && data instanceof Set) {
                return ZodParsedType.set;
            }
            if (typeof Date !== "undefined" && data instanceof Date) {
                return ZodParsedType.date;
            }
            return ZodParsedType.object;
        default:
            return ZodParsedType.unknown;
    }
};

const ZodIssueCode = util.arrayToEnum([
    "invalid_type",
    "invalid_literal",
    "custom",
    "invalid_union",
    "invalid_union_discriminator",
    "invalid_enum_value",
    "unrecognized_keys",
    "invalid_arguments",
    "invalid_return_type",
    "invalid_date",
    "invalid_string",
    "too_small",
    "too_big",
    "invalid_intersection_types",
    "not_multiple_of",
    "not_finite",
]);
const quotelessJson = (obj) => {
    const json = JSON.stringify(obj, null, 2);
    return json.replace(/"([^"]+)":/g, "$1:");
};
class ZodError extends Error {
    constructor(issues) {
        super();
        this.issues = [];
        this.addIssue = (sub) => {
            this.issues = [...this.issues, sub];
        };
        this.addIssues = (subs = []) => {
            this.issues = [...this.issues, ...subs];
        };
        const actualProto = new.target.prototype;
        if (Object.setPrototypeOf) {
            // eslint-disable-next-line ban/ban
            Object.setPrototypeOf(this, actualProto);
        }
        else {
            this.__proto__ = actualProto;
        }
        this.name = "ZodError";
        this.issues = issues;
    }
    get errors() {
        return this.issues;
    }
    format(_mapper) {
        const mapper = _mapper ||
            function (issue) {
                return issue.message;
            };
        const fieldErrors = { _errors: [] };
        const processError = (error) => {
            for (const issue of error.issues) {
                if (issue.code === "invalid_union") {
                    issue.unionErrors.map(processError);
                }
                else if (issue.code === "invalid_return_type") {
                    processError(issue.returnTypeError);
                }
                else if (issue.code === "invalid_arguments") {
                    processError(issue.argumentsError);
                }
                else if (issue.path.length === 0) {
                    fieldErrors._errors.push(mapper(issue));
                }
                else {
                    let curr = fieldErrors;
                    let i = 0;
                    while (i < issue.path.length) {
                        const el = issue.path[i];
                        const terminal = i === issue.path.length - 1;
                        if (!terminal) {
                            curr[el] = curr[el] || { _errors: [] };
                            // if (typeof el === "string") {
                            //   curr[el] = curr[el] || { _errors: [] };
                            // } else if (typeof el === "number") {
                            //   const errorArray: any = [];
                            //   errorArray._errors = [];
                            //   curr[el] = curr[el] || errorArray;
                            // }
                        }
                        else {
                            curr[el] = curr[el] || { _errors: [] };
                            curr[el]._errors.push(mapper(issue));
                        }
                        curr = curr[el];
                        i++;
                    }
                }
            }
        };
        processError(this);
        return fieldErrors;
    }
    toString() {
        return this.message;
    }
    get message() {
        return JSON.stringify(this.issues, util.jsonStringifyReplacer, 2);
    }
    get isEmpty() {
        return this.issues.length === 0;
    }
    flatten(mapper = (issue) => issue.message) {
        const fieldErrors = {};
        const formErrors = [];
        for (const sub of this.issues) {
            if (sub.path.length > 0) {
                fieldErrors[sub.path[0]] = fieldErrors[sub.path[0]] || [];
                fieldErrors[sub.path[0]].push(mapper(sub));
            }
            else {
                formErrors.push(mapper(sub));
            }
        }
        return { formErrors, fieldErrors };
    }
    get formErrors() {
        return this.flatten();
    }
}
ZodError.create = (issues) => {
    const error = new ZodError(issues);
    return error;
};

const errorMap = (issue, _ctx) => {
    let message;
    switch (issue.code) {
        case ZodIssueCode.invalid_type:
            if (issue.received === ZodParsedType.undefined) {
                message = "Required";
            }
            else {
                message = `Expected ${issue.expected}, received ${issue.received}`;
            }
            break;
        case ZodIssueCode.invalid_literal:
            message = `Invalid literal value, expected ${JSON.stringify(issue.expected, util.jsonStringifyReplacer)}`;
            break;
        case ZodIssueCode.unrecognized_keys:
            message = `Unrecognized key(s) in object: ${util.joinValues(issue.keys, ", ")}`;
            break;
        case ZodIssueCode.invalid_union:
            message = `Invalid input`;
            break;
        case ZodIssueCode.invalid_union_discriminator:
            message = `Invalid discriminator value. Expected ${util.joinValues(issue.options)}`;
            break;
        case ZodIssueCode.invalid_enum_value:
            message = `Invalid enum value. Expected ${util.joinValues(issue.options)}, received '${issue.received}'`;
            break;
        case ZodIssueCode.invalid_arguments:
            message = `Invalid function arguments`;
            break;
        case ZodIssueCode.invalid_return_type:
            message = `Invalid function return type`;
            break;
        case ZodIssueCode.invalid_date:
            message = `Invalid date`;
            break;
        case ZodIssueCode.invalid_string:
            if (typeof issue.validation === "object") {
                if ("includes" in issue.validation) {
                    message = `Invalid input: must include "${issue.validation.includes}"`;
                    if (typeof issue.validation.position === "number") {
                        message = `${message} at one or more positions greater than or equal to ${issue.validation.position}`;
                    }
                }
                else if ("startsWith" in issue.validation) {
                    message = `Invalid input: must start with "${issue.validation.startsWith}"`;
                }
                else if ("endsWith" in issue.validation) {
                    message = `Invalid input: must end with "${issue.validation.endsWith}"`;
                }
                else {
                    util.assertNever(issue.validation);
                }
            }
            else if (issue.validation !== "regex") {
                message = `Invalid ${issue.validation}`;
            }
            else {
                message = "Invalid";
            }
            break;
        case ZodIssueCode.too_small:
            if (issue.type === "array")
                message = `Array must contain ${issue.exact ? "exactly" : issue.inclusive ? `at least` : `more than`} ${issue.minimum} element(s)`;
            else if (issue.type === "string")
                message = `String must contain ${issue.exact ? "exactly" : issue.inclusive ? `at least` : `over`} ${issue.minimum} character(s)`;
            else if (issue.type === "number")
                message = `Number must be ${issue.exact
                    ? `exactly equal to `
                    : issue.inclusive
                        ? `greater than or equal to `
                        : `greater than `}${issue.minimum}`;
            else if (issue.type === "date")
                message = `Date must be ${issue.exact
                    ? `exactly equal to `
                    : issue.inclusive
                        ? `greater than or equal to `
                        : `greater than `}${new Date(Number(issue.minimum))}`;
            else
                message = "Invalid input";
            break;
        case ZodIssueCode.too_big:
            if (issue.type === "array")
                message = `Array must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `less than`} ${issue.maximum} element(s)`;
            else if (issue.type === "string")
                message = `String must contain ${issue.exact ? `exactly` : issue.inclusive ? `at most` : `under`} ${issue.maximum} character(s)`;
            else if (issue.type === "number")
                message = `Number must be ${issue.exact
                    ? `exactly`
                    : issue.inclusive
                        ? `less than or equal to`
                        : `less than`} ${issue.maximum}`;
            else if (issue.type === "bigint")
                message = `BigInt must be ${issue.exact
                    ? `exactly`
                    : issue.inclusive
                        ? `less than or equal to`
                        : `less than`} ${issue.maximum}`;
            else if (issue.type === "date")
                message = `Date must be ${issue.exact
                    ? `exactly`
                    : issue.inclusive
                        ? `smaller than or equal to`
                        : `smaller than`} ${new Date(Number(issue.maximum))}`;
            else
                message = "Invalid input";
            break;
        case ZodIssueCode.custom:
            message = `Invalid input`;
            break;
        case ZodIssueCode.invalid_intersection_types:
            message = `Intersection results could not be merged`;
            break;
        case ZodIssueCode.not_multiple_of:
            message = `Number must be a multiple of ${issue.multipleOf}`;
            break;
        case ZodIssueCode.not_finite:
            message = "Number must be finite";
            break;
        default:
            message = _ctx.defaultError;
            util.assertNever(issue);
    }
    return { message };
};

let overrideErrorMap = errorMap;
function setErrorMap(map) {
    overrideErrorMap = map;
}
function getErrorMap() {
    return overrideErrorMap;
}

const makeIssue = (params) => {
    const { data, path, errorMaps, issueData } = params;
    const fullPath = [...path, ...(issueData.path || [])];
    const fullIssue = {
        ...issueData,
        path: fullPath,
    };
    let errorMessage = "";
    const maps = errorMaps
        .filter((m) => !!m)
        .slice()
        .reverse();
    for (const map of maps) {
        errorMessage = map(fullIssue, { data, defaultError: errorMessage }).message;
    }
    return {
        ...issueData,
        path: fullPath,
        message: issueData.message || errorMessage,
    };
};
const EMPTY_PATH = [];
function addIssueToContext(ctx, issueData) {
    const issue = makeIssue({
        issueData: issueData,
        data: ctx.data,
        path: ctx.path,
        errorMaps: [
            ctx.common.contextualErrorMap,
            ctx.schemaErrorMap,
            getErrorMap(),
            errorMap, // then global default map
        ].filter((x) => !!x),
    });
    ctx.common.issues.push(issue);
}
class ParseStatus {
    constructor() {
        this.value = "valid";
    }
    dirty() {
        if (this.value === "valid")
            this.value = "dirty";
    }
    abort() {
        if (this.value !== "aborted")
            this.value = "aborted";
    }
    static mergeArray(status, results) {
        const arrayValue = [];
        for (const s of results) {
            if (s.status === "aborted")
                return INVALID;
            if (s.status === "dirty")
                status.dirty();
            arrayValue.push(s.value);
        }
        return { status: status.value, value: arrayValue };
    }
    static async mergeObjectAsync(status, pairs) {
        const syncPairs = [];
        for (const pair of pairs) {
            syncPairs.push({
                key: await pair.key,
                value: await pair.value,
            });
        }
        return ParseStatus.mergeObjectSync(status, syncPairs);
    }
    static mergeObjectSync(status, pairs) {
        const finalObject = {};
        for (const pair of pairs) {
            const { key, value } = pair;
            if (key.status === "aborted")
                return INVALID;
            if (value.status === "aborted")
                return INVALID;
            if (key.status === "dirty")
                status.dirty();
            if (value.status === "dirty")
                status.dirty();
            if (typeof value.value !== "undefined" || pair.alwaysSet) {
                finalObject[key.value] = value.value;
            }
        }
        return { status: status.value, value: finalObject };
    }
}
const INVALID = Object.freeze({
    status: "aborted",
});
const DIRTY = (value) => ({ status: "dirty", value });
const OK = (value) => ({ status: "valid", value });
const isAborted = (x) => x.status === "aborted";
const isDirty = (x) => x.status === "dirty";
const isValid = (x) => x.status === "valid";
const isAsync = (x) => typeof Promise !== "undefined" && x instanceof Promise;

var errorUtil;
(function (errorUtil) {
    errorUtil.errToObj = (message) => typeof message === "string" ? { message } : message || {};
    errorUtil.toString = (message) => typeof message === "string" ? message : message === null || message === void 0 ? void 0 : message.message;
})(errorUtil || (errorUtil = {}));

class ParseInputLazyPath {
    constructor(parent, value, path, key) {
        this._cachedPath = [];
        this.parent = parent;
        this.data = value;
        this._path = path;
        this._key = key;
    }
    get path() {
        if (!this._cachedPath.length) {
            if (this._key instanceof Array) {
                this._cachedPath.push(...this._path, ...this._key);
            }
            else {
                this._cachedPath.push(...this._path, this._key);
            }
        }
        return this._cachedPath;
    }
}
const handleResult = (ctx, result) => {
    if (isValid(result)) {
        return { success: true, data: result.value };
    }
    else {
        if (!ctx.common.issues.length) {
            throw new Error("Validation failed but no issues detected.");
        }
        return {
            success: false,
            get error() {
                if (this._error)
                    return this._error;
                const error = new ZodError(ctx.common.issues);
                this._error = error;
                return this._error;
            },
        };
    }
};
function processCreateParams(params) {
    if (!params)
        return {};
    const { errorMap, invalid_type_error, required_error, description } = params;
    if (errorMap && (invalid_type_error || required_error)) {
        throw new Error(`Can't use "invalid_type_error" or "required_error" in conjunction with custom error map.`);
    }
    if (errorMap)
        return { errorMap: errorMap, description };
    const customMap = (iss, ctx) => {
        if (iss.code !== "invalid_type")
            return { message: ctx.defaultError };
        if (typeof ctx.data === "undefined") {
            return { message: required_error !== null && required_error !== void 0 ? required_error : ctx.defaultError };
        }
        return { message: invalid_type_error !== null && invalid_type_error !== void 0 ? invalid_type_error : ctx.defaultError };
    };
    return { errorMap: customMap, description };
}
class ZodType {
    constructor(def) {
        /** Alias of safeParseAsync */
        this.spa = this.safeParseAsync;
        this._def = def;
        this.parse = this.parse.bind(this);
        this.safeParse = this.safeParse.bind(this);
        this.parseAsync = this.parseAsync.bind(this);
        this.safeParseAsync = this.safeParseAsync.bind(this);
        this.spa = this.spa.bind(this);
        this.refine = this.refine.bind(this);
        this.refinement = this.refinement.bind(this);
        this.superRefine = this.superRefine.bind(this);
        this.optional = this.optional.bind(this);
        this.nullable = this.nullable.bind(this);
        this.nullish = this.nullish.bind(this);
        this.array = this.array.bind(this);
        this.promise = this.promise.bind(this);
        this.or = this.or.bind(this);
        this.and = this.and.bind(this);
        this.transform = this.transform.bind(this);
        this.brand = this.brand.bind(this);
        this.default = this.default.bind(this);
        this.catch = this.catch.bind(this);
        this.describe = this.describe.bind(this);
        this.pipe = this.pipe.bind(this);
        this.isNullable = this.isNullable.bind(this);
        this.isOptional = this.isOptional.bind(this);
    }
    get description() {
        return this._def.description;
    }
    _getType(input) {
        return getParsedType(input.data);
    }
    _getOrReturnCtx(input, ctx) {
        return (ctx || {
            common: input.parent.common,
            data: input.data,
            parsedType: getParsedType(input.data),
            schemaErrorMap: this._def.errorMap,
            path: input.path,
            parent: input.parent,
        });
    }
    _processInputParams(input) {
        return {
            status: new ParseStatus(),
            ctx: {
                common: input.parent.common,
                data: input.data,
                parsedType: getParsedType(input.data),
                schemaErrorMap: this._def.errorMap,
                path: input.path,
                parent: input.parent,
            },
        };
    }
    _parseSync(input) {
        const result = this._parse(input);
        if (isAsync(result)) {
            throw new Error("Synchronous parse encountered promise.");
        }
        return result;
    }
    _parseAsync(input) {
        const result = this._parse(input);
        return Promise.resolve(result);
    }
    parse(data, params) {
        const result = this.safeParse(data, params);
        if (result.success)
            return result.data;
        throw result.error;
    }
    safeParse(data, params) {
        var _a;
        const ctx = {
            common: {
                issues: [],
                async: (_a = params === null || params === void 0 ? void 0 : params.async) !== null && _a !== void 0 ? _a : false,
                contextualErrorMap: params === null || params === void 0 ? void 0 : params.errorMap,
            },
            path: (params === null || params === void 0 ? void 0 : params.path) || [],
            schemaErrorMap: this._def.errorMap,
            parent: null,
            data,
            parsedType: getParsedType(data),
        };
        const result = this._parseSync({ data, path: ctx.path, parent: ctx });
        return handleResult(ctx, result);
    }
    async parseAsync(data, params) {
        const result = await this.safeParseAsync(data, params);
        if (result.success)
            return result.data;
        throw result.error;
    }
    async safeParseAsync(data, params) {
        const ctx = {
            common: {
                issues: [],
                contextualErrorMap: params === null || params === void 0 ? void 0 : params.errorMap,
                async: true,
            },
            path: (params === null || params === void 0 ? void 0 : params.path) || [],
            schemaErrorMap: this._def.errorMap,
            parent: null,
            data,
            parsedType: getParsedType(data),
        };
        const maybeAsyncResult = this._parse({ data, path: ctx.path, parent: ctx });
        const result = await (isAsync(maybeAsyncResult)
            ? maybeAsyncResult
            : Promise.resolve(maybeAsyncResult));
        return handleResult(ctx, result);
    }
    refine(check, message) {
        const getIssueProperties = (val) => {
            if (typeof message === "string" || typeof message === "undefined") {
                return { message };
            }
            else if (typeof message === "function") {
                return message(val);
            }
            else {
                return message;
            }
        };
        return this._refinement((val, ctx) => {
            const result = check(val);
            const setError = () => ctx.addIssue({
                code: ZodIssueCode.custom,
                ...getIssueProperties(val),
            });
            if (typeof Promise !== "undefined" && result instanceof Promise) {
                return result.then((data) => {
                    if (!data) {
                        setError();
                        return false;
                    }
                    else {
                        return true;
                    }
                });
            }
            if (!result) {
                setError();
                return false;
            }
            else {
                return true;
            }
        });
    }
    refinement(check, refinementData) {
        return this._refinement((val, ctx) => {
            if (!check(val)) {
                ctx.addIssue(typeof refinementData === "function"
                    ? refinementData(val, ctx)
                    : refinementData);
                return false;
            }
            else {
                return true;
            }
        });
    }
    _refinement(refinement) {
        return new ZodEffects({
            schema: this,
            typeName: ZodFirstPartyTypeKind.ZodEffects,
            effect: { type: "refinement", refinement },
        });
    }
    superRefine(refinement) {
        return this._refinement(refinement);
    }
    optional() {
        return ZodOptional.create(this, this._def);
    }
    nullable() {
        return ZodNullable.create(this, this._def);
    }
    nullish() {
        return this.nullable().optional();
    }
    array() {
        return ZodArray.create(this, this._def);
    }
    promise() {
        return ZodPromise.create(this, this._def);
    }
    or(option) {
        return ZodUnion.create([this, option], this._def);
    }
    and(incoming) {
        return ZodIntersection.create(this, incoming, this._def);
    }
    transform(transform) {
        return new ZodEffects({
            ...processCreateParams(this._def),
            schema: this,
            typeName: ZodFirstPartyTypeKind.ZodEffects,
            effect: { type: "transform", transform },
        });
    }
    default(def) {
        const defaultValueFunc = typeof def === "function" ? def : () => def;
        return new ZodDefault({
            ...processCreateParams(this._def),
            innerType: this,
            defaultValue: defaultValueFunc,
            typeName: ZodFirstPartyTypeKind.ZodDefault,
        });
    }
    brand() {
        return new ZodBranded({
            typeName: ZodFirstPartyTypeKind.ZodBranded,
            type: this,
            ...processCreateParams(this._def),
        });
    }
    catch(def) {
        const catchValueFunc = typeof def === "function" ? def : () => def;
        return new ZodCatch({
            ...processCreateParams(this._def),
            innerType: this,
            catchValue: catchValueFunc,
            typeName: ZodFirstPartyTypeKind.ZodCatch,
        });
    }
    describe(description) {
        const This = this.constructor;
        return new This({
            ...this._def,
            description,
        });
    }
    pipe(target) {
        return ZodPipeline.create(this, target);
    }
    isOptional() {
        return this.safeParse(undefined).success;
    }
    isNullable() {
        return this.safeParse(null).success;
    }
}
const cuidRegex = /^c[^\s-]{8,}$/i;
const cuid2Regex = /^[a-z][a-z0-9]*$/;
const ulidRegex = /[0-9A-HJKMNP-TV-Z]{26}/;
const uuidRegex = /^([a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[a-f0-9]{4}-[a-f0-9]{12}|00000000-0000-0000-0000-000000000000)$/i;
// from https://stackoverflow.com/a/46181/1550155
// old version: too slow, didn't support unicode
// const emailRegex = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i;
//old email regex
// const emailRegex = /^(([^<>()[\].,;:\s@"]+(\.[^<>()[\].,;:\s@"]+)*)|(".+"))@((?!-)([^<>()[\].,;:\s@"]+\.)+[^<>()[\].,;:\s@"]{1,})[^-<>()[\].,;:\s@"]$/i;
// eslint-disable-next-line
const emailRegex = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\])|(\[IPv6:(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))\])|([A-Za-z0-9]([A-Za-z0-9-]*[A-Za-z0-9])*(\.[A-Za-z]{2,})+))$/;
// from https://thekevinscott.com/emojis-in-javascript/#writing-a-regular-expression
const emojiRegex = /^(\p{Extended_Pictographic}|\p{Emoji_Component})+$/u;
const ipv4Regex = /^(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))$/;
const ipv6Regex = /^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$/;
// Adapted from https://stackoverflow.com/a/3143231
const datetimeRegex = (args) => {
    if (args.precision) {
        if (args.offset) {
            return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{${args.precision}}(([+-]\\d{2}(:?\\d{2})?)|Z)$`);
        }
        else {
            return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{${args.precision}}Z$`);
        }
    }
    else if (args.precision === 0) {
        if (args.offset) {
            return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(([+-]\\d{2}(:?\\d{2})?)|Z)$`);
        }
        else {
            return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$`);
        }
    }
    else {
        if (args.offset) {
            return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(([+-]\\d{2}(:?\\d{2})?)|Z)$`);
        }
        else {
            return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$`);
        }
    }
};
function isValidIP(ip, version) {
    if ((version === "v4" || !version) && ipv4Regex.test(ip)) {
        return true;
    }
    if ((version === "v6" || !version) && ipv6Regex.test(ip)) {
        return true;
    }
    return false;
}
class ZodString extends ZodType {
    constructor() {
        super(...arguments);
        this._regex = (regex, validation, message) => this.refinement((data) => regex.test(data), {
            validation,
            code: ZodIssueCode.invalid_string,
            ...errorUtil.errToObj(message),
        });
        /**
         * @deprecated Use z.string().min(1) instead.
         * @see {@link ZodString.min}
         */
        this.nonempty = (message) => this.min(1, errorUtil.errToObj(message));
        this.trim = () => new ZodString({
            ...this._def,
            checks: [...this._def.checks, { kind: "trim" }],
        });
        this.toLowerCase = () => new ZodString({
            ...this._def,
            checks: [...this._def.checks, { kind: "toLowerCase" }],
        });
        this.toUpperCase = () => new ZodString({
            ...this._def,
            checks: [...this._def.checks, { kind: "toUpperCase" }],
        });
    }
    _parse(input) {
        if (this._def.coerce) {
            input.data = String(input.data);
        }
        const parsedType = this._getType(input);
        if (parsedType !== ZodParsedType.string) {
            const ctx = this._getOrReturnCtx(input);
            addIssueToContext(ctx, {
                code: ZodIssueCode.invalid_type,
                expected: ZodParsedType.string,
                received: ctx.parsedType,
            }
            //
            );
            return INVALID;
        }
        const status = new ParseStatus();
        let ctx = undefined;
        for (const check of this._def.checks) {
            if (check.kind === "min") {
                if (input.data.length < check.value) {
                    ctx = this._getOrReturnCtx(input, ctx);
                    addIssueToContext(ctx, {
                        code: ZodIssueCode.too_small,
                        minimum: check.value,
                        type: "string",
                        inclusive: true,
                        exact: false,
                        message: check.message,
                    });
                    status.dirty();
                }
            }
            else if (check.kind === "max") {
                if (input.data.length > check.value) {
                    ctx = this._getOrReturnCtx(input, ctx);
                    addIssueToContext(ctx, {
                        code: ZodIssueCode.too_big,
                        maximum: check.value,
                        type: "string",
                        inclusive: true,
                        exact: false,
                        message: check.message,
                    });
                    status.dirty();
                }
            }
            else if (check.kind === "length") {
                const tooBig = input.data.length > check.value;
                const tooSmall = input.data.length < check.value;
                if (tooBig || tooSmall) {
                    ctx = this._getOrReturnCtx(input, ctx);
                    if (tooBig) {
                        addIssueToContext(ctx, {
                            code: ZodIssueCode.too_big,
                            maximum: check.value,
                            type: "string",
                            inclusive: true,
                            exact: true,
                            message: check.message,
                        });
                    }
                    else if (tooSmall) {
                        addIssueToContext(ctx, {
                            code: ZodIssueCode.too_small,
                            minimum: check.value,
                            type: "string",
                            inclusive: true,
                            exact: true,
                            message: check.message,
                        });
                    }
                    status.dirty();
                }
            }
            else if (check.kind === "email") {
                if (!emailRegex.test(input.data)) {
                    ctx = this._getOrReturnCtx(input, ctx);
                    addIssueToContext(ctx, {
                        validation: "email",
                        code: ZodIssueCode.invalid_string,
                        message: check.message,
                    });
                    status.dirty();
                }
            }
            else if (check.kind === "emoji") {
                if (!emojiRegex.test(input.data)) {
                    ctx = this._getOrReturnCtx(input, ctx);
                    addIssueToContext(ctx, {
                        validation: "emoji",
                        code: ZodIssueCode.invalid_string,
                        message: check.message,
                    });
                    status.dirty();
                }
            }
            else if (check.kind === "uuid") {
                if (!uuidRegex.test(input.data)) {
                    ctx = this._getOrReturnCtx(input, ctx);
                    addIssueToContext(ctx, {
                        validation: "uuid",
                        code: ZodIssueCode.invalid_string,
                        message: check.message,
                    });
                    status.dirty();
                }
            }
            else if (check.kind === "cuid") {
                if (!cuidRegex.test(input.data)) {
                    ctx = this._getOrReturnCtx(input, ctx);
                    addIssueToContext(ctx, {
                        validation: "cuid",
                        code: ZodIssueCode.invalid_string,
                        message: check.message,
                    });
                    status.dirty();
                }
            }
            else if (check.kind === "cuid2") {
                if (!cuid2Regex.test(input.data)) {
                    ctx = this._getOrReturnCtx(input, ctx);
                    addIssueToContext(ctx, {
                        validation: "cuid2",
                        code: ZodIssueCode.invalid_string,
                        message: check.message,
                    });
                    status.dirty();
                }
            }
            else if (check.kind === "ulid") {
                if (!ulidRegex.test(input.data)) {
                    ctx = this._getOrReturnCtx(input, ctx);
                    addIssueToContext(ctx, {
                        validation: "ulid",
                        code: ZodIssueCode.invalid_string,
                        message: check.message,
                    });
                    status.dirty();
                }
            }
            else if (check.kind === "url") {
                try {
                    new URL(input.data);
                }
                catch (_a) {
                    ctx = this._getOrReturnCtx(input, ctx);
                    addIssueToContext(ctx, {
                        validation: "url",
                        code: ZodIssueCode.invalid_string,
                        message: check.message,
                    });
                    status.dirty();
                }
            }
            else if (check.kind === "regex") {
                check.regex.lastIndex = 0;
                const testResult = check.regex.test(input.data);
                if (!testResult) {
                    ctx = this._getOrReturnCtx(input, ctx);
                    addIssueToContext(ctx, {
                        validation: "regex",
                        code: ZodIssueCode.invalid_string,
                        message: check.message,
                    });
                    status.dirty();
                }
            }
            else if (check.kind === "trim") {
                input.data = input.data.trim();
            }
            else if (check.kind === "includes") {
                if (!input.data.includes(check.value, check.position)) {
                    ctx = this._getOrReturnCtx(input, ctx);
                    addIssueToContext(ctx, {
                        code: ZodIssueCode.invalid_string,
                        validation: { includes: check.value, position: check.position },
                        message: check.message,
                    });
                    status.dirty();
                }
            }
            else if (check.kind === "toLowerCase") {
                input.data = input.data.toLowerCase();
            }
            else if (check.kind === "toUpperCase") {
                input.data = input.data.toUpperCase();
            }
            else if (check.kind === "startsWith") {
                if (!input.data.startsWith(check.value)) {
                    ctx = this._getOrReturnCtx(input, ctx);
                    addIssueToContext(ctx, {
                        code: ZodIssueCode.invalid_string,
                        validation: { startsWith: check.value },
                        message: check.message,
                    });
                    status.dirty();
                }
            }
            else if (check.kind === "endsWith") {
                if (!input.data.endsWith(check.value)) {
                    ctx = this._getOrReturnCtx(input, ctx);
                    addIssueToContext(ctx, {
                        code: ZodIssueCode.invalid_string,
                        validation: { endsWith: check.value },
                        message: check.message,
                    });
                    status.dirty();
                }
            }
            else if (check.kind === "datetime") {
                const regex = datetimeRegex(check);
                if (!regex.test(input.data)) {
                    ctx = this._getOrReturnCtx(input, ctx);
                    addIssueToContext(ctx, {
                        code: ZodIssueCode.invalid_string,
                        validation: "datetime",
                        message: check.message,
                    });
                    status.dirty();
                }
            }
            else if (check.kind === "ip") {
                if (!isValidIP(input.data, check.version)) {
                    ctx = this._getOrReturnCtx(input, ctx);
                    addIssueToContext(ctx, {
                        validation: "ip",
                        code: ZodIssueCode.invalid_string,
                        message: check.message,
                    });
                    status.dirty();
                }
            }
            else {
                util.assertNever(check);
            }
        }
        return { status: status.value, value: input.data };
    }
    _addCheck(check) {
        return new ZodString({
            ...this._def,
            checks: [...this._def.checks, check],
        });
    }
    email(message) {
        return this._addCheck({ kind: "email", ...errorUtil.errToObj(message) });
    }
    url(message) {
        return this._addCheck({ kind: "url", ...errorUtil.errToObj(message) });
    }
    emoji(message) {
        return this._addCheck({ kind: "emoji", ...errorUtil.errToObj(message) });
    }
    uuid(message) {
        return this._addCheck({ kind: "uuid", ...errorUtil.errToObj(message) });
    }
    cuid(message) {
        return this._addCheck({ kind: "cuid", ...errorUtil.errToObj(message) });
    }
    cuid2(message) {
        return this._addCheck({ kind: "cuid2", ...errorUtil.errToObj(message) });
    }
    ulid(message) {
        return this._addCheck({ kind: "ulid", ...errorUtil.errToObj(message) });
    }
    ip(options) {
        return this._addCheck({ kind: "ip", ...errorUtil.errToObj(options) });
    }
    datetime(options) {
        var _a;
        if (typeof options === "string") {
            return this._addCheck({
                kind: "datetime",
                precision: null,
                offset: false,
                message: options,
            });
        }
        return this._addCheck({
            kind: "datetime",
            precision: typeof (options === null || options === void 0 ? void 0 : options.precision) === "undefined" ? null : options === null || options === void 0 ? void 0 : options.precision,
            offset: (_a = options === null || options === void 0 ? void 0 : options.offset) !== null && _a !== void 0 ? _a : false,
            ...errorUtil.errToObj(options === null || options === void 0 ? void 0 : options.message),
        });
    }
    regex(regex, message) {
        return this._addCheck({
            kind: "regex",
            regex: regex,
            ...errorUtil.errToObj(message),
        });
    }
    includes(value, options) {
        return this._addCheck({
            kind: "includes",
            value: value,
            position: options === null || options === void 0 ? void 0 : options.position,
            ...errorUtil.errToObj(options === null || options === void 0 ? void 0 : options.message),
        });
    }
    startsWith(value, message) {
        return this._addCheck({
            kind: "startsWith",
            value: value,
            ...errorUtil.errToObj(message),
        });
    }
    endsWith(value, message) {
        return this._addCheck({
            kind: "endsWith",
            value: value,
            ...errorUtil.errToObj(message),
        });
    }
    min(minLength, message) {
        return this._addCheck({
            kind: "min",
            value: minLength,
            ...errorUtil.errToObj(message),
        });
    }
    max(maxLength, message) {
        return this._addCheck({
            kind: "max",
            value: maxLength,
            ...errorUtil.errToObj(message),
        });
    }
    length(len, message) {
        return this._addCheck({
            kind: "length",
            value: len,
            ...errorUtil.errToObj(message),
        });
    }
    get isDatetime() {
        return !!this._def.checks.find((ch) => ch.kind === "datetime");
    }
    get isEmail() {
        return !!this._def.checks.find((ch) => ch.kind === "email");
    }
    get isURL() {
        return !!this._def.checks.find((ch) => ch.kind === "url");
    }
    get isEmoji() {
        return !!this._def.checks.find((ch) => ch.kind === "emoji");
    }
    get isUUID() {
        return !!this._def.checks.find((ch) => ch.kind === "uuid");
    }
    get isCUID() {
        return !!this._def.checks.find((ch) => ch.kind === "cuid");
    }
    get isCUID2() {
        return !!this._def.checks.find((ch) => ch.kind === "cuid2");
    }
    get isULID() {
        return !!this._def.checks.find((ch) => ch.kind === "ulid");
    }
    get isIP() {
        return !!this._def.checks.find((ch) => ch.kind === "ip");
    }
    get minLength() {
        let min = null;
        for (const ch of this._def.checks) {
            if (ch.kind === "min") {
                if (min === null || ch.value > min)
                    min = ch.value;
            }
        }
        return min;
    }
    get maxLength() {
        let max = null;
        for (const ch of this._def.checks) {
            if (ch.kind === "max") {
                if (max === null || ch.value < max)
                    max = ch.value;
            }
        }
        return max;
    }
}
ZodString.create = (params) => {
    var _a;
    return new ZodString({
        checks: [],
        typeName: ZodFirstPartyTypeKind.ZodString,
        coerce: (_a = params === null || params === void 0 ? void 0 : params.coerce) !== null && _a !== void 0 ? _a : false,
        ...processCreateParams(params),
    });
};
// https://stackoverflow.com/questions/3966484/why-does-modulus-operator-return-fractional-number-in-javascript/31711034#31711034
function floatSafeRemainder(val, step) {
    const valDecCount = (val.toString().split(".")[1] || "").length;
    const stepDecCount = (step.toString().split(".")[1] || "").length;
    const decCount = valDecCount > stepDecCount ? valDecCount : stepDecCount;
    const valInt = parseInt(val.toFixed(decCount).replace(".", ""));
    const stepInt = parseInt(step.toFixed(decCount).replace(".", ""));
    return (valInt % stepInt) / Math.pow(10, decCount);
}
class ZodNumber extends ZodType {
    constructor() {
        super(...arguments);
        this.min = this.gte;
        this.max = this.lte;
        this.step = this.multipleOf;
    }
    _parse(input) {
        if (this._def.coerce) {
            input.data = Number(input.data);
        }
        const parsedType = this._getType(input);
        if (parsedType !== ZodParsedType.number) {
            const ctx = this._getOrReturnCtx(input);
            addIssueToContext(ctx, {
                code: ZodIssueCode.invalid_type,
                expected: ZodParsedType.number,
                received: ctx.parsedType,
            });
            return INVALID;
        }
        let ctx = undefined;
        const status = new ParseStatus();
        for (const check of this._def.checks) {
            if (check.kind === "int") {
                if (!util.isInteger(input.data)) {
                    ctx = this._getOrReturnCtx(input, ctx);
                    addIssueToContext(ctx, {
                        code: ZodIssueCode.invalid_type,
                        expected: "integer",
                        received: "float",
                        message: check.message,
                    });
                    status.dirty();
                }
            }
            else if (check.kind === "min") {
                const tooSmall = check.inclusive
                    ? input.data < check.value
                    : input.data <= check.value;
                if (tooSmall) {
                    ctx = this._getOrReturnCtx(input, ctx);
                    addIssueToContext(ctx, {
                        code: ZodIssueCode.too_small,
                        minimum: check.value,
                        type: "number",
                        inclusive: check.inclusive,
                        exact: false,
                        message: check.message,
                    });
                    status.dirty();
                }
            }
            else if (check.kind === "max") {
                const tooBig = check.inclusive
                    ? input.data > check.value
                    : input.data >= check.value;
                if (tooBig) {
                    ctx = this._getOrReturnCtx(input, ctx);
                    addIssueToContext(ctx, {
                        code: ZodIssueCode.too_big,
                        maximum: check.value,
                        type: "number",
                        inclusive: check.inclusive,
                        exact: false,
                        message: check.message,
                    });
                    status.dirty();
                }
            }
            else if (check.kind === "multipleOf") {
                if (floatSafeRemainder(input.data, check.value) !== 0) {
                    ctx = this._getOrReturnCtx(input, ctx);
                    addIssueToContext(ctx, {
                        code: ZodIssueCode.not_multiple_of,
                        multipleOf: check.value,
                        message: check.message,
                    });
                    status.dirty();
                }
            }
            else if (check.kind === "finite") {
                if (!Number.isFinite(input.data)) {
                    ctx = this._getOrReturnCtx(input, ctx);
                    addIssueToContext(ctx, {
                        code: ZodIssueCode.not_finite,
                        message: check.message,
                    });
                    status.dirty();
                }
            }
            else {
                util.assertNever(check);
            }
        }
        return { status: status.value, value: input.data };
    }
    gte(value, message) {
        return this.setLimit("min", value, true, errorUtil.toString(message));
    }
    gt(value, message) {
        return this.setLimit("min", value, false, errorUtil.toString(message));
    }
    lte(value, message) {
        return this.setLimit("max", value, true, errorUtil.toString(message));
    }
    lt(value, message) {
        return this.setLimit("max", value, false, errorUtil.toString(message));
    }
    setLimit(kind, value, inclusive, message) {
        return new ZodNumber({
            ...this._def,
            checks: [
                ...this._def.checks,
                {
                    kind,
                    value,
                    inclusive,
                    message: errorUtil.toString(message),
                },
            ],
        });
    }
    _addCheck(check) {
        return new ZodNumber({
            ...this._def,
            checks: [...this._def.checks, check],
        });
    }
    int(message) {
        return this._addCheck({
            kind: "int",
            message: errorUtil.toString(message),
        });
    }
    positive(message) {
        return this._addCheck({
            kind: "min",
            value: 0,
            inclusive: false,
            message: errorUtil.toString(message),
        });
    }
    negative(message) {
        return this._addCheck({
            kind: "max",
            value: 0,
            inclusive: false,
            message: errorUtil.toString(message),
        });
    }
    nonpositive(message) {
        return this._addCheck({
            kind: "max",
            value: 0,
            inclusive: true,
            message: errorUtil.toString(message),
        });
    }
    nonnegative(message) {
        return this._addCheck({
            kind: "min",
            value: 0,
            inclusive: true,
            message: errorUtil.toString(message),
        });
    }
    multipleOf(value, message) {
        return this._addCheck({
            kind: "multipleOf",
            value: value,
            message: errorUtil.toString(message),
        });
    }
    finite(message) {
        return this._addCheck({
            kind: "finite",
            message: errorUtil.toString(message),
        });
    }
    safe(message) {
        return this._addCheck({
            kind: "min",
            inclusive: true,
            value: Number.MIN_SAFE_INTEGER,
            message: errorUtil.toString(message),
        })._addCheck({
            kind: "max",
            inclusive: true,
            value: Number.MAX_SAFE_INTEGER,
            message: errorUtil.toString(message),
        });
    }
    get minValue() {
        let min = null;
        for (const ch of this._def.checks) {
            if (ch.kind === "min") {
                if (min === null || ch.value > min)
                    min = ch.value;
            }
        }
        return min;
    }
    get maxValue() {
        let max = null;
        for (const ch of this._def.checks) {
            if (ch.kind === "max") {
                if (max === null || ch.value < max)
                    max = ch.value;
            }
        }
        return max;
    }
    get isInt() {
        return !!this._def.checks.find((ch) => ch.kind === "int" ||
            (ch.kind === "multipleOf" && util.isInteger(ch.value)));
    }
    get isFinite() {
        let max = null, min = null;
        for (const ch of this._def.checks) {
            if (ch.kind === "finite" ||
                ch.kind === "int" ||
                ch.kind === "multipleOf") {
                return true;
            }
            else if (ch.kind === "min") {
                if (min === null || ch.value > min)
                    min = ch.value;
            }
            else if (ch.kind === "max") {
                if (max === null || ch.value < max)
                    max = ch.value;
            }
        }
        return Number.isFinite(min) && Number.isFinite(max);
    }
}
ZodNumber.create = (params) => {
    return new ZodNumber({
        checks: [],
        typeName: ZodFirstPartyTypeKind.ZodNumber,
        coerce: (params === null || params === void 0 ? void 0 : params.coerce) || false,
        ...processCreateParams(params),
    });
};
class ZodBigInt extends ZodType {
    constructor() {
        super(...arguments);
        this.min = this.gte;
        this.max = this.lte;
    }
    _parse(input) {
        if (this._def.coerce) {
            input.data = BigInt(input.data);
        }
        const parsedType = this._getType(input);
        if (parsedType !== ZodParsedType.bigint) {
            const ctx = this._getOrReturnCtx(input);
            addIssueToContext(ctx, {
                code: ZodIssueCode.invalid_type,
                expected: ZodParsedType.bigint,
                received: ctx.parsedType,
            });
            return INVALID;
        }
        let ctx = undefined;
        const status = new ParseStatus();
        for (const check of this._def.checks) {
            if (check.kind === "min") {
                const tooSmall = check.inclusive
                    ? input.data < check.value
                    : input.data <= check.value;
                if (tooSmall) {
                    ctx = this._getOrReturnCtx(input, ctx);
                    addIssueToContext(ctx, {
                        code: ZodIssueCode.too_small,
                        type: "bigint",
                        minimum: check.value,
                        inclusive: check.inclusive,
                        message: check.message,
                    });
                    status.dirty();
                }
            }
            else if (check.kind === "max") {
                const tooBig = check.inclusive
                    ? input.data > check.value
                    : input.data >= check.value;
                if (tooBig) {
                    ctx = this._getOrReturnCtx(input, ctx);
                    addIssueToContext(ctx, {
                        code: ZodIssueCode.too_big,
                        type: "bigint",
                        maximum: check.value,
                        inclusive: check.inclusive,
                        message: check.message,
                    });
                    status.dirty();
                }
            }
            else if (check.kind === "multipleOf") {
                if (input.data % check.value !== BigInt(0)) {
                    ctx = this._getOrReturnCtx(input, ctx);
                    addIssueToContext(ctx, {
                        code: ZodIssueCode.not_multiple_of,
                        multipleOf: check.value,
                        message: check.message,
                    });
                    status.dirty();
                }
            }
            else {
                util.assertNever(check);
            }
        }
        return { status: status.value, value: input.data };
    }
    gte(value, message) {
        return this.setLimit("min", value, true, errorUtil.toString(message));
    }
    gt(value, message) {
        return this.setLimit("min", value, false, errorUtil.toString(message));
    }
    lte(value, message) {
        return this.setLimit("max", value, true, errorUtil.toString(message));
    }
    lt(value, message) {
        return this.setLimit("max", value, false, errorUtil.toString(message));
    }
    setLimit(kind, value, inclusive, message) {
        return new ZodBigInt({
            ...this._def,
            checks: [
                ...this._def.checks,
                {
                    kind,
                    value,
                    inclusive,
                    message: errorUtil.toString(message),
                },
            ],
        });
    }
    _addCheck(check) {
        return new ZodBigInt({
            ...this._def,
            checks: [...this._def.checks, check],
        });
    }
    positive(message) {
        return this._addCheck({
            kind: "min",
            value: BigInt(0),
            inclusive: false,
            message: errorUtil.toString(message),
        });
    }
    negative(message) {
        return this._addCheck({
            kind: "max",
            value: BigInt(0),
            inclusive: false,
            message: errorUtil.toString(message),
        });
    }
    nonpositive(message) {
        return this._addCheck({
            kind: "max",
            value: BigInt(0),
            inclusive: true,
            message: errorUtil.toString(message),
        });
    }
    nonnegative(message) {
        return this._addCheck({
            kind: "min",
            value: BigInt(0),
            inclusive: true,
            message: errorUtil.toString(message),
        });
    }
    multipleOf(value, message) {
        return this._addCheck({
            kind: "multipleOf",
            value,
            message: errorUtil.toString(message),
        });
    }
    get minValue() {
        let min = null;
        for (const ch of this._def.checks) {
            if (ch.kind === "min") {
                if (min === null || ch.value > min)
                    min = ch.value;
            }
        }
        return min;
    }
    get maxValue() {
        let max = null;
        for (const ch of this._def.checks) {
            if (ch.kind === "max") {
                if (max === null || ch.value < max)
                    max = ch.value;
            }
        }
        return max;
    }
}
ZodBigInt.create = (params) => {
    var _a;
    return new ZodBigInt({
        checks: [],
        typeName: ZodFirstPartyTypeKind.ZodBigInt,
        coerce: (_a = params === null || params === void 0 ? void 0 : params.coerce) !== null && _a !== void 0 ? _a : false,
        ...processCreateParams(params),
    });
};
class ZodBoolean extends ZodType {
    _parse(input) {
        if (this._def.coerce) {
            input.data = Boolean(input.data);
        }
        const parsedType = this._getType(input);
        if (parsedType !== ZodParsedType.boolean) {
            const ctx = this._getOrReturnCtx(input);
            addIssueToContext(ctx, {
                code: ZodIssueCode.invalid_type,
                expected: ZodParsedType.boolean,
                received: ctx.parsedType,
            });
            return INVALID;
        }
        return OK(input.data);
    }
}
ZodBoolean.create = (params) => {
    return new ZodBoolean({
        typeName: ZodFirstPartyTypeKind.ZodBoolean,
        coerce: (params === null || params === void 0 ? void 0 : params.coerce) || false,
        ...processCreateParams(params),
    });
};
class ZodDate extends ZodType {
    _parse(input) {
        if (this._def.coerce) {
            input.data = new Date(input.data);
        }
        const parsedType = this._getType(input);
        if (parsedType !== ZodParsedType.date) {
            const ctx = this._getOrReturnCtx(input);
            addIssueToContext(ctx, {
                code: ZodIssueCode.invalid_type,
                expected: ZodParsedType.date,
                received: ctx.parsedType,
            });
            return INVALID;
        }
        if (isNaN(input.data.getTime())) {
            const ctx = this._getOrReturnCtx(input);
            addIssueToContext(ctx, {
                code: ZodIssueCode.invalid_date,
            });
            return INVALID;
        }
        const status = new ParseStatus();
        let ctx = undefined;
        for (const check of this._def.checks) {
            if (check.kind === "min") {
                if (input.data.getTime() < check.value) {
                    ctx = this._getOrReturnCtx(input, ctx);
                    addIssueToContext(ctx, {
                        code: ZodIssueCode.too_small,
                        message: check.message,
                        inclusive: true,
                        exact: false,
                        minimum: check.value,
                        type: "date",
                    });
                    status.dirty();
                }
            }
            else if (check.kind === "max") {
                if (input.data.getTime() > check.value) {
                    ctx = this._getOrReturnCtx(input, ctx);
                    addIssueToContext(ctx, {
                        code: ZodIssueCode.too_big,
                        message: check.message,
                        inclusive: true,
                        exact: false,
                        maximum: check.value,
                        type: "date",
                    });
                    status.dirty();
                }
            }
            else {
                util.assertNever(check);
            }
        }
        return {
            status: status.value,
            value: new Date(input.data.getTime()),
        };
    }
    _addCheck(check) {
        return new ZodDate({
            ...this._def,
            checks: [...this._def.checks, check],
        });
    }
    min(minDate, message) {
        return this._addCheck({
            kind: "min",
            value: minDate.getTime(),
            message: errorUtil.toString(message),
        });
    }
    max(maxDate, message) {
        return this._addCheck({
            kind: "max",
            value: maxDate.getTime(),
            message: errorUtil.toString(message),
        });
    }
    get minDate() {
        let min = null;
        for (const ch of this._def.checks) {
            if (ch.kind === "min") {
                if (min === null || ch.value > min)
                    min = ch.value;
            }
        }
        return min != null ? new Date(min) : null;
    }
    get maxDate() {
        let max = null;
        for (const ch of this._def.checks) {
            if (ch.kind === "max") {
                if (max === null || ch.value < max)
                    max = ch.value;
            }
        }
        return max != null ? new Date(max) : null;
    }
}
ZodDate.create = (params) => {
    return new ZodDate({
        checks: [],
        coerce: (params === null || params === void 0 ? void 0 : params.coerce) || false,
        typeName: ZodFirstPartyTypeKind.ZodDate,
        ...processCreateParams(params),
    });
};
class ZodSymbol extends ZodType {
    _parse(input) {
        const parsedType = this._getType(input);
        if (parsedType !== ZodParsedType.symbol) {
            const ctx = this._getOrReturnCtx(input);
            addIssueToContext(ctx, {
                code: ZodIssueCode.invalid_type,
                expected: ZodParsedType.symbol,
                received: ctx.parsedType,
            });
            return INVALID;
        }
        return OK(input.data);
    }
}
ZodSymbol.create = (params) => {
    return new ZodSymbol({
        typeName: ZodFirstPartyTypeKind.ZodSymbol,
        ...processCreateParams(params),
    });
};
class ZodUndefined extends ZodType {
    _parse(input) {
        const parsedType = this._getType(input);
        if (parsedType !== ZodParsedType.undefined) {
            const ctx = this._getOrReturnCtx(input);
            addIssueToContext(ctx, {
                code: ZodIssueCode.invalid_type,
                expected: ZodParsedType.undefined,
                received: ctx.parsedType,
            });
            return INVALID;
        }
        return OK(input.data);
    }
}
ZodUndefined.create = (params) => {
    return new ZodUndefined({
        typeName: ZodFirstPartyTypeKind.ZodUndefined,
        ...processCreateParams(params),
    });
};
class ZodNull extends ZodType {
    _parse(input) {
        const parsedType = this._getType(input);
        if (parsedType !== ZodParsedType.null) {
            const ctx = this._getOrReturnCtx(input);
            addIssueToContext(ctx, {
                code: ZodIssueCode.invalid_type,
                expected: ZodParsedType.null,
                received: ctx.parsedType,
            });
            return INVALID;
        }
        return OK(input.data);
    }
}
ZodNull.create = (params) => {
    return new ZodNull({
        typeName: ZodFirstPartyTypeKind.ZodNull,
        ...processCreateParams(params),
    });
};
class ZodAny extends ZodType {
    constructor() {
        super(...arguments);
        // to prevent instances of other classes from extending ZodAny. this causes issues with catchall in ZodObject.
        this._any = true;
    }
    _parse(input) {
        return OK(input.data);
    }
}
ZodAny.create = (params) => {
    return new ZodAny({
        typeName: ZodFirstPartyTypeKind.ZodAny,
        ...processCreateParams(params),
    });
};
class ZodUnknown extends ZodType {
    constructor() {
        super(...arguments);
        // required
        this._unknown = true;
    }
    _parse(input) {
        return OK(input.data);
    }
}
ZodUnknown.create = (params) => {
    return new ZodUnknown({
        typeName: ZodFirstPartyTypeKind.ZodUnknown,
        ...processCreateParams(params),
    });
};
class ZodNever extends ZodType {
    _parse(input) {
        const ctx = this._getOrReturnCtx(input);
        addIssueToContext(ctx, {
            code: ZodIssueCode.invalid_type,
            expected: ZodParsedType.never,
            received: ctx.parsedType,
        });
        return INVALID;
    }
}
ZodNever.create = (params) => {
    return new ZodNever({
        typeName: ZodFirstPartyTypeKind.ZodNever,
        ...processCreateParams(params),
    });
};
class ZodVoid extends ZodType {
    _parse(input) {
        const parsedType = this._getType(input);
        if (parsedType !== ZodParsedType.undefined) {
            const ctx = this._getOrReturnCtx(input);
            addIssueToContext(ctx, {
                code: ZodIssueCode.invalid_type,
                expected: ZodParsedType.void,
                received: ctx.parsedType,
            });
            return INVALID;
        }
        return OK(input.data);
    }
}
ZodVoid.create = (params) => {
    return new ZodVoid({
        typeName: ZodFirstPartyTypeKind.ZodVoid,
        ...processCreateParams(params),
    });
};
class ZodArray extends ZodType {
    _parse(input) {
        const { ctx, status } = this._processInputParams(input);
        const def = this._def;
        if (ctx.parsedType !== ZodParsedType.array) {
            addIssueToContext(ctx, {
                code: ZodIssueCode.invalid_type,
                expected: ZodParsedType.array,
                received: ctx.parsedType,
            });
            return INVALID;
        }
        if (def.exactLength !== null) {
            const tooBig = ctx.data.length > def.exactLength.value;
            const tooSmall = ctx.data.length < def.exactLength.value;
            if (tooBig || tooSmall) {
                addIssueToContext(ctx, {
                    code: tooBig ? ZodIssueCode.too_big : ZodIssueCode.too_small,
                    minimum: (tooSmall ? def.exactLength.value : undefined),
                    maximum: (tooBig ? def.exactLength.value : undefined),
                    type: "array",
                    inclusive: true,
                    exact: true,
                    message: def.exactLength.message,
                });
                status.dirty();
            }
        }
        if (def.minLength !== null) {
            if (ctx.data.length < def.minLength.value) {
                addIssueToContext(ctx, {
                    code: ZodIssueCode.too_small,
                    minimum: def.minLength.value,
                    type: "array",
                    inclusive: true,
                    exact: false,
                    message: def.minLength.message,
                });
                status.dirty();
            }
        }
        if (def.maxLength !== null) {
            if (ctx.data.length > def.maxLength.value) {
                addIssueToContext(ctx, {
                    code: ZodIssueCode.too_big,
                    maximum: def.maxLength.value,
                    type: "array",
                    inclusive: true,
                    exact: false,
                    message: def.maxLength.message,
                });
                status.dirty();
            }
        }
        if (ctx.common.async) {
            return Promise.all([...ctx.data].map((item, i) => {
                return def.type._parseAsync(new ParseInputLazyPath(ctx, item, ctx.path, i));
            })).then((result) => {
                return ParseStatus.mergeArray(status, result);
            });
        }
        const result = [...ctx.data].map((item, i) => {
            return def.type._parseSync(new ParseInputLazyPath(ctx, item, ctx.path, i));
        });
        return ParseStatus.mergeArray(status, result);
    }
    get element() {
        return this._def.type;
    }
    min(minLength, message) {
        return new ZodArray({
            ...this._def,
            minLength: { value: minLength, message: errorUtil.toString(message) },
        });
    }
    max(maxLength, message) {
        return new ZodArray({
            ...this._def,
            maxLength: { value: maxLength, message: errorUtil.toString(message) },
        });
    }
    length(len, message) {
        return new ZodArray({
            ...this._def,
            exactLength: { value: len, message: errorUtil.toString(message) },
        });
    }
    nonempty(message) {
        return this.min(1, message);
    }
}
ZodArray.create = (schema, params) => {
    return new ZodArray({
        type: schema,
        minLength: null,
        maxLength: null,
        exactLength: null,
        typeName: ZodFirstPartyTypeKind.ZodArray,
        ...processCreateParams(params),
    });
};
function deepPartialify(schema) {
    if (schema instanceof ZodObject) {
        const newShape = {};
        for (const key in schema.shape) {
            const fieldSchema = schema.shape[key];
            newShape[key] = ZodOptional.create(deepPartialify(fieldSchema));
        }
        return new ZodObject({
            ...schema._def,
            shape: () => newShape,
        });
    }
    else if (schema instanceof ZodArray) {
        return new ZodArray({
            ...schema._def,
            type: deepPartialify(schema.element),
        });
    }
    else if (schema instanceof ZodOptional) {
        return ZodOptional.create(deepPartialify(schema.unwrap()));
    }
    else if (schema instanceof ZodNullable) {
        return ZodNullable.create(deepPartialify(schema.unwrap()));
    }
    else if (schema instanceof ZodTuple) {
        return ZodTuple.create(schema.items.map((item) => deepPartialify(item)));
    }
    else {
        return schema;
    }
}
class ZodObject extends ZodType {
    constructor() {
        super(...arguments);
        this._cached = null;
        /**
         * @deprecated In most cases, this is no longer needed - unknown properties are now silently stripped.
         * If you want to pass through unknown properties, use `.passthrough()` instead.
         */
        this.nonstrict = this.passthrough;
        // extend<
        //   Augmentation extends ZodRawShape,
        //   NewOutput extends util.flatten<{
        //     [k in keyof Augmentation | keyof Output]: k extends keyof Augmentation
        //       ? Augmentation[k]["_output"]
        //       : k extends keyof Output
        //       ? Output[k]
        //       : never;
        //   }>,
        //   NewInput extends util.flatten<{
        //     [k in keyof Augmentation | keyof Input]: k extends keyof Augmentation
        //       ? Augmentation[k]["_input"]
        //       : k extends keyof Input
        //       ? Input[k]
        //       : never;
        //   }>
        // >(
        //   augmentation: Augmentation
        // ): ZodObject<
        //   extendShape<T, Augmentation>,
        //   UnknownKeys,
        //   Catchall,
        //   NewOutput,
        //   NewInput
        // > {
        //   return new ZodObject({
        //     ...this._def,
        //     shape: () => ({
        //       ...this._def.shape(),
        //       ...augmentation,
        //     }),
        //   }) as any;
        // }
        /**
         * @deprecated Use `.extend` instead
         *  */
        this.augment = this.extend;
    }
    _getCached() {
        if (this._cached !== null)
            return this._cached;
        const shape = this._def.shape();
        const keys = util.objectKeys(shape);
        return (this._cached = { shape, keys });
    }
    _parse(input) {
        const parsedType = this._getType(input);
        if (parsedType !== ZodParsedType.object) {
            const ctx = this._getOrReturnCtx(input);
            addIssueToContext(ctx, {
                code: ZodIssueCode.invalid_type,
                expected: ZodParsedType.object,
                received: ctx.parsedType,
            });
            return INVALID;
        }
        const { status, ctx } = this._processInputParams(input);
        const { shape, keys: shapeKeys } = this._getCached();
        const extraKeys = [];
        if (!(this._def.catchall instanceof ZodNever &&
            this._def.unknownKeys === "strip")) {
            for (const key in ctx.data) {
                if (!shapeKeys.includes(key)) {
                    extraKeys.push(key);
                }
            }
        }
        const pairs = [];
        for (const key of shapeKeys) {
            const keyValidator = shape[key];
            const value = ctx.data[key];
            pairs.push({
                key: { status: "valid", value: key },
                value: keyValidator._parse(new ParseInputLazyPath(ctx, value, ctx.path, key)),
                alwaysSet: key in ctx.data,
            });
        }
        if (this._def.catchall instanceof ZodNever) {
            const unknownKeys = this._def.unknownKeys;
            if (unknownKeys === "passthrough") {
                for (const key of extraKeys) {
                    pairs.push({
                        key: { status: "valid", value: key },
                        value: { status: "valid", value: ctx.data[key] },
                    });
                }
            }
            else if (unknownKeys === "strict") {
                if (extraKeys.length > 0) {
                    addIssueToContext(ctx, {
                        code: ZodIssueCode.unrecognized_keys,
                        keys: extraKeys,
                    });
                    status.dirty();
                }
            }
            else if (unknownKeys === "strip") ;
            else {
                throw new Error(`Internal ZodObject error: invalid unknownKeys value.`);
            }
        }
        else {
            // run catchall validation
            const catchall = this._def.catchall;
            for (const key of extraKeys) {
                const value = ctx.data[key];
                pairs.push({
                    key: { status: "valid", value: key },
                    value: catchall._parse(new ParseInputLazyPath(ctx, value, ctx.path, key) //, ctx.child(key), value, getParsedType(value)
                    ),
                    alwaysSet: key in ctx.data,
                });
            }
        }
        if (ctx.common.async) {
            return Promise.resolve()
                .then(async () => {
                const syncPairs = [];
                for (const pair of pairs) {
                    const key = await pair.key;
                    syncPairs.push({
                        key,
                        value: await pair.value,
                        alwaysSet: pair.alwaysSet,
                    });
                }
                return syncPairs;
            })
                .then((syncPairs) => {
                return ParseStatus.mergeObjectSync(status, syncPairs);
            });
        }
        else {
            return ParseStatus.mergeObjectSync(status, pairs);
        }
    }
    get shape() {
        return this._def.shape();
    }
    strict(message) {
        errorUtil.errToObj;
        return new ZodObject({
            ...this._def,
            unknownKeys: "strict",
            ...(message !== undefined
                ? {
                    errorMap: (issue, ctx) => {
                        var _a, _b, _c, _d;
                        const defaultError = (_c = (_b = (_a = this._def).errorMap) === null || _b === void 0 ? void 0 : _b.call(_a, issue, ctx).message) !== null && _c !== void 0 ? _c : ctx.defaultError;
                        if (issue.code === "unrecognized_keys")
                            return {
                                message: (_d = errorUtil.errToObj(message).message) !== null && _d !== void 0 ? _d : defaultError,
                            };
                        return {
                            message: defaultError,
                        };
                    },
                }
                : {}),
        });
    }
    strip() {
        return new ZodObject({
            ...this._def,
            unknownKeys: "strip",
        });
    }
    passthrough() {
        return new ZodObject({
            ...this._def,
            unknownKeys: "passthrough",
        });
    }
    // const AugmentFactory =
    //   <Def extends ZodObjectDef>(def: Def) =>
    //   <Augmentation extends ZodRawShape>(
    //     augmentation: Augmentation
    //   ): ZodObject<
    //     extendShape<ReturnType<Def["shape"]>, Augmentation>,
    //     Def["unknownKeys"],
    //     Def["catchall"]
    //   > => {
    //     return new ZodObject({
    //       ...def,
    //       shape: () => ({
    //         ...def.shape(),
    //         ...augmentation,
    //       }),
    //     }) as any;
    //   };
    extend(augmentation) {
        return new ZodObject({
            ...this._def,
            shape: () => ({
                ...this._def.shape(),
                ...augmentation,
            }),
        });
    }
    /**
     * Prior to zod@1.0.12 there was a bug in the
     * inferred type of merged objects. Please
     * upgrade if you are experiencing issues.
     */
    merge(merging) {
        const merged = new ZodObject({
            unknownKeys: merging._def.unknownKeys,
            catchall: merging._def.catchall,
            shape: () => ({
                ...this._def.shape(),
                ...merging._def.shape(),
            }),
            typeName: ZodFirstPartyTypeKind.ZodObject,
        });
        return merged;
    }
    // merge<
    //   Incoming extends AnyZodObject,
    //   Augmentation extends Incoming["shape"],
    //   NewOutput extends {
    //     [k in keyof Augmentation | keyof Output]: k extends keyof Augmentation
    //       ? Augmentation[k]["_output"]
    //       : k extends keyof Output
    //       ? Output[k]
    //       : never;
    //   },
    //   NewInput extends {
    //     [k in keyof Augmentation | keyof Input]: k extends keyof Augmentation
    //       ? Augmentation[k]["_input"]
    //       : k extends keyof Input
    //       ? Input[k]
    //       : never;
    //   }
    // >(
    //   merging: Incoming
    // ): ZodObject<
    //   extendShape<T, ReturnType<Incoming["_def"]["shape"]>>,
    //   Incoming["_def"]["unknownKeys"],
    //   Incoming["_def"]["catchall"],
    //   NewOutput,
    //   NewInput
    // > {
    //   const merged: any = new ZodObject({
    //     unknownKeys: merging._def.unknownKeys,
    //     catchall: merging._def.catchall,
    //     shape: () =>
    //       objectUtil.mergeShapes(this._def.shape(), merging._def.shape()),
    //     typeName: ZodFirstPartyTypeKind.ZodObject,
    //   }) as any;
    //   return merged;
    // }
    setKey(key, schema) {
        return this.augment({ [key]: schema });
    }
    // merge<Incoming extends AnyZodObject>(
    //   merging: Incoming
    // ): //ZodObject<T & Incoming["_shape"], UnknownKeys, Catchall> = (merging) => {
    // ZodObject<
    //   extendShape<T, ReturnType<Incoming["_def"]["shape"]>>,
    //   Incoming["_def"]["unknownKeys"],
    //   Incoming["_def"]["catchall"]
    // > {
    //   // const mergedShape = objectUtil.mergeShapes(
    //   //   this._def.shape(),
    //   //   merging._def.shape()
    //   // );
    //   const merged: any = new ZodObject({
    //     unknownKeys: merging._def.unknownKeys,
    //     catchall: merging._def.catchall,
    //     shape: () =>
    //       objectUtil.mergeShapes(this._def.shape(), merging._def.shape()),
    //     typeName: ZodFirstPartyTypeKind.ZodObject,
    //   }) as any;
    //   return merged;
    // }
    catchall(index) {
        return new ZodObject({
            ...this._def,
            catchall: index,
        });
    }
    pick(mask) {
        const shape = {};
        util.objectKeys(mask).forEach((key) => {
            if (mask[key] && this.shape[key]) {
                shape[key] = this.shape[key];
            }
        });
        return new ZodObject({
            ...this._def,
            shape: () => shape,
        });
    }
    omit(mask) {
        const shape = {};
        util.objectKeys(this.shape).forEach((key) => {
            if (!mask[key]) {
                shape[key] = this.shape[key];
            }
        });
        return new ZodObject({
            ...this._def,
            shape: () => shape,
        });
    }
    /**
     * @deprecated
     */
    deepPartial() {
        return deepPartialify(this);
    }
    partial(mask) {
        const newShape = {};
        util.objectKeys(this.shape).forEach((key) => {
            const fieldSchema = this.shape[key];
            if (mask && !mask[key]) {
                newShape[key] = fieldSchema;
            }
            else {
                newShape[key] = fieldSchema.optional();
            }
        });
        return new ZodObject({
            ...this._def,
            shape: () => newShape,
        });
    }
    required(mask) {
        const newShape = {};
        util.objectKeys(this.shape).forEach((key) => {
            if (mask && !mask[key]) {
                newShape[key] = this.shape[key];
            }
            else {
                const fieldSchema = this.shape[key];
                let newField = fieldSchema;
                while (newField instanceof ZodOptional) {
                    newField = newField._def.innerType;
                }
                newShape[key] = newField;
            }
        });
        return new ZodObject({
            ...this._def,
            shape: () => newShape,
        });
    }
    keyof() {
        return createZodEnum(util.objectKeys(this.shape));
    }
}
ZodObject.create = (shape, params) => {
    return new ZodObject({
        shape: () => shape,
        unknownKeys: "strip",
        catchall: ZodNever.create(),
        typeName: ZodFirstPartyTypeKind.ZodObject,
        ...processCreateParams(params),
    });
};
ZodObject.strictCreate = (shape, params) => {
    return new ZodObject({
        shape: () => shape,
        unknownKeys: "strict",
        catchall: ZodNever.create(),
        typeName: ZodFirstPartyTypeKind.ZodObject,
        ...processCreateParams(params),
    });
};
ZodObject.lazycreate = (shape, params) => {
    return new ZodObject({
        shape,
        unknownKeys: "strip",
        catchall: ZodNever.create(),
        typeName: ZodFirstPartyTypeKind.ZodObject,
        ...processCreateParams(params),
    });
};
class ZodUnion extends ZodType {
    _parse(input) {
        const { ctx } = this._processInputParams(input);
        const options = this._def.options;
        function handleResults(results) {
            // return first issue-free validation if it exists
            for (const result of results) {
                if (result.result.status === "valid") {
                    return result.result;
                }
            }
            for (const result of results) {
                if (result.result.status === "dirty") {
                    // add issues from dirty option
                    ctx.common.issues.push(...result.ctx.common.issues);
                    return result.result;
                }
            }
            // return invalid
            const unionErrors = results.map((result) => new ZodError(result.ctx.common.issues));
            addIssueToContext(ctx, {
                code: ZodIssueCode.invalid_union,
                unionErrors,
            });
            return INVALID;
        }
        if (ctx.common.async) {
            return Promise.all(options.map(async (option) => {
                const childCtx = {
                    ...ctx,
                    common: {
                        ...ctx.common,
                        issues: [],
                    },
                    parent: null,
                };
                return {
                    result: await option._parseAsync({
                        data: ctx.data,
                        path: ctx.path,
                        parent: childCtx,
                    }),
                    ctx: childCtx,
                };
            })).then(handleResults);
        }
        else {
            let dirty = undefined;
            const issues = [];
            for (const option of options) {
                const childCtx = {
                    ...ctx,
                    common: {
                        ...ctx.common,
                        issues: [],
                    },
                    parent: null,
                };
                const result = option._parseSync({
                    data: ctx.data,
                    path: ctx.path,
                    parent: childCtx,
                });
                if (result.status === "valid") {
                    return result;
                }
                else if (result.status === "dirty" && !dirty) {
                    dirty = { result, ctx: childCtx };
                }
                if (childCtx.common.issues.length) {
                    issues.push(childCtx.common.issues);
                }
            }
            if (dirty) {
                ctx.common.issues.push(...dirty.ctx.common.issues);
                return dirty.result;
            }
            const unionErrors = issues.map((issues) => new ZodError(issues));
            addIssueToContext(ctx, {
                code: ZodIssueCode.invalid_union,
                unionErrors,
            });
            return INVALID;
        }
    }
    get options() {
        return this._def.options;
    }
}
ZodUnion.create = (types, params) => {
    return new ZodUnion({
        options: types,
        typeName: ZodFirstPartyTypeKind.ZodUnion,
        ...processCreateParams(params),
    });
};
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
//////////                                 //////////
//////////      ZodDiscriminatedUnion      //////////
//////////                                 //////////
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
const getDiscriminator = (type) => {
    if (type instanceof ZodLazy) {
        return getDiscriminator(type.schema);
    }
    else if (type instanceof ZodEffects) {
        return getDiscriminator(type.innerType());
    }
    else if (type instanceof ZodLiteral) {
        return [type.value];
    }
    else if (type instanceof ZodEnum) {
        return type.options;
    }
    else if (type instanceof ZodNativeEnum) {
        // eslint-disable-next-line ban/ban
        return Object.keys(type.enum);
    }
    else if (type instanceof ZodDefault) {
        return getDiscriminator(type._def.innerType);
    }
    else if (type instanceof ZodUndefined) {
        return [undefined];
    }
    else if (type instanceof ZodNull) {
        return [null];
    }
    else {
        return null;
    }
};
class ZodDiscriminatedUnion extends ZodType {
    _parse(input) {
        const { ctx } = this._processInputParams(input);
        if (ctx.parsedType !== ZodParsedType.object) {
            addIssueToContext(ctx, {
                code: ZodIssueCode.invalid_type,
                expected: ZodParsedType.object,
                received: ctx.parsedType,
            });
            return INVALID;
        }
        const discriminator = this.discriminator;
        const discriminatorValue = ctx.data[discriminator];
        const option = this.optionsMap.get(discriminatorValue);
        if (!option) {
            addIssueToContext(ctx, {
                code: ZodIssueCode.invalid_union_discriminator,
                options: Array.from(this.optionsMap.keys()),
                path: [discriminator],
            });
            return INVALID;
        }
        if (ctx.common.async) {
            return option._parseAsync({
                data: ctx.data,
                path: ctx.path,
                parent: ctx,
            });
        }
        else {
            return option._parseSync({
                data: ctx.data,
                path: ctx.path,
                parent: ctx,
            });
        }
    }
    get discriminator() {
        return this._def.discriminator;
    }
    get options() {
        return this._def.options;
    }
    get optionsMap() {
        return this._def.optionsMap;
    }
    /**
     * The constructor of the discriminated union schema. Its behaviour is very similar to that of the normal z.union() constructor.
     * However, it only allows a union of objects, all of which need to share a discriminator property. This property must
     * have a different value for each object in the union.
     * @param discriminator the name of the discriminator property
     * @param types an array of object schemas
     * @param params
     */
    static create(discriminator, options, params) {
        // Get all the valid discriminator values
        const optionsMap = new Map();
        // try {
        for (const type of options) {
            const discriminatorValues = getDiscriminator(type.shape[discriminator]);
            if (!discriminatorValues) {
                throw new Error(`A discriminator value for key \`${discriminator}\` could not be extracted from all schema options`);
            }
            for (const value of discriminatorValues) {
                if (optionsMap.has(value)) {
                    throw new Error(`Discriminator property ${String(discriminator)} has duplicate value ${String(value)}`);
                }
                optionsMap.set(value, type);
            }
        }
        return new ZodDiscriminatedUnion({
            typeName: ZodFirstPartyTypeKind.ZodDiscriminatedUnion,
            discriminator,
            options,
            optionsMap,
            ...processCreateParams(params),
        });
    }
}
function mergeValues(a, b) {
    const aType = getParsedType(a);
    const bType = getParsedType(b);
    if (a === b) {
        return { valid: true, data: a };
    }
    else if (aType === ZodParsedType.object && bType === ZodParsedType.object) {
        const bKeys = util.objectKeys(b);
        const sharedKeys = util
            .objectKeys(a)
            .filter((key) => bKeys.indexOf(key) !== -1);
        const newObj = { ...a, ...b };
        for (const key of sharedKeys) {
            const sharedValue = mergeValues(a[key], b[key]);
            if (!sharedValue.valid) {
                return { valid: false };
            }
            newObj[key] = sharedValue.data;
        }
        return { valid: true, data: newObj };
    }
    else if (aType === ZodParsedType.array && bType === ZodParsedType.array) {
        if (a.length !== b.length) {
            return { valid: false };
        }
        const newArray = [];
        for (let index = 0; index < a.length; index++) {
            const itemA = a[index];
            const itemB = b[index];
            const sharedValue = mergeValues(itemA, itemB);
            if (!sharedValue.valid) {
                return { valid: false };
            }
            newArray.push(sharedValue.data);
        }
        return { valid: true, data: newArray };
    }
    else if (aType === ZodParsedType.date &&
        bType === ZodParsedType.date &&
        +a === +b) {
        return { valid: true, data: a };
    }
    else {
        return { valid: false };
    }
}
class ZodIntersection extends ZodType {
    _parse(input) {
        const { status, ctx } = this._processInputParams(input);
        const handleParsed = (parsedLeft, parsedRight) => {
            if (isAborted(parsedLeft) || isAborted(parsedRight)) {
                return INVALID;
            }
            const merged = mergeValues(parsedLeft.value, parsedRight.value);
            if (!merged.valid) {
                addIssueToContext(ctx, {
                    code: ZodIssueCode.invalid_intersection_types,
                });
                return INVALID;
            }
            if (isDirty(parsedLeft) || isDirty(parsedRight)) {
                status.dirty();
            }
            return { status: status.value, value: merged.data };
        };
        if (ctx.common.async) {
            return Promise.all([
                this._def.left._parseAsync({
                    data: ctx.data,
                    path: ctx.path,
                    parent: ctx,
                }),
                this._def.right._parseAsync({
                    data: ctx.data,
                    path: ctx.path,
                    parent: ctx,
                }),
            ]).then(([left, right]) => handleParsed(left, right));
        }
        else {
            return handleParsed(this._def.left._parseSync({
                data: ctx.data,
                path: ctx.path,
                parent: ctx,
            }), this._def.right._parseSync({
                data: ctx.data,
                path: ctx.path,
                parent: ctx,
            }));
        }
    }
}
ZodIntersection.create = (left, right, params) => {
    return new ZodIntersection({
        left: left,
        right: right,
        typeName: ZodFirstPartyTypeKind.ZodIntersection,
        ...processCreateParams(params),
    });
};
class ZodTuple extends ZodType {
    _parse(input) {
        const { status, ctx } = this._processInputParams(input);
        if (ctx.parsedType !== ZodParsedType.array) {
            addIssueToContext(ctx, {
                code: ZodIssueCode.invalid_type,
                expected: ZodParsedType.array,
                received: ctx.parsedType,
            });
            return INVALID;
        }
        if (ctx.data.length < this._def.items.length) {
            addIssueToContext(ctx, {
                code: ZodIssueCode.too_small,
                minimum: this._def.items.length,
                inclusive: true,
                exact: false,
                type: "array",
            });
            return INVALID;
        }
        const rest = this._def.rest;
        if (!rest && ctx.data.length > this._def.items.length) {
            addIssueToContext(ctx, {
                code: ZodIssueCode.too_big,
                maximum: this._def.items.length,
                inclusive: true,
                exact: false,
                type: "array",
            });
            status.dirty();
        }
        const items = [...ctx.data]
            .map((item, itemIndex) => {
            const schema = this._def.items[itemIndex] || this._def.rest;
            if (!schema)
                return null;
            return schema._parse(new ParseInputLazyPath(ctx, item, ctx.path, itemIndex));
        })
            .filter((x) => !!x); // filter nulls
        if (ctx.common.async) {
            return Promise.all(items).then((results) => {
                return ParseStatus.mergeArray(status, results);
            });
        }
        else {
            return ParseStatus.mergeArray(status, items);
        }
    }
    get items() {
        return this._def.items;
    }
    rest(rest) {
        return new ZodTuple({
            ...this._def,
            rest,
        });
    }
}
ZodTuple.create = (schemas, params) => {
    if (!Array.isArray(schemas)) {
        throw new Error("You must pass an array of schemas to z.tuple([ ... ])");
    }
    return new ZodTuple({
        items: schemas,
        typeName: ZodFirstPartyTypeKind.ZodTuple,
        rest: null,
        ...processCreateParams(params),
    });
};
class ZodRecord extends ZodType {
    get keySchema() {
        return this._def.keyType;
    }
    get valueSchema() {
        return this._def.valueType;
    }
    _parse(input) {
        const { status, ctx } = this._processInputParams(input);
        if (ctx.parsedType !== ZodParsedType.object) {
            addIssueToContext(ctx, {
                code: ZodIssueCode.invalid_type,
                expected: ZodParsedType.object,
                received: ctx.parsedType,
            });
            return INVALID;
        }
        const pairs = [];
        const keyType = this._def.keyType;
        const valueType = this._def.valueType;
        for (const key in ctx.data) {
            pairs.push({
                key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, key)),
                value: valueType._parse(new ParseInputLazyPath(ctx, ctx.data[key], ctx.path, key)),
            });
        }
        if (ctx.common.async) {
            return ParseStatus.mergeObjectAsync(status, pairs);
        }
        else {
            return ParseStatus.mergeObjectSync(status, pairs);
        }
    }
    get element() {
        return this._def.valueType;
    }
    static create(first, second, third) {
        if (second instanceof ZodType) {
            return new ZodRecord({
                keyType: first,
                valueType: second,
                typeName: ZodFirstPartyTypeKind.ZodRecord,
                ...processCreateParams(third),
            });
        }
        return new ZodRecord({
            keyType: ZodString.create(),
            valueType: first,
            typeName: ZodFirstPartyTypeKind.ZodRecord,
            ...processCreateParams(second),
        });
    }
}
class ZodMap extends ZodType {
    _parse(input) {
        const { status, ctx } = this._processInputParams(input);
        if (ctx.parsedType !== ZodParsedType.map) {
            addIssueToContext(ctx, {
                code: ZodIssueCode.invalid_type,
                expected: ZodParsedType.map,
                received: ctx.parsedType,
            });
            return INVALID;
        }
        const keyType = this._def.keyType;
        const valueType = this._def.valueType;
        const pairs = [...ctx.data.entries()].map(([key, value], index) => {
            return {
                key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, [index, "key"])),
                value: valueType._parse(new ParseInputLazyPath(ctx, value, ctx.path, [index, "value"])),
            };
        });
        if (ctx.common.async) {
            const finalMap = new Map();
            return Promise.resolve().then(async () => {
                for (const pair of pairs) {
                    const key = await pair.key;
                    const value = await pair.value;
                    if (key.status === "aborted" || value.status === "aborted") {
                        return INVALID;
                    }
                    if (key.status === "dirty" || value.status === "dirty") {
                        status.dirty();
                    }
                    finalMap.set(key.value, value.value);
                }
                return { status: status.value, value: finalMap };
            });
        }
        else {
            const finalMap = new Map();
            for (const pair of pairs) {
                const key = pair.key;
                const value = pair.value;
                if (key.status === "aborted" || value.status === "aborted") {
                    return INVALID;
                }
                if (key.status === "dirty" || value.status === "dirty") {
                    status.dirty();
                }
                finalMap.set(key.value, value.value);
            }
            return { status: status.value, value: finalMap };
        }
    }
}
ZodMap.create = (keyType, valueType, params) => {
    return new ZodMap({
        valueType,
        keyType,
        typeName: ZodFirstPartyTypeKind.ZodMap,
        ...processCreateParams(params),
    });
};
class ZodSet extends ZodType {
    _parse(input) {
        const { status, ctx } = this._processInputParams(input);
        if (ctx.parsedType !== ZodParsedType.set) {
            addIssueToContext(ctx, {
                code: ZodIssueCode.invalid_type,
                expected: ZodParsedType.set,
                received: ctx.parsedType,
            });
            return INVALID;
        }
        const def = this._def;
        if (def.minSize !== null) {
            if (ctx.data.size < def.minSize.value) {
                addIssueToContext(ctx, {
                    code: ZodIssueCode.too_small,
                    minimum: def.minSize.value,
                    type: "set",
                    inclusive: true,
                    exact: false,
                    message: def.minSize.message,
                });
                status.dirty();
            }
        }
        if (def.maxSize !== null) {
            if (ctx.data.size > def.maxSize.value) {
                addIssueToContext(ctx, {
                    code: ZodIssueCode.too_big,
                    maximum: def.maxSize.value,
                    type: "set",
                    inclusive: true,
                    exact: false,
                    message: def.maxSize.message,
                });
                status.dirty();
            }
        }
        const valueType = this._def.valueType;
        function finalizeSet(elements) {
            const parsedSet = new Set();
            for (const element of elements) {
                if (element.status === "aborted")
                    return INVALID;
                if (element.status === "dirty")
                    status.dirty();
                parsedSet.add(element.value);
            }
            return { status: status.value, value: parsedSet };
        }
        const elements = [...ctx.data.values()].map((item, i) => valueType._parse(new ParseInputLazyPath(ctx, item, ctx.path, i)));
        if (ctx.common.async) {
            return Promise.all(elements).then((elements) => finalizeSet(elements));
        }
        else {
            return finalizeSet(elements);
        }
    }
    min(minSize, message) {
        return new ZodSet({
            ...this._def,
            minSize: { value: minSize, message: errorUtil.toString(message) },
        });
    }
    max(maxSize, message) {
        return new ZodSet({
            ...this._def,
            maxSize: { value: maxSize, message: errorUtil.toString(message) },
        });
    }
    size(size, message) {
        return this.min(size, message).max(size, message);
    }
    nonempty(message) {
        return this.min(1, message);
    }
}
ZodSet.create = (valueType, params) => {
    return new ZodSet({
        valueType,
        minSize: null,
        maxSize: null,
        typeName: ZodFirstPartyTypeKind.ZodSet,
        ...processCreateParams(params),
    });
};
class ZodFunction extends ZodType {
    constructor() {
        super(...arguments);
        this.validate = this.implement;
    }
    _parse(input) {
        const { ctx } = this._processInputParams(input);
        if (ctx.parsedType !== ZodParsedType.function) {
            addIssueToContext(ctx, {
                code: ZodIssueCode.invalid_type,
                expected: ZodParsedType.function,
                received: ctx.parsedType,
            });
            return INVALID;
        }
        function makeArgsIssue(args, error) {
            return makeIssue({
                data: args,
                path: ctx.path,
                errorMaps: [
                    ctx.common.contextualErrorMap,
                    ctx.schemaErrorMap,
                    getErrorMap(),
                    errorMap,
                ].filter((x) => !!x),
                issueData: {
                    code: ZodIssueCode.invalid_arguments,
                    argumentsError: error,
                },
            });
        }
        function makeReturnsIssue(returns, error) {
            return makeIssue({
                data: returns,
                path: ctx.path,
                errorMaps: [
                    ctx.common.contextualErrorMap,
                    ctx.schemaErrorMap,
                    getErrorMap(),
                    errorMap,
                ].filter((x) => !!x),
                issueData: {
                    code: ZodIssueCode.invalid_return_type,
                    returnTypeError: error,
                },
            });
        }
        const params = { errorMap: ctx.common.contextualErrorMap };
        const fn = ctx.data;
        if (this._def.returns instanceof ZodPromise) {
            return OK(async (...args) => {
                const error = new ZodError([]);
                const parsedArgs = await this._def.args
                    .parseAsync(args, params)
                    .catch((e) => {
                    error.addIssue(makeArgsIssue(args, e));
                    throw error;
                });
                const result = await fn(...parsedArgs);
                const parsedReturns = await this._def.returns._def.type
                    .parseAsync(result, params)
                    .catch((e) => {
                    error.addIssue(makeReturnsIssue(result, e));
                    throw error;
                });
                return parsedReturns;
            });
        }
        else {
            return OK((...args) => {
                const parsedArgs = this._def.args.safeParse(args, params);
                if (!parsedArgs.success) {
                    throw new ZodError([makeArgsIssue(args, parsedArgs.error)]);
                }
                const result = fn(...parsedArgs.data);
                const parsedReturns = this._def.returns.safeParse(result, params);
                if (!parsedReturns.success) {
                    throw new ZodError([makeReturnsIssue(result, parsedReturns.error)]);
                }
                return parsedReturns.data;
            });
        }
    }
    parameters() {
        return this._def.args;
    }
    returnType() {
        return this._def.returns;
    }
    args(...items) {
        return new ZodFunction({
            ...this._def,
            args: ZodTuple.create(items).rest(ZodUnknown.create()),
        });
    }
    returns(returnType) {
        return new ZodFunction({
            ...this._def,
            returns: returnType,
        });
    }
    implement(func) {
        const validatedFunc = this.parse(func);
        return validatedFunc;
    }
    strictImplement(func) {
        const validatedFunc = this.parse(func);
        return validatedFunc;
    }
    static create(args, returns, params) {
        return new ZodFunction({
            args: (args
                ? args
                : ZodTuple.create([]).rest(ZodUnknown.create())),
            returns: returns || ZodUnknown.create(),
            typeName: ZodFirstPartyTypeKind.ZodFunction,
            ...processCreateParams(params),
        });
    }
}
class ZodLazy extends ZodType {
    get schema() {
        return this._def.getter();
    }
    _parse(input) {
        const { ctx } = this._processInputParams(input);
        const lazySchema = this._def.getter();
        return lazySchema._parse({ data: ctx.data, path: ctx.path, parent: ctx });
    }
}
ZodLazy.create = (getter, params) => {
    return new ZodLazy({
        getter: getter,
        typeName: ZodFirstPartyTypeKind.ZodLazy,
        ...processCreateParams(params),
    });
};
class ZodLiteral extends ZodType {
    _parse(input) {
        if (input.data !== this._def.value) {
            const ctx = this._getOrReturnCtx(input);
            addIssueToContext(ctx, {
                received: ctx.data,
                code: ZodIssueCode.invalid_literal,
                expected: this._def.value,
            });
            return INVALID;
        }
        return { status: "valid", value: input.data };
    }
    get value() {
        return this._def.value;
    }
}
ZodLiteral.create = (value, params) => {
    return new ZodLiteral({
        value: value,
        typeName: ZodFirstPartyTypeKind.ZodLiteral,
        ...processCreateParams(params),
    });
};
function createZodEnum(values, params) {
    return new ZodEnum({
        values: values,
        typeName: ZodFirstPartyTypeKind.ZodEnum,
        ...processCreateParams(params),
    });
}
class ZodEnum extends ZodType {
    _parse(input) {
        if (typeof input.data !== "string") {
            const ctx = this._getOrReturnCtx(input);
            const expectedValues = this._def.values;
            addIssueToContext(ctx, {
                expected: util.joinValues(expectedValues),
                received: ctx.parsedType,
                code: ZodIssueCode.invalid_type,
            });
            return INVALID;
        }
        if (this._def.values.indexOf(input.data) === -1) {
            const ctx = this._getOrReturnCtx(input);
            const expectedValues = this._def.values;
            addIssueToContext(ctx, {
                received: ctx.data,
                code: ZodIssueCode.invalid_enum_value,
                options: expectedValues,
            });
            return INVALID;
        }
        return OK(input.data);
    }
    get options() {
        return this._def.values;
    }
    get enum() {
        const enumValues = {};
        for (const val of this._def.values) {
            enumValues[val] = val;
        }
        return enumValues;
    }
    get Values() {
        const enumValues = {};
        for (const val of this._def.values) {
            enumValues[val] = val;
        }
        return enumValues;
    }
    get Enum() {
        const enumValues = {};
        for (const val of this._def.values) {
            enumValues[val] = val;
        }
        return enumValues;
    }
    extract(values) {
        return ZodEnum.create(values);
    }
    exclude(values) {
        return ZodEnum.create(this.options.filter((opt) => !values.includes(opt)));
    }
}
ZodEnum.create = createZodEnum;
class ZodNativeEnum extends ZodType {
    _parse(input) {
        const nativeEnumValues = util.getValidEnumValues(this._def.values);
        const ctx = this._getOrReturnCtx(input);
        if (ctx.parsedType !== ZodParsedType.string &&
            ctx.parsedType !== ZodParsedType.number) {
            const expectedValues = util.objectValues(nativeEnumValues);
            addIssueToContext(ctx, {
                expected: util.joinValues(expectedValues),
                received: ctx.parsedType,
                code: ZodIssueCode.invalid_type,
            });
            return INVALID;
        }
        if (nativeEnumValues.indexOf(input.data) === -1) {
            const expectedValues = util.objectValues(nativeEnumValues);
            addIssueToContext(ctx, {
                received: ctx.data,
                code: ZodIssueCode.invalid_enum_value,
                options: expectedValues,
            });
            return INVALID;
        }
        return OK(input.data);
    }
    get enum() {
        return this._def.values;
    }
}
ZodNativeEnum.create = (values, params) => {
    return new ZodNativeEnum({
        values: values,
        typeName: ZodFirstPartyTypeKind.ZodNativeEnum,
        ...processCreateParams(params),
    });
};
class ZodPromise extends ZodType {
    unwrap() {
        return this._def.type;
    }
    _parse(input) {
        const { ctx } = this._processInputParams(input);
        if (ctx.parsedType !== ZodParsedType.promise &&
            ctx.common.async === false) {
            addIssueToContext(ctx, {
                code: ZodIssueCode.invalid_type,
                expected: ZodParsedType.promise,
                received: ctx.parsedType,
            });
            return INVALID;
        }
        const promisified = ctx.parsedType === ZodParsedType.promise
            ? ctx.data
            : Promise.resolve(ctx.data);
        return OK(promisified.then((data) => {
            return this._def.type.parseAsync(data, {
                path: ctx.path,
                errorMap: ctx.common.contextualErrorMap,
            });
        }));
    }
}
ZodPromise.create = (schema, params) => {
    return new ZodPromise({
        type: schema,
        typeName: ZodFirstPartyTypeKind.ZodPromise,
        ...processCreateParams(params),
    });
};
class ZodEffects extends ZodType {
    innerType() {
        return this._def.schema;
    }
    sourceType() {
        return this._def.schema._def.typeName === ZodFirstPartyTypeKind.ZodEffects
            ? this._def.schema.sourceType()
            : this._def.schema;
    }
    _parse(input) {
        const { status, ctx } = this._processInputParams(input);
        const effect = this._def.effect || null;
        if (effect.type === "preprocess") {
            const processed = effect.transform(ctx.data);
            if (ctx.common.async) {
                return Promise.resolve(processed).then((processed) => {
                    return this._def.schema._parseAsync({
                        data: processed,
                        path: ctx.path,
                        parent: ctx,
                    });
                });
            }
            else {
                return this._def.schema._parseSync({
                    data: processed,
                    path: ctx.path,
                    parent: ctx,
                });
            }
        }
        const checkCtx = {
            addIssue: (arg) => {
                addIssueToContext(ctx, arg);
                if (arg.fatal) {
                    status.abort();
                }
                else {
                    status.dirty();
                }
            },
            get path() {
                return ctx.path;
            },
        };
        checkCtx.addIssue = checkCtx.addIssue.bind(checkCtx);
        if (effect.type === "refinement") {
            const executeRefinement = (acc
            // effect: RefinementEffect<any>
            ) => {
                const result = effect.refinement(acc, checkCtx);
                if (ctx.common.async) {
                    return Promise.resolve(result);
                }
                if (result instanceof Promise) {
                    throw new Error("Async refinement encountered during synchronous parse operation. Use .parseAsync instead.");
                }
                return acc;
            };
            if (ctx.common.async === false) {
                const inner = this._def.schema._parseSync({
                    data: ctx.data,
                    path: ctx.path,
                    parent: ctx,
                });
                if (inner.status === "aborted")
                    return INVALID;
                if (inner.status === "dirty")
                    status.dirty();
                // return value is ignored
                executeRefinement(inner.value);
                return { status: status.value, value: inner.value };
            }
            else {
                return this._def.schema
                    ._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx })
                    .then((inner) => {
                    if (inner.status === "aborted")
                        return INVALID;
                    if (inner.status === "dirty")
                        status.dirty();
                    return executeRefinement(inner.value).then(() => {
                        return { status: status.value, value: inner.value };
                    });
                });
            }
        }
        if (effect.type === "transform") {
            if (ctx.common.async === false) {
                const base = this._def.schema._parseSync({
                    data: ctx.data,
                    path: ctx.path,
                    parent: ctx,
                });
                if (!isValid(base))
                    return base;
                const result = effect.transform(base.value, checkCtx);
                if (result instanceof Promise) {
                    throw new Error(`Asynchronous transform encountered during synchronous parse operation. Use .parseAsync instead.`);
                }
                return { status: status.value, value: result };
            }
            else {
                return this._def.schema
                    ._parseAsync({ data: ctx.data, path: ctx.path, parent: ctx })
                    .then((base) => {
                    if (!isValid(base))
                        return base;
                    return Promise.resolve(effect.transform(base.value, checkCtx)).then((result) => ({ status: status.value, value: result }));
                });
            }
        }
        util.assertNever(effect);
    }
}
ZodEffects.create = (schema, effect, params) => {
    return new ZodEffects({
        schema,
        typeName: ZodFirstPartyTypeKind.ZodEffects,
        effect,
        ...processCreateParams(params),
    });
};
ZodEffects.createWithPreprocess = (preprocess, schema, params) => {
    return new ZodEffects({
        schema,
        effect: { type: "preprocess", transform: preprocess },
        typeName: ZodFirstPartyTypeKind.ZodEffects,
        ...processCreateParams(params),
    });
};
class ZodOptional extends ZodType {
    _parse(input) {
        const parsedType = this._getType(input);
        if (parsedType === ZodParsedType.undefined) {
            return OK(undefined);
        }
        return this._def.innerType._parse(input);
    }
    unwrap() {
        return this._def.innerType;
    }
}
ZodOptional.create = (type, params) => {
    return new ZodOptional({
        innerType: type,
        typeName: ZodFirstPartyTypeKind.ZodOptional,
        ...processCreateParams(params),
    });
};
class ZodNullable extends ZodType {
    _parse(input) {
        const parsedType = this._getType(input);
        if (parsedType === ZodParsedType.null) {
            return OK(null);
        }
        return this._def.innerType._parse(input);
    }
    unwrap() {
        return this._def.innerType;
    }
}
ZodNullable.create = (type, params) => {
    return new ZodNullable({
        innerType: type,
        typeName: ZodFirstPartyTypeKind.ZodNullable,
        ...processCreateParams(params),
    });
};
class ZodDefault extends ZodType {
    _parse(input) {
        const { ctx } = this._processInputParams(input);
        let data = ctx.data;
        if (ctx.parsedType === ZodParsedType.undefined) {
            data = this._def.defaultValue();
        }
        return this._def.innerType._parse({
            data,
            path: ctx.path,
            parent: ctx,
        });
    }
    removeDefault() {
        return this._def.innerType;
    }
}
ZodDefault.create = (type, params) => {
    return new ZodDefault({
        innerType: type,
        typeName: ZodFirstPartyTypeKind.ZodDefault,
        defaultValue: typeof params.default === "function"
            ? params.default
            : () => params.default,
        ...processCreateParams(params),
    });
};
class ZodCatch extends ZodType {
    _parse(input) {
        const { ctx } = this._processInputParams(input);
        // newCtx is used to not collect issues from inner types in ctx
        const newCtx = {
            ...ctx,
            common: {
                ...ctx.common,
                issues: [],
            },
        };
        const result = this._def.innerType._parse({
            data: newCtx.data,
            path: newCtx.path,
            parent: {
                ...newCtx,
            },
        });
        if (isAsync(result)) {
            return result.then((result) => {
                return {
                    status: "valid",
                    value: result.status === "valid"
                        ? result.value
                        : this._def.catchValue({
                            get error() {
                                return new ZodError(newCtx.common.issues);
                            },
                            input: newCtx.data,
                        }),
                };
            });
        }
        else {
            return {
                status: "valid",
                value: result.status === "valid"
                    ? result.value
                    : this._def.catchValue({
                        get error() {
                            return new ZodError(newCtx.common.issues);
                        },
                        input: newCtx.data,
                    }),
            };
        }
    }
    removeCatch() {
        return this._def.innerType;
    }
}
ZodCatch.create = (type, params) => {
    return new ZodCatch({
        innerType: type,
        typeName: ZodFirstPartyTypeKind.ZodCatch,
        catchValue: typeof params.catch === "function" ? params.catch : () => params.catch,
        ...processCreateParams(params),
    });
};
class ZodNaN extends ZodType {
    _parse(input) {
        const parsedType = this._getType(input);
        if (parsedType !== ZodParsedType.nan) {
            const ctx = this._getOrReturnCtx(input);
            addIssueToContext(ctx, {
                code: ZodIssueCode.invalid_type,
                expected: ZodParsedType.nan,
                received: ctx.parsedType,
            });
            return INVALID;
        }
        return { status: "valid", value: input.data };
    }
}
ZodNaN.create = (params) => {
    return new ZodNaN({
        typeName: ZodFirstPartyTypeKind.ZodNaN,
        ...processCreateParams(params),
    });
};
const BRAND = Symbol("zod_brand");
class ZodBranded extends ZodType {
    _parse(input) {
        const { ctx } = this._processInputParams(input);
        const data = ctx.data;
        return this._def.type._parse({
            data,
            path: ctx.path,
            parent: ctx,
        });
    }
    unwrap() {
        return this._def.type;
    }
}
class ZodPipeline extends ZodType {
    _parse(input) {
        const { status, ctx } = this._processInputParams(input);
        if (ctx.common.async) {
            const handleAsync = async () => {
                const inResult = await this._def.in._parseAsync({
                    data: ctx.data,
                    path: ctx.path,
                    parent: ctx,
                });
                if (inResult.status === "aborted")
                    return INVALID;
                if (inResult.status === "dirty") {
                    status.dirty();
                    return DIRTY(inResult.value);
                }
                else {
                    return this._def.out._parseAsync({
                        data: inResult.value,
                        path: ctx.path,
                        parent: ctx,
                    });
                }
            };
            return handleAsync();
        }
        else {
            const inResult = this._def.in._parseSync({
                data: ctx.data,
                path: ctx.path,
                parent: ctx,
            });
            if (inResult.status === "aborted")
                return INVALID;
            if (inResult.status === "dirty") {
                status.dirty();
                return {
                    status: "dirty",
                    value: inResult.value,
                };
            }
            else {
                return this._def.out._parseSync({
                    data: inResult.value,
                    path: ctx.path,
                    parent: ctx,
                });
            }
        }
    }
    static create(a, b) {
        return new ZodPipeline({
            in: a,
            out: b,
            typeName: ZodFirstPartyTypeKind.ZodPipeline,
        });
    }
}
const custom = (check, params = {}, 
/*
 * @deprecated
 *
 * Pass `fatal` into the params object instead:
 *
 * ```ts
 * z.string().custom((val) => val.length > 5, { fatal: false })
 * ```
 *
 */
fatal) => {
    if (check)
        return ZodAny.create().superRefine((data, ctx) => {
            var _a, _b;
            if (!check(data)) {
                const p = typeof params === "function"
                    ? params(data)
                    : typeof params === "string"
                        ? { message: params }
                        : params;
                const _fatal = (_b = (_a = p.fatal) !== null && _a !== void 0 ? _a : fatal) !== null && _b !== void 0 ? _b : true;
                const p2 = typeof p === "string" ? { message: p } : p;
                ctx.addIssue({ code: "custom", ...p2, fatal: _fatal });
            }
        });
    return ZodAny.create();
};
const late = {
    object: ZodObject.lazycreate,
};
var ZodFirstPartyTypeKind;
(function (ZodFirstPartyTypeKind) {
    ZodFirstPartyTypeKind["ZodString"] = "ZodString";
    ZodFirstPartyTypeKind["ZodNumber"] = "ZodNumber";
    ZodFirstPartyTypeKind["ZodNaN"] = "ZodNaN";
    ZodFirstPartyTypeKind["ZodBigInt"] = "ZodBigInt";
    ZodFirstPartyTypeKind["ZodBoolean"] = "ZodBoolean";
    ZodFirstPartyTypeKind["ZodDate"] = "ZodDate";
    ZodFirstPartyTypeKind["ZodSymbol"] = "ZodSymbol";
    ZodFirstPartyTypeKind["ZodUndefined"] = "ZodUndefined";
    ZodFirstPartyTypeKind["ZodNull"] = "ZodNull";
    ZodFirstPartyTypeKind["ZodAny"] = "ZodAny";
    ZodFirstPartyTypeKind["ZodUnknown"] = "ZodUnknown";
    ZodFirstPartyTypeKind["ZodNever"] = "ZodNever";
    ZodFirstPartyTypeKind["ZodVoid"] = "ZodVoid";
    ZodFirstPartyTypeKind["ZodArray"] = "ZodArray";
    ZodFirstPartyTypeKind["ZodObject"] = "ZodObject";
    ZodFirstPartyTypeKind["ZodUnion"] = "ZodUnion";
    ZodFirstPartyTypeKind["ZodDiscriminatedUnion"] = "ZodDiscriminatedUnion";
    ZodFirstPartyTypeKind["ZodIntersection"] = "ZodIntersection";
    ZodFirstPartyTypeKind["ZodTuple"] = "ZodTuple";
    ZodFirstPartyTypeKind["ZodRecord"] = "ZodRecord";
    ZodFirstPartyTypeKind["ZodMap"] = "ZodMap";
    ZodFirstPartyTypeKind["ZodSet"] = "ZodSet";
    ZodFirstPartyTypeKind["ZodFunction"] = "ZodFunction";
    ZodFirstPartyTypeKind["ZodLazy"] = "ZodLazy";
    ZodFirstPartyTypeKind["ZodLiteral"] = "ZodLiteral";
    ZodFirstPartyTypeKind["ZodEnum"] = "ZodEnum";
    ZodFirstPartyTypeKind["ZodEffects"] = "ZodEffects";
    ZodFirstPartyTypeKind["ZodNativeEnum"] = "ZodNativeEnum";
    ZodFirstPartyTypeKind["ZodOptional"] = "ZodOptional";
    ZodFirstPartyTypeKind["ZodNullable"] = "ZodNullable";
    ZodFirstPartyTypeKind["ZodDefault"] = "ZodDefault";
    ZodFirstPartyTypeKind["ZodCatch"] = "ZodCatch";
    ZodFirstPartyTypeKind["ZodPromise"] = "ZodPromise";
    ZodFirstPartyTypeKind["ZodBranded"] = "ZodBranded";
    ZodFirstPartyTypeKind["ZodPipeline"] = "ZodPipeline";
})(ZodFirstPartyTypeKind || (ZodFirstPartyTypeKind = {}));
const instanceOfType = (
// const instanceOfType = <T extends new (...args: any[]) => any>(
cls, params = {
    message: `Input not instance of ${cls.name}`,
}) => custom((data) => data instanceof cls, params);
const stringType = ZodString.create;
const numberType = ZodNumber.create;
const nanType = ZodNaN.create;
const bigIntType = ZodBigInt.create;
const booleanType = ZodBoolean.create;
const dateType = ZodDate.create;
const symbolType = ZodSymbol.create;
const undefinedType = ZodUndefined.create;
const nullType = ZodNull.create;
const anyType = ZodAny.create;
const unknownType = ZodUnknown.create;
const neverType = ZodNever.create;
const voidType = ZodVoid.create;
const arrayType = ZodArray.create;
const objectType = ZodObject.create;
const strictObjectType = ZodObject.strictCreate;
const unionType = ZodUnion.create;
const discriminatedUnionType = ZodDiscriminatedUnion.create;
const intersectionType = ZodIntersection.create;
const tupleType = ZodTuple.create;
const recordType = ZodRecord.create;
const mapType = ZodMap.create;
const setType = ZodSet.create;
const functionType = ZodFunction.create;
const lazyType = ZodLazy.create;
const literalType = ZodLiteral.create;
const enumType = ZodEnum.create;
const nativeEnumType = ZodNativeEnum.create;
const promiseType = ZodPromise.create;
const effectsType = ZodEffects.create;
const optionalType = ZodOptional.create;
const nullableType = ZodNullable.create;
const preprocessType = ZodEffects.createWithPreprocess;
const pipelineType = ZodPipeline.create;
const ostring = () => stringType().optional();
const onumber = () => numberType().optional();
const oboolean = () => booleanType().optional();
const coerce = {
    string: ((arg) => ZodString.create({ ...arg, coerce: true })),
    number: ((arg) => ZodNumber.create({ ...arg, coerce: true })),
    boolean: ((arg) => ZodBoolean.create({
        ...arg,
        coerce: true,
    })),
    bigint: ((arg) => ZodBigInt.create({ ...arg, coerce: true })),
    date: ((arg) => ZodDate.create({ ...arg, coerce: true })),
};
const NEVER = INVALID;

var z = /*#__PURE__*/Object.freeze({
    __proto__: null,
    defaultErrorMap: errorMap,
    setErrorMap: setErrorMap,
    getErrorMap: getErrorMap,
    makeIssue: makeIssue,
    EMPTY_PATH: EMPTY_PATH,
    addIssueToContext: addIssueToContext,
    ParseStatus: ParseStatus,
    INVALID: INVALID,
    DIRTY: DIRTY,
    OK: OK,
    isAborted: isAborted,
    isDirty: isDirty,
    isValid: isValid,
    isAsync: isAsync,
    get util () { return util; },
    get objectUtil () { return objectUtil; },
    ZodParsedType: ZodParsedType,
    getParsedType: getParsedType,
    ZodType: ZodType,
    ZodString: ZodString,
    ZodNumber: ZodNumber,
    ZodBigInt: ZodBigInt,
    ZodBoolean: ZodBoolean,
    ZodDate: ZodDate,
    ZodSymbol: ZodSymbol,
    ZodUndefined: ZodUndefined,
    ZodNull: ZodNull,
    ZodAny: ZodAny,
    ZodUnknown: ZodUnknown,
    ZodNever: ZodNever,
    ZodVoid: ZodVoid,
    ZodArray: ZodArray,
    ZodObject: ZodObject,
    ZodUnion: ZodUnion,
    ZodDiscriminatedUnion: ZodDiscriminatedUnion,
    ZodIntersection: ZodIntersection,
    ZodTuple: ZodTuple,
    ZodRecord: ZodRecord,
    ZodMap: ZodMap,
    ZodSet: ZodSet,
    ZodFunction: ZodFunction,
    ZodLazy: ZodLazy,
    ZodLiteral: ZodLiteral,
    ZodEnum: ZodEnum,
    ZodNativeEnum: ZodNativeEnum,
    ZodPromise: ZodPromise,
    ZodEffects: ZodEffects,
    ZodTransformer: ZodEffects,
    ZodOptional: ZodOptional,
    ZodNullable: ZodNullable,
    ZodDefault: ZodDefault,
    ZodCatch: ZodCatch,
    ZodNaN: ZodNaN,
    BRAND: BRAND,
    ZodBranded: ZodBranded,
    ZodPipeline: ZodPipeline,
    custom: custom,
    Schema: ZodType,
    ZodSchema: ZodType,
    late: late,
    get ZodFirstPartyTypeKind () { return ZodFirstPartyTypeKind; },
    coerce: coerce,
    any: anyType,
    array: arrayType,
    bigint: bigIntType,
    boolean: booleanType,
    date: dateType,
    discriminatedUnion: discriminatedUnionType,
    effect: effectsType,
    'enum': enumType,
    'function': functionType,
    'instanceof': instanceOfType,
    intersection: intersectionType,
    lazy: lazyType,
    literal: literalType,
    map: mapType,
    nan: nanType,
    nativeEnum: nativeEnumType,
    never: neverType,
    'null': nullType,
    nullable: nullableType,
    number: numberType,
    object: objectType,
    oboolean: oboolean,
    onumber: onumber,
    optional: optionalType,
    ostring: ostring,
    pipeline: pipelineType,
    preprocess: preprocessType,
    promise: promiseType,
    record: recordType,
    set: setType,
    strictObject: strictObjectType,
    string: stringType,
    symbol: symbolType,
    transformer: effectsType,
    tuple: tupleType,
    'undefined': undefinedType,
    union: unionType,
    unknown: unknownType,
    'void': voidType,
    NEVER: NEVER,
    ZodIssueCode: ZodIssueCode,
    quotelessJson: quotelessJson,
    ZodError: ZodError
});




/***/ })

},
/******/ __webpack_require__ => { // webpackRuntimeModules
/******/ var __webpack_exec__ = (moduleId) => (__webpack_require__(__webpack_require__.s = moduleId))
/******/ __webpack_require__.O(0, [870], () => (__webpack_exec__(37302)));
/******/ var __webpack_exports__ = __webpack_require__.O();
/******/ }
]);