# -*- coding: utf-8 -*-

'''
	Gaia Add-on
	Copyright (C) 2016 Gaia

	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.

	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.

	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
'''

'''
	NB: gaiaremove

	The native 're' library is less strict than the third-party 'regex' library.
	If the functions in Stream are updated, sometimes replacements (eg {separator}) are forgotten. That is, maybe this is used:
		re.compile(expression)
	instead of this:
		re.compile(self._expressionFormatCommon(expression))
	Then the expression passed to re/regex is not fully formatted and there might still be {separator} (and other) replacements in the string.
	're' does not care and will still evaluate the expression. 'regex' on the other hand will throw an exception.

	It is therefore advised to use 'regex' if Stream is updated with new expression to make sure everything works correctly:
		1. Copy ../resources/python/regex to script.gaia.externals.
		2. In stream.py replace "import re" with "from lib.modules.external import Importer; re = Importer.module('externals.regex')"
		3. Run tester.py
		4. Remember to delete directory from script.gaia.externals again.
'''

import re
import os
import pickle
import collections

from lib.modules.serializer import Serializer
from lib.modules import tools
from lib.modules import network
from lib.modules import interface
from lib.modules.cache import Cache
from lib.modules.concurrency import Pool, Lock, Event
from lib.meta.pack import MetaPack

# https://whereyouwatch.com/articles/ultimate-guide-to-movie-piracy-termonology/

class Stream(Serializer):

	##############################################################################
	# DEBUG
	##############################################################################

	Debug		= None

	##############################################################################
	# PERFORMANCE
	##############################################################################

	Performance	= None

	##############################################################################
	# LOCK
	##############################################################################

	LockCache	= Lock()
	LockThread	= Lock()
	LockOther	= Lock()

	##############################################################################
	# CACHE
	##############################################################################

	# Must correspond with settings.xml.
	CacheDisabled	= 0
	CacheMemory		= 1
	CacheFull		= 2

	CacheData		= {}
	CacheEvent		= {}
	CacheInit		= None
	CacheFile		= True # Wether or not to cache compiled regexs to file.

	##############################################################################
	# STATISTIC
	##############################################################################

	Statistics			= []

	StatisticExtracted	= 'extracted'
	StatisticCached		= 'cached'
	StatisticImported	= 'imported'
	StatisticFailed		= 'failed'
	StatisticGlobal		= 'global'

	##############################################################################
	# PARAMTER
	##############################################################################

	# Must correspond to the function names.

	ParameterThresholdFake				= 'thresholdFake'
	ParameterThresholdSize				= 'thresholdSize'
	ParameterThresholdTime				= 'thresholdTime'
	ParameterThresholdPeers				= 'thresholdPeers'
	ParameterThresholdSeeds				= 'thresholdSeeds'
	ParameterThresholdLeeches			= 'thresholdLeeches'

	ParameterLink						= 'link'

	ParameterId							= 'id'
	ParameterIdGaia						= 'idGaia'
	ParameterIdGaiaItem					= 'idGaiaItem'
	ParameterIdGaiaStream				= 'idGaiaStream'
	ParameterIdOrion					= 'idOrion'
	ParameterIdOrionStream				= 'idOrionStream'
	ParameterIdOrionMovie				= 'idOrionMovie'
	ParameterIdOrionCollection			= 'idOrionCollection'
	ParameterIdOrionShow				= 'idOrionShow'
	ParameterIdOrionSeason				= 'idOrionSeason'
	ParameterIdOrionEpisode				= 'idOrionEpisode'
	ParameterIdProviderLocal			= 'idProviderLocal'
	ParameterIdProviderUniversal		= 'idProviderUniversal'
	ParameterIdProviderCollection		= 'idProviderCollection'
	ParameterIdProviderItem				= 'idProviderItem'

	ParameterHash						= 'hash'
	ParameterHashContainer				= 'hashContainer'
	ParameterHashContainerUnknown		= 'hashContainerUnknown'
	ParameterHashContainerMd5			= 'hashContainerMd5'
	ParameterHashContainerSha1			= 'hashContainerSha1'
	ParameterHashContainerSha256		= 'hashContainerSha256'
	ParameterHashContainerSha512		= 'hashContainerSha512'
	ParameterHashFile					= 'hashFile'
	ParameterHashFileUnknown			= 'hashFileUnknown'
	ParameterHashFileMd5				= 'hashFileMd5'
	ParameterHashFileSha1				= 'hashFileSha1'
	ParameterHashFileSha256				= 'hashFileSha256'
	ParameterHashFileSha512				= 'hashFileSha512'
	ParameterHashOther					= 'hashOther'
	ParameterHashOtherUnknown			= 'hashOtherUnknown'
	ParameterHashOtherMd5				= 'hashOtherMd5'
	ParameterHashOtherSha1				= 'hashOtherSha1'
	ParameterHashOtherSha256			= 'hashOtherSha256'
	ParameterHashOtherSha512			= 'hashOtherSha512'

	ParameterVideoQuality				= 'videoQuality'
	ParameterVideoQualityInexact		= 'videoQualityInexact'
	ParameterVideoResolution			= 'videoResolution'
	ParameterVideoResolutionInexact		= 'videoResolutionInexact'
	ParameterVideoWidth					= 'videoWidth'
	ParameterVideoWidthInexact			= 'videoWidthInexact'
	ParameterVideoHeight				= 'videoHeight'
	ParameterVideoHeightInexact			= 'videoHeightInexact'
	ParameterVideoAspect				= 'videoAspect'
	ParameterVideoAspectInexact			= 'videoAspectInexact'
	ParameterVideoCodec					= 'videoCodec'
	ParameterVideoDepth					= 'videoDepth'
	ParameterVideoRange					= 'videoRange'
	ParameterVideo3d					= 'video3d'

	ParameterAudioType					= 'audioType'
	ParameterAudioChannels				= 'audioChannels'
	ParameterAudioSystem				= 'audioSystem'
	ParameterAudioCodec					= 'audioCodec'
	ParameterAudioLanguage				= 'audioLanguage'
	ParameterAudioLanguageInexact		= 'audioLanguageInexact'

	ParameterSubtitleType				= 'subtitleType'
	ParameterSubtitleLanguage			= 'subtitleLanguage'
	ParameterSubtitleLanguageInexact	= 'subtitleLanguageInexact'

	ParameterReleaseType				= 'releaseType'
	ParameterReleaseFormat				= 'releaseFormat'
	ParameterReleaseEdition				= 'releaseEdition'
	ParameterReleaseNetwork				= 'releaseNetwork'
	ParameterReleaseGroup				= 'releaseGroup'
	ParameterReleaseUploader			= 'releaseUploader'

	ParameterFileName					= 'fileName'
	ParameterFileNameInexact			= 'fileNameInexact'
	ParameterFileNameProcess			= 'fileNameProcess'
	ParameterFileExtra					= 'fileExtra'
	ParameterFileSize					= 'fileSize'
	ParameterFileSizeInexact			= 'fileSizeInexact'
	ParameterFileContainer				= 'fileContainer'
	ParameterFilePack					= 'filePack'

	ParameterSourceType					= 'sourceType'
	ParameterSourcePeers				= 'sourcePeers'
	ParameterSourceSeeds				= 'sourceSeeds'
	ParameterSourceSeedsInexact			= 'sourceSeedsInexact'
	ParameterSourceLeeches				= 'sourceLeeches'
	ParameterSourceLeechesInexact		= 'sourceLeechesInexact'
	ParameterSourceTime					= 'sourceTime'
	ParameterSourceTimeInexact			= 'sourceTimeInexact'
	ParameterSourceTimeFormat			= 'sourceTimeFormat'
	ParameterSourcePopularity			= 'sourcePopularity'
	ParameterSourceApproval				= 'sourceApproval'
	ParameterSourceOrigin				= 'sourceOrigin'
	ParameterSourceProvider				= 'sourceProvider'
	ParameterSourcePublisher			= 'sourcePublisher'
	ParameterSourceHoster				= 'sourceHoster'

	ParameterAccessType					= 'accessType'
	ParameterAccessOffline				= 'accessOffline'
	ParameterAccessDirect				= 'accessDirect'
	ParameterAccessMember				= 'accessMember'
	ParameterAccessOpen					= 'accessOpen'
	ParameterAccessOrion				= 'accessOrion'
	ParameterAccessDebrid				= 'accessDebrid'
	ParameterAccessCache				= 'accessCache'

	##############################################################################
	# EXACT
	##############################################################################

	ExactYes	= True		# The value is an exact value.
	ExactNo		= False		# The value is an inexact/estimated/generated value.
	ExactRaw	= 'raw'		# The raw, unprocessssed value.
	ExactTime	= 'time'	# The time the value was added.
	ExactAuto	= None		# Try the exact value, and if it does not exist, use the inexact value.

	##############################################################################
	# VALIDATE
	##############################################################################

	ValidateNone	= False
	ValidateStrict	= True
	ValidateLenient	= 'lenient'	# Validate streams that have a file name and the name has a minimum length. Do not validate shorter names.

	##############################################################################
	# FORMAT
	##############################################################################

	FormatKodi		= 'kodi'		# Returns the value as required by Kodi.
	FormatDecorate	= 'decorate'	# Returns the decorated value with units, color, bold, and other formatting.
	FormatBold		= 'bold'		# Same as FormatDecorate, but without color.
	FormatColor		= 'color'		# Same as FormatDecorate, but without bold.
	FormatBasic		= 'basic'		# Same as FormatDecorate, but without color and bold.
	FormatNone		= None			# Returns the raw unprocessed value.

	##############################################################################
	# LABEL
	##############################################################################

	LabelShort		= 'short'		# Short unit label, typically an abbreviation with capital case letters.
	LabelMedium		= 'medium'		# Medium unit label, typically a semi-abbreviation with capital or camel case letters.
	LabelLong		= 'long'		# Full unit label, typically the full name with camel case letters.
	LabelSettings	= 'settings'	# Use the label type specified by the user in the settings.
	LabelForce		= 'force'		# Same as LabelSettings. But if LabelSettings was disabled, a label is still forced by using the default layout.
	LabelDetails	= 'details'		# Concatenated primary and secondary labels in stream info dialogs.
	LabelHidden		= 'hidden'		# Do not show the label at all.
	LabelNone		= None			# Raw unprocessed label.

	# Internal Only
	LabelDefault	= 'default'
	LabelList1		= 'list1'		# Label to use for the stream list in the special navigation.
	LabelList2		= 'list2'		# Label to use for the stream list in the directory navigation.
	LabelList3		= 'list3'		# Label to use for the stream list in the multi-line dialog navigation.
	LabelList4		= 'list4'		# Label to use for the stream list in the single-line dialog navigation.
	LabelInfo1		= 'info1'		# Main label to use in stream info dialogs.
	LabelInfo2		= 'info2'		# Extended label to use in stream info dialogs.
	LabelSettings1	= 'settings1'	# Main label to use in settings dialogs.
	LabelSettings2	= 'settings2'	# Extended label to use in settings dialogs. Typically the prefix wrapped in brackets added before LabelSettings1.

	LabelLength = {
		LabelShort	: 3,
		LabelMedium	: 5,
	}

	##############################################################################
	# ORDER
	##############################################################################

	OrderInterface	= 'interface'	# Order in which labels are presented to the user in dialogs. Should typically group similar values together and place common values first.
	OrderSorting	= 'sorting'		# Order in which values are sorted. Typically sorting is done from best to worst, or otherwise alphabetically.

	##############################################################################
	# SPLIT
	##############################################################################

	SplitNone	= None
	SplitLeft	= 'left'
	SplitRight	= 'right'

	##############################################################################
	# TITLE
	##############################################################################

	TitleNone		= None
	TitleAll		= 'all'
	TitleMain		= 'main'
	TitleCollection	= 'collection'
	TitleEpisode	= 'episode'
	TitleDefault	= TitleAll
	TitleLimit		= [125, 75, 50]
	TitleMatches	= {}

	##############################################################################
	# DURATION
	##############################################################################

	DurationMovie	= 7200	# 2 hours.
	DurationShow	= 2100	# 35 minutes.
	DurationSpecial	= 600	# 10 minutes.
	DurationUnknown	= 3600	# 1 hour.
	DurationDay		= 86400 # 1 day

	##############################################################################
	# SETTINGS
	##############################################################################

	SettingsLanguage	= None
	SettingsUsage		= None

	##############################################################################
	# THRESHOLD
	##############################################################################

	Threshold = {
		'settings'				: False,	# If thresholds were loaded from the settings yet.

		'validate'				: 10,		# The minimum file name length lenient validation.

		# NB: If these values change, the help labels might have to be updated (eg: currently it only mentions file size, since the other values are 0).
		# Minimum file size considered valid.
		'size' : {
			'common'			: 20971520,		# 20 MB
			'movie'				: 83886080,		# 80 MB.
			'show'				: 104857600,	# 100 MB.
			'episode'			: 20971520,		# 20 MB.
		},

		'time'					: 0,		# The maximum age in number of seconds considered valid.
		'peers'					: 0,		# Minimum number of peers/seeds/leeches considered valid. Leave this at 0, since many 0-seed torrents are still cached with a debrid service, or the seed count is outdated. Users can manually filtere these out using filters.
		'seeds'					: 0,
		'leeches'				: 0,

		'fake'					: 0.7,		# The minimum fakeness threshold. Most have a value of 0.75+.

		'filename'				: 0.2,		# The minimum filename length (percentage of the entire file name) considered valid for usenet filename cleaning.

		'title'	: {
			'base'				: 0.7,		# Minimum ratio of title-filename matches considered valid (will change from settings).
			'maximum'			: 0.95,		# The maximum threshold for dynamically calculated thresholds.
			'strict'			: 1.3,		# Value to multiply dynamically calculated strict thresholds with.
			'concatenated' : {
				'start'			: 0.6,		# Value to multiply dynamically calculated thresholds with 2 concatentated titles, matching against the ratio of a single title.
				'multiplier'	: 0.85,		# Value to multiply dynamically calculated thresholds with 2 concatentated titles, matching against the ratio of the concatenated title. Allows for short words like "aka" between the concatenated titles.
				'count'			: 2,		# The number of different titles that appear in the same filename that will result in a valid match. Usefull for Zooqle that often contains 2-4 titles in the filename (eg: English, Russian, and French).
				'matched'		: 7,		# The minimum number of words that must appear in the 'count' concatenated titles, to avoid single words from different titles adding up to 'count' too easily.
				'unmatched'		: 5,		# The maximum number of unmatched words in concatenated titles. If there are two many words that are not in the title, it should be rejected.
			},
			'short' : {
				'length'		: 3,		# The string length at which titles are considered short.
				'multiplier'	: 0.85,		# Value to multiply dynamically calculated thresholds with for short titles.
				'letter'		: 0.1,		# Value to multiply the multiplier with for every letter in the short title.
			},
			'long' : {
				'length'		: 30,		# The string length at which titles are considered long.
				'multiplier'	: 1.0,		# Value to multiply dynamically calculated thresholds with for long titles. Even 0.95 is too low. Otherwise the file name "the lord of the rings the return of the king" matches the title "the lord of the rings the two towers".
			},
			'multiple' : {					# Thresholds used when iteratively matching multiple file names
				'start'			: 2.0,		# The starting adjustment ratio that other limits like "base" are multiplied with. A value of 2 means all thresholds are twice as strict. A value of 1 means use the normal unadjusted limits
				'decrease'		: 0.05,		# How much do decrease the start ratio with during each iteration. Smaller values result in higher processing time, larger values might be too coarse if matching file names that are very similar (eg collection packs).
			},
		},
	}

	##############################################################################
	# TIME
	##############################################################################

	TimeDate		= 'date'		# Output in date/time format.
	TimeDuration	= 'duration'	# Output in duration format.
	TimeSeconds		= 'seconds'		# Output in number of seconds.
	TimeDays		= 'days'		# Output in number of days.
	TimeDefault		= TimeDays		# NB: Days assumed when filtering age in _filterLimit().
	TimeNone		= None			# Output timestamp.

	##############################################################################
	# NUMBER
	##############################################################################

	NumberPack				= -1	# Season/episode number used to indicate an entire pack.
	NumberSpecial			= 0		# Episode number used to indicate special episodes.

	# Exclude numbers if it is a disk.
	# Eg: Avatar Extended Cut - Disk 2 [DVD9 PAL - Ita Eng] MIRCrew
	ExpressionNumberRange	= '(?<!dis[ck]){symbol_start}(?<![^\d]\d{separator})(?<![^\d]\d{separator})(?<![^\d]\d{separator}{{2}})(?:(%s){separator}?[\-\–\/]{separator}?(%s))(?!{separator}+\d{separator})(?!{separator}\d[^\d])(?!\.{{2}}){symbol_end}(?<!\.{{2}})'
	ExpressionNumberList	= '(?<!dis[ck]){symbol_start}(?:(%s){separator}+)(?:(%s){separator}+)?(?:(%s){separator}+)?(?:(%s){separator}+)?(?:(%s){separator}+)?(?:(%s){separator}+)?(?:(%s){separator}+)?(?:(%s){separator}+)?(?:(%s){separator}+)?(?:(%s){separator}*)?(?!\.{{2}}){symbol_end}(?<!\.{{2}})'

	##############################################################################
	# EXPRESSIONS
	##############################################################################

	# [NOT APPLICABLE ANYMORE] Do not use re.UNICODE, since there are problems with expressions that contain unicode characters (eg (?:a|à)).
	# re.UNICODE is importnant. Otherwise IGNORECASE is not applied to unicode characters. Eg: The first character in "Сезон" will not match a lower cyrillic character 'es'.
	ExpressionFlags				= re.IGNORECASE | re.UNICODE
	ExpressionFlagsCase			= re.UNICODE

	ExpressionGroups			= 100 # The maximum number of named groups allowed in Python's re module.

	ExpressionSymbol			= u'[\s\.\-\–\_\,\;\+\&\|\\\/\:\(\)\{\}\[\]\<\>\$\%\^\*\~\=\#\"\'\`\!\?]'
	ExpressionSymbolAlternative	= u'[\s\.\-\–\_\,\;\+\&\|\\\/\:\(\)\{\}\[\]\<\>\$\%\^\*\~\=\#\"\'\`]' # Without ! and ?.
	ExpressionSymbolStart		= u'(?:^|' + ExpressionSymbol + '+)'
	ExpressionSymbolEnd			= u'(?:$|' + ExpressionSymbol + '+)'
	ExpressionGlyph				= u'[^a-zA-Z\d]'
	ExpressionGlyphStart		= u'(?:^|' + ExpressionGlyph + '+)'
	ExpressionGlyphEnd			= u'(?:$|' + ExpressionGlyph + '+)'
	ExpressionSeparator			= u'[\s\.\-\–\_\,\+\&\|\\\/\:]'
	ExpressionSeparatorExtra	= u'[\s\.\-\–\_\,\+\&\|\\\/\:\(\[\{]'
	ExpressionSeparatorBasic	= u'[\s\.\-\–\_\,\+]'
	ExpressionBrackets			= u'[\(\[\{\)\]\}]'
	ExpressionBracketsStart		= u'[\(\[\{]'
	ExpressionBracketsEnd		= u'[\)\]\}]'

	ExpressionReplacement		= None

	ExpressionPrecede			= None
	ExpressionPrecedeSet		= ['(?<!%s)', '(?<!%s' + ExpressionSeparator + ')']
	ExpressionPrecedeSeparator	= ['with', 'and', 'plus', 'including', 'incl', 'full', '\+', '&']
	ExpressionPrecedeKeyword	= ['bluray', 'dvd', 'dis[ck]']

	ExpressionNumber			= u'\d+'
	ExpressionNumberGroup		= u'([\d\,\.\s]+)'
	ExpressionNumberSeparator	= u'[\,\.\s]'
	ExpressionNumberSucceed		= u'(?!\d)'

	ExpressionYear				= u'(?:19|2[01])\d{{2}}'
	ExpressionYearSingle		= '(?<!' + ExpressionYear + ExpressionSeparator + ')' + ExpressionYear + '(?!' + ExpressionSeparator + '+' + ExpressionYear + ')'
	ExpressionYearMultiple		= ExpressionYear + ExpressionSeparator + '+(?:to)?' + ExpressionSeparator + '*' + ExpressionYear

	ExpressionYearGroup			= u'(' + ExpressionYear + ')'
	ExpressionYearGroupSingle	= '(?<!' + ExpressionYear + ExpressionSeparator + ')' + ExpressionYearGroup + '(?!' + ExpressionSeparator + '+' + ExpressionYear + ')'
	ExpressionYearGroupMultiple	= ExpressionYearGroup + ExpressionSeparator + '+(?:to)?' + ExpressionSeparator + '*' + ExpressionYearGroup

	# Multiple groups/words in any order.
	ExpressionKeyword			= 'keyword'
	ExpressionSequential		= 'sequential'
	ExpressionNonsequential		= 'nonsequential'

	# There is a problem with Japanese (anime) and Chinese file names.
	# In non-Latin alphabets, spaces are rarely used and all characters are concatenated.
	# This is generally not a problem when looking only at Japanese/Chinese characters.
	# However, these file names often also contain Latin characters (video quality, resolution, release network, etc).
	# Some of these file names then also do not add spaces between the Latin an non-Latin characters.
	# This means that ExpressionSymbol does not see these as separate words, but rather one long word.
	# This in turn means that much of the metadata cannot be extracted.
	# Hence, use ExpressionGlyph instead of ExpressionSymbol, which will see any non alphanumeric character as symbol.
	# Using ExpressionGlyph takes a little longer per full-stream-extraction than ExpressionSymbol:
	#	Intel: 16.52 ms (symbol) -> 18.54 ms (glyph) per item (full metadata load, extraction, and validation).
	#	Odroid: 49.38 ms (symbol) -> 52.45 ms (glyph) per item (full metadata load, extraction, and validation).
	ExpressionGroup = {
		ExpressionKeyword : {
			1 : u'{value1}',
			2 : u'{value1}{glyph}*{value2}|{value2}{glyph}*{value1}',
			3 : u'{value1}{glyph}*{value2}{glyph}*{value3}|{value1}{glyph}*{value3}{glyph}*{value2}|{value2}{glyph}*{value1}{glyph}*{value3}|{value2}{glyph}*{value3}{glyph}*{value1}|{value3}{glyph}*{value1}{glyph}*{value2}|{value3}{glyph}*{value2}{glyph}*{value1}',
		},
		ExpressionSequential : {
			1 : u'{glyph_start}({value1}){glyph_end}',
			2 : u'{glyph_start}({value1}{glyph}*{value2}|{value2}{glyph}*{value1}){glyph_end}',
			3 : u'{glyph_start}({value1}{glyph}*{value2}{glyph}*{value3}|{value1}{glyph}*{value3}{glyph}*{value2}|{value2}{glyph}*{value1}{glyph}*{value3}|{value2}{glyph}*{value3}{glyph}*{value1}|{value3}{glyph}*{value1}{glyph}*{value2}|{value3}{glyph}*{value2}{glyph}*{value1}){glyph_end}',
		},
		ExpressionNonsequential : {
			1 : u'{glyph_start}({value1}){glyph_end}',
			2 : u'{glyph_start}({value1}(?:{glyph}|{glyph}.*{glyph})?{value2}|{value2}(?:{glyph}|{glyph}.*{glyph})?{value1}){glyph_end}',
			3 : u'{glyph_start}({value1}(?:{glyph}|{glyph}.*{glyph})?{value2}(?:{glyph}|{glyph}.*{glyph})?{value3}|{value1}(?:{glyph}|{glyph}.*{glyph})?{value3}(?:{glyph}|{glyph}.*{glyph})?{value2}|{value2}(?:{glyph}|{glyph}.*{glyph})?{value1}(?:{glyph}|{glyph}.*{glyph})?{value3}|{value2}(?:{glyph}|{glyph}.*{glyph})?{value3}(?:{glyph}|{glyph}.*{glyph})?{value1}|{value3}(?:{glyph}|{glyph}.*{glyph})?{value1}(?:{glyph}|{glyph}.*{glyph})?{value2}|{value3}(?:{glyph}|{glyph}.*{glyph})?{value2}(?:{glyph}|{glyph}.*{glyph})?{value1}){glyph_end}',
		},
	}

	# Cannot repeat groups for consecutive episode detection. Each consecutive group must be appended into a long final expression.
	# In the languages, accomodate formatting/encoding errors. Eg: "à" might show up as "a?".
	# (?!26(?:\d|$)): Do not detect video codec, including when cut off at the end (eg: "x265" or "x26").
	# (?!\d{{2,3}}) and (?!\d{{3,4}}): Do not detect resolutions (eg: "(480x320)").
	# (?!(?:1[56789]|2[01])\d{{2}}): Do not detect years (eg: "S01.1966-1967" or "1883.S01E02").
	ExpressionShow = {
 		'groups'		: 15, # NB: Python's regex only supports a maximum of 100 groups. This value might need to be lowered if more groups are added.
		'number'		: u'(?![5789]\.1(?!\d)|(?:1[56789]|2[01])\d{2})(?:\d+(?!\.0(?!\d))(?!\d*[ipbkmg]))', # Exclude audio channels (eg: 7.1 or 2.0, or ddp5.1) and years. Also not followed by a letter (eg: 1080p or 100MB).
		'exclude'		: u'(s[789]\d(?!\d)|007)', # Some movie file names contain various Sxx words (eg S74, S83, S92, etc). Not sure what they are. Eg Toy Story 4 2019 (2160p x265 10bit S82 Joy). Also exclude "007" since that is often James Bond stuff, otherwise it might be detected as a season number (in titleValid() -> numberShowIndex()).
		'special'		: ExpressionSymbolStart + u'(?!26(?:\d|$))(\d)(0[1-9]|[1-9][0-9])' + ExpressionSymbolEnd, # Special episode number (eg: "101" for S01E01).
		'disc'			: u'(?:' + ExpressionSeparatorExtra + '*d' + ExpressionSeparatorExtra + '*\d{1,2})?', # Disk number (eg: S01D5).
		'prefix'		: u'(?:\d|' + ExpressionSymbol + '|^)',
		'divider'		: u'[x×]', # × used by ElliteTorrent
		'ordinal'		: u'(?:\s*%s(?=\W|\d|_|x\d))?', # Contains {nonalphabet}, but hardcode it here, since it is not replaced.
		'unordinal'		: u'(?!%s)', # Also exclude 1st/2nd/3rd/etc (One Piece Season 1 - 3rd Voyage [SE][720p][x264][JPN][SUB]).
		'nonalphabet'	: u'(?=\W|\d|_|x\d)', # Ordinals and episode labels need to be followed by numbers/symbols, otherwise "Generation Kill (2008) Season 1 S01 Extras ..." the "E" in "Extras" is seen as an episode label.
		'description'	: u'(?!\s*episodes)', # Eg: Star Trek Original Series: Season 1: 30 Episodes 5 GB File Size:..
		'duration'		: u'(?<!\dm)(?<!\dm\d)', # Eg: Avatar(ExtendedCollectorsEdition)(2h58m09s)(3D inserts2D)2009.halfOU(TopGun)

		# Eg: One Piece S03 - (078-091)" and "One Piece Season 3 Complete 031 - 047 720p HDTV x264 [i_c]
		# Eg: One Piece - S06 Voyage 1,2,3 (337-372) English Dub
		# Eg: [Pn8] One Piece S06 Voyage 4 (373-384) [Funi-DL] [720p] [Dub]
		'custom'		: u'(?:(?<!^)(?<!season' + ExpressionSeparator + ')\s*[\(\[]\s*|' + ExpressionSeparator + '*(?:complett?e?|komplett|pack|collecti(?:on|e)s?|colecci(?:o|ó)n|cole(?:c|ç)(?:a|ã)o|collezione|kollektion(?:en)?|sammlung|verzameling|samling|kolekcja|kolekce|koleksiyonu|трилогия|коллекция|полный|int(?:e|é)grale?|voyage' + ExpressionSeparator + '*(?:\d+' + ExpressionSeparator + '*)+[\(\[]?)' + ExpressionSeparator + '*)',

		'show_forward' : { # Both season and episode number (season_label season_number episode_label episode_number).
			'group'		: {'season' : (0, 2), 'episode' : None}, # Groups to extract. None = all groups. Not present = no groups.
			'main'		: u'{prefix}(?:0*({season_number}){divider}0*(?!26(?:\d|$))(?!\d{{3,4}})({episode_number})|{season_label}{separator}*0*({season_number}){ordinal}{separator}*(?:{custom}?{episode_label}|{custom}){nonalphabet}{separator}*0*({episode_number}){ordinal})',
			'repeat'	: u'(?:{separator}*(?:&|{range}|{conjunction})*{separator}*(?:0*(?:{season_number})?{divider}0*(?!26(?:\d|$))(?!\d{{3,4}})({episode_number})|(?:{season_label}{separator}*0*(?:{season_number}{ordinal}){separator}*)?{episode_label}?{nonalphabet}{separator}*0*({episode_number}){ordinal}(?={season_label}{separator}*\d+|{episode_label}{nonalphabet}{separator}*\d+|{symbol}|$)))?',
		},
		'show_backward' : { # Both season and episode number (season_number season_label episode_number episode_label).
			'group'		: {'season' : (0, ), 'episode' : None}, # Groups to extract. None = all groups. Not present = no groups.
			'main'		: u'{prefix}(?:0*({season_number}){separator}*{season_label}{separator}*0*({episode_number}){separator}*(?={episode_label}{nonalphabet}|{separator}*(?:&|{range}|{conjunction}|-){separator}*\d+{separator}*{episode_label}))',
			'repeat'	: u'(?:{separator}*(?:&|{range}|{conjunction})*{separator}*(?:(?:0*(?:{season_number}){separator}*{season_label}{separator}*)?0*({episode_number}){separator}*{episode_label}{nonalphabet}(?!{separator}*{season_label})(?={separator}*\d+{separator}*{episode_label}{nonalphabet}|{symbol}|$)))?',
		},
		# Ignore a season number if followed by "joy". Eg: the huntsman winters war 2016 extended (1080p x265 10bit s91 joy).mkv
		'season_forward' : { # Only season number (season_label season_number).
			'group'		: {'season' : None}, # Groups to extract. None = all groups. Not present = no groups.
			'main'		: u'{prefix}(?:(?<=[^1-9])0*({season_number}){divider}\d(?!\d{{2,3}})|{season_label}{separator_extra}*(?!(?:19|2[01])\d{{2}})0*({season_number})(?!{separator}joy){ordinal}{disc}(?={season_label}{separator_extra}*\d+|{episode_label}{nonalphabet}{separator}*\d+|{symbol}|$))',
			'repeat'	: u'(?:{separator}*(?:&|{range}|{conjunction})*{separator}*(?:(?<=[^1-9])0*({season_number})?{divider}\d(?!\d{{2,3}})|(?:{season_label}|{separator}){separator}*(?!(?:19|2[01])\d{{2}})0*({season_number}){unordinal}{description}{ordinal}{disc}(?={season_label}{separator}*\d+|{episode_label}{nonalphabet}{separator}*\d+|{symbol}|$)))?',
		},
		'season_backward' : { # Only season number (season_number season_label).
			'group'		: {'season' : None}, # Groups to extract. None = all groups. Not present = no groups.
			'main'		: u'{prefix}(?:(?!(?:19|2[01])\d{{2}})0*{duration}({season_number}){ordinal}{disc}{separator_extra}*{season_label}(?=\d+{separator_extra}*{season_label}|\d+{separator}*{episode_label}{nonalphabet}|{symbol}|$))',
			'repeat'	: u'(?:{separator}*(?:&|{range}|{conjunction})*{separator}*(?:(?!(?:19|2[01])\d{{2}})0*({season_number}){ordinal}{disc}{separator}*(?:{season_label}|{separator})(?=\d+{separator}*{season_label}|\d+{separator}*{episode_label}{nonalphabet}|{symbol}|$)))?',
		},
		'episode_forward' : { # Only episode number (episode_label episode_number).
			'group'		: {'episode' : None}, # Groups to extract. None = all groups. Not present = no groups.
			'main'		: u'{prefix}(?:(?:^|\d+|{separator}){divider}0*(?!26(?:\d|$))(?!\d{{3,4}})({episode_number})(?={season_label}{separator}*\d+|(?:{custom}?{episode_label}|{custom}){nonalphabet}{separator}*\d+|{symbol}|$)|{episode_label}{nonalphabet}{separator}*0*({episode_number}){ordinal}(?={season_label}{separator}*\d+|{episode_label}{nonalphabet}{separator}*\d+|{symbol}|$))',
			'repeat'	: u'(?:{separator}*(?:&|{range}|{conjunction})*{separator}*(?:(?:^|\d+|{separator}){divider}0*(?!26(?:\d|$))(?!\d{{3,4}})({episode_number}){unordinal}|(?:{season_label}{separator}*0*(?:\d+){separator}*)?{episode_label}?{nonalphabet}{separator}*0*({episode_number}){unordinal}(?={season_label}{separator}*\d+|{episode_label}{nonalphabet}{separator}*\d+|{symbol}|$)))?',
		},
		'episode_backward' : { # Only episode number (episode_number episode_label).
			'group'		: {'episode' : None}, # Groups to extract. None = all groups. Not present = no groups.
			'main'		: u'{prefix}(?<!\d)(?:^|{symbol})(?:0*({episode_number}){ordinal}{separator}*{episode_label}{nonalphabet}(?=\d+{separator}*{season_label}|\d+{separator}*{episode_label}{nonalphabet}|{symbol}|$))',
			'repeat'	: u'(?:{separator}*(?:&|{range}|{conjunction})*{separator}*(?:(?:0*(?:\d+){separator}*{season_label}{separator}*)?0*({episode_number}){ordinal}{separator}*{episode_label}?{nonalphabet}(?=\d+{separator}*{season_label}|\d+{separator}*{episode_label}{nonalphabet}|{symbol}|$)))?',
		},

		# (?!\d+(?:[\s\.\,\-\_]rar|$)) to not match "part01.rar" and (?<!\d{3}) to not match "720p 2.0".
		'language' : (
			# Place English first for _numberShowExpression().
			('english', {
				'season'		: u'(?:s(?:e|easons?|eries?)?)',
				'episode'		: u'(?:e(?:p|pisodes?)?|(?<!\d{3})p(?:art(?!\d+(?:[\s\.\,\-\–\_]rar|$)))?)',
				'full'			: u'(?:(?:all\s*(?:of\s*)?(?:the\s*)?|full|total)?(?:seasons?|series?|episodes?|parts?|batch(?:es)?))',
				'pack'			: u'(?:(?:all\s*(?:of\s*)?(?:the\s*)?|full|total)?(?:seasons|series|episodes|parts|batches))',
				'range'			: u'(?:to|till|until)',
				'conjunction'	: u'(?:and)',
				'ordinal'		: u'(?:st|nd|rd|th)',
			}),
			('french', {
				'season'		: u'(?:s(?:a|aisons?)?|box)',
				'episode'		: u'(?:(?:e|é|e\?)(?:p|pisode)?|(?<!\d{3})p(?:art(?!\d+(?:[\s\.\,\-\–\_]rar|$))|artie)?)',
				'full'			: u'(?:(?:toutes\s*(?:les\s*)?)?(?:saisons?|box|(?:e|é|e\?)pisodes?|part(?:ie)?s?))',
				'pack'			: u'(?:(?:toutes\s*(?:les\s*)?)?(?:saisons|box|(?:e|é|e\?)pisodes|part(?:ie)?s))',
				'range'			: u'(?:a|à|a\?|pour|de|vers|en|avant(?:\s*de)?|jusqu\'?(?:a|à|a\?)?)',
				'conjunction'	: u'(?:et|aussi)',
				'ordinal'		: u'(?:e)',
			}),
			('russian', {
				'season'		: u'(?:сезоны?)',
				'episode'		: u'(?:сери[ия]|эпизоды?)',
				'full'			: u'(?:(?:bсе\s*)?(?:сезоны?|сери[ия]|эпизоды?))',
				'pack'			: u'(?:(?:bсе\s*)?(?:сезоны|эпизоды))',
				'range'			: u'(?:до)',
				'conjunction'	: u'(?:и|a)',
				'ordinal'		: u'(?:(?:ы|о)?й|ая|ое|ые)',
			}),
			('german', {
				'season'		: u'(?:s(?:t|taffeln?|erien?|aisons?)?)',
				'episode'		: u'(?:fo(lgen?)?|te(ile?)?|e(?:p|pisoden?))',
				'full'			: u'(?:(?:(?:alle?|volle?|ganze?)\s*)?(?:staffeln?|serien?|saisons?|folgen?|teile?|episoden?|kapitel))',
				'pack'			: u'(?:(?:(?:alle?|volle?|ganze?)\s*)?(?:staffeln|serien|saisons|folgen|teile|episoden|kapitel))',
				'range'			: u'(?:bis|zum?)',
				'conjunction'	: u'(?:und)',
				'ordinal'		: u'(?:s?te)',
			}),
			('dutch', {
				'season'		: u'(?:s(?:e|eizoen(?:en)?|eries?)?)',
				'episode'		: u'(?:af(?:levering(?:en)?)?|de(?:el|len)?)',
				'full'			: u'(?:(?:alle?\s*)?(?:seizoen(?:en)?|series?|aflevering(?:en)?|de(?:el|len)))',
				'pack'			: u'(?:(?:alle?\s*)?(?:seizoenen|series|afleveringen|delen))',
				'range'			: u'(?:tot)',
				'conjunction'	: u'(?:en)',
				'ordinal'		: u'(?:e|d?e|ste)', # Pronounced as "de" and "ste", but typically written as (eg: 1e, 3e)
			}),
			('spanish', {
				'season'		: u'(?:te(?:mporadas?)?|s(?:(?:e|é|e\?)ries?)?)',
				'episode'		: u'(?:e(?:p|pis(?:o|ó|o\?)dio)?|ca(?:p(?:i|í)tulos?)?|(?<!\d{3})p(?:arte)?)',
				'full'			: u'(?:(?:todas\s*(?:as\s*)?)?(?:temp(?:oradas?)?|s(?:e|é|e\?)ries?|epis(?:o|ó|o\?)dios?|cap(?:i|í)tulos?|partes?))',
				'pack'			: u'(?:(?:todas\s*(?:as\s*)?)?(?:temporadas|s(?:e|é|e\?)ries|epis(?:o|ó|o\?)dios|cap(?:i|í)tulos|partes))',
				'range'			: u'(?:al?|para|en|hasta(?:\s*que)?|hacia|por)',
				'conjunction'	: u'(?:y|e)',
				'ordinal'		: u'(?:ª|º|a|o|ao)',
			}),
			('portuguese', {
				'season'		: u'(?:te(?:mporada)?|s(?:(?:e|é|e\?)ries?)?)',
				'episode'		: u'(?:e(?:p|pis(?:o|ó|o\?)dio)?|ca(?:p(?:i|í)tulo)?|(?<!\d{3})p(?:arte)?)',
				'full'			: u'(?:(?:todas\s*(?:as\s*)?)?(?:temporadas?|s(?:e|é|e\?)ries?|epis(?:o|ó|o\?)dios?|cap(?:i|í)tulos?|partes?))',
				'pack'			: u'(?:(?:todas\s*(?:as\s*)?)?(?:temporadas|s(?:e|é|e\?)ries|epis(?:o|ó|o\?)dios|cap(?:i|í)tulos|partes))',
				'range'			: u'(?:a|at(?:e|é|e\?)(?:\s*que)?|ate(?:\s*que)?)',
				'conjunction'	: u'(?:e)',
				'ordinal'		: u'(?:ª|º|a|o|ao)',
			}),
			('italian', {
				'season'		: u'(?:s(?:t|tagione)?)',
				'episode'		: u'(?:e(?:p|pisodio)?|(?<!\d{3})p(?:arte)?)',
				'full'			: u'(?:(?:tutte\s*(?:le\s*)?)?(?:stagion[ei]|episodio?|part[ei]))',
				'pack'			: u'(?:(?:tutte\s*(?:le\s*)?)?(?:stagioni|episodi|parti))',
				'range'			: u'(?:a|per|di|da|verso|in|fino(?:\s*a)?|sino(?:\s*a)?|prima(?:\s*di)?)',
				'conjunction'	: u'(?:e|di|con|poi|pi(?:u|ù|u\?))',
				'ordinal'		: u'(?:ª|º|a|o|ao)',
			}),
		),
	}

	# Any other keywords that should be ignored during title matching that is not part of other keywords.
	# Only keywords not appearing in the title will be removed, so one does not have to be conservative when adding keywords here.
	# Do not group together, this will be done automatically.
	ExpressionIgnore = (
		u'dvds?(?:\d|iso)?',
		u'cds?(?:\d|iso)?',
		u'blurays?(?:\d|iso)?',
		u'imax',
		u'3d',
		u'(?:h\-?)?sbs',
		u'dl',
		u'the',
		u'dual',
		u'full',
		u'multi',
		u'multi' + ExpressionSeparator + '*lingu(?:al|e)',
		u'internal',
		u'proper',
		u're' + ExpressionSeparator + '*rip(?:ped)?',
		u'repack(?:ed)?',
		u'remaster(?:ed)?',
		u'repost(?:ed)?',
		u'retail',
		u'watch(?:ed)?',
		u'unrated?',
		u'uncensored?',
		u'editions?',
		u'endings?',
		u'(?:the' + ExpressionSeparator + ')?complet(?:e|o)?(?:' + ExpressionSeparator + '*(?:shows?|series?))?',
		u'(?:the' + ExpressionSeparator + ')?remaster(?:ed)?',
		u'(?:the' + ExpressionSeparator + ')?official',
		u'(?:the' + ExpressionSeparator + ')?retail',
		u'(?:the' + ExpressionSeparator + ')?premiere?',
		u'(?:the' + ExpressionSeparator + ')?ultimate',
		u'(?:the' + ExpressionSeparator + ')?alternat(?:e|ive)?',
		u'(?:the' + ExpressionSeparator + ')?movies?',
		u'movies?',
		u'film[es]?',
		u'ultimate',
		u'b(?:o|ô)nus',
		u'complee?t(?:e|a|o|are)?',
		u'box(?:set)?',
		u'saga',
		u'int(?:e|é)grale?',
		u'collecti(?:on|e)s?',
		u'vol(?:ume)?',
		u'(?:\d+th' + ExpressionSeparator + '*)?anniversary',
		u'mega',
		u'(?:(?:with|and|plus|includ(?:es|ing)|[\+\&])?' + ExpressionSeparator + '*(?:full|tons?' + ExpressionSeparator + 'of)' + ExpressionSeparator + '*)?(?:extras?|bonus(?:es)?)',
		u'story',
		u'dis[ck](?:' + ExpressionSeparator + '*\d+)?',
		u'animatics?',
		u'webisodes?',
		u'pilot',
		u'presents?',
		u'finale?',
		u'expand(?:ed)?',
		u'ext(?:end)?(?:ed)?',
		u'(?:limited|ltd)',
		u'(?:tv\s*)?novela',
		u'classic[ae]?',
		u'u' + ExpressionSeparator + '?[ks]' + ExpressionSeparator + '?',
		u'(?:(?:u(?:ltra' + ExpressionSeparator + '*)?)?h[dq]|(?:8|4)k|(?:hd)?(?:2160|1080|720|480|320|240)[ipр]?|sd)', # Titles containing multiple qualities (1917 - Remastered 4K (2019 ITA/ENG) [1080p]).
		u'(?:dts|dd|dolby(?:' + ExpressionSeparator + '*digital)?|e' + ExpressionSeparator + '*?[aа][cс]' + ExpressionSeparator + '*\d|dd(?:plus|p|\+)|true' + ExpressionSeparator + '*hd|atmos|dca|hd' + ExpressionSeparator + '*(?:ma|hra)|aac)', # Multiple audio systems - only one is detected (Amelie.DTS.FR.DD.PL.PAL.DVDR-SNTY.iso)
		u'disney\\\?(?:\'|\`|.?\xB4)?s?',
		u'pixar\\\?(?:\'|\`|.?\xB4)?s?',
		u'hd\-?rip\d?',
		u'vo', # Eg "Deadpool VO HDTS 2016", probably meant "Deadpool VOSTFR HDTS 2016"
		u'ntsc',
		u'pal',
		u'secam',
		u'ipod',
		u'ipad',
		u'torrent[sz]?',
		u'download[sz]?',
		u'leaked',
		u'original(?!.serie)', # Do not apply to "Star Trek The Original Series".
		u'(?<!original.|animated.)series?\d*', # Do not apply to "Star Trek The Original Series", "Star Trek The Animated Series", etc.
		u'seasons?\d*',
		u'temp',
		u'ecc',
		u'microhd', # Is present in the middle of the file name with many hosters.
		u'action',
		u'thriller',
		u'horror',
		u'anmiation',
		u'comedy',
		u'fantasy',
		u'adventure',
		u'mystery',
		u'crime',
		u'western',
		u'sci(?:ence)?' + ExpressionSeparator + '*fi(?:ction)?',
		u'docu?(?:mentary)?',
		u'music(?:al)?',
		u'(?:wizards?|pottermore|(?:j' + ExpressionSeparator + '*k' + ExpressionSeparator + '*)?rowling)', # Harry Potter collections.
		u'(?:two|three|four|five|six|seven|eight|nine)',
		u'original.?(?:name|title)',
		u'\d{2}' + ExpressionSeparator + '*fps', # FPS
		u'\d{1,4}(?:\.\d{1,2})?' + ExpressionSeparator + '*(?:gb|mb)', # Size
		u'\d+[h:]\d+[m:](?:\d+[s])?', # Duration
	)

	ExpressionUsenetNumber		= u'[\[\(\{](?:(?!\d\-\–\d|' + ExpressionYear + u'[\-\–\/\\\]' + ExpressionYear + u')\d+[\_\-\–\.\/\\\]\d+|\d{{2,3}}|\d{{5,}})[\]\)\}]' # Ecludes year, year ranges, and collection number ranges.
	ExpressionUsenetSize		= u'\d+(?:[\.\,]\d+)?\s*(?:bytes?|[kmgt]b(?!ps))' # Exclude kbps.
	ExpressionUsenetSeparator	= u'[\.\-\–\_\s]'
	ExpressionUsenetSeparator2	= u'[\-\–\_\s]'
	ExpressionUsenetQuotes		= u'"(.+?)"'
	ExpressionUsenetYenc		= ExpressionUsenetSeparator + u'yenc(?:$|' + ExpressionUsenetSeparator + u')'
	ExpressionUsenetNfo			= u'\.nfo'
	ExpressionUsenetNzb			= u'\.nzb'
	ExpressionUsenetRar			= u'\.rar\s*\d*'
	ExpressionUsenetPar			= u'\.part?\s*\d*'
	ExpressionUsenetPart		= u'\.\d+'
	ExpressionUsenetExtension	= u'(?:' + ExpressionUsenetNfo + u'|' + ExpressionUsenetNzb + u'|' + ExpressionUsenetPart + u'|' + ExpressionUsenetPar + u'|' + ExpressionUsenetRar + u')+'
	ExpressionUsenetFile		= u'".+?' + ExpressionUsenetExtension + u'"'
	ExpressionUsenetName		= u'(?:' + ExpressionUsenetYenc + '|' + ExpressionUsenetNzb + ')'

	##############################################################################
	# PROHIBITION
	##############################################################################

	ProhibitionSound		= 'sound'
	ProhibitionTrailer		= 'trailer'
	ProhibitionExtra		= 'extra'
	ProhibitionSpoiler		= 'spoiler'
	ProhibitionReview		= 'review'
	ProhibitionRecap		= 'recap'
	ProhibitionSample		= 'sample'
	ProhibitionPromo		= 'promo'
	ProhibitionFan			= 'fan'
	ProhibitionGame			= 'game'
	ProhibitionBook			= 'book'
	ProhibitionPorn			= 'porn'
	ProhibitionNone			= None

	# Make an exception for some prohibited keywords and label them instead of excluding them.
	ExceptionProhibition	= {
		ProhibitionExtra : True, # Too many streams contain "extras" (without being preceded by "with"/"and"/"+"/etc).
		ProhibitionSample : True, # If this is ONLY a sample, let the file size validation remove it.
	}

	# Titles with certain words that should be excluded.
	# Exclude only if the words are not preceeded by "with", "and", "including", "plus", "full", "&", or "+" (eg: "Movie (Year) with sample")
	# These are only applied if the keywords do not appear in the title.
	ExpressionProhibition = {
		'keyword' : {},
		'special' : ['soundtrack', 'trailer', 'sample', 'fan', 'game', 'porn'], # Allow certain keywords for specials (eg: S08 Extras).
		'expression' : [ # Use array, since these can be edited.
			(ProhibitionSound,		u'{precede}(ost|music|albums?|scores?|(?:un)?sound{separator}*tracks?|themes?{separator}*(?:music|songs?|tacks?)|theme{separator}*songs?)'), # Do not include "mp3", since this removes valid links (eg: Kim.Possible.Intégrale.VF.PDTV.XviD.MP3-splanck-BaLLanTeAm).
			(ProhibitionTrailer,	u'{precede}(trailers?|teasers?)'),
			(ProhibitionExtra,		u'{precede}(e?xtras?|bloopers?|deleted{separator}*scenes?|featurett?es?|animatics?)'),
			(ProhibitionSpoiler,	u'{precede}(spoilers?|funny|funniest|(?:best|great(?:est)?){separator}*moments?|easter{separator}*eggs?)'),
			(ProhibitionReview,		u'{precede}(reviews?|analy[sz]es?|discussions?|breakdowns?|react(?:ion)?s?|explain|explanation|explained|recenzja)'),
			(ProhibitionRecap,		u'{precede}(recaps?)'),
			(ProhibitionSample,		u'{precede}(samples?|previews?)'),
			(ProhibitionPromo,		u'{precede}(promo(?:tion)?s?)'),
			(ProhibitionFan,		u'{precede}(fan{separator}*(?:made|content|film|movie|isode))'),
			(ProhibitionGame,		u'(game(?:{separator}*play)?|(?:the{separator}*)?(?:video|pc|console|xbox|ps\d|playstation|nintendo|nds|ios|android|windows)?game|walkthrough)'), # Do not include "RPG", since it is also a release group.
			(ProhibitionBook,		u'((?:(?:e|audio){separator}?)?books?|e{separator}?pub|m4b|h(?:oe?|ö)r(?:spiele?|buch)|l(?:y|ju)dbok|kindle|(?:read{separator}by|reader){separator}[a-z]{{2,}}{separator}[a-z]{{2,}}|pdf|azw3|(?<=\.)(?:djvu|mobi)(?=$))'),
			(ProhibitionPorn,		u'(p[o\*]rn|s[e\*]x(?:y|ual|art)?|xxx|fuck(?:ing|ed)?|f[x\*]+(?:ing|c?k(?:ed)?)|hentai|lesbian|gay|anal|gangbang|orgy|creampie|cum|facial|oral|milf|nudes?|pussy|vigina|cunt|penis|tits?|boobs?|bdsm|threesome|squirt(?:ing)?|masturbat(?:e|ing)?|blowjob|fetish|ebony|hardcore|brazzers|nubiles)'),
		],
	}

	LabelProhibition = {
		LabelDefault : {
			LabelList1		: LabelMedium,
			LabelList2		: LabelMedium,
			LabelList3		: LabelMedium,
			LabelList4		: LabelMedium,
			LabelInfo1		: LabelLong,
			LabelInfo2		: LabelHidden,
			LabelSettings1	: LabelLong,
			LabelSettings2	: LabelHidden,
		},

		ProhibitionSound	: { LabelShort : 'SND',	LabelMedium : 'SOUND',		LabelLong : 'Soundtrack' },
		ProhibitionTrailer	: { LabelShort : 'TRL',	LabelMedium : 'TRAILER',	LabelLong : 'Trailer' },
		ProhibitionExtra	: { LabelShort : 'EXT',	LabelMedium : 'EXTRA',		LabelLong : 'Extra' },
		ProhibitionSpoiler	: { LabelShort : 'SPL',	LabelMedium : 'SPOILER',	LabelLong : 'Spoiler' },
		ProhibitionReview	: { LabelShort : 'RVW',	LabelMedium : 'REVIEW',		LabelLong : 'Review' },
		ProhibitionRecap	: { LabelShort : 'RCP',	LabelMedium : 'RECAP',		LabelLong : 'Recaption' },
		ProhibitionSample	: { LabelShort : 'SMP',	LabelMedium : 'SAMPLE',		LabelLong : 'Sample' },
		ProhibitionPromo	: { LabelShort : 'PRM',	LabelMedium : 'PROMO',		LabelLong : 'Promotion' },
		ProhibitionFan		: { LabelShort : 'FAN',	LabelMedium : 'FAN',		LabelLong : 'Fanmade' },
		ProhibitionGame		: { LabelShort : 'GAM',	LabelMedium : 'GAME',		LabelLong : 'Game' },
		ProhibitionBook		: { LabelShort : 'BOK',	LabelMedium : 'BOOK',		LabelLong : 'Book' },
		ProhibitionPorn		: { LabelShort : 'PRN',	LabelMedium : 'PORN',		LabelLong : 'Pornography' },
	}

	##############################################################################
	# ID
	##############################################################################

	IdNone				= None

	IdCategoryProvider	= 'provider'
	IdCategoryGaia		= 'gaia'
	IdCategoryOrion		= 'orion'
	IdCategoryImdb		= 'imdb'
	IdCategoryTmdb		= 'tmdb'
	IdCategoryTvdb		= 'tvdb'
	IdCategoryTrakt		= 'trakt'
	IdCategorySlug		= 'slug'

	IdTypeMovie			= 'movie'
	IdTypeShow			= 'show'
	IdTypeSeason		= 'season'
	IdTypeEpisode		= 'episode'

	IdTypeStream		= 'stream'			# Some stream ID.
	IdTypeLocal			= 'local'			# Some local ID used by the site/API.
	IdTypeUniversal		= 'universal'		# Some universal ID, such as a UUID or GUID, typically used by usenet sites.
	IdTypeCollection	= 'collection'		# Collection ID, typically used by usenet sites. Can also be used for movie collections.
	IdTypeItem			= 'item'			# Some other item ID.
	IdTypeData			= 'data'			# ID used to identify the stream data (aka hash of some metadata attributes).

	IdExtraProvider		= 'provider'		# Provider ID.
	IdExtraLink			= 'link'			# Source link.
	IdExtraHash			= 'hash'			# File hash.

	IdDefaultMovie		= IdTypeMovie		# Default movie ID to use for IMDb/TMDb/TVDb/Trakt.
	IdDefaultShow		= IdTypeEpisode		# Default movie ID to use for IMDb/TMDb/TVDb/Trakt.

	# Ensures that the ID is always generated with the same order of values.
	IdOrder				= [
							IdExtraProvider,
							IdExtraHash,
							IdExtraLink,

							IdTypeLocal,
							IdTypeUniversal,
							IdTypeCollection,
							IdTypeItem,
						]

	##############################################################################
	# HASH
	##############################################################################

	HashTypeContainer		= 'container'	# The hash present in the container file. For torrents/magnets it is the info hash (Merkel root hash). For NZBs it is the hash of the .nzb container file.
	HashTypeFile			= 'file'		# The hash of the actual file. If there are multiple, it is the global hash of all files (the exact way to caluclate this is undefine).
	HashTypeOther			= 'other'		# Any other type of hash. Newznab sometimes returns a "sha1" attribute. This hash does not seem to be the hash of the .nzb or the actual file. From Newznab's code, the hash seems to be caulcated from the title, but this also does not match. So store it as an other hash.
	HashTypeDefault			= None			# Pick the first best.
	HashTypeOrder			= [HashTypeContainer, HashTypeFile, HashTypeOther]

	HashAlgorithmMd5		= 'md5'
	HashAlgorithmSha1		= 'sha1'
	HashAlgorithmSha256		= 'sha256'
	HashAlgorithmSha512		= 'sha512'
	HashAlgorithmUnknown	= 'unknown'		# Hash algorithm is not known.
	HashAlgorithmDefault	= None			# Pick the first best.
	HashAlgorithmOrder		= [HashAlgorithmSha512, HashAlgorithmSha256, HashAlgorithmSha1, HashAlgorithmMd5, HashAlgorithmUnknown]

	HashLength				= {
								HashAlgorithmMd5	: 32,
								HashAlgorithmSha1	: 40,
								HashAlgorithmSha256	: 64,
								HashAlgorithmSha512	: 128,
							}

	##############################################################################
	# LANGUAGE
	##############################################################################

	LabelLanguage = {
		LabelDefault : {
			LabelList1		: LabelShort,
			LabelList2		: LabelShort,
			LabelList3		: LabelShort,
			LabelList4		: LabelShort,
			LabelInfo1		: LabelLong,
			LabelInfo2		: LabelHidden,
			LabelSettings1	: LabelLong,
			LabelSettings2	: LabelShort,
		},
	}

	##############################################################################
	# SOURCE TYPE
	##############################################################################

	SourceTypeLocal		= 'local'
	SourceTypePremium	= 'premium'
	SourceTypeTorrent	= 'torrent'
	SourceTypeUsenet	= 'usenet'
	SourceTypeHoster	= 'hoster'
	SourceTypeNone		= None

	LabelSourceType = {
		LabelDefault : {
			LabelList1		: LabelLong,
			LabelList2		: LabelMedium,
			LabelList3		: LabelMedium,
			LabelList4		: LabelMedium,
			LabelInfo1		: LabelLong,
			LabelInfo2		: LabelHidden,
			LabelSettings1	: LabelLong,
			LabelSettings2	: LabelMedium,
		},

		SourceTypeLocal		: { LabelShort : 'L',	LabelMedium : 'LOC',	LabelLong : 'Local' },
		SourceTypePremium	: { LabelShort : 'P',	LabelMedium : 'PRE',	LabelLong : 'Premium' },
		SourceTypeTorrent	: { LabelShort : 'T',	LabelMedium : 'TOR',	LabelLong : 'Torrent' },
		SourceTypeUsenet	: { LabelShort : 'U',	LabelMedium : 'USE',	LabelLong : 'Usenet' },
		SourceTypeHoster	: { LabelShort : 'H',	LabelMedium : 'HOS',	LabelLong : 'Hoster' },
	}

	OrderSourceType = {
		SourceTypeLocal		: { OrderInterface : 1,	OrderSorting : 1 },
		SourceTypePremium	: { OrderInterface : 2,	OrderSorting : 2 },
		SourceTypeTorrent	: { OrderInterface : 3,	OrderSorting : 3 },
		SourceTypeUsenet	: { OrderInterface : 4,	OrderSorting : 4 },
		SourceTypeHoster	: { OrderInterface : 5,	OrderSorting : 5 },
	}

	##############################################################################
	# SOURCE PEERS
	##############################################################################

	LabelSourcePeers = {
		LabelDefault : {
			LabelList1		: LabelMedium,
			LabelList2		: LabelShort,
			LabelList3		: LabelShort,
			LabelList4		: LabelShort,
			LabelInfo1		: LabelLong,
			LabelInfo2		: LabelHidden,
			LabelSettings1	: LabelLong,
			LabelSettings2	: LabelHidden,
		},
	}

	##############################################################################
	# SOURCE TIME
	##############################################################################

	LabelSourceTime = {
		LabelDefault : {
			LabelList1		: LabelLong,
			LabelList2		: LabelShort,
			LabelList3		: LabelHidden,
			LabelList4		: LabelHidden,
			LabelInfo1		: LabelLong,
			LabelInfo2		: LabelHidden,
			LabelSettings1	: LabelLong,
			LabelSettings2	: LabelHidden,
		},
	}

	##############################################################################
	# SOURCE POPULARITY
	##############################################################################

	SourcePopularityRatio = {
		'seeds'		: 0.4,
		'leeches'	: 0.2,
		'time'		: 0.6,
		'approval'	: 0.4,
	}

	# Seeds/Leeches: The upper threshold at which it is considered perfect.
	# Time: The lower threshold. Everything above this value is considered too old to be alive.
	SourcePopularityLimit = {
		'seeds'		: 200, # 200 seeds.
		'leeches'	: 500, # 500 leeches.
		'time'		: 730, # 2 years. Do not make too low. Most usenet providers have a retention of 10+ years.
	}

	LabelSourcePopularity = {
		LabelDefault : {
			LabelList1		: LabelMedium,
			LabelList2		: LabelMedium,
			LabelList3		: LabelHidden,
			LabelList4		: LabelHidden,
			LabelInfo1		: LabelLong,
			LabelInfo2		: LabelHidden,
			LabelSettings1	: LabelLong,
			LabelSettings2	: LabelHidden,
		},
	}

	##############################################################################
	# SOURCE ORIGIN
	##############################################################################

	LabelSourceOrigin = {
		LabelDefault : {
			LabelList1		: LabelMedium,
			LabelList2		: LabelMedium,
			LabelList3		: LabelMedium,
			LabelList4		: LabelMedium,
			LabelInfo1		: LabelLong,
			LabelInfo2		: LabelHidden,
			LabelSettings1	: LabelLong,
			LabelSettings2	: LabelHidden,
		},
	}

	##############################################################################
	# SOURCE PROVIDER
	##############################################################################

	LabelSourceProvider = {
		LabelDefault : {
			LabelList1		: LabelLong,
			LabelList2		: LabelLong,
			LabelList3		: LabelLong,
			LabelList4		: LabelLong,
			LabelInfo1		: LabelLong,
			LabelInfo2		: LabelHidden,
			LabelSettings1	: LabelLong,
			LabelSettings2	: LabelHidden,
		},
	}

	##############################################################################
	# SOURCE PUBLISHER
	##############################################################################

	# Mainly for TheCrew providers.
	SourcePublisherAlias = {
		'releasebb' : 'rlsbb',
		'rmz' : 'rapidmoviez',
	}

	LabelSourcePublisher = {
		LabelDefault : {
			LabelList1		: LabelLong,
			LabelList2		: LabelLong,
			LabelList3		: LabelHidden,
			LabelList4		: LabelHidden,
			LabelInfo1		: LabelLong,
			LabelInfo2		: LabelHidden,
			LabelSettings1	: LabelLong,
			LabelSettings2	: LabelHidden,
		},
	}

	##############################################################################
	# SOURCE HOSTER
	##############################################################################

	LabelSourceHoster = {
		LabelDefault : {
			LabelList1		: LabelLong,
			LabelList2		: LabelLong,
			LabelList3		: LabelLong,
			LabelList4		: LabelLong,
			LabelInfo1		: LabelLong,
			LabelInfo2		: LabelHidden,
			LabelSettings1	: LabelLong,
			LabelSettings2	: LabelHidden,
		},
	}

	##############################################################################
	# ACCESS TYPE
	##############################################################################

	AccessTypeDebrid	= 'debrid'
	AccessTypeCache		= 'cache'
	AccessTypeOffline	= 'offline'
	AccessTypeDirect	= 'direct'
	AccessTypeMember	= 'member'
	AccessTypeOpen		= 'open'
	AccessTypeOrion		= 'orion'
	AccessTypeNone		= None

	LabelAccessType = {
		LabelDefault : {
			LabelList1		: LabelLong,
			LabelList2		: LabelMedium,
			LabelList3		: LabelMedium,
			LabelList4		: LabelMedium,
			LabelInfo1		: LabelLong,
			LabelInfo2		: LabelHidden,
			LabelSettings1	: LabelLong,
			LabelSettings2	: LabelMedium,
		},

		AccessTypeDebrid	: { LabelShort : 'DB',	LabelMedium : 'DEB',	LabelLong : 'Debrid' },
		AccessTypeCache		: { LabelShort : 'CH',	LabelMedium : 'CHD',	LabelLong : 'Cached' },
		AccessTypeOffline	: { LabelShort : 'OF',	LabelMedium : 'OFF',	LabelLong : 'Offline' },
		AccessTypeDirect	: { LabelShort : 'DI',	LabelMedium : 'DIR',	LabelLong : 'Direct' },
		AccessTypeMember	: { LabelShort : 'ME',	LabelMedium : 'MEM',	LabelLong : 'Member' },
		AccessTypeOpen		: { LabelShort : 'OP',	LabelMedium : 'OPE',	LabelLong : 'Open' },
		AccessTypeOrion		: { LabelShort : 'OR',	LabelMedium : 'ORI',	LabelLong : 'Orion' },
	}

	OrderAccessType = {
		AccessTypeDebrid	: { OrderInterface : 2,		OrderSorting : 3 },
		AccessTypeCache		: { OrderInterface : 1,		OrderSorting : 1 },
		AccessTypeDirect	: { OrderInterface : 3,		OrderSorting : 2 },
		AccessTypeMember	: { OrderInterface : 4,		OrderSorting : 4 },
		AccessTypeOpen		: { OrderInterface : 5,		OrderSorting : 5 },
		AccessTypeOffline	: { OrderInterface : 6,		OrderSorting : 6 },
		AccessTypeOrion		: { OrderInterface : None,	OrderSorting : None },
	}

	##############################################################################
	# ACCESS DEBRID
	##############################################################################

	AccessDebridPremiumize		= 'premiumize'
	AccessDebridOffcloud		= 'offcloud'
	AccessDebridTorbox			= 'torbox'
	AccessDebridEasydebrid		= 'easydebrid'
	AccessDebridRealdebrid		= 'realdebrid'
	AccessDebridDebridlink		= 'debridlink'
	AccessDebridAlldebrid		= 'alldebrid'
	AccessDebridLinksnappy		= 'linksnappy'
	AccessDebridMegadebrid		= 'megadebrid'
	AccessDebridRapidpremium	= 'rapidpremium'
	AccessDebridSimplydebrid	= 'simplydebrid'
	AccessDebridSmoozed			= 'smoozed'
	AccessDebridNone			= None

	AccessDebridHandles			= None
	AccessDebridSingle 			= None

	OrderAccessDebrid = {
		AccessDebridPremiumize		: { OrderInterface : 1,		OrderSorting : 1 },
		AccessDebridOffcloud		: { OrderInterface : 2,		OrderSorting : 2 },
		AccessDebridTorbox			: { OrderInterface : 3,		OrderSorting : 3 },
		AccessDebridEasydebrid		: { OrderInterface : 4,		OrderSorting : 4 },
		#AccessDebridRealdebrid		: { OrderInterface : 5,		OrderSorting : 5 },
		#AccessDebridDebridlink		: { OrderInterface : 6,		OrderSorting : 6 },
		#AccessDebridAlldebrid		: { OrderInterface : 7,		OrderSorting : 7 },
		AccessDebridLinksnappy		: { OrderInterface : 8,		OrderSorting : 8 },
		AccessDebridMegadebrid		: { OrderInterface : 9,		OrderSorting : 9 },
		AccessDebridRapidpremium	: { OrderInterface : 10,	OrderSorting : 10 },
		AccessDebridSimplydebrid	: { OrderInterface : 11,	OrderSorting : 11 },
		AccessDebridSmoozed			: { OrderInterface : 12,	OrderSorting : 12 },

		# Add last, since it does not support cache lookups anymore.
		AccessDebridRealdebrid		: { OrderInterface : 21,	OrderSorting : 21 },
		AccessDebridDebridlink		: { OrderInterface : 22,	OrderSorting : 22 },
		AccessDebridAlldebrid		: { OrderInterface : 23,	OrderSorting : 23 },
	}

	LabelAccessDebrid = {
		LabelDefault : {
			LabelList1		: LabelLong,
			LabelList2		: LabelMedium,
			LabelList3		: LabelMedium,
			LabelList4		: LabelMedium,
			LabelInfo1		: LabelLong,
			LabelInfo2		: LabelHidden,
			LabelSettings1	: LabelLong,
			LabelSettings2	: LabelHidden,
		},
	}

	##############################################################################
	# ACCESS CACHE
	##############################################################################

	AccessCacheExpired		= 'expired'

	# Only used for filtering.
	OrderAccessCache = {
		SourceTypeTorrent	: { OrderInterface : 1,	OrderSorting : 1 },
		SourceTypeUsenet	: { OrderInterface : 2,	OrderSorting : 2 },
		SourceTypeHoster	: { OrderInterface : 3,	OrderSorting : 3 },
	}

	LabelAccessCache = {
		LabelDefault : {
			LabelList1		: LabelShort,
			LabelList2		: LabelShort,
			LabelList3		: LabelShort,
			LabelList4		: LabelShort,
			LabelInfo1		: LabelLong,
			LabelInfo2		: LabelHidden,
			LabelSettings1	: LabelLong,
			LabelSettings2	: LabelMedium,
		},

		# Only used for filtering.
		SourceTypeTorrent	: LabelSourceType[SourceTypeTorrent],
		SourceTypeUsenet	: LabelSourceType[SourceTypeUsenet],
		SourceTypeHoster	: LabelSourceType[SourceTypeHoster],
	}

	##############################################################################
	# ACCESS USAGE
	##############################################################################

	AccessUsageCost			= 'cost'
	AccessUsageRemaining	= 'remaining'
	AccessUsageConsumed		= 'consumed'

	LabelAccessUsage = {
		LabelDefault : {
			LabelList1		: LabelShort,
			LabelList2		: LabelShort,
			LabelList3		: LabelShort,
			LabelList4		: LabelShort,
			LabelInfo1		: LabelHidden,
			LabelInfo2		: LabelHidden,
			LabelSettings1	: LabelHidden,
			LabelSettings2	: LabelHidden,
		},

		AccessUsageCost			: { LabelShort : '',	LabelMedium : 'Cos',	LabelLong : 'Cost' },
		AccessUsageRemaining	: { LabelShort : '',	LabelMedium : 'Rem',	LabelLong : 'Remaining' },
		AccessUsageConsumed		: { LabelShort : '',	LabelMedium : 'Con',	LabelLong : 'Consumed' },
	}

	##############################################################################
	# VIDEO QUALITY
	##############################################################################

	VideoQualityHd		= 'hd'
	VideoQualityHdUltra	= 'hdultra'
	VideoQualityHd16k	= 'hd16k'
	VideoQualityHd14k	= 'hd14k'
	VideoQualityHd12k	= 'hd12k'
	VideoQualityHd10k	= 'hd10k'
	VideoQualityHd8k	= 'hd8k'
	VideoQualityHd6k	= 'hd6k'
	VideoQualityHd4k	= 'hd4k'
	VideoQualityHd2k	= 'hd2k'
	VideoQualityHd1080	= 'hd1080'
	VideoQualityHd720	= 'hd720'

	VideoQualitySd		= 'sd'
	VideoQualitySd576	= 'sd576'
	VideoQualitySd540	= 'sd540'
	VideoQualitySd480	= 'sd480'
	VideoQualitySd360	= 'sd360'
	VideoQualitySd240	= 'sd240'
	VideoQualitySd144	= 'sd144'

	VideoQualityScr		= 'scr'
	VideoQualityScr4k	= 'scr4k'
	VideoQualityScr2k	= 'scr2k'
	VideoQualityScr1080	= 'scr1080'
	VideoQualityScr720	= 'scr720'
	VideoQualityScr576	= 'scr576'
	VideoQualityScr540	= 'scr540'
	VideoQualityScr480	= 'scr480'
	VideoQualityScr360	= 'scr360'
	VideoQualityScr240	= 'scr240'
	VideoQualityScr144	= 'scr144'

	VideoQualityCam		= 'cam'
	VideoQualityCam4k	= 'cam4k'
	VideoQualityCam2k	= 'cam2k'
	VideoQualityCam1080	= 'cam1080'
	VideoQualityCam720	= 'cam720'
	VideoQualityCam576	= 'cam576'
	VideoQualityCam540	= 'cam540'
	VideoQualityCam480	= 'cam480'
	VideoQualityCam360	= 'cam360'
	VideoQualityCam240	= 'cam240'
	VideoQualityCam144	= 'cam144'

	VideoQualityNone	= None
	VideoQualityDefault	= VideoQualitySd480

	ExpressionVideoQuality = {
		'keyword' : {
			'8640x'		: u'(8640|8640{suffixuhd}|{ultra}8640{suffix}?|{res4}8640)',
			'8192x'		: u'(8192{suffixuhd}|{ultra}8192{suffix}?|{res4}8192)',
			'5120x'		: u'(5120{suffixuhd}|{ultra}5120{suffix}?|{res4}5120)',
			'4320x'		: u'(4320|4320{suffixuhd}|{ultra}4320{suffix}?|{res4}4320)',
			'4096x'		: u'(4096{suffixuhd}|{ultra}4096{suffix}?|{res4}4096)',
			'3160x'		: u'(3160{suffixuhd}|{ultra}3160{suffix}?|{res4}3160)',
			'3112x'		: u'(3112{suffixuhd}|{ultra}3112{suffix}?|{res4}3112)',
			'2880x'		: u'(2880{suffixuhd}|{ultra}2880{suffix}?|{res4}2880)',
			'2664x'		: u'(2664{suffixuhd}|{ultra}2664{suffix}?|{res4}2664)',
			'2160x'		: u'(2160|2160{suffixuhd}|{ultra}2160{suffix}?|3840{times}(?:2160)?|{res4}2160)',
			'2048x'		: u'(2048{suffixuhd}|{ultra}2048{suffix}?|{res4}2048)',
			'1716x'		: u'(1716{suffixuhd}|{ultra}1716{suffix}?|{res4}1716)',
			'1556x'		: u'(1556{suffixuhd}|{ultra}1556{suffix}?|{res4}1556)',
			'1440x'		: u'(1440{suffixuhd}|{ultra}1440{suffix}?|{res4}1440)',
			'1332x'		: u'(1332{suffixuhd}|{ultra}1332{suffix}?|{res4}1332)',
			'1200x'		: u'(1200{suffixuhd}|{ultra}1200{suffix}?|{res4}1200)',
			'1080x'		: u'(1080|10[48]0{suffixhd}|{prefix}10[48]0{suffix}?|1920{times}(?:10[48]0)?|{res4}10[48]0)',
			'720x'		: u'(720|720{suffixhd}|{prefix}720{suffix}?|1280{times}(?:720)?|{res3}720)',
			'576x'		: u'(576{suffixld}|(?:ld|sd)576{suffix}?|{res3}576)',
			'540x'		: u'(540{suffixld}|(?:ld|sd)540{suffix}?|{res3}540)',
			'480x'		: u'(480{suffixld}|(?:ld|sd)480{suffix}?|(?:768|854){times}(?:480)?|{res3}480)',
			'360x'		: u'(3[26]0{suffixld}|(?:ld|sd)3[26]0{suffix}?|480{times}(?:352|360)?|{res3}(?:352|360|320))',
			'240x'		: u'((?:240|272){suffixld}|(?:ld|sd)(?:240|272){suffix}?|(?:320|352|426){times}(?:240|272)?|{res3}(?:240|272))',
			'144x'		: u'(144{suffixld}|(?:ld|sd)144{suffix}?|(?:176|256){times}(?:144)?|{res3}144)',

			'16k'		: u'((?:{ultra}|{extra})?16k(?:{ultra})?)',
			'14k'		: u'((?:{ultra}|{extra})?14k(?:{ultra})?)',
			'12k'		: u'((?:{ultra}|{extra})?12k(?:{ultra})?)',
			'10k'		: u'((?:{ultra}|{extra})?10k(?:{ultra})?)',
			'8k'		: u'((?:{ultra}|{extra})?8k(?:{ultra})?)',
			'6k'		: u'((?:{ultra}|{extra})?6k(?:{ultra})?)',
			'4k'		: u'((?:{ultra}|{extra})?4k(?:{ultra})?)',
			'2k'		: u'((?:{ultra}|{extra})?2k(?:{ultra})?)',

			'prefix'	: '(?:hd|bd|m)',
			'suffix'	: '(?!x)(?:[ipр]|[ipр]?(?:buray|bd|br)(?:rip)?|res?)',
			'suffixuhd'	: '(?!x)(?:{suffix}|{ultra})',
			'suffixhd'	: '(?!x)(?:{suffix}|hd)',
			'suffixld'	: '(?!x)(?:{suffix}|sd|ld)',
			'times'		: '{separator}*x{separator}*',
			'extra'		: '(?:bs)', # NHK BS Premium (BS4K and BS8K)

			'res4'		: '\d\d\d\d{times}',
			'res3'		: '\d\d\d\d?{times}',

			'cam'		: u'((?:(?:dvd|digital{separator}*(?:versatile|video){separator}*dis[ck])|(?:h[dq]|high{separator}*(?:definition|quality)))?{separator}*(?:cam(?:era)?|(?:(?<!mpeg.)(?<!mpeg..)(?<!mpeg...)ts(?<!\.ts$)(?!{brackets}+$)|t(?:ele)?{separator}*sync)|(?:tc|t(?:ele)?{separator}*cine)){separator}*(?:rip)?)', # Exclude MPEG "Transport Stream" and ".ts" file extensions
			'scr'		: u'((?:(?:dvd|digital{separator}*(?:versatile|video){separator}*dis[ck])|(?:b[dr]r?|blu{separator}*ray(?:{separator}*dis[ck])?)|(?:ts|tc|t(?:ele)?{separator}*(?:sync|cine))|mc)?{separator}*scr(?:e[en]ner)?(?:{separator}*rip)?|(?:ddc|digital{separator}*distribution{separator}*copy|(?:downloadable|direct){separator}*digital{separator}*content)|(?:wp|work{separator}*print))',

			'sd'		: u'([ls][dq]|(?:low|std|standard){separator}*(?:definition|quality))',
			'hd'		: u'(h[dq]|high{separator}*(?:definition|quality))',
			'ultra'		: u'(?:u(?:ltra)?)?{separator}*hd',
		},

		# Order is important here. Check for SCR and CAM first. Then check from highest to lowest (since 720 can be detected by only the "hd" keyword).
		# Use this weird order to speed up execution. First check the most common keywords.
		# Use: (VideoQualityScr1080,	[['{scr}'], ['(?:{1080x}|{1200x})']]),
		# Instead of: (VideoQualityScr1080,	[['{scr}'], ['{1080x}', '{1200x}']]),
		# Since it is about 50% faster.
		'expression' : (
			('{scr}', (
				(VideoQualityScr4k,		[[u'{scr}'], [u'(?:{4k}|{2160x}|{2664x}|{2880x}|{3112x})']]),
				(VideoQualityScr2k,		[[u'{scr}'], [u'(?:{2k}|{1332x}|{1440x}|{1556x}|{1716x}|{2048x})']]),
				(VideoQualityScr1080,	[[u'{scr}'], [u'(?:{1080x}|{1200x})']]),
				(VideoQualityScr720,	[[u'{scr}'], [u'(?:{720x}|{hd})']]),
				(VideoQualityScr480,	[[u'{scr}'], [u'{480x}']]),
				(VideoQualityScr360,	[[u'{scr}'], [u'{360x}']]),
				(VideoQualityScr576,	[[u'{scr}'], [u'{576x}']]),
				(VideoQualityScr540,	[[u'{scr}'], [u'{540x}']]),
				(VideoQualityScr240,	[[u'{scr}'], [u'{240x}']]),
				(VideoQualityScr144,	[[u'{scr}'], [u'{144x}']]),
				(VideoQualityScr480,	[[u'{scr}']]),
			)),

			('{cam}', (
				(VideoQualityCam4k,		[[u'{cam}'], [u'(?:{4k}|{2160x}|{2664x}|{2880x}|{3112x})']]),
				(VideoQualityCam2k,		[[u'{cam}'], [u'(?:{2k}|{1332x}|{1440x}|{1556x}|{1716x}|{2048x})']]),
				(VideoQualityCam1080,	[[u'{cam}'], [u'(?:{1080x}|{1200x})']]),
				(VideoQualityCam720,	[[u'{cam}'], [u'(?:{720x}|{hd})']]),
				(VideoQualityCam480,	[[u'{cam}'], [u'{480x}']]),
				(VideoQualityCam360,	[[u'{cam}'], [u'{360x}']]),
				(VideoQualityCam576,	[[u'{cam}'], [u'{576x}']]),
				(VideoQualityCam540,	[[u'{cam}'], [u'{540x}']]),
				(VideoQualityCam240,	[[u'{cam}'], [u'{240x}']]),
				(VideoQualityCam144,	[[u'{cam}'], [u'{144x}']]),
				(VideoQualityCam480,	[[u'{cam}']]),
			)),

			('', (
				(VideoQualityHd1080,	[[u'(?:{1080x}|{1200x})']]),
				(VideoQualityHd720,		[[u'{720x}']]),

				(VideoQualityHd8k,		[[u'(?:{8k}|{4320x})']]),
				(VideoQualityHd6k,		[[u'(?:{6k}|{3160x}|{4096x})']]),
				(VideoQualityHd4k,		[[u'(?:{4k}|{2160x}|{2664x}|{2880x}|{3112x})']]),

				(VideoQualitySd480,		[[u'{480x}']]),
				(VideoQualitySd360,		[[u'{360x}']]),
				(VideoQualitySd576,		[[u'{576x}']]),
				(VideoQualitySd540,		[[u'{540x}']]),
				(VideoQualitySd240,		[[u'{240x}']]),
				(VideoQualitySd144,		[[u'{144x}']]),

				(VideoQualityHd16k,		[[u'(?:{16k}|{8640x})']]),
				(VideoQualityHd14k,		[[u'(?:{14k}|{8192x})']]),
				(VideoQualityHd12k,		[[u'(?:{12k}|{5120x})']]),
				(VideoQualityHd10k,		[[u'{10k}']]),
				(VideoQualityHd2k,		[[u'(?:{2k}|{1332x}|{1440x}|{1556x}|{1716x}|{2048x})']]),

				(VideoQualityHd4k,		[[u'(?:ultra|(?:u(?:ltra)?){separator}*hd)']]),
				(VideoQualityHd720,		[[u'{hd}']]), #Check this last, otherwise "DTS-HD.MA" is matched before checking the other quality expressions.
			)),
		),
	}

	LabelVideoQuality = {
		LabelDefault : {
			LabelList1		: LabelShort,
			LabelList2		: LabelShort,
			LabelList3		: LabelShort,
			LabelList4		: LabelShort,
			LabelInfo1		: LabelShort,
			LabelInfo2		: LabelLong,
			LabelSettings1	: LabelLong,
			LabelSettings2	: LabelShort,
		},

		VideoQualityHd		: { LabelShort : 'HD',		LabelMedium : 'HD',			LabelLong : 'High Definition' },
		VideoQualityHdUltra	: { LabelShort : 'HDULTRA',	LabelMedium : 'HD Ultra',	LabelLong : 'High Definition Ultra' },
		VideoQualityHd16k	: { LabelShort : 'HD16K',	LabelMedium : 'HD 16K',		LabelLong : 'High Definition 16K' },
		VideoQualityHd14k	: { LabelShort : 'HD14K',	LabelMedium : 'HD 14K',		LabelLong : 'High Definition 14K' },
		VideoQualityHd12k	: { LabelShort : 'HD12K',	LabelMedium : 'HD 12K',		LabelLong : 'High Definition 12K' },
		VideoQualityHd10k	: { LabelShort : 'HD10K',	LabelMedium : 'HD 10K',		LabelLong : 'High Definition 10K' },
		VideoQualityHd8k	: { LabelShort : 'HD8K',	LabelMedium : 'HD 8K',		LabelLong : 'High Definition 8K' },
		VideoQualityHd6k	: { LabelShort : 'HD6K',	LabelMedium : 'HD 6K',		LabelLong : 'High Definition 6K' },
		VideoQualityHd4k	: { LabelShort : 'HD4K',	LabelMedium : 'HD 4K',		LabelLong : 'High Definition 4K' },
		VideoQualityHd2k	: { LabelShort : 'HD2K',	LabelMedium : 'HD 2K',		LabelLong : 'High Definition 2K' },
		VideoQualityHd1080	: { LabelShort : 'HD1080',	LabelMedium : 'HD 1080P',	LabelLong : 'High Definition 1080P' },
		VideoQualityHd720	: { LabelShort : 'HD720',	LabelMedium : 'HD 720P',	LabelLong : 'High Definition 720P' },

		VideoQualitySd		: { LabelShort : 'SD',		LabelMedium : 'SD',			LabelLong : 'Standard Definition' },
		VideoQualitySd576	: { LabelShort : 'SD576',	LabelMedium : 'SD 576P',	LabelLong : 'Standard Definition 576P' },
		VideoQualitySd540	: { LabelShort : 'SD540',	LabelMedium : 'SD 540P',	LabelLong : 'Standard Definition 540P' },
		VideoQualitySd480	: { LabelShort : 'SD480',	LabelMedium : 'SD 480P',	LabelLong : 'Standard Definition 480P' },
		VideoQualitySd360	: { LabelShort : 'SD360',	LabelMedium : 'SD 360P',	LabelLong : 'Standard Definition 360P' },
		VideoQualitySd240	: { LabelShort : 'SD240',	LabelMedium : 'SD 240P',	LabelLong : 'Standard Definition 240P' },
		VideoQualitySd144	: { LabelShort : 'SD144',	LabelMedium : 'SD 144P',	LabelLong : 'Standard Definition 144P' },

		VideoQualityScr		: { LabelShort : 'SCR',		LabelMedium : 'SCR',		LabelLong : 'Screener' },
		VideoQualityScr4k	: { LabelShort : 'SCR4K',	LabelMedium : 'SCR 4K',		LabelLong : 'Screener 4K' },
		VideoQualityScr2k	: { LabelShort : 'SCR2K',	LabelMedium : 'SCR 2K',		LabelLong : 'Screener 2K' },
		VideoQualityScr1080	: { LabelShort : 'SCR1080',	LabelMedium : 'SCR 1080P',	LabelLong : 'Screener 1080P' },
		VideoQualityScr720	: { LabelShort : 'SCR720',	LabelMedium : 'SCR 720P',	LabelLong : 'Screener 720P' },
		VideoQualityScr576	: { LabelShort : 'SCR576',	LabelMedium : 'SCR 576P',	LabelLong : 'Screener 576P' },
		VideoQualityScr540	: { LabelShort : 'SCR540',	LabelMedium : 'SCR 540P',	LabelLong : 'Screener 540P' },
		VideoQualityScr480	: { LabelShort : 'SCR480',	LabelMedium : 'SCR 480P',	LabelLong : 'Screener 480P' },
		VideoQualityScr360	: { LabelShort : 'SCR360',	LabelMedium : 'SCR 360P',	LabelLong : 'Screener 360P' },
		VideoQualityScr240	: { LabelShort : 'SCR240',	LabelMedium : 'SCR 240P',	LabelLong : 'Screener 240P' },
		VideoQualityScr144	: { LabelShort : 'SCR144',	LabelMedium : 'SCR 144P',	LabelLong : 'Screener 144P' },

		VideoQualityCam		: { LabelShort : 'CAM',		LabelMedium : 'CAM',		LabelLong : 'Camera' },
		VideoQualityCam4k	: { LabelShort : 'CAM4K',	LabelMedium : 'CAM 4K',		LabelLong : 'Camera 4K' },
		VideoQualityCam2k	: { LabelShort : 'CAM2K',	LabelMedium : 'CAM 2K',		LabelLong : 'Camera 2K' },
		VideoQualityCam1080	: { LabelShort : 'CAM1080',	LabelMedium : 'CAM 1080P',	LabelLong : 'Camera 1080P' },
		VideoQualityCam720	: { LabelShort : 'CAM720',	LabelMedium : 'CAM 720P',	LabelLong : 'Camera 720P' },
		VideoQualityCam576	: { LabelShort : 'CAM576',	LabelMedium : 'CAM 576P',	LabelLong : 'Camera 576P' },
		VideoQualityCam540	: { LabelShort : 'CAM540',	LabelMedium : 'CAM 540P',	LabelLong : 'Camera 540P' },
		VideoQualityCam480	: { LabelShort : 'CAM480',	LabelMedium : 'CAM 480P',	LabelLong : 'Camera 480P' },
		VideoQualityCam360	: { LabelShort : 'CAM360',	LabelMedium : 'CAM 360P',	LabelLong : 'Camera 360P' },
		VideoQualityCam240	: { LabelShort : 'CAM240',	LabelMedium : 'CAM 240P',	LabelLong : 'Camera 240P' },
		VideoQualityCam144	: { LabelShort : 'CAM144',	LabelMedium : 'CAM 144P',	LabelLong : 'Camera 144P' },
	}

	OrderVideoQuality = {
		VideoQualityHd		: { OrderInterface : None,	OrderSorting : None },
		VideoQualityHdUltra	: { OrderInterface : None,	OrderSorting : None },
		VideoQualityHd16k	: { OrderInterface : 1,		OrderSorting : 1 },
		VideoQualityHd14k	: { OrderInterface : 2,		OrderSorting : 2 },
		VideoQualityHd12k	: { OrderInterface : 3,		OrderSorting : 3 },
		VideoQualityHd10k	: { OrderInterface : 4,		OrderSorting : 4 },
		VideoQualityHd8k	: { OrderInterface : 5,		OrderSorting : 5 },
		VideoQualityHd6k	: { OrderInterface : 6,		OrderSorting : 6 },
		VideoQualityHd4k	: { OrderInterface : 7,		OrderSorting : 7 },
		VideoQualityHd2k	: { OrderInterface : 8,		OrderSorting : 8 },
		VideoQualityHd1080	: { OrderInterface : 9,		OrderSorting : 9 },
		VideoQualityHd720	: { OrderInterface : 10,	OrderSorting : 10 },

		VideoQualitySd		: { OrderInterface : None,	OrderSorting : None },
		VideoQualitySd576	: { OrderInterface : 11,	OrderSorting : 11 },
		VideoQualitySd540	: { OrderInterface : 12,	OrderSorting : 12 },
		VideoQualitySd480	: { OrderInterface : 13,	OrderSorting : 13 },
		VideoQualitySd360	: { OrderInterface : 14,	OrderSorting : 14 },
		VideoQualitySd240	: { OrderInterface : 15,	OrderSorting : 15 },
		VideoQualitySd144	: { OrderInterface : 16,	OrderSorting : 16 },

		VideoQualityScr		: { OrderInterface : None,	OrderSorting : None },
		VideoQualityScr4k	: { OrderInterface : 17,	OrderSorting : 17 },
		VideoQualityScr2k	: { OrderInterface : 18,	OrderSorting : 18 },
		VideoQualityScr1080	: { OrderInterface : 19,	OrderSorting : 19 },
		VideoQualityScr720	: { OrderInterface : 20,	OrderSorting : 20 },
		VideoQualityScr576	: { OrderInterface : 21,	OrderSorting : 21 },
		VideoQualityScr540	: { OrderInterface : 22,	OrderSorting : 22 },
		VideoQualityScr480	: { OrderInterface : 23,	OrderSorting : 23 },
		VideoQualityScr360	: { OrderInterface : 24,	OrderSorting : 24 },
		VideoQualityScr240	: { OrderInterface : 25,	OrderSorting : 25 },
		VideoQualityScr144	: { OrderInterface : 26,	OrderSorting : 26 },

		VideoQualityCam		: { OrderInterface : None,	OrderSorting : None },
		VideoQualityCam4k	: { OrderInterface : 27,	OrderSorting : 27 },
		VideoQualityCam2k	: { OrderInterface : 28,	OrderSorting : 28 },
		VideoQualityCam1080	: { OrderInterface : 29,	OrderSorting : 29 },
		VideoQualityCam720	: { OrderInterface : 30,	OrderSorting : 30 },
		VideoQualityCam576	: { OrderInterface : 31,	OrderSorting : 31 },
		VideoQualityCam540	: { OrderInterface : 32,	OrderSorting : 32 },
		VideoQualityCam480	: { OrderInterface : 33,	OrderSorting : 33 },
		VideoQualityCam360	: { OrderInterface : 34,	OrderSorting : 34 },
		VideoQualityCam240	: { OrderInterface : 35,	OrderSorting : 35 },
		VideoQualityCam144	: { OrderInterface : 36,	OrderSorting : 36 },
	}

	KodiVideoQuality = {
		VideoQualityHd		: '720',
		VideoQualityHdUltra	: '8K',
		VideoQualityHd16k	: '8K',
		VideoQualityHd14k	: '8K',
		VideoQualityHd12k	: '8K',
		VideoQualityHd10k	: '8K',
		VideoQualityHd8k	: '8K',
		VideoQualityHd6k	: '4K',
		VideoQualityHd4k	: '4K',
		VideoQualityHd2k	: '1080',
		VideoQualityHd1080	: '1080',
		VideoQualityHd720	: '720',

		VideoQualitySd		: '480',
		VideoQualitySd576	: '576',
		VideoQualitySd540	: '540',
		VideoQualitySd480	: '480',
		VideoQualitySd360	: '480',
		VideoQualitySd240	: '480',
		VideoQualitySd144	: '480',

		VideoQualityScr		: '480',
		VideoQualityScr4k	: '4K',
		VideoQualityScr2k	: '1080',
		VideoQualityScr1080	: '1080',
		VideoQualityScr720	: '720',
		VideoQualityScr576	: '576',
		VideoQualityScr540	: '540',
		VideoQualityScr480	: '480',
		VideoQualityScr360	: '480',
		VideoQualityScr240	: '480',
		VideoQualityScr144	: '480',

		VideoQualityCam		: '480',
		VideoQualityCam4k	: '4K',
		VideoQualityCam2k	: '1080',
		VideoQualityCam1080	: '1080',
		VideoQualityCam720	: '720',
		VideoQualityCam576	: '576',
		VideoQualityCam540	: '540',
		VideoQualityCam480	: '480',
		VideoQualityCam360	: '480',
		VideoQualityCam240	: '480',
		VideoQualityCam144	: '480',

		VideoQualityNone	: '',
	}

	CategoryVideoQuality = {
		VideoQualityHdUltra	: VideoQualityHdUltra,
		VideoQualityHd16k	: VideoQualityHdUltra,
		VideoQualityHd14k	: VideoQualityHdUltra,
		VideoQualityHd12k	: VideoQualityHdUltra,
		VideoQualityHd10k	: VideoQualityHdUltra,
		VideoQualityHd8k	: VideoQualityHdUltra,
		VideoQualityHd6k	: VideoQualityHdUltra,
		VideoQualityHd4k	: VideoQualityHdUltra,
		VideoQualityHd2k	: VideoQualityHdUltra,

		VideoQualityHd		: VideoQualityHd,
		VideoQualityHd1080	: VideoQualityHd,
		VideoQualityHd720	: VideoQualityHd,

		VideoQualitySd		: VideoQualitySd,
		VideoQualitySd576	: VideoQualitySd,
		VideoQualitySd540	: VideoQualitySd,
		VideoQualitySd480	: VideoQualitySd,
		VideoQualitySd360	: VideoQualitySd,
		VideoQualitySd240	: VideoQualitySd,
		VideoQualitySd144	: VideoQualitySd,

		VideoQualityScr		: VideoQualityScr,
		VideoQualityScr4k	: VideoQualityScr,
		VideoQualityScr2k	: VideoQualityScr,
		VideoQualityScr1080	: VideoQualityScr,
		VideoQualityScr720	: VideoQualityScr,
		VideoQualityScr576	: VideoQualityScr,
		VideoQualityScr540	: VideoQualityScr,
		VideoQualityScr480	: VideoQualityScr,
		VideoQualityScr360	: VideoQualityScr,
		VideoQualityScr240	: VideoQualityScr,
		VideoQualityScr144	: VideoQualityScr,

		VideoQualityCam		: VideoQualityCam,
		VideoQualityCam4k	: VideoQualityCam,
		VideoQualityCam2k	: VideoQualityCam,
		VideoQualityCam1080	: VideoQualityCam,
		VideoQualityCam720	: VideoQualityCam,
		VideoQualityCam576	: VideoQualityCam,
		VideoQualityCam540	: VideoQualityCam,
		VideoQualityCam480	: VideoQualityCam,
		VideoQualityCam360	: VideoQualityCam,
		VideoQualityCam240	: VideoQualityCam,
		VideoQualityCam144	: VideoQualityCam,
	}

	##############################################################################
	# VIDEO RESOLUTION
	##############################################################################

	# https://kodi.wiki/view/InfoLabels#ListItem - ListItem.VideoResolution

	ExpressionVideoResolution	= u'(\d{{3,5}}{separator}*x{separator}*\d{{3,5}}p?)'

	VideoWidth	= 'width'
	VideoHeight	= 'height'

	VideoResolutionDefault		= VideoQualitySd480
	VideoResolutionThreshold	= 40 # Some videos are a bit smaller.

	VideoResolution = (
		(VideoQualityHd16k,		{ VideoWidth : 15360,	VideoHeight : 8640 }),
		(VideoQualityHd14k,		{ VideoWidth : 14560,	VideoHeight : 8192 }),
		(VideoQualityHd12k,		{ VideoWidth : 11520,	VideoHeight : 4320 }),
		(VideoQualityHd10k,		{ VideoWidth : 10240,	VideoHeight : 4320 }),
		(VideoQualityHd8k,		{ VideoWidth : 7680,	VideoHeight : 4320 }),
		(VideoQualityHd6k,		{ VideoWidth : 6144,	VideoHeight : 3160 }),
		(VideoQualityHd4k,		{ VideoWidth : 3840,	VideoHeight : 2160 }),
		(VideoQualityHd2k,		{ VideoWidth : 2048,	VideoHeight : 1080 }),
		(VideoQualityHd1080,	{ VideoWidth : 1920,	VideoHeight : 1080 }),
		(VideoQualityHd720,		{ VideoWidth : 1280,	VideoHeight : 720 }),

		(VideoQualitySd576,		{ VideoWidth : 720,		VideoHeight : 576 }),
		(VideoQualitySd540,		{ VideoWidth : 960,		VideoHeight : 540 }),
		(VideoQualitySd480,		{ VideoWidth : 854,		VideoHeight : 480 }),
		(VideoQualitySd360,		{ VideoWidth : 640,		VideoHeight : 360 }),
		(VideoQualitySd240,		{ VideoWidth : 426,		VideoHeight : 240 }),
		(VideoQualitySd144,		{ VideoWidth : 256,		VideoHeight : 144 }),

		(VideoQualityScr4k,		{ VideoWidth : 3840,	VideoHeight : 2160 }),
		(VideoQualityScr2k,		{ VideoWidth : 2048,	VideoHeight : 1080 }),
		(VideoQualityScr1080,	{ VideoWidth : 1920,	VideoHeight : 1080 }),
		(VideoQualityScr720,	{ VideoWidth : 1280,	VideoHeight : 720 }),
		(VideoQualityScr576,	{ VideoWidth : 720,		VideoHeight : 576 }),
		(VideoQualityScr540,	{ VideoWidth : 960,		VideoHeight : 540 }),
		(VideoQualityScr480,	{ VideoWidth : 854,		VideoHeight : 480 }),
		(VideoQualityScr360,	{ VideoWidth : 640,		VideoHeight : 360 }),
		(VideoQualityScr240,	{ VideoWidth : 426,		VideoHeight : 240 }),
		(VideoQualityScr144,	{ VideoWidth : 256,		VideoHeight : 144 }),

		(VideoQualityCam4k,		{ VideoWidth : 3840,	VideoHeight : 2160 }),
		(VideoQualityCam2k,		{ VideoWidth : 2048,	VideoHeight : 1080 }),
		(VideoQualityCam1080,	{ VideoWidth : 1920,	VideoHeight : 1080 }),
		(VideoQualityCam720,	{ VideoWidth : 1280,	VideoHeight : 720 }),
		(VideoQualityCam576,	{ VideoWidth : 720,		VideoHeight : 576 }),
		(VideoQualityCam540,	{ VideoWidth : 960,		VideoHeight : 540 }),
		(VideoQualityCam480,	{ VideoWidth : 854,		VideoHeight : 480 }),
		(VideoQualityCam360,	{ VideoWidth : 640,		VideoHeight : 360 }),
		(VideoQualityCam240,	{ VideoWidth : 426,		VideoHeight : 240 }),
		(VideoQualityCam144,	{ VideoWidth : 256,		VideoHeight : 144 }),

		(VideoQualityNone,		{ VideoWidth : None,	VideoHeight : None }),
	)

	##############################################################################
	# VIDEO ASPECT
	##############################################################################

	VideoAspectDefault = 1.78

	VideoAspect = (
		1.00, # 1:1
		1.20, # 6:5
		1.25, # 5:4
		1.33, # 4:3
		1.38, # 11:8
		1.43, # IMAX
		1.50, # 3:2
		1.56, # 14:9
		1.60, # 16:10
		1.67, # 5:3
		1.78, # 16:9
		1.85, # US Cinema Widescreen
		1.90, # Digital IMAX
		2.00, # Univisium
		2.20, # 70mm Film
		2.35, # Standard Cinema Widescreen
		2.37, # 64:27
		2.39, # Standard Cinema Widescreen
		2.40, # Standard Cinema Widescreen
		2.56, # 23:9
		2.76, # Ultra Panavision 70
		3.56, # 32:9
		3.60, # 18:5
		4.00, # 4:1
	)

	# https://kodi.wiki/view/InfoLabels#ListItem - ListItem.VideoAspect
	KodiVideoAspect = (
		1.33,
		1.37,
		1.66,
		1.78,
		1.85,
		2.20,
		2.35,
		2.40,
		2.55,
		2.76,
	)

	##############################################################################
	# VIDEO CODEC
	##############################################################################

	# https://en.wikipedia.org/wiki/Video_CD

	VideoCodecH266	= 'h266'	# Versatile Video Coding (VVC)
	VideoCodecH265	= 'h265'	# High Efficiency Video Coding (HEVC)
	VideoCodecH264	= 'h264'	# Advanced Video Coding (AVC)
	VideoCodecH263	= 'h263'	# MPEG-2 Video Coding
	VideoCodecH262	= 'h262'	# MPEG-2 Video Coding
	VideoCodecH261	= 'h261'	# MPEG-2 Video Coding
	VideoCodecH222	= 'h222'	# MPEG-2 Generic Coding

	VideoCodecEvc	= 'evc'		# MPEG-5 Essential Video Coding (EVC)
	VideoCodecLcevc	= 'lcevc'	# AOMedia Low Complexity Essential Video Coding (LCEVC)

	VideoCodecAv2	= 'av2'		# AOMedia Video 2 (AV2)
	VideoCodecAv1	= 'av1'		# AOMedia Video 1 (AV1)

	VideoCodecVp10	= 'vp10'	# Video Processor 10 (VP10)
	VideoCodecVp9	= 'vp9'		# Video Processor 9 (VP9)
	VideoCodecVp8	= 'vp8'		# Video Processor 8 (VP8)
	VideoCodecVp7	= 'vp7'		# Video Processor 7 (VP7)
	VideoCodecVp6	= 'vp6'		# Video Processor 6 (VP6)
	VideoCodecVp5	= 'vp5'		# Video Processor 5 (VP5)
	VideoCodecVp4	= 'vp4'		# Video Processor 4 (VP4)
	VideoCodecVp3	= 'vp3'		# Video Processor 3 (VP3)

	VideoCodecXvid	= 'xvid'	# Xvid
	VideoCodecDivx	= 'divx'	# DivX

	VideoCodecWmv	= 'wmv'		# Windows Media Video (WMV)
	VideoCodecVc1	= 'vc1'		# VC-1

	VideoCodecThr	= 'thr'		# Xiph Theora
	VideoCodecMvc	= 'mvc'		# Multiview Video Coding (MVC)
	VideoCodecMpeg	= 'mpeg'	# Various MPEG and MP4 codecs.

	VideoCodecNone	= None

	# https://kodi.wiki/view/InfoLabels#ListItem - ListItem.VideoCodec
	# https://github.com/xbmc/xbmc/tree/master/addons/skin.estuary/media/flags/videocodec
	KodiVideoCodec = {
		VideoCodecH266	: 'hevc',
		VideoCodecH265	: 'hevc',
		VideoCodecH264	: 'h264',
		VideoCodecH263	: 'h264',
		VideoCodecH262	: 'h264',
		VideoCodecH261	: 'h264',
		VideoCodecH222	: 'h264',

		VideoCodecEvc	: 'hevc',
		VideoCodecLcevc	: 'hevc',

		VideoCodecAv2	: 'av1',
		VideoCodecAv1	: 'av1',

		VideoCodecVp10	: 'vp9',
		VideoCodecVp9	: 'vp9',
		VideoCodecVp8	: 'vp8',
		VideoCodecVp7	: 'vp8',
		VideoCodecVp6	: 'vp8',
		VideoCodecVp5	: 'vp8',
		VideoCodecVp4	: 'vp8',
		VideoCodecVp3	: 'vp8',

		VideoCodecXvid	: 'xvid',
		VideoCodecDivx	: 'divx',

		VideoCodecWmv	: 'wmv',
		VideoCodecVc1	: 'vc1',

		VideoCodecThr	: 'theora',
		VideoCodecMvc	: 'wvc1',
		VideoCodecMpeg	: 'mp4v',

		VideoCodecNone	: '',
	}

	ExpressionVideoCodec = {
		'keyword' : {
			'h'			: u'[hx]{{1,2}}{separator}*',
			'av'		: u'(?:av|aomedia{separator}*video){separator}*',
			'vp'		: u'(?:vp|video{separator}*processor){separator}*',
			'vpx'		: u'(?:\d|f)?',
			'extension'	: u'(?:hd|remux)?',
		},

		# Use this weird order to speed up execution. First check the most common keywords.
		'expression' : (
			(VideoCodecH264,	u'({h}264|avc1?|hi10p){extension}'),
			(VideoCodecH265,	u'({h}265|hevc){extension}'),
			(VideoCodecH266,	u'({h}266|vvc|fvc)'),

			(VideoCodecVp9,		u'({vp}9{vpx})'),
			(VideoCodecVp8,		u'({vp}8{vpx})'),
			(VideoCodecVp10,	u'({vp}10{vpx})'),

			(VideoCodecAv1,		u'({av}1)'),
			(VideoCodecAv2,		u'({av}2)'),

			(VideoCodecXvid,	u'(xvid\d?)'),
			(VideoCodecDivx,	u'(div(?:x|\d)\d?)'),
			(VideoCodecMpeg,	u'((?:mpeg|mp[124])(?:v|video|\d))'), # Do not check for "mp4" or "mpeg" only, since it is a container and not a codec.
			(VideoCodecWmv,		u'(wmv\d?)'),

			(VideoCodecH263,	u'({h}263)'),
			(VideoCodecH262,	u'({h}262)'),
			(VideoCodecH261,	u'({h}261)'),
			(VideoCodecH222,	u'({h}222)'),

			(VideoCodecVp7,		u'({vp}7{vpx})'),
			(VideoCodecVp6,		u'({vp}6{vpx})'),
			(VideoCodecVp5,		u'({vp}5{vpx})'),
			(VideoCodecVp4,		u'({vp}4{vpx})'),
			(VideoCodecVp3,		u'({vp}3{vpx})'),

			(VideoCodecEvc,		u'(evc)'),
			(VideoCodecLcevc,	u'(lcevc)'),

			(VideoCodecVc1,		u'(w?vc{separator}*1)'),
			(VideoCodecThr,		u'(theora)'),
			(VideoCodecMvc,		u'(mvc)'),
		)
	}

	LabelVideoCodec = {
		LabelDefault : {
			LabelList1		: LabelShort,
			LabelList2		: LabelShort,
			LabelList3		: LabelShort,
			LabelList4		: LabelShort,
			LabelInfo1		: LabelShort,
			LabelInfo2		: LabelMedium,
			LabelSettings1	: LabelMedium,
			LabelSettings2	: LabelShort,
		},

		VideoCodecH266	: { LabelShort : 'H266',	LabelMedium : 'MPEG Versatile Video Coding',				LabelLong : 'Moving Picture Experts Group Versatile Video Coding' },
		VideoCodecH265	: { LabelShort : 'H265',	LabelMedium : 'MPEG High Efficiency Video Coding',			LabelLong : 'Moving Picture Experts Group High Efficiency Video Coding' },
		VideoCodecH264	: { LabelShort : 'H264',	LabelMedium : 'MPEG Advanced Video Coding',					LabelLong : 'Moving Picture Experts Group Advanced Video Coding' },
		VideoCodecH263	: { LabelShort : 'H263',	LabelMedium : 'MPEG H263 Video Coding',						LabelLong : 'Moving Picture Experts Group H263 Video Coding' },
		VideoCodecH262	: { LabelShort : 'H262',	LabelMedium : 'MPEG H262 Video Coding',						LabelLong : 'Moving Picture Experts Group H262 Video Coding' },
		VideoCodecH261	: { LabelShort : 'H261',	LabelMedium : 'MPEG H261 Video Coding',						LabelLong : 'Moving Picture Experts Group H261 Video Coding' },
		VideoCodecH222	: { LabelShort : 'H222',	LabelMedium : 'MPEG H222 Video Coding',						LabelLong : 'Moving Picture Experts Group H222 Video Coding' },

		VideoCodecEvc	: { LabelShort : 'EVC',		LabelMedium : 'MPEG Essential Video Coding',				LabelLong : 'Moving Picture Experts Group Essential Video Coding' },
		VideoCodecLcevc	: { LabelShort : 'LCEVC',	LabelMedium : 'MPEG Low Complexity Essential Video Coding',	LabelLong : 'Moving Picture Experts Group Low Complexity Essential Video Coding' },

		VideoCodecAv2	: { LabelShort : 'AV2',		LabelMedium : 'AOMedia Video 2',							LabelLong : 'Alliance For Open Media Video 2' },
		VideoCodecAv1	: { LabelShort : 'AV1',		LabelMedium : 'AOMedia Video 1',							LabelLong : 'Alliance For Open Media Video 1' },

		VideoCodecVp10	: { LabelShort : 'VP10',	LabelMedium : 'Video Processor 10',							LabelLong : 'Video Processor 10' },
		VideoCodecVp9	: { LabelShort : 'VP9',		LabelMedium : 'Video Processor 9',							LabelLong : 'Video Processor 9' },
		VideoCodecVp8	: { LabelShort : 'VP8',		LabelMedium : 'Video Processor 8',							LabelLong : 'Video Processor 8' },
		VideoCodecVp7	: { LabelShort : 'VP7',		LabelMedium : 'Video Processor 7',							LabelLong : 'Video Processor 7' },
		VideoCodecVp6	: { LabelShort : 'VP6',		LabelMedium : 'Video Processor 6',							LabelLong : 'Video Processor 6' },
		VideoCodecVp5	: { LabelShort : 'VP5',		LabelMedium : 'Video Processor 5',							LabelLong : 'Video Processor 5' },
		VideoCodecVp4	: { LabelShort : 'VP4',		LabelMedium : 'Video Processor 4',							LabelLong : 'Video Processor 4' },
		VideoCodecVp3	: { LabelShort : 'VP3',		LabelMedium : 'Video Processor 3',							LabelLong : 'Video Processor 3' },

		VideoCodecXvid	: { LabelShort : 'XVID',	LabelMedium : 'Xvid',										LabelLong : 'Xvid' },
		VideoCodecDivx	: { LabelShort : 'DIVX',	LabelMedium : 'DivX',										LabelLong : 'DivX' },

		VideoCodecWmv	: { LabelShort : 'WMV',		LabelMedium : 'Windows Media Video',						LabelLong : 'Windows Media Video' },
		VideoCodecVc1	: { LabelShort : 'VC1',		LabelMedium : 'Video Codec 1',								LabelLong : 'Video Codec 1' },

		VideoCodecThr	: { LabelShort : 'THR',		LabelMedium : 'Theora',										LabelLong : 'Xiph Theora' },
		VideoCodecMvc	: { LabelShort : 'MVC',		LabelMedium : 'Multiview Video Coding',						LabelLong : 'Multiview Video Coding' },
		VideoCodecMpeg	: { LabelShort : 'MPEG',	LabelMedium : 'MPEG Video Coding',							LabelLong : 'Moving Picture Experts Group Video Coding' },
	}

	OrderVideoCodec = {
		VideoCodecH266	: { OrderInterface : 1,		OrderSorting : 1 },
		VideoCodecH265	: { OrderInterface : 2,		OrderSorting : 5 },
		VideoCodecH264	: { OrderInterface : 3,		OrderSorting : 9 },
		VideoCodecH263	: { OrderInterface : 4,		OrderSorting : 11 },
		VideoCodecH262	: { OrderInterface : 5,		OrderSorting : 18 },
		VideoCodecH261	: { OrderInterface : 6,		OrderSorting : 22 },
		VideoCodecH222	: { OrderInterface : 7,		OrderSorting : 24 },

		VideoCodecEvc	: { OrderInterface : 8,		OrderSorting : 7 },
		VideoCodecLcevc	: { OrderInterface : 9,		OrderSorting : 8 },

		VideoCodecAv2	: { OrderInterface : 12,	OrderSorting : 2 },
		VideoCodecAv1	: { OrderInterface : 11,	OrderSorting : 3 },

		VideoCodecVp10	: { OrderInterface : 13,	OrderSorting : 4 },
		VideoCodecVp9	: { OrderInterface : 14,	OrderSorting : 6 },
		VideoCodecVp8	: { OrderInterface : 15,	OrderSorting : 10 },
		VideoCodecVp7	: { OrderInterface : 16,	OrderSorting : 12 },
		VideoCodecVp6	: { OrderInterface : 17,	OrderSorting : 19 },
		VideoCodecVp5	: { OrderInterface : 18,	OrderSorting : 23 },
		VideoCodecVp4	: { OrderInterface : 19,	OrderSorting : 25 },
		VideoCodecVp3	: { OrderInterface : 20,	OrderSorting : 26 },

		VideoCodecXvid	: { OrderInterface : 21,	OrderSorting : 13 },
		VideoCodecDivx	: { OrderInterface : 22,	OrderSorting : 14 },

		VideoCodecWmv	: { OrderInterface : 23,	OrderSorting : 20 },
		VideoCodecVc1	: { OrderInterface : 24,	OrderSorting : 21 },

		VideoCodecThr	: { OrderInterface : 25,	OrderSorting : 15 },
		VideoCodecMvc	: { OrderInterface : 26,	OrderSorting : 16 },
		VideoCodecMpeg	: { OrderInterface : 10,	OrderSorting : 17 },
	}

	##############################################################################
	# VIDEO DEPTH
	##############################################################################

	VideoDepth6bit	= '6bit'
	VideoDepth8bit	= '8bit'
	VideoDepth10bit	= '10bit'
	VideoDepth12bit	= '12bit'
	VideoDepth14bit	= '14bit'
	VideoDepth16bit	= '16bit'
	VideoDepth18bit	= '18bit'
	VideoDepth20bit	= '20bit'
	VideoDepthBit	= 'bit'		# Intrernal
	VideoDepthNone	= None

	ExpressionVideoDepth = {
		'keyword' : {
			'bit'	: u'{separator}*bits?',
		},

		# Use this weird order to speed up execution. First check the most common keywords.
		'expression' : (
			(VideoDepth10bit,	u'(10{bit}|hi10p)'),
			(VideoDepth8bit,	u'(8{bit})'),
			(VideoDepth12bit,	u'(12{bit})'),
			(VideoDepth6bit,	u'(6{bit})'),
			(VideoDepth14bit,	u'(14{bit})'),
			(VideoDepth16bit,	u'(16{bit})'),
			(VideoDepth18bit,	u'(18{bit})'),
			(VideoDepth20bit,	u'(20{bit})'),
		),
	}

	LabelVideoDepth = {
		LabelDefault : {
			LabelList1		: LabelShort,
			LabelList2		: LabelHidden,
			LabelList3		: LabelHidden,
			LabelList4		: LabelHidden,
			LabelInfo1		: LabelMedium,
			LabelInfo2		: LabelHidden,
			LabelSettings1	: LabelMedium,
			LabelSettings2	: LabelShort,
		},

		VideoDepth6bit	: { LabelShort : '6BIT',	LabelMedium : '6 bit',	LabelLong : '6 bit' },
		VideoDepth8bit	: { LabelShort : '8BIT',	LabelMedium : '8 bit',	LabelLong : '8 bit' },
		VideoDepth10bit	: { LabelShort : '10BIT',	LabelMedium : '10 bit',	LabelLong : '10 bit' },
		VideoDepth12bit	: { LabelShort : '12BIT',	LabelMedium : '12 bit',	LabelLong : '12 bit' },
		VideoDepth14bit	: { LabelShort : '14BIT',	LabelMedium : '14 bit',	LabelLong : '14 bit' },
		VideoDepth16bit	: { LabelShort : '16BIT',	LabelMedium : '16 bit',	LabelLong : '16 bit' },
		VideoDepth18bit	: { LabelShort : '18BIT',	LabelMedium : '18 bit',	LabelLong : '18 bit' },
		VideoDepth20bit	: { LabelShort : '20BIT',	LabelMedium : '20 bit',	LabelLong : '20 bit' },
	}

	OrderVideoDepth = {
		VideoDepth6bit	: { OrderInterface : 1,	OrderSorting : 8 },
		VideoDepth8bit	: { OrderInterface : 2,	OrderSorting : 7 },
		VideoDepth10bit	: { OrderInterface : 3,	OrderSorting : 6 },
		VideoDepth12bit	: { OrderInterface : 4,	OrderSorting : 5 },
		VideoDepth14bit	: { OrderInterface : 5,	OrderSorting : 4 },
		VideoDepth16bit	: { OrderInterface : 6,	OrderSorting : 3 },
		VideoDepth18bit	: { OrderInterface : 7,	OrderSorting : 2 },
		VideoDepth20bit	: { OrderInterface : 8,	OrderSorting : 1 },
	}

	##############################################################################
	# VIDEO RANGE
	##############################################################################

	# https://www.benq.com/en-us/knowledge-center/knowledge/bt2020.html

	VideoRangeLdr			= 'ldr'			# Low Dynamic Range
	VideoRangeSdr			= 'sdr'			# Standard Dynamic Range
	VideoRangeSdr601		= 'sdr601'		# Standard Dynamic Range ITU Radiocommunication Sector Recommendation 601 (BT.601)
	VideoRangeSdr709		= 'sdr709'		# Standard Dynamic Range ITU Radiocommunication Sector Recommendation 709 (BT.709)
	VideoRangeSdr1886		= 'sdr1886'		# Standard Dynamic Range ITU Radiocommunication Sector Recommendation 1886 (BT.1886)
	VideoRangeSdrSrgb		= 'sdrsrgb'		# Standard Dynamic Range sRGB
	VideoRangeHdr			= 'hdr'			# High Dynamic Range (HDR)
	VideoRangeHdr10			= 'hdr10'		# High Dynamic Range 10 (HDR10)
	VideoRangeHdr10p		= 'hdr10p'		# High Dynamic Range 10 Plus (HDR10+)
	VideoRangeHdr2020		= 'hdr2020'		# High Dynamic Range ITU Radiocommunication Sector Recommendation 2020 (BT.2020) - Actually SDR
	VideoRangeHdr2100		= 'hdr2100'		# High Dynamic Range ITU Radiocommunication Sector Recommendation 2100 (BT.2100)
	VideoRangeHdr2390		= 'hdr2390'		# High Dynamic Range ITU Radiocommunication Sector Recommendation 2390 (BT.2390)
	VideoRangeHdrDcip3		= 'hdrdcip3'	# High Dynamic Range DCI-P3
	VideoRangeHdrD			= 'hdrd'		# High Dynamic Range Display (DisplayHDR)
	VideoRangeHdrPq			= 'hdrpq'		# High Dynamic Range Perceptual Quantizer (PQ)
	VideoRangeHdrSl			= 'hdrsl'		# High Dynamic Range Single (SL-HDR1)
	VideoRangeHdrHlg		= 'hdrhlg'		# High Dynamic Range Hybrid Log Gamma (HLG)
	VideoRangeHdrDv			= 'hdrdv'		# High Dynamic Range Dolby Vision (Dolby Vision)
	VideoRangeHdrDvi		= 'hdrdvi'		# High Dynamic Range Dolby Vision IQ (Dolby Vision IQ)
	VideoRangeHdrRx			= 'hdrrx'		# High Dynamic Range Red X (HDRx) - https://www.red.com/red-101/hdrx-high-dynamic-range-video
	VideoRangeHdrVp			= 'hdrvp'		# High Dynamic Range Dolby Vision Plus (VisionPlus) - https://tekno3d.com
	VideoRangeHdrVp2020		= 'hdrvp2020'	# High Dynamic Range Dolby Vision Plus (VisionPlus) ITU Radiocommunication Sector Recommendation 2020 (BT.2020) - https://tekno3d.com
	VideoRangeHdrVpx		= 'hdrvpx'		# High Dynamic Range Dolby Vision Plus X (VisionPlus HDR-X) - https://tekno3d.com
	VideoRangeHdrVpx2020	= 'hdrvpx2020'	# High Dynamic Range Dolby Vision Plus X (VisionPlus HDR-X) ITU Radiocommunication Sector Recommendation 2020 (BT.2020) - https://tekno3d.com

	VideoRangeNone			= None
	VideoRangeDolby			= {VideoRangeHdrDv : True, VideoRangeHdrDvi : True}

	ExpressionVideoRange	= {
		'keyword' : {
			'short'			: u'dri?',
			'long'			: u'{separator}*dynamic{separator}*range',
			'hdr'			: u'(?:h{short}|high{long})',
			'sdr'			: u'(?:s{short}|standard{long})',
			'ldr'			: u'(?:l{short}|low{long})',
			'x'				: u'x',
			'ten'			: u'10(?!{separator}*bit)',
			'number'		: u'(?:(?:{separator}*p(?:art)?)?{separator}*\d+)?', # Some end with eg 400, 1000, etc.
			'plus'			: u'(?:\+|p(?:lus)?)',
			'hlg'			: u'(?:h(?:ybrid)?{separator}*l(?:og)?{separator}*g(?:amma)?)',
			'pq'			: u'(?:p(?:erceptual)?{separator}*q(?:uantizer)?)',
			'sl'			: u'(?:s(?:ingle)?{separator}*l(?:ayer)?)',
			'd'				: u'(?:display|vesa)',
			'dv1'			: u'(?:dv|do(?:lby)?{separator}*vi(?:sion)?)',
			'dv2'			: u'dv',
			'vp1'			: u'vision{separator}*plus',
			'vp2'			: u'vp',
			'vp'			: u'(?:(?:{hdr}{separator}*)?{vp1}(?:{separator}*{hdr})?|{hdr}{separator}*{vp2}){number}',
			'vpx'			: u'(?:(?:{hdr}{separator}*)?{vp1}(?:{separator}*{hdr})?|{hdr}{separator}*{vp2}){separator}*{x}{number}',
			'itu'			: u'(?:itu{separator}*r|bt|rec)',
			'itu2020'		: u'(?:{itu}|{hdr}){separator}*2020',
			'itu2100'		: u'(?:{itu}|{hdr}){separator}*2100',
			'itu2390'		: u'(?:{itu}|{hdr}){separator}*2390',
			'dci'			: u'dci',
			'part'			: u'p(?:art)?',
		},

		'expression' : (
			(VideoRangeHdrDvi,		u'((?:(?:{hdr}{separator}*)?{dv1}|{hdr}{separator}*{dv2}){separator}*iq{number})'),
			(VideoRangeHdrDv,		u'((?:(?:{hdr}{separator}*)?{dv1}|{hdr}{separator}*{dv2}){number})'),

			(VideoRangeHdrVpx2020,	[u'({vpx})', u'({itu2020})']),
			(VideoRangeHdrVpx,		u'({vpx})'),
			(VideoRangeHdrVp2020,	[u'({vp})', u'({itu2020})']),
			(VideoRangeHdrVp,		u'({vp})'),

			(VideoRangeHdrHlg,		u'({hdr}{separator}*{hlg}{number}|{hlg}{separator}*{hdr}{number})'),
			(VideoRangeHdrPq,		u'({hdr}{separator}*{pq}{number}|{pq}{separator}*{hdr}{number})'),
			(VideoRangeHdrSl,		u'({hdr}{separator}*{sl}{number}|{sl}{separator}*{hdr}{number})'),
			(VideoRangeHdrD,		u'({hdr}{separator}*{d}{number}|{d}{separator}*{hdr}{number})'),

			(VideoRangeHdr10p,		u'({hdr}{separator}*(?:{ten}{separator}*{plus}|{plus}{separator}*{ten}))'),
			(VideoRangeHdr10,		u'({hdr}{separator}*{ten})'),

			(VideoRangeHdrRx,		u'({hdr}x)'),

			(VideoRangeHdr2020,		u'({itu2020})'),
			(VideoRangeHdr2100,		u'({itu2100})'),
			(VideoRangeHdr2390,		u'({itu2390})'),

			(VideoRangeHdrDcip3,	u'{dci}{separator}*{part}{separator}*3'),

			(VideoRangeHdr,			u'(h{short}|high{long}|hdr{separator}*10{separator}*(?:plus|\+)?)'),

			(VideoRangeSdr601,		u'((?:{itu}|{sdr}){separator}*601)'),
			(VideoRangeSdr709,		u'((?:{itu}|{sdr}){separator}*709)'),
			(VideoRangeSdr1886,		u'((?:{itu}|{sdr}){separator}*1886)'),

			(VideoRangeSdrSrgb,		u'(srgb)'),
			(VideoRangeSdr,			u'({sdr})'),

			(VideoRangeLdr,			u'({ldr})'),
		)
	}

	LabelVideoRange = {
		LabelDefault : {
			LabelList1		: LabelShort,
			LabelList2		: LabelHidden,
			LabelList3		: LabelHidden,
			LabelList4		: LabelHidden,
			LabelInfo1		: LabelShort,
			LabelInfo2		: LabelLong,
			LabelSettings1	: LabelMedium,
			LabelSettings2	: LabelShort,
		},

		VideoRangeLdr		: { LabelShort : 'LDR',			LabelMedium : 'LDR',						LabelLong : 'Low Dynamic Range' },
		VideoRangeSdr		: { LabelShort : 'SDR',			LabelMedium : 'SDR',						LabelLong : 'Standard Dynamic Range' },
		VideoRangeSdr601	: { LabelShort : 'SDR-601',		LabelMedium : 'SDR ITU BT 601',				LabelLong : 'ITU Radiocommunication Sector Recommendation 601' },
		VideoRangeSdr709	: { LabelShort : 'SDR-709',		LabelMedium : 'SDR ITU BT 709',				LabelLong : 'ITU Radiocommunication Sector Recommendation 709' },
		VideoRangeSdr1886	: { LabelShort : 'SDR-1886',	LabelMedium : 'SDR ITU BT 1886',			LabelLong : 'ITU Radiocommunication Sector Recommendation 1886' },
		VideoRangeSdrSrgb	: { LabelShort : 'SDR-SRGB',	LabelMedium : 'SDR sRGB',					LabelLong : 'Standard Red Green Blue' },
		VideoRangeHdr		: { LabelShort : 'HDR',			LabelMedium : 'HDR',						LabelLong : 'High Dynamic Range' },
		VideoRangeHdr10		: { LabelShort : 'HDR-10',		LabelMedium : 'HDR 10 Media Profile',		LabelLong : 'High Dynamic Range 10 Media Profile' },
		VideoRangeHdr10p	: { LabelShort : 'HDR-10P',		LabelMedium : 'HDR 10 Plus',				LabelLong : 'High Dynamic Range 10 Plus' },
		VideoRangeHdr2020	: { LabelShort : 'HDR-2020',	LabelMedium : 'HDR ITU BT 2020',			LabelLong : 'ITU Radiocommunication Sector Recommendation 2020' },
		VideoRangeHdr2100	: { LabelShort : 'HDR-2100',	LabelMedium : 'HDR ITU BT 2100',			LabelLong : 'ITU Radiocommunication Sector Recommendation 2100' },
		VideoRangeHdr2390	: { LabelShort : 'HDR-2390',	LabelMedium : 'HDR ITU BT 2390',			LabelLong : 'ITU Radiocommunication Sector Recommendation 2390' },
		VideoRangeHdrDcip3	: { LabelShort : 'HDR-DCIP3',	LabelMedium : 'HDR DCI P3',					LabelLong : 'Digital Cinema Initiatives Part 3' },
		VideoRangeHdrD		: { LabelShort : 'HDR-D',		LabelMedium : 'Display HDR',				LabelLong : 'Display High Dynamic Range' },
		VideoRangeHdrPq		: { LabelShort : 'HDR-PQ',		LabelMedium : 'Perceptual Quantizer HDR',	LabelLong : 'Perceptual Quantizer High Dynamic Range' },
		VideoRangeHdrSl		: { LabelShort : 'HDR-SL',		LabelMedium : 'Single Layer HDR',			LabelLong : 'Single Layer High Dynamic Range' },
		VideoRangeHdrHlg	: { LabelShort : 'HDR-HLG',		LabelMedium : 'Hybrid Log Gamma HDR',		LabelLong : 'Hybrid Log Gamma High Dynamic Range' },
		VideoRangeHdrDv		: { LabelShort : 'HDR-DV',		LabelMedium : 'Dolby Vision HDR',			LabelLong : 'Dolby Vision High Dynamic Range' },
		VideoRangeHdrDvi	: { LabelShort : 'HDR-DVI',		LabelMedium : 'Dolby Vision IQ HDR',		LabelLong : 'Dolby Vision IQ High Dynamic Range' },
		VideoRangeHdrRx		: { LabelShort : 'HDR-RX',		LabelMedium : 'Red HDR X',					LabelLong : 'Red High Dynamic Range X' },
		VideoRangeHdrVp		: { LabelShort : 'HDR-VP',		LabelMedium : 'VisionPlus HDR',				LabelLong : 'VisionPlus High Dynamic Range' },
		VideoRangeHdrVp2020	: { LabelShort : 'HDR-VP2020',	LabelMedium : 'VisionPlus HDR BT 2020',		LabelLong : 'VisionPlus High Dynamic Range ITU Radiocommunication Sector Recommendation 2020' },
		VideoRangeHdrVpx	: { LabelShort : 'HDR-VPX',		LabelMedium : 'VisionPlus HDR X',			LabelLong : 'VisionPlus High Dynamic Range X' },
	}

	OrderVideoRange = {
		VideoRangeLdr		: { OrderInterface : 23,	OrderSorting : 23 },
		VideoRangeSdr		: { OrderInterface : 22,	OrderSorting : 22 },
		VideoRangeSdr601	: { OrderInterface : 20,	OrderSorting : 20 },
		VideoRangeSdr709	: { OrderInterface : 19,	OrderSorting : 19 },
		VideoRangeSdr1886	: { OrderInterface : 18,	OrderSorting : 18 },
		VideoRangeSdrSrgb	: { OrderInterface : 21,	OrderSorting : 21 },
		VideoRangeHdr		: { OrderInterface : 1,		OrderSorting : 17 },
		VideoRangeHdr10		: { OrderInterface : 4,		OrderSorting : 4 },
		VideoRangeHdr10p	: { OrderInterface : 5,		OrderSorting : 3 },
		VideoRangeHdr2020	: { OrderInterface : 8,		OrderSorting : 7 },
		VideoRangeHdr2100	: { OrderInterface : 7,		OrderSorting : 6 },
		VideoRangeHdr2390	: { OrderInterface : 6,		OrderSorting : 5 },
		VideoRangeHdrDcip3	: { OrderInterface : 9,		OrderSorting : 8 },
		VideoRangeHdrD		: { OrderInterface : 13,	OrderSorting : 11 },
		VideoRangeHdrPq		: { OrderInterface : 10,	OrderSorting : 10 },
		VideoRangeHdrSl		: { OrderInterface : 12,	OrderSorting : 9 },
		VideoRangeHdrHlg	: { OrderInterface : 9,		OrderSorting : 12 },
		VideoRangeHdrDv		: { OrderInterface : 2,		OrderSorting : 2 },
		VideoRangeHdrDvi	: { OrderInterface : 3,		OrderSorting : 1 },
		VideoRangeHdrRx		: { OrderInterface : 14,	OrderSorting : 13 },
		VideoRangeHdrVp		: { OrderInterface : 15,	OrderSorting : 16 },
		VideoRangeHdrVp2020	: { OrderInterface : 16,	OrderSorting : 15 },
		VideoRangeHdrVpx	: { OrderInterface : 17,	OrderSorting : 14 },
	}

	##############################################################################
	# VIDEO 3D
	##############################################################################

	# https://kodi.wiki/view/InfoLabels#ListItem - ListItem.StereoscopicMode
	# https://www.avforums.com/threads/how-to-convert-sbs-side-by-side-3d-to-tab-top-and-bottom-ou-3d.1817009/
	# https://forum.skybox.xyz/d/157-filename-rules-for-vr-format

	Video3d			= '3d'		# General 3D
	Video3dStereo	= 'stereo'	# Stereoscopic
	Video3dMono		= 'mono'	# Monoscopic
	Video3dFsbs		= 'fsbs'	# Full Side By Side
	Video3dHsbs		= 'hsbs'	# Half Side By Side
	Video3dRsbs		= 'rsbs'	# Reversed Side By Side (SBSRL)
	Video3dFou		= 'fou'		# Full Over Under (Top And Bottom)
	Video3dHou		= 'hou'		# Half Over Under (Top And Bottom)
	Video3dRou		= 'rou'		# Reversed Over Under (Bottom And Top)
	Video3dPou		= 'pou'		# Passive Over Under (Top And Bottom)
	Video3d180		= '180'		# Virtual Reality 180
	Video3d360		= '360'		# Virtual Reality 360
	Video3dRi		= 'ri'		# Row Interleaved
	Video3dArc		= 'arc'		# Anaglyph Red Cyan
	Video3dAgm		= 'agm'		# Anaglyph Green Magenta
	Video3dNone		= None

	KodiVideo3d = {
		Video3dStereo	: 'split_horizontal',
		Video3dMono		: 'mono',
		Video3dFsbs		: 'split_horizontal',
		Video3dHsbs		: 'split_horizontal',
		Video3dRsbs		: 'split_horizontal',
		Video3dFou		: 'split_vertical',
		Video3dHou		: 'split_vertical',
		Video3dRou		: 'split_vertical',
		Video3dPou		: 'split_vertical',
		Video3d180		: 'split_horizontal',
		Video3d360		: 'split_horizontal',
		Video3dRi		: 'row_interleaved',
		Video3dArc		: 'anaglyph_cyan_red',
		Video3dAgm		: 'anaglyph_green_magenta',
		Video3dNone		: '',
	}

	ExpressionVideo3d = {
		'keyword' : {
			'bluray'		: u'(?:{separator}*(?:bluray|bd))?',
			'standalone'	: u'(3(?:d|Д))',
			'3d'			: u'(?:{separator}*{bluray}?3d{bluray}?{separator}*)',
			'sbs'			: u'(?:sbs|side{separator}*(?:by)?{separator}*side|lr|left{separator}*(?:and)?{separator}*right|split{separator}*horizontal(?:ly)?|horizontal(?:ly)?{separator}*split|3dh)',
			'rsbs'			: u'(?:(?:sbs|side{separator}*(?:by)?{separator}*side){separator}*(?:right{separator}*(?:and)?{separator}*left|r{separator}*l)|right{separator}*(?:and)?{separator}*left)',
			'ou'			: u'(?:ou|over{separator}*(?:and)?{separator}*under|ta?b|top{separator}*(?:and)?{separator}*bottom|split{separator}*vertical(?:ly)?|vertical(?:ly)?{separator}*split|3dv)',
			'ou2'			: u'(?:over{separator}*(?:and)?{separator}*under|top{separator}*(?:and)?{separator}*bottom|split{separator}*vertical(?:ly)?|vertical(?:ly)?{separator}*split|3dv)',
			'rou'			: u'(?:under{separator}*(?:and)?{separator}*over|bottom{separator}*(?:and)?{separator}*top)',
			'full'			: u'(?:f(?:ull)?)?{separator}*',
			'passive'		: u'(?:p(?:assive)?)?{separator}', # Do not make separator optional, since the keyword POU is used for other things as well.
			'half'			: u'(?:h(?:alf)?){separator}*',
			'vr'			: u'(?:vr|virtual{separator}*reality|eac|f(?:ish{separator}*eye)?){separator}*',
			'anaglyph'		: u'anaglyph(?:ic)?{symbol}*',
			'red'			: u'r(?:ed)?',
			'cyan'			: u'c(?:yan)?',
			'green'			: u'g(?:reen)?',
			'magenta'		: u'm(?:agenta)?',
		},

		'expression' : (
			(Video3dRsbs,		u'({3d}?{rsbs}{3d}?)'),
			(Video3dHsbs,		u'({3d}?{half}{sbs}{3d}?)'),
			(Video3dFsbs,		u'({3d}?{full}{sbs}{3d}?)'),
			(Video3dRou,		u'({3d}?{rou}{3d}?)'),
			(Video3dHou,		u'({3d}?{half}{ou}{3d}?)'),
			(Video3dFou,		u'({3d}.*?{full}{ou}{3d}?|{3d}?{full}{ou}[^a-z].*?{3d}|{3d}?{full}{ou2}{3d}?)'), # Avoid "OU" keyword being detected as 3D if no other 3D keyword appears.
			(Video3dPou,		u'({3d}?{passive}{ou}{3d}?)'),
			(Video3d180,		u'({3d}?{vr}180{3d}?)'),
			(Video3d360,		u'({3d}?{vr}360{3d}?)'),
			(Video3dRi,			u'({3d}?(?:row|line){separator}*inter(?:leaved|laced){3d}?)'),
			(Video3dAgm,		u'({3d}?(?:{anaglyph})?(?:{green}{symbol}*{magenta}|{magenta}{symbol}*{green}){3d})'),
			(Video3dArc,		u'({3d}?{anaglyph}|(?:{anaglyph})?(?:{red}{symbol}*{cyan}|{cyan}{symbol}*{red}){3d})'), # Assume RC if only the {anaglyph} keyword is present.
			(Video3dMono,		u'({3d}?monoscop(?:ic|y|e){3d}?)'),
			(Video3dStereo,		u'({3d}|{3d}?e?stereoscop(?:ico?|y|e){3d}?)'),
		),
	}

	LabelVideo3d = {
		LabelDefault : {
			LabelList1		: LabelMedium,
			LabelList2		: LabelShort,
			LabelList3		: LabelShort,
			LabelList4		: LabelShort,
			LabelInfo1		: LabelMedium,
			LabelInfo2		: LabelLong,
			LabelSettings1	: LabelLong,
			LabelSettings2	: LabelMedium,
		},

		Video3d			: { LabelShort : '3D',	LabelMedium : '3D',		LabelLong : '3D' },
		Video3dStereo	: { LabelShort : '3D',	LabelMedium : 'STRO',	LabelLong : 'Stereoscopic' },
		Video3dMono		: { LabelShort : '3D',	LabelMedium : 'MONO',	LabelLong : 'Monoscopic' },
		Video3dFsbs		: { LabelShort : '3D',	LabelMedium : 'FSBS',	LabelLong : 'Full Side By Side' },
		Video3dHsbs		: { LabelShort : '3D',	LabelMedium : 'HSBS',	LabelLong : 'Half Side By Side' },
		Video3dRsbs		: { LabelShort : '3D',	LabelMedium : 'RSBS',	LabelLong : 'Reversed Side By Side' },
		Video3dFou		: { LabelShort : '3D',	LabelMedium : 'FOU',	LabelLong : 'Full Over And Under' },
		Video3dHou		: { LabelShort : '3D',	LabelMedium : 'HOU',	LabelLong : 'Half Over And Under' },
		Video3dRou		: { LabelShort : '3D',	LabelMedium : 'ROU',	LabelLong : 'Reversed Over And Under' },
		Video3dPou		: { LabelShort : '3D',	LabelMedium : 'POU',	LabelLong : 'Passive Over And Under' },
		Video3d180		: { LabelShort : '3D',	LabelMedium : '180',	LabelLong : 'Virtual Reality 180' },
		Video3d360		: { LabelShort : '3D',	LabelMedium : '360',	LabelLong : 'Virtual Reality 360' },
		Video3dRi		: { LabelShort : '3D',	LabelMedium : 'RI',		LabelLong : 'Row Interleaved' },
		Video3dArc		: { LabelShort : '3D',	LabelMedium : 'ARC',	LabelLong : 'Anaglyph Red Cyan' },
		Video3dAgm		: { LabelShort : '3D',	LabelMedium : 'AGM',	LabelLong : 'Anaglyph Green Magenta' },
	}

	OrderVideo3d = {
		Video3d			: { OrderInterface : None,	OrderSorting : None },
		Video3dStereo	: { OrderInterface : 1,		OrderSorting : 8 },
		Video3dMono		: { OrderInterface : 2,		OrderSorting : 14 },
		Video3dFsbs		: { OrderInterface : 3,		OrderSorting : 1 },
		Video3dHsbs		: { OrderInterface : 4,		OrderSorting : 4 },
		Video3dRsbs		: { OrderInterface : 5,		OrderSorting : 6 },
		Video3dFou		: { OrderInterface : 6,		OrderSorting : 2 },
		Video3dHou		: { OrderInterface : 7,		OrderSorting : 5 },
		Video3dRou		: { OrderInterface : 8,		OrderSorting : 7 },
		Video3dPou		: { OrderInterface : 9,		OrderSorting : 3 },
		Video3d180		: { OrderInterface : 10,	OrderSorting : 10 },
		Video3d360		: { OrderInterface : 11,	OrderSorting : 9 },
		Video3dRi		: { OrderInterface : 12,	OrderSorting : 11 },
		Video3dArc		: { OrderInterface : 13,	OrderSorting : 12 },
		Video3dAgm		: { OrderInterface : 14,	OrderSorting : 13 },

	}

	##############################################################################
	# AUDIO TYPE
	##############################################################################

	AudioTypeOriginal	= 'original'	# Original high quality untouched audio.
	AudioTypeLine		= 'line'		# Low quality audio recorded from a line out connection of a projector, or live environment from earing impaired feeds or drive-ins.
	AudioTypeMic		= 'mic'			# Lowest quality audio recorded with a microphone from a live environment, often unintelligible or with people talking in the background.
	AudioTypeDubbed		= 'dubbed'		# High quality dubbed-over audio.
	AudioTypeDubbedLine	= 'dubbedline'	# Just like AudioTypeLine, but the recorded audio has a different language to the original video.
	AudioTypeDubbedMic	= 'dubbedmic'	# Just like AudioTypeMic, but the recorded audio has a different language to the original video.
	AudioTypeDubbedFan	= 'dubbedfan'	# Fan-made, probably low-quality, dubbed-over audio.
	AudioTypeDefault	= AudioTypeOriginal
	AudioTypeDubbeds	= {
		AudioTypeDubbed : True,
		AudioTypeDubbedLine : True,
		AudioTypeDubbedMic : True,
		AudioTypeDubbedFan : True,
	}
	AudioTypeRecordings	= {
		AudioTypeLine : True,
		AudioTypeMic : True,
	}

	# Exclude certain keywords from matching language, since they are too common.
	# Use a dictionary for faster lookups.
	# Eg: Icelandic's code/country is "is", but that is a very common English word that might appear in decsriptions, episode titles, etc.
	AudioExcluded		= {
							# Common English words.
							'is' : True, 'ice' : True,
							'in' : True,
							'it' : True,
							'us' : True,
							'no' : True,

							# Used in German file names, eg: "German.ML"
							'ml' : True,
						}

	# https://translate.google.com/translate?hl=en&sl=fr&u=https://astuto.fr/definitions-vfq-vf-vost-truefrench-subforced-vostfr/&prev=search&pto=aue
	# https://translate.google.com/translate?hl=en&sl=fr&u=https://fr.wikipedia.org/wiki/Doublage&prev=search&pto=aue
	# https://translate.google.com/translate?hl=en&sl=fr&u=https://lesniouzdotcom.wordpress.com/2013/10/06/version-francaise-ou-quebecoise-comment-les-reconnaitre/comment-page-1/&prev=search&pto=aue
	#	VFSTFR/VFSTF = French audio (dubbed) + French subtitles
	#	VOSTFR/VOSTF = Original audio (not dubbed) + French subtitles
	#	VOST = Original audio (not dubbed) + subtitles (don't have to be French, but probably are French)
	#	VO = Original audio (not dubbed)
	#	VOF/VOFR = French audio (not dubbed)
	#	VF = French audio (dubbed)
	#	VFF/TRUEFRENCH/PFD = French audio from France (dubbed)
	#	VQ/VFQ = French audio from Québec (dubbed)
	#	VFB = French audio from Belgium (dubbed)
	#	VFI = French audio international (dubbed - same as TRUEFRENCH/PFD)

	# https://translate.google.com/translate?hl=en&sl=es&u=https://hinative.com/en-US/questions/5087505&prev=search&pto=aue
	#	VOS = Original audio (not dubbed) + subtitles (don't have to be Spanish, but probably are Spanish, but can also be French)
	#	VOSE = Original audio (not dubbed) + Spanish subtitles

	ExpressionAudio				= u'(?:(?<!discovery[\s\-\–\_\+\.])(?<!history[\s\-\–\_\+\.])ch(?:annels?)?|audios?|sound|surround|spoken|gesproken?|(?<!the.)(?<!an.)original)' # Original for: "Dub + Original Eng + Sub Rus, Eng", but exclude "Star Trek The Original series".
	ExpressionAudioDual			= u'{symbol_start}(dual(?:{separator}*audio)?|multi(?:ple)?{separator}*(?:audio|lang(?:uages?)?)|multi{separator}*lingu(?:al|e)){symbol_end}'
	ExpressionAudioEnglish		= [u'engelsk?', 'engl']
	ExpressionAudioFrench		= [u'vfstfr', u'vfstf', u'vfst', u'vf', u'vof', u'vofr', u'vff', u'vfq', u'vfb', u'truefrench', u'fq', u'pfd', u'vfi']
	ExpressionAudioSpanish		= [u'lat(?:i(?:no)?)?', u'hispan(?:ic|o)', 'cast(?:ellano|ilian|ile)']
	ExpressionAudioPortuguese	= [u'ptbr?']
	ExpressionAudioGerman		= [u'tysk']
	ExpressionAudioPolish		= [u'lek(?:tor)?' + ExpressionSeparator + '*pl']
	ExpressionAudioChinese		= [u'chs', u'mandarin']
	ExpressionAudioRussian		= [u'ussr'] # For old encodings, eg: The.Terminator.1984.dub.USSR_encoded.mkv
	ExpressionAudioHindi		= [u'hind']
	ExpressionAudioArabic		= [u'arabian?']
	ExpressionAudioAzerbaijani	= [u'Azerbaijan']
	ExpressionAudioNordic 		= [[u'nordic', u'scandinavian?'], u'nor swe fin dan']
	ExpressionAudioOther		= [u'vo', u'vost', u'vostfr', u'vostf', u'vos', u'vose']

	ExpressionAudioType = {
		'keyword' : {
			'codec'			: u'(?:(?:e{separator}*)?[aа][cс]{separator}*\d|dd(?:plus|p|\+)|true{separator}*hd|atmos|dts(?:{separator}*x)?|dca|hd{separator}*(?:ma|hra?)|aac)', # Eg: AC3D means AC3 Dubbed.
			'dubbed'		: u'(?:dub(?:s|bs?|bed|bings?)?|d[ou]bla(?:d(?:[ao]|je)|gem)|synchron(?:isiert)|doubl(?:é|e)e|vf|Дублированный|{french}|{polish})',
			'dubbedline'	: u'(?:(?<!trek.)ld|Профессиональный{separator}*(?:одноголосый|многоголосый))', # Exclude "Star Trek LD" (Lower Decks).
			'dubbedmic'		: u'md',
			'dubbedfan'		: u'Любительский{separator}*(?:одноголосый|многоголосый)',
			'line'			: u'line',
			'mic'			: u'(?:mic(?:rophone)?|cam{separator}*(?:aud(?:io)?|sound))',
			'fan'			: u'fan{separator}*(?:made|created)?',

			'french'		: u'(?:vfstfr?|vff?|true{separator}*french|pfd|vf?q|vfb|vfi)',
			'polish'		: u'(?:lektor(?:{separator}*pl)?|lek{separator}*pl)',
		},

		'expression' : (
			(AudioTypeDubbedFan,	u'({dubbedfan}|{fan}{symbol}*{dubbed}|{dubbed}{symbol}*{fan})'),
			(AudioTypeDubbedLine,	u'({dubbedline}|{line}{symbol}*{dubbed}|{dubbed}{symbol}*{line}|{codec}{separator}*{dubbedline})'),
			(AudioTypeDubbedMic,	u'({dubbedmic}|{mic}{symbol}*{dubbed}|{dubbed}{symbol}*{mic}|{codec}{separator}*{dubbedmic})'),
			(AudioTypeDubbed,		u'({dubbed}|{codec}d)'),
			(AudioTypeLine,			u'({line})'),
			(AudioTypeMic,			u'({mic})'),
		),
	}

	LabelAudioType = {
		LabelDefault : {
			LabelList1		: LabelMedium,
			LabelList2		: LabelShort,
			LabelList3		: LabelShort,
			LabelList4		: LabelShort,
			LabelInfo1		: LabelLong,
			LabelInfo2		: LabelHidden,
			LabelSettings1	: LabelLong,
			LabelSettings2	: LabelShort,
		},

		AudioTypeOriginal	: { LabelShort : 'ORG',	LabelMedium : 'Original',		LabelLong : 'Original Audio' },
		AudioTypeLine		: { LabelShort : 'LIN',	LabelMedium : 'Line',			LabelLong : 'Line Recorded Audio' },
		AudioTypeMic		: { LabelShort : 'MIC',	LabelMedium : 'Mic',			LabelLong : 'Microphone Recorded Audio' },
		AudioTypeDubbed		: { LabelShort : 'DUB',	LabelMedium : 'Dubbed',			LabelLong : 'Dubbed Audio' },
		AudioTypeDubbedLine	: { LabelShort : 'DLN',	LabelMedium : 'Line-Dubbed',	LabelLong : 'Dubbed Line Recorded Audio' },
		AudioTypeDubbedMic	: { LabelShort : 'DMC',	LabelMedium : 'Mic-Dubbed',		LabelLong : 'Dubbed Microphone Recorded Audio' },
		AudioTypeDubbedFan	: { LabelShort : 'DFN',	LabelMedium : 'Fan-Dubbed',		LabelLong : 'Dubbed Fan-Made Audio' },
	}

	OrderAudioType = {
		AudioTypeOriginal	: { OrderInterface : 1,	OrderSorting : 1 },
		AudioTypeLine		: { OrderInterface : 2,	OrderSorting : 3 },
		AudioTypeMic		: { OrderInterface : 3,	OrderSorting : 4 },
		AudioTypeDubbed		: { OrderInterface : 4,	OrderSorting : 2 },
		AudioTypeDubbedLine	: { OrderInterface : 5,	OrderSorting : 5 },
		AudioTypeDubbedMic	: { OrderInterface : 6,	OrderSorting : 6 },
		AudioTypeDubbedFan	: { OrderInterface : 7,	OrderSorting : 7 },
	}

	##############################################################################
	# AUDIO CHANNELS
	##############################################################################

	# https://kodi.wiki/view/InfoLabels#ListItem - ListItem.AudioChannels

	AudioChannels1			= 1		# 1.0 Mono
	AudioChannels2			= 2		# 2.0 Stereo
	AudioChannels3			= 3		# 2.1 Surround Sound
	AudioChannels4			= 4		# 3.1 Surround Sound
	AudioChannels5			= 5		# 4.1 Surround Sound
	AudioChannels6			= 6		# 5.1 Surround Sound
	AudioChannels7			= 7		# 5.2 or 6.1 Surround Sound
	AudioChannels8			= 8		# 7.1 Surround Sound
	AudioChannels9			= 9		# 7.2 or 8.1 Surround Sound
	AudioChannels10			= 10	# 9.1 Surround Sound
	AudioChannels11			= 11	# 9.2 or 10.1 Surround Sound
	AudioChannels12			= 12	# 11.1 Surround Sound
	AudioChannels13			= 13	# 11.2 or 12.1 Surround Sound
	AudioChannelsNone		= None

	KodiAudioChannels = {
		AudioChannels1		: 1,
		AudioChannels2		: 2,
		AudioChannels3		: 2,
		AudioChannels4		: 4,
		AudioChannels5		: 5,
		AudioChannels6		: 6,
		AudioChannels7		: 7,
		AudioChannels8		: 8,
		AudioChannels9		: 8,
		AudioChannels10		: 10,
		AudioChannels11		: 10,
		AudioChannels12		: 10,
		AudioChannels13		: 10,
	}

	ExpressionAudioChannels = {
		'keyword' : {
			'size'		: u'(?!(?:\.\d+)?\s*[mgt]i?bs?)', # Not followed by size (eg: 5.1GB)
			'preceed'	: u'(?<![578]{separator})',
			'system'	: u'(?:ddp?|truehd|atmos|plus|e?[aа][cс]{separator}*[34]|dts(?:{separator}*x)?|dca|hd{separator}*hra?|hd{separator}*ma|hd|aac(?:{separator}*vl)?|mp3|flac|ogg|alac|dbx{separator}*[12]|dra|l?pcm|lcpm){symbol}*',
			'channels'	: u'{separator}*(?:ch(?:annel?)?s?|surround|spoken|gesproken?|original)',
			'extension'	: u'(?!{separator}\d)',
			'prefix'	: u'(?:[a-z]{{2,3}})?', # Eng5.1
			'suffix'	: u'(?:@\d+|[a-z]{{2,3}})?', # Bitrate: 5.1@768 - Eng5.1
		},

		# Use this weird order to speed up execution. First check the most common keywords.
		# Use: ['(?:{channels}|{system})']]),
		# Instead of: ['{channels}', '{system}']]),
		# Sincee it is about 30% faster.
		'expression' : (
			(AudioChannels8,	[[u'{prefix}(?:8(?:{separator}0)?{size}{suffix}{extension})'],									[u'{channels}']]),
			(AudioChannels8,	[[u'{prefix}(?:7{separator}*1){size}{suffix}'],													[u'(?:{channels}|{system})']]),
			(AudioChannels8,	[[u'{prefix}(?:7{separator}1){size}{suffix}']]),

			(AudioChannels6,	[[u'{prefix}(?:6(?:{separator}0)?{size}{suffix}{extension})'],									[u'{channels}']]),
			(AudioChannels6,	[[u'{prefix}(?:5{separator}*1){size}{suffix}'],													[u'(?:{channels}|{system})']]),
			(AudioChannels6,	[[u'{prefix}(?:5{separator}1){size}{suffix}']]),

			(AudioChannels2,	[[u'{prefix}(?<!hd)(?:2(?:{separator}0)?{size}{suffix})'],										[u'{channels}']]),
			(AudioChannels2,	[[u'{prefix}(?<!hd)(?:2(?:{separator}0)?){size}{suffix}'],										[u'(?:{channels}|{system})']]),
			(AudioChannels2,	[[u'{prefix}(?<!hd)(?:stereo|(?:2{separator}0){size}{suffix})']]),

			(AudioChannels13,	[[u'{prefix}(?:13(?:{separator}0)?{size}{suffix}{extension})'],									[u'{channels}']]),
			(AudioChannels13,	[[u'{prefix}(?:12{separator}*1|11{separator}2){size}{suffix}'],									[u'(?:{channels}|{system})']]),
			(AudioChannels13,	[[u'{prefix}(?:12{separator}1|11{separator}2){size}{suffix}']]),

			(AudioChannels12,	[[u'{prefix}(?:12(?:{separator}0)?{size}{suffix}{extension})'],									[u'{channels}']]),
			(AudioChannels12,	[[u'{prefix}(?:11{separator}1){size}{suffix}'],													[u'(?:{channels}|{system})']]),
			(AudioChannels12,	[[u'{prefix}(?:11{separator}1){size}{suffix}']]),

			(AudioChannels11,	[[u'{prefix}(?:11(?:{separator}0)?{size}{suffix}{extension})'],									[u'{channels}']]),
			(AudioChannels11,	[[u'{prefix}(?:10{separator}1|9{separator}2){size}{suffix}'],									[u'(?:{channels}|{system})']]),
			(AudioChannels11,	[[u'{prefix}(?:10{separator}1|9{separator}2){size}{suffix}']]),

			(AudioChannels10,	[[u'{prefix}(?:10(?:{separator}0)?{extension}){size}{suffix}'],									[u'{channels}']]),
			(AudioChannels10,	[[u'{prefix}(?:9{separator}1){size}{suffix}'],													[u'(?:{channels}|{system})']]),
			(AudioChannels10,	[[u'{prefix}(?:9{separator}1){size}{suffix}']]),

			(AudioChannels9,	[[u'{prefix}(?:9(?:{separator}0)?{size}{suffix}{extension})'],									[u'{channels}']]),
			(AudioChannels9,	[[u'{prefix}(?:8{separator}1|7{separator}2){size}{suffix}'],									[u'(?:{channels}|{system})']]),
			(AudioChannels9,	[[u'{prefix}(?:8{separator}1|7{separator}2){size}{suffix}']]),

			(AudioChannels7,	[[u'{prefix}(?:7(?:{separator}0)?{size}{suffix}{extension})'],									[u'{channels}']]),
			(AudioChannels7,	[[u'{prefix}(?:6{separator}1|5{separator}2){size}{suffix}'],									[u'(?:{channels}|{system})']]),
			(AudioChannels7,	[[u'{prefix}(?:6{separator}1|5{separator}2){size}{suffix}']]),

			(AudioChannels5,	[[u'{prefix}(?:5(?:{separator}0)?{size}{suffix}{extension})'],									[u'{channels}']]),
			(AudioChannels5,	[[u'{prefix}(?:4{separator}1){size}{suffix}'],													[u'(?:{channels}|{system})']]),
			(AudioChannels5,	[[u'{prefix}(?:4{separator}1){size}{suffix}']]),

			(AudioChannels4,	[[u'{prefix}(?:4(?:{separator}0)?){size}'],														[u'{channels}']]),
			(AudioChannels4,	[[u'{prefix}(?:3{separator}1){size}'],															[u'(?:{channels}|{system})']]),
			(AudioChannels4,	[[u'{prefix}(?:quad(?:ra|ro)?(?:phonic|sonic)?|(?:4{separator}0|3{separator}1){size})']]),

			(AudioChannels1,	[[u'{prefix}(?:mono|{preceed}1(?:{separator}0)?{size})'],										[u'(?:{channels}|{system})']]),
			(AudioChannels1,	[[u'{prefix}(?:mono)']]),
		),
	}

	LabelAudioChannels = {
		LabelDefault : {
			LabelList1		: LabelShort,
			LabelList2		: LabelShort,
			LabelList3		: LabelShort,
			LabelList4		: LabelShort,
			LabelInfo1		: LabelMedium,
			LabelInfo2		: LabelLong,
			LabelSettings1	: LabelLong,
			LabelSettings2	: LabelShort,
		},

		AudioChannels1	: { LabelShort : '1CH',		LabelMedium : '1 Channel',		LabelLong : 'Mono Sound' },
		AudioChannels2	: { LabelShort : '2CH',		LabelMedium : '2 Channels',		LabelLong : 'Stereo Sound' },
		AudioChannels3	: { LabelShort : '3CH',		LabelMedium : '3 Channels',		LabelLong : '2.1 Front Sound' },
		AudioChannels4	: { LabelShort : '4CH',		LabelMedium : '4 Channels',		LabelLong : '3.1 Front Sound' },
		AudioChannels5	: { LabelShort : '5CH',		LabelMedium : '5 Channels',		LabelLong : '4.1 Surround Sound' },
		AudioChannels6	: { LabelShort : '6CH',		LabelMedium : '6 Channels',		LabelLong : '5.1 Surround Sound' },
		AudioChannels7	: { LabelShort : '7CH',		LabelMedium : '7 Channels',		LabelLong : '5.2 Surround Sound' },
		AudioChannels8	: { LabelShort : '8CH',		LabelMedium : '8 Channels',		LabelLong : '7.1 Surround Sound' },
		AudioChannels9	: { LabelShort : '9CH',		LabelMedium : '9 Channels',		LabelLong : '7.2 Surround Sound' },
		AudioChannels10	: { LabelShort : '10CH',	LabelMedium : '10 Channels',	LabelLong : '9.1 Surround Sound' },
		AudioChannels11	: { LabelShort : '11CH',	LabelMedium : '11 Channels',	LabelLong : '9.2 Surround Sound' },
		AudioChannels12	: { LabelShort : '12CH',	LabelMedium : '12 Channels',	LabelLong : '11.1 Surround Sound' },
		AudioChannels13	: { LabelShort : '13CH',	LabelMedium : '13 Channels',	LabelLong : '11.2 Surround Sound' },
	}

	OrderAudioChannels = {
		AudioChannels1	: { OrderInterface : 1,		OrderSorting : 13 },
		AudioChannels2	: { OrderInterface : 2,		OrderSorting : 12 },
		AudioChannels3	: { OrderInterface : 3,		OrderSorting : 11 },
		AudioChannels4	: { OrderInterface : 4,		OrderSorting : 10 },
		AudioChannels5	: { OrderInterface : 5,		OrderSorting : 9 },
		AudioChannels6	: { OrderInterface : 6,		OrderSorting : 8 },
		AudioChannels7	: { OrderInterface : 7,		OrderSorting : 7 },
		AudioChannels8	: { OrderInterface : 8,		OrderSorting : 6 },
		AudioChannels9	: { OrderInterface : 9,		OrderSorting : 5 },
		AudioChannels10	: { OrderInterface : 10,	OrderSorting : 4 },
		AudioChannels11	: { OrderInterface : 11,	OrderSorting : 3 },
		AudioChannels12	: { OrderInterface : 12,	OrderSorting : 2 },
		AudioChannels13	: { OrderInterface : 13,	OrderSorting : 1 },
	}

	##############################################################################
	# AUDIO SYSTEM
	##############################################################################

	AudioSystemDolby	= 'dolby'		# Dolby Laboratories
	AudioSystemDts		= 'dts'			# Digital Theater Systems
	AudioSystemMpeg		= 'mpeg'		# Moving Picture Experts Group
	AudioSystemSrs		= 'srs'			# SRS Labs
	AudioSystemDbx		= 'dbx'			# DBX
	AudioSystemXiph		= 'xiph'		# Xiph Foundation
	AudioSystemSony		= 'sony'		# Sony
	AudioSystemApple	= 'apple'		# Apple
	AudioSystemWindows	= 'windows'		# Windows
	AudioSystemDigirise	= 'digirise'	# DigiRise Interactive Media
	AudioSystemNone		= None

	ExpressionAudioSystem = {
		'keyword' : {
			'extension'	: u'(?:(?:{separator}*\d{{1,2}}{separator}*[01]|@\d{{2,4}}){separator}*)?', # Channels or bitrate (eg: AAC5.1 or AAC@128).
		},

		'expression' : (
			(AudioSystemDolby,		u'({extension}(dd|dolby(?:{separator}*digital)?){extension})'),
			(AudioSystemDts,		u'({extension}(dts|dca|digital{separator}*theater{separator}*systems){extension})'), # DCA seems to be the original DTS core codec (DTS Coherent Acoustics). Today it is used as synonym to DTS. Do not interpret it as codec, but rather as system.
			(AudioSystemMpeg,		u'({extension}mpg123{extension})'), # Sometimes returned by EasyNews (a tool/library rather than a codec/system).

			# Do not check these, since the are uncommon/non-existent in file names and only increase execution time.
			# These should in any case be detected by the audio codec.
			#(AudioSystemSrs,		u'({extension}srs{extension})'),
			#(AudioSystemDbx,		u'({extension}dbx{extension})'),
			#(AudioSystemXiph,		u'({extension}xiph{extension})'),
			#(AudioSystemSony,		u'({extension}(?:sony|sdds){extension})'),
			#(AudioSystemApple,		u'({extension}apple{extension})'),
			#(AudioSystemWindows,	u'({extension}windows{extension})'),
			#(AudioSystemDigirise,	u'({extension}digi{separator}*rise{extension})'),
		),
	}

	LabelAudioSystem = {
		LabelDefault : {
			LabelList1		: LabelShort,
			LabelList2		: LabelShort,
			LabelList3		: LabelShort,
			LabelList4		: LabelShort,
			LabelInfo1		: LabelShort,
			LabelInfo2		: LabelLong,
			LabelSettings1	: LabelLong,
			LabelSettings2	: LabelShort,
		},

		AudioSystemDolby	: { LabelShort : 'DLBY',	LabelMedium : 'Dolby',		LabelLong : 'Dolby Laboratories' },
		AudioSystemDts		: { LabelShort : 'DTS',		LabelMedium : 'DTS',		LabelLong : 'Digital Theater Systems' },
		AudioSystemMpeg		: { LabelShort : 'MPEG',	LabelMedium : 'MPEG',		LabelLong : 'Moving Picture Experts Group' },
		AudioSystemSrs		: { LabelShort : 'SRS',		LabelMedium : 'SRS',		LabelLong : 'SRS Labs' },
		AudioSystemXiph		: { LabelShort : 'XIPH',	LabelMedium : 'Xiph',		LabelLong : 'Xiph Foundation' },
		AudioSystemApple	: { LabelShort : 'APP',		LabelMedium : 'Apple',		LabelLong : 'Apple' },
		AudioSystemWindows	: { LabelShort : 'WIN',		LabelMedium : 'Windows',	LabelLong : 'Windows' },
		AudioSystemSony		: { LabelShort : 'SONY',	LabelMedium : 'Sony',		LabelLong : 'Sony' },
		AudioSystemDbx		: { LabelShort : 'DBX',		LabelMedium : 'DBX',		LabelLong : 'DBX' },
		AudioSystemDigirise	: { LabelShort : 'DIGI',	LabelMedium : 'DigiRise',	LabelLong : 'DigiRise Interactive Media' },
	}

	OrderAudioSystem = {
		AudioSystemDolby	: { OrderInterface : 1,		OrderSorting : 1 },
		AudioSystemDts		: { OrderInterface : 2,		OrderSorting : 2 },
		AudioSystemMpeg		: { OrderInterface : 3,		OrderSorting : 7 },
		AudioSystemSrs		: { OrderInterface : 7,		OrderSorting : 3 },
		AudioSystemXiph		: { OrderInterface : 4,		OrderSorting : 8 },
		AudioSystemApple	: { OrderInterface : 5,		OrderSorting : 9 },
		AudioSystemWindows	: { OrderInterface : 6,		OrderSorting : 10 },
		AudioSystemSony		: { OrderInterface : 8,		OrderSorting : 6 },
		AudioSystemDbx		: { OrderInterface : 9,		OrderSorting : 5 },
		AudioSystemDigirise	: { OrderInterface : 10,	OrderSorting : 4 },
	}

	PrefixAudioSystem = (
		AudioSystemDolby,
		AudioSystemDts,
		AudioSystemSrs,
		AudioSystemDigirise,
	)

	##############################################################################
	# AUDIO CODEC
	##############################################################################

	# https://en.wikipedia.org/wiki/Dolby_Laboratories
	# https://en.wikipedia.org/wiki/Dolby_Digital
	# https://en.wikipedia.org/wiki/DTS_(sound_system)
	# https://kodi.wiki/view/InfoLabels#ListItem - ListItem.AudioCodec

	AudioCodecAms		= 'ams'			# Dobly Atmos
	AudioCodecThd		= 'thd'			# Dobly TrueHD [lossless]
	AudioCodecThdams	= 'thdams'		# Dobly TrueHD Atmos
	AudioCodecPls		= 'pls'			# Dobly Digital Plus (EAC3) [lossy]
	AudioCodecPlsams	= 'plsams'		# Dobly Digital Plus (EAC3) Atmos
	AudioCodecAc4		= 'ac4'			# Dobly AC4
	AudioCodecAc4ams	= 'ac4ams'		# Dobly AC4 Atmos
	AudioCodecAc3		= 'ac3'			# Dobly Digital AC3
	AudioCodecPul		= 'pul'			# Dobly Pulse
	AudioCodecLve		= 'lve'			# Dobly Digital Live
	AudioCodecEx		= 'ex'			# Dobly Digital EX
	AudioCodecSex		= 'sex'			# Dobly Digital Surround EX
	AudioCodecPro		= 'pro'			# Dobly Pro Logic
	AudioCodecPro2		= 'pro2'		# Dobly Pro Logic II
	AudioCodecPro2x		= 'pro2x'		# Dobly Pro Logic IIx
	AudioCodecPro2z		= 'pro2z'		# Dobly Pro Logic IIz

	AudioCodecX			= 'x'			# DTS:X
	AudioCodecXp		= 'xp'			# DTS:X Pro
	AudioCodecHdma		= 'hdma'		# DTS HD Master Audio [lossless]
	AudioCodecHdmax		= 'hdmax'		# DTS HD Master Audio X
	AudioCodecHdmaxp	= 'hdmaxp'		# DTS HD Master Audio X Pro
	AudioCodecHdhr		= 'hdhr'		# DTS HD High Resolution Audio [lossy]
	AudioCodecHdhrx		= 'hdhrx'		# DTS HD High Resolution Audio X
	AudioCodecHdhrxp	= 'hdhrxp'		# DTS HD High Resolution Audio X Pro
	AudioCodecNeo		= 'neo'			# DTS Neo
	AudioCodecNeo6		= 'neo6'		# DTS Neo:6
	AudioCodecNeox		= 'neox'		# DTS Neo:X
	AudioCodecNeopc		= 'neopc'		# DTS Neo:PC
	AudioCodecNx		= 'nx'			# DTS Neural:X
	AudioCodecVx		= 'vx'			# DTS Virtual:X
	AudioCodecHx		= 'hx'			# DTS Headphone:X
	AudioCodecCon		= 'con'			# DTS Connect
	AudioCodecIna		= 'ina'			# DTS Interactive
	AudioCodecPyf		= 'pyf'			# DTS Play-Fi
	AudioCodecSur		= 'sur'			# DTS Surround
	AudioCodecSurs		= 'surs'		# DTS Surround Sensation
	AudioCodecEsur		= 'esur'		# DTS Extended Surround
	AudioCodec70		= '70'			# DTS 70MM
	AudioCodec9624		= '9624'		# DTS 96/24

	AudioCodecAac		= 'aac'			# MPEG Advanced Audio Coding
	AudioCodecHeaac		= 'heaac'		# MPEG High Efficiency Advanced Audio Coding
	AudioCodecLcaac		= 'lcaac'		# MPEG Low Complexity Advanced Audio Coding
	AudioCodecMp3		= 'mp3'			# MPEG Audio Layer III
	AudioCodecMp2		= 'mp2'			# MPEG Audio Layer II
	AudioCodecMp1		= 'mp1'			# MPEG Audio Layer I

	AudioCodecAtrac		= 'atrac'		# Sony Adaptive Transform Acoustic Coding
	AudioCodecAtrac3	= 'atrac3'		# Sony Adaptive Transform Acoustic Coding 3
	AudioCodecAtrac3p	= 'atrac3p'		# Sony Adaptive Transform Acoustic Coding 3 Plus
	AudioCodecAtrac9	= 'atrac9'		# Sony Adaptive Transform Acoustic Coding 9
	AudioCodecAtracal	= 'atracal'		# Sony Adaptive Transform Acoustic Coding Advanced Lossless

	AudioCodecTv		= 'tv'			# SRS TruVolume
	AudioCodecSshd		= 'sshd'		# SRS StudioSound HD
	AudioCodecTshd		= 'tshd'		# SRS TruSurround HD
	AudioCodecTshd4		= 'tshd4'		# SRS TruSurround HD4
	AudioCodecTsxt		= 'tsxt'		# SRS TruSurround XT
	AudioCodecTs		= 'ts'			# SRS TheaterSound
	AudioCodecTshd		= 'tshd'		# SRS TheaterSound HD
	AudioCodecH360		= 'h360'		# SRS Headphone 360
	AudioCodecTb		= 'tb'			# SRS TruBass
	AudioCodecWhd		= 'whd'			# SRS WOW HD
	AudioCodecTm		= 'tm'			# SRS TruMedia
	AudioCodecDc		= 'dc'			# SRS Dialog Clarity
	AudioCodecCs		= 'cs'			# SRS Circle Surround
	AudioCodecCsh		= 'csh'			# SRS Circle Surround Headphone
	AudioCodecCsa		= 'csa'			# SRS Circle Surround Auto

	AudioCodecWma		= 'wma'			# Windows Media Audio
	AudioCodecWma2		= 'wma2'		# Windows Media Audio Version 2
	AudioCodecWmap		= 'wmap'		# Windows Media Audio Professional
	AudioCodecWmal		= 'wmal'		# Windows Media Audio Lossless
	AudioCodecWmav		= 'wmav'		# Windows Media Audio Voice

	AudioCodecFlac		= 'flac'		# Xiph FLAC
	AudioCodecVorbis	= 'vorbis'		# Xiph Vorbis
	AudioCodecOpus		= 'opus'		# Xiph Opus

	AudioCodecAlac		= 'alac'		# Apple Lossless Audio Codec
	AudioCodecAiff		= 'aiff'		# Apple Audio Interchange File Format

	AudioCodecDra		= 'dra'			# DigiRise Dynamic Resolution Adaptation

	AudioCodecDbx1		= 'dbx1'		# DBX Type 1
	AudioCodecDbx2		= 'dbx2'		# DBX Type 2

	AudioCodecPcm		= 'pcm'			# Pulse Code Modulation

	AudioCodecNone		= None

	AudioCodecSystem = {
		AudioCodecAms		: AudioSystemDolby,
		AudioCodecThd		: AudioSystemDolby,
		AudioCodecThdams	: AudioSystemDolby,
		AudioCodecPls		: AudioSystemDolby,
		AudioCodecPlsams	: AudioSystemDolby,
		AudioCodecAc4		: AudioSystemDolby,
		AudioCodecAc4ams	: AudioSystemDolby,
		AudioCodecAc3		: AudioSystemDolby,
		AudioCodecPul		: AudioSystemDolby,
		AudioCodecLve		: AudioSystemDolby,
		AudioCodecEx		: AudioSystemDolby,
		AudioCodecSex		: AudioSystemDolby,
		AudioCodecPro		: AudioSystemDolby,
		AudioCodecPro2		: AudioSystemDolby,
		AudioCodecPro2x		: AudioSystemDolby,
		AudioCodecPro2z		: AudioSystemDolby,

		AudioCodecX			: AudioSystemDts,
		AudioCodecXp		: AudioSystemDts,
		AudioCodecHdma		: AudioSystemDts,
		AudioCodecHdmax		: AudioSystemDts,
		AudioCodecHdmaxp	: AudioSystemDts,
		AudioCodecHdhr		: AudioSystemDts,
		AudioCodecHdhrx		: AudioSystemDts,
		AudioCodecHdhrxp	: AudioSystemDts,
		AudioCodecNeo		: AudioSystemDts,
		AudioCodecNeo6		: AudioSystemDts,
		AudioCodecNeox		: AudioSystemDts,
		AudioCodecNeopc		: AudioSystemDts,
		AudioCodecNx		: AudioSystemDts,
		AudioCodecVx		: AudioSystemDts,
		AudioCodecHx		: AudioSystemDts,
		AudioCodecCon		: AudioSystemDts,
		AudioCodecIna		: AudioSystemDts,
		AudioCodecPyf		: AudioSystemDts,
		AudioCodecSur		: AudioSystemDts,
		AudioCodecSurs		: AudioSystemDts,
		AudioCodecEsur		: AudioSystemDts,
		AudioCodec70		: AudioSystemDts,
		AudioCodec9624		: AudioSystemDts,

		AudioCodecAac		: AudioSystemMpeg,
		AudioCodecHeaac		: AudioSystemMpeg,
		AudioCodecLcaac		: AudioSystemMpeg,
		AudioCodecMp3		: AudioSystemMpeg,
		AudioCodecMp2		: AudioSystemMpeg,
		AudioCodecMp1		: AudioSystemMpeg,

		AudioCodecAtrac		: AudioSystemSony,
		AudioCodecAtrac3	: AudioSystemSony,
		AudioCodecAtrac3p	: AudioSystemSony,
		AudioCodecAtrac9	: AudioSystemSony,
		AudioCodecAtracal	: AudioSystemSony,

		AudioCodecTv		: AudioSystemSrs,
		AudioCodecSshd		: AudioSystemSrs,
		AudioCodecTshd		: AudioSystemSrs,
		AudioCodecTshd4		: AudioSystemSrs,
		AudioCodecTsxt		: AudioSystemSrs,
		AudioCodecTs		: AudioSystemSrs,
		AudioCodecTshd		: AudioSystemSrs,
		AudioCodecH360		: AudioSystemSrs,
		AudioCodecTb		: AudioSystemSrs,
		AudioCodecWhd		: AudioSystemSrs,
		AudioCodecTm		: AudioSystemSrs,
		AudioCodecDc		: AudioSystemSrs,
		AudioCodecCs		: AudioSystemSrs,
		AudioCodecCsh		: AudioSystemSrs,
		AudioCodecCsa		: AudioSystemSrs,

		AudioCodecWma		: AudioSystemWindows,
		AudioCodecWma2		: AudioSystemWindows,
		AudioCodecWmap		: AudioSystemWindows,
		AudioCodecWmal		: AudioSystemWindows,
		AudioCodecWmav		: AudioSystemWindows,

		AudioCodecFlac		: AudioSystemXiph,
		AudioCodecVorbis	: AudioSystemXiph,
		AudioCodecOpus		: AudioSystemXiph,

		AudioCodecAlac		: AudioSystemApple,
		AudioCodecAiff		: AudioSystemApple,

		AudioCodecDra		: AudioSystemDigirise,

		AudioCodecDbx1		: AudioSystemDbx,
		AudioCodecDbx2		: AudioSystemDbx,

		AudioCodecPcm		: AudioSystemNone,
	}

	# https://github.com/xbmc/xbmc/tree/master/addons/skin.estuary/media/flags/audiocodec
	KodiAudioCodec = {
		AudioCodecAms		: 'dolbydigital',
		AudioCodecThd		: 'truehd',
		AudioCodecThdams	: 'truehd',
		AudioCodecPls		: 'eac3',
		AudioCodecPlsams	: 'eac3',
		AudioCodecAc4		: 'dolbydigital',
		AudioCodecAc4ams	: 'dolbydigital',
		AudioCodecAc3		: 'ac3',
		AudioCodecPul		: 'dolbydigital',
		AudioCodecLve		: 'dolbydigital',
		AudioCodecEx		: 'dolbydigital',
		AudioCodecSex		: 'dolbydigital',
		AudioCodecPro		: 'dolbydigital',
		AudioCodecPro2		: 'dolbydigital',
		AudioCodecPro2x		: 'dolbydigital',
		AudioCodecPro2z		: 'dolbydigital',

		AudioCodecX			: 'dts',
		AudioCodecXp		: 'dts',
		AudioCodecHdma		: 'dtshd_ma',
		AudioCodecHdmax		: 'dtshd_ma',
		AudioCodecHdmaxp	: 'dtshd_ma',
		AudioCodecHdhr		: 'dtshd_hra',
		AudioCodecHdhrx		: 'dtshd_hra',
		AudioCodecHdhrxp	: 'dtshd_hra',
		AudioCodecNeo		: 'dts',
		AudioCodecNeo6		: 'dts',
		AudioCodecNeox		: 'dts',
		AudioCodecNeopc		: 'dts',
		AudioCodecNx		: 'dts',
		AudioCodecVx		: 'dts',
		AudioCodecHx		: 'dts',
		AudioCodecCon		: 'dts',
		AudioCodecIna		: 'dts',
		AudioCodecPyf		: 'dts',
		AudioCodecSur		: 'dts',
		AudioCodecSurs		: 'dts',
		AudioCodecEsur		: 'dts',
		AudioCodec70		: 'dts',
		AudioCodec9624		: 'dts',

		AudioCodecAac		: 'aac',
		AudioCodecHeaac		: 'aac',
		AudioCodecLcaac		: 'aac',
		AudioCodecMp3		: 'mp3',
		AudioCodecMp2		: 'mp2',
		AudioCodecMp1		: 'mp1',

		AudioCodecAtrac		: '',
		AudioCodecAtrac3	: '',
		AudioCodecAtrac3p	: '',
		AudioCodecAtrac9	: '',
		AudioCodecAtracal	: '',

		AudioCodecTv		: '',
		AudioCodecSshd		: '',
		AudioCodecTshd		: '',
		AudioCodecTshd4		: '',
		AudioCodecTsxt		: '',
		AudioCodecTs		: '',
		AudioCodecTshd		: '',
		AudioCodecH360		: '',
		AudioCodecTb		: '',
		AudioCodecWhd		: '',
		AudioCodecTm		: '',
		AudioCodecDc		: '',
		AudioCodecCs		: '',
		AudioCodecCsh		: '',
		AudioCodecCsa		: '',

		AudioCodecWma		: 'wma',
		AudioCodecWma2		: 'wmav2',
		AudioCodecWmap		: 'wmapro',
		AudioCodecWmal		: 'wmav2',
		AudioCodecWmav		: 'wmav2',

		AudioCodecFlac		: 'flac',
		AudioCodecVorbis	: 'vorbis',
		AudioCodecOpus		: 'opus',

		AudioCodecAlac		: 'alac',
		AudioCodecAiff		: 'aiff',

		AudioCodecDra		: '',

		AudioCodecDbx1		: '',
		AudioCodecDbx2		: '',

		AudioCodecPcm		: 'pcm',

		AudioCodecNone		: '',
	}

	ExpressionAudioCodec = {
		'keyword' : {
			'prefix'		: u'(?:\dx{separator}*)?',
			'colon'			: u'(?:{separator}|:)*',
			'registered'	: u'(?:{separator}*®)?',
			'extension'		: u'(?:(?:[lm]?d|{symbol}*(?:\d|\d\d){symbol}*[01]|@(?:\d\d|\d\d\d)|max){symbol}*)?', # Channels, bitrate, or dubbed (eg: AAC5.1 or AAC@128 or AC3D or AC3MD).
			'dts'			: u'{extension}(?:dts|dca){registered}{extension}',
			'dolby'			: u'{extension}(?:dd|dolby(?:{separator}*digital)?){registered}{extension}',
			'ams'			: u'{extension}atmos{extension}',
			'pls'			: u'{extension}(?:{dolby}{separator}*(?:plus|p|\+)|e(?:nhanced)?{separator}*ac{separator}*3|ec{separator}*3){extension}',
			'thd'			: u'{extension}(?:true{separator}*hd|thd){extension}',
			'ex'			: u'{extension}ex{extension}',
			'ac'			: u'{extension}[aа][cс]', # 2nd  characters are Cryllic.
			'pro'			: u'{extension}pro(?:{separator}*logic)?{extension}',
			'x'				: u'{extension}(?:dts{colon})?(?<!ma)x{extension}',
			'xp'			: u'{extension}(?:dts{colon})?(?<!ma)x{colon}pro{extension}',
			'hdhr'			: u'(?:{extension}(?:hd{separator}*)?hra?)',
			'hdma'			: u'(?:{extension}hd(?:{separator}*ma)?|ma|xll)',
			'neo'			: u'neo',
		},

		# Use this weird order to speed up execution. First check the most common keywords.
		'expression' : (
			# Do not check other codecs, since the are uncommon/non-existent in file names and only increase execution time.

			(AudioCodecPlsams,		[[u'({prefix}{pls})'], [u'({prefix}{ams})']]),
			(AudioCodecPlsams,		[[u'({prefix}{pls}a{extension})']]),
			(AudioCodecPls,			[[u'({prefix}{pls})']]),

			(AudioCodecThdams,		[[u'({prefix}{thd})'], [u'({prefix}{ams})']]),
			(AudioCodecThdams,		[[u'({prefix}{thd}a{extension})']]),
			(AudioCodecThd,			[[u'({prefix}{thd})']]),

			(AudioCodecAc4ams,		[[u'({prefix}{ac}{separator}*4{extension})'], [u'({prefix}{ams})']]),
			(AudioCodecAc4,			[[u'({prefix}{ac}{separator}*4{extension})']]),

			(AudioCodecAms,			[[u'({prefix}{ams})']]),
			(AudioCodecAc3,			[[u'({prefix}{ac}{separator}*3{extension})']]),

			(AudioCodecHdhrxp,		[[u'({prefix}(?:{hdhr}{colon}{xp}|{xp}{colon}{hdhr}){extension})']]),
			(AudioCodecHdhrx,		[[u'({prefix}(?:{hdhr}{colon}{x}|{x}{colon}{hdhr}){extension})']]),

			(AudioCodecHdmaxp,		[[u'({prefix}(?:{hdma}{colon}{xp}|{xp}{colon}{hdma}){extension})']]),
			(AudioCodecHdmax,		[[u'({prefix}(?:{hdma}{colon}{x}|{x}{colon}{hdma}){extension})']]),

			(AudioCodecXp,			[[u'({prefix}{dts}{colon}{xp})']]),
			(AudioCodecX,			[[u'({prefix}{dts}{colon}{x})']]),

			(AudioCodecHdhr,		[[u'({prefix}(?:{extension}hd{separator}*hra?|{dts}{separator}*{hdhr}){extension})']]),
			(AudioCodecHdma,		[[u'({prefix}(?:{extension}hd{separator}*ma|{dts}{separator}*{hdma}){extension})']]),

			(AudioCodecHeaac,		[[u'({prefix}{extension}(?:he{separator}*aac|e?aac{separator}*(?:he|plus|\+)){extension})']]),
			(AudioCodecLcaac,		[[u'({prefix}{extension}(?:lc{separator}*aac|aac{separator}*lc){extension})']]),
			(AudioCodecAac,			[[u'({prefix}{extension}(?:aac|faa[cd]\d?)(?:{separator}*vl)?{extension})']]),

			(AudioCodecMp3,			[[u'({prefix}mp3{extension})']]),
			(AudioCodecMp2,			[[u'({prefix}mp2{extension})']]),
			(AudioCodecMp1,			[[u'({prefix}mp1{extension})']]),

			(AudioCodecFlac,		[[u'({prefix}{extension}flac{extension})']]),
			(AudioCodecOpus,		[[u'({prefix}{extension}opus{extension})']]),
			(AudioCodecVorbis,		[[u'({prefix}{extension}(?:vorbis|ogg){extension})']]),

			(AudioCodecPul,			[[u'({prefix}{dolby}{separator}*pulse{extension})']]),
			(AudioCodecLve,			[[u'({prefix}{dolby}{separator}*live{extension})']]),
			(AudioCodecEx,			[[u'({prefix}{dolby}{separator}*{ex})']]),
			(AudioCodecSex,			[[u'({prefix}{dolby}{separator}*s(?:urround)?{separator}*{ex})']]),
			(AudioCodecPro2z,		[[u'({prefix}{pro}{separator}*(?:ii|2)z{extension})']]),
			(AudioCodecPro2x,		[[u'({prefix}{pro}{separator}*(?:ii|2)x{extension})']]),
			(AudioCodecPro2,		[[u'({prefix}{pro}{separator}*(?:ii|2){extension})']]),
			(AudioCodecPro,			[[u'({prefix}{dolby}{separator}*{pro})']]),
			(AudioCodecAc3,			[[u'({prefix}{dolby})']]),

			(AudioCodecNeopc,		[[u'({prefix}{dts}{separator}*{neo}{colon}pc{extension})']]),
			(AudioCodecNeox,		[[u'({prefix}{dts}{separator}*{neo}{colon}x{extension})']]),
			(AudioCodecNeo6,		[[u'({prefix}{dts}{separator}*{neo}{colon}6{extension})']]),
			(AudioCodecNeo,			[[u'({prefix}{dts}{separator}*{neo}{extension})']]),
			(AudioCodecNx,			[[u'({prefix}{dts}{separator}*neural{colon}x{extension})']]),
			(AudioCodecVx,			[[u'({prefix}{dts}{separator}*virtual{colon}x{extension})']]),
			(AudioCodecHx,			[[u'({prefix}{dts}{separator}*headphone{colon}x{extension})']]),
			(AudioCodecCon,			[[u'({prefix}{dts}{separator}*connect{extension})']]),
			(AudioCodecIna,			[[u'({prefix}{dts}{separator}*interactive{extension})']]),
			(AudioCodecPyf,			[[u'({prefix}{dts}{separator}*play{separator}*fi{extension})']]),
			(AudioCodecSur,			[[u'({prefix}{dts}{separator}*surround{extension})']]),
			(AudioCodecSurs,		[[u'({prefix}{dts}{separator}*surround{separator}*sensation{extension})']]),
			(AudioCodecEsur,		[[u'({prefix}{dts}{separator}*ext(?:ended)?{separator}*surround{extension})']]),
			(AudioCodec70,			[[u'({prefix}{dts}{separator}*70{separator}*mm{extension})']]),
			(AudioCodec9624,		[[u'({prefix}{dts}{separator}*96{separator}*24{extension})']]),

			(AudioCodecWma2,		[[u'({prefix}{extension}wma{separator}*v?2{extension})']]),
			(AudioCodecWmap,		[[u'({prefix}{extension}wma{separator}*pro(?:fessional)?{extension})']]),
			(AudioCodecWmal,		[[u'({prefix}{extension}wma{separator}*lossless{extension})']]),
			(AudioCodecWma,			[[u'({prefix}{extension}wma{extension})']]),

			(AudioCodecAlac,		[[u'({prefix}{extension}alac{extension})']]),
			(AudioCodecPcm,			[[u'({prefix}{extension}(?:l(?:inear{separator}*)?)?pcm{extension}|lcpm)']]),
		),
	}

	LabelAudioCodec = {
		LabelDefault : {
			LabelList1		: LabelShort,
			LabelList2		: LabelShort,
			LabelList3		: LabelShort,
			LabelList4		: LabelShort,
			LabelInfo1		: LabelShort,
			LabelInfo2		: LabelLong,
			LabelSettings1	: LabelLong,
			LabelSettings2	: LabelShort,
		},

		AudioCodecAms		: { LabelShort : 'AMS',			LabelMedium : 'Atmos',									LabelLong : 'Dolby Atmos' },
		AudioCodecThd		: { LabelShort : 'THD',			LabelMedium : 'TrueHD',									LabelLong : 'Dolby TrueHD' },
		AudioCodecThdams	: { LabelShort : 'THD-AMS',		LabelMedium : 'TrueHD Atmos',							LabelLong : 'Dolby TrueHD Atmos' },
		AudioCodecPls		: { LabelShort : 'PLS',			LabelMedium : 'Digital Plus',							LabelLong : 'Dolby Digital Plus' },
		AudioCodecPlsams	: { LabelShort : 'PLS-AMS',		LabelMedium : 'Digital Plus Atmos',						LabelLong : 'Dolby Digital Plus Atmos' },
		AudioCodecAc4		: { LabelShort : 'AC4',			LabelMedium : 'AC4',									LabelLong : 'Dolby AC4' },
		AudioCodecAc4ams	: { LabelShort : 'AC4-AMS',		LabelMedium : 'AC4 Atmos',								LabelLong : 'Dolby AC4 Atmos' },
		AudioCodecAc3		: { LabelShort : 'AC3',			LabelMedium : 'Digital AC3',							LabelLong : 'Dolby Digital AC3' },
		AudioCodecPul		: { LabelShort : 'PUL',			LabelMedium : 'Pulse',									LabelLong : 'Dolby Pulse' },
		AudioCodecLve		: { LabelShort : 'LVE',			LabelMedium : 'Digital Live',							LabelLong : 'Dolby Digital Live' },
		AudioCodecEx		: { LabelShort : 'EX',			LabelMedium : 'Digital EX',								LabelLong : 'Dolby Digital EX' },
		AudioCodecSex		: { LabelShort : 'SEX',			LabelMedium : 'Digital Surround EX',					LabelLong : 'Dolby Digital Surround EX' },
		AudioCodecPro		: { LabelShort : 'PRO',			LabelMedium : 'Pro Logic',								LabelLong : 'Dolby Pro Logic' },
		AudioCodecPro2		: { LabelShort : 'PRO2',		LabelMedium : 'Pro Logic II',							LabelLong : 'Dolby Pro Logic II' },
		AudioCodecPro2x		: { LabelShort : 'PRO2X',		LabelMedium : 'Pro Logic IIx',							LabelLong : 'Dolby Pro Logic IIx' },
		AudioCodecPro2z		: { LabelShort : 'PRO2Z',		LabelMedium : 'Pro Logic IIz',							LabelLong : 'Dolby Pro Logic IIz' },

		AudioCodecX			: { LabelShort : 'X',			LabelMedium : 'X',										LabelLong : 'DTS:X' },
		AudioCodecXp		: { LabelShort : 'XP',			LabelMedium : 'X Pro',									LabelLong : 'DTS:X Pro' },
		AudioCodecHdma		: { LabelShort : 'HDMA',		LabelMedium : 'HD Master Audio',						LabelLong : 'DTS HD Master Audio' },
		AudioCodecHdmax		: { LabelShort : 'HDMA-X',		LabelMedium : 'HD Master Audio X',						LabelLong : 'DTS HD Master Audio X' },
		AudioCodecHdmaxp	: { LabelShort : 'HDMA-XP',		LabelMedium : 'HD Master Audio X Pro',					LabelLong : 'DTS HD Master Audio X Pro' },
		AudioCodecHdhr		: { LabelShort : 'HDHR',		LabelMedium : 'HD High Resolution Audio',				LabelLong : 'DTS HD High Resolution Audio' },
		AudioCodecHdhrx		: { LabelShort : 'HDHR-X',		LabelMedium : 'HD High Resolution Audio X',				LabelLong : 'DTS HD High Resolution Audio X' },
		AudioCodecHdhrxp	: { LabelShort : 'HDHR-XP',		LabelMedium : 'HD High Resolution Audio X Pro',			LabelLong : 'DTS HD High Resolution Audio X Pro' },
		AudioCodecNeo		: { LabelShort : 'NEO',			LabelMedium : 'Neo',									LabelLong : 'DTS Neo' },
		AudioCodecNeo6		: { LabelShort : 'NEO6',		LabelMedium : 'Neo:6',									LabelLong : 'DTS Neo:6' },
		AudioCodecNeox		: { LabelShort : 'NEOX',		LabelMedium : 'Neo:X',									LabelLong : 'DTS Neo:X' },
		AudioCodecNeopc		: { LabelShort : 'NEOPC',		LabelMedium : 'Neo:PC',									LabelLong : 'DTS Neo:PC' },
		AudioCodecNx		: { LabelShort : 'NX',			LabelMedium : 'Neural:X',								LabelLong : 'DTS Neural:X' },
		AudioCodecVx		: { LabelShort : 'VX',			LabelMedium : 'Virtual:X',								LabelLong : 'DTS Virtual:X' },
		AudioCodecHx		: { LabelShort : 'HX',			LabelMedium : 'Headphone:X',							LabelLong : 'DTS Headphone:X' },
		AudioCodecCon		: { LabelShort : 'CON',			LabelMedium : 'Connect',								LabelLong : 'DTS Connect' },
		AudioCodecIna		: { LabelShort : 'INA',			LabelMedium : 'Interactive',							LabelLong : 'DTS Interactive' },
		AudioCodecPyf		: { LabelShort : 'PYF',			LabelMedium : 'Play-Fi',								LabelLong : 'DTS Play-Fi' },
		AudioCodecSur		: { LabelShort : 'SUR',			LabelMedium : 'Surround',								LabelLong : 'DTS Surround' },
		AudioCodecSurs		: { LabelShort : 'SURS',		LabelMedium : 'Surround Sensation',						LabelLong : 'DTS Surround Sensation' },
		AudioCodecEsur		: { LabelShort : 'ESUR',		LabelMedium : 'Extended Surround',						LabelLong : 'DTS Extended Surround' },
		AudioCodec70		: { LabelShort : '70',			LabelMedium : '70MM',									LabelLong : 'DTS 70MM' },
		AudioCodec9624		: { LabelShort : '9624',		LabelMedium : '96/24',									LabelLong : 'DTS 96/24' },

		AudioCodecAac		: { LabelShort : 'AAC',			LabelMedium : 'Advanced Audio Coding',					LabelLong : 'MPEG Advanced Audio Coding' },
		AudioCodecHeaac		: { LabelShort : 'HEAAC',		LabelMedium : 'High Efficiency Advanced Audio Coding',	LabelLong : 'MPEG High Efficiency Advanced Audio Coding' },
		AudioCodecLcaac		: { LabelShort : 'LCAAC',		LabelMedium : 'Low Complexity Advanced Audio Coding',	LabelLong : 'MPEG Low Complexity Advanced Audio Coding' },
		AudioCodecMp3		: { LabelShort : 'MP3',			LabelMedium : 'MPEG Audio Layer III',					LabelLong : 'MPEG Layer III' },
		AudioCodecMp2		: { LabelShort : 'MP2',			LabelMedium : 'MPEG Audio Layer II',					LabelLong : 'MPEG Layer II' },
		AudioCodecMp1		: { LabelShort : 'MP1',			LabelMedium : 'MPEG Audio Layer I',						LabelLong : 'MPEG Audio Layer I' },

		AudioCodecAtrac		: { LabelShort : 'ATRAC',		LabelMedium : 'ATRAC',									LabelLong : 'Sony Adaptive Transform Acoustic Coding' },
		AudioCodecAtrac3	: { LabelShort : 'ATRAC3',		LabelMedium : 'ATRAC 3',								LabelLong : 'Sony Adaptive Transform Acoustic Coding 3' },
		AudioCodecAtrac3p	: { LabelShort : 'ATRAC3P',		LabelMedium : 'ATRAC 3 Plus',							LabelLong : 'Sony Adaptive Transform Acoustic Coding 3 Plus' },
		AudioCodecAtrac9	: { LabelShort : 'ATRAC9',		LabelMedium : 'ATRAC 9',								LabelLong : 'Sony Adaptive Transform Acoustic Coding 9' },
		AudioCodecAtracal	: { LabelShort : 'ATRACAL',		LabelMedium : 'ATRAC Advanced Lossless',				LabelLong : 'Sony Adaptive Transform Acoustic Coding Advanced Lossless' },

		AudioCodecTv		: { LabelShort : 'TV',			LabelMedium : 'TruVolume',								LabelLong : 'SRS TruVolume' },
		AudioCodecSshd		: { LabelShort : 'SSHD',		LabelMedium : 'StudioSound HD',							LabelLong : 'SRS StudioSound HD' },
		AudioCodecTshd		: { LabelShort : 'TSHD',		LabelMedium : 'TruSurround HD',							LabelLong : 'SRS TruSurround HD' },
		AudioCodecTshd4		: { LabelShort : 'TSHD4',		LabelMedium : 'TruSurround HD4',						LabelLong : 'SRS TruSurround HD4' },
		AudioCodecTsxt		: { LabelShort : 'TSXT',		LabelMedium : 'TruSurround XT',							LabelLong : 'SRS TruSurround XT' },
		AudioCodecTs		: { LabelShort : 'TS',			LabelMedium : 'TheaterSound',							LabelLong : 'SRS TheaterSound' },
		AudioCodecTshd		: { LabelShort : 'TSHD',		LabelMedium : 'TheaterSound HD',						LabelLong : 'SRS TheaterSound HD' },
		AudioCodecH360		: { LabelShort : 'H360',		LabelMedium : 'Headphone 360',							LabelLong : 'SRS Headphone 360' },
		AudioCodecTb		: { LabelShort : 'TB',			LabelMedium : 'TruBass',								LabelLong : 'SRS TruBass' },
		AudioCodecWhd		: { LabelShort : 'WHD',			LabelMedium : 'WOW HD',									LabelLong : 'SRS WOW HD' },
		AudioCodecTm		: { LabelShort : 'TM',			LabelMedium : 'TruMedia',								LabelLong : 'SRS TruMedia' },
		AudioCodecDc		: { LabelShort : 'DC',			LabelMedium : 'Dialog Clarity',							LabelLong : 'SRS Dialog Clarity' },
		AudioCodecCs		: { LabelShort : 'CS',			LabelMedium : 'Circle Surround',						LabelLong : 'SRS Circle Surround' },
		AudioCodecCsh		: { LabelShort : 'CSH',			LabelMedium : 'Circle Surround Headphone',				LabelLong : 'SRS Circle Surround Headphone' },
		AudioCodecCsa		: { LabelShort : 'CSA',			LabelMedium : 'Circle Surround Auto',					LabelLong : 'SRS Circle Surround Auto' },

		AudioCodecWma		: { LabelShort : 'WMA',			LabelMedium : 'Windows Media Audio',					LabelLong : 'Windows Media Audio' },
		AudioCodecWma2		: { LabelShort : 'WMA2',		LabelMedium : 'Windows Media Audio Version 2',			LabelLong : 'Windows Media Audio Version 2' },
		AudioCodecWmap		: { LabelShort : 'WMAP',		LabelMedium : 'Windows Media Audio Professional',		LabelLong : 'Windows Media Audio Professional' },
		AudioCodecWmal		: { LabelShort : 'WMAL',		LabelMedium : 'Windows Media Audio Lossless',			LabelLong : 'Windows Media Audio Lossless' },
		AudioCodecWmav		: { LabelShort : 'WMAV',		LabelMedium : 'Windows Media Audio Voice',				LabelLong : 'Windows Media Audio Voice' },

		AudioCodecFlac		: { LabelShort : 'FLAC',		LabelMedium : 'Free Lossless Audio Codec',				LabelLong : 'Xiph Free Lossless Audio Codec' },
		AudioCodecVorbis	: { LabelShort : 'VORBIS',		LabelMedium : 'Vorbis',									LabelLong : 'Xiph Vorbis' },
		AudioCodecOpus		: { LabelShort : 'OPUS',		LabelMedium : 'Opus',									LabelLong : 'Xiph Opus' },

		AudioCodecAlac		: { LabelShort : 'ALAC',		LabelMedium : 'Apple Lossless Audio Codec',				LabelLong : 'Apple Lossless Audio Codec' },
		AudioCodecAiff		: { LabelShort : 'AIFF',		LabelMedium : 'Audio Interchange File Format',			LabelLong : 'Apple Audio Interchange File Format' },

		AudioCodecDra		: { LabelShort : 'DRA',			LabelMedium : 'Dynamic Resolution Adaptation',			LabelLong : 'DigiRise Dynamic Resolution Adaptation' },

		AudioCodecDbx1		: { LabelShort : 'DBX1',		LabelMedium : 'DBX Type 1',								LabelLong : 'DBX Type 1' },
		AudioCodecDbx2		: { LabelShort : 'DBX2',		LabelMedium : 'DBX Type 2',								LabelLong : 'DBX Type 2' },

		AudioCodecPcm		: { LabelShort : 'PCM',			LabelMedium : 'Pulse Code Modulation',					LabelLong : 'Pulse Code Modulation' },
	}

	OrderAudioCodec = {
		AudioCodecAms		: { OrderInterface : 1,		OrderSorting : 8 },
		AudioCodecThd		: { OrderInterface : 2,		OrderSorting : 11 },
		AudioCodecThdams	: { OrderInterface : 3,		OrderSorting : 1 },
		AudioCodecPls		: { OrderInterface : 4,		OrderSorting : 14 },
		AudioCodecPlsams	: { OrderInterface : 5,		OrderSorting : 5 },
		AudioCodecAc4		: { OrderInterface : 6,		OrderSorting : 13 },
		AudioCodecAc4ams	: { OrderInterface : 7,		OrderSorting : 4 },
		AudioCodecAc3		: { OrderInterface : 8,		OrderSorting : 16 },
		AudioCodecPul		: { OrderInterface : 9,		OrderSorting : 27 },
		AudioCodecLve		: { OrderInterface : 10,	OrderSorting : 28 },
		AudioCodecEx		: { OrderInterface : 11,	OrderSorting : 26 },
		AudioCodecSex		: { OrderInterface : 12,	OrderSorting : 25 },
		AudioCodecPro		: { OrderInterface : 13,	OrderSorting : 24 },
		AudioCodecPro2		: { OrderInterface : 14,	OrderSorting : 23 },
		AudioCodecPro2x		: { OrderInterface : 15,	OrderSorting : 22 },
		AudioCodecPro2z		: { OrderInterface : 16,	OrderSorting : 21 },

		AudioCodecX			: { OrderInterface : 17,	OrderSorting : 10 },
		AudioCodecXp		: { OrderInterface : 18,	OrderSorting : 9 },
		AudioCodecHdma		: { OrderInterface : 19,	OrderSorting : 12 },
		AudioCodecHdmax		: { OrderInterface : 20,	OrderSorting : 3 },
		AudioCodecHdmaxp	: { OrderInterface : 21,	OrderSorting : 2 },
		AudioCodecHdhr		: { OrderInterface : 22,	OrderSorting : 15 },
		AudioCodecHdhrx		: { OrderInterface : 23,	OrderSorting : 7 },
		AudioCodecHdhrxp	: { OrderInterface : 24,	OrderSorting : 6 },
		AudioCodecNeo		: { OrderInterface : 25,	OrderSorting : 20 },
		AudioCodecNeo6		: { OrderInterface : 26,	OrderSorting : 18 },
		AudioCodecNeox		: { OrderInterface : 27,	OrderSorting : 17 },
		AudioCodecNeopc		: { OrderInterface : 28,	OrderSorting : 19 },
		AudioCodecNx		: { OrderInterface : 29,	OrderSorting : 29 },
		AudioCodecVx		: { OrderInterface : 30,	OrderSorting : 30 },
		AudioCodecHx		: { OrderInterface : 31,	OrderSorting : 31 },
		AudioCodecCon		: { OrderInterface : 32,	OrderSorting : 32 },
		AudioCodecIna		: { OrderInterface : 33,	OrderSorting : 33 },
		AudioCodecPyf		: { OrderInterface : 34,	OrderSorting : 34 },
		AudioCodecSur		: { OrderInterface : 35,	OrderSorting : 36 },
		AudioCodecSurs		: { OrderInterface : 36,	OrderSorting : 35 },
		AudioCodecEsur		: { OrderInterface : 37,	OrderSorting : 38 },
		AudioCodec70		: { OrderInterface : 38,	OrderSorting : 37 },
		AudioCodec9624		: { OrderInterface : 39,	OrderSorting : 39 },

		AudioCodecAac		: { OrderInterface : 40,	OrderSorting : 42 },
		AudioCodecHeaac		: { OrderInterface : 41,	OrderSorting : 40 },
		AudioCodecLcaac		: { OrderInterface : 42,	OrderSorting : 41 },
		AudioCodecMp3		: { OrderInterface : 43,	OrderSorting : 46 },
		AudioCodecMp2		: { OrderInterface : 44,	OrderSorting : 77 },
		AudioCodecMp1		: { OrderInterface : 45,	OrderSorting : 78 },

		AudioCodecAtrac		: { OrderInterface : 56,	OrderSorting : 61 },
		AudioCodecAtrac3	: { OrderInterface : 57,	OrderSorting : 60 },
		AudioCodecAtrac3p	: { OrderInterface : 58,	OrderSorting : 59 },
		AudioCodecAtrac9	: { OrderInterface : 59,	OrderSorting : 58 },
		AudioCodecAtracal	: { OrderInterface : 60,	OrderSorting : 57 },

		AudioCodecTv		: { OrderInterface : 61,	OrderSorting : 62 },
		AudioCodecSshd		: { OrderInterface : 62,	OrderSorting : 65 },
		AudioCodecTshd		: { OrderInterface : 63,	OrderSorting : 64 },
		AudioCodecTshd4		: { OrderInterface : 64,	OrderSorting : 63 },
		AudioCodecTsxt		: { OrderInterface : 65,	OrderSorting : 66 },
		AudioCodecTs		: { OrderInterface : 66,	OrderSorting : 68 },
		AudioCodecTshd		: { OrderInterface : 67,	OrderSorting : 67 },
		AudioCodecH360		: { OrderInterface : 68,	OrderSorting : 69 },
		AudioCodecTb		: { OrderInterface : 69,	OrderSorting : 70 },
		AudioCodecWhd		: { OrderInterface : 70,	OrderSorting : 71 },
		AudioCodecTm		: { OrderInterface : 71,	OrderSorting : 72 },
		AudioCodecDc		: { OrderInterface : 72,	OrderSorting : 73 },
		AudioCodecCs		: { OrderInterface : 73,	OrderSorting : 76 },
		AudioCodecCsh		: { OrderInterface : 74,	OrderSorting : 75 },
		AudioCodecCsa		: { OrderInterface : 75,	OrderSorting : 74 },

		AudioCodecWma		: { OrderInterface : 51,	OrderSorting : 56 },
		AudioCodecWma2		: { OrderInterface : 52,	OrderSorting : 55 },
		AudioCodecWmap		: { OrderInterface : 53,	OrderSorting : 54 },
		AudioCodecWmal		: { OrderInterface : 54,	OrderSorting : 53 },
		AudioCodecWmav		: { OrderInterface : 55,	OrderSorting : 52 },

		AudioCodecFlac		: { OrderInterface : 46,	OrderSorting : 43 },
		AudioCodecVorbis	: { OrderInterface : 47,	OrderSorting : 44 },
		AudioCodecOpus		: { OrderInterface : 48,	OrderSorting : 45 },

		AudioCodecAlac		: { OrderInterface : 49,	OrderSorting : 50 },
		AudioCodecAiff		: { OrderInterface : 50,	OrderSorting : 51 },

		AudioCodecDra		: { OrderInterface : 78,	OrderSorting : 47 },

		AudioCodecDbx1		: { OrderInterface : 76,	OrderSorting : 49 },
		AudioCodecDbx2		: { OrderInterface : 77,	OrderSorting : 48 },

		AudioCodecPcm		: { OrderInterface : 79,	OrderSorting : 79 },
	}

	##############################################################################
	# SUBTITLE TYPE
	##############################################################################

	SubtitleTypeSoft 	= 'soft'
	SubtitleTypeHard 	= 'hard'
	SubtitleTypeNone 	= None
	SubtitleTypeDefault = SubtitleTypeSoft

	# 3 forms: subtitle, subtitles, subtitled.
	ExpressionSubtitle				 = u'(?:(?:retail{separator}*)?sub(?:{separator}*|s|be[dr]|{separator}*title[ds]?)?|srt|sous{separator}*titr(?:e|é)?[es]?|legenda(?:s|do)|subt(?:i|í)tul(?:os?|ar|ad[ao])|sottotitol(?:i|o|ato)|untertitel|ondertitel[ds]?|napisy|tekst|texti?|cубтитр(?:ы|ами))'

	ExpressionSubtitleTrailing		= u'{symbol}[a-z]{{2,3}}\.{{2,}}$'
	ExpressionSubtitleExtended		= u'(?:' + ExpressionSubtitle + '|(?:hc|(?:hard|soft)(?:{separator}*cod(?:ed?)?)?|optional|itegrated?|fixa){separator}*(?:' + ExpressionSubtitle + u')?|' + ExpressionSubtitle + u'' + ExpressionSeparator + u'*forced?|forced?' + ExpressionSeparator + u'*' + ExpressionSubtitle + u')'
	ExpressionSubtitleFixed			= u'.+' + ExpressionSubtitle
	ExpressionSubtitleSingle		= u'{symbol_start}([a-z]{separator}' + ExpressionSubtitle + u'|' + ExpressionSubtitle + u'{separator}[a-z]){symbol_end}'
	ExpressionSubtitleSingleFixed	= u'{symbol_start}([a-z]{separator}?' + ExpressionSubtitle + u'|' + ExpressionSubtitle + u'{separator}?[a-z]){symbol_end}'
	ExpressionSubtitleMulti			= u'(?:m(?:ulti(?:ple)?)?)'
	ExpressionSubtitleDual			= {u'french' : [u'vfst', u'vfstf', u'vfstfr']}
	ExpressionSubtitleFrench		= [u'vfst', u'vost']
	ExpressionSubtitleSpanish		= [u'vose']
	ExpressionSubtitleSeparator		= u'([\]\)\}]\s*[\[\(\{]|with|w\/)'
	ExpressionSubtitleExclude		= u'{symbol_start}(no{separator}+rars?){symbol_end}'
	ExpressionSubtitleCutoff		= u'{symbol}(sub(?:t(?:i(?:t(?:l(?:e)?)?)?)?)?){symbol_end}'
	ExpressionSubtitleCutoffMulti	= u'(m(?:ulti(?:ple)?){separator}*su{symbol_end})'

	ExpressionSubtitleType = {
		'keyword' : {
			'subtitle'	: u'(?:{separator}*' + ExpressionSubtitle + ')',
			'coded'		: u'(?:{separator}*cod(?:ed?)?)?',
			'single'	: u'[a-z]{{1,3}}',
			'forced'	: u'forced?',
			'multi'		: ExpressionSubtitleMulti,

			# Use specific language codes.
			# Otherwise the word "Richard" will be detected as hardcoded subs.
			#'language'	: '(?:[a-z]{{2,3}})?',
			'language'	: '(?:ar|ara|zh|chi|zho|nl|dut|nld|en|eng|fr|fre|fra|de|ger|deu|el|gre|ell|hi|hin|it|ita|ja|jpn|ko|kor|fa|per|fas|pl|pol|pt|por|ru|rus|es|spa|ta|tam|te|tel|th|tha|uk|ukr|vi|vie|af|afr|sq|alb|sqi|hy|arm|hye|az|aze|bm|bam|be|bel|bn|ben|bs|bos|bg|bul|my|bur|mya|cs|cze|ces|da|dan|fi|fin|ka|geo|kat|gu|guj|ht|hat|ha|hau|he|heb|hu|hun|id|ind|ig|ibo|is|ice|isl|jv|jav|kn|kan|kk|kaz|km|khm|ky|kir|ku|kur|ln|lin|lo|lao|mk|mac|mkd|ms|may|msa|ml|mal|mn|mon|ne|nep|no|nor|pa|pan|ro|rum|ron|sr|srp|si|sin|sk|slo|slk|sl|slv|st|sot|su|sun|sv|swe|tk|tuk|tl|tgl|tr|tur|uz|uzb|xh|xho|yo|yor|zu|zul)?',
		},

		'expression' : (
			(SubtitleTypeHard,	u'{language}((?:hc|hard{coded}|burned{separator}in|ingeb(?:akken|rande?)|fixa){subtitle}?|{subtitle}{separator}*{forced}|{forced}{separator}*{subtitle})'),
			(SubtitleTypeSoft,	u'((?:soft{coded}|optional|itegra(?:ted?|dos)|extern(?:al|e)){subtitle}?|(?:{multi}|{single})?{separator}*{subtitle})'),
		),
	}

	LabelSubtitleType = {
		LabelDefault : {
			LabelList1		: LabelMedium,
			LabelList2		: LabelShort,
			LabelList3		: LabelShort,
			LabelList4		: LabelShort,
			LabelInfo1		: LabelLong,
			LabelInfo2		: LabelHidden,
			LabelSettings1	: LabelLong,
			LabelSettings2	: LabelShort,
		},

		SubtitleTypeSoft	: { LabelShort : 'SOFT',	LabelMedium : 'Softcoded',	LabelLong : 'Softcoded Subtitles' },
		SubtitleTypeHard	: { LabelShort : 'HARD',	LabelMedium : 'Hardcoded',	LabelLong : 'Hardcoded Subtitles' },
	}

	OrderSubtitleType = {
		SubtitleTypeSoft	: { OrderInterface : 1,	OrderSorting : 1 },
		SubtitleTypeHard	: { OrderInterface : 2,	OrderSorting : 2 },
	}

	##############################################################################
	# FILE NAME
	##############################################################################

	# The separator to combine fileName and fileExtra.
	# Do not use symbols, since symbols are stripped as separators/symbols.
	FileSeparator					= ' X0X0X0X '
	ExpressionFileSeparator			= '\s*X0X0X0X\s*'

	ExpressionFileNameIncomplete	= '\.{2,}\s*$'	# The suffix for file names that are incomplete or were cut off. Only use 2 dots, since some sites like LimeTorrent or MagnetDl do not add 3.

	##############################################################################
	# FILE SIZE
	##############################################################################

	ExpressionFileSize = ExpressionSymbolStart + u'(\d+(?:[\.\,]\d+)?\s*[kmgtКМГТ]i?[bБ]s?)' + ExpressionSymbolEnd

	LabelFileSize = {
		LabelDefault : {
			LabelList1		: LabelLong,
			LabelList2		: LabelHidden,
			LabelList3		: LabelHidden,
			LabelList4		: LabelHidden,
			LabelInfo1		: LabelShort,
			LabelInfo2		: LabelShort,
			LabelSettings1	: LabelShort,
			LabelSettings2	: LabelShort,
		},
	}

	##############################################################################
	# FILE BANDWIDTH
	##############################################################################

	# Keep the maximum high enough, since colors below it are already red-ish.
	# https://en.wikipedia.org/wiki/List_of_countries_by_Internet_connection_speeds
	# Take 1.5x US speed (the US speed should not be too red).
	FileBandwidthMinimum	= 2097152	# 2 mbps
	FileBandwidthMaximum	= 41943040	# 40 mbps

	FileBandwidthCount		= 200		# Reduce the number of colors generated.

	LabelFileBandwidth = {
		LabelDefault : {
			LabelList1		: LabelLong,
			LabelList2		: LabelMedium,
			LabelList3		: LabelMedium,
			LabelList4		: LabelMedium,
			LabelInfo1		: LabelShort,
			LabelInfo2		: LabelShort,
			LabelSettings1	: LabelShort,
			LabelSettings2	: LabelShort,
		},
	}

	##############################################################################
	# FILE CONTAINER
	##############################################################################

	# https://en.wikipedia.org/wiki/Comparison_of_video_container_formats

	FileContainerMkv	= 'mkv'		# Matroska Multimedia Container
	FileContainerWebm	= 'webm'	# Web Multimedia
	FileContainerMp4	= 'mp4'		# MPEG-4 Part 14
	FileContainerMpg	= 'mpg'		# MPEG-1 Video File
	FileContainerPs		= 'ps'		# MPEG Program Stream
	FileContainerTs		= 'ts'		# MPEG Transport Stream
	FileContainerM2ts	= 'm2ts'	# BDAV MPEG-2 Transport Stream
	FileContainerAvi	= 'avi'		# Audio Video Interleave
	FileContainerFlv	= 'flv'		# Flash Video
	FileContainerDmf	= 'dmf'		# DivX Media Format
	FileContainerWmv	= 'wmv'		# Windows Media Video
	FileContainerAsf	= 'asf'		# Advanced Systems Format
	FileContainer3gp	= '3gp'		# 3GPP
	FileContainer3g2	= '3g2'		# 3GPP2
	FileContainerOgg	= 'ogg'		# Xiph OGG
	FileContainerVob	= 'vob'		# Video Object
	FileContainerEvo	= 'evo'		# Enhanced VOB
	FileContainerQtff	= 'qtff'	# QuickTime File Format
	FileContainerRmvb	= 'rmvb'	# RealMedia Variable Bitrate
	FileContainerMxf	= 'mxf'		# Material Exchange Format

	FileContainerIso	= 'iso'		# ISO Disk Image
	FileContainerNrg	= 'nrg'		# Nero Disk Image
	FileContainer7z		= '7z'		# 7ZIP Archive
	FileContainerZip	= 'zip'		# ZIP Archive
	FileContainerRar	= 'rar'		# RAR Archive

	# Not really file containers.
	FileContainerStrm	= 'strm'	# Stream
	FileContainerM3u	= 'm3u'		# MP3 URL
	FileContainerM3u8	= 'm3u8'	# MP3 URL UTF8
	FileContainerVtt	= 'vtt'		# Web Video Text Tracks
	FileContainerPls	= 'pls'		# Playlist
	FileContainerAsx	= 'asx'		# Advanced Stream Redirector
	FileContainerWpl	= 'wpl'		# Windows Media Player Playlist
	FileContainerXspf	= 'xspf'	# XML Shareable Playlist Format

	FileContainerNone = None

	ExpressionFileContainer = {
		'keyword' : {
		},

		'expression' : (
			(FileContainerMkv,	u'(mk(?:v|3d)|matroska)'),
			(FileContainerWebm,	u'(webm)'),

			(FileContainerPs,	u'(mp?2p|mp1s|mpe?g{separator}*[12]?{separator}*ps)'),
			(FileContainerTs,	u'(mts|tsv|mp2t|mpe?g{separator}*ts)'),
			(FileContainerMp4,	u'((?:ms{separator}*)?mpe?g?{separator}*4|m4v)'),
			(FileContainerMpg,	u'((?:ms{separator}*)?mpe?g?[12]?|mp[12v]|m2v)'),
			(FileContainerM2ts,	u'(m2?ts)'),

			(FileContainerAvi,	u'(avi)'),
			(FileContainerFlv,	u'(f[l4]v|swf)'),

			# Do not match "divx", since it is almost always the codec instead of the container.
			#(FileContainerDmf,	u'(dmf|(?:div(?:x|\d)\d?))'),
			(FileContainerDmf,	u'(dmf|(?:div(?:x|\d)\d?){separator}*(?:media(?:{separator}*format)?|plus(?:{separator}*hd)?))'),

			(FileContainerWmv,	u'(wmv)'),
			(FileContainerAsf,	u'(asf)'),

			(FileContainer3gp,	u'(3gpp?)'),
			(FileContainer3g2,	u'(3g2|3gpp?2)'),

			(FileContainerOgg,	u'(og[gv])'),

			(FileContainerVob,	u'(vob)'),
			(FileContainerEvo,	u'((?<=\.)evo|evob|enhanced{separator}*vob)'), # Uploader called EVO, be very strict.

			(FileContainerQtff,	u'(mov|qt)'),
			(FileContainerRmvb,	u'(rmvb)'),
			(FileContainerMxf,	u'(mxf)'),

			(FileContainerIso,	u'((?<!{symbol}no{symbol})iso|udf|img)'),
			(FileContainerNrg,	u'((?<!{symbol}no{symbol})nrg)'),
			(FileContainer7z,	u'((?<!{symbol}no{symbol})7z(?:ip)?|s7z)'),
			(FileContainerZip,	u'((?<!{symbol}no{symbol})zipx?)'),
			(FileContainerRar,	u'((?<!{symbol}no{symbol})rar)'), # Exclude "no-rar".

			(FileContainerStrm,	u'(strm)'),
			(FileContainerM3u,	u'(m3u)'),
			(FileContainerM3u8,	u'(m3u8)'),
			(FileContainerVtt,	u'(vtt)'),
			(FileContainerPls,	u'(pls)'),
			(FileContainerAsx,	u'(asx)'),
			(FileContainerWpl,	u'(wpl)'),
			(FileContainerXspf,	u'(xspf)'),
		),
	}

	LabelFileContainer = {
		LabelDefault : {
			LabelList1		: LabelShort,
			LabelList2		: LabelHidden,
			LabelList3		: LabelHidden,
			LabelList4		: LabelHidden,
			LabelInfo1		: LabelShort,
			LabelInfo2		: LabelMedium,
			LabelSettings1	: LabelMedium,
			LabelSettings2	: LabelShort,
		},

		FileContainerMkv	: { LabelShort : 'MKV',		LabelMedium : 'Matroska Multimedia Container',	LabelLong : 'Matroska Multimedia Container' },
		FileContainerWebm	: { LabelShort : 'WEBM',	LabelMedium : 'Web Multimedia',					LabelLong : 'Web Multimedia' },
		FileContainerMp4	: { LabelShort : 'MP4',		LabelMedium : 'MPEG 4 Part 14',					LabelLong : 'Moving Picture Experts Group 4 Part 14' },
		FileContainerMpg	: { LabelShort : 'MPG',		LabelMedium : 'MPEG 1 Video File',				LabelLong : 'Moving Picture Experts Group 1 Video File' },
		FileContainerPs		: { LabelShort : 'PS',		LabelMedium : 'MPEG Program Stream',			LabelLong : 'Moving Picture Experts Group Program Stream' },
		FileContainerTs		: { LabelShort : 'TS',		LabelMedium : 'MPEG Transport Stream',			LabelLong : 'Moving Picture Experts Group Transport Stream' },
		FileContainerM2ts	: { LabelShort : 'M2TS',	LabelMedium : 'BDAV MPEG 2 Transport Stream',	LabelLong : 'Bluray Disc Audio Video Moving Picture Experts Group 2 Transport Stream' },
		FileContainerAvi	: { LabelShort : 'AVI',		LabelMedium : 'Audio Video Interleave',			LabelLong : 'Audio Video Interleave' },
		FileContainerFlv	: { LabelShort : 'FLV',		LabelMedium : 'Flash Video',					LabelLong : 'Flash Video' },
		FileContainerDmf	: { LabelShort : 'DMF',		LabelMedium : 'DivX Media Format',				LabelLong : 'DivX Media Format' },
		FileContainerWmv	: { LabelShort : 'WMV',		LabelMedium : 'Windows Media Video',			LabelLong : 'Windows Media Video' },
		FileContainerAsf	: { LabelShort : 'ASF',		LabelMedium : 'Advanced Systems Format',		LabelLong : 'Advanced Systems Format' },
		FileContainer3gp	: { LabelShort : '3GP',		LabelMedium : '3rd GPP',						LabelLong : '3rd Generation Partnership Project' },
		FileContainer3g2	: { LabelShort : '3G2',		LabelMedium : '3rd GPP 2',						LabelLong : '3rd Generation Partnership Project 2' },
		FileContainerOgg	: { LabelShort : 'OGG',		LabelMedium : 'Xiph Ogg',						LabelLong : 'Xiph Ogg' },
		FileContainerVob	: { LabelShort : 'VOB',		LabelMedium : 'Video Object',					LabelLong : 'Video Object' },
		FileContainerEvo	: { LabelShort : 'EVO',		LabelMedium : 'Enhanced Video Object',			LabelLong : 'Enhanced Video Object' },
		FileContainerQtff	: { LabelShort : 'QTFF',	LabelMedium : 'QuickTime File Format',			LabelLong : 'QuickTime File Format' },
		FileContainerRmvb	: { LabelShort : 'RMVB',	LabelMedium : 'RealMedia Variable Bitrate',		LabelLong : 'RealMedia Variable Bitrate' },
		FileContainerMxf	: { LabelShort : 'MXF',		LabelMedium : 'Material Exchange Format',		LabelLong : 'Material Exchange Format' },

		FileContainerIso	: { LabelShort : 'ISO',		LabelMedium : 'ISO Disk Image',					LabelLong : 'International Organization for Standardization Disk Image' },
		FileContainerNrg	: { LabelShort : 'NRG',		LabelMedium : 'Nero Disk Image',				LabelLong : 'Nero Disk Image' },
		FileContainer7z		: { LabelShort : '7Z',		LabelMedium : '7ZIP Archive',					LabelLong : '7ZIP Archive' },
		FileContainerZip	: { LabelShort : 'ZIP',		LabelMedium : 'ZIP Archive',					LabelLong : 'ZIP Archive' },
		FileContainerRar	: { LabelShort : 'RAR',		LabelMedium : 'RAR Archive',					LabelLong : 'Resource Adapter Archive' },

		FileContainerStrm	: { LabelShort : 'STRM',	LabelMedium : 'Stream',							LabelLong : 'Stream' },
		FileContainerM3u	: { LabelShort : 'M3U',		LabelMedium : 'MP3 URL',						LabelLong : 'Moving Picture Experts Group Audio Layer 3 URL' },
		FileContainerM3u8	: { LabelShort : 'M3U8',	LabelMedium : 'MP3 URL UTF8',					LabelLong : 'Moving Picture Experts Group Audio Layer 3 URL UTF8' },
		FileContainerVtt	: { LabelShort : 'VTT',		LabelMedium : 'Web Video Text Tracks',			LabelLong : 'Web Video Text Tracks' },
		FileContainerPls	: { LabelShort : 'PLS',		LabelMedium : 'Playlist',						LabelLong : 'Playlist' },
		FileContainerAsx	: { LabelShort : 'ASX',		LabelMedium : 'Advanced Stream Redirector',		LabelLong : 'Advanced Stream Redirector' },
		FileContainerWpl	: { LabelShort : 'WPL',		LabelMedium : 'Windows Media Player Playlist',	LabelLong : 'Windows Media Player Playlist' },
		FileContainerXspf	: { LabelShort : 'XSPF',	LabelMedium : 'XML Shareable Playlist Format',	LabelLong : 'XML Shareable Playlist Format' },
	}

	OrderFileContainer = {
		FileContainerMkv	: { OrderInterface : 1,		OrderSorting : 1 },
		FileContainerWebm	: { OrderInterface : 2,		OrderSorting : 2 },
		FileContainerMp4	: { OrderInterface : 3,		OrderSorting : 3 },
		FileContainerMpg	: { OrderInterface : 4,		OrderSorting : 4 },
		FileContainerPs		: { OrderInterface : 5,		OrderSorting : 6 },
		FileContainerTs		: { OrderInterface : 6,		OrderSorting : 7 },
		FileContainerM2ts	: { OrderInterface : 7,		OrderSorting : 5 },
		FileContainerAvi	: { OrderInterface : 8,		OrderSorting : 8 },
		FileContainerFlv	: { OrderInterface : 9,		OrderSorting : 14 },
		FileContainerDmf	: { OrderInterface : 10,	OrderSorting : 15 },
		FileContainerWmv	: { OrderInterface : 11,	OrderSorting : 16 },
		FileContainerAsf	: { OrderInterface : 12,	OrderSorting : 17 },
		FileContainer3gp	: { OrderInterface : 13,	OrderSorting : 11 },
		FileContainer3g2	: { OrderInterface : 14,	OrderSorting : 10 },
		FileContainerOgg	: { OrderInterface : 15,	OrderSorting : 9 },
		FileContainerVob	: { OrderInterface : 16,	OrderSorting : 12 },
		FileContainerEvo	: { OrderInterface : 17,	OrderSorting : 13 },
		FileContainerQtff	: { OrderInterface : 18,	OrderSorting : 18 },
		FileContainerRmvb	: { OrderInterface : 19,	OrderSorting : 19 },
		FileContainerMxf	: { OrderInterface : 20,	OrderSorting : 20 },

		FileContainerIso	: { OrderInterface : 28,	OrderSorting : 28 },
		FileContainerNrg	: { OrderInterface : 29,	OrderSorting : 29 },
		FileContainer7z		: { OrderInterface : 30,	OrderSorting : 31 },
		FileContainerZip	: { OrderInterface : 31,	OrderSorting : 30 },
		FileContainerRar	: { OrderInterface : 32,	OrderSorting : 32 },

		FileContainerStrm	: { OrderInterface : 21,	OrderSorting : 21 },
		FileContainerM3u	: { OrderInterface : 22,	OrderSorting : 22 },
		FileContainerM3u8	: { OrderInterface : 23,	OrderSorting : 23 },
		FileContainerVtt	: { OrderInterface : 24,	OrderSorting : 24 },
		FileContainerPls	: { OrderInterface : 25,	OrderSorting : 25 },
		FileContainerAsx	: { OrderInterface : 26,	OrderSorting : 26 },
		FileContainerWpl	: { OrderInterface : 27,	OrderSorting : 27 },
		FileContainerXspf	: { OrderInterface : 28,	OrderSorting : 28 },
	}

	##############################################################################
	# FILE PACK
	##############################################################################

	# https://en.wiktionary.org/wiki/trilogy

	FilePackShow		= 'show'		# Packs with multiple seasons (show pack).
	FilePackSeason		= 'season'		# Packs with a single season (season pack).
	FilePackEpisode		= 'episode'		# Packs with multiple episodes, but not a full season (episode pack).
	FilePackCollection	= 'collection'	# Packs with multiple movies (trilogies, boxsets, etc).
	FilePackInternal	= 'internal'	# Internal pack types that are hardcoded instead of extracted (used by OffCloud provider to estimate the size of an individual episode).
	FilePackYear		= 'year'		# Internal use where movie collections are detected by a year range.
	FilePackDisabled	= False			# Internal pack type to force no pack, even if detected in file name.
	FilePackNone		= None

	# Only accept the "complete" keyword if the title does not contain a year (multipe year and year ranges are allow).
	# This is because some file names contain the work "complete", but are not packs.
	# Eg: Harry.Potter.and.the.Sorcerers.Stone.2001.COMPLETE.UHD.BLURAY-TERMiNAL
	ExpressionFilePack = {
		'keyword' : {
			'2number'	: 'd(?:i|uo|ou)',
			'3number'	: 'tr[iy]',
			'4number'	: '(?:quadr[iao]|tetr[ao])',
			'5number'	: 'penta',
			'6number'	: 'hex[ao]',
			'7number'	: 'hept[ao]',
			'8number'	: 'oct[ao]',
			'9number'	: 'enn?e[ao]',
			'10number'	: 'dec[ao]',

			'double'	: 'd(?:ou|uo)(?:ble)?',
			'tripple'	: 'tri(?:pp?le)?',
			'quadruple'	: 'quad(?:ruple)?',

			'logy'		: 'log(?:(?:i|í)[ae]?|y)s?',
			'pack'		: 'pack(?:age)?',
			'complete'	: 'complee?t(?:e|a|o|are)?',
		},

		'expression' : (
			(FilePackCollection, u'((?:{2number}|{3number}|{4number}|{5number}|{6number}|{7number}|{8number}|{9number}|{10number}|antho){logy}|{complete}|(?<!criterion{separator})coll?ecti(?:on|e)s?|sagas?|(?:(?:sub|{double}|{tripple}|{quadruple}){separator}*)?{pack}|batch(?:es)?|saga|(?<!pandoras.)(?<!pandora.s.)box|set(?![\s\-\_\.\+]in)|(?:box|discs?|dvds?|blurays?|collect[eo]r(?:.s{separator}|\\\?(?:\.|\'|\`|.?\xB4)?s?)?){separator}*set|colecci(?:o|ó)n|cole(?:c|ç)(?:a|ã)o|collezione|kollektion(?:en)?|sammlung|(?:film)?reihe|komplett|verzameling|samling|kolekcja|kolekce|koleksiyonu|трилогия|коллекция|полный|int(?:e|é)grale?)'),
		),

		'collection' : (
			(2, u'(?:{2number}{logy}|{double}{separator}*{pack})'),
			(3, u'(?:{3number}{logy}|{tripple}{separator}*{pack})'),
			(4, u'(?:{4number}{logy}|{quadruple}{separator}*{pack})'),
			(5, u'(?:{5number}{logy})'),
			(6, u'(?:{6number}{logy})'),
			(7, u'(?:{7number}{logy})'),
			(8, u'(?:{8number}{logy})'),
			(9, u'(?:{9number}{logy})'),
			(10, u'(?:{10number}{logy})'),
		),

		# If this expression matches and the file name contains a single year, the file is not considered to be a pack.
		'exception' : '(complee?t(?:e|a|o|are)?)',
		'completeless' : u'((?:d(?:i|uo)|tr[iy]|quadri|tetra|penta|hexa|hepta|oct[ao]|enn?ea|deca|antho)log(?:(?:i|í)[ae]?|y)s?|collecti(?:on|e)s?|sagas?|(?:(?:sub|d(?:ou|uo)(?:ble)?|tri(?:pp?le)?|quad(?:ruple)?){separator}*)?pack(?:age)?|batch(?:es)?|saga|(?<!pandoras.)(?<!pandora.s.)box|set|(?:box|discs?|dvds?|blurays?|collect[eo]r(?:.s{separator}|\\\?(?:\.|\'|\`|.?\xB4)?s?)?){separator}*set|colecci(?:o|ó)n|cole(?:c|ç)(?:a|ã)o|collezione|kollektion(?:en)?|sammlung|(?:film)?reihe|verzameling|samling|kolekcja|kolekce|koleksiyonu|трилогия|коллекция|полный|int(?:e|é)grale?)',
	}

	LabelFilePack = {
		LabelDefault : {
			LabelList1		: LabelMedium,
			LabelList2		: LabelMedium,
			LabelList3		: LabelMedium,
			LabelList4		: LabelMedium,
			LabelInfo1		: LabelLong,
			LabelInfo2		: LabelHidden,
			LabelSettings1	: LabelLong,
			LabelSettings2	: LabelMedium,
		},

		FilePackShow		: { LabelShort : 'PCK',	LabelMedium : 'PACK',	LabelLong : 'Show Pack' },
		FilePackSeason		: { LabelShort : 'PCK',	LabelMedium : 'PACK',	LabelLong : 'Season Pack' },
		FilePackEpisode		: { LabelShort : 'PCK',	LabelMedium : 'PACK',	LabelLong : 'Episode Pack' },
		FilePackCollection	: { LabelShort : 'PCK',	LabelMedium : 'PACK',	LabelLong : 'Collection Pack' },
		FilePackInternal	: { LabelShort : None,	LabelMedium : None,		LabelLong : None },
	}

	OrderFilePack = {
		FilePackShow		: { OrderInterface : 1,		OrderSorting : 1 },
		FilePackSeason		: { OrderInterface : 2,		OrderSorting : 2 },
		FilePackEpisode		: { OrderInterface : 3,		OrderSorting : 3 },
		FilePackCollection	: { OrderInterface : 4,		OrderSorting : 4 },
		FilePackInternal	: { OrderInterface : None,	OrderSorting : None },
	}

	##############################################################################
	# RELEASE TYPE
	##############################################################################

	# https://en.wikipedia.org/wiki/Pirated_movie_release_types
	# https://www.ph4.org/video_rip.php
	# https://www.facebook.com/notes/ryzalansav-terrano/bluray-brrip-bdrip-dvdrip-r5-web-dl-etc-man-this-is-so-confusing/560698634066561/
	# https://whereyouwatch.com/articles/ultimate-guide-to-movie-piracy-termonology/

	ReleaseTypeCam			= 'cam'			# Cam
	ReleaseTypeCamRip		= 'camrip'		# Cam Rip
	ReleaseTypeHdCam		= 'hdcam'		# HD CAM
	ReleaseTypeHdCamRip		= 'hdcamrip'	# HD CAM Rip
	ReleaseTypeDvdCam		= 'dvdcam'		# DVD Cam
	ReleaseTypeDvdCamRip	= 'dvdcamrip'	# DVD Cam Rip

	ReleaseTypeTs			= 'ts'			# Telesync (NB: "TS" can also mean for MPEG "Transport Stream", used a lot by anime)
	ReleaseTypeTsRip		= 'tsrip'		# Telesync Rip
	ReleaseTypeHdTs			= 'hdts'		# HD Telesync
	ReleaseTypeHdTsRip		= 'hdtsrip'		# HD Telesync
	ReleaseTypeSuperTs		= 'superts'		# Super Telesync

	ReleaseTypeTc			= 'tc'			# Telecine
	ReleaseTypeTcRip		= 'tcrip'		# Telecine Rip
	ReleaseTypeHdTc			= 'hdtc'		# HD Telecine
	ReleaseTypeHdTcRip		= 'hdtcrip'		# HD Telecine Rip
	ReleaseTypeSuperTc		= 'supertc'		# Super Telecine

	ReleaseTypeScr			= 'scr'			# Screener
	ReleaseTypeScrRip		= 'scrrip'		# Screener Rip
	ReleaseTypeTsScr		= 'tsscr'		# Telesync Screener
	ReleaseTypeTcScr		= 'tcscr'		# Telecine Screener
	ReleaseTypeVhsScr		= 'vhsscr'		# VHS Screener
	ReleaseTypeVhsScrRip	= 'vhsscrrip'	# VHS Screener Rip
	ReleaseTypeDvdScr		= 'dvdscr'		# DVD Screener
	ReleaseTypeDvdScrRip	= 'dvdscrrip'	# DVD Screener Rip
	ReleaseTypeBdScr		= 'bdscr'		# Bluray Disc Screener
	ReleaseTypeBdScrRip		= 'bdscrrip'	# Bluray Disc Screener Rip

	ReleaseTypeDdc			= 'ddc'			# Direct Digital Content
	ReleaseTypeDdcRip		= 'ddcrip'		# Direct Digital Content Rip

	ReleaseTypeWp			= 'wp'			# Workprint
	ReleaseTypeWpRip		= 'wprip'		# Workprint Rip

	ReleaseTypePdvd			= 'pdvd'		# Pre DVD
	ReleaseTypePdvdRip		= 'pdvdrip'		# Pre DVD Rip

	ReleaseTypeVod			= 'vod'			# Video On Demand
	ReleaseTypeVodRip		= 'vodrip'		# Video On Demand Rip

	ReleaseTypePpv			= 'ppv'			# Pay Per View
	ReleaseTypePpvRip		= 'ppvrip'		# Pay Per View Rip

	ReleaseTypeDcp			= 'dcp'			# Digital Cinema Package
	ReleaseTypeDcpRip		= 'dcprip'		# Digital Cinema Package Rip

	ReleaseTypePdtv			= 'pdtv'		# Pure Digital Television
	ReleaseTypePdtvRip		= 'pdtvrip'		# Pure Digital Television Rip

	ReleaseTypeSat			= 'sat'			# Satellite
	ReleaseTypeSatRip		= 'satrip'		# Satellite Rip

	ReleaseTypeDs			= 'ds'			# Digital Satellite
	ReleaseTypeDsRip		= 'dsrip'		# Digital Satellite Rip

	ReleaseTypeDth			= 'dth'			# Direct To Home
	ReleaseTypeDthRip		= 'dthrip'		# Direct To Home Rip

	ReleaseTypeDvb			= 'dvb'			# Digital TV Broadcasting
	ReleaseTypeDvbRip		= 'dvbrip'		# Digital TV Broadcasting Rip

	ReleaseTypeDtv			= 'dtv'			# Digital TV
	ReleaseTypeDtvRip		= 'dtvrip'		# Digital TV Rip

	ReleaseTypeIptv			= 'iptv'		# Internet Protocol TV
	ReleaseTypeIptvRip		= 'iptvrip'		# Internet Protocol TV Rip

	ReleaseTypeAhdtv		= 'ahdtv'		# Analog High Definition Television
	ReleaseTypeAhdtvRip		= 'ahdtvrip'	# Analog High Definition Television Rip

	ReleaseTypeHdRip		= 'hdrip'		# HD Rip
	ReleaseTypeTv			= 'tv'			# TV
	ReleaseTypeTvRip		= 'tvrip'		# TV Rip
	ReleaseTypeHdTv			= 'hdtv'		# HD TV
	ReleaseTypeHdTvRip		= 'hdtvrip'		# HD TV Rip

	ReleaseTypeWeb			= 'web'			# Web
	ReleaseTypeWebRip		= 'webrip'		# Web Rip
	ReleaseTypeWebCap		= 'webcap'		# Web Capture
	ReleaseTypeWebCapRip	= 'webcaprip'	# Web Capture Rip
	ReleaseTypeWebDl		= 'webdl'		# Web Download
	ReleaseTypeWebDlRip		= 'webdlrip'	# Web Download Rip
	ReleaseTypeWebHd		= 'webhd'		# Web HD
	ReleaseTypeWebHdRip		= 'webhdrip'	# Web HD Rip

	ReleaseTypeVhs			= 'vhs'			# VHS
	ReleaseTypeVhsRip		= 'vhsrip'		# VHS Rip

	ReleaseTypeDvhs			= 'dvhs'		# Digital VHS
	ReleaseTypeDvhsRip		= 'dvhsrip'		# Digital VHS Rip

	ReleaseTypeVcd			= 'vcd'			# Video CD
	ReleaseTypeVcdRip		= 'vcdrip'		# Video CD Rip

	ReleaseTypeCvcd			= 'cvcd'		# Compressed Video CD
	ReleaseTypeCvcdRip		= 'cvcdrip'		# Compressed Video CD Rip

	ReleaseTypeXvcd			= 'xvcd'		# eXtended Video CD
	ReleaseTypeXvcdRip		= 'xvcdrip'		# eXtended Video CD Rip

	ReleaseTypeDvcd			= 'dvcd'		# Double Video CD
	ReleaseTypeDvcdRip		= 'dvcdrip'		# Double Video CD Rip

	ReleaseTypeSvcd			= 'svcd'		# Super Video CD
	ReleaseTypeSvcdRip		= 'svcdrip'		# Super Video CD Rip

	ReleaseTypeKvcd			= 'kvcd'		# K Video Compression Dynamics
	ReleaseTypeKvcdRip		= 'kvcdrip'		# K Video Compression Dynamics Rip

	ReleaseTypeSkvcd		= 'skvcd'		# Super Compressed Video CD
	ReleaseTypeSkvcdRip		= 'skvcdrip'	# Super Compressed Video CD Rip

	ReleaseTypeLd			= 'ld'			# Laser Disc
	ReleaseTypeLdRip		= 'ldrip'		# Laser Disc Rip

	ReleaseTypeR1			= 'r1'			# DVD Region 1
	ReleaseTypeR1Rip		= 'r1rip'		# DVD Region 1 Rip
	ReleaseTypeR2			= 'r2'			# DVD Region 2
	ReleaseTypeR2Rip		= 'r2rip'		# DVD Region 2 Rip
	ReleaseTypeR3			= 'r3'			# DVD Region 3
	ReleaseTypeR3Rip		= 'r3rip'		# DVD Region 3 Rip
	ReleaseTypeR4			= 'r4'			# DVD Region 4
	ReleaseTypeR4Rip		= 'r4rip'		# DVD Region 4 Rip
	ReleaseTypeR5			= 'r5'			# DVD Region 5
	ReleaseTypeR5Rip		= 'r5rip'		# DVD Region 5 Rip
	ReleaseTypeR6			= 'r6'			# DVD Region 6
	ReleaseTypeR6Rip		= 'r6rip'		# DVD Region 6 Rip
	ReleaseTypeR7			= 'r7'			# DVD Region 7
	ReleaseTypeR7Rip		= 'r7rip'		# DVD Region 7 Rip
	ReleaseTypeR8			= 'r8'			# DVD Region 8
	ReleaseTypeR8Rip		= 'r8rip'		# DVD Region 8 Rip

	ReleaseTypeDvd			= 'dvd'			# DVD
	ReleaseTypeDvd5			= 'dvd5'		# DVD 5GB
	ReleaseTypeDvd9			= 'dvd9'		# DVD 9GB
	ReleaseTypeDvdR			= 'dvdr'		# DVD Recordable
	ReleaseTypeDvdRip		= 'dvdrip'		# DVD Rip

	ReleaseTypeHdDvd		= 'hddvd'		# HD DVD
	ReleaseTypeHdDvdRip		= 'hddvdrip'	# HD DVD Rip

	ReleaseTypeBluray		= 'bluray'		# Bluray
	ReleaseTypeBd5			= 'bd5'			# Bluray Disc 5GB
	ReleaseTypeBd9			= 'bd9'			# Bluray Disc 9GB
	ReleaseTypeBd25			= 'bd25'		# Bluray Disc 25GB
	ReleaseTypeBd50			= 'bd50'		# Bluray Disc 50GB
	ReleaseTypeBd100		= 'bd100'		# Bluray Disc 100GB
	ReleaseTypeBdR			= 'bdr'			# Bluray Disc Recordable
	ReleaseTypeBr			= 'br'			# Bluray Release
	ReleaseTypeBdRip		= 'bdrip'		# Bluray Disc Rip
	ReleaseTypeBrRip		= 'brrip'		# Bluray Release Rip

	ReleaseTypeNone			= None

	ExpressionReleaseType = {
		'keyword' : {
			'hd'		: u'(?:(?:f(?:ull)?)?h[dq]|high{separator}*(?:definition|quality))',
			'rip'		: u'rip(?:ped)?',
			'ripx'		: u'(?:(?:(?:f(?:ull)?)?h[dq]|dvd|tv){separator}*)?{rip}',
			'super'		: u'super(?:{separator}*(?:f(?:ull)?)?h[dq]{separator}*)?',
			'web'		: u'web(?:{separator}*(?:f(?:ull)?)?h[dq]{separator}*)?',
			'dl'		: u'(?:dl|download)(?:{separator}*(?:f(?:ull)?)?h[dq]{separator}*)?',
			'cap'		: u'cap(?:ture)?(?:{separator}*(?:f(?:ull)?)?h[dq]{separator}*)?',
			'pre'		: u'p(?:re)?',
			'tv'		: u'(?:tv|television)',
			'region'	: u'r(?:egion)?',
			'mux'		: u'{separator}*(?:rmx|(?:re)?mux(?:ed|ing)?)',
			'vhs'		: u'(?:vhs|video{separator}*home{separator}*system)',
			'dvhs'		: u'(?:dvhs|d(?:igital)?{separator}*(?:vhs|video{separator}*home{separator}*system|theater))',
			'ld'		: u'(?:(?<!trek.)ld|laser{separator}*dis[ck])', # Exclude "Star Trek LD" (Lower Decks).
			'ldfull'	: u'(?:laser{separator}*dis[ck])',
			'dvd'		: u'(?:(?:dvd|digital{separator}*(?:versatile|video){separator}*dis[ck])(?:\d{{1,2}})?)',
			'pdvd'		: u'p(?:re)?{separator}*(?:dvd|digital{separator}*(?:versatile|video){separator}*dis[ck])',
			'iso'		: u'(?:f?(?:dvdr?|(?:dvd{separator}*)?iso|digital{separator}*(?:versatile|video){separator}*dis[ck])(?:\d{{1,2}})?)',
			'bluray'	: u'(?:(?:bd(?:r|mv|av|3d|1080p?)?|br|blue?{separator}*ray(?:{separator}*dis[ck])?)(?:\d{{1,3}})?)',
			'bd'		: u'(?:(?:bd(?:r|mv|av|3d|1080p?)?|blue?{separator}*ray(?:{separator}*dis[ck])?)(?:\d{{1,3}})?)',

			'vcd'		: u'(?:vcd|video{separator}*(?:cd|compact{separator}*dis[ck])|compact{separator}*dis[ck]{separator}*digital{separator}*video)s?',
			'cvcd'		: u'(?:c(?:ompressed{separator}*)?{vcd})',
			'kvcd'		: u'(?:k{vcd}|k{separator}*video{separator}*compression{separator}*dynamics)',
			'xvcd'		: u'(?:(?:x|extended{separator}*){vcd})',
			'dvcd'		: u'(?:(?:d|double{separator}*){vcd})',
			'svcd'		: u'(?:(?:s|super{separator}*){vcd})',
			'skvcd'		: u'(?:sk{vcd})',

			'cam'		: u'cam(?:era)?',
			'scr'		: u'scr(?:e[en]ner)?',
			'ts'		: u'(?:(?<!mpeg.)(?<!mpeg..)(?<!mpeg...)ts(?<!\.ts$)(?!{brackets}+$)|t(?:ele)?{separator}*sync)', # Exclude MPEG "Transport Stream" and ".ts" file extensions
			'tc'		: u'(?:tc|t(?:ele)?{separator}*cine)',

			'ddc'		: u'(?:ddc|digital{separator}*distribution{separator}*copy|(?:downloadable|direct){separator}*digital{separator}*content)',
			'wp'		: u'(?:wp|work{separator}*print)',
			'vod'		: u'(?:vod|video{separator}*on{separator}*demand)',
			'ppv'		: u'(?:ppv|pay{separator}*per{separator}*view)',
			'dcp'		: u'(?:dcp|digital{separator}*cinema{separator}*package)',
			'ds'		: u'(?:ds|digital{separator}*sat(?:ellite)?)',
			'sat'		: u'(?:sat|satellite)',
			'dth'		: u'(?:dth|direct{separator}*to{separator}*home)',
			'dvb'		: u'(?:dvb|digital{separator}*(?:tv|television){separator}*broadcast(?:ing)?)(?:{separator}*t)?',
			'dtv'		: u'(?:dtv|digital{separator}*(?:tv|television))',
			'pdtv'		: u'(?:pd|pure{separator}*digital){separator}*(?:tv|television)',
			'iptv'		: u'(?:iptv|(?:ip|internet{separator}*protocol){separator}*(?:tv|television))',
			'ahdtv'		: u'(?:ahdtv|analog{separator}*hd{separator}*(?:tv|television))',
			'multiple'	: u'(?:\d+x)?',

			'n1'		: u'{separator}*1',
			'n2'		: u'{separator}*2',
			'n3'		: u'{separator}*3',
			'n4'		: u'{separator}*4',
			'n5'		: u'{separator}*5(?!{separator}+1[^\d])', # Ignore BD 5.1
			'n6'		: u'{separator}*6',
			'n7'		: u'{separator}*7(?!{separator}+1[^\d])', # Ignore BD 7.1
			'n8'		: u'{separator}*8',
			'n9'		: u'{separator}*9(?!{separator}+1[^\d])', # Ignore BD 9.1
			'n25'		: u'{separator}*25',
			'n50'		: u'{separator}*50',
			'n100'		: u'{separator}*100',
			'r'			: u'{separator}*r',
			'xl'		: u'{separator}*xl',
		},

		# Use this weird order to speed up execution. First check the most common keywords.
		'expression' : (
			('{web}', (
				(ReleaseTypeWebCapRip,	[u'{web}', u'{cap}', u'{rip}']),
				(ReleaseTypeWebCap,		[u'{web}', u'{cap}']),
				(ReleaseTypeWebDlRip,	[u'{web}', u'{dl}', u'{rip}']),
				(ReleaseTypeWebDl,		[u'{web}', u'{dl}']),
				(ReleaseTypeWebHdRip,	[u'{web}', u'{hd}', u'{rip}']),
				(ReleaseTypeWebHd,		[u'{web}', u'{hd}']),
				(ReleaseTypeWebRip,		[u'{web}', u'{rip}']),
				(ReleaseTypeWeb,		[u'{web}{mux}?']),
			)),

			('{cam}', (
				(ReleaseTypeDvdCamRip,	[u'{dvd}', u'{cam}', u'{rip}']),
				(ReleaseTypeDvdCam,		[u'{dvd}', u'{cam}']),
				(ReleaseTypeHdCamRip,	[u'{hd}', u'{cam}', u'{rip}']),
				(ReleaseTypeHdCam,		[u'{hd}', u'{cam}']),
				(ReleaseTypeCamRip,		[u'{cam}', u'{rip}']),
				(ReleaseTypeCam,		[u'{cam}']),
			)),

			('{scr}', (
				(ReleaseTypeBdScrRip,	[u'{bluray}', u'{scr}', u'{rip}']),
				(ReleaseTypeBdScr,		[u'{bluray}', u'{scr}']),
				(ReleaseTypeDvdScrRip,	[u'{dvd}', u'{scr}', u'{rip}']),
				(ReleaseTypeDvdScr,		[u'{dvd}', u'{scr}']),
				(ReleaseTypeVhsScrRip,	[u'{vhs}', u'{scr}', u'{rip}']),
				(ReleaseTypeVhsScr,		[u'{vhs}', u'{scr}']),
				(ReleaseTypeTsScr,		[u'{ts}', u'{scr}']),
				(ReleaseTypeTcScr,		[u'{tc}', u'{scr}']),
				(ReleaseTypeScrRip,		[u'{scr}', u'{rip}']),
				(ReleaseTypeScr,		[u'{scr}']),
			)),

			('{wp}', (
				(ReleaseTypeWpRip,		[u'{wp}', u'{rip}']),
				(ReleaseTypeWp,			[u'{wp}']),
			)),

			('{bluray}', (
				(ReleaseTypeBd100,		[u'{bd}(?:{n100}|{xl})']),
				(ReleaseTypeBd50,		[u'{bd}{n50}']),
				(ReleaseTypeBd25,		[u'{bd}{n25}']),
				(ReleaseTypeBd9,		[u'{bd}{n9}']),
				(ReleaseTypeBd5,		[u'{bd}{n5}']),
				(ReleaseTypeBdR,		[u'{bd}{r}']),
				(ReleaseTypeBdRip,		[u'{bd}', u'{rip}']),
				(ReleaseTypeBrRip,		[u'(?:br?)', u'{rip}']),
				(ReleaseTypeBr,			[u'(?<!pt{separator})(?<!por{separator})(?<!portugu.s{separator})(?<!portugu.se{separator})br{mux}?(?!{separator}pt)(?!{separator}por)(?!{separator}portugu.s)(?!{separator}portugu.se)']), # Do not match only "br" since it can also mean Brazil.
				(ReleaseTypeBluray,		[u'{bd}{mux}?']), # Do not uuse {bluray} since "br" can also mean Brazil.
			)),

			('{ts}', (
				(ReleaseTypeSuperTs,	[u'{super}', u'{ts}']),
				(ReleaseTypeHdTsRip,	[u'{hd}', u'{ts}', u'{rip}']),
				(ReleaseTypeHdTs,		[u'{hd}', u'{ts}']),
				(ReleaseTypeTsRip,		[u'{ts}', u'{rip}']),
				(ReleaseTypeTs,			[u'{ts}']),
			)),

			('{tc}', (
				(ReleaseTypeSuperTc,	[u'{super}', u'{tc}']),
				(ReleaseTypeHdTcRip,	[u'{hd}', u'{tc}', u'{rip}']),
				(ReleaseTypeHdTc,		[u'{hd}', u'{tc}']),
				(ReleaseTypeTcRip,		[u'{tc}', u'{rip}']),
				(ReleaseTypeTc,			[u'{tc}']),
			)),

			('{hd}', (
				(ReleaseTypeHdDvdRip,	[u'{hd}', u'{iso}', u'{rip}']),
				(ReleaseTypeHdDvd,		[u'{hd}', u'{dvd}']),
			)),

			('{region}{separator}*\d', (
				(ReleaseTypeR1Rip,		[u'{region}{n1}', u'{ripx}']),
				(ReleaseTypeR1,			[u'{region}{n1}']),
				(ReleaseTypeR2Rip,		[u'{region}{n2}', u'{ripx}']),
				(ReleaseTypeR2,			[u'{region}{n2}']),
				(ReleaseTypeR3Rip,		[u'{region}{n3}', u'{ripx}']),
				(ReleaseTypeR3,			[u'{region}{n3}']),
				(ReleaseTypeR4Rip,		[u'{region}{n4}', u'{ripx}']),
				(ReleaseTypeR4,			[u'{region}{n4}']),
				(ReleaseTypeR5Rip,		[u'{region}{n5}', u'{ripx}']),
				(ReleaseTypeR5,			[u'{region}{n5}']),
				(ReleaseTypeR6Rip,		[u'{region}{n6}', u'{ripx}']),
				(ReleaseTypeR6,			[u'{region}{n6}']),
				(ReleaseTypeR7Rip,		[u'{region}{n7}', u'{ripx}']),
				(ReleaseTypeR7,			[u'{region}{n7}']),
				(ReleaseTypeR8Rip,		[u'{region}{n8}', u'{ripx}']),
				(ReleaseTypeR8,			[u'{region}{n8}']),
			)),

			('{pdvd}', (
				(ReleaseTypePdvdRip,	[u'{pdvd}', u'{ripx}']),
				(ReleaseTypePdvd,		[u'{pdvd}']),
			)),

			('{iso}', (
				(ReleaseTypeDvd9,		[u'{dvd}{n9}']),
				(ReleaseTypeDvd5,		[u'{dvd}{n5}']),
				(ReleaseTypeDvdR,		[u'{multiple}{dvd}{r}']),
				(ReleaseTypeDvdRip,		[u'{multiple}{iso}', u'{rip}']),
				(ReleaseTypeDvd,		[u'{multiple}{dvd}']),
			)),

			('{dvhs}', (
				(ReleaseTypeDvhsRip,	[u'{dvhs}', u'{ripx}']),
				(ReleaseTypeDvhs,		[u'{dvhs}']),
			)),

			('{ddc}', (
				(ReleaseTypeDdcRip,		[u'{ddc}', u'{rip}']),
				(ReleaseTypeDdc,		[u'{ddc}']),
			)),

			('{vod}', (
				(ReleaseTypeVodRip,		[u'{vod}', u'{ripx}']),
				(ReleaseTypeVod,		[u'{vod}']),
			)),

			('{ppv}', (
				(ReleaseTypePpvRip,		[u'{ppv}', u'{ripx}']),
				(ReleaseTypePpv,		[u'{ppv}']),
			)),

			('{dcp}', (
				(ReleaseTypeDcpRip,		[u'{dcp}', u'{ripx}']),
				(ReleaseTypeDcp,		[u'{dcp}']),
			)),

			('{vhs}', (
				(ReleaseTypeVhsRip,		[u'{vhs}', u'{ripx}']),
				(ReleaseTypeVhs,		[u'{vhs}']),
			)),

			('{cvcd}', (
				(ReleaseTypeCvcdRip,		[u'{cvcd}', u'{ripx}']),
				(ReleaseTypeCvcd,		[u'{cvcd}']),
			)),

			('{xvcd}', (
				(ReleaseTypeXvcdRip,	[u'{xvcd}', u'{ripx}']),
				(ReleaseTypeXvcd,		[u'{xvcd}']),
			)),

			('{dvcd}', (
				(ReleaseTypeDvcdRip,	[u'{dvcd}', u'{ripx}']),
				(ReleaseTypeDvcd,		[u'{dvcd}']),
			)),

			('{svcd}', (
				(ReleaseTypeSvcdRip,	[u'{svcd}', u'{ripx}']),
				(ReleaseTypeSvcd,		[u'{svcd}']),
			)),

			('{kvcd}', (
				(ReleaseTypeKvcdRip,	[u'{kvcd}', u'{ripx}']),
				(ReleaseTypeKvcd,		[u'{kvcd}']),
			)),

			('{skvcd}', (
				(ReleaseTypeSkvcdRip,	[u'{skvcd}', u'{ripx}']),
				(ReleaseTypeSkvcd,		[u'{skvcd}']),
			)),

			('{vcd}', (
				(ReleaseTypeVcdRip,		[u'{vcd}', u'{ripx}']),
				(ReleaseTypeVcd,		[u'{vcd}']),
			)),

			('{ld}', (
				(ReleaseTypeLdRip,		[u'{ld}', u'{ripx}']),
				#(ReleaseTypeLd,		[u'{ld}']), # Leave for now, since "ld" is too common and could also be "low definition" and more commonly "line dubbed".
				(ReleaseTypeLd,			[u'{ldfull}'])
			)),

			('{pdtv}', (
				(ReleaseTypePdtvRip,	[u'{pdtv}', u'{ripx}']),
				(ReleaseTypePdtv,		[u'{pdtv}']),
			)),

			('{ds}', (
				(ReleaseTypeDsRip,		[u'{ds}', u'{ripx}']),
				#(ReleaseTypeDs,		[u'{ds}']), # Leave for now, since it is too general and a "DS" uplaader exists.
			)),

			('{sat}', (
				(ReleaseTypeSatRip,		[u'{sat}', u'{ripx}']),
				(ReleaseTypeSat,		[u'{sat}']),
			)),

			('{dth}', (
				(ReleaseTypeDthRip,		[u'{dth}', u'{ripx}']),
				(ReleaseTypeDth,		[u'{dth}']), # Leave for now, since it is too general and a "DTH" audio exists.
			)),

			('{dvb}', (
				(ReleaseTypeDvbRip,		[u'{dvb}', u'{ripx}']),
				(ReleaseTypeDvb,		[u'{dvb}']),
			)),

			('{dtv}', (
				(ReleaseTypeDtvRip,		[u'{dtv}', u'{ripx}']),
				(ReleaseTypeDtv,		[u'{dtv}']),
			)),

			('{iptv}', (
				(ReleaseTypeIptvRip,	[u'{iptv}', u'{ripx}']),
				(ReleaseTypeIptv,		[u'{iptv}']),
			)),

			('{ahdtv}', (
				(ReleaseTypeAhdtvRip,	[u'{ahdtv}', u'{ripx}']),
				(ReleaseTypeAhdtv,		[u'{ahdtv}']),
			)),

			('{hd}', (
				(ReleaseTypeHdTvRip,	[u'{hd}', u'{tv}', u'{rip}']),
				(ReleaseTypeHdTv,		[u'{hd}', u'{tv}{mux}?']),
				(ReleaseTypeHdRip,		[u'{hd}', u'(?:{rip}|{mux})']),
			)),

			('', (
				(ReleaseTypeTvRip,		[u'{tv}', u'{rip}']),
				(ReleaseTypeTv,			[u'{tv}{mux}?']),
				(ReleaseTypeWebDl,		[u'{dl}', u'{mux}']),
			)),
		),
	}

	LabelReleaseType = {
		LabelDefault : {
			LabelList1		: LabelShort,
			LabelList2		: LabelShort,
			LabelList3		: LabelShort,
			LabelList4		: LabelHidden,
			LabelInfo1		: LabelShort,
			LabelInfo2		: LabelMedium,
			LabelSettings1	: LabelMedium,
			LabelSettings2	: LabelShort,
		},

		ReleaseTypeWeb			: { LabelShort : 'WEB',			LabelMedium : 'Web',								LabelLong : 'Web' },
		ReleaseTypeWebRip		: { LabelShort : 'WEBRIP',		LabelMedium : 'Web Rip',							LabelLong : 'Web Rip' },
		ReleaseTypeWebDl		: { LabelShort : 'WEBDL',		LabelMedium : 'Web Download',						LabelLong : 'Web Download' },
		ReleaseTypeWebDlRip		: { LabelShort : 'WEBDLRIP',	LabelMedium : 'Web Download Rip',					LabelLong : 'Web Download Rip' },
		ReleaseTypeWebHd		: { LabelShort : 'WEBHD',		LabelMedium : 'Web HD',								LabelLong : 'Web High Definition' },
		ReleaseTypeWebHdRip		: { LabelShort : 'WEBHDRIP',	LabelMedium : 'Web HD Rip',							LabelLong : 'Web High Definition Rip' },
		ReleaseTypeWebCap		: { LabelShort : 'WEBCAP',		LabelMedium : 'Web Capture',						LabelLong : 'Web Capture' },
		ReleaseTypeWebCapRip	: { LabelShort : 'WEBCAPRIP',	LabelMedium : 'Web Capture Rip',					LabelLong : 'Web Capture Rip' },

		ReleaseTypeBluray		: { LabelShort : 'BLURAY',		LabelMedium : 'Bluray',								LabelLong : 'Bluray' },
		ReleaseTypeBd5			: { LabelShort : 'BD5',			LabelMedium : 'Bluray Disc 5GB',					LabelLong : 'Bluray Disc 5GB' },
		ReleaseTypeBd9			: { LabelShort : 'BD9',			LabelMedium : 'Bluray Disc 9GB',					LabelLong : 'Bluray Disc 9GB' },
		ReleaseTypeBd25			: { LabelShort : 'BD25',		LabelMedium : 'Bluray Disc 25GB',					LabelLong : 'Bluray Disc 25GB' },
		ReleaseTypeBd50			: { LabelShort : 'BD50',		LabelMedium : 'Bluray Disc 50GB',					LabelLong : 'Bluray Disc 50GB' },
		ReleaseTypeBd100		: { LabelShort : 'BD100',		LabelMedium : 'Bluray Disc 100GB',					LabelLong : 'Bluray Disc 100GB' },
		ReleaseTypeBdR			: { LabelShort : 'BDR',			LabelMedium : 'Bluray Disc Recordable',				LabelLong : 'Bluray Disc Recordable' },
		ReleaseTypeBdRip		: { LabelShort : 'BDRIP',		LabelMedium : 'Bluray Disc Rip',					LabelLong : 'Bluray Disc Rip' },
		ReleaseTypeBr			: { LabelShort : 'BR',			LabelMedium : 'Bluray Release',						LabelLong : 'Bluray Release' },
		ReleaseTypeBrRip		: { LabelShort : 'BRRIP',		LabelMedium : 'Bluray Release Rip',					LabelLong : 'Bluray Release Rip' },

		ReleaseTypeDvd			: { LabelShort : 'DVD',			LabelMedium : 'DVD',								LabelLong : 'Digital Versatile Disc' },
		ReleaseTypeDvd5			: { LabelShort : 'DVD5',		LabelMedium : 'DVD 5GB',							LabelLong : 'Digital Versatile Disc 5GB' },
		ReleaseTypeDvd9			: { LabelShort : 'DVD9',		LabelMedium : 'DVD 9GB',							LabelLong : 'Digital Versatile Disc 9GB' },
		ReleaseTypeDvdR			: { LabelShort : 'DVDR',		LabelMedium : 'DVD Recordable',						LabelLong : 'Digital Versatile Disc Recordable' },
		ReleaseTypeDvdRip		: { LabelShort : 'DVDRIP',		LabelMedium : 'DVD Rip',							LabelLong : 'Digital Versatile Disc Rip' },

		ReleaseTypeHdDvd		: { LabelShort : 'HDDVD',		LabelMedium : 'HD DVD',								LabelLong : 'High Definition Digital Versatile Disc' },
		ReleaseTypeHdDvdRip		: { LabelShort : 'HDDVDRIP',	LabelMedium : 'HD DVD Rip',							LabelLong : 'High Definition Digital Versatile Disc Rip' },

		ReleaseTypeHdRip		: { LabelShort : 'HDRIP',		LabelMedium : 'HD Rip',								LabelLong : 'High Definition Rip' },
		ReleaseTypeHdTv			: { LabelShort : 'HDTV',		LabelMedium : 'HD TV',								LabelLong : 'High Definition Television' },
		ReleaseTypeHdTvRip		: { LabelShort : 'HDTVRIP',		LabelMedium : 'HD TV Rip',							LabelLong : 'High Definition Television Rip' },
		ReleaseTypeTv			: { LabelShort : 'TV',			LabelMedium : 'TV',									LabelLong : 'Television' },
		ReleaseTypeTvRip		: { LabelShort : 'TVRIP',		LabelMedium : 'TV Rip',								LabelLong : 'Television Rip' },

		ReleaseTypeScr			: { LabelShort : 'SCR',			LabelMedium : 'Screener',							LabelLong : 'Screener' },
		ReleaseTypeScrRip		: { LabelShort : 'SCRRIP',		LabelMedium : 'Screener Rip',						LabelLong : 'Screener Rip' },
		ReleaseTypeTsScr		: { LabelShort : 'TSSCR',		LabelMedium : 'Telesync Screener',					LabelLong : 'Telesync Screener' },
		ReleaseTypeTcScr		: { LabelShort : 'TCSCR',		LabelMedium : 'Telecine Screener',					LabelLong : 'Telecine Screener' },
		ReleaseTypeVhsScr		: { LabelShort : 'VHSSCR',		LabelMedium : 'VHS Screener',						LabelLong : 'Video Home System Screener' },
		ReleaseTypeVhsScrRip	: { LabelShort : 'VHSSCRRIP',	LabelMedium : 'VHS Screener Rip',					LabelLong : 'Video Home System Screener Rip' },
		ReleaseTypeDvdScr		: { LabelShort : 'DVDSCR',		LabelMedium : 'DVD Screener',						LabelLong : 'Digital Versatile Disc Screener' },
		ReleaseTypeDvdScrRip	: { LabelShort : 'DVDSCRRIP',	LabelMedium : 'DVD Screener Rip',					LabelLong : 'Digital Versatile Disc Screener Rip' },
		ReleaseTypeBdScr		: { LabelShort : 'BDSCR',		LabelMedium : 'Bluray Screener',					LabelLong : 'Bluray Screener' },
		ReleaseTypeBdScrRip		: { LabelShort : 'BDSCRRIP',	LabelMedium : 'Bluray Screener Rip',				LabelLong : 'Bluray Screener Rip' },

		ReleaseTypeTs			: { LabelShort : 'TS',			LabelMedium : 'Telesync',							LabelLong : 'Telesync' },
		ReleaseTypeTsRip		: { LabelShort : 'TSRIP',		LabelMedium : 'Telesync Rip',						LabelLong : 'Telesync Rip' },
		ReleaseTypeHdTs			: { LabelShort : 'HDTS',		LabelMedium : 'HD Telesync',						LabelLong : 'High Definition Telesync' },
		ReleaseTypeHdTsRip		: { LabelShort : 'HDTSRIP',		LabelMedium : 'HD Telesync Rip',					LabelLong : 'High Definition Telesync Rip' },
		ReleaseTypeSuperTs		: { LabelShort : 'SUPERTS',		LabelMedium : 'Super Telesync',						LabelLong : 'Super Telesync' },

		ReleaseTypeTc			: { LabelShort : 'TC',			LabelMedium : 'Telecine',							LabelLong : 'Telecine' },
		ReleaseTypeTcRip		: { LabelShort : 'TCRIP',		LabelMedium : 'Telecine Rip',						LabelLong : 'Telecine Rip' },
		ReleaseTypeHdTc			: { LabelShort : 'HDTC',		LabelMedium : 'HD Telecine',						LabelLong : 'High Definition Telecine' },
		ReleaseTypeHdTcRip		: { LabelShort : 'HDTCRIP',		LabelMedium : 'HD Telecine Rip',					LabelLong : 'High Definition Telecine Rip' },
		ReleaseTypeSuperTc		: { LabelShort : 'SUPERTC',		LabelMedium : 'Super Telecine',						LabelLong : 'Super Telecine' },

		ReleaseTypeCam			: { LabelShort : 'CAM',			LabelMedium : 'Camera',								LabelLong : 'Camera' },
		ReleaseTypeCamRip		: { LabelShort : 'CAMRIP',		LabelMedium : 'Camera Rip',							LabelLong : 'Camera Rip' },
		ReleaseTypeHdCam		: { LabelShort : 'HDCAM',		LabelMedium : 'HD Camera',							LabelLong : 'High Definition Camera' },
		ReleaseTypeHdCamRip		: { LabelShort : 'HDCAMRIP',	LabelMedium : 'HD Camera Rip',						LabelLong : 'High Definition Camera Rip' },
		ReleaseTypeDvdCam		: { LabelShort : 'DVDCAM',		LabelMedium : 'DVD Camera',							LabelLong : 'Digital Versatile Disc Camera' },
		ReleaseTypeDvdCamRip	: { LabelShort : 'DVDCAMRIP',	LabelMedium : 'DVD Camera Rip',						LabelLong : 'Digital Versatile Disc Camera Rip' },

		ReleaseTypeDdc			: { LabelShort : 'DDC',			LabelMedium : 'Direct Digital Content',				LabelLong : 'Direct Digital Content' },
		ReleaseTypeDdcRip		: { LabelShort : 'DDCRIP',		LabelMedium : 'Direct Digital Content Rip',			LabelLong : 'Direct Digital Content Rip' },

		ReleaseTypeWp			: { LabelShort : 'WP',			LabelMedium : 'Workprint',							LabelLong : 'Workprint' },
		ReleaseTypeWpRip		: { LabelShort : 'WPRIP',		LabelMedium : 'Workprint Rip',						LabelLong : 'Workprint Rip' },

		ReleaseTypePdvd			: { LabelShort : 'PDVD',		LabelMedium : 'Pre DVD',							LabelLong : 'Pre Digital Versatile Disc' },
		ReleaseTypePdvdRip		: { LabelShort : 'PDVDRIP',		LabelMedium : 'Pre DVD Rip',						LabelLong : 'Pre Digital Versatile Disc Rip' },

		ReleaseTypeVod			: { LabelShort : 'VOD',			LabelMedium : 'Video On Demand',					LabelLong : 'Video On Demand' },
		ReleaseTypeVodRip		: { LabelShort : 'VODRIP',		LabelMedium : 'Video On Demand Rip',				LabelLong : 'Video On Demand Rip' },

		ReleaseTypePpv			: { LabelShort : 'PPV',			LabelMedium : 'Pay Per View',						LabelLong : 'Pay Per View' },
		ReleaseTypePpvRip		: { LabelShort : 'PPVRIP',		LabelMedium : 'Pay Per View Rip',					LabelLong : 'Pay Per View Rip' },

		ReleaseTypeDcp			: { LabelShort : 'DCP',			LabelMedium : 'Digital Cinema Package',				LabelLong : 'Digital Cinema Package' },
		ReleaseTypeDcpRip		: { LabelShort : 'DCPRIP',		LabelMedium : 'Digital Cinema Package Rip',			LabelLong : 'Digital Cinema Package Rip' },

		ReleaseTypePdtv			: { LabelShort : 'PDTV',		LabelMedium : 'Pure Digital TV',					LabelLong : 'Pure Digital Television' },
		ReleaseTypePdtvRip		: { LabelShort : 'PDTVRIP',		LabelMedium : 'Pure Digital TV Rip',				LabelLong : 'Pure Digital Television Rip' },

		ReleaseTypeSat			: { LabelShort : 'SAT',			LabelMedium : 'Satellite',							LabelLong : 'Satellite' },
		ReleaseTypeSatRip		: { LabelShort : 'SATRIP',		LabelMedium : 'Satellite Rip',						LabelLong : 'Satellite Rip' },

		ReleaseTypeDs			: { LabelShort : 'DS',			LabelMedium : 'Digital Satellite',					LabelLong : 'Digital Satellite' },
		ReleaseTypeDsRip		: { LabelShort : 'DSRIP',		LabelMedium : 'Digital Satellite Rip',				LabelLong : 'Digital Satellite Rip' },

		ReleaseTypeDth			: { LabelShort : 'DTH',			LabelMedium : 'Direct To Home',						LabelLong : 'Direct To Home' },
		ReleaseTypeDthRip		: { LabelShort : 'DTHRIP',		LabelMedium : 'Direct To Home Rip',					LabelLong : 'Direct To Home Rip' },

		ReleaseTypeDvb			: { LabelShort : 'DVB',			LabelMedium : 'Digital TV Broadcasting',			LabelLong : 'Digital Television Broadcasting' },
		ReleaseTypeDvbRip		: { LabelShort : 'DVBRIP',		LabelMedium : 'Digital TV Broadcasting Rip',		LabelLong : 'Digital Television Broadcasting Rip' },

		ReleaseTypeDtv			: { LabelShort : 'DTV',			LabelMedium : 'Digital TV',							LabelLong : 'Digital Television' },
		ReleaseTypeDtvRip		: { LabelShort : 'DTVRIP',		LabelMedium : 'Digital TV Rip',						LabelLong : 'Digital Television Rip' },

		ReleaseTypeIptv			: { LabelShort : 'IPTV',		LabelMedium : 'IP TV',								LabelLong : 'Internet Protocol Television' },
		ReleaseTypeIptvRip		: { LabelShort : 'IPTVRIP',		LabelMedium : 'IP TV Rip',							LabelLong : 'Internet Protocol Television Rip' },

		ReleaseTypeAhdtv		: { LabelShort : 'AHDTV',		LabelMedium : 'Analog HD TV',						LabelLong : 'Analog High Definition Television' },
		ReleaseTypeAhdtvRip		: { LabelShort : 'AHDTVRIP',	LabelMedium : 'Analog HD TV Rip',					LabelLong : 'Analog High Definition Television Rip' },

		ReleaseTypeVhs			: { LabelShort : 'VHS',			LabelMedium : 'VHS',								LabelLong : 'Video Home System' },
		ReleaseTypeVhsRip		: { LabelShort : 'VHSRIP',		LabelMedium : 'VHS Rip',							LabelLong : 'Video Home System Rip' },

		ReleaseTypeDvhs			: { LabelShort : 'DVHS',		LabelMedium : 'Digital VHS',						LabelLong : 'Digital Video Home System' },
		ReleaseTypeDvhsRip		: { LabelShort : 'DVHSRIP',		LabelMedium : 'Digital VHS Rip',					LabelLong : 'Digital Video Home System Rip' },

		ReleaseTypeVcd			: { LabelShort : 'VCD',			LabelMedium : 'Video CD',							LabelLong : 'Video Compact Disc' },
		ReleaseTypeVcdRip		: { LabelShort : 'VCDRIP',		LabelMedium : 'Video CD Rip',						LabelLong : 'Video Compact Disc Rip' },

		ReleaseTypeCvcd			: { LabelShort : 'XVCD',		LabelMedium : 'Compressed Video CD',				LabelLong : 'Compressed Video Compact Disc' },
		ReleaseTypeCvcdRip		: { LabelShort : 'XVCDRIP',		LabelMedium : 'Compressed Video CD Rip',			LabelLong : 'Compressed Video Compact Disc Rip' },

		ReleaseTypeXvcd			: { LabelShort : 'XVCD',		LabelMedium : 'Extended Video CD',					LabelLong : 'Extended Video Compact Disc' },
		ReleaseTypeXvcdRip		: { LabelShort : 'XVCDRIP',		LabelMedium : 'Extended Video CD Rip',				LabelLong : 'Extended Video Compact Disc Rip' },

		ReleaseTypeDvcd			: { LabelShort : 'DVCD',		LabelMedium : 'Double Video CD',					LabelLong : 'Double Video Compact Disc' },
		ReleaseTypeDvcdRip		: { LabelShort : 'DVCDRIP',		LabelMedium : 'Double Video CD Rip',				LabelLong : 'Double Video Compact Disc Rip' },

		ReleaseTypeSvcd			: { LabelShort : 'SVCD',		LabelMedium : 'Super Video CD',						LabelLong : 'Super Video Compact Disc' },
		ReleaseTypeSvcdRip		: { LabelShort : 'SVCDRIP',		LabelMedium : 'Super Video CD Rip',					LabelLong : 'Super Video Compact Disc Rip' },

		ReleaseTypeKvcd			: { LabelShort : 'KVCD',		LabelMedium : 'K Video Compression Dynamics',		LabelLong : 'K Video Compression Dynamics' },
		ReleaseTypeKvcdRip		: { LabelShort : 'KVCDRIP',		LabelMedium : 'K Video Compression Dynamics Rip',	LabelLong : 'K Video Compression Dynamicsa Rip' },

		ReleaseTypeSkvcd		: { LabelShort : 'SKVCD',		LabelMedium : 'Super Compressed Video CD',			LabelLong : 'Super Compressed Video Compact Disc' },
		ReleaseTypeSkvcdRip		: { LabelShort : 'SKVCDRIP',	LabelMedium : 'Super Compressed Video CD Rip',		LabelLong : 'Super Compressed Video Compact Disc Rip' },

		ReleaseTypeLd			: { LabelShort : 'LD',			LabelMedium : 'Laser Disc',							LabelLong : 'Laser Disc' },
		ReleaseTypeLdRip		: { LabelShort : 'LDRIP',		LabelMedium : 'Laser Disc Rip',						LabelLong : 'Laser Disc Rip' },

		ReleaseTypeR1			: { LabelShort : 'R1',			LabelMedium : 'DVD Region 1',						LabelLong : 'Digital Versatile Disc Region 1' },
		ReleaseTypeR1Rip		: { LabelShort : 'R1RIP',		LabelMedium : 'DVD Region 1 Rip',					LabelLong : 'Digital Versatile Disc Region 1 Rip' },
		ReleaseTypeR2			: { LabelShort : 'R2',			LabelMedium : 'DVD Region 2',						LabelLong : 'Digital Versatile Disc Region 2' },
		ReleaseTypeR2Rip		: { LabelShort : 'R2RIP',		LabelMedium : 'DVD Region 2 Rip',					LabelLong : 'Digital Versatile Disc Region 2 Rip' },
		ReleaseTypeR3			: { LabelShort : 'R3',			LabelMedium : 'DVD Region 3',						LabelLong : 'Digital Versatile Disc Region 3' },
		ReleaseTypeR3Rip		: { LabelShort : 'R3RIP',		LabelMedium : 'DVD Region 3 Rip',					LabelLong : 'Digital Versatile Disc Region 3 Rip' },
		ReleaseTypeR4			: { LabelShort : 'R4',			LabelMedium : 'DVD Region 4',						LabelLong : 'Digital Versatile Disc Region 4' },
		ReleaseTypeR4Rip		: { LabelShort : 'R4RIP',		LabelMedium : 'DVD Region 4 Rip',					LabelLong : 'Digital Versatile Disc Region 4 Rip' },
		ReleaseTypeR5			: { LabelShort : 'R5',			LabelMedium : 'DVD Region 5',						LabelLong : 'Digital Versatile Disc Region 5' },
		ReleaseTypeR5Rip		: { LabelShort : 'R5RIP',		LabelMedium : 'DVD Region 5 Rip',					LabelLong : 'Digital Versatile Disc Region 5 Rip' },
		ReleaseTypeR6			: { LabelShort : 'R6',			LabelMedium : 'DVD Region 6',						LabelLong : 'Digital Versatile Disc Region 6' },
		ReleaseTypeR6Rip		: { LabelShort : 'R6RIP',		LabelMedium : 'DVD Region 6 Rip',					LabelLong : 'Digital Versatile Disc Region 6 Rip' },
		ReleaseTypeR7			: { LabelShort : 'R7',			LabelMedium : 'DVD Region 7',						LabelLong : 'Digital Versatile Disc Region 7' },
		ReleaseTypeR7Rip		: { LabelShort : 'R7RIP',		LabelMedium : 'DVD Region 7 Rip',					LabelLong : 'Digital Versatile Disc Region 7 Rip' },
		ReleaseTypeR8			: { LabelShort : 'R8',			LabelMedium : 'DVD Region 8',						LabelLong : 'Digital Versatile Disc Region 8' },
		ReleaseTypeR8Rip		: { LabelShort : 'R8RIP',		LabelMedium : 'DVD Region 8 Rip',					LabelLong : 'Digital Versatile Disc Region 8 Rip' },
	}

	OrderReleaseType = {
		ReleaseTypeWeb			: { OrderInterface : 1,		OrderSorting : 11 },
		ReleaseTypeWebRip		: { OrderInterface : 2,		OrderSorting : 15 },
		ReleaseTypeWebDl		: { OrderInterface : 3,		OrderSorting : 12 },
		ReleaseTypeWebDlRip		: { OrderInterface : 4,		OrderSorting : 16 },
		ReleaseTypeWebHd		: { OrderInterface : 5,		OrderSorting : 13 },
		ReleaseTypeWebHdRip		: { OrderInterface : 6,		OrderSorting : 17 },
		ReleaseTypeWebCap		: { OrderInterface : 7,		OrderSorting : 14 },
		ReleaseTypeWebCapRip	: { OrderInterface : 8,		OrderSorting : 18 },

		ReleaseTypeBluray		: { OrderInterface : 9,		OrderSorting : 1 },
		ReleaseTypeBd5			: { OrderInterface : 10,	OrderSorting : 6 },
		ReleaseTypeBd9			: { OrderInterface : 11,	OrderSorting : 5 },
		ReleaseTypeBd25			: { OrderInterface : 12,	OrderSorting : 4 },
		ReleaseTypeBd50			: { OrderInterface : 13,	OrderSorting : 3 },
		ReleaseTypeBd100		: { OrderInterface : 14,	OrderSorting : 2 },
		ReleaseTypeBdR			: { OrderInterface : 15,	OrderSorting : 7 },
		ReleaseTypeBr			: { OrderInterface : 16,	OrderSorting : 9 },
		ReleaseTypeBdRip		: { OrderInterface : 17,	OrderSorting : 8 },
		ReleaseTypeBrRip		: { OrderInterface : 18,	OrderSorting : 10 },

		ReleaseTypeDvd			: { OrderInterface : 19,	OrderSorting : 21 },
		ReleaseTypeDvd5			: { OrderInterface : 20,	OrderSorting : 23 },
		ReleaseTypeDvd9			: { OrderInterface : 21,	OrderSorting : 22 },
		ReleaseTypeDvdR			: { OrderInterface : 22,	OrderSorting : 24 },
		ReleaseTypeDvdRip		: { OrderInterface : 23,	OrderSorting : 25 },

		ReleaseTypeHdDvd		: { OrderInterface : 24,	OrderSorting : 19 },
		ReleaseTypeHdDvdRip		: { OrderInterface : 25,	OrderSorting : 20 },

		ReleaseTypeHdRip		: { OrderInterface : 26,	OrderSorting : 27 },
		ReleaseTypeHdTv			: { OrderInterface : 27,	OrderSorting : 26 },
		ReleaseTypeHdTvRip		: { OrderInterface : 28,	OrderSorting : 28 },
		ReleaseTypeTv			: { OrderInterface : 29,	OrderSorting : 29 },
		ReleaseTypeTvRip		: { OrderInterface : 30,	OrderSorting : 30 },

		ReleaseTypeScr			: { OrderInterface : 31,	OrderSorting : 99 },
		ReleaseTypeScrRip		: { OrderInterface : 32,	OrderSorting : 100 },
		ReleaseTypeTsScr		: { OrderInterface : 33,	OrderSorting : 101 },
		ReleaseTypeTcScr		: { OrderInterface : 34,	OrderSorting : 102 },
		ReleaseTypeVhsScr		: { OrderInterface : 35,	OrderSorting : 103 },
		ReleaseTypeVhsScrRip	: { OrderInterface : 36,	OrderSorting : 104 },
		ReleaseTypeDvdScr		: { OrderInterface : 37,	OrderSorting : 97 },
		ReleaseTypeDvdScrRip	: { OrderInterface : 38,	OrderSorting : 98 },
		ReleaseTypeBdScr		: { OrderInterface : 39,	OrderSorting : 95 },
		ReleaseTypeBdScrRip		: { OrderInterface : 40,	OrderSorting : 96 },

		ReleaseTypeTs			: { OrderInterface : 41,	OrderSorting : 113 },
		ReleaseTypeTsRip		: { OrderInterface : 42,	OrderSorting : 114 },
		ReleaseTypeHdTs			: { OrderInterface : 43,	OrderSorting : 111 },
		ReleaseTypeHdTsRip		: { OrderInterface : 44,	OrderSorting : 112 },
		ReleaseTypeSuperTs		: { OrderInterface : 45,	OrderSorting : 110 },

		ReleaseTypeTc			: { OrderInterface : 46,	OrderSorting : 108 },
		ReleaseTypeTcRip		: { OrderInterface : 47,	OrderSorting : 109 },
		ReleaseTypeHdTc			: { OrderInterface : 48,	OrderSorting : 106 },
		ReleaseTypeHdTcRip		: { OrderInterface : 49,	OrderSorting : 107 },
		ReleaseTypeSuperTc		: { OrderInterface : 50,	OrderSorting : 105 },

		ReleaseTypeCam			: { OrderInterface : 51,	OrderSorting : 119 },
		ReleaseTypeCamRip		: { OrderInterface : 52,	OrderSorting : 120 },
		ReleaseTypeHdCam		: { OrderInterface : 53,	OrderSorting : 117 },
		ReleaseTypeHdCamRip		: { OrderInterface : 54,	OrderSorting : 118 },
		ReleaseTypeDvdCam		: { OrderInterface : 55,	OrderSorting : 115 },
		ReleaseTypeDvdCamRip	: { OrderInterface : 56,	OrderSorting : 116 },

		ReleaseTypeDdc			: { OrderInterface : 57,	OrderSorting : 53 },
		ReleaseTypeDdcRip		: { OrderInterface : 58,	OrderSorting : 54 },

		ReleaseTypeWp			: { OrderInterface : 59,	OrderSorting : 55 },
		ReleaseTypeWpRip		: { OrderInterface : 60,	OrderSorting : 56 },

		ReleaseTypePdvd			: { OrderInterface : 61,	OrderSorting : 51 },
		ReleaseTypePdvdRip		: { OrderInterface : 62,	OrderSorting : 52 },

		ReleaseTypeVod			: { OrderInterface : 63,	OrderSorting : 57 },
		ReleaseTypeVodRip		: { OrderInterface : 64,	OrderSorting : 58 },

		ReleaseTypePpv			: { OrderInterface : 65,	OrderSorting : 49 },
		ReleaseTypePpvRip		: { OrderInterface : 66,	OrderSorting : 50 },

		ReleaseTypeDcp			: { OrderInterface : 67,	OrderSorting : 59 },
		ReleaseTypeDcpRip		: { OrderInterface : 68,	OrderSorting : 60 },

		ReleaseTypePdtv			: { OrderInterface : 69,	OrderSorting : 61 },
		ReleaseTypePdtvRip		: { OrderInterface : 70,	OrderSorting : 62 },

		ReleaseTypeSat			: { OrderInterface : 71,	OrderSorting : 63 },
		ReleaseTypeSatRip		: { OrderInterface : 72,	OrderSorting : 64 },

		ReleaseTypeDs			: { OrderInterface : 73,	OrderSorting : 65 },
		ReleaseTypeDsRip		: { OrderInterface : 74,	OrderSorting : 66 },

		ReleaseTypeDth			: { OrderInterface : 75,	OrderSorting : 67 },
		ReleaseTypeDthRip		: { OrderInterface : 76,	OrderSorting : 68 },

		ReleaseTypeDvb			: { OrderInterface : 77,	OrderSorting : 69 },
		ReleaseTypeDvbRip		: { OrderInterface : 78,	OrderSorting : 70 },

		ReleaseTypeDtv			: { OrderInterface : 79,	OrderSorting : 71 },
		ReleaseTypeDtvRip		: { OrderInterface : 80,	OrderSorting : 72 },

		ReleaseTypeIptv			: { OrderInterface : 81,	OrderSorting : 73 },
		ReleaseTypeIptvRip		: { OrderInterface : 82,	OrderSorting : 74 },

		ReleaseTypeAhdtv		: { OrderInterface : 83,	OrderSorting : 75 },
		ReleaseTypeAhdtvRip		: { OrderInterface : 84,	OrderSorting : 76 },

		ReleaseTypeVhs			: { OrderInterface : 85,	OrderSorting : 93 },
		ReleaseTypeVhsRip		: { OrderInterface : 86,	OrderSorting : 94 },

		ReleaseTypeDvhs			: { OrderInterface : 87,	OrderSorting : 91 },
		ReleaseTypeDvhsRip		: { OrderInterface : 88,	OrderSorting : 92 },

		ReleaseTypeVcd			: { OrderInterface : 89,	OrderSorting : 89 },
		ReleaseTypeVcdRip		: { OrderInterface : 90,	OrderSorting : 90 },

		ReleaseTypeCvcd			: { OrderInterface : 91,	OrderSorting : 87 },
		ReleaseTypeCvcdRip		: { OrderInterface : 92,	OrderSorting : 88 },

		ReleaseTypeXvcd			: { OrderInterface : 93,	OrderSorting : 85 },
		ReleaseTypeXvcdRip		: { OrderInterface : 94,	OrderSorting : 86 },

		ReleaseTypeDvcd			: { OrderInterface : 95,	OrderSorting : 83 },
		ReleaseTypeDvcdRip		: { OrderInterface : 96,	OrderSorting : 84 },

		ReleaseTypeSvcd			: { OrderInterface : 97,	OrderSorting : 81 },
		ReleaseTypeSvcdRip		: { OrderInterface : 98,	OrderSorting : 82 },

		ReleaseTypeKvcd			: { OrderInterface : 99,	OrderSorting : 79 },
		ReleaseTypeKvcdRip		: { OrderInterface : 100,	OrderSorting : 80 },

		ReleaseTypeSkvcd		: { OrderInterface : 101,	OrderSorting : 77 },
		ReleaseTypeSkvcdRip		: { OrderInterface : 102,	OrderSorting : 78 },

		ReleaseTypeLd			: { OrderInterface : 103,	OrderSorting : 47 },
		ReleaseTypeLdRip		: { OrderInterface : 104,	OrderSorting : 48 },

		ReleaseTypeR1			: { OrderInterface : 105,	OrderSorting : 38 },
		ReleaseTypeR1Rip		: { OrderInterface : 106,	OrderSorting : 46 },
		ReleaseTypeR2			: { OrderInterface : 107,	OrderSorting : 37 },
		ReleaseTypeR2Rip		: { OrderInterface : 108,	OrderSorting : 45 },
		ReleaseTypeR3			: { OrderInterface : 109,	OrderSorting : 36 },
		ReleaseTypeR3Rip		: { OrderInterface : 110,	OrderSorting : 44 },
		ReleaseTypeR4			: { OrderInterface : 111,	OrderSorting : 35 },
		ReleaseTypeR4Rip		: { OrderInterface : 112,	OrderSorting : 43 },
		ReleaseTypeR5			: { OrderInterface : 113,	OrderSorting : 34 },
		ReleaseTypeR5Rip		: { OrderInterface : 114,	OrderSorting : 42 },
		ReleaseTypeR6			: { OrderInterface : 115,	OrderSorting : 33 },
		ReleaseTypeR6Rip		: { OrderInterface : 116,	OrderSorting : 41 },
		ReleaseTypeR7			: { OrderInterface : 117,	OrderSorting : 32 },
		ReleaseTypeR7Rip		: { OrderInterface : 118,	OrderSorting : 40 },
		ReleaseTypeR8			: { OrderInterface : 119,	OrderSorting : 31 },
		ReleaseTypeR8Rip		: { OrderInterface : 120,	OrderSorting : 39 },
	}

	##############################################################################
	# RELEASE FORMAT
	##############################################################################

	# https://www.reddit.com/r/Piracy/comments/9r54lr/what_does_proper_and_repack_mean/
	# https://en.wikipedia.org/wiki/Pirated_movie_release_types
	# https://en.wikipedia.org/wiki/Talk%3APirated_movie_release_types
	# http://www.dslreports.com/faq/10705
	# https://whereyouwatch.com/articles/ultimate-guide-to-movie-piracy-termonology/
	# https://www.reddit.com/r/Piracy/comments/curbjk/what_does_internal_mean/
	# https://scenelingo.wordpress.com/2008/07/16/what-does-internal-mean/
	# https://scenelingo.wordpress.com/2012/06/17/what-does-dirfix-mean/
	# https://scenelingo.wordpress.com/2015/09/09/what-does-remux-mean/

	ReleaseFormatRemaster	= 'remaster'	# Changing the quality of the video and/or audio.
	ReleaseFormatRestore	= 'restore'		# Restored video and/or audio from old or corrupted media.
	ReleaseFormatRepack		= 'repack'		# Previous release had problems and the SAME release group re-released a fixed version.
	ReleaseFormatRerip		= 'rerip'		# Similar to repack. Repack handles packing issues. Rerip handles ripping issues.
	ReleaseFormatReencode	= 'reencode'	# Renecoded from another source, typically to a smaller size.
	ReleaseFormatRegrade	= 'regrade'		# Color grading is improving the appearance of an image for presentation in different environments on different devices
	ReleaseFormatRemux		= 'remux'		# Creating a new ontainer with the original video and audio, but all extras, commentary, menus, and deleted scenes were removed.
	ReleaseFormatProper		= 'proper'		# Previous release had problems and ANOTHER release group re-released a fixed version.
	ReleaseFormatInternal	= 'internal'	# Release only for internal use of the release group or the members of their website.
	ReleaseFormatUncut		= 'uncut'		# Unedited version before release. Might miss or have extra material not part of the final theatrical release.
	ReleaseFormatUntouched	= 'untouched'	# Untouched release.
	ReleaseFormatReal		= 'real'		# Not sure what this means.
	ReleaseFormatMatte		= 'matte'		# Open matte involves matting out the top and bottom of the film frame.
	ReleaseFormatAi			= 'ai'			# Used AI inference software.
	ReleaseFormatInterlace	= 'interlace'	# Picture will appear wavy to the trained eye.
	ReleaseFormatUpscale	= 'upscale'		# Video quality upscaled from a lower to a higher quality.
	ReleaseFormatDownscale	= 'downscale'	# Video quality downscaled from a higher to a lower quality.
	ReleaseFormatDirfix		= 'dirfix'		# Typo or inaccuracy is detected in the original release name.
	ReleaseFormatSyncfix	= 'syncfix'		# Fixed video and audio synchronization errors.
	ReleaseFormatRarfix		= 'rarfix'		# RAR archive corruption fixed.
	ReleaseFormatNfofix		= 'nfofix'		# NFO file updated.
	ReleaseFormatFix		= 'fix'			# General fix.
	ReleaseFormatEdit		= 'edit'		# General edit.
	ReleaseFormatDuplicate	= 'duplicate'	# Duplicate release.
	ReleaseFormatWatermark	= 'watermark'	# Contains watermarks.
	ReleaseFormatNuke		= 'nuke'		# Release was nuked/deleted because of major problems. Often followed by a repack/proper/rerip.
	ReleaseFormatNone		= None

	ReleaseFormatOriginal	= 'original'	# Internal use for Emby/Jellyfin.
	ReleaseFormatTranscoded	= 'transcoded'	# Internal use for Emby/Jellyfin.

	ExpressionReleaseFormat = {
		'keyword' : {
			're'		: 're{separator}*',
			'fix'		: '{separator}*fix(?:ed?)?',
			'scale'		: 'scal(?:ed?|ing)',
			'restore'	: '{re}stor(?:ed|ation)',
			'color'		: 'colou?rs?',
		},

		'expression' : (
		 	# Is often combined with other keywords (eg: repack/rerip). Place first, since it is more important than other formats.
			(ReleaseFormatInternal,		u'(internal)'),
			(ReleaseFormatUpscale,		u'((?:ai)?up{separator}*{scale}|{scale}{separator}*up)'),
			(ReleaseFormatDownscale,	u'(ds4k|down{separator}*{scale}|{scale}{separator}*down)'),
			(ReleaseFormatMatte,		u'(open{separator}*matted?)'),
			(ReleaseFormatAi,			u'(ai|artificial{separator}*intelligence)'),
			(ReleaseFormatWatermark,	u'((?<!{symbol}no{separator})(?<!{symbol}no)(?<!{symbol}un{separator})(?<!{symbol}un)(?<!{symbol}de{separator})(?<!{symbol}de)(?<!{symbol}without{separator})(?<!{symbol}without)(?<!{symbol}and{separator})(?<!{symbol}and)(?<![@&\+]{separator})(?<![@&\+])watermark(?:ed|s)?)(?!less)(?!free)(?!{separator}free)'),

			(ReleaseFormatRemux,		u'(web(?:dl)?|(?:hd)?(?:dvd|tv)(?:rip)?|bluray|b[dr](?:rip)?|hd|avc|hevc|dl)?(?:rmx|(?:re)?mux(?:ed|ing)?)(?:dl|hd|b[dr])?'),
			(ReleaseFormatReencode,		u'({re}enc(?:oded?)?)'),
			(ReleaseFormatRegrade,		u'({re}graded?|{color}{separator}*(?:{restore}|{fix}|fx)|(?:{restore}|{fix}){separator}*{color})'),
			(ReleaseFormatRemaster,		u'(rm4k|{re}master(?:ed)?)'),
			(ReleaseFormatRestore,		u'({restore})'),
			(ReleaseFormatRerip,		u'({re}rip(?:ped)?)'),
			(ReleaseFormatRepack,		u'(?:{fix}{separator}*(?:only{separator}*)?)?({re}pack(?:age?)?(?:ed)?)'),
			(ReleaseFormatUncut,		u'(uncut|ungeschnittene?)'),
			(ReleaseFormatUntouched,	u'(untouch(?:ed)?)'),
			(ReleaseFormatProper,		u'((?:final)?proper)'),

			(ReleaseFormatDuplicate,	u'(dupe|duplicate[ds]?)'),
			(ReleaseFormatNuke,			u'(nuked?)'),

			(ReleaseFormatDirfix,		u'(dir{fix})'),
			(ReleaseFormatSyncfix,		u'(sync{fix})'),
			(ReleaseFormatRarfix,		u'(rar{fix})'),
			(ReleaseFormatNfofix,		u'(i?nfo{fix})'),
			(ReleaseFormatFix,			u'({fix})'),

			# Do last, since it is the least common and/or often combined with other keywords.
			(ReleaseFormatEdit,			u'(edited)'),
			(ReleaseFormatReal,			u'(real)'),
			(ReleaseFormatInterlace,	u'((?:de{separator}*)?interlaced?)'),
		),
	}

	LabelReleaseFormat = {
		LabelDefault : {
			LabelList1		: LabelMedium,
			LabelList2		: LabelShort,
			LabelList3		: LabelShort,
			LabelList4		: LabelHidden,
			LabelInfo1		: LabelShort,
			LabelInfo2		: LabelMedium,
			LabelSettings1	: LabelMedium,
			LabelSettings2	: LabelShort,
		},

		ReleaseFormatRemaster		: { LabelShort : 'REM',		LabelMedium : 'REMASTERED',		LabelLong : 'Remastered Release' },
		ReleaseFormatRestore		: { LabelShort : 'RES',		LabelMedium : 'RESTORED',		LabelLong : 'Restored Release' },
		ReleaseFormatRepack			: { LabelShort : 'REP',		LabelMedium : 'REPACKED',		LabelLong : 'Repacked Release' },
		ReleaseFormatRerip			: { LabelShort : 'RER',		LabelMedium : 'RERIPPED',		LabelLong : 'Reripped Release' },
		ReleaseFormatReencode		: { LabelShort : 'REE',		LabelMedium : 'REENCODED',		LabelLong : 'Reencoded Release' },
		ReleaseFormatRegrade		: { LabelShort : 'REG',		LabelMedium : 'REGRADED',		LabelLong : 'Regraded Release' },
		ReleaseFormatRemux			: { LabelShort : 'REM',		LabelMedium : 'REMUXED',		LabelLong : 'Remuxed Release' },
		ReleaseFormatProper			: { LabelShort : 'PRO',		LabelMedium : 'PROPER',			LabelLong : 'Proper Release' },
		ReleaseFormatInternal		: { LabelShort : 'INT',		LabelMedium : 'INTERNAL',		LabelLong : 'Internal Release' },
		ReleaseFormatUncut			: { LabelShort : 'UNC',		LabelMedium : 'UNCUT',			LabelLong : 'Uncut Release' },
		ReleaseFormatUntouched		: { LabelShort : 'UNT',		LabelMedium : 'UNTOUCHED',		LabelLong : 'Untouched Release' },
		ReleaseFormatReal			: { LabelShort : 'REA',		LabelMedium : 'REAL',			LabelLong : 'Real Release' },
		ReleaseFormatMatte			: { LabelShort : 'MAT',		LabelMedium : 'MATTE',			LabelLong : 'Open Matte Release' },
		ReleaseFormatAi				: { LabelShort : 'AI',		LabelMedium : 'AI',				LabelLong : 'Artificial Intelligence Release' },
		ReleaseFormatInterlace		: { LabelShort : 'INL',		LabelMedium : 'INTERLANCED',	LabelLong : 'Interlaced Release' },
		ReleaseFormatUpscale		: { LabelShort : 'UPS',		LabelMedium : 'UPSCALED',		LabelLong : 'Upscaled Quality Release' },
		ReleaseFormatDownscale		: { LabelShort : 'DWS',		LabelMedium : 'DOWNSCALED',		LabelLong : 'Downscaled Quality Release' },
		ReleaseFormatDirfix			: { LabelShort : 'DIF',		LabelMedium : 'DIRFIXED',		LabelLong : 'Dir Fixed Release' },
		ReleaseFormatSyncfix		: { LabelShort : 'SYF',		LabelMedium : 'SYNCFIXED',		LabelLong : 'Sync Fixed Release' },
		ReleaseFormatRarfix			: { LabelShort : 'RAF',		LabelMedium : 'RARFIXED',		LabelLong : 'RAR Fixed Release' },
		ReleaseFormatNfofix			: { LabelShort : 'NFF',		LabelMedium : 'NFOFIXED',		LabelLong : 'NFO Fixed Release' },
		ReleaseFormatFix			: { LabelShort : 'FIX',		LabelMedium : 'FIXED',			LabelLong : 'Fixed Release' },
		ReleaseFormatEdit			: { LabelShort : 'EDT',		LabelMedium : 'EDITED',			LabelLong : 'Edited Release' },
		ReleaseFormatDuplicate		: { LabelShort : 'DUP',		LabelMedium : 'DUPLICCATE',		LabelLong : 'Duplicate Release' },
		ReleaseFormatWatermark		: { LabelShort : 'WAM',		LabelMedium : 'WATERMARKED',	LabelLong : 'Watermarked Release' },
		ReleaseFormatNuke			: { LabelShort : 'NUK',		LabelMedium : 'NUKED',			LabelLong : 'Nuked Release' },

		ReleaseFormatOriginal		: { LabelShort : 'ORI',		LabelMedium : 'ORIGINAL',		LabelLong : 'Original Release' },
		ReleaseFormatTranscoded		: { LabelShort : 'TRC',		LabelMedium : 'TRANSCODED',		LabelLong : 'Transcoded Release' },
	}

	OrderReleaseFormat = {
		ReleaseFormatRemaster		: { OrderInterface : 1,		OrderSorting : 1 },
		ReleaseFormatRestore		: { OrderInterface : 2,		OrderSorting : 2 },
		ReleaseFormatRepack			: { OrderInterface : 3,		OrderSorting : 3 },
		ReleaseFormatRerip			: { OrderInterface : 4,		OrderSorting : 4 },
		ReleaseFormatReencode		: { OrderInterface : 5,		OrderSorting : 5 },
		ReleaseFormatRegrade		: { OrderInterface : 6,		OrderSorting : 6 },
		ReleaseFormatRemux			: { OrderInterface : 7,		OrderSorting : 7 },
		ReleaseFormatProper			: { OrderInterface : 8,		OrderSorting : 8 },
		ReleaseFormatInternal		: { OrderInterface : 9,		OrderSorting : 9 },
		ReleaseFormatUncut			: { OrderInterface : 10,	OrderSorting : 10 },
		ReleaseFormatUntouched		: { OrderInterface : 11,	OrderSorting : 11 },
		ReleaseFormatReal			: { OrderInterface : 12,	OrderSorting : 12 },
		ReleaseFormatMatte			: { OrderInterface : 13,	OrderSorting : 13 },
		ReleaseFormatAi				: { OrderInterface : 14,	OrderSorting : 14 },
		ReleaseFormatInterlace		: { OrderInterface : 15,	OrderSorting : 15 },
		ReleaseFormatUpscale		: { OrderInterface : 16,	OrderSorting : 16 },
		ReleaseFormatDownscale		: { OrderInterface : 17,	OrderSorting : 17 },
		ReleaseFormatDirfix			: { OrderInterface : 18,	OrderSorting : 18 },
		ReleaseFormatSyncfix		: { OrderInterface : 19,	OrderSorting : 19 },
		ReleaseFormatRarfix			: { OrderInterface : 20,	OrderSorting : 20 },
		ReleaseFormatNfofix			: { OrderInterface : 21,	OrderSorting : 21 },
		ReleaseFormatFix			: { OrderInterface : 22,	OrderSorting : 22 },
		ReleaseFormatEdit			: { OrderInterface : 23,	OrderSorting : 23 },
		ReleaseFormatDuplicate		: { OrderInterface : 24,	OrderSorting : 24 },
		ReleaseFormatWatermark		: { OrderInterface : 25,	OrderSorting : 25 },
		ReleaseFormatNuke			: { OrderInterface : 26,	OrderSorting : 26 },

		ReleaseFormatOriginal		: { OrderInterface : 27,	OrderSorting : 27 },
		ReleaseFormatTranscoded		: { OrderInterface : 28,	OrderSorting : 28 },
	}

	##############################################################################
	# RELEASE EDITION
	##############################################################################

	ReleaseEditionCollector		= 'collector'	# Collector's Edition
	ReleaseEditionDirector		= 'director'	# Director's Cut
	ReleaseEditionCommentary	= 'commentary'	# Commentary
	ReleaseEditionMaking		= 'making'		# Making Of and Behind The Scenes
	ReleaseEditionExtended		= 'extended'	# Extended Version
	ReleaseEditionSpecial		= 'special'		# Special Version
	ReleaseEditionSuper			= 'super'		# Super Version
	ReleaseEditionDefinitive	= 'definitive'	# Definitive Edition
	ReleaseEditionUltimate		= 'ultimate'	# Ultimate Cut
	ReleaseEditionLimited		= 'limited'		# Limited Edition
	ReleaseEditionUncensored	= 'uncensored'	# Uncensored/Unrated Edition
	ReleaseEditionAlternative	= 'alternative'	# Alternative Edition
	ReleaseEditionFan			= 'fan'			# Fan Edit Edition
	ReleaseEditionTheatrical	= 'theatrical'	# Theatrical Version
	ReleaseEditionRetail		= 'retail'		# Retail Edition
	ReleaseEditionFestival		= 'festival'	# Festival Edition
	ReleaseEditionRetro			= 'retro'		# Retro Edition
	ReleaseEditionImax			= 'imax'		# IMAX Edition
	ReleaseEditionNone			= None

	# NB: Do not use [eé], since it does not match (maybe Python cannot mix ASCII and UTF inside [] brackets). This should now work, since all expressions are in unicode. But we also want to match "e\?" which is 2 characters and requires (?:..) anyways.
	ExpressionReleaseEdition = {
		'keyword' : {
			'apostrophe'	: u'(?:.s{separator}|\\\?(?:\.|\'|\`|.?\xB4)?s?)?',
			'version'		: u'(?:(?:e|é|e\?)di?(?:t(?:ions?)?|(?:c|ç|\?)(?:a|ã|a\?)o|zione|ci(?:o|ó|o\?)n|tie)|ver(?:(?:si(?:o|ó|o\?)n[es]?)?|versi[jy]a|s(?:a|ã|a\?)o|sie)|set|box|releases?|(?:un)?cut|cortar|ausführung|auflage|schnitt|fassung|версия|издание)s?',
			'extra'			: u'ece?',
			'standalone'	: u'(?:(?:(?:e)?xtend(?:ed)?|ext{separator}*(?:ed)?)|ece?|s?ee|collect(?:or|ion)|direc?tora?|limit(?:ed)?|ltd)',
			'item'			: u'(?:{separator}*{version})?',
		},

		# (?:(?<!\.)se|\.se(?:\.|$)) - Exclude TLDs: Tenet [TS][Castellano][wWw.EliteTorrent.SE]
		'expression' : (
			(ReleaseEditionImax,		u'((?:digital)?imax(?:3d|hd|vr|dome|shift|digital)?)'), # Do not test with a separator in between, since this could remove the 3d/hd/digital keywords used by other extractors ("imax 3d-sbs" the 3d is removed in the cleaning function when imax is detected).
			(ReleaseEditionCommentary,	u'((?:comm?ent(?:ary|s|o|aar|(?:a|á)rios?)?|kommentare?|комментарий){apostrophe}{item})'),
			(ReleaseEditionMaking,		u'((?:making?(?:{separator}*of)?|behind{separator}*(?:the{separator}*)?scenes?){apostrophe}{item})'),
			(ReleaseEditionFan,			u'((?:fan(?:ats)?|custom|edited){separator}*(?:(?:e)?xtend(?:ed)?|ext(?:ed)?)?{separator}*(?:edit|made|{version}))'),
			(ReleaseEditionExtended,	u'((?:(?:e)?xtend(?:ed)?|extened|ext(?:ed)?){apostrophe}{item}|ece?|s?ee|(?:e|é|e\?)largie|esteso|(?:(?:v\.?|{version}){separator}*)?e[sx]tendid[ao]|verlängert|verlengd|расширенн(?:ый|ая)|rasshirenna[jy]a|long(?:ue)?{separator}*{version}|{version}{separator}*long(?:ue)?)'), # Match before others, because it is used in connection with others (eg: "Extended Collector's Edition", "Extended Director's Cut"). And we rather want it to be labeled as "Extended" instead of eg "Collector".
			(ReleaseEditionCollector,	u'((?:((?<!\.)s?ce|\.s?ce(?:\.|$))|col(?:lect[eo]r)?|(?:de{separator})?colec(?:ionadora?|cionista)|colle(?:ttrice|ctionneuse)|kollektor|sammler){apostrophe}{item})'), # Do not match "collection", since this will match for some show/season packs.
			(ReleaseEditionDirector,	u'((?:direc?tora?|dc(?!{separator}*(?:universe|comics?))|direttrice|r(?:e|é|e\?)alisatrice|regisseur|директор){apostrophe}{item})'),
			(ReleaseEditionTheatrical,	u'(theatr(?:e|ical){apostrophe}{item})'),
			(ReleaseEditionSpecial,		u'((?:(?:xmas|christmas|holiday){separator}*)?(?:(?:(?<!\.)se|\.se(?:\.|$)|e?sp(?:e|é|e\?)ciale?s?|exclusive|sonder|специальный|Эксклюзивная){apostrophe}{item}))'),
			(ReleaseEditionSuper,		u'(super(?:{separator}*duper|fan))'), # Super Duper: Deadpool, Superfan: Avatar
			(ReleaseEditionUltimate,	u'((?:ultimat(?:e|iv)|ultieme|(?:ú|u)ltim[ao]|definitiv[ao]|última){apostrophe}{item})'),
			(ReleaseEditionDefinitive,	u'(definitive)'),
			(ReleaseEditionUncensored,	u'(unrated?|uncensor(?:ed)?)'),
			(ReleaseEditionAlternative,	u'(alternat(?:e|ive))'),
			(ReleaseEditionFestival,	u'(festival)'),
			(ReleaseEditionRetail,		u'(retail{apostrophe}{item})'),
			(ReleaseEditionLimited,		u'((?:limit(?:ed)?|ltd){apostrophe}{item})'), # Do last, since it is often used in combination with other editions (eg: limited extended, or limited retail).
			(ReleaseEditionRetro,		u'(retro){separator}*{version}'),
		),
	}

	LabelReleaseEdition = {
		LabelDefault : {
			LabelList1		: LabelMedium,
			LabelList2		: LabelShort,
			LabelList3		: LabelShort,
			LabelList4		: LabelShort,
			LabelInfo1		: LabelLong,
			LabelInfo2		: LabelHidden,
			LabelSettings1	: LabelLong,
			LabelSettings2	: LabelShort,
		},

		ReleaseEditionCollector		: { LabelShort : 'COL',		LabelMedium : 'Collector',		LabelLong : 'Collector\'s Edition' },
		ReleaseEditionDirector		: { LabelShort : 'DIR',		LabelMedium : 'Director',		LabelLong : 'Director\'s Edition' },
		ReleaseEditionCommentary	: { LabelShort : 'COM',		LabelMedium : 'Commentary',		LabelLong : 'Commentary Edition' },
		ReleaseEditionMaking		: { LabelShort : 'MAK',		LabelMedium : 'Making',			LabelLong : 'Making Of Edition' },
		ReleaseEditionExtended		: { LabelShort : 'EXT',		LabelMedium : 'Extended',		LabelLong : 'Extended Edition' },
		ReleaseEditionSpecial		: { LabelShort : 'SPE',		LabelMedium : 'Special',		LabelLong : 'Special Edition' },
		ReleaseEditionSuper			: { LabelShort : 'SUP',		LabelMedium : 'Super',			LabelLong : 'Super Edition' },
		ReleaseEditionDefinitive	: { LabelShort : 'DEF',		LabelMedium : 'Definitive',		LabelLong : 'Definitive Edition' },
		ReleaseEditionUltimate		: { LabelShort : 'ULT',		LabelMedium : 'Ultimate',		LabelLong : 'Ultimate Edition' },
		ReleaseEditionLimited		: { LabelShort : 'LTD',		LabelMedium : 'Limited',		LabelLong : 'Limited Edition' },
		ReleaseEditionUncensored	: { LabelShort : 'UNC',		LabelMedium : 'Uncensored',		LabelLong : 'Uncensored Edition' },
		ReleaseEditionAlternative	: { LabelShort : 'ALT',		LabelMedium : 'Alternative',	LabelLong : 'Alternative Edition' },
		ReleaseEditionFan			: { LabelShort : 'FAN',		LabelMedium : 'Fan',			LabelLong : 'Fan Edit Edition' },
		ReleaseEditionTheatrical	: { LabelShort : 'THE',		LabelMedium : 'Theatrical',		LabelLong : 'Theatrical Edition' },
		ReleaseEditionRetail		: { LabelShort : 'RET',		LabelMedium : 'Retail',			LabelLong : 'Retail Edition' },
		ReleaseEditionFestival		: { LabelShort : 'FSV',		LabelMedium : 'Festival',		LabelLong : 'Festival Edition' },
		ReleaseEditionRetro			: { LabelShort : 'RTR',		LabelMedium : 'Retro',			LabelLong : 'Retro Edition' },
		ReleaseEditionImax			: { LabelShort : 'IMX',		LabelMedium : 'IMAX',			LabelLong : 'IMAX Edition' },
	}

	OrderReleaseEdition = {
		ReleaseEditionCollector		: { OrderInterface : 2,		OrderSorting : 2 },
		ReleaseEditionDirector		: { OrderInterface : 1,		OrderSorting : 1 },
		ReleaseEditionCommentary	: { OrderInterface : 17,	OrderSorting : 17 },
		ReleaseEditionMaking		: { OrderInterface : 18,	OrderSorting : 18 },
		ReleaseEditionExtended		: { OrderInterface : 3,		OrderSorting : 3 },
		ReleaseEditionSpecial		: { OrderInterface : 4,		OrderSorting : 4 },
		ReleaseEditionSuper			: { OrderInterface : 5,		OrderSorting : 5 },
		ReleaseEditionDefinitive	: { OrderInterface : 11,	OrderSorting : 11 },
		ReleaseEditionUltimate		: { OrderInterface : 6,		OrderSorting : 6 },
		ReleaseEditionLimited		: { OrderInterface : 7,		OrderSorting : 7 },
		ReleaseEditionUncensored	: { OrderInterface : 8,		OrderSorting : 8 },
		ReleaseEditionAlternative	: { OrderInterface : 10,	OrderSorting : 10 },
		ReleaseEditionFan			: { OrderInterface : 9,		OrderSorting : 9 },
		ReleaseEditionTheatrical	: { OrderInterface : 13,	OrderSorting : 13 },
		ReleaseEditionRetail		: { OrderInterface : 14,	OrderSorting : 14 },
		ReleaseEditionFestival		: { OrderInterface : 15,	OrderSorting : 15 },
		ReleaseEditionRetro			: { OrderInterface : 16,	OrderSorting : 16 },
		ReleaseEditionImax			: { OrderInterface : 12,	OrderSorting : 12 },
	}

	##############################################################################
	# RELEASE NETWORK
	##############################################################################

	# https://en.wikipedia.org/wiki/Pirated_movie_release_types
	# https://en.wikipedia.org/wiki/List_of_streaming_media_services#References
	# We combine networks into one, otherwise there are just too many, and more to come in the future.
	# Eg: HBO Max/Now/Go, YouTube Premium/TV, Disney normal/+/hotstar, etc.

	# General
	ReleaseNetwork7pls	= '7pls'	# 7plus
	ReleaseNetwork9now	= '9now'	# 9Now
	ReleaseNetwork10py	= '10py'	# 10Play
	ReleaseNetworkAbc	= 'abc'		# American Broadcasting Company (same abbreviation used for "Australian Broadcasting Corporation" and "Asahi Broadcasting Corporation")
	ReleaseNetworkAha	= 'aha'		# Aha
	ReleaseNetworkAmc	= 'amc'		# American Movie Classics
	ReleaseNetworkAmzn	= 'amzn'	# Amazon
	ReleaseNetworkAppl	= 'appl'	# Apple TV+
	ReleaseNetworkArd	= 'ard'		# Erstes Deutsches Fernsehen
	ReleaseNetworkAtbj	= 'atbj'	# ALTBalaji
	ReleaseNetworkAtrs	= 'atrs'	# Atresplayer / Atresmedia
	ReleaseNetworkAtsm	= 'atsm'	# Adult Swim
	ReleaseNetworkAubc	= 'aubc'	# Australian Broadcasting Corporation
	ReleaseNetworkBbc	= 'bbc'		# British Broadcasting Corporation
	ReleaseNetworkBmrg	= 'bmrg'	# Boomerang
	ReleaseNetworkBms	= 'bms'		# BookMyShow
	ReleaseNetworkBnge	= 'bnge'	# Binge
	ReleaseNetworkBtbx	= 'btbx'	# BritBox
	ReleaseNetworkCbc	= 'cbc'		# Canadian Broadcasting Corporation / CBC Gem
	ReleaseNetworkCbs	= 'cbs'		# Columbia Broadcasting System
	ReleaseNetworkCh4	= 'ch4'		# Channel 4
	ReleaseNetworkCh5	= 'ch5'		# Channel 5
	ReleaseNetworkClro	= 'clro'	# Claro Video
	ReleaseNetworkCnmx	= 'cnmx'	# Cinemax (part of and owned by HBO)
	ReleaseNetworkCrtn	= 'crtn'	# The Criterion Collection
	ReleaseNetworkCrve	= 'crve'	# Crave
	ReleaseNetworkCtnw	= 'ctnw'	# Cartoon Network
	ReleaseNetworkCycl	= 'cycl'	# Comedy Central
	ReleaseNetworkDazn	= 'dazn'	# DAZN
	ReleaseNetworkDcu	= 'dcu'		# DC Universe
	ReleaseNetworkDscy	= 'dscy'	# Discovery Plus/Channel / DMAX
	ReleaseNetworkDsny	= 'dsny'	# Disney Networks Channel/XD/Junior/+
	ReleaseNetworkEpix	= 'epix'	# Epix (now MGM+)
	ReleaseNetworkEros	= 'eros'	# Eros Now
	ReleaseNetworkEspn	= 'espn'	# ESPN
	ReleaseNetworkFbwh	= 'fbwh'	# Facebook Watch
	ReleaseNetworkFox	= 'fox'		# Fox Broadcasting Company
	ReleaseNetworkFrfm	= 'frfm'	# Freeform (part of ABC and Disney)
	ReleaseNetworkFubo	= 'fubo'	# FuboTV
	ReleaseNetworkFxtl	= 'fxtl'	# Foxtel
	ReleaseNetworkGala	= 'gala'	# GagaOOLala
	ReleaseNetworkGlbo	= 'glbo'	# Globoplay and Rede Globo
	ReleaseNetworkGogl	= 'gogl'	# Google Play
	ReleaseNetworkHbo	= 'hbo'		# HBO Max/Now/Go
	ReleaseNetworkHngm	= 'hngm'	# Hungama Play
	ReleaseNetworkHsty	= 'hsty'	# History Channel
	ReleaseNetworkHtsr	= 'htsr'	# Hotstar (now Disney+ Hotstar, but was previously not part of Disney)
	ReleaseNetworkHulu	= 'hulu'	# Hulu
	ReleaseNetworkIfc	= 'ifc'		# Independent Film Channel
	ReleaseNetworkIflx	= 'iflx'	# iflix
	ReleaseNetworkIplr	= 'iplr'	# BBC iPlayer
	ReleaseNetworkIqyi	= 'iqyi'	# iQIYI
	ReleaseNetworkItns	= 'itns'	# iTunes
	ReleaseNetworkItv	= 'itv'		# Independent Television
	ReleaseNetworkIviw	= 'iviw'	# ABC iview
	ReleaseNetworkIwtc	= 'iwtc'	# iWantTFC
	ReleaseNetworkJio	= 'jio'		# Jio TV/Cinema
	ReleaseNetworkLftm	= 'lftm'	# Lifetime
	ReleaseNetworkLngt	= 'lngt'	# Lionsgate +/Play (previously Starzplay)
	ReleaseNetworkMgm	= 'mgm'		# MGM+
	ReleaseNetworkMnrm	= 'mnrm'	# ManoramaMAX
	ReleaseNetworkMtv	= 'mtv'		# MTV Networks
	ReleaseNetworkMubi	= 'mubi'	# Mubi
	ReleaseNetworkMvar	= 'mvar'	# Movies Anywhere
	ReleaseNetworkMy5	= 'my5'		# My5
	ReleaseNetworkMytv	= 'mytv'	# myTV
	ReleaseNetworkNbc	= 'nbc'		# National Broadcasting Company
	ReleaseNetworkNckn	= 'nckn'	# Nickelodeon
	ReleaseNetworkNlgc	= 'nlgc'	# National Geographic
	ReleaseNetworkNow	= 'now'		# NOW
	ReleaseNetworkNrk	= 'nrk'		# Norwegian Broadcasting Corporation
	ReleaseNetworkNtfx	= 'ntfx'	# Netflix
	ReleaseNetworkPbs	= 'pbs'		# PBS
	ReleaseNetworkPcok	= 'pcok'	# Peacock
	ReleaseNetworkPrmt	= 'prmt'	# Paramount Plus
	ReleaseNetworkRktn	= 'rktn'	# Rakuten TV
	ReleaseNetworkRlbp	= 'rlbp'	# Royal Bioscope
	ReleaseNetworkRoku	= 'roku'	# Roku
	ReleaseNetworkRte	= 'rte'		# Raidió Teilifís Éireann
	ReleaseNetworkSana	= 'sana'	# Saina Play
	ReleaseNetworkSbs	= 'sbs'		# Special Broadcasting Service
	ReleaseNetworkShdr	= 'shdr'	# AMC Shudder
	ReleaseNetworkShid	= 'shid'	# Shahid
	ReleaseNetworkShwt	= 'shwt'	# Showtime
	ReleaseNetworkSky	= 'sky'		# Sky
	ReleaseNetworkSnxt	= 'snxt'	# Sun NXT
	ReleaseNetworkSony	= 'sony'	# Sony Pictures Core (formerly Bravia Core)
	ReleaseNetworkStan	= 'stan'	# Stan
	ReleaseNetworkStrz	= 'strz'	# Starz
	ReleaseNetworkStv	= 'stv'		# Scottish Television
	ReleaseNetworkSyfy	= 'syfy'	# SyFy
	ReleaseNetworkSysh	= 'sysh'	# Simply South
	ReleaseNetworkTbs	= 'tbs'		# Turner Broadcasting System
	ReleaseNetworkTcw	= 'tcw'		# The CW Network
	ReleaseNetworkTf1	= 'tf1'		# TF1 Network
	ReleaseNetworkTnct	= 'tnct'	# Tencent Video
	ReleaseNetworkTnkt	= 'tnkt'	# Tentkotta
	ReleaseNetworkTnt	= 'tnt'		# Turner Network Television
	ReleaseNetworkTubi	= 'tubi'	# Tubi
	ReleaseNetworkTvng	= 'tvng'	# TVING
	ReleaseNetworkTvnz	= 'tvnz'	# Television New Zealand
	ReleaseNetworkUsa	= 'usa'		# USA Network
	ReleaseNetworkVh1	= 'vh1'		# VH1
	ReleaseNetworkVido	= 'vido'	# Vidio
	ReleaseNetworkVimx	= 'vimx'	# Vivamax
	ReleaseNetworkVipy	= 'vipy'	# Viaplay
	ReleaseNetworkViu	= 'viu'		# Viu
	ReleaseNetworkWetv	= 'wetv'	# WeTV (there are different WeTV: Tencent/iflix WeTV, AMC We Tv+)
	ReleaseNetworkWtch	= 'wtch'	# Watcha
	ReleaseNetworkYoku	= 'yoku'	# Youku
	ReleaseNetworkYtb	= 'ytb'		# YouTube TV/Premium (formerly Red)
	ReleaseNetworkZee	= 'zee'		# ZEE5
	ReleaseNetworkZdf	= 'zdf'		# Zweites Deutsches Fernsehen

	# Anime
	ReleaseNetworkAbma	= 'abma'	# [Anime] Abema
	ReleaseNetworkAdn	= 'adn'		# [Anime] Anime Digital Network (French)
	ReleaseNetworkAnmx	= 'anmx'	# [Anime] Animax
	ReleaseNetworkAmog	= 'amog'	# [Anime] Anime Onegai (Spanish)
	ReleaseNetworkAntx	= 'antx'	# [Anime] Anime Theatre X
	ReleaseNetworkAsbc	= 'asbc'	# [Anime] Asahi Broadcasting Corporation (ABC)
	ReleaseNetworkBhmt	= 'bhmt'	# [Anime] Bahamut Animation Madness (Chinese)
	ReleaseNetworkBlbl	= 'blbl'	# [Anime] Bilibili
	ReleaseNetworkBspm	= 'bspm'	# [Anime] NHK BS Premium
	ReleaseNetworkBsnt	= 'bsnt'	# [Anime] BS4 Nippon TV
	ReleaseNetworkBsta	= 'bsta'	# [Anime] BS5 TV Asahi
	ReleaseNetworkBsts	= 'bsts'	# [Anime] BS6 TBS
	ReleaseNetworkBstt	= 'bstt'	# [Anime] BS7 TV Tokyo
	ReleaseNetworkBsfj	= 'bsfj'	# [Anime] BS8 Fuji
	ReleaseNetworkBsnb	= 'bsnb'	# [Anime] BS11 Nippon BS Broadcasting
	ReleaseNetworkBswh	= 'bswh'	# [Anime] BS12 World Hi-Vision Channel
	ReleaseNetworkCyrl	= 'cyrl'	# [Anime] Crunchyroll
	ReleaseNetworkDmm	= 'dmm'		# [Anime] Digital Media Mart
	ReleaseNetworkFjtv	= 'fjtv'	# [Anime] Fuji TV
	ReleaseNetworkFjto	= 'fjto'	# [Anime] Fuji TV One
	ReleaseNetworkFjod	= 'fjod'	# [Anime] Fuji TV On Demand
	ReleaseNetworkFmtn	= 'fmtn'	# [Anime] Funimation
	ReleaseNetworkHdve	= 'hdve'	# [Anime] Hidive
	ReleaseNetworkKab	= 'kab'		# [Anime] Kyushu Asahi Broadcasting
	ReleaseNetworkLmno	= 'lmno'	# [Anime] Lemino
	ReleaseNetworkMotv	= 'motv'	# [Anime] Music On! TV
	ReleaseNetworkNhkg	= 'nhkg'	# [Anime] NHK General TV
	ReleaseNetworkNhke	= 'nhke'	# [Anime] NHK Education TV
	ReleaseNetworkNptv	= 'nptv'	# [Anime] Nippon TV
	ReleaseNetworkTbst	= 'tbst'	# [Anime] TBS Television
	ReleaseNetworkTlsa	= 'tlsa'	# [Anime] Telasa
	ReleaseNetworkTvas	= 'tvas'	# [Anime] TV Asahi
	ReleaseNetworkTvac	= 'tvac'	# [Anime] TV Asahi Channel 1
	ReleaseNetworkTver	= 'tver'	# [Anime] TVer
	ReleaseNetworkTvty	= 'tvty'	# [Anime] TV Tokyo
	ReleaseNetworkTymx	= 'tymx'	# [Anime] Tokyo MX
	ReleaseNetworkUnxt	= 'unxt'	# [Anime] U-Next
	ReleaseNetworkWknm	= 'wknm'	# [Anime] Wakanim (French)
	ReleaseNetworkWowo	= 'wowo'	# [Anime] Wowow
	ReleaseNetworkYrtv	= 'yrtv'	# [Anime] Yomiuri TV

	ReleaseNetworkNone	= None

	ExpressionReleaseNetwork = {
		'keyword' : {
			'plus'			: u'(?:\+|p(?:lus)?)',
			'rip'			: u'(?:{separator}*(?:(?:(?:original|web|vod|h[cd](?:{separator}*tv)?|tv){separator}*)?(?:dl{separator}*)?rip(?:p?ed)?|web(?:{separator}*dl)?|vod|h[cd](?:{separator}*tv)?|releases?|networks?|stream(?:ing)?|studios?))',
			'suffix'		: u'(?:{rip}|{plus}{rip}?)',
			'group'			: u'(?!{symbol}*(?:hd|tgx|yts|publichd|rar(?:bg|tv)|prime|n1c|sparrow|sniper|e[tz][a-z\.]*)?(?:{symbol}*(?:mkv|mp4|avi|webm))?{symbol}*$)',
			'japanese'		: u'(?:[一-龠]|[ぁ-ゔ]|[ァ-ヴー]|[々〆〤ヶ])',
			'chinese'		: u'[\u4E00-\u9FFF]',
			'korean'		: u'[가-힣]',
			'asian'			: u'(?:{japanese}|{chinese}|{korean})',
			'date'			: u'(?:(?:19|2[01])\d{2}(?:[\.\-\_][0-3][0-9]){2}|(?:[0-3][0-9][\.\-\_]){2}(?:19|2[01])\d{2})',
			'resolution'	: u'\d{3,}x\d{3,}',
		},

		'expression' : (
			# Detect these before other ones, since they can overlap.
			(ReleaseNetworkHtsr,	u'((?:di?sne?y|dsnp)?(?:hot{separator}*star|(?:di?sne?y|dsnp){plus}?{separator}*hs|hs{separator}*(?:di?sne?y|dsnp){plus}?){suffix}?)'), # Detect before "Disney".
			(ReleaseNetworkEpix,	u'(epix{rip})'), # Detect before "MGM7".
			(ReleaseNetworkIviw,	u'((?:au?bc{separator}*)?iview{suffix}?)'), # Before "AUBC".
			(ReleaseNetworkAubc,	u'(aubc\d?{suffix}?)'), # Before US "ABC".
			(ReleaseNetworkAubc,	[[u'(au?bc\d?{suffix}?)'], [u'(aus?(?:tralia[ns]?)?)']]), # Before US "ABC".
			(ReleaseNetworkTbst,	[[u'((?<!bs.)tbs(?:.ts$)?{group}{suffix}?)'], [u'(j(?:a|pn?)|anim(?:e|ations?)|e\d{{3,}}|(?<!dynamite.){date}|{resolution}|^{brackets_start}?(?:.{{0,10}}raws?|ye){brackets_end}?|\.ts$)', u'({asian})']]), # Same abbreviation as the US TBS network. Try finding other "anime" indicators.

			(ReleaseNetworkNtfx,	u'((?:nf|netflix){rip}?)'),
			(ReleaseNetworkAmzn,	u'((?:ama?zo?n|prime{separator}*video){rip}?|prime{suffix})'),
			(ReleaseNetworkAppl,	u'(apple?(?!&)(?:{separator}*tv)?{suffix}?|a{separator}*tv{suffix})'), # Do not match "atv" only, since it is also an uploader.
			(ReleaseNetworkBbc,		u'(bbc\d?{suffix}?)'),
			(ReleaseNetworkDsny,	u'((?:(?:di?sne?y|dsnp)(?:{plus}|xd|junior)?(?:ho?ts(?:ta)?r)?|apps){suffix}?)'), # Do not include "DSN" for "Start Trek DSN" (Deep Space Nine"). APPS = Disney Plus MENA.
			(ReleaseNetworkHbo,		u'(?:hbo|hbo\d{group}|home{separator}*box{separator}*office|h(?:bo)?(?:{separator}*(?:max|now|go|spain)))'),
			(ReleaseNetworkHulu,	u'(hulu{suffix}?)'),
			(ReleaseNetworkPcok,	u'(p(?:ea)?coc?k{suffix}?)'),
			(ReleaseNetworkPrmt,	u'((?:paramount|pmtp){suffix}?)'),
			(ReleaseNetworkDscy,	u'((?:dsc{plus}|discovery(?:{plus}|{separator}*channel)|^(?:hdtv{separator}*)?discovery|dmax){suffix}?)'), # Do not make "channel" optional, otherwise "Start Trek Discovery" will be valid for "Star Trek".
			(ReleaseNetworkShwt,	u'(show{separator}*time{suffix}?)'),
			(ReleaseNetworkStrz,	u'((?:stz|starz(?:{separator}*play)?){group}{suffix}?)'), # "STARZ" is also a release group.
			(ReleaseNetworkSyfy,	u'(sy{separator}*fy{suffix}?)'),
			(ReleaseNetworkCbc,		u'(cbc(?:g|{separator}*gem)?{suffix}?)'),
			(ReleaseNetworkCbs,		u'(cbs(?!=){suffix}?)'), # "=CBS=" is a release group.

			(ReleaseNetwork7pls,	u'((?:seven|7){separator}*plu?s{suffix}?)'),
			(ReleaseNetwork9now,	u'((?:nine|9){separator}*now{suffix}?)'),
			(ReleaseNetwork10py,	u'((?:ten|10){separator}*play{suffix}?)'),
			(ReleaseNetworkAbc,		u'(abc\d?{suffix}|abc{separator}*family{suffix}?)'),
			(ReleaseNetworkAtbj,	u'(alt{separator}*balaji{suffix}?)'),
			(ReleaseNetworkAmc,		u'(amc{suffix})'),
			(ReleaseNetworkArd,		u'(ard(?:{separator}*mediathek|{suffix})?)'),
			(ReleaseNetworkAtsm,	u'(as{rip}|adult{separator}*swim{suffix}?)'),
			(ReleaseNetworkAtrs,	u'(atres{separator}*(?:player|media){suffix}?)'),
			(ReleaseNetworkBmrg,	u'(boom{rip}|boomerang{group}{suffix}?)'), # "Boomerang" at the end of the file name is a release group.
			(ReleaseNetworkBtbx,	u'(brit{separator}*box?{suffix}?)'),
			(ReleaseNetworkCh4,		u'((?<!history.)(?<!hist.)(?:channel{separator}*(?:4|four)|ch{separator}*(?:4|four)(?!.\d[^\d])){suffix}?)'),
			(ReleaseNetworkCh5,		u'((?<!history.)(?<!hist.)(?:channel{separator}*(?:5|five)|ch{separator}*(?:5|five)(?!.\d[^\d])){suffix}?)'),
			(ReleaseNetworkCnmx,	u'(cinemax{suffix}?)'),
			(ReleaseNetworkCtnw,	u'(cartoon{separator}*network{suffix}?)'),
			(ReleaseNetworkClro,	u'(claro(?:{separator}*video)?{suffix}?)'),
			(ReleaseNetworkCyrl,	u'(crunchyroll{suffix}?)'),
			(ReleaseNetworkCrve,	u'(crave?{suffix}?)'),
			(ReleaseNetworkCrtn,	u'((?:the{separator}*)?criterion(?:{separator}*collection)?{suffix}?)'),
			(ReleaseNetworkTcw,		u'(the{separator}*cw{suffix}?)'),
			(ReleaseNetworkDazn,	u'(dazn{suffix}?)'),
			(ReleaseNetworkEros,	u'(eros(?:{separator}*now)?{suffix}?)'),
			(ReleaseNetworkEspn,	u'(espn[\du]?{suffix}?)'),
			(ReleaseNetworkFbwh,	u'(facebook|(?:fb|facebook){separator}*watch{suffix}?)'),
			(ReleaseNetworkFrfm,	u'((?<!last.)(?<!final.)(?<!finally.)free(?:{separator}*form|{rip}))'),
			(ReleaseNetworkFox,		u'(fox{rip})'),
			(ReleaseNetworkFxtl,	u'(fo?xtel{suffix}?)'),
			(ReleaseNetworkFubo,	u'(fubo(?:{separator}*tv)?{suffix}?)'),
			(ReleaseNetworkGala,	u'(gagaoo?lala{suffix}?)'),
			(ReleaseNetworkGlbo,	u'((?:rede{separator}*)?globo(?:{separator}*play)?{suffix}?)'),
			(ReleaseNetworkGogl,	u'((?:google(?:{separator}*play)?|g{separator}*play){suffix}?)'),
			(ReleaseNetworkHngm,	u'((?:hplay|hungama){suffix}?)'),
			(ReleaseNetworkHsty,	u'(history{separator}*(?:ch(?:annel)?|play)\d?{suffix}?)'),
			(ReleaseNetworkIqyi,	u'((?:i?qiyi|爱奇艺|奇艺){suffix}?)'),
			(ReleaseNetworkItns,	u'(itunes{rip}?|it{rip})'),
			(ReleaseNetworkItv,		u'(c?itv(?:\d|x|{separator}*(?:be|plc|box{separator}*office|encore|studios?)?)?)'),
			(ReleaseNetworkIplr,	u'((?:(?:bbc{separator}*)ip(?:p?layer)?|ipp?layer){suffix}?)'),
			(ReleaseNetworkIwtc,	u'(i{separator}*want{separator}*tfc{suffix}?)'),
			(ReleaseNetworkJio,		u'((?<!team.)(?:jio{separator}*(?:tv|cine?(?:ma)?)|jio{group}){suffix}?)'),
			(ReleaseNetworkLmno,	u'(lemino{suffix}?)'),
			(ReleaseNetworkLftm,	u'(life{separator}*time{suffix}?)'),
			(ReleaseNetworkLngt,	u'((?:lions{separator}*gate(?:{separator}*play)?|lgp){suffix}?)'),
			(ReleaseNetworkMvar,	u'(movies{separator}*any{separator}*where{suffix}?)'),
			(ReleaseNetworkMgm,		u'((?:mgm{group}|mgm{separator}*hd){suffix}?)'), # "MGM" is also a release group.
			(ReleaseNetworkMnrm,	u'((?:mmax|manorama(?:{separator}*max)?){suffix}?)'),
			(ReleaseNetworkMtv,		u'((?<!ghosts.)mtv\d?{group}{suffix}?)'),
			(ReleaseNetworkMubi,	u'(mubi{rip}{suffix}?)'),
			(ReleaseNetworkMy5,		u'(my5{suffix}?)'),
			(ReleaseNetworkMytv,	u'(mytv{group}{suffix}?)'),
			(ReleaseNetworkNlgc,	u'(nat(?:ional)?{separator}*geo(?:graphic)?{suffix}?)'),
			(ReleaseNetworkNbc,		u'(nbc(?:{separator}*universal)?{suffix}?)'),
			(ReleaseNetworkNckn,	u'(nickelodeon{suffix}?)'), # "NICK" is also a release group.
			(ReleaseNetworkNrk,		u'(nrk(?:{separator}*tv)?{suffix}?)'),
			(ReleaseNetworkPbs,		u'(pbs{separator}*(?:{group}|kids|{rip}))'), # "PBS" is also a release group.
			(ReleaseNetworkRktn,	u'(rakuten(?:{separator}*tv)?{suffix}?)'),
			(ReleaseNetworkRlbp,	u'((?:royal{separator}*)?bioscope{suffix}?)'),
			(ReleaseNetworkRoku,	u'(roku{suffix}?)'),
			(ReleaseNetworkRte,		u'(rt[eé](?:{separator}*play(?:er)?)?{suffix}?)'),
			(ReleaseNetworkSana,	u'(saina(?:{separator}*play)?{suffix}?)'),
			(ReleaseNetworkShid,	u'(shahid{suffix}?)'),
			(ReleaseNetworkSysh,	u'(simply{separator}*south{suffix}?)'),
			(ReleaseNetworkSnxt,	u'((?:snxt|sun{separator}*nxt){suffix}?)'),
			(ReleaseNetworkStan,	u'(stan{group}{suffix}?)'), # "STAN" is also a release group.
			(ReleaseNetworkSky,		u'(sky{separator}*(?:q|go|tv|studios?|atlantic|{rip})?{suffix}?)'),
			(ReleaseNetworkSony,	u'(sony(?!(?:hd)?{symbol}*$)(?:{separator}*(?:liv|tv|pictures))?(?:{separator}*core)?|bcore|bravia{suffix}?)'), # "SONY" and "SONYHD" at the end of the file name is a release group.
			(ReleaseNetworkStv,		u'(stv{suffix}?)'),
			(ReleaseNetworkTbs,		u'((?<!bs.)tbs(?!(?:.{{0,8}}|[a-z]{{0,6}}(?:\s*[\[\(]([a-z\.]{{0,8}})[\]\)]\s*)?(?:\.[a-z]{{0,4}})?)$){group}{suffix}?)'), # "TBS" is also a release group. NB: 99% of the time "TBS" is the release group. Only extract the network if it is not close to the end of the file name. Also exclude "BS-TBS" anime.
			(ReleaseNetworkTlsa,	u'(telasa{suffix}?)'),
			(ReleaseNetworkTnct,	u'((?:tencent(?:{separator}*video)?|腾讯视频){suffix}?)'),
			(ReleaseNetworkTnkt,	u'(tent?kotta{suffix}?)'),
			(ReleaseNetworkTf1,		u'(tf{separator}*1{suffix}?)'),
			(ReleaseNetworkTnt,		u'((?<!team.)(?<!ekipa.)tnt(?!{separator}*v(?:i(?:l(?:l(?:a(?:ge?)?)?)?)?)?){suffix}?)'), # Do not match the release group "TNT Village". Only require the "v", since the file name might be cut off.
			(ReleaseNetworkTubi,	u'(tubi{suffix}?)'),
			(ReleaseNetworkTvng,	u'(tving{group}{suffix}?)'),
			(ReleaseNetworkTvnz,	u'(tvnz{suffix}?)'),
			(ReleaseNetworkUnxt,	u'(u(?:sen)?{separator}*ne?xt{suffix}?)'),
			(ReleaseNetworkUsa,		u'(usa{separator}*net(?:works?)?{suffix}?)'),
			(ReleaseNetworkVh1,		u'(vh1{suffix}?)'),
			(ReleaseNetworkVipy,	u'(via{separator}*play{suffix}?)'),
			(ReleaseNetworkVimx,	u'(viva(?:{separator}*(?:max|cinemas?|films?)){suffix}?)'),
			(ReleaseNetworkViu,		u'(viu{suffix}?)'),
			(ReleaseNetworkWtch,	u'((?:wtch|watcha){suffix}?)'),
			(ReleaseNetworkYoku,	u'(youku{suffix}?)'),
			(ReleaseNetworkYtb,		u'((?:ytb|youtube)(?:{separator}*(?:tv|red|premium))?{suffix}?)'), # "RED" is also a release group or TLD.
			(ReleaseNetworkZdf,		u'(zdf(?:{separator}*mediathek|{suffix})?)'),
			(ReleaseNetworkZee,		u'(zee{separator}*5{suffix}?)'),

			(ReleaseNetworkCycl,	u'(cc{rip}|comedy{separator}*central{suffix}?)'), # Do not match "cc", since it is also an uploader.
			(ReleaseNetworkTvty,	u'(tv{separator}*tokyo(?!.*broadcast){suffix}?)'), # Before BSTT.
			(ReleaseNetworkAsbc,	[[u'(abc{suffix}?)'], [u'(j(?:a|pn?)|anim(?:e|ations?)|e\d{{3,}}|{date}|^{brackets_start}?(?:.{{0,10}}raws?|ye){brackets_end}?|\.ts$)', u'({asian})', u'((?<=abc).{{0,4}}\d{{3,4}}[ipx]\d*)']]), # Same abbreviation as the US/AU networks. Try finding other "anime" indicators.
			(ReleaseNetworkAbma,	u'(abe?ma{suffix}?)'),
			(ReleaseNetworkAdn,		u'((?:adn|anime{separator}*digital{separator}*net(?:work)?){suffix}?)'),
			(ReleaseNetworkAnmx,	u'(animax{suffix}?)'),
			(ReleaseNetworkAmog,	u'(anime{separator}*onegai{suffix}?)'),
			(ReleaseNetworkAntx,	u'((?:at\-?x|anime{separator}*theatre{separator}*x){suffix}?)'),
			(ReleaseNetworkBhmt,	u'(baha(?:mut)?{suffix}?)'),
			(ReleaseNetworkBlbl,	u'((?:bilibili|b{separator}*global|b{separator}*station){suffix}?)'),
			(ReleaseNetworkBspm,	u'((?:bs(?:[48]k)?p{group}|bs[48]k|bs[12]|bs{separator}*premium|bspbs|nhk{separator}*(?:bs(?:[48]k)?p|bs(?:[48]k)?(?:{separator}*premium)?)){suffix}?)'),
			(ReleaseNetworkBsnt,	u'((?:bs{separator}*(?:4|four){group}|bs{separator}*nippon(?:{separator}*tv)?){suffix}?)'),
			(ReleaseNetworkBsta,	u'((?:bs{separator}*(?:5|five){group}|ex{separator}*bs|bs{separator}*ex|bs(?:{separator}*tv)?{separator}*asahi){suffix}?)'),
			(ReleaseNetworkBsts,	u'((?:bs{separator}*(?:6|six){group}|bs{separator}*(?:tbs|i)){suffix}?)'),
			(ReleaseNetworkBstt,	u'((?:bs{separator}*(?:7|seven){group}|bs{separator}*(?:j|tx|tv{separator}*tokyo)|tv{separator}*tokyo|jotx{separator}*dtv){suffix}?)'),
			(ReleaseNetworkBsfj,	u'((?:bs{separator}*(?:8|eight){group}|bs{separator}*(?:fuji)){suffix}?)'),
			(ReleaseNetworkBsnb,	u'((?:bs{separator}*(?:11|eleven){group}|nippon{separator}*bs{separator}*broadcasting){suffix}?)'),
			(ReleaseNetworkBswh,	u'((?:bs{separator}*(?:12|twelve){group}|world{separator}*hi(?:gh)?{separator}*vision){suffix}?)'),
			(ReleaseNetworkFjtv,	u'((?:fuji{separator}*tv(?!{separator}one)){suffix}?)'),
			(ReleaseNetworkFjto,	u'((?:cs{separator}*fuji(?:{separator}*(?:1|one))?|fuji{separator}*tv{separator}*(?:1|one)){suffix}?)'),
			(ReleaseNetworkDmm,		u'((?:dmm|digital{separator}*media{separator}*mart)(?:{separator}*(?:tv|com))?{suffix}?)'),
			(ReleaseNetworkTvac,	u'((?:cs3|ex{separator}*cs1|cs{separator}*ex1){suffix}?)'),
			(ReleaseNetworkTvas,	u'(tv{separator}*asahi(?!{separator}channel)(?!{separator}one)(?!{separator}1[^\d]){suffix}?)'), # After ReleaseNetworkTvac
			(ReleaseNetworkFjod,	u'(fuji{separator}*(?:tv{separator}*)?on{separator}*demand?{suffix}?)'),
			(ReleaseNetworkFmtn,	u'(funi(?:mation)?{suffix}?)'),
			(ReleaseNetworkHdve,	u'(hidi(?:ve)?{suffix}?)'),
			(ReleaseNetworkKab,		u'(kyushu{separator}*asahi{separator}*broadcast(?:ing)?{suffix}?)'),
			(ReleaseNetworkMotv,	u'((?:m{separator}*on{symbol}*|music{separator}*on{symbol}*tv){suffix}?)'),
			(ReleaseNetworkTymx,	u'(tokyo{separator}*mx{suffix}?)'),
			(ReleaseNetworkNhkg,	u'(nhk(?:{separator}*tv)?{separator}*(?:g|general)(?:{separator}*tv)?{suffix}?)'),
			(ReleaseNetworkNhke,	u'(nhk(?:{separator}*tv)?{separator}*(?:e|education(?:al)?)(?:{separator}*tv)?{suffix}?)'),
			(ReleaseNetworkNptv,	u'((?<!bs)(?<!bs.)nippon{separator}*tv{suffix}?)'),
			(ReleaseNetworkWknm,	u'(wakanim{suffix}?)'),
			(ReleaseNetworkWowo,	u'(wowow(?:{separator}*prime)?{suffix}?)'),
			(ReleaseNetworkYrtv,	u'(y(?:omiuri{separator}*)?tv{suffix}?)'),
			(ReleaseNetworkTver,	u'(tver{suffix}?)'),

			# Match these last, since they are not really networks, and some other network keywords might also appear in the file name.
			(ReleaseNetworkBms,		u'(bms{rip}|book{separator}*my{separator}*show{suffix}?)'),
			(ReleaseNetworkDcu,		u'(dc(?:u|{separator}*(?:universe|comics?)))'), # Do not match "dc", since it is also "director's cut".
		),
	}

	# Match upper case characters that can be confused with other words.
	ExpressionReleaseNetworkCase = {
		'keyword' : {
			'plus'		: u'(?:\+|[pP](?:[lL][uU][sS])?)',
			'rip'		: u'(?:{separator}*(?:(?:(?:[oO][rR][iI][gG][aA][nN][aA][lL]|[wW][eE][bB]|[vV][oO][dD]|[hH][cCdD](?:{separator}*[tT][vV])?|[tT][vV]){separator}*)?(?:[dD][lL]{separator}*)?[rR][iI][pP](?:[pP]?[eE][dD])?|[wW][eE][bB](?:{separator}*[dD][lL])?|[vV][oO][dD]|[hH][cCdD](?:{separator}*[tT][vV])?|[rR][eE][lL][eE][aA][sS][eE][sS]?|[nN][eE][tT][wW][oO][rR][kK][sS]?|[sS][tT][rR][eE][aA][mM](?:[iI][nN][gG])?|[sS][tT][uU][dD][iI][oO][sS]?))',
			'suffix'	: u'(?:{rip}|{plus}{rip}?)',
			'group'		: u'(?!{symbol}*(?:[hH][dD]|[tT][gG][xX]|[yY][tT][sS]|[pP][uU][bB][lL][iI][cC][hH][dD]|[rR][aA][rR](?:[bB][gG]|[tT][vV])|[pP][rR][iI][mM][eE]|[nN]1[cC]|[sS][pP][aA][rR][rR][oO][wW]|[sS][nN][iI][pP][eE][rR]|[eE][tTzZ][a-zA-Z\.]*)?(?:{symbol}*(?:[mM][kK][vV]|[mM][pP]4|[aA][vV][iI]|[wW][eE][bB][mM]))?{symbol}*$)',
			'dts'		: u'(?<![dD][tT][sS][hH][dD]{separator})(?<![dD][tT][sS]{separator})(?<![hH][dD]{separator})',
			'audio'		: u'(?!{separator}\d{separator}\d)(?!\d{separator}\d)(?!{separator}[xX])',
			'dot'		: '(?<!\.)',
			'tld'		: '(?![\]\)\}\-\s])',
			'tld2'		: '(?![\]\)\}])',
		},

		'expression' : (
			# Detect these before other ones, since they can overlap.
			(ReleaseNetworkHtsr,	u'(HS{suffix}?)'), # Detect before "Disney".
			(ReleaseNetworkEpix,	u'(EPIX{suffix}?)'), # Detect before "MGM". "EPiX" is a release group.

			(ReleaseNetworkAbc,		u'((?:ABC|abc)\d?{suffix}?)'),
			(ReleaseNetworkAha,		u'({dot}AHA{tld}{group}{suffix}?|AHA{group}{suffix}?)'),
			(ReleaseNetworkAmc,		u'((?:AMC|amc){suffix}?)'),
			(ReleaseNetworkAppl,	u'(ATV{group}{suffix}?)'),
			(ReleaseNetworkAtsm,	u'(AS{suffix}?(?!{separator}*(?:[aA][nN]?|[tT][hH][eE])))'),
			(ReleaseNetworkBnge,	u'((?:[bB]inge|BINGE){suffix}?)'), # "BiNGE" is also a release group.
			(ReleaseNetworkBmrg,	u'((?:BOOM|Boom){suffix}?)'),
			(ReleaseNetworkCycl,	u'({dot}CC{tld}{group}{rip}|CC{tld}{group}{rip})'), # Many "CC" are actually "Criterion Collection". It seems that those followed by web/rip/etc are "Comedy Central".
			(ReleaseNetworkCtnw,	u'({dot}CN{tld}{group}{suffix}?|CN{group}{symbol}*{rip})'), # "CN" is a China TLD and sometimes used as language code.
			(ReleaseNetworkCyrl,	u'({dot}CR(?!.[bB][tT]){tld}{group}{rip}|CR(?!.[bB][tT]){tld2}{group}{rip}|{rip}{symbol}*CR(?!.[bB][tT]){tld2}{group}|[\[\(\{]CR[\]\)\}]{group})'),
			(ReleaseNetworkCrtn,	u'({dot}CC{tld}{group}(?!{rip})|CC{tld}{group}(?!{rip}))'), # Many "CC" are actually "Criterion Collection". It seems that those followed by web/rip/etc are "Comedy Central".
			(ReleaseNetworkTcw,		u'(CW{suffix}?)'),
			(ReleaseNetworkFrfm,	u'(FREE{suffix}?)'),
			(ReleaseNetworkFox,		u'((?:F[oO][xX]|FX[XM]?){suffix}?)'),
			(ReleaseNetworkHbo,		u'(MAX{suffix}?)'),
			(ReleaseNetworkIfc,		u'(IFC{rip}|(?<![\]\)])IFC{group}{rip}?)'),
			(ReleaseNetworkIflx,	u'([iI][fF][lL][iI][xX](?<![iI]FLiX){suffix}?)'), # "iFLiX" is also a release group.
			(ReleaseNetworkIplr,	u'([iI]P{suffix}?)'),
			(ReleaseNetworkItns,	u'(iT{suffix}?)'),
			(ReleaseNetworkJio,		u'(JC{group}{suffix}?)'),
			(ReleaseNetworkLftm,	u'(LIFE{group}{suffix}?)'),
			(ReleaseNetworkMvar,	u'({dts}(?:{dot}MA{tld2}{group}{audio}{rip}|MA{tld2}{group}{audio}{rip}?))'), # Exclude "DTS HD MA".
			(ReleaseNetworkMubi,	u'(MUB[iI]{suffix}?)'),
			(ReleaseNetworkNckn,	u'(NICK{suffix}?)'),
			(ReleaseNetworkNow,		u'((?<![eE][rR][oO][sS].)NOW{group}{suffix}?)'),

			#(ReleaseNetworkSana,	u'({dot}SP{tld}{group}{suffix}?|SP{group}{suffix}?)'), # Can't find "SP". And it is too short and common. Eg some people use "Sp" as Spanish language.
			(ReleaseNetworkSbs,		u'((?<!3[dD].)(?<![hHfF].)(?<!(?:[hH][aA][lL][fF]|[fF][uU][lL][lL]).)(?:{dot}SBS{tld}{group}{suffix}?|SBS{group}{suffix}?))'), # "sbs" is also a TLD and 3D-SBS.
			(ReleaseNetworkShdr,	u'((?:[sS]hudder|SHUDDER{group}){suffix}?)'),
			(ReleaseNetworkShwt,	u'({dot}SHO{tld}{group}{suffix}?|SHO{group}{suffix}?)'), # "SHO" is also a release group.
			(ReleaseNetworkSysh,	u'({dot}SS{tld}{group}{suffix}?|SS{group}{suffix}?)'), # "SS" is also a release group.
			(ReleaseNetworkTnkt,	u'({dot}TK{tld}{group}{suffix}?|TK{group}{suffix}?)'), # "TK" is also a release group and TLD.
			(ReleaseNetworkVido,	u'(VIDIO{suffix}?)'), # "Vidio" means "video" in a number of languages.
			(ReleaseNetworkWetv,	u'(W[eE][tT][vV](?<!WeTv){suffix}?)'), # "WeTv" is also a release group.
			(ReleaseNetworkYtb,		u'({dot}RED{tld}{group}{suffix}?|RED{group}{suffix}?)'),

			(ReleaseNetworkAmog,	u'({dot}AO{tld}{group}{suffix}?|AO{group}{suffix}?)'),
			(ReleaseNetworkFjtv,	u'(CX{suffix}?)'),
			(ReleaseNetworkTvas,	u'(EX(?!\-){suffix}?)'),
			(ReleaseNetworkTvac,	u'(CSA{group}{suffix}?)'), # "CSA" is also a release group.
			(ReleaseNetworkFjod,	u'(FOD{suffix}?)'),
			(ReleaseNetworkKab,		u'((?:KBC|KAB){group}{suffix}?)'), # "KBC" is also a release group.
			(ReleaseNetworkTymx,	u'({dot}MX{tld2}{suffix}?)'), # "MX" is also a TLD.
			(ReleaseNetworkNptv,	u'((?<![bB][sS])(?<![bB][sS].)NTV{suffix}?)'),
			(ReleaseNetworkTvty,	u'(TX{suffix}?)'),
			(ReleaseNetworkWknm,	u'((?:WAKA|waka){suffix}?)'),

			# Match these last, since they are not really networks, and some other network keywords might also appear in the file name.
			(ReleaseNetworkBms,		u'(BMS{suffix}?)'),
		)
	}

	LabelReleaseNetwork = {
		LabelDefault : {
			LabelList1		: LabelShort,
			LabelList2		: LabelHidden,
			LabelList3		: LabelHidden,
			LabelList4		: LabelHidden,
			LabelInfo1		: LabelShort,
			LabelInfo2		: LabelMedium,
			LabelSettings1	: LabelMedium,
			LabelSettings2	: LabelShort,
		},

		ReleaseNetwork7pls	: { LabelShort : '7PLS',	LabelMedium : '7Plus',				LabelLong : '7Plus' },
		ReleaseNetwork9now	: { LabelShort : '9NOW',	LabelMedium : '9Now',				LabelLong : '9Now' },
		ReleaseNetwork10py	: { LabelShort : '10PY',	LabelMedium : '10Play',				LabelLong : '10Play' },
		ReleaseNetworkAbc	: { LabelShort : 'ABC',		LabelMedium : 'ABC',				LabelLong : 'American Broadcasting Company' },
		ReleaseNetworkAha	: { LabelShort : 'AHA',		LabelMedium : 'Aha',				LabelLong : 'Aha' },
		ReleaseNetworkAmc	: { LabelShort : 'AMC',		LabelMedium : 'AMC',				LabelLong : 'American Movie Classics' },
		ReleaseNetworkAmzn	: { LabelShort : 'AMZN',	LabelMedium : 'Amazon',				LabelLong : 'Amazon Prime Video' },
		ReleaseNetworkAppl	: { LabelShort : 'APPL',	LabelMedium : 'Apple',				LabelLong : 'Apple TV' },
		ReleaseNetworkArd	: { LabelShort : 'ARD',		LabelMedium : 'ARD',				LabelLong : 'Erstes Deutsches Fernsehen' },
		ReleaseNetworkAtbj	: { LabelShort : 'ATBJ',	LabelMedium : 'ALTBalaji',			LabelLong : 'ALTBalaji' },
		ReleaseNetworkAtrs	: { LabelShort : 'ATRS',	LabelMedium : 'Atres',				LabelLong : 'Atresplayer' },
		ReleaseNetworkAtsm	: { LabelShort : 'ATSM',	LabelMedium : 'Adult Swim',			LabelLong : 'Adult Swim' },
		ReleaseNetworkAubc	: { LabelShort : 'AUBC',	LabelMedium : 'AUBC',				LabelLong : 'Australian Broadcasting Corporation' },
		ReleaseNetworkBbc	: { LabelShort : 'BBC',		LabelMedium : 'BBC',				LabelLong : 'British Broadcasting Corporation' },
		ReleaseNetworkBmrg	: { LabelShort : 'BMRG',	LabelMedium : 'Boomerang',			LabelLong : 'Boomerang' },
		ReleaseNetworkBms	: { LabelShort : 'BMS',		LabelMedium : 'BookMyShow',			LabelLong : 'BookMyShow' },
		ReleaseNetworkBnge	: { LabelShort : 'BNGE',	LabelMedium : 'Binge',				LabelLong : 'Binge' },
		ReleaseNetworkBtbx	: { LabelShort : 'BTBX',	LabelMedium : 'BritBox',			LabelLong : 'BritBox' },
		ReleaseNetworkCbc	: { LabelShort : 'CBC',		LabelMedium : 'CBC',				LabelLong : 'Canadian Broadcasting Corporation' },
		ReleaseNetworkCbs	: { LabelShort : 'CBS',		LabelMedium : 'CBS',				LabelLong : 'Columbia Broadcasting System' },
		ReleaseNetworkCh4	: { LabelShort : 'CH4',		LabelMedium : 'Channel 4',			LabelLong : 'Channel 4' },
		ReleaseNetworkCh5	: { LabelShort : 'CH5',		LabelMedium : 'Channel 5',			LabelLong : 'Channel 5' },
		ReleaseNetworkClro	: { LabelShort : 'CLRO',	LabelMedium : 'Claro',				LabelLong : 'Claro Video' },
		ReleaseNetworkCnmx	: { LabelShort : 'CNMX',	LabelMedium : 'Cinemax',			LabelLong : 'Cinemax' },
		ReleaseNetworkCrtn	: { LabelShort : 'CRTN',	LabelMedium : 'Criterion',			LabelLong : 'The Criterion Collection' },
		ReleaseNetworkCrve	: { LabelShort : 'CRVE',	LabelMedium : 'Crave',				LabelLong : 'Crave' },
		ReleaseNetworkCtnw	: { LabelShort : 'CTNW',	LabelMedium : 'Cartoon Network',	LabelLong : 'Cartoon Network' },
		ReleaseNetworkCycl	: { LabelShort : 'CYCL',	LabelMedium : 'Comedy Central',		LabelLong : 'Comedy Central' },
		ReleaseNetworkDazn	: { LabelShort : 'DAZN',	LabelMedium : 'DAZN',				LabelLong : 'DAZN' },
		ReleaseNetworkDcu	: { LabelShort : 'DCU',		LabelMedium : 'DC Universe',		LabelLong : 'Detective Comics Universe' },
		ReleaseNetworkDscy	: { LabelShort : 'DSCY',	LabelMedium : 'Discovery',			LabelLong : 'Discovery' },
		ReleaseNetworkDsny	: { LabelShort : 'DSNY',	LabelMedium : 'Disney',				LabelLong : 'Disney' },
		ReleaseNetworkEpix	: { LabelShort : 'EPIX',	LabelMedium : 'Epix',				LabelLong : 'Epix' },
		ReleaseNetworkEros	: { LabelShort : 'EROS',	LabelMedium : 'Eros',				LabelLong : 'Eros Now' },
		ReleaseNetworkEspn	: { LabelShort : 'ESPN',	LabelMedium : 'ESPN',				LabelLong : 'Entertainment and Sports Programming Network' },
		ReleaseNetworkFbwh	: { LabelShort : 'FBWH',	LabelMedium : 'Facebook',			LabelLong : 'Facebook Watch' },
		ReleaseNetworkFox	: { LabelShort : 'FOX',		LabelMedium : 'Fox',				LabelLong : 'Fox Broadcasting Company' },
		ReleaseNetworkFrfm	: { LabelShort : 'FRFM',	LabelMedium : 'Freeform',			LabelLong : 'Freeform' },
		ReleaseNetworkFubo	: { LabelShort : 'FUBO',	LabelMedium : 'Fubo',				LabelLong : 'FuboTV' },
		ReleaseNetworkFxtl	: { LabelShort : 'FXTL',	LabelMedium : 'Foxtel',				LabelLong : 'Foxtel' },
		ReleaseNetworkGala	: { LabelShort : 'GALA',	LabelMedium : 'GagaOoLala',			LabelLong : 'GagaOOLala' },
		ReleaseNetworkGlbo	: { LabelShort : 'GLBO',	LabelMedium : 'Globo',				LabelLong : 'Globo' },
		ReleaseNetworkGogl	: { LabelShort : 'GOGL',	LabelMedium : 'Google',				LabelLong : 'Google Play' },
		ReleaseNetworkHbo	: { LabelShort : 'HBO',		LabelMedium : 'HBO',				LabelLong : 'Home Box Office' },
		ReleaseNetworkHngm	: { LabelShort : 'HNGM',	LabelMedium : 'Hungama',			LabelLong : 'Hungama Play' },
		ReleaseNetworkHsty	: { LabelShort : 'HSTY',	LabelMedium : 'History',			LabelLong : 'History Channel' },
		ReleaseNetworkHtsr	: { LabelShort : 'HTSR',	LabelMedium : 'Hotstar',			LabelLong : 'Hotstar' },
		ReleaseNetworkHulu	: { LabelShort : 'HULU',	LabelMedium : 'Hulu',				LabelLong : 'Hulu' },
		ReleaseNetworkIfc	: { LabelShort : 'IFC',		LabelMedium : 'IFC',				LabelLong : 'Independent Film Channel,' },
		ReleaseNetworkIflx	: { LabelShort : 'IFLX',	LabelMedium : 'iFlix',				LabelLong : 'WeTV iFlix' },
		ReleaseNetworkIplr	: { LabelShort : 'IPLR',	LabelMedium : 'iPlayer',			LabelLong : 'BBC iPlayer' },
		ReleaseNetworkIqyi	: { LabelShort : 'IQYI',	LabelMedium : 'iQIYI',				LabelLong : 'iQIYI' },
		ReleaseNetworkItns	: { LabelShort : 'ITNS',	LabelMedium : 'iTunes',				LabelLong : 'iTunes' },
		ReleaseNetworkItv	: { LabelShort : 'ITV',		LabelMedium : 'ITV',				LabelLong : 'Independent Television' },
		ReleaseNetworkIviw	: { LabelShort : 'IVIW',	LabelMedium : 'iView',				LabelLong : 'ABC iView' },
		ReleaseNetworkIwtc	: { LabelShort : 'IWTC',	LabelMedium : 'iWantTFC',			LabelLong : 'iWantTFC' },
		ReleaseNetworkJio	: { LabelShort : 'JIO',		LabelMedium : 'Jio',				LabelLong : 'Jio' },
		ReleaseNetworkLftm	: { LabelShort : 'LFTM',	LabelMedium : 'Lifetime',			LabelLong : 'Lifetime' },
		ReleaseNetworkLngt	: { LabelShort : 'LNGT',	LabelMedium : 'Lionsgate',			LabelLong : 'Lionsgate Play' },
		ReleaseNetworkMgm	: { LabelShort : 'MGM',		LabelMedium : 'MGM',				LabelLong : 'Metro Goldwyn Mayer' },
		ReleaseNetworkMnrm	: { LabelShort : 'MNRM',	LabelMedium : 'Manorama',			LabelLong : 'ManoramaMAX' },
		ReleaseNetworkMtv	: { LabelShort : 'MTV',		LabelMedium : 'MTV',				LabelLong : 'Music Television' },
		ReleaseNetworkMubi	: { LabelShort : 'MUBI',	LabelMedium : 'Mubi',				LabelLong : 'Mubi' },
		ReleaseNetworkMvar	: { LabelShort : 'MVAR',	LabelMedium : 'Movies Anywhere',	LabelLong : 'Movies Anywhere' },
		ReleaseNetworkMy5	: { LabelShort : 'MY5',		LabelMedium : 'My5',				LabelLong : 'My5' },
		ReleaseNetworkMytv	: { LabelShort : 'MYTV',	LabelMedium : 'MyTV',				LabelLong : 'MyTV' },
		ReleaseNetworkNbc	: { LabelShort : 'NBC',		LabelMedium : 'NBC',				LabelLong : 'National Broadcasting Company' },
		ReleaseNetworkNckn	: { LabelShort : 'NCKN',	LabelMedium : 'Nickelodeon',		LabelLong : 'Nickelodeon' },
		ReleaseNetworkNlgc	: { LabelShort : 'NLGC',	LabelMedium : 'Nat Geo',			LabelLong : 'National Geographic' },
		ReleaseNetworkNow	: { LabelShort : 'NOW',		LabelMedium : 'NOW',				LabelLong : 'NOW' },
		ReleaseNetworkNrk	: { LabelShort : 'NRK',		LabelMedium : 'NRK',				LabelLong : 'Norwegian Broadcasting Corporation' },
		ReleaseNetworkNtfx	: { LabelShort : 'NTFX',	LabelMedium : 'Netflix',			LabelLong : 'Netflix' },
		ReleaseNetworkPbs	: { LabelShort : 'PBS',		LabelMedium : 'PBS',				LabelLong : 'Public Broadcasting Service' },
		ReleaseNetworkPcok	: { LabelShort : 'PCOK',	LabelMedium : 'Peacock',			LabelLong : 'Peacock' },
		ReleaseNetworkPrmt	: { LabelShort : 'PRMT',	LabelMedium : 'Paramount',			LabelLong : 'Paramount' },
		ReleaseNetworkRktn	: { LabelShort : 'RKTN',	LabelMedium : 'Rakuten',			LabelLong : 'Rakuten TV' },
		ReleaseNetworkRlbp	: { LabelShort : 'RLBP',	LabelMedium : 'Royal Bioscope',		LabelLong : 'Royal Bioscope' },
		ReleaseNetworkRoku	: { LabelShort : 'ROKU',	LabelMedium : 'Roku',				LabelLong : 'Roku' },
		ReleaseNetworkRte	: { LabelShort : 'RTE',		LabelMedium : 'RTE',				LabelLong : 'Raidió Teilifís Éireann' },
		ReleaseNetworkSana	: { LabelShort : 'SANA',	LabelMedium : 'Saina',				LabelLong : 'Saina Play' },
		ReleaseNetworkSbs	: { LabelShort : 'SBS',		LabelMedium : 'SBS',				LabelLong : 'Special Broadcasting Service' },
		ReleaseNetworkShdr	: { LabelShort : 'SHDR',	LabelMedium : 'Shudder',			LabelLong : 'AMC Shudder' },
		ReleaseNetworkShid	: { LabelShort : 'SHID',	LabelMedium : 'Shahid',				LabelLong : 'Shahid' },
		ReleaseNetworkShwt	: { LabelShort : 'SHWT',	LabelMedium : 'Showtime',			LabelLong : 'Showtime' },
		ReleaseNetworkSky	: { LabelShort : 'SKY',		LabelMedium : 'Sky',				LabelLong : 'Sky' },
		ReleaseNetworkSnxt	: { LabelShort : 'SNXT',	LabelMedium : 'Sun NXT',			LabelLong : 'Sun NXT' },
		ReleaseNetworkSony	: { LabelShort : 'SONY',	LabelMedium : 'Sony',				LabelLong : 'Sony' },
		ReleaseNetworkStan	: { LabelShort : 'STAN',	LabelMedium : 'Stan',				LabelLong : 'Stan' },
		ReleaseNetworkStrz	: { LabelShort : 'STRZ',	LabelMedium : 'Starz',				LabelLong : 'Starz' },
		ReleaseNetworkStv	: { LabelShort : 'STV',		LabelMedium : 'STV',				LabelLong : 'Scottish Television' },
		ReleaseNetworkSyfy	: { LabelShort : 'SYFY',	LabelMedium : 'SyFy',				LabelLong : 'SyFy' },
		ReleaseNetworkSysh	: { LabelShort : 'SYSH',	LabelMedium : 'Simply South',		LabelLong : 'Simply South' },
		ReleaseNetworkTbs	: { LabelShort : 'TBS',		LabelMedium : 'TBS',				LabelLong : 'Turner Broadcasting System' },
		ReleaseNetworkTcw	: { LabelShort : 'TCW',		LabelMedium : 'The CW',				LabelLong : 'The CBS and Warner Bros Network' },
		ReleaseNetworkTf1	: { LabelShort : 'TF1',		LabelMedium : 'TF1',				LabelLong : 'Télévision Française Une' },
		ReleaseNetworkTlsa	: { LabelShort : 'TLSA',	LabelMedium : 'Telasa',				LabelLong : 'Telasa' },
		ReleaseNetworkTnct	: { LabelShort : 'TNCT',	LabelMedium : 'Tencent',			LabelLong : 'Tencent Video' },
		ReleaseNetworkTnkt	: { LabelShort : 'TNKT',	LabelMedium : 'Tentkotta',			LabelLong : 'Tentkotta' },
		ReleaseNetworkTnt	: { LabelShort : 'TNT',		LabelMedium : 'TNT',				LabelLong : 'Turner Network Television' },
		ReleaseNetworkTubi	: { LabelShort : 'TUBI',	LabelMedium : 'Tubi',				LabelLong : 'Tubi' },
		ReleaseNetworkTvng	: { LabelShort : 'TVNG',	LabelMedium : 'Tving',				LabelLong : 'Tving' },
		ReleaseNetworkTvnz	: { LabelShort : 'TVNZ',	LabelMedium : 'TVNZ',				LabelLong : 'Television New Zealand' },
		ReleaseNetworkUsa	: { LabelShort : 'USA',		LabelMedium : 'USA Network',		LabelLong : 'USA Network' },
		ReleaseNetworkVh1	: { LabelShort : 'VH1',		LabelMedium : 'VH1',				LabelLong : 'Video Hits One' },
		ReleaseNetworkVido	: { LabelShort : 'VIDO',	LabelMedium : 'Vidio',				LabelLong : 'Vidio' },
		ReleaseNetworkVimx	: { LabelShort : 'VIMX',	LabelMedium : 'Vivamax',			LabelLong : 'Vivamax' },
		ReleaseNetworkVipy	: { LabelShort : 'VIPY',	LabelMedium : 'Viaplay',			LabelLong : 'Viaplay' },
		ReleaseNetworkViu	: { LabelShort : 'VIU',		LabelMedium : 'Viu',				LabelLong : 'Viu' },
		ReleaseNetworkWetv	: { LabelShort : 'WETV',	LabelMedium : 'WeTV',				LabelLong : 'Tencent WeTV' },
		ReleaseNetworkWtch	: { LabelShort : 'WTCH',	LabelMedium : 'Watcha',				LabelLong : 'Watcha' },
		ReleaseNetworkYoku	: { LabelShort : 'YOKU',	LabelMedium : 'Youku',				LabelLong : 'Youku' },
		ReleaseNetworkYtb	: { LabelShort : 'YTB',		LabelMedium : 'YouTube',			LabelLong : 'YouTube' },
		ReleaseNetworkZee	: { LabelShort : 'ZEE',		LabelMedium : 'ZEE',				LabelLong : 'ZEE5' },
		ReleaseNetworkZdf	: { LabelShort : 'ZDF',		LabelMedium : 'ZDF',				LabelLong : 'Zweites Deutsches Fernsehen' },

		ReleaseNetworkAbma	: { LabelShort : 'ABMA',	LabelMedium : 'Abema',				LabelLong : 'Abema' },
		ReleaseNetworkAdn	: { LabelShort : 'ADN',		LabelMedium : 'ADN',				LabelLong : 'Anime Digital Network' },
		ReleaseNetworkAnmx	: { LabelShort : 'ANMX',	LabelMedium : 'Animax',				LabelLong : 'Animax' },
		ReleaseNetworkAntx	: { LabelShort : 'ANTX',	LabelMedium : 'Anime Theatre X',	LabelLong : 'Anime Theatre X' },
		ReleaseNetworkAmog	: { LabelShort : 'AMOG',	LabelMedium : 'Anime Onegai',		LabelLong : 'Anime Onegai' },
		ReleaseNetworkAsbc	: { LabelShort : 'ASBC',	LabelMedium : 'ASBC',				LabelLong : 'Asahi Broadcasting Corporation' },
		ReleaseNetworkBhmt	: { LabelShort : 'BHMT',	LabelMedium : 'Bahamut',			LabelLong : 'Bahamut Animation Madness' },
		ReleaseNetworkBlbl	: { LabelShort : 'BLBL',	LabelMedium : 'Bilibili',			LabelLong : 'Bilibili' },
		ReleaseNetworkBspm	: { LabelShort : 'BSPM',	LabelMedium : 'BS Premium',			LabelLong : 'NHK BS Premium' },
		ReleaseNetworkBsnt	: { LabelShort : 'BSNT',	LabelMedium : 'BS Nippon',			LabelLong : 'BS4 Nippon TV' },
		ReleaseNetworkBsta	: { LabelShort : 'BSTA',	LabelMedium : 'BS Asahi',			LabelLong : 'BS5 TV Asahi' },
		ReleaseNetworkBsts	: { LabelShort : 'BSTS',	LabelMedium : 'BS TBS',				LabelLong : 'BS6 Tokyo Broadcasting System' },
		ReleaseNetworkBstt	: { LabelShort : 'BSTT',	LabelMedium : 'BS Tokyo',			LabelLong : 'BS7 TV Tokyo Corporation' },
		ReleaseNetworkBsfj	: { LabelShort : 'BSFJ',	LabelMedium : 'BS Fuji',			LabelLong : 'BS8 Fuji Network System' },
		ReleaseNetworkBsnb	: { LabelShort : 'BSNB',	LabelMedium : 'BS Eleven',			LabelLong : 'BS11 Nippon BS Broadcasting' },
		ReleaseNetworkBswh	: { LabelShort : 'BSWH',	LabelMedium : 'BS Twelve',			LabelLong : 'BS12 World High Vision Channel' },
		ReleaseNetworkCyrl	: { LabelShort : 'CYRL',	LabelMedium : 'Crunchyroll',		LabelLong : 'Crunchyroll' },
		ReleaseNetworkDmm	: { LabelShort : 'DMM',		LabelMedium : 'DMM',				LabelLong : 'Digital Media Mart' },
		ReleaseNetworkFjtv	: { LabelShort : 'FJTV',	LabelMedium : 'Fuji TV',			LabelLong : 'Fuji TV' },
		ReleaseNetworkFjto	: { LabelShort : 'FJTO',	LabelMedium : 'Fuji TV One',		LabelLong : 'Fuji TV One' },
		ReleaseNetworkFjod	: { LabelShort : 'FJOD',	LabelMedium : 'Fuji On Demand',		LabelLong : 'Fuji TV On Demand' },
		ReleaseNetworkFmtn	: { LabelShort : 'FMTN',	LabelMedium : 'Funimation',			LabelLong : 'Funimation' },
		ReleaseNetworkHdve	: { LabelShort : 'HDVE',	LabelMedium : 'Hidive',				LabelLong : 'Hidive' },
		ReleaseNetworkKab	: { LabelShort : 'KAB',		LabelMedium : 'KAB',				LabelLong : 'Kyushu Asahi Broadcasting' },
		ReleaseNetworkLmno	: { LabelShort : 'LMNO',	LabelMedium : 'Lemino',				LabelLong : 'Lemino' },
		ReleaseNetworkMotv	: { LabelShort : 'MOTV',	LabelMedium : 'Music On',			LabelLong : 'Music On TV' },
		ReleaseNetworkNhkg	: { LabelShort : 'NHKG',	LabelMedium : 'NHK General',		LabelLong : 'NHK General TV' },
		ReleaseNetworkNhke	: { LabelShort : 'NHKE',	LabelMedium : 'NHK Education',		LabelLong : 'NHK Education TV' },
		ReleaseNetworkNptv	: { LabelShort : 'NPTV',	LabelMedium : 'Nippon TV',			LabelLong : 'Nippon TV' },
		ReleaseNetworkTbst	: { LabelShort : 'TBST',	LabelMedium : 'TBS TV',				LabelLong : 'TBS Television' },
		ReleaseNetworkTvas	: { LabelShort : 'TVAS',	LabelMedium : 'TV Asahi',			LabelLong : 'TV Asahi' },
		ReleaseNetworkTvac	: { LabelShort : 'TVAC',	LabelMedium : 'TV Asahi 1',			LabelLong : 'TV Asahi Channel 1' },
		ReleaseNetworkTver	: { LabelShort : 'TVER',	LabelMedium : 'TVer',				LabelLong : 'TVer' },
		ReleaseNetworkTvty	: { LabelShort : 'TVTY',	LabelMedium : 'TV Tokyo',			LabelLong : 'TV Tokyo' },
		ReleaseNetworkTymx	: { LabelShort : 'TYMX',	LabelMedium : 'Tokyo MX',			LabelLong : 'Tokyo MX' },
		ReleaseNetworkUnxt	: { LabelShort : 'UNXT',	LabelMedium : 'U-Next',				LabelLong : 'U-Next' },
		ReleaseNetworkWknm	: { LabelShort : 'WKNM',	LabelMedium : 'Wakanim',			LabelLong : 'Wakanim' },
		ReleaseNetworkWowo	: { LabelShort : 'WOWO',	LabelMedium : 'Wowow',				LabelLong : 'Wowow' },
		ReleaseNetworkYrtv	: { LabelShort : 'YRTV',	LabelMedium : 'Yomiuri TV',			LabelLong : 'Yomiuri TV' },
	}

	OrderReleaseNetwork = {
		ReleaseNetwork7pls	: { OrderInterface : 1,		OrderSorting : 500 },
		ReleaseNetwork9now	: { OrderInterface : 2,		OrderSorting : 500 },
		ReleaseNetwork10py	: { OrderInterface : 3,		OrderSorting : 500 },
		ReleaseNetworkAbc	: { OrderInterface : 4,		OrderSorting : 200 },
		ReleaseNetworkAbma	: { OrderInterface : 5,		OrderSorting : 600 },
		ReleaseNetworkAdn	: { OrderInterface : 6,		OrderSorting : 600 },
		ReleaseNetworkAtsm	: { OrderInterface : 7,		OrderSorting : 300 },
		ReleaseNetworkAha	: { OrderInterface : 8,		OrderSorting : 500 },
		ReleaseNetworkAtbj	: { OrderInterface : 9,		OrderSorting : 500 },
		ReleaseNetworkAmzn	: { OrderInterface : 10,	OrderSorting : 2 },
		ReleaseNetworkAmc	: { OrderInterface : 11,	OrderSorting : 200 },
		ReleaseNetworkAnmx	: { OrderInterface : 12,	OrderSorting : 600 },
		ReleaseNetworkAmog	: { OrderInterface : 13,	OrderSorting : 600 },
		ReleaseNetworkAntx	: { OrderInterface : 14,	OrderSorting : 600 },
		ReleaseNetworkAppl	: { OrderInterface : 15,	OrderSorting : 3 },
		ReleaseNetworkArd	: { OrderInterface : 16,	OrderSorting : 300 },
		ReleaseNetworkAsbc	: { OrderInterface : 17,	OrderSorting : 600 },
		ReleaseNetworkAtrs	: { OrderInterface : 18,	OrderSorting : 500 },
		ReleaseNetworkAubc	: { OrderInterface : 19,	OrderSorting : 200 },
		ReleaseNetworkBhmt	: { OrderInterface : 20,	OrderSorting : 600 },
		ReleaseNetworkBbc	: { OrderInterface : 21,	OrderSorting : 10 },
		ReleaseNetworkBlbl	: { OrderInterface : 22,	OrderSorting : 600 },
		ReleaseNetworkBnge	: { OrderInterface : 23,	OrderSorting : 500 },
		ReleaseNetworkBms	: { OrderInterface : 24,	OrderSorting : 500 },
		ReleaseNetworkBmrg	: { OrderInterface : 25,	OrderSorting : 500 },
		ReleaseNetworkBtbx	: { OrderInterface : 26,	OrderSorting : 200 },
		ReleaseNetworkBsta	: { OrderInterface : 27,	OrderSorting : 600 },
		ReleaseNetworkBsnb	: { OrderInterface : 28,	OrderSorting : 600 },
		ReleaseNetworkBsfj	: { OrderInterface : 29,	OrderSorting : 600 },
		ReleaseNetworkBsnt	: { OrderInterface : 30,	OrderSorting : 600 },
		ReleaseNetworkBspm	: { OrderInterface : 31,	OrderSorting : 600 },
		ReleaseNetworkBsts	: { OrderInterface : 32,	OrderSorting : 600 },
		ReleaseNetworkBstt	: { OrderInterface : 33,	OrderSorting : 600 },
		ReleaseNetworkBswh	: { OrderInterface : 34,	OrderSorting : 600 },
		ReleaseNetworkCtnw	: { OrderInterface : 35,	OrderSorting : 200 },
		ReleaseNetworkCbc	: { OrderInterface : 36,	OrderSorting : 200 },
		ReleaseNetworkCbs	: { OrderInterface : 37,	OrderSorting : 200 },
		ReleaseNetworkCh4	: { OrderInterface : 38,	OrderSorting : 14 },
		ReleaseNetworkCh5	: { OrderInterface : 39,	OrderSorting : 15 },
		ReleaseNetworkCnmx	: { OrderInterface : 40,	OrderSorting : 16 },
		ReleaseNetworkClro	: { OrderInterface : 41,	OrderSorting : 500 },
		ReleaseNetworkCycl	: { OrderInterface : 42,	OrderSorting : 300 },
		ReleaseNetworkCrve	: { OrderInterface : 43,	OrderSorting : 500 },
		ReleaseNetworkCrtn	: { OrderInterface : 44,	OrderSorting : 300 },
		ReleaseNetworkCyrl	: { OrderInterface : 45,	OrderSorting : 999 },
		ReleaseNetworkDazn	: { OrderInterface : 46,	OrderSorting : 500 },
		ReleaseNetworkDcu	: { OrderInterface : 47,	OrderSorting : 700 },
		ReleaseNetworkDscy	: { OrderInterface : 48,	OrderSorting : 6 },
		ReleaseNetworkDsny	: { OrderInterface : 49,	OrderSorting : 4 },
		ReleaseNetworkDmm	: { OrderInterface : 50,	OrderSorting : 600 },
		ReleaseNetworkEpix	: { OrderInterface : 51,	OrderSorting : 500 },
		ReleaseNetworkEros	: { OrderInterface : 52,	OrderSorting : 500 },
		ReleaseNetworkEspn	: { OrderInterface : 53,	OrderSorting : 700 },
		ReleaseNetworkFbwh	: { OrderInterface : 54,	OrderSorting : 300 },
		ReleaseNetworkFox	: { OrderInterface : 55,	OrderSorting : 200 },
		ReleaseNetworkFxtl	: { OrderInterface : 56,	OrderSorting : 500 },
		ReleaseNetworkFrfm	: { OrderInterface : 57,	OrderSorting : 500 },
		ReleaseNetworkFubo	: { OrderInterface : 58,	OrderSorting : 500 },
		ReleaseNetworkFjod	: { OrderInterface : 59,	OrderSorting : 600 },
		ReleaseNetworkFjtv	: { OrderInterface : 60,	OrderSorting : 600 },
		ReleaseNetworkFjto	: { OrderInterface : 61,	OrderSorting : 600 },
		ReleaseNetworkFmtn	: { OrderInterface : 62,	OrderSorting : 600 },
		ReleaseNetworkGala	: { OrderInterface : 63,	OrderSorting : 500 },
		ReleaseNetworkGlbo	: { OrderInterface : 64,	OrderSorting : 500 },
		ReleaseNetworkGogl	: { OrderInterface : 65,	OrderSorting : 300 },
		ReleaseNetworkHbo	: { OrderInterface : 66,	OrderSorting : 5 },
		ReleaseNetworkHdve	: { OrderInterface : 67,	OrderSorting : 600 },
		ReleaseNetworkHsty	: { OrderInterface : 68,	OrderSorting : 13 },
		ReleaseNetworkHtsr	: { OrderInterface : 69,	OrderSorting : 300 },
		ReleaseNetworkHulu	: { OrderInterface : 70,	OrderSorting : 7 },
		ReleaseNetworkHngm	: { OrderInterface : 71,	OrderSorting : 500 },
		ReleaseNetworkIfc	: { OrderInterface : 72,	OrderSorting : 500 },
		ReleaseNetworkIflx	: { OrderInterface : 73,	OrderSorting : 500 },
		ReleaseNetworkIplr	: { OrderInterface : 74,	OrderSorting : 11 },
		ReleaseNetworkIqyi	: { OrderInterface : 75,	OrderSorting : 500 },
		ReleaseNetworkItns	: { OrderInterface : 76,	OrderSorting : 12 },
		ReleaseNetworkItv	: { OrderInterface : 77,	OrderSorting : 300 },
		ReleaseNetworkIviw	: { OrderInterface : 78,	OrderSorting : 500 },
		ReleaseNetworkIwtc	: { OrderInterface : 79,	OrderSorting : 500 },
		ReleaseNetworkJio	: { OrderInterface : 80,	OrderSorting : 500 },
		ReleaseNetworkKab	: { OrderInterface : 81,	OrderSorting : 600 },
		ReleaseNetworkLmno	: { OrderInterface : 82,	OrderSorting : 600 },
		ReleaseNetworkLftm	: { OrderInterface : 83,	OrderSorting : 500 },
		ReleaseNetworkLngt	: { OrderInterface : 84,	OrderSorting : 300 },
		ReleaseNetworkMnrm	: { OrderInterface : 85,	OrderSorting : 500 },
		ReleaseNetworkMgm	: { OrderInterface : 86,	OrderSorting : 300 },
		ReleaseNetworkMvar	: { OrderInterface : 87,	OrderSorting : 500 },
		ReleaseNetworkMtv	: { OrderInterface : 88,	OrderSorting : 200 },
		ReleaseNetworkMubi	: { OrderInterface : 89,	OrderSorting : 500 },
		ReleaseNetworkMotv	: { OrderInterface : 90,	OrderSorting : 600 },
		ReleaseNetworkMy5	: { OrderInterface : 91,	OrderSorting : 500 },
		ReleaseNetworkMytv	: { OrderInterface : 92,	OrderSorting : 500 },
		ReleaseNetworkNlgc	: { OrderInterface : 93,	OrderSorting : 200 },
		ReleaseNetworkNbc	: { OrderInterface : 94,	OrderSorting : 200 },
		ReleaseNetworkNtfx	: { OrderInterface : 95,	OrderSorting : 1 },
		ReleaseNetworkNhkg	: { OrderInterface : 96,	OrderSorting : 600 },
		ReleaseNetworkNhke	: { OrderInterface : 97,	OrderSorting : 600 },
		ReleaseNetworkNckn	: { OrderInterface : 98,	OrderSorting : 200 },
		ReleaseNetworkNptv	: { OrderInterface : 99,	OrderSorting : 600 },
		ReleaseNetworkNow	: { OrderInterface : 100,	OrderSorting : 500 },
		ReleaseNetworkNrk	: { OrderInterface : 101,	OrderSorting : 500 },
		ReleaseNetworkPrmt	: { OrderInterface : 102,	OrderSorting : 8 },
		ReleaseNetworkPbs	: { OrderInterface : 103,	OrderSorting : 200 },
		ReleaseNetworkPcok	: { OrderInterface : 104,	OrderSorting : 9 },
		ReleaseNetworkRktn	: { OrderInterface : 105,	OrderSorting : 500 },
		ReleaseNetworkRoku	: { OrderInterface : 106,	OrderSorting : 400 },
		ReleaseNetworkRlbp	: { OrderInterface : 107,	OrderSorting : 500 },
		ReleaseNetworkRte	: { OrderInterface : 108,	OrderSorting : 500 },
		ReleaseNetworkSana	: { OrderInterface : 109,	OrderSorting : 500 },
		ReleaseNetworkSbs	: { OrderInterface : 110,	OrderSorting : 500 },
		ReleaseNetworkShid	: { OrderInterface : 111,	OrderSorting : 500 },
		ReleaseNetworkShwt	: { OrderInterface : 112,	OrderSorting : 200 },
		ReleaseNetworkShdr	: { OrderInterface : 113,	OrderSorting : 300 },
		ReleaseNetworkSysh	: { OrderInterface : 114,	OrderSorting : 500 },
		ReleaseNetworkSky	: { OrderInterface : 115,	OrderSorting : 300 },
		ReleaseNetworkSony	: { OrderInterface : 116,	OrderSorting : 300 },
		ReleaseNetworkStan	: { OrderInterface : 117,	OrderSorting : 400 },
		ReleaseNetworkStrz	: { OrderInterface : 118,	OrderSorting : 200 },
		ReleaseNetworkStv	: { OrderInterface : 119,	OrderSorting : 500 },
		ReleaseNetworkSnxt	: { OrderInterface : 120,	OrderSorting : 500 },
		ReleaseNetworkSyfy	: { OrderInterface : 121,	OrderSorting : 300 },
		ReleaseNetworkTbs	: { OrderInterface : 122,	OrderSorting : 300 },
		ReleaseNetworkTbst	: { OrderInterface : 123,	OrderSorting : 600 },
		ReleaseNetworkTlsa	: { OrderInterface : 124,	OrderSorting : 600 },
		ReleaseNetworkTnct	: { OrderInterface : 125,	OrderSorting : 500 },
		ReleaseNetworkTnkt	: { OrderInterface : 126,	OrderSorting : 500 },
		ReleaseNetworkTf1	: { OrderInterface : 127,	OrderSorting : 300 },
		ReleaseNetworkTcw	: { OrderInterface : 128,	OrderSorting : 300 },
		ReleaseNetworkTnt	: { OrderInterface : 129,	OrderSorting : 300 },
		ReleaseNetworkTubi	: { OrderInterface : 130,	OrderSorting : 500 },
		ReleaseNetworkTvac	: { OrderInterface : 131,	OrderSorting : 600 },
		ReleaseNetworkTvas	: { OrderInterface : 132,	OrderSorting : 600 },
		ReleaseNetworkTver	: { OrderInterface : 133,	OrderSorting : 600 },
		ReleaseNetworkTvng	: { OrderInterface : 134,	OrderSorting : 500 },
		ReleaseNetworkTvnz	: { OrderInterface : 135,	OrderSorting : 400 },
		ReleaseNetworkTvty	: { OrderInterface : 136,	OrderSorting : 600 },
		ReleaseNetworkTymx	: { OrderInterface : 137,	OrderSorting : 600 },
		ReleaseNetworkUnxt	: { OrderInterface : 138,	OrderSorting : 600 },
		ReleaseNetworkUsa	: { OrderInterface : 139,	OrderSorting : 400 },
		ReleaseNetworkVh1	: { OrderInterface : 140,	OrderSorting : 400 },
		ReleaseNetworkVipy	: { OrderInterface : 141,	OrderSorting : 500 },
		ReleaseNetworkVido	: { OrderInterface : 142,	OrderSorting : 500 },
		ReleaseNetworkViu	: { OrderInterface : 143,	OrderSorting : 500 },
		ReleaseNetworkVimx	: { OrderInterface : 144,	OrderSorting : 500 },
		ReleaseNetworkWknm	: { OrderInterface : 145,	OrderSorting : 600 },
		ReleaseNetworkWtch	: { OrderInterface : 146,	OrderSorting : 500 },
		ReleaseNetworkWetv	: { OrderInterface : 147,	OrderSorting : 500 },
		ReleaseNetworkWowo	: { OrderInterface : 148,	OrderSorting : 600 },
		ReleaseNetworkYoku	: { OrderInterface : 149,	OrderSorting : 500 },
		ReleaseNetworkYrtv	: { OrderInterface : 150,	OrderSorting : 600 },
		ReleaseNetworkYtb	: { OrderInterface : 151,	OrderSorting : 400 },
		ReleaseNetworkZee	: { OrderInterface : 152,	OrderSorting : 500 },
		ReleaseNetworkZdf	: { OrderInterface : 153,	OrderSorting : 300 },
	}

	##############################################################################
	# RELEASE GROUP
	##############################################################################

	# The maximum number of release groups to extract.
	# Changing this value to 3 increases the execution time by 100%.
	# There are a few that have 3+ groups, but not worth the execution time.
	# On a high-end device: 3 groups = 18.76ms | 2 groups = 15.44ms | 1 group = 12.90ms | 0 groups = 9.68ms (when just returning None in releaseGroupExtract())
	ReleaseGroupCount = 2

	ExpressionReleaseGroup = {
		'keyword' : {
		},

		'expression' : (
			('eztv',						u'eztv'),
			('rarbg',						u'rarbg'),
			('tgx',							u'tgx'),
			('rartv',						u'rartv'),
			('msd',							u'msd'),
			('megusta',						u'megusta'),
			('afg',							u'afg'),
			('ntb',							u'ntb'),
			('ettv',						u'ettv'),
			('tbs',							u'tbs'),
			('evo',							u'evo'),
			('yify',						u'yify'),
			('yts',							u'(?:yts|yts{separator}+am|yts{separator}+lt|yts{separator}+ag)'),
			('ion10',						u'ion10'),
			('fgt',							u'fgt'),
			('killers',						u'killers'),
			('psa',							u'psa'),
			('lol',							u'lol'),
			('publichd',					u'publichd'),
			('crimson',						u'crimson'),
			('dimension',					u'dimension'),
			('sva',							u'sva'),
			('w4f',							u'w4f'),
			('mkvcage',						u'(?:mkvcage|mkvcage{separator}+ws)'),
			('utr',							u'utr'),
			('minx',						u'minx'),
			('rmteam',						u'rmteam'),
			('avs',							u'avs'),
			('ethd',						u'ethd'),
			('cmrg',						u'cmrg'),
			('extreme',						u'extreme'),
			('ntg',							u'ntg'),
			('prime',						u'prime'),
			('lostfilm',					u'lostfilm'),
			('bae',							u'bae'),
			('etrg',						u'etrg'),
			('caffeine',					u'caffeine'),
			('coldfilm',					u'coldfilm'),
			('vtv',							u'vtv'),
			('shaanig',						u'shaanig'),
			('kings',						u'kings'),
			('2hd',							u'2hd'),
			('phoenix',						u'phoenix'),
			('hurtom',						u'hurtom'),
			('galaxyrg',					u'galaxyrg'),
			('etmovies',					u'etmovies'),
			('amiable',						u'amiable'),
			('strife',						u'strife'),
			('n1c',							u'n1c'),
			('ideafilm',					u'ideafilm'),
			('max',							u'max'),
			('rbb',							u'rbb'),
			('newstudio',					u'newstudio'),
			('scarabey',					u'scarabey'),
			('vid',							u'vid'),
			('bamboozle',					u'bamboozle'),
			('amrap',						u'amrap'),
			('kingdom',						u'kingdom'),
			('xlf',							u'xlf'),
			('worldmkv',					u'worldmkv'),
			('mtb',							u'mtb'),
			('trump',						u'trump'),
			('metcon',						u'metcon'),
			('movcr',						u'movcr'),
			('nickarad',					u'nickarad'),
			('fum',							u'fum'),
			('cakes',						u'cakes'),
			('sparks',						u'sparks'),
			('fleet',						u'fleet'),
			('deflate',						u'deflate'),
			('ift',							u'ift'),
			('x0r',							u'x0r'),
			('mkvhub',						u'mkvhub'),
			('ic',							u'i{separator}+c'),
			('ddltv',						u'ddltv'),
			('fqm',							u'fqm'),
			('iextv',						u'iextv'),
			('telly',						u'telly'),
			('aaf',							u'aaf'),
			('id',							u'id'),
			('ddr',							u'ddr'),
			('qxr',							u'qxr'),
			('ozlem',						u'ozlem'),
			('joy',							u'joy'),
			('kit',							u'kit'),
			('maxrls',						u'maxrls'),
			('exkinoray',					u'exkinoray'),
			('asap',						u'asap'),
			('jaskier',						u'jaskier'),
			('geckos',						u'geckos'),
			('megapeer',					u'megapeer'),
			('zmnt',						u'zmnt'),
			('hon3y',						u'hon3y'),
			('kompost',						u'kompost'),
			('chd',							u'chd'),
			('ds',							u'ds'),
			('ctrlhd',						u'ctrlhd'),
			('ajp69',						u'ajp69'),
			('tigole',						u'tigole'),
			('monkee',						u'monkee'),
			('kogi',						u'kogi'),
			('syncopy',						u'syncopy'),
			('memento',						u'memento'),
			('mw',							u'mw'),
			('vxt',							u'vxt'),
			('man',							u'man'),
			('mircrew',						u'mircrew'),
			('rovers',						u'rovers'),
			('downloadhub',					u'downloadhub'),
			('regret',						u'regret'),
			('1xbet',						u'1xbet'),
			('reward',						u'reward'),
			('robots',						u'robots'),
			('drones',						u'drones'),
			('koshara',						u'koshara'),
			('batv',						u'batv'),
			('legi0n',						u'legi0n'),
			('dutchreleaseteam',			u'dutchreleaseteam'),
			('rg',							u'rg'),
			('qman',						u'qman'),
			('btn',							u'btn'),
			('wiki',						u'wiki'),
			('lucidtv',						u'lucidtv'),
			('qoq',							u'qoq'),
			('taoe',						u'taoe'),
			('gearsmedia',					u'gears{separator}+media'),
			('p2pdl',						u'p2pdl'),
			('glhf',						u'glhf'),
			('ghosts',						u'ghosts'),
			('sdi',							u'sdi'),
			('tepes',						u'tepes'),
			('baibako',						u'baibako'),
			('mp4ba',						u'mp4ba'),
			('linkle',						u'linkle'),
			('organic',						u'organic'),
			('dhd',							u'dhd'),
			('evolve',						u'evolve'),
			('ggwp',						u'ggwp'),
			('plutonium',					u'plutonium'),
			('ggez',						u'ggez'),
			('cookiemonster',				u'cookiemonster'),
			('loki',						u'loki'),
			('vppv',						u'vppv'),
			('bs',							u'bs'),
			('sadpanda',					u'sadpanda'),
			('gossip',						u'gossip'),
			('ganool',						u'ganool'),
			('yestv',						u'yestv'),
			('cc',							u'cc'),
			('tntvillage',					u'tntvillage'),
			('immerse',						u'immerse'),
			('hon3yhd',						u'hon3yhd'),
			('exclusive',					u'exclusive'),
			('casstudio',					u'casstudio'),
			('gopisahi',					u'(?:gopisahi|gopi{separator}+sahi)'),
			('love',						u'love'),
			('dmt',							u'dmt'),
			('sam',							u'sam'),
			('nogrp',						u'nogrp'),
			('convoy',						u'convoy'),
			('demand',						u'demand'),
			('hdclub',						u'hdclub'),
			('lazy',						u'lazy'),
			('cielos',						u'cielos'),
			('webtube',						u'webtube'),
			('elite',						u'elite'),
			('btx',							u'btx'),
			('lost',						u'lost'),
			('psychd',						u'psychd'),
			('strontium',					u'strontium'),
			('visum',						u'visum'),
			('agusiq',						u'agusiq'),
			('majestic',					u'majestic'),
			('ollandgroup',					u'ollandgroup'),
			('cm8',							u'cm8'),
			('zeiz',						u'zeiz'),
			('selezen',						u'selezen'),
			('d3g',							u'd3g'),
			('ranvijay',					u'ranvijay'),
			('vyndros',						u'vyndros'),
			('river',						u'river'),
			('mind',						u'mind'),
			('swtyblz',						u'swtyblz'),
			('mzabi',						u'mzabi'),
			('cravers',						u'cravers'),
			('ligate',						u'ligate'),
			('sigma',						u'sigma'),
			('crooks',						u'crooks'),
			('anoxmous',					u'anoxmous'),
			('2lions',						u'2lions'),
			('goki',						u'goki'),
			('full4movies',					u'full4movies'),
			('skgtv',						u'skgtv'),
			('mt',							u'mt'),
			('dtone',						u'dtone'),
			('hdrezka',						u'hdrezka'),
			('jyk',							u'jyk'),
			('waf',							u'waf'),
			('cbfm',						u'cbfm'),
			('1337x',						u'1337x'),
			('hivecm8',						u'(?:hive{separator}+cm8|hivecm8)'),
			('playnow',						u'playnow'),
			('esc',							u'esc'),
			('tla',							u'tla'),
			('baibakotv',					u'baibako{separator}+tv'),
			('axxo',						u'axxo'),
			('darkflix',					u'darkflix'),
			('alexfilm',					u'alexfilm'),
			('don',							u'don'),
			('grym',						u'grym'),
			('solar',						u'solar'),
			('srigga',						u'srigga'),
			('nhanc3',						u'nhanc3'),
			('trollhd',						u'trollhd'),
			('phunpsyz',					u'(?:phunpsyz|phun{separator}+psyz)'),
			('cinefile',					u'cinefile'),
			('black',						u'black'),
			('amcon',						u'amcon'),
			('rs',							u'rs'),
			('prof',						u'prof'),
			('sinners',						u'sinners'),
			('xred',						u'xred'),
			('tommy',						u'tommy'),
			('boop',						u'boop'),
			('home',						u'home'),
			('jaybob',						u'jaybob'),
			('st',							u'st'),
			('nlt',							u'nlt'),
			('mvo',							u'mvo'),
			('shadow',						u'shadow'),
			('katmoviehd',					u'(?:katmoviehd{separator}+me|katmoviehd)'),
			('fuzerhd',						u'fuzerhd'),
			('omskbird',					u'omskbird'),
			('ion',							u'ion'),
			('insidious',					u'insidious'),
			('eci',							u'eci'),
			('fllortv',						u'fllortv'),
			('hdchina',						u'hdchina'),
			('sev',							u'sev'),
			('cpg',							u'cpg'),
			('titan',						u'titan'),
			('turbo',						u'turbo'),
			('starz',						u'starz'),
			('junoon',						u'junoon'),
			('b4nd1t69',					u'b4nd1t69'),
			('vomit',						u'vomit'),
			('btw',							u'btw'),
			('ika',							u'ika'),
			('edhd',						u'edhd'),
			('vyto',						u'vyto'),
			('feelfree',					u'(?:feel{separator}+free|feelfree)'),
			('redblade',					u'redblade'),
			('millenium',					u'millenium'),
			('mkvcinemas',					u'mkvcinemas'),
			('yfn',							u'yfn'),
			('bg',							u'(?:bg|b{separator}+g)'),
			('tombdoc',						u'tombdoc'),
			('ar',							u'(?:a{separator}+r|ar)'),
			('stb',							u'stb'),
			('flx',							u'flx'),
			('aqos',						u'aqos'),
			('orenji',						u'orenji'),
			('bhrg',						u'bhrg'),
			('exyu',						u'exyu'),
			('bipolar',						u'bipolar'),
			('failed',						u'failed'),
			('brn',							u'brn'),
			('bdp',							u'bdp'),
			('llg',							u'llg'),
			('veto',						u'veto'),
			('dark',						u'dark'),
			('mors',						u'mors'),
			('ack',							u'ack'),
			('cr',							u'cr'),
			('novarip',						u'novarip'),
			('ss',							u'(?:ss|s{separator}+s)'),
			('sno',							u'sno'),
			('hybris',						u'hybris'),
			('flux',						u'flux'),
			('pahe',						u'(?:pahe|pahe{separator}+in)'),
			('ny2',							u'ny2'),
			('as',							u'(?:a{separator}+s|as)'),
			('amedia',						u'amedia'),
			('galaxytv',					u'galaxytv'),
			('ghouls',						u'ghouls'),
			('juggs',						u'juggs'),
			('rtn',							u'rtn'),
			('ghost',						u'ghost'),
			('hqclub',						u'hqclub'),
			('playxd',						u'playxd'),
			('sprinter',					u'sprinter'),
			('newsource',					u'new{separator}+source'),
			('cody',						u'cody'),
			('murder',						u'murder'),
			('kerob',						u'kerob'),
			('judas',						u'judas'),
			('cm',							u'cm'),
			('manning',						u'manning'),
			('arenabg',						u'arenabg'),
			('btdx8',						u'btdx8'),
			('paso77',						u'paso77'),
			('m2tv',						u'm2tv'),
			('ale13',						u'ale13'),
			('mhd',							u'mhd'),
			('ctu',							u'ctu'),
			('underbelly',					u'underbelly'),
			('fxg',							u'fxg'),
			('mindthegap',					u'mindthegap'),
			('down',						u'down'),
			('framestor',					u'framestor'),
			('blackbit',					u'blackbit'),
			('hevcbay',						u'hevcbay'),
			('mem',							u'mem'),
			('din',							u'din'),
			('hellywood',					u'hellywood'),
			('intention',					u'intention'),
			('fov',							u'fov'),
			('cadaver',						u'cadaver'),
			('devil',						u'devil'),
			('sujaidr',						u'sujaidr'),
			('revittony',					u'revittony'),
			('nt',							u'nt'),
			('noir',						u'noir'),
			('imagine',						u'imagine'),
			('state',						u'state'),
			('idncrew',						u'idn{separator}+crew'),
			('int',							u'int'),
			('pimprg',						u'pimprg'),
			('jive',						u'jive'),
			('pfa',							u'pfa'),
			('xrg',							u'xrg'),
			('mixed',						u'mixed'),
			('tr',							u'tr'),
			('mteam',						u'mteam'),
			('tvc',							u'tvc'),
			('deejayahmed',					u'deejayahmed'),
			('shortbrehd',					u'shortbrehd'),
			('brisk',						u'brisk'),
			('ebp',							u'ebp'),
			('comandotorrents',				u'comandotorrents'),
			('stuttershit',					u'stuttershit'),
			('nezu',						u'nezu'),
			('ssn',							u'ssn'),
			('usury',						u'usury'),
			('mrkeff',						u'mr{separator}+keff'),
			('d0ct0rlew',					u'd0ct0rlew'),
			('santi',						u'santi'),
			('sneaky',						u'sneaky'),
			('tastetv',						u'tastetv'),
			('sys',							u'sys'),
			('vip3r',						u'vip3r'),
			('divxnl',						u'divxnl'),
			('c4tv',						u'c4tv'),
			('highcode',					u'highcode'),
			('inferno',						u'inferno'),
			('tvsmash',						u'tvsmash'),
			('26k',							u'26k'),
			('abm',							u'abm'),
			('notv',						u'notv'),
			('rapta',						u'rapta'),
			('ltt',							u'ltt'),
			('guacamole',					u'guacamole'),
			('nydic',						u'nydic'),
			('venue',						u'venue'),
			('saints',						u'saints'),
			('getit',						u'getit'),
			('threesixtyp',					u'threesixtyp'),
			('ime',							u'ime'),
			('sbr',							u'sbr'),
			('librarians',					u'librarians'),
			('nodlabs',						u'nodlabs'),
			('heat',						u'heat'),
			('unique',						u'unique'),
			('nahom',						u'nahom'),
			('dascubadude',					u'dascubadude'),
			('playsd',						u'playsd'),
			('rick',						u'rick'),
			('nitro',						u'nitro'),
			('inspiral',					u'inspiral'),
			('mafiaking',					u'mafiaking'),
			('mpup',						u'mpup'),
			('diamond',						u'diamond'),
			('moviesfd',					u'moviesfd'),
			('fun',							u'fun'),
			('blow',						u'blow'),
			('cinecalidad',					u'cinecalidad'),
			('maxspeed',					u'maxspeed'),
			('meguil',						u'meguil'),
			('ice',							u'ice'),
			('hdt',							u'hdt'),
			('avchd',						u'avchd'),
			('walmart',						u'walmart'),
			('hdrezkastudio',				u'hdrezka{separator}+studio'),
			('viethd',						u'viethd'),
			('hdsector',					u'hdsector'),
			('lord',						u'lord'),
			('ptpower',						u'ptpower'),
			('barc0de',						u'barc0de'),
			('jmt',							u'jmt'),
			('geekrg',						u'geekrg'),
			('divxnlteam',					u'divxnl{separator}+team'),
			('glowgaze',					u'(?:glowgaze{separator}+com|glowgaze)'),
			('justiso',						u'justiso'),
			('spooks',						u'spooks'),
			('hdlight',						u'hdlight'),
			('sunshinestudio',				u'(?:sunshine{separator}+studio|sunshinestudio)'),
			('nixon',						u'nixon'),
			('mars',						u'mars'),
			('fihtv',						u'fihtv'),
			('tjet',						u'tjet'),
			('rusted',						u'rusted'),
			('newteam',						u'(?:new{separator}+team|newteam)'),
			('xpau',						u'xpau'),
			('wbz',							u'wbz'),
			('npw',							u'npw'),
			('ltn',							u'ltn'),
			('hd4u',						u'hd4u'),
			('bida',						u'bida'),
			('bajskorv',					u'bajskorv'),
			('tvp',							u'tvp'),
			('eve',							u'eve'),
			('phenomenal',					u'phenomenal'),
			('adit',						u'adit'),
			('nfofix',						u'nfofix'),
			('mrn',							u'mrn'),
			('phr0sty',						u'phr0sty'),
			('japhson',						u'japhson'),
			('peculate',					u'peculate'),
			('nvee',						u'nvee'),
			('hds',							u'hds'),
			('zaeem',						u'zaeem'),
			('kettle',						u'kettle'),
			('fraternity',					u'fraternity'),
			('3lt0n',						u'3lt0n'),
			('buymore',						u'buymore'),
			('siso',						u'siso'),
			('utt',							u'utt'),
			('extramovies',					u'extramovies'),
			('bluworld',					u'bluworld'),
			('torrentcounter',				u'torrentcounter'),
			('sfm',							u'sfm'),
			('ttl',							u'ttl'),
			('poop',						u'poop'),
			('sic',							u'sic'),
			('snake',						u'snake'),
			('b2b',							u'b2b'),
			('exyusubs',					u'exyusubs'),
			('ms',							u'(?:ms|m{separator}+s)'),
			('kralimarko',					u'kralimarko'),
			('silver007',					u'silver007'),
			('crime',						u'crime'),
			('uav',							u'uav'),
			('ictv',						u'ictv'),
			('gwc',							u'gwc'),
			('istance',						u'istance'),
			('leonardo',					u'leonardo'),
			('ftp',							u'ftp'),
			('psig',						u'psig'),
			('coot',						u'coot'),
			('bone',						u'bone'),
			('armor',						u'armor'),
			('hdetg',						u'hdetg'),
			('inspirit',					u'inspirit'),
			('octopus',						u'octopus'),
			('trl',							u'trl'),
			('fico',						u'fico'),
			('nemo',						u'nemo'),
			('terminal',					u'terminal'),
			('hdc',							u'hdc'),
			('rutracker',					u'rutracker'),
			('nhd',							u'nhd'),
			('foxm',						u'foxm'),
			('top',							u'top'),
			('goodpeople',					u'good{separator}+people'),
			('naisu',						u'naisu'),
			('lokihd',						u'lokihd'),
			('p2p',							u'p2p'),
			('moviesbyrizzo',				u'moviesbyrizzo'),
			('align',						u'align'),
			('yg',							u'yg'),
			('elitetorrent',				u'(?:www{separator}+elitetorrent{separator}+biz|elitetorrent)'),
			('lkrg',						u'lkrg'),
			('finale',						u'finale'),
			('rpg',							u'rpg'),
			('saicord',						u'saicord'),
			('diversity',					u'diversity'),
			('bt',							u'bt'),
			('drstar',						u'dr{separator}+star'),
			('playhd',						u'playhd'),
			('dot',							u'dot'),
			('deadpool',					u'deadpool'),
			('brmp',						u'brmp'),
			('associate',					u'associate'),
			('alliance',					u'alliance'),
			('gillop',						u'gillop'),
			('fookas',						u'fookas'),
			('mulvacoded',					u'mulvacoded'),
			('esir',						u'esir'),
			('qpel',						u'qpel'),
			('lgc',							u'lgc'),
			('icvmircrew',					u'icv{separator}+mircrew'),
			('drsi',						u'drsi'),
			('portablius',					u'portablius'),
			('west',						u'west'),
			('morpheus',					u'morpheus'),
			('haggis',						u'haggis'),
			('rtm',							u'rtm'),
			('epsilon',						u'epsilon'),
			('magic',						u'magic'),
			('cytsunee',					u'cytsunee'),
			('taste',						u'taste'),
			('goenwae',						u'goenwae'),
			('filmanta',					u'filmanta'),
			('mysilu',						u'mysilu'),
			('arrow',						u'arrow'),
			('xor',							u'xor'),
			('nnm',							u'nnm'),
			('makintos13',					u'makintos13'),
			('seriously',					u'seriously'),
			('c1nem4',						u'c1nem4'),
			('pimp4003',					u'pimp4003'),
			('wwrg',						u'wwrg'),
			('it00nz',						u'it00nz'),
			('mrs',							u'mrs'),
			('qqss44',						u'qqss44'),
			('teamtr',						u'teamtr'),
			('cocain',						u'cocain'),
			('lion',						u'lion'),
			('hud',							u'hud'),
			('nedivx',						u'nedivx'),
			('aaa',							u'aaa'),
			('epz',							u'epz'),
			('duqa',						u'duqa'),
			('will1869',					u'will1869'),
			('lounge',						u'lounge'),
			('releaselounge',				u'release{separator}+lounge'),
			('cttv',						u'cttv'),
			('t4p3',						u't4p3'),
			('pignus',						u'pignus'),
			('momentum',					u'momentum'),
			('creed',						u'creed'),
			('wide',						u'wide'),
			('whosnext',					u'whosnext'),
			('3li',							u'3li'),
			('ans',							u'ans'),
			('hashminer',					u'hashminer'),
			('rmx',							u'rmx'),
			('epic',						u'epic'),
			('lpd',							u'lpd'),
			('wow',							u'wow'),
			('flawl3ss',					u'flawl3ss'),
			('moviezworldz',				u'moviezworldz'),
			('uump4',						u'uump4'),
			('nick',						u'nick'),
			('crewsade',					u'crewsade'),
			('cyber',						u'cyber'),
			('xpoz',						u'xpoz'),
			('getb8',						u'getb8'),
			('wrcr',						u'wrcr'),
			('fragment',					u'fragment'),
			('bia',							u'bia'),
			('dawn',						u'dawn'),
			('empire',						u'empire'),
			('nogroup',						u'nogroup'),
			('qcf',							u'qcf'),
			('trolluhd',					u'trolluhd'),
			('coo7',						u'coo7'),
			('nnmclub',						u'nnmclub'),
			('axed',						u'axed'),
			('psypher',						u'psypher'),
			('monster',						u'monster'),
			('mgb',							u'mgb'),
			('multiply',					u'multiply'),
			('hrdr',						u'hr{separator}+dr'),
			('ark01',						u'ark01'),
			('theory',						u'theory'),
			('rbg',							u'rbg'),
			('bob',							u'bob'),
			('siriusshare',					u'sirius{separator}+share'),
			('brshnkv',						u'brshnkv'),
			('phobos',						u'phobos'),
			('noscreens',					u'noscreens'),
			('klingon',						u'klingon'),
			('vain',						u'vain'),
			('aa',							u'(?:aa|\~aa\~)'),
			('iguana',						u'iguana'),
			('rx',							u'rx'),
			('exploit',						u'exploit'),
			('riprg',						u'riprg'),
			('99mp4',						u'99mp4'),
			('acool',						u'acool'),
			('seehd',						u'seehd'),
			('extratorrentrg',				u'extratorrentrg'),
			('bluebird',					u'bluebird'),
			('friends',						u'friends'),
			('skorpion',					u'skorpion'),
			('lapumia',						u'lapumia'),
			('maxx',						u'maxx'),
			('zeus',						u'zeus'),
			('stvfrv',						u'stvfrv'),
			('legend',						u'legend'),
			('domino',						u'domino'),
			('yellowbird',					u'yellowbird'),
			('greenbud1969',				u'greenbud1969'),
			('rob',							u'rob'),
			('god',							u'god'),
			('target',						u'target'),
			('flame',						u'flame'),
			('ascendance',					u'ascendance'),
			('sonido',						u'sonido'),
			('zen',							u'zen'),
			('ind',							u'ind'),
			('dream',						u'dream'),
			('poke',						u'poke'),
			('exd',							u'exd'),
			('o69',							u'o69'),
			('mkvtv',						u'(?:mkvtv|mkvtv{separator}+net)'),
			('tvd',							u'tvd'),
			('prodji',						u'prodji'),
			('silence',						u'silence'),
			('pseudo',						u'pseudo'),
			('dracula',						u'dracula'),
			('rdx',							u'rdx'),
			('yol0w',						u'yol0w'),
			('silent',						u'silent'),
			('intenso',						u'intenso'),
			('acab',						u'acab'),
			('beast',						u'beast'),
			('exvid',						u'exvid'),
			('truavc',						u'truavc'),
			('sartre',						u'sartre'),
			('hdmaniacs',					u'hdmaniacs'),
			('goodfilms',					u'goodfilms'),
			('atlas47',						u'atlas47'),
			('blackhat',					u'blackhat'),
			('bonsai',						u'bonsai'),
			('wolf',						u'wolf'),
			('byme7alh',					u'byme7alh'),
			('excellence',					u'excellence'),
			('lf',							u'(?:lf|l{separator}+f)'),
			('rb58',						u'rb58'),
			('uranime',						u'uranime'),
			('ill',							u'ill'),
			('melite',						u'melite'),
			('ent',							u'ent'),
			('plzproper',					u'plzproper'),
			('tk',							u'tk'),
			('heteam',						u'heteam'),
			('tb',							u'tb'),
			('alterego',					u'alterego'),
			('bozx',						u'bozx'),
			('0tv',							u'0tv'),
			('condo',						u'condo'),
			('cnscg',						u'cnscg'),
			('sp33dy94',					u'sp33dy94'),
			('oosh',						u'oosh'),
			('omikron',						u'omikron'),
			('cinemania',					u'cinemania'),
			('intgrity',					u'intgrity'),
			('morose',						u'morose'),
			('snow',						u'snow'),
			('rd',							u'rd'),
			('musafirboy',					u'musafirboy'),
			('phd',							u'phd'),
			('tomcat12',					u'tomcat12'),
			('jrr',							u'jrr'),
			('master5',						u'master5'),
			('depth',						u'depth'),
			('horizon',						u'horizon'),
			('simple',						u'simple'),
			('sticky83',					u'sticky83'),
			('eps',							u'eps'),
			('erev',						u'e{separator}+rev'),
			('hunter',						u'hunter'),
			('justwatch',					u'justwatch'),
			('pure',						u'pure'),
			('vector',						u'vector'),
			('stars',						u'stars'),
			('futv',						u'futv'),
			('force',						u'force'),
			('flash',						u'flash'),
			('storm',						u'storm'),
			('eagle',						u'eagle'),
			('eniahd',						u'eniahd'),
			('klio',						u'klio'),
			('hdwing',						u'hdwing'),
			('trtdteam',					u'trtd{separator}+team'),
			('t0m',							u't0m'),
			('hillary',						u'hillary'),
			('secretmyth',					u'secretmyth'),
			('gs',							u'gs'),
			('prince',						u'prince'),
			('an0nym0us',					u'an0nym0us'),
			('nosivid',						u'nosivid'),
			('creepshow',					u'creepshow'),
			('ddb',							u'ddb'),
			('liberty',						u'liberty'),
			('rakuvfinhel',					u'rakuvfinhel'),
			('queens',						u'queens'),
			('kk650',						u'kk650'),
			('ons',							u'ons'),
			('unveil',						u'unveil'),
			('edge',						u'edge'),
			('maximersk',					u'maximersk'),
			('uniongang',					u'uniongang'),
			('hazmatt',						u'hazmatt'),
			('heel',						u'heel'),
			('7sins',						u'7sins'),
			('elektri4ka',					u'elektri4ka'),
			('crys',						u'crys'),
			('bb',							u'bb'),
			('iamable',						u'iamable'),
			('dz0n3',						u'd{separator}+z0n3'),
			('moritz',						u'moritz'),
			('done',						u'done'),
			('rough',						u'rough'),
			('alfahd',						u'alfahd'),
			('chamele0n',					u'chamele0n'),
			('deal',						u'deal'),
			('lifetime',					u'lifetime'),
			('iplayertv',					u'iplayertv'),
			('omifast',						u'omifast'),
			('archivist',					u'archivist'),
			('batman',						u'batman'),
			('break',						u'break'),
			('prod',						u'prod'),
			('gungrave',					u'gungrave'),
			('pristine',					u'pristine'),
			('ewdp',						u'ewdp'),
			('clue',						u'clue'),
			('remarkable',					u'remarkable'),
			('novalan',						u'novalan'),
			('txb',							u'txb'),
			('rev',							u'rev'),
			('cinefeel',					u'cinefeel'),
			('ysteam',						u'ysteam'),
			('roflcopter2110',				u'roflcopter2110'),
			('alien',						u'alien'),
			('xv',							u'xv'),
			('ys',							u'ys'),
			('absurdity',					u'absurdity'),
			('artsubs',						u'artsubs'),
			('nes',							u'nes'),
			('mag',							u'mag'),
			('dalemake',					u'dalemake'),
			('webster',						u'webster'),
			('hdh',							u'hdh'),
			('horizonartsubs',				u'horizon{separator}+artsubs'),
			('57chan',						u'57chan'),
			('shortrips',					u'shortrips'),
			('teamhd',						u'teamhd'),
			('tbd',							u'tbd'),
			('fever',						u'fever'),
			('spamtv',						u'spamtv'),
			('ssdd',						u'ssdd'),
			('silverrg',					u'silver{separator}+rg'),
			('resistance',					u'resistance'),
			('jcgoku21',					u'jcgoku21'),
			('hidt',						u'hidt'),
			('psix',						u'psix'),
			('ods',							u'ods'),
			('bx',							u'bx'),
			('sunscreen',					u'sunscreen'),
			('history',						u'history'),
			('deprived',					u'deprived'),
			('t6d',							u't6d'),
			('mayhem',						u'mayhem'),
			('authority',					u'authority'),
			('paddo',						u'paddo'),
			('zoneempire',					u'zone{separator}+empire'),
			('rcvr',						u'rcvr'),
			('legion',						u'legion'),
			('secretos',					u'secretos'),
			('bhd',							u'bhd'),
			('rmt',							u'rmt'),
			('r2d2',						u'r2d2'),
			('nikt0',						u'nikt0'),
			('ozzy1',						u'ozzy1'),
			('tugazx',						u'tugazx'),
			('eider',						u'eider'),
			('ngp',							u'ngp'),
			('krave',						u'krave'),
			('nextbit',						u'nextbit'),
			('preums',						u'preums'),
			('leon',						u'leon'),
			('poolla',						u'poolla'),
			('kamikaze',					u'kamikaze'),
			('speranzah',					u'speranzah'),
			('med',							u'med'),
			('gly',							u'gly'),
			('kickfoot',					u'kickfoot'),
			('dirt',						u'dirt'),
			('empathy',						u'empathy'),
			('icmal',						u'icmal'),
			('afi',							u'afi'),
			('kid',							u'kid'),
			('wman',						u'wman'),
			('tayto',						u'tayto'),
			('notag',						u'notag'),
			('paleale',						u'paleale'),
			('homefei',						u'homefei'),
			('hisd',						u'hisd'),
			('tusahd',						u'tusahd'),
			('rockblueladyrg',				u'(?:rockblueladyrg|rock\&blueladyrg)'),
			('iahd',						u'iahd'),
			('getschwifty',					u'getschwifty'),
			('kotuwa',						u'kotuwa'),
			('replica',						u'replica'),
			('imsamirofficial',				u'imsamirofficial'),
			('ingot',						u'ingot'),
			('catch',						u'catch'),
			('mxmg',						u'mxmg'),
			('ronin',						u'(?:ron\!n|ronin)'),
			('zektorm',						u'zektorm'),
			('p0w4',						u'p0w4'),
			('phase',						u'phase'),
			('pc',							u'pc'),
			('eie',							u'eie'),
			('aniurl',						u'aniurl'),
			('rofl',						u'rofl'),
			('carpediem',					u'carpediem'),
			('webtiful',					u'webtiful'),
			('rumour',						u'rumour'),
			('criminal',					u'criminal'),
			('blitzkrieg',					u'blitzkrieg'),
			('panda',						u'panda'),
			('aymo',						u'aymo'),
			('fiasco',						u'fiasco'),
			('rdlinks',						u'rdlinks'),
			('ff',							u'ff'),
			('anarchy',						u'anarchy'),
			('brazino777',					u'brazino777'),
			('s4a',							u's4a'),
			('tvs',							u'tvs'),
			('cro',							u'cro'),
			('mo',							u'm{separator}+o'),
			('korsar',						u'korsar'),
			('phantom',						u'phantom'),
			('cyd',							u'cyd'),
			('tne',							u'tne'),
			('ide',							u'ide'),
			('uktv',						u'uktv'),
			('sharpysword',					u'sharpysword'),
			('zero',						u'zero'),
			('wutang',						u'wutang'),
			('tinymkv',						u'tinymkv'),
			('law',							u'law'),
			('ea',							u'ea'),
			('saphire',						u'saphire'),
			('pophd',						u'pophd'),
			('cht',							u'cht'),
			('thunder',						u'thunder'),
			('xf',							u'xf'),
			('zenbud',						u'zen{separator}+bud'),
			('peruguy',						u'peruguy'),
			('mf',							u'(?:mf|m{separator}+f)'),
			('speed',						u'speed'),
			('pbk',							u'pbk'),
			('ember',						u'ember'),
			('0sec',						u'0sec'),
			('daddy',						u'daddy'),
			('turg',						u'turg'),
			('roccat',						u'roccat'),
			('rekode',						u'rekode'),
			('afm72',						u'afm72'),
			('keltz',						u'keltz'),
			('hp',							u'hp'),
			('moovee',						u'moovee'),
			('downrev',						u'downrev'),
			('taxes',						u'taxes'),
			('tree',						u'tree'),
			('h3llg0d',						u'h3llg0d'),
			('rzerox',						u'rzerox'),
			('ak',							u'(?:a{separator}+k|ak)'),
			('aglet',						u'aglet'),
			('topaz',						u'topaz'),
			('jedi',						u'jedi'),
			('petrified',					u'petrified'),
			('playweb',						u'playweb'),
			('sof',							u'sof'),
			('royskatt',					u'royskatt'),
			('matter',						u'matter'),
			('koenig',						u'koenig'),
			('welp',						u'welp'),
			('2dvd',						u'2dvd'),
			('bdc',							u'bdc'),
			('unit',						u'unit'),
			('monolith',					u'monolith'),
			('lchd',						u'lchd'),
			('dirty',						u'dirty'),
			('spirit',						u'spirit'),
			('circle',						u'circle'),
			('robin',						u'robin'),
			('ass',							u'(?:as{separator}+s|ass)'),
			('ifpd',						u'ifpd'),
			('exvidint',					u'exvidint'),
			('doc',							u'doc'),
			('hybrid',						u'hybrid'),
			('frost',						u'frost'),
			('24hd',						u'24hd'),
			('lee',							u'lee'),
			('machine',						u'machine'),
			('sp3ll',						u'sp3ll'),
			('sa89',						u'sa89'),
			('jane',						u'jane'),
			('badassmedia',					u'badassmedia'),
			('secrecy',						u'secrecy'),
			('deimos',						u'deimos'),
			('crisc',						u'crisc'),
			('itg',							u'itg'),
			('undercover',					u'undercover'),
			('ltrg',						u'ltrg'),
			('barge',						u'barge'),
			('wayne',						u'wayne'),
			('shitbox',						u'shitbox'),
			('invandraren',					u'invandraren'),
			('trial',						u'trial'),
			('kiss',						u'kiss'),
			('hdlite',						u'hdlite'),
			('lividity',					u'lividity'),
			('encounters',					u'encounters'),
			('bito',						u'bito'),
			('tlf',							u'tlf'),
			('e1',							u'e1'),
			('mrsk',						u'mrsk'),
			('titans',						u'titans'),
			('microflix',					u'microflix'),
			('chattchittorg',				u'chattchitto{separator}+rg'),
			('gti',							u'gti'),
			('kyr',							u'kyr'),
			('hwd',							u'hwd'),
			('funkky',						u'funkky'),
			('fxm',							u'fxm'),
			('tvbeasts',					u'tvbeasts'),
			('mrcs',						u'mrcs'),
			('rsg',							u'rsg'),
			('d3fil3r',						u'd3fil3r'),
			('ny',							u'ny'),
			('xii',							u'xii'),
			('mfo',							u'mfo'),
			('vlis',						u'vlis'),
			('warriors',					u'warriors'),
			('sons',						u'sons'),
			('retro',						u'retro'),
			('0ptimus',						u'0ptimus'),
			('sector7',						u'sector7'),
			('nik',							u'(?:n\!k|nik)'),
			('eureka',						u'eureka'),
			('maxpro',						u'maxpro'),
			('spacehd',						u'spacehd'),
			('kickass',						u'kickass'),
			('fanta',						u'fanta'),
			('coaster',						u'coaster'),
			('larceny',						u'larceny'),
			('daa',							u'daa'),
			('kaka',						u'kaka'),
			('webhiker',					u'webhiker'),
			('d3si',						u'd3si'),
			('resurrection',				u'resurrection'),
			('meteam',						u'meteam'),
			('relentless',					u'relentless'),
			('sa',							u's{separator}+a'),
			('ame',							u'ame'),
			('core',						u'core'),
			('mkvking',						u'mkvking'),
			('h2',							u'h2'),
			('hush',						u'hush'),
			('tvslices',					u'tvslices'),
			('nikoo',						u'nikoo'),
			('ouija',						u'ouija'),
			('infamous',					u'infamous'),
			('crf',							u'crf'),
			('bluury',						u'bluury'),
			('ash61',						u'ash61'),
			('meg',							u'meg'),
			('wind',						u'wind'),
			('srs',							u'srs'),
			('littledevil',					u'little{separator}+devil'),
			('sless',						u's{separator}+less'),
			('sight',						u'sight'),
			('7meiju',						u'7meiju'),
			('angelic',						u'angelic'),
			('topkek',						u'topkek'),
			('vlad',						u'vlad'),
			('uyirvani',					u'uyirvani'),
			('bigjazz',						u'bigjazz'),
			('realdmdj',					u'realdmdj'),
			('latency',						u'latency'),
			('lycan',						u'lycan'),
			('runner',						u'runner'),
			('lot',							u'lot'),
			('ptp',							u'ptp'),
			('oldseasons',					u'oldseasons'),
			('newartriot',					u'newartriot'),
			('aced',						u'aced'),
			('chdbits',						u'chdbits'),
			('rapidcows',					u'rapidcows'),
			('ilg',							u'ilg'),
			('c7b',							u'c7b'),
			('bokutox',						u'bokutox'),
			('lonewolf',					u'lonewolf'),
			('mvgroup',						u'(?:mvgroup|mvgroup{separator}+org)'),
			('nikonxp',						u'nikonxp'),
			('lumi',						u'lumi'),
			('abhisona',					u'abhisona'),
			('hornigold',					u'hornigold'),
			('30nama',						u'30nama'),
			('chronicles',					u'chronicles'),
			('stylishsalh',					u'stylishsalh'),
			('ben',							u'ben'),
			('republic',					u'republic'),
			('goape',						u'goape'),
			('ontherun',					u'ontherun'),
			('fratposa',					u'fratposa'),
			('hotlips',						u'hotlips'),
			('cz530',						u'cz530'),
			('sriz',						u'sriz'),
			('kira',						u'kira'),
			('besthd',						u'besthd'),
			('sin',							u'sin'),
			('pitu',						u'pitu'),
			('filmhd',						u'filmhd'),
			('lucifer22',					u'lucifer22'),
			('aida',						u'aida'),
			('reaper',						u'reaper'),
			('ig',							u'ig'),
			('hevcclub',					u'hevc{separator}+club'),
			('whip93',						u'whip93'),
			('watcher',						u'watcher'),
			('xyz',							u'xyz'),
			('aries',						u'aries'),
			('thor',						u'thor'),
			('nesmeured',					u'nesmeured'),
			('airtv',						u'airtv'),
			('hs',							u'(?:hs|h{separator}+s)'),
			('contribution',				u'contribution'),
			('af',							u'(?:a{separator}+f|af)'),
			('undead',						u'undead'),
			('imbt',						u'imbt'),
			('altezachen',					u'altezachen'),
			('hdi',							u'hdi'),
			('omicron',						u'omicron'),
			('nanban',						u'nanban'),
			('riddlera',					u'riddlera'),
			('abh',							u'abh'),
			('ignition',					u'ignition'),
			('illusion',					u'illusion'),
			('cryptic',						u'cryptic'),
			('freebee',						u'freebee'),
			('mutznutz',					u'mutznutz'),
			('ga',							u'ga'),
			('phoenixrg',					u'(?:phoenixrg|phoenix{separator}+rg)'),
			('scones',						u'scones'),
			('ink',							u'ink'),
			('vajnis',						u'vajnis'),
			('crystal',						u'crystal'),
			('deuterium',					u'deuterium'),
			('supernova',					u'supernova'),
			('multiplex',					u'multiplex'),
			('rifftrax',					u'rifftrax'),
			('rtfm',						u'rtfm'),
			('cake',						u'cake'),
			('ils',							u'ils'),
			('holiday',						u'holiday'),
			('hellraz0r',					u'hellraz0r'),
			('lordvako',					u'lordvako'),
			('sinister',					u'sinister'),
			('ulshd',						u'ulshd'),
			('scream',						u'scream'),
			('hifi',						u'hifi'),
			('dr3adlox',					u'dr3adlox'),
			('lmao',						u'lmao'),
			('bhdstudio',					u'bhdstudio'),
			('seskapile',					u'seskapile'),
			('fidelio',						u'fidelio'),
			('slay3r',						u'slay3r'),
			('compulsion',					u'compulsion'),
			('bestdivx',					u'bestdivx'),
			('itsat',						u'itsat'),
			('gopo',						u'gopo'),
			('teneighty',					u'teneighty'),
			('highcal',						u'highcal'),
			('menaceiisociety',				u'menaceiisociety'),
			('bt4k',						u'bt4k'),
			('esq',							u'esq'),
			('invincible',					u'(?:\~invincible|invincible)'),
			('marge',						u'marge'),
			('freethefish',					u'freethefish'),
			('ryan',						u'ryan'),
			('dirg',						u'dirg'),
			('pvr',							u'pvr'),
			('thugline',					u'thugline'),
			('thd',							u'thd'),
			('focus',						u'focus'),
			('dexterous',					u'dexterous'),
			('e76',							u'e76'),
			('qtz',							u'qtz'),
			('pia',							u'pia'),
			('refined',						u'refined'),
			('mkvanime',					u'mkvanime'),
			('oo',							u'oo'),
			('wuruhi',						u'wuruhi'),
			('mrkickass',					u'mr{separator}+kickass'),
			('moviesmb',					u'moviesmb'),
			('divulged',					u'divulged'),
			('pitufo180',					u'pitufo180'),
			('tdr',							u'tdr'),
			('bladebdp',					u'bladebdp'),
			('nfhd',						u'nfhd'),
			('lp',							u'lp'),
			('danger2u',					u'danger2u'),
			('pso',							u'pso'),
			('hdil',						u'hdil'),
			('orpheus',						u'orpheus'),
			('ctr',							u'ctr'),
			('guardians',					u'guardians'),
			('nge',							u'nge'),
			('opentsubasa',					u'opentsubasa'),
			('arc',							u'arc'),
			('wire',						u'wire'),
			('twizted',						u'twizted'),
			('lbr',							u'lbr'),
			('dvsux',						u'dvsux'),
			('omega',						u'omega'),
			('jfkdvd',						u'jfkdvd'),
			('tpb',							u'tpb'),
			('order',						u'order'),
			('senpai',						u'senpai'),
			('pcsyndicate',					u'pcsyndicate'),
			('value',						u'value'),
			('tdf',							u'tdf'),
			('eclipse',						u'eclipse'),
			('dem3nt3',						u'dem3nt3'),
			('felony',						u'felony'),
			('mys',							u'mys'),
			('sphinctone1',					u'sphinctone1'),
			('terra',						u'terra'),
			('fantascienza',				u'fantascienza'),
			('frisky',						u'frisky'),
			('nelly45',						u'nelly45'),
			('drsd',						u'drsd'),
			('ddn',							u'ddn'),
			('r00t',						u'r00t'),
			('dp',							u'dp'),
			('nova',						u'nova'),
			('lap',							u'lap'),
			('aw',							u'(?:a{separator}+w|aw)'),
			('cyphanix',					u'cyphanix'),
			('fasm',						u'fasm'),
			('fsihd',						u'fsihd'),
			('ositv',						u'ositv'),
			('hannibal',					u'hannibal'),
			('whiterhino',					u'whiterhino'),
			('unity',						u'unity'),
			('hdb',							u'hdb'),
			('ae',							u'(?:a{separator}+e|ae)'),
			('neo',							u'neo'),
			('woat',						u'woat'),
			('bet',							u'bet'),
			('gasmask',						u'gasmask'),
			('zest',						u'zest'),
			('chivaman',					u'chivaman'),
			('tm',							u'tm'),
			('n0m1',						u'n0m1'),
			('ulysse',						u'ulysse'),
			('hdaccess',					u'hdaccess'),
			('pch',							u'pch'),
			('worldfree4u',					u'(?:worldfree4u{separator}+link|worldfree4u)'),
			('airline',						u'airline'),
			('pussyfoot',					u'pussyfoot'),
			('toxic',						u'toxic'),
			('slag',						u'slag'),
			('orca88',						u'orca88'),
			('twister',						u'twister'),
			('hector',						u'hector'),
			('fronky',						u'fronky'),
			('lum1x',						u'lum1x'),
			('paradox',						u'paradox'),
			('kimchi',						u'kimchi'),
			('dkb',							u'dkb'),
			('pioneer',						u'pioneer'),
			('zsewdc',						u'zsewdc'),
			('tozoon',						u'tozoon'),
			('crown',						u'crown'),
			('justin',						u'justin'),
			('tt',							u'tt'),
			('disposable',					u'disposable'),
			('crazy4ad',					u'crazy4ad'),
			('theamresh',					u'theamresh'),
			('haiku',						u'haiku'),
			('pter',						u'pter'),
			('atax',						u'atax'),
			('tvr',							u'tvr'),
			('spectre',						u'spectre'),
			('ion265',						u'ion265'),
			('trg',							u'trg'),
			('nohate',						u'nohate'),
			('huzzah',						u'huzzah'),
			('mrshanku',					u'mrshanku'),
			('hdreactor',					u'hdreactor'),
			('dubby',						u'dubby'),
			('freedom',						u'freedom'),
			('cartel',						u'cartel'),
			('sharphd',						u'sharphd'),
			('badbajo',						u'badbajo'),
			('vex',							u'vex'),
			('truck',						u'truck'),
			('megatron',					u'megatron'),
			('mortal',						u'mortal'),
			('vedett',						u'vedett'),
			('fusion',						u'fusion'),
			('xannyfamily',					u'xannyfamily'),
			('weasley',						u'weasley'),
			('wem',							u'wem'),
			('wpi',							u'wpi'),
			('cbgb',						u'cbgb'),
			('f1rebladerunner',				u'f1rebladerunner'),
			('isubs',						u'isubs'),
			('tv2lax9',						u'tv2lax9'),
			('bluevo',						u'bluevo'),
			('bigdoc',						u'bigdoc'),
			('patrol',						u'patrol'),
			('tsrg',						u'tsrg'),
			('fzteam',						u'fzteam'),
			('budgetbits',					u'budgetbits'),
			('r10',							u'r10'),
			('hangover',					u'hangover'),
			('osiris',						u'osiris'),
			('metis',						u'metis'),
			('reveille',					u'reveille'),
			('zeusdias',					u'zeus{separator}+dias'),
			('anihls',						u'anihls'),
			('hoodbag',						u'hoodbag'),
			('frozen',						u'frozen'),
			('devise',						u'devise'),
			('poe',							u'poe'),
			('didee',						u'didee'),
			('dxo',							u'dxo'),
			('gdr',							u'gdr'),
			('gaz',							u'gaz'),
			('vox',							u'vox'),
			('piratemkv',					u'piratemkv'),
			('idtv',						u'idtv'),
			('hn',							u'hn'),
			('pluto',						u'pluto'),
			('qrips',						u'qrips'),
			('caf',							u'caf'),
			('horriblesubs',				u'horriblesubs'),
			('pop',							u'pop'),
			('bf1',							u'bf1'),
			('blutonium',					u'blutonium'),
			('crr',							u'crr'),
			('dragsterps',					u'dragsterps'),
			('skazhutin',					u'skazhutin'),
			('waters',						u'waters'),
			('babytorrent',					u'babytorrent'),
			('xxxpav69',					u'xxxpav69'),
			('abjex',						u'abjex'),
			('kookoo',						u'kookoo'),
			('dic',							u'dic'),
			('surcode',						u'surcode'),
			('nlibra',						u'nlibra'),
			('alt',							u'alt'),
			('ism',							u'ism'),
			('ser',							u'ser'),
			('xpress',						u'xpress'),
			('gerald99',					u'gerald99'),
			('byteshare',					u'byteshare'),
			('document',					u'document'),
			('animal',						u'animal'),
			('decibel',						u'decibel'),
			('pod',							u'pod'),
			('asw',							u'asw'),
			('nitroteam',					u'nitroteam'),
			('rtl',							u'rtl'),
			('cowry',						u'cowry'),
			('sitv',						u'sitv'),
			('gimchi',						u'gimchi'),
			('punch',						u'punch'),
			('untouchables',				u'untouchables'),
			('atg',							u'atg'),
			('watchable',					u'watchable'),
			('septic',						u'septic'),
			('ltu',							u'ltu'),
			('donna',						u'donna'),
			('retreat',						u'retreat'),
			('hdex',						u'hdex'),
			('leverage',					u'leverage'),
			('ling',						u'ling'),
			('lostyears',					u'lostyears'),
			('exquisite',					u'exquisite'),
			('neroz',						u'neroz'),
			('jam',							u'jam'),
			('etm',							u'etm'),
			('kaidubs',						u'kaidubs'),
			('wishtv',						u'wishtv'),
			('cinedome',					u'cinedome'),
			('inception',					u'inception'),
			('juggalotus',					u'juggalotus'),
			('boo',							u'boo'),
			('roger',						u'roger'),
			('rebels',						u'rebels'),
			('nondrm',						u'nondrm'),
			('hdq',							u'hdq'),
			('twist',						u'twist'),
			('wheels',						u'wheels'),
			('ruby',						u'ruby'),
			('markii',						u'markii'),
			('crisp',						u'crisp'),
			('teamtelly',					u'teamtelly'),
			('nile',						u'nile'),
			('vigi',						u'vigi'),
			('ancient',						u'ancient'),
			('rrh',							u'rrh'),
			('sho',							u'sho'),
			('bordure',						u'bordure'),
			('crossfit',					u'crossfit'),
			('ssg',							u'ssg'),
			('surfer',						u'surfer'),
			('cf',							u'(?:cf|c{separator}+f)'),
			('mikos',						u'mikos'),
			('counterfeit',					u'counterfeit'),
			('brad',						u'brad'),
			('brg',							u'brg'),
			('ukdhd',						u'ukdhd'),
			('hiqve',						u'hiqve'),
			('rc',							u'(?:r\&c|rc)'),
			('euhd',						u'euhd'),
			('oom',							u'oom'),
			('thepunisher',					u'the{separator}+punisher'),
			('bigint',						u'bigint'),
			('astrd',						u'astrd'),
			('dreamseed',					u'dreamseed'),
			('fcc',							u'fcc'),
			('cpt',							u'cpt'),
			('flicksick',					u'flicksick'),
			('ethics',						u'ethics'),
			('trips',						u'trips'),
			('timelords',					u'timelords'),
			('ya',							u'ya'),
			('f1',							u'f1'),
			('saimorny',					u'saimorny'),
			('verum',						u'verum'),
			('ap',							u'ap'),
			('debtvid',						u'debtvid'),
			('mnhd',						u'mnhd'),
			('a1rip',						u'a1rip'),
			('ppb',							u'ppb'),
			('elysium',						u'elysium'),
			('adrenaline',					u'adrenaline'),
			('twa',							u'twa'),
			('fightbb',						u'(?:fightbb|fight{separator}+bb)'),
			('podo',						u'podo'),
			('liebehd',						u'liebehd'),
			('lazers',						u'lazers'),
			('playbd',						u'playbd'),
			('hone',						u'hone'),
			('absinth',						u'absinth'),
			('dss',							u'dss'),
			('newcomers',					u'newcomers'),
			('bravery',						u'bravery'),
			('rwp',							u'rwp'),
			('opt',							u'opt'),
			('duck',						u'duck'),
			('hdtracker',					u'hdtracker'),
			('bawls',						u'bawls'),
			('bst',							u'bst'),
			('deka',						u'deka'),
			('ncmt',						u'ncmt'),
			('jebaited',					u'jebaited'),
			('dir',							u'dir'),
			('ccat',						u'ccat'),
			('winks',						u'winks'),
			('innocence',					u'innocence'),
			('nada',						u'nada'),
			('nextgen',						u'nextgen'),
			('actie',						u'actie'),
			('goon',						u'goon'),
			('gon',							u'gon'),
			('bunny',						u'bunny'),
			('danny',						u'danny'),
			('vivi',						u'vivi'),
			('spc',							u'spc'),
			('ttg',							u'ttg'),
			('ep1c',						u'ep1c'),
			('nate666',						u'nate{separator}+666'),
			('reign',						u'reign'),
			('ambit',						u'ambit'),
			('m3q',							u'm3q'),
			('jah',							u'jah'),
			('mkvhu',						u'mkvhu'),
			('roor',						u'roor'),
			('gabe',						u'gabe'),
			('halcyon',						u'halcyon'),
			('rap',							u'rap'),
			('t3nzin',						u't3nzin'),
			('goatlove',					u'goatlove'),
			('dbretail',					u'dbretail'),
			('viper',						u'viper'),
			('skedaddle',					u'skedaddle'),
			('natty',						u'natty'),
			('lds',							u'lds'),
			('pir8',						u'pir8'),
			('leralouf',					u'leralouf'),
			('mch',							u'mch'),
			('me7alh',						u'me7alh'),
			('web4hd',						u'web4hd'),
			('b0mbardiers',					u'b0mbardiers'),
			('bedlam',						u'bedlam'),
			('ddlv',						u'ddlv'),
			('gs88',						u'gs88'),
			('ssl',							u'ssl'),
			('kate',						u'kate'),
			('soigneur',					u'soigneur'),
			('hdx',							u'hdx'),
			('gl',							u'gl'),
			('prithwi',						u'prithwi'),
			('bingo',						u'bingo'),
			('rightsize',					u'rightsize'),
			('doubt',						u'doubt'),
			('exdr',						u'exdr'),
			('ps3team',						u'ps3{separator}+team'),
			('freak',						u'freak'),
			('define',						u'define'),
			('sicario',						u'sicario'),
			('t1',							u't1'),
			('pmp',							u'pmp'),
			('rude',						u'rude'),
			('medieval',					u'medieval'),
			('dddd',						u'dddd'),
			('gbm',							u'gbm'),
			('strong',						u'strong'),
			('abd',							u'abd'),
			('salt',						u'salt'),
			('bizkit',						u'bizkit'),
			('tmg',							u'tmg'),
			('hdfilmboss',					u'hdfilmboss'),
			('girays',						u'girays'),
			('rnc',							u'rnc'),
			('le',							u'l{separator}+e'),
			('slot',						u'slot'),
			('bzingaz',						u'bzingaz'),
			('tvaddict',					u'tvaddict'),
			('bbtor',						u'bbtor'),
			('vfhd',						u'vfhd'),
			('mdgp',						u'mdgp'),
			('dvt',							u'dvt'),
			('tvillage',					u'tvillage'),
			('bwb',							u'bwb'),
			('nerdhd',						u'nerdhd'),
			('snowdon',						u'snowdon'),
			('kaizen',						u'kaizen'),
			('pot',							u'pot'),
			('gi',							u'gi'),
			('sg',							u'(?:s{separator}+g|sg)'),
			('fzhd',						u'fzhd'),
			('ba',							u'(?:ba|b{separator}+a)'),
			('voxhd',						u'voxhd'),
			('diverge',						u'diverge'),
			('mtk',							u'mtk'),
			('hammer71',					u'hammer71'),
			('wat',							u'wat'),
			('shitty',						u'shitty'),
			('sampa',						u'sampa'),
			('shitspread',					u'shitspread'),
			('yogi',						u'yogi'),
			('dav1nci',						u'dav1nci'),
			('herakler',					u'herakler'),
			('incognito',					u'incognito'),
			('cia',							u'cia'),
			('smurfenlars',					u'smurfenlars'),
			('paai',						u'paai'),
			('xdr',							u'xdr'),
			('lycanhd',						u'lycanhd'),
			('splitsville',					u'splitsville'),
			('gas',							u'gas'),
			('tide',						u'tide'),
			('abyss',						u'abyss'),
			('sour',						u'sour'),
			('subzero',						u'subzero'),
			('dvsky',						u'dvsky'),
			('lazarus',						u'lazarus'),
			('playready',					u'playready'),
			('bff',							u'bff'),
			('tv21',						u'tv21'),
			('assassins',					u'assassins'),
			('fant',						u'fant'),
			('rcdivx',						u'rcdivx'),
			('wing',						u'wing'),
			('npms',						u'npms'),
			('nip',							u'nip'),
			('desire',						u'desire'),
			('weby',						u'weby'),
			('wilder',						u'wilder'),
			('culthd',						u'culthd'),
			('minihd',						u'minihd'),
			('slow',						u'slow'),
			('andy',						u'andy'),
			('reloaded',					u'reloaded'),
			('nok',							u'n{separator}+o{separator}+k'),
			('sh3lby',						u'sh3lby'),
			('ann',							u'ann'),
			('tdd',							u'tdd'),
			('form',						u'form'),
			('lapumiafilmes',				u'lapumiafilmes'),
			('shock',						u'shock'),
			('codres',						u'codres'),
			('different',					u'different'),
			('forward',						u'forward'),
			('nbs',							u'nbs'),
			('dash',						u'dash'),
			('nbt',							u'nbt'),
			('occor',						u'occor'),
			('hls',							u'hls'),
			('ripley',						u'ripley'),
			('jetix',						u'jetix'),
			('sigeris',						u'sigeris'),
			('mp4king',						u'mp4king'),
			('puzzle',						u'puzzle'),
			('kazan',						u'kazan'),
			('kuchikirukia',				u'kuchikirukia'),
			('kingstoner',					u'kingstoner'),
			('rets',						u'rets'),
			('fatman',						u'fatman'),
			('kaf',							u'kaf'),
			('apekat',						u'apekat'),
			('gsftx',						u'gsftx'),
			('stealthmaster',				u'stealthmaster'),
			('anon',						u'anon'),
			('dtech',						u'dtech'),
			('cult',						u'cult'),
			('d4',							u'd4'),
			('ipt',							u'ipt'),
			('ryotox',						u'ryotox'),
			('maxi',						u'maxi'),
			('caph',						u'caph'),
			('tasted',						u'tasted'),
			('kappa',						u'kappa'),
			('goku61',						u'goku61'),
			('icandy',						u'icandy'),
			('diesel',						u'diesel'),
			('bow',							u'bow'),
			('espise',						u'espise'),
			('unkn0wn',						u'unkn0wn'),
			('pm',							u'pm'),
			('aen',							u'aen'),
			('rhood',						u'rhood'),
			('erairaws',					u'erai{separator}+raws'),
			('ane',							u'ane'),
			('wowrip',						u'wowrip'),
			('iflix',						u'iflix'),
			('atilla82',					u'atilla82'),
			('frog',						u'frog'),
			('ngb',							u'ngb'),
			('zq',							u'zq'),
			('dude',						u'dude'),
			('promise',						u'promise'),
			('glenn',						u'glenn'),
			('end',							u'e{separator}+n{separator}+d'),
			('xme',							u'xme'),
			('coincidence',					u'coincidence'),
			('doktor',						u'doktor'),
			('aroma',						u'aroma'),
			('pb',							u'pb'),
			('zoom',						u'zoom'),
			('akraa',						u'akraa'),
			('ssf',							u'ssf'),
			('to4ka',						u'to4ka'),
			('dvf',							u'dvf'),
			('stratos',						u'stratos'),
			('no1knows',					u'no1knows'),
			('jackie',						u'jackie'),
			('hdrinvasion',					u'hdrinvasion'),
			('dawgs',						u'dawgs'),
			('inject',						u'inject'),
			('hdw',							u'hdw'),
			('lok',							u'lok'),
			('babylon',						u'babylon'),
			('nyh',							u'nyh'),
			('pwe',							u'pwe'),
			('dukes',						u'dukes'),
			('hdv0t',						u'hdv0t'),
			('genesis',						u'genesis'),
			('inspired',					u'inspired'),
			('hushrips',					u'hushrips'),
			('mack',						u'mack'),
			('memories',					u'memories'),
			('universum',					u'universum'),
			('langbard',					u'langbard'),
			('tangoalpha',					u'tangoalpha'),
			('milk',						u'milk'),
			('leethd',						u'leethd'),
			('nwo',							u'nwo'),
			('moly',						u'moly'),
			('crisgsm33',					u'crisgsm33'),
			('jm',							u'jm'),
			('simba',						u'simba'),
			('hdclassics',					u'hdclassics'),
			('e7',							u'e7'),
			('rady',						u'rady'),
			('excited',						u'excited'),
			('geek',						u'geek'),
			('xander',						u'xander'),
			('gur',							u'gur'),
			('ntropic',						u'ntropic'),
			('spedboy',						u'spedboy'),
			('ping',						u'ping'),
			('bigsinema',					u'bigsinema'),
			('starlord',					u'starlord'),
			('poiasd',						u'poiasd'),
			('shd',							u'shd'),
			('bhatti',						u'bhatti'),
			('coalition',					u'coalition'),
			('orphan',						u'orphan'),
			('eatdik',						u'eatdik'),
			('avs720',						u'avs720'),
			('galactica',					u'galactica'),
			('kg',							u'kg'),
			('svd',							u'svd'),
			('dbo',							u'dbo'),
			('lotv',						u'lotv'),
			('hqx',							u'hqx'),
			('yazoomix',					u'yazoomix'),
			('bugz',						u'bugz'),
			('vr',							u'vr'),
			('dna',							u'dna'),
			('tcpa',						u'tcpa'),
			('aaauhd',						u'aaauhd'),
			('biq',							u'biq'),
			('noma',						u'noma'),
			('verovenlo',					u'verovenlo'),
			('norars',						u'norars'),
			('thewretched',					u'thewretched'),
			('fly635',						u'fly635'),
			('skrin',						u'skrin'),
			('semtex',						u'semtex'),
			('egen',						u'egen'),
			('foxpro',						u'foxpro'),
			('adrian',						u'adrian'),
			('slo',							u'slo'),
			('khn',							u'khn'),
			('melba',						u'melba'),
			('yt',							u'(?:yt|y{separator}+t)'),
			('tv4a',						u'tv4a'),
			('xtrill',						u'xtrill'),
			('fapcave',						u'fapcave'),
			('void',						u'void'),
			('pctnew',						u'pctnew'),
			('btshoufa',					u'btshoufa'),
			('condition',					u'condition'),
			('mg',							u'mg'),
			('fendt',						u'fendt'),
			('btt',							u'btt'),
			('fls',							u'fls'),
			('cbm',							u'cbm'),
			('hdalx',						u'hdalx'),
			('utopia',						u'utopia'),
			('4everdowns',					u'4everdowns'),
			('winters',						u'winters'),
			('capricorn',					u'capricorn'),
			('whd',							u'whd'),
			('hrip',						u'hrip'),
			('barbie',						u'barbie'),
			('diablo',						u'diablo'),
			('trojan',						u'trojan'),
			('spacehd13',					u'spacehd13'),
			('noretail',					u'noretail'),
			('tdm',							u'tdm'),
			('reaktor',						u'reaktor'),
			('fff',							u'fff'),
			('hda',							u'hda'),
			('hdbee',						u'hdbee'),
			('symbiotes',					u'symbiotes'),
			('timpe',						u'timpe'),
			('ssa',							u'ssa'),
			('dh',							u'dh'),
			('dr',							u'd{separator}+r'),
			('tha',							u'tha'),
			('jester',						u'jester'),
			('gattopollo',					u'gattopollo'),
			('loverulz',					u'love{separator}+rulz'),
			('seedup',						u'seedup'),
			('mighty',						u'mighty'),
			('fries',						u'fries'),
			('shrpy',						u'shrpy'),
			('come2daddy',					u'come2daddy'),
			('inam',						u'inam'),
			('bludragon',					u'bludragon'),
			('anona911',					u'anona911'),
			('wvf',							u'wvf'),
			('mooi1990',					u'mooi1990'),
			('tbz',							u'tbz'),
			('kickoff',						u'kickoff'),
			('mcr',							u'mcr'),
			('bmf',							u'bmf'),
			('turmoil',						u'turmoil'),
			('ab',							u'ab'),
			('digg',						u'digg'),
			('reactor',						u'reactor'),
			('freaks',						u'freaks'),
			('schizo',						u'schizo'),
			('samuel98',					u'samuel98'),
			('lust',						u'lust'),
			('disruption',					u'disruption'),
			('nix',							u'nix'),
			('lamb',						u'lamb'),
			('rakuv02',						u'rakuv02'),
			('rem',							u'rem'),
			('sumvision',					u'sumvision'),
			('rb',							u'(?:rb|r{separator}+b)'),
			('senation',					u'senation'),
			('axe',							u'axe'),
			('particle',					u'particle'),
			('pukka',						u'pukka'),
			('paulista',					u'paulista'),
			('gogeta',						u'gogeta'),
			('ultrahdclub',					u'ultrahdclub'),
			('nws',							u'nws'),
			('unitail',						u'unitail'),
			('gos',							u'gos'),
			('emem',						u'emem'),
			('cpd',							u'cpd'),
			('ztorrenter',					u'ztorrenter'),
			('thumperdc',					u'thumperdc'),
			('magical',						u'magical'),
			('rmp4l',						u'rmp4l'),
			('ffndvd',						u'ffndvd'),
			('baked',						u'baked'),
			('fbi',							u'fbi'),
			('videostar',					u'videostar'),
			('polar',						u'polar'),
			('gfw',							u'gfw'),
			('db',							u'db'),
			('gtvg',						u'gtvg'),
			('shitbusters',					u'shitbusters'),
			('jumanji',						u'jumanji'),
			('serum',						u'serum'),
			('sf',							u'(?:sf|s{separator}+f)'),
			('camelot',						u'camelot'),
			('pas',							u'pas'),
			('hype',						u'hype'),
			('theincognito',				u'theincognito'),
			('emerald',						u'emerald'),
			('wgz',							u'wgz'),
			('beer',						u'beer'),
			('zzgtv',						u'zzgtv'),
			('ddncrew',						u'ddncrew'),
			('gorehounds',					u'gorehounds'),
			('ricky',						u'ricky'),
			('gxp',							u'gxp'),
			('sorrow',						u'sorrow'),
			('trash',						u'trash'),
			('judgement',					u'judgement'),
			('dnl',							u'dnl'),
			('delicious',					u'(?:delicio{separator}+us|delicious)'),
			('tjhd',						u'tjhd'),
			('ultradox',					u'ultradox'),
			('420ripz',						u'420ripz'),
			('skyrg',						u'skyrg'),
			('dbr',							u'dbr'),
			('movierush',					u'movierush'),
			('crossbow',					u'crossbow'),
			('eimi',						u'eimi'),
			('mhq',							u'mhq'),
			('ats',							u'ats'),
			('g4ris',						u'g4ris'),
			('helix',						u'helix'),
			('mctav',						u'mctav'),
			('tvslf',						u'tvslf'),
			('l0l',							u'l0l'),
			('cultfilms',					u'(?:cultfilms|cultfilms™)'),
			('decatora27',					u'decatora27'),
			('hab',							u'hab'),
			('swim',						u'swim'),
			('mixtv',						u'mixtv'),
			('ihd',							u'ihd'),
			('btchkek',						u'btchkek'),
			('tech',						u'tech'),
			('pcroland',					u'pcroland'),
			('dirtyburger',					u'dirtyburger'),
			('viazac',						u'viazac'),
			('hdhub',						u'hdhub'),
			('immortals',					u'immortals'),
			('incite',						u'incite'),
			('spiro',						u'spiro'),
			('pikachu',						u'pikachu'),
			('rta',							u'rta'),
			('garshasp',					u'garshasp'),
			('kuth',						u'kuth'),
			('wolverdonfilmes',				u'(?:wolverdonfilmes|wolverdonfilmes{separator}+to)'),
			('azaze',						u'azaze'),
			('bullit',						u'bullit'),
			('thyrso10',					u'thyrso10'),
			('hodl',						u'hodl'),
			('cinemaet',					u'cinemaet'),
			('hca',							u'hca'),
			('sublime',						u'sublime'),
			('safety',						u'safety'),
			('globe',						u'globe'),
			('avg',							u'avg'),
			('maxhd',						u'maxhd'),
			('ikiw',						u'ikiw'),
			('seventwenty',					u'seventwenty'),
			('hyde',						u'hyde'),
			('zit',							u'zi{separator}+t'),
			('xs',							u'(?:xs|x{separator}+s)'),
			('awards',						u'awards'),
			('bugsfunny',					u'bugsfunny'),
			('khoshmard',					u'khoshmard'),
			('beitai',						u'beitai'),
			('mrstrange',					u'mrstrange'),
			('abhistuff',					u'abhistuff'),
			('cottage',						u'cottage'),
			('thick',						u'thick'),
			('hddevils',					u'hddevils'),
			('rog',							u'rog'),
			('nox',							u'nox'),
			('hdl',							u'hdl'),
			('clockwork',					u'clockwork'),
			('prevail',						u'prevail'),
			('baum',						u'baum'),
			('dea',							u'dea'),
			('glasses',						u'glasses'),
			('jj',							u'jj'),
			('ephemerid',					u'ephemerid'),
			('scared',						u'scared'),
			('itz',							u'itz'),
			('tscc',						u'tscc'),
			('gothic',						u'gothic'),
			('tasko',						u'tasko'),
			('monk',						u'monk'),
			('nordichd',					u'nordichd'),
			('intimid',						u'intimid'),
			('gg',							u'gg'),
			('oft',							u'oft'),
			('cldd',						u'cldd'),
			('seight',						u'seight'),
			('district',					u'district'),
			('filmsclub',					u'films{separator}+club'),
			('fmdab',						u'fmdab'),
			('yn1d',						u'yn1d'),
			('religious',					u'religious'),
			('gzcrew',						u'gzcrew'),
			('sl',							u'sl'),
			('veritas',						u'veritas'),
			('kingmaker',					u'kingmaker'),
			('musketeers',					u'musketeers'),
			('blupanther',					u'blupanther'),
			('nano',						u'nano'),
			('motion',						u'motion'),
			('bobo',						u'bobo'),
			('okq',							u'okq'),
			('moh',							u'moh'),
			('clerks',						u'clerks'),
			('epik',						u'epik'),
			('xvik',						u'xvik'),
			('amirite',						u'amirite'),
			('miky',						u'miky'),
			('uvall',						u'uvall'),
			('qrus',						u'qrus'),
			('playtv',						u'playtv'),
			('zonatorrent2',				u'zonatorrent2'),
			('sunspot',						u'sunspot'),
			('drg',							u'drg'),
			('burger',						u'burger'),
			('btsfilms',					u'btsfilms'),
			('bootstrap',					u'bootstrap'),
			('ano',							u'ano'),
			('propltv',						u'propltv'),
			('rknorloading',				u'r{separator}+knorloading'),
			('reaperza',					u'reaperza'),
			('male',						u'male'),
			('mrhive',						u'mr{separator}+hive'),
			('bish',						u'bish'),
			('r0b0t',						u'r0b0t'),
			('mmi',							u'mmi'),
			('vet',							u'vet'),
			('ank',							u'ank'),
			('pimp',						u'pimp'),
			('hhi',							u'hhi'),
			('missripz',					u'missripz'),
			('gerudo',						u'gerudo'),
			('howl',						u'howl'),
			('arin',						u'arin'),
			('m3d',							u'm3d'),
			('g3lhd',						u'g3lhd'),
			('archie',						u'archie'),
			('mojo',						u'mojo'),
			('h3ll2p4y',					u'h3ll2p4y'),
			('ebi',							u'ebi'),
			('bluhd',						u'bluhd'),
			('km',							u'km'),
			('sunny',						u'sunny'),
			('swc',							u'swc'),
			('lb',							u'lb'),
			('hdxt',						u'hdxt'),
			('outbreak',					u'outbreak'),
			('hh',							u'hh'),
			('pate',						u'pate'),
			('nks',							u'nks'),
			('kirklestat',					u'kirklestat'),
			('s8',							u's8'),
			('xshd',						u'xshd'),
			('bithd',						u'bithd'),
			('sneak',						u'sneak'),
			('arigold',						u'arigold'),
			('punisher694',					u'punisher694'),
			('checkmate',					u'checkmate'),
			('shitsony',					u'shitsony'),
			('jass',						u'jass'),
			('waste',						u'waste'),
			('blaze',						u'blaze'),
			('ico',							u'ico'),
			('gsg9',						u'gsg9'),
			('enigma',						u'enigma'),
			('rishibhai',					u'rishibhai'),
			('aggr0',						u'aggr0'),
			('macro',						u'macro'),
			('mbrhdrg',						u'mbrhdrg'),
			('slisu',						u'slisu'),
			('savannah',					u'savannah'),
			('woody',						u'woody'),
			('donjuan',						u'donjuan'),
			('delight',						u'delight'),
			('numy',						u'numy'),
			('dygc',						u'dygc'),
			('topcat',						u'topcat'),
			('optic',						u'optic'),
			('cis',							u'cis'),
			('vrs',							u'vrs'),
			('zmg',							u'zmg'),
			('xhd',							u'xhd'),
			('neptune',						u'neptune'),
			('ahd',							u'ahd'),
			('diamonds',					u'diamonds'),
			('tvv',							u'tvv'),
			('tekno3d',						u'tekno3d'),
			('jolly',						u'jolly'),
			('imax',						u'im\@x'),
			('nva',							u'nva'),
			('supersize',					u'supersize'),
			('curiosity',					u'curiosity'),
			('hdvn',						u'hdvn'),
			('yakuza',						u'yakuza'),
			('pikanet128',					u'pikanet128'),
			('ptnk',						u'ptnk'),
			('frangoassado',				u'frangoassado'),
			('forcebleue',					u'forcebleue'),
			('ryuuga',						u'ryuuga'),
			('katmaster',					u'katmaster'),
			('am',							u'a{separator}+m'),
			('definition',					u'definition'),
			('flaite',						u'flaite'),
			('dustin',						u'dustin'),
			('zito',						u'zito'),
			('shinobi',						u'shinobi'),
			('sdc',							u'sdc'),
			('madman',						u'madman'),
			('watchmo',						u'watchmo'),
			('ena',							u'ena'),
			('feature',						u'feature'),
			('yoyo',						u'yoyo'),
			('nightripper',					u'nightripper'),
			('zodiac',						u'zodiac'),
			('fullsize',					u'fullsize'),
			('ritalix',						u'ritalix'),
			('vhd',							u'vhd'),
			('bass',						u'bass'),
			('hqm',							u'hqm'),
			('arizone',						u'arizone'),
			('wb',							u'(?:w{separator}+b|wb)'),
			('bulldozer',					u'bulldozer'),
			('oki',							u'oki'),
			('kronos',						u'kronos'),
			('pa',							u'p{separator}+a'),
			('electric',					u'electric'),
			('fk99',						u'fk99'),
			('c1',							u'c1'),
			('vista',						u'(?:vista|vista™)'),
			('bags',						u'bags'),
			('pinkpanters',					u'pinkpanters'),
			('filmytorrents',				u'(?:filmytorrents|filmytorrents{separator}+com)'),
			('apa',							u'apa'),
			('taco',						u'taco'),
			('slg',							u'slg'),
			('tvarchiv',					u'tvarchiv'),
			('ekolb',						u'ekolb'),
			('naa',							u'naa'),
			('4sj',							u'4sj'),
			('meth',						u'meth'),
			('lovehd',						u'lovehd'),
			('esi',							u'esi'),
			('mvs',							u'mvs'),
			('cmr',							u'cmr'),
			('torrentcouch',				u'(?:torrentcouch|torrentcouch{separator}+com)'),
			('smokey',						u'smokey'),
			('bgfr',						u'bgfr'),
			('tit',							u'tit'),
			('xc',							u'xc'),
			('lightspeed',					u'lightspeed'),
			('grep',						u'grep'),
			('jade',						u'jade'),
			('mvgee',						u'mvgee'),
			('lolhd',						u'lolhd'),
			('eisbock',						u'eisbock'),
			('imperium',					u'imperium'),
			('xwt',							u'xwt'),
			('avenue',						u'avenue'),
			('t00ng0d',						u't00ng0d'),
			('hdo',							u'hdo'),
			('qmax',						u'qmax'),
			('klaxxon',						u'klaxxon'),
			('drake',						u'drake'),
			('ifh',							u'ifh'),
			('voa',							u'voa'),
			('hdbrise',						u'hdbrise'),
			('edvok',						u'(?:edvok|edvok{separator}+com)'),
			('deity',						u'deity'),
			('gothicmaster',				u'gothicmaster'),
			('cdd',							u'cdd'),
			('lookmane',					u'lookmane'),
			('grind',						u'grind'),
			('aj',							u'aj'),
			('xoxo',						u'xoxo'),
			('tcm',							u'tcm'),
			('gnarly',						u'gnarly'),
			('amx',							u'amx'),
			('jfkxvid',						u'jfkxvid'),
			('callmebrado',					u'callmebrado'),
			('mobee1',						u'mobee1'),
			('ms89',						u'ms89'),
			('tmd',							u'tmd'),
			('beyondhd',					u'beyondhd'),
			('mchd',						u'mchd'),
			('aoe',							u'aoe'),
			('bright',						u'bright'),
			('definite',					u'definite'),
			('tenaciousd',					u'tenaciousd'),
			('at',							u'a{separator}+t'),
			('wdk',							u'wdk'),
			('ambassador',					u'ambassador'),
			('chotab',						u'chotab'),
			('whoknow',						u'whoknow'),
			('sus',							u'sus'),
			('tvnation',					u'tvnation'),
			('sigla',						u'sigla'),
			('fap',							u'fap'),
			('flair',						u'flair'),
			('primehd',						u'primehd'),
			('300mbmovieshub',				u'300mbmovieshub'),
			('meow',						u'meow'),
			('whiizz',						u'whiizz'),
			('mro',							u'mro'),
			('pxhd',						u'pxhd'),
			('qix',							u'qix'),
			('haco',						u'haco'),
			('ctrlsd',						u'ctrlsd'),
			('lite',						u'lite'),
			('ov3rload',					u'ov3rload'),
			('throne',						u'throne'),
			('nmd',							u'nmd'),
			('mkvgod',						u'mkvgod'),
			('lund',						u'lund'),
			('marhaba',						u'marhaba'),
			('doge',						u'doge'),
			('knifesharp',					u'knifesharp'),
			('cddhd',						u'cddhd'),
			('0mnidvd',						u'0mnidvd'),
			('turkiso',						u'turkiso'),
			('hb',							u'(?:h{separator}+b|hb)'),
			('roimez',						u'roimez'),
			('reptile',						u'reptile'),
			('progress',					u'progress'),
			('cdp',							u'cdp'),
			('kaga',						u'kaga'),
			('avcdvd',						u'avcdvd'),
			('xtm',							u'xtm'),
			('insanity',					u'insanity'),
			('borderline',					u'borderline'),
			('mvn',							u'mvn'),
			('oj',							u'oj'),
			('deadtorights',				u'deadtorights'),
			('c2c',							u'c2c'),
			('primalhd',					u'primalhd'),
			('xorbitant',					u'xorbitant'),
			('raindeer',					u'raindeer'),
			('thizz',						u'thizz'),
			('thora',						u'thora'),
			('haideaf',						u'haideaf'),
			('hdctv',						u'hdctv'),
			('darkdream',					u'darkdream'),
			('morris',						u'morris'),
			('sozer',						u'sozer'),
			('nemesis',						u'nemesis'),
			('positive',					u'positive'),
			('fandango',					u'fandango'),
			('edi',							u'edi'),
			('omgtv',						u'omgtv'),
			('excommunicado',				u'excommunicado'),
			('moma',						u'moma'),
			('rlf',							u'rlf'),
			('infotv',						u'infotv'),
			('qrc',							u'qrc'),
			('4k4u',						u'4k4u'),
			('glue',						u'glue'),
			('kir4',						u'kir4'),
			('chc',							u'chc'),
			('hdcp',						u'hdcp'),
			('blin',						u'blin'),
			('tnp',							u'tnp'),
			('rj',							u'rj'),
			('wam',							u'wam'),
			('wombat',						u'wombat'),
			('noobless',					u'noobless'),
			('jitb',						u'jitb'),
			('hdv',							u'hdv'),
			('gore',						u'gore'),
			('mrgrey',						u'mrgrey'),
			('flop',						u'flop'),
			('afo',							u'afo'),
			('nfrip',						u'nfrip'),
			('krs',							u'krs'),
			('veil',						u'veil'),
			('cinefox',						u'cinefox'),
			('sage',						u'sage'),
			('hrs',							u'hrs'),
			('cleo',						u'cleo'),
			('bd4yu',						u'bd4yu'),
			('squalor',						u'squalor'),
			('robo',						u'robo'),
			('ftmvhd',						u'ftmvhd'),
			('spicy',						u'spicy'),
			('ssrmovies',					u'ssrmovies'),
			('krissz',						u'krissz'),
			('misfits',						u'misfits'),
			('fido',						u'fido'),
			('rh',							u'rh'),
			('koyumu',						u'koyumu'),
			('ras',							u'ras'),
			('insects',						u'insects'),
			('gooz',						u'gooz'),
			('pat',							u'pat'),
			('wrd',							u'wrd'),
			('bong',						u'bong'),
			('precious',					u'precious'),
			('moreland',					u'moreland'),
			('7rip',						u'7{separator}+rip'),
			('fabulous',					u'fabulous'),
			('fij',							u'fij'),
			('filmiwar',					u'filmiwar'),
			('rknor',						u'r{separator}+knor'),
			('sapphire',					u'sapphire'),
			('geo',							u'geo'),
			('oped',						u'oped'),
			('nerds',						u'nerds'),
			('dar',							u'dar'),
			('dx',							u'dx'),
			('tfin',						u'tfin'),
			('jollyroger',					u'jollyroger'),
			('viscabarca',					u'viscabarca'),
			('cute',						u'cute'),
			('monument',					u'monument'),
			('cielo',						u'cielo'),
			('machd',						u'machd'),
			('vinyl',						u'vinyl'),
			('heesten',						u'heesten'),
			('foxtrot',						u'foxtrot'),
			('rucucu',						u'rucucu'),
			('remake',						u'remake'),
			('critical',					u'critical'),
			('hkd',							u'hkd'),
			('kesh',						u'kesh'),
			('frame',						u'frame'),
			('invaders',					u'invaders'),
			('bennett',						u'bennett'),
			('defaced',						u'defaced'),
			('mc5',							u'mc5'),
			('maximum',						u'maximum'),
			('noobsubs',					u'noobsubs'),
			('j4f',							u'j4f'),
			('baggerinc',					u'baggerinc'),
			('carved',						u'carved'),
			('fty',							u'fty'),
			('kart3ldvd',					u'kart3ldvd'),
			('oem1080',						u'oem1080'),
			('cybermen',					u'cybermen'),
			('pandemonium',					u'pandemonium'),
			('mint',						u'mint'),
			('em0c0re',						u'em0c0re'),
			('syndicate',					u'syndicate'),
			('finally',						u'finally'),
			('lizardsquad',					u'lizardsquad'),
			('tribal',						u'tribal'),
			('filmikz',						u'filmikz'),
			('jatt',						u'jatt'),
			('jew',							u'jew'),
			('lulz',						u'lulz'),
			('ska',							u'ska'),
			('nvm',							u'nvm'),
			('bulgariahd',					u'bulgariahd'),
			('h4s5s',						u'h4s5s'),
			('chakra',						u'chakra'),
			('tbb',							u'tbb'),
			('c78',							u'c78'),
			('meakes',						u'meakes'),
			('pp',							u'pp'),
			('bearfish',					u'bearfish'),
			('baron',						u'baron'),
			('affinity',					u'affinity'),
			('cnhd',						u'cnhd'),
			('saviour',						u'saviour'),
			('tapochek',					u'tapochek'),
			('aiden0',						u'aiden0'),
			('vt',							u'vt'),
			('imp3rial',					u'imp3rial'),
			('hdteam',						u'hdteam'),
			('swaggerhd',					u'swaggerhd'),
			('kole',						u'kole'),
			('koc',							u'koc'),
			('alanis',						u'alanis'),
			('stfu',						u'stfu'),
			('omfug',						u'omfug'),
			('depravity',					u'depravity'),
			('sharereactor',				u'sharereactor'),
			('jasperp',						u'jasperp'),
			('ctc',							u'(?:стс|ctc)'),
			('gfy',							u'gfy'),
			('wiifi',						u'wiifi'),
			('nuxx',						u'nuxx'),
			('nortv',						u'nortv'),
			('srls',						u'srls'),
			('bge',							u'bge'),
			('hatchetgear',					u'hatchetgear'),
			('thenightmareinhd',			u'thenightmareinhd'),
			('hq7',							u'hq7'),
			('nixx',						u'nixx'),
			('ilovehd',						u'ilovehd'),
			('giu',							u'giu'),
			('bjl',							u'bjl'),
			('bugzbunny',					u'bugzbunny'),
			('danishbits',					u'danishbits'),
			('pmhd',						u'pmhd'),
			('dnr',							u'dnr'),
			('aja',							u'aja'),
			('exile',						u'exile'),
			('tear',						u'tear'),
			('yifi',						u'yifi'),
			('zman',						u'zman'),
			('whatelse',					u'whatelse'),
			('p2u',							u'p2u'),
			('kalipso',						u'kalipso'),
			('cinevision',					u'cinevision'),
			('leetay',						u'leetay'),
			('despite',						u'despite'),
			('enticement',					u'enticement'),
			('elia',						u'elia'),
			('fabutrash',					u'fabutrash'),
			('showehd',						u'showehd'),
			('supreme',						u'supreme'),
			('tmsf',						u'tmsf'),
			('imposters',					u'imposters'),
			('spk',							u'spk'),
			('apex',						u'apex'),
			('s8rhino',						u's8rhino'),
			('shinigami',					u'shinigami'),
			('rms',							u'rms'),
			('wmt',							u'wmt'),
			('breakers',					u'breakers'),
			('moe',							u'(?:moe|moe{separator}+ap)'),
			('kz',							u'k{separator}+z'),
			('paranoid06',					u'paranoid06'),
			('stock',						u'stock'),
			('spyc',						u'spyc'),
			('knp',							u'knp'),
			('vcdvault',					u'vcdvault'),
			('treble',						u'treble'),
			('bubanee',						u'bubanee'),
			('pankhabd',					u'pankhabd'),
			('ddc',							u'ddc'),
			('ethos',						u'ethos'),
			('cihd',						u'cihd'),
			('renegades',					u'renegades'),
			('dekabroken',					u'dekabroken'),
			('triton',						u'triton'),
			('reel',						u'reel'),
			('ouzo',						u'ouzo'),
			('randi',						u'randi'),
			('aihd',						u'aihd'),
			('hqe',							u'hqe'),
			('exps',						u'exps'),
			('genemige',					u'genemige'),
			('sit',							u'sit'),
			('oldsman',						u'oldsman'),
			('hao4k',						u'hao4k'),
			('timegod',						u'timegod'),
			('dreamcatcher',				u'dreamcatcher'),
			('species180',					u'species180'),
			('hdroad',						u'hdroad'),
			('sirpaul',						u'sir{separator}+paul'),
			('ffansweb',					u'ffansweb'),
			('slappy',						u'slappy'),
			('prd',							u'prd'),
			('hay',							u'hay'),
			('novo',						u'novo'),
			('bla',							u'bla'),
			('tinye',						u'tinye'),
			('ohd',							u'ohd'),
			('inklusion',					u'inklusion'),
			('flights',						u'flights'),
			('siambit',						u'siambit'),
			('awake',						u'awake'),
			('suave',						u'suave'),
			('glados',						u'glados'),
			('bonkai77',					u'bonkai77'),
			('ede',							u'ede'),
			('animerg',						u'(?:anime{separator}+rg|animerg)'),
			('fck',							u'fck'),
			('ncpx',						u'ncpx'),
			('kashmir',						u'kashmir'),
			('udf',							u'udf'),
			('wildcat',						u'(?:wildcat|wild{separator}+cat)'),
			('nomore',						u'nomore'),
			('sov',							u'sov'),
			('football',					u'football'),
			('lmg',							u'lmg'),
			('perfectionhd',				u'perfectionhd'),
			('edph',						u'edph'),
			('ubm',							u'ubm'),
			('m794',						u'm794'),
			('ausy',						u'ausy'),
			('mysterion',					u'mysterion'),
			('ifn',							u'ifn'),
			('rkrips',						u'rkrips'),
			('useless',						u'useless'),
			('nima4k',						u'nima4k'),
			('tbr',							u'tbr'),
			('badtaste',					u'badtaste'),
			('hdu',							u'hdu'),
			('truedef',						u'truedef'),
			('mvp',							u'mvp'),
			('sow',							u'sow'),
			('axial',						u'axial'),
			('precursor',					u'precursor'),
			('hidef',						u'hidef'),
			('trexhd',						u'trexhd'),
			('zan',							u'zan'),
			('rudos',						u'rudos'),
			('candial',						u'candial'),
			('dharma',						u'dharma'),
			('adhd',						u'adhd'),
			('alldayin',					u'alldayin'),
			('tsv',							u'tsv'),
			('lff',							u'lff'),
			('fractal',						u'fractal'),
			('bluray3d',					u'bluray3d'),
			('scorn',						u'scorn'),
			('butter',						u'butter'),
			('blueyes',						u'blueyes'),
			('nlc',							u'nlc'),
			('marvelous',					u'marvelous'),
			('maz',							u'maz'),
			('teehee',						u'teehee'),
			('gotv',						u'gotv'),
			('antiordinary',				u'antiordinary'),
			('psycho791',					u'psycho791'),
			('rhd',							u'rhd'),
			('ourbits',						u'ourbits'),
			('whitehat',					u'whitehat'),
			('chgrp',						u'chgrp'),
			('fkkhd',						u'fkkhd'),
			('bda',							u'bda'),
			('jackal',						u'jackal'),
			('lako',						u'lako'),
			('adl',							u'adl'),
			('jetset',						u'jetset'),
			('raoul',						u'raoul'),
			('rig',							u'rig'),
			('oma',							u'oma'),
			('xd2v',						u'xd2v'),
			('sphd',						u'sphd'),
			('etach',						u'etach'),
			('bloodweiser',					u'bloodweiser'),
			('dupli',						u'dupli'),
			('scotluhd',					u'scotluhd'),
			('asister',						u'asister'),
			('d0ber',						u'd0ber'),
			('samfd',						u'samfd'),
			('scarfilm',					u'(?:scarfilm{separator}+org|scarfilm)'),
			('efterlyst',					u'efterlyst'),
			('bk',							u'bk'),
			('scientology',					u'scientology'),
			('iht',							u'iht'),
			('dokumania',					u'dokumania'),
			('highvoltage',					u'highvoltage'),
			('lwn',							u'lwn'),
			('befree',						u'befree'),
			('radius',						u'radius'),
			('valiomedia',					u'valiomedia'),
			('chuppi',						u'chuppi'),
			('sos',							u'sos'),
			('ambitious',					u'ambitious'),
			('c4k',							u'c4k'),
			('qom',							u'qom'),
			('ehmd',						u'ehmd'),
			('fargirenis',					u'fargirenis'),
			('xanax',						u'xanax'),
			('thenightmare',				u'thenightmare'),
			('sby',							u'sby'),
			('gaygay',						u'gaygay'),
			('proxy',						u'proxy'),
			('surya',						u'surya'),
			('zuzuu',						u'zuzuu'),
			('nowinhd',						u'nowinhd'),
			('hostile',						u'hostile'),
			('sft',							u'sft'),
			('skaliwagz',					u'skaliwagz'),
			('otv',							u'otv'),
			('valhalla',					u'valhalla'),
			('spooky',						u'spooky'),
			('emg',							u'emg'),
			('kafferep',					u'kafferep'),
			('timedistortion',				u'timedistortion'),
			('omnic',						u'omnic'),
			('182k',						u'182k'),
			('animetime',					u'anime{separator}+time'),
			('deadpixel',					u'deadpixel'),
			('tooncore',					u'tooncore'),
			('deranged',					u'deranged'),
			('nbdy',						u'nbdy'),
			('jato',						u'jato'),
			('usd',							u'usd'),
			('dflarrowfilms',				u'd{separator}+flarrow{separator}+films'),
			('ignite',						u'ignite'),
			('t4h',							u't4h'),
			('ari',							u'ari'),
			('v0',							u'v0'),
			('sillybird',					u'sillybird'),
			('aurora',						u'aurora'),
			('d0nk',						u'd0nk'),
			('coveiro',						u'coveiro'),
			('mcfly',						u'mcfly'),
			('som',							u'som'),
			('sol',							u'sol'),
			('ov3rl1f3',					u'ov3rl1f3'),
			('p4dge',						u'p4dge'),
			('division',					u'division'),
			('mediamaniacs',				u'mediamaniacs'),
			('shreddie',					u'shreddie'),
			('triad',						u'triad'),
			('nya',							u'nya'),
			('anubis',						u'anubis'),
			('astral',						u'astral'),
			('bdisc',						u'bdisc'),
			('ga645zi',						u'ga645zi'),
			('full4',						u'full4'),
			('wlm',							u'wlm'),
			('mink',						u'mink'),
			('jch',							u'jch'),
			('zmachine',					u'zmachine'),
			('gw',							u'gw'),
			('lunar',						u'lunar'),
			('portos',						u'portos'),
			('cafardax',					u'cafardax'),
			('band1d0s',					u'band1d0s'),
			('sajid790',					u'sajid790'),
			('crest',						u'crest'),
			('gbb',							u'gbb'),
			('hnr',							u'hnr'),
			('doa',							u'doa'),
			('oursuperpilaencode',			u'oursuperpilaencode'),
			('risingsun',					u'(?:rising{separator}+sun|risingsun)'),
			('msr',							u'msr'),
			('zsiso',						u'zsiso'),
			('yuma',						u'yuma'),
			('rjaa',						u'rjaa'),
			('gelob',						u'gelo{separator}+b'),
			('foxy',						u'foxy'),
			('24xhd',						u'24xhd'),
			('bifos',						u'bifos'),
			('bdys',						u'bdys'),
			('fkktv',						u'fkktv'),
			('abu',							u'abu'),
			('aio',							u'aio'),
			('lamehd',						u'lamehd'),
			('lrc',							u'lrc'),
			('swolled',						u'swolled'),
			('lmk',							u'lmk'),
			('mibr',						u'mibr'),
			('reavers',						u'reavers'),
			('underwater',					u'underwater'),
			('momo',						u'momo'),
			('stella',						u'stella'),
			('tof',							u'tof'),
			('sps',							u'sps'),
			('dynamics',					u'dynamics'),
			('lime',						u'lime'),
			('unskilled',					u'unskilled'),
			('moviesevil',					u'moviesevil'),
			('unfired',						u'unfired'),
			('pipick',						u'pipick'),
			('zza',							u'zza'),
			('mis',							u'mis'),
			('m2',							u'm2'),
			('tg7',							u'tg7'),
			('multi4',						u'multi4'),
			('armo',						u'armo'),
			('slomo',						u'slomo'),
			('shotv',						u'shotv'),
			('iy',							u'iy'),
			('zeke',						u'zeke'),
			('dich',						u'dich'),
			('tx',							u'tx'),
			('sunsujaidr',					u'sun{separator}+sujaidr'),
			('jhonny2',						u'jhonny2'),
			('keaton',						u'keaton'),
			('psv',							u'psv'),
			('bradje',						u'bradje'),
			('apb',							u'apb'),
			('dlc',							u'dlc'),
			('thisoneyouwontsell',			u'thisoneyouwontsell'),
			('hdmonsk',						u'hdmonsk'),
			('mobidik',						u'mobidik'),
			('etmid',						u'etmid'),
			('plaid',						u'plaid'),
			('vite',						u'vite'),
			('straub',						u'straub'),
			('konzillarg',					u'konzillarg'),
			('zagon',						u'zagon'),
			('droids',						u'droids'),
			('deviant',						u'deviant'),
			('theend',						u'theend'),
			('xstreem',						u'xstreem'),
			('fuc0v1d',						u'fuc0v1d'),
			('fts',							u'fts'),
			('fto',							u'fto'),
			('pl3x',						u'pl3x'),
			('visionx',						u'visionx'),
			('c1n3m4',						u'c1n3m4'),
			('centi',						u'centi'),
			('oem',							u'oem'),
			('movieit',						u'movieit'),
			('privatehd',					u'privatehd'),
			('c0nfused',					u'c0nfused'),
			('dvdmania',					u'dvdmania'),
			('ott',							u'ott'),
			('sxales',						u'sxales'),
			('hoh',							u'hoh'),
			('rdvas',						u'rdvas'),
			('gop',							u'gop'),
			('tot',							u'tot'),
			('swty',						u'swty'),
			('getb9',						u'getb9'),
			('outdated',					u'outdated'),
			('hubris',						u'hubris'),
			('tts',							u'tts'),
			('tto',							u'tto'),
			('rzf',							u'rzf'),
			('mrm',							u'mrm'),
			('jtv',							u'jtv'),
			('shadowman',					u'shadowman'),
			('scy',							u'scy'),
			('pts',							u'pts'),
			('phoque',						u'phoque'),
			('smc',							u'smc'),
			('d0pe',						u'd0pe'),
			('crohd',						u'crohd'),
			('tfe',							u'tfe'),
			('exy',							u'exy'),
			('doomguy',						u'doomguy'),
			('mouseclick',					u'mouseclick'),
			('bonzo',						u'bonzo'),
			('gm',							u'gm'),
			('volatile',					u'volatile'),
			('dawgsserier',					u'dawgsserier'),
			('leetxd',						u'leetxd'),
			('splendide',					u'splendide'),
			('pretail',						u'pretail'),
			('imacruel1',					u'imacruel1'),
			('hz',							u'hz'),
			('sammie',						u'sammie'),
			('vlaluk',						u'vlaluk'),
			('nosegment',					u'nosegment'),
			('hdhome',						u'hdhome'),
			('slowhd',						u'slowhd'),
			('klassigerhd',					u'klassigerhd'),
			('pims',						u'pims'),
			('formula',						u'formula'),
			('gopanda',						u'gopanda'),
			('decent',						u'decent'),
			('heh',							u'heh'),
			('overtime',					u'overtime'),
			('ffa',							u'ffa'),
			('wrs',							u'wrs'),
			('dthd',						u'dthd'),
			('darktiger',					u'darktiger'),
			('kh',							u'kh'),
			('cdb',							u'cdb'),
			('imdths',						u'imdths'),
			('kata',						u'kata'),
			('grupohds',					u'grupohds'),
			('reserved',					u'reserved'),
			('pudding',						u'pudding'),
			('btv',							u'btv'),
			('termi',						u'termi'),
			('dvl',							u'dvl'),
			('dca',							u'dca'),
			('tomx',						u'tomx'),
			('birdhouse',					u'birdhouse'),
			('drm',							u'drm'),
			('whiterevtmp',					u'whiterevtmp'),
			('mxb',							u'mxb'),
			('6ixt33n',						u'6ixt33n'),
			('df',							u'd{separator}+f'),
			('forsaken',					u'forsaken'),
			('m4xd0me',						u'm4xd0me'),
			('greenstorm',					u'greenstorm'),
			('5kull5',						u'5kull5'),
			('remax',						u'remax'),
			('lse',							u'lse'),
			('extacy',						u'extacy'),
			('rzp',							u'rzp'),
			('stegner',						u'stegner'),
			('hdarea',						u'hdarea'),
			('nmr',							u'nmr'),
			('nme',							u'nme'),
			('threesome',					u'threesome'),
			('igd',							u'igd'),
			('koalf',						u'koalf'),
			('essential',					u'essential'),
			('nsn',							u'nsn'),
			('taichi',						u'taichi'),
			('decade',						u'decade'),
			('tvtime',						u'tvtime'),
			('bien',						u'bien'),
			('revteam',						u'revteam'),
			('regelrecht',					u'regelrecht'),
			('pzk',							u'pzk'),
			('bald',						u'bald'),
			('shunpo',						u'shunpo'),
			('neutrino',					u'neutrino'),
			('dnb',							u'dnb'),
			('sms',							u'sms'),
			('mobbit',						u'mobbit'),
			('euchd',						u'euchd'),
			('s0ld13r',						u's0ld13r'),
			('phmhd',						u'phmhd'),
			('moviesmix',					u'moviesmix'),
			('fizo',						u'fizo'),
			('flt',							u'flt'),
			('banker',						u'banker'),
			('mrc',							u'mrc'),
			('ssk',							u'ssk'),
			('xxunkn0wnxx',					u'xxunkn0wnxx'),
			('videowelt',					u'videowelt'),
			('lod',							u'lod'),
			('sashimi',						u'sashimi'),
			('hhh',							u'hhh'),
			('wavey',						u'wavey'),
			('silu',						u'silu'),
			('r0cked',						u'r0cked'),
			('divas',						u'divas'),
			('ila',							u'ila'),
			('artemis',						u'artemis'),
			('zr',							u'zr'),
			('ru4hd',						u'ru4hd'),
			('fetish',						u'fetish'),
			('heisenberg',					u'heisenberg'),
			('dkids',						u'dkids'),
			('cj',							u'cj'),
			('flintfilms',					u'flintfilms'),
			('gyroscope',					u'gyroscope'),
			('rax',							u'rax'),
			('propl',						u'propl'),
			('roland',						u'roland'),
			('excalibur',					u'excalibur'),
			('slight',						u'slight'),
			('sicfoi',						u'sicfoi'),
			('moa',							u'moa'),
			('nelwyn',						u'nelwyn'),
			('ffs',							u'ffs'),
			('slater',						u'slater'),
			('rdk123',						u'rdk123'),
			('classico',					u'classico'),
			('arthouse',					u'arthouse'),
			('no1cares',					u'no1cares'),
			('o2stk',						u'o2stk'),
			('lame',						u'lame'),
			('crucial',						u'crucial'),
			('aot',							u'aot'),
			('sfs',							u'sfs'),
			('xbay',						u'xbay'),
			('ajp',							u'ajp'),
			('tennreed',					u'tennreed'),
			('p0w4dvd',						u'p0w4dvd'),
			('inp',							u'inp'),
			('m00tv',						u'm00tv'),
			('s4l',							u's4l'),
			('pasha',						u'pasha'),
			('ficodvdr',					u'ficodvdr'),
			('cifer',						u'cifer'),
			('bountyhunters',				u'bountyhunters'),
			('redeamer',					u'rede\@mer'),
			('d2v',							u'd2v'),
			('greid',						u'greid'),
			('connazakamrpirate',			u'connaz{separator}+aka{separator}+mrpirate'),
			('mont',						u'mont'),
			('coalgirls',					u'coalgirls'),
			('donuts',						u'donuts'),
			('mori',						u'mori'),
			('sola',						u'sola'),
			('hevclovers',					u'(?:hevclovers|hevclovers{separator}+com)'),
			('edo',							u'edo'),
			('icn',							u'icn'),
			('whisky',						u'whisky'),
			('ctd',							u'ctd'),
			('omertahd',					u'omertahd'),
			('defused',						u'defused'),
			('caligari',					u'caligari'),
			('tss',							u'tss'),
			('dominion',					u'dominion'),
			('crx',							u'crx'),
			('abbie',						u'abbie'),
			('aeroholics',					u'aeroholics'),
			('stranded',					u'stranded'),
			('tnan',						u'tnan'),
			('kinowelt',					u'kinowelt'),
			('dns',							u'dns'),
			('ginji',						u'ginji'),
			('modemslayer',					u'modemslayer'),
			('aoksquad',					u'aok{separator}+squad'),
			('wihd',						u'wihd'),
			('soy',							u'soy'),
			('chrono',						u'chrono'),
			('smurf',						u'smurf'),
			('bluzilla',					u'bluzilla'),
			('lamexd',						u'lamexd'),
			('ghs',							u'ghs'),
			('kristallprinz',				u'kristallprinz'),
			('dollhead',					u'dollhead'),
			('bigzt',						u'bigzt'),
			('gage',						u'gage'),
			('torrentgui',					u'torrentgui'),
			('almighty',					u'almighty'),
			('invictus',					u'invictus'),
			('rockriot',					u'rockriot'),
			('geneside',					u'geneside'),
			('imsorny',						u'imsorny'),
			('hdvision',					u'hdvision'),
			('aceford',						u'aceford'),
			('bluntslayerobfuscated',		u'bluntslayer{separator}+obfuscated'),
			('rbt',							u'rbt'),
			('p0618',						u'p0{separator}+618'),
			('meister',						u'meister'),
			('betamax',						u'betamax'),
			('bonbon',						u'bonbon'),
			('shiro',						u'shiro'),
			('fzero',						u'fzero'),
			('gwp',							u'gwp'),
			('socks',						u'socks'),
			('djd',							u'djd'),
			('edge2020',					u'edge2020'),
			('dsubs',						u'd{separator}+subs'),
			('nassau',						u'nassau'),
			('cme',							u'cme'),
			('btvrg',						u'btvrg'),
			('mdr',							u'mdr'),
			('4ddl',						u'4ddl'),
			('gooner',						u'gooner'),
			('brutus',						u'brutus'),
			('lovesick',					u'lovesick'),
			('ngr',							u'ngr'),
			('submerge',					u'submerge'),
			('devived',						u'devived'),
			('anonimo',						u'anonimo'),
			('aero',						u'aero'),
			('cybertyger',					u'cybertyger'),
			('prophets',					u'prophets'),
			('ubik',						u'ubik'),
			('4pl',							u'4pl'),
			('xpert',						u'xpert'),
			('ikaos',						u'ikaos'),
			('stp',							u'stp'),
			('4fun',						u'4fun'),
			('movieaddicts',				u'movieaddicts'),
			('bht',							u'bht'),
			('ritalin',						u'ritalin'),
			('newmov',						u'newmov'),
			('slbenfica',					u'slbenfica'),
			('toho',						u'toho'),
			('gvd',							u'gvd'),
			('varyg',						u'varyg'),
			('nflx',						u'nflx'),
			('ladybug',						u'ladybug'),
			('luso',						u'luso'),
			('lusi',						u'lusi'),
			('gellard',						u'gellard'),
			('shr',							u'shr'),
			('zinc',						u'zinc'),
			('capbd',						u'capbd'),
			('hm',							u'hm'),
			('substance',					u'substance'),
			('rastafariantargaryen',		u'rastafariantargaryen'),
			('bigfart',						u'bigfart'),
			('mdm',							u'mdm'),
			('vixon',						u'vixon'),
			('bbdvdr',						u'bbdvdr'),
			('hevcguy',						u'hevcguy'),
			('thebatman',					u'thebatman'),
			('trevor333',					u'trevor333'),
			('justhd',						u'justhd'),
			('flatline',					u'flatline'),
			('sj',							u'sj'),
			('orc',							u'orc'),
			('fme',							u'fme'),
			('psyc',						u'psyc'),
			('watbath',						u'watbath'),
			('nwb',							u'nwb'),
			('lnt',							u'lnt'),
			('anbc',						u'anbc'),
			('dizhuwang',					u'dizhuwang'),
			('wesen',						u'wesen'),
			('flex',						u'flex'),
			('mandr',						u'mandr'),
			('doesntsuck',					u'doesntsuck'),
			('abb',							u'abb'),
			('dopehd',						u'dopehd'),
			('kiyoshistar',					u'kiyoshistar'),
			('vodtv',						u'vodtv'),
			('bluetv',						u'bluetv'),
			('kas',							u'kas'),
			('eff',							u'eff'),
			('motu',						u'motu'),
			('rockefeller',					u'rockefeller'),
			('chihiro',						u'chihiro'),
			('sector',						u'sector'),
			('zechs',						u'zechs'),
			('mirai',						u'mirai'),
			('tcl',							u'tcl'),
			('zel',							u'zel'),
			('qui',							u'qui'),
			('arey',						u'arey'),
			('wolfpack',					u'wolfpack'),
			('fasthd',						u'fasthd'),
			('feral',						u'feral'),
			('goblin10',					u'goblin10'),
			('pta',							u'pta'),
			('fixi0n',						u'fixi0n'),
			('blasphemy',					u'blasphemy'),
			('westside',					u'westside'),
			('graveurexterne',				u'graveurexterne'),
			('muhhd',						u'muhhd'),
			('v99',							u'v99'),
			('akihitosubs',					u'akihitosubs'),
			('backtorg',					u'backtorg'),
			('postx',						u'postx'),
			('kamera',						u'kamera'),
			('derschuft',					u'derschuft'),
			('council',						u'council'),
			('nyu',							u'nyu'),
			('didomh',						u'didomh'),
			('qsp',							u'qsp'),
			('lipan',						u'lipan'),
			('greyhounds',					u'greyhounds'),
			('golumpa',						u'golumpa'),
			('tonyk',						u'tonyk'),
			('tesdrox',						u'tesdrox'),
			('mish',						u'mish'),
			('boredor',						u'boredor'),
			('transience',					u'transience'),
			('k2',							u'k2'),
			('sjca',						u'sjca'),
			('vcore',						u'vcore'),
			('hjs',							u'hjs'),
			('oyhd',						u'oyhd'),
			('zs',							u'zs'),
			('wackos',						u'wackos'),
			('tse',							u'tse'),
			('truedukes',					u'truedukes'),
			('narb',						u'narb'),
			('pyc',							u'pyc'),
			('cache',						u'cache'),
			('phdteam',						u'phdteam'),
			('jason28',						u'jason28'),
			('rias',						u'rias'),
			('pilaf',						u'pilaf'),
			('tweet',						u'tweet'),
			('pahein',						u'pahein'),
			('aku',							u'aku'),
			('atx',							u'at{separator}+x'),
			('object',						u'object'),
			('eszc',						u'eszc'),
			('friday21st',					u'friday21st'),
			('fuckads',						u'fuckads'),
			('lesnick',						u'lesnick'),
			('khp',							u'khp'),
			('c0ke',						u'c0ke'),
			('jvc',							u'jvc'),
			('nys',							u'nys'),
			('d69a74',						u'd69a74'),
			('adblue',						u'adblue'),
			('ndrt',						u'ndrt'),
			('2brothers',					u'2brothers'),
			('sceneguardians',				u'sceneguardians'),
			('ftwhd',						u'(?:ftw{separator}+hd|ftwhd)'),
			('jellybean',					u'jellybean'),
			('badquality',					u'badquality'),
			('n0ttz',						u'n0ttz'),
			('tical',						u'tical'),
			('henderson',					u'henderson'),
			('thebest',						u'thebest'),
			('movee',						u'movee'),
			('teo',							u'teo'),
			('f7',							u'f7'),
			('css',							u'css'),
			('myst',						u'myst'),
			('dina',						u'dina'),
			('gma',							u'gma'),
			('aterfallet',					u'aterfallet'),
			('hyb',							u'hyb'),
			('xibirikinho',					u'xibirikinho'),
			('jbs',							u'jbs'),
			('gsn',							u'gsn'),
			('telefunken',					u'telefunken'),
			('lard',						u'lard'),
			('ppq',							u'ppq'),
			('gnome',						u'gnome'),
			('yourmom',						u'your{separator}+mom'),
			('mse',							u'mse'),
			('peewee',						u'peewee'),
			('autv',						u'autv'),
			('nnr',							u'nnr'),
			('omer',						u'omer'),
			('orgo',						u'orgo'),
			('pze',							u'pze'),
			('mrlore',						u'mrlore'),
			('dcn',							u'dcn'),
			('big4umovies',					u'big4umovies'),
			('hookah',						u'hookah'),
			('zw',							u'zw'),
			('endor',						u'endor'),
			('blurg',						u'blurg'),
			('axine',						u'axine'),
			('rebelsd',						u'rebelsd'),
			('janedoe',						u'janedoe'),
			('slax',						u'slax'),
			('rustle',						u'rustle'),
			('mss',							u'mss'),
			('gzp',							u'gzp'),
			('gtf',							u'gtf'),
			('hdspace',						u'hdspace'),
			('satanic',						u'satanic'),
			('ngserier',					u'ngserier'),
			('semantics',					u'semantics'),
			('glm8892',						u'glm8892'),
			('keg',							u'keg'),
			('sparel',						u'sparel'),
			('piephd',						u'piephd'),
			('burek',						u'burek'),
			('meddy',						u'meddy'),
			('decide',						u'decide'),
			('skizoid',						u'skizoid'),
			('zer0',						u'zer0'),
			('chronos',						u'chronos'),
			('peppe',						u'peppe'),
			('ttva',						u'ttva'),
			('ballerina',					u'ballerina'),
			('just4fun',					u'just4fun'),
			('o0o',							u'o0o'),
			('origen',						u'origen'),
			('madoff',						u'madoff'),
			('v3ritas',						u'v3ritas'),
			('xtsf',						u'xtsf'),
			('redone',						u'redone'),
			('hdme',						u'hdme'),
			('apt',							u'apt'),
			('phocis',						u'phocis'),
			('ls',							u'l{separator}+s'),
			('tatugamescf',					u'tatugamescf'),
			('genuine',						u'genuine'),
			('3lton',						u'3lton'),
			('kf',							u'(?:k{separator}+f|kf)'),
			('aq',							u'aq'),
			('natv',						u'natv'),
			('partyboy',					u'partyboy'),
			('funner',						u'funner'),
		),
	}

	LabelReleaseGroup = {
		LabelDefault : {
			LabelList1		: LabelHidden,
			LabelList2		: LabelHidden,
			LabelList3		: LabelHidden,
			LabelList4		: LabelHidden,
			LabelInfo1		: LabelLong,
			LabelInfo2		: LabelHidden,
			LabelSettings1	: LabelMedium,
			LabelSettings2	: LabelHidden,
		},

		'0mnidvd'					: { LabelShort : '0MNIDVD',						LabelMedium : '0MNiDVD',					LabelLong : '0MNiDVD' },
		'0ptimus'					: { LabelShort : '0PTIMUS',						LabelMedium : '0PTiMUS',					LabelLong : '0PTiMUS' },
		'0sec'						: { LabelShort : '0SEC',						LabelMedium : '0SEC',					LabelLong : '0SEC' },
		'0tv'						: { LabelShort : '0TV',							LabelMedium : '0TV',					LabelLong : '0TV' },
		'1337x'						: { LabelShort : '1337X',						LabelMedium : '1337x',					LabelLong : '1337x' },
		'182k'						: { LabelShort : '182K',						LabelMedium : '182K',					LabelLong : '182K' },
		'1xbet'						: { LabelShort : '1XBET',						LabelMedium : '1XBET',					LabelLong : '1XBET' },
		'24hd'						: { LabelShort : '24HD',						LabelMedium : '24HD',					LabelLong : '24HD' },
		'24xhd'						: { LabelShort : '24XHD',						LabelMedium : '24xHD',					LabelLong : '24xHD' },
		'26k'						: { LabelShort : '26K',							LabelMedium : '26k',					LabelLong : '26k' },
		'2brothers'					: { LabelShort : '2BROTHERS',					LabelMedium : '2Brothers',				LabelLong : '2Brothers' },
		'2dvd'						: { LabelShort : '2DVD',						LabelMedium : '2DVD',					LabelLong : '2DVD' },
		'2hd'						: { LabelShort : '2HD',							LabelMedium : '2HD',					LabelLong : '2HD' },
		'2lions'					: { LabelShort : '2LIONS',						LabelMedium : '2Lions',					LabelLong : '2Lions' },
		'300mbmovieshub'			: { LabelShort : '300MBMOVIESHUB',				LabelMedium : '300MbMoviesHub',			LabelLong : '300MbMoviesHub' },
		'30nama'					: { LabelShort : '30NAMA',						LabelMedium : '30nama',					LabelLong : '30nama' },
		'3li'						: { LabelShort : '3LI',							LabelMedium : '3Li',					LabelLong : '3Li' },
		'3lt0n'						: { LabelShort : '3LT0N',						LabelMedium : '3LT0N',					LabelLong : '3LT0N' },
		'3lton'						: { LabelShort : '3LTON',						LabelMedium : '3LTON',					LabelLong : '3LTON' },
		'420ripz'					: { LabelShort : '420RIPZ',						LabelMedium : '420RipZ',					LabelLong : '420RipZ' },
		'4ddl'						: { LabelShort : '4DDL',						LabelMedium : '4DDL',					LabelLong : '4DDL' },
		'4everdowns'					: { LabelShort : '4EVERDOWNS',					LabelMedium : '4EVERDOWNS',				LabelLong : '4EVERDOWNS' },
		'4fun'						: { LabelShort : '4FUN',						LabelMedium : '4FuN',					LabelLong : '4FuN' },
		'4k4u'						: { LabelShort : '4K4U',						LabelMedium : '4K4U',					LabelLong : '4K4U' },
		'4pl'						: { LabelShort : '4PL',							LabelMedium : '4PL',					LabelLong : '4PL' },
		'4sj'						: { LabelShort : '4SJ',							LabelMedium : '4SJ',					LabelLong : '4SJ' },
		'57chan'					: { LabelShort : '57CHAN',						LabelMedium : '57CHAN',					LabelLong : '57CHAN' },
		'5kull5'					: { LabelShort : '5KULL5',						LabelMedium : '5KULL5',					LabelLong : '5KULL5' },
		'6ixt33n'					: { LabelShort : '6IXT33N',						LabelMedium : '6iXT33N',					LabelLong : '6iXT33N' },
		'7meiju'					: { LabelShort : '7MEIJU',						LabelMedium : '7meiju',					LabelLong : '7meiju' },
		'7rip'						: { LabelShort : '7RIP',						LabelMedium : '7Rip',					LabelLong : '7-Rip' },
		'7sins'						: { LabelShort : '7SINS',						LabelMedium : '7SiNS',					LabelLong : '7SiNS' },
		'99mp4'						: { LabelShort : '99MP4',						LabelMedium : '99Mp4',					LabelLong : '99Mp4' },
		'a1rip'						: { LabelShort : 'A1RIP',						LabelMedium : 'A1Rip',					LabelLong : 'A1Rip' },
		'aa'							: { LabelShort : 'AA',							LabelMedium : 'AA',						LabelLong : '~AA~' },
		'aaa'						: { LabelShort : 'AAA',							LabelMedium : 'AAA',					LabelLong : 'AAA' },
		'aaauhd'					: { LabelShort : 'AAAUHD',						LabelMedium : 'AAAUHD',					LabelLong : 'AAAUHD' },
		'aaf'						: { LabelShort : 'AAF',							LabelMedium : 'aAF',					LabelLong : 'aAF' },
		'ab'							: { LabelShort : 'AB',							LabelMedium : 'aB',						LabelLong : 'aB' },
		'abb'						: { LabelShort : 'ABB',							LabelMedium : 'ABB',					LabelLong : 'ABB' },
		'abbie'						: { LabelShort : 'ABBIE',						LabelMedium : 'ABBiE',					LabelLong : 'ABBiE' },
		'abd'						: { LabelShort : 'ABD',							LabelMedium : 'aBD',					LabelLong : 'aBD' },
		'abh'						: { LabelShort : 'ABH',							LabelMedium : 'ABH',					LabelLong : 'ABH' },
		'abhisona'					: { LabelShort : 'ABHISONA',					LabelMedium : 'AbhiSona',				LabelLong : 'AbhiSona' },
		'abhistuff'					: { LabelShort : 'ABHISTUFF',					LabelMedium : 'AbhiStuff',				LabelLong : 'AbhiStuff' },
		'abjex'						: { LabelShort : 'ABJEX',						LabelMedium : 'Abjex',					LabelLong : 'Abjex' },
		'abm'						: { LabelShort : 'ABM',							LabelMedium : 'ABM',					LabelLong : 'ABM' },
		'absinth'					: { LabelShort : 'ABSINTH',						LabelMedium : 'Absinth',					LabelLong : 'Absinth' },
		'absurdity'					: { LabelShort : 'ABSURDITY',					LabelMedium : 'AbSurdity',				LabelLong : 'AbSurdity' },
		'abu'						: { LabelShort : 'ABU',							LabelMedium : 'ABU',					LabelLong : 'ABU' },
		'abyss'						: { LabelShort : 'ABYSS',						LabelMedium : 'ABYSS',					LabelLong : 'ABYSS' },
		'acab'						: { LabelShort : 'ACAB',						LabelMedium : 'ACAB',					LabelLong : 'ACAB' },
		'aced'						: { LabelShort : 'ACED',						LabelMedium : 'ACED',					LabelLong : 'ACED' },
		'aceford'					: { LabelShort : 'ACEFORD',						LabelMedium : 'aceford',					LabelLong : 'aceford' },
		'ack'						: { LabelShort : 'ACK',							LabelMedium : 'ACK',					LabelLong : 'ACK' },
		'acool'						: { LabelShort : 'ACOOL',						LabelMedium : 'ACOOL',					LabelLong : 'ACOOL' },
		'actie'						: { LabelShort : 'ACTIE',						LabelMedium : 'Actie',					LabelLong : 'Actie' },
		'adblue'					: { LabelShort : 'ADBLUE',						LabelMedium : 'AdBlue',					LabelLong : 'AdBlue' },
		'adhd'						: { LabelShort : 'ADHD',						LabelMedium : 'ADHD',					LabelLong : 'ADHD' },
		'adit'						: { LabelShort : 'ADIT',						LabelMedium : 'AdiT',					LabelLong : 'AdiT' },
		'adl'						: { LabelShort : 'ADL',							LabelMedium : 'aDL',					LabelLong : 'aDL' },
		'adrenaline'					: { LabelShort : 'ADRENALINE',					LabelMedium : 'ADRENALiNE',				LabelLong : 'ADRENALiNE' },
		'adrian'					: { LabelShort : 'ADRIAN',						LabelMedium : 'Adrian',					LabelLong : 'Adrian' },
		'ae'							: { LabelShort : 'AE',							LabelMedium : 'AE',						LabelLong : 'A-E' },
		'aen'						: { LabelShort : 'AEN',							LabelMedium : 'AEN',					LabelLong : 'AEN' },
		'aero'						: { LabelShort : 'AERO',						LabelMedium : 'AERO',					LabelLong : 'AERO' },
		'aeroholics'					: { LabelShort : 'AEROHOLICS',					LabelMedium : 'AEROHOLiCS',				LabelLong : 'AEROHOLiCS' },
		'af'							: { LabelShort : 'AF',							LabelMedium : 'AF',						LabelLong : 'A-F' },
		'affinity'					: { LabelShort : 'AFFINITY',					LabelMedium : 'AFFiNiTY',				LabelLong : 'AFFiNiTY' },
		'afg'						: { LabelShort : 'AFG',							LabelMedium : 'AFG',					LabelLong : 'AFG' },
		'afi'						: { LabelShort : 'AFI',							LabelMedium : 'afi',					LabelLong : 'afi' },
		'afm72'						: { LabelShort : 'AFM72',						LabelMedium : 'afm72',					LabelLong : 'afm72' },
		'afo'						: { LabelShort : 'AFO',							LabelMedium : 'AFO',					LabelLong : 'AFO' },
		'aggr0'						: { LabelShort : 'AGGR0',						LabelMedium : 'aGGr0',					LabelLong : 'aGGr0' },
		'aglet'						: { LabelShort : 'AGLET',						LabelMedium : 'AGLET',					LabelLong : 'AGLET' },
		'agusiq'					: { LabelShort : 'AGUSIQ',						LabelMedium : 'AgusiQ',					LabelLong : 'AgusiQ' },
		'ahd'						: { LabelShort : 'AHD',							LabelMedium : 'AHD',					LabelLong : 'AHD' },
		'aida'						: { LabelShort : 'AIDA',						LabelMedium : 'AIDA',					LabelLong : 'AIDA' },
		'aiden0'					: { LabelShort : 'AIDEN0',						LabelMedium : 'Aiden0',					LabelLong : 'Aiden0' },
		'aihd'						: { LabelShort : 'AIHD',						LabelMedium : 'AiHD',					LabelLong : 'AiHD' },
		'aio'						: { LabelShort : 'AIO',							LabelMedium : 'AiO',					LabelLong : 'AiO' },
		'airline'					: { LabelShort : 'AIRLINE',						LabelMedium : 'AiRLiNE',					LabelLong : 'AiRLiNE' },
		'airtv'						: { LabelShort : 'AIRTV',						LabelMedium : 'AiRTV',					LabelLong : 'AiRTV' },
		'aj'							: { LabelShort : 'AJ',							LabelMedium : 'AJ',						LabelLong : 'AJ' },
		'aja'						: { LabelShort : 'AJA',							LabelMedium : 'AJA',					LabelLong : 'AJA' },
		'ajp'						: { LabelShort : 'AJP',							LabelMedium : 'AJP',					LabelLong : 'AJP' },
		'ajp69'						: { LabelShort : 'AJP69',						LabelMedium : 'AJP69',					LabelLong : 'AJP69' },
		'ak'							: { LabelShort : 'AK',							LabelMedium : 'AK',						LabelLong : 'A-K' },
		'akihitosubs'				: { LabelShort : 'AKIHITOSUBS',					LabelMedium : 'akihitosubs',			LabelLong : 'akihitosubs' },
		'akraa'						: { LabelShort : 'AKRAA',						LabelMedium : 'aKraa',					LabelLong : 'aKraa' },
		'aku'						: { LabelShort : 'AKU',							LabelMedium : 'AKU',					LabelLong : 'AKU' },
		'alanis'					: { LabelShort : 'ALANIS',						LabelMedium : 'ALANiS',					LabelLong : 'ALANiS' },
		'ale13'						: { LabelShort : 'ALE13',						LabelMedium : 'alE13',					LabelLong : 'alE13' },
		'alexfilm'					: { LabelShort : 'ALEXFILM',					LabelMedium : 'AlexFilm',				LabelLong : 'AlexFilm' },
		'alfahd'					: { LabelShort : 'ALFAHD',						LabelMedium : 'AlfaHD',					LabelLong : 'AlfaHD' },
		'alien'						: { LabelShort : 'ALIEN',						LabelMedium : 'ALiEN',					LabelLong : 'ALiEN' },
		'align'						: { LabelShort : 'ALIGN',						LabelMedium : 'ALiGN',					LabelLong : 'ALiGN' },
		'alldayin'					: { LabelShort : 'ALLDAYIN',					LabelMedium : 'ALLDAYiN',				LabelLong : 'ALLDAYiN' },
		'alliance'					: { LabelShort : 'ALLIANCE',					LabelMedium : 'ALLiANCE',				LabelLong : 'ALLiANCE' },
		'almighty'					: { LabelShort : 'ALMIGHTY',					LabelMedium : 'ALMIGHTY',				LabelLong : 'ALMIGHTY' },
		'alt'						: { LabelShort : 'ALT',							LabelMedium : 'ALT',					LabelLong : 'ALT' },
		'alterego'					: { LabelShort : 'ALTEREGO',					LabelMedium : 'ALTEREGO',				LabelLong : 'ALTEREGO' },
		'altezachen'					: { LabelShort : 'ALTEZACHEN',					LabelMedium : 'AlteZachen',				LabelLong : 'AlteZachen' },
		'am'							: { LabelShort : 'AM',							LabelMedium : 'AM',						LabelLong : 'A-M' },
		'ambassador'					: { LabelShort : 'AMBASSADOR',					LabelMedium : 'AMBASSADOR',				LabelLong : 'AMBASSADOR' },
		'ambit'						: { LabelShort : 'AMBIT',						LabelMedium : 'AMBIT',					LabelLong : 'AMBIT' },
		'ambitious'					: { LabelShort : 'AMBITIOUS',					LabelMedium : 'AMBiTiOUS',				LabelLong : 'AMBiTiOUS' },
		'amcon'						: { LabelShort : 'AMCON',						LabelMedium : 'AMCON',					LabelLong : 'AMCON' },
		'ame'						: { LabelShort : 'AME',							LabelMedium : 'AME',					LabelLong : 'AME' },
		'amedia'					: { LabelShort : 'AMEDIA',						LabelMedium : 'Amedia',					LabelLong : 'Amedia' },
		'amiable'					: { LabelShort : 'AMIABLE',						LabelMedium : 'AMIABLE',					LabelLong : 'AMIABLE' },
		'amirite'					: { LabelShort : 'AMIRITE',						LabelMedium : 'AMIRITE',					LabelLong : 'AMIRITE' },
		'amrap'						: { LabelShort : 'AMRAP',						LabelMedium : 'AMRAP',					LabelLong : 'AMRAP' },
		'amx'						: { LabelShort : 'AMX',							LabelMedium : 'AmX',					LabelLong : 'AmX' },
		'an0nym0us'					: { LabelShort : 'AN0NYM0US',					LabelMedium : 'AN0NYM0US',				LabelLong : 'AN0NYM0US' },
		'anarchy'					: { LabelShort : 'ANARCHY',						LabelMedium : 'ANARCHY',					LabelLong : 'ANARCHY' },
		'anbc'						: { LabelShort : 'ANBC',						LabelMedium : 'aNBc',					LabelLong : 'aNBc' },
		'ancient'					: { LabelShort : 'ANCIENT',						LabelMedium : 'ANCIENT',					LabelLong : 'ANCIENT' },
		'andy'						: { LabelShort : 'ANDY',						LabelMedium : 'aNDy',					LabelLong : 'aNDy' },
		'ane'						: { LabelShort : 'ANE',							LabelMedium : 'ANE',					LabelLong : 'ANE' },
		'angelic'					: { LabelShort : 'ANGELIC',						LabelMedium : 'ANGELiC',					LabelLong : 'ANGELiC' },
		'anihls'					: { LabelShort : 'ANIHLS',						LabelMedium : 'ANiHLS',					LabelLong : 'ANiHLS' },
		'animal'					: { LabelShort : 'ANIMAL',						LabelMedium : 'AniMaL',					LabelLong : 'AniMaL' },
		'animerg'					: { LabelShort : 'ANIMERG',						LabelMedium : 'AnimeRG',					LabelLong : 'AnimeRG' },
		'animetime'					: { LabelShort : 'ANIMETIME',					LabelMedium : 'AnimeTime',				LabelLong : 'Anime.Time' },
		'aniurl'					: { LabelShort : 'ANIURL',						LabelMedium : 'ANiURL',					LabelLong : 'ANiURL' },
		'ank'						: { LabelShort : 'ANK',							LabelMedium : 'ANK',					LabelLong : 'ANK' },
		'ann'						: { LabelShort : 'ANN',							LabelMedium : 'Ann',					LabelLong : 'Ann' },
		'ano'						: { LabelShort : 'ANO',							LabelMedium : 'ANO',					LabelLong : 'ANO' },
		'anon'						: { LabelShort : 'ANON',						LabelMedium : 'ANON',					LabelLong : 'ANON' },
		'anona911'					: { LabelShort : 'ANONA911',					LabelMedium : 'ANONA911',				LabelLong : 'ANONA911' },
		'anonimo'					: { LabelShort : 'ANONIMO',						LabelMedium : 'Anonimo',					LabelLong : 'Anonimo' },
		'anoxmous'					: { LabelShort : 'ANOXMOUS',					LabelMedium : 'anoXmous',				LabelLong : 'anoXmous' },
		'ans'						: { LabelShort : 'ANS',							LabelMedium : 'AnS',					LabelLong : 'AnS' },
		'antiordinary'				: { LabelShort : 'ANTIORDINARY',				LabelMedium : 'AntiOrdinary',			LabelLong : 'AntiOrdinary' },
		'anubis'					: { LabelShort : 'ANUBIS',						LabelMedium : 'ANUBIS',					LabelLong : 'ANUBIS' },
		'aoe'						: { LabelShort : 'AOE',							LabelMedium : 'AOE',					LabelLong : 'AOE' },
		'aoksquad'					: { LabelShort : 'AOKSQUAD',					LabelMedium : 'AOKSQUAD',				LabelLong : 'AOK SQUAD' },
		'aot'						: { LabelShort : 'AOT',							LabelMedium : 'AoT',					LabelLong : 'AoT' },
		'ap'							: { LabelShort : 'AP',							LabelMedium : 'AP',						LabelLong : 'AP' },
		'apa'						: { LabelShort : 'APA',							LabelMedium : 'APA',					LabelLong : 'APA' },
		'apb'						: { LabelShort : 'APB',							LabelMedium : 'APB',					LabelLong : 'APB' },
		'apekat'					: { LabelShort : 'APEKAT',						LabelMedium : 'apekat',					LabelLong : 'apekat' },
		'apex'						: { LabelShort : 'APEX',						LabelMedium : 'APEX',					LabelLong : 'APEX' },
		'apt'						: { LabelShort : 'APT',							LabelMedium : 'APT',					LabelLong : 'APT' },
		'aq'							: { LabelShort : 'AQ',							LabelMedium : 'AQ',						LabelLong : 'AQ' },
		'aqos'						: { LabelShort : 'AQOS',						LabelMedium : 'AQOS',					LabelLong : 'AQOS' },
		'ar'							: { LabelShort : 'AR',							LabelMedium : 'AR',						LabelLong : 'A-R' },
		'arc'						: { LabelShort : 'ARC',							LabelMedium : 'ARC',					LabelLong : 'ARC' },
		'archie'					: { LabelShort : 'ARCHIE',						LabelMedium : 'Archie',					LabelLong : 'Archie' },
		'archivist'					: { LabelShort : 'ARCHIVIST',					LabelMedium : 'ARCHiViST',				LabelLong : 'ARCHiViST' },
		'arenabg'					: { LabelShort : 'ARENABG',						LabelMedium : 'ArenaBG',					LabelLong : 'ArenaBG' },
		'arey'						: { LabelShort : 'AREY',						LabelMedium : 'AREY',					LabelLong : 'AREY' },
		'ari'						: { LabelShort : 'ARI',							LabelMedium : 'ARI',					LabelLong : 'ARI' },
		'aries'						: { LabelShort : 'ARIES',						LabelMedium : 'ARiES',					LabelLong : 'ARiES' },
		'arigold'					: { LabelShort : 'ARIGOLD',						LabelMedium : 'ARiGOLD',					LabelLong : 'ARiGOLD' },
		'arin'						: { LabelShort : 'ARIN',						LabelMedium : 'ARiN',					LabelLong : 'ARiN' },
		'arizone'					: { LabelShort : 'ARIZONE',						LabelMedium : 'ARIZONE',					LabelLong : 'ARIZONE' },
		'ark01'						: { LabelShort : 'ARK01',						LabelMedium : 'ARK01',					LabelLong : 'ARK01' },
		'armo'						: { LabelShort : 'ARMO',						LabelMedium : 'ARMO',					LabelLong : 'ARMO' },
		'armor'						: { LabelShort : 'ARMOR',						LabelMedium : 'ArMor',					LabelLong : 'ArMor' },
		'aroma'						: { LabelShort : 'AROMA',						LabelMedium : 'AROMA',					LabelLong : 'AROMA' },
		'arrow'						: { LabelShort : 'ARROW',						LabelMedium : 'ARROW',					LabelLong : 'ARROW' },
		'artemis'					: { LabelShort : 'ARTEMIS',						LabelMedium : 'ARTEMiS',					LabelLong : 'ARTEMiS' },
		'arthouse'					: { LabelShort : 'ARTHOUSE',					LabelMedium : 'ARTHOUSE',				LabelLong : 'ARTHOUSE' },
		'artsubs'					: { LabelShort : 'ARTSUBS',						LabelMedium : 'ArtSubs',					LabelLong : 'ArtSubs' },
		'as'							: { LabelShort : 'AS',							LabelMedium : 'aS',						LabelLong : 'a-S' },
		'asap'						: { LabelShort : 'ASAP',						LabelMedium : 'ASAP',					LabelLong : 'ASAP' },
		'ascendance'					: { LabelShort : 'ASCENDANCE',					LabelMedium : 'ASCENDANCE',				LabelLong : 'ASCENDANCE' },
		'ash61'						: { LabelShort : 'ASH61',						LabelMedium : 'Ash61',					LabelLong : 'Ash61' },
		'asister'					: { LabelShort : 'ASISTER',						LabelMedium : 'AsiSter',					LabelLong : 'AsiSter' },
		'ass'						: { LabelShort : 'ASS',							LabelMedium : 'ASS',					LabelLong : 'AS-S' },
		'assassins'					: { LabelShort : 'ASSASSINS',					LabelMedium : 'ASSASSiNS',				LabelLong : 'ASSASSiNS' },
		'associate'					: { LabelShort : 'ASSOCIATE',					LabelMedium : 'ASSOCiATE',				LabelLong : 'ASSOCiATE' },
		'astral'					: { LabelShort : 'ASTRAL',						LabelMedium : 'ASTRAL',					LabelLong : 'ASTRAL' },
		'astrd'						: { LabelShort : 'ASTRD',						LabelMedium : 'ASTRD',					LabelLong : 'ASTRD' },
		'asw'						: { LabelShort : 'ASW',							LabelMedium : 'ASW',					LabelLong : 'ASW' },
		'at'							: { LabelShort : 'AT',							LabelMedium : 'AT',						LabelLong : 'A-T' },
		'atax'						: { LabelShort : 'ATAX',						LabelMedium : 'ATAX',					LabelLong : 'ATAX' },
		'aterfallet'					: { LabelShort : 'ATERFALLET',					LabelMedium : 'aTerFalleT',				LabelLong : 'aTerFalleT' },
		'atg'						: { LabelShort : 'ATG',							LabelMedium : 'ATG',					LabelLong : 'ATG' },
		'atilla82'					: { LabelShort : 'ATILLA82',					LabelMedium : 'ATILLA82',				LabelLong : 'ATILLA82' },
		'atlas47'					: { LabelShort : 'ATLAS47',						LabelMedium : 'Atlas47',					LabelLong : 'Atlas47' },
		'ats'						: { LabelShort : 'ATS',							LabelMedium : 'ATS',					LabelLong : 'ATS' },
		'atx'						: { LabelShort : 'ATX',							LabelMedium : 'ATX',					LabelLong : 'AT-X' },
		'aurora'					: { LabelShort : 'AURORA',						LabelMedium : 'AURORA',					LabelLong : 'AURORA' },
		'ausy'						: { LabelShort : 'AUSY',						LabelMedium : 'AuSy',					LabelLong : 'AuSy' },
		'authority'					: { LabelShort : 'AUTHORITY',					LabelMedium : 'AUTHORiTY',				LabelLong : 'AUTHORiTY' },
		'autv'						: { LabelShort : 'AUTV',						LabelMedium : 'AUTV',					LabelLong : 'AUTV' },
		'avcdvd'					: { LabelShort : 'AVCDVD',						LabelMedium : 'AVCDVD',					LabelLong : 'AVCDVD' },
		'avchd'						: { LabelShort : 'AVCHD',						LabelMedium : 'AVCHD',					LabelLong : 'AVCHD' },
		'avenue'					: { LabelShort : 'AVENUE',						LabelMedium : 'AVENUE',					LabelLong : 'AVENUE' },
		'avg'						: { LabelShort : 'AVG',							LabelMedium : 'AVG',					LabelLong : 'AVG' },
		'avs'						: { LabelShort : 'AVS',							LabelMedium : 'AVS',					LabelLong : 'AVS' },
		'avs720'					: { LabelShort : 'AVS720',						LabelMedium : 'AVS720',					LabelLong : 'AVS720' },
		'aw'							: { LabelShort : 'AW',							LabelMedium : 'AW',						LabelLong : 'A-W' },
		'awake'						: { LabelShort : 'AWAKE',						LabelMedium : 'aWake',					LabelLong : 'aWake' },
		'awards'					: { LabelShort : 'AWARDS',						LabelMedium : 'AWARDS',					LabelLong : 'AWARDS' },
		'axe'						: { LabelShort : 'AXE',							LabelMedium : 'AXE',					LabelLong : 'AXE' },
		'axed'						: { LabelShort : 'AXED',						LabelMedium : 'AXED',					LabelLong : 'AXED' },
		'axial'						: { LabelShort : 'AXIAL',						LabelMedium : 'AXIAL',					LabelLong : 'AXIAL' },
		'axine'						: { LabelShort : 'AXINE',						LabelMedium : 'AXiNE',					LabelLong : 'AXiNE' },
		'axxo'						: { LabelShort : 'AXXO',						LabelMedium : 'aXXo',					LabelLong : 'aXXo' },
		'aymo'						: { LabelShort : 'AYMO',						LabelMedium : 'AYMO',					LabelLong : 'AYMO' },
		'azaze'						: { LabelShort : 'AZAZE',						LabelMedium : 'AZAZE',					LabelLong : 'AZAZE' },
		'b0mbardiers'				: { LabelShort : 'B0MBARDIERS',					LabelMedium : 'B0MBARDiERS',			LabelLong : 'B0MBARDiERS' },
		'b2b'						: { LabelShort : 'B2B',							LabelMedium : 'B2B',					LabelLong : 'B2B' },
		'b4nd1t69'					: { LabelShort : 'B4ND1T69',					LabelMedium : 'B4ND1T69',				LabelLong : 'B4ND1T69' },
		'ba'							: { LabelShort : 'BA',							LabelMedium : 'BA',						LabelLong : 'B-A' },
		'babylon'					: { LabelShort : 'BABYLON',						LabelMedium : 'BABYLON',					LabelLong : 'BABYLON' },
		'babytorrent'				: { LabelShort : 'BABYTORRENT',					LabelMedium : 'BabyTorrent',			LabelLong : 'BabyTorrent' },
		'backtorg'					: { LabelShort : 'BACKTORG',					LabelMedium : 'BaCKToRG',				LabelLong : 'BaCKToRG' },
		'badassmedia'				: { LabelShort : 'BADASSMEDIA',					LabelMedium : 'BADASSMEDIA',			LabelLong : 'BADASSMEDIA' },
		'badbajo'					: { LabelShort : 'BADBAJO',						LabelMedium : 'BadBajo',					LabelLong : 'BadBajo' },
		'badquality'					: { LabelShort : 'BADQUALITY',					LabelMedium : 'BADQUALITY',				LabelLong : 'BADQUALITY' },
		'badtaste'					: { LabelShort : 'BADTASTE',					LabelMedium : 'BaDTaStE',				LabelLong : 'BaDTaStE' },
		'bae'						: { LabelShort : 'BAE',							LabelMedium : 'BAE',					LabelLong : 'BAE' },
		'baggerinc'					: { LabelShort : 'BAGGERINC',					LabelMedium : 'BaggerInc',				LabelLong : 'BaggerInc' },
		'bags'						: { LabelShort : 'BAGS',						LabelMedium : 'BAGS',					LabelLong : 'BAGS' },
		'baibako'					: { LabelShort : 'BAIBAKO',						LabelMedium : 'BaibaKo',					LabelLong : 'BaibaKo' },
		'baibakotv'					: { LabelShort : 'BAIBAKOTV',					LabelMedium : 'Baibakotv',				LabelLong : 'Baibako.tv' },
		'bajskorv'					: { LabelShort : 'BAJSKORV',					LabelMedium : 'BAJSKORV',				LabelLong : 'BAJSKORV' },
		'baked'						: { LabelShort : 'BAKED',						LabelMedium : 'BAKED',					LabelLong : 'BAKED' },
		'bald'						: { LabelShort : 'BALD',						LabelMedium : 'BaLD',					LabelLong : 'BaLD' },
		'ballerina'					: { LabelShort : 'BALLERINA',					LabelMedium : 'BALLERINA',				LabelLong : 'BALLERINA' },
		'bamboozle'					: { LabelShort : 'BAMBOOZLE',					LabelMedium : 'BAMBOOZLE',				LabelLong : 'BAMBOOZLE' },
		'band1d0s'					: { LabelShort : 'BAND1D0S',					LabelMedium : 'BAND1D0S',				LabelLong : 'BAND1D0S' },
		'banker'					: { LabelShort : 'BANKER',						LabelMedium : 'BaNkeR',					LabelLong : 'BaNkeR' },
		'barbie'					: { LabelShort : 'BARBIE',						LabelMedium : 'BARBIE',					LabelLong : 'BARBIE' },
		'barc0de'					: { LabelShort : 'BARC0DE',						LabelMedium : 'BARC0DE',					LabelLong : 'BARC0DE' },
		'barge'						: { LabelShort : 'BARGE',						LabelMedium : 'BARGE',					LabelLong : 'BARGE' },
		'baron'						: { LabelShort : 'BARON',						LabelMedium : 'BARON',					LabelLong : 'BARON' },
		'bass'						: { LabelShort : 'BASS',						LabelMedium : 'BaSS',					LabelLong : 'BaSS' },
		'batman'					: { LabelShort : 'BATMAN',						LabelMedium : 'BATMAN',					LabelLong : 'BATMAN' },
		'batv'						: { LabelShort : 'BATV',						LabelMedium : 'BATV',					LabelLong : 'BATV' },
		'baum'						: { LabelShort : 'BAUM',						LabelMedium : 'BAUM',					LabelLong : 'BAUM' },
		'bawls'						: { LabelShort : 'BAWLS',						LabelMedium : 'BAWLS',					LabelLong : 'BAWLS' },
		'bb'							: { LabelShort : 'BB',							LabelMedium : 'BB',						LabelLong : 'BB' },
		'bbdvdr'					: { LabelShort : 'BBDVDR',						LabelMedium : 'BBDvDR',					LabelLong : 'BBDvDR' },
		'bbtor'						: { LabelShort : 'BBTOR',						LabelMedium : 'BBTOR',					LabelLong : 'BBTOR' },
		'bd4yu'						: { LabelShort : 'BD4YU',						LabelMedium : 'BD4YU',					LabelLong : 'BD4YU' },
		'bda'						: { LabelShort : 'BDA',							LabelMedium : 'BDA',					LabelLong : 'BDA' },
		'bdc'						: { LabelShort : 'BDC',							LabelMedium : 'BdC',					LabelLong : 'BdC' },
		'bdisc'						: { LabelShort : 'BDISC',						LabelMedium : 'BDiSC',					LabelLong : 'BDiSC' },
		'bdp'						: { LabelShort : 'BDP',							LabelMedium : 'BDP',					LabelLong : 'BDP' },
		'bdys'						: { LabelShort : 'BDYS',						LabelMedium : 'BDYS',					LabelLong : 'BDYS' },
		'bearfish'					: { LabelShort : 'BEARFISH',					LabelMedium : 'Bearfish',				LabelLong : 'Bearfish' },
		'beast'						: { LabelShort : 'BEAST',						LabelMedium : 'beAst',					LabelLong : 'beAst' },
		'bedlam'					: { LabelShort : 'BEDLAM',						LabelMedium : 'BEDLAM',					LabelLong : 'BEDLAM' },
		'beer'						: { LabelShort : 'BEER',						LabelMedium : 'BEER',					LabelLong : 'BEER' },
		'befree'					: { LabelShort : 'BEFREE',						LabelMedium : 'BeFree',					LabelLong : 'BeFree' },
		'beitai'					: { LabelShort : 'BEITAI',						LabelMedium : 'BeiTai',					LabelLong : 'BeiTai' },
		'ben'						: { LabelShort : 'BEN',							LabelMedium : 'BeN',					LabelLong : 'BeN' },
		'bennett'					: { LabelShort : 'BENNETT',						LabelMedium : 'BENNETT',					LabelLong : 'BENNETT' },
		'bestdivx'					: { LabelShort : 'BESTDIVX',					LabelMedium : 'BeStDivX',				LabelLong : 'BeStDivX' },
		'besthd'					: { LabelShort : 'BESTHD',						LabelMedium : 'BestHD',					LabelLong : 'BestHD' },
		'bet'						: { LabelShort : 'BET',							LabelMedium : 'BET',					LabelLong : 'BET' },
		'betamax'					: { LabelShort : 'BETAMAX',						LabelMedium : 'BETAMAX',					LabelLong : 'BETAMAX' },
		'beyondhd'					: { LabelShort : 'BEYONDHD',					LabelMedium : 'BeyondHD',				LabelLong : 'BeyondHD' },
		'bf1'						: { LabelShort : 'BF1',							LabelMedium : 'BF1',					LabelLong : 'BF1' },
		'bff'						: { LabelShort : 'BFF',							LabelMedium : 'BFF',					LabelLong : 'BFF' },
		'bg'							: { LabelShort : 'BG',							LabelMedium : 'BG',						LabelLong : 'B-G' },
		'bge'						: { LabelShort : 'BGE',							LabelMedium : 'BGE',					LabelLong : 'BGE' },
		'bgfr'						: { LabelShort : 'BGFR',						LabelMedium : 'BgFr',					LabelLong : 'BgFr' },
		'bhatti'					: { LabelShort : 'BHATTI',						LabelMedium : 'BHATTI',					LabelLong : 'BHATTI' },
		'bhd'						: { LabelShort : 'BHD',							LabelMedium : 'BHD',					LabelLong : 'BHD' },
		'bhdstudio'					: { LabelShort : 'BHDSTUDIO',					LabelMedium : 'BHDStudio',				LabelLong : 'BHDStudio' },
		'bhrg'						: { LabelShort : 'BHRG',						LabelMedium : 'BHRG',					LabelLong : 'BHRG' },
		'bht'						: { LabelShort : 'BHT',							LabelMedium : 'BHT',					LabelLong : 'BHT' },
		'bia'						: { LabelShort : 'BIA',							LabelMedium : 'BiA',					LabelLong : 'BiA' },
		'bida'						: { LabelShort : 'BIDA',						LabelMedium : 'BiDA',					LabelLong : 'BiDA' },
		'bien'						: { LabelShort : 'BIEN',						LabelMedium : 'BiEN',					LabelLong : 'BiEN' },
		'bifos'						: { LabelShort : 'BIFOS',						LabelMedium : 'BiFOS',					LabelLong : 'BiFOS' },
		'big4umovies'				: { LabelShort : 'BIG4UMOVIES',					LabelMedium : 'Big4uMOVIES',			LabelLong : 'Big4uMOVIES' },
		'bigdoc'					: { LabelShort : 'BIGDOC',						LabelMedium : 'BIGDOC',					LabelLong : 'BIGDOC' },
		'bigfart'					: { LabelShort : 'BIGFART',						LabelMedium : 'BiGFArT',					LabelLong : 'BiGFArT' },
		'bigint'					: { LabelShort : 'BIGINT',						LabelMedium : 'BiGiNT',					LabelLong : 'BiGiNT' },
		'bigjazz'					: { LabelShort : 'BIGJAZZ',						LabelMedium : 'Bigjazz',					LabelLong : 'Bigjazz' },
		'bigsinema'					: { LabelShort : 'BIGSINEMA',					LabelMedium : 'Bigsinema',				LabelLong : 'Bigsinema' },
		'bigzt'						: { LabelShort : 'BIGZT',						LabelMedium : 'BigZT',					LabelLong : 'BigZT' },
		'bingo'						: { LabelShort : 'BINGO',						LabelMedium : 'BINGO',					LabelLong : 'BINGO' },
		'bipolar'					: { LabelShort : 'BIPOLAR',						LabelMedium : 'BiPOLAR',					LabelLong : 'BiPOLAR' },
		'biq'						: { LabelShort : 'BIQ',							LabelMedium : 'BiQ',					LabelLong : 'BiQ' },
		'birdhouse'					: { LabelShort : 'BIRDHOUSE',					LabelMedium : 'BiRDHOUSE',				LabelLong : 'BiRDHOUSE' },
		'bish'						: { LabelShort : 'BISH',						LabelMedium : 'BiSH',					LabelLong : 'BiSH' },
		'bithd'						: { LabelShort : 'BITHD',						LabelMedium : 'BITHD',					LabelLong : 'BITHD' },
		'bito'						: { LabelShort : 'BITO',						LabelMedium : 'BiTo',					LabelLong : 'BiTo' },
		'bizkit'					: { LabelShort : 'BIZKIT',						LabelMedium : 'BiZKiT',					LabelLong : 'BiZKiT' },
		'bjl'						: { LabelShort : 'BJL',							LabelMedium : 'BJL',					LabelLong : 'BJL' },
		'bk'							: { LabelShort : 'BK',							LabelMedium : 'BK',						LabelLong : 'BK' },
		'bla'						: { LabelShort : 'BLA',							LabelMedium : 'BLA',					LabelLong : 'BLA' },
		'black'						: { LabelShort : 'BLACK',						LabelMedium : 'BLACK',					LabelLong : 'BLACK' },
		'blackbit'					: { LabelShort : 'BLACKBIT',					LabelMedium : 'BlackBit',				LabelLong : 'BlackBit' },
		'blackhat'					: { LabelShort : 'BLACKHAT',					LabelMedium : 'BLACKHAT',				LabelLong : 'BLACKHAT' },
		'bladebdp'					: { LabelShort : 'BLADEBDP',					LabelMedium : 'BladeBDP',				LabelLong : 'BladeBDP' },
		'blasphemy'					: { LabelShort : 'BLASPHEMY',					LabelMedium : 'BLASPHEMY',				LabelLong : 'BLASPHEMY' },
		'blaze'						: { LabelShort : 'BLAZE',						LabelMedium : 'BlaZe',					LabelLong : 'BlaZe' },
		'blin'						: { LabelShort : 'BLIN',						LabelMedium : 'BLiN',					LabelLong : 'BLiN' },
		'blitzkrieg'					: { LabelShort : 'BLITZKRIEG',					LabelMedium : 'BLiTZKRiEG',				LabelLong : 'BLiTZKRiEG' },
		'bloodweiser'				: { LabelShort : 'BLOODWEISER',					LabelMedium : 'BLooDWeiSeR',			LabelLong : 'BLooDWeiSeR' },
		'blow'						: { LabelShort : 'BLOW',						LabelMedium : 'BLOW',					LabelLong : 'BLOW' },
		'bludragon'					: { LabelShort : 'BLUDRAGON',					LabelMedium : 'BluDragon',				LabelLong : 'BluDragon' },
		'bluebird'					: { LabelShort : 'BLUEBIRD',					LabelMedium : 'BlueBird',				LabelLong : 'BlueBird' },
		'bluetv'					: { LabelShort : 'BLUETV',						LabelMedium : 'BlueTV',					LabelLong : 'BlueTV' },
		'bluevo'					: { LabelShort : 'BLUEVO',						LabelMedium : 'BluEvo',					LabelLong : 'BluEvo' },
		'blueyes'					: { LabelShort : 'BLUEYES',						LabelMedium : 'BLUEYES',					LabelLong : 'BLUEYES' },
		'bluhd'						: { LabelShort : 'BLUHD',						LabelMedium : 'BluHD',					LabelLong : 'BluHD' },
		'bluntslayerobfuscated'		: { LabelShort : 'BLUNTSLAYEROBFUSCATED',		LabelMedium : 'BluntSlayerObfuscated',	LabelLong : 'BluntSlayer-Obfuscated' },
		'blupanther'					: { LabelShort : 'BLUPANTHER',					LabelMedium : 'BluPanther',				LabelLong : 'BluPanther' },
		'bluray3d'					: { LabelShort : 'BLURAY3D',					LabelMedium : 'BluRay3D',				LabelLong : 'BluRay3D' },
		'blurg'						: { LabelShort : 'BLURG',						LabelMedium : 'BluRG',					LabelLong : 'BluRG' },
		'blutonium'					: { LabelShort : 'BLUTONIUM',					LabelMedium : 'BLUTONiUM',				LabelLong : 'BLUTONiUM' },
		'bluury'					: { LabelShort : 'BLUURY',						LabelMedium : 'BLUURY',					LabelLong : 'BLUURY' },
		'bluworld'					: { LabelShort : 'BLUWORLD',					LabelMedium : 'BLUWORLD',				LabelLong : 'BLUWORLD' },
		'bluzilla'					: { LabelShort : 'BLUZILLA',					LabelMedium : 'BluZilla',				LabelLong : 'BluZilla' },
		'bmf'						: { LabelShort : 'BMF',							LabelMedium : 'BMF',					LabelLong : 'BMF' },
		'bob'						: { LabelShort : 'BOB',							LabelMedium : 'BoB',					LabelLong : 'BoB' },
		'bobo'						: { LabelShort : 'BOBO',						LabelMedium : 'BoBo',					LabelLong : 'BoBo' },
		'bokutox'					: { LabelShort : 'BOKUTOX',						LabelMedium : 'BOKUTOX',					LabelLong : 'BOKUTOX' },
		'bonbon'					: { LabelShort : 'BONBON',						LabelMedium : 'BONBON',					LabelLong : 'BONBON' },
		'bone'						: { LabelShort : 'BONE',						LabelMedium : 'BONE',					LabelLong : 'BONE' },
		'bong'						: { LabelShort : 'BONG',						LabelMedium : 'BonG',					LabelLong : 'BonG' },
		'bonkai77'					: { LabelShort : 'BONKAI77',					LabelMedium : 'bonkai77',				LabelLong : 'bonkai77' },
		'bonsai'					: { LabelShort : 'BONSAI',						LabelMedium : 'BONSAI',					LabelLong : 'BONSAI' },
		'bonzo'						: { LabelShort : 'BONZO',						LabelMedium : 'BONZO',					LabelLong : 'BONZO' },
		'boo'						: { LabelShort : 'BOO',							LabelMedium : 'BoO',					LabelLong : 'BoO' },
		'boop'						: { LabelShort : 'BOOP',						LabelMedium : 'BOOP',					LabelLong : 'BOOP' },
		'bootstrap'					: { LabelShort : 'BOOTSTRAP',					LabelMedium : 'Bootstrap',				LabelLong : 'Bootstrap' },
		'borderline'					: { LabelShort : 'BORDERLINE',					LabelMedium : 'BORDERLiNE',				LabelLong : 'BORDERLiNE' },
		'bordure'					: { LabelShort : 'BORDURE',						LabelMedium : 'BORDURE',					LabelLong : 'BORDURE' },
		'boredor'					: { LabelShort : 'BOREDOR',						LabelMedium : 'BOREDOR',					LabelLong : 'BOREDOR' },
		'bountyhunters'				: { LabelShort : 'BOUNTYHUNTERS',				LabelMedium : 'BountyHunters',			LabelLong : 'BountyHunters' },
		'bow'						: { LabelShort : 'BOW',							LabelMedium : 'BOW',					LabelLong : 'BOW' },
		'bozx'						: { LabelShort : 'BOZX',						LabelMedium : 'BOZX',					LabelLong : 'BOZX' },
		'brad'						: { LabelShort : 'BRAD',						LabelMedium : 'BraD',					LabelLong : 'BraD' },
		'bradje'					: { LabelShort : 'BRADJE',						LabelMedium : 'BRADJE',					LabelLong : 'BRADJE' },
		'bravery'					: { LabelShort : 'BRAVERY',						LabelMedium : 'BRAVERY',					LabelLong : 'BRAVERY' },
		'brazino777'					: { LabelShort : 'BRAZINO777',					LabelMedium : 'BRAZINO777',				LabelLong : 'BRAZINO777' },
		'break'						: { LabelShort : 'BREAK',						LabelMedium : 'bReAK',					LabelLong : 'bReAK' },
		'breakers'					: { LabelShort : 'BREAKERS',					LabelMedium : 'BREAKERS',				LabelLong : 'BREAKERS' },
		'brg'						: { LabelShort : 'BRG',							LabelMedium : 'BrG',					LabelLong : 'BrG' },
		'bright'					: { LabelShort : 'BRIGHT',						LabelMedium : 'BRiGHT',					LabelLong : 'BRiGHT' },
		'brisk'						: { LabelShort : 'BRISK',						LabelMedium : 'BRISK',					LabelLong : 'BRISK' },
		'brmp'						: { LabelShort : 'BRMP',						LabelMedium : 'BRMP',					LabelLong : 'BRMP' },
		'brn'						: { LabelShort : 'BRN',							LabelMedium : 'BRN',					LabelLong : 'BRN' },
		'brshnkv'					: { LabelShort : 'BRSHNKV',						LabelMedium : 'BRSHNKV',					LabelLong : 'BRSHNKV' },
		'brutus'					: { LabelShort : 'BRUTUS',						LabelMedium : 'BRUTUS',					LabelLong : 'BRUTUS' },
		'bs'							: { LabelShort : 'BS',							LabelMedium : 'BS',						LabelLong : 'BS' },
		'bst'						: { LabelShort : 'BST',							LabelMedium : 'BST',					LabelLong : 'BST' },
		'bt'							: { LabelShort : 'BT',							LabelMedium : 'BT',						LabelLong : 'BT' },
		'bt4k'						: { LabelShort : 'BT4K',						LabelMedium : 'BT4K',					LabelLong : 'BT4K' },
		'btchkek'					: { LabelShort : 'BTCHKEK',						LabelMedium : 'BTCHKEK',					LabelLong : 'BTCHKEK' },
		'btdx8'						: { LabelShort : 'BTDX8',						LabelMedium : 'BTDX8',					LabelLong : 'BTDX8' },
		'btn'						: { LabelShort : 'BTN',							LabelMedium : 'BTN',					LabelLong : 'BTN' },
		'btsfilms'					: { LabelShort : 'BTSFILMS',					LabelMedium : 'BTSFilms',				LabelLong : 'BTSFilms' },
		'btshoufa'					: { LabelShort : 'BTSHOUFA',					LabelMedium : 'BTshoufa',				LabelLong : 'BTshoufa' },
		'btt'						: { LabelShort : 'BTT',							LabelMedium : 'BTT',					LabelLong : 'BTT' },
		'btv'						: { LabelShort : 'BTV',							LabelMedium : 'BTV',					LabelLong : 'BTV' },
		'btvrg'						: { LabelShort : 'BTVRG',						LabelMedium : 'BTVRG',					LabelLong : 'BTVRG' },
		'btw'						: { LabelShort : 'BTW',							LabelMedium : 'BTW',					LabelLong : 'BTW' },
		'btx'						: { LabelShort : 'BTX',							LabelMedium : 'BTX',					LabelLong : 'BTX' },
		'bubanee'					: { LabelShort : 'BUBANEE',						LabelMedium : 'Bubanee',					LabelLong : 'Bubanee' },
		'budgetbits'					: { LabelShort : 'BUDGETBITS',					LabelMedium : 'budgetbits',				LabelLong : 'budgetbits' },
		'bugsfunny'					: { LabelShort : 'BUGSFUNNY',					LabelMedium : 'BugsFunny',				LabelLong : 'BugsFunny' },
		'bugz'						: { LabelShort : 'BUGZ',						LabelMedium : 'BugZ',					LabelLong : 'BugZ' },
		'bugzbunny'					: { LabelShort : 'BUGZBUNNY',					LabelMedium : 'BugzBunny',				LabelLong : 'BugzBunny' },
		'bulgariahd'					: { LabelShort : 'BULGARIAHD',					LabelMedium : 'BulgariaHD',				LabelLong : 'BulgariaHD' },
		'bulldozer'					: { LabelShort : 'BULLDOZER',					LabelMedium : 'BULLDOZER',				LabelLong : 'BULLDOZER' },
		'bullit'					: { LabelShort : 'BULLIT',						LabelMedium : 'BuLLiT',					LabelLong : 'BuLLiT' },
		'bunny'						: { LabelShort : 'BUNNY',						LabelMedium : 'BUNNY',					LabelLong : 'BUNNY' },
		'burek'						: { LabelShort : 'BUREK',						LabelMedium : 'BuReK',					LabelLong : 'BuReK' },
		'burger'					: { LabelShort : 'BURGER',						LabelMedium : 'BURGER',					LabelLong : 'BURGER' },
		'butter'					: { LabelShort : 'BUTTER',						LabelMedium : 'BUTTER',					LabelLong : 'BUTTER' },
		'buymore'					: { LabelShort : 'BUYMORE',						LabelMedium : 'BUYMORE',					LabelLong : 'BUYMORE' },
		'bwb'						: { LabelShort : 'BWB',							LabelMedium : 'BWB',					LabelLong : 'BWB' },
		'bx'							: { LabelShort : 'BX',							LabelMedium : 'BX',						LabelLong : 'BX' },
		'byme7alh'					: { LabelShort : 'BYME7ALH',					LabelMedium : 'byMe7alh',				LabelLong : 'byMe7alh' },
		'byteshare'					: { LabelShort : 'BYTESHARE',					LabelMedium : 'ByteShare',				LabelLong : 'ByteShare' },
		'bzingaz'					: { LabelShort : 'BZINGAZ',						LabelMedium : 'Bzingaz',					LabelLong : 'Bzingaz' },
		'c0ke'						: { LabelShort : 'C0KE',						LabelMedium : 'c0kE',					LabelLong : 'c0kE' },
		'c0nfused'					: { LabelShort : 'C0NFUSED',					LabelMedium : 'c0nFuSed',				LabelLong : 'c0nFuSed' },
		'c1'							: { LabelShort : 'C1',							LabelMedium : 'C1',						LabelLong : 'C1' },
		'c1n3m4'					: { LabelShort : 'C1N3M4',						LabelMedium : 'C1N3M4',					LabelLong : 'C1N3M4' },
		'c1nem4'					: { LabelShort : 'C1NEM4',						LabelMedium : 'C1NEM4',					LabelLong : 'C1NEM4' },
		'c2c'						: { LabelShort : 'C2C',							LabelMedium : 'C2C',					LabelLong : 'C2C' },
		'c4k'						: { LabelShort : 'C4K',							LabelMedium : 'C4K',					LabelLong : 'C4K' },
		'c4tv'						: { LabelShort : 'C4TV',						LabelMedium : 'C4TV',					LabelLong : 'C4TV' },
		'c78'						: { LabelShort : 'C78',							LabelMedium : 'C78',					LabelLong : 'C78' },
		'c7b'						: { LabelShort : 'C7B',							LabelMedium : 'C7B',					LabelLong : 'C7B' },
		'cache'						: { LabelShort : 'CACHE',						LabelMedium : 'CACHE',					LabelLong : 'CACHE' },
		'cadaver'					: { LabelShort : 'CADAVER',						LabelMedium : 'CADAVER',					LabelLong : 'CADAVER' },
		'caf'						: { LabelShort : 'CAF',							LabelMedium : 'CAF',					LabelLong : 'CAF' },
		'cafardax'					: { LabelShort : 'CAFARDAX',					LabelMedium : 'CaFaRDaX',				LabelLong : 'CaFaRDaX' },
		'caffeine'					: { LabelShort : 'CAFFEINE',					LabelMedium : 'CAFFEiNE',				LabelLong : 'CAFFEiNE' },
		'cake'						: { LabelShort : 'CAKE',						LabelMedium : 'CAKE',					LabelLong : 'CAKE' },
		'cakes'						: { LabelShort : 'CAKES',						LabelMedium : 'CAKES',					LabelLong : 'CAKES' },
		'caligari'					: { LabelShort : 'CALIGARI',					LabelMedium : 'CALiGARi',				LabelLong : 'CALiGARi' },
		'callmebrado'				: { LabelShort : 'CALLMEBRADO',					LabelMedium : 'CallMeBrado',			LabelLong : 'CallMeBrado' },
		'camelot'					: { LabelShort : 'CAMELOT',						LabelMedium : 'CAMELOT',					LabelLong : 'CAMELOT' },
		'candial'					: { LabelShort : 'CANDIAL',						LabelMedium : 'Candial',					LabelLong : 'Candial' },
		'capbd'						: { LabelShort : 'CAPBD',						LabelMedium : 'CapBd',					LabelLong : 'CapBd' },
		'caph'						: { LabelShort : 'CAPH',						LabelMedium : 'CAPH',					LabelLong : 'CAPH' },
		'capricorn'					: { LabelShort : 'CAPRICORN',					LabelMedium : 'CAPRiCORN',				LabelLong : 'CAPRiCORN' },
		'carpediem'					: { LabelShort : 'CARPEDIEM',					LabelMedium : 'CarpeDiem',				LabelLong : 'CarpeDiem' },
		'cartel'					: { LabelShort : 'CARTEL',						LabelMedium : 'CARTEL',					LabelLong : 'CARTEL' },
		'carved'					: { LabelShort : 'CARVED',						LabelMedium : 'CARVED',					LabelLong : 'CARVED' },
		'casstudio'					: { LabelShort : 'CASSTUDIO',					LabelMedium : 'CasStudio',				LabelLong : 'CasStudio' },
		'catch'						: { LabelShort : 'CATCH',						LabelMedium : 'CATCH',					LabelLong : 'CATCH' },
		'cbfm'						: { LabelShort : 'CBFM',						LabelMedium : 'CBFM',					LabelLong : 'CBFM' },
		'cbgb'						: { LabelShort : 'CBGB',						LabelMedium : 'CBGB',					LabelLong : 'CBGB' },
		'cbm'						: { LabelShort : 'CBM',							LabelMedium : 'CBM',					LabelLong : 'CBM' },
		'cc'							: { LabelShort : 'CC',							LabelMedium : 'CC',						LabelLong : 'CC' },
		'ccat'						: { LabelShort : 'CCAT',						LabelMedium : 'CCAT',					LabelLong : 'CCAT' },
		'cdb'						: { LabelShort : 'CDB',							LabelMedium : 'CDB',					LabelLong : 'CDB' },
		'cdd'						: { LabelShort : 'CDD',							LabelMedium : 'CDD',					LabelLong : 'CDD' },
		'cddhd'						: { LabelShort : 'CDDHD',						LabelMedium : 'CDDHD',					LabelLong : 'CDDHD' },
		'cdp'						: { LabelShort : 'CDP',							LabelMedium : 'CDP',					LabelLong : 'CDP' },
		'centi'						: { LabelShort : 'CENTI',						LabelMedium : 'CENTi',					LabelLong : 'CENTi' },
		'cf'							: { LabelShort : 'CF',							LabelMedium : 'CF',						LabelLong : 'CF' },
		'chakra'					: { LabelShort : 'CHAKRA',						LabelMedium : 'CHAKRA',					LabelLong : 'CHAKRA' },
		'chamele0n'					: { LabelShort : 'CHAMELE0N',					LabelMedium : 'Chamele0n',				LabelLong : 'Chamele0n' },
		'chattchittorg'				: { LabelShort : 'CHATTCHITTORG',				LabelMedium : 'ChattChittoRG',			LabelLong : 'ChattChitto RG' },
		'chc'						: { LabelShort : 'CHC',							LabelMedium : 'CHC',					LabelLong : 'CHC' },
		'chd'						: { LabelShort : 'CHD',							LabelMedium : 'CHD',					LabelLong : 'CHD' },
		'chdbits'					: { LabelShort : 'CHDBITS',						LabelMedium : 'CHDBits',					LabelLong : 'CHDBits' },
		'checkmate'					: { LabelShort : 'CHECKMATE',					LabelMedium : 'CHECKMATE',				LabelLong : 'CHECKMATE' },
		'chgrp'						: { LabelShort : 'CHGRP',						LabelMedium : 'CHGRP',					LabelLong : 'CHGRP' },
		'chihiro'					: { LabelShort : 'CHIHIRO',						LabelMedium : 'Chihiro',					LabelLong : 'Chihiro' },
		'chivaman'					: { LabelShort : 'CHIVAMAN',					LabelMedium : 'Chivaman',				LabelLong : 'Chivaman' },
		'chotab'					: { LabelShort : 'CHOTAB',						LabelMedium : 'Chotab',					LabelLong : 'Chotab' },
		'chronicles'					: { LabelShort : 'CHRONICLES',					LabelMedium : 'CHRONiCLES',				LabelLong : 'CHRONiCLES' },
		'chrono'					: { LabelShort : 'CHRONO',						LabelMedium : 'CHRONO',					LabelLong : 'CHRONO' },
		'chronos'					: { LabelShort : 'CHRONOS',						LabelMedium : 'CHRONOS',					LabelLong : 'CHRONOS' },
		'cht'						: { LabelShort : 'CHT',							LabelMedium : 'CHT',					LabelLong : 'CHT' },
		'chuppi'					: { LabelShort : 'CHUPPI',						LabelMedium : 'CHUPPI',					LabelLong : 'CHUPPI' },
		'cia'						: { LabelShort : 'CIA',							LabelMedium : 'CiA',					LabelLong : 'CiA' },
		'cielo'						: { LabelShort : 'CIELO',						LabelMedium : 'CiELO',					LabelLong : 'CiELO' },
		'cielos'					: { LabelShort : 'CIELOS',						LabelMedium : 'CiELOS',					LabelLong : 'CiELOS' },
		'cifer'						: { LabelShort : 'CIFER',						LabelMedium : 'CiFER',					LabelLong : 'CiFER' },
		'cihd'						: { LabelShort : 'CIHD',						LabelMedium : 'CiHD',					LabelLong : 'CiHD' },
		'cinecalidad'				: { LabelShort : 'CINECALIDAD',					LabelMedium : 'Cinecalidad',			LabelLong : 'Cinecalidad' },
		'cinedome'					: { LabelShort : 'CINEDOME',					LabelMedium : 'CiNEDOME',				LabelLong : 'CiNEDOME' },
		'cinefeel'					: { LabelShort : 'CINEFEEL',					LabelMedium : 'Cinefeel',				LabelLong : 'Cinefeel' },
		'cinefile'					: { LabelShort : 'CINEFILE',					LabelMedium : 'CiNEFiLE',				LabelLong : 'CiNEFiLE' },
		'cinefox'					: { LabelShort : 'CINEFOX',						LabelMedium : 'CiNEFOX',					LabelLong : 'CiNEFOX' },
		'cinemaet'					: { LabelShort : 'CINEMAET',					LabelMedium : 'CiNEMAET',				LabelLong : 'CiNEMAET' },
		'cinemania'					: { LabelShort : 'CINEMANIA',					LabelMedium : 'CINEMANIA',				LabelLong : 'CINEMANIA' },
		'cinevision'					: { LabelShort : 'CINEVISION',					LabelMedium : 'CiNEViSiON',				LabelLong : 'CiNEViSiON' },
		'circle'					: { LabelShort : 'CIRCLE',						LabelMedium : 'CiRCLE',					LabelLong : 'CiRCLE' },
		'cis'						: { LabelShort : 'CIS',							LabelMedium : 'CIS',					LabelLong : 'CIS' },
		'cj'							: { LabelShort : 'CJ',							LabelMedium : 'CJ',						LabelLong : 'CJ' },
		'classico'					: { LabelShort : 'CLASSICO',					LabelMedium : 'CLASSiCO',				LabelLong : 'CLASSiCO' },
		'cldd'						: { LabelShort : 'CLDD',						LabelMedium : 'CLDD',					LabelLong : 'CLDD' },
		'cleo'						: { LabelShort : 'CLEO',						LabelMedium : 'Cleo',					LabelLong : 'Cleo' },
		'clerks'					: { LabelShort : 'CLERKS',						LabelMedium : 'CLERKS',					LabelLong : 'CLERKS' },
		'clockwork'					: { LabelShort : 'CLOCKWORK',					LabelMedium : 'CLOCKWORK',				LabelLong : 'CLOCKWORK' },
		'clue'						: { LabelShort : 'CLUE',						LabelMedium : 'CLUE',					LabelLong : 'CLUE' },
		'cm'							: { LabelShort : 'CM',							LabelMedium : 'CM',						LabelLong : 'CM' },
		'cm8'						: { LabelShort : 'CM8',							LabelMedium : 'CM8',					LabelLong : 'CM8' },
		'cme'						: { LabelShort : 'CME',							LabelMedium : 'CME',					LabelLong : 'CME' },
		'cmr'						: { LabelShort : 'CMR',							LabelMedium : 'CMR',					LabelLong : 'CMR' },
		'cmrg'						: { LabelShort : 'CMRG',						LabelMedium : 'CMRG',					LabelLong : 'CMRG' },
		'cnhd'						: { LabelShort : 'CNHD',						LabelMedium : 'CNHD',					LabelLong : 'CNHD' },
		'cnscg'						: { LabelShort : 'CNSCG',						LabelMedium : 'CnSCG',					LabelLong : 'CnSCG' },
		'coalgirls'					: { LabelShort : 'COALGIRLS',					LabelMedium : 'Coalgirls',				LabelLong : 'Coalgirls' },
		'coalition'					: { LabelShort : 'COALITION',					LabelMedium : 'COALiTiON',				LabelLong : 'COALiTiON' },
		'coaster'					: { LabelShort : 'COASTER',						LabelMedium : 'COASTER',					LabelLong : 'COASTER' },
		'cocain'					: { LabelShort : 'COCAIN',						LabelMedium : 'COCAIN',					LabelLong : 'COCAIN' },
		'codres'					: { LabelShort : 'CODRES',						LabelMedium : 'Codres',					LabelLong : 'Codres' },
		'cody'						: { LabelShort : 'CODY',						LabelMedium : 'CODY',					LabelLong : 'CODY' },
		'coincidence'				: { LabelShort : 'COINCIDENCE',					LabelMedium : 'COiNCiDENCE',			LabelLong : 'COiNCiDENCE' },
		'coldfilm'					: { LabelShort : 'COLDFILM',					LabelMedium : 'ColdFilm',				LabelLong : 'ColdFilm' },
		'comandotorrents'			: { LabelShort : 'COMANDOTORRENTS',				LabelMedium : 'COMANDOTORRENTS',			LabelLong : 'COMANDOTORRENTS' },
		'come2daddy'					: { LabelShort : 'COME2DADDY',					LabelMedium : 'Come2daddy',				LabelLong : 'Come2daddy' },
		'compulsion'					: { LabelShort : 'COMPULSION',					LabelMedium : 'COMPULSION',				LabelLong : 'COMPULSION' },
		'condition'					: { LabelShort : 'CONDITION',					LabelMedium : 'CONDITION',				LabelLong : 'CONDITION' },
		'condo'						: { LabelShort : 'CONDO',						LabelMedium : 'CONDO',					LabelLong : 'CONDO' },
		'connazakamrpirate'			: { LabelShort : 'CONNAZAKAMRPIRATE',			LabelMedium : 'ConnazAKAMrPirate',		LabelLong : 'Connaz-AKA-MrPirate' },
		'contribution'				: { LabelShort : 'CONTRIBUTION',				LabelMedium : 'CONTRiBUTiON',			LabelLong : 'CONTRiBUTiON' },
		'convoy'					: { LabelShort : 'CONVOY',						LabelMedium : 'CONVOY',					LabelLong : 'CONVOY' },
		'coo7'						: { LabelShort : 'COO7',						LabelMedium : 'Coo7',					LabelLong : 'Coo7' },
		'cookiemonster'				: { LabelShort : 'COOKIEMONSTER',				LabelMedium : 'CookieMonster',			LabelLong : 'CookieMonster' },
		'coot'						: { LabelShort : 'COOT',						LabelMedium : 'cOOt',					LabelLong : 'cOOt' },
		'core'						: { LabelShort : 'CORE',						LabelMedium : 'CORE',					LabelLong : 'CORE' },
		'cottage'					: { LabelShort : 'COTTAGE',						LabelMedium : 'COTTAGE',					LabelLong : 'COTTAGE' },
		'council'					: { LabelShort : 'COUNCIL',						LabelMedium : 'COUNCiL',					LabelLong : 'COUNCiL' },
		'counterfeit'				: { LabelShort : 'COUNTERFEIT',					LabelMedium : 'COUNTERFEIT',			LabelLong : 'COUNTERFEIT' },
		'coveiro'					: { LabelShort : 'COVEIRO',						LabelMedium : 'COVEIRO',					LabelLong : 'COVEIRO' },
		'cowry'						: { LabelShort : 'COWRY',						LabelMedium : 'CoWRY',					LabelLong : 'CoWRY' },
		'cpd'						: { LabelShort : 'CPD',							LabelMedium : 'CPD',					LabelLong : 'CPD' },
		'cpg'						: { LabelShort : 'CPG',							LabelMedium : 'CPG',					LabelLong : 'CPG' },
		'cpt'						: { LabelShort : 'CPT',							LabelMedium : 'CPT',					LabelLong : 'CPT' },
		'cr'							: { LabelShort : 'CR',							LabelMedium : 'CR',						LabelLong : 'CR' },
		'cravers'					: { LabelShort : 'CRAVERS',						LabelMedium : 'CRAVERS',					LabelLong : 'CRAVERS' },
		'crazy4ad'					: { LabelShort : 'CRAZY4AD',					LabelMedium : 'Crazy4ad',				LabelLong : 'Crazy4ad' },
		'creed'						: { LabelShort : 'CREED',						LabelMedium : 'CREED',					LabelLong : 'CREED' },
		'creepshow'					: { LabelShort : 'CREEPSHOW',					LabelMedium : 'CREEPSHOW',				LabelLong : 'CREEPSHOW' },
		'crest'						: { LabelShort : 'CREST',						LabelMedium : 'CREST',					LabelLong : 'CREST' },
		'crewsade'					: { LabelShort : 'CREWSADE',					LabelMedium : 'CrEwSaDe',				LabelLong : 'CrEwSaDe' },
		'crf'						: { LabelShort : 'CRF',							LabelMedium : 'CRF',					LabelLong : 'CRF' },
		'crime'						: { LabelShort : 'CRIME',						LabelMedium : 'CRiME',					LabelLong : 'CRiME' },
		'criminal'					: { LabelShort : 'CRIMINAL',					LabelMedium : 'CriMiNaL',				LabelLong : 'CriMiNaL' },
		'crimson'					: { LabelShort : 'CRIMSON',						LabelMedium : 'CRiMSON',					LabelLong : 'CRiMSON' },
		'crisc'						: { LabelShort : 'CRISC',						LabelMedium : 'CRiSC',					LabelLong : 'CRiSC' },
		'crisgsm33'					: { LabelShort : 'CRISGSM33',					LabelMedium : 'Crisgsm33',				LabelLong : 'Crisgsm33' },
		'crisp'						: { LabelShort : 'CRISP',						LabelMedium : 'CRiSP',					LabelLong : 'CRiSP' },
		'critical'					: { LabelShort : 'CRITICAL',					LabelMedium : 'CriTiCAL',				LabelLong : 'CriTiCAL' },
		'cro'						: { LabelShort : 'CRO',							LabelMedium : 'CRO',					LabelLong : 'CRO' },
		'crohd'						: { LabelShort : 'CROHD',						LabelMedium : 'CroHD',					LabelLong : 'CroHD' },
		'crooks'					: { LabelShort : 'CROOKS',						LabelMedium : 'CROOKS',					LabelLong : 'CROOKS' },
		'crossbow'					: { LabelShort : 'CROSSBOW',					LabelMedium : 'CROSSBOW',				LabelLong : 'CROSSBOW' },
		'crossfit'					: { LabelShort : 'CROSSFIT',					LabelMedium : 'CROSSFIT',				LabelLong : 'CROSSFIT' },
		'crown'						: { LabelShort : 'CROWN',						LabelMedium : 'CROWN',					LabelLong : 'CROWN' },
		'crr'						: { LabelShort : 'CRR',							LabelMedium : 'CRR',					LabelLong : 'CRR' },
		'crucial'					: { LabelShort : 'CRUCIAL',						LabelMedium : 'CRUCiAL',					LabelLong : 'CRUCiAL' },
		'crx'						: { LabelShort : 'CRX',							LabelMedium : 'CRX',					LabelLong : 'CRX' },
		'cryptic'					: { LabelShort : 'CRYPTIC',						LabelMedium : 'CRYPTIC',					LabelLong : 'CRYPTIC' },
		'crys'						: { LabelShort : 'CRYS',						LabelMedium : 'CRYS',					LabelLong : 'CRYS' },
		'crystal'					: { LabelShort : 'CRYSTAL',						LabelMedium : 'CRYSTAL',					LabelLong : 'CRYSTAL' },
		'css'						: { LabelShort : 'CSS',							LabelMedium : 'CSS',					LabelLong : 'CSS' },
		'ctc'						: { LabelShort : 'CTC',							LabelMedium : 'CTC',					LabelLong : 'CTC' },
		'ctd'						: { LabelShort : 'CTD',							LabelMedium : 'CTD',					LabelLong : 'CTD' },
		'ctr'						: { LabelShort : 'CTR',							LabelMedium : 'CTR',					LabelLong : 'CTR' },
		'ctrlhd'					: { LabelShort : 'CTRLHD',						LabelMedium : 'CtrlHD',					LabelLong : 'CtrlHD' },
		'ctrlsd'					: { LabelShort : 'CTRLSD',						LabelMedium : 'CtrlSD',					LabelLong : 'CtrlSD' },
		'cttv'						: { LabelShort : 'CTTV',						LabelMedium : 'CTTV',					LabelLong : 'CTTV' },
		'ctu'						: { LabelShort : 'CTU',							LabelMedium : 'CTU',					LabelLong : 'CTU' },
		'cult'						: { LabelShort : 'CULT',						LabelMedium : 'CULT',					LabelLong : 'CULT' },
		'cultfilms'					: { LabelShort : 'CULTFILMS',					LabelMedium : 'CultFilms',				LabelLong : 'CultFilms™' },
		'culthd'					: { LabelShort : 'CULTHD',						LabelMedium : 'CultHD',					LabelLong : 'CultHD' },
		'curiosity'					: { LabelShort : 'CURIOSITY',					LabelMedium : 'CURIOSITY',				LabelLong : 'CURIOSITY' },
		'cute'						: { LabelShort : 'CUTE',						LabelMedium : 'CUTE',					LabelLong : 'CUTE' },
		'cyber'						: { LabelShort : 'CYBER',						LabelMedium : 'CYBER',					LabelLong : 'CYBER' },
		'cybermen'					: { LabelShort : 'CYBERMEN',					LabelMedium : 'CYBERMEN',				LabelLong : 'CYBERMEN' },
		'cybertyger'					: { LabelShort : 'CYBERTYGER',					LabelMedium : 'CyberTyger',				LabelLong : 'CyberTyger' },
		'cyd'						: { LabelShort : 'CYD',							LabelMedium : 'CYD',					LabelLong : 'CYD' },
		'cyphanix'					: { LabelShort : 'CYPHANIX',					LabelMedium : 'Cyphanix',				LabelLong : 'Cyphanix' },
		'cytsunee'					: { LabelShort : 'CYTSUNEE',					LabelMedium : 'CyTSuNee',				LabelLong : 'CyTSuNee' },
		'cz530'						: { LabelShort : 'CZ530',						LabelMedium : 'CZ530',					LabelLong : 'CZ530' },
		'd0ber'						: { LabelShort : 'D0BER',						LabelMedium : 'd0ber',					LabelLong : 'd0ber' },
		'd0ct0rlew'					: { LabelShort : 'D0CT0RLEW',					LabelMedium : 'D0ct0rLew',				LabelLong : 'D0ct0rLew' },
		'd0nk'						: { LabelShort : 'D0NK',						LabelMedium : 'D0NK',					LabelLong : 'D0NK' },
		'd0pe'						: { LabelShort : 'D0PE',						LabelMedium : 'D0PE',					LabelLong : 'D0PE' },
		'd2v'						: { LabelShort : 'D2V',							LabelMedium : 'D2V',					LabelLong : 'D2V' },
		'd3fil3r'					: { LabelShort : 'D3FIL3R',						LabelMedium : 'D3FiL3R',					LabelLong : 'D3FiL3R' },
		'd3g'						: { LabelShort : 'D3G',							LabelMedium : 'd3g',					LabelLong : 'd3g' },
		'd3si'						: { LabelShort : 'D3SI',						LabelMedium : 'D3Si',					LabelLong : 'D3Si' },
		'd4'							: { LabelShort : 'D4',							LabelMedium : 'D4',						LabelLong : 'D4' },
		'd69a74'					: { LabelShort : 'D69A74',						LabelMedium : 'd69a74',					LabelLong : 'd69a74' },
		'daa'						: { LabelShort : 'DAA',							LabelMedium : 'DAA',					LabelLong : 'DAA' },
		'daddy'						: { LabelShort : 'DADDY',						LabelMedium : 'DADDY',					LabelLong : 'DADDY' },
		'dalemake'					: { LabelShort : 'DALEMAKE',					LabelMedium : 'Dalemake',				LabelLong : 'Dalemake' },
		'danger2u'					: { LabelShort : 'DANGER2U',					LabelMedium : 'danger2u',				LabelLong : 'danger2u' },
		'danishbits'					: { LabelShort : 'DANISHBITS',					LabelMedium : 'Danishbits',				LabelLong : 'Danishbits' },
		'danny'						: { LabelShort : 'DANNY',						LabelMedium : 'DANNY',					LabelLong : 'DANNY' },
		'dar'						: { LabelShort : 'DAR',							LabelMedium : 'DaR',					LabelLong : 'DaR' },
		'dark'						: { LabelShort : 'DARK',						LabelMedium : 'DARK',					LabelLong : 'DARK' },
		'darkdream'					: { LabelShort : 'DARKDREAM',					LabelMedium : 'DarkDream',				LabelLong : 'DarkDream' },
		'darkflix'					: { LabelShort : 'DARKFLIX',					LabelMedium : 'DARKFLiX',				LabelLong : 'DARKFLiX' },
		'darktiger'					: { LabelShort : 'DARKTIGER',					LabelMedium : 'DARKTIGER',				LabelLong : 'DARKTIGER' },
		'dascubadude'				: { LabelShort : 'DASCUBADUDE',					LabelMedium : 'DaScubaDude',			LabelLong : 'DaScubaDude' },
		'dash'						: { LabelShort : 'DASH',						LabelMedium : 'DASH',					LabelLong : 'DASH' },
		'dav1nci'					: { LabelShort : 'DAV1NCI',						LabelMedium : 'dAV1nci',					LabelLong : 'dAV1nci' },
		'dawgs'						: { LabelShort : 'DAWGS',						LabelMedium : 'DAWGS',					LabelLong : 'DAWGS' },
		'dawgsserier'				: { LabelShort : 'DAWGSSERIER',					LabelMedium : 'DAWGSSERiER',			LabelLong : 'DAWGSSERiER' },
		'dawn'						: { LabelShort : 'DAWN',						LabelMedium : 'DAWN',					LabelLong : 'DAWN' },
		'db'							: { LabelShort : 'DB',							LabelMedium : 'DB',						LabelLong : 'DB' },
		'dbo'						: { LabelShort : 'DBO',							LabelMedium : 'DBO',					LabelLong : 'DBO' },
		'dbr'						: { LabelShort : 'DBR',							LabelMedium : 'dbR',					LabelLong : 'dbR' },
		'dbretail'					: { LabelShort : 'DBRETAIL',					LabelMedium : 'DBRETAiL',				LabelLong : 'DBRETAiL' },
		'dca'						: { LabelShort : 'DCA',							LabelMedium : 'DCA',					LabelLong : 'DCA' },
		'dcn'						: { LabelShort : 'DCN',							LabelMedium : 'DcN',					LabelLong : 'DcN' },
		'ddb'						: { LabelShort : 'DDB',							LabelMedium : 'DDB',					LabelLong : 'DDB' },
		'ddc'						: { LabelShort : 'DDC',							LabelMedium : 'DDC',					LabelLong : 'DDC' },
		'dddd'						: { LabelShort : 'DDDD',						LabelMedium : 'DDDD',					LabelLong : 'DDDD' },
		'ddltv'						: { LabelShort : 'DDLTV',						LabelMedium : 'DDLTV',					LabelLong : 'DDLTV' },
		'ddlv'						: { LabelShort : 'DDLV',						LabelMedium : 'DDLV',					LabelLong : 'DDLV' },
		'ddn'						: { LabelShort : 'DDN',							LabelMedium : 'DDN',					LabelLong : 'DDN' },
		'ddncrew'					: { LabelShort : 'DDNCREW',						LabelMedium : 'DDNCREW',					LabelLong : 'DDNCREW' },
		'ddr'						: { LabelShort : 'DDR',							LabelMedium : 'DDR',					LabelLong : 'DDR' },
		'dea'						: { LabelShort : 'DEA',							LabelMedium : 'DEA',					LabelLong : 'DEA' },
		'deadpixel'					: { LabelShort : 'DEADPIXEL',					LabelMedium : 'DEADPiXEL',				LabelLong : 'DEADPiXEL' },
		'deadpool'					: { LabelShort : 'DEADPOOL',					LabelMedium : 'DEADPOOL',				LabelLong : 'DEADPOOL' },
		'deadtorights'				: { LabelShort : 'DEADTORIGHTS',				LabelMedium : 'DeadToRights',			LabelLong : 'DeadToRights' },
		'deal'						: { LabelShort : 'DEAL',						LabelMedium : 'DEAL',					LabelLong : 'DEAL' },
		'debtvid'					: { LabelShort : 'DEBTVID',						LabelMedium : 'DeBTViD',					LabelLong : 'DeBTViD' },
		'decade'					: { LabelShort : 'DECADE',						LabelMedium : 'DECADE',					LabelLong : 'DECADE' },
		'decatora27'					: { LabelShort : 'DECATORA27',					LabelMedium : 'decatora27',				LabelLong : 'decatora27' },
		'decent'					: { LabelShort : 'DECENT',						LabelMedium : 'DECENT',					LabelLong : 'DECENT' },
		'decibel'					: { LabelShort : 'DECIBEL',						LabelMedium : 'decibeL',					LabelLong : 'decibeL' },
		'decide'					: { LabelShort : 'DECIDE',						LabelMedium : 'DECiDE',					LabelLong : 'DECiDE' },
		'deejayahmed'				: { LabelShort : 'DEEJAYAHMED',					LabelMedium : 'DeeJayAhmed',			LabelLong : 'DeeJayAhmed' },
		'defaced'					: { LabelShort : 'DEFACED',						LabelMedium : 'DEFACED',					LabelLong : 'DEFACED' },
		'define'					: { LabelShort : 'DEFINE',						LabelMedium : 'DEFiNE',					LabelLong : 'DEFiNE' },
		'definite'					: { LabelShort : 'DEFINITE',					LabelMedium : 'DEFiNiTE',				LabelLong : 'DEFiNiTE' },
		'definition'					: { LabelShort : 'DEFINITION',					LabelMedium : 'DEFiNiTiON',				LabelLong : 'DEFiNiTiON' },
		'deflate'					: { LabelShort : 'DEFLATE',						LabelMedium : 'DEFLATE',					LabelLong : 'DEFLATE' },
		'defused'					: { LabelShort : 'DEFUSED',						LabelMedium : 'DEFUSED',					LabelLong : 'DEFUSED' },
		'deimos'					: { LabelShort : 'DEIMOS',						LabelMedium : 'DEiMOS',					LabelLong : 'DEiMOS' },
		'deity'						: { LabelShort : 'DEITY',						LabelMedium : 'DEiTY',					LabelLong : 'DEiTY' },
		'deka'						: { LabelShort : 'DEKA',						LabelMedium : 'deka',					LabelLong : 'deka' },
		'dekabroken'					: { LabelShort : 'DEKABROKEN',					LabelMedium : 'dekabroken',				LabelLong : 'dekabroken' },
		'delicious'					: { LabelShort : 'DELICIOUS',					LabelMedium : 'DELiCiOUS',				LabelLong : 'DELiCiOUS' },
		'delight'					: { LabelShort : 'DELIGHT',						LabelMedium : 'DELiGHT',					LabelLong : 'DELiGHT' },
		'dem3nt3'					: { LabelShort : 'DEM3NT3',						LabelMedium : 'dem3nt3',					LabelLong : 'dem3nt3' },
		'demand'					: { LabelShort : 'DEMAND',						LabelMedium : 'DEMAND',					LabelLong : 'DEMAND' },
		'depravity'					: { LabelShort : 'DEPRAVITY',					LabelMedium : 'DEPRAViTY',				LabelLong : 'DEPRAViTY' },
		'deprived'					: { LabelShort : 'DEPRIVED',					LabelMedium : 'DEPRiVED',				LabelLong : 'DEPRiVED' },
		'depth'						: { LabelShort : 'DEPTH',						LabelMedium : 'DEPTH',					LabelLong : 'DEPTH' },
		'deranged'					: { LabelShort : 'DERANGED',					LabelMedium : 'DERANGED',				LabelLong : 'DERANGED' },
		'derschuft'					: { LabelShort : 'DERSCHUFT',					LabelMedium : 'DerSchuft',				LabelLong : 'DerSchuft' },
		'desire'					: { LabelShort : 'DESIRE',						LabelMedium : 'DESIRE',					LabelLong : 'DESIRE' },
		'despite'					: { LabelShort : 'DESPITE',						LabelMedium : 'DESPiTE',					LabelLong : 'DESPiTE' },
		'deuterium'					: { LabelShort : 'DEUTERIUM',					LabelMedium : 'DEUTERIUM',				LabelLong : 'DEUTERIUM' },
		'deviant'					: { LabelShort : 'DEVIANT',						LabelMedium : 'DEViANT',					LabelLong : 'DEViANT' },
		'devil'						: { LabelShort : 'DEVIL',						LabelMedium : 'DEVIL',					LabelLong : 'DEVIL' },
		'devise'					: { LabelShort : 'DEVISE',						LabelMedium : 'DEViSE',					LabelLong : 'DEViSE' },
		'devived'					: { LabelShort : 'DEVIVED',						LabelMedium : 'DEVIVED',					LabelLong : 'DEVIVED' },
		'dexterous'					: { LabelShort : 'DEXTEROUS',					LabelMedium : 'DEXTEROUS',				LabelLong : 'DEXTEROUS' },
		'df'							: { LabelShort : 'DF',							LabelMedium : 'DF',						LabelLong : 'D-F' },
		'dflarrowfilms'				: { LabelShort : 'DFLARROWFILMS',				LabelMedium : 'DFlarrowFilms',			LabelLong : 'D Flarrow Films' },
		'dh'							: { LabelShort : 'DH',							LabelMedium : 'dH',						LabelLong : 'dH' },
		'dharma'					: { LabelShort : 'DHARMA',						LabelMedium : 'DHARMA',					LabelLong : 'DHARMA' },
		'dhd'						: { LabelShort : 'DHD',							LabelMedium : 'DHD',					LabelLong : 'DHD' },
		'diablo'					: { LabelShort : 'DIABLO',						LabelMedium : 'DIABLO',					LabelLong : 'DIABLO' },
		'diamond'					: { LabelShort : 'DIAMOND',						LabelMedium : 'DiAMOND',					LabelLong : 'DiAMOND' },
		'diamonds'					: { LabelShort : 'DIAMONDS',					LabelMedium : 'DIAMONDS',				LabelLong : 'DIAMONDS' },
		'dic'						: { LabelShort : 'DIC',							LabelMedium : 'DiC',					LabelLong : 'DiC' },
		'dich'						: { LabelShort : 'DICH',						LabelMedium : 'DiCH',					LabelLong : 'DiCH' },
		'didee'						: { LabelShort : 'DIDEE',						LabelMedium : 'DiDee',					LabelLong : 'DiDee' },
		'didomh'					: { LabelShort : 'DIDOMH',						LabelMedium : 'didomh',					LabelLong : 'didomh' },
		'diesel'					: { LabelShort : 'DIESEL',						LabelMedium : 'DIESEL',					LabelLong : 'DIESEL' },
		'different'					: { LabelShort : 'DIFFERENT',					LabelMedium : 'DiFFERENT',				LabelLong : 'DiFFERENT' },
		'digg'						: { LabelShort : 'DIGG',						LabelMedium : 'DiGG',					LabelLong : 'DiGG' },
		'dimension'					: { LabelShort : 'DIMENSION',					LabelMedium : 'DIMENSION',				LabelLong : 'DIMENSION' },
		'din'						: { LabelShort : 'DIN',							LabelMedium : 'DiN',					LabelLong : 'DiN' },
		'dina'						: { LabelShort : 'DINA',						LabelMedium : 'DiNA',					LabelLong : 'DiNA' },
		'dir'						: { LabelShort : 'DIR',							LabelMedium : 'DiR',					LabelLong : 'DiR' },
		'dirg'						: { LabelShort : 'DIRG',						LabelMedium : 'DiRG',					LabelLong : 'DiRG' },
		'dirt'						: { LabelShort : 'DIRT',						LabelMedium : 'DiRT',					LabelLong : 'DiRT' },
		'dirty'						: { LabelShort : 'DIRTY',						LabelMedium : 'DiRTY',					LabelLong : 'DiRTY' },
		'dirtyburger'				: { LabelShort : 'DIRTYBURGER',					LabelMedium : 'DiRTYBURGER',			LabelLong : 'DiRTYBURGER' },
		'disposable'					: { LabelShort : 'DISPOSABLE',					LabelMedium : 'DiSPOSABLE',				LabelLong : 'DiSPOSABLE' },
		'disruption'					: { LabelShort : 'DISRUPTION',					LabelMedium : 'DiSRUPTION',				LabelLong : 'DiSRUPTION' },
		'district'					: { LabelShort : 'DISTRICT',					LabelMedium : 'DiSTRiCT',				LabelLong : 'DiSTRiCT' },
		'divas'						: { LabelShort : 'DIVAS',						LabelMedium : 'DiVAS',					LabelLong : 'DiVAS' },
		'diverge'					: { LabelShort : 'DIVERGE',						LabelMedium : 'DiVERGE',					LabelLong : 'DiVERGE' },
		'diversity'					: { LabelShort : 'DIVERSITY',					LabelMedium : 'DiVERSiTY',				LabelLong : 'DiVERSiTY' },
		'division'					: { LabelShort : 'DIVISION',					LabelMedium : 'DiViSiON',				LabelLong : 'DiViSiON' },
		'divulged'					: { LabelShort : 'DIVULGED',					LabelMedium : 'DiVULGED',				LabelLong : 'DiVULGED' },
		'divxnl'					: { LabelShort : 'DIVXNL',						LabelMedium : 'DivXNL',					LabelLong : 'DivXNL' },
		'divxnlteam'					: { LabelShort : 'DIVXNLTEAM',					LabelMedium : 'DivXNLTeam',				LabelLong : 'DivXNL-Team' },
		'dizhuwang'					: { LabelShort : 'DIZHUWANG',					LabelMedium : 'dizhuwang',				LabelLong : 'dizhuwang' },
		'djd'						: { LabelShort : 'DJD',							LabelMedium : 'djd',					LabelLong : 'djd' },
		'dkb'						: { LabelShort : 'DKB',							LabelMedium : 'DKB',					LabelLong : 'DKB' },
		'dkids'						: { LabelShort : 'DKIDS',						LabelMedium : 'DKiDS',					LabelLong : 'DKiDS' },
		'dlc'						: { LabelShort : 'DLC',							LabelMedium : 'DLC',					LabelLong : 'DLC' },
		'dmt'						: { LabelShort : 'DMT',							LabelMedium : 'DMT',					LabelLong : 'DMT' },
		'dna'						: { LabelShort : 'DNA',							LabelMedium : 'DNA',					LabelLong : 'DNA' },
		'dnb'						: { LabelShort : 'DNB',							LabelMedium : 'DnB',					LabelLong : 'DnB' },
		'dnl'						: { LabelShort : 'DNL',							LabelMedium : 'DNL',					LabelLong : 'DNL' },
		'dnr'						: { LabelShort : 'DNR',							LabelMedium : 'DNR',					LabelLong : 'DNR' },
		'dns'						: { LabelShort : 'DNS',							LabelMedium : 'dns',					LabelLong : 'dns' },
		'doa'						: { LabelShort : 'DOA',							LabelMedium : 'DoA',					LabelLong : 'DoA' },
		'doc'						: { LabelShort : 'DOC',							LabelMedium : 'DoC',					LabelLong : 'DoC' },
		'document'					: { LabelShort : 'DOCUMENT',					LabelMedium : 'DOCUMENT',				LabelLong : 'DOCUMENT' },
		'doesntsuck'					: { LabelShort : 'DOESNTSUCK',					LabelMedium : 'DOESNTSUCK',				LabelLong : 'DOESNTSUCK' },
		'doge'						: { LabelShort : 'DOGE',						LabelMedium : 'DOGE',					LabelLong : 'DOGE' },
		'doktor'					: { LabelShort : 'DOKTOR',						LabelMedium : 'DoKtor',					LabelLong : 'DoKtor' },
		'dokumania'					: { LabelShort : 'DOKUMANIA',					LabelMedium : 'DOKUMANiA',				LabelLong : 'DOKUMANiA' },
		'dollhead'					: { LabelShort : 'DOLLHEAD',					LabelMedium : 'DOLLHEAD',				LabelLong : 'DOLLHEAD' },
		'dominion'					: { LabelShort : 'DOMINION',					LabelMedium : 'dominion',				LabelLong : 'dominion' },
		'domino'					: { LabelShort : 'DOMINO',						LabelMedium : 'DOMiNO',					LabelLong : 'DOMiNO' },
		'don'						: { LabelShort : 'DON',							LabelMedium : 'DON',					LabelLong : 'DON' },
		'done'						: { LabelShort : 'DONE',						LabelMedium : 'DoNE',					LabelLong : 'DoNE' },
		'donjuan'					: { LabelShort : 'DONJUAN',						LabelMedium : 'DonJuan',					LabelLong : 'DonJuan' },
		'donna'						: { LabelShort : 'DONNA',						LabelMedium : 'DONNA',					LabelLong : 'DONNA' },
		'donuts'					: { LabelShort : 'DONUTS',						LabelMedium : 'DONUTS',					LabelLong : 'DONUTS' },
		'doomguy'					: { LabelShort : 'DOOMGUY',						LabelMedium : 'DOOMGUY',					LabelLong : 'DOOMGUY' },
		'dopehd'					: { LabelShort : 'DOPEHD',						LabelMedium : 'DopeHD',					LabelLong : 'DopeHD' },
		'dot'						: { LabelShort : 'DOT',							LabelMedium : 'DOT',					LabelLong : 'DOT' },
		'doubt'						: { LabelShort : 'DOUBT',						LabelMedium : 'DOUBT',					LabelLong : 'DOUBT' },
		'down'						: { LabelShort : 'DOWN',						LabelMedium : 'DOWN',					LabelLong : 'DOWN' },
		'downloadhub'				: { LabelShort : 'DOWNLOADHUB',					LabelMedium : 'Downloadhub',			LabelLong : 'Downloadhub' },
		'downrev'					: { LabelShort : 'DOWNREV',						LabelMedium : 'DownRev',					LabelLong : 'DownRev' },
		'dp'							: { LabelShort : 'DP',							LabelMedium : 'DP',						LabelLong : 'DP' },
		'dr'							: { LabelShort : 'DR',							LabelMedium : 'DR',						LabelLong : 'D-R' },
		'dr3adlox'					: { LabelShort : 'DR3ADLOX',					LabelMedium : 'Dr3adLoX',				LabelLong : 'Dr3adLoX' },
		'dracula'					: { LabelShort : 'DRACULA',						LabelMedium : 'DRACULA',					LabelLong : 'DRACULA' },
		'dragsterps'					: { LabelShort : 'DRAGSTERPS',					LabelMedium : 'dragsterps',				LabelLong : 'dragsterps' },
		'drake'						: { LabelShort : 'DRAKE',						LabelMedium : 'DRAKE',					LabelLong : 'DRAKE' },
		'dream'						: { LabelShort : 'DREAM',						LabelMedium : 'DREAM',					LabelLong : 'DREAM' },
		'dreamcatcher'				: { LabelShort : 'DREAMCATCHER',				LabelMedium : 'DREAMCATCHER',			LabelLong : 'DREAMCATCHER' },
		'dreamseed'					: { LabelShort : 'DREAMSEED',					LabelMedium : 'Dreamseed',				LabelLong : 'Dreamseed' },
		'drg'						: { LabelShort : 'DRG',							LabelMedium : 'DRG',					LabelLong : 'DRG' },
		'drm'						: { LabelShort : 'DRM',							LabelMedium : 'DRM',					LabelLong : 'DRM' },
		'droids'					: { LabelShort : 'DROIDS',						LabelMedium : 'DROiDS',					LabelLong : 'DROiDS' },
		'drones'					: { LabelShort : 'DRONES',						LabelMedium : 'DRONES',					LabelLong : 'DRONES' },
		'drsd'						: { LabelShort : 'DRSD',						LabelMedium : 'DRSD',					LabelLong : 'DRSD' },
		'drsi'						: { LabelShort : 'DRSI',						LabelMedium : 'DrSi',					LabelLong : 'DrSi' },
		'drstar'					: { LabelShort : 'DRSTAR',						LabelMedium : 'DrSTAR',					LabelLong : 'Dr.STAR' },
		'ds'							: { LabelShort : 'DS',							LabelMedium : 'DS',						LabelLong : 'DS' },
		'dss'						: { LabelShort : 'DSS',							LabelMedium : 'DSS',					LabelLong : 'DSS' },
		'dsubs'						: { LabelShort : 'DSUBS',						LabelMedium : 'DSubs',					LabelLong : 'D-Subs' },
		'dtech'						: { LabelShort : 'DTECH',						LabelMedium : 'Dtech',					LabelLong : 'Dtech' },
		'dthd'						: { LabelShort : 'DTHD',						LabelMedium : 'DTHD',					LabelLong : 'DTHD' },
		'dtone'						: { LabelShort : 'DTONE',						LabelMedium : 'DTOne',					LabelLong : 'DTOne' },
		'dubby'						: { LabelShort : 'DUBBY',						LabelMedium : 'DUBBY',					LabelLong : 'DUBBY' },
		'duck'						: { LabelShort : 'DUCK',						LabelMedium : 'DUCK',					LabelLong : 'DUCK' },
		'dude'						: { LabelShort : 'DUDE',						LabelMedium : 'DUDE',					LabelLong : 'DUDE' },
		'dukes'						: { LabelShort : 'DUKES',						LabelMedium : 'DUKES',					LabelLong : 'DUKES' },
		'dupli'						: { LabelShort : 'DUPLI',						LabelMedium : 'DUPLI',					LabelLong : 'DUPLI' },
		'duqa'						: { LabelShort : 'DUQA',						LabelMedium : 'DUQA',					LabelLong : 'DUQA' },
		'dustin'					: { LabelShort : 'DUSTIN',						LabelMedium : 'DUSTiN',					LabelLong : 'DUSTiN' },
		'dutchreleaseteam'			: { LabelShort : 'DUTCHRELEASETEAM',			LabelMedium : 'DutchReleaseTeam',		LabelLong : 'DutchReleaseTeam' },
		'dvdmania'					: { LabelShort : 'DVDMANIA',					LabelMedium : 'DVDMANiA',				LabelLong : 'DVDMANiA' },
		'dvf'						: { LabelShort : 'DVF',							LabelMedium : 'DvF',					LabelLong : 'DvF' },
		'dvl'						: { LabelShort : 'DVL',							LabelMedium : 'DVL',					LabelLong : 'DVL' },
		'dvsky'						: { LabelShort : 'DVSKY',						LabelMedium : 'dvsky',					LabelLong : 'dvsky' },
		'dvsux'						: { LabelShort : 'DVSUX',						LabelMedium : 'DVSUX',					LabelLong : 'DVSUX' },
		'dvt'						: { LabelShort : 'DVT',							LabelMedium : 'DVT',					LabelLong : 'DVT' },
		'dx'							: { LabelShort : 'DX',							LabelMedium : 'DX',						LabelLong : 'DX' },
		'dxo'						: { LabelShort : 'DXO',							LabelMedium : 'DXO',					LabelLong : 'DXO' },
		'dygc'						: { LabelShort : 'DYGC',						LabelMedium : 'DYGC',					LabelLong : 'DYGC' },
		'dynamics'					: { LabelShort : 'DYNAMICS',					LabelMedium : 'DYNAMiCS',				LabelLong : 'DYNAMiCS' },
		'dz0n3'						: { LabelShort : 'DZ0N3',						LabelMedium : 'DZ0N3',					LabelLong : 'D-Z0N3' },
		'e1'							: { LabelShort : 'E1',							LabelMedium : 'E1',						LabelLong : 'E1' },
		'e7'							: { LabelShort : 'E7',							LabelMedium : 'E7',						LabelLong : 'E7' },
		'e76'						: { LabelShort : 'E76',							LabelMedium : 'E76',					LabelLong : 'E76' },
		'ea'							: { LabelShort : 'EA',							LabelMedium : 'EA',						LabelLong : 'EA' },
		'eagle'						: { LabelShort : 'EAGLE',						LabelMedium : 'EAGLE',					LabelLong : 'EAGLE' },
		'eatdik'					: { LabelShort : 'EATDIK',						LabelMedium : 'EATDIK',					LabelLong : 'EATDIK' },
		'ebi'						: { LabelShort : 'EBI',							LabelMedium : 'EBi',					LabelLong : 'EBi' },
		'ebp'						: { LabelShort : 'EBP',							LabelMedium : 'EbP',					LabelLong : 'EbP' },
		'eci'						: { LabelShort : 'ECI',							LabelMedium : 'ECI',					LabelLong : 'ECI' },
		'eclipse'					: { LabelShort : 'ECLIPSE',						LabelMedium : 'eclipse',					LabelLong : 'eclipse' },
		'ede'						: { LabelShort : 'EDE',							LabelMedium : 'EDE',					LabelLong : 'EDE' },
		'edge'						: { LabelShort : 'EDGE',						LabelMedium : 'EDGE',					LabelLong : 'EDGE' },
		'edge2020'					: { LabelShort : 'EDGE2020',					LabelMedium : 'EDGE2020',				LabelLong : 'EDGE2020' },
		'edhd'						: { LabelShort : 'EDHD',						LabelMedium : 'EDHD',					LabelLong : 'EDHD' },
		'edi'						: { LabelShort : 'EDI',							LabelMedium : 'eDi',					LabelLong : 'eDi' },
		'edo'						: { LabelShort : 'EDO',							LabelMedium : 'Edo',					LabelLong : 'Edo' },
		'edph'						: { LabelShort : 'EDPH',						LabelMedium : 'EDPH',					LabelLong : 'EDPH' },
		'edvok'						: { LabelShort : 'EDVOK',						LabelMedium : 'EDVOK',					LabelLong : 'EDVOK.COM' },
		'eff'						: { LabelShort : 'EFF',							LabelMedium : 'EFF',					LabelLong : 'EFF' },
		'efterlyst'					: { LabelShort : 'EFTERLYST',					LabelMedium : 'EFTERLYST',				LabelLong : 'EFTERLYST' },
		'egen'						: { LabelShort : 'EGEN',						LabelMedium : 'EGEN',					LabelLong : 'EGEN' },
		'ehmd'						: { LabelShort : 'EHMD',						LabelMedium : 'ehMD',					LabelLong : 'ehMD' },
		'eider'						: { LabelShort : 'EIDER',						LabelMedium : 'EiDER',					LabelLong : 'EiDER' },
		'eie'						: { LabelShort : 'EIE',							LabelMedium : 'EiE',					LabelLong : 'EiE' },
		'eimi'						: { LabelShort : 'EIMI',						LabelMedium : 'EiMi',					LabelLong : 'EiMi' },
		'eisbock'					: { LabelShort : 'EISBOCK',						LabelMedium : 'EiSBOCK',					LabelLong : 'EiSBOCK' },
		'ekolb'						: { LabelShort : 'EKOLB',						LabelMedium : 'Ekolb',					LabelLong : 'Ekolb' },
		'electric'					: { LabelShort : 'ELECTRIC',					LabelMedium : 'ELECTRiC',				LabelLong : 'ELECTRiC' },
		'elektri4ka'					: { LabelShort : 'ELEKTRI4KA',					LabelMedium : 'ELEKTRI4KA',				LabelLong : 'ELEKTRI4KA' },
		'elia'						: { LabelShort : 'ELIA',						LabelMedium : 'ELiA',					LabelLong : 'ELiA' },
		'elite'						: { LabelShort : 'ELITE',						LabelMedium : 'ELiTE',					LabelLong : 'ELiTE' },
		'elitetorrent'				: { LabelShort : 'ELITETORRENT',				LabelMedium : 'EliteTorrent',			LabelLong : 'wWw.EliteTorrent.BiZ' },
		'elysium'					: { LabelShort : 'ELYSIUM',						LabelMedium : 'ELYSIUM',					LabelLong : 'ELYSIUM' },
		'em0c0re'					: { LabelShort : 'EM0C0RE',						LabelMedium : 'EM0C0RE',					LabelLong : 'EM0C0RE' },
		'ember'						: { LabelShort : 'EMBER',						LabelMedium : 'EMBER',					LabelLong : 'EMBER' },
		'emem'						: { LabelShort : 'EMEM',						LabelMedium : 'EmEm',					LabelLong : 'EmEm' },
		'emerald'					: { LabelShort : 'EMERALD',						LabelMedium : 'EMERALD',					LabelLong : 'EMERALD' },
		'emg'						: { LabelShort : 'EMG',							LabelMedium : 'EMG',					LabelLong : 'EMG' },
		'empathy'					: { LabelShort : 'EMPATHY',						LabelMedium : 'EMPATHY',					LabelLong : 'EMPATHY' },
		'empire'					: { LabelShort : 'EMPIRE',						LabelMedium : 'EMPiRE',					LabelLong : 'EMPiRE' },
		'ena'						: { LabelShort : 'ENA',							LabelMedium : 'EnA',					LabelLong : 'EnA' },
		'encounters'					: { LabelShort : 'ENCOUNTERS',					LabelMedium : 'ENCOUNTERS',				LabelLong : 'ENCOUNTERS' },
		'end'						: { LabelShort : 'END',							LabelMedium : 'END',					LabelLong : 'E.N.D' },
		'endor'						: { LabelShort : 'ENDOR',						LabelMedium : 'EnDoR',					LabelLong : 'EnDoR' },
		'eniahd'					: { LabelShort : 'ENIAHD',						LabelMedium : 'EniaHD',					LabelLong : 'EniaHD' },
		'enigma'					: { LabelShort : 'ENIGMA',						LabelMedium : 'ENiGMA',					LabelLong : 'ENiGMA' },
		'ent'						: { LabelShort : 'ENT',							LabelMedium : 'ENT',					LabelLong : 'ENT' },
		'enticement'					: { LabelShort : 'ENTICEMENT',					LabelMedium : 'ENTiCEMENT',				LabelLong : 'ENTiCEMENT' },
		'ep1c'						: { LabelShort : 'EP1C',						LabelMedium : 'EP1C',					LabelLong : 'EP1C' },
		'ephemerid'					: { LabelShort : 'EPHEMERID',					LabelMedium : 'EPHEMERiD',				LabelLong : 'EPHEMERiD' },
		'epic'						: { LabelShort : 'EPIC',						LabelMedium : 'EPiC',					LabelLong : 'EPiC' },
		'epik'						: { LabelShort : 'EPIK',						LabelMedium : 'EPiK',					LabelLong : 'EPiK' },
		'eps'						: { LabelShort : 'EPS',							LabelMedium : 'EPS',					LabelLong : 'EPS' },
		'epsilon'					: { LabelShort : 'EPSILON',						LabelMedium : 'EPSiLON',					LabelLong : 'EPSiLON' },
		'epz'						: { LabelShort : 'EPZ',							LabelMedium : 'EPZ',					LabelLong : 'EPZ' },
		'erairaws'					: { LabelShort : 'ERAIRAWS',					LabelMedium : 'Erairaws',				LabelLong : 'Erai-raws' },
		'erev'						: { LabelShort : 'EREV',						LabelMedium : 'ERev',					LabelLong : 'E.Rev' },
		'esc'						: { LabelShort : 'ESC',							LabelMedium : 'eSc',					LabelLong : 'eSc' },
		'esi'						: { LabelShort : 'ESI',							LabelMedium : 'ESI',					LabelLong : 'ESI' },
		'esir'						: { LabelShort : 'ESIR',						LabelMedium : 'ESiR',					LabelLong : 'ESiR' },
		'espise'					: { LabelShort : 'ESPISE',						LabelMedium : 'ESPiSE',					LabelLong : 'ESPiSE' },
		'esq'						: { LabelShort : 'ESQ',							LabelMedium : 'EsQ',					LabelLong : 'EsQ' },
		'essential'					: { LabelShort : 'ESSENTIAL',					LabelMedium : 'ESSENTiAL',				LabelLong : 'ESSENTiAL' },
		'eszc'						: { LabelShort : 'ESZC',						LabelMedium : 'ESZC',					LabelLong : 'ESZC' },
		'etach'						: { LabelShort : 'ETACH',						LabelMedium : 'ETACH',					LabelLong : 'ETACH' },
		'ethd'						: { LabelShort : 'ETHD',						LabelMedium : 'EtHD',					LabelLong : 'EtHD' },
		'ethics'					: { LabelShort : 'ETHICS',						LabelMedium : 'ETHiCS',					LabelLong : 'ETHiCS' },
		'ethos'						: { LabelShort : 'ETHOS',						LabelMedium : 'ETHOS',					LabelLong : 'ETHOS' },
		'etm'						: { LabelShort : 'ETM',							LabelMedium : 'ETM',					LabelLong : 'ETM' },
		'etmid'						: { LabelShort : 'ETMID',						LabelMedium : 'ETMID',					LabelLong : 'ETMID' },
		'etmovies'					: { LabelShort : 'ETMOVIES',					LabelMedium : 'EtMovies',				LabelLong : 'EtMovies' },
		'etrg'						: { LabelShort : 'ETRG',						LabelMedium : 'ETRG',					LabelLong : 'ETRG' },
		'ettv'						: { LabelShort : 'ETTV',						LabelMedium : 'ETTV',					LabelLong : 'ETTV' },
		'euchd'						: { LabelShort : 'EUCHD',						LabelMedium : 'EucHD',					LabelLong : 'EucHD' },
		'euhd'						: { LabelShort : 'EUHD',						LabelMedium : 'euHD',					LabelLong : 'euHD' },
		'eureka'					: { LabelShort : 'EUREKA',						LabelMedium : 'EuReKA',					LabelLong : 'EuReKA' },
		'eve'						: { LabelShort : 'EVE',							LabelMedium : 'EVE',					LabelLong : 'EVE' },
		'evo'						: { LabelShort : 'EVO',							LabelMedium : 'EVO',					LabelLong : 'EVO' },
		'evolve'					: { LabelShort : 'EVOLVE',						LabelMedium : 'EVOLVE',					LabelLong : 'EVOLVE' },
		'ewdp'						: { LabelShort : 'EWDP',						LabelMedium : 'EwDp',					LabelLong : 'EwDp' },
		'excalibur'					: { LabelShort : 'EXCALIBUR',					LabelMedium : 'ExCaLiBuR',				LabelLong : 'ExCaLiBuR' },
		'excellence'					: { LabelShort : 'EXCELLENCE',					LabelMedium : 'EXCELLENCE',				LabelLong : 'EXCELLENCE' },
		'excited'					: { LabelShort : 'EXCITED',						LabelMedium : 'EXCiTED',					LabelLong : 'EXCiTED' },
		'exclusive'					: { LabelShort : 'EXCLUSIVE',					LabelMedium : 'Exclusive',				LabelLong : 'Exclusive' },
		'excommunicado'				: { LabelShort : 'EXCOMMUNICADO',				LabelMedium : 'eXcommunicado',			LabelLong : 'eXcommunicado' },
		'exd'						: { LabelShort : 'EXD',							LabelMedium : 'eXD',					LabelLong : 'eXD' },
		'exdr'						: { LabelShort : 'EXDR',						LabelMedium : 'ExDR',					LabelLong : 'ExDR' },
		'exile'						: { LabelShort : 'EXILE',						LabelMedium : 'EXiLE',					LabelLong : 'EXiLE' },
		'exkinoray'					: { LabelShort : 'EXKINORAY',					LabelMedium : 'ExKinoRay',				LabelLong : 'ExKinoRay' },
		'exploit'					: { LabelShort : 'EXPLOIT',						LabelMedium : 'EXPLOIT',					LabelLong : 'EXPLOIT' },
		'exps'						: { LabelShort : 'EXPS',						LabelMedium : 'EXPS',					LabelLong : 'EXPS' },
		'exquisite'					: { LabelShort : 'EXQUISITE',					LabelMedium : 'EXQUiSiTE',				LabelLong : 'EXQUiSiTE' },
		'extacy'					: { LabelShort : 'EXTACY',						LabelMedium : 'eXtaCY',					LabelLong : 'eXtaCY' },
		'extramovies'				: { LabelShort : 'EXTRAMOVIES',					LabelMedium : 'ExtraMovies',			LabelLong : 'ExtraMovies' },
		'extratorrentrg'			: { LabelShort : 'EXTRATORRENTRG',				LabelMedium : 'ExtraTorrentRG',			LabelLong : 'ExtraTorrentRG' },
		'extreme'					: { LabelShort : 'EXTREME',						LabelMedium : 'EXTREME',					LabelLong : 'EXTREME' },
		'exvid'						: { LabelShort : 'EXVID',						LabelMedium : 'EXViD',					LabelLong : 'EXViD' },
		'exvidint'					: { LabelShort : 'EXVIDINT',					LabelMedium : 'EXViDiNT',				LabelLong : 'EXViDiNT' },
		'exy'						: { LabelShort : 'EXY',							LabelMedium : 'ExY',					LabelLong : 'ExY' },
		'exyu'						: { LabelShort : 'EXYU',						LabelMedium : 'ExYu',					LabelLong : 'ExYu' },
		'exyusubs'					: { LabelShort : 'EXYUSUBS',					LabelMedium : 'ExYuSubs',				LabelLong : 'ExYuSubs' },
		'eztv'						: { LabelShort : 'EZTV',						LabelMedium : 'EZTV',					LabelLong : 'EZTV' },
		'f1'							: { LabelShort : 'F1',							LabelMedium : 'F1',						LabelLong : 'F1' },
		'f1rebladerunner'			: { LabelShort : 'F1REBLADERUNNER',				LabelMedium : 'F1rebladerunner',			LabelLong : 'F1rebladerunner' },
		'f7'							: { LabelShort : 'F7',							LabelMedium : 'F7',						LabelLong : 'F7' },
		'fabulous'					: { LabelShort : 'FABULOUS',					LabelMedium : 'FABULOUS',				LabelLong : 'FABULOUS' },
		'fabutrash'					: { LabelShort : 'FABUTRASH',					LabelMedium : 'fabutrash',				LabelLong : 'fabutrash' },
		'failed'					: { LabelShort : 'FAILED',						LabelMedium : 'FaiLED',					LabelLong : 'FaiLED' },
		'fandango'					: { LabelShort : 'FANDANGO',					LabelMedium : 'FANDANGO',				LabelLong : 'FANDANGO' },
		'fant'						: { LabelShort : 'FANT',						LabelMedium : 'FANT',					LabelLong : 'FANT' },
		'fanta'						: { LabelShort : 'FANTA',						LabelMedium : 'FANTA',					LabelLong : 'FANTA' },
		'fantascienza'				: { LabelShort : 'FANTASCIENZA',				LabelMedium : 'Fantascienza',			LabelLong : 'Fantascienza' },
		'fap'						: { LabelShort : 'FAP',							LabelMedium : 'FaP',					LabelLong : 'FaP' },
		'fapcave'					: { LabelShort : 'FAPCAVE',						LabelMedium : 'FAPCAVE',					LabelLong : 'FAPCAVE' },
		'fargirenis'					: { LabelShort : 'FARGIRENIS',					LabelMedium : 'FARGIRENIS',				LabelLong : 'FARGIRENIS' },
		'fasm'						: { LabelShort : 'FASM',						LabelMedium : 'FASM',					LabelLong : 'FASM' },
		'fasthd'					: { LabelShort : 'FASTHD',						LabelMedium : 'FASTHD',					LabelLong : 'FASTHD' },
		'fatman'					: { LabelShort : 'FATMAN',						LabelMedium : 'fatman',					LabelLong : 'fatman' },
		'fbi'						: { LabelShort : 'FBI',							LabelMedium : 'FBI',					LabelLong : 'FBI' },
		'fcc'						: { LabelShort : 'FCC',							LabelMedium : 'FCC',					LabelLong : 'FCC' },
		'fck'						: { LabelShort : 'FCK',							LabelMedium : 'FCK',					LabelLong : 'FCK' },
		'feature'					: { LabelShort : 'FEATURE',						LabelMedium : 'FEATURE',					LabelLong : 'FEATURE' },
		'feelfree'					: { LabelShort : 'FEELFREE',					LabelMedium : 'FeelFree',				LabelLong : 'Feel-Free' },
		'felony'					: { LabelShort : 'FELONY',						LabelMedium : 'FELONY',					LabelLong : 'FELONY' },
		'fendt'						: { LabelShort : 'FENDT',						LabelMedium : 'FENDT',					LabelLong : 'FENDT' },
		'feral'						: { LabelShort : 'FERAL',						LabelMedium : 'FERAL',					LabelLong : 'FERAL' },
		'fetish'					: { LabelShort : 'FETISH',						LabelMedium : 'FETiSH',					LabelLong : 'FETiSH' },
		'fever'						: { LabelShort : 'FEVER',						LabelMedium : 'FEVER',					LabelLong : 'FEVER' },
		'ff'							: { LabelShort : 'FF',							LabelMedium : 'FF',						LabelLong : 'FF' },
		'ffa'						: { LabelShort : 'FFA',							LabelMedium : 'FFA',					LabelLong : 'FFA' },
		'ffansweb'					: { LabelShort : 'FFANSWEB',					LabelMedium : 'FFansWEB',				LabelLong : 'FFansWEB' },
		'fff'						: { LabelShort : 'FFF',							LabelMedium : 'FFF',					LabelLong : 'FFF' },
		'ffndvd'					: { LabelShort : 'FFNDVD',						LabelMedium : 'FFNDVD',					LabelLong : 'FFNDVD' },
		'ffs'						: { LabelShort : 'FFS',							LabelMedium : 'FFS',					LabelLong : 'FFS' },
		'fgt'						: { LabelShort : 'FGT',							LabelMedium : 'FGT',					LabelLong : 'FGT' },
		'fiasco'					: { LabelShort : 'FIASCO',						LabelMedium : 'FiASCO',					LabelLong : 'FiASCO' },
		'fico'						: { LabelShort : 'FICO',						LabelMedium : 'FiCO',					LabelLong : 'FiCO' },
		'ficodvdr'					: { LabelShort : 'FICODVDR',					LabelMedium : 'FiCODVDR',				LabelLong : 'FiCODVDR' },
		'fidelio'					: { LabelShort : 'FIDELIO',						LabelMedium : 'FiDELiO',					LabelLong : 'FiDELiO' },
		'fido'						: { LabelShort : 'FIDO',						LabelMedium : 'FiDO',					LabelLong : 'FiDO' },
		'fightbb'					: { LabelShort : 'FIGHTBB',						LabelMedium : 'FightBB',					LabelLong : 'FightBB' },
		'fihtv'						: { LabelShort : 'FIHTV',						LabelMedium : 'FiHTV',					LabelLong : 'FiHTV' },
		'fij'						: { LabelShort : 'FIJ',							LabelMedium : 'FIJ',					LabelLong : 'FIJ' },
		'filmanta'					: { LabelShort : 'FILMANTA',					LabelMedium : 'FiLMANTA',				LabelLong : 'FiLMANTA' },
		'filmhd'					: { LabelShort : 'FILMHD',						LabelMedium : 'FilmHD',					LabelLong : 'FilmHD' },
		'filmikz'					: { LabelShort : 'FILMIKZ',						LabelMedium : 'Filmikz',					LabelLong : 'Filmikz' },
		'filmiwar'					: { LabelShort : 'FILMIWAR',					LabelMedium : 'Filmiwar',				LabelLong : 'Filmiwar' },
		'filmsclub'					: { LabelShort : 'FILMSCLUB',					LabelMedium : 'FilmsClub',				LabelLong : 'Films.Club' },
		'filmytorrents'				: { LabelShort : 'FILMYTORRENTS',				LabelMedium : 'Filmytorrents',			LabelLong : 'Filmytorrents' },
		'finale'					: { LabelShort : 'FINALE',						LabelMedium : 'FiNaLe',					LabelLong : 'FiNaLe' },
		'finally'					: { LabelShort : 'FINALLY',						LabelMedium : 'FINALLY',					LabelLong : 'FINALLY' },
		'fixi0n'					: { LabelShort : 'FIXI0N',						LabelMedium : 'FiXi0N',					LabelLong : 'FiXi0N' },
		'fizo'						: { LabelShort : 'FIZO',						LabelMedium : 'Fizo',					LabelLong : 'Fizo' },
		'fk99'						: { LabelShort : 'FK99',						LabelMedium : 'FK99',					LabelLong : 'FK99' },
		'fkkhd'						: { LabelShort : 'FKKHD',						LabelMedium : 'FKKHD',					LabelLong : 'FKKHD' },
		'fkktv'						: { LabelShort : 'FKKTV',						LabelMedium : 'FKKTV',					LabelLong : 'FKKTV' },
		'flair'						: { LabelShort : 'FLAIR',						LabelMedium : 'FLAiR',					LabelLong : 'FLAiR' },
		'flaite'					: { LabelShort : 'FLAITE',						LabelMedium : 'FLAiTE',					LabelLong : 'FLAiTE' },
		'flame'						: { LabelShort : 'FLAME',						LabelMedium : 'FLAME',					LabelLong : 'FLAME' },
		'flash'						: { LabelShort : 'FLASH',						LabelMedium : 'FLASH',					LabelLong : 'FLASH' },
		'flatline'					: { LabelShort : 'FLATLINE',					LabelMedium : 'FLATLiNE',				LabelLong : 'FLATLiNE' },
		'flawl3ss'					: { LabelShort : 'FLAWL3SS',					LabelMedium : 'FLAWL3SS',				LabelLong : 'FLAWL3SS' },
		'fleet'						: { LabelShort : 'FLEET',						LabelMedium : 'FLEET',					LabelLong : 'FLEET' },
		'flex'						: { LabelShort : 'FLEX',						LabelMedium : 'FLEX',					LabelLong : 'FLEX' },
		'flicksick'					: { LabelShort : 'FLICKSICK',					LabelMedium : 'FLiCKSiCK',				LabelLong : 'FLiCKSiCK' },
		'flights'					: { LabelShort : 'FLIGHTS',						LabelMedium : 'FLIGHTS',					LabelLong : 'FLIGHTS' },
		'flintfilms'					: { LabelShort : 'FLINTFILMS',					LabelMedium : 'FLINTFILMS',				LabelLong : 'FLINTFILMS' },
		'fllortv'					: { LabelShort : 'FLLORTV',						LabelMedium : 'FllorTV',					LabelLong : 'FllorTV' },
		'flop'						: { LabelShort : 'FLOP',						LabelMedium : 'FLOP',					LabelLong : 'FLOP' },
		'fls'						: { LabelShort : 'FLS',							LabelMedium : 'FLS',					LabelLong : 'FLS' },
		'flt'						: { LabelShort : 'FLT',							LabelMedium : 'FLT',					LabelLong : 'FLT' },
		'flux'						: { LabelShort : 'FLUX',						LabelMedium : 'FLUX',					LabelLong : 'FLUX' },
		'flx'						: { LabelShort : 'FLX',							LabelMedium : 'FLX',					LabelLong : 'FLX' },
		'fly635'					: { LabelShort : 'FLY635',						LabelMedium : 'FLY635',					LabelLong : 'FLY635' },
		'fmdab'						: { LabelShort : 'FMDAB',						LabelMedium : 'FMDAB',					LabelLong : 'FMDAB' },
		'fme'						: { LabelShort : 'FME',							LabelMedium : 'FmE',					LabelLong : 'FmE' },
		'focus'						: { LabelShort : 'FOCUS',						LabelMedium : 'FOCUS',					LabelLong : 'FOCUS' },
		'fookas'					: { LabelShort : 'FOOKAS',						LabelMedium : 'FooKaS',					LabelLong : 'FooKaS' },
		'football'					: { LabelShort : 'FOOTBALL',					LabelMedium : 'FOOTBALL',				LabelLong : 'FOOTBALL' },
		'force'						: { LabelShort : 'FORCE',						LabelMedium : 'FORCE',					LabelLong : 'FORCE' },
		'forcebleue'					: { LabelShort : 'FORCEBLEUE',					LabelMedium : 'ForceBleue',				LabelLong : 'ForceBleue' },
		'form'						: { LabelShort : 'FORM',						LabelMedium : 'FoRM',					LabelLong : 'FoRM' },
		'formula'					: { LabelShort : 'FORMULA',						LabelMedium : 'FORMULA',					LabelLong : 'FORMULA' },
		'forsaken'					: { LabelShort : 'FORSAKEN',					LabelMedium : 'FORSAKEN',				LabelLong : 'FORSAKEN' },
		'forward'					: { LabelShort : 'FORWARD',						LabelMedium : 'FORWARD',					LabelLong : 'FORWARD' },
		'fov'						: { LabelShort : 'FOV',							LabelMedium : 'FoV',					LabelLong : 'FoV' },
		'foxm'						: { LabelShort : 'FOXM',						LabelMedium : 'FOXM',					LabelLong : 'FOXM' },
		'foxpro'					: { LabelShort : 'FOXPRO',						LabelMedium : 'FOXPRO',					LabelLong : 'FOXPRO' },
		'foxtrot'					: { LabelShort : 'FOXTROT',						LabelMedium : 'FOXTROT',					LabelLong : 'FOXTROT' },
		'foxy'						: { LabelShort : 'FOXY',						LabelMedium : 'FOXY',					LabelLong : 'FOXY' },
		'fqm'						: { LabelShort : 'FQM',							LabelMedium : 'FQM',					LabelLong : 'FQM' },
		'fractal'					: { LabelShort : 'FRACTAL',						LabelMedium : 'FRACTAL',					LabelLong : 'FRACTAL' },
		'fragment'					: { LabelShort : 'FRAGMENT',					LabelMedium : 'FRAGMENT',				LabelLong : 'FRAGMENT' },
		'frame'						: { LabelShort : 'FRAME',						LabelMedium : 'FraMe',					LabelLong : 'FraMe' },
		'framestor'					: { LabelShort : 'FRAMESTOR',					LabelMedium : 'FraMeSToR',				LabelLong : 'FraMeSToR' },
		'frangoassado'				: { LabelShort : 'FRANGOASSADO',				LabelMedium : 'FrangoAssado',			LabelLong : 'FrangoAssado' },
		'fraternity'					: { LabelShort : 'FRATERNITY',					LabelMedium : 'FRATERNiTY',				LabelLong : 'FRATERNiTY' },
		'fratposa'					: { LabelShort : 'FRATPOSA',					LabelMedium : 'Fratposa',				LabelLong : 'Fratposa' },
		'freak'						: { LabelShort : 'FREAK',						LabelMedium : 'FreaK',					LabelLong : 'FreaK' },
		'freaks'					: { LabelShort : 'FREAKS',						LabelMedium : 'FREAKS',					LabelLong : 'FREAKS' },
		'freebee'					: { LabelShort : 'FREEBEE',						LabelMedium : 'Freebee',					LabelLong : 'Freebee' },
		'freedom'					: { LabelShort : 'FREEDOM',						LabelMedium : 'FREEDOM',					LabelLong : 'FREEDOM' },
		'freethefish'				: { LabelShort : 'FREETHEFISH',					LabelMedium : 'FreetheFish',			LabelLong : 'FreetheFish' },
		'friday21st'					: { LabelShort : 'FRIDAY21ST',					LabelMedium : 'Friday21st',				LabelLong : 'Friday21st' },
		'friends'					: { LabelShort : 'FRIENDS',						LabelMedium : 'FrIeNdS',					LabelLong : 'FrIeNdS' },
		'fries'						: { LabelShort : 'FRIES',						LabelMedium : 'FRiES',					LabelLong : 'FRiES' },
		'frisky'					: { LabelShort : 'FRISKY',						LabelMedium : 'FRISKY',					LabelLong : 'FRISKY' },
		'frog'						: { LabelShort : 'FROG',						LabelMedium : 'FROG',					LabelLong : 'FROG' },
		'fronky'					: { LabelShort : 'FRONKY',						LabelMedium : 'FrOnkY',					LabelLong : 'FrOnkY' },
		'frost'						: { LabelShort : 'FROST',						LabelMedium : 'FROST',					LabelLong : 'FROST' },
		'frozen'					: { LabelShort : 'FROZEN',						LabelMedium : 'FroZen',					LabelLong : 'FroZen' },
		'fsihd'						: { LabelShort : 'FSIHD',						LabelMedium : 'FSiHD',					LabelLong : 'FSiHD' },
		'ftmvhd'					: { LabelShort : 'FTMVHD',						LabelMedium : 'FTMVHD',					LabelLong : 'FTMVHD' },
		'fto'						: { LabelShort : 'FTO',							LabelMedium : 'FTO',					LabelLong : 'FTO' },
		'ftp'						: { LabelShort : 'FTP',							LabelMedium : 'FTP',					LabelLong : 'FTP' },
		'fts'						: { LabelShort : 'FTS',							LabelMedium : 'FTS',					LabelLong : 'FTS' },
		'ftwhd'						: { LabelShort : 'FTWHD',						LabelMedium : 'FTWHD',					LabelLong : 'FTW-HD' },
		'fty'						: { LabelShort : 'FTY',							LabelMedium : 'fty',					LabelLong : 'fty' },
		'fuc0v1d'					: { LabelShort : 'FUC0V1D',						LabelMedium : 'FUC0V1D',					LabelLong : 'FUC0V1D' },
		'fuckads'					: { LabelShort : 'FUCKADS',						LabelMedium : 'FuckAds',					LabelLong : 'FuckAds' },
		'full4'						: { LabelShort : 'FULL4',						LabelMedium : 'Full4',					LabelLong : 'Full4' },
		'full4movies'				: { LabelShort : 'FULL4MOVIES',					LabelMedium : 'Full4Movies',			LabelLong : 'Full4Movies' },
		'fullsize'					: { LabelShort : 'FULLSIZE',					LabelMedium : 'FULLSIZE',				LabelLong : 'FULLSIZE' },
		'fum'						: { LabelShort : 'FUM',							LabelMedium : 'FUM',					LabelLong : 'FUM' },
		'fun'						: { LabelShort : 'FUN',							LabelMedium : 'FuN',					LabelLong : 'FuN' },
		'funkky'					: { LabelShort : 'FUNKKY',						LabelMedium : 'FUNKKY',					LabelLong : 'FUNKKY' },
		'funner'					: { LabelShort : 'FUNNER',						LabelMedium : 'FUNNER',					LabelLong : 'FUNNER' },
		'fusion'					: { LabelShort : 'FUSION',						LabelMedium : 'FUSiON',					LabelLong : 'FUSiON' },
		'futv'						: { LabelShort : 'FUTV',						LabelMedium : 'FUtV',					LabelLong : 'FUtV' },
		'fuzerhd'					: { LabelShort : 'FUZERHD',						LabelMedium : 'FuzerHD',					LabelLong : 'FuzerHD' },
		'fxg'						: { LabelShort : 'FXG',							LabelMedium : 'FXG',					LabelLong : 'FXG' },
		'fxm'						: { LabelShort : 'FXM',							LabelMedium : 'FxM',					LabelLong : 'FxM' },
		'fzero'						: { LabelShort : 'FZERO',						LabelMedium : 'FZERO',					LabelLong : 'FZERO' },
		'fzhd'						: { LabelShort : 'FZHD',						LabelMedium : 'FZHD',					LabelLong : 'FZHD' },
		'fzteam'					: { LabelShort : 'FZTEAM',						LabelMedium : 'FzTeam',					LabelLong : 'FzTeam' },
		'g3lhd'						: { LabelShort : 'G3LHD',						LabelMedium : 'G3LHD',					LabelLong : 'G3LHD' },
		'g4ris'						: { LabelShort : 'G4RIS',						LabelMedium : 'G4RiS',					LabelLong : 'G4RiS' },
		'ga'							: { LabelShort : 'GA',							LabelMedium : 'GA',						LabelLong : 'GA' },
		'ga645zi'					: { LabelShort : 'GA645ZI',						LabelMedium : 'GA645Zi',					LabelLong : 'GA645Zi' },
		'gabe'						: { LabelShort : 'GABE',						LabelMedium : 'GABE',					LabelLong : 'GABE' },
		'gage'						: { LabelShort : 'GAGE',						LabelMedium : 'GAGE',					LabelLong : 'GAGE' },
		'galactica'					: { LabelShort : 'GALACTICA',					LabelMedium : 'GALACTiCA',				LabelLong : 'GALACTiCA' },
		'galaxyrg'					: { LabelShort : 'GALAXYRG',					LabelMedium : 'GalaxyRG',				LabelLong : 'GalaxyRG' },
		'galaxytv'					: { LabelShort : 'GALAXYTV',					LabelMedium : 'GalaxyTV',				LabelLong : 'GalaxyTV' },
		'ganool'					: { LabelShort : 'GANOOL',						LabelMedium : 'GANOOL',					LabelLong : 'GANOOL' },
		'garshasp'					: { LabelShort : 'GARSHASP',					LabelMedium : 'Garshasp',				LabelLong : 'Garshasp' },
		'gas'						: { LabelShort : 'GAS',							LabelMedium : 'GAS',					LabelLong : 'GAS' },
		'gasmask'					: { LabelShort : 'GASMASK',						LabelMedium : 'GASMASK',					LabelLong : 'GASMASK' },
		'gattopollo'					: { LabelShort : 'GATTOPOLLO',					LabelMedium : 'gattopollo',				LabelLong : 'gattopollo' },
		'gaygay'					: { LabelShort : 'GAYGAY',						LabelMedium : 'GAYGAY',					LabelLong : 'GAYGAY' },
		'gaz'						: { LabelShort : 'GAZ',							LabelMedium : 'GAZ',					LabelLong : 'GAZ' },
		'gbb'						: { LabelShort : 'GBB',							LabelMedium : 'GBB',					LabelLong : 'GBB' },
		'gbm'						: { LabelShort : 'GBM',							LabelMedium : 'GBM',					LabelLong : 'GBM' },
		'gdr'						: { LabelShort : 'GDR',							LabelMedium : 'GDR',					LabelLong : 'GDR' },
		'gearsmedia'					: { LabelShort : 'GEARSMEDIA',					LabelMedium : 'GearsMedia',				LabelLong : 'Gears.Media' },
		'geckos'					: { LabelShort : 'GECKOS',						LabelMedium : 'GECKOS',					LabelLong : 'GECKOS' },
		'geek'						: { LabelShort : 'GEEK',						LabelMedium : 'GEEK',					LabelLong : 'GEEK' },
		'geekrg'					: { LabelShort : 'GEEKRG',						LabelMedium : 'GeekRG',					LabelLong : 'GeekRG' },
		'gellard'					: { LabelShort : 'GELLARD',						LabelMedium : 'Gellard',					LabelLong : 'Gellard' },
		'gelob'						: { LabelShort : 'GELOB',						LabelMedium : 'GeloB',					LabelLong : 'Gelo.B' },
		'genemige'					: { LabelShort : 'GENEMIGE',					LabelMedium : 'GeneMige',				LabelLong : 'GeneMige' },
		'geneside'					: { LabelShort : 'GENESIDE',					LabelMedium : 'GENESIDE',				LabelLong : 'GENESIDE' },
		'genesis'					: { LabelShort : 'GENESIS',						LabelMedium : 'GENESIS',					LabelLong : 'GENESIS' },
		'genuine'					: { LabelShort : 'GENUINE',						LabelMedium : 'GENUiNE',					LabelLong : 'GENUiNE' },
		'geo'						: { LabelShort : 'GEO',							LabelMedium : 'GEO',					LabelLong : 'GEO' },
		'gerald99'					: { LabelShort : 'GERALD99',					LabelMedium : 'gerald99',				LabelLong : 'gerald99' },
		'gerudo'					: { LabelShort : 'GERUDO',						LabelMedium : 'GERUDO',					LabelLong : 'GERUDO' },
		'getb8'						: { LabelShort : 'GETB8',						LabelMedium : 'GETB8',					LabelLong : 'GETB8' },
		'getb9'						: { LabelShort : 'GETB9',						LabelMedium : 'GETB9',					LabelLong : 'GETB9' },
		'getit'						: { LabelShort : 'GETIT',						LabelMedium : 'GETiT',					LabelLong : 'GETiT' },
		'getschwifty'				: { LabelShort : 'GETSCHWIFTY',					LabelMedium : 'GetSchwifty',			LabelLong : 'GetSchwifty' },
		'gfw'						: { LabelShort : 'GFW',							LabelMedium : 'GFW',					LabelLong : 'GFW' },
		'gfy'						: { LabelShort : 'GFY',							LabelMedium : 'GFY',					LabelLong : 'GFY' },
		'gg'							: { LabelShort : 'GG',							LabelMedium : 'gg',						LabelLong : 'gg' },
		'ggez'						: { LabelShort : 'GGEZ',						LabelMedium : 'GGEZ',					LabelLong : 'GGEZ' },
		'ggwp'						: { LabelShort : 'GGWP',						LabelMedium : 'GGWP',					LabelLong : 'GGWP' },
		'ghost'						: { LabelShort : 'GHOST',						LabelMedium : 'GHOST',					LabelLong : 'GHOST' },
		'ghosts'					: { LabelShort : 'GHOSTS',						LabelMedium : 'GHOSTS',					LabelLong : 'GHOSTS' },
		'ghouls'					: { LabelShort : 'GHOULS',						LabelMedium : 'GHOULS',					LabelLong : 'GHOULS' },
		'ghs'						: { LabelShort : 'GHS',							LabelMedium : 'GHS',					LabelLong : 'GHS' },
		'gi'							: { LabelShort : 'GI',							LabelMedium : 'GI',						LabelLong : 'GI' },
		'gillop'					: { LabelShort : 'GILLOP',						LabelMedium : 'Gillop',					LabelLong : 'Gillop' },
		'gimchi'					: { LabelShort : 'GIMCHI',						LabelMedium : 'GiMCHi',					LabelLong : 'GiMCHi' },
		'ginji'						: { LabelShort : 'GINJI',						LabelMedium : 'GiNJi',					LabelLong : 'GiNJi' },
		'girays'					: { LabelShort : 'GIRAYS',						LabelMedium : 'GIRAYS',					LabelLong : 'GIRAYS' },
		'giu'						: { LabelShort : 'GIU',							LabelMedium : 'giu',					LabelLong : 'giu' },
		'gl'							: { LabelShort : 'GL',							LabelMedium : 'GL',						LabelLong : 'GL' },
		'glados'					: { LabelShort : 'GLADOS',						LabelMedium : 'GLaDOS',					LabelLong : 'GLaDOS' },
		'glasses'					: { LabelShort : 'GLASSES',						LabelMedium : 'GLASSES',					LabelLong : 'GLASSES' },
		'glenn'						: { LabelShort : 'GLENN',						LabelMedium : 'Glenn',					LabelLong : 'Glenn' },
		'glhf'						: { LabelShort : 'GLHF',						LabelMedium : 'GLHF',					LabelLong : 'GLHF' },
		'glm8892'					: { LabelShort : 'GLM8892',						LabelMedium : 'glm8892',					LabelLong : 'glm8892' },
		'globe'						: { LabelShort : 'GLOBE',						LabelMedium : 'GLOBE',					LabelLong : 'GLOBE' },
		'glowgaze'					: { LabelShort : 'GLOWGAZE',					LabelMedium : 'GlowGaze',				LabelLong : 'GlowGaze.Com' },
		'glue'						: { LabelShort : 'GLUE',						LabelMedium : 'GLUE',					LabelLong : 'GLUE' },
		'gly'						: { LabelShort : 'GLY',							LabelMedium : 'GLY',					LabelLong : 'GLY' },
		'gm'							: { LabelShort : 'GM',							LabelMedium : 'GM',						LabelLong : 'GM' },
		'gma'						: { LabelShort : 'GMA',							LabelMedium : 'GMA',					LabelLong : 'GMA' },
		'gnarly'					: { LabelShort : 'GNARLY',						LabelMedium : 'GNARLY',					LabelLong : 'GNARLY' },
		'gnome'						: { LabelShort : 'GNOME',						LabelMedium : 'GNOME',					LabelLong : 'GNOME' },
		'goape'						: { LabelShort : 'GOAPE',						LabelMedium : 'GoApe',					LabelLong : 'GoApe' },
		'goatlove'					: { LabelShort : 'GOATLOVE',					LabelMedium : 'GOATLOVE',				LabelLong : 'GOATLOVE' },
		'goblin10'					: { LabelShort : 'GOBLIN10',					LabelMedium : 'Goblin10',				LabelLong : 'Goblin10' },
		'god'						: { LabelShort : 'GOD',							LabelMedium : 'GOD',					LabelLong : 'GOD' },
		'goenwae'					: { LabelShort : 'GOENWAE',						LabelMedium : 'GoenWae',					LabelLong : 'GoenWae' },
		'gogeta'					: { LabelShort : 'GOGETA',						LabelMedium : 'Gogeta',					LabelLong : 'Gogeta' },
		'goki'						: { LabelShort : 'GOKI',						LabelMedium : 'Goki',					LabelLong : 'Goki' },
		'goku61'					: { LabelShort : 'GOKU61',						LabelMedium : 'GokU61',					LabelLong : 'GokU61' },
		'golumpa'					: { LabelShort : 'GOLUMPA',						LabelMedium : 'Golumpa',					LabelLong : 'Golumpa' },
		'gon'						: { LabelShort : 'GON',							LabelMedium : 'GoN',					LabelLong : 'GoN' },
		'goodfilms'					: { LabelShort : 'GOODFILMS',					LabelMedium : 'GoodFilms',				LabelLong : 'GoodFilms' },
		'goodpeople'					: { LabelShort : 'GOODPEOPLE',					LabelMedium : 'GOODPEOPLE',				LabelLong : 'GOOD.PEOPLE' },
		'goon'						: { LabelShort : 'GOON',						LabelMedium : 'GooN',					LabelLong : 'GooN' },
		'gooner'					: { LabelShort : 'GOONER',						LabelMedium : 'Gooner',					LabelLong : 'Gooner' },
		'gooz'						: { LabelShort : 'GOOZ',						LabelMedium : 'gooz',					LabelLong : 'gooz' },
		'gop'						: { LabelShort : 'GOP',							LabelMedium : 'GOP',					LabelLong : 'GOP' },
		'gopanda'					: { LabelShort : 'GOPANDA',						LabelMedium : 'GoPanda',					LabelLong : 'GoPanda' },
		'gopisahi'					: { LabelShort : 'GOPISAHI',					LabelMedium : 'GOPISAHI',				LabelLong : 'GOPI.SAHI' },
		'gopo'						: { LabelShort : 'GOPO',						LabelMedium : 'GOPO',					LabelLong : 'GOPO' },
		'gore'						: { LabelShort : 'GORE',						LabelMedium : 'GORE',					LabelLong : 'GORE' },
		'gorehounds'					: { LabelShort : 'GOREHOUNDS',					LabelMedium : 'GOREHOUNDS',				LabelLong : 'GOREHOUNDS' },
		'gos'						: { LabelShort : 'GOS',							LabelMedium : 'GOS',					LabelLong : 'GOS' },
		'gossip'					: { LabelShort : 'GOSSIP',						LabelMedium : 'GOSSIP',					LabelLong : 'GOSSIP' },
		'gothic'					: { LabelShort : 'GOTHIC',						LabelMedium : 'GOTHiC',					LabelLong : 'GOTHiC' },
		'gothicmaster'				: { LabelShort : 'GOTHICMASTER',				LabelMedium : 'Gothicmaster',			LabelLong : 'Gothicmaster' },
		'gotv'						: { LabelShort : 'GOTV',						LabelMedium : 'GoTV',					LabelLong : 'GoTV' },
		'graveurexterne'			: { LabelShort : 'GRAVEUREXTERNE',				LabelMedium : 'Graveurexterne',			LabelLong : 'Graveurexterne' },
		'greenbud1969'				: { LabelShort : 'GREENBUD1969',				LabelMedium : 'greenbud1969',			LabelLong : 'greenbud1969' },
		'greenstorm'					: { LabelShort : 'GREENSTORM',					LabelMedium : 'GreenStorm',				LabelLong : 'GreenStorm' },
		'greid'						: { LabelShort : 'GREID',						LabelMedium : 'GREiD',					LabelLong : 'GREiD' },
		'grep'						: { LabelShort : 'GREP',						LabelMedium : 'GREP',					LabelLong : 'GREP' },
		'greyhounds'					: { LabelShort : 'GREYHOUNDS',					LabelMedium : 'GREYHOUNDS',				LabelLong : 'GREYHOUNDS' },
		'grind'						: { LabelShort : 'GRIND',						LabelMedium : 'GRiND',					LabelLong : 'GRiND' },
		'grupohds'					: { LabelShort : 'GRUPOHDS',					LabelMedium : 'GrupoHDS',				LabelLong : 'GrupoHDS' },
		'grym'						: { LabelShort : 'GRYM',						LabelMedium : 'GRYM',					LabelLong : 'GRYM' },
		'gs'							: { LabelShort : 'GS',							LabelMedium : 'GS',						LabelLong : 'GS' },
		'gs88'						: { LabelShort : 'GS88',						LabelMedium : 'GS88',					LabelLong : 'GS88' },
		'gsftx'						: { LabelShort : 'GSFTX',						LabelMedium : 'GSFTX',					LabelLong : 'GSFTX' },
		'gsg9'						: { LabelShort : 'GSG9',						LabelMedium : 'GSG9',					LabelLong : 'GSG9' },
		'gsn'						: { LabelShort : 'GSN',							LabelMedium : 'GSN',					LabelLong : 'GSN' },
		'gtf'						: { LabelShort : 'GTF',							LabelMedium : 'GTF',					LabelLong : 'GTF' },
		'gti'						: { LabelShort : 'GTI',							LabelMedium : 'GTi',					LabelLong : 'GTi' },
		'gtvg'						: { LabelShort : 'GTVG',						LabelMedium : 'GTVG',					LabelLong : 'GTVG' },
		'guacamole'					: { LabelShort : 'GUACAMOLE',					LabelMedium : 'GUACAMOLE',				LabelLong : 'GUACAMOLE' },
		'guardians'					: { LabelShort : 'GUARDIANS',					LabelMedium : 'GUARDiANS',				LabelLong : 'GUARDiANS' },
		'gungrave'					: { LabelShort : 'GUNGRAVE',					LabelMedium : 'GunGravE',				LabelLong : 'GunGravE' },
		'gur'						: { LabelShort : 'GUR',							LabelMedium : 'GUR',					LabelLong : 'GUR' },
		'gvd'						: { LabelShort : 'GVD',							LabelMedium : 'GVD',					LabelLong : 'GVD' },
		'gw'							: { LabelShort : 'GW',							LabelMedium : 'GW',						LabelLong : 'GW' },
		'gwc'						: { LabelShort : 'GWC',							LabelMedium : 'GWC',					LabelLong : 'GWC' },
		'gwp'						: { LabelShort : 'GWP',							LabelMedium : 'GWP',					LabelLong : 'GWP' },
		'gxp'						: { LabelShort : 'GXP',							LabelMedium : 'GxP',					LabelLong : 'GxP' },
		'gyroscope'					: { LabelShort : 'GYROSCOPE',					LabelMedium : 'Gyroscope',				LabelLong : 'Gyroscope' },
		'gzcrew'					: { LabelShort : 'GZCREW',						LabelMedium : 'GZCrew',					LabelLong : 'GZCrew' },
		'gzp'						: { LabelShort : 'GZP',							LabelMedium : 'GZP',					LabelLong : 'GZP' },
		'h2'							: { LabelShort : 'H2',							LabelMedium : 'H2',						LabelLong : 'H2' },
		'h3ll2p4y'					: { LabelShort : 'H3LL2P4Y',					LabelMedium : 'H3LL2P4Y',				LabelLong : 'H3LL2P4Y' },
		'h3llg0d'					: { LabelShort : 'H3LLG0D',						LabelMedium : 'h3llg0d',					LabelLong : 'h3llg0d' },
		'h4s5s'						: { LabelShort : 'H4S5S',						LabelMedium : 'H4S5S',					LabelLong : 'H4S5S' },
		'hab'						: { LabelShort : 'HAB',							LabelMedium : 'HaB',					LabelLong : 'HaB' },
		'haco'						: { LabelShort : 'HACO',						LabelMedium : 'HACO',					LabelLong : 'HACO' },
		'haggis'					: { LabelShort : 'HAGGIS',						LabelMedium : 'HAGGiS',					LabelLong : 'HAGGiS' },
		'haideaf'					: { LabelShort : 'HAIDEAF',						LabelMedium : 'HAiDEAF',					LabelLong : 'HAiDEAF' },
		'haiku'						: { LabelShort : 'HAIKU',						LabelMedium : 'HAiKU',					LabelLong : 'HAiKU' },
		'halcyon'					: { LabelShort : 'HALCYON',						LabelMedium : 'HALCYON',					LabelLong : 'HALCYON' },
		'hammer71'					: { LabelShort : 'HAMMER71',					LabelMedium : 'Hammer71',				LabelLong : 'Hammer71' },
		'hangover'					: { LabelShort : 'HANGOVER',					LabelMedium : 'HANGOVER',				LabelLong : 'HANGOVER' },
		'hannibal'					: { LabelShort : 'HANNIBAL',					LabelMedium : 'HANNIBAL',				LabelLong : 'HANNIBAL' },
		'hao4k'						: { LabelShort : 'HAO4K',						LabelMedium : 'HAO4K',					LabelLong : 'HAO4K' },
		'hashminer'					: { LabelShort : 'HASHMINER',					LabelMedium : 'HashMiner',				LabelLong : 'HashMiner' },
		'hatchetgear'				: { LabelShort : 'HATCHETGEAR',					LabelMedium : 'HatchetGear',			LabelLong : 'HatchetGear' },
		'hay'						: { LabelShort : 'HAY',							LabelMedium : 'HAY',					LabelLong : 'HAY' },
		'hazmatt'					: { LabelShort : 'HAZMATT',						LabelMedium : 'HazMatt',					LabelLong : 'HazMatt' },
		'hb'							: { LabelShort : 'HB',							LabelMedium : 'HB',						LabelLong : 'HB' },
		'hca'						: { LabelShort : 'HCA',							LabelMedium : 'HCA',					LabelLong : 'HCA' },
		'hd4u'						: { LabelShort : 'HD4U',						LabelMedium : 'HD4U',					LabelLong : 'HD4U' },
		'hda'						: { LabelShort : 'HDA',							LabelMedium : 'HDA',					LabelLong : 'HDA' },
		'hdaccess'					: { LabelShort : 'HDACCESS',					LabelMedium : 'HDAccess',				LabelLong : 'HDAccess' },
		'hdalx'						: { LabelShort : 'HDALX',						LabelMedium : 'hdalx',					LabelLong : 'hdalx' },
		'hdarea'					: { LabelShort : 'HDAREA',						LabelMedium : 'HDArea',					LabelLong : 'HDArea' },
		'hdb'						: { LabelShort : 'HDB',							LabelMedium : 'HDB',					LabelLong : 'HDB' },
		'hdbee'						: { LabelShort : 'HDBEE',						LabelMedium : 'HDBEE',					LabelLong : 'HDBEE' },
		'hdbrise'					: { LabelShort : 'HDBRISE',						LabelMedium : 'HDBRiSe',					LabelLong : 'HDBRiSe' },
		'hdc'						: { LabelShort : 'HDC',							LabelMedium : 'HDC',					LabelLong : 'HDC' },
		'hdchina'					: { LabelShort : 'HDCHINA',						LabelMedium : 'HDChina',					LabelLong : 'HDChina' },
		'hdclassics'					: { LabelShort : 'HDCLASSICS',					LabelMedium : 'HDCLASSiCS',				LabelLong : 'HDCLASSiCS' },
		'hdclub'					: { LabelShort : 'HDCLUB',						LabelMedium : 'HDClub',					LabelLong : 'HDClub' },
		'hdcp'						: { LabelShort : 'HDCP',						LabelMedium : 'HDCP',					LabelLong : 'HDCP' },
		'hdctv'						: { LabelShort : 'HDCTV',						LabelMedium : 'HDCTV',					LabelLong : 'HDCTV' },
		'hddevils'					: { LabelShort : 'HDDEVILS',					LabelMedium : 'HDDEViLS',				LabelLong : 'HDDEViLS' },
		'hdetg'						: { LabelShort : 'HDETG',						LabelMedium : 'HDETG',					LabelLong : 'HDETG' },
		'hdex'						: { LabelShort : 'HDEX',						LabelMedium : 'HDEX',					LabelLong : 'HDEX' },
		'hdfilmboss'					: { LabelShort : 'HDFILMBOSS',					LabelMedium : 'HDFilmBoss',				LabelLong : 'HDFilmBoss' },
		'hdh'						: { LabelShort : 'HDH',							LabelMedium : 'HDH',					LabelLong : 'HDH' },
		'hdhome'					: { LabelShort : 'HDHOME',						LabelMedium : 'HDHome',					LabelLong : 'HDHome' },
		'hdhub'						: { LabelShort : 'HDHUB',						LabelMedium : 'HDHub',					LabelLong : 'HDHub' },
		'hdi'						: { LabelShort : 'HDI',							LabelMedium : 'HDi',					LabelLong : 'HDi' },
		'hdil'						: { LabelShort : 'HDIL',						LabelMedium : 'HDIL',					LabelLong : 'HDIL' },
		'hdl'						: { LabelShort : 'HDL',							LabelMedium : 'HDL',					LabelLong : 'HDL' },
		'hdlight'					: { LabelShort : 'HDLIGHT',						LabelMedium : 'HDLight',					LabelLong : 'HDLight' },
		'hdlite'					: { LabelShort : 'HDLITE',						LabelMedium : 'HDLiTE',					LabelLong : 'HDLiTE' },
		'hdmaniacs'					: { LabelShort : 'HDMANIACS',					LabelMedium : 'HDMaNiAcS',				LabelLong : 'HDMaNiAcS' },
		'hdme'						: { LabelShort : 'HDME',						LabelMedium : 'HDME',					LabelLong : 'HDME' },
		'hdmonsk'					: { LabelShort : 'HDMONSK',						LabelMedium : 'HDmonSK',					LabelLong : 'HDmonSK' },
		'hdo'						: { LabelShort : 'HDO',							LabelMedium : 'HDO',					LabelLong : 'HDO' },
		'hdq'						: { LabelShort : 'HDQ',							LabelMedium : 'HDQ',					LabelLong : 'HDQ' },
		'hdreactor'					: { LabelShort : 'HDREACTOR',					LabelMedium : 'HDReactor',				LabelLong : 'HDReactor' },
		'hdrezka'					: { LabelShort : 'HDREZKA',						LabelMedium : 'HDRezka',					LabelLong : 'HDRezka' },
		'hdrezkastudio'				: { LabelShort : 'HDREZKASTUDIO',				LabelMedium : 'HDREZKASTUDIO',			LabelLong : 'HDREZKA.STUDIO' },
		'hdrinvasion'				: { LabelShort : 'HDRINVASION',					LabelMedium : 'HDRINVASION',			LabelLong : 'HDRINVASION' },
		'hdroad'					: { LabelShort : 'HDROAD',						LabelMedium : 'HDRoad',					LabelLong : 'HDRoad' },
		'hds'						: { LabelShort : 'HDS',							LabelMedium : 'HDS',					LabelLong : 'HDS' },
		'hdsector'					: { LabelShort : 'HDSECTOR',					LabelMedium : 'HDSector',				LabelLong : 'HDSector' },
		'hdspace'					: { LabelShort : 'HDSPACE',						LabelMedium : 'HDSpace',					LabelLong : 'HDSpace' },
		'hdt'						: { LabelShort : 'HDT',							LabelMedium : 'HDT',					LabelLong : 'HDT' },
		'hdteam'					: { LabelShort : 'HDTEAM',						LabelMedium : 'HDTeam',					LabelLong : 'HDTeam' },
		'hdtracker'					: { LabelShort : 'HDTRACKER',					LabelMedium : 'HDTracker',				LabelLong : 'HDTracker' },
		'hdu'						: { LabelShort : 'HDU',							LabelMedium : 'HDU',					LabelLong : 'HDU' },
		'hdv'						: { LabelShort : 'HDV',							LabelMedium : 'HDV',					LabelLong : 'HDV' },
		'hdv0t'						: { LabelShort : 'HDV0T',						LabelMedium : 'HDv0T',					LabelLong : 'HDv0T' },
		'hdvision'					: { LabelShort : 'HDVISION',					LabelMedium : 'HDViSiON',				LabelLong : 'HDViSiON' },
		'hdvn'						: { LabelShort : 'HDVN',						LabelMedium : 'HDVN',					LabelLong : 'HDVN' },
		'hdw'						: { LabelShort : 'HDW',							LabelMedium : 'HDW',					LabelLong : 'HDW' },
		'hdwing'					: { LabelShort : 'HDWING',						LabelMedium : 'HDWinG',					LabelLong : 'HDWinG' },
		'hdx'						: { LabelShort : 'HDX',							LabelMedium : 'HDX',					LabelLong : 'HDX' },
		'hdxt'						: { LabelShort : 'HDXT',						LabelMedium : 'HDxT',					LabelLong : 'HDxT' },
		'heat'						: { LabelShort : 'HEAT',						LabelMedium : 'HEAT',					LabelLong : 'HEAT' },
		'hector'					: { LabelShort : 'HECTOR',						LabelMedium : 'HECTOR',					LabelLong : 'HECTOR' },
		'heel'						: { LabelShort : 'HEEL',						LabelMedium : 'HEEL',					LabelLong : 'HEEL' },
		'heesten'					: { LabelShort : 'HEESTEN',						LabelMedium : 'hEESten',					LabelLong : 'hEESten' },
		'heh'						: { LabelShort : 'HEH',							LabelMedium : 'HEH',					LabelLong : 'HEH' },
		'heisenberg'					: { LabelShort : 'HEISENBERG',					LabelMedium : 'HEiSENBERG',				LabelLong : 'HEiSENBERG' },
		'helix'						: { LabelShort : 'HELIX',						LabelMedium : 'HELIX',					LabelLong : 'HELIX' },
		'hellraz0r'					: { LabelShort : 'HELLRAZ0R',					LabelMedium : 'HELLRAZ0R',				LabelLong : 'HELLRAZ0R' },
		'hellywood'					: { LabelShort : 'HELLYWOOD',					LabelMedium : 'HELLYWOOD',				LabelLong : 'HELLYWOOD' },
		'henderson'					: { LabelShort : 'HENDERSON',					LabelMedium : 'HenDerson',				LabelLong : 'HenDerson' },
		'herakler'					: { LabelShort : 'HERAKLER',					LabelMedium : 'Herakler',				LabelLong : 'Herakler' },
		'heteam'					: { LabelShort : 'HETEAM',						LabelMedium : 'HETeam',					LabelLong : 'HETeam' },
		'hevcbay'					: { LabelShort : 'HEVCBAY',						LabelMedium : 'HEVCBay',					LabelLong : 'HEVCBay' },
		'hevcclub'					: { LabelShort : 'HEVCCLUB',					LabelMedium : 'HEVCCLUB',				LabelLong : 'HEVC.CLUB' },
		'hevcguy'					: { LabelShort : 'HEVCGUY',						LabelMedium : 'HEVCguy',					LabelLong : 'HEVCguy' },
		'hevclovers'					: { LabelShort : 'HEVCLOVERS',					LabelMedium : 'HEVCLovers',				LabelLong : 'HEVCLovers' },
		'hh'							: { LabelShort : 'HH',							LabelMedium : 'HH',						LabelLong : 'HH' },
		'hhh'						: { LabelShort : 'HHH',							LabelMedium : 'HHH',					LabelLong : 'HHH' },
		'hhi'						: { LabelShort : 'HHI',							LabelMedium : 'HHI',					LabelLong : 'HHI' },
		'hidef'						: { LabelShort : 'HIDEF',						LabelMedium : 'HiDeF',					LabelLong : 'HiDeF' },
		'hidt'						: { LabelShort : 'HIDT',						LabelMedium : 'HiDt',					LabelLong : 'HiDt' },
		'hifi'						: { LabelShort : 'HIFI',						LabelMedium : 'HiFi',					LabelLong : 'HiFi' },
		'highcal'					: { LabelShort : 'HIGHCAL',						LabelMedium : 'highcal',					LabelLong : 'highcal' },
		'highcode'					: { LabelShort : 'HIGHCODE',					LabelMedium : 'HighCode',				LabelLong : 'HighCode' },
		'highvoltage'				: { LabelShort : 'HIGHVOLTAGE',					LabelMedium : 'Highvoltage',			LabelLong : 'Highvoltage' },
		'hillary'					: { LabelShort : 'HILLARY',						LabelMedium : 'HILLARY',					LabelLong : 'HILLARY' },
		'hiqve'						: { LabelShort : 'HIQVE',						LabelMedium : 'HiQVE',					LabelLong : 'HiQVE' },
		'hisd'						: { LabelShort : 'HISD',						LabelMedium : 'HiSD',					LabelLong : 'HiSD' },
		'history'					: { LabelShort : 'HISTORY',						LabelMedium : 'HiSTORY',					LabelLong : 'HiSTORY' },
		'hivecm8'					: { LabelShort : 'HIVECM8',						LabelMedium : 'HiveCM8',					LabelLong : 'Hive-CM8' },
		'hjs'						: { LabelShort : 'HJS',							LabelMedium : 'HJS',					LabelLong : 'HJS' },
		'hkd'						: { LabelShort : 'HKD',							LabelMedium : 'HKD',					LabelLong : 'HKD' },
		'hls'						: { LabelShort : 'HLS',							LabelMedium : 'HLS',					LabelLong : 'HLS' },
		'hm'							: { LabelShort : 'HM',							LabelMedium : 'HM',						LabelLong : 'HM' },
		'hn'							: { LabelShort : 'HN',							LabelMedium : 'HN',						LabelLong : 'HN' },
		'hnr'						: { LabelShort : 'HNR',							LabelMedium : 'HNR',					LabelLong : 'HNR' },
		'hodl'						: { LabelShort : 'HODL',						LabelMedium : 'HODL',					LabelLong : 'HODL' },
		'hoh'						: { LabelShort : 'HOH',							LabelMedium : 'HoH',					LabelLong : 'HoH' },
		'holiday'					: { LabelShort : 'HOLIDAY',						LabelMedium : 'HOLiDAY',					LabelLong : 'HOLiDAY' },
		'home'						: { LabelShort : 'HOME',						LabelMedium : 'HOME',					LabelLong : 'HOME' },
		'homefei'					: { LabelShort : 'HOMEFEI',						LabelMedium : 'homefei',					LabelLong : 'homefei' },
		'hon3y'						: { LabelShort : 'HON3Y',						LabelMedium : 'Hon3y',					LabelLong : 'Hon3y' },
		'hon3yhd'					: { LabelShort : 'HON3YHD',						LabelMedium : 'Hon3yHD',					LabelLong : 'Hon3yHD' },
		'hone'						: { LabelShort : 'HONE',						LabelMedium : 'HonE',					LabelLong : 'HonE' },
		'hoodbag'					: { LabelShort : 'HOODBAG',						LabelMedium : 'HoodBag',					LabelLong : 'HoodBag' },
		'hookah'					: { LabelShort : 'HOOKAH',						LabelMedium : 'HooKah',					LabelLong : 'HooKah' },
		'horizon'					: { LabelShort : 'HORIZON',						LabelMedium : 'HORiZON',					LabelLong : 'HORiZON' },
		'horizonartsubs'			: { LabelShort : 'HORIZONARTSUBS',				LabelMedium : 'HORiZONArtSubs',			LabelLong : 'HORiZON-ArtSubs' },
		'hornigold'					: { LabelShort : 'HORNIGOLD',					LabelMedium : 'Hornigold',				LabelLong : 'Hornigold' },
		'horriblesubs'				: { LabelShort : 'HORRIBLESUBS',				LabelMedium : 'HorribleSubs',			LabelLong : 'HorribleSubs' },
		'hostile'					: { LabelShort : 'HOSTILE',						LabelMedium : 'HOSTiLE',					LabelLong : 'HOSTiLE' },
		'hotlips'					: { LabelShort : 'HOTLIPS',						LabelMedium : 'HOTLiPS',					LabelLong : 'HOTLiPS' },
		'howl'						: { LabelShort : 'HOWL',						LabelMedium : 'HOWL',					LabelLong : 'HOWL' },
		'hp'							: { LabelShort : 'HP',							LabelMedium : 'HP',						LabelLong : 'HP' },
		'hq7'						: { LabelShort : 'HQ7',							LabelMedium : 'HQ7',					LabelLong : 'HQ7' },
		'hqclub'					: { LabelShort : 'HQCLUB',						LabelMedium : 'HQCLUB',					LabelLong : 'HQCLUB' },
		'hqe'						: { LabelShort : 'HQE',							LabelMedium : 'HQE',					LabelLong : 'HQE' },
		'hqm'						: { LabelShort : 'HQM',							LabelMedium : 'HQM',					LabelLong : 'HQM' },
		'hqx'						: { LabelShort : 'HQX',							LabelMedium : 'HQX',					LabelLong : 'HQX' },
		'hrdr'						: { LabelShort : 'HRDR',						LabelMedium : 'HRDR',					LabelLong : 'HR-DR' },
		'hrip'						: { LabelShort : 'HRIP',						LabelMedium : 'HRiP',					LabelLong : 'HRiP' },
		'hrs'						: { LabelShort : 'HRS',							LabelMedium : 'HRS',					LabelLong : 'HRS' },
		'hs'							: { LabelShort : 'HS',							LabelMedium : 'HS',						LabelLong : 'H-S' },
		'hubris'					: { LabelShort : 'HUBRIS',						LabelMedium : 'HUBRiS',					LabelLong : 'HUBRiS' },
		'hud'						: { LabelShort : 'HUD',							LabelMedium : 'HUD',					LabelLong : 'HUD' },
		'hunter'					: { LabelShort : 'HUNTER',						LabelMedium : 'HuNTER',					LabelLong : 'HuNTER' },
		'hurtom'					: { LabelShort : 'HURTOM',						LabelMedium : 'Hurtom',					LabelLong : 'Hurtom' },
		'hush'						: { LabelShort : 'HUSH',						LabelMedium : 'HuSh',					LabelLong : 'HuSh' },
		'hushrips'					: { LabelShort : 'HUSHRIPS',					LabelMedium : 'HushRips',				LabelLong : 'HushRips' },
		'huzzah'					: { LabelShort : 'HUZZAH',						LabelMedium : 'Huzzah',					LabelLong : 'Huzzah' },
		'hwd'						: { LabelShort : 'HWD',							LabelMedium : 'HWD',					LabelLong : 'HWD' },
		'hyb'						: { LabelShort : 'HYB',							LabelMedium : 'Hyb',					LabelLong : 'Hyb' },
		'hybrid'					: { LabelShort : 'HYBRID',						LabelMedium : 'HYBRiD',					LabelLong : 'HYBRiD' },
		'hybris'					: { LabelShort : 'HYBRIS',						LabelMedium : 'HYBRiS',					LabelLong : 'HYBRiS' },
		'hyde'						: { LabelShort : 'HYDE',						LabelMedium : 'HyDe',					LabelLong : 'HyDe' },
		'hype'						: { LabelShort : 'HYPE',						LabelMedium : 'HYPE',					LabelLong : 'HYPE' },
		'hz'							: { LabelShort : 'HZ',							LabelMedium : 'HZ',						LabelLong : 'HZ' },
		'iahd'						: { LabelShort : 'IAHD',						LabelMedium : 'iAHD',					LabelLong : 'iAHD' },
		'iamable'					: { LabelShort : 'IAMABLE',						LabelMedium : 'IAMABLE',					LabelLong : 'IAMABLE' },
		'ic'							: { LabelShort : 'IC',							LabelMedium : 'ic',						LabelLong : 'i_c' },
		'icandy'					: { LabelShort : 'ICANDY',						LabelMedium : 'iCANDY',					LabelLong : 'iCANDY' },
		'ice'						: { LabelShort : 'ICE',							LabelMedium : 'ICE',					LabelLong : 'ICE' },
		'icmal'						: { LabelShort : 'ICMAL',						LabelMedium : 'iCMAL',					LabelLong : 'iCMAL' },
		'icn'						: { LabelShort : 'ICN',							LabelMedium : 'icn',					LabelLong : 'icn' },
		'ico'						: { LabelShort : 'ICO',							LabelMedium : 'iCO',					LabelLong : 'iCO' },
		'ictv'						: { LabelShort : 'ICTV',						LabelMedium : 'IcTv',					LabelLong : 'IcTv' },
		'icvmircrew'					: { LabelShort : 'ICVMIRCREW',					LabelMedium : 'iCVMIRCrew',				LabelLong : 'iCV-MIRCrew' },
		'id'							: { LabelShort : 'ID',							LabelMedium : 'iD',						LabelLong : 'iD' },
		'ide'						: { LabelShort : 'IDE',							LabelMedium : 'IDE',					LabelLong : 'IDE' },
		'ideafilm'					: { LabelShort : 'IDEAFILM',					LabelMedium : 'IdeaFilm',				LabelLong : 'IdeaFilm' },
		'idncrew'					: { LabelShort : 'IDNCREW',						LabelMedium : 'iDNCreW',					LabelLong : 'iDN CreW' },
		'idtv'						: { LabelShort : 'IDTV',						LabelMedium : 'idTV',					LabelLong : 'idTV' },
		'iextv'						: { LabelShort : 'IEXTV',						LabelMedium : 'iExTV',					LabelLong : 'iExTV' },
		'ifh'						: { LabelShort : 'IFH',							LabelMedium : 'iFH',					LabelLong : 'iFH' },
		'iflix'						: { LabelShort : 'IFLIX',						LabelMedium : 'iFLiX',					LabelLong : 'iFLiX' },
		'ifn'						: { LabelShort : 'IFN',							LabelMedium : 'iFN',					LabelLong : 'iFN' },
		'ifpd'						: { LabelShort : 'IFPD',						LabelMedium : 'iFPD',					LabelLong : 'iFPD' },
		'ift'						: { LabelShort : 'IFT',							LabelMedium : 'iFT',					LabelLong : 'iFT' },
		'ig'							: { LabelShort : 'IG',							LabelMedium : 'iG',						LabelLong : 'iG' },
		'igd'						: { LabelShort : 'IGD',							LabelMedium : 'IGD',					LabelLong : 'IGD' },
		'ignite'					: { LabelShort : 'IGNITE',						LabelMedium : 'iGNiTE',					LabelLong : 'iGNiTE' },
		'ignition'					: { LabelShort : 'IGNITION',					LabelMedium : 'iGNiTiON',				LabelLong : 'iGNiTiON' },
		'iguana'					: { LabelShort : 'IGUANA',						LabelMedium : 'IGUANA',					LabelLong : 'IGUANA' },
		'ihd'						: { LabelShort : 'IHD',							LabelMedium : 'iHD',					LabelLong : 'iHD' },
		'iht'						: { LabelShort : 'IHT',							LabelMedium : 'iHT',					LabelLong : 'iHT' },
		'ika'						: { LabelShort : 'IKA',							LabelMedium : 'iKA',					LabelLong : 'iKA' },
		'ikaos'						: { LabelShort : 'IKAOS',						LabelMedium : 'iKaos',					LabelLong : 'iKaos' },
		'ikiw'						: { LabelShort : 'IKIW',						LabelMedium : 'iKiW',					LabelLong : 'iKiW' },
		'ila'						: { LabelShort : 'ILA',							LabelMedium : 'ILA',					LabelLong : 'ILA' },
		'ilg'						: { LabelShort : 'ILG',							LabelMedium : 'iLG',					LabelLong : 'iLG' },
		'ill'						: { LabelShort : 'ILL',							LabelMedium : 'iLL',					LabelLong : 'iLL' },
		'illusion'					: { LabelShort : 'ILLUSION',					LabelMedium : 'iLLUSiON',				LabelLong : 'iLLUSiON' },
		'ilovehd'					: { LabelShort : 'ILOVEHD',						LabelMedium : 'iLoveHD',					LabelLong : 'iLoveHD' },
		'ils'						: { LabelShort : 'ILS',							LabelMedium : 'iLS',					LabelLong : 'iLS' },
		'imacruel1'					: { LabelShort : 'IMACRUEL1',					LabelMedium : 'imacRuel1',				LabelLong : 'imacRuel1' },
		'imagine'					: { LabelShort : 'IMAGINE',						LabelMedium : 'iMAGiNE',					LabelLong : 'iMAGiNE' },
		'imax'						: { LabelShort : 'IMAX',						LabelMedium : 'iMaX',					LabelLong : 'iM@X' },
		'imbt'						: { LabelShort : 'IMBT',						LabelMedium : 'iMBT',					LabelLong : 'iMBT' },
		'imdths'					: { LabelShort : 'IMDTHS',						LabelMedium : 'IMDTHS',					LabelLong : 'IMDTHS' },
		'ime'						: { LabelShort : 'IME',							LabelMedium : 'ImE',					LabelLong : 'ImE' },
		'immerse'					: { LabelShort : 'IMMERSE',						LabelMedium : 'IMMERSE',					LabelLong : 'IMMERSE' },
		'immortals'					: { LabelShort : 'IMMORTALS',					LabelMedium : 'iMMORTALs',				LabelLong : 'iMMORTALs' },
		'imp3rial'					: { LabelShort : 'IMP3RIAL',					LabelMedium : 'iMP3RiAL',				LabelLong : 'iMP3RiAL' },
		'imperium'					: { LabelShort : 'IMPERIUM',					LabelMedium : 'iMPERiUM',				LabelLong : 'iMPERiUM' },
		'imposters'					: { LabelShort : 'IMPOSTERS',					LabelMedium : 'IMPOSTERS',				LabelLong : 'IMPOSTERS' },
		'imsamirofficial'			: { LabelShort : 'IMSAMIROFFICIAL',				LabelMedium : 'imSamirOFFICIAL',			LabelLong : 'imSamirOFFICIAL' },
		'imsorny'					: { LabelShort : 'IMSORNY',						LabelMedium : 'iMSORNY',					LabelLong : 'iMSORNY' },
		'inam'						: { LabelShort : 'INAM',						LabelMedium : 'INaM',					LabelLong : 'INaM' },
		'inception'					: { LabelShort : 'INCEPTION',					LabelMedium : 'iNCEPTiON',				LabelLong : 'iNCEPTiON' },
		'incite'					: { LabelShort : 'INCITE',						LabelMedium : 'iNCiTE',					LabelLong : 'iNCiTE' },
		'incognito'					: { LabelShort : 'INCOGNITO',					LabelMedium : 'iNCOGNiTO',				LabelLong : 'iNCOGNiTO' },
		'ind'						: { LabelShort : 'IND',							LabelMedium : 'iND',					LabelLong : 'iND' },
		'infamous'					: { LabelShort : 'INFAMOUS',					LabelMedium : 'iNFAMOUS',				LabelLong : 'iNFAMOUS' },
		'inferno'					: { LabelShort : 'INFERNO',						LabelMedium : 'INFERNO',					LabelLong : 'INFERNO' },
		'infotv'					: { LabelShort : 'INFOTV',						LabelMedium : 'iNFOtv',					LabelLong : 'iNFOtv' },
		'ingot'						: { LabelShort : 'INGOT',						LabelMedium : 'iNGOT',					LabelLong : 'iNGOT' },
		'inject'					: { LabelShort : 'INJECT',						LabelMedium : 'iNjECT',					LabelLong : 'iNjECT' },
		'ink'						: { LabelShort : 'INK',							LabelMedium : 'iNK',					LabelLong : 'iNK' },
		'inklusion'					: { LabelShort : 'INKLUSION',					LabelMedium : 'iNKLUSiON',				LabelLong : 'iNKLUSiON' },
		'innocence'					: { LabelShort : 'INNOCENCE',					LabelMedium : 'INNOCENCE',				LabelLong : 'INNOCENCE' },
		'inp'						: { LabelShort : 'INP',							LabelMedium : 'INP',					LabelLong : 'INP' },
		'insanity'					: { LabelShort : 'INSANITY',					LabelMedium : 'InSaNiTy',				LabelLong : 'InSaNiTy' },
		'insects'					: { LabelShort : 'INSECTS',						LabelMedium : 'iNSECTS',					LabelLong : 'iNSECTS' },
		'insidious'					: { LabelShort : 'INSIDIOUS',					LabelMedium : 'iNSIDiOUS',				LabelLong : 'iNSIDiOUS' },
		'inspiral'					: { LabelShort : 'INSPIRAL',					LabelMedium : 'INSPIRAL',				LabelLong : 'INSPIRAL' },
		'inspired'					: { LabelShort : 'INSPIRED',					LabelMedium : 'iNSPiRED',				LabelLong : 'iNSPiRED' },
		'inspirit'					: { LabelShort : 'INSPIRIT',					LabelMedium : 'iNSPiRiT',				LabelLong : 'iNSPiRiT' },
		'int'						: { LabelShort : 'INT',							LabelMedium : 'iNT',					LabelLong : 'iNT' },
		'intenso'					: { LabelShort : 'INTENSO',						LabelMedium : 'iNTENSO',					LabelLong : 'iNTENSO' },
		'intention'					: { LabelShort : 'INTENTION',					LabelMedium : 'iNTENTiON',				LabelLong : 'iNTENTiON' },
		'intgrity'					: { LabelShort : 'INTGRITY',					LabelMedium : 'inTGrity',				LabelLong : 'inTGrity' },
		'intimid'					: { LabelShort : 'INTIMID',						LabelMedium : 'iNTiMiD',					LabelLong : 'iNTiMiD' },
		'invaders'					: { LabelShort : 'INVADERS',					LabelMedium : 'iNVADERS',				LabelLong : 'iNVADERS' },
		'invandraren'				: { LabelShort : 'INVANDRAREN',					LabelMedium : 'iNVANDRAREN',			LabelLong : 'iNVANDRAREN' },
		'invictus'					: { LabelShort : 'INVICTUS',					LabelMedium : 'INVICTUS',				LabelLong : 'INVICTUS' },
		'invincible'					: { LabelShort : 'INVINCIBLE',					LabelMedium : 'Invincible',				LabelLong : '~Invincible' },
		'ion'						: { LabelShort : 'ION',							LabelMedium : 'iON',					LabelLong : 'iON' },
		'ion10'						: { LabelShort : 'ION10',						LabelMedium : 'ION10',					LabelLong : 'ION10' },
		'ion265'					: { LabelShort : 'ION265',						LabelMedium : 'ION265',					LabelLong : 'ION265' },
		'iplayertv'					: { LabelShort : 'IPLAYERTV',					LabelMedium : 'iPlayerTV',				LabelLong : 'iPlayerTV' },
		'ipt'						: { LabelShort : 'IPT',							LabelMedium : 'IPT',					LabelLong : 'IPT' },
		'ism'						: { LabelShort : 'ISM',							LabelMedium : 'iSm',					LabelLong : 'iSm' },
		'istance'					: { LabelShort : 'ISTANCE',						LabelMedium : 'iSTANCE',					LabelLong : 'iSTANCE' },
		'isubs'						: { LabelShort : 'ISUBS',						LabelMedium : 'iSUBS',					LabelLong : 'iSUBS' },
		'it00nz'					: { LabelShort : 'IT00NZ',						LabelMedium : 'iT00NZ',					LabelLong : 'iT00NZ' },
		'itg'						: { LabelShort : 'ITG',							LabelMedium : 'ITG',					LabelLong : 'ITG' },
		'itsat'						: { LabelShort : 'ITSAT',						LabelMedium : 'ITSat',					LabelLong : 'ITSat' },
		'itz'						: { LabelShort : 'ITZ',							LabelMedium : 'ITZ',					LabelLong : 'ITZ' },
		'iy'							: { LabelShort : 'IY',							LabelMedium : 'IY',						LabelLong : 'IY' },
		'j4f'						: { LabelShort : 'J4F',							LabelMedium : 'J4F',					LabelLong : 'J4F' },
		'jackal'					: { LabelShort : 'JACKAL',						LabelMedium : 'JACKAL',					LabelLong : 'JACKAL' },
		'jackie'					: { LabelShort : 'JACKIE',						LabelMedium : 'jackie',					LabelLong : 'jackie' },
		'jade'						: { LabelShort : 'JADE',						LabelMedium : 'JADE',					LabelLong : 'JADE' },
		'jah'						: { LabelShort : 'JAH',							LabelMedium : 'jAh',					LabelLong : 'jAh' },
		'jam'						: { LabelShort : 'JAM',							LabelMedium : 'JAM',					LabelLong : 'JAM' },
		'jane'						: { LabelShort : 'JANE',						LabelMedium : 'JANE',					LabelLong : 'JANE' },
		'janedoe'					: { LabelShort : 'JANEDOE',						LabelMedium : 'JaneDoe',					LabelLong : 'JaneDoe' },
		'japhson'					: { LabelShort : 'JAPHSON',						LabelMedium : 'JAPHSON',					LabelLong : 'JAPHSON' },
		'jaskier'					: { LabelShort : 'JASKIER',						LabelMedium : 'Jaskier',					LabelLong : 'Jaskier' },
		'jason28'					: { LabelShort : 'JASON28',						LabelMedium : 'Jason28',					LabelLong : 'Jason28' },
		'jasperp'					: { LabelShort : 'JASPERP',						LabelMedium : 'JASPERP',					LabelLong : 'JASPERP' },
		'jass'						: { LabelShort : 'JASS',						LabelMedium : 'JASS',					LabelLong : 'JASS' },
		'jato'						: { LabelShort : 'JATO',						LabelMedium : 'JATO',					LabelLong : 'JATO' },
		'jatt'						: { LabelShort : 'JATT',						LabelMedium : 'JATT',					LabelLong : 'JATT' },
		'jaybob'					: { LabelShort : 'JAYBOB',						LabelMedium : 'Jaybob',					LabelLong : 'Jaybob' },
		'jbs'						: { LabelShort : 'JBS',							LabelMedium : 'JBS',					LabelLong : 'JBS' },
		'jcgoku21'					: { LabelShort : 'JCGOKU21',					LabelMedium : 'JcGoku21',				LabelLong : 'JcGoku21' },
		'jch'						: { LabelShort : 'JCH',							LabelMedium : 'JCH',					LabelLong : 'JCH' },
		'jebaited'					: { LabelShort : 'JEBAITED',					LabelMedium : 'JEBAITED',				LabelLong : 'JEBAITED' },
		'jedi'						: { LabelShort : 'JEDI',						LabelMedium : 'jedi',					LabelLong : 'jedi' },
		'jellybean'					: { LabelShort : 'JELLYBEAN',					LabelMedium : 'JellyBean',				LabelLong : 'JellyBean' },
		'jester'					: { LabelShort : 'JESTER',						LabelMedium : 'JESTER',					LabelLong : 'JESTER' },
		'jetix'						: { LabelShort : 'JETIX',						LabelMedium : 'JETIX',					LabelLong : 'JETIX' },
		'jetset'					: { LabelShort : 'JETSET',						LabelMedium : 'JETSET',					LabelLong : 'JETSET' },
		'jew'						: { LabelShort : 'JEW',							LabelMedium : 'JEW',					LabelLong : 'JEW' },
		'jfkdvd'					: { LabelShort : 'JFKDVD',						LabelMedium : 'JFKDVD',					LabelLong : 'JFKDVD' },
		'jfkxvid'					: { LabelShort : 'JFKXVID',						LabelMedium : 'JFKXVID',					LabelLong : 'JFKXVID' },
		'jhonny2'					: { LabelShort : 'JHONNY2',						LabelMedium : 'jhonny2',					LabelLong : 'jhonny2' },
		'jitb'						: { LabelShort : 'JITB',						LabelMedium : 'JiTB',					LabelLong : 'JiTB' },
		'jive'						: { LabelShort : 'JIVE',						LabelMedium : 'JIVE',					LabelLong : 'JIVE' },
		'jj'							: { LabelShort : 'JJ',							LabelMedium : 'JJ',						LabelLong : 'JJ' },
		'jm'							: { LabelShort : 'JM',							LabelMedium : 'JM',						LabelLong : 'JM' },
		'jmt'						: { LabelShort : 'JMT',							LabelMedium : 'JMT',					LabelLong : 'JMT' },
		'jolly'						: { LabelShort : 'JOLLY',						LabelMedium : 'JOLLY',					LabelLong : 'JOLLY' },
		'jollyroger'					: { LabelShort : 'JOLLYROGER',					LabelMedium : 'JoLLyRoGeR',				LabelLong : 'JoLLyRoGeR' },
		'joy'						: { LabelShort : 'JOY',							LabelMedium : 'JOY',					LabelLong : 'JOY' },
		'jrr'						: { LabelShort : 'JRR',							LabelMedium : 'JRR',					LabelLong : 'JRR' },
		'jtv'						: { LabelShort : 'JTV',							LabelMedium : 'jTV',					LabelLong : 'jTV' },
		'judas'						: { LabelShort : 'JUDAS',						LabelMedium : 'Judas',					LabelLong : 'Judas' },
		'judgement'					: { LabelShort : 'JUDGEMENT',					LabelMedium : 'JUDGEMENT',				LabelLong : 'JUDGEMENT' },
		'juggalotus'					: { LabelShort : 'JUGGALOTUS',					LabelMedium : 'Juggalotus',				LabelLong : 'Juggalotus' },
		'juggs'						: { LabelShort : 'JUGGS',						LabelMedium : 'JUGGS',					LabelLong : 'JUGGS' },
		'jumanji'					: { LabelShort : 'JUMANJI',						LabelMedium : 'JUMANJi',					LabelLong : 'JUMANJi' },
		'junoon'					: { LabelShort : 'JUNOON',						LabelMedium : 'Junoon',					LabelLong : 'Junoon' },
		'just4fun'					: { LabelShort : 'JUST4FUN',					LabelMedium : 'Just4fun',				LabelLong : 'Just4fun' },
		'justhd'					: { LabelShort : 'JUSTHD',						LabelMedium : 'JustHD',					LabelLong : 'JustHD' },
		'justin'					: { LabelShort : 'JUSTIN',						LabelMedium : 'JusTiN',					LabelLong : 'JusTiN' },
		'justiso'					: { LabelShort : 'JUSTISO',						LabelMedium : 'Justiso',					LabelLong : 'Justiso' },
		'justwatch'					: { LabelShort : 'JUSTWATCH',					LabelMedium : 'JustWatch',				LabelLong : 'JustWatch' },
		'jvc'						: { LabelShort : 'JVC',							LabelMedium : 'JVC',					LabelLong : 'JVC' },
		'jyk'						: { LabelShort : 'JYK',							LabelMedium : 'JYK',					LabelLong : 'JYK' },
		'k2'							: { LabelShort : 'K2',							LabelMedium : 'k2',						LabelLong : 'k2' },
		'kaf'						: { LabelShort : 'KAF',							LabelMedium : 'KAF',					LabelLong : 'KAF' },
		'kafferep'					: { LabelShort : 'KAFFEREP',					LabelMedium : 'KAFFEREP',				LabelLong : 'KAFFEREP' },
		'kaga'						: { LabelShort : 'KAGA',						LabelMedium : 'KAGA',					LabelLong : 'KAGA' },
		'kaidubs'					: { LabelShort : 'KAIDUBS',						LabelMedium : 'KaiDubs',					LabelLong : 'KaiDubs' },
		'kaizen'					: { LabelShort : 'KAIZEN',						LabelMedium : 'KAIZEN',					LabelLong : 'KAIZEN' },
		'kaka'						: { LabelShort : 'KAKA',						LabelMedium : 'KaKa',					LabelLong : 'KaKa' },
		'kalipso'					: { LabelShort : 'KALIPSO',						LabelMedium : 'KALiPSO',					LabelLong : 'KALiPSO' },
		'kamera'					: { LabelShort : 'KAMERA',						LabelMedium : 'KAMERA',					LabelLong : 'KAMERA' },
		'kamikaze'					: { LabelShort : 'KAMIKAZE',					LabelMedium : 'KAMIKAZE',				LabelLong : 'KAMIKAZE' },
		'kappa'						: { LabelShort : 'KAPPA',						LabelMedium : 'Kappa',					LabelLong : 'Kappa' },
		'kart3ldvd'					: { LabelShort : 'KART3LDVD',					LabelMedium : 'KART3LDVD',				LabelLong : 'KART3LDVD' },
		'kas'						: { LabelShort : 'KAS',							LabelMedium : 'KAS',					LabelLong : 'KAS' },
		'kashmir'					: { LabelShort : 'KASHMIR',						LabelMedium : 'KASHMiR',					LabelLong : 'KASHMiR' },
		'kata'						: { LabelShort : 'KATA',						LabelMedium : 'KATA',					LabelLong : 'KATA' },
		'kate'						: { LabelShort : 'KATE',						LabelMedium : 'KaTe',					LabelLong : 'KaTe' },
		'katmaster'					: { LabelShort : 'KATMASTER',					LabelMedium : 'KatMaster',				LabelLong : 'KatMaster' },
		'katmoviehd'					: { LabelShort : 'KATMOVIEHD',					LabelMedium : 'KatmovieHD',				LabelLong : 'KatmovieHD' },
		'kazan'						: { LabelShort : 'KAZAN',						LabelMedium : 'KAZAN',					LabelLong : 'KAZAN' },
		'keaton'					: { LabelShort : 'KEATON',						LabelMedium : 'KEATON',					LabelLong : 'KEATON' },
		'keg'						: { LabelShort : 'KEG',							LabelMedium : 'KEG',					LabelLong : 'KEG' },
		'keltz'						: { LabelShort : 'KELTZ',						LabelMedium : 'keltz',					LabelLong : 'keltz' },
		'kerob'						: { LabelShort : 'KEROB',						LabelMedium : 'Kerob',					LabelLong : 'Kerob' },
		'kesh'						: { LabelShort : 'KESH',						LabelMedium : 'KESH',					LabelLong : 'KESH' },
		'kettle'					: { LabelShort : 'KETTLE',						LabelMedium : 'KETTLE',					LabelLong : 'KETTLE' },
		'kf'							: { LabelShort : 'KF',							LabelMedium : 'KF',						LabelLong : 'K-F' },
		'kg'							: { LabelShort : 'KG',							LabelMedium : 'KG',						LabelLong : 'KG' },
		'kh'							: { LabelShort : 'KH',							LabelMedium : 'KH',						LabelLong : 'KH' },
		'khn'						: { LabelShort : 'KHN',							LabelMedium : 'KHN',					LabelLong : 'KHN' },
		'khoshmard'					: { LabelShort : 'KHOSHMARD',					LabelMedium : 'khoshmard',				LabelLong : 'khoshmard' },
		'khp'						: { LabelShort : 'KHP',							LabelMedium : 'KHP',					LabelLong : 'KHP' },
		'kickass'					: { LabelShort : 'KICKASS',						LabelMedium : 'kickass',					LabelLong : 'kickass' },
		'kickfoot'					: { LabelShort : 'KICKFOOT',					LabelMedium : 'KickFoot',				LabelLong : 'KickFoot' },
		'kickoff'					: { LabelShort : 'KICKOFF',						LabelMedium : 'KICKOFF',					LabelLong : 'KICKOFF' },
		'kid'						: { LabelShort : 'KID',							LabelMedium : 'KiD',					LabelLong : 'KiD' },
		'killers'					: { LabelShort : 'KILLERS',						LabelMedium : 'KILLERS',					LabelLong : 'KILLERS' },
		'kimchi'					: { LabelShort : 'KIMCHI',						LabelMedium : 'KiMCHi',					LabelLong : 'KiMCHi' },
		'kingdom'					: { LabelShort : 'KINGDOM',						LabelMedium : 'KINGDOM',					LabelLong : 'KINGDOM' },
		'kingmaker'					: { LabelShort : 'KINGMAKER',					LabelMedium : 'Kingmaker',				LabelLong : 'Kingmaker' },
		'kings'						: { LabelShort : 'KINGS',						LabelMedium : 'KiNGS',					LabelLong : 'KiNGS' },
		'kingstoner'					: { LabelShort : 'KINGSTONER',					LabelMedium : 'KingStoner',				LabelLong : 'KingStoner' },
		'kinowelt'					: { LabelShort : 'KINOWELT',					LabelMedium : 'KiNOWELT',				LabelLong : 'KiNOWELT' },
		'kir4'						: { LabelShort : 'KIR4',						LabelMedium : 'KIR4',					LabelLong : 'KIR4' },
		'kira'						: { LabelShort : 'KIRA',						LabelMedium : 'Kira',					LabelLong : 'Kira' },
		'kirklestat'					: { LabelShort : 'KIRKLESTAT',					LabelMedium : 'kirklestat',				LabelLong : 'kirklestat' },
		'kiss'						: { LabelShort : 'KISS',						LabelMedium : 'KiSS',					LabelLong : 'KiSS' },
		'kit'						: { LabelShort : 'KIT',							LabelMedium : 'KiT',					LabelLong : 'KiT' },
		'kiyoshistar'				: { LabelShort : 'KIYOSHISTAR',					LabelMedium : 'KiyoshiStar',			LabelLong : 'KiyoshiStar' },
		'kk650'						: { LabelShort : 'KK650',						LabelMedium : 'KK650',					LabelLong : 'KK650' },
		'klassigerhd'				: { LabelShort : 'KLASSIGERHD',					LabelMedium : 'KLASSiGERHD',			LabelLong : 'KLASSiGERHD' },
		'klaxxon'					: { LabelShort : 'KLAXXON',						LabelMedium : 'KLAXXON',					LabelLong : 'KLAXXON' },
		'klingon'					: { LabelShort : 'KLINGON',						LabelMedium : 'KLINGON',					LabelLong : 'KLINGON' },
		'klio'						: { LabelShort : 'KLIO',						LabelMedium : 'KLiO',					LabelLong : 'KLiO' },
		'km'							: { LabelShort : 'KM',							LabelMedium : 'km',						LabelLong : 'km' },
		'knifesharp'					: { LabelShort : 'KNIFESHARP',					LabelMedium : 'knifesharp',				LabelLong : 'knifesharp' },
		'knp'						: { LabelShort : 'KNP',							LabelMedium : 'KNP',					LabelLong : 'KNP' },
		'koalf'						: { LabelShort : 'KOALF',						LabelMedium : 'koalf',					LabelLong : 'koalf' },
		'koc'						: { LabelShort : 'KOC',							LabelMedium : 'KOC',					LabelLong : 'KOC' },
		'koenig'					: { LabelShort : 'KOENIG',						LabelMedium : 'KOENiG',					LabelLong : 'KOENiG' },
		'kogi'						: { LabelShort : 'KOGI',						LabelMedium : 'KOGi',					LabelLong : 'KOGi' },
		'kole'						: { LabelShort : 'KOLE',						LabelMedium : 'KOLE',					LabelLong : 'KOLE' },
		'kompost'					: { LabelShort : 'KOMPOST',						LabelMedium : 'KOMPOST',					LabelLong : 'KOMPOST' },
		'konzillarg'					: { LabelShort : 'KONZILLARG',					LabelMedium : 'KonzillaRG',				LabelLong : 'KonzillaRG' },
		'kookoo'					: { LabelShort : 'KOOKOO',						LabelMedium : 'KooKoo',					LabelLong : 'KooKoo' },
		'korsar'					: { LabelShort : 'KORSAR',						LabelMedium : 'KORSAR',					LabelLong : 'KORSAR' },
		'koshara'					: { LabelShort : 'KOSHARA',						LabelMedium : 'KOSHARA',					LabelLong : 'KOSHARA' },
		'kotuwa'					: { LabelShort : 'KOTUWA',						LabelMedium : 'KoTuWa',					LabelLong : 'KoTuWa' },
		'koyumu'					: { LabelShort : 'KOYUMU',						LabelMedium : 'Koyumu',					LabelLong : 'Koyumu' },
		'kralimarko'					: { LabelShort : 'KRALIMARKO',					LabelMedium : 'KRaLiMaRKo',				LabelLong : 'KRaLiMaRKo' },
		'krave'						: { LabelShort : 'KRAVE',						LabelMedium : 'KRAVE',					LabelLong : 'KRAVE' },
		'krissz'					: { LabelShort : 'KRISSZ',						LabelMedium : 'Krissz',					LabelLong : 'Krissz' },
		'kristallprinz'				: { LabelShort : 'KRISTALLPRINZ',				LabelMedium : 'Kristallprinz',			LabelLong : 'Kristallprinz' },
		'kronos'					: { LabelShort : 'KRONOS',						LabelMedium : 'Kronos',					LabelLong : 'Kronos' },
		'krs'						: { LabelShort : 'KRS',							LabelMedium : 'KRS',					LabelLong : 'KRS' },
		'kuchikirukia'				: { LabelShort : 'KUCHIKIRUKIA',				LabelMedium : 'kuchikirukia',			LabelLong : 'kuchikirukia' },
		'kuth'						: { LabelShort : 'KUTH',						LabelMedium : 'KUTH',					LabelLong : 'KUTH' },
		'kyr'						: { LabelShort : 'KYR',							LabelMedium : 'KYR',					LabelLong : 'KYR' },
		'kz'							: { LabelShort : 'KZ',							LabelMedium : 'KZ',						LabelLong : 'K-Z' },
		'l0l'						: { LabelShort : 'L0L',							LabelMedium : 'L0L',					LabelLong : 'L0L' },
		'ladybug'					: { LabelShort : 'LADYBUG',						LabelMedium : 'LADYBUG',					LabelLong : 'LADYBUG' },
		'lako'						: { LabelShort : 'LAKO',						LabelMedium : 'LAKO',					LabelLong : 'LAKO' },
		'lamb'						: { LabelShort : 'LAMB',						LabelMedium : 'LamB',					LabelLong : 'LamB' },
		'lame'						: { LabelShort : 'LAME',						LabelMedium : 'LaMe',					LabelLong : 'LaMe' },
		'lamehd'					: { LabelShort : 'LAMEHD',						LabelMedium : 'LameHD',					LabelLong : 'LameHD' },
		'lamexd'					: { LabelShort : 'LAMEXD',						LabelMedium : 'LameXD',					LabelLong : 'LameXD' },
		'langbard'					: { LabelShort : 'LANGBARD',					LabelMedium : 'Langbard',				LabelLong : 'Langbard' },
		'lap'						: { LabelShort : 'LAP',							LabelMedium : 'LAP',					LabelLong : 'LAP' },
		'lapumia'					: { LabelShort : 'LAPUMIA',						LabelMedium : 'LAPUMiA',					LabelLong : 'LAPUMiA' },
		'lapumiafilmes'				: { LabelShort : 'LAPUMIAFILMES',				LabelMedium : 'LAPUMiAFiLMES',			LabelLong : 'LAPUMiAFiLMES' },
		'larceny'					: { LabelShort : 'LARCENY',						LabelMedium : 'LARCENY',					LabelLong : 'LARCENY' },
		'lard'						: { LabelShort : 'LARD',						LabelMedium : 'LARD',					LabelLong : 'LARD' },
		'latency'					: { LabelShort : 'LATENCY',						LabelMedium : 'LATENCY',					LabelLong : 'LATENCY' },
		'law'						: { LabelShort : 'LAW',							LabelMedium : 'LAW',					LabelLong : 'LAW' },
		'lazarus'					: { LabelShort : 'LAZARUS',						LabelMedium : 'LAZARUS',					LabelLong : 'LAZARUS' },
		'lazers'					: { LabelShort : 'LAZERS',						LabelMedium : 'LAZERS',					LabelLong : 'LAZERS' },
		'lazy'						: { LabelShort : 'LAZY',						LabelMedium : 'LAZY',					LabelLong : 'LAZY' },
		'lb'							: { LabelShort : 'LB',							LabelMedium : 'LB',						LabelLong : 'LB' },
		'lbr'						: { LabelShort : 'LBR',							LabelMedium : 'LBR',					LabelLong : 'LBR' },
		'lchd'						: { LabelShort : 'LCHD',						LabelMedium : 'LCHD',					LabelLong : 'LCHD' },
		'lds'						: { LabelShort : 'LDS',							LabelMedium : 'LDS',					LabelLong : 'LDS' },
		'le'							: { LabelShort : 'LE',							LabelMedium : 'LE',						LabelLong : 'L-E' },
		'lee'						: { LabelShort : 'LEE',							LabelMedium : 'Lee',					LabelLong : 'Lee' },
		'leetay'					: { LabelShort : 'LEETAY',						LabelMedium : 'leetay',					LabelLong : 'leetay' },
		'leethd'					: { LabelShort : 'LEETHD',						LabelMedium : 'LeetHD',					LabelLong : 'LeetHD' },
		'leetxd'					: { LabelShort : 'LEETXD',						LabelMedium : 'LeetXD',					LabelLong : 'LeetXD' },
		'legend'					: { LabelShort : 'LEGEND',						LabelMedium : 'LEGEND',					LabelLong : 'LEGEND' },
		'legi0n'					: { LabelShort : 'LEGI0N',						LabelMedium : 'LEGi0N',					LabelLong : 'LEGi0N' },
		'legion'					: { LabelShort : 'LEGION',						LabelMedium : 'LEGiON',					LabelLong : 'LEGiON' },
		'leon'						: { LabelShort : 'LEON',						LabelMedium : 'LeON',					LabelLong : 'LeON' },
		'leonardo'					: { LabelShort : 'LEONARDO',					LabelMedium : 'LEONARDO',				LabelLong : 'LEONARDO' },
		'leralouf'					: { LabelShort : 'LERALOUF',					LabelMedium : 'LeRalouf',				LabelLong : 'LeRalouf' },
		'lesnick'					: { LabelShort : 'LESNICK',						LabelMedium : 'Lesnick',					LabelLong : 'Lesnick' },
		'leverage'					: { LabelShort : 'LEVERAGE',					LabelMedium : 'LEVERAGE',				LabelLong : 'LEVERAGE' },
		'lf'							: { LabelShort : 'LF',							LabelMedium : 'LF',						LabelLong : 'L-F' },
		'lff'						: { LabelShort : 'LFF',							LabelMedium : 'LFF',					LabelLong : 'LFF' },
		'lgc'						: { LabelShort : 'LGC',							LabelMedium : 'LGC',					LabelLong : 'LGC' },
		'liberty'					: { LabelShort : 'LIBERTY',						LabelMedium : 'LiBERTY',					LabelLong : 'LiBERTY' },
		'librarians'					: { LabelShort : 'LIBRARIANS',					LabelMedium : 'LiBRARiANS',				LabelLong : 'LiBRARiANS' },
		'liebehd'					: { LabelShort : 'LIEBEHD',						LabelMedium : 'LiebeHD',					LabelLong : 'LiebeHD' },
		'lifetime'					: { LabelShort : 'LIFETIME',					LabelMedium : 'LIFETIME',				LabelLong : 'LIFETIME' },
		'ligate'					: { LabelShort : 'LIGATE',						LabelMedium : 'LiGATE',					LabelLong : 'LiGATE' },
		'lightspeed'					: { LabelShort : 'LIGHTSPEED',					LabelMedium : 'LiGHTSPEED',				LabelLong : 'LiGHTSPEED' },
		'lime'						: { LabelShort : 'LIME',						LabelMedium : 'LIME',					LabelLong : 'LIME' },
		'ling'						: { LabelShort : 'LING',						LabelMedium : 'LiNG',					LabelLong : 'LiNG' },
		'linkle'					: { LabelShort : 'LINKLE',						LabelMedium : 'LiNKLE',					LabelLong : 'LiNKLE' },
		'lion'						: { LabelShort : 'LION',						LabelMedium : 'LiON',					LabelLong : 'LiON' },
		'lipan'						: { LabelShort : 'LIPAN',						LabelMedium : 'LiPAN',					LabelLong : 'LiPAN' },
		'lite'						: { LabelShort : 'LITE',						LabelMedium : 'LiTE',					LabelLong : 'LiTE' },
		'littledevil'				: { LabelShort : 'LITTLEDEVIL',					LabelMedium : 'littledevil',			LabelLong : 'little_devil' },
		'lividity'					: { LabelShort : 'LIVIDITY',					LabelMedium : 'LiViDiTY',				LabelLong : 'LiViDiTY' },
		'lizardsquad'				: { LabelShort : 'LIZARDSQUAD',					LabelMedium : 'LizardSquad',			LabelLong : 'LizardSquad' },
		'lkrg'						: { LabelShort : 'LKRG',						LabelMedium : 'LKRG',					LabelLong : 'LKRG' },
		'llg'						: { LabelShort : 'LLG',							LabelMedium : 'LLG',					LabelLong : 'LLG' },
		'lmao'						: { LabelShort : 'LMAO',						LabelMedium : 'LMAO',					LabelLong : 'LMAO' },
		'lmg'						: { LabelShort : 'LMG',							LabelMedium : 'LMG',					LabelLong : 'LMG' },
		'lmk'						: { LabelShort : 'LMK',							LabelMedium : 'LMK',					LabelLong : 'LMK' },
		'lnt'						: { LabelShort : 'LNT',							LabelMedium : 'LNT',					LabelLong : 'LNT' },
		'lod'						: { LabelShort : 'LOD',							LabelMedium : 'LoD',					LabelLong : 'LoD' },
		'lok'						: { LabelShort : 'LOK',							LabelMedium : 'LOK',					LabelLong : 'LOK' },
		'loki'						: { LabelShort : 'LOKI',						LabelMedium : 'LoKI',					LabelLong : 'LoKI' },
		'lokihd'					: { LabelShort : 'LOKIHD',						LabelMedium : 'LOKiHD',					LabelLong : 'LOKiHD' },
		'lol'						: { LabelShort : 'LOL',							LabelMedium : 'LOL',					LabelLong : 'LOL' },
		'lolhd'						: { LabelShort : 'LOLHD',						LabelMedium : 'LoLHD',					LabelLong : 'LoLHD' },
		'lonewolf'					: { LabelShort : 'LONEWOLF',					LabelMedium : 'LoneWolf',				LabelLong : 'LoneWolf' },
		'lookmane'					: { LabelShort : 'LOOKMANE',					LabelMedium : 'LooKMaNe',				LabelLong : 'LooKMaNe' },
		'lord'						: { LabelShort : 'LORD',						LabelMedium : 'LoRD',					LabelLong : 'LoRD' },
		'lordvako'					: { LabelShort : 'LORDVAKO',					LabelMedium : 'LordVako',				LabelLong : 'LordVako' },
		'lost'						: { LabelShort : 'LOST',						LabelMedium : 'LOST',					LabelLong : 'LOST' },
		'lostfilm'					: { LabelShort : 'LOSTFILM',					LabelMedium : 'LostFilm',				LabelLong : 'LostFilm' },
		'lostyears'					: { LabelShort : 'LOSTYEARS',					LabelMedium : 'LostYears',				LabelLong : 'LostYears' },
		'lot'						: { LabelShort : 'LOT',							LabelMedium : 'LoT',					LabelLong : 'LoT' },
		'lotv'						: { LabelShort : 'LOTV',						LabelMedium : 'LoTV',					LabelLong : 'LoTV' },
		'lounge'					: { LabelShort : 'LOUNGE',						LabelMedium : 'LOUNGE',					LabelLong : 'LOUNGE' },
		'love'						: { LabelShort : 'LOVE',						LabelMedium : 'lOVE',					LabelLong : 'lOVE' },
		'lovehd'					: { LabelShort : 'LOVEHD',						LabelMedium : 'LoveHD',					LabelLong : 'LoveHD' },
		'loverulz'					: { LabelShort : 'LOVERULZ',					LabelMedium : 'LoveRulz',				LabelLong : 'Love Rulz' },
		'lovesick'					: { LabelShort : 'LOVESICK',					LabelMedium : 'LOVESICK',				LabelLong : 'LOVESICK' },
		'lp'							: { LabelShort : 'LP',							LabelMedium : 'LP',						LabelLong : 'LP' },
		'lpd'						: { LabelShort : 'LPD',							LabelMedium : 'LPD',					LabelLong : 'LPD' },
		'lrc'						: { LabelShort : 'LRC',							LabelMedium : 'lrc',					LabelLong : 'lrc' },
		'ls'							: { LabelShort : 'LS',							LabelMedium : 'LS',						LabelLong : 'L-S' },
		'lse'						: { LabelShort : 'LSE',							LabelMedium : 'LsE',					LabelLong : 'LsE' },
		'ltn'						: { LabelShort : 'LTN',							LabelMedium : 'LTN',					LabelLong : 'LTN' },
		'ltrg'						: { LabelShort : 'LTRG',						LabelMedium : 'LTRG',					LabelLong : 'LTRG' },
		'ltt'						: { LabelShort : 'LTT',							LabelMedium : 'LTT',					LabelLong : 'LTT' },
		'ltu'						: { LabelShort : 'LTU',							LabelMedium : 'LTU',					LabelLong : 'LTU' },
		'lucidtv'					: { LabelShort : 'LUCIDTV',						LabelMedium : 'LucidTV',					LabelLong : 'LucidTV' },
		'lucifer22'					: { LabelShort : 'LUCIFER22',					LabelMedium : 'Lucifer22',				LabelLong : 'Lucifer22' },
		'lulz'						: { LabelShort : 'LULZ',						LabelMedium : 'lulz',					LabelLong : 'lulz' },
		'lum1x'						: { LabelShort : 'LUM1X',						LabelMedium : 'Lum1x',					LabelLong : 'Lum1x' },
		'lumi'						: { LabelShort : 'LUMI',						LabelMedium : 'LUMI',					LabelLong : 'LUMI' },
		'lunar'						: { LabelShort : 'LUNAR',						LabelMedium : 'LUNAR',					LabelLong : 'LUNAR' },
		'lund'						: { LabelShort : 'LUND',						LabelMedium : 'LUND',					LabelLong : 'LUND' },
		'lusi'						: { LabelShort : 'LUSI',						LabelMedium : 'LUSi',					LabelLong : 'LUSi' },
		'luso'						: { LabelShort : 'LUSO',						LabelMedium : 'LUSO',					LabelLong : 'LUSO' },
		'lust'						: { LabelShort : 'LUST',						LabelMedium : 'LUST',					LabelLong : 'LUST' },
		'lwn'						: { LabelShort : 'LWN',							LabelMedium : 'LWN',					LabelLong : 'LWN' },
		'lycan'						: { LabelShort : 'LYCAN',						LabelMedium : 'LYCAN',					LabelLong : 'LYCAN' },
		'lycanhd'					: { LabelShort : 'LYCANHD',						LabelMedium : 'LycanHD',					LabelLong : 'LycanHD' },
		'm00tv'						: { LabelShort : 'M00TV',						LabelMedium : 'm00tv',					LabelLong : 'm00tv' },
		'm2'							: { LabelShort : 'M2',							LabelMedium : 'M2',						LabelLong : 'M2' },
		'm2tv'						: { LabelShort : 'M2TV',						LabelMedium : 'M2Tv',					LabelLong : 'M2Tv' },
		'm3d'						: { LabelShort : 'M3D',							LabelMedium : 'M3D',					LabelLong : 'M3D' },
		'm3q'						: { LabelShort : 'M3Q',							LabelMedium : 'M3Q',					LabelLong : 'M3Q' },
		'm4xd0me'					: { LabelShort : 'M4XD0ME',						LabelMedium : 'M4XD0ME',					LabelLong : 'M4XD0ME' },
		'm794'						: { LabelShort : 'M794',						LabelMedium : 'M794',					LabelLong : 'M794' },
		'machd'						: { LabelShort : 'MACHD',						LabelMedium : 'MACHD',					LabelLong : 'MACHD' },
		'machine'					: { LabelShort : 'MACHINE',						LabelMedium : 'MACHiNE',					LabelLong : 'MACHiNE' },
		'mack'						: { LabelShort : 'MACK',						LabelMedium : 'mAck',					LabelLong : 'mAck' },
		'macro'						: { LabelShort : 'MACRO',						LabelMedium : 'macro',					LabelLong : 'macro' },
		'madman'					: { LabelShort : 'MADMAN',						LabelMedium : 'MadMan',					LabelLong : 'MadMan' },
		'madoff'					: { LabelShort : 'MADOFF',						LabelMedium : 'madoff',					LabelLong : 'madoff' },
		'mafiaking'					: { LabelShort : 'MAFIAKING',					LabelMedium : 'Mafiaking',				LabelLong : 'Mafiaking' },
		'mag'						: { LabelShort : 'MAG',							LabelMedium : 'MaG',					LabelLong : 'MaG' },
		'magic'						: { LabelShort : 'MAGIC',						LabelMedium : 'MAGiC',					LabelLong : 'MAGiC' },
		'magical'					: { LabelShort : 'MAGICAL',						LabelMedium : 'MAGiCAL',					LabelLong : 'MAGiCAL' },
		'majestic'					: { LabelShort : 'MAJESTIC',					LabelMedium : 'MAJESTiC',				LabelLong : 'MAJESTiC' },
		'makintos13'					: { LabelShort : 'MAKINTOS13',					LabelMedium : 'Makintos13',				LabelLong : 'Makintos13' },
		'male'						: { LabelShort : 'MALE',						LabelMedium : 'Male',					LabelLong : 'Male' },
		'man'						: { LabelShort : 'MAN',							LabelMedium : 'MAN',					LabelLong : 'MAN' },
		'mandr'						: { LabelShort : 'MANDR',						LabelMedium : 'MandR',					LabelLong : 'MandR' },
		'manning'					: { LabelShort : 'MANNING',						LabelMedium : 'MANNING',					LabelLong : 'MANNING' },
		'marge'						: { LabelShort : 'MARGE',						LabelMedium : 'MarGe',					LabelLong : 'MarGe' },
		'marhaba'					: { LabelShort : 'MARHABA',						LabelMedium : 'Marhaba',					LabelLong : 'Marhaba' },
		'markii'					: { LabelShort : 'MARKII',						LabelMedium : 'MarkII',					LabelLong : 'MarkII' },
		'mars'						: { LabelShort : 'MARS',						LabelMedium : 'MARS',					LabelLong : 'MARS' },
		'marvelous'					: { LabelShort : 'MARVELOUS',					LabelMedium : 'MaRVeLouS',				LabelLong : 'MaRVeLouS' },
		'master5'					: { LabelShort : 'MASTER5',						LabelMedium : 'Master5',					LabelLong : 'Master5' },
		'matter'					: { LabelShort : 'MATTER',						LabelMedium : 'MATTER',					LabelLong : 'MATTER' },
		'max'						: { LabelShort : 'MAX',							LabelMedium : 'MaX',					LabelLong : 'MaX' },
		'maxhd'						: { LabelShort : 'MAXHD',						LabelMedium : 'MaxHD',					LabelLong : 'MaxHD' },
		'maxi'						: { LabelShort : 'MAXI',						LabelMedium : 'MAXi',					LabelLong : 'MAXi' },
		'maximersk'					: { LabelShort : 'MAXIMERSK',					LabelMedium : 'maximersk',				LabelLong : 'maximersk' },
		'maximum'					: { LabelShort : 'MAXIMUM',						LabelMedium : 'MAXiMUM',					LabelLong : 'MAXiMUM' },
		'maxpro'					: { LabelShort : 'MAXPRO',						LabelMedium : 'MAXPRO',					LabelLong : 'MAXPRO' },
		'maxrls'					: { LabelShort : 'MAXRLS',						LabelMedium : 'MaxRls',					LabelLong : 'MaxRls' },
		'maxspeed'					: { LabelShort : 'MAXSPEED',					LabelMedium : 'MAXSPEED',				LabelLong : 'MAXSPEED' },
		'maxx'						: { LabelShort : 'MAXX',						LabelMedium : 'MAXX',					LabelLong : 'MAXX' },
		'mayhem'					: { LabelShort : 'MAYHEM',						LabelMedium : 'MAYHEM',					LabelLong : 'MAYHEM' },
		'maz'						: { LabelShort : 'MAZ',							LabelMedium : 'maz',					LabelLong : 'maz' },
		'mbrhdrg'					: { LabelShort : 'MBRHDRG',						LabelMedium : 'MBRHDRG',					LabelLong : 'MBRHDRG' },
		'mc5'						: { LabelShort : 'MC5',							LabelMedium : 'Mc5',					LabelLong : 'Mc5' },
		'mcfly'						: { LabelShort : 'MCFLY',						LabelMedium : 'McFly',					LabelLong : 'McFly' },
		'mch'						: { LabelShort : 'MCH',							LabelMedium : 'MCH',					LabelLong : 'MCH' },
		'mchd'						: { LabelShort : 'MCHD',						LabelMedium : 'MCHD',					LabelLong : 'MCHD' },
		'mcr'						: { LabelShort : 'MCR',							LabelMedium : 'MCR',					LabelLong : 'MCR' },
		'mctav'						: { LabelShort : 'MCTAV',						LabelMedium : 'McTav',					LabelLong : 'McTav' },
		'mdgp'						: { LabelShort : 'MDGP',						LabelMedium : 'MDGP',					LabelLong : 'MDGP' },
		'mdm'						: { LabelShort : 'MDM',							LabelMedium : 'MdM',					LabelLong : 'MdM' },
		'mdr'						: { LabelShort : 'MDR',							LabelMedium : 'MDR',					LabelLong : 'MDR' },
		'me7alh'					: { LabelShort : 'ME7ALH',						LabelMedium : 'Me7alh',					LabelLong : 'Me7alh' },
		'meakes'					: { LabelShort : 'MEAKES',						LabelMedium : 'Meakes',					LabelLong : 'Meakes' },
		'med'						: { LabelShort : 'MED',							LabelMedium : 'med',					LabelLong : 'med' },
		'meddy'						: { LabelShort : 'MEDDY',						LabelMedium : 'MEDDY',					LabelLong : 'MEDDY' },
		'mediamaniacs'				: { LabelShort : 'MEDIAMANIACS',				LabelMedium : 'MEDiAMANiACS',			LabelLong : 'MEDiAMANiACS' },
		'medieval'					: { LabelShort : 'MEDIEVAL',					LabelMedium : 'MEDiEVAL',				LabelLong : 'MEDiEVAL' },
		'meg'						: { LabelShort : 'MEG',							LabelMedium : 'MEG',					LabelLong : 'MEG' },
		'megapeer'					: { LabelShort : 'MEGAPEER',					LabelMedium : 'MegaPeer',				LabelLong : 'MegaPeer' },
		'megatron'					: { LabelShort : 'MEGATRON',					LabelMedium : 'MeGaTroN',				LabelLong : 'MeGaTroN' },
		'meguil'					: { LabelShort : 'MEGUIL',						LabelMedium : 'MeGUiL',					LabelLong : 'MeGUiL' },
		'megusta'					: { LabelShort : 'MEGUSTA',						LabelMedium : 'MeGusta',					LabelLong : 'MeGusta' },
		'meister'					: { LabelShort : 'MEISTER',						LabelMedium : 'MEiSTER',					LabelLong : 'MEiSTER' },
		'melba'						: { LabelShort : 'MELBA',						LabelMedium : 'MELBA',					LabelLong : 'MELBA' },
		'melite'					: { LabelShort : 'MELITE',						LabelMedium : 'MELiTE',					LabelLong : 'MELiTE' },
		'mem'						: { LabelShort : 'MEM',							LabelMedium : 'MeM',					LabelLong : 'MeM' },
		'memento'					: { LabelShort : 'MEMENTO',						LabelMedium : 'MEMENTO',					LabelLong : 'MEMENTO' },
		'memories'					: { LabelShort : 'MEMORIES',					LabelMedium : 'MEMORiES',				LabelLong : 'MEMORiES' },
		'menaceiisociety'			: { LabelShort : 'MENACEIISOCIETY',				LabelMedium : 'MenaceIISociety',			LabelLong : 'MenaceIISociety' },
		'meow'						: { LabelShort : 'MEOW',						LabelMedium : 'MEOW',					LabelLong : 'MEOW' },
		'metcon'					: { LabelShort : 'METCON',						LabelMedium : 'METCON',					LabelLong : 'METCON' },
		'meteam'					: { LabelShort : 'METEAM',						LabelMedium : 'METeam',					LabelLong : 'METeam' },
		'meth'						: { LabelShort : 'METH',						LabelMedium : 'MeTH',					LabelLong : 'MeTH' },
		'metis'						: { LabelShort : 'METIS',						LabelMedium : 'METiS',					LabelLong : 'METiS' },
		'mf'							: { LabelShort : 'MF',							LabelMedium : 'MF',						LabelLong : 'M-F' },
		'mfo'						: { LabelShort : 'MFO',							LabelMedium : 'MFO',					LabelLong : 'MFO' },
		'mg'							: { LabelShort : 'MG',							LabelMedium : 'MG',						LabelLong : 'MG' },
		'mgb'						: { LabelShort : 'MGB',							LabelMedium : 'MgB',					LabelLong : 'MgB' },
		'mhd'						: { LabelShort : 'MHD',							LabelMedium : 'mHD',					LabelLong : 'mHD' },
		'mhq'						: { LabelShort : 'MHQ',							LabelMedium : 'MHQ',					LabelLong : 'MHQ' },
		'mibr'						: { LabelShort : 'MIBR',						LabelMedium : 'MiBR',					LabelLong : 'MiBR' },
		'microflix'					: { LabelShort : 'MICROFLIX',					LabelMedium : 'Microflix',				LabelLong : 'Microflix' },
		'mighty'					: { LabelShort : 'MIGHTY',						LabelMedium : 'MiGHTY',					LabelLong : 'MiGHTY' },
		'mikos'						: { LabelShort : 'MIKOS',						LabelMedium : 'mikos',					LabelLong : 'mikos' },
		'miky'						: { LabelShort : 'MIKY',						LabelMedium : 'MIKY',					LabelLong : 'MIKY' },
		'milk'						: { LabelShort : 'MILK',						LabelMedium : 'MiLK',					LabelLong : 'MiLK' },
		'millenium'					: { LabelShort : 'MILLENIUM',					LabelMedium : 'MiLLENiUM',				LabelLong : 'MiLLENiUM' },
		'mind'						: { LabelShort : 'MIND',						LabelMedium : 'MiND',					LabelLong : 'MiND' },
		'mindthegap'					: { LabelShort : 'MINDTHEGAP',					LabelMedium : 'MiNDTHEGAP',				LabelLong : 'MiNDTHEGAP' },
		'minihd'					: { LabelShort : 'MINIHD',						LabelMedium : 'MiniHD',					LabelLong : 'MiniHD' },
		'mink'						: { LabelShort : 'MINK',						LabelMedium : 'MiNK',					LabelLong : 'MiNK' },
		'mint'						: { LabelShort : 'MINT',						LabelMedium : 'MiNT',					LabelLong : 'MiNT' },
		'minx'						: { LabelShort : 'MINX',						LabelMedium : 'MiNX',					LabelLong : 'MiNX' },
		'mirai'						: { LabelShort : 'MIRAI',						LabelMedium : 'Mirai',					LabelLong : 'Mirai' },
		'mircrew'					: { LabelShort : 'MIRCREW',						LabelMedium : 'MIRCrew',					LabelLong : 'MIRCrew' },
		'mis'						: { LabelShort : 'MIS',							LabelMedium : 'MIS',					LabelLong : 'MIS' },
		'misfits'					: { LabelShort : 'MISFITS',						LabelMedium : 'MiSFiTS',					LabelLong : 'MiSFiTS' },
		'mish'						: { LabelShort : 'MISH',						LabelMedium : 'Mish',					LabelLong : 'Mish' },
		'missripz'					: { LabelShort : 'MISSRIPZ',					LabelMedium : 'MissRipZ',				LabelLong : 'MissRipZ' },
		'mixed'						: { LabelShort : 'MIXED',						LabelMedium : 'MiXED',					LabelLong : 'MiXED' },
		'mixtv'						: { LabelShort : 'MIXTV',						LabelMedium : 'MIXTV',					LabelLong : 'MIXTV' },
		'mkvanime'					: { LabelShort : 'MKVANIME',					LabelMedium : 'mkvAnime',				LabelLong : 'mkvAnime' },
		'mkvcage'					: { LabelShort : 'MKVCAGE',						LabelMedium : 'MkvCage',					LabelLong : 'MkvCage' },
		'mkvcinemas'					: { LabelShort : 'MKVCINEMAS',					LabelMedium : 'mkvCinemas',				LabelLong : 'mkvCinemas' },
		'mkvgod'					: { LabelShort : 'MKVGOD',						LabelMedium : 'mkvGOd',					LabelLong : 'mkvGOd' },
		'mkvhu'						: { LabelShort : 'MKVHU',						LabelMedium : 'MkvHu',					LabelLong : 'MkvHu' },
		'mkvhub'					: { LabelShort : 'MKVHUB',						LabelMedium : 'MkvHub',					LabelLong : 'MkvHub' },
		'mkvking'					: { LabelShort : 'MKVKING',						LabelMedium : 'Mkvking',					LabelLong : 'Mkvking' },
		'mkvtv'						: { LabelShort : 'MKVTV',						LabelMedium : 'MKVTV',					LabelLong : 'MKVTV.NET' },
		'mmi'						: { LabelShort : 'MMI',							LabelMedium : 'MMI',					LabelLong : 'MMI' },
		'mnhd'						: { LabelShort : 'MNHD',						LabelMedium : 'MNHD',					LabelLong : 'MNHD' },
		'mo'							: { LabelShort : 'MO',							LabelMedium : 'MO',						LabelLong : 'M.O' },
		'moa'						: { LabelShort : 'MOA',							LabelMedium : 'MoA',					LabelLong : 'MoA' },
		'mobbit'					: { LabelShort : 'MOBBIT',						LabelMedium : 'MOBBit',					LabelLong : 'MOBBit' },
		'mobee1'					: { LabelShort : 'MOBEE1',						LabelMedium : 'MOBEE1',					LabelLong : 'MOBEE1' },
		'mobidik'					: { LabelShort : 'MOBIDIK',						LabelMedium : 'MOBiDiK',					LabelLong : 'MOBiDiK' },
		'modemslayer'				: { LabelShort : 'MODEMSLAYER',					LabelMedium : 'MoDeMSLaYER',			LabelLong : 'MoDeMSLaYER' },
		'moe'						: { LabelShort : 'MOE',							LabelMedium : 'Moe',					LabelLong : 'Moe.AP' },
		'moh'						: { LabelShort : 'MOH',							LabelMedium : 'MoH',					LabelLong : 'MoH' },
		'mojo'						: { LabelShort : 'MOJO',						LabelMedium : 'Mojo',					LabelLong : 'Mojo' },
		'moly'						: { LabelShort : 'MOLY',						LabelMedium : 'MOLY',					LabelLong : 'MOLY' },
		'moma'						: { LabelShort : 'MOMA',						LabelMedium : 'MOMA',					LabelLong : 'MOMA' },
		'momentum'					: { LabelShort : 'MOMENTUM',					LabelMedium : 'MOMENTUM',				LabelLong : 'MOMENTUM' },
		'momo'						: { LabelShort : 'MOMO',						LabelMedium : 'MOMO',					LabelLong : 'MOMO' },
		'monk'						: { LabelShort : 'MONK',						LabelMedium : 'MONK',					LabelLong : 'MONK' },
		'monkee'					: { LabelShort : 'MONKEE',						LabelMedium : 'monkee',					LabelLong : 'monkee' },
		'monolith'					: { LabelShort : 'MONOLITH',					LabelMedium : 'MONOLITH',				LabelLong : 'MONOLITH' },
		'monster'					: { LabelShort : 'MONSTER',						LabelMedium : 'MONSTER',					LabelLong : 'MONSTER' },
		'mont'						: { LabelShort : 'MONT',						LabelMedium : 'MONT',					LabelLong : 'MONT' },
		'monument'					: { LabelShort : 'MONUMENT',					LabelMedium : 'MONUMENT',				LabelLong : 'MONUMENT' },
		'mooi1990'					: { LabelShort : 'MOOI1990',					LabelMedium : 'Mooi1990',				LabelLong : 'Mooi1990' },
		'moovee'					: { LabelShort : 'MOOVEE',						LabelMedium : 'MOOVEE',					LabelLong : 'MOOVEE' },
		'moreland'					: { LabelShort : 'MORELAND',					LabelMedium : 'moreland',				LabelLong : 'moreland' },
		'mori'						: { LabelShort : 'MORI',						LabelMedium : 'Mori',					LabelLong : 'Mori' },
		'moritz'					: { LabelShort : 'MORITZ',						LabelMedium : 'MORiTZ',					LabelLong : 'MORiTZ' },
		'morose'					: { LabelShort : 'MOROSE',						LabelMedium : 'MOROSE',					LabelLong : 'MOROSE' },
		'morpheus'					: { LabelShort : 'MORPHEUS',					LabelMedium : 'Morpheus',				LabelLong : 'Morpheus' },
		'morris'					: { LabelShort : 'MORRIS',						LabelMedium : 'MORRiS',					LabelLong : 'MORRiS' },
		'mors'						: { LabelShort : 'MORS',						LabelMedium : 'MORS',					LabelLong : 'MORS' },
		'mortal'					: { LabelShort : 'MORTAL',						LabelMedium : 'MORTAL',					LabelLong : 'MORTAL' },
		'motion'					: { LabelShort : 'MOTION',						LabelMedium : 'MOTION',					LabelLong : 'MOTION' },
		'motu'						: { LabelShort : 'MOTU',						LabelMedium : 'MOTU',					LabelLong : 'MOTU' },
		'mouseclick'					: { LabelShort : 'MOUSECLICK',					LabelMedium : 'MOUSECLiCK',				LabelLong : 'MOUSECLiCK' },
		'movcr'						: { LabelShort : 'MOVCR',						LabelMedium : 'MovCr',					LabelLong : 'MovCr' },
		'movee'						: { LabelShort : 'MOVEE',						LabelMedium : 'MOVEE',					LabelLong : 'MOVEE' },
		'movieaddicts'				: { LabelShort : 'MOVIEADDICTS',				LabelMedium : 'MOViEADDiCTS',			LabelLong : 'MOViEADDiCTS' },
		'movieit'					: { LabelShort : 'MOVIEIT',						LabelMedium : 'MOViEiT',					LabelLong : 'MOViEiT' },
		'movierush'					: { LabelShort : 'MOVIERUSH',					LabelMedium : 'MOViERUSH',				LabelLong : 'MOViERUSH' },
		'moviesbyrizzo'				: { LabelShort : 'MOVIESBYRIZZO',				LabelMedium : 'moviesbyrizzo',			LabelLong : 'moviesbyrizzo' },
		'moviesevil'					: { LabelShort : 'MOVIESEVIL',					LabelMedium : 'MoviesEvil',				LabelLong : 'MoviesEvil' },
		'moviesfd'					: { LabelShort : 'MOVIESFD',					LabelMedium : 'MoviesFD',				LabelLong : 'MoviesFD' },
		'moviesmb'					: { LabelShort : 'MOVIESMB',					LabelMedium : 'MoviesMB',				LabelLong : 'MoviesMB' },
		'moviesmix'					: { LabelShort : 'MOVIESMIX',					LabelMedium : 'MoviesMix',				LabelLong : 'MoviesMix' },
		'moviezworldz'				: { LabelShort : 'MOVIEZWORLDZ',				LabelMedium : 'Moviezworldz',			LabelLong : 'Moviezworldz' },
		'mp4ba'						: { LabelShort : 'MP4BA',						LabelMedium : 'Mp4Ba',					LabelLong : 'Mp4Ba' },
		'mp4king'					: { LabelShort : 'MP4KING',						LabelMedium : 'MP4KiNG',					LabelLong : 'MP4KiNG' },
		'mpup'						: { LabelShort : 'MPUP',						LabelMedium : 'MPup',					LabelLong : 'MPup' },
		'mrc'						: { LabelShort : 'MRC',							LabelMedium : 'MRC',					LabelLong : 'MRC' },
		'mrcs'						: { LabelShort : 'MRCS',						LabelMedium : 'MRCS',					LabelLong : 'MRCS' },
		'mrgrey'					: { LabelShort : 'MRGREY',						LabelMedium : 'MrGrey',					LabelLong : 'MrGrey' },
		'mrhive'					: { LabelShort : 'MRHIVE',						LabelMedium : 'MrHive',					LabelLong : 'Mr.Hive' },
		'mrkeff'					: { LabelShort : 'MRKEFF',						LabelMedium : 'MrKeFF',					LabelLong : 'Mr_KeFF' },
		'mrkickass'					: { LabelShort : 'MRKICKASS',					LabelMedium : 'MrKickASS',				LabelLong : 'Mr. KickASS' },
		'mrlore'					: { LabelShort : 'MRLORE',						LabelMedium : 'MrLore',					LabelLong : 'MrLore' },
		'mrm'						: { LabelShort : 'MRM',							LabelMedium : 'MRM',					LabelLong : 'MRM' },
		'mrn'						: { LabelShort : 'MRN',							LabelMedium : 'MRN',					LabelLong : 'MRN' },
		'mro'						: { LabelShort : 'MRO',							LabelMedium : 'MrO',					LabelLong : 'MrO' },
		'mrs'						: { LabelShort : 'MRS',							LabelMedium : 'mRs',					LabelLong : 'mRs' },
		'mrshanku'					: { LabelShort : 'MRSHANKU',					LabelMedium : 'MRShanku',				LabelLong : 'MRShanku' },
		'mrsk'						: { LabelShort : 'MRSK',						LabelMedium : 'MRSK',					LabelLong : 'MRSK' },
		'mrstrange'					: { LabelShort : 'MRSTRANGE',					LabelMedium : 'MrStrange',				LabelLong : 'MrStrange' },
		'ms'							: { LabelShort : 'MS',							LabelMedium : 'MS',						LabelLong : 'M-S' },
		'ms89'						: { LabelShort : 'MS89',						LabelMedium : 'Ms89',					LabelLong : 'Ms89' },
		'msd'						: { LabelShort : 'MSD',							LabelMedium : 'mSD',					LabelLong : 'mSD' },
		'mse'						: { LabelShort : 'MSE',							LabelMedium : 'MSE',					LabelLong : 'MSE' },
		'msr'						: { LabelShort : 'MSR',							LabelMedium : 'MsR',					LabelLong : 'MsR' },
		'mss'						: { LabelShort : 'MSS',							LabelMedium : 'mSS',					LabelLong : 'mSS' },
		'mt'							: { LabelShort : 'MT',							LabelMedium : 'MT',						LabelLong : 'MT' },
		'mtb'						: { LabelShort : 'MTB',							LabelMedium : 'MTB',					LabelLong : 'MTB' },
		'mteam'						: { LabelShort : 'MTEAM',						LabelMedium : 'MTeam',					LabelLong : 'MTeam' },
		'mtk'						: { LabelShort : 'MTK',							LabelMedium : 'MTK',					LabelLong : 'MTK' },
		'muhhd'						: { LabelShort : 'MUHHD',						LabelMedium : 'muhHD',					LabelLong : 'muhHD' },
		'multi4'					: { LabelShort : 'MULTI4',						LabelMedium : 'Multi4',					LabelLong : 'Multi4' },
		'multiplex'					: { LabelShort : 'MULTIPLEX',					LabelMedium : 'MULTiPLEX',				LabelLong : 'MULTiPLEX' },
		'multiply'					: { LabelShort : 'MULTIPLY',					LabelMedium : 'MULTiPLY',				LabelLong : 'MULTiPLY' },
		'mulvacoded'					: { LabelShort : 'MULVACODED',					LabelMedium : 'MULVAcoded',				LabelLong : 'MULVAcoded' },
		'murder'					: { LabelShort : 'MURDER',						LabelMedium : 'MURDER',					LabelLong : 'MURDER' },
		'musafirboy'					: { LabelShort : 'MUSAFIRBOY',					LabelMedium : 'Musafirboy',				LabelLong : 'Musafirboy' },
		'musketeers'					: { LabelShort : 'MUSKETEERS',					LabelMedium : 'MuskeTeerS',				LabelLong : 'MuskeTeerS' },
		'mutznutz'					: { LabelShort : 'MUTZNUTZ',					LabelMedium : 'MutzNutz',				LabelLong : 'MutzNutz' },
		'mvgee'						: { LabelShort : 'MVGEE',						LabelMedium : 'MVGEE',					LabelLong : 'MVGEE' },
		'mvgroup'					: { LabelShort : 'MVGROUP',						LabelMedium : 'MVGroup',					LabelLong : 'MVGroup' },
		'mvn'						: { LabelShort : 'MVN',							LabelMedium : 'MVN',					LabelLong : 'MVN' },
		'mvo'						: { LabelShort : 'MVO',							LabelMedium : 'MVO',					LabelLong : 'MVO' },
		'mvp'						: { LabelShort : 'MVP',							LabelMedium : 'MVP',					LabelLong : 'MVP' },
		'mvs'						: { LabelShort : 'MVS',							LabelMedium : 'MVS',					LabelLong : 'MVS' },
		'mw'							: { LabelShort : 'MW',							LabelMedium : 'MW',						LabelLong : 'MW' },
		'mxb'						: { LabelShort : 'MXB',							LabelMedium : 'MXB',					LabelLong : 'MXB' },
		'mxmg'						: { LabelShort : 'MXMG',						LabelMedium : 'MXMG',					LabelLong : 'MXMG' },
		'mys'						: { LabelShort : 'MYS',							LabelMedium : 'MyS',					LabelLong : 'MyS' },
		'mysilu'					: { LabelShort : 'MYSILU',						LabelMedium : 'MySiLU',					LabelLong : 'MySiLU' },
		'myst'						: { LabelShort : 'MYST',						LabelMedium : 'MYST',					LabelLong : 'MYST' },
		'mysterion'					: { LabelShort : 'MYSTERION',					LabelMedium : 'MYSTERiON',				LabelLong : 'MYSTERiON' },
		'mzabi'						: { LabelShort : 'MZABI',						LabelMedium : 'MZABI',					LabelLong : 'MZABI' },
		'n0m1'						: { LabelShort : 'N0M1',						LabelMedium : 'n0m1',					LabelLong : 'n0m1' },
		'n0ttz'						: { LabelShort : 'N0TTZ',						LabelMedium : 'N0TTZ',					LabelLong : 'N0TTZ' },
		'n1c'						: { LabelShort : 'N1C',							LabelMedium : 'N1C',					LabelLong : 'N1C' },
		'naa'						: { LabelShort : 'NAA',							LabelMedium : 'NAA',					LabelLong : 'NAA' },
		'nada'						: { LabelShort : 'NADA',						LabelMedium : 'Nada',					LabelLong : 'Nada' },
		'nahom'						: { LabelShort : 'NAHOM',						LabelMedium : 'NAHOM',					LabelLong : 'NAHOM' },
		'naisu'						: { LabelShort : 'NAISU',						LabelMedium : 'Naisu',					LabelLong : 'Naisu' },
		'nanban'					: { LabelShort : 'NANBAN',						LabelMedium : 'Nanban',					LabelLong : 'Nanban' },
		'nano'						: { LabelShort : 'NANO',						LabelMedium : 'NANO',					LabelLong : 'NANO' },
		'narb'						: { LabelShort : 'NARB',						LabelMedium : 'NaRB',					LabelLong : 'NaRB' },
		'nassau'					: { LabelShort : 'NASSAU',						LabelMedium : 'NASSAU',					LabelLong : 'NASSAU' },
		'nate666'					: { LabelShort : 'NATE666',						LabelMedium : 'nate666',					LabelLong : 'nate_666' },
		'natty'						: { LabelShort : 'NATTY',						LabelMedium : 'NATTY',					LabelLong : 'NATTY' },
		'natv'						: { LabelShort : 'NATV',						LabelMedium : 'NATV',					LabelLong : 'NATV' },
		'nbdy'						: { LabelShort : 'NBDY',						LabelMedium : 'NBDY',					LabelLong : 'NBDY' },
		'nbs'						: { LabelShort : 'NBS',							LabelMedium : 'NBS',					LabelLong : 'NBS' },
		'nbt'						: { LabelShort : 'NBT',							LabelMedium : 'NbT',					LabelLong : 'NbT' },
		'ncmt'						: { LabelShort : 'NCMT',						LabelMedium : 'NCmt',					LabelLong : 'NCmt' },
		'ncpx'						: { LabelShort : 'NCPX',						LabelMedium : 'NCPX',					LabelLong : 'NCPX' },
		'ndrt'						: { LabelShort : 'NDRT',						LabelMedium : 'NDRT',					LabelLong : 'NDRT' },
		'nedivx'					: { LabelShort : 'NEDIVX',						LabelMedium : 'NeDiVx',					LabelLong : 'NeDiVx' },
		'nelly45'					: { LabelShort : 'NELLY45',						LabelMedium : 'nelly45',					LabelLong : 'nelly45' },
		'nelwyn'					: { LabelShort : 'NELWYN',						LabelMedium : 'Nelwyn',					LabelLong : 'Nelwyn' },
		'nemesis'					: { LabelShort : 'NEMESIS',						LabelMedium : 'NEMESIS',					LabelLong : 'NEMESIS' },
		'nemo'						: { LabelShort : 'NEMO',						LabelMedium : 'NEMO',					LabelLong : 'NEMO' },
		'neo'						: { LabelShort : 'NEO',							LabelMedium : 'Neo',					LabelLong : 'Neo' },
		'neptune'					: { LabelShort : 'NEPTUNE',						LabelMedium : 'NEPTUNE',					LabelLong : 'NEPTUNE' },
		'nerdhd'					: { LabelShort : 'NERDHD',						LabelMedium : 'NERDHD',					LabelLong : 'NERDHD' },
		'nerds'						: { LabelShort : 'NERDS',						LabelMedium : 'NERDS',					LabelLong : 'NERDS' },
		'neroz'						: { LabelShort : 'NEROZ',						LabelMedium : 'NeRoZ',					LabelLong : 'NeRoZ' },
		'nes'						: { LabelShort : 'NES',							LabelMedium : 'NES',					LabelLong : 'NES' },
		'nesmeured'					: { LabelShort : 'NESMEURED',					LabelMedium : 'NESMEURED',				LabelLong : 'NESMEURED' },
		'neutrino'					: { LabelShort : 'NEUTRINO',					LabelMedium : 'NEUTRINO',				LabelLong : 'NEUTRINO' },
		'newartriot'					: { LabelShort : 'NEWARTRIOT',					LabelMedium : 'NewArtRiot',				LabelLong : 'NewArtRiot' },
		'newcomers'					: { LabelShort : 'NEWCOMERS',					LabelMedium : 'NewComers',				LabelLong : 'NewComers' },
		'newmov'					: { LabelShort : 'NEWMOV',						LabelMedium : 'NewMov',					LabelLong : 'NewMov' },
		'newsource'					: { LabelShort : 'NEWSOURCE',					LabelMedium : 'NEWSOURCE',				LabelLong : 'NEW.SOURCE' },
		'newstudio'					: { LabelShort : 'NEWSTUDIO',					LabelMedium : 'NewStudio',				LabelLong : 'NewStudio' },
		'newteam'					: { LabelShort : 'NEWTEAM',						LabelMedium : 'NeWTeaM',					LabelLong : 'NeWTeaM' },
		'nextbit'					: { LabelShort : 'NEXTBIT',						LabelMedium : 'NextBit',					LabelLong : 'NextBit' },
		'nextgen'					: { LabelShort : 'NEXTGEN',						LabelMedium : 'NEXTGEN',					LabelLong : 'NEXTGEN' },
		'nezu'						: { LabelShort : 'NEZU',						LabelMedium : 'NEZU',					LabelLong : 'NEZU' },
		'nfhd'						: { LabelShort : 'NFHD',						LabelMedium : 'NFHD',					LabelLong : 'NFHD' },
		'nflx'						: { LabelShort : 'NFLX',						LabelMedium : 'NFLX',					LabelLong : 'NFLX' },
		'nfofix'					: { LabelShort : 'NFOFIX',						LabelMedium : 'NFOFiX',					LabelLong : 'NFOFiX' },
		'nfrip'						: { LabelShort : 'NFRIP',						LabelMedium : 'NFRiP',					LabelLong : 'NFRiP' },
		'ngb'						: { LabelShort : 'NGB',							LabelMedium : 'NGB',					LabelLong : 'NGB' },
		'nge'						: { LabelShort : 'NGE',							LabelMedium : 'NGE',					LabelLong : 'NGE' },
		'ngp'						: { LabelShort : 'NGP',							LabelMedium : 'NGP',					LabelLong : 'NGP' },
		'ngr'						: { LabelShort : 'NGR',							LabelMedium : 'NGR',					LabelLong : 'NGR' },
		'ngserier'					: { LabelShort : 'NGSERIER',					LabelMedium : 'NGSerier',				LabelLong : 'NGSerier' },
		'nhanc3'					: { LabelShort : 'NHANC3',						LabelMedium : 'NhaNc3',					LabelLong : 'NhaNc3' },
		'nhd'						: { LabelShort : 'NHD',							LabelMedium : 'NHD',					LabelLong : 'NHD' },
		'nick'						: { LabelShort : 'NICK',						LabelMedium : 'NICK',					LabelLong : 'NICK' },
		'nickarad'					: { LabelShort : 'NICKARAD',					LabelMedium : 'nickarad',				LabelLong : 'nickarad' },
		'nightripper'				: { LabelShort : 'NIGHTRIPPER',					LabelMedium : 'Nightripper',			LabelLong : 'Nightripper' },
		'nik'						: { LabelShort : 'NIK',							LabelMedium : 'NiK',					LabelLong : 'N!K' },
		'nikonxp'					: { LabelShort : 'NIKONXP',						LabelMedium : 'NikonXP',					LabelLong : 'NikonXP' },
		'nikoo'						: { LabelShort : 'NIKOO',						LabelMedium : 'NIKOo',					LabelLong : 'NIKOo' },
		'nikt0'						: { LabelShort : 'NIKT0',						LabelMedium : 'nikt0',					LabelLong : 'nikt0' },
		'nile'						: { LabelShort : 'NILE',						LabelMedium : 'NILE',					LabelLong : 'NILE' },
		'nima4k'					: { LabelShort : 'NIMA4K',						LabelMedium : 'NIMA4K',					LabelLong : 'NIMA4K' },
		'nip'						: { LabelShort : 'NIP',							LabelMedium : 'NiP',					LabelLong : 'NiP' },
		'nitro'						: { LabelShort : 'NITRO',						LabelMedium : 'nItRo',					LabelLong : 'nItRo' },
		'nitroteam'					: { LabelShort : 'NITROTEAM',					LabelMedium : 'NitroTeam',				LabelLong : 'NitroTeam' },
		'nix'						: { LabelShort : 'NIX',							LabelMedium : 'NiX',					LabelLong : 'NiX' },
		'nixon'						: { LabelShort : 'NIXON',						LabelMedium : 'NiXON',					LabelLong : 'NiXON' },
		'nixx'						: { LabelShort : 'NIXX',						LabelMedium : 'NiXX',					LabelLong : 'NiXX' },
		'nks'						: { LabelShort : 'NKS',							LabelMedium : 'NKS',					LabelLong : 'NKS' },
		'nlc'						: { LabelShort : 'NLC',							LabelMedium : 'NLC',					LabelLong : 'NLC' },
		'nlibra'					: { LabelShort : 'NLIBRA',						LabelMedium : 'nLiBRA',					LabelLong : 'nLiBRA' },
		'nlt'						: { LabelShort : 'NLT',							LabelMedium : 'NLT',					LabelLong : 'NLT' },
		'nmd'						: { LabelShort : 'NMD',							LabelMedium : 'nmd',					LabelLong : 'nmd' },
		'nme'						: { LabelShort : 'NME',							LabelMedium : 'NME',					LabelLong : 'NME' },
		'nmr'						: { LabelShort : 'NMR',							LabelMedium : 'NMR',					LabelLong : 'NMR' },
		'nnm'						: { LabelShort : 'NNM',							LabelMedium : 'NNM',					LabelLong : 'NNM' },
		'nnmclub'					: { LabelShort : 'NNMCLUB',						LabelMedium : 'NNMClub',					LabelLong : 'NNMClub' },
		'nnr'						: { LabelShort : 'NNR',							LabelMedium : 'nnr',					LabelLong : 'nnr' },
		'no1cares'					: { LabelShort : 'NO1CARES',					LabelMedium : 'NO1CARES',				LabelLong : 'NO1CARES' },
		'no1knows'					: { LabelShort : 'NO1KNOWS',					LabelMedium : 'NO1KNOWS',				LabelLong : 'NO1KNOWS' },
		'nodlabs'					: { LabelShort : 'NODLABS',						LabelMedium : 'NODLABS',					LabelLong : 'NODLABS' },
		'nogroup'					: { LabelShort : 'NOGROUP',						LabelMedium : 'NOGROUP',					LabelLong : 'NOGROUP' },
		'nogrp'						: { LabelShort : 'NOGRP',						LabelMedium : 'NOGRP',					LabelLong : 'NOGRP' },
		'nohate'					: { LabelShort : 'NOHATE',						LabelMedium : 'NoHaTE',					LabelLong : 'NoHaTE' },
		'noir'						: { LabelShort : 'NOIR',						LabelMedium : 'NOiR',					LabelLong : 'NOiR' },
		'nok'						: { LabelShort : 'NOK',							LabelMedium : 'NOK',					LabelLong : 'N.O.K' },
		'noma'						: { LabelShort : 'NOMA',						LabelMedium : 'NOMA',					LabelLong : 'NOMA' },
		'nomore'					: { LabelShort : 'NOMORE',						LabelMedium : 'NoMore',					LabelLong : 'NoMore' },
		'nondrm'					: { LabelShort : 'NONDRM',						LabelMedium : 'NonDRM',					LabelLong : 'NonDRM' },
		'noobless'					: { LabelShort : 'NOOBLESS',					LabelMedium : 'noobless',				LabelLong : 'noobless' },
		'noobsubs'					: { LabelShort : 'NOOBSUBS',					LabelMedium : 'NoobSubs',				LabelLong : 'NoobSubs' },
		'norars'					: { LabelShort : 'NORARS',						LabelMedium : 'NORARS',					LabelLong : 'NORARS' },
		'nordichd'					: { LabelShort : 'NORDICHD',					LabelMedium : 'NORDiCHD',				LabelLong : 'NORDiCHD' },
		'noretail'					: { LabelShort : 'NORETAIL',					LabelMedium : 'NORETAiL',				LabelLong : 'NORETAiL' },
		'nortv'						: { LabelShort : 'NORTV',						LabelMedium : 'NorTV',					LabelLong : 'NorTV' },
		'noscreens'					: { LabelShort : 'NOSCREENS',					LabelMedium : 'NOSCREENS',				LabelLong : 'NOSCREENS' },
		'nosegment'					: { LabelShort : 'NOSEGMENT',					LabelMedium : 'NOsegmenT',				LabelLong : 'NOsegmenT' },
		'nosivid'					: { LabelShort : 'NOSIVID',						LabelMedium : 'NOSiViD',					LabelLong : 'NOSiViD' },
		'notag'						: { LabelShort : 'NOTAG',						LabelMedium : 'NoTag',					LabelLong : 'NoTag' },
		'notv'						: { LabelShort : 'NOTV',						LabelMedium : 'NOTV',					LabelLong : 'NOTV' },
		'nova'						: { LabelShort : 'NOVA',						LabelMedium : 'NoVA',					LabelLong : 'NoVA' },
		'novalan'					: { LabelShort : 'NOVALAN',						LabelMedium : 'NovaLan',					LabelLong : 'NovaLan' },
		'novarip'					: { LabelShort : 'NOVARIP',						LabelMedium : 'NovaRip',					LabelLong : 'NovaRip' },
		'novo'						: { LabelShort : 'NOVO',						LabelMedium : 'NOVO',					LabelLong : 'NOVO' },
		'nowinhd'					: { LabelShort : 'NOWINHD',						LabelMedium : 'NOWiNHD',					LabelLong : 'NOWiNHD' },
		'nox'						: { LabelShort : 'NOX',							LabelMedium : 'nox',					LabelLong : 'nox' },
		'npms'						: { LabelShort : 'NPMS',						LabelMedium : 'NPMS',					LabelLong : 'NPMS' },
		'npw'						: { LabelShort : 'NPW',							LabelMedium : 'NPW',					LabelLong : 'NPW' },
		'nsn'						: { LabelShort : 'NSN',							LabelMedium : 'NSN',					LabelLong : 'NSN' },
		'nt'							: { LabelShort : 'NT',							LabelMedium : 'NT',						LabelLong : 'NT' },
		'ntb'						: { LabelShort : 'NTB',							LabelMedium : 'NTb',					LabelLong : 'NTb' },
		'ntg'						: { LabelShort : 'NTG',							LabelMedium : 'NTG',					LabelLong : 'NTG' },
		'ntropic'					: { LabelShort : 'NTROPIC',						LabelMedium : 'NTROPiC',					LabelLong : 'NTROPiC' },
		'numy'						: { LabelShort : 'NUMY',						LabelMedium : 'NuMy',					LabelLong : 'NuMy' },
		'nuxx'						: { LabelShort : 'NUXX',						LabelMedium : 'NUXX',					LabelLong : 'NUXX' },
		'nva'						: { LabelShort : 'NVA',							LabelMedium : 'NVA',					LabelLong : 'NVA' },
		'nvee'						: { LabelShort : 'NVEE',						LabelMedium : 'NVEE',					LabelLong : 'NVEE' },
		'nvm'						: { LabelShort : 'NVM',							LabelMedium : 'NVM',					LabelLong : 'NVM' },
		'nwb'						: { LabelShort : 'NWB',							LabelMedium : 'NWB',					LabelLong : 'NWB' },
		'nwo'						: { LabelShort : 'NWO',							LabelMedium : 'NWO',					LabelLong : 'NWO' },
		'nws'						: { LabelShort : 'NWS',							LabelMedium : 'NwS',					LabelLong : 'NwS' },
		'ny'							: { LabelShort : 'NY',							LabelMedium : 'NY',						LabelLong : 'NY' },
		'ny2'						: { LabelShort : 'NY2',							LabelMedium : 'NY2',					LabelLong : 'NY2' },
		'nya'						: { LabelShort : 'NYA',							LabelMedium : 'NYA',					LabelLong : 'NYA' },
		'nydic'						: { LabelShort : 'NYDIC',						LabelMedium : 'NYDIC',					LabelLong : 'NYDIC' },
		'nyh'						: { LabelShort : 'NYH',							LabelMedium : 'NYH',					LabelLong : 'NYH' },
		'nys'						: { LabelShort : 'NYS',							LabelMedium : 'NYS',					LabelLong : 'NYS' },
		'nyu'						: { LabelShort : 'NYU',							LabelMedium : 'Nyu',					LabelLong : 'Nyu' },
		'o0o'						: { LabelShort : 'O0O',							LabelMedium : 'o0o',					LabelLong : 'o0o' },
		'o2stk'						: { LabelShort : 'O2STK',						LabelMedium : 'O2STK',					LabelLong : 'O2STK' },
		'o69'						: { LabelShort : 'O69',							LabelMedium : 'O69',					LabelLong : 'O69' },
		'object'					: { LabelShort : 'OBJECT',						LabelMedium : 'OBjECT',					LabelLong : 'OBjECT' },
		'occor'						: { LabelShort : 'OCCOR',						LabelMedium : 'Occor',					LabelLong : 'Occor' },
		'octopus'					: { LabelShort : 'OCTOPUS',						LabelMedium : 'Octopus',					LabelLong : 'Octopus' },
		'ods'						: { LabelShort : 'ODS',							LabelMedium : 'ODS',					LabelLong : 'ODS' },
		'oem'						: { LabelShort : 'OEM',							LabelMedium : 'OEM',					LabelLong : 'OEM' },
		'oem1080'					: { LabelShort : 'OEM1080',						LabelMedium : 'OEM1080',					LabelLong : 'OEM1080' },
		'oft'						: { LabelShort : 'OFT',							LabelMedium : 'OFT',					LabelLong : 'OFT' },
		'ohd'						: { LabelShort : 'OHD',							LabelMedium : 'OHD',					LabelLong : 'OHD' },
		'oj'							: { LabelShort : 'OJ',							LabelMedium : 'Oj',						LabelLong : 'Oj' },
		'oki'						: { LabelShort : 'OKI',							LabelMedium : 'oki',					LabelLong : 'oki' },
		'okq'						: { LabelShort : 'OKQ',							LabelMedium : 'OKQ',					LabelLong : 'OKQ' },
		'oldseasons'					: { LabelShort : 'OLDSEASONS',					LabelMedium : 'OldSeasons',				LabelLong : 'OldSeasons' },
		'oldsman'					: { LabelShort : 'OLDSMAN',						LabelMedium : 'OldsMan',					LabelLong : 'OldsMan' },
		'ollandgroup'				: { LabelShort : 'OLLANDGROUP',					LabelMedium : 'OlLanDGroup',			LabelLong : 'OlLanDGroup' },
		'oma'						: { LabelShort : 'OMA',							LabelMedium : 'OMA',					LabelLong : 'OMA' },
		'omega'						: { LabelShort : 'OMEGA',						LabelMedium : 'OMEGA',					LabelLong : 'OMEGA' },
		'omer'						: { LabelShort : 'OMER',						LabelMedium : 'OMER',					LabelLong : 'OMER' },
		'omertahd'					: { LabelShort : 'OMERTAHD',					LabelMedium : 'OmertaHD',				LabelLong : 'OmertaHD' },
		'omfug'						: { LabelShort : 'OMFUG',						LabelMedium : 'OMFUG',					LabelLong : 'OMFUG' },
		'omgtv'						: { LabelShort : 'OMGTV',						LabelMedium : 'OMGtv',					LabelLong : 'OMGtv' },
		'omicron'					: { LabelShort : 'OMICRON',						LabelMedium : 'OMiCRON',					LabelLong : 'OMiCRON' },
		'omifast'					: { LabelShort : 'OMIFAST',						LabelMedium : 'Omifast',					LabelLong : 'Omifast' },
		'omikron'					: { LabelShort : 'OMIKRON',						LabelMedium : 'Omikron',					LabelLong : 'Omikron' },
		'omnic'						: { LabelShort : 'OMNIC',						LabelMedium : 'OmNiC',					LabelLong : 'OmNiC' },
		'omskbird'					: { LabelShort : 'OMSKBIRD',					LabelMedium : 'OmskBird',				LabelLong : 'OmskBird' },
		'ons'						: { LabelShort : 'ONS',							LabelMedium : 'ONS',					LabelLong : 'ONS' },
		'ontherun'					: { LabelShort : 'ONTHERUN',					LabelMedium : 'ontherun',				LabelLong : 'ontherun' },
		'oo'							: { LabelShort : 'OO',							LabelMedium : 'oO',						LabelLong : 'oO' },
		'oom'						: { LabelShort : 'OOM',							LabelMedium : 'OOM',					LabelLong : 'OOM' },
		'oosh'						: { LabelShort : 'OOSH',						LabelMedium : 'Oosh',					LabelLong : 'Oosh' },
		'oped'						: { LabelShort : 'OPED',						LabelMedium : 'OpeD',					LabelLong : 'OpeD' },
		'opentsubasa'				: { LabelShort : 'OPENTSUBASA',					LabelMedium : 'OpenTsubasa',			LabelLong : 'OpenTsubasa' },
		'opt'						: { LabelShort : 'OPT',							LabelMedium : 'OPT',					LabelLong : 'OPT' },
		'optic'						: { LabelShort : 'OPTIC',						LabelMedium : 'OPTiC',					LabelLong : 'OPTiC' },
		'orc'						: { LabelShort : 'ORC',							LabelMedium : 'ORC',					LabelLong : 'ORC' },
		'orca88'					: { LabelShort : 'ORCA88',						LabelMedium : 'ORCA88',					LabelLong : 'ORCA88' },
		'order'						: { LabelShort : 'ORDER',						LabelMedium : 'ORDER',					LabelLong : 'ORDER' },
		'orenji'					: { LabelShort : 'ORENJI',						LabelMedium : 'ORENJi',					LabelLong : 'ORENJi' },
		'organic'					: { LabelShort : 'ORGANIC',						LabelMedium : 'ORGANiC',					LabelLong : 'ORGANiC' },
		'orgo'						: { LabelShort : 'ORGO',						LabelMedium : 'ORGO',					LabelLong : 'ORGO' },
		'origen'					: { LabelShort : 'ORIGEN',						LabelMedium : 'ORiGEN',					LabelLong : 'ORiGEN' },
		'orphan'					: { LabelShort : 'ORPHAN',						LabelMedium : 'ORPHAN',					LabelLong : 'ORPHAN' },
		'orpheus'					: { LabelShort : 'ORPHEUS',						LabelMedium : 'ORPHEUS',					LabelLong : 'ORPHEUS' },
		'osiris'					: { LabelShort : 'OSIRIS',						LabelMedium : 'OSiRiS',					LabelLong : 'OSiRiS' },
		'ositv'						: { LabelShort : 'OSITV',						LabelMedium : 'OSiTV',					LabelLong : 'OSiTV' },
		'ott'						: { LabelShort : 'OTT',							LabelMedium : 'OTT',					LabelLong : 'OTT' },
		'otv'						: { LabelShort : 'OTV',							LabelMedium : 'OTV',					LabelLong : 'OTV' },
		'ouija'						: { LabelShort : 'OUIJA',						LabelMedium : 'OUIJA',					LabelLong : 'OUIJA' },
		'ourbits'					: { LabelShort : 'OURBITS',						LabelMedium : 'OurBits',					LabelLong : 'OurBits' },
		'oursuperpilaencode'			: { LabelShort : 'OURSUPERPILAENCODE',			LabelMedium : 'OurSuperPilaEncode',		LabelLong : 'OurSuperPilaEncode' },
		'outbreak'					: { LabelShort : 'OUTBREAK',					LabelMedium : 'OUTBREAK',				LabelLong : 'OUTBREAK' },
		'outdated'					: { LabelShort : 'OUTDATED',					LabelMedium : 'OUTDATED',				LabelLong : 'OUTDATED' },
		'ouzo'						: { LabelShort : 'OUZO',						LabelMedium : 'OUZO',					LabelLong : 'OUZO' },
		'ov3rl1f3'					: { LabelShort : 'OV3RL1F3',					LabelMedium : 'Ov3rl1f3',				LabelLong : 'Ov3rl1f3' },
		'ov3rload'					: { LabelShort : 'OV3RLOAD',					LabelMedium : 'Ov3rload',				LabelLong : 'Ov3rload' },
		'overtime'					: { LabelShort : 'OVERTIME',					LabelMedium : 'OVERTiME',				LabelLong : 'OVERTiME' },
		'oyhd'						: { LabelShort : 'OYHD',						LabelMedium : 'OYHD',					LabelLong : 'OYHD' },
		'ozlem'						: { LabelShort : 'OZLEM',						LabelMedium : 'Ozlem',					LabelLong : 'Ozlem' },
		'ozzy1'						: { LabelShort : 'OZZY1',						LabelMedium : 'OzZY1',					LabelLong : 'OzZY1' },
		'p0618'						: { LabelShort : 'P0618',						LabelMedium : 'p0618',					LabelLong : 'p0.618' },
		'p0w4'						: { LabelShort : 'P0W4',						LabelMedium : 'P0W4',					LabelLong : 'P0W4' },
		'p0w4dvd'					: { LabelShort : 'P0W4DVD',						LabelMedium : 'P0W4DVD',					LabelLong : 'P0W4DVD' },
		'p2p'						: { LabelShort : 'P2P',							LabelMedium : 'P2P',					LabelLong : 'P2P' },
		'p2pdl'						: { LabelShort : 'P2PDL',						LabelMedium : 'P2PDL',					LabelLong : 'P2PDL' },
		'p2u'						: { LabelShort : 'P2U',							LabelMedium : 'P2u',					LabelLong : 'P2u' },
		'p4dge'						: { LabelShort : 'P4DGE',						LabelMedium : 'P4DGE',					LabelLong : 'P4DGE' },
		'pa'							: { LabelShort : 'PA',							LabelMedium : 'pa',						LabelLong : 'p-a' },
		'paai'						: { LabelShort : 'PAAI',						LabelMedium : 'PAAI',					LabelLong : 'PAAI' },
		'paddo'						: { LabelShort : 'PADDO',						LabelMedium : 'PADDO',					LabelLong : 'PADDO' },
		'pahe'						: { LabelShort : 'PAHE',						LabelMedium : 'Pahe',					LabelLong : 'Pahe.in' },
		'pahein'					: { LabelShort : 'PAHEIN',						LabelMedium : 'Pahein',					LabelLong : 'Pahein' },
		'paleale'					: { LabelShort : 'PALEALE',						LabelMedium : 'PALEALE',					LabelLong : 'PALEALE' },
		'panda'						: { LabelShort : 'PANDA',						LabelMedium : 'PANDA',					LabelLong : 'PANDA' },
		'pandemonium'				: { LabelShort : 'PANDEMONIUM',					LabelMedium : 'PANDEMONiUM',			LabelLong : 'PANDEMONiUM' },
		'pankhabd'					: { LabelShort : 'PANKHABD',					LabelMedium : 'Pankhabd',				LabelLong : 'Pankhabd' },
		'paradox'					: { LabelShort : 'PARADOX',						LabelMedium : 'PARADOX',					LabelLong : 'PARADOX' },
		'paranoid06'					: { LabelShort : 'PARANOID06',					LabelMedium : 'paranoid06',				LabelLong : 'paranoid06' },
		'particle'					: { LabelShort : 'PARTICLE',					LabelMedium : 'PARTICLE',				LabelLong : 'PARTICLE' },
		'partyboy'					: { LabelShort : 'PARTYBOY',					LabelMedium : 'PartyBoy',				LabelLong : 'PartyBoy' },
		'pas'						: { LabelShort : 'PAS',							LabelMedium : 'PAS',					LabelLong : 'PAS' },
		'pasha'						: { LabelShort : 'PASHA',						LabelMedium : 'PASHA',					LabelLong : 'PASHA' },
		'paso77'					: { LabelShort : 'PASO77',						LabelMedium : 'Paso77',					LabelLong : 'Paso77' },
		'pat'						: { LabelShort : 'PAT',							LabelMedium : 'pat',					LabelLong : 'pat' },
		'pate'						: { LabelShort : 'PATE',						LabelMedium : 'PATE',					LabelLong : 'PATE' },
		'patrol'					: { LabelShort : 'PATROL',						LabelMedium : 'PaTrol',					LabelLong : 'PaTrol' },
		'paulista'					: { LabelShort : 'PAULISTA',					LabelMedium : 'Paulista',				LabelLong : 'Paulista' },
		'pb'							: { LabelShort : 'PB',							LabelMedium : 'pB',						LabelLong : 'pB' },
		'pbk'						: { LabelShort : 'PBK',							LabelMedium : 'PbK',					LabelLong : 'PbK' },
		'pc'							: { LabelShort : 'PC',							LabelMedium : 'PC',						LabelLong : 'PC' },
		'pch'						: { LabelShort : 'PCH',							LabelMedium : 'PCH',					LabelLong : 'PCH' },
		'pcroland'					: { LabelShort : 'PCROLAND',					LabelMedium : 'pcroland',				LabelLong : 'pcroland' },
		'pcsyndicate'				: { LabelShort : 'PCSYNDICATE',					LabelMedium : 'pcsyndicate',			LabelLong : 'pcsyndicate' },
		'pctnew'					: { LabelShort : 'PCTNEW',						LabelMedium : 'PctNew',					LabelLong : 'PctNew' },
		'peculate'					: { LabelShort : 'PECULATE',					LabelMedium : 'PECULATE',				LabelLong : 'PECULATE' },
		'peewee'					: { LabelShort : 'PEEWEE',						LabelMedium : 'PeeWee',					LabelLong : 'PeeWee' },
		'peppe'						: { LabelShort : 'PEPPE',						LabelMedium : 'PEPPE',					LabelLong : 'PEPPE' },
		'perfectionhd'				: { LabelShort : 'PERFECTIONHD',				LabelMedium : 'PerfectionHD',			LabelLong : 'PerfectionHD' },
		'peruguy'					: { LabelShort : 'PERUGUY',						LabelMedium : 'PeruGuy',					LabelLong : 'PeruGuy' },
		'petrified'					: { LabelShort : 'PETRIFIED',					LabelMedium : 'PETRiFiED',				LabelLong : 'PETRiFiED' },
		'pfa'						: { LabelShort : 'PFA',							LabelMedium : 'PFa',					LabelLong : 'PFa' },
		'phantom'					: { LabelShort : 'PHANTOM',						LabelMedium : 'Phantom',					LabelLong : 'Phantom' },
		'phase'						: { LabelShort : 'PHASE',						LabelMedium : 'phase',					LabelLong : 'phase' },
		'phd'						: { LabelShort : 'PHD',							LabelMedium : 'PHD',					LabelLong : 'PHD' },
		'phdteam'					: { LabelShort : 'PHDTEAM',						LabelMedium : 'PHDTeam',					LabelLong : 'PHDTeam' },
		'phenomenal'					: { LabelShort : 'PHENOMENAL',					LabelMedium : 'PHENOMENAL',				LabelLong : 'PHENOMENAL' },
		'phmhd'						: { LabelShort : 'PHMHD',						LabelMedium : 'PHMHD',					LabelLong : 'PHMHD' },
		'phobos'					: { LabelShort : 'PHOBOS',						LabelMedium : 'PHOBOS',					LabelLong : 'PHOBOS' },
		'phocis'					: { LabelShort : 'PHOCIS',						LabelMedium : 'PHOCiS',					LabelLong : 'PHOCiS' },
		'phoenix'					: { LabelShort : 'PHOENIX',						LabelMedium : 'PHOENiX',					LabelLong : 'PHOENiX' },
		'phoenixrg'					: { LabelShort : 'PHOENIXRG',					LabelMedium : 'PhoeniXRG',				LabelLong : 'PhoeniX-RG' },
		'phoque'					: { LabelShort : 'PHOQUE',						LabelMedium : 'PHoQUE',					LabelLong : 'PHoQUE' },
		'phr0sty'					: { LabelShort : 'PHR0STY',						LabelMedium : 'Phr0stY',					LabelLong : 'Phr0stY' },
		'phunpsyz'					: { LabelShort : 'PHUNPSYZ',					LabelMedium : 'PhunPsyz',				LabelLong : 'Phun.Psyz' },
		'pia'						: { LabelShort : 'PIA',							LabelMedium : 'PiA',					LabelLong : 'PiA' },
		'piephd'					: { LabelShort : 'PIEPHD',						LabelMedium : 'piepHD',					LabelLong : 'piepHD' },
		'pignus'					: { LabelShort : 'PIGNUS',						LabelMedium : 'PiGNUS',					LabelLong : 'PiGNUS' },
		'pikachu'					: { LabelShort : 'PIKACHU',						LabelMedium : 'PiKACHU',					LabelLong : 'PiKACHU' },
		'pikanet128'					: { LabelShort : 'PIKANET128',					LabelMedium : 'Pikanet128',				LabelLong : 'Pikanet128' },
		'pilaf'						: { LabelShort : 'PILAF',						LabelMedium : 'PiLAF',					LabelLong : 'PiLAF' },
		'pimp'						: { LabelShort : 'PIMP',						LabelMedium : 'PiMP',					LabelLong : 'PiMP' },
		'pimp4003'					: { LabelShort : 'PIMP4003',					LabelMedium : 'Pimp4003',				LabelLong : 'Pimp4003' },
		'pimprg'					: { LabelShort : 'PIMPRG',						LabelMedium : 'pimprg',					LabelLong : 'pimprg' },
		'pims'						: { LabelShort : 'PIMS',						LabelMedium : 'PiMS',					LabelLong : 'PiMS' },
		'ping'						: { LabelShort : 'PING',						LabelMedium : 'PiNG',					LabelLong : 'PiNG' },
		'pinkpanters'				: { LabelShort : 'PINKPANTERS',					LabelMedium : 'PiNKPANTERS',			LabelLong : 'PiNKPANTERS' },
		'pioneer'					: { LabelShort : 'PIONEER',						LabelMedium : 'PIONEER',					LabelLong : 'PIONEER' },
		'pipick'					: { LabelShort : 'PIPICK',						LabelMedium : 'PiPicK',					LabelLong : 'PiPicK' },
		'pir8'						: { LabelShort : 'PIR8',						LabelMedium : 'Pir8',					LabelLong : 'Pir8' },
		'piratemkv'					: { LabelShort : 'PIRATEMKV',					LabelMedium : 'PirateMKV',				LabelLong : 'PirateMKV' },
		'pitu'						: { LabelShort : 'PITU',						LabelMedium : 'Pitu',					LabelLong : 'Pitu' },
		'pitufo180'					: { LabelShort : 'PITUFO180',					LabelMedium : 'Pitufo180',				LabelLong : 'Pitufo180' },
		'pl3x'						: { LabelShort : 'PL3X',						LabelMedium : 'PL3X',					LabelLong : 'PL3X' },
		'plaid'						: { LabelShort : 'PLAID',						LabelMedium : 'PLAiD',					LabelLong : 'PLAiD' },
		'playbd'					: { LabelShort : 'PLAYBD',						LabelMedium : 'playBD',					LabelLong : 'playBD' },
		'playhd'					: { LabelShort : 'PLAYHD',						LabelMedium : 'PlayHD',					LabelLong : 'PlayHD' },
		'playnow'					: { LabelShort : 'PLAYNOW',						LabelMedium : 'PLAYNOW',					LabelLong : 'PLAYNOW' },
		'playready'					: { LabelShort : 'PLAYREADY',					LabelMedium : 'PLAYREADY',				LabelLong : 'PLAYREADY' },
		'playsd'					: { LabelShort : 'PLAYSD',						LabelMedium : 'PlaySD',					LabelLong : 'PlaySD' },
		'playtv'					: { LabelShort : 'PLAYTV',						LabelMedium : 'playTV',					LabelLong : 'playTV' },
		'playweb'					: { LabelShort : 'PLAYWEB',						LabelMedium : 'PlayWEB',					LabelLong : 'PlayWEB' },
		'playxd'					: { LabelShort : 'PLAYXD',						LabelMedium : 'playXD',					LabelLong : 'playXD' },
		'pluto'						: { LabelShort : 'PLUTO',						LabelMedium : 'PlutO',					LabelLong : 'PlutO' },
		'plutonium'					: { LabelShort : 'PLUTONIUM',					LabelMedium : 'PLUTONiUM',				LabelLong : 'PLUTONiUM' },
		'plzproper'					: { LabelShort : 'PLZPROPER',					LabelMedium : 'plzproper',				LabelLong : 'plzproper' },
		'pm'							: { LabelShort : 'PM',							LabelMedium : 'PM',						LabelLong : 'PM' },
		'pmhd'						: { LabelShort : 'PMHD',						LabelMedium : 'pmHD',					LabelLong : 'pmHD' },
		'pmp'						: { LabelShort : 'PMP',							LabelMedium : 'PmP',					LabelLong : 'PmP' },
		'pod'						: { LabelShort : 'POD',							LabelMedium : 'POD',					LabelLong : 'POD' },
		'podo'						: { LabelShort : 'PODO',						LabelMedium : 'PODO',					LabelLong : 'PODO' },
		'poe'						: { LabelShort : 'POE',							LabelMedium : 'POE',					LabelLong : 'POE' },
		'poiasd'					: { LabelShort : 'POIASD',						LabelMedium : 'POIASD',					LabelLong : 'POIASD' },
		'poke'						: { LabelShort : 'POKE',						LabelMedium : 'POKE',					LabelLong : 'POKE' },
		'polar'						: { LabelShort : 'POLAR',						LabelMedium : 'POLAR',					LabelLong : 'POLAR' },
		'poolla'					: { LabelShort : 'POOLLA',						LabelMedium : 'PoOlLa',					LabelLong : 'PoOlLa' },
		'poop'						: { LabelShort : 'POOP',						LabelMedium : 'POOP',					LabelLong : 'POOP' },
		'pop'						: { LabelShort : 'POP',							LabelMedium : 'Pop',					LabelLong : 'Pop' },
		'pophd'						: { LabelShort : 'POPHD',						LabelMedium : 'PopHD',					LabelLong : 'PopHD' },
		'portablius'					: { LabelShort : 'PORTABLIUS',					LabelMedium : 'Portablius',				LabelLong : 'Portablius' },
		'portos'					: { LabelShort : 'PORTOS',						LabelMedium : 'PORTOS',					LabelLong : 'PORTOS' },
		'positive'					: { LabelShort : 'POSITIVE',					LabelMedium : 'POSITIVE',				LabelLong : 'POSITIVE' },
		'postx'						: { LabelShort : 'POSTX',						LabelMedium : 'PosTX',					LabelLong : 'PosTX' },
		'pot'						: { LabelShort : 'POT',							LabelMedium : 'PoT',					LabelLong : 'PoT' },
		'pp'							: { LabelShort : 'PP',							LabelMedium : 'PP',						LabelLong : 'PP' },
		'ppb'						: { LabelShort : 'PPB',							LabelMedium : 'PPb',					LabelLong : 'PPb' },
		'ppq'						: { LabelShort : 'PPQ',							LabelMedium : 'PPQ',					LabelLong : 'PPQ' },
		'prd'						: { LabelShort : 'PRD',							LabelMedium : 'PRD',					LabelLong : 'PRD' },
		'precious'					: { LabelShort : 'PRECIOUS',					LabelMedium : 'PRECiOUS',				LabelLong : 'PRECiOUS' },
		'precursor'					: { LabelShort : 'PRECURSOR',					LabelMedium : 'PRECURSOR',				LabelLong : 'PRECURSOR' },
		'pretail'					: { LabelShort : 'PRETAIL',						LabelMedium : 'PRETAiL',					LabelLong : 'PRETAiL' },
		'preums'					: { LabelShort : 'PREUMS',						LabelMedium : 'PREUMS',					LabelLong : 'PREUMS' },
		'prevail'					: { LabelShort : 'PREVAIL',						LabelMedium : 'prevail',					LabelLong : 'prevail' },
		'primalhd'					: { LabelShort : 'PRIMALHD',					LabelMedium : 'PriMaLHD',				LabelLong : 'PriMaLHD' },
		'prime'						: { LabelShort : 'PRIME',						LabelMedium : 'PRIME',					LabelLong : 'PRIME' },
		'primehd'					: { LabelShort : 'PRIMEHD',						LabelMedium : 'PriMeHD',					LabelLong : 'PriMeHD' },
		'prince'					: { LabelShort : 'PRINCE',						LabelMedium : 'PRiNCE',					LabelLong : 'PRiNCE' },
		'pristine'					: { LabelShort : 'PRISTINE',					LabelMedium : 'PRiSTiNE',				LabelLong : 'PRiSTiNE' },
		'prithwi'					: { LabelShort : 'PRITHWI',						LabelMedium : 'prithwi',					LabelLong : 'prithwi' },
		'privatehd'					: { LabelShort : 'PRIVATEHD',					LabelMedium : 'PrivateHD',				LabelLong : 'PrivateHD' },
		'prod'						: { LabelShort : 'PROD',						LabelMedium : 'PROD',					LabelLong : 'PROD' },
		'prodji'					: { LabelShort : 'PRODJI',						LabelMedium : 'PRoDJi',					LabelLong : 'PRoDJi' },
		'prof'						: { LabelShort : 'PROF',						LabelMedium : 'PROF',					LabelLong : 'PROF' },
		'progress'					: { LabelShort : 'PROGRESS',					LabelMedium : 'PROGRESS',				LabelLong : 'PROGRESS' },
		'promise'					: { LabelShort : 'PROMISE',						LabelMedium : 'PROMiSE',					LabelLong : 'PROMiSE' },
		'prophets'					: { LabelShort : 'PROPHETS',					LabelMedium : 'PROPHETS',				LabelLong : 'PROPHETS' },
		'propl'						: { LabelShort : 'PROPL',						LabelMedium : 'ProPL',					LabelLong : 'ProPL' },
		'propltv'					: { LabelShort : 'PROPLTV',						LabelMedium : 'ProPLTV',					LabelLong : 'ProPLTV' },
		'proxy'						: { LabelShort : 'PROXY',						LabelMedium : 'PROXY',					LabelLong : 'PROXY' },
		'ps3team'					: { LabelShort : 'PS3TEAM',						LabelMedium : 'PS3TEAM',					LabelLong : 'PS3-TEAM' },
		'psa'						: { LabelShort : 'PSA',							LabelMedium : 'PSA',					LabelLong : 'PSA' },
		'pseudo'					: { LabelShort : 'PSEUDO',						LabelMedium : 'PSEUDO',					LabelLong : 'PSEUDO' },
		'psig'						: { LabelShort : 'PSIG',						LabelMedium : 'PSiG',					LabelLong : 'PSiG' },
		'psix'						: { LabelShort : 'PSIX',						LabelMedium : 'PsiX',					LabelLong : 'PsiX' },
		'pso'						: { LabelShort : 'PSO',							LabelMedium : 'PsO',					LabelLong : 'PsO' },
		'psv'						: { LabelShort : 'PSV',							LabelMedium : 'PSV',					LabelLong : 'PSV' },
		'psyc'						: { LabelShort : 'PSYC',						LabelMedium : 'Psyc',					LabelLong : 'Psyc' },
		'psychd'					: { LabelShort : 'PSYCHD',						LabelMedium : 'PSYCHD',					LabelLong : 'PSYCHD' },
		'psycho791'					: { LabelShort : 'PSYCHO791',					LabelMedium : 'PSYCHO791',				LabelLong : 'PSYCHO791' },
		'psypher'					: { LabelShort : 'PSYPHER',						LabelMedium : 'PSYPHER',					LabelLong : 'PSYPHER' },
		'pta'						: { LabelShort : 'PTA',							LabelMedium : 'PTA',					LabelLong : 'PTA' },
		'pter'						: { LabelShort : 'PTER',						LabelMedium : 'PTer',					LabelLong : 'PTer' },
		'ptnk'						: { LabelShort : 'PTNK',						LabelMedium : 'PTNK',					LabelLong : 'PTNK' },
		'ptp'						: { LabelShort : 'PTP',							LabelMedium : 'PtP',					LabelLong : 'PtP' },
		'ptpower'					: { LabelShort : 'PTPOWER',						LabelMedium : 'PTpOWeR',					LabelLong : 'PTpOWeR' },
		'pts'						: { LabelShort : 'PTS',							LabelMedium : 'PtS',					LabelLong : 'PtS' },
		'publichd'					: { LabelShort : 'PUBLICHD',					LabelMedium : 'PublicHD',				LabelLong : 'PublicHD' },
		'pudding'					: { LabelShort : 'PUDDING',						LabelMedium : 'PUDDING',					LabelLong : 'PUDDING' },
		'pukka'						: { LabelShort : 'PUKKA',						LabelMedium : 'PUKKA',					LabelLong : 'PUKKA' },
		'punch'						: { LabelShort : 'PUNCH',						LabelMedium : 'PUNCH',					LabelLong : 'PUNCH' },
		'punisher694'				: { LabelShort : 'PUNISHER694',					LabelMedium : 'Punisher694',			LabelLong : 'Punisher694' },
		'pure'						: { LabelShort : 'PURE',						LabelMedium : 'PURE',					LabelLong : 'PURE' },
		'pussyfoot'					: { LabelShort : 'PUSSYFOOT',					LabelMedium : 'PussyFoot',				LabelLong : 'PussyFoot' },
		'puzzle'					: { LabelShort : 'PUZZLE',						LabelMedium : 'PUZZLE',					LabelLong : 'PUZZLE' },
		'pvr'						: { LabelShort : 'PVR',							LabelMedium : 'PVR',					LabelLong : 'PVR' },
		'pwe'						: { LabelShort : 'PWE',							LabelMedium : 'PWE',					LabelLong : 'PWE' },
		'pxhd'						: { LabelShort : 'PXHD',						LabelMedium : 'PxHD',					LabelLong : 'PxHD' },
		'pyc'						: { LabelShort : 'PYC',							LabelMedium : 'PyC',					LabelLong : 'PyC' },
		'pze'						: { LabelShort : 'PZE',							LabelMedium : 'PZE',					LabelLong : 'PZE' },
		'pzk'						: { LabelShort : 'PZK',							LabelMedium : 'PZK',					LabelLong : 'PZK' },
		'qcf'						: { LabelShort : 'QCF',							LabelMedium : 'QCF',					LabelLong : 'QCF' },
		'qix'						: { LabelShort : 'QIX',							LabelMedium : 'QiX',					LabelLong : 'QiX' },
		'qman'						: { LabelShort : 'QMAN',						LabelMedium : 'Qman',					LabelLong : 'Qman' },
		'qmax'						: { LabelShort : 'QMAX',						LabelMedium : 'Qmax',					LabelLong : 'Qmax' },
		'qom'						: { LabelShort : 'QOM',							LabelMedium : 'QoM',					LabelLong : 'QoM' },
		'qoq'						: { LabelShort : 'QOQ',							LabelMedium : 'QOQ',					LabelLong : 'QOQ' },
		'qpel'						: { LabelShort : 'QPEL',						LabelMedium : 'QPEL',					LabelLong : 'QPEL' },
		'qqss44'					: { LabelShort : 'QQSS44',						LabelMedium : 'qqss44',					LabelLong : 'qqss44' },
		'qrc'						: { LabelShort : 'QRC',							LabelMedium : 'QRC',					LabelLong : 'QRC' },
		'qrips'						: { LabelShort : 'QRIPS',						LabelMedium : 'QRips',					LabelLong : 'QRips' },
		'qrus'						: { LabelShort : 'QRUS',						LabelMedium : 'QRUS',					LabelLong : 'QRUS' },
		'qsp'						: { LabelShort : 'QSP',							LabelMedium : 'QSP',					LabelLong : 'QSP' },
		'qtz'						: { LabelShort : 'QTZ',							LabelMedium : 'QTZ',					LabelLong : 'QTZ' },
		'queens'					: { LabelShort : 'QUEENS',						LabelMedium : 'QUEENS',					LabelLong : 'QUEENS' },
		'qui'						: { LabelShort : 'QUI',							LabelMedium : 'QUI',					LabelLong : 'QUI' },
		'qxr'						: { LabelShort : 'QXR',							LabelMedium : 'QxR',					LabelLong : 'QxR' },
		'r00t'						: { LabelShort : 'R00T',						LabelMedium : 'r00t',					LabelLong : 'r00t' },
		'r0b0t'						: { LabelShort : 'R0B0T',						LabelMedium : 'R0B0T',					LabelLong : 'R0B0T' },
		'r0cked'					: { LabelShort : 'R0CKED',						LabelMedium : 'R0CKED',					LabelLong : 'R0CKED' },
		'r10'						: { LabelShort : 'R10',							LabelMedium : 'R10',					LabelLong : 'R10' },
		'r2d2'						: { LabelShort : 'R2D2',						LabelMedium : 'R2D2',					LabelLong : 'R2D2' },
		'radius'					: { LabelShort : 'RADIUS',						LabelMedium : 'RaDiuS',					LabelLong : 'RaDiuS' },
		'rady'						: { LabelShort : 'RADY',						LabelMedium : 'RADY',					LabelLong : 'RADY' },
		'raindeer'					: { LabelShort : 'RAINDEER',					LabelMedium : 'RAiNDEER',				LabelLong : 'RAiNDEER' },
		'rakuv02'					: { LabelShort : 'RAKUV02',						LabelMedium : 'rakuv02',					LabelLong : 'rakuv02' },
		'rakuvfinhel'				: { LabelShort : 'RAKUVFINHEL',					LabelMedium : 'Rakuvfinhel',			LabelLong : 'Rakuvfinhel' },
		'randi'						: { LabelShort : 'RANDI',						LabelMedium : 'RANDi',					LabelLong : 'RANDi' },
		'ranvijay'					: { LabelShort : 'RANVIJAY',					LabelMedium : 'Ranvijay',				LabelLong : 'Ranvijay' },
		'raoul'						: { LabelShort : 'RAOUL',						LabelMedium : 'Raoul',					LabelLong : 'Raoul' },
		'rap'						: { LabelShort : 'RAP',							LabelMedium : 'RAP',					LabelLong : 'RAP' },
		'rapidcows'					: { LabelShort : 'RAPIDCOWS',					LabelMedium : 'RAPiDCOWS',				LabelLong : 'RAPiDCOWS' },
		'rapta'						: { LabelShort : 'RAPTA',						LabelMedium : 'Rapta',					LabelLong : 'Rapta' },
		'rarbg'						: { LabelShort : 'RARBG',						LabelMedium : 'RARBG',					LabelLong : 'RARBG' },
		'rartv'						: { LabelShort : 'RARTV',						LabelMedium : 'RARTV',					LabelLong : 'RARTV' },
		'ras'						: { LabelShort : 'RAS',							LabelMedium : 'RAS',					LabelLong : 'RAS' },
		'rastafariantargaryen'		: { LabelShort : 'RASTAFARIANTARGARYEN',		LabelMedium : 'RastafarianTargaryen',	LabelLong : 'RastafarianTargaryen' },
		'rax'						: { LabelShort : 'RAX',							LabelMedium : 'RaX',					LabelLong : 'RaX' },
		'rb'							: { LabelShort : 'RB',							LabelMedium : 'RB',						LabelLong : 'R-B' },
		'rb58'						: { LabelShort : 'RB58',						LabelMedium : 'RB58',					LabelLong : 'RB58' },
		'rbb'						: { LabelShort : 'RBB',							LabelMedium : 'RBB',					LabelLong : 'RBB' },
		'rbg'						: { LabelShort : 'RBG',							LabelMedium : 'RBG',					LabelLong : 'RBG' },
		'rbt'						: { LabelShort : 'RBT',							LabelMedium : 'RBT',					LabelLong : 'RBT' },
		'rc'							: { LabelShort : 'RC',							LabelMedium : 'RC',						LabelLong : 'R&C' },
		'rcdivx'					: { LabelShort : 'RCDIVX',						LabelMedium : 'RCDiVX',					LabelLong : 'RCDiVX' },
		'rcvr'						: { LabelShort : 'RCVR',						LabelMedium : 'RCVR',					LabelLong : 'RCVR' },
		'rd'							: { LabelShort : 'RD',							LabelMedium : 'RD',						LabelLong : 'RD' },
		'rdk123'					: { LabelShort : 'RDK123',						LabelMedium : 'RDK123',					LabelLong : 'RDK123' },
		'rdlinks'					: { LabelShort : 'RDLINKS',						LabelMedium : 'RDLinks',					LabelLong : 'RDLinks' },
		'rdvas'						: { LabelShort : 'RDVAS',						LabelMedium : 'RDVAS',					LabelLong : 'RDVAS' },
		'rdx'						: { LabelShort : 'RDX',							LabelMedium : 'rDX',					LabelLong : 'rDX' },
		'reactor'					: { LabelShort : 'REACTOR',						LabelMedium : 'REACTOR',					LabelLong : 'REACTOR' },
		'reaktor'					: { LabelShort : 'REAKTOR',						LabelMedium : 'Reaktor',					LabelLong : 'Reaktor' },
		'realdmdj'					: { LabelShort : 'REALDMDJ',					LabelMedium : 'realDMDJ',				LabelLong : 'realDMDJ' },
		'reaper'					: { LabelShort : 'REAPER',						LabelMedium : 'REAPER',					LabelLong : 'REAPER' },
		'reaperza'					: { LabelShort : 'REAPERZA',					LabelMedium : 'Reaperza',				LabelLong : 'Reaperza' },
		'reavers'					: { LabelShort : 'REAVERS',						LabelMedium : 'REAVERS',					LabelLong : 'REAVERS' },
		'rebels'					: { LabelShort : 'REBELS',						LabelMedium : 'REBELS',					LabelLong : 'REBELS' },
		'rebelsd'					: { LabelShort : 'REBELSD',						LabelMedium : 'RebelSD',					LabelLong : 'RebelSD' },
		'redblade'					: { LabelShort : 'REDBLADE',					LabelMedium : 'RedBlade',				LabelLong : 'RedBlade' },
		'redeamer'					: { LabelShort : 'REDEAMER',					LabelMedium : 'ReDeamer',				LabelLong : 'ReDe@mer' },
		'redone'					: { LabelShort : 'REDONE',						LabelMedium : 'ReDone',					LabelLong : 'ReDone' },
		'reel'						: { LabelShort : 'REEL',						LabelMedium : 'REEL',					LabelLong : 'REEL' },
		'refined'					: { LabelShort : 'REFINED',						LabelMedium : 'REFiNED',					LabelLong : 'REFiNED' },
		'regelrecht'					: { LabelShort : 'REGELRECHT',					LabelMedium : 'RegeLRechT',				LabelLong : 'RegeLRechT' },
		'regret'					: { LabelShort : 'REGRET',						LabelMedium : 'REGRET',					LabelLong : 'REGRET' },
		'reign'						: { LabelShort : 'REIGN',						LabelMedium : 'REiGN',					LabelLong : 'REiGN' },
		'rekode'					: { LabelShort : 'REKODE',						LabelMedium : 'REKoDE',					LabelLong : 'REKoDE' },
		'releaselounge'				: { LabelShort : 'RELEASELOUNGE',				LabelMedium : 'ReleaseLounge',			LabelLong : 'Release.Lounge' },
		'relentless'					: { LabelShort : 'RELENTLESS',					LabelMedium : 'ReLeNTLesS',				LabelLong : 'ReLeNTLesS' },
		'religious'					: { LabelShort : 'RELIGIOUS',					LabelMedium : 'RELiGiOUS',				LabelLong : 'RELiGiOUS' },
		'reloaded'					: { LabelShort : 'RELOADED',					LabelMedium : 'RELOADED',				LabelLong : 'RELOADED' },
		'rem'						: { LabelShort : 'REM',							LabelMedium : 'REM',					LabelLong : 'REM' },
		'remake'					: { LabelShort : 'REMAKE',						LabelMedium : 'REMAKE',					LabelLong : 'REMAKE' },
		'remarkable'					: { LabelShort : 'REMARKABLE',					LabelMedium : 'REMARKABLE',				LabelLong : 'REMARKABLE' },
		'remax'						: { LabelShort : 'REMAX',						LabelMedium : 'REMAX',					LabelLong : 'REMAX' },
		'renegades'					: { LabelShort : 'RENEGADES',					LabelMedium : 'RENEGADES',				LabelLong : 'RENEGADES' },
		'replica'					: { LabelShort : 'REPLICA',						LabelMedium : 'REPLICA',					LabelLong : 'REPLICA' },
		'reptile'					: { LabelShort : 'REPTILE',						LabelMedium : 'REPTiLE',					LabelLong : 'REPTiLE' },
		'republic'					: { LabelShort : 'REPUBLIC',					LabelMedium : 'REPUBLIC',				LabelLong : 'REPUBLIC' },
		'reserved'					: { LabelShort : 'RESERVED',					LabelMedium : 'Reserved',				LabelLong : 'Reserved' },
		'resistance'					: { LabelShort : 'RESISTANCE',					LabelMedium : 'RESiSTANCE',				LabelLong : 'RESiSTANCE' },
		'resurrection'				: { LabelShort : 'RESURRECTION',				LabelMedium : 'REsuRRecTioN',			LabelLong : 'REsuRRecTioN' },
		'retreat'					: { LabelShort : 'RETREAT',						LabelMedium : 'RETREAT',					LabelLong : 'RETREAT' },
		'retro'						: { LabelShort : 'RETRO',						LabelMedium : 'RETRO',					LabelLong : 'RETRO' },
		'rets'						: { LabelShort : 'RETS',						LabelMedium : 'Rets',					LabelLong : 'Rets' },
		'rev'						: { LabelShort : 'REV',							LabelMedium : 'rev',					LabelLong : 'rev' },
		'reveille'					: { LabelShort : 'REVEILLE',					LabelMedium : 'REVEiLLE',				LabelLong : 'REVEiLLE' },
		'revittony'					: { LabelShort : 'REVITTONY',					LabelMedium : 'revittony',				LabelLong : 'revittony' },
		'revteam'					: { LabelShort : 'REVTEAM',						LabelMedium : 'REVTEAM',					LabelLong : 'REVTEAM' },
		'reward'					: { LabelShort : 'REWARD',						LabelMedium : 'REWARD',					LabelLong : 'REWARD' },
		'rg'							: { LabelShort : 'RG',							LabelMedium : 'rG',						LabelLong : 'rG' },
		'rh'							: { LabelShort : 'RH',							LabelMedium : 'RH',						LabelLong : 'RH' },
		'rhd'						: { LabelShort : 'RHD',							LabelMedium : 'RHD',					LabelLong : 'RHD' },
		'rhood'						: { LabelShort : 'RHOOD',						LabelMedium : 'RHooD',					LabelLong : 'RHooD' },
		'rias'						: { LabelShort : 'RIAS',						LabelMedium : 'RIAS',					LabelLong : 'RIAS' },
		'rick'						: { LabelShort : 'RICK',						LabelMedium : 'RiCK',					LabelLong : 'RiCK' },
		'ricky'						: { LabelShort : 'RICKY',						LabelMedium : 'RiCKY',					LabelLong : 'RiCKY' },
		'riddlera'					: { LabelShort : 'RIDDLERA',					LabelMedium : 'RiddlerA',				LabelLong : 'RiddlerA' },
		'rifftrax'					: { LabelShort : 'RIFFTRAX',					LabelMedium : 'Rifftrax',				LabelLong : 'Rifftrax' },
		'rig'						: { LabelShort : 'RIG',							LabelMedium : 'RIG',					LabelLong : 'RIG' },
		'rightsize'					: { LabelShort : 'RIGHTSIZE',					LabelMedium : 'RightSiZE',				LabelLong : 'RightSiZE' },
		'ripley'					: { LabelShort : 'RIPLEY',						LabelMedium : 'RIPLEY',					LabelLong : 'RIPLEY' },
		'riprg'						: { LabelShort : 'RIPRG',						LabelMedium : 'RiPRG',					LabelLong : 'RiPRG' },
		'rishibhai'					: { LabelShort : 'RISHIBHAI',					LabelMedium : 'RishiBhai',				LabelLong : 'RishiBhai' },
		'risingsun'					: { LabelShort : 'RISINGSUN',					LabelMedium : 'RisingSun',				LabelLong : 'Rising.Sun' },
		'ritalin'					: { LabelShort : 'RITALIN',						LabelMedium : 'RiTALiN',					LabelLong : 'RiTALiN' },
		'ritalix'					: { LabelShort : 'RITALIX',						LabelMedium : 'RiTALiX',					LabelLong : 'RiTALiX' },
		'river'						: { LabelShort : 'RIVER',						LabelMedium : 'RiVER',					LabelLong : 'RiVER' },
		'rj'							: { LabelShort : 'RJ',							LabelMedium : 'RJ',						LabelLong : 'RJ' },
		'rjaa'						: { LabelShort : 'RJAA',						LabelMedium : 'Rjaa',					LabelLong : 'Rjaa' },
		'rknor'						: { LabelShort : 'RKNOR',						LabelMedium : 'RKNOR',					LabelLong : 'R.KNOR' },
		'rknorloading'				: { LabelShort : 'RKNORLOADING',				LabelMedium : 'RKnorloading',			LabelLong : 'R_Knorloading' },
		'rkrips'					: { LabelShort : 'RKRIPS',						LabelMedium : 'RKRips',					LabelLong : 'RKRips' },
		'rlf'						: { LabelShort : 'RLF',							LabelMedium : 'RLF',					LabelLong : 'RLF' },
		'rmp4l'						: { LabelShort : 'RMP4L',						LabelMedium : 'RMP4L',					LabelLong : 'RMP4L' },
		'rms'						: { LabelShort : 'RMS',							LabelMedium : 'RMS',					LabelLong : 'RMS' },
		'rmt'						: { LabelShort : 'RMT',							LabelMedium : 'RMT',					LabelLong : 'RMT' },
		'rmteam'					: { LabelShort : 'RMTEAM',						LabelMedium : 'RMTeam',					LabelLong : 'RMTeam' },
		'rmx'						: { LabelShort : 'RMX',							LabelMedium : 'RMx',					LabelLong : 'RMx' },
		'rnc'						: { LabelShort : 'RNC',							LabelMedium : 'RnC',					LabelLong : 'RnC' },
		'rob'						: { LabelShort : 'ROB',							LabelMedium : 'RoB',					LabelLong : 'RoB' },
		'robin'						: { LabelShort : 'ROBIN',						LabelMedium : 'ROBiN',					LabelLong : 'ROBiN' },
		'robo'						: { LabelShort : 'ROBO',						LabelMedium : 'ROBO',					LabelLong : 'ROBO' },
		'robots'					: { LabelShort : 'ROBOTS',						LabelMedium : 'ROBOTS',					LabelLong : 'ROBOTS' },
		'roccat'					: { LabelShort : 'ROCCAT',						LabelMedium : 'ROCCaT',					LabelLong : 'ROCCaT' },
		'rockblueladyrg'			: { LabelShort : 'ROCKBLUELADYRG',				LabelMedium : 'RoCKBlueLadyRG',			LabelLong : 'RoCK&BlueLadyRG' },
		'rockefeller'				: { LabelShort : 'ROCKEFELLER',					LabelMedium : 'ROCKEFELLER',			LabelLong : 'ROCKEFELLER' },
		'rockriot'					: { LabelShort : 'ROCKRIOT',					LabelMedium : 'RoCKRioT',				LabelLong : 'RoCKRioT' },
		'rofl'						: { LabelShort : 'ROFL',						LabelMedium : 'RoFL',					LabelLong : 'RoFL' },
		'roflcopter2110'			: { LabelShort : 'ROFLCOPTER2110',				LabelMedium : 'roflcopter2110',			LabelLong : 'roflcopter2110' },
		'rog'						: { LabelShort : 'ROG',							LabelMedium : 'RoG',					LabelLong : 'RoG' },
		'roger'						: { LabelShort : 'ROGER',						LabelMedium : 'ROGER',					LabelLong : 'ROGER' },
		'roimez'					: { LabelShort : 'ROIMEZ',						LabelMedium : 'ROIMEZ',					LabelLong : 'ROIMEZ' },
		'roland'					: { LabelShort : 'ROLAND',						LabelMedium : 'ROLAND',					LabelLong : 'ROLAND' },
		'ronin'						: { LabelShort : 'RONIN',						LabelMedium : 'ROniN',					LabelLong : 'ROn!N' },
		'roor'						: { LabelShort : 'ROOR',						LabelMedium : 'ROOR',					LabelLong : 'ROOR' },
		'rough'						: { LabelShort : 'ROUGH',						LabelMedium : 'ROUGH',					LabelLong : 'ROUGH' },
		'rovers'					: { LabelShort : 'ROVERS',						LabelMedium : 'ROVERS',					LabelLong : 'ROVERS' },
		'royskatt'					: { LabelShort : 'ROYSKATT',					LabelMedium : 'Royskatt',				LabelLong : 'Royskatt' },
		'rpg'						: { LabelShort : 'RPG',							LabelMedium : 'RPG',					LabelLong : 'RPG' },
		'rrh'						: { LabelShort : 'RRH',							LabelMedium : 'RRH',					LabelLong : 'RRH' },
		'rs'							: { LabelShort : 'RS',							LabelMedium : 'RS',						LabelLong : 'RS' },
		'rsg'						: { LabelShort : 'RSG',							LabelMedium : 'RSG',					LabelLong : 'RSG' },
		'rta'						: { LabelShort : 'RTA',							LabelMedium : 'RTA',					LabelLong : 'RTA' },
		'rtfm'						: { LabelShort : 'RTFM',						LabelMedium : 'RTFM',					LabelLong : 'RTFM' },
		'rtl'						: { LabelShort : 'RTL',							LabelMedium : 'RTL',					LabelLong : 'RTL' },
		'rtm'						: { LabelShort : 'RTM',							LabelMedium : 'RTM',					LabelLong : 'RTM' },
		'rtn'						: { LabelShort : 'RTN',							LabelMedium : 'RTN',					LabelLong : 'RTN' },
		'ru4hd'						: { LabelShort : 'RU4HD',						LabelMedium : 'RU4HD',					LabelLong : 'RU4HD' },
		'ruby'						: { LabelShort : 'RUBY',						LabelMedium : 'RUBY',					LabelLong : 'RUBY' },
		'rucucu'					: { LabelShort : 'RUCUCU',						LabelMedium : 'rucucu',					LabelLong : 'rucucu' },
		'rude'						: { LabelShort : 'RUDE',						LabelMedium : 'RuDE',					LabelLong : 'RuDE' },
		'rudos'						: { LabelShort : 'RUDOS',						LabelMedium : 'RUDOS',					LabelLong : 'RUDOS' },
		'rumour'					: { LabelShort : 'RUMOUR',						LabelMedium : 'RUMOUR',					LabelLong : 'RUMOUR' },
		'runner'					: { LabelShort : 'RUNNER',						LabelMedium : 'RUNNER',					LabelLong : 'RUNNER' },
		'rusted'					: { LabelShort : 'RUSTED',						LabelMedium : 'RUSTED',					LabelLong : 'RUSTED' },
		'rustle'					: { LabelShort : 'RUSTLE',						LabelMedium : 'RUSTLE',					LabelLong : 'RUSTLE' },
		'rutracker'					: { LabelShort : 'RUTRACKER',					LabelMedium : 'rutracker',				LabelLong : 'rutracker' },
		'rwp'						: { LabelShort : 'RWP',							LabelMedium : 'RWP',					LabelLong : 'RWP' },
		'rx'							: { LabelShort : 'RX',							LabelMedium : 'Rx',						LabelLong : 'Rx' },
		'ryan'						: { LabelShort : 'RYAN',						LabelMedium : 'RYAN',					LabelLong : 'RYAN' },
		'ryotox'					: { LabelShort : 'RYOTOX',						LabelMedium : 'Ryotox',					LabelLong : 'Ryotox' },
		'ryuuga'					: { LabelShort : 'RYUUGA',						LabelMedium : 'ryuuga',					LabelLong : 'ryuuga' },
		'rzerox'					: { LabelShort : 'RZEROX',						LabelMedium : 'RZeroX',					LabelLong : 'RZeroX' },
		'rzf'						: { LabelShort : 'RZF',							LabelMedium : 'RZF',					LabelLong : 'RZF' },
		'rzp'						: { LabelShort : 'RZP',							LabelMedium : 'RZP',					LabelLong : 'RZP' },
		's0ld13r'					: { LabelShort : 'S0LD13R',						LabelMedium : 'S0LD13R',					LabelLong : 'S0LD13R' },
		's4a'						: { LabelShort : 'S4A',							LabelMedium : 'S4A',					LabelLong : 'S4A' },
		's4l'						: { LabelShort : 'S4L',							LabelMedium : 'S4L',					LabelLong : 'S4L' },
		's8'							: { LabelShort : 'S8',							LabelMedium : 'S8',						LabelLong : 'S8' },
		's8rhino'					: { LabelShort : 'S8RHINO',						LabelMedium : 'S8RHiNO',					LabelLong : 'S8RHiNO' },
		'sa'							: { LabelShort : 'SA',							LabelMedium : 'SA',						LabelLong : 'S-A' },
		'sa89'						: { LabelShort : 'SA89',						LabelMedium : 'SA89',					LabelLong : 'SA89' },
		'sadpanda'					: { LabelShort : 'SADPANDA',					LabelMedium : 'SADPANDA',				LabelLong : 'SADPANDA' },
		'safety'					: { LabelShort : 'SAFETY',						LabelMedium : 'SAFETY',					LabelLong : 'SAFETY' },
		'sage'						: { LabelShort : 'SAGE',						LabelMedium : 'SAGE',					LabelLong : 'SAGE' },
		'saicord'					: { LabelShort : 'SAICORD',						LabelMedium : 'Saicord',					LabelLong : 'Saicord' },
		'saimorny'					: { LabelShort : 'SAIMORNY',					LabelMedium : 'SAiMORNY',				LabelLong : 'SAiMORNY' },
		'saints'					: { LabelShort : 'SAINTS',						LabelMedium : 'SAiNTS',					LabelLong : 'SAiNTS' },
		'sajid790'					: { LabelShort : 'SAJID790',					LabelMedium : 'Sajid790',				LabelLong : 'Sajid790' },
		'salt'						: { LabelShort : 'SALT',						LabelMedium : 'SALT',					LabelLong : 'SALT' },
		'sam'						: { LabelShort : 'SAM',							LabelMedium : 'SAM',					LabelLong : 'SAM' },
		'samfd'						: { LabelShort : 'SAMFD',						LabelMedium : 'SAMFD',					LabelLong : 'SAMFD' },
		'sammie'					: { LabelShort : 'SAMMIE',						LabelMedium : 'saMMie',					LabelLong : 'saMMie' },
		'sampa'						: { LabelShort : 'SAMPA',						LabelMedium : 'SAMPA',					LabelLong : 'SAMPA' },
		'samuel98'					: { LabelShort : 'SAMUEL98',					LabelMedium : 'SAMUEL98',				LabelLong : 'SAMUEL98' },
		'santi'						: { LabelShort : 'SANTI',						LabelMedium : 'SANTI',					LabelLong : 'SANTI' },
		'saphire'					: { LabelShort : 'SAPHIRE',						LabelMedium : 'SAPHiRE',					LabelLong : 'SAPHiRE' },
		'sapphire'					: { LabelShort : 'SAPPHIRE',					LabelMedium : 'SAPPHIRE',				LabelLong : 'SAPPHIRE' },
		'sartre'					: { LabelShort : 'SARTRE',						LabelMedium : 'SARTRE',					LabelLong : 'SARTRE' },
		'sashimi'					: { LabelShort : 'SASHIMI',						LabelMedium : 'SaSHiMi',					LabelLong : 'SaSHiMi' },
		'satanic'					: { LabelShort : 'SATANIC',						LabelMedium : 'SATANiC',					LabelLong : 'SATANiC' },
		'savannah'					: { LabelShort : 'SAVANNAH',					LabelMedium : 'SAVANNAH',				LabelLong : 'SAVANNAH' },
		'saviour'					: { LabelShort : 'SAVIOUR',						LabelMedium : 'SAViOUR',					LabelLong : 'SAViOUR' },
		'sbr'						: { LabelShort : 'SBR',							LabelMedium : 'SbR',					LabelLong : 'SbR' },
		'sby'						: { LabelShort : 'SBY',							LabelMedium : 'SbY',					LabelLong : 'SbY' },
		'scarabey'					: { LabelShort : 'SCARABEY',					LabelMedium : 'Scarabey',				LabelLong : 'Scarabey' },
		'scared'					: { LabelShort : 'SCARED',						LabelMedium : 'SCARED',					LabelLong : 'SCARED' },
		'scarfilm'					: { LabelShort : 'SCARFILM',					LabelMedium : 'ScarFilm',				LabelLong : 'ScarFilm' },
		'sceneguardians'			: { LabelShort : 'SCENEGUARDIANS',				LabelMedium : 'SceneGuardians',			LabelLong : 'SceneGuardians' },
		'schizo'					: { LabelShort : 'SCHIZO',						LabelMedium : 'SChiZO',					LabelLong : 'SChiZO' },
		'scientology'				: { LabelShort : 'SCIENTOLOGY',					LabelMedium : 'SCiENTOLOGY',			LabelLong : 'SCiENTOLOGY' },
		'scones'					: { LabelShort : 'SCONES',						LabelMedium : 'SCONES',					LabelLong : 'SCONES' },
		'scorn'						: { LabelShort : 'SCORN',						LabelMedium : 'SCORN',					LabelLong : 'SCORN' },
		'scotluhd'					: { LabelShort : 'SCOTLUHD',					LabelMedium : 'SCOTLUHD',				LabelLong : 'SCOTLUHD' },
		'scream'					: { LabelShort : 'SCREAM',						LabelMedium : 'SCREAM',					LabelLong : 'SCREAM' },
		'scy'						: { LabelShort : 'SCY',							LabelMedium : 'SCY',					LabelLong : 'SCY' },
		'sdc'						: { LabelShort : 'SDC',							LabelMedium : 'SDC',					LabelLong : 'SDC' },
		'sdi'						: { LabelShort : 'SDI',							LabelMedium : 'SDI',					LabelLong : 'SDI' },
		'secrecy'					: { LabelShort : 'SECRECY',						LabelMedium : 'SECRECY',					LabelLong : 'SECRECY' },
		'secretmyth'					: { LabelShort : 'SECRETMYTH',					LabelMedium : 'SecretMyth',				LabelLong : 'SecretMyth' },
		'secretos'					: { LabelShort : 'SECRETOS',					LabelMedium : 'SECRETOS',				LabelLong : 'SECRETOS' },
		'sector'					: { LabelShort : 'SECTOR',						LabelMedium : 'SECTOR',					LabelLong : 'SECTOR' },
		'sector7'					: { LabelShort : 'SECTOR7',						LabelMedium : 'SECTOR7',					LabelLong : 'SECTOR7' },
		'seedup'					: { LabelShort : 'SEEDUP',						LabelMedium : 'SeedUp',					LabelLong : 'SeedUp' },
		'seehd'						: { LabelShort : 'SEEHD',						LabelMedium : 'SeeHD',					LabelLong : 'SeeHD' },
		'seight'					: { LabelShort : 'SEIGHT',						LabelMedium : 'SEiGHT',					LabelLong : 'SEiGHT' },
		'selezen'					: { LabelShort : 'SELEZEN',						LabelMedium : 'seleZen',					LabelLong : 'seleZen' },
		'semantics'					: { LabelShort : 'SEMANTICS',					LabelMedium : 'SEMANTiCS',				LabelLong : 'SEMANTiCS' },
		'semtex'					: { LabelShort : 'SEMTEX',						LabelMedium : 'SEMTEX',					LabelLong : 'SEMTEX' },
		'senation'					: { LabelShort : 'SENATION',					LabelMedium : 'SENATiON',				LabelLong : 'SENATiON' },
		'senpai'					: { LabelShort : 'SENPAI',						LabelMedium : 'SENPAI',					LabelLong : 'SENPAI' },
		'septic'					: { LabelShort : 'SEPTIC',						LabelMedium : 'SEPTiC',					LabelLong : 'SEPTiC' },
		'ser'						: { LabelShort : 'SER',							LabelMedium : 'SER',					LabelLong : 'SER' },
		'seriously'					: { LabelShort : 'SERIOUSLY',					LabelMedium : 'SERIOUSLY',				LabelLong : 'SERIOUSLY' },
		'serum'						: { LabelShort : 'SERUM',						LabelMedium : 'SERUM',					LabelLong : 'SERUM' },
		'seskapile'					: { LabelShort : 'SESKAPILE',					LabelMedium : 'SESKAPiLE',				LabelLong : 'SESKAPiLE' },
		'sev'						: { LabelShort : 'SEV',							LabelMedium : 'SEV',					LabelLong : 'SEV' },
		'seventwenty'				: { LabelShort : 'SEVENTWENTY',					LabelMedium : 'SEVENTWENTY',			LabelLong : 'SEVENTWENTY' },
		'sf'							: { LabelShort : 'SF',							LabelMedium : 'SF',						LabelLong : 'SF' },
		'sfm'						: { LabelShort : 'SFM',							LabelMedium : 'SFM',					LabelLong : 'SFM' },
		'sfs'						: { LabelShort : 'SFS',							LabelMedium : 'SFS',					LabelLong : 'SFS' },
		'sft'						: { LabelShort : 'SFT',							LabelMedium : 'SFT',					LabelLong : 'SFT' },
		'sg'							: { LabelShort : 'SG',							LabelMedium : 'SG',						LabelLong : 'S-G' },
		'sh3lby'					: { LabelShort : 'SH3LBY',						LabelMedium : 'SH3LBY',					LabelLong : 'SH3LBY' },
		'shaanig'					: { LabelShort : 'SHAANIG',						LabelMedium : 'ShAaNiG',					LabelLong : 'ShAaNiG' },
		'shadow'					: { LabelShort : 'SHADOW',						LabelMedium : 'SHADOW',					LabelLong : 'SHADOW' },
		'shadowman'					: { LabelShort : 'SHADOWMAN',					LabelMedium : 'Shadowman',				LabelLong : 'Shadowman' },
		'sharereactor'				: { LabelShort : 'SHAREREACTOR',				LabelMedium : 'ShareReactor',			LabelLong : 'ShareReactor' },
		'sharphd'					: { LabelShort : 'SHARPHD',						LabelMedium : 'SharpHD',					LabelLong : 'SharpHD' },
		'sharpysword'				: { LabelShort : 'SHARPYSWORD',					LabelMedium : 'sharpysword',			LabelLong : 'sharpysword' },
		'shd'						: { LabelShort : 'SHD',							LabelMedium : 'SHD',					LabelLong : 'SHD' },
		'shinigami'					: { LabelShort : 'SHINIGAMI',					LabelMedium : 'SHiNiGAMi',				LabelLong : 'SHiNiGAMi' },
		'shinobi'					: { LabelShort : 'SHINOBI',						LabelMedium : 'ShiNobi',					LabelLong : 'ShiNobi' },
		'shiro'						: { LabelShort : 'SHIRO',						LabelMedium : 'shiro',					LabelLong : 'shiro' },
		'shitbox'					: { LabelShort : 'SHITBOX',						LabelMedium : 'SHITBOX',					LabelLong : 'SHITBOX' },
		'shitbusters'				: { LabelShort : 'SHITBUSTERS',					LabelMedium : 'ShitBusters',			LabelLong : 'ShitBusters' },
		'shitsony'					: { LabelShort : 'SHITSONY',					LabelMedium : 'SHiTSoNy',				LabelLong : 'SHiTSoNy' },
		'shitspread'					: { LabelShort : 'SHITSPREAD',					LabelMedium : 'SHiTSPREAD',				LabelLong : 'SHiTSPREAD' },
		'shitty'					: { LabelShort : 'SHITTY',						LabelMedium : 'SHiTTy',					LabelLong : 'SHiTTy' },
		'sho'						: { LabelShort : 'SHO',							LabelMedium : 'SHO',					LabelLong : 'SHO' },
		'shock'						: { LabelShort : 'SHOCK',						LabelMedium : 'ShocK',					LabelLong : 'ShocK' },
		'shortbrehd'					: { LabelShort : 'SHORTBREHD',					LabelMedium : 'SHORTBREHD',				LabelLong : 'SHORTBREHD' },
		'shortrips'					: { LabelShort : 'SHORTRIPS',					LabelMedium : 'ShortRips',				LabelLong : 'ShortRips' },
		'shotv'						: { LabelShort : 'SHOTV',						LabelMedium : 'shoTV',					LabelLong : 'shoTV' },
		'showehd'					: { LabelShort : 'SHOWEHD',						LabelMedium : 'SHOWEHD',					LabelLong : 'SHOWEHD' },
		'shr'						: { LabelShort : 'SHR',							LabelMedium : 'SHR',					LabelLong : 'SHR' },
		'shreddie'					: { LabelShort : 'SHREDDIE',					LabelMedium : 'SHREDDiE',				LabelLong : 'SHREDDiE' },
		'shrpy'						: { LabelShort : 'SHRPY',						LabelMedium : 'SHRPY',					LabelLong : 'SHRPY' },
		'shunpo'					: { LabelShort : 'SHUNPO',						LabelMedium : 'SHUNPO',					LabelLong : 'SHUNPO' },
		'siambit'					: { LabelShort : 'SIAMBIT',						LabelMedium : 'Siambit',					LabelLong : 'Siambit' },
		'sic'						: { LabelShort : 'SIC',							LabelMedium : 'SiC',					LabelLong : 'SiC' },
		'sicario'					: { LabelShort : 'SICARIO',						LabelMedium : 'SICARIO',					LabelLong : 'SICARIO' },
		'sicfoi'					: { LabelShort : 'SICFOI',						LabelMedium : 'SiCFoI',					LabelLong : 'SiCFoI' },
		'sigeris'					: { LabelShort : 'SIGERIS',						LabelMedium : 'SiGERiS',					LabelLong : 'SiGERiS' },
		'sight'						: { LabelShort : 'SIGHT',						LabelMedium : 'SiGHT',					LabelLong : 'SiGHT' },
		'sigla'						: { LabelShort : 'SIGLA',						LabelMedium : 'SiGLA',					LabelLong : 'SiGLA' },
		'sigma'						: { LabelShort : 'SIGMA',						LabelMedium : 'SiGMA',					LabelLong : 'SiGMA' },
		'silence'					: { LabelShort : 'SILENCE',						LabelMedium : 'SILENCE',					LabelLong : 'SILENCE' },
		'silent'					: { LabelShort : 'SILENT',						LabelMedium : 'SiLENT',					LabelLong : 'SiLENT' },
		'sillybird'					: { LabelShort : 'SILLYBIRD',					LabelMedium : 'SillyBird',				LabelLong : 'SillyBird' },
		'silu'						: { LabelShort : 'SILU',						LabelMedium : 'SiLU',					LabelLong : 'SiLU' },
		'silver007'					: { LabelShort : 'SILVER007',					LabelMedium : 'Silver007',				LabelLong : 'Silver007' },
		'silverrg'					: { LabelShort : 'SILVERRG',					LabelMedium : 'SilverRG',				LabelLong : 'Silver.RG' },
		'simba'						: { LabelShort : 'SIMBA',						LabelMedium : 'SiMbA',					LabelLong : 'SiMbA' },
		'simple'					: { LabelShort : 'SIMPLE',						LabelMedium : 'SiMPLE',					LabelLong : 'SiMPLE' },
		'sin'						: { LabelShort : 'SIN',							LabelMedium : 'SiN',					LabelLong : 'SiN' },
		'sinister'					: { LabelShort : 'SINISTER',					LabelMedium : 'SINISTER',				LabelLong : 'SINISTER' },
		'sinners'					: { LabelShort : 'SINNERS',						LabelMedium : 'SiNNERS',					LabelLong : 'SiNNERS' },
		'siriusshare'				: { LabelShort : 'SIRIUSSHARE',					LabelMedium : 'SiRiUssHaRe',			LabelLong : 'SiRiUs.sHaRe' },
		'sirpaul'					: { LabelShort : 'SIRPAUL',						LabelMedium : 'SirPaul',					LabelLong : 'Sir.Paul' },
		'siso'						: { LabelShort : 'SISO',						LabelMedium : 'SiSO',					LabelLong : 'SiSO' },
		'sit'						: { LabelShort : 'SIT',							LabelMedium : 'SiT',					LabelLong : 'SiT' },
		'sitv'						: { LabelShort : 'SITV',						LabelMedium : 'SiTV',					LabelLong : 'SiTV' },
		'sj'							: { LabelShort : 'SJ',							LabelMedium : 'SJ',						LabelLong : 'SJ' },
		'sjca'						: { LabelShort : 'SJCA',						LabelMedium : 'SJCA',					LabelLong : 'SJCA' },
		'ska'						: { LabelShort : 'SKA',							LabelMedium : 'SKA',					LabelLong : 'SKA' },
		'skaliwagz'					: { LabelShort : 'SKALIWAGZ',					LabelMedium : 'SKALiWAGZ',				LabelLong : 'SKALiWAGZ' },
		'skazhutin'					: { LabelShort : 'SKAZHUTIN',					LabelMedium : 'Skazhutin',				LabelLong : 'Skazhutin' },
		'skedaddle'					: { LabelShort : 'SKEDADDLE',					LabelMedium : 'SKEDADDLE',				LabelLong : 'SKEDADDLE' },
		'skgtv'						: { LabelShort : 'SKGTV',						LabelMedium : 'SKGTV',					LabelLong : 'SKGTV' },
		'skizoid'					: { LabelShort : 'SKIZOID',						LabelMedium : 'SKiZOiD',					LabelLong : 'SKiZOiD' },
		'skorpion'					: { LabelShort : 'SKORPION',					LabelMedium : 'skorpion',				LabelLong : 'skorpion' },
		'skrin'						: { LabelShort : 'SKRIN',						LabelMedium : 'SkRiN',					LabelLong : 'SkRiN' },
		'skyrg'						: { LabelShort : 'SKYRG',						LabelMedium : 'SKYRG',					LabelLong : 'SKYRG' },
		'sl'							: { LabelShort : 'SL',							LabelMedium : 'SL',						LabelLong : 'SL' },
		'slag'						: { LabelShort : 'SLAG',						LabelMedium : 'SLAG',					LabelLong : 'SLAG' },
		'slappy'					: { LabelShort : 'SLAPPY',						LabelMedium : 'Slappy',					LabelLong : 'Slappy' },
		'slater'					: { LabelShort : 'SLATER',						LabelMedium : 'Slater',					LabelLong : 'Slater' },
		'slax'						: { LabelShort : 'SLAX',						LabelMedium : 'slax',					LabelLong : 'slax' },
		'slay3r'					: { LabelShort : 'SLAY3R',						LabelMedium : 'Slay3R',					LabelLong : 'Slay3R' },
		'slbenfica'					: { LabelShort : 'SLBENFICA',					LabelMedium : 'Slbenfica',				LabelLong : 'Slbenfica' },
		'sless'						: { LabelShort : 'SLESS',						LabelMedium : 'SLess',					LabelLong : 'S-Less' },
		'slg'						: { LabelShort : 'SLG',							LabelMedium : 'SLG',					LabelLong : 'SLG' },
		'slight'					: { LabelShort : 'SLIGHT',						LabelMedium : 'SLiGHT',					LabelLong : 'SLiGHT' },
		'slisu'						: { LabelShort : 'SLISU',						LabelMedium : 'SLiSU',					LabelLong : 'SLiSU' },
		'slo'						: { LabelShort : 'SLO',							LabelMedium : 'SLO',					LabelLong : 'SLO' },
		'slomo'						: { LabelShort : 'SLOMO',						LabelMedium : 'SLOMO',					LabelLong : 'SLOMO' },
		'slot'						: { LabelShort : 'SLOT',						LabelMedium : 'SLOT',					LabelLong : 'SLOT' },
		'slow'						: { LabelShort : 'SLOW',						LabelMedium : 'SLOW',					LabelLong : 'SLOW' },
		'slowhd'					: { LabelShort : 'SLOWHD',						LabelMedium : 'SlowHD',					LabelLong : 'SlowHD' },
		'smc'						: { LabelShort : 'SMC',							LabelMedium : 'SMC',					LabelLong : 'SMC' },
		'smokey'					: { LabelShort : 'SMOKEY',						LabelMedium : 'SMOKEY',					LabelLong : 'SMOKEY' },
		'sms'						: { LabelShort : 'SMS',							LabelMedium : 'SMS',					LabelLong : 'SMS' },
		'smurf'						: { LabelShort : 'SMURF',						LabelMedium : 'SMURF',					LabelLong : 'SMURF' },
		'smurfenlars'				: { LabelShort : 'SMURFENLARS',					LabelMedium : 'Smurfenlars',			LabelLong : 'Smurfenlars' },
		'snake'						: { LabelShort : 'SNAKE',						LabelMedium : 'SNAKE',					LabelLong : 'SNAKE' },
		'sneak'						: { LabelShort : 'SNEAK',						LabelMedium : 'SNEAK',					LabelLong : 'SNEAK' },
		'sneaky'					: { LabelShort : 'SNEAKY',						LabelMedium : 'SNEAkY',					LabelLong : 'SNEAkY' },
		'sno'						: { LabelShort : 'SNO',							LabelMedium : 'Sno',					LabelLong : 'Sno' },
		'snow'						: { LabelShort : 'SNOW',						LabelMedium : 'SNOW',					LabelLong : 'SNOW' },
		'snowdon'					: { LabelShort : 'SNOWDON',						LabelMedium : 'SnowDoN',					LabelLong : 'SnowDoN' },
		'socks'						: { LabelShort : 'SOCKS',						LabelMedium : 'SoCkS',					LabelLong : 'SoCkS' },
		'sof'						: { LabelShort : 'SOF',							LabelMedium : 'SOF',					LabelLong : 'SOF' },
		'soigneur'					: { LabelShort : 'SOIGNEUR',					LabelMedium : 'SOIGNEUR',				LabelLong : 'SOIGNEUR' },
		'sol'						: { LabelShort : 'SOL',							LabelMedium : 'SOL',					LabelLong : 'SOL' },
		'sola'						: { LabelShort : 'SOLA',						LabelMedium : 'SOLA',					LabelLong : 'SOLA' },
		'solar'						: { LabelShort : 'SOLAR',						LabelMedium : 'SOLAR',					LabelLong : 'SOLAR' },
		'som'						: { LabelShort : 'SOM',							LabelMedium : 'SoM',					LabelLong : 'SoM' },
		'sonido'					: { LabelShort : 'SONIDO',						LabelMedium : 'SONiDO',					LabelLong : 'SONiDO' },
		'sons'						: { LabelShort : 'SONS',						LabelMedium : 'SONS',					LabelLong : 'SONS' },
		'sorrow'					: { LabelShort : 'SORROW',						LabelMedium : 'SORROW',					LabelLong : 'SORROW' },
		'sos'						: { LabelShort : 'SOS',							LabelMedium : 'SoS',					LabelLong : 'SoS' },
		'sour'						: { LabelShort : 'SOUR',						LabelMedium : 'SOUR',					LabelLong : 'SOUR' },
		'sov'						: { LabelShort : 'SOV',							LabelMedium : 'SOV',					LabelLong : 'SOV' },
		'sow'						: { LabelShort : 'SOW',							LabelMedium : 'SoW',					LabelLong : 'SoW' },
		'soy'						: { LabelShort : 'SOY',							LabelMedium : 'SOY',					LabelLong : 'SOY' },
		'sozer'						: { LabelShort : 'SOZER',						LabelMedium : 'SOZER',					LabelLong : 'SOZER' },
		'sp33dy94'					: { LabelShort : 'SP33DY94',					LabelMedium : 'Sp33dy94',				LabelLong : 'Sp33dy94' },
		'sp3ll'						: { LabelShort : 'SP3LL',						LabelMedium : 'SP3LL',					LabelLong : 'SP3LL' },
		'spacehd'					: { LabelShort : 'SPACEHD',						LabelMedium : 'SpaceHD',					LabelLong : 'SpaceHD' },
		'spacehd13'					: { LabelShort : 'SPACEHD13',					LabelMedium : 'SpaceHD13',				LabelLong : 'SpaceHD13' },
		'spamtv'					: { LabelShort : 'SPAMTV',						LabelMedium : 'spamTV',					LabelLong : 'spamTV' },
		'sparel'					: { LabelShort : 'SPAREL',						LabelMedium : 'SPAREL',					LabelLong : 'SPAREL' },
		'sparks'					: { LabelShort : 'SPARKS',						LabelMedium : 'SPARKS',					LabelLong : 'SPARKS' },
		'spc'						: { LabelShort : 'SPC',							LabelMedium : 'SPC',					LabelLong : 'SPC' },
		'species180'					: { LabelShort : 'SPECIES180',					LabelMedium : 'Species180',				LabelLong : 'Species180' },
		'spectre'					: { LabelShort : 'SPECTRE',						LabelMedium : 'SPECTRE',					LabelLong : 'SPECTRE' },
		'spedboy'					: { LabelShort : 'SPEDBOY',						LabelMedium : 'Spedboy',					LabelLong : 'Spedboy' },
		'speed'						: { LabelShort : 'SPEED',						LabelMedium : 'SPEED',					LabelLong : 'SPEED' },
		'speranzah'					: { LabelShort : 'SPERANZAH',					LabelMedium : 'Speranzah',				LabelLong : 'Speranzah' },
		'sphd'						: { LabelShort : 'SPHD',						LabelMedium : 'sPHD',					LabelLong : 'sPHD' },
		'sphinctone1'				: { LabelShort : 'SPHINCTONE1',					LabelMedium : 'Sphinctone1',			LabelLong : 'Sphinctone1' },
		'spicy'						: { LabelShort : 'SPICY',						LabelMedium : 'SPiCY',					LabelLong : 'SPiCY' },
		'spirit'					: { LabelShort : 'SPIRIT',						LabelMedium : 'SPiRiT',					LabelLong : 'SPiRiT' },
		'spiro'						: { LabelShort : 'SPIRO',						LabelMedium : 'SPiRO',					LabelLong : 'SPiRO' },
		'spk'						: { LabelShort : 'SPK',							LabelMedium : 'SPK',					LabelLong : 'SPK' },
		'splendide'					: { LabelShort : 'SPLENDIDE',					LabelMedium : 'SPLENDIDE',				LabelLong : 'SPLENDIDE' },
		'splitsville'				: { LabelShort : 'SPLITSVILLE',					LabelMedium : 'SPLiTSViLLE',			LabelLong : 'SPLiTSViLLE' },
		'spooks'					: { LabelShort : 'SPOOKS',						LabelMedium : 'SPOOKS',					LabelLong : 'SPOOKS' },
		'spooky'					: { LabelShort : 'SPOOKY',						LabelMedium : 'SPOOKY',					LabelLong : 'SPOOKY' },
		'sprinter'					: { LabelShort : 'SPRINTER',					LabelMedium : 'SPRiNTER',				LabelLong : 'SPRiNTER' },
		'sps'						: { LabelShort : 'SPS',							LabelMedium : 'SpS',					LabelLong : 'SpS' },
		'spyc'						: { LabelShort : 'SPYC',						LabelMedium : 'SPYC',					LabelLong : 'SPYC' },
		'squalor'					: { LabelShort : 'SQUALOR',						LabelMedium : 'squalor',					LabelLong : 'squalor' },
		'srigga'					: { LabelShort : 'SRIGGA',						LabelMedium : 'SRIGGA',					LabelLong : 'SRIGGA' },
		'sriz'						: { LabelShort : 'SRIZ',						LabelMedium : 'sriz',					LabelLong : 'sriz' },
		'srls'						: { LabelShort : 'SRLS',						LabelMedium : 'SRLS',					LabelLong : 'SRLS' },
		'srs'						: { LabelShort : 'SRS',							LabelMedium : 'SRS',					LabelLong : 'SRS' },
		'ss'							: { LabelShort : 'SS',							LabelMedium : 'SS',						LabelLong : 'S-S' },
		'ssa'						: { LabelShort : 'SSA',							LabelMedium : 'SSA',					LabelLong : 'SSA' },
		'ssdd'						: { LabelShort : 'SSDD',						LabelMedium : 'SSDD',					LabelLong : 'SSDD' },
		'ssf'						: { LabelShort : 'SSF',							LabelMedium : 'SSF',					LabelLong : 'SSF' },
		'ssg'						: { LabelShort : 'SSG',							LabelMedium : 'SSG',					LabelLong : 'SSG' },
		'ssk'						: { LabelShort : 'SSK',							LabelMedium : 'SSK',					LabelLong : 'SSK' },
		'ssl'						: { LabelShort : 'SSL',							LabelMedium : 'SSL',					LabelLong : 'SSL' },
		'ssn'						: { LabelShort : 'SSN',							LabelMedium : 'SSN',					LabelLong : 'SSN' },
		'ssrmovies'					: { LabelShort : 'SSRMOVIES',					LabelMedium : 'SSRmovies',				LabelLong : 'SSRmovies' },
		'st'							: { LabelShort : 'ST',							LabelMedium : 'ST',						LabelLong : 'ST' },
		'starlord'					: { LabelShort : 'STARLORD',					LabelMedium : 'StarLord',				LabelLong : 'StarLord' },
		'stars'						: { LabelShort : 'STARS',						LabelMedium : 'STARS',					LabelLong : 'STARS' },
		'starz'						: { LabelShort : 'STARZ',						LabelMedium : 'STARZ',					LabelLong : 'STARZ' },
		'state'						: { LabelShort : 'STATE',						LabelMedium : 'state',					LabelLong : 'state' },
		'stb'						: { LabelShort : 'STB',							LabelMedium : 'StB',					LabelLong : 'StB' },
		'stealthmaster'				: { LabelShort : 'STEALTHMASTER',				LabelMedium : 'Stealthmaster',			LabelLong : 'Stealthmaster' },
		'stegner'					: { LabelShort : 'STEGNER',						LabelMedium : 'STEGNER',					LabelLong : 'STEGNER' },
		'stella'					: { LabelShort : 'STELLA',						LabelMedium : 'STELLA',					LabelLong : 'STELLA' },
		'stfu'						: { LabelShort : 'STFU',						LabelMedium : 'STFU',					LabelLong : 'STFU' },
		'sticky83'					: { LabelShort : 'STICKY83',					LabelMedium : 'Sticky83',				LabelLong : 'Sticky83' },
		'stock'						: { LabelShort : 'STOCK',						LabelMedium : 'STOCK',					LabelLong : 'STOCK' },
		'storm'						: { LabelShort : 'STORM',						LabelMedium : 'STORM',					LabelLong : 'STORM' },
		'stp'						: { LabelShort : 'STP',							LabelMedium : 'STP',					LabelLong : 'STP' },
		'stranded'					: { LabelShort : 'STRANDED',					LabelMedium : 'STRANDED',				LabelLong : 'STRANDED' },
		'stratos'					: { LabelShort : 'STRATOS',						LabelMedium : 'STRATOS',					LabelLong : 'STRATOS' },
		'straub'					: { LabelShort : 'STRAUB',						LabelMedium : 'STRAUB',					LabelLong : 'STRAUB' },
		'strife'					: { LabelShort : 'STRIFE',						LabelMedium : 'STRiFE',					LabelLong : 'STRiFE' },
		'strong'					: { LabelShort : 'STRONG',						LabelMedium : 'STRONG',					LabelLong : 'STRONG' },
		'strontium'					: { LabelShort : 'STRONTIUM',					LabelMedium : 'STRONTiUM',				LabelLong : 'STRONTiUM' },
		'stuttershit'				: { LabelShort : 'STUTTERSHIT',					LabelMedium : 'STUTTERSHIT',			LabelLong : 'STUTTERSHIT' },
		'stvfrv'					: { LabelShort : 'STVFRV',						LabelMedium : 'STVFRV',					LabelLong : 'STVFRV' },
		'stylishsalh'				: { LabelShort : 'STYLISHSALH',					LabelMedium : 'StyLishSaLH',			LabelLong : 'StyLishSaLH' },
		'suave'						: { LabelShort : 'SUAVE',						LabelMedium : 'SuAvE',					LabelLong : 'SuAvE' },
		'sublime'					: { LabelShort : 'SUBLIME',						LabelMedium : 'SUBLiME',					LabelLong : 'SUBLiME' },
		'submerge'					: { LabelShort : 'SUBMERGE',					LabelMedium : 'SUBMERGE',				LabelLong : 'SUBMERGE' },
		'substance'					: { LabelShort : 'SUBSTANCE',					LabelMedium : 'SUBSTANCE',				LabelLong : 'SUBSTANCE' },
		'subzero'					: { LabelShort : 'SUBZERO',						LabelMedium : 'SUBZERO',					LabelLong : 'SUBZERO' },
		'sujaidr'					: { LabelShort : 'SUJAIDR',						LabelMedium : 'SUJAIDR',					LabelLong : 'SUJAIDR' },
		'sumvision'					: { LabelShort : 'SUMVISION',					LabelMedium : 'SumVision',				LabelLong : 'SumVision' },
		'sunny'						: { LabelShort : 'SUNNY',						LabelMedium : 'Sunny',					LabelLong : 'Sunny' },
		'sunscreen'					: { LabelShort : 'SUNSCREEN',					LabelMedium : 'SUNSCREEN',				LabelLong : 'SUNSCREEN' },
		'sunshinestudio'			: { LabelShort : 'SUNSHINESTUDIO',				LabelMedium : 'SunshineStudio',			LabelLong : 'Sunshine.Studio' },
		'sunspot'					: { LabelShort : 'SUNSPOT',						LabelMedium : 'SUNSPOT',					LabelLong : 'SUNSPOT' },
		'sunsujaidr'					: { LabelShort : 'SUNSUJAIDR',					LabelMedium : 'sUNsujaidr',				LabelLong : 'sUN.sujaidr' },
		'supernova'					: { LabelShort : 'SUPERNOVA',					LabelMedium : 'SuperNova',				LabelLong : 'SuperNova' },
		'supersize'					: { LabelShort : 'SUPERSIZE',					LabelMedium : 'SUPERSIZE',				LabelLong : 'SUPERSIZE' },
		'supreme'					: { LabelShort : 'SUPREME',						LabelMedium : 'SuPReME',					LabelLong : 'SuPReME' },
		'surcode'					: { LabelShort : 'SURCODE',						LabelMedium : 'SURCODE',					LabelLong : 'SURCODE' },
		'surfer'					: { LabelShort : 'SURFER',						LabelMedium : 'SURFER',					LabelLong : 'SURFER' },
		'surya'						: { LabelShort : 'SURYA',						LabelMedium : 'SurYa',					LabelLong : 'SurYa' },
		'sus'						: { LabelShort : 'SUS',							LabelMedium : 'SuS',					LabelLong : 'SuS' },
		'sva'						: { LabelShort : 'SVA',							LabelMedium : 'SVA',					LabelLong : 'SVA' },
		'svd'						: { LabelShort : 'SVD',							LabelMedium : 'SVD',					LabelLong : 'SVD' },
		'swaggerhd'					: { LabelShort : 'SWAGGERHD',					LabelMedium : 'SWAGGERHD',				LabelLong : 'SWAGGERHD' },
		'swc'						: { LabelShort : 'SWC',							LabelMedium : 'SWC',					LabelLong : 'SWC' },
		'swim'						: { LabelShort : 'SWIM',						LabelMedium : 'SWiM',					LabelLong : 'SWiM' },
		'swolled'					: { LabelShort : 'SWOLLED',						LabelMedium : 'SWOLLED',					LabelLong : 'SWOLLED' },
		'swty'						: { LabelShort : 'SWTY',						LabelMedium : 'SWTY',					LabelLong : 'SWTY' },
		'swtyblz'					: { LabelShort : 'SWTYBLZ',						LabelMedium : 'SWTYBLZ',					LabelLong : 'SWTYBLZ' },
		'sxales'					: { LabelShort : 'SXALES',						LabelMedium : 'sxales',					LabelLong : 'sxales' },
		'symbiotes'					: { LabelShort : 'SYMBIOTES',					LabelMedium : 'SymBiOTes',				LabelLong : 'SymBiOTes' },
		'syncopy'					: { LabelShort : 'SYNCOPY',						LabelMedium : 'SYNCOPY',					LabelLong : 'SYNCOPY' },
		'syndicate'					: { LabelShort : 'SYNDICATE',					LabelMedium : 'SYNDICATE',				LabelLong : 'SYNDICATE' },
		'sys'						: { LabelShort : 'SYS',							LabelMedium : 'SYS',					LabelLong : 'SYS' },
		't00ng0d'					: { LabelShort : 'T00NG0D',						LabelMedium : 't00ng0d',					LabelLong : 't00ng0d' },
		't0m'						: { LabelShort : 'T0M',							LabelMedium : 'T0M',					LabelLong : 'T0M' },
		't1'							: { LabelShort : 'T1',							LabelMedium : 'T1',						LabelLong : 'T1' },
		't3nzin'					: { LabelShort : 'T3NZIN',						LabelMedium : 't3nzin',					LabelLong : 't3nzin' },
		't4h'						: { LabelShort : 'T4H',							LabelMedium : 'T4H',					LabelLong : 'T4H' },
		't4p3'						: { LabelShort : 'T4P3',						LabelMedium : 'T4P3',					LabelLong : 'T4P3' },
		't6d'						: { LabelShort : 'T6D',							LabelMedium : 'T6D',					LabelLong : 'T6D' },
		'taco'						: { LabelShort : 'TACO',						LabelMedium : 'TACO',					LabelLong : 'TACO' },
		'taichi'					: { LabelShort : 'TAICHI',						LabelMedium : 'TAiCHi',					LabelLong : 'TAiCHi' },
		'tangoalpha'					: { LabelShort : 'TANGOALPHA',					LabelMedium : 'TangoAlpha',				LabelLong : 'TangoAlpha' },
		'taoe'						: { LabelShort : 'TAOE',						LabelMedium : 'TAoE',					LabelLong : 'TAoE' },
		'tapochek'					: { LabelShort : 'TAPOCHEK',					LabelMedium : 'Tapochek',				LabelLong : 'Tapochek' },
		'target'					: { LabelShort : 'TARGET',						LabelMedium : 'TARGET',					LabelLong : 'TARGET' },
		'tasko'						: { LabelShort : 'TASKO',						LabelMedium : 'Tasko',					LabelLong : 'Tasko' },
		'taste'						: { LabelShort : 'TASTE',						LabelMedium : 'TASTE',					LabelLong : 'TASTE' },
		'tasted'					: { LabelShort : 'TASTED',						LabelMedium : 'TASTED',					LabelLong : 'TASTED' },
		'tastetv'					: { LabelShort : 'TASTETV',						LabelMedium : 'TASTETV',					LabelLong : 'TASTETV' },
		'tatugamescf'				: { LabelShort : 'TATUGAMESCF',					LabelMedium : 'TATUGAMESCF',			LabelLong : 'TATUGAMESCF' },
		'taxes'						: { LabelShort : 'TAXES',						LabelMedium : 'TAXES',					LabelLong : 'TAXES' },
		'tayto'						: { LabelShort : 'TAYTO',						LabelMedium : 'TayTO',					LabelLong : 'TayTO' },
		'tb'							: { LabelShort : 'TB',							LabelMedium : 'TB',						LabelLong : 'TB' },
		'tbb'						: { LabelShort : 'TBB',							LabelMedium : 'TBB',					LabelLong : 'TBB' },
		'tbd'						: { LabelShort : 'TBD',							LabelMedium : 'TBd',					LabelLong : 'TBd' },
		'tbr'						: { LabelShort : 'TBR',							LabelMedium : 'TBR',					LabelLong : 'TBR' },
		'tbs'						: { LabelShort : 'TBS',							LabelMedium : 'TBS',					LabelLong : 'TBS' },
		'tbz'						: { LabelShort : 'TBZ',							LabelMedium : 'TbZ',					LabelLong : 'TbZ' },
		'tcl'						: { LabelShort : 'TCL',							LabelMedium : 'TCL',					LabelLong : 'TCL' },
		'tcm'						: { LabelShort : 'TCM',							LabelMedium : 'TCM',					LabelLong : 'TCM' },
		'tcpa'						: { LabelShort : 'TCPA',						LabelMedium : 'TCPA',					LabelLong : 'TCPA' },
		'tdd'						: { LabelShort : 'TDD',							LabelMedium : 'TDD',					LabelLong : 'TDD' },
		'tdf'						: { LabelShort : 'TDF',							LabelMedium : 'TDF',					LabelLong : 'TDF' },
		'tdm'						: { LabelShort : 'TDM',							LabelMedium : 'TDM',					LabelLong : 'TDM' },
		'tdr'						: { LabelShort : 'TDR',							LabelMedium : 'TDR',					LabelLong : 'TDR' },
		'teamhd'					: { LabelShort : 'TEAMHD',						LabelMedium : 'TeamHD',					LabelLong : 'TeamHD' },
		'teamtelly'					: { LabelShort : 'TEAMTELLY',					LabelMedium : 'TeamTelly',				LabelLong : 'TeamTelly' },
		'teamtr'					: { LabelShort : 'TEAMTR',						LabelMedium : 'TeamTR',					LabelLong : 'TeamTR' },
		'tear'						: { LabelShort : 'TEAR',						LabelMedium : 'tear',					LabelLong : 'tear' },
		'tech'						: { LabelShort : 'TECH',						LabelMedium : 'TECH',					LabelLong : 'TECH' },
		'teehee'					: { LabelShort : 'TEEHEE',						LabelMedium : 'TeeHee',					LabelLong : 'TeeHee' },
		'tekno3d'					: { LabelShort : 'TEKNO3D',						LabelMedium : 'Tekno3d',					LabelLong : 'Tekno3d' },
		'telefunken'					: { LabelShort : 'TELEFUNKEN',					LabelMedium : 'TELEFUNKEN',				LabelLong : 'TELEFUNKEN' },
		'telly'						: { LabelShort : 'TELLY',						LabelMedium : 'TELLY',					LabelLong : 'TELLY' },
		'tenaciousd'					: { LabelShort : 'TENACIOUSD',					LabelMedium : 'TenaciousD',				LabelLong : 'TenaciousD' },
		'teneighty'					: { LabelShort : 'TENEIGHTY',					LabelMedium : 'TENEIGHTY',				LabelLong : 'TENEIGHTY' },
		'tennreed'					: { LabelShort : 'TENNREED',					LabelMedium : 'TeNNReeD',				LabelLong : 'TeNNReeD' },
		'teo'						: { LabelShort : 'TEO',							LabelMedium : 'Teo',					LabelLong : 'Teo' },
		'tepes'						: { LabelShort : 'TEPES',						LabelMedium : 'TEPES',					LabelLong : 'TEPES' },
		'termi'						: { LabelShort : 'TERMI',						LabelMedium : 'TERMi',					LabelLong : 'TERMi' },
		'terminal'					: { LabelShort : 'TERMINAL',					LabelMedium : 'TERMiNAL',				LabelLong : 'TERMiNAL' },
		'terra'						: { LabelShort : 'TERRA',						LabelMedium : 'TERRA',					LabelLong : 'TERRA' },
		'tesdrox'					: { LabelShort : 'TESDROX',						LabelMedium : 'TESDROX',					LabelLong : 'TESDROX' },
		'tfe'						: { LabelShort : 'TFE',							LabelMedium : 'TFE',					LabelLong : 'TFE' },
		'tfin'						: { LabelShort : 'TFIN',						LabelMedium : 'TFiN',					LabelLong : 'TFiN' },
		'tg7'						: { LabelShort : 'TG7',							LabelMedium : 'TG7',					LabelLong : 'TG7' },
		'tgx'						: { LabelShort : 'TGX',							LabelMedium : 'TGx',					LabelLong : 'TGx' },
		'tha'						: { LabelShort : 'THA',							LabelMedium : 'ThA',					LabelLong : 'ThA' },
		'thd'						: { LabelShort : 'THD',							LabelMedium : 'ThD',					LabelLong : 'ThD' },
		'theamresh'					: { LabelShort : 'THEAMRESH',					LabelMedium : 'theAmresh',				LabelLong : 'theAmresh' },
		'thebatman'					: { LabelShort : 'THEBATMAN',					LabelMedium : 'TheBatman',				LabelLong : 'TheBatman' },
		'thebest'					: { LabelShort : 'THEBEST',						LabelMedium : 'THEBEST',					LabelLong : 'THEBEST' },
		'theend'					: { LabelShort : 'THEEND',						LabelMedium : 'THeeND',					LabelLong : 'THeeND' },
		'theincognito'				: { LabelShort : 'THEINCOGNITO',				LabelMedium : 'theincognito',			LabelLong : 'theincognito' },
		'thenightmare'				: { LabelShort : 'THENIGHTMARE',				LabelMedium : 'THENiGHTMARE',			LabelLong : 'THENiGHTMARE' },
		'thenightmareinhd'			: { LabelShort : 'THENIGHTMAREINHD',			LabelMedium : 'THENiGHTMAREiNHD',		LabelLong : 'THENiGHTMAREiNHD' },
		'theory'					: { LabelShort : 'THEORY',						LabelMedium : 'THEORY',					LabelLong : 'THEORY' },
		'thepunisher'				: { LabelShort : 'THEPUNISHER',					LabelMedium : 'ThePunisheR',			LabelLong : 'The PunisheR' },
		'thewretched'				: { LabelShort : 'THEWRETCHED',					LabelMedium : 'TheWretched',			LabelLong : 'TheWretched' },
		'thick'						: { LabelShort : 'THICK',						LabelMedium : 'THICK',					LabelLong : 'THICK' },
		'thisoneyouwontsell'			: { LabelShort : 'THISONEYOUWONTSELL',			LabelMedium : 'ThisOneYouWontSell',		LabelLong : 'ThisOneYouWontSell' },
		'thizz'						: { LabelShort : 'THIZZ',						LabelMedium : 'Thizz',					LabelLong : 'Thizz' },
		'thor'						: { LabelShort : 'THOR',						LabelMedium : 'THOR',					LabelLong : 'THOR' },
		'thora'						: { LabelShort : 'THORA',						LabelMedium : 'THORA',					LabelLong : 'THORA' },
		'threesixtyp'				: { LabelShort : 'THREESIXTYP',					LabelMedium : 'threesixtyp',			LabelLong : 'threesixtyp' },
		'threesome'					: { LabelShort : 'THREESOME',					LabelMedium : 'THREESOME',				LabelLong : 'THREESOME' },
		'throne'					: { LabelShort : 'THRONE',						LabelMedium : 'THRONE',					LabelLong : 'THRONE' },
		'thugline'					: { LabelShort : 'THUGLINE',					LabelMedium : 'THUGLiNE',				LabelLong : 'THUGLiNE' },
		'thumperdc'					: { LabelShort : 'THUMPERDC',					LabelMedium : 'ThumperDC',				LabelLong : 'ThumperDC' },
		'thunder'					: { LabelShort : 'THUNDER',						LabelMedium : 'THUNDER',					LabelLong : 'THUNDER' },
		'thyrso10'					: { LabelShort : 'THYRSO10',					LabelMedium : 'THYRSO10',				LabelLong : 'THYRSO10' },
		'tical'						: { LabelShort : 'TICAL',						LabelMedium : 'TiCAL',					LabelLong : 'TiCAL' },
		'tide'						: { LabelShort : 'TIDE',						LabelMedium : 'TiDE',					LabelLong : 'TiDE' },
		'tigole'					: { LabelShort : 'TIGOLE',						LabelMedium : 'Tigole',					LabelLong : 'Tigole' },
		'timedistortion'			: { LabelShort : 'TIMEDISTORTION',				LabelMedium : 'TimeDistortion',			LabelLong : 'TimeDistortion' },
		'timegod'					: { LabelShort : 'TIMEGOD',						LabelMedium : 'TiMEGOD',					LabelLong : 'TiMEGOD' },
		'timelords'					: { LabelShort : 'TIMELORDS',					LabelMedium : 'TiMELORDS',				LabelLong : 'TiMELORDS' },
		'timpe'						: { LabelShort : 'TIMPE',						LabelMedium : 'TiMPE',					LabelLong : 'TiMPE' },
		'tinye'						: { LabelShort : 'TINYE',						LabelMedium : 'TinyE',					LabelLong : 'TinyE' },
		'tinymkv'					: { LabelShort : 'TINYMKV',						LabelMedium : 'TINYMKV',					LabelLong : 'TINYMKV' },
		'tit'						: { LabelShort : 'TIT',							LabelMedium : 'TiT',					LabelLong : 'TiT' },
		'titan'						: { LabelShort : 'TITAN',						LabelMedium : 'TiTAN',					LabelLong : 'TiTAN' },
		'titans'					: { LabelShort : 'TITANS',						LabelMedium : 'TiTANS',					LabelLong : 'TiTANS' },
		'tjet'						: { LabelShort : 'TJET',						LabelMedium : 'TJET',					LabelLong : 'TJET' },
		'tjhd'						: { LabelShort : 'TJHD',						LabelMedium : 'TjHD',					LabelLong : 'TjHD' },
		'tk'							: { LabelShort : 'TK',							LabelMedium : 'TK',						LabelLong : 'TK' },
		'tla'						: { LabelShort : 'TLA',							LabelMedium : 'TLA',					LabelLong : 'TLA' },
		'tlf'						: { LabelShort : 'TLF',							LabelMedium : 'TLF',					LabelLong : 'TLF' },
		'tm'							: { LabelShort : 'TM',							LabelMedium : 'TM',						LabelLong : 'TM' },
		'tmd'						: { LabelShort : 'TMD',							LabelMedium : 'TMd',					LabelLong : 'TMd' },
		'tmg'						: { LabelShort : 'TMG',							LabelMedium : 'TmG',					LabelLong : 'TmG' },
		'tmsf'						: { LabelShort : 'TMSF',						LabelMedium : 'TMSF',					LabelLong : 'TMSF' },
		'tnan'						: { LabelShort : 'TNAN',						LabelMedium : 'TNAN',					LabelLong : 'TNAN' },
		'tne'						: { LabelShort : 'TNE',							LabelMedium : 'tNe',					LabelLong : 'tNe' },
		'tnp'						: { LabelShort : 'TNP',							LabelMedium : 'TnP',					LabelLong : 'TnP' },
		'tntvillage'					: { LabelShort : 'TNTVILLAGE',					LabelMedium : 'TnTvillage',				LabelLong : 'TnTvillage' },
		'to4ka'						: { LabelShort : 'TO4KA',						LabelMedium : 'To4ka',					LabelLong : 'To4ka' },
		'tof'						: { LabelShort : 'TOF',							LabelMedium : 'ToF',					LabelLong : 'ToF' },
		'toho'						: { LabelShort : 'TOHO',						LabelMedium : 'toho',					LabelLong : 'toho' },
		'tombdoc'					: { LabelShort : 'TOMBDOC',						LabelMedium : 'TombDoc',					LabelLong : 'TombDoc' },
		'tomcat12'					: { LabelShort : 'TOMCAT12',					LabelMedium : 'tomcat12',				LabelLong : 'tomcat12' },
		'tommy'						: { LabelShort : 'TOMMY',						LabelMedium : 'TOMMY',					LabelLong : 'TOMMY' },
		'tomx'						: { LabelShort : 'TOMX',						LabelMedium : 'TomX',					LabelLong : 'TomX' },
		'tonyk'						: { LabelShort : 'TONYK',						LabelMedium : 'Tonyk',					LabelLong : 'Tonyk' },
		'tooncore'					: { LabelShort : 'TOONCORE',					LabelMedium : 'Tooncore',				LabelLong : 'Tooncore' },
		'top'						: { LabelShort : 'TOP',							LabelMedium : 'TOP',					LabelLong : 'TOP' },
		'topaz'						: { LabelShort : 'TOPAZ',						LabelMedium : 'TOPAZ',					LabelLong : 'TOPAZ' },
		'topcat'					: { LabelShort : 'TOPCAT',						LabelMedium : 'TOPCAT',					LabelLong : 'TOPCAT' },
		'topkek'					: { LabelShort : 'TOPKEK',						LabelMedium : 'TOPKEK',					LabelLong : 'TOPKEK' },
		'torrentcouch'				: { LabelShort : 'TORRENTCOUCH',				LabelMedium : 'TorrentCouch',			LabelLong : 'TorrentCouch' },
		'torrentcounter'			: { LabelShort : 'TORRENTCOUNTER',				LabelMedium : 'TorrentCounter',			LabelLong : 'TorrentCounter' },
		'torrentgui'					: { LabelShort : 'TORRENTGUI',					LabelMedium : 'TorrenTGui',				LabelLong : 'TorrenTGui' },
		'tot'						: { LabelShort : 'TOT',							LabelMedium : 'ToT',					LabelLong : 'ToT' },
		'toxic'						: { LabelShort : 'TOXIC',						LabelMedium : 'TOXIC',					LabelLong : 'TOXIC' },
		'tozoon'					: { LabelShort : 'TOZOON',						LabelMedium : 'ToZoon',					LabelLong : 'ToZoon' },
		'tpb'						: { LabelShort : 'TPB',							LabelMedium : 'TPB',					LabelLong : 'TPB' },
		'tr'							: { LabelShort : 'TR',							LabelMedium : 'TR',						LabelLong : 'TR' },
		'transience'					: { LabelShort : 'TRANSIENCE',					LabelMedium : 'TRANSiENCE',				LabelLong : 'TRANSiENCE' },
		'trash'						: { LabelShort : 'TRASH',						LabelMedium : 'trAsh',					LabelLong : 'trAsh' },
		'treble'					: { LabelShort : 'TREBLE',						LabelMedium : 'TREBLE',					LabelLong : 'TREBLE' },
		'tree'						: { LabelShort : 'TREE',						LabelMedium : 'TREE',					LabelLong : 'TREE' },
		'trevor333'					: { LabelShort : 'TREVOR333',					LabelMedium : 'trevor333',				LabelLong : 'trevor333' },
		'trexhd'					: { LabelShort : 'TREXHD',						LabelMedium : 'TRexHD',					LabelLong : 'TRexHD' },
		'trg'						: { LabelShort : 'TRG',							LabelMedium : 'TRG',					LabelLong : 'TRG' },
		'triad'						: { LabelShort : 'TRIAD',						LabelMedium : 'TRIAD',					LabelLong : 'TRIAD' },
		'trial'						: { LabelShort : 'TRIAL',						LabelMedium : 'TRiAL',					LabelLong : 'TRiAL' },
		'tribal'					: { LabelShort : 'TRIBAL',						LabelMedium : 'TRIBAL',					LabelLong : 'TRIBAL' },
		'trips'						: { LabelShort : 'TRIPS',						LabelMedium : 'TRiPS',					LabelLong : 'TRiPS' },
		'triton'					: { LabelShort : 'TRITON',						LabelMedium : 'TRiToN',					LabelLong : 'TRiToN' },
		'trl'						: { LabelShort : 'TRL',							LabelMedium : 'TRL',					LabelLong : 'TRL' },
		'trojan'					: { LabelShort : 'TROJAN',						LabelMedium : 'TROJAN',					LabelLong : 'TROJAN' },
		'trollhd'					: { LabelShort : 'TROLLHD',						LabelMedium : 'TrollHD',					LabelLong : 'TrollHD' },
		'trolluhd'					: { LabelShort : 'TROLLUHD',					LabelMedium : 'TrollUHD',				LabelLong : 'TrollUHD' },
		'trtdteam'					: { LabelShort : 'TRTDTEAM',					LabelMedium : 'TrTdTeaM',				LabelLong : 'TrTd_TeaM' },
		'truavc'					: { LabelShort : 'TRUAVC',						LabelMedium : 'tRuAVC',					LabelLong : 'tRuAVC' },
		'truck'						: { LabelShort : 'TRUCK',						LabelMedium : 'TruCK',					LabelLong : 'TruCK' },
		'truedef'					: { LabelShort : 'TRUEDEF',						LabelMedium : 'TRUEDEF',					LabelLong : 'TRUEDEF' },
		'truedukes'					: { LabelShort : 'TRUEDUKES',					LabelMedium : 'TRUEDUKES',				LabelLong : 'TRUEDUKES' },
		'trump'						: { LabelShort : 'TRUMP',						LabelMedium : 'TRUMP',					LabelLong : 'TRUMP' },
		'tscc'						: { LabelShort : 'TSCC',						LabelMedium : 'TSCC',					LabelLong : 'TSCC' },
		'tse'						: { LabelShort : 'TSE',							LabelMedium : 'TSE',					LabelLong : 'TSE' },
		'tsrg'						: { LabelShort : 'TSRG',						LabelMedium : 'TSRG',					LabelLong : 'TSRG' },
		'tss'						: { LabelShort : 'TSS',							LabelMedium : 'TSs',					LabelLong : 'TSs' },
		'tsv'						: { LabelShort : 'TSV',							LabelMedium : 'TSV',					LabelLong : 'TSV' },
		'tt'							: { LabelShort : 'TT',							LabelMedium : 'TT',						LabelLong : 'TT' },
		'ttg'						: { LabelShort : 'TTG',							LabelMedium : 'TTG',					LabelLong : 'TTG' },
		'ttl'						: { LabelShort : 'TTL',							LabelMedium : 'TTL',					LabelLong : 'TTL' },
		'tto'						: { LabelShort : 'TTO',							LabelMedium : 'TTO',					LabelLong : 'TTO' },
		'tts'						: { LabelShort : 'TTS',							LabelMedium : 'tts',					LabelLong : 'tts' },
		'ttva'						: { LabelShort : 'TTVA',						LabelMedium : 'TTVa',					LabelLong : 'TTVa' },
		'tugazx'					: { LabelShort : 'TUGAZX',						LabelMedium : 'TuGAZx',					LabelLong : 'TuGAZx' },
		'turbo'						: { LabelShort : 'TURBO',						LabelMedium : 'TURBO',					LabelLong : 'TURBO' },
		'turg'						: { LabelShort : 'TURG',						LabelMedium : 'TURG',					LabelLong : 'TURG' },
		'turkiso'					: { LabelShort : 'TURKISO',						LabelMedium : 'TURKiSO',					LabelLong : 'TURKiSO' },
		'turmoil'					: { LabelShort : 'TURMOIL',						LabelMedium : 'TURMOiL',					LabelLong : 'TURMOiL' },
		'tusahd'					: { LabelShort : 'TUSAHD',						LabelMedium : 'TUSAHD',					LabelLong : 'TUSAHD' },
		'tv21'						: { LabelShort : 'TV21',						LabelMedium : 'Tv21',					LabelLong : 'Tv21' },
		'tv2lax9'					: { LabelShort : 'TV2LAX9',						LabelMedium : 'TV2LAX9',					LabelLong : 'TV2LAX9' },
		'tv4a'						: { LabelShort : 'TV4A',						LabelMedium : 'TV4A',					LabelLong : 'TV4A' },
		'tvaddict'					: { LabelShort : 'TVADDICT',					LabelMedium : 'TVADDiCT',				LabelLong : 'TVADDiCT' },
		'tvarchiv'					: { LabelShort : 'TVARCHIV',					LabelMedium : 'TVARCHiV',				LabelLong : 'TVARCHiV' },
		'tvbeasts'					: { LabelShort : 'TVBEASTS',					LabelMedium : 'TVBeastS',				LabelLong : 'TVBeastS' },
		'tvc'						: { LabelShort : 'TVC',							LabelMedium : 'TVC',					LabelLong : 'TVC' },
		'tvd'						: { LabelShort : 'TVD',							LabelMedium : 'TvD',					LabelLong : 'TvD' },
		'tvillage'					: { LabelShort : 'TVILLAGE',					LabelMedium : 'TViLLAGE',				LabelLong : 'TViLLAGE' },
		'tvnation'					: { LabelShort : 'TVNATION',					LabelMedium : 'TVNATiON',				LabelLong : 'TVNATiON' },
		'tvp'						: { LabelShort : 'TVP',							LabelMedium : 'TVP',					LabelLong : 'TVP' },
		'tvr'						: { LabelShort : 'TVR',							LabelMedium : 'TvR',					LabelLong : 'TvR' },
		'tvs'						: { LabelShort : 'TVS',							LabelMedium : 'TVS',					LabelLong : 'TVS' },
		'tvslf'						: { LabelShort : 'TVSLF',						LabelMedium : 'tvslf',					LabelLong : 'tvslf' },
		'tvslices'					: { LabelShort : 'TVSLICES',					LabelMedium : 'TVSLiCES',				LabelLong : 'TVSLiCES' },
		'tvsmash'					: { LabelShort : 'TVSMASH',						LabelMedium : 'TVSmash',					LabelLong : 'TVSmash' },
		'tvtime'					: { LabelShort : 'TVTIME',						LabelMedium : 'TvTiME',					LabelLong : 'TvTiME' },
		'tvv'						: { LabelShort : 'TVV',							LabelMedium : 'TVV',					LabelLong : 'TVV' },
		'twa'						: { LabelShort : 'TWA',							LabelMedium : 'TWA',					LabelLong : 'TWA' },
		'tweet'						: { LabelShort : 'TWEET',						LabelMedium : 'TWEET',					LabelLong : 'TWEET' },
		'twist'						: { LabelShort : 'TWIST',						LabelMedium : 'TWiST',					LabelLong : 'TWiST' },
		'twister'					: { LabelShort : 'TWISTER',						LabelMedium : 'TWISTER',					LabelLong : 'TWISTER' },
		'twizted'					: { LabelShort : 'TWIZTED',						LabelMedium : 'TWiZTED',					LabelLong : 'TWiZTED' },
		'tx'							: { LabelShort : 'TX',							LabelMedium : 'TX',						LabelLong : 'TX' },
		'txb'						: { LabelShort : 'TXB',							LabelMedium : 'TXB',					LabelLong : 'TXB' },
		'uav'						: { LabelShort : 'UAV',							LabelMedium : 'UAV',					LabelLong : 'UAV' },
		'ubik'						: { LabelShort : 'UBIK',						LabelMedium : 'UBiK',					LabelLong : 'UBiK' },
		'ubm'						: { LabelShort : 'UBM',							LabelMedium : 'UbM',					LabelLong : 'UbM' },
		'udf'						: { LabelShort : 'UDF',							LabelMedium : 'UDF',					LabelLong : 'UDF' },
		'ukdhd'						: { LabelShort : 'UKDHD',						LabelMedium : 'UKDHD',					LabelLong : 'UKDHD' },
		'uktv'						: { LabelShort : 'UKTV',						LabelMedium : 'UKTV',					LabelLong : 'UKTV' },
		'ulshd'						: { LabelShort : 'ULSHD',						LabelMedium : 'ULSHD',					LabelLong : 'ULSHD' },
		'ultradox'					: { LabelShort : 'ULTRADOX',					LabelMedium : 'Ultradox',				LabelLong : 'Ultradox' },
		'ultrahdclub'				: { LabelShort : 'ULTRAHDCLUB',					LabelMedium : 'ULTRAHDCLUB',			LabelLong : 'ULTRAHDCLUB' },
		'ulysse'					: { LabelShort : 'ULYSSE',						LabelMedium : 'ULYSSE',					LabelLong : 'ULYSSE' },
		'undead'					: { LabelShort : 'UNDEAD',						LabelMedium : 'UNDEAD',					LabelLong : 'UNDEAD' },
		'underbelly'					: { LabelShort : 'UNDERBELLY',					LabelMedium : 'UNDERBELLY',				LabelLong : 'UNDERBELLY' },
		'undercover'					: { LabelShort : 'UNDERCOVER',					LabelMedium : 'UNDERCOVER',				LabelLong : 'UNDERCOVER' },
		'underwater'					: { LabelShort : 'UNDERWATER',					LabelMedium : 'UNDERWATER',				LabelLong : 'UNDERWATER' },
		'unfired'					: { LabelShort : 'UNFIRED',						LabelMedium : 'UNFIrED',					LabelLong : 'UNFIrED' },
		'uniongang'					: { LabelShort : 'UNIONGANG',					LabelMedium : 'UNIONGANG',				LabelLong : 'UNIONGANG' },
		'unique'					: { LabelShort : 'UNIQUE',						LabelMedium : 'UNiQUE',					LabelLong : 'UNiQUE' },
		'unit'						: { LabelShort : 'UNIT',						LabelMedium : 'UNiT',					LabelLong : 'UNiT' },
		'unitail'					: { LabelShort : 'UNITAIL',						LabelMedium : 'UNiTAiL',					LabelLong : 'UNiTAiL' },
		'unity'						: { LabelShort : 'UNITY',						LabelMedium : 'UNiTY',					LabelLong : 'UNiTY' },
		'universum'					: { LabelShort : 'UNIVERSUM',					LabelMedium : 'UNiVERSUM',				LabelLong : 'UNiVERSUM' },
		'unkn0wn'					: { LabelShort : 'UNKN0WN',						LabelMedium : 'UnKn0wn',					LabelLong : 'UnKn0wn' },
		'unskilled'					: { LabelShort : 'UNSKILLED',					LabelMedium : 'UNSKiLLED',				LabelLong : 'UNSKiLLED' },
		'untouchables'				: { LabelShort : 'UNTOUCHABLES',				LabelMedium : 'UNTOUCHABLES',			LabelLong : 'UNTOUCHABLES' },
		'unveil'					: { LabelShort : 'UNVEIL',						LabelMedium : 'UNVEiL',					LabelLong : 'UNVEiL' },
		'uranime'					: { LabelShort : 'URANIME',						LabelMedium : 'URANiME',					LabelLong : 'URANiME' },
		'usd'						: { LabelShort : 'USD',							LabelMedium : 'USD',					LabelLong : 'USD' },
		'useless'					: { LabelShort : 'USELESS',						LabelMedium : 'USELESS',					LabelLong : 'USELESS' },
		'usury'						: { LabelShort : 'USURY',						LabelMedium : 'USURY',					LabelLong : 'USURY' },
		'utopia'					: { LabelShort : 'UTOPIA',						LabelMedium : 'UTOPiA',					LabelLong : 'UTOPiA' },
		'utr'						: { LabelShort : 'UTR',							LabelMedium : 'UTR',					LabelLong : 'UTR' },
		'utt'						: { LabelShort : 'UTT',							LabelMedium : 'UTT',					LabelLong : 'UTT' },
		'uump4'						: { LabelShort : 'UUMP4',						LabelMedium : 'UUMp4',					LabelLong : 'UUMp4' },
		'uvall'						: { LabelShort : 'UVALL',						LabelMedium : 'UVall',					LabelLong : 'UVall' },
		'uyirvani'					: { LabelShort : 'UYIRVANI',					LabelMedium : 'Uyirvani',				LabelLong : 'Uyirvani' },
		'v0'							: { LabelShort : 'V0',							LabelMedium : 'v0',						LabelLong : 'v0' },
		'v3ritas'					: { LabelShort : 'V3RITAS',						LabelMedium : 'V3RiTAS',					LabelLong : 'V3RiTAS' },
		'v99'						: { LabelShort : 'V99',							LabelMedium : 'v99',					LabelLong : 'v99' },
		'vain'						: { LabelShort : 'VAIN',						LabelMedium : 'VAiN',					LabelLong : 'VAiN' },
		'vajnis'					: { LabelShort : 'VAJNIS',						LabelMedium : 'Vajnis',					LabelLong : 'Vajnis' },
		'valhalla'					: { LabelShort : 'VALHALLA',					LabelMedium : 'VALHALLA',				LabelLong : 'VALHALLA' },
		'valiomedia'					: { LabelShort : 'VALIOMEDIA',					LabelMedium : 'VALiOMEDiA',				LabelLong : 'VALiOMEDiA' },
		'value'						: { LabelShort : 'VALUE',						LabelMedium : 'VALUE',					LabelLong : 'VALUE' },
		'varyg'						: { LabelShort : 'VARYG',						LabelMedium : 'VARYG',					LabelLong : 'VARYG' },
		'vcdvault'					: { LabelShort : 'VCDVAULT',					LabelMedium : 'VCDVaULT',				LabelLong : 'VCDVaULT' },
		'vcore'						: { LabelShort : 'VCORE',						LabelMedium : 'VCORE',					LabelLong : 'VCORE' },
		'vector'					: { LabelShort : 'VECTOR',						LabelMedium : 'VectoR',					LabelLong : 'VectoR' },
		'vedett'					: { LabelShort : 'VEDETT',						LabelMedium : 'VeDeTT',					LabelLong : 'VeDeTT' },
		'veil'						: { LabelShort : 'VEIL',						LabelMedium : 'VEiL',					LabelLong : 'VEiL' },
		'venue'						: { LabelShort : 'VENUE',						LabelMedium : 'VENUE',					LabelLong : 'VENUE' },
		'veritas'					: { LabelShort : 'VERITAS',						LabelMedium : 'Veritas',					LabelLong : 'Veritas' },
		'verovenlo'					: { LabelShort : 'VEROVENLO',					LabelMedium : 'VeroVenlo',				LabelLong : 'VeroVenlo' },
		'verum'						: { LabelShort : 'VERUM',						LabelMedium : 'VERUM',					LabelLong : 'VERUM' },
		'vet'						: { LabelShort : 'VET',							LabelMedium : 'VET',					LabelLong : 'VET' },
		'veto'						: { LabelShort : 'VETO',						LabelMedium : 'VETO',					LabelLong : 'VETO' },
		'vex'						: { LabelShort : 'VEX',							LabelMedium : 'Vex',					LabelLong : 'Vex' },
		'vfhd'						: { LabelShort : 'VFHD',						LabelMedium : 'VFHD',					LabelLong : 'VFHD' },
		'vhd'						: { LabelShort : 'VHD',							LabelMedium : 'VHD',					LabelLong : 'VHD' },
		'viazac'					: { LabelShort : 'VIAZAC',						LabelMedium : 'VIAZAC',					LabelLong : 'VIAZAC' },
		'vid'						: { LabelShort : 'VID',							LabelMedium : 'ViD',					LabelLong : 'ViD' },
		'videostar'					: { LabelShort : 'VIDEOSTAR',					LabelMedium : 'VideoStar',				LabelLong : 'VideoStar' },
		'videowelt'					: { LabelShort : 'VIDEOWELT',					LabelMedium : 'ViDEOWELT',				LabelLong : 'ViDEOWELT' },
		'viethd'					: { LabelShort : 'VIETHD',						LabelMedium : 'VietHD',					LabelLong : 'VietHD' },
		'vigi'						: { LabelShort : 'VIGI',						LabelMedium : 'ViGi',					LabelLong : 'ViGi' },
		'vinyl'						: { LabelShort : 'VINYL',						LabelMedium : 'ViNYL',					LabelLong : 'ViNYL' },
		'vip3r'						: { LabelShort : 'VIP3R',						LabelMedium : 'ViP3R',					LabelLong : 'ViP3R' },
		'viper'						: { LabelShort : 'VIPER',						LabelMedium : 'ViPER',					LabelLong : 'ViPER' },
		'viscabarca'					: { LabelShort : 'VISCABARCA',					LabelMedium : 'ViscaBarca',				LabelLong : 'ViscaBarca' },
		'visionx'					: { LabelShort : 'VISIONX',						LabelMedium : 'VisionX',					LabelLong : 'VisionX' },
		'vista'						: { LabelShort : 'VISTA',						LabelMedium : 'ViSTA',					LabelLong : 'ViSTA' },
		'visum'						: { LabelShort : 'VISUM',						LabelMedium : 'ViSUM',					LabelLong : 'ViSUM' },
		'vite'						: { LabelShort : 'VITE',						LabelMedium : 'ViTE',					LabelLong : 'ViTE' },
		'vivi'						: { LabelShort : 'VIVI',						LabelMedium : 'ViVi',					LabelLong : 'ViVi' },
		'vixon'						: { LabelShort : 'VIXON',						LabelMedium : 'ViXON',					LabelLong : 'ViXON' },
		'vlad'						: { LabelShort : 'VLAD',						LabelMedium : 'VLAD',					LabelLong : 'VLAD' },
		'vlaluk'					: { LabelShort : 'VLALUK',						LabelMedium : 'vlaluk',					LabelLong : 'vlaluk' },
		'vlis'						: { LabelShort : 'VLIS',						LabelMedium : 'VLiS',					LabelLong : 'VLiS' },
		'voa'						: { LabelShort : 'VOA',							LabelMedium : 'VOA',					LabelLong : 'VOA' },
		'vodtv'						: { LabelShort : 'VODTV',						LabelMedium : 'VoDTv',					LabelLong : 'VoDTv' },
		'void'						: { LabelShort : 'VOID',						LabelMedium : 'VOID',					LabelLong : 'VOID' },
		'volatile'					: { LabelShort : 'VOLATILE',					LabelMedium : 'VOLATiLE',				LabelLong : 'VOLATiLE' },
		'vomit'						: { LabelShort : 'VOMIT',						LabelMedium : 'VoMiT',					LabelLong : 'VoMiT' },
		'vox'						: { LabelShort : 'VOX',							LabelMedium : 'VoX',					LabelLong : 'VoX' },
		'voxhd'						: { LabelShort : 'VOXHD',						LabelMedium : 'VoXHD',					LabelLong : 'VoXHD' },
		'vppv'						: { LabelShort : 'VPPV',						LabelMedium : 'VPPV',					LabelLong : 'VPPV' },
		'vr'							: { LabelShort : 'VR',							LabelMedium : 'VR',						LabelLong : 'VR' },
		'vrs'						: { LabelShort : 'VRS',							LabelMedium : 'vrs',					LabelLong : 'vrs' },
		'vt'							: { LabelShort : 'VT',							LabelMedium : 'VT',						LabelLong : 'VT' },
		'vtv'						: { LabelShort : 'VTV',							LabelMedium : 'VTV',					LabelLong : 'VTV' },
		'vxt'						: { LabelShort : 'VXT',							LabelMedium : 'VXT',					LabelLong : 'VXT' },
		'vyndros'					: { LabelShort : 'VYNDROS',						LabelMedium : 'Vyndros',					LabelLong : 'Vyndros' },
		'vyto'						: { LabelShort : 'VYTO',						LabelMedium : 'VYTO',					LabelLong : 'VYTO' },
		'w4f'						: { LabelShort : 'W4F',							LabelMedium : 'W4F',					LabelLong : 'W4F' },
		'wackos'					: { LabelShort : 'WACKOS',						LabelMedium : 'WaCkOs',					LabelLong : 'WaCkOs' },
		'waf'						: { LabelShort : 'WAF',							LabelMedium : 'WAF',					LabelLong : 'WAF' },
		'walmart'					: { LabelShort : 'WALMART',						LabelMedium : 'WaLMaRT',					LabelLong : 'WaLMaRT' },
		'wam'						: { LabelShort : 'WAM',							LabelMedium : 'wAm',					LabelLong : 'wAm' },
		'warriors'					: { LabelShort : 'WARRIORS',					LabelMedium : 'WARRIORS',				LabelLong : 'WARRIORS' },
		'waste'						: { LabelShort : 'WASTE',						LabelMedium : 'WASTE',					LabelLong : 'WASTE' },
		'wat'						: { LabelShort : 'WAT',							LabelMedium : 'WAT',					LabelLong : 'WAT' },
		'watbath'					: { LabelShort : 'WATBATH',						LabelMedium : 'WATBATH',					LabelLong : 'WATBATH' },
		'watchable'					: { LabelShort : 'WATCHABLE',					LabelMedium : 'WATCHABLE',				LabelLong : 'WATCHABLE' },
		'watcher'					: { LabelShort : 'WATCHER',						LabelMedium : 'WATCHER',					LabelLong : 'WATCHER' },
		'watchmo'					: { LabelShort : 'WATCHMO',						LabelMedium : 'WATCHMO',					LabelLong : 'WATCHMO' },
		'waters'					: { LabelShort : 'WATERS',						LabelMedium : 'WATERS',					LabelLong : 'WATERS' },
		'wavey'						: { LabelShort : 'WAVEY',						LabelMedium : 'WAVEY',					LabelLong : 'WAVEY' },
		'wayne'						: { LabelShort : 'WAYNE',						LabelMedium : 'WAYNE',					LabelLong : 'WAYNE' },
		'wb'							: { LabelShort : 'WB',							LabelMedium : 'WB',						LabelLong : 'W-B' },
		'wbz'						: { LabelShort : 'WBZ',							LabelMedium : 'WBZ',					LabelLong : 'WBZ' },
		'wdk'						: { LabelShort : 'WDK',							LabelMedium : 'WDK',					LabelLong : 'WDK' },
		'weasley'					: { LabelShort : 'WEASLEY',						LabelMedium : 'Weasley',					LabelLong : 'Weasley' },
		'web4hd'					: { LabelShort : 'WEB4HD',						LabelMedium : 'Web4HD',					LabelLong : 'Web4HD' },
		'webhiker'					: { LabelShort : 'WEBHIKER',					LabelMedium : 'Webhiker',				LabelLong : 'Webhiker' },
		'webster'					: { LabelShort : 'WEBSTER',						LabelMedium : 'WEBSTER',					LabelLong : 'WEBSTER' },
		'webtiful'					: { LabelShort : 'WEBTIFUL',					LabelMedium : 'WEBTiFUL',				LabelLong : 'WEBTiFUL' },
		'webtube'					: { LabelShort : 'WEBTUBE',						LabelMedium : 'WEBTUBE',					LabelLong : 'WEBTUBE' },
		'weby'						: { LabelShort : 'WEBY',						LabelMedium : 'Weby',					LabelLong : 'Weby' },
		'welp'						: { LabelShort : 'WELP',						LabelMedium : 'WELP',					LabelLong : 'WELP' },
		'wem'						: { LabelShort : 'WEM',							LabelMedium : 'WEM',					LabelLong : 'WEM' },
		'wesen'						: { LabelShort : 'WESEN',						LabelMedium : 'WESEN',					LabelLong : 'WESEN' },
		'west'						: { LabelShort : 'WEST',						LabelMedium : 'WEST',					LabelLong : 'WEST' },
		'westside'					: { LabelShort : 'WESTSIDE',					LabelMedium : 'WESTSiDE',				LabelLong : 'WESTSiDE' },
		'wgz'						: { LabelShort : 'WGZ',							LabelMedium : 'WGZ',					LabelLong : 'WGZ' },
		'whatelse'					: { LabelShort : 'WHATELSE',					LabelMedium : 'WHATELSE',				LabelLong : 'WHATELSE' },
		'whd'						: { LabelShort : 'WHD',							LabelMedium : 'WHD',					LabelLong : 'WHD' },
		'wheels'					: { LabelShort : 'WHEELS',						LabelMedium : 'WHEELS',					LabelLong : 'WHEELS' },
		'whiizz'					: { LabelShort : 'WHIIZZ',						LabelMedium : 'WHiiZz',					LabelLong : 'WHiiZz' },
		'whip93'					: { LabelShort : 'WHIP93',						LabelMedium : 'whip93',					LabelLong : 'whip93' },
		'whisky'					: { LabelShort : 'WHISKY',						LabelMedium : 'WHISKY',					LabelLong : 'WHISKY' },
		'whitehat'					: { LabelShort : 'WHITEHAT',					LabelMedium : 'WhiteHat',				LabelLong : 'WhiteHat' },
		'whiterevtmp'				: { LabelShort : 'WHITEREVTMP',					LabelMedium : 'WhiteRevtmp',			LabelLong : 'WhiteRevtmp' },
		'whiterhino'					: { LabelShort : 'WHITERHINO',					LabelMedium : 'WhiteRhino',				LabelLong : 'WhiteRhino' },
		'whoknow'					: { LabelShort : 'WHOKNOW',						LabelMedium : 'WhoKnow',					LabelLong : 'WhoKnow' },
		'whosnext'					: { LabelShort : 'WHOSNEXT',					LabelMedium : 'WHOSNEXT',				LabelLong : 'WHOSNEXT' },
		'wide'						: { LabelShort : 'WIDE',						LabelMedium : 'WiDE',					LabelLong : 'WiDE' },
		'wihd'						: { LabelShort : 'WIHD',						LabelMedium : 'WiHD',					LabelLong : 'WiHD' },
		'wiifi'						: { LabelShort : 'WIIFI',						LabelMedium : 'WiiFi',					LabelLong : 'WiiFi' },
		'wiki'						: { LabelShort : 'WIKI',						LabelMedium : 'WiKi',					LabelLong : 'WiKi' },
		'wildcat'					: { LabelShort : 'WILDCAT',						LabelMedium : 'WiLDCAT',					LabelLong : 'WiLDCAT' },
		'wilder'					: { LabelShort : 'WILDER',						LabelMedium : 'WILDER',					LabelLong : 'WILDER' },
		'will1869'					: { LabelShort : 'WILL1869',					LabelMedium : 'Will1869',				LabelLong : 'Will1869' },
		'wind'						: { LabelShort : 'WIND',						LabelMedium : 'WinD',					LabelLong : 'WinD' },
		'wing'						: { LabelShort : 'WING',						LabelMedium : 'WiNG',					LabelLong : 'WiNG' },
		'winks'						: { LabelShort : 'WINKS',						LabelMedium : 'Winks',					LabelLong : 'Winks' },
		'winters'					: { LabelShort : 'WINTERS',						LabelMedium : 'WINTERS',					LabelLong : 'WINTERS' },
		'wire'						: { LabelShort : 'WIRE',						LabelMedium : 'WiRE',					LabelLong : 'WiRE' },
		'wishtv'					: { LabelShort : 'WISHTV',						LabelMedium : 'WiSHTV',					LabelLong : 'WiSHTV' },
		'wlm'						: { LabelShort : 'WLM',							LabelMedium : 'WLM',					LabelLong : 'WLM' },
		'wman'						: { LabelShort : 'WMAN',						LabelMedium : 'WMAN',					LabelLong : 'WMAN' },
		'wmt'						: { LabelShort : 'WMT',							LabelMedium : 'wmt',					LabelLong : 'wmt' },
		'woat'						: { LabelShort : 'WOAT',						LabelMedium : 'WoAT',					LabelLong : 'WoAT' },
		'wolf'						: { LabelShort : 'WOLF',						LabelMedium : 'WoLF',					LabelLong : 'WoLF' },
		'wolfpack'					: { LabelShort : 'WOLFPACK',					LabelMedium : 'WOLFPACK',				LabelLong : 'WOLFPACK' },
		'wolverdonfilmes'			: { LabelShort : 'WOLVERDONFILMES',				LabelMedium : 'WOLVERDONFILMES',			LabelLong : 'WOLVERDONFILMES.TO' },
		'wombat'					: { LabelShort : 'WOMBAT',						LabelMedium : 'WOMBAT',					LabelLong : 'WOMBAT' },
		'woody'						: { LabelShort : 'WOODY',						LabelMedium : 'WooDY',					LabelLong : 'WooDY' },
		'worldfree4u'				: { LabelShort : 'WORLDFREE4U',					LabelMedium : 'Worldfree4u',			LabelLong : 'Worldfree4u.Link' },
		'worldmkv'					: { LabelShort : 'WORLDMKV',					LabelMedium : 'WorldMkv',				LabelLong : 'WorldMkv' },
		'wow'						: { LabelShort : 'WOW',							LabelMedium : 'WoW',					LabelLong : 'WoW' },
		'wowrip'					: { LabelShort : 'WOWRIP',						LabelMedium : 'WOWRip',					LabelLong : 'WOWRip' },
		'wpi'						: { LabelShort : 'WPI',							LabelMedium : 'WPi',					LabelLong : 'WPi' },
		'wrcr'						: { LabelShort : 'WRCR',						LabelMedium : 'WRCR',					LabelLong : 'WRCR' },
		'wrd'						: { LabelShort : 'WRD',							LabelMedium : 'WRD',					LabelLong : 'WRD' },
		'wrs'						: { LabelShort : 'WRS',							LabelMedium : 'WRS',					LabelLong : 'WRS' },
		'wuruhi'					: { LabelShort : 'WURUHI',						LabelMedium : 'WURUHI',					LabelLong : 'WURUHI' },
		'wutang'					: { LabelShort : 'WUTANG',						LabelMedium : 'WUTANG',					LabelLong : 'WUTANG' },
		'wvf'						: { LabelShort : 'WVF',							LabelMedium : 'WvF',					LabelLong : 'WvF' },
		'wwrg'						: { LabelShort : 'WWRG',						LabelMedium : 'WWRG',					LabelLong : 'WWRG' },
		'x0r'						: { LabelShort : 'X0R',							LabelMedium : 'x0r',					LabelLong : 'x0r' },
		'xanax'						: { LabelShort : 'XANAX',						LabelMedium : 'XanaX',					LabelLong : 'XanaX' },
		'xander'					: { LabelShort : 'XANDER',						LabelMedium : 'xander',					LabelLong : 'xander' },
		'xannyfamily'				: { LabelShort : 'XANNYFAMILY',					LabelMedium : 'XannyFamily',			LabelLong : 'XannyFamily' },
		'xbay'						: { LabelShort : 'XBAY',						LabelMedium : 'xBay',					LabelLong : 'xBay' },
		'xc'							: { LabelShort : 'XC',							LabelMedium : 'XC',						LabelLong : 'XC' },
		'xd2v'						: { LabelShort : 'XD2V',						LabelMedium : 'xD2V',					LabelLong : 'xD2V' },
		'xdr'						: { LabelShort : 'XDR',							LabelMedium : 'xDR',					LabelLong : 'xDR' },
		'xf'							: { LabelShort : 'XF',							LabelMedium : 'XF',						LabelLong : 'XF' },
		'xhd'						: { LabelShort : 'XHD',							LabelMedium : 'XHD',					LabelLong : 'XHD' },
		'xibirikinho'				: { LabelShort : 'XIBIRIKINHO',					LabelMedium : 'Xibirikinho',			LabelLong : 'Xibirikinho' },
		'xii'						: { LabelShort : 'XII',							LabelMedium : 'XII',					LabelLong : 'XII' },
		'xlf'						: { LabelShort : 'XLF',							LabelMedium : 'XLF',					LabelLong : 'XLF' },
		'xme'						: { LabelShort : 'XME',							LabelMedium : 'XME',					LabelLong : 'XME' },
		'xor'						: { LabelShort : 'XOR',							LabelMedium : 'XOR',					LabelLong : 'XOR' },
		'xorbitant'					: { LabelShort : 'XORBITANT',					LabelMedium : 'XORBiTANT',				LabelLong : 'XORBiTANT' },
		'xoxo'						: { LabelShort : 'XOXO',						LabelMedium : 'XOXO',					LabelLong : 'XOXO' },
		'xpau'						: { LabelShort : 'XPAU',						LabelMedium : 'xPau',					LabelLong : 'xPau' },
		'xpert'						: { LabelShort : 'XPERT',						LabelMedium : 'XPERT',					LabelLong : 'XPERT' },
		'xpoz'						: { LabelShort : 'XPOZ',						LabelMedium : 'XpoZ',					LabelLong : 'XpoZ' },
		'xpress'					: { LabelShort : 'XPRESS',						LabelMedium : 'XPRESS',					LabelLong : 'XPRESS' },
		'xred'						: { LabelShort : 'XRED',						LabelMedium : 'xRed',					LabelLong : 'xRed' },
		'xrg'						: { LabelShort : 'XRG',							LabelMedium : 'xRG',					LabelLong : 'xRG' },
		'xs'							: { LabelShort : 'XS',							LabelMedium : 'XS',						LabelLong : 'X-S' },
		'xshd'						: { LabelShort : 'XSHD',						LabelMedium : 'XSHD',					LabelLong : 'XSHD' },
		'xstreem'					: { LabelShort : 'XSTREEM',						LabelMedium : 'XSTREEM',					LabelLong : 'XSTREEM' },
		'xtm'						: { LabelShort : 'XTM',							LabelMedium : 'XTM',					LabelLong : 'XTM' },
		'xtrill'					: { LabelShort : 'XTRILL',						LabelMedium : 'xTriLL',					LabelLong : 'xTriLL' },
		'xtsf'						: { LabelShort : 'XTSF',						LabelMedium : 'XTSF',					LabelLong : 'XTSF' },
		'xv'							: { LabelShort : 'XV',							LabelMedium : 'xV',						LabelLong : 'xV' },
		'xvik'						: { LabelShort : 'XVIK',						LabelMedium : 'XviK',					LabelLong : 'XviK' },
		'xwt'						: { LabelShort : 'XWT',							LabelMedium : 'XWT',					LabelLong : 'XWT' },
		'xxunkn0wnxx'				: { LabelShort : 'XXUNKN0WNXX',					LabelMedium : 'XxUnkn0wnxX',			LabelLong : 'XxUnkn0wnxX' },
		'xxxpav69'					: { LabelShort : 'XXXPAV69',					LabelMedium : 'xxxpav69',				LabelLong : 'xxxpav69' },
		'xyz'						: { LabelShort : 'XYZ',							LabelMedium : 'XYZ',					LabelLong : 'XYZ' },
		'ya'							: { LabelShort : 'YA',							LabelMedium : 'YA',						LabelLong : 'YA' },
		'yakuza'					: { LabelShort : 'YAKUZA',						LabelMedium : 'YaKuZa',					LabelLong : 'YaKuZa' },
		'yazoomix'					: { LabelShort : 'YAZOOMIX',					LabelMedium : 'YazooMix',				LabelLong : 'YazooMix' },
		'yellowbird'					: { LabelShort : 'YELLOWBIRD',					LabelMedium : 'YELLOWBiRD',				LabelLong : 'YELLOWBiRD' },
		'yestv'						: { LabelShort : 'YESTV',						LabelMedium : 'YesTV',					LabelLong : 'YesTV' },
		'yfn'						: { LabelShort : 'YFN',							LabelMedium : 'YFN',					LabelLong : 'YFN' },
		'yg'							: { LabelShort : 'YG',							LabelMedium : 'YG',						LabelLong : 'YG' },
		'yifi'						: { LabelShort : 'YIFI',						LabelMedium : 'YIFI',					LabelLong : 'YIFI' },
		'yify'						: { LabelShort : 'YIFY',						LabelMedium : 'YIFY',					LabelLong : 'YIFY' },
		'yn1d'						: { LabelShort : 'YN1D',						LabelMedium : 'Yn1D',					LabelLong : 'Yn1D' },
		'yogi'						: { LabelShort : 'YOGI',						LabelMedium : 'YOGI',					LabelLong : 'YOGI' },
		'yol0w'						: { LabelShort : 'YOL0W',						LabelMedium : 'YOL0W',					LabelLong : 'YOL0W' },
		'yourmom'					: { LabelShort : 'YOURMOM',						LabelMedium : 'YourMom',					LabelLong : 'Your-Mom' },
		'yoyo'						: { LabelShort : 'YOYO',						LabelMedium : 'YOYO',					LabelLong : 'YOYO' },
		'ys'							: { LabelShort : 'YS',							LabelMedium : 'YS',						LabelLong : 'YS' },
		'ysteam'					: { LabelShort : 'YSTEAM',						LabelMedium : 'YSTeam',					LabelLong : 'YSTeam' },
		'yt'							: { LabelShort : 'YT',							LabelMedium : 'YT',						LabelLong : 'Y-T' },
		'yts'						: { LabelShort : 'YTS',							LabelMedium : 'YTS',					LabelLong : 'YTS.AG' },
		'yuma'						: { LabelShort : 'YUMA',						LabelMedium : 'YUMA',					LabelLong : 'YUMA' },
		'zaeem'						: { LabelShort : 'ZAEEM',						LabelMedium : 'Zaeem',					LabelLong : 'Zaeem' },
		'zagon'						: { LabelShort : 'ZAGON',						LabelMedium : 'Zagon',					LabelLong : 'Zagon' },
		'zan'						: { LabelShort : 'ZAN',							LabelMedium : 'zan',					LabelLong : 'zan' },
		'zechs'						: { LabelShort : 'ZECHS',						LabelMedium : 'ZECHS',					LabelLong : 'ZECHS' },
		'zeiz'						: { LabelShort : 'ZEIZ',						LabelMedium : 'ZeiZ',					LabelLong : 'ZeiZ' },
		'zeke'						: { LabelShort : 'ZEKE',						LabelMedium : 'ZEKE',					LabelLong : 'ZEKE' },
		'zektorm'					: { LabelShort : 'ZEKTORM',						LabelMedium : 'ZEKTORM',					LabelLong : 'ZEKTORM' },
		'zel'						: { LabelShort : 'ZEL',							LabelMedium : 'Zel',					LabelLong : 'Zel' },
		'zen'						: { LabelShort : 'ZEN',							LabelMedium : 'ZEN',					LabelLong : 'ZEN' },
		'zenbud'					: { LabelShort : 'ZENBUD',						LabelMedium : 'ZenBud',					LabelLong : 'Zen_Bud' },
		'zer0'						: { LabelShort : 'ZER0',						LabelMedium : 'ZER0',					LabelLong : 'ZER0' },
		'zero'						: { LabelShort : 'ZERO',						LabelMedium : 'ZeRO',					LabelLong : 'ZeRO' },
		'zest'						: { LabelShort : 'ZEST',						LabelMedium : 'ZEST',					LabelLong : 'ZEST' },
		'zeus'						: { LabelShort : 'ZEUS',						LabelMedium : 'ZEUS',					LabelLong : 'ZEUS' },
		'zeusdias'					: { LabelShort : 'ZEUSDIAS',					LabelMedium : 'ZeusDias',				LabelLong : 'Zeus-Dias' },
		'zinc'						: { LabelShort : 'ZINC',						LabelMedium : 'ZiNC',					LabelLong : 'ZiNC' },
		'zit'						: { LabelShort : 'ZIT',							LabelMedium : 'Zit',					LabelLong : 'Zi.t' },
		'zito'						: { LabelShort : 'ZITO',						LabelMedium : 'ZiTO',					LabelLong : 'ZiTO' },
		'zmachine'					: { LabelShort : 'ZMACHINE',					LabelMedium : 'ZMachine',				LabelLong : 'ZMachine' },
		'zman'						: { LabelShort : 'ZMAN',						LabelMedium : 'zman',					LabelLong : 'zman' },
		'zmg'						: { LabelShort : 'ZMG',							LabelMedium : 'ZMG',					LabelLong : 'ZMG' },
		'zmnt'						: { LabelShort : 'ZMNT',						LabelMedium : 'ZMNT',					LabelLong : 'ZMNT' },
		'zodiac'					: { LabelShort : 'ZODIAC',						LabelMedium : 'Zodiac',					LabelLong : 'Zodiac' },
		'zonatorrent2'				: { LabelShort : 'ZONATORRENT2',				LabelMedium : 'ZonaTorrent2',			LabelLong : 'ZonaTorrent2' },
		'zoneempire'					: { LabelShort : 'ZONEEMPIRE',					LabelMedium : 'ZoneEmpire',				LabelLong : 'Zone-Empire' },
		'zoom'						: { LabelShort : 'ZOOM',						LabelMedium : 'ZoOm',					LabelLong : 'ZoOm' },
		'zq'							: { LabelShort : 'ZQ',							LabelMedium : 'ZQ',						LabelLong : 'ZQ' },
		'zr'							: { LabelShort : 'ZR',							LabelMedium : 'ZR',						LabelLong : 'ZR' },
		'zs'							: { LabelShort : 'ZS',							LabelMedium : 'ZS',						LabelLong : 'ZS' },
		'zsewdc'					: { LabelShort : 'ZSEWDC',						LabelMedium : 'zsewdc',					LabelLong : 'zsewdc' },
		'zsiso'						: { LabelShort : 'ZSISO',						LabelMedium : 'ZSiSO',					LabelLong : 'ZSiSO' },
		'ztorrenter'					: { LabelShort : 'ZTORRENTER',					LabelMedium : 'ztorrenter',				LabelLong : 'ztorrenter' },
		'zuzuu'						: { LabelShort : 'ZUZUU',						LabelMedium : 'Zuzuu',					LabelLong : 'Zuzuu' },
		'zw'							: { LabelShort : 'ZW',							LabelMedium : 'zw',						LabelLong : 'zw' },
		'zza'						: { LabelShort : 'ZZA',							LabelMedium : 'zza',					LabelLong : 'zza' },
		'zzgtv'						: { LabelShort : 'ZZGTV',						LabelMedium : 'ZZGtv',					LabelLong : 'ZZGtv' },
	}

	OrderReleaseGroup = {
		'0mnidvd'					: { OrderInterface : 1,		OrderSorting : 1 },
		'0ptimus'					: { OrderInterface : 2,		OrderSorting : 2 },
		'0sec'						: { OrderInterface : 3,		OrderSorting : 3 },
		'0tv'						: { OrderInterface : 4,		OrderSorting : 4 },
		'1337x'						: { OrderInterface : 5,		OrderSorting : 5 },
		'182k'						: { OrderInterface : 6,		OrderSorting : 6 },
		'1xbet'						: { OrderInterface : 7,		OrderSorting : 7 },
		'24hd'						: { OrderInterface : 8,		OrderSorting : 8 },
		'24xhd'						: { OrderInterface : 9,		OrderSorting : 9 },
		'26k'						: { OrderInterface : 10,		OrderSorting : 10 },
		'2brothers'					: { OrderInterface : 11,		OrderSorting : 11 },
		'2dvd'						: { OrderInterface : 12,		OrderSorting : 12 },
		'2hd'						: { OrderInterface : 13,		OrderSorting : 13 },
		'2lions'					: { OrderInterface : 14,		OrderSorting : 14 },
		'300mbmovieshub'			: { OrderInterface : 15,		OrderSorting : 15 },
		'30nama'					: { OrderInterface : 16,		OrderSorting : 16 },
		'3li'						: { OrderInterface : 17,		OrderSorting : 17 },
		'3lt0n'						: { OrderInterface : 18,		OrderSorting : 18 },
		'3lton'						: { OrderInterface : 19,		OrderSorting : 19 },
		'420ripz'					: { OrderInterface : 20,		OrderSorting : 20 },
		'4ddl'						: { OrderInterface : 21,		OrderSorting : 21 },
		'4everdowns'					: { OrderInterface : 22,		OrderSorting : 22 },
		'4fun'						: { OrderInterface : 23,		OrderSorting : 23 },
		'4k4u'						: { OrderInterface : 24,		OrderSorting : 24 },
		'4pl'						: { OrderInterface : 25,		OrderSorting : 25 },
		'4sj'						: { OrderInterface : 26,		OrderSorting : 26 },
		'57chan'					: { OrderInterface : 27,		OrderSorting : 27 },
		'5kull5'					: { OrderInterface : 28,		OrderSorting : 28 },
		'6ixt33n'					: { OrderInterface : 29,		OrderSorting : 29 },
		'7meiju'					: { OrderInterface : 30,		OrderSorting : 30 },
		'7rip'						: { OrderInterface : 31,		OrderSorting : 31 },
		'7sins'						: { OrderInterface : 32,		OrderSorting : 32 },
		'99mp4'						: { OrderInterface : 33,		OrderSorting : 33 },
		'a1rip'						: { OrderInterface : 34,		OrderSorting : 34 },
		'aa'							: { OrderInterface : 35,		OrderSorting : 35 },
		'aaa'						: { OrderInterface : 36,		OrderSorting : 36 },
		'aaauhd'					: { OrderInterface : 37,		OrderSorting : 37 },
		'aaf'						: { OrderInterface : 38,		OrderSorting : 38 },
		'ab'							: { OrderInterface : 39,		OrderSorting : 39 },
		'abb'						: { OrderInterface : 40,		OrderSorting : 40 },
		'abbie'						: { OrderInterface : 41,		OrderSorting : 41 },
		'abd'						: { OrderInterface : 42,		OrderSorting : 42 },
		'abh'						: { OrderInterface : 43,		OrderSorting : 43 },
		'abhisona'					: { OrderInterface : 44,		OrderSorting : 44 },
		'abhistuff'					: { OrderInterface : 45,		OrderSorting : 45 },
		'abjex'						: { OrderInterface : 46,		OrderSorting : 46 },
		'abm'						: { OrderInterface : 47,		OrderSorting : 47 },
		'absinth'					: { OrderInterface : 48,		OrderSorting : 48 },
		'absurdity'					: { OrderInterface : 49,		OrderSorting : 49 },
		'abu'						: { OrderInterface : 50,		OrderSorting : 50 },
		'abyss'						: { OrderInterface : 51,		OrderSorting : 51 },
		'acab'						: { OrderInterface : 52,		OrderSorting : 52 },
		'aced'						: { OrderInterface : 53,		OrderSorting : 53 },
		'aceford'					: { OrderInterface : 54,		OrderSorting : 54 },
		'ack'						: { OrderInterface : 55,		OrderSorting : 55 },
		'acool'						: { OrderInterface : 56,		OrderSorting : 56 },
		'actie'						: { OrderInterface : 57,		OrderSorting : 57 },
		'adblue'					: { OrderInterface : 58,		OrderSorting : 58 },
		'adhd'						: { OrderInterface : 59,		OrderSorting : 59 },
		'adit'						: { OrderInterface : 60,		OrderSorting : 60 },
		'adl'						: { OrderInterface : 61,		OrderSorting : 61 },
		'adrenaline'					: { OrderInterface : 62,		OrderSorting : 62 },
		'adrian'					: { OrderInterface : 63,		OrderSorting : 63 },
		'ae'							: { OrderInterface : 64,		OrderSorting : 64 },
		'aen'						: { OrderInterface : 65,		OrderSorting : 65 },
		'aero'						: { OrderInterface : 66,		OrderSorting : 66 },
		'aeroholics'					: { OrderInterface : 67,		OrderSorting : 67 },
		'af'							: { OrderInterface : 68,		OrderSorting : 68 },
		'affinity'					: { OrderInterface : 69,		OrderSorting : 69 },
		'afg'						: { OrderInterface : 70,		OrderSorting : 70 },
		'afi'						: { OrderInterface : 71,		OrderSorting : 71 },
		'afm72'						: { OrderInterface : 72,		OrderSorting : 72 },
		'afo'						: { OrderInterface : 73,		OrderSorting : 73 },
		'aggr0'						: { OrderInterface : 74,		OrderSorting : 74 },
		'aglet'						: { OrderInterface : 75,		OrderSorting : 75 },
		'agusiq'					: { OrderInterface : 76,		OrderSorting : 76 },
		'ahd'						: { OrderInterface : 77,		OrderSorting : 77 },
		'aida'						: { OrderInterface : 78,		OrderSorting : 78 },
		'aiden0'					: { OrderInterface : 79,		OrderSorting : 79 },
		'aihd'						: { OrderInterface : 80,		OrderSorting : 80 },
		'aio'						: { OrderInterface : 81,		OrderSorting : 81 },
		'airline'					: { OrderInterface : 82,		OrderSorting : 82 },
		'airtv'						: { OrderInterface : 83,		OrderSorting : 83 },
		'aj'							: { OrderInterface : 84,		OrderSorting : 84 },
		'aja'						: { OrderInterface : 85,		OrderSorting : 85 },
		'ajp'						: { OrderInterface : 86,		OrderSorting : 86 },
		'ajp69'						: { OrderInterface : 87,		OrderSorting : 87 },
		'ak'							: { OrderInterface : 88,		OrderSorting : 88 },
		'akihitosubs'				: { OrderInterface : 89,		OrderSorting : 89 },
		'akraa'						: { OrderInterface : 90,		OrderSorting : 90 },
		'aku'						: { OrderInterface : 91,		OrderSorting : 91 },
		'alanis'					: { OrderInterface : 92,		OrderSorting : 92 },
		'ale13'						: { OrderInterface : 93,		OrderSorting : 93 },
		'alexfilm'					: { OrderInterface : 94,		OrderSorting : 94 },
		'alfahd'					: { OrderInterface : 95,		OrderSorting : 95 },
		'alien'						: { OrderInterface : 96,		OrderSorting : 96 },
		'align'						: { OrderInterface : 97,		OrderSorting : 97 },
		'alldayin'					: { OrderInterface : 98,		OrderSorting : 98 },
		'alliance'					: { OrderInterface : 99,		OrderSorting : 99 },
		'almighty'					: { OrderInterface : 100,	OrderSorting : 100 },
		'alt'						: { OrderInterface : 101,	OrderSorting : 101 },
		'alterego'					: { OrderInterface : 102,	OrderSorting : 102 },
		'altezachen'					: { OrderInterface : 103,	OrderSorting : 103 },
		'am'							: { OrderInterface : 104,	OrderSorting : 104 },
		'ambassador'					: { OrderInterface : 105,	OrderSorting : 105 },
		'ambit'						: { OrderInterface : 106,	OrderSorting : 106 },
		'ambitious'					: { OrderInterface : 107,	OrderSorting : 107 },
		'amcon'						: { OrderInterface : 108,	OrderSorting : 108 },
		'ame'						: { OrderInterface : 109,	OrderSorting : 109 },
		'amedia'					: { OrderInterface : 110,	OrderSorting : 110 },
		'amiable'					: { OrderInterface : 111,	OrderSorting : 111 },
		'amirite'					: { OrderInterface : 112,	OrderSorting : 112 },
		'amrap'						: { OrderInterface : 113,	OrderSorting : 113 },
		'amx'						: { OrderInterface : 114,	OrderSorting : 114 },
		'an0nym0us'					: { OrderInterface : 115,	OrderSorting : 115 },
		'anarchy'					: { OrderInterface : 116,	OrderSorting : 116 },
		'anbc'						: { OrderInterface : 117,	OrderSorting : 117 },
		'ancient'					: { OrderInterface : 118,	OrderSorting : 118 },
		'andy'						: { OrderInterface : 119,	OrderSorting : 119 },
		'ane'						: { OrderInterface : 120,	OrderSorting : 120 },
		'angelic'					: { OrderInterface : 121,	OrderSorting : 121 },
		'anihls'					: { OrderInterface : 122,	OrderSorting : 122 },
		'animal'					: { OrderInterface : 123,	OrderSorting : 123 },
		'animerg'					: { OrderInterface : 124,	OrderSorting : 124 },
		'animetime'					: { OrderInterface : 125,	OrderSorting : 125 },
		'aniurl'					: { OrderInterface : 126,	OrderSorting : 126 },
		'ank'						: { OrderInterface : 127,	OrderSorting : 127 },
		'ann'						: { OrderInterface : 128,	OrderSorting : 128 },
		'ano'						: { OrderInterface : 129,	OrderSorting : 129 },
		'anon'						: { OrderInterface : 130,	OrderSorting : 130 },
		'anona911'					: { OrderInterface : 131,	OrderSorting : 131 },
		'anonimo'					: { OrderInterface : 132,	OrderSorting : 132 },
		'anoxmous'					: { OrderInterface : 133,	OrderSorting : 133 },
		'ans'						: { OrderInterface : 134,	OrderSorting : 134 },
		'antiordinary'				: { OrderInterface : 135,	OrderSorting : 135 },
		'anubis'					: { OrderInterface : 136,	OrderSorting : 136 },
		'aoe'						: { OrderInterface : 137,	OrderSorting : 137 },
		'aoksquad'					: { OrderInterface : 138,	OrderSorting : 138 },
		'aot'						: { OrderInterface : 139,	OrderSorting : 139 },
		'ap'							: { OrderInterface : 140,	OrderSorting : 140 },
		'apa'						: { OrderInterface : 141,	OrderSorting : 141 },
		'apb'						: { OrderInterface : 142,	OrderSorting : 142 },
		'apekat'					: { OrderInterface : 143,	OrderSorting : 143 },
		'apex'						: { OrderInterface : 144,	OrderSorting : 144 },
		'apt'						: { OrderInterface : 145,	OrderSorting : 145 },
		'aq'							: { OrderInterface : 146,	OrderSorting : 146 },
		'aqos'						: { OrderInterface : 147,	OrderSorting : 147 },
		'ar'							: { OrderInterface : 148,	OrderSorting : 148 },
		'arc'						: { OrderInterface : 149,	OrderSorting : 149 },
		'archie'					: { OrderInterface : 150,	OrderSorting : 150 },
		'archivist'					: { OrderInterface : 151,	OrderSorting : 151 },
		'arenabg'					: { OrderInterface : 152,	OrderSorting : 152 },
		'arey'						: { OrderInterface : 153,	OrderSorting : 153 },
		'ari'						: { OrderInterface : 154,	OrderSorting : 154 },
		'aries'						: { OrderInterface : 155,	OrderSorting : 155 },
		'arigold'					: { OrderInterface : 156,	OrderSorting : 156 },
		'arin'						: { OrderInterface : 157,	OrderSorting : 157 },
		'arizone'					: { OrderInterface : 158,	OrderSorting : 158 },
		'ark01'						: { OrderInterface : 159,	OrderSorting : 159 },
		'armo'						: { OrderInterface : 160,	OrderSorting : 160 },
		'armor'						: { OrderInterface : 161,	OrderSorting : 161 },
		'aroma'						: { OrderInterface : 162,	OrderSorting : 162 },
		'arrow'						: { OrderInterface : 163,	OrderSorting : 163 },
		'artemis'					: { OrderInterface : 164,	OrderSorting : 164 },
		'arthouse'					: { OrderInterface : 165,	OrderSorting : 165 },
		'artsubs'					: { OrderInterface : 166,	OrderSorting : 166 },
		'as'							: { OrderInterface : 167,	OrderSorting : 167 },
		'asap'						: { OrderInterface : 168,	OrderSorting : 168 },
		'ascendance'					: { OrderInterface : 169,	OrderSorting : 169 },
		'ash61'						: { OrderInterface : 170,	OrderSorting : 170 },
		'asister'					: { OrderInterface : 171,	OrderSorting : 171 },
		'ass'						: { OrderInterface : 172,	OrderSorting : 172 },
		'assassins'					: { OrderInterface : 173,	OrderSorting : 173 },
		'associate'					: { OrderInterface : 174,	OrderSorting : 174 },
		'astral'					: { OrderInterface : 175,	OrderSorting : 175 },
		'astrd'						: { OrderInterface : 176,	OrderSorting : 176 },
		'asw'						: { OrderInterface : 177,	OrderSorting : 177 },
		'at'							: { OrderInterface : 178,	OrderSorting : 178 },
		'atax'						: { OrderInterface : 179,	OrderSorting : 179 },
		'aterfallet'					: { OrderInterface : 180,	OrderSorting : 180 },
		'atg'						: { OrderInterface : 181,	OrderSorting : 181 },
		'atilla82'					: { OrderInterface : 182,	OrderSorting : 182 },
		'atlas47'					: { OrderInterface : 183,	OrderSorting : 183 },
		'ats'						: { OrderInterface : 184,	OrderSorting : 184 },
		'atx'						: { OrderInterface : 185,	OrderSorting : 185 },
		'aurora'					: { OrderInterface : 186,	OrderSorting : 186 },
		'ausy'						: { OrderInterface : 187,	OrderSorting : 187 },
		'authority'					: { OrderInterface : 188,	OrderSorting : 188 },
		'autv'						: { OrderInterface : 189,	OrderSorting : 189 },
		'avcdvd'					: { OrderInterface : 190,	OrderSorting : 190 },
		'avchd'						: { OrderInterface : 191,	OrderSorting : 191 },
		'avenue'					: { OrderInterface : 192,	OrderSorting : 192 },
		'avg'						: { OrderInterface : 193,	OrderSorting : 193 },
		'avs'						: { OrderInterface : 194,	OrderSorting : 194 },
		'avs720'					: { OrderInterface : 195,	OrderSorting : 195 },
		'aw'							: { OrderInterface : 196,	OrderSorting : 196 },
		'awake'						: { OrderInterface : 197,	OrderSorting : 197 },
		'awards'					: { OrderInterface : 198,	OrderSorting : 198 },
		'axe'						: { OrderInterface : 199,	OrderSorting : 199 },
		'axed'						: { OrderInterface : 200,	OrderSorting : 200 },
		'axial'						: { OrderInterface : 201,	OrderSorting : 201 },
		'axine'						: { OrderInterface : 202,	OrderSorting : 202 },
		'axxo'						: { OrderInterface : 203,	OrderSorting : 203 },
		'aymo'						: { OrderInterface : 204,	OrderSorting : 204 },
		'azaze'						: { OrderInterface : 205,	OrderSorting : 205 },
		'b0mbardiers'				: { OrderInterface : 206,	OrderSorting : 206 },
		'b2b'						: { OrderInterface : 207,	OrderSorting : 207 },
		'b4nd1t69'					: { OrderInterface : 208,	OrderSorting : 208 },
		'ba'							: { OrderInterface : 209,	OrderSorting : 209 },
		'babylon'					: { OrderInterface : 210,	OrderSorting : 210 },
		'babytorrent'				: { OrderInterface : 211,	OrderSorting : 211 },
		'backtorg'					: { OrderInterface : 212,	OrderSorting : 212 },
		'badassmedia'				: { OrderInterface : 213,	OrderSorting : 213 },
		'badbajo'					: { OrderInterface : 214,	OrderSorting : 214 },
		'badquality'					: { OrderInterface : 215,	OrderSorting : 215 },
		'badtaste'					: { OrderInterface : 216,	OrderSorting : 216 },
		'bae'						: { OrderInterface : 217,	OrderSorting : 217 },
		'baggerinc'					: { OrderInterface : 218,	OrderSorting : 218 },
		'bags'						: { OrderInterface : 219,	OrderSorting : 219 },
		'baibako'					: { OrderInterface : 220,	OrderSorting : 220 },
		'baibakotv'					: { OrderInterface : 221,	OrderSorting : 221 },
		'bajskorv'					: { OrderInterface : 222,	OrderSorting : 222 },
		'baked'						: { OrderInterface : 223,	OrderSorting : 223 },
		'bald'						: { OrderInterface : 224,	OrderSorting : 224 },
		'ballerina'					: { OrderInterface : 225,	OrderSorting : 225 },
		'bamboozle'					: { OrderInterface : 226,	OrderSorting : 226 },
		'band1d0s'					: { OrderInterface : 227,	OrderSorting : 227 },
		'banker'					: { OrderInterface : 228,	OrderSorting : 228 },
		'barbie'					: { OrderInterface : 229,	OrderSorting : 229 },
		'barc0de'					: { OrderInterface : 230,	OrderSorting : 230 },
		'barge'						: { OrderInterface : 231,	OrderSorting : 231 },
		'baron'						: { OrderInterface : 232,	OrderSorting : 232 },
		'bass'						: { OrderInterface : 233,	OrderSorting : 233 },
		'batman'					: { OrderInterface : 234,	OrderSorting : 234 },
		'batv'						: { OrderInterface : 235,	OrderSorting : 235 },
		'baum'						: { OrderInterface : 236,	OrderSorting : 236 },
		'bawls'						: { OrderInterface : 237,	OrderSorting : 237 },
		'bb'							: { OrderInterface : 238,	OrderSorting : 238 },
		'bbdvdr'					: { OrderInterface : 239,	OrderSorting : 239 },
		'bbtor'						: { OrderInterface : 240,	OrderSorting : 240 },
		'bd4yu'						: { OrderInterface : 241,	OrderSorting : 241 },
		'bda'						: { OrderInterface : 242,	OrderSorting : 242 },
		'bdc'						: { OrderInterface : 243,	OrderSorting : 243 },
		'bdisc'						: { OrderInterface : 244,	OrderSorting : 244 },
		'bdp'						: { OrderInterface : 245,	OrderSorting : 245 },
		'bdys'						: { OrderInterface : 246,	OrderSorting : 246 },
		'bearfish'					: { OrderInterface : 247,	OrderSorting : 247 },
		'beast'						: { OrderInterface : 248,	OrderSorting : 248 },
		'bedlam'					: { OrderInterface : 249,	OrderSorting : 249 },
		'beer'						: { OrderInterface : 250,	OrderSorting : 250 },
		'befree'					: { OrderInterface : 251,	OrderSorting : 251 },
		'beitai'					: { OrderInterface : 252,	OrderSorting : 252 },
		'ben'						: { OrderInterface : 253,	OrderSorting : 253 },
		'bennett'					: { OrderInterface : 254,	OrderSorting : 254 },
		'bestdivx'					: { OrderInterface : 255,	OrderSorting : 255 },
		'besthd'					: { OrderInterface : 256,	OrderSorting : 256 },
		'bet'						: { OrderInterface : 257,	OrderSorting : 257 },
		'betamax'					: { OrderInterface : 258,	OrderSorting : 258 },
		'beyondhd'					: { OrderInterface : 259,	OrderSorting : 259 },
		'bf1'						: { OrderInterface : 260,	OrderSorting : 260 },
		'bff'						: { OrderInterface : 261,	OrderSorting : 261 },
		'bg'							: { OrderInterface : 262,	OrderSorting : 262 },
		'bge'						: { OrderInterface : 263,	OrderSorting : 263 },
		'bgfr'						: { OrderInterface : 264,	OrderSorting : 264 },
		'bhatti'					: { OrderInterface : 265,	OrderSorting : 265 },
		'bhd'						: { OrderInterface : 266,	OrderSorting : 266 },
		'bhdstudio'					: { OrderInterface : 267,	OrderSorting : 267 },
		'bhrg'						: { OrderInterface : 268,	OrderSorting : 268 },
		'bht'						: { OrderInterface : 269,	OrderSorting : 269 },
		'bia'						: { OrderInterface : 270,	OrderSorting : 270 },
		'bida'						: { OrderInterface : 271,	OrderSorting : 271 },
		'bien'						: { OrderInterface : 272,	OrderSorting : 272 },
		'bifos'						: { OrderInterface : 273,	OrderSorting : 273 },
		'big4umovies'				: { OrderInterface : 274,	OrderSorting : 274 },
		'bigdoc'					: { OrderInterface : 275,	OrderSorting : 275 },
		'bigfart'					: { OrderInterface : 276,	OrderSorting : 276 },
		'bigint'					: { OrderInterface : 277,	OrderSorting : 277 },
		'bigjazz'					: { OrderInterface : 278,	OrderSorting : 278 },
		'bigsinema'					: { OrderInterface : 279,	OrderSorting : 279 },
		'bigzt'						: { OrderInterface : 280,	OrderSorting : 280 },
		'bingo'						: { OrderInterface : 281,	OrderSorting : 281 },
		'bipolar'					: { OrderInterface : 282,	OrderSorting : 282 },
		'biq'						: { OrderInterface : 283,	OrderSorting : 283 },
		'birdhouse'					: { OrderInterface : 284,	OrderSorting : 284 },
		'bish'						: { OrderInterface : 285,	OrderSorting : 285 },
		'bithd'						: { OrderInterface : 286,	OrderSorting : 286 },
		'bito'						: { OrderInterface : 287,	OrderSorting : 287 },
		'bizkit'					: { OrderInterface : 288,	OrderSorting : 288 },
		'bjl'						: { OrderInterface : 289,	OrderSorting : 289 },
		'bk'							: { OrderInterface : 290,	OrderSorting : 290 },
		'bla'						: { OrderInterface : 291,	OrderSorting : 291 },
		'black'						: { OrderInterface : 292,	OrderSorting : 292 },
		'blackbit'					: { OrderInterface : 293,	OrderSorting : 293 },
		'blackhat'					: { OrderInterface : 294,	OrderSorting : 294 },
		'bladebdp'					: { OrderInterface : 295,	OrderSorting : 295 },
		'blasphemy'					: { OrderInterface : 296,	OrderSorting : 296 },
		'blaze'						: { OrderInterface : 297,	OrderSorting : 297 },
		'blin'						: { OrderInterface : 298,	OrderSorting : 298 },
		'blitzkrieg'					: { OrderInterface : 299,	OrderSorting : 299 },
		'bloodweiser'				: { OrderInterface : 300,	OrderSorting : 300 },
		'blow'						: { OrderInterface : 301,	OrderSorting : 301 },
		'bludragon'					: { OrderInterface : 302,	OrderSorting : 302 },
		'bluebird'					: { OrderInterface : 303,	OrderSorting : 303 },
		'bluetv'					: { OrderInterface : 304,	OrderSorting : 304 },
		'bluevo'					: { OrderInterface : 305,	OrderSorting : 305 },
		'blueyes'					: { OrderInterface : 306,	OrderSorting : 306 },
		'bluhd'						: { OrderInterface : 307,	OrderSorting : 307 },
		'bluntslayerobfuscated'		: { OrderInterface : 308,	OrderSorting : 308 },
		'blupanther'					: { OrderInterface : 309,	OrderSorting : 309 },
		'bluray3d'					: { OrderInterface : 310,	OrderSorting : 310 },
		'blurg'						: { OrderInterface : 311,	OrderSorting : 311 },
		'blutonium'					: { OrderInterface : 312,	OrderSorting : 312 },
		'bluury'					: { OrderInterface : 313,	OrderSorting : 313 },
		'bluworld'					: { OrderInterface : 314,	OrderSorting : 314 },
		'bluzilla'					: { OrderInterface : 315,	OrderSorting : 315 },
		'bmf'						: { OrderInterface : 316,	OrderSorting : 316 },
		'bob'						: { OrderInterface : 317,	OrderSorting : 317 },
		'bobo'						: { OrderInterface : 318,	OrderSorting : 318 },
		'bokutox'					: { OrderInterface : 319,	OrderSorting : 319 },
		'bonbon'					: { OrderInterface : 320,	OrderSorting : 320 },
		'bone'						: { OrderInterface : 321,	OrderSorting : 321 },
		'bong'						: { OrderInterface : 322,	OrderSorting : 322 },
		'bonkai77'					: { OrderInterface : 323,	OrderSorting : 323 },
		'bonsai'					: { OrderInterface : 324,	OrderSorting : 324 },
		'bonzo'						: { OrderInterface : 325,	OrderSorting : 325 },
		'boo'						: { OrderInterface : 326,	OrderSorting : 326 },
		'boop'						: { OrderInterface : 327,	OrderSorting : 327 },
		'bootstrap'					: { OrderInterface : 328,	OrderSorting : 328 },
		'borderline'					: { OrderInterface : 329,	OrderSorting : 329 },
		'bordure'					: { OrderInterface : 330,	OrderSorting : 330 },
		'boredor'					: { OrderInterface : 331,	OrderSorting : 331 },
		'bountyhunters'				: { OrderInterface : 332,	OrderSorting : 332 },
		'bow'						: { OrderInterface : 333,	OrderSorting : 333 },
		'bozx'						: { OrderInterface : 334,	OrderSorting : 334 },
		'brad'						: { OrderInterface : 335,	OrderSorting : 335 },
		'bradje'					: { OrderInterface : 336,	OrderSorting : 336 },
		'bravery'					: { OrderInterface : 337,	OrderSorting : 337 },
		'brazino777'					: { OrderInterface : 338,	OrderSorting : 338 },
		'break'						: { OrderInterface : 339,	OrderSorting : 339 },
		'breakers'					: { OrderInterface : 340,	OrderSorting : 340 },
		'brg'						: { OrderInterface : 341,	OrderSorting : 341 },
		'bright'					: { OrderInterface : 342,	OrderSorting : 342 },
		'brisk'						: { OrderInterface : 343,	OrderSorting : 343 },
		'brmp'						: { OrderInterface : 344,	OrderSorting : 344 },
		'brn'						: { OrderInterface : 345,	OrderSorting : 345 },
		'brshnkv'					: { OrderInterface : 346,	OrderSorting : 346 },
		'brutus'					: { OrderInterface : 347,	OrderSorting : 347 },
		'bs'							: { OrderInterface : 348,	OrderSorting : 348 },
		'bst'						: { OrderInterface : 349,	OrderSorting : 349 },
		'bt'							: { OrderInterface : 350,	OrderSorting : 350 },
		'bt4k'						: { OrderInterface : 351,	OrderSorting : 351 },
		'btchkek'					: { OrderInterface : 352,	OrderSorting : 352 },
		'btdx8'						: { OrderInterface : 353,	OrderSorting : 353 },
		'btn'						: { OrderInterface : 354,	OrderSorting : 354 },
		'btsfilms'					: { OrderInterface : 355,	OrderSorting : 355 },
		'btshoufa'					: { OrderInterface : 356,	OrderSorting : 356 },
		'btt'						: { OrderInterface : 357,	OrderSorting : 357 },
		'btv'						: { OrderInterface : 358,	OrderSorting : 358 },
		'btvrg'						: { OrderInterface : 359,	OrderSorting : 359 },
		'btw'						: { OrderInterface : 360,	OrderSorting : 360 },
		'btx'						: { OrderInterface : 361,	OrderSorting : 361 },
		'bubanee'					: { OrderInterface : 362,	OrderSorting : 362 },
		'budgetbits'					: { OrderInterface : 363,	OrderSorting : 363 },
		'bugsfunny'					: { OrderInterface : 364,	OrderSorting : 364 },
		'bugz'						: { OrderInterface : 365,	OrderSorting : 365 },
		'bugzbunny'					: { OrderInterface : 366,	OrderSorting : 366 },
		'bulgariahd'					: { OrderInterface : 367,	OrderSorting : 367 },
		'bulldozer'					: { OrderInterface : 368,	OrderSorting : 368 },
		'bullit'					: { OrderInterface : 369,	OrderSorting : 369 },
		'bunny'						: { OrderInterface : 370,	OrderSorting : 370 },
		'burek'						: { OrderInterface : 371,	OrderSorting : 371 },
		'burger'					: { OrderInterface : 372,	OrderSorting : 372 },
		'butter'					: { OrderInterface : 373,	OrderSorting : 373 },
		'buymore'					: { OrderInterface : 374,	OrderSorting : 374 },
		'bwb'						: { OrderInterface : 375,	OrderSorting : 375 },
		'bx'							: { OrderInterface : 376,	OrderSorting : 376 },
		'byme7alh'					: { OrderInterface : 377,	OrderSorting : 377 },
		'byteshare'					: { OrderInterface : 378,	OrderSorting : 378 },
		'bzingaz'					: { OrderInterface : 379,	OrderSorting : 379 },
		'c0ke'						: { OrderInterface : 380,	OrderSorting : 380 },
		'c0nfused'					: { OrderInterface : 381,	OrderSorting : 381 },
		'c1'							: { OrderInterface : 382,	OrderSorting : 382 },
		'c1n3m4'					: { OrderInterface : 383,	OrderSorting : 383 },
		'c1nem4'					: { OrderInterface : 384,	OrderSorting : 384 },
		'c2c'						: { OrderInterface : 385,	OrderSorting : 385 },
		'c4k'						: { OrderInterface : 386,	OrderSorting : 386 },
		'c4tv'						: { OrderInterface : 387,	OrderSorting : 387 },
		'c78'						: { OrderInterface : 388,	OrderSorting : 388 },
		'c7b'						: { OrderInterface : 389,	OrderSorting : 389 },
		'cache'						: { OrderInterface : 390,	OrderSorting : 390 },
		'cadaver'					: { OrderInterface : 391,	OrderSorting : 391 },
		'caf'						: { OrderInterface : 392,	OrderSorting : 392 },
		'cafardax'					: { OrderInterface : 393,	OrderSorting : 393 },
		'caffeine'					: { OrderInterface : 394,	OrderSorting : 394 },
		'cake'						: { OrderInterface : 395,	OrderSorting : 395 },
		'cakes'						: { OrderInterface : 396,	OrderSorting : 396 },
		'caligari'					: { OrderInterface : 397,	OrderSorting : 397 },
		'callmebrado'				: { OrderInterface : 398,	OrderSorting : 398 },
		'camelot'					: { OrderInterface : 399,	OrderSorting : 399 },
		'candial'					: { OrderInterface : 400,	OrderSorting : 400 },
		'capbd'						: { OrderInterface : 401,	OrderSorting : 401 },
		'caph'						: { OrderInterface : 402,	OrderSorting : 402 },
		'capricorn'					: { OrderInterface : 403,	OrderSorting : 403 },
		'carpediem'					: { OrderInterface : 404,	OrderSorting : 404 },
		'cartel'					: { OrderInterface : 405,	OrderSorting : 405 },
		'carved'					: { OrderInterface : 406,	OrderSorting : 406 },
		'casstudio'					: { OrderInterface : 407,	OrderSorting : 407 },
		'catch'						: { OrderInterface : 408,	OrderSorting : 408 },
		'cbfm'						: { OrderInterface : 409,	OrderSorting : 409 },
		'cbgb'						: { OrderInterface : 410,	OrderSorting : 410 },
		'cbm'						: { OrderInterface : 411,	OrderSorting : 411 },
		'cc'							: { OrderInterface : 412,	OrderSorting : 412 },
		'ccat'						: { OrderInterface : 413,	OrderSorting : 413 },
		'cdb'						: { OrderInterface : 414,	OrderSorting : 414 },
		'cdd'						: { OrderInterface : 415,	OrderSorting : 415 },
		'cddhd'						: { OrderInterface : 416,	OrderSorting : 416 },
		'cdp'						: { OrderInterface : 417,	OrderSorting : 417 },
		'centi'						: { OrderInterface : 418,	OrderSorting : 418 },
		'cf'							: { OrderInterface : 419,	OrderSorting : 419 },
		'chakra'					: { OrderInterface : 420,	OrderSorting : 420 },
		'chamele0n'					: { OrderInterface : 421,	OrderSorting : 421 },
		'chattchittorg'				: { OrderInterface : 422,	OrderSorting : 422 },
		'chc'						: { OrderInterface : 423,	OrderSorting : 423 },
		'chd'						: { OrderInterface : 424,	OrderSorting : 424 },
		'chdbits'					: { OrderInterface : 425,	OrderSorting : 425 },
		'checkmate'					: { OrderInterface : 426,	OrderSorting : 426 },
		'chgrp'						: { OrderInterface : 427,	OrderSorting : 427 },
		'chihiro'					: { OrderInterface : 428,	OrderSorting : 428 },
		'chivaman'					: { OrderInterface : 429,	OrderSorting : 429 },
		'chotab'					: { OrderInterface : 430,	OrderSorting : 430 },
		'chronicles'					: { OrderInterface : 431,	OrderSorting : 431 },
		'chrono'					: { OrderInterface : 432,	OrderSorting : 432 },
		'chronos'					: { OrderInterface : 433,	OrderSorting : 433 },
		'cht'						: { OrderInterface : 434,	OrderSorting : 434 },
		'chuppi'					: { OrderInterface : 435,	OrderSorting : 435 },
		'cia'						: { OrderInterface : 436,	OrderSorting : 436 },
		'cielo'						: { OrderInterface : 437,	OrderSorting : 437 },
		'cielos'					: { OrderInterface : 438,	OrderSorting : 438 },
		'cifer'						: { OrderInterface : 439,	OrderSorting : 439 },
		'cihd'						: { OrderInterface : 440,	OrderSorting : 440 },
		'cinecalidad'				: { OrderInterface : 441,	OrderSorting : 441 },
		'cinedome'					: { OrderInterface : 442,	OrderSorting : 442 },
		'cinefeel'					: { OrderInterface : 443,	OrderSorting : 443 },
		'cinefile'					: { OrderInterface : 444,	OrderSorting : 444 },
		'cinefox'					: { OrderInterface : 445,	OrderSorting : 445 },
		'cinemaet'					: { OrderInterface : 446,	OrderSorting : 446 },
		'cinemania'					: { OrderInterface : 447,	OrderSorting : 447 },
		'cinevision'					: { OrderInterface : 448,	OrderSorting : 448 },
		'circle'					: { OrderInterface : 449,	OrderSorting : 449 },
		'cis'						: { OrderInterface : 450,	OrderSorting : 450 },
		'cj'							: { OrderInterface : 451,	OrderSorting : 451 },
		'classico'					: { OrderInterface : 452,	OrderSorting : 452 },
		'cldd'						: { OrderInterface : 453,	OrderSorting : 453 },
		'cleo'						: { OrderInterface : 454,	OrderSorting : 454 },
		'clerks'					: { OrderInterface : 455,	OrderSorting : 455 },
		'clockwork'					: { OrderInterface : 456,	OrderSorting : 456 },
		'clue'						: { OrderInterface : 457,	OrderSorting : 457 },
		'cm'							: { OrderInterface : 458,	OrderSorting : 458 },
		'cm8'						: { OrderInterface : 459,	OrderSorting : 459 },
		'cme'						: { OrderInterface : 460,	OrderSorting : 460 },
		'cmr'						: { OrderInterface : 461,	OrderSorting : 461 },
		'cmrg'						: { OrderInterface : 462,	OrderSorting : 462 },
		'cnhd'						: { OrderInterface : 463,	OrderSorting : 463 },
		'cnscg'						: { OrderInterface : 464,	OrderSorting : 464 },
		'coalgirls'					: { OrderInterface : 465,	OrderSorting : 465 },
		'coalition'					: { OrderInterface : 466,	OrderSorting : 466 },
		'coaster'					: { OrderInterface : 467,	OrderSorting : 467 },
		'cocain'					: { OrderInterface : 468,	OrderSorting : 468 },
		'codres'					: { OrderInterface : 469,	OrderSorting : 469 },
		'cody'						: { OrderInterface : 470,	OrderSorting : 470 },
		'coincidence'				: { OrderInterface : 471,	OrderSorting : 471 },
		'coldfilm'					: { OrderInterface : 472,	OrderSorting : 472 },
		'comandotorrents'			: { OrderInterface : 473,	OrderSorting : 473 },
		'come2daddy'					: { OrderInterface : 474,	OrderSorting : 474 },
		'compulsion'					: { OrderInterface : 475,	OrderSorting : 475 },
		'condition'					: { OrderInterface : 476,	OrderSorting : 476 },
		'condo'						: { OrderInterface : 477,	OrderSorting : 477 },
		'connazakamrpirate'			: { OrderInterface : 478,	OrderSorting : 478 },
		'contribution'				: { OrderInterface : 479,	OrderSorting : 479 },
		'convoy'					: { OrderInterface : 480,	OrderSorting : 480 },
		'coo7'						: { OrderInterface : 481,	OrderSorting : 481 },
		'cookiemonster'				: { OrderInterface : 482,	OrderSorting : 482 },
		'coot'						: { OrderInterface : 483,	OrderSorting : 483 },
		'core'						: { OrderInterface : 484,	OrderSorting : 484 },
		'cottage'					: { OrderInterface : 485,	OrderSorting : 485 },
		'council'					: { OrderInterface : 486,	OrderSorting : 486 },
		'counterfeit'				: { OrderInterface : 487,	OrderSorting : 487 },
		'coveiro'					: { OrderInterface : 488,	OrderSorting : 488 },
		'cowry'						: { OrderInterface : 489,	OrderSorting : 489 },
		'cpd'						: { OrderInterface : 490,	OrderSorting : 490 },
		'cpg'						: { OrderInterface : 491,	OrderSorting : 491 },
		'cpt'						: { OrderInterface : 492,	OrderSorting : 492 },
		'cr'							: { OrderInterface : 493,	OrderSorting : 493 },
		'cravers'					: { OrderInterface : 494,	OrderSorting : 494 },
		'crazy4ad'					: { OrderInterface : 495,	OrderSorting : 495 },
		'creed'						: { OrderInterface : 496,	OrderSorting : 496 },
		'creepshow'					: { OrderInterface : 497,	OrderSorting : 497 },
		'crest'						: { OrderInterface : 498,	OrderSorting : 498 },
		'crewsade'					: { OrderInterface : 499,	OrderSorting : 499 },
		'crf'						: { OrderInterface : 500,	OrderSorting : 500 },
		'crime'						: { OrderInterface : 501,	OrderSorting : 501 },
		'criminal'					: { OrderInterface : 502,	OrderSorting : 502 },
		'crimson'					: { OrderInterface : 503,	OrderSorting : 503 },
		'crisc'						: { OrderInterface : 504,	OrderSorting : 504 },
		'crisgsm33'					: { OrderInterface : 505,	OrderSorting : 505 },
		'crisp'						: { OrderInterface : 506,	OrderSorting : 506 },
		'critical'					: { OrderInterface : 507,	OrderSorting : 507 },
		'cro'						: { OrderInterface : 508,	OrderSorting : 508 },
		'crohd'						: { OrderInterface : 509,	OrderSorting : 509 },
		'crooks'					: { OrderInterface : 510,	OrderSorting : 510 },
		'crossbow'					: { OrderInterface : 511,	OrderSorting : 511 },
		'crossfit'					: { OrderInterface : 512,	OrderSorting : 512 },
		'crown'						: { OrderInterface : 513,	OrderSorting : 513 },
		'crr'						: { OrderInterface : 514,	OrderSorting : 514 },
		'crucial'					: { OrderInterface : 515,	OrderSorting : 515 },
		'crx'						: { OrderInterface : 516,	OrderSorting : 516 },
		'cryptic'					: { OrderInterface : 517,	OrderSorting : 517 },
		'crys'						: { OrderInterface : 518,	OrderSorting : 518 },
		'crystal'					: { OrderInterface : 519,	OrderSorting : 519 },
		'css'						: { OrderInterface : 520,	OrderSorting : 520 },
		'ctc'						: { OrderInterface : 521,	OrderSorting : 521 },
		'ctd'						: { OrderInterface : 522,	OrderSorting : 522 },
		'ctr'						: { OrderInterface : 523,	OrderSorting : 523 },
		'ctrlhd'					: { OrderInterface : 524,	OrderSorting : 524 },
		'ctrlsd'					: { OrderInterface : 525,	OrderSorting : 525 },
		'cttv'						: { OrderInterface : 526,	OrderSorting : 526 },
		'ctu'						: { OrderInterface : 527,	OrderSorting : 527 },
		'cult'						: { OrderInterface : 528,	OrderSorting : 528 },
		'cultfilms'					: { OrderInterface : 529,	OrderSorting : 529 },
		'culthd'					: { OrderInterface : 530,	OrderSorting : 530 },
		'curiosity'					: { OrderInterface : 531,	OrderSorting : 531 },
		'cute'						: { OrderInterface : 532,	OrderSorting : 532 },
		'cyber'						: { OrderInterface : 533,	OrderSorting : 533 },
		'cybermen'					: { OrderInterface : 534,	OrderSorting : 534 },
		'cybertyger'					: { OrderInterface : 535,	OrderSorting : 535 },
		'cyd'						: { OrderInterface : 536,	OrderSorting : 536 },
		'cyphanix'					: { OrderInterface : 537,	OrderSorting : 537 },
		'cytsunee'					: { OrderInterface : 538,	OrderSorting : 538 },
		'cz530'						: { OrderInterface : 539,	OrderSorting : 539 },
		'd0ber'						: { OrderInterface : 540,	OrderSorting : 540 },
		'd0ct0rlew'					: { OrderInterface : 541,	OrderSorting : 541 },
		'd0nk'						: { OrderInterface : 542,	OrderSorting : 542 },
		'd0pe'						: { OrderInterface : 543,	OrderSorting : 543 },
		'd2v'						: { OrderInterface : 544,	OrderSorting : 544 },
		'd3fil3r'					: { OrderInterface : 545,	OrderSorting : 545 },
		'd3g'						: { OrderInterface : 546,	OrderSorting : 546 },
		'd3si'						: { OrderInterface : 547,	OrderSorting : 547 },
		'd4'							: { OrderInterface : 548,	OrderSorting : 548 },
		'd69a74'					: { OrderInterface : 549,	OrderSorting : 549 },
		'daa'						: { OrderInterface : 550,	OrderSorting : 550 },
		'daddy'						: { OrderInterface : 551,	OrderSorting : 551 },
		'dalemake'					: { OrderInterface : 552,	OrderSorting : 552 },
		'danger2u'					: { OrderInterface : 553,	OrderSorting : 553 },
		'danishbits'					: { OrderInterface : 554,	OrderSorting : 554 },
		'danny'						: { OrderInterface : 555,	OrderSorting : 555 },
		'dar'						: { OrderInterface : 556,	OrderSorting : 556 },
		'dark'						: { OrderInterface : 557,	OrderSorting : 557 },
		'darkdream'					: { OrderInterface : 558,	OrderSorting : 558 },
		'darkflix'					: { OrderInterface : 559,	OrderSorting : 559 },
		'darktiger'					: { OrderInterface : 560,	OrderSorting : 560 },
		'dascubadude'				: { OrderInterface : 561,	OrderSorting : 561 },
		'dash'						: { OrderInterface : 562,	OrderSorting : 562 },
		'dav1nci'					: { OrderInterface : 563,	OrderSorting : 563 },
		'dawgs'						: { OrderInterface : 564,	OrderSorting : 564 },
		'dawgsserier'				: { OrderInterface : 565,	OrderSorting : 565 },
		'dawn'						: { OrderInterface : 566,	OrderSorting : 566 },
		'db'							: { OrderInterface : 567,	OrderSorting : 567 },
		'dbo'						: { OrderInterface : 568,	OrderSorting : 568 },
		'dbr'						: { OrderInterface : 569,	OrderSorting : 569 },
		'dbretail'					: { OrderInterface : 570,	OrderSorting : 570 },
		'dca'						: { OrderInterface : 571,	OrderSorting : 571 },
		'dcn'						: { OrderInterface : 572,	OrderSorting : 572 },
		'ddb'						: { OrderInterface : 573,	OrderSorting : 573 },
		'ddc'						: { OrderInterface : 574,	OrderSorting : 574 },
		'dddd'						: { OrderInterface : 575,	OrderSorting : 575 },
		'ddltv'						: { OrderInterface : 576,	OrderSorting : 576 },
		'ddlv'						: { OrderInterface : 577,	OrderSorting : 577 },
		'ddn'						: { OrderInterface : 578,	OrderSorting : 578 },
		'ddncrew'					: { OrderInterface : 579,	OrderSorting : 579 },
		'ddr'						: { OrderInterface : 580,	OrderSorting : 580 },
		'dea'						: { OrderInterface : 581,	OrderSorting : 581 },
		'deadpixel'					: { OrderInterface : 582,	OrderSorting : 582 },
		'deadpool'					: { OrderInterface : 583,	OrderSorting : 583 },
		'deadtorights'				: { OrderInterface : 584,	OrderSorting : 584 },
		'deal'						: { OrderInterface : 585,	OrderSorting : 585 },
		'debtvid'					: { OrderInterface : 586,	OrderSorting : 586 },
		'decade'					: { OrderInterface : 587,	OrderSorting : 587 },
		'decatora27'					: { OrderInterface : 588,	OrderSorting : 588 },
		'decent'					: { OrderInterface : 589,	OrderSorting : 589 },
		'decibel'					: { OrderInterface : 590,	OrderSorting : 590 },
		'decide'					: { OrderInterface : 591,	OrderSorting : 591 },
		'deejayahmed'				: { OrderInterface : 592,	OrderSorting : 592 },
		'defaced'					: { OrderInterface : 593,	OrderSorting : 593 },
		'define'					: { OrderInterface : 594,	OrderSorting : 594 },
		'definite'					: { OrderInterface : 595,	OrderSorting : 595 },
		'definition'					: { OrderInterface : 596,	OrderSorting : 596 },
		'deflate'					: { OrderInterface : 597,	OrderSorting : 597 },
		'defused'					: { OrderInterface : 598,	OrderSorting : 598 },
		'deimos'					: { OrderInterface : 599,	OrderSorting : 599 },
		'deity'						: { OrderInterface : 600,	OrderSorting : 600 },
		'deka'						: { OrderInterface : 601,	OrderSorting : 601 },
		'dekabroken'					: { OrderInterface : 602,	OrderSorting : 602 },
		'delicious'					: { OrderInterface : 603,	OrderSorting : 603 },
		'delight'					: { OrderInterface : 604,	OrderSorting : 604 },
		'dem3nt3'					: { OrderInterface : 605,	OrderSorting : 605 },
		'demand'					: { OrderInterface : 606,	OrderSorting : 606 },
		'depravity'					: { OrderInterface : 607,	OrderSorting : 607 },
		'deprived'					: { OrderInterface : 608,	OrderSorting : 608 },
		'depth'						: { OrderInterface : 609,	OrderSorting : 609 },
		'deranged'					: { OrderInterface : 610,	OrderSorting : 610 },
		'derschuft'					: { OrderInterface : 611,	OrderSorting : 611 },
		'desire'					: { OrderInterface : 612,	OrderSorting : 612 },
		'despite'					: { OrderInterface : 613,	OrderSorting : 613 },
		'deuterium'					: { OrderInterface : 614,	OrderSorting : 614 },
		'deviant'					: { OrderInterface : 615,	OrderSorting : 615 },
		'devil'						: { OrderInterface : 616,	OrderSorting : 616 },
		'devise'					: { OrderInterface : 617,	OrderSorting : 617 },
		'devived'					: { OrderInterface : 618,	OrderSorting : 618 },
		'dexterous'					: { OrderInterface : 619,	OrderSorting : 619 },
		'df'							: { OrderInterface : 620,	OrderSorting : 620 },
		'dflarrowfilms'				: { OrderInterface : 621,	OrderSorting : 621 },
		'dh'							: { OrderInterface : 622,	OrderSorting : 622 },
		'dharma'					: { OrderInterface : 623,	OrderSorting : 623 },
		'dhd'						: { OrderInterface : 624,	OrderSorting : 624 },
		'diablo'					: { OrderInterface : 625,	OrderSorting : 625 },
		'diamond'					: { OrderInterface : 626,	OrderSorting : 626 },
		'diamonds'					: { OrderInterface : 627,	OrderSorting : 627 },
		'dic'						: { OrderInterface : 628,	OrderSorting : 628 },
		'dich'						: { OrderInterface : 629,	OrderSorting : 629 },
		'didee'						: { OrderInterface : 630,	OrderSorting : 630 },
		'didomh'					: { OrderInterface : 631,	OrderSorting : 631 },
		'diesel'					: { OrderInterface : 632,	OrderSorting : 632 },
		'different'					: { OrderInterface : 633,	OrderSorting : 633 },
		'digg'						: { OrderInterface : 634,	OrderSorting : 634 },
		'dimension'					: { OrderInterface : 635,	OrderSorting : 635 },
		'din'						: { OrderInterface : 636,	OrderSorting : 636 },
		'dina'						: { OrderInterface : 637,	OrderSorting : 637 },
		'dir'						: { OrderInterface : 638,	OrderSorting : 638 },
		'dirg'						: { OrderInterface : 639,	OrderSorting : 639 },
		'dirt'						: { OrderInterface : 640,	OrderSorting : 640 },
		'dirty'						: { OrderInterface : 641,	OrderSorting : 641 },
		'dirtyburger'				: { OrderInterface : 642,	OrderSorting : 642 },
		'disposable'					: { OrderInterface : 643,	OrderSorting : 643 },
		'disruption'					: { OrderInterface : 644,	OrderSorting : 644 },
		'district'					: { OrderInterface : 645,	OrderSorting : 645 },
		'divas'						: { OrderInterface : 646,	OrderSorting : 646 },
		'diverge'					: { OrderInterface : 647,	OrderSorting : 647 },
		'diversity'					: { OrderInterface : 648,	OrderSorting : 648 },
		'division'					: { OrderInterface : 649,	OrderSorting : 649 },
		'divulged'					: { OrderInterface : 650,	OrderSorting : 650 },
		'divxnl'					: { OrderInterface : 651,	OrderSorting : 651 },
		'divxnlteam'					: { OrderInterface : 652,	OrderSorting : 652 },
		'dizhuwang'					: { OrderInterface : 653,	OrderSorting : 653 },
		'djd'						: { OrderInterface : 654,	OrderSorting : 654 },
		'dkb'						: { OrderInterface : 655,	OrderSorting : 655 },
		'dkids'						: { OrderInterface : 656,	OrderSorting : 656 },
		'dlc'						: { OrderInterface : 657,	OrderSorting : 657 },
		'dmt'						: { OrderInterface : 658,	OrderSorting : 658 },
		'dna'						: { OrderInterface : 659,	OrderSorting : 659 },
		'dnb'						: { OrderInterface : 660,	OrderSorting : 660 },
		'dnl'						: { OrderInterface : 661,	OrderSorting : 661 },
		'dnr'						: { OrderInterface : 662,	OrderSorting : 662 },
		'dns'						: { OrderInterface : 663,	OrderSorting : 663 },
		'doa'						: { OrderInterface : 664,	OrderSorting : 664 },
		'doc'						: { OrderInterface : 665,	OrderSorting : 665 },
		'document'					: { OrderInterface : 666,	OrderSorting : 666 },
		'doesntsuck'					: { OrderInterface : 667,	OrderSorting : 667 },
		'doge'						: { OrderInterface : 668,	OrderSorting : 668 },
		'doktor'					: { OrderInterface : 669,	OrderSorting : 669 },
		'dokumania'					: { OrderInterface : 670,	OrderSorting : 670 },
		'dollhead'					: { OrderInterface : 671,	OrderSorting : 671 },
		'dominion'					: { OrderInterface : 672,	OrderSorting : 672 },
		'domino'					: { OrderInterface : 673,	OrderSorting : 673 },
		'don'						: { OrderInterface : 674,	OrderSorting : 674 },
		'done'						: { OrderInterface : 675,	OrderSorting : 675 },
		'donjuan'					: { OrderInterface : 676,	OrderSorting : 676 },
		'donna'						: { OrderInterface : 677,	OrderSorting : 677 },
		'donuts'					: { OrderInterface : 678,	OrderSorting : 678 },
		'doomguy'					: { OrderInterface : 679,	OrderSorting : 679 },
		'dopehd'					: { OrderInterface : 680,	OrderSorting : 680 },
		'dot'						: { OrderInterface : 681,	OrderSorting : 681 },
		'doubt'						: { OrderInterface : 682,	OrderSorting : 682 },
		'down'						: { OrderInterface : 683,	OrderSorting : 683 },
		'downloadhub'				: { OrderInterface : 684,	OrderSorting : 684 },
		'downrev'					: { OrderInterface : 685,	OrderSorting : 685 },
		'dp'							: { OrderInterface : 686,	OrderSorting : 686 },
		'dr'							: { OrderInterface : 687,	OrderSorting : 687 },
		'dr3adlox'					: { OrderInterface : 688,	OrderSorting : 688 },
		'dracula'					: { OrderInterface : 689,	OrderSorting : 689 },
		'dragsterps'					: { OrderInterface : 690,	OrderSorting : 690 },
		'drake'						: { OrderInterface : 691,	OrderSorting : 691 },
		'dream'						: { OrderInterface : 692,	OrderSorting : 692 },
		'dreamcatcher'				: { OrderInterface : 693,	OrderSorting : 693 },
		'dreamseed'					: { OrderInterface : 694,	OrderSorting : 694 },
		'drg'						: { OrderInterface : 695,	OrderSorting : 695 },
		'drm'						: { OrderInterface : 696,	OrderSorting : 696 },
		'droids'					: { OrderInterface : 697,	OrderSorting : 697 },
		'drones'					: { OrderInterface : 698,	OrderSorting : 698 },
		'drsd'						: { OrderInterface : 699,	OrderSorting : 699 },
		'drsi'						: { OrderInterface : 700,	OrderSorting : 700 },
		'drstar'					: { OrderInterface : 701,	OrderSorting : 701 },
		'ds'							: { OrderInterface : 702,	OrderSorting : 702 },
		'dss'						: { OrderInterface : 703,	OrderSorting : 703 },
		'dsubs'						: { OrderInterface : 704,	OrderSorting : 704 },
		'dtech'						: { OrderInterface : 705,	OrderSorting : 705 },
		'dthd'						: { OrderInterface : 706,	OrderSorting : 706 },
		'dtone'						: { OrderInterface : 707,	OrderSorting : 707 },
		'dubby'						: { OrderInterface : 708,	OrderSorting : 708 },
		'duck'						: { OrderInterface : 709,	OrderSorting : 709 },
		'dude'						: { OrderInterface : 710,	OrderSorting : 710 },
		'dukes'						: { OrderInterface : 711,	OrderSorting : 711 },
		'dupli'						: { OrderInterface : 712,	OrderSorting : 712 },
		'duqa'						: { OrderInterface : 713,	OrderSorting : 713 },
		'dustin'					: { OrderInterface : 714,	OrderSorting : 714 },
		'dutchreleaseteam'			: { OrderInterface : 715,	OrderSorting : 715 },
		'dvdmania'					: { OrderInterface : 716,	OrderSorting : 716 },
		'dvf'						: { OrderInterface : 717,	OrderSorting : 717 },
		'dvl'						: { OrderInterface : 718,	OrderSorting : 718 },
		'dvsky'						: { OrderInterface : 719,	OrderSorting : 719 },
		'dvsux'						: { OrderInterface : 720,	OrderSorting : 720 },
		'dvt'						: { OrderInterface : 721,	OrderSorting : 721 },
		'dx'							: { OrderInterface : 722,	OrderSorting : 722 },
		'dxo'						: { OrderInterface : 723,	OrderSorting : 723 },
		'dygc'						: { OrderInterface : 724,	OrderSorting : 724 },
		'dynamics'					: { OrderInterface : 725,	OrderSorting : 725 },
		'dz0n3'						: { OrderInterface : 726,	OrderSorting : 726 },
		'e1'							: { OrderInterface : 727,	OrderSorting : 727 },
		'e7'							: { OrderInterface : 728,	OrderSorting : 728 },
		'e76'						: { OrderInterface : 729,	OrderSorting : 729 },
		'ea'							: { OrderInterface : 730,	OrderSorting : 730 },
		'eagle'						: { OrderInterface : 731,	OrderSorting : 731 },
		'eatdik'					: { OrderInterface : 732,	OrderSorting : 732 },
		'ebi'						: { OrderInterface : 733,	OrderSorting : 733 },
		'ebp'						: { OrderInterface : 734,	OrderSorting : 734 },
		'eci'						: { OrderInterface : 735,	OrderSorting : 735 },
		'eclipse'					: { OrderInterface : 736,	OrderSorting : 736 },
		'ede'						: { OrderInterface : 737,	OrderSorting : 737 },
		'edge'						: { OrderInterface : 738,	OrderSorting : 738 },
		'edge2020'					: { OrderInterface : 739,	OrderSorting : 739 },
		'edhd'						: { OrderInterface : 740,	OrderSorting : 740 },
		'edi'						: { OrderInterface : 741,	OrderSorting : 741 },
		'edo'						: { OrderInterface : 742,	OrderSorting : 742 },
		'edph'						: { OrderInterface : 743,	OrderSorting : 743 },
		'edvok'						: { OrderInterface : 744,	OrderSorting : 744 },
		'eff'						: { OrderInterface : 745,	OrderSorting : 745 },
		'efterlyst'					: { OrderInterface : 746,	OrderSorting : 746 },
		'egen'						: { OrderInterface : 747,	OrderSorting : 747 },
		'ehmd'						: { OrderInterface : 748,	OrderSorting : 748 },
		'eider'						: { OrderInterface : 749,	OrderSorting : 749 },
		'eie'						: { OrderInterface : 750,	OrderSorting : 750 },
		'eimi'						: { OrderInterface : 751,	OrderSorting : 751 },
		'eisbock'					: { OrderInterface : 752,	OrderSorting : 752 },
		'ekolb'						: { OrderInterface : 753,	OrderSorting : 753 },
		'electric'					: { OrderInterface : 754,	OrderSorting : 754 },
		'elektri4ka'					: { OrderInterface : 755,	OrderSorting : 755 },
		'elia'						: { OrderInterface : 756,	OrderSorting : 756 },
		'elite'						: { OrderInterface : 757,	OrderSorting : 757 },
		'elitetorrent'				: { OrderInterface : 758,	OrderSorting : 758 },
		'elysium'					: { OrderInterface : 759,	OrderSorting : 759 },
		'em0c0re'					: { OrderInterface : 760,	OrderSorting : 760 },
		'ember'						: { OrderInterface : 761,	OrderSorting : 761 },
		'emem'						: { OrderInterface : 762,	OrderSorting : 762 },
		'emerald'					: { OrderInterface : 763,	OrderSorting : 763 },
		'emg'						: { OrderInterface : 764,	OrderSorting : 764 },
		'empathy'					: { OrderInterface : 765,	OrderSorting : 765 },
		'empire'					: { OrderInterface : 766,	OrderSorting : 766 },
		'ena'						: { OrderInterface : 767,	OrderSorting : 767 },
		'encounters'					: { OrderInterface : 768,	OrderSorting : 768 },
		'end'						: { OrderInterface : 769,	OrderSorting : 769 },
		'endor'						: { OrderInterface : 770,	OrderSorting : 770 },
		'eniahd'					: { OrderInterface : 771,	OrderSorting : 771 },
		'enigma'					: { OrderInterface : 772,	OrderSorting : 772 },
		'ent'						: { OrderInterface : 773,	OrderSorting : 773 },
		'enticement'					: { OrderInterface : 774,	OrderSorting : 774 },
		'ep1c'						: { OrderInterface : 775,	OrderSorting : 775 },
		'ephemerid'					: { OrderInterface : 776,	OrderSorting : 776 },
		'epic'						: { OrderInterface : 777,	OrderSorting : 777 },
		'epik'						: { OrderInterface : 778,	OrderSorting : 778 },
		'eps'						: { OrderInterface : 779,	OrderSorting : 779 },
		'epsilon'					: { OrderInterface : 780,	OrderSorting : 780 },
		'epz'						: { OrderInterface : 781,	OrderSorting : 781 },
		'erairaws'					: { OrderInterface : 782,	OrderSorting : 782 },
		'erev'						: { OrderInterface : 783,	OrderSorting : 783 },
		'esc'						: { OrderInterface : 784,	OrderSorting : 784 },
		'esi'						: { OrderInterface : 785,	OrderSorting : 785 },
		'esir'						: { OrderInterface : 786,	OrderSorting : 786 },
		'espise'					: { OrderInterface : 787,	OrderSorting : 787 },
		'esq'						: { OrderInterface : 788,	OrderSorting : 788 },
		'essential'					: { OrderInterface : 789,	OrderSorting : 789 },
		'eszc'						: { OrderInterface : 790,	OrderSorting : 790 },
		'etach'						: { OrderInterface : 791,	OrderSorting : 791 },
		'ethd'						: { OrderInterface : 792,	OrderSorting : 792 },
		'ethics'					: { OrderInterface : 793,	OrderSorting : 793 },
		'ethos'						: { OrderInterface : 794,	OrderSorting : 794 },
		'etm'						: { OrderInterface : 795,	OrderSorting : 795 },
		'etmid'						: { OrderInterface : 796,	OrderSorting : 796 },
		'etmovies'					: { OrderInterface : 797,	OrderSorting : 797 },
		'etrg'						: { OrderInterface : 798,	OrderSorting : 798 },
		'ettv'						: { OrderInterface : 799,	OrderSorting : 799 },
		'euchd'						: { OrderInterface : 800,	OrderSorting : 800 },
		'euhd'						: { OrderInterface : 801,	OrderSorting : 801 },
		'eureka'					: { OrderInterface : 802,	OrderSorting : 802 },
		'eve'						: { OrderInterface : 803,	OrderSorting : 803 },
		'evo'						: { OrderInterface : 804,	OrderSorting : 804 },
		'evolve'					: { OrderInterface : 805,	OrderSorting : 805 },
		'ewdp'						: { OrderInterface : 806,	OrderSorting : 806 },
		'excalibur'					: { OrderInterface : 807,	OrderSorting : 807 },
		'excellence'					: { OrderInterface : 808,	OrderSorting : 808 },
		'excited'					: { OrderInterface : 809,	OrderSorting : 809 },
		'exclusive'					: { OrderInterface : 810,	OrderSorting : 810 },
		'excommunicado'				: { OrderInterface : 811,	OrderSorting : 811 },
		'exd'						: { OrderInterface : 812,	OrderSorting : 812 },
		'exdr'						: { OrderInterface : 813,	OrderSorting : 813 },
		'exile'						: { OrderInterface : 814,	OrderSorting : 814 },
		'exkinoray'					: { OrderInterface : 815,	OrderSorting : 815 },
		'exploit'					: { OrderInterface : 816,	OrderSorting : 816 },
		'exps'						: { OrderInterface : 817,	OrderSorting : 817 },
		'exquisite'					: { OrderInterface : 818,	OrderSorting : 818 },
		'extacy'					: { OrderInterface : 819,	OrderSorting : 819 },
		'extramovies'				: { OrderInterface : 820,	OrderSorting : 820 },
		'extratorrentrg'			: { OrderInterface : 821,	OrderSorting : 821 },
		'extreme'					: { OrderInterface : 822,	OrderSorting : 822 },
		'exvid'						: { OrderInterface : 823,	OrderSorting : 823 },
		'exvidint'					: { OrderInterface : 824,	OrderSorting : 824 },
		'exy'						: { OrderInterface : 825,	OrderSorting : 825 },
		'exyu'						: { OrderInterface : 826,	OrderSorting : 826 },
		'exyusubs'					: { OrderInterface : 827,	OrderSorting : 827 },
		'eztv'						: { OrderInterface : 828,	OrderSorting : 828 },
		'f1'							: { OrderInterface : 829,	OrderSorting : 829 },
		'f1rebladerunner'			: { OrderInterface : 830,	OrderSorting : 830 },
		'f7'							: { OrderInterface : 831,	OrderSorting : 831 },
		'fabulous'					: { OrderInterface : 832,	OrderSorting : 832 },
		'fabutrash'					: { OrderInterface : 833,	OrderSorting : 833 },
		'failed'					: { OrderInterface : 834,	OrderSorting : 834 },
		'fandango'					: { OrderInterface : 835,	OrderSorting : 835 },
		'fant'						: { OrderInterface : 836,	OrderSorting : 836 },
		'fanta'						: { OrderInterface : 837,	OrderSorting : 837 },
		'fantascienza'				: { OrderInterface : 838,	OrderSorting : 838 },
		'fap'						: { OrderInterface : 839,	OrderSorting : 839 },
		'fapcave'					: { OrderInterface : 840,	OrderSorting : 840 },
		'fargirenis'					: { OrderInterface : 841,	OrderSorting : 841 },
		'fasm'						: { OrderInterface : 842,	OrderSorting : 842 },
		'fasthd'					: { OrderInterface : 843,	OrderSorting : 843 },
		'fatman'					: { OrderInterface : 844,	OrderSorting : 844 },
		'fbi'						: { OrderInterface : 845,	OrderSorting : 845 },
		'fcc'						: { OrderInterface : 846,	OrderSorting : 846 },
		'fck'						: { OrderInterface : 847,	OrderSorting : 847 },
		'feature'					: { OrderInterface : 848,	OrderSorting : 848 },
		'feelfree'					: { OrderInterface : 849,	OrderSorting : 849 },
		'felony'					: { OrderInterface : 850,	OrderSorting : 850 },
		'fendt'						: { OrderInterface : 851,	OrderSorting : 851 },
		'feral'						: { OrderInterface : 852,	OrderSorting : 852 },
		'fetish'					: { OrderInterface : 853,	OrderSorting : 853 },
		'fever'						: { OrderInterface : 854,	OrderSorting : 854 },
		'ff'							: { OrderInterface : 855,	OrderSorting : 855 },
		'ffa'						: { OrderInterface : 856,	OrderSorting : 856 },
		'ffansweb'					: { OrderInterface : 857,	OrderSorting : 857 },
		'fff'						: { OrderInterface : 858,	OrderSorting : 858 },
		'ffndvd'					: { OrderInterface : 859,	OrderSorting : 859 },
		'ffs'						: { OrderInterface : 860,	OrderSorting : 860 },
		'fgt'						: { OrderInterface : 861,	OrderSorting : 861 },
		'fiasco'					: { OrderInterface : 862,	OrderSorting : 862 },
		'fico'						: { OrderInterface : 863,	OrderSorting : 863 },
		'ficodvdr'					: { OrderInterface : 864,	OrderSorting : 864 },
		'fidelio'					: { OrderInterface : 865,	OrderSorting : 865 },
		'fido'						: { OrderInterface : 866,	OrderSorting : 866 },
		'fightbb'					: { OrderInterface : 867,	OrderSorting : 867 },
		'fihtv'						: { OrderInterface : 868,	OrderSorting : 868 },
		'fij'						: { OrderInterface : 869,	OrderSorting : 869 },
		'filmanta'					: { OrderInterface : 870,	OrderSorting : 870 },
		'filmhd'					: { OrderInterface : 871,	OrderSorting : 871 },
		'filmikz'					: { OrderInterface : 872,	OrderSorting : 872 },
		'filmiwar'					: { OrderInterface : 873,	OrderSorting : 873 },
		'filmsclub'					: { OrderInterface : 874,	OrderSorting : 874 },
		'filmytorrents'				: { OrderInterface : 875,	OrderSorting : 875 },
		'finale'					: { OrderInterface : 876,	OrderSorting : 876 },
		'finally'					: { OrderInterface : 877,	OrderSorting : 877 },
		'fixi0n'					: { OrderInterface : 878,	OrderSorting : 878 },
		'fizo'						: { OrderInterface : 879,	OrderSorting : 879 },
		'fk99'						: { OrderInterface : 880,	OrderSorting : 880 },
		'fkkhd'						: { OrderInterface : 881,	OrderSorting : 881 },
		'fkktv'						: { OrderInterface : 882,	OrderSorting : 882 },
		'flair'						: { OrderInterface : 883,	OrderSorting : 883 },
		'flaite'					: { OrderInterface : 884,	OrderSorting : 884 },
		'flame'						: { OrderInterface : 885,	OrderSorting : 885 },
		'flash'						: { OrderInterface : 886,	OrderSorting : 886 },
		'flatline'					: { OrderInterface : 887,	OrderSorting : 887 },
		'flawl3ss'					: { OrderInterface : 888,	OrderSorting : 888 },
		'fleet'						: { OrderInterface : 889,	OrderSorting : 889 },
		'flex'						: { OrderInterface : 890,	OrderSorting : 890 },
		'flicksick'					: { OrderInterface : 891,	OrderSorting : 891 },
		'flights'					: { OrderInterface : 892,	OrderSorting : 892 },
		'flintfilms'					: { OrderInterface : 893,	OrderSorting : 893 },
		'fllortv'					: { OrderInterface : 894,	OrderSorting : 894 },
		'flop'						: { OrderInterface : 895,	OrderSorting : 895 },
		'fls'						: { OrderInterface : 896,	OrderSorting : 896 },
		'flt'						: { OrderInterface : 897,	OrderSorting : 897 },
		'flux'						: { OrderInterface : 898,	OrderSorting : 898 },
		'flx'						: { OrderInterface : 899,	OrderSorting : 899 },
		'fly635'					: { OrderInterface : 900,	OrderSorting : 900 },
		'fmdab'						: { OrderInterface : 901,	OrderSorting : 901 },
		'fme'						: { OrderInterface : 902,	OrderSorting : 902 },
		'focus'						: { OrderInterface : 903,	OrderSorting : 903 },
		'fookas'					: { OrderInterface : 904,	OrderSorting : 904 },
		'football'					: { OrderInterface : 905,	OrderSorting : 905 },
		'force'						: { OrderInterface : 906,	OrderSorting : 906 },
		'forcebleue'					: { OrderInterface : 907,	OrderSorting : 907 },
		'form'						: { OrderInterface : 908,	OrderSorting : 908 },
		'formula'					: { OrderInterface : 909,	OrderSorting : 909 },
		'forsaken'					: { OrderInterface : 910,	OrderSorting : 910 },
		'forward'					: { OrderInterface : 911,	OrderSorting : 911 },
		'fov'						: { OrderInterface : 912,	OrderSorting : 912 },
		'foxm'						: { OrderInterface : 913,	OrderSorting : 913 },
		'foxpro'					: { OrderInterface : 914,	OrderSorting : 914 },
		'foxtrot'					: { OrderInterface : 915,	OrderSorting : 915 },
		'foxy'						: { OrderInterface : 916,	OrderSorting : 916 },
		'fqm'						: { OrderInterface : 917,	OrderSorting : 917 },
		'fractal'					: { OrderInterface : 918,	OrderSorting : 918 },
		'fragment'					: { OrderInterface : 919,	OrderSorting : 919 },
		'frame'						: { OrderInterface : 920,	OrderSorting : 920 },
		'framestor'					: { OrderInterface : 921,	OrderSorting : 921 },
		'frangoassado'				: { OrderInterface : 922,	OrderSorting : 922 },
		'fraternity'					: { OrderInterface : 923,	OrderSorting : 923 },
		'fratposa'					: { OrderInterface : 924,	OrderSorting : 924 },
		'freak'						: { OrderInterface : 925,	OrderSorting : 925 },
		'freaks'					: { OrderInterface : 926,	OrderSorting : 926 },
		'freebee'					: { OrderInterface : 927,	OrderSorting : 927 },
		'freedom'					: { OrderInterface : 928,	OrderSorting : 928 },
		'freethefish'				: { OrderInterface : 929,	OrderSorting : 929 },
		'friday21st'					: { OrderInterface : 930,	OrderSorting : 930 },
		'friends'					: { OrderInterface : 931,	OrderSorting : 931 },
		'fries'						: { OrderInterface : 932,	OrderSorting : 932 },
		'frisky'					: { OrderInterface : 933,	OrderSorting : 933 },
		'frog'						: { OrderInterface : 934,	OrderSorting : 934 },
		'fronky'					: { OrderInterface : 935,	OrderSorting : 935 },
		'frost'						: { OrderInterface : 936,	OrderSorting : 936 },
		'frozen'					: { OrderInterface : 937,	OrderSorting : 937 },
		'fsihd'						: { OrderInterface : 938,	OrderSorting : 938 },
		'ftmvhd'					: { OrderInterface : 939,	OrderSorting : 939 },
		'fto'						: { OrderInterface : 940,	OrderSorting : 940 },
		'ftp'						: { OrderInterface : 941,	OrderSorting : 941 },
		'fts'						: { OrderInterface : 942,	OrderSorting : 942 },
		'ftwhd'						: { OrderInterface : 943,	OrderSorting : 943 },
		'fty'						: { OrderInterface : 944,	OrderSorting : 944 },
		'fuc0v1d'					: { OrderInterface : 945,	OrderSorting : 945 },
		'fuckads'					: { OrderInterface : 946,	OrderSorting : 946 },
		'full4'						: { OrderInterface : 947,	OrderSorting : 947 },
		'full4movies'				: { OrderInterface : 948,	OrderSorting : 948 },
		'fullsize'					: { OrderInterface : 949,	OrderSorting : 949 },
		'fum'						: { OrderInterface : 950,	OrderSorting : 950 },
		'fun'						: { OrderInterface : 951,	OrderSorting : 951 },
		'funkky'					: { OrderInterface : 952,	OrderSorting : 952 },
		'funner'					: { OrderInterface : 953,	OrderSorting : 953 },
		'fusion'					: { OrderInterface : 954,	OrderSorting : 954 },
		'futv'						: { OrderInterface : 955,	OrderSorting : 955 },
		'fuzerhd'					: { OrderInterface : 956,	OrderSorting : 956 },
		'fxg'						: { OrderInterface : 957,	OrderSorting : 957 },
		'fxm'						: { OrderInterface : 958,	OrderSorting : 958 },
		'fzero'						: { OrderInterface : 959,	OrderSorting : 959 },
		'fzhd'						: { OrderInterface : 960,	OrderSorting : 960 },
		'fzteam'					: { OrderInterface : 961,	OrderSorting : 961 },
		'g3lhd'						: { OrderInterface : 962,	OrderSorting : 962 },
		'g4ris'						: { OrderInterface : 963,	OrderSorting : 963 },
		'ga'							: { OrderInterface : 964,	OrderSorting : 964 },
		'ga645zi'					: { OrderInterface : 965,	OrderSorting : 965 },
		'gabe'						: { OrderInterface : 966,	OrderSorting : 966 },
		'gage'						: { OrderInterface : 967,	OrderSorting : 967 },
		'galactica'					: { OrderInterface : 968,	OrderSorting : 968 },
		'galaxyrg'					: { OrderInterface : 969,	OrderSorting : 969 },
		'galaxytv'					: { OrderInterface : 970,	OrderSorting : 970 },
		'ganool'					: { OrderInterface : 971,	OrderSorting : 971 },
		'garshasp'					: { OrderInterface : 972,	OrderSorting : 972 },
		'gas'						: { OrderInterface : 973,	OrderSorting : 973 },
		'gasmask'					: { OrderInterface : 974,	OrderSorting : 974 },
		'gattopollo'					: { OrderInterface : 975,	OrderSorting : 975 },
		'gaygay'					: { OrderInterface : 976,	OrderSorting : 976 },
		'gaz'						: { OrderInterface : 977,	OrderSorting : 977 },
		'gbb'						: { OrderInterface : 978,	OrderSorting : 978 },
		'gbm'						: { OrderInterface : 979,	OrderSorting : 979 },
		'gdr'						: { OrderInterface : 980,	OrderSorting : 980 },
		'gearsmedia'					: { OrderInterface : 981,	OrderSorting : 981 },
		'geckos'					: { OrderInterface : 982,	OrderSorting : 982 },
		'geek'						: { OrderInterface : 983,	OrderSorting : 983 },
		'geekrg'					: { OrderInterface : 984,	OrderSorting : 984 },
		'gellard'					: { OrderInterface : 985,	OrderSorting : 985 },
		'gelob'						: { OrderInterface : 986,	OrderSorting : 986 },
		'genemige'					: { OrderInterface : 987,	OrderSorting : 987 },
		'geneside'					: { OrderInterface : 988,	OrderSorting : 988 },
		'genesis'					: { OrderInterface : 989,	OrderSorting : 989 },
		'genuine'					: { OrderInterface : 990,	OrderSorting : 990 },
		'geo'						: { OrderInterface : 991,	OrderSorting : 991 },
		'gerald99'					: { OrderInterface : 992,	OrderSorting : 992 },
		'gerudo'					: { OrderInterface : 993,	OrderSorting : 993 },
		'getb8'						: { OrderInterface : 994,	OrderSorting : 994 },
		'getb9'						: { OrderInterface : 995,	OrderSorting : 995 },
		'getit'						: { OrderInterface : 996,	OrderSorting : 996 },
		'getschwifty'				: { OrderInterface : 997,	OrderSorting : 997 },
		'gfw'						: { OrderInterface : 998,	OrderSorting : 998 },
		'gfy'						: { OrderInterface : 999,	OrderSorting : 999 },
		'gg'							: { OrderInterface : 1000,	OrderSorting : 1000 },
		'ggez'						: { OrderInterface : 1001,	OrderSorting : 1001 },
		'ggwp'						: { OrderInterface : 1002,	OrderSorting : 1002 },
		'ghost'						: { OrderInterface : 1003,	OrderSorting : 1003 },
		'ghosts'					: { OrderInterface : 1004,	OrderSorting : 1004 },
		'ghouls'					: { OrderInterface : 1005,	OrderSorting : 1005 },
		'ghs'						: { OrderInterface : 1006,	OrderSorting : 1006 },
		'gi'							: { OrderInterface : 1007,	OrderSorting : 1007 },
		'gillop'					: { OrderInterface : 1008,	OrderSorting : 1008 },
		'gimchi'					: { OrderInterface : 1009,	OrderSorting : 1009 },
		'ginji'						: { OrderInterface : 1010,	OrderSorting : 1010 },
		'girays'					: { OrderInterface : 1011,	OrderSorting : 1011 },
		'giu'						: { OrderInterface : 1012,	OrderSorting : 1012 },
		'gl'							: { OrderInterface : 1013,	OrderSorting : 1013 },
		'glados'					: { OrderInterface : 1014,	OrderSorting : 1014 },
		'glasses'					: { OrderInterface : 1015,	OrderSorting : 1015 },
		'glenn'						: { OrderInterface : 1016,	OrderSorting : 1016 },
		'glhf'						: { OrderInterface : 1017,	OrderSorting : 1017 },
		'glm8892'					: { OrderInterface : 1018,	OrderSorting : 1018 },
		'globe'						: { OrderInterface : 1019,	OrderSorting : 1019 },
		'glowgaze'					: { OrderInterface : 1020,	OrderSorting : 1020 },
		'glue'						: { OrderInterface : 1021,	OrderSorting : 1021 },
		'gly'						: { OrderInterface : 1022,	OrderSorting : 1022 },
		'gm'							: { OrderInterface : 1023,	OrderSorting : 1023 },
		'gma'						: { OrderInterface : 1024,	OrderSorting : 1024 },
		'gnarly'					: { OrderInterface : 1025,	OrderSorting : 1025 },
		'gnome'						: { OrderInterface : 1026,	OrderSorting : 1026 },
		'goape'						: { OrderInterface : 1027,	OrderSorting : 1027 },
		'goatlove'					: { OrderInterface : 1028,	OrderSorting : 1028 },
		'goblin10'					: { OrderInterface : 1029,	OrderSorting : 1029 },
		'god'						: { OrderInterface : 1030,	OrderSorting : 1030 },
		'goenwae'					: { OrderInterface : 1031,	OrderSorting : 1031 },
		'gogeta'					: { OrderInterface : 1032,	OrderSorting : 1032 },
		'goki'						: { OrderInterface : 1033,	OrderSorting : 1033 },
		'goku61'					: { OrderInterface : 1034,	OrderSorting : 1034 },
		'golumpa'					: { OrderInterface : 1035,	OrderSorting : 1035 },
		'gon'						: { OrderInterface : 1036,	OrderSorting : 1036 },
		'goodfilms'					: { OrderInterface : 1037,	OrderSorting : 1037 },
		'goodpeople'					: { OrderInterface : 1038,	OrderSorting : 1038 },
		'goon'						: { OrderInterface : 1039,	OrderSorting : 1039 },
		'gooner'					: { OrderInterface : 1040,	OrderSorting : 1040 },
		'gooz'						: { OrderInterface : 1041,	OrderSorting : 1041 },
		'gop'						: { OrderInterface : 1042,	OrderSorting : 1042 },
		'gopanda'					: { OrderInterface : 1043,	OrderSorting : 1043 },
		'gopisahi'					: { OrderInterface : 1044,	OrderSorting : 1044 },
		'gopo'						: { OrderInterface : 1045,	OrderSorting : 1045 },
		'gore'						: { OrderInterface : 1046,	OrderSorting : 1046 },
		'gorehounds'					: { OrderInterface : 1047,	OrderSorting : 1047 },
		'gos'						: { OrderInterface : 1048,	OrderSorting : 1048 },
		'gossip'					: { OrderInterface : 1049,	OrderSorting : 1049 },
		'gothic'					: { OrderInterface : 1050,	OrderSorting : 1050 },
		'gothicmaster'				: { OrderInterface : 1051,	OrderSorting : 1051 },
		'gotv'						: { OrderInterface : 1052,	OrderSorting : 1052 },
		'graveurexterne'			: { OrderInterface : 1053,	OrderSorting : 1053 },
		'greenbud1969'				: { OrderInterface : 1054,	OrderSorting : 1054 },
		'greenstorm'					: { OrderInterface : 1055,	OrderSorting : 1055 },
		'greid'						: { OrderInterface : 1056,	OrderSorting : 1056 },
		'grep'						: { OrderInterface : 1057,	OrderSorting : 1057 },
		'greyhounds'					: { OrderInterface : 1058,	OrderSorting : 1058 },
		'grind'						: { OrderInterface : 1059,	OrderSorting : 1059 },
		'grupohds'					: { OrderInterface : 1060,	OrderSorting : 1060 },
		'grym'						: { OrderInterface : 1061,	OrderSorting : 1061 },
		'gs'							: { OrderInterface : 1062,	OrderSorting : 1062 },
		'gs88'						: { OrderInterface : 1063,	OrderSorting : 1063 },
		'gsftx'						: { OrderInterface : 1064,	OrderSorting : 1064 },
		'gsg9'						: { OrderInterface : 1065,	OrderSorting : 1065 },
		'gsn'						: { OrderInterface : 1066,	OrderSorting : 1066 },
		'gtf'						: { OrderInterface : 1067,	OrderSorting : 1067 },
		'gti'						: { OrderInterface : 1068,	OrderSorting : 1068 },
		'gtvg'						: { OrderInterface : 1069,	OrderSorting : 1069 },
		'guacamole'					: { OrderInterface : 1070,	OrderSorting : 1070 },
		'guardians'					: { OrderInterface : 1071,	OrderSorting : 1071 },
		'gungrave'					: { OrderInterface : 1072,	OrderSorting : 1072 },
		'gur'						: { OrderInterface : 1073,	OrderSorting : 1073 },
		'gvd'						: { OrderInterface : 1074,	OrderSorting : 1074 },
		'gw'							: { OrderInterface : 1075,	OrderSorting : 1075 },
		'gwc'						: { OrderInterface : 1076,	OrderSorting : 1076 },
		'gwp'						: { OrderInterface : 1077,	OrderSorting : 1077 },
		'gxp'						: { OrderInterface : 1078,	OrderSorting : 1078 },
		'gyroscope'					: { OrderInterface : 1079,	OrderSorting : 1079 },
		'gzcrew'					: { OrderInterface : 1080,	OrderSorting : 1080 },
		'gzp'						: { OrderInterface : 1081,	OrderSorting : 1081 },
		'h2'							: { OrderInterface : 1082,	OrderSorting : 1082 },
		'h3ll2p4y'					: { OrderInterface : 1083,	OrderSorting : 1083 },
		'h3llg0d'					: { OrderInterface : 1084,	OrderSorting : 1084 },
		'h4s5s'						: { OrderInterface : 1085,	OrderSorting : 1085 },
		'hab'						: { OrderInterface : 1086,	OrderSorting : 1086 },
		'haco'						: { OrderInterface : 1087,	OrderSorting : 1087 },
		'haggis'					: { OrderInterface : 1088,	OrderSorting : 1088 },
		'haideaf'					: { OrderInterface : 1089,	OrderSorting : 1089 },
		'haiku'						: { OrderInterface : 1090,	OrderSorting : 1090 },
		'halcyon'					: { OrderInterface : 1091,	OrderSorting : 1091 },
		'hammer71'					: { OrderInterface : 1092,	OrderSorting : 1092 },
		'hangover'					: { OrderInterface : 1093,	OrderSorting : 1093 },
		'hannibal'					: { OrderInterface : 1094,	OrderSorting : 1094 },
		'hao4k'						: { OrderInterface : 1095,	OrderSorting : 1095 },
		'hashminer'					: { OrderInterface : 1096,	OrderSorting : 1096 },
		'hatchetgear'				: { OrderInterface : 1097,	OrderSorting : 1097 },
		'hay'						: { OrderInterface : 1098,	OrderSorting : 1098 },
		'hazmatt'					: { OrderInterface : 1099,	OrderSorting : 1099 },
		'hb'							: { OrderInterface : 1100,	OrderSorting : 1100 },
		'hca'						: { OrderInterface : 1101,	OrderSorting : 1101 },
		'hd4u'						: { OrderInterface : 1102,	OrderSorting : 1102 },
		'hda'						: { OrderInterface : 1103,	OrderSorting : 1103 },
		'hdaccess'					: { OrderInterface : 1104,	OrderSorting : 1104 },
		'hdalx'						: { OrderInterface : 1105,	OrderSorting : 1105 },
		'hdarea'					: { OrderInterface : 1106,	OrderSorting : 1106 },
		'hdb'						: { OrderInterface : 1107,	OrderSorting : 1107 },
		'hdbee'						: { OrderInterface : 1108,	OrderSorting : 1108 },
		'hdbrise'					: { OrderInterface : 1109,	OrderSorting : 1109 },
		'hdc'						: { OrderInterface : 1110,	OrderSorting : 1110 },
		'hdchina'					: { OrderInterface : 1111,	OrderSorting : 1111 },
		'hdclassics'					: { OrderInterface : 1112,	OrderSorting : 1112 },
		'hdclub'					: { OrderInterface : 1113,	OrderSorting : 1113 },
		'hdcp'						: { OrderInterface : 1114,	OrderSorting : 1114 },
		'hdctv'						: { OrderInterface : 1115,	OrderSorting : 1115 },
		'hddevils'					: { OrderInterface : 1116,	OrderSorting : 1116 },
		'hdetg'						: { OrderInterface : 1117,	OrderSorting : 1117 },
		'hdex'						: { OrderInterface : 1118,	OrderSorting : 1118 },
		'hdfilmboss'					: { OrderInterface : 1119,	OrderSorting : 1119 },
		'hdh'						: { OrderInterface : 1120,	OrderSorting : 1120 },
		'hdhome'					: { OrderInterface : 1121,	OrderSorting : 1121 },
		'hdhub'						: { OrderInterface : 1122,	OrderSorting : 1122 },
		'hdi'						: { OrderInterface : 1123,	OrderSorting : 1123 },
		'hdil'						: { OrderInterface : 1124,	OrderSorting : 1124 },
		'hdl'						: { OrderInterface : 1125,	OrderSorting : 1125 },
		'hdlight'					: { OrderInterface : 1126,	OrderSorting : 1126 },
		'hdlite'					: { OrderInterface : 1127,	OrderSorting : 1127 },
		'hdmaniacs'					: { OrderInterface : 1128,	OrderSorting : 1128 },
		'hdme'						: { OrderInterface : 1129,	OrderSorting : 1129 },
		'hdmonsk'					: { OrderInterface : 1130,	OrderSorting : 1130 },
		'hdo'						: { OrderInterface : 1131,	OrderSorting : 1131 },
		'hdq'						: { OrderInterface : 1132,	OrderSorting : 1132 },
		'hdreactor'					: { OrderInterface : 1133,	OrderSorting : 1133 },
		'hdrezka'					: { OrderInterface : 1134,	OrderSorting : 1134 },
		'hdrezkastudio'				: { OrderInterface : 1135,	OrderSorting : 1135 },
		'hdrinvasion'				: { OrderInterface : 1136,	OrderSorting : 1136 },
		'hdroad'					: { OrderInterface : 1137,	OrderSorting : 1137 },
		'hds'						: { OrderInterface : 1138,	OrderSorting : 1138 },
		'hdsector'					: { OrderInterface : 1139,	OrderSorting : 1139 },
		'hdspace'					: { OrderInterface : 1140,	OrderSorting : 1140 },
		'hdt'						: { OrderInterface : 1141,	OrderSorting : 1141 },
		'hdteam'					: { OrderInterface : 1142,	OrderSorting : 1142 },
		'hdtracker'					: { OrderInterface : 1143,	OrderSorting : 1143 },
		'hdu'						: { OrderInterface : 1144,	OrderSorting : 1144 },
		'hdv'						: { OrderInterface : 1145,	OrderSorting : 1145 },
		'hdv0t'						: { OrderInterface : 1146,	OrderSorting : 1146 },
		'hdvision'					: { OrderInterface : 1147,	OrderSorting : 1147 },
		'hdvn'						: { OrderInterface : 1148,	OrderSorting : 1148 },
		'hdw'						: { OrderInterface : 1149,	OrderSorting : 1149 },
		'hdwing'					: { OrderInterface : 1150,	OrderSorting : 1150 },
		'hdx'						: { OrderInterface : 1151,	OrderSorting : 1151 },
		'hdxt'						: { OrderInterface : 1152,	OrderSorting : 1152 },
		'heat'						: { OrderInterface : 1153,	OrderSorting : 1153 },
		'hector'					: { OrderInterface : 1154,	OrderSorting : 1154 },
		'heel'						: { OrderInterface : 1155,	OrderSorting : 1155 },
		'heesten'					: { OrderInterface : 1156,	OrderSorting : 1156 },
		'heh'						: { OrderInterface : 1157,	OrderSorting : 1157 },
		'heisenberg'					: { OrderInterface : 1158,	OrderSorting : 1158 },
		'helix'						: { OrderInterface : 1159,	OrderSorting : 1159 },
		'hellraz0r'					: { OrderInterface : 1160,	OrderSorting : 1160 },
		'hellywood'					: { OrderInterface : 1161,	OrderSorting : 1161 },
		'henderson'					: { OrderInterface : 1162,	OrderSorting : 1162 },
		'herakler'					: { OrderInterface : 1163,	OrderSorting : 1163 },
		'heteam'					: { OrderInterface : 1164,	OrderSorting : 1164 },
		'hevcbay'					: { OrderInterface : 1165,	OrderSorting : 1165 },
		'hevcclub'					: { OrderInterface : 1166,	OrderSorting : 1166 },
		'hevcguy'					: { OrderInterface : 1167,	OrderSorting : 1167 },
		'hevclovers'					: { OrderInterface : 1168,	OrderSorting : 1168 },
		'hh'							: { OrderInterface : 1169,	OrderSorting : 1169 },
		'hhh'						: { OrderInterface : 1170,	OrderSorting : 1170 },
		'hhi'						: { OrderInterface : 1171,	OrderSorting : 1171 },
		'hidef'						: { OrderInterface : 1172,	OrderSorting : 1172 },
		'hidt'						: { OrderInterface : 1173,	OrderSorting : 1173 },
		'hifi'						: { OrderInterface : 1174,	OrderSorting : 1174 },
		'highcal'					: { OrderInterface : 1175,	OrderSorting : 1175 },
		'highcode'					: { OrderInterface : 1176,	OrderSorting : 1176 },
		'highvoltage'				: { OrderInterface : 1177,	OrderSorting : 1177 },
		'hillary'					: { OrderInterface : 1178,	OrderSorting : 1178 },
		'hiqve'						: { OrderInterface : 1179,	OrderSorting : 1179 },
		'hisd'						: { OrderInterface : 1180,	OrderSorting : 1180 },
		'history'					: { OrderInterface : 1181,	OrderSorting : 1181 },
		'hivecm8'					: { OrderInterface : 1182,	OrderSorting : 1182 },
		'hjs'						: { OrderInterface : 1183,	OrderSorting : 1183 },
		'hkd'						: { OrderInterface : 1184,	OrderSorting : 1184 },
		'hls'						: { OrderInterface : 1185,	OrderSorting : 1185 },
		'hm'							: { OrderInterface : 1186,	OrderSorting : 1186 },
		'hn'							: { OrderInterface : 1187,	OrderSorting : 1187 },
		'hnr'						: { OrderInterface : 1188,	OrderSorting : 1188 },
		'hodl'						: { OrderInterface : 1189,	OrderSorting : 1189 },
		'hoh'						: { OrderInterface : 1190,	OrderSorting : 1190 },
		'holiday'					: { OrderInterface : 1191,	OrderSorting : 1191 },
		'home'						: { OrderInterface : 1192,	OrderSorting : 1192 },
		'homefei'					: { OrderInterface : 1193,	OrderSorting : 1193 },
		'hon3y'						: { OrderInterface : 1194,	OrderSorting : 1194 },
		'hon3yhd'					: { OrderInterface : 1195,	OrderSorting : 1195 },
		'hone'						: { OrderInterface : 1196,	OrderSorting : 1196 },
		'hoodbag'					: { OrderInterface : 1197,	OrderSorting : 1197 },
		'hookah'					: { OrderInterface : 1198,	OrderSorting : 1198 },
		'horizon'					: { OrderInterface : 1199,	OrderSorting : 1199 },
		'horizonartsubs'			: { OrderInterface : 1200,	OrderSorting : 1200 },
		'hornigold'					: { OrderInterface : 1201,	OrderSorting : 1201 },
		'horriblesubs'				: { OrderInterface : 1202,	OrderSorting : 1202 },
		'hostile'					: { OrderInterface : 1203,	OrderSorting : 1203 },
		'hotlips'					: { OrderInterface : 1204,	OrderSorting : 1204 },
		'howl'						: { OrderInterface : 1205,	OrderSorting : 1205 },
		'hp'							: { OrderInterface : 1206,	OrderSorting : 1206 },
		'hq7'						: { OrderInterface : 1207,	OrderSorting : 1207 },
		'hqclub'					: { OrderInterface : 1208,	OrderSorting : 1208 },
		'hqe'						: { OrderInterface : 1209,	OrderSorting : 1209 },
		'hqm'						: { OrderInterface : 1210,	OrderSorting : 1210 },
		'hqx'						: { OrderInterface : 1211,	OrderSorting : 1211 },
		'hrdr'						: { OrderInterface : 1212,	OrderSorting : 1212 },
		'hrip'						: { OrderInterface : 1213,	OrderSorting : 1213 },
		'hrs'						: { OrderInterface : 1214,	OrderSorting : 1214 },
		'hs'							: { OrderInterface : 1215,	OrderSorting : 1215 },
		'hubris'					: { OrderInterface : 1216,	OrderSorting : 1216 },
		'hud'						: { OrderInterface : 1217,	OrderSorting : 1217 },
		'hunter'					: { OrderInterface : 1218,	OrderSorting : 1218 },
		'hurtom'					: { OrderInterface : 1219,	OrderSorting : 1219 },
		'hush'						: { OrderInterface : 1220,	OrderSorting : 1220 },
		'hushrips'					: { OrderInterface : 1221,	OrderSorting : 1221 },
		'huzzah'					: { OrderInterface : 1222,	OrderSorting : 1222 },
		'hwd'						: { OrderInterface : 1223,	OrderSorting : 1223 },
		'hyb'						: { OrderInterface : 1224,	OrderSorting : 1224 },
		'hybrid'					: { OrderInterface : 1225,	OrderSorting : 1225 },
		'hybris'					: { OrderInterface : 1226,	OrderSorting : 1226 },
		'hyde'						: { OrderInterface : 1227,	OrderSorting : 1227 },
		'hype'						: { OrderInterface : 1228,	OrderSorting : 1228 },
		'hz'							: { OrderInterface : 1229,	OrderSorting : 1229 },
		'iahd'						: { OrderInterface : 1230,	OrderSorting : 1230 },
		'iamable'					: { OrderInterface : 1231,	OrderSorting : 1231 },
		'ic'							: { OrderInterface : 1232,	OrderSorting : 1232 },
		'icandy'					: { OrderInterface : 1233,	OrderSorting : 1233 },
		'ice'						: { OrderInterface : 1234,	OrderSorting : 1234 },
		'icmal'						: { OrderInterface : 1235,	OrderSorting : 1235 },
		'icn'						: { OrderInterface : 1236,	OrderSorting : 1236 },
		'ico'						: { OrderInterface : 1237,	OrderSorting : 1237 },
		'ictv'						: { OrderInterface : 1238,	OrderSorting : 1238 },
		'icvmircrew'					: { OrderInterface : 1239,	OrderSorting : 1239 },
		'id'							: { OrderInterface : 1240,	OrderSorting : 1240 },
		'ide'						: { OrderInterface : 1241,	OrderSorting : 1241 },
		'ideafilm'					: { OrderInterface : 1242,	OrderSorting : 1242 },
		'idncrew'					: { OrderInterface : 1243,	OrderSorting : 1243 },
		'idtv'						: { OrderInterface : 1244,	OrderSorting : 1244 },
		'iextv'						: { OrderInterface : 1245,	OrderSorting : 1245 },
		'ifh'						: { OrderInterface : 1246,	OrderSorting : 1246 },
		'iflix'						: { OrderInterface : 1247,	OrderSorting : 1247 },
		'ifn'						: { OrderInterface : 1248,	OrderSorting : 1248 },
		'ifpd'						: { OrderInterface : 1249,	OrderSorting : 1249 },
		'ift'						: { OrderInterface : 1250,	OrderSorting : 1250 },
		'ig'							: { OrderInterface : 1251,	OrderSorting : 1251 },
		'igd'						: { OrderInterface : 1252,	OrderSorting : 1252 },
		'ignite'					: { OrderInterface : 1253,	OrderSorting : 1253 },
		'ignition'					: { OrderInterface : 1254,	OrderSorting : 1254 },
		'iguana'					: { OrderInterface : 1255,	OrderSorting : 1255 },
		'ihd'						: { OrderInterface : 1256,	OrderSorting : 1256 },
		'iht'						: { OrderInterface : 1257,	OrderSorting : 1257 },
		'ika'						: { OrderInterface : 1258,	OrderSorting : 1258 },
		'ikaos'						: { OrderInterface : 1259,	OrderSorting : 1259 },
		'ikiw'						: { OrderInterface : 1260,	OrderSorting : 1260 },
		'ila'						: { OrderInterface : 1261,	OrderSorting : 1261 },
		'ilg'						: { OrderInterface : 1262,	OrderSorting : 1262 },
		'ill'						: { OrderInterface : 1263,	OrderSorting : 1263 },
		'illusion'					: { OrderInterface : 1264,	OrderSorting : 1264 },
		'ilovehd'					: { OrderInterface : 1265,	OrderSorting : 1265 },
		'ils'						: { OrderInterface : 1266,	OrderSorting : 1266 },
		'imacruel1'					: { OrderInterface : 1267,	OrderSorting : 1267 },
		'imagine'					: { OrderInterface : 1268,	OrderSorting : 1268 },
		'imax'						: { OrderInterface : 1269,	OrderSorting : 1269 },
		'imbt'						: { OrderInterface : 1270,	OrderSorting : 1270 },
		'imdths'					: { OrderInterface : 1271,	OrderSorting : 1271 },
		'ime'						: { OrderInterface : 1272,	OrderSorting : 1272 },
		'immerse'					: { OrderInterface : 1273,	OrderSorting : 1273 },
		'immortals'					: { OrderInterface : 1274,	OrderSorting : 1274 },
		'imp3rial'					: { OrderInterface : 1275,	OrderSorting : 1275 },
		'imperium'					: { OrderInterface : 1276,	OrderSorting : 1276 },
		'imposters'					: { OrderInterface : 1277,	OrderSorting : 1277 },
		'imsamirofficial'			: { OrderInterface : 1278,	OrderSorting : 1278 },
		'imsorny'					: { OrderInterface : 1279,	OrderSorting : 1279 },
		'inam'						: { OrderInterface : 1280,	OrderSorting : 1280 },
		'inception'					: { OrderInterface : 1281,	OrderSorting : 1281 },
		'incite'					: { OrderInterface : 1282,	OrderSorting : 1282 },
		'incognito'					: { OrderInterface : 1283,	OrderSorting : 1283 },
		'ind'						: { OrderInterface : 1284,	OrderSorting : 1284 },
		'infamous'					: { OrderInterface : 1285,	OrderSorting : 1285 },
		'inferno'					: { OrderInterface : 1286,	OrderSorting : 1286 },
		'infotv'					: { OrderInterface : 1287,	OrderSorting : 1287 },
		'ingot'						: { OrderInterface : 1288,	OrderSorting : 1288 },
		'inject'					: { OrderInterface : 1289,	OrderSorting : 1289 },
		'ink'						: { OrderInterface : 1290,	OrderSorting : 1290 },
		'inklusion'					: { OrderInterface : 1291,	OrderSorting : 1291 },
		'innocence'					: { OrderInterface : 1292,	OrderSorting : 1292 },
		'inp'						: { OrderInterface : 1293,	OrderSorting : 1293 },
		'insanity'					: { OrderInterface : 1294,	OrderSorting : 1294 },
		'insects'					: { OrderInterface : 1295,	OrderSorting : 1295 },
		'insidious'					: { OrderInterface : 1296,	OrderSorting : 1296 },
		'inspiral'					: { OrderInterface : 1297,	OrderSorting : 1297 },
		'inspired'					: { OrderInterface : 1298,	OrderSorting : 1298 },
		'inspirit'					: { OrderInterface : 1299,	OrderSorting : 1299 },
		'int'						: { OrderInterface : 1300,	OrderSorting : 1300 },
		'intenso'					: { OrderInterface : 1301,	OrderSorting : 1301 },
		'intention'					: { OrderInterface : 1302,	OrderSorting : 1302 },
		'intgrity'					: { OrderInterface : 1303,	OrderSorting : 1303 },
		'intimid'					: { OrderInterface : 1304,	OrderSorting : 1304 },
		'invaders'					: { OrderInterface : 1305,	OrderSorting : 1305 },
		'invandraren'				: { OrderInterface : 1306,	OrderSorting : 1306 },
		'invictus'					: { OrderInterface : 1307,	OrderSorting : 1307 },
		'invincible'					: { OrderInterface : 1308,	OrderSorting : 1308 },
		'ion'						: { OrderInterface : 1309,	OrderSorting : 1309 },
		'ion10'						: { OrderInterface : 1310,	OrderSorting : 1310 },
		'ion265'					: { OrderInterface : 1311,	OrderSorting : 1311 },
		'iplayertv'					: { OrderInterface : 1312,	OrderSorting : 1312 },
		'ipt'						: { OrderInterface : 1313,	OrderSorting : 1313 },
		'ism'						: { OrderInterface : 1314,	OrderSorting : 1314 },
		'istance'					: { OrderInterface : 1315,	OrderSorting : 1315 },
		'isubs'						: { OrderInterface : 1316,	OrderSorting : 1316 },
		'it00nz'					: { OrderInterface : 1317,	OrderSorting : 1317 },
		'itg'						: { OrderInterface : 1318,	OrderSorting : 1318 },
		'itsat'						: { OrderInterface : 1319,	OrderSorting : 1319 },
		'itz'						: { OrderInterface : 1320,	OrderSorting : 1320 },
		'iy'							: { OrderInterface : 1321,	OrderSorting : 1321 },
		'j4f'						: { OrderInterface : 1322,	OrderSorting : 1322 },
		'jackal'					: { OrderInterface : 1323,	OrderSorting : 1323 },
		'jackie'					: { OrderInterface : 1324,	OrderSorting : 1324 },
		'jade'						: { OrderInterface : 1325,	OrderSorting : 1325 },
		'jah'						: { OrderInterface : 1326,	OrderSorting : 1326 },
		'jam'						: { OrderInterface : 1327,	OrderSorting : 1327 },
		'jane'						: { OrderInterface : 1328,	OrderSorting : 1328 },
		'janedoe'					: { OrderInterface : 1329,	OrderSorting : 1329 },
		'japhson'					: { OrderInterface : 1330,	OrderSorting : 1330 },
		'jaskier'					: { OrderInterface : 1331,	OrderSorting : 1331 },
		'jason28'					: { OrderInterface : 1332,	OrderSorting : 1332 },
		'jasperp'					: { OrderInterface : 1333,	OrderSorting : 1333 },
		'jass'						: { OrderInterface : 1334,	OrderSorting : 1334 },
		'jato'						: { OrderInterface : 1335,	OrderSorting : 1335 },
		'jatt'						: { OrderInterface : 1336,	OrderSorting : 1336 },
		'jaybob'					: { OrderInterface : 1337,	OrderSorting : 1337 },
		'jbs'						: { OrderInterface : 1338,	OrderSorting : 1338 },
		'jcgoku21'					: { OrderInterface : 1339,	OrderSorting : 1339 },
		'jch'						: { OrderInterface : 1340,	OrderSorting : 1340 },
		'jebaited'					: { OrderInterface : 1341,	OrderSorting : 1341 },
		'jedi'						: { OrderInterface : 1342,	OrderSorting : 1342 },
		'jellybean'					: { OrderInterface : 1343,	OrderSorting : 1343 },
		'jester'					: { OrderInterface : 1344,	OrderSorting : 1344 },
		'jetix'						: { OrderInterface : 1345,	OrderSorting : 1345 },
		'jetset'					: { OrderInterface : 1346,	OrderSorting : 1346 },
		'jew'						: { OrderInterface : 1347,	OrderSorting : 1347 },
		'jfkdvd'					: { OrderInterface : 1348,	OrderSorting : 1348 },
		'jfkxvid'					: { OrderInterface : 1349,	OrderSorting : 1349 },
		'jhonny2'					: { OrderInterface : 1350,	OrderSorting : 1350 },
		'jitb'						: { OrderInterface : 1351,	OrderSorting : 1351 },
		'jive'						: { OrderInterface : 1352,	OrderSorting : 1352 },
		'jj'							: { OrderInterface : 1353,	OrderSorting : 1353 },
		'jm'							: { OrderInterface : 1354,	OrderSorting : 1354 },
		'jmt'						: { OrderInterface : 1355,	OrderSorting : 1355 },
		'jolly'						: { OrderInterface : 1356,	OrderSorting : 1356 },
		'jollyroger'					: { OrderInterface : 1357,	OrderSorting : 1357 },
		'joy'						: { OrderInterface : 1358,	OrderSorting : 1358 },
		'jrr'						: { OrderInterface : 1359,	OrderSorting : 1359 },
		'jtv'						: { OrderInterface : 1360,	OrderSorting : 1360 },
		'judas'						: { OrderInterface : 1361,	OrderSorting : 1361 },
		'judgement'					: { OrderInterface : 1362,	OrderSorting : 1362 },
		'juggalotus'					: { OrderInterface : 1363,	OrderSorting : 1363 },
		'juggs'						: { OrderInterface : 1364,	OrderSorting : 1364 },
		'jumanji'					: { OrderInterface : 1365,	OrderSorting : 1365 },
		'junoon'					: { OrderInterface : 1366,	OrderSorting : 1366 },
		'just4fun'					: { OrderInterface : 1367,	OrderSorting : 1367 },
		'justhd'					: { OrderInterface : 1368,	OrderSorting : 1368 },
		'justin'					: { OrderInterface : 1369,	OrderSorting : 1369 },
		'justiso'					: { OrderInterface : 1370,	OrderSorting : 1370 },
		'justwatch'					: { OrderInterface : 1371,	OrderSorting : 1371 },
		'jvc'						: { OrderInterface : 1372,	OrderSorting : 1372 },
		'jyk'						: { OrderInterface : 1373,	OrderSorting : 1373 },
		'k2'							: { OrderInterface : 1374,	OrderSorting : 1374 },
		'kaf'						: { OrderInterface : 1375,	OrderSorting : 1375 },
		'kafferep'					: { OrderInterface : 1376,	OrderSorting : 1376 },
		'kaga'						: { OrderInterface : 1377,	OrderSorting : 1377 },
		'kaidubs'					: { OrderInterface : 1378,	OrderSorting : 1378 },
		'kaizen'					: { OrderInterface : 1379,	OrderSorting : 1379 },
		'kaka'						: { OrderInterface : 1380,	OrderSorting : 1380 },
		'kalipso'					: { OrderInterface : 1381,	OrderSorting : 1381 },
		'kamera'					: { OrderInterface : 1382,	OrderSorting : 1382 },
		'kamikaze'					: { OrderInterface : 1383,	OrderSorting : 1383 },
		'kappa'						: { OrderInterface : 1384,	OrderSorting : 1384 },
		'kart3ldvd'					: { OrderInterface : 1385,	OrderSorting : 1385 },
		'kas'						: { OrderInterface : 1386,	OrderSorting : 1386 },
		'kashmir'					: { OrderInterface : 1387,	OrderSorting : 1387 },
		'kata'						: { OrderInterface : 1388,	OrderSorting : 1388 },
		'kate'						: { OrderInterface : 1389,	OrderSorting : 1389 },
		'katmaster'					: { OrderInterface : 1390,	OrderSorting : 1390 },
		'katmoviehd'					: { OrderInterface : 1391,	OrderSorting : 1391 },
		'kazan'						: { OrderInterface : 1392,	OrderSorting : 1392 },
		'keaton'					: { OrderInterface : 1393,	OrderSorting : 1393 },
		'keg'						: { OrderInterface : 1394,	OrderSorting : 1394 },
		'keltz'						: { OrderInterface : 1395,	OrderSorting : 1395 },
		'kerob'						: { OrderInterface : 1396,	OrderSorting : 1396 },
		'kesh'						: { OrderInterface : 1397,	OrderSorting : 1397 },
		'kettle'					: { OrderInterface : 1398,	OrderSorting : 1398 },
		'kf'							: { OrderInterface : 1399,	OrderSorting : 1399 },
		'kg'							: { OrderInterface : 1400,	OrderSorting : 1400 },
		'kh'							: { OrderInterface : 1401,	OrderSorting : 1401 },
		'khn'						: { OrderInterface : 1402,	OrderSorting : 1402 },
		'khoshmard'					: { OrderInterface : 1403,	OrderSorting : 1403 },
		'khp'						: { OrderInterface : 1404,	OrderSorting : 1404 },
		'kickass'					: { OrderInterface : 1405,	OrderSorting : 1405 },
		'kickfoot'					: { OrderInterface : 1406,	OrderSorting : 1406 },
		'kickoff'					: { OrderInterface : 1407,	OrderSorting : 1407 },
		'kid'						: { OrderInterface : 1408,	OrderSorting : 1408 },
		'killers'					: { OrderInterface : 1409,	OrderSorting : 1409 },
		'kimchi'					: { OrderInterface : 1410,	OrderSorting : 1410 },
		'kingdom'					: { OrderInterface : 1411,	OrderSorting : 1411 },
		'kingmaker'					: { OrderInterface : 1412,	OrderSorting : 1412 },
		'kings'						: { OrderInterface : 1413,	OrderSorting : 1413 },
		'kingstoner'					: { OrderInterface : 1414,	OrderSorting : 1414 },
		'kinowelt'					: { OrderInterface : 1415,	OrderSorting : 1415 },
		'kir4'						: { OrderInterface : 1416,	OrderSorting : 1416 },
		'kira'						: { OrderInterface : 1417,	OrderSorting : 1417 },
		'kirklestat'					: { OrderInterface : 1418,	OrderSorting : 1418 },
		'kiss'						: { OrderInterface : 1419,	OrderSorting : 1419 },
		'kit'						: { OrderInterface : 1420,	OrderSorting : 1420 },
		'kiyoshistar'				: { OrderInterface : 1421,	OrderSorting : 1421 },
		'kk650'						: { OrderInterface : 1422,	OrderSorting : 1422 },
		'klassigerhd'				: { OrderInterface : 1423,	OrderSorting : 1423 },
		'klaxxon'					: { OrderInterface : 1424,	OrderSorting : 1424 },
		'klingon'					: { OrderInterface : 1425,	OrderSorting : 1425 },
		'klio'						: { OrderInterface : 1426,	OrderSorting : 1426 },
		'km'							: { OrderInterface : 1427,	OrderSorting : 1427 },
		'knifesharp'					: { OrderInterface : 1428,	OrderSorting : 1428 },
		'knp'						: { OrderInterface : 1429,	OrderSorting : 1429 },
		'koalf'						: { OrderInterface : 1430,	OrderSorting : 1430 },
		'koc'						: { OrderInterface : 1431,	OrderSorting : 1431 },
		'koenig'					: { OrderInterface : 1432,	OrderSorting : 1432 },
		'kogi'						: { OrderInterface : 1433,	OrderSorting : 1433 },
		'kole'						: { OrderInterface : 1434,	OrderSorting : 1434 },
		'kompost'					: { OrderInterface : 1435,	OrderSorting : 1435 },
		'konzillarg'					: { OrderInterface : 1436,	OrderSorting : 1436 },
		'kookoo'					: { OrderInterface : 1437,	OrderSorting : 1437 },
		'korsar'					: { OrderInterface : 1438,	OrderSorting : 1438 },
		'koshara'					: { OrderInterface : 1439,	OrderSorting : 1439 },
		'kotuwa'					: { OrderInterface : 1440,	OrderSorting : 1440 },
		'koyumu'					: { OrderInterface : 1441,	OrderSorting : 1441 },
		'kralimarko'					: { OrderInterface : 1442,	OrderSorting : 1442 },
		'krave'						: { OrderInterface : 1443,	OrderSorting : 1443 },
		'krissz'					: { OrderInterface : 1444,	OrderSorting : 1444 },
		'kristallprinz'				: { OrderInterface : 1445,	OrderSorting : 1445 },
		'kronos'					: { OrderInterface : 1446,	OrderSorting : 1446 },
		'krs'						: { OrderInterface : 1447,	OrderSorting : 1447 },
		'kuchikirukia'				: { OrderInterface : 1448,	OrderSorting : 1448 },
		'kuth'						: { OrderInterface : 1449,	OrderSorting : 1449 },
		'kyr'						: { OrderInterface : 1450,	OrderSorting : 1450 },
		'kz'							: { OrderInterface : 1451,	OrderSorting : 1451 },
		'l0l'						: { OrderInterface : 1452,	OrderSorting : 1452 },
		'ladybug'					: { OrderInterface : 1453,	OrderSorting : 1453 },
		'lako'						: { OrderInterface : 1454,	OrderSorting : 1454 },
		'lamb'						: { OrderInterface : 1455,	OrderSorting : 1455 },
		'lame'						: { OrderInterface : 1456,	OrderSorting : 1456 },
		'lamehd'					: { OrderInterface : 1457,	OrderSorting : 1457 },
		'lamexd'					: { OrderInterface : 1458,	OrderSorting : 1458 },
		'langbard'					: { OrderInterface : 1459,	OrderSorting : 1459 },
		'lap'						: { OrderInterface : 1460,	OrderSorting : 1460 },
		'lapumia'					: { OrderInterface : 1461,	OrderSorting : 1461 },
		'lapumiafilmes'				: { OrderInterface : 1462,	OrderSorting : 1462 },
		'larceny'					: { OrderInterface : 1463,	OrderSorting : 1463 },
		'lard'						: { OrderInterface : 1464,	OrderSorting : 1464 },
		'latency'					: { OrderInterface : 1465,	OrderSorting : 1465 },
		'law'						: { OrderInterface : 1466,	OrderSorting : 1466 },
		'lazarus'					: { OrderInterface : 1467,	OrderSorting : 1467 },
		'lazers'					: { OrderInterface : 1468,	OrderSorting : 1468 },
		'lazy'						: { OrderInterface : 1469,	OrderSorting : 1469 },
		'lb'							: { OrderInterface : 1470,	OrderSorting : 1470 },
		'lbr'						: { OrderInterface : 1471,	OrderSorting : 1471 },
		'lchd'						: { OrderInterface : 1472,	OrderSorting : 1472 },
		'lds'						: { OrderInterface : 1473,	OrderSorting : 1473 },
		'le'							: { OrderInterface : 1474,	OrderSorting : 1474 },
		'lee'						: { OrderInterface : 1475,	OrderSorting : 1475 },
		'leetay'					: { OrderInterface : 1476,	OrderSorting : 1476 },
		'leethd'					: { OrderInterface : 1477,	OrderSorting : 1477 },
		'leetxd'					: { OrderInterface : 1478,	OrderSorting : 1478 },
		'legend'					: { OrderInterface : 1479,	OrderSorting : 1479 },
		'legi0n'					: { OrderInterface : 1480,	OrderSorting : 1480 },
		'legion'					: { OrderInterface : 1481,	OrderSorting : 1481 },
		'leon'						: { OrderInterface : 1482,	OrderSorting : 1482 },
		'leonardo'					: { OrderInterface : 1483,	OrderSorting : 1483 },
		'leralouf'					: { OrderInterface : 1484,	OrderSorting : 1484 },
		'lesnick'					: { OrderInterface : 1485,	OrderSorting : 1485 },
		'leverage'					: { OrderInterface : 1486,	OrderSorting : 1486 },
		'lf'							: { OrderInterface : 1487,	OrderSorting : 1487 },
		'lff'						: { OrderInterface : 1488,	OrderSorting : 1488 },
		'lgc'						: { OrderInterface : 1489,	OrderSorting : 1489 },
		'liberty'					: { OrderInterface : 1490,	OrderSorting : 1490 },
		'librarians'					: { OrderInterface : 1491,	OrderSorting : 1491 },
		'liebehd'					: { OrderInterface : 1492,	OrderSorting : 1492 },
		'lifetime'					: { OrderInterface : 1493,	OrderSorting : 1493 },
		'ligate'					: { OrderInterface : 1494,	OrderSorting : 1494 },
		'lightspeed'					: { OrderInterface : 1495,	OrderSorting : 1495 },
		'lime'						: { OrderInterface : 1496,	OrderSorting : 1496 },
		'ling'						: { OrderInterface : 1497,	OrderSorting : 1497 },
		'linkle'					: { OrderInterface : 1498,	OrderSorting : 1498 },
		'lion'						: { OrderInterface : 1499,	OrderSorting : 1499 },
		'lipan'						: { OrderInterface : 1500,	OrderSorting : 1500 },
		'lite'						: { OrderInterface : 1501,	OrderSorting : 1501 },
		'littledevil'				: { OrderInterface : 1502,	OrderSorting : 1502 },
		'lividity'					: { OrderInterface : 1503,	OrderSorting : 1503 },
		'lizardsquad'				: { OrderInterface : 1504,	OrderSorting : 1504 },
		'lkrg'						: { OrderInterface : 1505,	OrderSorting : 1505 },
		'llg'						: { OrderInterface : 1506,	OrderSorting : 1506 },
		'lmao'						: { OrderInterface : 1507,	OrderSorting : 1507 },
		'lmg'						: { OrderInterface : 1508,	OrderSorting : 1508 },
		'lmk'						: { OrderInterface : 1509,	OrderSorting : 1509 },
		'lnt'						: { OrderInterface : 1510,	OrderSorting : 1510 },
		'lod'						: { OrderInterface : 1511,	OrderSorting : 1511 },
		'lok'						: { OrderInterface : 1512,	OrderSorting : 1512 },
		'loki'						: { OrderInterface : 1513,	OrderSorting : 1513 },
		'lokihd'					: { OrderInterface : 1514,	OrderSorting : 1514 },
		'lol'						: { OrderInterface : 1515,	OrderSorting : 1515 },
		'lolhd'						: { OrderInterface : 1516,	OrderSorting : 1516 },
		'lonewolf'					: { OrderInterface : 1517,	OrderSorting : 1517 },
		'lookmane'					: { OrderInterface : 1518,	OrderSorting : 1518 },
		'lord'						: { OrderInterface : 1519,	OrderSorting : 1519 },
		'lordvako'					: { OrderInterface : 1520,	OrderSorting : 1520 },
		'lost'						: { OrderInterface : 1521,	OrderSorting : 1521 },
		'lostfilm'					: { OrderInterface : 1522,	OrderSorting : 1522 },
		'lostyears'					: { OrderInterface : 1523,	OrderSorting : 1523 },
		'lot'						: { OrderInterface : 1524,	OrderSorting : 1524 },
		'lotv'						: { OrderInterface : 1525,	OrderSorting : 1525 },
		'lounge'					: { OrderInterface : 1526,	OrderSorting : 1526 },
		'love'						: { OrderInterface : 1527,	OrderSorting : 1527 },
		'lovehd'					: { OrderInterface : 1528,	OrderSorting : 1528 },
		'loverulz'					: { OrderInterface : 1529,	OrderSorting : 1529 },
		'lovesick'					: { OrderInterface : 1530,	OrderSorting : 1530 },
		'lp'							: { OrderInterface : 1531,	OrderSorting : 1531 },
		'lpd'						: { OrderInterface : 1532,	OrderSorting : 1532 },
		'lrc'						: { OrderInterface : 1533,	OrderSorting : 1533 },
		'ls'							: { OrderInterface : 1534,	OrderSorting : 1534 },
		'lse'						: { OrderInterface : 1535,	OrderSorting : 1535 },
		'ltn'						: { OrderInterface : 1536,	OrderSorting : 1536 },
		'ltrg'						: { OrderInterface : 1537,	OrderSorting : 1537 },
		'ltt'						: { OrderInterface : 1538,	OrderSorting : 1538 },
		'ltu'						: { OrderInterface : 1539,	OrderSorting : 1539 },
		'lucidtv'					: { OrderInterface : 1540,	OrderSorting : 1540 },
		'lucifer22'					: { OrderInterface : 1541,	OrderSorting : 1541 },
		'lulz'						: { OrderInterface : 1542,	OrderSorting : 1542 },
		'lum1x'						: { OrderInterface : 1543,	OrderSorting : 1543 },
		'lumi'						: { OrderInterface : 1544,	OrderSorting : 1544 },
		'lunar'						: { OrderInterface : 1545,	OrderSorting : 1545 },
		'lund'						: { OrderInterface : 1546,	OrderSorting : 1546 },
		'lusi'						: { OrderInterface : 1547,	OrderSorting : 1547 },
		'luso'						: { OrderInterface : 1548,	OrderSorting : 1548 },
		'lust'						: { OrderInterface : 1549,	OrderSorting : 1549 },
		'lwn'						: { OrderInterface : 1550,	OrderSorting : 1550 },
		'lycan'						: { OrderInterface : 1551,	OrderSorting : 1551 },
		'lycanhd'					: { OrderInterface : 1552,	OrderSorting : 1552 },
		'm00tv'						: { OrderInterface : 1553,	OrderSorting : 1553 },
		'm2'							: { OrderInterface : 1554,	OrderSorting : 1554 },
		'm2tv'						: { OrderInterface : 1555,	OrderSorting : 1555 },
		'm3d'						: { OrderInterface : 1556,	OrderSorting : 1556 },
		'm3q'						: { OrderInterface : 1557,	OrderSorting : 1557 },
		'm4xd0me'					: { OrderInterface : 1558,	OrderSorting : 1558 },
		'm794'						: { OrderInterface : 1559,	OrderSorting : 1559 },
		'machd'						: { OrderInterface : 1560,	OrderSorting : 1560 },
		'machine'					: { OrderInterface : 1561,	OrderSorting : 1561 },
		'mack'						: { OrderInterface : 1562,	OrderSorting : 1562 },
		'macro'						: { OrderInterface : 1563,	OrderSorting : 1563 },
		'madman'					: { OrderInterface : 1564,	OrderSorting : 1564 },
		'madoff'					: { OrderInterface : 1565,	OrderSorting : 1565 },
		'mafiaking'					: { OrderInterface : 1566,	OrderSorting : 1566 },
		'mag'						: { OrderInterface : 1567,	OrderSorting : 1567 },
		'magic'						: { OrderInterface : 1568,	OrderSorting : 1568 },
		'magical'					: { OrderInterface : 1569,	OrderSorting : 1569 },
		'majestic'					: { OrderInterface : 1570,	OrderSorting : 1570 },
		'makintos13'					: { OrderInterface : 1571,	OrderSorting : 1571 },
		'male'						: { OrderInterface : 1572,	OrderSorting : 1572 },
		'man'						: { OrderInterface : 1573,	OrderSorting : 1573 },
		'mandr'						: { OrderInterface : 1574,	OrderSorting : 1574 },
		'manning'					: { OrderInterface : 1575,	OrderSorting : 1575 },
		'marge'						: { OrderInterface : 1576,	OrderSorting : 1576 },
		'marhaba'					: { OrderInterface : 1577,	OrderSorting : 1577 },
		'markii'					: { OrderInterface : 1578,	OrderSorting : 1578 },
		'mars'						: { OrderInterface : 1579,	OrderSorting : 1579 },
		'marvelous'					: { OrderInterface : 1580,	OrderSorting : 1580 },
		'master5'					: { OrderInterface : 1581,	OrderSorting : 1581 },
		'matter'					: { OrderInterface : 1582,	OrderSorting : 1582 },
		'max'						: { OrderInterface : 1583,	OrderSorting : 1583 },
		'maxhd'						: { OrderInterface : 1584,	OrderSorting : 1584 },
		'maxi'						: { OrderInterface : 1585,	OrderSorting : 1585 },
		'maximersk'					: { OrderInterface : 1586,	OrderSorting : 1586 },
		'maximum'					: { OrderInterface : 1587,	OrderSorting : 1587 },
		'maxpro'					: { OrderInterface : 1588,	OrderSorting : 1588 },
		'maxrls'					: { OrderInterface : 1589,	OrderSorting : 1589 },
		'maxspeed'					: { OrderInterface : 1590,	OrderSorting : 1590 },
		'maxx'						: { OrderInterface : 1591,	OrderSorting : 1591 },
		'mayhem'					: { OrderInterface : 1592,	OrderSorting : 1592 },
		'maz'						: { OrderInterface : 1593,	OrderSorting : 1593 },
		'mbrhdrg'					: { OrderInterface : 1594,	OrderSorting : 1594 },
		'mc5'						: { OrderInterface : 1595,	OrderSorting : 1595 },
		'mcfly'						: { OrderInterface : 1596,	OrderSorting : 1596 },
		'mch'						: { OrderInterface : 1597,	OrderSorting : 1597 },
		'mchd'						: { OrderInterface : 1598,	OrderSorting : 1598 },
		'mcr'						: { OrderInterface : 1599,	OrderSorting : 1599 },
		'mctav'						: { OrderInterface : 1600,	OrderSorting : 1600 },
		'mdgp'						: { OrderInterface : 1601,	OrderSorting : 1601 },
		'mdm'						: { OrderInterface : 1602,	OrderSorting : 1602 },
		'mdr'						: { OrderInterface : 1603,	OrderSorting : 1603 },
		'me7alh'					: { OrderInterface : 1604,	OrderSorting : 1604 },
		'meakes'					: { OrderInterface : 1605,	OrderSorting : 1605 },
		'med'						: { OrderInterface : 1606,	OrderSorting : 1606 },
		'meddy'						: { OrderInterface : 1607,	OrderSorting : 1607 },
		'mediamaniacs'				: { OrderInterface : 1608,	OrderSorting : 1608 },
		'medieval'					: { OrderInterface : 1609,	OrderSorting : 1609 },
		'meg'						: { OrderInterface : 1610,	OrderSorting : 1610 },
		'megapeer'					: { OrderInterface : 1611,	OrderSorting : 1611 },
		'megatron'					: { OrderInterface : 1612,	OrderSorting : 1612 },
		'meguil'					: { OrderInterface : 1613,	OrderSorting : 1613 },
		'megusta'					: { OrderInterface : 1614,	OrderSorting : 1614 },
		'meister'					: { OrderInterface : 1615,	OrderSorting : 1615 },
		'melba'						: { OrderInterface : 1616,	OrderSorting : 1616 },
		'melite'					: { OrderInterface : 1617,	OrderSorting : 1617 },
		'mem'						: { OrderInterface : 1618,	OrderSorting : 1618 },
		'memento'					: { OrderInterface : 1619,	OrderSorting : 1619 },
		'memories'					: { OrderInterface : 1620,	OrderSorting : 1620 },
		'menaceiisociety'			: { OrderInterface : 1621,	OrderSorting : 1621 },
		'meow'						: { OrderInterface : 1622,	OrderSorting : 1622 },
		'metcon'					: { OrderInterface : 1623,	OrderSorting : 1623 },
		'meteam'					: { OrderInterface : 1624,	OrderSorting : 1624 },
		'meth'						: { OrderInterface : 1625,	OrderSorting : 1625 },
		'metis'						: { OrderInterface : 1626,	OrderSorting : 1626 },
		'mf'							: { OrderInterface : 1627,	OrderSorting : 1627 },
		'mfo'						: { OrderInterface : 1628,	OrderSorting : 1628 },
		'mg'							: { OrderInterface : 1629,	OrderSorting : 1629 },
		'mgb'						: { OrderInterface : 1630,	OrderSorting : 1630 },
		'mhd'						: { OrderInterface : 1631,	OrderSorting : 1631 },
		'mhq'						: { OrderInterface : 1632,	OrderSorting : 1632 },
		'mibr'						: { OrderInterface : 1633,	OrderSorting : 1633 },
		'microflix'					: { OrderInterface : 1634,	OrderSorting : 1634 },
		'mighty'					: { OrderInterface : 1635,	OrderSorting : 1635 },
		'mikos'						: { OrderInterface : 1636,	OrderSorting : 1636 },
		'miky'						: { OrderInterface : 1637,	OrderSorting : 1637 },
		'milk'						: { OrderInterface : 1638,	OrderSorting : 1638 },
		'millenium'					: { OrderInterface : 1639,	OrderSorting : 1639 },
		'mind'						: { OrderInterface : 1640,	OrderSorting : 1640 },
		'mindthegap'					: { OrderInterface : 1641,	OrderSorting : 1641 },
		'minihd'					: { OrderInterface : 1642,	OrderSorting : 1642 },
		'mink'						: { OrderInterface : 1643,	OrderSorting : 1643 },
		'mint'						: { OrderInterface : 1644,	OrderSorting : 1644 },
		'minx'						: { OrderInterface : 1645,	OrderSorting : 1645 },
		'mirai'						: { OrderInterface : 1646,	OrderSorting : 1646 },
		'mircrew'					: { OrderInterface : 1647,	OrderSorting : 1647 },
		'mis'						: { OrderInterface : 1648,	OrderSorting : 1648 },
		'misfits'					: { OrderInterface : 1649,	OrderSorting : 1649 },
		'mish'						: { OrderInterface : 1650,	OrderSorting : 1650 },
		'missripz'					: { OrderInterface : 1651,	OrderSorting : 1651 },
		'mixed'						: { OrderInterface : 1652,	OrderSorting : 1652 },
		'mixtv'						: { OrderInterface : 1653,	OrderSorting : 1653 },
		'mkvanime'					: { OrderInterface : 1654,	OrderSorting : 1654 },
		'mkvcage'					: { OrderInterface : 1655,	OrderSorting : 1655 },
		'mkvcinemas'					: { OrderInterface : 1656,	OrderSorting : 1656 },
		'mkvgod'					: { OrderInterface : 1657,	OrderSorting : 1657 },
		'mkvhu'						: { OrderInterface : 1658,	OrderSorting : 1658 },
		'mkvhub'					: { OrderInterface : 1659,	OrderSorting : 1659 },
		'mkvking'					: { OrderInterface : 1660,	OrderSorting : 1660 },
		'mkvtv'						: { OrderInterface : 1661,	OrderSorting : 1661 },
		'mmi'						: { OrderInterface : 1662,	OrderSorting : 1662 },
		'mnhd'						: { OrderInterface : 1663,	OrderSorting : 1663 },
		'mo'							: { OrderInterface : 1664,	OrderSorting : 1664 },
		'moa'						: { OrderInterface : 1665,	OrderSorting : 1665 },
		'mobbit'					: { OrderInterface : 1666,	OrderSorting : 1666 },
		'mobee1'					: { OrderInterface : 1667,	OrderSorting : 1667 },
		'mobidik'					: { OrderInterface : 1668,	OrderSorting : 1668 },
		'modemslayer'				: { OrderInterface : 1669,	OrderSorting : 1669 },
		'moe'						: { OrderInterface : 1670,	OrderSorting : 1670 },
		'moh'						: { OrderInterface : 1671,	OrderSorting : 1671 },
		'mojo'						: { OrderInterface : 1672,	OrderSorting : 1672 },
		'moly'						: { OrderInterface : 1673,	OrderSorting : 1673 },
		'moma'						: { OrderInterface : 1674,	OrderSorting : 1674 },
		'momentum'					: { OrderInterface : 1675,	OrderSorting : 1675 },
		'momo'						: { OrderInterface : 1676,	OrderSorting : 1676 },
		'monk'						: { OrderInterface : 1677,	OrderSorting : 1677 },
		'monkee'					: { OrderInterface : 1678,	OrderSorting : 1678 },
		'monolith'					: { OrderInterface : 1679,	OrderSorting : 1679 },
		'monster'					: { OrderInterface : 1680,	OrderSorting : 1680 },
		'mont'						: { OrderInterface : 1681,	OrderSorting : 1681 },
		'monument'					: { OrderInterface : 1682,	OrderSorting : 1682 },
		'mooi1990'					: { OrderInterface : 1683,	OrderSorting : 1683 },
		'moovee'					: { OrderInterface : 1684,	OrderSorting : 1684 },
		'moreland'					: { OrderInterface : 1685,	OrderSorting : 1685 },
		'mori'						: { OrderInterface : 1686,	OrderSorting : 1686 },
		'moritz'					: { OrderInterface : 1687,	OrderSorting : 1687 },
		'morose'					: { OrderInterface : 1688,	OrderSorting : 1688 },
		'morpheus'					: { OrderInterface : 1689,	OrderSorting : 1689 },
		'morris'					: { OrderInterface : 1690,	OrderSorting : 1690 },
		'mors'						: { OrderInterface : 1691,	OrderSorting : 1691 },
		'mortal'					: { OrderInterface : 1692,	OrderSorting : 1692 },
		'motion'					: { OrderInterface : 1693,	OrderSorting : 1693 },
		'motu'						: { OrderInterface : 1694,	OrderSorting : 1694 },
		'mouseclick'					: { OrderInterface : 1695,	OrderSorting : 1695 },
		'movcr'						: { OrderInterface : 1696,	OrderSorting : 1696 },
		'movee'						: { OrderInterface : 1697,	OrderSorting : 1697 },
		'movieaddicts'				: { OrderInterface : 1698,	OrderSorting : 1698 },
		'movieit'					: { OrderInterface : 1699,	OrderSorting : 1699 },
		'movierush'					: { OrderInterface : 1700,	OrderSorting : 1700 },
		'moviesbyrizzo'				: { OrderInterface : 1701,	OrderSorting : 1701 },
		'moviesevil'					: { OrderInterface : 1702,	OrderSorting : 1702 },
		'moviesfd'					: { OrderInterface : 1703,	OrderSorting : 1703 },
		'moviesmb'					: { OrderInterface : 1704,	OrderSorting : 1704 },
		'moviesmix'					: { OrderInterface : 1705,	OrderSorting : 1705 },
		'moviezworldz'				: { OrderInterface : 1706,	OrderSorting : 1706 },
		'mp4ba'						: { OrderInterface : 1707,	OrderSorting : 1707 },
		'mp4king'					: { OrderInterface : 1708,	OrderSorting : 1708 },
		'mpup'						: { OrderInterface : 1709,	OrderSorting : 1709 },
		'mrc'						: { OrderInterface : 1710,	OrderSorting : 1710 },
		'mrcs'						: { OrderInterface : 1711,	OrderSorting : 1711 },
		'mrgrey'					: { OrderInterface : 1712,	OrderSorting : 1712 },
		'mrhive'					: { OrderInterface : 1713,	OrderSorting : 1713 },
		'mrkeff'					: { OrderInterface : 1714,	OrderSorting : 1714 },
		'mrkickass'					: { OrderInterface : 1715,	OrderSorting : 1715 },
		'mrlore'					: { OrderInterface : 1716,	OrderSorting : 1716 },
		'mrm'						: { OrderInterface : 1717,	OrderSorting : 1717 },
		'mrn'						: { OrderInterface : 1718,	OrderSorting : 1718 },
		'mro'						: { OrderInterface : 1719,	OrderSorting : 1719 },
		'mrs'						: { OrderInterface : 1720,	OrderSorting : 1720 },
		'mrshanku'					: { OrderInterface : 1721,	OrderSorting : 1721 },
		'mrsk'						: { OrderInterface : 1722,	OrderSorting : 1722 },
		'mrstrange'					: { OrderInterface : 1723,	OrderSorting : 1723 },
		'ms'							: { OrderInterface : 1724,	OrderSorting : 1724 },
		'ms89'						: { OrderInterface : 1725,	OrderSorting : 1725 },
		'msd'						: { OrderInterface : 1726,	OrderSorting : 1726 },
		'mse'						: { OrderInterface : 1727,	OrderSorting : 1727 },
		'msr'						: { OrderInterface : 1728,	OrderSorting : 1728 },
		'mss'						: { OrderInterface : 1729,	OrderSorting : 1729 },
		'mt'							: { OrderInterface : 1730,	OrderSorting : 1730 },
		'mtb'						: { OrderInterface : 1731,	OrderSorting : 1731 },
		'mteam'						: { OrderInterface : 1732,	OrderSorting : 1732 },
		'mtk'						: { OrderInterface : 1733,	OrderSorting : 1733 },
		'muhhd'						: { OrderInterface : 1734,	OrderSorting : 1734 },
		'multi4'					: { OrderInterface : 1735,	OrderSorting : 1735 },
		'multiplex'					: { OrderInterface : 1736,	OrderSorting : 1736 },
		'multiply'					: { OrderInterface : 1737,	OrderSorting : 1737 },
		'mulvacoded'					: { OrderInterface : 1738,	OrderSorting : 1738 },
		'murder'					: { OrderInterface : 1739,	OrderSorting : 1739 },
		'musafirboy'					: { OrderInterface : 1740,	OrderSorting : 1740 },
		'musketeers'					: { OrderInterface : 1741,	OrderSorting : 1741 },
		'mutznutz'					: { OrderInterface : 1742,	OrderSorting : 1742 },
		'mvgee'						: { OrderInterface : 1743,	OrderSorting : 1743 },
		'mvgroup'					: { OrderInterface : 1744,	OrderSorting : 1744 },
		'mvn'						: { OrderInterface : 1745,	OrderSorting : 1745 },
		'mvo'						: { OrderInterface : 1746,	OrderSorting : 1746 },
		'mvp'						: { OrderInterface : 1747,	OrderSorting : 1747 },
		'mvs'						: { OrderInterface : 1748,	OrderSorting : 1748 },
		'mw'							: { OrderInterface : 1749,	OrderSorting : 1749 },
		'mxb'						: { OrderInterface : 1750,	OrderSorting : 1750 },
		'mxmg'						: { OrderInterface : 1751,	OrderSorting : 1751 },
		'mys'						: { OrderInterface : 1752,	OrderSorting : 1752 },
		'mysilu'					: { OrderInterface : 1753,	OrderSorting : 1753 },
		'myst'						: { OrderInterface : 1754,	OrderSorting : 1754 },
		'mysterion'					: { OrderInterface : 1755,	OrderSorting : 1755 },
		'mzabi'						: { OrderInterface : 1756,	OrderSorting : 1756 },
		'n0m1'						: { OrderInterface : 1757,	OrderSorting : 1757 },
		'n0ttz'						: { OrderInterface : 1758,	OrderSorting : 1758 },
		'n1c'						: { OrderInterface : 1759,	OrderSorting : 1759 },
		'naa'						: { OrderInterface : 1760,	OrderSorting : 1760 },
		'nada'						: { OrderInterface : 1761,	OrderSorting : 1761 },
		'nahom'						: { OrderInterface : 1762,	OrderSorting : 1762 },
		'naisu'						: { OrderInterface : 1763,	OrderSorting : 1763 },
		'nanban'					: { OrderInterface : 1764,	OrderSorting : 1764 },
		'nano'						: { OrderInterface : 1765,	OrderSorting : 1765 },
		'narb'						: { OrderInterface : 1766,	OrderSorting : 1766 },
		'nassau'					: { OrderInterface : 1767,	OrderSorting : 1767 },
		'nate666'					: { OrderInterface : 1768,	OrderSorting : 1768 },
		'natty'						: { OrderInterface : 1769,	OrderSorting : 1769 },
		'natv'						: { OrderInterface : 1770,	OrderSorting : 1770 },
		'nbdy'						: { OrderInterface : 1771,	OrderSorting : 1771 },
		'nbs'						: { OrderInterface : 1772,	OrderSorting : 1772 },
		'nbt'						: { OrderInterface : 1773,	OrderSorting : 1773 },
		'ncmt'						: { OrderInterface : 1774,	OrderSorting : 1774 },
		'ncpx'						: { OrderInterface : 1775,	OrderSorting : 1775 },
		'ndrt'						: { OrderInterface : 1776,	OrderSorting : 1776 },
		'nedivx'					: { OrderInterface : 1777,	OrderSorting : 1777 },
		'nelly45'					: { OrderInterface : 1778,	OrderSorting : 1778 },
		'nelwyn'					: { OrderInterface : 1779,	OrderSorting : 1779 },
		'nemesis'					: { OrderInterface : 1780,	OrderSorting : 1780 },
		'nemo'						: { OrderInterface : 1781,	OrderSorting : 1781 },
		'neo'						: { OrderInterface : 1782,	OrderSorting : 1782 },
		'neptune'					: { OrderInterface : 1783,	OrderSorting : 1783 },
		'nerdhd'					: { OrderInterface : 1784,	OrderSorting : 1784 },
		'nerds'						: { OrderInterface : 1785,	OrderSorting : 1785 },
		'neroz'						: { OrderInterface : 1786,	OrderSorting : 1786 },
		'nes'						: { OrderInterface : 1787,	OrderSorting : 1787 },
		'nesmeured'					: { OrderInterface : 1788,	OrderSorting : 1788 },
		'neutrino'					: { OrderInterface : 1789,	OrderSorting : 1789 },
		'newartriot'					: { OrderInterface : 1790,	OrderSorting : 1790 },
		'newcomers'					: { OrderInterface : 1791,	OrderSorting : 1791 },
		'newmov'					: { OrderInterface : 1792,	OrderSorting : 1792 },
		'newsource'					: { OrderInterface : 1793,	OrderSorting : 1793 },
		'newstudio'					: { OrderInterface : 1794,	OrderSorting : 1794 },
		'newteam'					: { OrderInterface : 1795,	OrderSorting : 1795 },
		'nextbit'					: { OrderInterface : 1796,	OrderSorting : 1796 },
		'nextgen'					: { OrderInterface : 1797,	OrderSorting : 1797 },
		'nezu'						: { OrderInterface : 1798,	OrderSorting : 1798 },
		'nfhd'						: { OrderInterface : 1799,	OrderSorting : 1799 },
		'nflx'						: { OrderInterface : 1800,	OrderSorting : 1800 },
		'nfofix'					: { OrderInterface : 1801,	OrderSorting : 1801 },
		'nfrip'						: { OrderInterface : 1802,	OrderSorting : 1802 },
		'ngb'						: { OrderInterface : 1803,	OrderSorting : 1803 },
		'nge'						: { OrderInterface : 1804,	OrderSorting : 1804 },
		'ngp'						: { OrderInterface : 1805,	OrderSorting : 1805 },
		'ngr'						: { OrderInterface : 1806,	OrderSorting : 1806 },
		'ngserier'					: { OrderInterface : 1807,	OrderSorting : 1807 },
		'nhanc3'					: { OrderInterface : 1808,	OrderSorting : 1808 },
		'nhd'						: { OrderInterface : 1809,	OrderSorting : 1809 },
		'nick'						: { OrderInterface : 1810,	OrderSorting : 1810 },
		'nickarad'					: { OrderInterface : 1811,	OrderSorting : 1811 },
		'nightripper'				: { OrderInterface : 1812,	OrderSorting : 1812 },
		'nik'						: { OrderInterface : 1813,	OrderSorting : 1813 },
		'nikonxp'					: { OrderInterface : 1814,	OrderSorting : 1814 },
		'nikoo'						: { OrderInterface : 1815,	OrderSorting : 1815 },
		'nikt0'						: { OrderInterface : 1816,	OrderSorting : 1816 },
		'nile'						: { OrderInterface : 1817,	OrderSorting : 1817 },
		'nima4k'					: { OrderInterface : 1818,	OrderSorting : 1818 },
		'nip'						: { OrderInterface : 1819,	OrderSorting : 1819 },
		'nitro'						: { OrderInterface : 1820,	OrderSorting : 1820 },
		'nitroteam'					: { OrderInterface : 1821,	OrderSorting : 1821 },
		'nix'						: { OrderInterface : 1822,	OrderSorting : 1822 },
		'nixon'						: { OrderInterface : 1823,	OrderSorting : 1823 },
		'nixx'						: { OrderInterface : 1824,	OrderSorting : 1824 },
		'nks'						: { OrderInterface : 1825,	OrderSorting : 1825 },
		'nlc'						: { OrderInterface : 1826,	OrderSorting : 1826 },
		'nlibra'					: { OrderInterface : 1827,	OrderSorting : 1827 },
		'nlt'						: { OrderInterface : 1828,	OrderSorting : 1828 },
		'nmd'						: { OrderInterface : 1829,	OrderSorting : 1829 },
		'nme'						: { OrderInterface : 1830,	OrderSorting : 1830 },
		'nmr'						: { OrderInterface : 1831,	OrderSorting : 1831 },
		'nnm'						: { OrderInterface : 1832,	OrderSorting : 1832 },
		'nnmclub'					: { OrderInterface : 1833,	OrderSorting : 1833 },
		'nnr'						: { OrderInterface : 1834,	OrderSorting : 1834 },
		'no1cares'					: { OrderInterface : 1835,	OrderSorting : 1835 },
		'no1knows'					: { OrderInterface : 1836,	OrderSorting : 1836 },
		'nodlabs'					: { OrderInterface : 1837,	OrderSorting : 1837 },
		'nogroup'					: { OrderInterface : 1838,	OrderSorting : 1838 },
		'nogrp'						: { OrderInterface : 1839,	OrderSorting : 1839 },
		'nohate'					: { OrderInterface : 1840,	OrderSorting : 1840 },
		'noir'						: { OrderInterface : 1841,	OrderSorting : 1841 },
		'nok'						: { OrderInterface : 1842,	OrderSorting : 1842 },
		'noma'						: { OrderInterface : 1843,	OrderSorting : 1843 },
		'nomore'					: { OrderInterface : 1844,	OrderSorting : 1844 },
		'nondrm'					: { OrderInterface : 1845,	OrderSorting : 1845 },
		'noobless'					: { OrderInterface : 1846,	OrderSorting : 1846 },
		'noobsubs'					: { OrderInterface : 1847,	OrderSorting : 1847 },
		'norars'					: { OrderInterface : 1848,	OrderSorting : 1848 },
		'nordichd'					: { OrderInterface : 1849,	OrderSorting : 1849 },
		'noretail'					: { OrderInterface : 1850,	OrderSorting : 1850 },
		'nortv'						: { OrderInterface : 1851,	OrderSorting : 1851 },
		'noscreens'					: { OrderInterface : 1852,	OrderSorting : 1852 },
		'nosegment'					: { OrderInterface : 1853,	OrderSorting : 1853 },
		'nosivid'					: { OrderInterface : 1854,	OrderSorting : 1854 },
		'notag'						: { OrderInterface : 1855,	OrderSorting : 1855 },
		'notv'						: { OrderInterface : 1856,	OrderSorting : 1856 },
		'nova'						: { OrderInterface : 1857,	OrderSorting : 1857 },
		'novalan'					: { OrderInterface : 1858,	OrderSorting : 1858 },
		'novarip'					: { OrderInterface : 1859,	OrderSorting : 1859 },
		'novo'						: { OrderInterface : 1860,	OrderSorting : 1860 },
		'nowinhd'					: { OrderInterface : 1861,	OrderSorting : 1861 },
		'nox'						: { OrderInterface : 1862,	OrderSorting : 1862 },
		'npms'						: { OrderInterface : 1863,	OrderSorting : 1863 },
		'npw'						: { OrderInterface : 1864,	OrderSorting : 1864 },
		'nsn'						: { OrderInterface : 1865,	OrderSorting : 1865 },
		'nt'							: { OrderInterface : 1866,	OrderSorting : 1866 },
		'ntb'						: { OrderInterface : 1867,	OrderSorting : 1867 },
		'ntg'						: { OrderInterface : 1868,	OrderSorting : 1868 },
		'ntropic'					: { OrderInterface : 1869,	OrderSorting : 1869 },
		'numy'						: { OrderInterface : 1870,	OrderSorting : 1870 },
		'nuxx'						: { OrderInterface : 1871,	OrderSorting : 1871 },
		'nva'						: { OrderInterface : 1872,	OrderSorting : 1872 },
		'nvee'						: { OrderInterface : 1873,	OrderSorting : 1873 },
		'nvm'						: { OrderInterface : 1874,	OrderSorting : 1874 },
		'nwb'						: { OrderInterface : 1875,	OrderSorting : 1875 },
		'nwo'						: { OrderInterface : 1876,	OrderSorting : 1876 },
		'nws'						: { OrderInterface : 1877,	OrderSorting : 1877 },
		'ny'							: { OrderInterface : 1878,	OrderSorting : 1878 },
		'ny2'						: { OrderInterface : 1879,	OrderSorting : 1879 },
		'nya'						: { OrderInterface : 1880,	OrderSorting : 1880 },
		'nydic'						: { OrderInterface : 1881,	OrderSorting : 1881 },
		'nyh'						: { OrderInterface : 1882,	OrderSorting : 1882 },
		'nys'						: { OrderInterface : 1883,	OrderSorting : 1883 },
		'nyu'						: { OrderInterface : 1884,	OrderSorting : 1884 },
		'o0o'						: { OrderInterface : 1885,	OrderSorting : 1885 },
		'o2stk'						: { OrderInterface : 1886,	OrderSorting : 1886 },
		'o69'						: { OrderInterface : 1887,	OrderSorting : 1887 },
		'object'					: { OrderInterface : 1888,	OrderSorting : 1888 },
		'occor'						: { OrderInterface : 1889,	OrderSorting : 1889 },
		'octopus'					: { OrderInterface : 1890,	OrderSorting : 1890 },
		'ods'						: { OrderInterface : 1891,	OrderSorting : 1891 },
		'oem'						: { OrderInterface : 1892,	OrderSorting : 1892 },
		'oem1080'					: { OrderInterface : 1893,	OrderSorting : 1893 },
		'oft'						: { OrderInterface : 1894,	OrderSorting : 1894 },
		'ohd'						: { OrderInterface : 1895,	OrderSorting : 1895 },
		'oj'							: { OrderInterface : 1896,	OrderSorting : 1896 },
		'oki'						: { OrderInterface : 1897,	OrderSorting : 1897 },
		'okq'						: { OrderInterface : 1898,	OrderSorting : 1898 },
		'oldseasons'					: { OrderInterface : 1899,	OrderSorting : 1899 },
		'oldsman'					: { OrderInterface : 1900,	OrderSorting : 1900 },
		'ollandgroup'				: { OrderInterface : 1901,	OrderSorting : 1901 },
		'oma'						: { OrderInterface : 1902,	OrderSorting : 1902 },
		'omega'						: { OrderInterface : 1903,	OrderSorting : 1903 },
		'omer'						: { OrderInterface : 1904,	OrderSorting : 1904 },
		'omertahd'					: { OrderInterface : 1905,	OrderSorting : 1905 },
		'omfug'						: { OrderInterface : 1906,	OrderSorting : 1906 },
		'omgtv'						: { OrderInterface : 1907,	OrderSorting : 1907 },
		'omicron'					: { OrderInterface : 1908,	OrderSorting : 1908 },
		'omifast'					: { OrderInterface : 1909,	OrderSorting : 1909 },
		'omikron'					: { OrderInterface : 1910,	OrderSorting : 1910 },
		'omnic'						: { OrderInterface : 1911,	OrderSorting : 1911 },
		'omskbird'					: { OrderInterface : 1912,	OrderSorting : 1912 },
		'ons'						: { OrderInterface : 1913,	OrderSorting : 1913 },
		'ontherun'					: { OrderInterface : 1914,	OrderSorting : 1914 },
		'oo'							: { OrderInterface : 1915,	OrderSorting : 1915 },
		'oom'						: { OrderInterface : 1916,	OrderSorting : 1916 },
		'oosh'						: { OrderInterface : 1917,	OrderSorting : 1917 },
		'oped'						: { OrderInterface : 1918,	OrderSorting : 1918 },
		'opentsubasa'				: { OrderInterface : 1919,	OrderSorting : 1919 },
		'opt'						: { OrderInterface : 1920,	OrderSorting : 1920 },
		'optic'						: { OrderInterface : 1921,	OrderSorting : 1921 },
		'orc'						: { OrderInterface : 1922,	OrderSorting : 1922 },
		'orca88'					: { OrderInterface : 1923,	OrderSorting : 1923 },
		'order'						: { OrderInterface : 1924,	OrderSorting : 1924 },
		'orenji'					: { OrderInterface : 1925,	OrderSorting : 1925 },
		'organic'					: { OrderInterface : 1926,	OrderSorting : 1926 },
		'orgo'						: { OrderInterface : 1927,	OrderSorting : 1927 },
		'origen'					: { OrderInterface : 1928,	OrderSorting : 1928 },
		'orphan'					: { OrderInterface : 1929,	OrderSorting : 1929 },
		'orpheus'					: { OrderInterface : 1930,	OrderSorting : 1930 },
		'osiris'					: { OrderInterface : 1931,	OrderSorting : 1931 },
		'ositv'						: { OrderInterface : 1932,	OrderSorting : 1932 },
		'ott'						: { OrderInterface : 1933,	OrderSorting : 1933 },
		'otv'						: { OrderInterface : 1934,	OrderSorting : 1934 },
		'ouija'						: { OrderInterface : 1935,	OrderSorting : 1935 },
		'ourbits'					: { OrderInterface : 1936,	OrderSorting : 1936 },
		'oursuperpilaencode'			: { OrderInterface : 1937,	OrderSorting : 1937 },
		'outbreak'					: { OrderInterface : 1938,	OrderSorting : 1938 },
		'outdated'					: { OrderInterface : 1939,	OrderSorting : 1939 },
		'ouzo'						: { OrderInterface : 1940,	OrderSorting : 1940 },
		'ov3rl1f3'					: { OrderInterface : 1941,	OrderSorting : 1941 },
		'ov3rload'					: { OrderInterface : 1942,	OrderSorting : 1942 },
		'overtime'					: { OrderInterface : 1943,	OrderSorting : 1943 },
		'oyhd'						: { OrderInterface : 1944,	OrderSorting : 1944 },
		'ozlem'						: { OrderInterface : 1945,	OrderSorting : 1945 },
		'ozzy1'						: { OrderInterface : 1946,	OrderSorting : 1946 },
		'p0618'						: { OrderInterface : 1947,	OrderSorting : 1947 },
		'p0w4'						: { OrderInterface : 1948,	OrderSorting : 1948 },
		'p0w4dvd'					: { OrderInterface : 1949,	OrderSorting : 1949 },
		'p2p'						: { OrderInterface : 1950,	OrderSorting : 1950 },
		'p2pdl'						: { OrderInterface : 1951,	OrderSorting : 1951 },
		'p2u'						: { OrderInterface : 1952,	OrderSorting : 1952 },
		'p4dge'						: { OrderInterface : 1953,	OrderSorting : 1953 },
		'pa'							: { OrderInterface : 1954,	OrderSorting : 1954 },
		'paai'						: { OrderInterface : 1955,	OrderSorting : 1955 },
		'paddo'						: { OrderInterface : 1956,	OrderSorting : 1956 },
		'pahe'						: { OrderInterface : 1957,	OrderSorting : 1957 },
		'pahein'					: { OrderInterface : 1958,	OrderSorting : 1958 },
		'paleale'					: { OrderInterface : 1959,	OrderSorting : 1959 },
		'panda'						: { OrderInterface : 1960,	OrderSorting : 1960 },
		'pandemonium'				: { OrderInterface : 1961,	OrderSorting : 1961 },
		'pankhabd'					: { OrderInterface : 1962,	OrderSorting : 1962 },
		'paradox'					: { OrderInterface : 1963,	OrderSorting : 1963 },
		'paranoid06'					: { OrderInterface : 1964,	OrderSorting : 1964 },
		'particle'					: { OrderInterface : 1965,	OrderSorting : 1965 },
		'partyboy'					: { OrderInterface : 1966,	OrderSorting : 1966 },
		'pas'						: { OrderInterface : 1967,	OrderSorting : 1967 },
		'pasha'						: { OrderInterface : 1968,	OrderSorting : 1968 },
		'paso77'					: { OrderInterface : 1969,	OrderSorting : 1969 },
		'pat'						: { OrderInterface : 1970,	OrderSorting : 1970 },
		'pate'						: { OrderInterface : 1971,	OrderSorting : 1971 },
		'patrol'					: { OrderInterface : 1972,	OrderSorting : 1972 },
		'paulista'					: { OrderInterface : 1973,	OrderSorting : 1973 },
		'pb'							: { OrderInterface : 1974,	OrderSorting : 1974 },
		'pbk'						: { OrderInterface : 1975,	OrderSorting : 1975 },
		'pc'							: { OrderInterface : 1976,	OrderSorting : 1976 },
		'pch'						: { OrderInterface : 1977,	OrderSorting : 1977 },
		'pcroland'					: { OrderInterface : 1978,	OrderSorting : 1978 },
		'pcsyndicate'				: { OrderInterface : 1979,	OrderSorting : 1979 },
		'pctnew'					: { OrderInterface : 1980,	OrderSorting : 1980 },
		'peculate'					: { OrderInterface : 1981,	OrderSorting : 1981 },
		'peewee'					: { OrderInterface : 1982,	OrderSorting : 1982 },
		'peppe'						: { OrderInterface : 1983,	OrderSorting : 1983 },
		'perfectionhd'				: { OrderInterface : 1984,	OrderSorting : 1984 },
		'peruguy'					: { OrderInterface : 1985,	OrderSorting : 1985 },
		'petrified'					: { OrderInterface : 1986,	OrderSorting : 1986 },
		'pfa'						: { OrderInterface : 1987,	OrderSorting : 1987 },
		'phantom'					: { OrderInterface : 1988,	OrderSorting : 1988 },
		'phase'						: { OrderInterface : 1989,	OrderSorting : 1989 },
		'phd'						: { OrderInterface : 1990,	OrderSorting : 1990 },
		'phdteam'					: { OrderInterface : 1991,	OrderSorting : 1991 },
		'phenomenal'					: { OrderInterface : 1992,	OrderSorting : 1992 },
		'phmhd'						: { OrderInterface : 1993,	OrderSorting : 1993 },
		'phobos'					: { OrderInterface : 1994,	OrderSorting : 1994 },
		'phocis'					: { OrderInterface : 1995,	OrderSorting : 1995 },
		'phoenix'					: { OrderInterface : 1996,	OrderSorting : 1996 },
		'phoenixrg'					: { OrderInterface : 1997,	OrderSorting : 1997 },
		'phoque'					: { OrderInterface : 1998,	OrderSorting : 1998 },
		'phr0sty'					: { OrderInterface : 1999,	OrderSorting : 1999 },
		'phunpsyz'					: { OrderInterface : 2000,	OrderSorting : 2000 },
		'pia'						: { OrderInterface : 2001,	OrderSorting : 2001 },
		'piephd'					: { OrderInterface : 2002,	OrderSorting : 2002 },
		'pignus'					: { OrderInterface : 2003,	OrderSorting : 2003 },
		'pikachu'					: { OrderInterface : 2004,	OrderSorting : 2004 },
		'pikanet128'					: { OrderInterface : 2005,	OrderSorting : 2005 },
		'pilaf'						: { OrderInterface : 2006,	OrderSorting : 2006 },
		'pimp'						: { OrderInterface : 2007,	OrderSorting : 2007 },
		'pimp4003'					: { OrderInterface : 2008,	OrderSorting : 2008 },
		'pimprg'					: { OrderInterface : 2009,	OrderSorting : 2009 },
		'pims'						: { OrderInterface : 2010,	OrderSorting : 2010 },
		'ping'						: { OrderInterface : 2011,	OrderSorting : 2011 },
		'pinkpanters'				: { OrderInterface : 2012,	OrderSorting : 2012 },
		'pioneer'					: { OrderInterface : 2013,	OrderSorting : 2013 },
		'pipick'					: { OrderInterface : 2014,	OrderSorting : 2014 },
		'pir8'						: { OrderInterface : 2015,	OrderSorting : 2015 },
		'piratemkv'					: { OrderInterface : 2016,	OrderSorting : 2016 },
		'pitu'						: { OrderInterface : 2017,	OrderSorting : 2017 },
		'pitufo180'					: { OrderInterface : 2018,	OrderSorting : 2018 },
		'pl3x'						: { OrderInterface : 2019,	OrderSorting : 2019 },
		'plaid'						: { OrderInterface : 2020,	OrderSorting : 2020 },
		'playbd'					: { OrderInterface : 2021,	OrderSorting : 2021 },
		'playhd'					: { OrderInterface : 2022,	OrderSorting : 2022 },
		'playnow'					: { OrderInterface : 2023,	OrderSorting : 2023 },
		'playready'					: { OrderInterface : 2024,	OrderSorting : 2024 },
		'playsd'					: { OrderInterface : 2025,	OrderSorting : 2025 },
		'playtv'					: { OrderInterface : 2026,	OrderSorting : 2026 },
		'playweb'					: { OrderInterface : 2027,	OrderSorting : 2027 },
		'playxd'					: { OrderInterface : 2028,	OrderSorting : 2028 },
		'pluto'						: { OrderInterface : 2029,	OrderSorting : 2029 },
		'plutonium'					: { OrderInterface : 2030,	OrderSorting : 2030 },
		'plzproper'					: { OrderInterface : 2031,	OrderSorting : 2031 },
		'pm'							: { OrderInterface : 2032,	OrderSorting : 2032 },
		'pmhd'						: { OrderInterface : 2033,	OrderSorting : 2033 },
		'pmp'						: { OrderInterface : 2034,	OrderSorting : 2034 },
		'pod'						: { OrderInterface : 2035,	OrderSorting : 2035 },
		'podo'						: { OrderInterface : 2036,	OrderSorting : 2036 },
		'poe'						: { OrderInterface : 2037,	OrderSorting : 2037 },
		'poiasd'					: { OrderInterface : 2038,	OrderSorting : 2038 },
		'poke'						: { OrderInterface : 2039,	OrderSorting : 2039 },
		'polar'						: { OrderInterface : 2040,	OrderSorting : 2040 },
		'poolla'					: { OrderInterface : 2041,	OrderSorting : 2041 },
		'poop'						: { OrderInterface : 2042,	OrderSorting : 2042 },
		'pop'						: { OrderInterface : 2043,	OrderSorting : 2043 },
		'pophd'						: { OrderInterface : 2044,	OrderSorting : 2044 },
		'portablius'					: { OrderInterface : 2045,	OrderSorting : 2045 },
		'portos'					: { OrderInterface : 2046,	OrderSorting : 2046 },
		'positive'					: { OrderInterface : 2047,	OrderSorting : 2047 },
		'postx'						: { OrderInterface : 2048,	OrderSorting : 2048 },
		'pot'						: { OrderInterface : 2049,	OrderSorting : 2049 },
		'pp'							: { OrderInterface : 2050,	OrderSorting : 2050 },
		'ppb'						: { OrderInterface : 2051,	OrderSorting : 2051 },
		'ppq'						: { OrderInterface : 2052,	OrderSorting : 2052 },
		'prd'						: { OrderInterface : 2053,	OrderSorting : 2053 },
		'precious'					: { OrderInterface : 2054,	OrderSorting : 2054 },
		'precursor'					: { OrderInterface : 2055,	OrderSorting : 2055 },
		'pretail'					: { OrderInterface : 2056,	OrderSorting : 2056 },
		'preums'					: { OrderInterface : 2057,	OrderSorting : 2057 },
		'prevail'					: { OrderInterface : 2058,	OrderSorting : 2058 },
		'primalhd'					: { OrderInterface : 2059,	OrderSorting : 2059 },
		'prime'						: { OrderInterface : 2060,	OrderSorting : 2060 },
		'primehd'					: { OrderInterface : 2061,	OrderSorting : 2061 },
		'prince'					: { OrderInterface : 2062,	OrderSorting : 2062 },
		'pristine'					: { OrderInterface : 2063,	OrderSorting : 2063 },
		'prithwi'					: { OrderInterface : 2064,	OrderSorting : 2064 },
		'privatehd'					: { OrderInterface : 2065,	OrderSorting : 2065 },
		'prod'						: { OrderInterface : 2066,	OrderSorting : 2066 },
		'prodji'					: { OrderInterface : 2067,	OrderSorting : 2067 },
		'prof'						: { OrderInterface : 2068,	OrderSorting : 2068 },
		'progress'					: { OrderInterface : 2069,	OrderSorting : 2069 },
		'promise'					: { OrderInterface : 2070,	OrderSorting : 2070 },
		'prophets'					: { OrderInterface : 2071,	OrderSorting : 2071 },
		'propl'						: { OrderInterface : 2072,	OrderSorting : 2072 },
		'propltv'					: { OrderInterface : 2073,	OrderSorting : 2073 },
		'proxy'						: { OrderInterface : 2074,	OrderSorting : 2074 },
		'ps3team'					: { OrderInterface : 2075,	OrderSorting : 2075 },
		'psa'						: { OrderInterface : 2076,	OrderSorting : 2076 },
		'pseudo'					: { OrderInterface : 2077,	OrderSorting : 2077 },
		'psig'						: { OrderInterface : 2078,	OrderSorting : 2078 },
		'psix'						: { OrderInterface : 2079,	OrderSorting : 2079 },
		'pso'						: { OrderInterface : 2080,	OrderSorting : 2080 },
		'psv'						: { OrderInterface : 2081,	OrderSorting : 2081 },
		'psyc'						: { OrderInterface : 2082,	OrderSorting : 2082 },
		'psychd'					: { OrderInterface : 2083,	OrderSorting : 2083 },
		'psycho791'					: { OrderInterface : 2084,	OrderSorting : 2084 },
		'psypher'					: { OrderInterface : 2085,	OrderSorting : 2085 },
		'pta'						: { OrderInterface : 2086,	OrderSorting : 2086 },
		'pter'						: { OrderInterface : 2087,	OrderSorting : 2087 },
		'ptnk'						: { OrderInterface : 2088,	OrderSorting : 2088 },
		'ptp'						: { OrderInterface : 2089,	OrderSorting : 2089 },
		'ptpower'					: { OrderInterface : 2090,	OrderSorting : 2090 },
		'pts'						: { OrderInterface : 2091,	OrderSorting : 2091 },
		'publichd'					: { OrderInterface : 2092,	OrderSorting : 2092 },
		'pudding'					: { OrderInterface : 2093,	OrderSorting : 2093 },
		'pukka'						: { OrderInterface : 2094,	OrderSorting : 2094 },
		'punch'						: { OrderInterface : 2095,	OrderSorting : 2095 },
		'punisher694'				: { OrderInterface : 2096,	OrderSorting : 2096 },
		'pure'						: { OrderInterface : 2097,	OrderSorting : 2097 },
		'pussyfoot'					: { OrderInterface : 2098,	OrderSorting : 2098 },
		'puzzle'					: { OrderInterface : 2099,	OrderSorting : 2099 },
		'pvr'						: { OrderInterface : 2100,	OrderSorting : 2100 },
		'pwe'						: { OrderInterface : 2101,	OrderSorting : 2101 },
		'pxhd'						: { OrderInterface : 2102,	OrderSorting : 2102 },
		'pyc'						: { OrderInterface : 2103,	OrderSorting : 2103 },
		'pze'						: { OrderInterface : 2104,	OrderSorting : 2104 },
		'pzk'						: { OrderInterface : 2105,	OrderSorting : 2105 },
		'qcf'						: { OrderInterface : 2106,	OrderSorting : 2106 },
		'qix'						: { OrderInterface : 2107,	OrderSorting : 2107 },
		'qman'						: { OrderInterface : 2108,	OrderSorting : 2108 },
		'qmax'						: { OrderInterface : 2109,	OrderSorting : 2109 },
		'qom'						: { OrderInterface : 2110,	OrderSorting : 2110 },
		'qoq'						: { OrderInterface : 2111,	OrderSorting : 2111 },
		'qpel'						: { OrderInterface : 2112,	OrderSorting : 2112 },
		'qqss44'					: { OrderInterface : 2113,	OrderSorting : 2113 },
		'qrc'						: { OrderInterface : 2114,	OrderSorting : 2114 },
		'qrips'						: { OrderInterface : 2115,	OrderSorting : 2115 },
		'qrus'						: { OrderInterface : 2116,	OrderSorting : 2116 },
		'qsp'						: { OrderInterface : 2117,	OrderSorting : 2117 },
		'qtz'						: { OrderInterface : 2118,	OrderSorting : 2118 },
		'queens'					: { OrderInterface : 2119,	OrderSorting : 2119 },
		'qui'						: { OrderInterface : 2120,	OrderSorting : 2120 },
		'qxr'						: { OrderInterface : 2121,	OrderSorting : 2121 },
		'r00t'						: { OrderInterface : 2122,	OrderSorting : 2122 },
		'r0b0t'						: { OrderInterface : 2123,	OrderSorting : 2123 },
		'r0cked'					: { OrderInterface : 2124,	OrderSorting : 2124 },
		'r10'						: { OrderInterface : 2125,	OrderSorting : 2125 },
		'r2d2'						: { OrderInterface : 2126,	OrderSorting : 2126 },
		'radius'					: { OrderInterface : 2127,	OrderSorting : 2127 },
		'rady'						: { OrderInterface : 2128,	OrderSorting : 2128 },
		'raindeer'					: { OrderInterface : 2129,	OrderSorting : 2129 },
		'rakuv02'					: { OrderInterface : 2130,	OrderSorting : 2130 },
		'rakuvfinhel'				: { OrderInterface : 2131,	OrderSorting : 2131 },
		'randi'						: { OrderInterface : 2132,	OrderSorting : 2132 },
		'ranvijay'					: { OrderInterface : 2133,	OrderSorting : 2133 },
		'raoul'						: { OrderInterface : 2134,	OrderSorting : 2134 },
		'rap'						: { OrderInterface : 2135,	OrderSorting : 2135 },
		'rapidcows'					: { OrderInterface : 2136,	OrderSorting : 2136 },
		'rapta'						: { OrderInterface : 2137,	OrderSorting : 2137 },
		'rarbg'						: { OrderInterface : 2138,	OrderSorting : 2138 },
		'rartv'						: { OrderInterface : 2139,	OrderSorting : 2139 },
		'ras'						: { OrderInterface : 2140,	OrderSorting : 2140 },
		'rastafariantargaryen'		: { OrderInterface : 2141,	OrderSorting : 2141 },
		'rax'						: { OrderInterface : 2142,	OrderSorting : 2142 },
		'rb'							: { OrderInterface : 2143,	OrderSorting : 2143 },
		'rb58'						: { OrderInterface : 2144,	OrderSorting : 2144 },
		'rbb'						: { OrderInterface : 2145,	OrderSorting : 2145 },
		'rbg'						: { OrderInterface : 2146,	OrderSorting : 2146 },
		'rbt'						: { OrderInterface : 2147,	OrderSorting : 2147 },
		'rc'							: { OrderInterface : 2148,	OrderSorting : 2148 },
		'rcdivx'					: { OrderInterface : 2149,	OrderSorting : 2149 },
		'rcvr'						: { OrderInterface : 2150,	OrderSorting : 2150 },
		'rd'							: { OrderInterface : 2151,	OrderSorting : 2151 },
		'rdk123'					: { OrderInterface : 2152,	OrderSorting : 2152 },
		'rdlinks'					: { OrderInterface : 2153,	OrderSorting : 2153 },
		'rdvas'						: { OrderInterface : 2154,	OrderSorting : 2154 },
		'rdx'						: { OrderInterface : 2155,	OrderSorting : 2155 },
		'reactor'					: { OrderInterface : 2156,	OrderSorting : 2156 },
		'reaktor'					: { OrderInterface : 2157,	OrderSorting : 2157 },
		'realdmdj'					: { OrderInterface : 2158,	OrderSorting : 2158 },
		'reaper'					: { OrderInterface : 2159,	OrderSorting : 2159 },
		'reaperza'					: { OrderInterface : 2160,	OrderSorting : 2160 },
		'reavers'					: { OrderInterface : 2161,	OrderSorting : 2161 },
		'rebels'					: { OrderInterface : 2162,	OrderSorting : 2162 },
		'rebelsd'					: { OrderInterface : 2163,	OrderSorting : 2163 },
		'redblade'					: { OrderInterface : 2164,	OrderSorting : 2164 },
		'redeamer'					: { OrderInterface : 2165,	OrderSorting : 2165 },
		'redone'					: { OrderInterface : 2166,	OrderSorting : 2166 },
		'reel'						: { OrderInterface : 2167,	OrderSorting : 2167 },
		'refined'					: { OrderInterface : 2168,	OrderSorting : 2168 },
		'regelrecht'					: { OrderInterface : 2169,	OrderSorting : 2169 },
		'regret'					: { OrderInterface : 2170,	OrderSorting : 2170 },
		'reign'						: { OrderInterface : 2171,	OrderSorting : 2171 },
		'rekode'					: { OrderInterface : 2172,	OrderSorting : 2172 },
		'releaselounge'				: { OrderInterface : 2173,	OrderSorting : 2173 },
		'relentless'					: { OrderInterface : 2174,	OrderSorting : 2174 },
		'religious'					: { OrderInterface : 2175,	OrderSorting : 2175 },
		'reloaded'					: { OrderInterface : 2176,	OrderSorting : 2176 },
		'rem'						: { OrderInterface : 2177,	OrderSorting : 2177 },
		'remake'					: { OrderInterface : 2178,	OrderSorting : 2178 },
		'remarkable'					: { OrderInterface : 2179,	OrderSorting : 2179 },
		'remax'						: { OrderInterface : 2180,	OrderSorting : 2180 },
		'renegades'					: { OrderInterface : 2181,	OrderSorting : 2181 },
		'replica'					: { OrderInterface : 2182,	OrderSorting : 2182 },
		'reptile'					: { OrderInterface : 2183,	OrderSorting : 2183 },
		'republic'					: { OrderInterface : 2184,	OrderSorting : 2184 },
		'reserved'					: { OrderInterface : 2185,	OrderSorting : 2185 },
		'resistance'					: { OrderInterface : 2186,	OrderSorting : 2186 },
		'resurrection'				: { OrderInterface : 2187,	OrderSorting : 2187 },
		'retreat'					: { OrderInterface : 2188,	OrderSorting : 2188 },
		'retro'						: { OrderInterface : 2189,	OrderSorting : 2189 },
		'rets'						: { OrderInterface : 2190,	OrderSorting : 2190 },
		'rev'						: { OrderInterface : 2191,	OrderSorting : 2191 },
		'reveille'					: { OrderInterface : 2192,	OrderSorting : 2192 },
		'revittony'					: { OrderInterface : 2193,	OrderSorting : 2193 },
		'revteam'					: { OrderInterface : 2194,	OrderSorting : 2194 },
		'reward'					: { OrderInterface : 2195,	OrderSorting : 2195 },
		'rg'							: { OrderInterface : 2196,	OrderSorting : 2196 },
		'rh'							: { OrderInterface : 2197,	OrderSorting : 2197 },
		'rhd'						: { OrderInterface : 2198,	OrderSorting : 2198 },
		'rhood'						: { OrderInterface : 2199,	OrderSorting : 2199 },
		'rias'						: { OrderInterface : 2200,	OrderSorting : 2200 },
		'rick'						: { OrderInterface : 2201,	OrderSorting : 2201 },
		'ricky'						: { OrderInterface : 2202,	OrderSorting : 2202 },
		'riddlera'					: { OrderInterface : 2203,	OrderSorting : 2203 },
		'rifftrax'					: { OrderInterface : 2204,	OrderSorting : 2204 },
		'rig'						: { OrderInterface : 2205,	OrderSorting : 2205 },
		'rightsize'					: { OrderInterface : 2206,	OrderSorting : 2206 },
		'ripley'					: { OrderInterface : 2207,	OrderSorting : 2207 },
		'riprg'						: { OrderInterface : 2208,	OrderSorting : 2208 },
		'rishibhai'					: { OrderInterface : 2209,	OrderSorting : 2209 },
		'risingsun'					: { OrderInterface : 2210,	OrderSorting : 2210 },
		'ritalin'					: { OrderInterface : 2211,	OrderSorting : 2211 },
		'ritalix'					: { OrderInterface : 2212,	OrderSorting : 2212 },
		'river'						: { OrderInterface : 2213,	OrderSorting : 2213 },
		'rj'							: { OrderInterface : 2214,	OrderSorting : 2214 },
		'rjaa'						: { OrderInterface : 2215,	OrderSorting : 2215 },
		'rknor'						: { OrderInterface : 2216,	OrderSorting : 2216 },
		'rknorloading'				: { OrderInterface : 2217,	OrderSorting : 2217 },
		'rkrips'					: { OrderInterface : 2218,	OrderSorting : 2218 },
		'rlf'						: { OrderInterface : 2219,	OrderSorting : 2219 },
		'rmp4l'						: { OrderInterface : 2220,	OrderSorting : 2220 },
		'rms'						: { OrderInterface : 2221,	OrderSorting : 2221 },
		'rmt'						: { OrderInterface : 2222,	OrderSorting : 2222 },
		'rmteam'					: { OrderInterface : 2223,	OrderSorting : 2223 },
		'rmx'						: { OrderInterface : 2224,	OrderSorting : 2224 },
		'rnc'						: { OrderInterface : 2225,	OrderSorting : 2225 },
		'rob'						: { OrderInterface : 2226,	OrderSorting : 2226 },
		'robin'						: { OrderInterface : 2227,	OrderSorting : 2227 },
		'robo'						: { OrderInterface : 2228,	OrderSorting : 2228 },
		'robots'					: { OrderInterface : 2229,	OrderSorting : 2229 },
		'roccat'					: { OrderInterface : 2230,	OrderSorting : 2230 },
		'rockblueladyrg'			: { OrderInterface : 2231,	OrderSorting : 2231 },
		'rockefeller'				: { OrderInterface : 2232,	OrderSorting : 2232 },
		'rockriot'					: { OrderInterface : 2233,	OrderSorting : 2233 },
		'rofl'						: { OrderInterface : 2234,	OrderSorting : 2234 },
		'roflcopter2110'			: { OrderInterface : 2235,	OrderSorting : 2235 },
		'rog'						: { OrderInterface : 2236,	OrderSorting : 2236 },
		'roger'						: { OrderInterface : 2237,	OrderSorting : 2237 },
		'roimez'					: { OrderInterface : 2238,	OrderSorting : 2238 },
		'roland'					: { OrderInterface : 2239,	OrderSorting : 2239 },
		'ronin'						: { OrderInterface : 2240,	OrderSorting : 2240 },
		'roor'						: { OrderInterface : 2241,	OrderSorting : 2241 },
		'rough'						: { OrderInterface : 2242,	OrderSorting : 2242 },
		'rovers'					: { OrderInterface : 2243,	OrderSorting : 2243 },
		'royskatt'					: { OrderInterface : 2244,	OrderSorting : 2244 },
		'rpg'						: { OrderInterface : 2245,	OrderSorting : 2245 },
		'rrh'						: { OrderInterface : 2246,	OrderSorting : 2246 },
		'rs'							: { OrderInterface : 2247,	OrderSorting : 2247 },
		'rsg'						: { OrderInterface : 2248,	OrderSorting : 2248 },
		'rta'						: { OrderInterface : 2249,	OrderSorting : 2249 },
		'rtfm'						: { OrderInterface : 2250,	OrderSorting : 2250 },
		'rtl'						: { OrderInterface : 2251,	OrderSorting : 2251 },
		'rtm'						: { OrderInterface : 2252,	OrderSorting : 2252 },
		'rtn'						: { OrderInterface : 2253,	OrderSorting : 2253 },
		'ru4hd'						: { OrderInterface : 2254,	OrderSorting : 2254 },
		'ruby'						: { OrderInterface : 2255,	OrderSorting : 2255 },
		'rucucu'					: { OrderInterface : 2256,	OrderSorting : 2256 },
		'rude'						: { OrderInterface : 2257,	OrderSorting : 2257 },
		'rudos'						: { OrderInterface : 2258,	OrderSorting : 2258 },
		'rumour'					: { OrderInterface : 2259,	OrderSorting : 2259 },
		'runner'					: { OrderInterface : 2260,	OrderSorting : 2260 },
		'rusted'					: { OrderInterface : 2261,	OrderSorting : 2261 },
		'rustle'					: { OrderInterface : 2262,	OrderSorting : 2262 },
		'rutracker'					: { OrderInterface : 2263,	OrderSorting : 2263 },
		'rwp'						: { OrderInterface : 2264,	OrderSorting : 2264 },
		'rx'							: { OrderInterface : 2265,	OrderSorting : 2265 },
		'ryan'						: { OrderInterface : 2266,	OrderSorting : 2266 },
		'ryotox'					: { OrderInterface : 2267,	OrderSorting : 2267 },
		'ryuuga'					: { OrderInterface : 2268,	OrderSorting : 2268 },
		'rzerox'					: { OrderInterface : 2269,	OrderSorting : 2269 },
		'rzf'						: { OrderInterface : 2270,	OrderSorting : 2270 },
		'rzp'						: { OrderInterface : 2271,	OrderSorting : 2271 },
		's0ld13r'					: { OrderInterface : 2272,	OrderSorting : 2272 },
		's4a'						: { OrderInterface : 2273,	OrderSorting : 2273 },
		's4l'						: { OrderInterface : 2274,	OrderSorting : 2274 },
		's8'							: { OrderInterface : 2275,	OrderSorting : 2275 },
		's8rhino'					: { OrderInterface : 2276,	OrderSorting : 2276 },
		'sa'							: { OrderInterface : 2277,	OrderSorting : 2277 },
		'sa89'						: { OrderInterface : 2278,	OrderSorting : 2278 },
		'sadpanda'					: { OrderInterface : 2279,	OrderSorting : 2279 },
		'safety'					: { OrderInterface : 2280,	OrderSorting : 2280 },
		'sage'						: { OrderInterface : 2281,	OrderSorting : 2281 },
		'saicord'					: { OrderInterface : 2282,	OrderSorting : 2282 },
		'saimorny'					: { OrderInterface : 2283,	OrderSorting : 2283 },
		'saints'					: { OrderInterface : 2284,	OrderSorting : 2284 },
		'sajid790'					: { OrderInterface : 2285,	OrderSorting : 2285 },
		'salt'						: { OrderInterface : 2286,	OrderSorting : 2286 },
		'sam'						: { OrderInterface : 2287,	OrderSorting : 2287 },
		'samfd'						: { OrderInterface : 2288,	OrderSorting : 2288 },
		'sammie'					: { OrderInterface : 2289,	OrderSorting : 2289 },
		'sampa'						: { OrderInterface : 2290,	OrderSorting : 2290 },
		'samuel98'					: { OrderInterface : 2291,	OrderSorting : 2291 },
		'santi'						: { OrderInterface : 2292,	OrderSorting : 2292 },
		'saphire'					: { OrderInterface : 2293,	OrderSorting : 2293 },
		'sapphire'					: { OrderInterface : 2294,	OrderSorting : 2294 },
		'sartre'					: { OrderInterface : 2295,	OrderSorting : 2295 },
		'sashimi'					: { OrderInterface : 2296,	OrderSorting : 2296 },
		'satanic'					: { OrderInterface : 2297,	OrderSorting : 2297 },
		'savannah'					: { OrderInterface : 2298,	OrderSorting : 2298 },
		'saviour'					: { OrderInterface : 2299,	OrderSorting : 2299 },
		'sbr'						: { OrderInterface : 2300,	OrderSorting : 2300 },
		'sby'						: { OrderInterface : 2301,	OrderSorting : 2301 },
		'scarabey'					: { OrderInterface : 2302,	OrderSorting : 2302 },
		'scared'					: { OrderInterface : 2303,	OrderSorting : 2303 },
		'scarfilm'					: { OrderInterface : 2304,	OrderSorting : 2304 },
		'sceneguardians'			: { OrderInterface : 2305,	OrderSorting : 2305 },
		'schizo'					: { OrderInterface : 2306,	OrderSorting : 2306 },
		'scientology'				: { OrderInterface : 2307,	OrderSorting : 2307 },
		'scones'					: { OrderInterface : 2308,	OrderSorting : 2308 },
		'scorn'						: { OrderInterface : 2309,	OrderSorting : 2309 },
		'scotluhd'					: { OrderInterface : 2310,	OrderSorting : 2310 },
		'scream'					: { OrderInterface : 2311,	OrderSorting : 2311 },
		'scy'						: { OrderInterface : 2312,	OrderSorting : 2312 },
		'sdc'						: { OrderInterface : 2313,	OrderSorting : 2313 },
		'sdi'						: { OrderInterface : 2314,	OrderSorting : 2314 },
		'secrecy'					: { OrderInterface : 2315,	OrderSorting : 2315 },
		'secretmyth'					: { OrderInterface : 2316,	OrderSorting : 2316 },
		'secretos'					: { OrderInterface : 2317,	OrderSorting : 2317 },
		'sector'					: { OrderInterface : 2318,	OrderSorting : 2318 },
		'sector7'					: { OrderInterface : 2319,	OrderSorting : 2319 },
		'seedup'					: { OrderInterface : 2320,	OrderSorting : 2320 },
		'seehd'						: { OrderInterface : 2321,	OrderSorting : 2321 },
		'seight'					: { OrderInterface : 2322,	OrderSorting : 2322 },
		'selezen'					: { OrderInterface : 2323,	OrderSorting : 2323 },
		'semantics'					: { OrderInterface : 2324,	OrderSorting : 2324 },
		'semtex'					: { OrderInterface : 2325,	OrderSorting : 2325 },
		'senation'					: { OrderInterface : 2326,	OrderSorting : 2326 },
		'senpai'					: { OrderInterface : 2327,	OrderSorting : 2327 },
		'septic'					: { OrderInterface : 2328,	OrderSorting : 2328 },
		'ser'						: { OrderInterface : 2329,	OrderSorting : 2329 },
		'seriously'					: { OrderInterface : 2330,	OrderSorting : 2330 },
		'serum'						: { OrderInterface : 2331,	OrderSorting : 2331 },
		'seskapile'					: { OrderInterface : 2332,	OrderSorting : 2332 },
		'sev'						: { OrderInterface : 2333,	OrderSorting : 2333 },
		'seventwenty'				: { OrderInterface : 2334,	OrderSorting : 2334 },
		'sf'							: { OrderInterface : 2335,	OrderSorting : 2335 },
		'sfm'						: { OrderInterface : 2336,	OrderSorting : 2336 },
		'sfs'						: { OrderInterface : 2337,	OrderSorting : 2337 },
		'sft'						: { OrderInterface : 2338,	OrderSorting : 2338 },
		'sg'							: { OrderInterface : 2339,	OrderSorting : 2339 },
		'sh3lby'					: { OrderInterface : 2340,	OrderSorting : 2340 },
		'shaanig'					: { OrderInterface : 2341,	OrderSorting : 2341 },
		'shadow'					: { OrderInterface : 2342,	OrderSorting : 2342 },
		'shadowman'					: { OrderInterface : 2343,	OrderSorting : 2343 },
		'sharereactor'				: { OrderInterface : 2344,	OrderSorting : 2344 },
		'sharphd'					: { OrderInterface : 2345,	OrderSorting : 2345 },
		'sharpysword'				: { OrderInterface : 2346,	OrderSorting : 2346 },
		'shd'						: { OrderInterface : 2347,	OrderSorting : 2347 },
		'shinigami'					: { OrderInterface : 2348,	OrderSorting : 2348 },
		'shinobi'					: { OrderInterface : 2349,	OrderSorting : 2349 },
		'shiro'						: { OrderInterface : 2350,	OrderSorting : 2350 },
		'shitbox'					: { OrderInterface : 2351,	OrderSorting : 2351 },
		'shitbusters'				: { OrderInterface : 2352,	OrderSorting : 2352 },
		'shitsony'					: { OrderInterface : 2353,	OrderSorting : 2353 },
		'shitspread'					: { OrderInterface : 2354,	OrderSorting : 2354 },
		'shitty'					: { OrderInterface : 2355,	OrderSorting : 2355 },
		'sho'						: { OrderInterface : 2356,	OrderSorting : 2356 },
		'shock'						: { OrderInterface : 2357,	OrderSorting : 2357 },
		'shortbrehd'					: { OrderInterface : 2358,	OrderSorting : 2358 },
		'shortrips'					: { OrderInterface : 2359,	OrderSorting : 2359 },
		'shotv'						: { OrderInterface : 2360,	OrderSorting : 2360 },
		'showehd'					: { OrderInterface : 2361,	OrderSorting : 2361 },
		'shr'						: { OrderInterface : 2362,	OrderSorting : 2362 },
		'shreddie'					: { OrderInterface : 2363,	OrderSorting : 2363 },
		'shrpy'						: { OrderInterface : 2364,	OrderSorting : 2364 },
		'shunpo'					: { OrderInterface : 2365,	OrderSorting : 2365 },
		'siambit'					: { OrderInterface : 2366,	OrderSorting : 2366 },
		'sic'						: { OrderInterface : 2367,	OrderSorting : 2367 },
		'sicario'					: { OrderInterface : 2368,	OrderSorting : 2368 },
		'sicfoi'					: { OrderInterface : 2369,	OrderSorting : 2369 },
		'sigeris'					: { OrderInterface : 2370,	OrderSorting : 2370 },
		'sight'						: { OrderInterface : 2371,	OrderSorting : 2371 },
		'sigla'						: { OrderInterface : 2372,	OrderSorting : 2372 },
		'sigma'						: { OrderInterface : 2373,	OrderSorting : 2373 },
		'silence'					: { OrderInterface : 2374,	OrderSorting : 2374 },
		'silent'					: { OrderInterface : 2375,	OrderSorting : 2375 },
		'sillybird'					: { OrderInterface : 2376,	OrderSorting : 2376 },
		'silu'						: { OrderInterface : 2377,	OrderSorting : 2377 },
		'silver007'					: { OrderInterface : 2378,	OrderSorting : 2378 },
		'silverrg'					: { OrderInterface : 2379,	OrderSorting : 2379 },
		'simba'						: { OrderInterface : 2380,	OrderSorting : 2380 },
		'simple'					: { OrderInterface : 2381,	OrderSorting : 2381 },
		'sin'						: { OrderInterface : 2382,	OrderSorting : 2382 },
		'sinister'					: { OrderInterface : 2383,	OrderSorting : 2383 },
		'sinners'					: { OrderInterface : 2384,	OrderSorting : 2384 },
		'siriusshare'				: { OrderInterface : 2385,	OrderSorting : 2385 },
		'sirpaul'					: { OrderInterface : 2386,	OrderSorting : 2386 },
		'siso'						: { OrderInterface : 2387,	OrderSorting : 2387 },
		'sit'						: { OrderInterface : 2388,	OrderSorting : 2388 },
		'sitv'						: { OrderInterface : 2389,	OrderSorting : 2389 },
		'sj'							: { OrderInterface : 2390,	OrderSorting : 2390 },
		'sjca'						: { OrderInterface : 2391,	OrderSorting : 2391 },
		'ska'						: { OrderInterface : 2392,	OrderSorting : 2392 },
		'skaliwagz'					: { OrderInterface : 2393,	OrderSorting : 2393 },
		'skazhutin'					: { OrderInterface : 2394,	OrderSorting : 2394 },
		'skedaddle'					: { OrderInterface : 2395,	OrderSorting : 2395 },
		'skgtv'						: { OrderInterface : 2396,	OrderSorting : 2396 },
		'skizoid'					: { OrderInterface : 2397,	OrderSorting : 2397 },
		'skorpion'					: { OrderInterface : 2398,	OrderSorting : 2398 },
		'skrin'						: { OrderInterface : 2399,	OrderSorting : 2399 },
		'skyrg'						: { OrderInterface : 2400,	OrderSorting : 2400 },
		'sl'							: { OrderInterface : 2401,	OrderSorting : 2401 },
		'slag'						: { OrderInterface : 2402,	OrderSorting : 2402 },
		'slappy'					: { OrderInterface : 2403,	OrderSorting : 2403 },
		'slater'					: { OrderInterface : 2404,	OrderSorting : 2404 },
		'slax'						: { OrderInterface : 2405,	OrderSorting : 2405 },
		'slay3r'					: { OrderInterface : 2406,	OrderSorting : 2406 },
		'slbenfica'					: { OrderInterface : 2407,	OrderSorting : 2407 },
		'sless'						: { OrderInterface : 2408,	OrderSorting : 2408 },
		'slg'						: { OrderInterface : 2409,	OrderSorting : 2409 },
		'slight'					: { OrderInterface : 2410,	OrderSorting : 2410 },
		'slisu'						: { OrderInterface : 2411,	OrderSorting : 2411 },
		'slo'						: { OrderInterface : 2412,	OrderSorting : 2412 },
		'slomo'						: { OrderInterface : 2413,	OrderSorting : 2413 },
		'slot'						: { OrderInterface : 2414,	OrderSorting : 2414 },
		'slow'						: { OrderInterface : 2415,	OrderSorting : 2415 },
		'slowhd'					: { OrderInterface : 2416,	OrderSorting : 2416 },
		'smc'						: { OrderInterface : 2417,	OrderSorting : 2417 },
		'smokey'					: { OrderInterface : 2418,	OrderSorting : 2418 },
		'sms'						: { OrderInterface : 2419,	OrderSorting : 2419 },
		'smurf'						: { OrderInterface : 2420,	OrderSorting : 2420 },
		'smurfenlars'				: { OrderInterface : 2421,	OrderSorting : 2421 },
		'snake'						: { OrderInterface : 2422,	OrderSorting : 2422 },
		'sneak'						: { OrderInterface : 2423,	OrderSorting : 2423 },
		'sneaky'					: { OrderInterface : 2424,	OrderSorting : 2424 },
		'sno'						: { OrderInterface : 2425,	OrderSorting : 2425 },
		'snow'						: { OrderInterface : 2426,	OrderSorting : 2426 },
		'snowdon'					: { OrderInterface : 2427,	OrderSorting : 2427 },
		'socks'						: { OrderInterface : 2428,	OrderSorting : 2428 },
		'sof'						: { OrderInterface : 2429,	OrderSorting : 2429 },
		'soigneur'					: { OrderInterface : 2430,	OrderSorting : 2430 },
		'sol'						: { OrderInterface : 2431,	OrderSorting : 2431 },
		'sola'						: { OrderInterface : 2432,	OrderSorting : 2432 },
		'solar'						: { OrderInterface : 2433,	OrderSorting : 2433 },
		'som'						: { OrderInterface : 2434,	OrderSorting : 2434 },
		'sonido'					: { OrderInterface : 2435,	OrderSorting : 2435 },
		'sons'						: { OrderInterface : 2436,	OrderSorting : 2436 },
		'sorrow'					: { OrderInterface : 2437,	OrderSorting : 2437 },
		'sos'						: { OrderInterface : 2438,	OrderSorting : 2438 },
		'sour'						: { OrderInterface : 2439,	OrderSorting : 2439 },
		'sov'						: { OrderInterface : 2440,	OrderSorting : 2440 },
		'sow'						: { OrderInterface : 2441,	OrderSorting : 2441 },
		'soy'						: { OrderInterface : 2442,	OrderSorting : 2442 },
		'sozer'						: { OrderInterface : 2443,	OrderSorting : 2443 },
		'sp33dy94'					: { OrderInterface : 2444,	OrderSorting : 2444 },
		'sp3ll'						: { OrderInterface : 2445,	OrderSorting : 2445 },
		'spacehd'					: { OrderInterface : 2446,	OrderSorting : 2446 },
		'spacehd13'					: { OrderInterface : 2447,	OrderSorting : 2447 },
		'spamtv'					: { OrderInterface : 2448,	OrderSorting : 2448 },
		'sparel'					: { OrderInterface : 2449,	OrderSorting : 2449 },
		'sparks'					: { OrderInterface : 2450,	OrderSorting : 2450 },
		'spc'						: { OrderInterface : 2451,	OrderSorting : 2451 },
		'species180'					: { OrderInterface : 2452,	OrderSorting : 2452 },
		'spectre'					: { OrderInterface : 2453,	OrderSorting : 2453 },
		'spedboy'					: { OrderInterface : 2454,	OrderSorting : 2454 },
		'speed'						: { OrderInterface : 2455,	OrderSorting : 2455 },
		'speranzah'					: { OrderInterface : 2456,	OrderSorting : 2456 },
		'sphd'						: { OrderInterface : 2457,	OrderSorting : 2457 },
		'sphinctone1'				: { OrderInterface : 2458,	OrderSorting : 2458 },
		'spicy'						: { OrderInterface : 2459,	OrderSorting : 2459 },
		'spirit'					: { OrderInterface : 2460,	OrderSorting : 2460 },
		'spiro'						: { OrderInterface : 2461,	OrderSorting : 2461 },
		'spk'						: { OrderInterface : 2462,	OrderSorting : 2462 },
		'splendide'					: { OrderInterface : 2463,	OrderSorting : 2463 },
		'splitsville'				: { OrderInterface : 2464,	OrderSorting : 2464 },
		'spooks'					: { OrderInterface : 2465,	OrderSorting : 2465 },
		'spooky'					: { OrderInterface : 2466,	OrderSorting : 2466 },
		'sprinter'					: { OrderInterface : 2467,	OrderSorting : 2467 },
		'sps'						: { OrderInterface : 2468,	OrderSorting : 2468 },
		'spyc'						: { OrderInterface : 2469,	OrderSorting : 2469 },
		'squalor'					: { OrderInterface : 2470,	OrderSorting : 2470 },
		'srigga'					: { OrderInterface : 2471,	OrderSorting : 2471 },
		'sriz'						: { OrderInterface : 2472,	OrderSorting : 2472 },
		'srls'						: { OrderInterface : 2473,	OrderSorting : 2473 },
		'srs'						: { OrderInterface : 2474,	OrderSorting : 2474 },
		'ss'							: { OrderInterface : 2475,	OrderSorting : 2475 },
		'ssa'						: { OrderInterface : 2476,	OrderSorting : 2476 },
		'ssdd'						: { OrderInterface : 2477,	OrderSorting : 2477 },
		'ssf'						: { OrderInterface : 2478,	OrderSorting : 2478 },
		'ssg'						: { OrderInterface : 2479,	OrderSorting : 2479 },
		'ssk'						: { OrderInterface : 2480,	OrderSorting : 2480 },
		'ssl'						: { OrderInterface : 2481,	OrderSorting : 2481 },
		'ssn'						: { OrderInterface : 2482,	OrderSorting : 2482 },
		'ssrmovies'					: { OrderInterface : 2483,	OrderSorting : 2483 },
		'st'							: { OrderInterface : 2484,	OrderSorting : 2484 },
		'starlord'					: { OrderInterface : 2485,	OrderSorting : 2485 },
		'stars'						: { OrderInterface : 2486,	OrderSorting : 2486 },
		'starz'						: { OrderInterface : 2487,	OrderSorting : 2487 },
		'state'						: { OrderInterface : 2488,	OrderSorting : 2488 },
		'stb'						: { OrderInterface : 2489,	OrderSorting : 2489 },
		'stealthmaster'				: { OrderInterface : 2490,	OrderSorting : 2490 },
		'stegner'					: { OrderInterface : 2491,	OrderSorting : 2491 },
		'stella'					: { OrderInterface : 2492,	OrderSorting : 2492 },
		'stfu'						: { OrderInterface : 2493,	OrderSorting : 2493 },
		'sticky83'					: { OrderInterface : 2494,	OrderSorting : 2494 },
		'stock'						: { OrderInterface : 2495,	OrderSorting : 2495 },
		'storm'						: { OrderInterface : 2496,	OrderSorting : 2496 },
		'stp'						: { OrderInterface : 2497,	OrderSorting : 2497 },
		'stranded'					: { OrderInterface : 2498,	OrderSorting : 2498 },
		'stratos'					: { OrderInterface : 2499,	OrderSorting : 2499 },
		'straub'					: { OrderInterface : 2500,	OrderSorting : 2500 },
		'strife'					: { OrderInterface : 2501,	OrderSorting : 2501 },
		'strong'					: { OrderInterface : 2502,	OrderSorting : 2502 },
		'strontium'					: { OrderInterface : 2503,	OrderSorting : 2503 },
		'stuttershit'				: { OrderInterface : 2504,	OrderSorting : 2504 },
		'stvfrv'					: { OrderInterface : 2505,	OrderSorting : 2505 },
		'stylishsalh'				: { OrderInterface : 2506,	OrderSorting : 2506 },
		'suave'						: { OrderInterface : 2507,	OrderSorting : 2507 },
		'sublime'					: { OrderInterface : 2508,	OrderSorting : 2508 },
		'submerge'					: { OrderInterface : 2509,	OrderSorting : 2509 },
		'substance'					: { OrderInterface : 2510,	OrderSorting : 2510 },
		'subzero'					: { OrderInterface : 2511,	OrderSorting : 2511 },
		'sujaidr'					: { OrderInterface : 2512,	OrderSorting : 2512 },
		'sumvision'					: { OrderInterface : 2513,	OrderSorting : 2513 },
		'sunny'						: { OrderInterface : 2514,	OrderSorting : 2514 },
		'sunscreen'					: { OrderInterface : 2515,	OrderSorting : 2515 },
		'sunshinestudio'			: { OrderInterface : 2516,	OrderSorting : 2516 },
		'sunspot'					: { OrderInterface : 2517,	OrderSorting : 2517 },
		'sunsujaidr'					: { OrderInterface : 2518,	OrderSorting : 2518 },
		'supernova'					: { OrderInterface : 2519,	OrderSorting : 2519 },
		'supersize'					: { OrderInterface : 2520,	OrderSorting : 2520 },
		'supreme'					: { OrderInterface : 2521,	OrderSorting : 2521 },
		'surcode'					: { OrderInterface : 2522,	OrderSorting : 2522 },
		'surfer'					: { OrderInterface : 2523,	OrderSorting : 2523 },
		'surya'						: { OrderInterface : 2524,	OrderSorting : 2524 },
		'sus'						: { OrderInterface : 2525,	OrderSorting : 2525 },
		'sva'						: { OrderInterface : 2526,	OrderSorting : 2526 },
		'svd'						: { OrderInterface : 2527,	OrderSorting : 2527 },
		'swaggerhd'					: { OrderInterface : 2528,	OrderSorting : 2528 },
		'swc'						: { OrderInterface : 2529,	OrderSorting : 2529 },
		'swim'						: { OrderInterface : 2530,	OrderSorting : 2530 },
		'swolled'					: { OrderInterface : 2531,	OrderSorting : 2531 },
		'swty'						: { OrderInterface : 2532,	OrderSorting : 2532 },
		'swtyblz'					: { OrderInterface : 2533,	OrderSorting : 2533 },
		'sxales'					: { OrderInterface : 2534,	OrderSorting : 2534 },
		'symbiotes'					: { OrderInterface : 2535,	OrderSorting : 2535 },
		'syncopy'					: { OrderInterface : 2536,	OrderSorting : 2536 },
		'syndicate'					: { OrderInterface : 2537,	OrderSorting : 2537 },
		'sys'						: { OrderInterface : 2538,	OrderSorting : 2538 },
		't00ng0d'					: { OrderInterface : 2539,	OrderSorting : 2539 },
		't0m'						: { OrderInterface : 2540,	OrderSorting : 2540 },
		't1'							: { OrderInterface : 2541,	OrderSorting : 2541 },
		't3nzin'					: { OrderInterface : 2542,	OrderSorting : 2542 },
		't4h'						: { OrderInterface : 2543,	OrderSorting : 2543 },
		't4p3'						: { OrderInterface : 2544,	OrderSorting : 2544 },
		't6d'						: { OrderInterface : 2545,	OrderSorting : 2545 },
		'taco'						: { OrderInterface : 2546,	OrderSorting : 2546 },
		'taichi'					: { OrderInterface : 2547,	OrderSorting : 2547 },
		'tangoalpha'					: { OrderInterface : 2548,	OrderSorting : 2548 },
		'taoe'						: { OrderInterface : 2549,	OrderSorting : 2549 },
		'tapochek'					: { OrderInterface : 2550,	OrderSorting : 2550 },
		'target'					: { OrderInterface : 2551,	OrderSorting : 2551 },
		'tasko'						: { OrderInterface : 2552,	OrderSorting : 2552 },
		'taste'						: { OrderInterface : 2553,	OrderSorting : 2553 },
		'tasted'					: { OrderInterface : 2554,	OrderSorting : 2554 },
		'tastetv'					: { OrderInterface : 2555,	OrderSorting : 2555 },
		'tatugamescf'				: { OrderInterface : 2556,	OrderSorting : 2556 },
		'taxes'						: { OrderInterface : 2557,	OrderSorting : 2557 },
		'tayto'						: { OrderInterface : 2558,	OrderSorting : 2558 },
		'tb'							: { OrderInterface : 2559,	OrderSorting : 2559 },
		'tbb'						: { OrderInterface : 2560,	OrderSorting : 2560 },
		'tbd'						: { OrderInterface : 2561,	OrderSorting : 2561 },
		'tbr'						: { OrderInterface : 2562,	OrderSorting : 2562 },
		'tbs'						: { OrderInterface : 2563,	OrderSorting : 2563 },
		'tbz'						: { OrderInterface : 2564,	OrderSorting : 2564 },
		'tcl'						: { OrderInterface : 2565,	OrderSorting : 2565 },
		'tcm'						: { OrderInterface : 2566,	OrderSorting : 2566 },
		'tcpa'						: { OrderInterface : 2567,	OrderSorting : 2567 },
		'tdd'						: { OrderInterface : 2568,	OrderSorting : 2568 },
		'tdf'						: { OrderInterface : 2569,	OrderSorting : 2569 },
		'tdm'						: { OrderInterface : 2570,	OrderSorting : 2570 },
		'tdr'						: { OrderInterface : 2571,	OrderSorting : 2571 },
		'teamhd'					: { OrderInterface : 2572,	OrderSorting : 2572 },
		'teamtelly'					: { OrderInterface : 2573,	OrderSorting : 2573 },
		'teamtr'					: { OrderInterface : 2574,	OrderSorting : 2574 },
		'tear'						: { OrderInterface : 2575,	OrderSorting : 2575 },
		'tech'						: { OrderInterface : 2576,	OrderSorting : 2576 },
		'teehee'					: { OrderInterface : 2577,	OrderSorting : 2577 },
		'tekno3d'					: { OrderInterface : 2578,	OrderSorting : 2578 },
		'telefunken'					: { OrderInterface : 2579,	OrderSorting : 2579 },
		'telly'						: { OrderInterface : 2580,	OrderSorting : 2580 },
		'tenaciousd'					: { OrderInterface : 2581,	OrderSorting : 2581 },
		'teneighty'					: { OrderInterface : 2582,	OrderSorting : 2582 },
		'tennreed'					: { OrderInterface : 2583,	OrderSorting : 2583 },
		'teo'						: { OrderInterface : 2584,	OrderSorting : 2584 },
		'tepes'						: { OrderInterface : 2585,	OrderSorting : 2585 },
		'termi'						: { OrderInterface : 2586,	OrderSorting : 2586 },
		'terminal'					: { OrderInterface : 2587,	OrderSorting : 2587 },
		'terra'						: { OrderInterface : 2588,	OrderSorting : 2588 },
		'tesdrox'					: { OrderInterface : 2589,	OrderSorting : 2589 },
		'tfe'						: { OrderInterface : 2590,	OrderSorting : 2590 },
		'tfin'						: { OrderInterface : 2591,	OrderSorting : 2591 },
		'tg7'						: { OrderInterface : 2592,	OrderSorting : 2592 },
		'tgx'						: { OrderInterface : 2593,	OrderSorting : 2593 },
		'tha'						: { OrderInterface : 2594,	OrderSorting : 2594 },
		'thd'						: { OrderInterface : 2595,	OrderSorting : 2595 },
		'theamresh'					: { OrderInterface : 2596,	OrderSorting : 2596 },
		'thebatman'					: { OrderInterface : 2597,	OrderSorting : 2597 },
		'thebest'					: { OrderInterface : 2598,	OrderSorting : 2598 },
		'theend'					: { OrderInterface : 2599,	OrderSorting : 2599 },
		'theincognito'				: { OrderInterface : 2600,	OrderSorting : 2600 },
		'thenightmare'				: { OrderInterface : 2601,	OrderSorting : 2601 },
		'thenightmareinhd'			: { OrderInterface : 2602,	OrderSorting : 2602 },
		'theory'					: { OrderInterface : 2603,	OrderSorting : 2603 },
		'thepunisher'				: { OrderInterface : 2604,	OrderSorting : 2604 },
		'thewretched'				: { OrderInterface : 2605,	OrderSorting : 2605 },
		'thick'						: { OrderInterface : 2606,	OrderSorting : 2606 },
		'thisoneyouwontsell'			: { OrderInterface : 2607,	OrderSorting : 2607 },
		'thizz'						: { OrderInterface : 2608,	OrderSorting : 2608 },
		'thor'						: { OrderInterface : 2609,	OrderSorting : 2609 },
		'thora'						: { OrderInterface : 2610,	OrderSorting : 2610 },
		'threesixtyp'				: { OrderInterface : 2611,	OrderSorting : 2611 },
		'threesome'					: { OrderInterface : 2612,	OrderSorting : 2612 },
		'throne'					: { OrderInterface : 2613,	OrderSorting : 2613 },
		'thugline'					: { OrderInterface : 2614,	OrderSorting : 2614 },
		'thumperdc'					: { OrderInterface : 2615,	OrderSorting : 2615 },
		'thunder'					: { OrderInterface : 2616,	OrderSorting : 2616 },
		'thyrso10'					: { OrderInterface : 2617,	OrderSorting : 2617 },
		'tical'						: { OrderInterface : 2618,	OrderSorting : 2618 },
		'tide'						: { OrderInterface : 2619,	OrderSorting : 2619 },
		'tigole'					: { OrderInterface : 2620,	OrderSorting : 2620 },
		'timedistortion'			: { OrderInterface : 2621,	OrderSorting : 2621 },
		'timegod'					: { OrderInterface : 2622,	OrderSorting : 2622 },
		'timelords'					: { OrderInterface : 2623,	OrderSorting : 2623 },
		'timpe'						: { OrderInterface : 2624,	OrderSorting : 2624 },
		'tinye'						: { OrderInterface : 2625,	OrderSorting : 2625 },
		'tinymkv'					: { OrderInterface : 2626,	OrderSorting : 2626 },
		'tit'						: { OrderInterface : 2627,	OrderSorting : 2627 },
		'titan'						: { OrderInterface : 2628,	OrderSorting : 2628 },
		'titans'					: { OrderInterface : 2629,	OrderSorting : 2629 },
		'tjet'						: { OrderInterface : 2630,	OrderSorting : 2630 },
		'tjhd'						: { OrderInterface : 2631,	OrderSorting : 2631 },
		'tk'							: { OrderInterface : 2632,	OrderSorting : 2632 },
		'tla'						: { OrderInterface : 2633,	OrderSorting : 2633 },
		'tlf'						: { OrderInterface : 2634,	OrderSorting : 2634 },
		'tm'							: { OrderInterface : 2635,	OrderSorting : 2635 },
		'tmd'						: { OrderInterface : 2636,	OrderSorting : 2636 },
		'tmg'						: { OrderInterface : 2637,	OrderSorting : 2637 },
		'tmsf'						: { OrderInterface : 2638,	OrderSorting : 2638 },
		'tnan'						: { OrderInterface : 2639,	OrderSorting : 2639 },
		'tne'						: { OrderInterface : 2640,	OrderSorting : 2640 },
		'tnp'						: { OrderInterface : 2641,	OrderSorting : 2641 },
		'tntvillage'					: { OrderInterface : 2642,	OrderSorting : 2642 },
		'to4ka'						: { OrderInterface : 2643,	OrderSorting : 2643 },
		'tof'						: { OrderInterface : 2644,	OrderSorting : 2644 },
		'toho'						: { OrderInterface : 2645,	OrderSorting : 2645 },
		'tombdoc'					: { OrderInterface : 2646,	OrderSorting : 2646 },
		'tomcat12'					: { OrderInterface : 2647,	OrderSorting : 2647 },
		'tommy'						: { OrderInterface : 2648,	OrderSorting : 2648 },
		'tomx'						: { OrderInterface : 2649,	OrderSorting : 2649 },
		'tonyk'						: { OrderInterface : 2650,	OrderSorting : 2650 },
		'tooncore'					: { OrderInterface : 2651,	OrderSorting : 2651 },
		'top'						: { OrderInterface : 2652,	OrderSorting : 2652 },
		'topaz'						: { OrderInterface : 2653,	OrderSorting : 2653 },
		'topcat'					: { OrderInterface : 2654,	OrderSorting : 2654 },
		'topkek'					: { OrderInterface : 2655,	OrderSorting : 2655 },
		'torrentcouch'				: { OrderInterface : 2656,	OrderSorting : 2656 },
		'torrentcounter'			: { OrderInterface : 2657,	OrderSorting : 2657 },
		'torrentgui'					: { OrderInterface : 2658,	OrderSorting : 2658 },
		'tot'						: { OrderInterface : 2659,	OrderSorting : 2659 },
		'toxic'						: { OrderInterface : 2660,	OrderSorting : 2660 },
		'tozoon'					: { OrderInterface : 2661,	OrderSorting : 2661 },
		'tpb'						: { OrderInterface : 2662,	OrderSorting : 2662 },
		'tr'							: { OrderInterface : 2663,	OrderSorting : 2663 },
		'transience'					: { OrderInterface : 2664,	OrderSorting : 2664 },
		'trash'						: { OrderInterface : 2665,	OrderSorting : 2665 },
		'treble'					: { OrderInterface : 2666,	OrderSorting : 2666 },
		'tree'						: { OrderInterface : 2667,	OrderSorting : 2667 },
		'trevor333'					: { OrderInterface : 2668,	OrderSorting : 2668 },
		'trexhd'					: { OrderInterface : 2669,	OrderSorting : 2669 },
		'trg'						: { OrderInterface : 2670,	OrderSorting : 2670 },
		'triad'						: { OrderInterface : 2671,	OrderSorting : 2671 },
		'trial'						: { OrderInterface : 2672,	OrderSorting : 2672 },
		'tribal'					: { OrderInterface : 2673,	OrderSorting : 2673 },
		'trips'						: { OrderInterface : 2674,	OrderSorting : 2674 },
		'triton'					: { OrderInterface : 2675,	OrderSorting : 2675 },
		'trl'						: { OrderInterface : 2676,	OrderSorting : 2676 },
		'trojan'					: { OrderInterface : 2677,	OrderSorting : 2677 },
		'trollhd'					: { OrderInterface : 2678,	OrderSorting : 2678 },
		'trolluhd'					: { OrderInterface : 2679,	OrderSorting : 2679 },
		'trtdteam'					: { OrderInterface : 2680,	OrderSorting : 2680 },
		'truavc'					: { OrderInterface : 2681,	OrderSorting : 2681 },
		'truck'						: { OrderInterface : 2682,	OrderSorting : 2682 },
		'truedef'					: { OrderInterface : 2683,	OrderSorting : 2683 },
		'truedukes'					: { OrderInterface : 2684,	OrderSorting : 2684 },
		'trump'						: { OrderInterface : 2685,	OrderSorting : 2685 },
		'tscc'						: { OrderInterface : 2686,	OrderSorting : 2686 },
		'tse'						: { OrderInterface : 2687,	OrderSorting : 2687 },
		'tsrg'						: { OrderInterface : 2688,	OrderSorting : 2688 },
		'tss'						: { OrderInterface : 2689,	OrderSorting : 2689 },
		'tsv'						: { OrderInterface : 2690,	OrderSorting : 2690 },
		'tt'							: { OrderInterface : 2691,	OrderSorting : 2691 },
		'ttg'						: { OrderInterface : 2692,	OrderSorting : 2692 },
		'ttl'						: { OrderInterface : 2693,	OrderSorting : 2693 },
		'tto'						: { OrderInterface : 2694,	OrderSorting : 2694 },
		'tts'						: { OrderInterface : 2695,	OrderSorting : 2695 },
		'ttva'						: { OrderInterface : 2696,	OrderSorting : 2696 },
		'tugazx'					: { OrderInterface : 2697,	OrderSorting : 2697 },
		'turbo'						: { OrderInterface : 2698,	OrderSorting : 2698 },
		'turg'						: { OrderInterface : 2699,	OrderSorting : 2699 },
		'turkiso'					: { OrderInterface : 2700,	OrderSorting : 2700 },
		'turmoil'					: { OrderInterface : 2701,	OrderSorting : 2701 },
		'tusahd'					: { OrderInterface : 2702,	OrderSorting : 2702 },
		'tv21'						: { OrderInterface : 2703,	OrderSorting : 2703 },
		'tv2lax9'					: { OrderInterface : 2704,	OrderSorting : 2704 },
		'tv4a'						: { OrderInterface : 2705,	OrderSorting : 2705 },
		'tvaddict'					: { OrderInterface : 2706,	OrderSorting : 2706 },
		'tvarchiv'					: { OrderInterface : 2707,	OrderSorting : 2707 },
		'tvbeasts'					: { OrderInterface : 2708,	OrderSorting : 2708 },
		'tvc'						: { OrderInterface : 2709,	OrderSorting : 2709 },
		'tvd'						: { OrderInterface : 2710,	OrderSorting : 2710 },
		'tvillage'					: { OrderInterface : 2711,	OrderSorting : 2711 },
		'tvnation'					: { OrderInterface : 2712,	OrderSorting : 2712 },
		'tvp'						: { OrderInterface : 2713,	OrderSorting : 2713 },
		'tvr'						: { OrderInterface : 2714,	OrderSorting : 2714 },
		'tvs'						: { OrderInterface : 2715,	OrderSorting : 2715 },
		'tvslf'						: { OrderInterface : 2716,	OrderSorting : 2716 },
		'tvslices'					: { OrderInterface : 2717,	OrderSorting : 2717 },
		'tvsmash'					: { OrderInterface : 2718,	OrderSorting : 2718 },
		'tvtime'					: { OrderInterface : 2719,	OrderSorting : 2719 },
		'tvv'						: { OrderInterface : 2720,	OrderSorting : 2720 },
		'twa'						: { OrderInterface : 2721,	OrderSorting : 2721 },
		'tweet'						: { OrderInterface : 2722,	OrderSorting : 2722 },
		'twist'						: { OrderInterface : 2723,	OrderSorting : 2723 },
		'twister'					: { OrderInterface : 2724,	OrderSorting : 2724 },
		'twizted'					: { OrderInterface : 2725,	OrderSorting : 2725 },
		'tx'							: { OrderInterface : 2726,	OrderSorting : 2726 },
		'txb'						: { OrderInterface : 2727,	OrderSorting : 2727 },
		'uav'						: { OrderInterface : 2728,	OrderSorting : 2728 },
		'ubik'						: { OrderInterface : 2729,	OrderSorting : 2729 },
		'ubm'						: { OrderInterface : 2730,	OrderSorting : 2730 },
		'udf'						: { OrderInterface : 2731,	OrderSorting : 2731 },
		'ukdhd'						: { OrderInterface : 2732,	OrderSorting : 2732 },
		'uktv'						: { OrderInterface : 2733,	OrderSorting : 2733 },
		'ulshd'						: { OrderInterface : 2734,	OrderSorting : 2734 },
		'ultradox'					: { OrderInterface : 2735,	OrderSorting : 2735 },
		'ultrahdclub'				: { OrderInterface : 2736,	OrderSorting : 2736 },
		'ulysse'					: { OrderInterface : 2737,	OrderSorting : 2737 },
		'undead'					: { OrderInterface : 2738,	OrderSorting : 2738 },
		'underbelly'					: { OrderInterface : 2739,	OrderSorting : 2739 },
		'undercover'					: { OrderInterface : 2740,	OrderSorting : 2740 },
		'underwater'					: { OrderInterface : 2741,	OrderSorting : 2741 },
		'unfired'					: { OrderInterface : 2742,	OrderSorting : 2742 },
		'uniongang'					: { OrderInterface : 2743,	OrderSorting : 2743 },
		'unique'					: { OrderInterface : 2744,	OrderSorting : 2744 },
		'unit'						: { OrderInterface : 2745,	OrderSorting : 2745 },
		'unitail'					: { OrderInterface : 2746,	OrderSorting : 2746 },
		'unity'						: { OrderInterface : 2747,	OrderSorting : 2747 },
		'universum'					: { OrderInterface : 2748,	OrderSorting : 2748 },
		'unkn0wn'					: { OrderInterface : 2749,	OrderSorting : 2749 },
		'unskilled'					: { OrderInterface : 2750,	OrderSorting : 2750 },
		'untouchables'				: { OrderInterface : 2751,	OrderSorting : 2751 },
		'unveil'					: { OrderInterface : 2752,	OrderSorting : 2752 },
		'uranime'					: { OrderInterface : 2753,	OrderSorting : 2753 },
		'usd'						: { OrderInterface : 2754,	OrderSorting : 2754 },
		'useless'					: { OrderInterface : 2755,	OrderSorting : 2755 },
		'usury'						: { OrderInterface : 2756,	OrderSorting : 2756 },
		'utopia'					: { OrderInterface : 2757,	OrderSorting : 2757 },
		'utr'						: { OrderInterface : 2758,	OrderSorting : 2758 },
		'utt'						: { OrderInterface : 2759,	OrderSorting : 2759 },
		'uump4'						: { OrderInterface : 2760,	OrderSorting : 2760 },
		'uvall'						: { OrderInterface : 2761,	OrderSorting : 2761 },
		'uyirvani'					: { OrderInterface : 2762,	OrderSorting : 2762 },
		'v0'							: { OrderInterface : 2763,	OrderSorting : 2763 },
		'v3ritas'					: { OrderInterface : 2764,	OrderSorting : 2764 },
		'v99'						: { OrderInterface : 2765,	OrderSorting : 2765 },
		'vain'						: { OrderInterface : 2766,	OrderSorting : 2766 },
		'vajnis'					: { OrderInterface : 2767,	OrderSorting : 2767 },
		'valhalla'					: { OrderInterface : 2768,	OrderSorting : 2768 },
		'valiomedia'					: { OrderInterface : 2769,	OrderSorting : 2769 },
		'value'						: { OrderInterface : 2770,	OrderSorting : 2770 },
		'varyg'						: { OrderInterface : 2771,	OrderSorting : 2771 },
		'vcdvault'					: { OrderInterface : 2772,	OrderSorting : 2772 },
		'vcore'						: { OrderInterface : 2773,	OrderSorting : 2773 },
		'vector'					: { OrderInterface : 2774,	OrderSorting : 2774 },
		'vedett'					: { OrderInterface : 2775,	OrderSorting : 2775 },
		'veil'						: { OrderInterface : 2776,	OrderSorting : 2776 },
		'venue'						: { OrderInterface : 2777,	OrderSorting : 2777 },
		'veritas'					: { OrderInterface : 2778,	OrderSorting : 2778 },
		'verovenlo'					: { OrderInterface : 2779,	OrderSorting : 2779 },
		'verum'						: { OrderInterface : 2780,	OrderSorting : 2780 },
		'vet'						: { OrderInterface : 2781,	OrderSorting : 2781 },
		'veto'						: { OrderInterface : 2782,	OrderSorting : 2782 },
		'vex'						: { OrderInterface : 2783,	OrderSorting : 2783 },
		'vfhd'						: { OrderInterface : 2784,	OrderSorting : 2784 },
		'vhd'						: { OrderInterface : 2785,	OrderSorting : 2785 },
		'viazac'					: { OrderInterface : 2786,	OrderSorting : 2786 },
		'vid'						: { OrderInterface : 2787,	OrderSorting : 2787 },
		'videostar'					: { OrderInterface : 2788,	OrderSorting : 2788 },
		'videowelt'					: { OrderInterface : 2789,	OrderSorting : 2789 },
		'viethd'					: { OrderInterface : 2790,	OrderSorting : 2790 },
		'vigi'						: { OrderInterface : 2791,	OrderSorting : 2791 },
		'vinyl'						: { OrderInterface : 2792,	OrderSorting : 2792 },
		'vip3r'						: { OrderInterface : 2793,	OrderSorting : 2793 },
		'viper'						: { OrderInterface : 2794,	OrderSorting : 2794 },
		'viscabarca'					: { OrderInterface : 2795,	OrderSorting : 2795 },
		'visionx'					: { OrderInterface : 2796,	OrderSorting : 2796 },
		'vista'						: { OrderInterface : 2797,	OrderSorting : 2797 },
		'visum'						: { OrderInterface : 2798,	OrderSorting : 2798 },
		'vite'						: { OrderInterface : 2799,	OrderSorting : 2799 },
		'vivi'						: { OrderInterface : 2800,	OrderSorting : 2800 },
		'vixon'						: { OrderInterface : 2801,	OrderSorting : 2801 },
		'vlad'						: { OrderInterface : 2802,	OrderSorting : 2802 },
		'vlaluk'					: { OrderInterface : 2803,	OrderSorting : 2803 },
		'vlis'						: { OrderInterface : 2804,	OrderSorting : 2804 },
		'voa'						: { OrderInterface : 2805,	OrderSorting : 2805 },
		'vodtv'						: { OrderInterface : 2806,	OrderSorting : 2806 },
		'void'						: { OrderInterface : 2807,	OrderSorting : 2807 },
		'volatile'					: { OrderInterface : 2808,	OrderSorting : 2808 },
		'vomit'						: { OrderInterface : 2809,	OrderSorting : 2809 },
		'vox'						: { OrderInterface : 2810,	OrderSorting : 2810 },
		'voxhd'						: { OrderInterface : 2811,	OrderSorting : 2811 },
		'vppv'						: { OrderInterface : 2812,	OrderSorting : 2812 },
		'vr'							: { OrderInterface : 2813,	OrderSorting : 2813 },
		'vrs'						: { OrderInterface : 2814,	OrderSorting : 2814 },
		'vt'							: { OrderInterface : 2815,	OrderSorting : 2815 },
		'vtv'						: { OrderInterface : 2816,	OrderSorting : 2816 },
		'vxt'						: { OrderInterface : 2817,	OrderSorting : 2817 },
		'vyndros'					: { OrderInterface : 2818,	OrderSorting : 2818 },
		'vyto'						: { OrderInterface : 2819,	OrderSorting : 2819 },
		'w4f'						: { OrderInterface : 2820,	OrderSorting : 2820 },
		'wackos'					: { OrderInterface : 2821,	OrderSorting : 2821 },
		'waf'						: { OrderInterface : 2822,	OrderSorting : 2822 },
		'walmart'					: { OrderInterface : 2823,	OrderSorting : 2823 },
		'wam'						: { OrderInterface : 2824,	OrderSorting : 2824 },
		'warriors'					: { OrderInterface : 2825,	OrderSorting : 2825 },
		'waste'						: { OrderInterface : 2826,	OrderSorting : 2826 },
		'wat'						: { OrderInterface : 2827,	OrderSorting : 2827 },
		'watbath'					: { OrderInterface : 2828,	OrderSorting : 2828 },
		'watchable'					: { OrderInterface : 2829,	OrderSorting : 2829 },
		'watcher'					: { OrderInterface : 2830,	OrderSorting : 2830 },
		'watchmo'					: { OrderInterface : 2831,	OrderSorting : 2831 },
		'waters'					: { OrderInterface : 2832,	OrderSorting : 2832 },
		'wavey'						: { OrderInterface : 2833,	OrderSorting : 2833 },
		'wayne'						: { OrderInterface : 2834,	OrderSorting : 2834 },
		'wb'							: { OrderInterface : 2835,	OrderSorting : 2835 },
		'wbz'						: { OrderInterface : 2836,	OrderSorting : 2836 },
		'wdk'						: { OrderInterface : 2837,	OrderSorting : 2837 },
		'weasley'					: { OrderInterface : 2838,	OrderSorting : 2838 },
		'web4hd'					: { OrderInterface : 2839,	OrderSorting : 2839 },
		'webhiker'					: { OrderInterface : 2840,	OrderSorting : 2840 },
		'webster'					: { OrderInterface : 2841,	OrderSorting : 2841 },
		'webtiful'					: { OrderInterface : 2842,	OrderSorting : 2842 },
		'webtube'					: { OrderInterface : 2843,	OrderSorting : 2843 },
		'weby'						: { OrderInterface : 2844,	OrderSorting : 2844 },
		'welp'						: { OrderInterface : 2845,	OrderSorting : 2845 },
		'wem'						: { OrderInterface : 2846,	OrderSorting : 2846 },
		'wesen'						: { OrderInterface : 2847,	OrderSorting : 2847 },
		'west'						: { OrderInterface : 2848,	OrderSorting : 2848 },
		'westside'					: { OrderInterface : 2849,	OrderSorting : 2849 },
		'wgz'						: { OrderInterface : 2850,	OrderSorting : 2850 },
		'whatelse'					: { OrderInterface : 2851,	OrderSorting : 2851 },
		'whd'						: { OrderInterface : 2852,	OrderSorting : 2852 },
		'wheels'					: { OrderInterface : 2853,	OrderSorting : 2853 },
		'whiizz'					: { OrderInterface : 2854,	OrderSorting : 2854 },
		'whip93'					: { OrderInterface : 2855,	OrderSorting : 2855 },
		'whisky'					: { OrderInterface : 2856,	OrderSorting : 2856 },
		'whitehat'					: { OrderInterface : 2857,	OrderSorting : 2857 },
		'whiterevtmp'				: { OrderInterface : 2858,	OrderSorting : 2858 },
		'whiterhino'					: { OrderInterface : 2859,	OrderSorting : 2859 },
		'whoknow'					: { OrderInterface : 2860,	OrderSorting : 2860 },
		'whosnext'					: { OrderInterface : 2861,	OrderSorting : 2861 },
		'wide'						: { OrderInterface : 2862,	OrderSorting : 2862 },
		'wihd'						: { OrderInterface : 2863,	OrderSorting : 2863 },
		'wiifi'						: { OrderInterface : 2864,	OrderSorting : 2864 },
		'wiki'						: { OrderInterface : 2865,	OrderSorting : 2865 },
		'wildcat'					: { OrderInterface : 2866,	OrderSorting : 2866 },
		'wilder'					: { OrderInterface : 2867,	OrderSorting : 2867 },
		'will1869'					: { OrderInterface : 2868,	OrderSorting : 2868 },
		'wind'						: { OrderInterface : 2869,	OrderSorting : 2869 },
		'wing'						: { OrderInterface : 2870,	OrderSorting : 2870 },
		'winks'						: { OrderInterface : 2871,	OrderSorting : 2871 },
		'winters'					: { OrderInterface : 2872,	OrderSorting : 2872 },
		'wire'						: { OrderInterface : 2873,	OrderSorting : 2873 },
		'wishtv'					: { OrderInterface : 2874,	OrderSorting : 2874 },
		'wlm'						: { OrderInterface : 2875,	OrderSorting : 2875 },
		'wman'						: { OrderInterface : 2876,	OrderSorting : 2876 },
		'wmt'						: { OrderInterface : 2877,	OrderSorting : 2877 },
		'woat'						: { OrderInterface : 2878,	OrderSorting : 2878 },
		'wolf'						: { OrderInterface : 2879,	OrderSorting : 2879 },
		'wolfpack'					: { OrderInterface : 2880,	OrderSorting : 2880 },
		'wolverdonfilmes'			: { OrderInterface : 2881,	OrderSorting : 2881 },
		'wombat'					: { OrderInterface : 2882,	OrderSorting : 2882 },
		'woody'						: { OrderInterface : 2883,	OrderSorting : 2883 },
		'worldfree4u'				: { OrderInterface : 2884,	OrderSorting : 2884 },
		'worldmkv'					: { OrderInterface : 2885,	OrderSorting : 2885 },
		'wow'						: { OrderInterface : 2886,	OrderSorting : 2886 },
		'wowrip'					: { OrderInterface : 2887,	OrderSorting : 2887 },
		'wpi'						: { OrderInterface : 2888,	OrderSorting : 2888 },
		'wrcr'						: { OrderInterface : 2889,	OrderSorting : 2889 },
		'wrd'						: { OrderInterface : 2890,	OrderSorting : 2890 },
		'wrs'						: { OrderInterface : 2891,	OrderSorting : 2891 },
		'wuruhi'					: { OrderInterface : 2892,	OrderSorting : 2892 },
		'wutang'					: { OrderInterface : 2893,	OrderSorting : 2893 },
		'wvf'						: { OrderInterface : 2894,	OrderSorting : 2894 },
		'wwrg'						: { OrderInterface : 2895,	OrderSorting : 2895 },
		'x0r'						: { OrderInterface : 2896,	OrderSorting : 2896 },
		'xanax'						: { OrderInterface : 2897,	OrderSorting : 2897 },
		'xander'					: { OrderInterface : 2898,	OrderSorting : 2898 },
		'xannyfamily'				: { OrderInterface : 2899,	OrderSorting : 2899 },
		'xbay'						: { OrderInterface : 2900,	OrderSorting : 2900 },
		'xc'							: { OrderInterface : 2901,	OrderSorting : 2901 },
		'xd2v'						: { OrderInterface : 2902,	OrderSorting : 2902 },
		'xdr'						: { OrderInterface : 2903,	OrderSorting : 2903 },
		'xf'							: { OrderInterface : 2904,	OrderSorting : 2904 },
		'xhd'						: { OrderInterface : 2905,	OrderSorting : 2905 },
		'xibirikinho'				: { OrderInterface : 2906,	OrderSorting : 2906 },
		'xii'						: { OrderInterface : 2907,	OrderSorting : 2907 },
		'xlf'						: { OrderInterface : 2908,	OrderSorting : 2908 },
		'xme'						: { OrderInterface : 2909,	OrderSorting : 2909 },
		'xor'						: { OrderInterface : 2910,	OrderSorting : 2910 },
		'xorbitant'					: { OrderInterface : 2911,	OrderSorting : 2911 },
		'xoxo'						: { OrderInterface : 2912,	OrderSorting : 2912 },
		'xpau'						: { OrderInterface : 2913,	OrderSorting : 2913 },
		'xpert'						: { OrderInterface : 2914,	OrderSorting : 2914 },
		'xpoz'						: { OrderInterface : 2915,	OrderSorting : 2915 },
		'xpress'					: { OrderInterface : 2916,	OrderSorting : 2916 },
		'xred'						: { OrderInterface : 2917,	OrderSorting : 2917 },
		'xrg'						: { OrderInterface : 2918,	OrderSorting : 2918 },
		'xs'							: { OrderInterface : 2919,	OrderSorting : 2919 },
		'xshd'						: { OrderInterface : 2920,	OrderSorting : 2920 },
		'xstreem'					: { OrderInterface : 2921,	OrderSorting : 2921 },
		'xtm'						: { OrderInterface : 2922,	OrderSorting : 2922 },
		'xtrill'					: { OrderInterface : 2923,	OrderSorting : 2923 },
		'xtsf'						: { OrderInterface : 2924,	OrderSorting : 2924 },
		'xv'							: { OrderInterface : 2925,	OrderSorting : 2925 },
		'xvik'						: { OrderInterface : 2926,	OrderSorting : 2926 },
		'xwt'						: { OrderInterface : 2927,	OrderSorting : 2927 },
		'xxunkn0wnxx'				: { OrderInterface : 2928,	OrderSorting : 2928 },
		'xxxpav69'					: { OrderInterface : 2929,	OrderSorting : 2929 },
		'xyz'						: { OrderInterface : 2930,	OrderSorting : 2930 },
		'ya'							: { OrderInterface : 2931,	OrderSorting : 2931 },
		'yakuza'					: { OrderInterface : 2932,	OrderSorting : 2932 },
		'yazoomix'					: { OrderInterface : 2933,	OrderSorting : 2933 },
		'yellowbird'					: { OrderInterface : 2934,	OrderSorting : 2934 },
		'yestv'						: { OrderInterface : 2935,	OrderSorting : 2935 },
		'yfn'						: { OrderInterface : 2936,	OrderSorting : 2936 },
		'yg'							: { OrderInterface : 2937,	OrderSorting : 2937 },
		'yifi'						: { OrderInterface : 2938,	OrderSorting : 2938 },
		'yify'						: { OrderInterface : 2939,	OrderSorting : 2939 },
		'yn1d'						: { OrderInterface : 2940,	OrderSorting : 2940 },
		'yogi'						: { OrderInterface : 2941,	OrderSorting : 2941 },
		'yol0w'						: { OrderInterface : 2942,	OrderSorting : 2942 },
		'yourmom'					: { OrderInterface : 2943,	OrderSorting : 2943 },
		'yoyo'						: { OrderInterface : 2944,	OrderSorting : 2944 },
		'ys'							: { OrderInterface : 2945,	OrderSorting : 2945 },
		'ysteam'					: { OrderInterface : 2946,	OrderSorting : 2946 },
		'yt'							: { OrderInterface : 2947,	OrderSorting : 2947 },
		'yts'						: { OrderInterface : 2948,	OrderSorting : 2948 },
		'yuma'						: { OrderInterface : 2949,	OrderSorting : 2949 },
		'zaeem'						: { OrderInterface : 2950,	OrderSorting : 2950 },
		'zagon'						: { OrderInterface : 2951,	OrderSorting : 2951 },
		'zan'						: { OrderInterface : 2952,	OrderSorting : 2952 },
		'zechs'						: { OrderInterface : 2953,	OrderSorting : 2953 },
		'zeiz'						: { OrderInterface : 2954,	OrderSorting : 2954 },
		'zeke'						: { OrderInterface : 2955,	OrderSorting : 2955 },
		'zektorm'					: { OrderInterface : 2956,	OrderSorting : 2956 },
		'zel'						: { OrderInterface : 2957,	OrderSorting : 2957 },
		'zen'						: { OrderInterface : 2958,	OrderSorting : 2958 },
		'zenbud'					: { OrderInterface : 2959,	OrderSorting : 2959 },
		'zer0'						: { OrderInterface : 2960,	OrderSorting : 2960 },
		'zero'						: { OrderInterface : 2961,	OrderSorting : 2961 },
		'zest'						: { OrderInterface : 2962,	OrderSorting : 2962 },
		'zeus'						: { OrderInterface : 2963,	OrderSorting : 2963 },
		'zeusdias'					: { OrderInterface : 2964,	OrderSorting : 2964 },
		'zinc'						: { OrderInterface : 2965,	OrderSorting : 2965 },
		'zit'						: { OrderInterface : 2966,	OrderSorting : 2966 },
		'zito'						: { OrderInterface : 2967,	OrderSorting : 2967 },
		'zmachine'					: { OrderInterface : 2968,	OrderSorting : 2968 },
		'zman'						: { OrderInterface : 2969,	OrderSorting : 2969 },
		'zmg'						: { OrderInterface : 2970,	OrderSorting : 2970 },
		'zmnt'						: { OrderInterface : 2971,	OrderSorting : 2971 },
		'zodiac'					: { OrderInterface : 2972,	OrderSorting : 2972 },
		'zonatorrent2'				: { OrderInterface : 2973,	OrderSorting : 2973 },
		'zoneempire'					: { OrderInterface : 2974,	OrderSorting : 2974 },
		'zoom'						: { OrderInterface : 2975,	OrderSorting : 2975 },
		'zq'							: { OrderInterface : 2976,	OrderSorting : 2976 },
		'zr'							: { OrderInterface : 2977,	OrderSorting : 2977 },
		'zs'							: { OrderInterface : 2978,	OrderSorting : 2978 },
		'zsewdc'					: { OrderInterface : 2979,	OrderSorting : 2979 },
		'zsiso'						: { OrderInterface : 2980,	OrderSorting : 2980 },
		'ztorrenter'					: { OrderInterface : 2981,	OrderSorting : 2981 },
		'zuzuu'						: { OrderInterface : 2982,	OrderSorting : 2982 },
		'zw'							: { OrderInterface : 2983,	OrderSorting : 2983 },
		'zza'						: { OrderInterface : 2984,	OrderSorting : 2984 },
		'zzgtv'						: { OrderInterface : 2985,	OrderSorting : 2985 },
	}

	##############################################################################
	# RELEASE UPLOADER
	##############################################################################

	LabelReleaseUploader = {
		LabelDefault : {
			LabelList1		: LabelShort,
			LabelList2		: LabelShort,
			LabelList3		: LabelShort,
			LabelList4		: LabelHidden,
			LabelInfo1		: LabelLong,
			LabelInfo2		: LabelHidden,
			LabelSettings1	: LabelMedium,
			LabelSettings2	: LabelHidden,
		},
	}

	##############################################################################
	# EXCLUSION
	##############################################################################

	ExclusionDuplicate	= 'duplicate'
	ExclusionRelease	= 'release'
	ExclusionKeyword	= 'keyword'
	ExclusionMetadata	= 'metadata'
	ExclusionFormat		= 'format'
	ExclusionFake		= 'fake'
	ExclusionSupport	= 'support'
	ExclusionBlocked	= 'blocked'
	ExclusionCaptcha	= 'captcha'
	ExclusionPrecheck	= 'precheck'

	LabelExclusion = {
		LabelDefault : {
			LabelList1		: LabelMedium,
			LabelList2		: LabelMedium,
			LabelList3		: LabelMedium,
			LabelList4		: LabelMedium,
			LabelInfo1		: LabelLong,
			LabelInfo2		: LabelHidden,
			LabelSettings1	: LabelLong,
			LabelSettings2	: LabelHidden,
		},

		ExclusionDuplicate	: { LabelShort : 'DUP',	LabelMedium : 'DUPLICATE',		LabelLong : 'Duplicate Link' },
		ExclusionRelease	: { LabelShort : 'REL',	LabelMedium : 'RELEASE',		LabelLong : 'Invalid Release' },
		ExclusionKeyword	: { LabelShort : 'KEY',	LabelMedium : 'KEYWORD',		LabelLong : 'Prohibited Keyword' },
		ExclusionMetadata	: { LabelShort : 'INV',	LabelMedium : 'INVALID',		LabelLong : 'Invalid Metadata' },
		ExclusionFormat		: { LabelShort : 'FMT',	LabelMedium : 'FORMAT',			LabelLong : 'Incorrect Format' },
		ExclusionFake		: { LabelShort : 'FKE',	LabelMedium : 'FAKE',			LabelLong : 'Fake Upload' },
		ExclusionSupport	: { LabelShort : 'USP',	LabelMedium : 'UNSUPPORTED',	LabelLong : 'Unsupported Stream' },
		ExclusionBlocked	: { LabelShort : 'BLK',	LabelMedium : 'BLOCKED',		LabelLong : 'Blocked Hoster' },
		ExclusionCaptcha	: { LabelShort : 'CAP',	LabelMedium : 'CAPTCHA',		LabelLong : 'Captcha Protected' },
		ExclusionPrecheck	: { LabelShort : 'PRE',	LabelMedium : 'PRECHECK',		LabelLong : 'Precheck Failure' },
	}

	ExclusionData = None

	##############################################################################
	# INFO
	##############################################################################

	InfoCustom	= 'custom'

	LabelInfo = {
		LabelDefault : {
			LabelList1		: LabelMedium,
			LabelList2		: LabelMedium,
			LabelList3		: LabelMedium,
			LabelList4		: LabelMedium,
			LabelInfo1		: LabelLong,
			LabelInfo2		: LabelHidden,
			LabelSettings1	: LabelLong,
			LabelSettings2	: LabelHidden,
		},

		InfoCustom			: { LabelShort : 'CUS',	LabelMedium : 'CUSTOM',		LabelLong : 'Custom Link' },
	}

	##############################################################################
	# INVALID
	##############################################################################

	InvalidMedia	= 'media'
	InvalidTitle	= 'title'
	InvalidYear		= 'year'
	InvalidNumber	= 'number'
	InvalidRelease	= 'release'
	InvalidKeyword	= 'keyword'
	InvalidMetadata	= 'metadata'
	InvalidFormat	= 'format'
	InvalidFake		= 'fake'
	InvalidBlocked	= 'blocked'
	InvalidSize		= 'size'
	InvalidTime		= 'time'
	InvalidSeed		= 'seed'
	InvalidLeech	= 'leech'
	InvalidPeer		= 'peer'

	InvalidData = []
	InvalidExtract = None

	##############################################################################
	# CONSTRUCTOR
	##############################################################################

	'''
		FUNCTION:
			Constructs a new empty metadata object.
		PARAMETERS:
			other: Optional parameters equivalent to those in the load() function.
	'''
	def __init__(self, **kwargs):
		Serializer.__init__(self)

		# Overwrite class method with the instance method.
		# Allows these methods to be called with an instance or with a class.
		self.load = self._load
		self.idGenerate = self._idGenerate
		self.metaSpecial = self._metaSpecial
		self.valid = self._valid
		self.invalidate = self._invalidate
		self.validName = self._validName
		self.titleValid = self._titleValid
		self.titleValidQuick = self._titleValidQuick
		self.titleProhibited = self._titleProhibited
		self.yearValid = self._yearValid
		self.numberShowValid = self._numberShowValid
		self.numberSpecialValid = self._numberSpecialValid
		self.numberSeasonValid = self._numberSeasonValid
		self.numberEpisodeValid = self._numberEpisodeValid
		self.linkValid = self._linkValid
		self.fileNameIncomplete = self._fileNameIncomplete
		self.fileNameValid = self._fileNameValid
		self.fileSizeValid = self._fileSizeValid
		self.sourceTimeValid = self._sourceTimeValid
		self.sourcePeersValid = self._sourcePeersValid
		self.sourceSeedsValid = self._sourceSeedsValid
		self.sourceLeechesValid = self._sourceLeechesValid
		self.releaseValid = self._releaseValid

		self.mThreshold = {
			'size' : {
				'common' : None,
				'movie' : None,
				'show' : None,
				'episode' : None,
			},
			'fake' : None,
			'time' : None,
			'peers' : None,
			'seeds' : None,
			'leeches' : None,
		}

		self.mData = {
			'id' : {
				Stream.IdCategoryImdb : {
					Stream.IdTypeMovie : None,
					Stream.IdTypeCollection : None,
					Stream.IdTypeShow : None,
					Stream.IdTypeSeason : None,
					Stream.IdTypeEpisode : None,
				},
				Stream.IdCategoryTmdb : {
					Stream.IdTypeMovie : None,
					Stream.IdTypeCollection : None,
					Stream.IdTypeShow : None,
					Stream.IdTypeSeason : None,
					Stream.IdTypeEpisode : None,
				},
				Stream.IdCategoryTvdb : {
					Stream.IdTypeMovie : None,
					Stream.IdTypeCollection : None,
					Stream.IdTypeShow : None,
					Stream.IdTypeSeason : None,
					Stream.IdTypeEpisode : None,
				},
				Stream.IdCategoryTrakt : {
					Stream.IdTypeMovie : None,
					Stream.IdTypeCollection : None,
					Stream.IdTypeShow : None,
					Stream.IdTypeSeason : None,
					Stream.IdTypeEpisode : None,
				},
				Stream.IdCategorySlug : {
					Stream.IdTypeMovie : None,
					Stream.IdTypeCollection : None,
					Stream.IdTypeShow : None,
					Stream.IdTypeSeason : None,
					Stream.IdTypeEpisode : None,
				},

				Stream.IdCategoryProvider : {
					Stream.IdTypeLocal : None,
					Stream.IdTypeUniversal : None,
					Stream.IdTypeCollection : None,
					Stream.IdTypeItem : None,
				},

				Stream.IdCategoryGaia : {
					Stream.IdTypeStream : None,
				},

				Stream.IdCategoryOrion : {
					Stream.IdTypeStream : None,
					Stream.IdTypeMovie : None,
					Stream.IdTypeCollection : None,
					Stream.IdTypeShow : None,
					Stream.IdTypeSeason : None,
					Stream.IdTypeEpisode : None,
					Stream.IdTypeData : None,
				},
			},
			'meta' : {
				'media' : None,
				'niche' : None,
				'title' : None,
				'year' : None,
				'time' : None,
				'season' : None,
				'episode' : None,
				'number' : None,
				'language' : None,
				'country' : None,
				'network' : None,
				'studio' : None,
				'duration' : None,
				'pack' : None,
			},
			'number' : {
				'collection' : None,
				'season' : None,
				'episode' : None,
			},
			'link' : {
				'original' : None,
				'provider' : None,
			},
			'hash' : {
				Stream.HashTypeContainer : {},
				Stream.HashTypeFile : {},
				Stream.HashTypeOther : {},
			},
			'video' : {
				'quality' : {
					'exact' : None,
					'inexact' : None,
				},
				'resolution' : {
					'exact' : {
						Stream.VideoWidth : None,
						Stream.VideoHeight : None,
					},
					'inexact' : {
						Stream.VideoWidth : None,
						Stream.VideoHeight : None,
					},
				},
				'aspect' : {
					'exact' : None,
					'inexact' : None,
				},
				'codec' : None,
				'depth' : None,
				'range' : None,
				'3d' : None,
			},
			'audio' : {
				'type' : None,
				'channels' : None,
				'system' : None,
				'codec' : None,
				'language' : None,
				'default' : None,
			},
			'subtitle' : {
				'type' : None,
				'language' : None,
			},
			'release' : {
				'type' : None,
				'format' : None,
				'edition' : None,
				'network' : None,
				'group' : None,
				'uploader' : None,
			},
			'file' : {
				'name' : {
					'raw' : None,
					'exact' : None,
					'inexact' : None,
				},
				'extra' : None,
				'size' : {
					'exact' : None,
					'inexact' : None,
				},
				'container' : None,
				'pack' : None,
			},
			'source' : {
				'type' : None,
				'peers' : {
					'seeds' : {
						'exact' : None,
						'inexact' : None,
					},
					'leeches' : {
						'exact' : None,
						'inexact' : None,
					},
				},
				'time' : {
					'exact' : None,
					'inexact' : None,
				},
				'approval' : None,
				'popularity' : None,
				'origin' : None,
				'provider' : None,
				'publisher' : None,
				'hoster' : None,
				'resolved' : None, # Resolved Hoster
			},
			'access' : {
				'type' : {
					Stream.AccessTypeDebrid : None,
					Stream.AccessTypeCache : None,
					Stream.AccessTypeOffline : None,
					Stream.AccessTypeDirect : None,
					Stream.AccessTypeMember : None,
					Stream.AccessTypeOpen : None,
					Stream.AccessTypeOrion : None,
				},
				'debrid' : {
					Stream.AccessDebridPremiumize : None,
					Stream.AccessDebridOffcloud : None,
					Stream.AccessDebridTorbox : None,
					Stream.AccessDebridEasydebrid : None,
					Stream.AccessDebridRealdebrid : None,
					Stream.AccessDebridDebridlink : None,
					Stream.AccessDebridAlldebrid : None,
					Stream.AccessDebridLinksnappy : None,
					Stream.AccessDebridMegadebrid : None,
					Stream.AccessDebridRapidpremium : None,
					Stream.AccessDebridSimplydebrid : None,
					Stream.AccessDebridSmoozed : None,
				},
				'cache' : {
					Stream.AccessDebridPremiumize : {
						'exact' : None,
						'inexact' : None,
						'time' : None,
					},
					Stream.AccessDebridOffcloud : {
						'exact' : None,
						'inexact' : None,
						'time' : None,
					},
					Stream.AccessDebridTorbox : {
						'exact' : None,
						'inexact' : None,
						'time' : None,
					},
					Stream.AccessDebridEasydebrid : {
						'exact' : None,
						'inexact' : None,
						'time' : None,
					},
					Stream.AccessDebridRealdebrid : {
						'exact' : None,
						'inexact' : None,
						'time' : None,
					},
					Stream.AccessDebridDebridlink : {
						'exact' : None,
						'inexact' : None,
						'time' : None,
					},
					Stream.AccessDebridAlldebrid : {
						'exact' : None,
						'inexact' : None,
						'time' : None,
					},
					Stream.AccessDebridLinksnappy : {
						'exact' : None,
						'inexact' : None,
						'time' : None,
					},
					Stream.AccessDebridMegadebrid : {
						'exact' : None,
						'inexact' : None,
						'time' : None,
					},
					Stream.AccessDebridRapidpremium : {
						'exact' : None,
						'inexact' : None,
						'time' : None,
					},
					Stream.AccessDebridSimplydebrid : {
						'exact' : None,
						'inexact' : None,
						'time' : None,
					},
					Stream.AccessDebridSmoozed : {
						'exact' : None,
						'inexact' : None,
						'time' : None,
					},
				},
			},
			'segment' : {
				'first' : None,
				'last' : None,
				'list' : None,
			},
			'provider' : {
				'id' : None,
				'data' : None,
			},
			'stream' : {
				'success' : None,
				'error' : None,
				'id' : None,
				'link' : None,
				'items' : None,
				'notification' : None,
				'category' : None,
				'handle' : None,
			},
			'validation' : {
				'release' : None,
				'keyword' : None,
				'format' : None,
				'fake' : None,
				'size' : None,
				'time' : None,
				'peers' : None,
				'seeds' : None,
				'leeches' : None,
			},
			'exclusion' : {
				'duplicate' : None,
				'release' : None,
				'keyword' : None,
				'metadata' : None,
				'format' : None,
				'fake' : None,
				'support' : None,
				'blocked' : None,
				'captcha' : None,
				'precheck' : None,
			},
			'info' : {
				'termination' : [],
				'exact' : None,
				'custom' : None,
				'sort' : None,
				'language' : None,
				'query' : None,
				'cache' : None,
				'identifier' : None,
			},
		}
		if len(kwargs) > 0:
			if not 'validate' in kwargs: kwargs['validate'] = False
			self.load(**kwargs)

	##############################################################################
	# RESET
	##############################################################################

	@classmethod
	def reset(self, settings = True, full = True, invalid = True):
		self._cacheClear()
		self._statisticsClear()
		self._titleMatchClear()

		if settings:
			Stream.ExclusionData = None
			Stream.SettingsLanguage = None
			Stream.SettingsUsage = None

		if full:
			Manager.reset(settings = settings)
			Settings.reset(settings = settings)
			Filters.reset(settings = settings)
			Termination.reset(settings = settings)
			Layout.reset(settings = settings)

		if invalid: self.invalidClear()

	##############################################################################
	# PERFORMANCE
	##############################################################################

	@classmethod
	def performance(self):
		if Stream.Performance is None: Stream.Performance = tools.Hardware.performanceRating()
		return Stream.Performance

	##############################################################################
	# STATISTICS
	##############################################################################

	@classmethod
	def statistics(self):
		return Stream.Statistics

	@classmethod
	def statisticsSummary(self):
		result = {}
		for type in [Stream.StatisticGlobal, Stream.StatisticExtracted, Stream.StatisticCached, Stream.StatisticImported, Stream.StatisticFailed]:
			result[type] = {
				'count' : 0,
				'total' : 0,
				'average' : 0,
				'minimum' : 0,
				'maximum' : 0,
			}

		for statistic in Stream.Statistics:
			type = statistic['type']
			duration = statistic['duration']
			result[type]['count'] += 1
			result[type]['total'] += duration
			if not result[type]['minimum'] or duration < result[type]['minimum']: result[type]['minimum'] = duration
			if not result[type]['maximum'] or duration > result[type]['maximum']: result[type]['maximum'] = duration

		count = 0
		total = 0
		minimum = 0
		maximum = 0
		for type in [Stream.StatisticExtracted, Stream.StatisticCached, Stream.StatisticImported, Stream.StatisticFailed]:
			result[type]['average'] = (result[type]['total'] / result[type]['count']) if result[type]['count'] else 0
			count += result[type]['count']
			total += result[type]['total']
			if not minimum or result[type]['minimum'] < minimum: minimum = result[type]['minimum']
			if not maximum or result[type]['maximum'] > maximum: maximum = result[type]['maximum']

		result[Stream.StatisticGlobal]['count'] = count
		result[Stream.StatisticGlobal]['total'] = total
		result[Stream.StatisticGlobal]['average'] = (total / count) if count else 0
		result[Stream.StatisticGlobal]['minimum'] = minimum
		result[Stream.StatisticGlobal]['maximum'] = maximum

		return result

	@classmethod
	def statisticsUpdate(self, type = None, timer = None, statistics = None):
		if statistics is None: Stream.Statistics.append({'type' : type, 'duration' : timer.elapsed(milliseconds = True)})
		else: Stream.Statistics.extend(statistics)

	@classmethod
	def _statisticsClear(self):
		Stream.Statistics = []

	##############################################################################
	# LOAD
	##############################################################################

	'''
		FUNCTION:
			Loads metadata in different/alternative ways:
				1. If the "data" parameter is provided, load the metadata from a dictionary, JSON string, or other Stream object.
				2. If the "extract" parameter is True and a "fileName" or "link" is provided, extract the metadata from the file name.
				3. Specify individual parameters to be set.
			Can be called on an instance (returns True/False), or on the class (returns Stream object on successful validation and None on failed validation).
		THREADING:
			When loading (extracting and/or validating) metadata from multiple parallel threads, it is about twice as slow than executing sequentially.
			This is due to Python's GIL which allows the code of only a single thread to be executed at any time.
			This is not problematic if the threads' code is not computationally expensive.
			However, if the threads' code is computationally expensive, execution slows down considerably, since Python constantly switches between threads executing some of the code, pausing, and switching to another thread.
			If the "lock" parameter is True, a global lock is used to only allow a single thread to execute the load() function at any give time.
			Locking adds about 1-6% time overhead, whereas using no locking adds about 100-185% time overhead.
		PARAMETERS:
			data (None/dictionary): An optional dictionary, JSON string, or Stream object to load the data from.
			extractor (boolean): Wether or not to use the Extractor class to extract metadata from a file.
			extract (boolean): Whether or not to extract the metadata from the file name or link.
			cache (boolean): Whether or not to load/save the metadata from/to cache if the file name was already processed previously.
			lock (boolean): Whether or not to use a global lock to only allow a single thread to execute the load() function at any give time, improving the overall execution time.
			validate (boolean/ValidateLenient): Validate the metadata while extracting it. This is more efficient that extracting everything from the file name and validating only afterwards. This stops the extraction the moment validation fails.
			validateAdjust (float): An adjustment ratio to multiple title validation thresholds with, used to make file name matching stricter (values in (1,inf]) or more lenient (value in [0,1)).
			validate<XXX> (boolean): Whether or not to validate specific attributes. Can be used to disable certain validation steps if the attribute is known to be correct.
			id<XXX> (various): The various IDs.
			meta<XXX> (various): The target metadata that the file is expected to adhere to. Eg: metaSeason is the season we are looking for, and not the season extracted from the file name.
			number<XXX> (integer/list): The season and episode numbers.
			link (string/list): One or more links.
			video/audio/subtitle/release/file<XXX> (various): The metadata of the file. If these parameters are not provided, they will be extracted from the file name.
			source<XXX> (various): Additional source attributes that can be provided. These attributes cannot be extracted from the file name.
			access<XXX> (various): Additional access attributes that can be provided. These attributes cannot be extracted from the file name.
			segment<XXX> (various): Additional NZB segment attributes that can be provided. These attributes cannot be extracted from the file name.
			threshold<XXX> (various): Custom thresholds. If None, the default threshold is used.
		RETURNS:
			When the function is called on an instance: True if the extraction and validation was successful. False if the validation failed.
			When the function is called on the class: Stream object if the extraction and validation was successful. None if the validation failed.
	'''
	@classmethod
	def load(self, **kwargs):
		if 'data' in kwargs:
			data = kwargs.get('data')
			if tools.Tools.isInstance(data, Stream): return data
		instance = Stream()
		if instance.__load(**kwargs): return instance
		else: return None

	def _load(self, **kwargs):
		return self.__load(**kwargs)

	def __load(self,
		data = None,
		reload = False,
		extractor = False,
		extract = True,
		cache = True,
		lock = True,

		validate = True,
		validateAdjust = None,
		validateTitle = True,
		validateYear = True,
		validateShow = True,
		validateSeason = True,
		validateEpisode = True,
		validateLink = True,
		validateRelease = True,
		validateKeyword = True,
		validateFormat = True,
		validateFake = True,
		validateSize = True,
		validateTime = True,
		validatePeers = True,
		validateSeeds = True,
		validateLeeches = True,

		idGaiaItem = None,
		idGaiaStream = None,

		idOrionStream = None,
		idOrionMovie = None,
		idOrionCollection = None,
		idOrionShow = None,
		idOrionSeason = None,
		idOrionEpisode = None,
		idOrionData = None,

		idProviderLocal = None,
		idProviderUniversal = None,
		idProviderCollection = None,
		idProviderItem = None,

		idImdb = None,
		idTmdb = None,
		idTvdb = None,
		idTrakt = None,
		idSlug = None,

		metaMedia = None,
		metaNiche = None,
		metaTitle = None,
		metaYear = None,
		metaTime = None,
		metaSeason = None,
		metaEpisode = None,
		metaNumber = None,
		metaLanguage = None,
		metaCountry = None,
		metaNetwork = None,
		metaStudio = None,
		metaDuration = None,
		metaPack = None,

		numberCollection = None,
		numberSeason = None,
		numberEpisode = None,

		link = None,

		hash = None,
		hashContainer = None,
		hashContainerUnknown = None,
		hashContainerMd5 = None,
		hashContainerSha1 = None,
		hashContainerSha256 = None,
		hashContainerSha512 = None,
		hashFile = None,
		hashFileUnknown = None,
		hashFileMd5 = None,
		hashFileSha1 = None,
		hashFileSha256 = None,
		hashFileSha512 = None,
		hashOther = None,
		hashOtherUnknown = None,
		hashOtherMd5 = None,
		hashOtherSha1 = None,
		hashOtherSha256 = None,
		hashOtherSha512 = None,

		videoQuality = None,
		videoQualityInexact = None,
		videoResolution = None,
		videoResolutionInexact = None,
		videoWidth = None,
		videoWidthInexact = None,
		videoHeight = None,
		videoHeightInexact = None,
		videoAspect = None,
		videoAspectInexact = None,
		videoCodec = None,
		videoDepth = None,
		videoRange = None,
		video3d = None,

		audioType = None,
		audioChannels = None,
		audioSystem = None,
		audioCodec = None,
		audioLanguage = None,
		audioLanguageInexact = None, # Added to the languages extracted from the file name.

		subtitleType = None,
		subtitleLanguage = None,
		subtitleLanguageInexact = None, # Added to the languages extracted from the file name.

		releaseType = None,
		releaseFormat = None,
		releaseEdition = None,
		releaseNetwork = None,
		releaseGroup = None,
		releaseUploader = None,

		fileName = None, # If True, will generate a file name from the metadata.
		fileNameInexact = None, # If True, will generate a file name  from the metadata.
		fileNameProcess = None, # A function that takes a string and returns a string. Additional processing after the filename was cleaned.
		fileExtra = None,
		fileSize = None,
		fileSizeInexact = None,
		fileContainer = None,
		filePack = None,

		sourceType = None,
		sourceSeeds = None,
		sourceSeedsInexact = None,
		sourceLeeches = None,
		sourceLeechesInexact = None,
		sourceTime = None,
		sourceTimeInexact = None,
		sourceTimeFormat = None, # Custom date/time format string.
		sourcePopularity = None,
		sourceApproval = None,
		sourceOrigin = None,
		sourceProvider = None,
		sourcePublisher = None,
		sourceHoster = None,

		accessType = None,
		accessOffline = None,
		accessDirect = None,
		accessMember = None,
		accessOpen = None,
		accessOrion = None,
		accessDebrid = None,
		accessCache = None,
		accessCacheInexact = None,

		segment = None,
		segmentFirst = None,
		segmentLargest = None,
		segmentList = None,

		exclusionDuplicate = None,
		exclusionRelease = None,
		exclusionKeyword = None,
		exclusionMetadata = None,
		exclusionFormat = None,
		exclusionFake = None,
		exclusionSupport = None,
		exclusionBlocked = None,
		exclusionCaptcha = None,
		exclusionPrecheck = None,

		infoTermination = None,
		infoExact = None,
		infoCustom = None,
		infoSort = None,
		infoLanguage = None,
		infoQuery = None,

		thresholdFake = None,
		thresholdSize = None,
		thresholdTime = None,
		thresholdPeers = None,
		thresholdSeeds = None,
		thresholdLeeches = None,
	):
		try:
			self.lock(lock)
			timer = tools.Time(start = True, mode = tools.Time.ModeThread) # Not sure if ModeThread is the most accurate, but it seems to be on par with what is expected.

			def cacheInvalid(id, cache, lock):
				if cache and not id is None: self._cacheId(id, False)
				self.unlock(lock)
				self.statisticsUpdate(type = Stream.StatisticFailed, timer = timer)
				return False

			if extractor and link:
				extractor = Extractor().extract(link)
				if extractor:
					if not fileName:
						try: fileName = extractor['name']
						except: pass
					if not fileSize:
						try: fileSize = extractor['size']
						except: pass
					if not fileContainer:
						try: fileContainer = extractor['container']
						except: pass
					if not videoWidth:
						try: videoWidth = extractor['video']['width']
						except: pass
					if not videoHeight:
						try: videoHeight = extractor['video']['height']
						except: pass
					if not videoAspect:
						try: videoAspect = extractor['video']['aspectratio']
						except: pass
					if not videoCodec:
						try: videoCodec = extractor['video']['codec']
						except: pass
					if not videoDepth:
						try: videoDepth = extractor['video']['bitdepth']
						except: pass
					if not audioChannels:
						try: audioChannels = extractor['audio']['channels']
						except: pass
					if not audioCodec:
						try: audioCodec = extractor['audio']['codec']
						except: pass
					if not audioLanguage:
						try: audioLanguage = extractor['audio']['language']
						except: pass
					if not subtitleLanguage:
						try: subtitleLanguage = extractor['subtitle']['language']
						except: pass

			processed = not extract # Must be set before "extract = False" is changed below.

			if reload:
				if metaMedia is None: metaMedia = self.metaMedia()
				if metaNiche is None: metaNiche = self.metaNiche()
				if metaTitle is None: metaTitle = self.metaTitle(title = Stream.TitleNone) # TitleNone: make sure to retireve the entire ditionary of titles.
				if metaYear is None: metaYear = self.metaYear()
				if metaTime is None: metaTime = self.metaTime()
				if metaSeason is None: metaSeason = self.metaSeason()
				if metaEpisode is None: metaEpisode = self.metaEpisode()
				if metaNumber is None: metaNumber = self.metaNumber()
				if metaLanguage is None: metaLanguage = self.metaLanguage()
				if metaCountry is None: metaCountry = self.metaCountry()
				if metaNetwork is None: metaNetwork = self.metaNetwork()
				if metaStudio is None: metaStudio = self.metaStudio()
				if metaPack is None: metaPack = self.metaPack()
				if metaDuration is None: metaDuration = self.metaDuration()

			link = self.linkClean(link)
			if fileName is True or self.__fileNameIncomplete(fileName): # Also try to extract if the filename is cut off (ends with ...).
				if link:
					fileNameNew = self.fileNameExtract(data = link)
					if fileName is True: fileName = fileNameNew
					elif fileNameNew: fileName = fileNameNew
				if fileName is True or not fileName:
					if fileNameInexact is None: fileNameInexact = True
					fileName = None
			elif not fileName and link: # When reloaded or when extracting name form the file name.
				fileNameCurrent = self.fileName()
				if self.__fileNameIncomplete(fileNameCurrent) or (not fileName and not self.fileName(exact = Stream.ExactRaw)): # Also try to extract if the filename is cut off (ends with ...).
					fileNameNew = self.fileNameExtract(data = link)
					if fileNameNew:
						fileName = fileNameNew
						reload = False

			# Used by reload() and fileNameValid().
			if fileName: self.fileNameSet(fileName, exact = Stream.ExactRaw)
			elif fileNameInexact: self.fileNameSet(fileNameInexact, exact = Stream.ExactRaw)

			usenet = True if sourceType == Stream.SourceTypeUsenet else None
			if tools.Tools.isString(fileName):
				fileName = self.cleanBasic(data = fileName, usenet = usenet, process = fileNameProcess)
				if extract:
					if fileName is None and link and not reload:
						fileName = self.fileNameExtract(data = link)
						if fileName: fileName = self.cleanBasic(fileName)

			if fileNameInexact and not fileNameInexact is True: fileNameInexact = self.cleanBasic(data = fileNameInexact, usenet = usenet, process = fileNameProcess)

			if tools.Tools.isArray(fileExtra):
				fileExtraTemp = []
				for i in fileExtra:
					if i:
						if tools.Tools.isArray(i): fileExtraTemp.append('[%s]' % ' '.join([self.cleanBasic(data = f, usenet = usenet, process = fileNameProcess) for f in i]))
						else: fileExtraTemp.append('[%s]' % self.cleanBasic(data = i, usenet = usenet, process = fileNameProcess))
				fileExtra = ''.join(fileExtraTemp)
			elif fileExtra: fileExtra = '[%s]' % self.cleanBasic(data = fileExtra, usenet = usenet, process = fileNameProcess)

			files = []
			if fileName: files.append(fileName)
			elif fileNameInexact and not fileNameInexact is True: files.append(fileNameInexact)
			elif reload and fileExtra: # If set during the previous load() call. Required for validating the show number, if the number is in fileExtra.
				fileNameTemp = self.fileName(exact = Stream.ExactYes)
				if fileNameTemp: files.append(fileNameTemp)
				else:
					fileNameTemp = self.fileName(exact = Stream.ExactNo)
					if fileNameTemp: files.append(fileNameTemp)

			if fileExtra: files.append(fileExtra)
			if files:
				# Combine with FileSeparator, since some extraction requires to know where the actual file name ends.
				# Eg: the language expressions for HU.
				fileNameExtra = Stream.FileSeparator.join(files)
			else:
				fileNameExtra = None
				extract = False

			if validate == Stream.ValidateLenient:
				if fileName and len(fileName) >= Stream.Threshold['validate']:
					validate = True
					validateTitle = True
					validateYear = True
					validateShow = True
					validateSeason = True
					validateEpisode = True
				else:
					validate = True
					validateTitle = False
					validateYear = False
					validateShow = False
					validateSeason = False
					validateEpisode = False
			self.validationReleaseSet(value = validate and validateRelease)
			self.validationKeywordSet(value = validate and validateKeyword)
			self.validationFormatSet(value = validate and validateFormat)
			self.validationFakeSet(value = validate and validateFake)
			self.validationSizeSet(value = validate and validateSize)
			self.validationTimeSet(value = validate and validateTime)
			self.validationPeersSet(value = validate and validatePeers)
			self.validationSeedsSet(value = validate and validateSeeds)
			self.validationLeechesSet(value = validate and validateLeeches)

			if metaMedia is None:
				if not metaSeason is None or not metaEpisode is None: metaMedia = tools.Media.Show
				elif not metaYear is None: metaMedia = tools.Media.Movie
			metaMediaMovie = tools.Media.isFilm(metaMedia)
			metaMediaShow = tools.Media.isSerie(metaMedia)

			metaTitle = self.cleanEncode(metaTitle)
			try: metaTitle = metaTitle['processed']
			except: pass
			try: metaTitleMain = metaTitle[Stream.TitleMain]
			except: metaTitleMain = metaTitle
			if tools.Tools.isArray(metaTitleMain): metaTitleMain = metaTitleMain[0]
			try: metaTitleAll = metaTitle[Stream.TitleAll]
			except: metaTitleAll = metaTitle
			try: metaTitleCollection = metaTitle[Stream.TitleCollection]
			except: metaTitleCollection = None
			try: metaTitleEpisode = metaTitle[Stream.TitleEpisode]
			except: metaTitleEpisode = None

			# Some movies have 150+ aliases which drastically increases scraping time to match all the titles.
			# Most of the aliases are similar and will not add much to the title-filename matching.
			# Eg: All movies from "The Lord of the Rings" or "The Hobbit".
			performance = self.performance()
			if performance >= 0.7: titleLimit = Stream.TitleLimit[0]
			elif performance >= 0.4: titleLimit = Stream.TitleLimit[1]
			else: titleLimit = Stream.TitleLimit[2]
			try:
				if tools.Tools.isArray(metaTitleAll): metaTitleAll = metaTitleAll[:titleLimit]
			except: pass
			try:
				if tools.Tools.isArray(metaTitleCollection): metaTitleCollection = metaTitleCollection[:titleLimit]
			except: pass
			try:
				if tools.Tools.isArray(metaTitleEpisode): metaTitleEpisode = metaTitleEpisode[:titleLimit]
			except: pass

			metaTitleCombined = []
			if metaTitleMain: metaTitleCombined.append(metaTitleMain)
			if metaTitleCollection: metaTitleCombined.extend(metaTitleCollection)
			if metaTitleEpisode: metaTitleCombined.extend(metaTitleEpisode)

			# Always set these values, even if the validation fails, since they are used in other functions (eg: titleValid).
			if not metaMedia is None: self.metaMediaSet(metaMedia)
			if not metaNiche is None: self.metaNicheSet(metaNiche)
			if not metaTitle is None: self.metaTitleSet(metaTitle)
			if not metaYear is None: self.metaYearSet(metaYear)
			if not metaTime is None: self.metaTimeSet(metaTime)
			if not metaSeason is None: self.metaSeasonSet(metaSeason)
			if not metaEpisode is None: self.metaEpisodeSet(metaEpisode)
			if not metaNumber is None: self.metaNumberSet(metaNumber)
			if not metaLanguage is None: self.metaLanguageSet(metaLanguage)
			if not metaCountry is None: self.metaCountrySet(metaCountry)
			if not metaNetwork is None: self.metaNetworkSet(metaNetwork)
			if not metaStudio is None: self.metaStudioSet(metaStudio)
			if not metaDuration is None: self.metaDurationSet(metaDuration)
			if not metaPack is None: self.metaPackSet(metaPack)
			if not fileName is None: self.fileNameSet(fileName)
			if not fileExtra is None: self.fileExtraSet(fileExtra)

			if hash:
				if (sourceType == self.SourceTypeTorrent or sourceType == self.SourceTypeUsenet) and hashContainer is None: hashContainer = hash
				elif hashFile is None: hashFile = hash
			if hashContainer:
				algorithm = self.hashAlgorithm(hashContainer)
				if algorithm == Stream.HashAlgorithmMd5: hashContainerMd5 = hashContainer
				elif algorithm == Stream.HashAlgorithmSha1: hashContainerSha1 = hashContainer
				elif algorithm == Stream.HashAlgorithmSha256: hashContainerSha256 = hashContainer
				elif algorithm == Stream.HashAlgorithmSha512: hashContainerSha512 = hashContainer
				else: hashContainerUnknown = hashContainer
			if hashFile:
				algorithm = self.hashAlgorithm(hashFile)
				if algorithm == Stream.HashAlgorithmMd5: hashFileMd5 = hashFile
				elif algorithm == Stream.HashAlgorithmSha1: hashFileSha1 = hashFile
				elif algorithm == Stream.HashAlgorithmSha256: hashFileSha256 = hashFile
				elif algorithm == Stream.HashAlgorithmSha512: hashFileSha512 = hashFile
				else: hashFileUnknown = hashFile
			if hashOther:
				algorithm = self.hashAlgorithm(hashOther)
				if algorithm == Stream.HashAlgorithmMd5: hashOtherMd5 = hashOther
				elif algorithm == Stream.HashAlgorithmSha1: hashOtherSha1 = hashOther
				elif algorithm == Stream.HashAlgorithmSha256: hashOtherSha256 = hashOther
				elif algorithm == Stream.HashAlgorithmSha512: hashOtherSha512 = hashOther
				else: hashOtherUnknown = hashOther

			# Hash
			if hash is None and sourceType == Stream.SourceTypeTorrent and link:
				hash = self.hashExtract(data = link)
				if hash and hash['hash']:
					if hash['type'] == Stream.HashTypeContainer:
						if hash['algorithm'] == Stream.HashAlgorithmMd5: hashContainerMd5 = hash['hash']
						elif hash['algorithm'] == Stream.HashAlgorithmSha1: hashContainerSha1 = hash['hash']
						elif hash['algorithm'] == Stream.HashAlgorithmSha256: hashContainerSha256 = hash['hash']
						elif hash['algorithm'] == Stream.HashAlgorithmSha512: hashContainerSha512 = hash['hash']
						else: hashContainerUnknown = hash['hash']
					elif hash['type'] == Stream.HashTypeFile:
						if hash['algorithm'] == Stream.HashAlgorithmMd5: hashFileMd5 = hash['hash']
						elif hash['algorithm'] == Stream.HashAlgorithmSha1: hashFileSha1 = hash['hash']
						elif hash['algorithm'] == Stream.HashAlgorithmSha256: hashFileSha256 = hash['hash']
						elif hash['algorithm'] == Stream.HashAlgorithmSha512: hashFileSha512 = hash['hash']
						else: hashFileUnknown = hash['hash']
					elif hash['type'] == Stream.HashTypeOther:
						if hash['algorithm'] == Stream.HashAlgorithmMd5: hashOtherMd5 = hash['hash']
						elif hash['algorithm'] == Stream.HashAlgorithmSha1: hashOtherSha1 = hash['hash']
						elif hash['algorithm'] == Stream.HashAlgorithmSha256: hashOtherSha256 = hash['hash']
						elif hash['algorithm'] == Stream.HashAlgorithmSha512: hashOtherSha512 = hash['hash']
						else: hashOtherUnknown = hash['hash']

			hashes = [
				hashContainerUnknown,
				hashContainerMd5,
				hashContainerSha1,
				hashContainerSha256,
				hashContainerSha512,
				hashFileUnknown,
				hashFileMd5,
				hashFileSha1,
				hashFileSha256,
				hashFileSha512,
				hashOtherUnknown,
				hashOtherMd5,
				hashOtherSha1,
				hashOtherSha256,
				hashOtherSha512,
			]
			hashes = [i for i in hashes if i]
			if not hashes: hashes = None

			# Load existing data from the function parameter or from cache.
			id = None
			dataHas = True if data else False
			dataCache = False
			if cache or data:
				# Must have a fileName or hash. Otherwise different hoster links (that do not have a fileName or hash) will end up with the same ID if the fileSize/sourceTime is the same.
				#if data is None and (fileName or hashes or fileSize or fileSizeInexact or sourceTime or sourceTimeInexact):
				if data is None and (fileName or hashes):
					id = u''

					# NB: Include the hash in the ID, not just the file name, since some have the same file name, but different hashes.
					# If we exclude the hash, then streams with the same file name will end up calling dataImport below.
					# This will then import all extracted data correctly (since it is based on the same file name), but other data (eg: hash, seeds, age, etc) will be incorrect after the import.
					# In usenet there are sometimes files with the same name AND size, but the age differs.
					if fileName:
						try: id += '_' + fileName
						except: id += '_' + tools.Converter.unicode(fileName)
					if hashes:
						try: id += '_' + ('_'.join(hashes).lower())
						except: id += '_' + ('_'.join([tools.Converter.unicode(i) for i in hashes]).lower())
					elif fileSize or fileSizeInexact or sourceTime or sourceTimeInexact: # Usenet
						if fileSize:
							try: id += '_' + str(fileSize)
							except: id += '_' + fileSize # If size comes in as unicode, eg Russian size units.
						elif fileSizeInexact: id += '_' + str(fileSizeInexact)
						if sourceTime:
							try: id += '_' + str(sourceTime)
							except: id += '_' + sourceTime # If date comes in as unicode, eg Russian date.
						elif sourceTimeInexact:
							try: id += '_' + str(sourceTimeInexact)
							except: id += '_' + sourceTimeInexact # If date comes in as unicode, eg Russian date.
					try: id += '_' + str(accessOrion) # NB: Do not reuse the data from Orion, otherwise if Orion uses its preset data instead extracting it from the filename (eg: low-end devices), other providers might reuse this inaccurate data.
					except: pass

					# This is important for Emby/Jellyfin, otherwise transcoded streams will load the extracted metadata from from the original stream, since the file names are the same.
					for i in [idProviderLocal, idProviderUniversal, idProviderCollection, idProviderItem]:
						try:
							if i: id += '_' + str(i)
						except: pass

					if metaMedia: id += '_' + metaMedia
					if metaTitleAll:
						try: id += '_' + metaTitleAll[0]
						except: id += '_' + tools.Converter.unicode(metaTitleAll[0])
					if metaYear: id += '_' + str(metaYear)
					if metaSeason: id += '_' + str(metaSeason)
					if metaEpisode: id += '_' + str(metaEpisode)

					data = self._cacheId(id, None)
					dataCache = True

				if not reload and data:
					# The exact same file (same file name and file size) might appear on different hosters (eg: Nitro and Rapidgator).
					# In such a case, the _cacheId() calculated above will be the same for both files on different hosters.
					# The extracted metadata from the file name will be the same, however, other values could be different, such as the debrid support and debrid cache status.
					# This also causes a lot more hoster links to show up as Premiumize-cached that are actually not.
					# This is important in core.py -> addSources() -> accessDebridSet().
					# One way is to add the link to _cacheId() to make sure that the cached stream data is not used between different hosters. However, this will also mean the metadata will have to be re-extracted from the file name.
					# A better way is to still use the cached stream data, but reset the values that might be differnt.
					# In dataImport(), the entire 'access' sub-dictionary is deleted to make sure the debrid support and cache status is always set on a per-stream basis.
					# Not sure if there is any other data that has to be reset, maybe the 'exclusion' sub-dictionary (these values are only calculated aty the end of the scsraping process).
					full = True
					if cache and (sourceType == Stream.SourceTypeUsenet or sourceType == Stream.SourceTypeHoster):
						if not link or not data['link']['original'] or not data['link']['original'][0] == link:
							full = False

					self.dataImport(data = data, full = full)

					# Always set the non-extracted values, since the filename could be cached with other eg titles.
					if not metaMedia is None: self.metaMediaSet(metaMedia)
					if not metaNiche is None: self.metaNicheSet(metaNiche)
					if not metaTitle is None: self.metaTitleSet(metaTitle)
					if not metaYear is None: self.metaYearSet(metaYear)
					if not metaTime is None: self.metaTimeSet(metaTime)
					if not metaSeason is None: self.metaSeasonSet(metaSeason)
					if not metaEpisode is None: self.metaEpisodeSet(metaEpisode)
					if not metaNumber is None: self.metaNumberSet(metaNumber)
					if not metaLanguage is None: self.metaLanguageSet(metaLanguage)
					if not metaCountry is None: self.metaCountrySet(metaCountry)
					if not metaNetwork is None: self.metaNetworkSet(metaNetwork)
					if not metaStudio is None: self.metaStudioSet(metaStudio)
					if not metaDuration is None: self.metaDurationSet(metaDuration)
					if not metaPack is None: self.metaPackSet(metaPack)

					# Always set these values, since they might be different across providers, even if the file name is the same.
					# Eg: The same file might be found by different premium/debrid providers. Certain values might differ, like the time, or size (OffCloud does not have exact sizes).
					if not link is None: self.linkSet(link)

					if not hashContainerUnknown is None: self.hashContainerUnknownSet(hashContainerUnknown)
					if not hashContainerMd5 is None: self.hashContainerMd5Set(hashContainerMd5)
					if not hashContainerSha1 is None: self.hashContainerSha1Set(hashContainerSha1)
					if not hashContainerSha256 is None: self.hashContainerSha256Set(hashContainerSha256)
					if not hashContainerSha512 is None: self.hashContainerSha512Set(hashContainerSha512)
					if not hashFileUnknown is None: self.hashFileUnknownSet(hashFileUnknown)
					if not hashFileMd5 is None: self.hashFileMd5Set(hashFileMd5)
					if not hashFileSha1 is None: self.hashFileSha1Set(hashFileSha1)
					if not hashFileSha256 is None: self.hashFileSha256Set(hashFileSha256)
					if not hashFileSha512 is None: self.hashFileSha512Set(hashFileSha512)
					if not hashOtherUnknown is None: self.hashOtherUnknownSet(hashOtherUnknown)
					if not hashOtherMd5 is None: self.hashOtherMd5Set(hashOtherMd5)
					if not hashOtherSha1 is None: self.hashOtherSha1Set(hashOtherSha1)
					if not hashOtherSha256 is None: self.hashOtherSha256Set(hashOtherSha256)
					if not hashOtherSha512 is None: self.hashOtherSha512Set(hashOtherSha512)

					if not videoQuality is None: self.videoQualitySet(videoQuality)
					if not videoQualityInexact is None: self.videoQualitySet(videoQualityInexact, exact = Stream.ExactNo)
					if not videoResolution is None: self.videoResolutionSet(videoResolution)
					if not videoResolutionInexact is None: self.videoResolutionSet(videoResolutionInexact, exact = Stream.ExactNo)
					if not videoWidth is None: self.videoWidthSet(videoWidth)
					if not videoWidthInexact is None: self.videoWidthSet(videoWidthInexact, exact = Stream.ExactNo)
					if not videoHeight is None: self.videoHeightSet(videoHeight)
					if not videoHeightInexact is None: self.videoHeightSet(videoHeightInexact, exact = Stream.ExactNo)
					if not videoAspect is None: self.videoAspectSet(videoAspect)
					if not videoAspectInexact is None: self.videoAspectSet(videoAspectInexact, exact = Stream.ExactNo)
					if not videoCodec is None: self.videoCodecSet(videoCodec)
					if not videoDepth is None: self.videoDepthSet(videoDepth)
					if not videoRange is None: self.videoRangeSet(videoRange)
					if not video3d is None: self.video3dSet(video3d)

					if not audioType is None: self.audioTypeSet(audioType)
					if not audioChannels is None: self.audioChannelsSet(audioChannels)
					if not audioSystem is None: self.audioSystemSet(audioSystem)
					if not audioCodec is None: self.audioCodecSet(audioCodec)
					if audioSystem is None and not audioCodec is None: self.audioSystemSet(audioCodec)
					if not audioLanguage is None: self.audioLanguageSet(audioLanguage)

					if not subtitleType is None: self.subtitleTypeSet(subtitleType)
					if not subtitleLanguage is None: self.subtitleLanguageSet(subtitleLanguage)

					if not releaseType is None: self.releaseTypeSet(releaseType)
					if not releaseFormat is None: self.releaseFormatSet(releaseFormat)
					if not releaseEdition is None: self.releaseEditionSet(releaseEdition)
					if not releaseNetwork is None: self.releaseNetworkSet(releaseNetwork)
					if not releaseGroup is None: self.releaseGroupSet(releaseGroup)
					if not releaseUploader is None: self.releaseUploaderSet(releaseUploader)

					if not fileNameInexact is None: self.fileNameSet(fileNameInexact, exact = Stream.ExactNo)
					if not fileContainer is None: self.fileContainerSet(fileContainer)
					if not filePack is None: self.filePackSet(filePack, number = self.numberShow())

					# Must be after file pack, since the file size could be estimated.
					if not fileSize is None: self.fileSizeSet(fileSize)
					if not fileSizeInexact is None: self.fileSizeSet(fileSizeInexact, exact = Stream.ExactNo)

					if not sourceType is None: self.sourceTypeSet(sourceType)
					if not sourceSeeds is None: self.sourceSeedsSet(sourceSeeds)
					if not sourceSeedsInexact is None: self.sourceSeedsSet(sourceSeedsInexact, exact = Stream.ExactNo)
					if not sourceLeeches is None: self.sourceLeechesSet(sourceLeeches)
					if not sourceLeechesInexact is None: self.sourceLeechesSet(sourceLeechesInexact, exact = Stream.ExactNo)
					if not sourceTime is None: self.sourceTimeSet(sourceTime, format = sourceTimeFormat)
					if not sourceTimeInexact is None: self.sourceTimeSet(sourceTimeInexact, exact = Stream.ExactNo, format = sourceTimeFormat)
					if not sourceOrigin is None: self.sourceOriginSet(sourceOrigin)
					if not sourceProvider is None: self.sourceProviderSet(sourceProvider)
					if not sourcePublisher is None: self.sourcePublisherSet(sourcePublisher)
					if not sourceHoster is None: self.sourceHosterSet(sourceHoster)

					if not accessType is None: self.accessTypeSet(accessType)
					if accessOffline: self.accessTypeSet(type = Stream.AccessTypeOffline)
					if accessDirect: self.accessTypeSet(type = Stream.AccessTypeDirect)
					if accessMember: self.accessTypeSet(type = Stream.AccessTypeMember)
					if accessOpen: self.accessTypeSet(type = Stream.AccessTypeOpen)
					if accessOrion: self.accessTypeSet(type = Stream.AccessTypeOrion)
					if not accessDebrid is None: self.accessDebridSet(accessDebrid)
					if not accessCache is None: self.accessCacheSet(accessCache)
					if not accessCacheInexact is None: self.accessCacheSet(accessCacheInexact, exact = Stream.ExactNo)

					if not sourceApproval is None: self.sourceApprovalSet(sourceApproval)

					if not sourcePopularity is None: self.sourcePopularitySet(sourcePopularity)
					elif not sourceApproval is None: self.sourcePopularityCalculate(approval = sourceApproval)

					if not segment is None: self.segmentSet(segment)
					if not segmentFirst is None: self.segmentFirstSet(segmentFirst)
					if not segmentLargest is None: self.segmentLargestSet(segmentLargest)
					if not segmentList is None: self.segmentListSet(segmentList)

					if not exclusionDuplicate is None: self.exclusionDuplicateSet(exclusionDuplicate)
					if not exclusionRelease is None: self.exclusionReleaseSet(exclusionRelease)
					if not exclusionKeyword is None: self.exclusionKeywordSet(exclusionKeyword)
					if not exclusionMetadata is None: self.exclusionMetadataSet(exclusionMetadata)
					if not exclusionFormat is None: self.exclusionFormatSet(exclusionFormat)
					if not exclusionFake is None: self.exclusionFakeSet(exclusionFake)
					if not exclusionSupport is None: self.exclusionSupportSet(exclusionSupport)
					if not exclusionBlocked is None: self.exclusionBlockedSet(exclusionBlocked)
					if not exclusionCaptcha is None: self.exclusionCaptchaSet(exclusionCaptcha)
					if not exclusionPrecheck is None: self.exclusionPrecheckSet(exclusionPrecheck)

					if not infoTermination is None: self.infoTerminationSet(infoTermination)
					if not infoExact is None: self.infoExactSet(infoExact)
					if not infoCustom is None: self.infoCustomSet(infoCustom)
					if not infoSort is None: self.infoSortSet(infoSort)
					if not infoLanguage is None: self.infoLanguageSet(infoLanguage)
					if not infoQuery is None: self.infoQuerySet(infoQuery)

					if not idGaiaItem is None: self.idGaiaItemSet(idGaiaItem)
					if not idGaiaStream is None: self.idGaiaStreamSet(idGaiaStream)

					if not idOrionStream is None: self.idOrionStreamSet(idOrionStream)
					if not idOrionMovie is None: self.idOrionMovieSet(idOrionMovie)
					if not idOrionCollection is None: self.idOrionCollectionSet(idOrionCollection)
					if not idOrionShow is None: self.idOrionShowSet(idOrionShow)
					if not idOrionSeason is None: self.idOrionSeasonSet(idOrionSeason)
					if not idOrionEpisode is None: self.idOrionEpisodeSet(idOrionEpisode)
					if not idOrionData is None: self.idOrionDataSet(idOrionData)

					if not idProviderLocal is None: self.idProviderLocalSet(idProviderLocal)
					if not idProviderUniversal is None: self.idProviderUniversalSet(idProviderUniversal)
					if not idProviderCollection is None: self.idProviderCollectionSet(idProviderCollection)
					if not idProviderItem is None: self.idProviderItemSet(idProviderItem)

					if not idImdb is None: self.idImdbSet(idImdb)
					if not idTmdb is None: self.idTmdbSet(idTmdb)
					if not idTvdb is None: self.idTvdbSet(idTvdb)
					if not idTrakt is None: self.idTraktSet(idTrakt)
					if not idSlug is None: self.idSlugSet(idSlug)

					# Exclusions
					# Do not do here, otherwise the exclusion is calculated every time the stream window is reloaded.
					# Only do this for data retreived from the cache, since the metadata (fileName, etc) might be the same and therefore have the same cache ID, but the link/hoster is different and therefore exclusion might be different.
					if dataCache: self.exclusionUpdate()

					self.unlock(lock)
					self.statisticsUpdate(type = Stream.StatisticImported if dataHas else Stream.StatisticCached, timer = timer)
					return True
				elif data is False:
					self.unlock(lock)
					self.statisticsUpdate(type = Stream.StatisticCached, timer = timer)
					return False

			processed = {
				'video' : {
					'quality'		: {'exact' : processed, 'inexact' : processed},
					'resolution'	: {'exact' : processed, 'inexact' : processed},
					'width'			: {'exact' : processed, 'inexact' : processed},
					'height'		: {'exact' : processed, 'inexact' : processed},
					'aspect'		: {'exact' : processed, 'inexact' : processed},
					'codec'			: processed,
					'depth'			: processed,
					'range'			: processed,
					'3d'			: processed,
				},
				'audio' : {
					'type'			: processed,
					'channels'		: processed,
					'system'		: processed,
					'codec'			: processed,
					'language'		: processed,
				},
				'subtitle' : {
					'type'			: processed,
					'language'		: processed,
				},
				'release' : {
					'format'		: processed,
					'source'		: processed,
					'edition'		: processed,
					'network'		: processed,
					'group'			: processed,
				},
				'file' : {
					'size'			: {'exact' : processed, 'inexact' : processed},
					'container'		: processed,
					'pack'			: processed,
				},
				'source' : {
					'time'			: {'exact' : processed, 'inexact' : processed},
					'seeds'			: {'exact' : processed, 'inexact' : processed},
					'leeches'		: {'exact' : processed, 'inexact' : processed},
					'hoster'		: {'exact' : processed, 'inexact' : processed},
				},
			}

			# Fake
			if not thresholdFake is None: self.thresholdFakeSet(thresholdFake)

			# Link
			# Only check if there is a link. Some torrent providers do not have a link, only a hash.
			if validate and validateLink and link and not self.__linkValid(data = link, type = sourceType):
				self.debug(reason = 'Invalid Link', link = link)
				return cacheInvalid(id, cache, lock)

			# Source Peers
			if not thresholdPeers is None: self.thresholdPeersSet(thresholdPeers)
			if not thresholdSeeds is None: self.thresholdSeedsSet(thresholdSeeds)
			if not thresholdLeeches is None: self.thresholdLeechesSet(thresholdLeeches)
			if not sourceSeeds is None:
				if not sourceSeeds is None:
					processed['source']['seeds']['exact'] = True
					sourceSeeds = self.sourceSeedsExtract(data = sourceSeeds)
				if not sourceSeedsInexact is None:
					processed['source']['seeds']['inexact'] = True
					sourceSeeds = self.sourceSeedsExtract(data = sourceSeedsInexact)
			if not sourceLeeches is None:
				if not sourceLeeches is None:
					processed['source']['leeches']['exact'] = True
					sourceLeeches = self.sourceLeechesExtract(data = sourceLeeches)
				if not sourceLeechesInexact is None:
					processed['source']['leeches']['inexact'] = True
					sourceLeeches = self.sourceLeechesExtract(data = sourceLeechesInexact)

			# File Size
			if not thresholdSize is None: self.thresholdSizeSet(value = thresholdSize, media = metaMedia, pack = filePack)
			if fileNameExtra or not fileSize is None or not fileSizeInexact is None:
				if fileSize is None and fileSizeInexact is None:
					processed['file']['size']['inexact'] = True
					fileSizeInexact = self.fileSizeExtract(data = fileNameExtra, clean = False, name = True)
				else:
					if fileSize:
						processed['file']['size']['exact'] = True
						fileSize = self.fileSizeExtract(data = fileSize, clean = False, name = False)
					if fileSizeInexact:
						processed['file']['size']['inexact'] = True
						fileSizeInexact = self.fileSizeExtract(data = fileSizeInexact, clean = False, name = False)

				# If the file size is 0, assume it is not known.
				# Happens a lot with TorrentParadise, where torrents are listed as "0 Bytes".
				# Otherwise if left at 0, these links are removed due to invalid file size validation.
				if fileSize == 0: fileSize = None
				if fileSizeInexact == 0: fileSizeInexact = None

			# Source Time
			if not thresholdTime is None: self.thresholdTimeSet(thresholdTime)
			if not sourceTime is None or not sourceTimeInexact is None:
				if not sourceTime is None:
					processed['source']['time']['exact'] = True
					sourceTime = self.sourceTimeExtract(data = sourceTime, format = sourceTimeFormat)
				if not sourceTimeInexact is None:
					processed['source']['time']['inexact'] = True
					sourceTimeInexact = self.sourceTimeExtract(data = sourceTimeInexact, format = sourceTimeFormat)

			# Validation
			if validate and fileName:
				# Do not validate the year here already. We need the filePack for better validating the year for special cases of movie collections.
				#if validateYear and self.__yearValid(year = metaYear, data = fileName, pack = metaPack, 'filePack = filePack', deviation = True) is False:
				#	self.__invalidate(id = idOrionStream, link = link, hash = hashes, name = fileName, provider = sourceProvider, invalid = Stream.InvalidYear)
				#	self.debug(reason = 'Invalid Year', link = link, name = fileNameExtra, extra = sourceProvider)
				#	return cacheInvalid(id, cache, lock)

				if validateTitle and metaTitleAll and not self.__titleValidQuick(data = fileName, title = metaTitleAll) and (fileName == fileNameExtra or not self.__titleValidQuick(data = fileNameExtra, title = metaTitleAll)):
					self.__invalidate(id = idOrionStream, link = link, hash = hashes, name = fileName, provider = sourceProvider, invalid = Stream.InvalidTitle)
					self.debug(reason = 'Invalid Title Quick', link = link, name = fileNameExtra, extra = sourceProvider)
					return cacheInvalid(id, cache, lock)

			# Show Number
			number = {'collection' : [], 'season' : [], 'episode' : []}
			if metaMediaShow and (numberSeason is None or numberEpisode is None) and fileNameExtra: # Extract even if "extract=False", so that metadata extraction can be disabled, but the show number validation can still take place.
				number = self.numberShowExtract(data = fileNameExtra, niche = metaNiche, show = True, season = True, episode = True, clean = False)
				if numberSeason is None: numberSeason = number['season']
				if numberEpisode is None: numberEpisode = number['episode']
			else:
				if numberCollection: number['collection'] = numberCollection if tools.Tools.isArray(numberCollection) else [numberCollection]
				if numberSeason: number['season'] = numberSeason if tools.Tools.isArray(numberSeason) else [numberSeason]
				if numberEpisode: number['episode'] = numberEpisode if tools.Tools.isArray(numberEpisode) else [numberEpisode]

			# File Pack
			if not filePack is None:
				processed['file']['pack'] = True
				filePack = self.filePackSet(filePack)
			if filePack is None and extract:
				processed['file']['pack'] = True
				filePack = self.filePackExtract(data = fileNameExtra, number = number, pack = metaPack, exclude = metaTitleAll, encode = False, clean = False)

			# Requires the file pack.
			if validate and metaMediaShow and validateShow and (validateSeason or validateEpisode) and fileNameExtra:
				if not self.__numberSpecialValid(data = fileNameExtra, title = metaTitleEpisode, niche = metaNiche, real = number, season = metaSeason if validateSeason else None, episode = metaEpisode if validateEpisode else None, number = metaNumber, pack = metaPack, filePack = filePack):
					self.__invalidate(id = idOrionStream, link = link, hash = hashes, name = fileName, provider = sourceProvider, invalid = Stream.InvalidNumber)
					self.debug(reason = 'Invalid Show Number', link = link, name = fileNameExtra, extra = 'Expected: %s x %s' % ('Pack' if metaSeason is None else str(metaSeason), 'Pack' if metaEpisode is None else str(metaEpisode)))
					return cacheInvalid(id, cache, lock)

			# Collection Number
			if metaMediaMovie and fileNameExtra:
				numberCollection = self.numberCollectionExtract(data = fileNameExtra, filePack = filePack, pack = metaPack, clean = False)
				if numberCollection is None: numberCollection = number['collection']
				# No pack keywords, but a number range/list.
				# Eg: Terminator 1 - 4 H264 STAR.1 NWRG
				if not filePack and numberCollection:
					collectionCount = self.numberCollectionCount(numberCollection)
					if collectionCount and collectionCount > 1: filePack = Stream.FilePackCollection

			# Validation
			# Do here, so filePack is available for more accurate year validation of movie collections.
			if validate and validateYear and fileName and self.__yearValid(media = metaMedia, year = metaYear, data = fileName, pack = metaPack, filePack = filePack, deviation = True) is False:
				self.__invalidate(id = idOrionStream, link = link, hash = hashes, name = fileName, provider = sourceProvider, invalid = Stream.InvalidYear)
				self.debug(reason = 'Invalid Year', link = link, name = fileNameExtra, extra = sourceProvider)
				return cacheInvalid(id, cache, lock)

			# If a parameter is passed in (aka not None), first try to set it setter functions will apply extraction to it).
			# Only if the set value is None, try to extract it from the file name.
			# This is useful for providers like EasyNews. These providers have some metadata as separate attributes, but their value can be wrong/unknown.
			# For instance, EasyNews often returns "UNKNOWN" or "MPG123" as the audio codec. Try to set/convert it to a known codec. If it fails, use the file name to extract it.

			# Video Resolution
			if videoResolution is None and videoWidth and videoHeight:
				videoResolution = {Stream.VideoWidth : videoWidth, Stream.VideoHeight : videoHeight}
			if videoResolutionInexact is None and videoWidthInexact and videoHeightInexact:
				videoResolutionInexact = {Stream.VideoWidth : videoWidthInexact, Stream.VideoHeight : videoHeightInexact}

			# Video Width
			if not videoWidth is None:
				processed['video']['width']['exact'] = True
				videoWidth = self.videoWidthSet(videoWidth)
			if not videoWidthInexact is None:
				processed['video']['width']['inexact'] = True
				videoWidthInexact = self.videoWidthSet(videoWidthInexact, exact = Stream.ExactNo)

			# Video Height
			if not videoHeight is None:
				processed['video']['height']['exact'] = True
				videoHeight = self.videoHeightSet(videoHeight)
			if not videoHeightInexact is None:
				processed['video']['height']['inexact'] = True
				videoHeightInexact = self.videoHeightSet(videoHeightInexact, exact = Stream.ExactNo)

			# Video Resolution
			if not videoResolution is None:
				processed['video']['resolution']['exact'] = True
				videoResolution = self.videoResolutionSet(videoResolution)
			if not videoResolutionInexact is None:
				processed['video']['resolution']['inexact'] = True
				videoResolutionInexact = self.videoResolutionSet(videoResolutionInexact, exact = Stream.ExactNo)
			if (videoQuality or videoQualityInexact) and videoResolution is None and videoResolutionInexact is None:
				processed['video']['resolution']['inexact'] = True
				videoResolutionInexact = self.videoResolutionConvert(quality = videoQuality if videoQuality else videoQualityInexact, default = True)
			elif (videoResolution or videoResolutionInexact) and videoQuality is None and videoQualityInexact is None:
				processed['video']['quality']['inexact'] = True
				if videoResolution: videoQuality = self.videoResolutionConvert(resolution = videoResolution, default = True)
				else: videoQualityInexact = self.videoResolutionConvert(resolution = videoResolutionInexact, default = True)

			# Video Quality
			# Set after resolution, in order to get a more accurate quality from the given width and height (eg: EasyNews).
			if not videoQuality is None:
				videoQuality = self.videoQualitySet(videoQuality, extract = not processed['video']['quality']['exact'])
				processed['video']['quality']['exact'] = True
			if not videoQualityInexact is None:
				videoQualityInexact = self.videoQualitySet(videoQualityInexact, extract = not processed['video']['quality']['inexact'], exact = Stream.ExactNo)
				processed['video']['quality']['inexact'] = True
			if videoQuality is None and videoQualityInexact is None and extract:
				videoQuality = self.videoQualityExtract(data = fileNameExtra, exclude = metaTitleAll, encode = False, default = False, clean = False)
				if videoQuality:
					processed['video']['quality']['exact'] = True
				else:
					processed['video']['quality']['inexact'] = True
					videoQualityInexact = Stream.VideoQualityDefault

			# Video Resolution
			# After the videoQuality was extracted from the file name.
			if (videoQuality or videoQualityInexact) and videoResolution is None and videoResolutionInexact is None:
				processed['video']['resolution']['inexact'] = True
				videoResolutionInexact = self.videoResolutionConvert(quality = videoQuality if videoQuality else videoQualityInexact, default = True)

			# Video Aspect
			if not videoAspect is None:
				processed['video']['aspect']['exact'] = True
				videoAspect = self.videoAspectSet(videoAspect)
			if not videoAspectInexact is None:
				processed['video']['aspect']['inexact'] = True
				videoAspectInexact = self.videoAspectSet(videoAspectInexact, exact = Stream.ExactNo)
			if (videoResolution or videoResolutionInexact) and videoAspect is None and videoAspectInexact is None:
				if videoResolution:
					processed['video']['aspect']['exact'] = True
					videoAspect = self.videoAspectConvert(resolution = videoResolution, default = True)
				else:
					processed['video']['aspect']['inexact'] = True
					videoAspectInexact = self.videoAspectConvert(resolution = videoResolutionInexact, default = True)

			# Video Codec
			if not videoCodec is None:
				processed['video']['codec'] = True
				videoCodec = self.videoCodecSet(videoCodec)
			if videoCodec is None and extract:
				processed['video']['codec'] = True
				videoCodec = self.videoCodecExtract(data = fileNameExtra, exclude = metaTitleAll, clean = False)

			# Video Depth
			if not videoDepth is None:
				processed['video']['depth'] = True
				videoDepth = self.videoDepthSet(videoDepth)
			if videoDepth is None and extract:
				processed['video']['depth'] = True
				videoDepth = self.videoDepthExtract(data = fileNameExtra, exclude = metaTitleAll, encode = False, clean = False)

			# Video Range
			if not videoRange is None:
				processed['video']['range'] = True
				videoRange = self.videoRangeSet(videoRange)
			if videoRange is None and extract:
				processed['video']['range'] = True
				videoRange = self.videoRangeExtract(data = fileNameExtra, exclude = metaTitleAll, encode = False, clean = False)

			# Video 3D
			if not video3d is None:
				processed['video']['3d'] = True
				video3d = self.video3dSet(video3d)
			if video3d is None and extract:
				processed['video']['3d'] = True
				video3d = self.video3dExtract(data = fileNameExtra, exclude = metaTitleAll, encode = False, clean = False)

			# Audio Type
			if not audioType is None:
				processed['audio']['type'] = True
				audioType = self.audioTypeSet(audioType)
			if audioType is None and extract:
				processed['audio']['type'] = True
				audioType = self.audioTypeExtract(data = fileNameExtra, exclude = metaTitleAll, encode = False, clean = False)

			# Audio Channels
			if not audioChannels is None:
				processed['audio']['channels'] = True
				audioChannels = self.audioChannelsSet(audioChannels)
			if audioChannels is None and extract:
				processed['audio']['channels'] = True
				audioChannels = self.audioChannelsExtract(data = fileNameExtra, exclude = metaTitleAll, encode = False, clean = False)

			# Audio Codec
			if not audioCodec is None:
				processed['audio']['codec'] = True
				audioCodec =  self.audioCodecSet(audioCodec)
			if audioCodec is None and extract:
				processed['audio']['codec'] = True
				audioCodec = self.audioCodecExtract(data = fileNameExtra, exclude = metaTitleAll, encode = False, clean = False)

			# Audio System
			if not audioSystem is None:
				processed['audio']['system'] = True
				audioSystem = self.audioSystemSet(audioSystem)
			if audioSystem is None and audioCodec is None and extract:
				processed['audio']['system'] = True
				audioSystem = self.audioSystemExtract(data = fileNameExtra, codec = audioCodec, exclude = metaTitleAll, encode = False, clean = False)

			# Audio Language
			audioDefault = None
			if not audioLanguage is None:
				processed['audio']['language'] = True
				audioLanguage = self.audioLanguageSet(audioLanguage)
			if audioLanguage is None and extract:
				processed['audio']['language'] = True
				audioLanguage, audioDefault = self.audioLanguageExtract(data = fileNameExtra, exclude = metaTitleAll, encode = False, clean = False, default = self.metaLanguage(single = True, audioType = audioType), native = infoLanguage, full = True)

			# Subtitle Type
			if not subtitleType is None:
				processed['subtitle']['type'] = True
				subtitleType = self.subtitleTypeSet(subtitleType)
			if subtitleType is None and extract:
				processed['subtitle']['type'] = True
				subtitleType = self.subtitleTypeExtract(data = fileNameExtra, exclude = metaTitleAll, encode = False, clean = False)

			# Subtitle Language
			if not subtitleLanguage is None:
				processed['subtitle']['language'] = True
				subtitleLanguage = self.subtitleLanguageSet(subtitleLanguage)
			if subtitleLanguage is None and extract:
				processed['subtitle']['language'] = True
				subtitleLanguage = self.subtitleLanguageExtract(data = fileNameExtra, exclude = metaTitleAll, encode = False, clean = False, default = self.metaLanguage(single = True), native = infoLanguage)

			# Release Type
			if not releaseType is None:
				processed['release']['type'] = True
				releaseType = self.releaseTypeSet(releaseType)
			if releaseType is None and extract:
				processed['release']['type'] = True
				releaseType = self.releaseTypeExtract(data = fileNameExtra, exclude = metaTitleAll, encode = False, clean = False)

			# Release Format
			if not releaseFormat is None:
				processed['release']['format'] = True
				releaseFormat = self.releaseFormatSet(releaseFormat)
			if releaseFormat is None and extract:
				processed['release']['format'] = True
				releaseFormat = self.releaseFormatExtract(data = fileNameExtra, exclude = metaTitleAll, encode = False, clean = False)

			# Release Edition
			if not releaseEdition is None:
				processed['release']['edition'] = True
				releaseEdition = self.releaseEditionSet(releaseEdition)
			if releaseEdition is None and extract:
				processed['release']['edition'] = True
				# Use metaTitleCombined instead of metaTitleAll.
				# Otherwise aliases containing edition keywords will make the edition go undetected.
				# Eg: Avatar - Collector's Extended Edition
				# Eg: Avatar: An IMAX 3D Experience
				# Still include the episode title.
				# Eg: Abbott.Elementary.S02E19.Festival.1080p.AMZN.WEBRip.DDP5.1.x264-NTb[rartv]
				releaseEdition = self.releaseEditionExtract(data = fileNameExtra, exclude = metaTitleCombined, encode = False, clean = False)

			# Release Network
			if not releaseNetwork is None:
				processed['release']['network'] = True
				releaseNetwork = self.releaseNetworkSet(releaseNetwork)
			if releaseNetwork is None and extract:
				processed['release']['network'] = True
				releaseNetwork = self.releaseNetworkExtract(data = fileNameExtra, exclude = metaTitleAll, encode = False, clean = False)

			# Release Group
			if not releaseGroup is None:
				processed['release']['group'] = True
				releaseGroup = self.releaseGroupSet(releaseGroup)
			if releaseGroup is None and extract:
				processed['release']['group'] = True
				releaseGroup = self.releaseGroupExtract(data = fileNameExtra, exclude = metaTitleAll, encode = False, clean = False)

			# File Container
			if not fileContainer is None:
				processed['file']['container'] = True
				fileContainer = self.fileContainerSet(fileContainer)
			if fileContainer is None and extract:
				processed['file']['container'] = True
				fileContainer = self.fileContainerExtract(data = fileNameExtra, exclude = metaTitleAll, encode = False, clean = False)

			# Source Hoster
			if not sourceHoster is None:
				processed['source']['hoster'] = True
				sourceHoster = self.sourceHosterSet(sourceHoster)
			if sourceHoster is None and link and (sourceType == Stream.SourceTypePremium or sourceType == Stream.SourceTypeHoster):
				processed['source']['hoster'] = True
				sourceHoster = self.sourceHosterExtract(data = link)

			if not numberCollection is None: self.numberCollectionSet(numberCollection)
			if not numberSeason is None: self.numberSeasonSet(numberSeason)
			if not numberEpisode is None: self.numberEpisodeSet(numberEpisode)

			if not link is None: self.linkSet(link)

			if not hashContainerUnknown is None: self.hashContainerUnknownSet(hashContainerUnknown)
			if not hashContainerMd5 is None: self.hashContainerMd5Set(hashContainerMd5)
			if not hashContainerSha1 is None: self.hashContainerSha1Set(hashContainerSha1)
			if not hashContainerSha256 is None: self.hashContainerSha256Set(hashContainerSha256)
			if not hashContainerSha512 is None: self.hashContainerSha512Set(hashContainerSha512)
			if not hashFileUnknown is None: self.hashFileUnknownSet(hashFileUnknown)
			if not hashFileMd5 is None: self.hashFileMd5Set(hashFileMd5)
			if not hashFileSha1 is None: self.hashFileSha1Set(hashFileSha1)
			if not hashFileSha256 is None: self.hashFileSha256Set(hashFileSha256)
			if not hashFileSha512 is None: self.hashFileSha512Set(hashFileSha512)
			if not hashOtherUnknown is None: self.hashOtherUnknownSet(hashOtherUnknown)
			if not hashOtherMd5 is None: self.hashOtherMd5Set(hashOtherMd5)
			if not hashOtherSha1 is None: self.hashOtherSha1Set(hashOtherSha1)
			if not hashOtherSha256 is None: self.hashOtherSha256Set(hashOtherSha256)
			if not hashOtherSha512 is None: self.hashOtherSha512Set(hashOtherSha512)

			if not videoQuality is None: self.videoQualitySet(videoQuality, extract = not processed['video']['quality']['exact'])
			if not videoQualityInexact is None: self.videoQualitySet(videoQualityInexact, extract = not processed['video']['quality']['inexact'], exact = Stream.ExactNo)
			if not videoResolution is None: self.videoResolutionSet(videoResolution)
			if not videoResolutionInexact is None: self.videoResolutionSet(videoResolutionInexact, exact = Stream.ExactNo)
			if not videoWidth is None: self.videoWidthSet(videoWidth)
			if not videoWidthInexact is None: self.videoWidthSet(videoWidthInexact, exact = Stream.ExactNo)
			if not videoHeight is None: self.videoHeightSet(videoHeight)
			if not videoHeightInexact is None: self.videoHeightSet(videoHeightInexact, exact = Stream.ExactNo)
			if not videoAspect is None: self.videoAspectSet(videoAspect)
			if not videoAspectInexact is None: self.videoAspectSet(videoAspectInexact, exact = Stream.ExactNo)
			if not videoCodec is None: self.videoCodecSet(videoCodec, extract = not processed['video']['codec'])
			if not videoDepth is None: self.videoDepthSet(videoDepth, extract = not processed['video']['depth'])
			if not videoRange is None: self.videoRangeSet(videoRange, extract = not processed['video']['range'])
			if not video3d is None: self.video3dSet(video3d, extract = not processed['video']['3d'])

			if not audioType is None: self.audioTypeSet(audioType, extract = not processed['audio']['type'])
			if not audioChannels is None: self.audioChannelsSet(audioChannels, extract = not processed['audio']['channels'])
			if not audioSystem is None: self.audioSystemSet(audioSystem, extract = not processed['audio']['system'])
			if not audioCodec is None: self.audioCodecSet(audioCodec, extract = not processed['audio']['codec'])
			if audioSystem is None and not audioCodec is None: self.audioSystemSet(audioCodec, extract = not processed['audio']['codec'])
			if not audioLanguage is None: self.audioLanguageSet(audioLanguage, extract = not processed['audio']['language'])
			if not audioLanguageInexact is None: self.audioLanguageSet(audioLanguageInexact, exact = Stream.ExactNo)
			if not audioDefault is None: self.audioDefaultSet(audioDefault)

			if not subtitleType is None: self.subtitleTypeSet(subtitleType, extract = not processed['subtitle']['type'])
			if not subtitleLanguage is None: self.subtitleLanguageSet(subtitleLanguage, extract = not processed['subtitle']['language'])
			if not subtitleLanguageInexact is None: self.subtitleLanguageSet(subtitleLanguageInexact, exact = Stream.ExactNo)

			if not releaseType is None: self.releaseTypeSet(releaseType, extract = not processed['release']['type'])
			if not releaseFormat is None: self.releaseFormatSet(releaseFormat, extract = not processed['release']['format'])
			if not releaseEdition is None: self.releaseEditionSet(releaseEdition, extract = not processed['release']['edition'])
			if not releaseNetwork is None: self.releaseNetworkSet(releaseNetwork, extract = not processed['release']['network'])
			if not releaseGroup is None: self.releaseGroupSet(releaseGroup, extract = not processed['release']['group'])
			if not releaseUploader is None: self.releaseUploaderSet(releaseUploader)

			if not fileContainer is None: self.fileContainerSet(fileContainer, extract = not processed['file']['container'])
			if not filePack is None: self.filePackSet(filePack, number = number, extract = not processed['file']['pack'])

			# Must be after file pack, since the file size could be estimated.
			if not fileSize is None: self.fileSizeSet(fileSize, extract = not processed['file']['size']['exact'])
			if not fileSizeInexact is None: self.fileSizeSet(fileSizeInexact, extract = not processed['file']['size']['inexact'], exact = Stream.ExactNo)

			# Allows the file size to be recalculated if the pack was extracted from the newly added file name.
			if reload and self.filePack() and fileSize is None and fileSizeInexact is None:
				fileSize = self.fileSize(fileSize, exact = Stream.ExactYes, estimate = False)
				if fileSize is None:
					fileSizeInexact = self.fileSize(fileSize, exact = Stream.ExactNo, estimate = False)
					if not fileSizeInexact is None: self.fileSizeSet(fileSizeInexact, exact = Stream.ExactNo, extract = False)
				else:
					self.fileSizeSet(fileSize, exact = Stream.ExactYes, extract = False)

			if not sourceType is None: self.sourceTypeSet(sourceType)
			if not sourceSeeds is None: self.sourceSeedsSet(sourceSeeds, extract = not processed['source']['seeds']['exact'])
			if not sourceSeedsInexact is None: self.sourceSeedsSet(sourceSeedsInexact, extract = not processed['source']['seeds']['inexact'], exact = Stream.ExactNo)
			if not sourceLeeches is None: self.sourceLeechesSet(sourceLeeches, extract = not processed['source']['leeches']['exact'])
			if not sourceLeechesInexact is None: self.sourceLeechesSet(sourceLeechesInexact, extract = not processed['source']['leeches']['inexact'], exact = Stream.ExactNo)
			if not sourceTime is None: self.sourceTimeSet(sourceTime, extract = not processed['source']['time']['exact'], format = sourceTimeFormat)
			if not sourceTimeInexact is None: self.sourceTimeSet(sourceTimeInexact, extract = not processed['source']['time']['inexact'], exact = Stream.ExactNo, format = sourceTimeFormat)
			if not sourceOrigin is None: self.sourceOriginSet(sourceOrigin)
			if not sourceProvider is None: self.sourceProviderSet(sourceProvider)
			if not sourcePublisher is None: self.sourcePublisherSet(sourcePublisher)
			if not sourceHoster is None: self.sourceHosterSet(sourceHoster)

			if not accessType is None: self.accessTypeSet(accessType)
			if accessOffline: self.accessTypeSet(type = Stream.AccessTypeOffline)
			if accessDirect: self.accessTypeSet(type = Stream.AccessTypeDirect)
			if accessMember: self.accessTypeSet(type = Stream.AccessTypeMember)
			if accessOpen: self.accessTypeSet(type = Stream.AccessTypeOpen)
			if accessOrion: self.accessTypeSet(type = Stream.AccessTypeOrion)
			if not accessDebrid is None: self.accessDebridSet(accessDebrid)
			if not accessCache is None: self.accessCacheSet(accessCache)
			if not accessCacheInexact is None: self.accessCacheSet(accessCacheInexact, exact = Stream.ExactNo)

			if not sourceApproval is None: self.sourceApprovalSet(sourceApproval)

			if not sourcePopularity is None: self.sourcePopularitySet(sourcePopularity)
			else: self.sourcePopularityCalculate(approval = sourceApproval)

			# NB: Check (fileName or not fileNameInexact is True) for file names that are generate below with self.fileNameSet(fileNameInexact, exact = Stream.ExactNo)
			# Eg: Popcorntime
			validation = {}
			if validate and validateTitle and (fileName or not fileNameInexact is True) and (
				not self.__titleValid(data = fileName, media = metaMedia, title = metaTitleAll, titleCollection = metaTitleCollection, year = metaYear, language = metaLanguage, country = metaCountry, network = metaNetwork, studio = metaStudio, quick = False, guidance = self.data(), native = infoLanguage, adjust = validateAdjust, result = validation)
				or (not fileName == fileNameExtra and not self.__titleValid(data = fileNameExtra, media = metaMedia, title = metaTitleAll, titleCollection = metaTitleCollection, language = metaLanguage, country = metaCountry, network = metaNetwork, studio = metaStudio, quick = False, guidance = self.data(), native = infoLanguage, adjust = validateAdjust, result = validation))
			):
				self.__invalidate(id = idOrionStream, link = link, hash = hashes, name = fileName, provider = sourceProvider, invalid = Stream.InvalidTitle)
				self.debug(reason = 'Invalid Title Full', link = link, name = fileNameExtra, extra = sourceProvider)
				return cacheInvalid(id, cache, lock)

			# Do not include seasons/episodes for movies, even if the title matches.
			# Only do this if the matched title was not the primary title (aka > 1), to reduce processing power.
			# Eg: "Gran Turismo 2023" has an alias "Gran Turismo: Based on a True Story", which will be processed to "Based on a True Story".
			# Hence, this will match: "Based.on.a.True.Story.2023.S01.WEB-DL.1080p.PCOK.HDREZKA.STUDIO"
			if metaMediaMovie and validate and validateTitle and validation and validation['index'] > 1 and self.numberShowContains(data = fileNameExtra, niche = metaNiche, pack = False, exclude = True, basic = True):
				self.__invalidate(id = idOrionStream, link = link, hash = hashes, name = fileName, provider = sourceProvider, invalid = Stream.InvalidMedia)
				self.debug(reason = 'Invalid Media Type', link = link, name = fileNameExtra)
				return cacheInvalid(id, cache, lock)

			if not segment is None: self.segmentSet(segment)
			if not segmentFirst is None: self.segmentFirstSet(segmentFirst)
			if not segmentLargest is None: self.segmentLargestSet(segmentLargest)
			if not segmentList is None: self.segmentListSet(segmentList)

			if not exclusionDuplicate is None: self.exclusionDuplicateSet(exclusionDuplicate)
			if not exclusionRelease is None: self.exclusionReleaseSet(exclusionRelease)
			if not exclusionKeyword is None: self.exclusionKeywordSet(exclusionKeyword)
			if not exclusionMetadata is None: self.exclusionMetadataSet(exclusionMetadata)
			if not exclusionFormat is None: self.exclusionFormatSet(exclusionFormat)
			if not exclusionFake is None: self.exclusionFakeSet(exclusionFake)
			if not exclusionSupport is None: self.exclusionSupportSet(exclusionSupport)
			if not exclusionBlocked is None: self.exclusionBlockedSet(exclusionBlocked)
			if not exclusionCaptcha is None: self.exclusionCaptchaSet(exclusionCaptcha)
			if not exclusionPrecheck is None: self.exclusionPrecheckSet(exclusionPrecheck)

			if not infoTermination is None: self.infoTerminationSet(infoTermination)
			if not infoExact is None: self.infoExactSet(infoExact)
			if not infoCustom is None: self.infoCustomSet(infoCustom)
			if not infoSort is None: self.infoSortSet(infoSort)
			if not infoLanguage is None: self.infoLanguageSet(infoLanguage)
			if not infoQuery is None: self.infoQuerySet(infoQuery)

			if not idGaiaItem is None: self.idGaiaItemSet(idGaiaItem)
			if not idGaiaStream is None: self.idGaiaStreamSet(idGaiaStream)

			if not idOrionStream is None: self.idOrionStreamSet(idOrionStream)
			if not idOrionMovie is None: self.idOrionMovieSet(idOrionMovie)
			if not idOrionCollection is None: self.idOrionCollectionSet(idOrionCollection)
			if not idOrionShow is None: self.idOrionShowSet(idOrionShow)
			if not idOrionSeason is None: self.idOrionSeasonSet(idOrionSeason)
			if not idOrionEpisode is None: self.idOrionEpisodeSet(idOrionEpisode)
			if not idOrionData is None: self.idOrionDataSet(idOrionData)

			if not idProviderLocal is None: self.idProviderLocalSet(idProviderLocal)
			if not idProviderUniversal is None: self.idProviderUniversalSet(idProviderUniversal)
			if not idProviderCollection is None: self.idProviderCollectionSet(idProviderCollection)
			if not idProviderItem is None: self.idProviderItemSet(idProviderItem)

			if not idImdb is None: self.idImdbSet(idImdb)
			if not idTmdb is None: self.idTmdbSet(idTmdb)
			if not idTvdb is None: self.idTvdbSet(idTvdb)
			if not idTrakt is None: self.idTraktSet(idTrakt)
			if not idSlug is None: self.idSlugSet(idSlug)

			# No filename to detect from.
			if not self.videoQuality(): self.videoQualitySet(Stream.VideoQualityDefault, extract = False, exact = Stream.ExactNo)

			# Put last, since it might generate a file name from the metadata.
			if not fileNameInexact is None: self.fileNameSet(fileNameInexact, exact = Stream.ExactNo)

			# Change the magnet link name if absent ot incomplete.
			self.linkRename()

			# Exclusions
			self.exclusionUpdate()

			if cache and not id is None: self._cacheId(id, self.data())
			self.unlock(lock)
			self.statisticsUpdate(type = Stream.StatisticExtracted, timer = timer)

			return True
		except:
			tools.Logger.error()
			self.unlock(lock)
			self.statisticsUpdate(type = Stream.StatisticFailed, timer = timer)
			return False

	def reload(self, **kwargs):
		kwargs['reload'] = True
		if not 'sourceType' in kwargs or not kwargs['sourceType']: kwargs['sourceType'] = self.sourceType() # Needed for extraction, like deciding if the hash should be extracted from the link.

		# If a file name was previously passed in, do not pass it in again (except if it changed), since it will trigger loading the data from cache (eg: iDope's detail page).
		# Currently this should not be triggered, since web.py only extracts the file name it it was not previously extracted.
		fileName = self.fileName(exact = Stream.ExactRaw)
		if fileName:
			try:
				fileNameNew = kwargs['fileName']
				if fileName == fileNameNew:
					kwargs['fileName'] = None
					kwargs['validateTitle'] = False
					kwargs['validateYear'] = False
					kwargs['validateShow'] = False
					kwargs['validateSeason'] = False
					kwargs['validateEpisode'] = False
			except: pass

		return self.__load(**kwargs)

	##############################################################################
	# COPY
	##############################################################################

	'''
		FUNCTION:
			Clones the current stream object with deep copy.
	'''
	def copy(self):
		stream = Stream()
		stream.dataImport(self)
		return stream

	##############################################################################
	# EXACT
	##############################################################################

	@classmethod
	def exact(self, exact, data, sub = None):
		if exact is Stream.ExactAuto:
			try: value = data['exact']
			except: value = None
			if value is None or (sub and value[sub] is None):
				try: value = data['inexact']
				except: value = None
		elif exact is Stream.ExactNo:
			try: value = data['inexact']
			except: value = None
		elif exact == Stream.ExactRaw:
			try: value = data['raw']
			except: value = None
		elif exact == Stream.ExactTime:
			try: value = data['time']
			except: value = None
		else: value = data['exact']
		return value

	@classmethod
	def exactSet(self, exact, data, value):
		data['raw' if exact == Stream.ExactRaw else 'time' if exact == Stream.ExactTime else 'inexact' if exact is Stream.ExactNo else 'exact'] = value

	@classmethod
	def exactUpdate(self, exact, data, value):
		data['raw' if exact == Stream.ExactRaw else 'time' if exact == Stream.ExactTime else 'inexact' if exact is Stream.ExactNo else 'exact'].update(value)

	@classmethod
	def exactSub(self, exact, data, sub):
		if exact is Stream.ExactAuto:
			try: value = data['exact'][sub]
			except: value = None
			if value is None:
				try: value = data['inexact'][sub]
				except: value = None
		elif exact is Stream.ExactNo:
			try: value = data['inexact'][sub]
			except: value = None
		elif exact == Stream.ExactRaw:
			try: value = data['raw'][sub]
			except: value = None
		elif exact == Stream.ExactTime:
			try: value = data['time'][sub]
			except: value = None
		else: value = data['exact'][sub]
		return value

	@classmethod
	def exactSubSet(self, exact, data, value, sub):
		data['raw' if exact == Stream.ExactRaw else 'time' if exact == Stream.ExactTime else 'inexact' if exact is Stream.ExactNo else 'exact'][sub] = value

	@classmethod
	def exactSubUpdate(self, exact, data, value, sub):
		data['raw' if exact == Stream.ExactRaw else 'time' if exact == Stream.ExactTime else 'inexact' if exact is Stream.ExactNo else 'exact'][sub].update(value)

	##############################################################################
	# DEBUG
	##############################################################################

	@classmethod
	def debug(self, reason, link = None, name = None, extra = None):
		if self.debugEnabled():
			message = 'Stream Rejected: %s' % reason
			if name:
				message += ' [%s]'
				try: message = message % name
				except: message = message % tools.Converter.unicode(name)
			elif link:
				message += ' [%s]'
				try: message = message % link
				except: message = message % tools.Converter.unicode(link)
			if extra: message += ' (%s)' % extra
			tools.Logger.log(message)

	@classmethod
	def debugEnabled(self):
		return False#gaiaremove
		if Stream.Debug is None: Stream.Debug = tools.System.developer()
		return Stream.Debug

	##############################################################################
	# DATA
	##############################################################################

	'''
		FUNCTION:
			Called before exporting the metadata to a copied dictionary.
	'''
	def dataExportBefore(self):
		return self.providerUnload()

	'''
		FUNCTION:
			Called after exporting the metadata to a copied dictionary.
	'''
	def dataExportAfter(self, data = None):
		self.providerReload(data)

	'''
		FUNCTION:
			Imports the metadata from a JSON string or metadata object.
	'''
	def dataImport(self, data, full = True):
		try:
			# NB: Important to create a deep copy of the dictionary.
			# Otherwise multiple streams can have metadata that points to the same dictionary.
			# Changing values in one metadata, will change the value in the other metadatas as well.
			provider = None
			if tools.Tools.isString(data):
				data = tools.Converter.jsonFrom(data)
			elif tools.Tools.isInstance(data, Stream):
				stream = data
				provider = stream.provider(load = False)
				if provider: providerData = stream.providerUnload()
				data = stream.dataCopy()
				if provider: stream.providerReload(providerData)
			else:
				try:
					provider = data['provider']['data']
					data['provider']['data'] = None
				except: pass
				data = tools.Tools.copy(data)

			if not full:
				try: del data['access']
				except: pass

			self.mData.update(data)
			if provider: self.providerSet(provider)
		except: tools.Logger.error()

	'''
		FUNCTION:
			Counts the number of valid attributes.
	'''
	def dataCount(self):
		def _count(value):
			count = 0
			if tools.Tools.isDictionary(value):
				for val in value.values():
					count += _count(val)
			else:
				if not value is None: count += 1
			return count

		result = 0
		for i in ['hash', 'video', 'audio', 'subtitle', 'release', 'file', 'source', 'access']:
			result += _count(self.mData[i])
		return result

	##############################################################################
	# CACHE
	##############################################################################

	# When passing large arguments into this function (like large lists of regex), calculating the id might take very long.
	# Try to instead use _cacheId() with a fixed ID.
	@classmethod
	def _cache(self, function, *args, **kwargs):
		id = self._cacheIdGenerate(function, self._cacheArguments(function, *args, **kwargs))
		return self._cacheIdHandle(id, False, function, *args, **kwargs)

	@classmethod
	def _cacheInternal(self, function, *args, **kwargs):
		id = self._cacheIdGenerate(function, self._cacheArguments(function, *args, **kwargs))
		return self._cacheIdHandle(id, True, function, *args, **kwargs)

	@classmethod
	def _cacheId(self, id, function, *args, **kwargs):
		return self._cacheIdHandle(id, False, function, *args, **kwargs)

	@classmethod
	def _cacheIdInternal(self, id, function, *args, **kwargs):
		return self._cacheIdHandle(id, True, function, *args, **kwargs)

	@classmethod
	def _cacheIdHandle(self, id, internal, function, *args, **kwargs):
		if id is None: id = self._cacheIdGenerate(function, self._cacheArguments(function, *args, **kwargs))
		if id in Stream.CacheData:
			return Stream.CacheData[id]
		elif function:
			# No locking is needed for threads, since Python structures are thread-safe.
			# However, when multiple threads all call this function to execute something computationally expensive (eg re.compile), only let one thread execute it and the rest wait for the result.
			Stream.LockCache.acquire()
			try:
				event = Stream.CacheEvent[id]
				Stream.LockCache.release()
				event.wait()
				return Stream.CacheData[id]
			except:
				event = Event()
				Stream.CacheEvent[id] = event
				Stream.LockCache.release()
				data = None

				# There are 3 levels of caching:
				#	1. Cache in a class variable (Stream.CacheData). Fastest access, but the variable is reset after each execution.
				#	2. Cache in Kodi's global variable. Only for re.compile. Fast access, data remains between executions. Data resets if Kodi restarts.
				#	3. Cache in a database file. Only for re.compile. Slow access, but data remains between executions and Kodi restarts.
				# Compiling regex can take a long time, especially in _numberShowExtract(), which can take +- 2.5 seconds.
				# This only takes so long the first time the compilation happens. Each subsequent execution of the expression will use the locally cached already-compiled regex.
				# Cache the compiled regex in Kodi's global variable and in a database file. This ensures that compiled regex can be quickly retrieved among different executions and Kodi restarts.
				# The Kodi and Gaia version are added to the id from _cacheIdGenerate(), in order to ensure changes to the regex or Python version will not use the cached values form older versions.
				# This increases the scraping time during the first ever scrape (after a new Gaia/Kodi version), since a lot has to be written to the database.
				# However, every subsequent run should be a few seconds faster.
				# Not sure if this actually reduces the overall scraping time.
				property = None
				settings = None
				try:
					# Only do this for re.compile, since other cache functions might be too dependent on unique data (eg: file name).
					# Do not do for developer, since changing the regex always requires the cache database to be cleared in order to reload the new regex.
					# This might be problematic, since if there is an error in the code below, it will only show up in the public release.
					# Do not cache if "internal = True", since it might contain titles or something that is not generic.
					if Stream.CacheFile:
						init = self._cacheInitialize()
						settings = init['settings']
						if not settings == Stream.CacheDisabled:
							if not internal and function == re.compile and not init['developer']:
								property = 'GaiaExpression_' + str(tools.Hash.hashPersistent(init['version'] + '_' + str(id)))
								value = tools.System.windowPropertyGet(property)
								if not value and settings == Stream.CacheFull:
									value = Cache.instance().expressionRetrieve(id = property)
									if value: tools.System.windowPropertySet(property, value)
								if value:
									Stream.CacheData[id] = pickle.loads(tools.Converter.base64From(value))
									data = Stream.CacheData[id]
				except:
					tools.Logger.error()
					property = None

				if not data:
					if callable(function):
						kwargs = self._cacheArguments(function, *args, **kwargs)
						if kwargs:
							for k, v in kwargs.items():
								if callable(v): kwargs[k] = v()
						data = function(**kwargs)
					else:
						data = function

					Stream.CacheData[id] = data
					try:
						if property:
							value = tools.Converter.base64To(pickle.dumps(data))
							tools.System.windowPropertySet(property, value)
							if settings == Stream.CacheFull: Cache.instance().expressionCache(id = property, data = value)
					except:
						tools.Logger.error()

				del Stream.CacheEvent[id]
				event.set()

				return data

		return None

	@classmethod
	def _cacheIdGenerate(self, function, kwargs = None):
		if function is None: return None

		init = self._cacheInitialize()
		id = init['expression2'].sub('', init['expression1'].sub('', repr(function))) + '_'

		if kwargs:
			items = []
			for key, value in kwargs.items():
				# Do not stringify large lists/dictionaries that should be the same across calls.
				# This takes extra time, including when the value is already cached, but we still have to calculate the ID for the lookup.
				# Not sure if this might cause issues in special cases. If so, remove this again or adjust accordingly.
				if key == 'pack': # metaPack (called from numberCollectionExtract()).
					if value and tools.Tools.isDictionary(value): value = [len(value.keys()), value.get('title'), value.get('count')]
				elif key == 'title' or key == 'titles': # metaTitle (this should not be called from anywhere at the moment).
					if value and tools.Tools.isList(value):
						length = len(value)
						if length > 3: value = [length, length[:3], length[-3:]]

				try: value = tools.Converter.unicode(value)
				except: pass
				items.append(str(key) + '=' + value)
			id += '_'.join(items)

		return tools.Hash.hashPersistent(id) # Faster than other hashing algorithms like SHA256.

	@classmethod
	def _cacheIdMinimize(self, *args):
		# Use mutiple titles for the ID, otherwise from tester.py if there are mutiple test cases with the same title (eg: The Office US/UK/PL/IL/etc), the same cached values are used.
		id = []
		first = True
		for i in args:
			if i:
				if first:
					first = False
					if tools.Tools.isArray(i):
						id.extend(i[:3])
						id.append(i[-1])
						id.append(str(len(i)))
					else:
						id.append(str(i))
				else:
					if tools.Tools.isArray(i): id.append(i[0])
					else: id.append(str(i))
		return '_'.join(id) if id else ''

	@classmethod
	def _cacheInitialize(self):
		if Stream.CacheInit is None:
			# The "id" is not important for local caching (adding to Stream.Cache).
			# However, it is important for permanent caching (global var or database).
			# If Kodi's version changes, Python's version might also change, possibly making the compiled regex from older versions incompatible with newer versions.
			# If Gaia's version changes, it might mean that the expressions themeselves were changed.
			from lib.providers.core.base import ProviderBase
			Stream.CacheInit = {
				'version' : tools.System.versionKodi(full = True) + '_' + tools.System.version(),
				'developer' : tools.System.developer(code = False),
				'settings' : ProviderBase.settingsGlobalSaveExpression(),
				'expression1' : re.compile('.+\smethod\s|.+function\s|\sat\s.+|\sof\s.+'),
				'expression2' : re.compile('>'),
			}
		return Stream.CacheInit

	@classmethod
	def _cacheArguments(self, function, *args, **kwargs):
		try: parameters = function.__code__.co_varnames # Python 3
		except: parameters = function.func_code.co_varnames # Python 2
		parameters = (parameter for parameter in parameters if not parameter == 'self')
		kwargs.update(dict(zip(parameters, args)))
		return kwargs

	@classmethod
	def _cacheClear(self):
		Stream.CacheData = {}
		Stream.CacheEvent = {}
		Stream.CacheInit = None

	##############################################################################
	# LOCK
	##############################################################################

	@classmethod
	def lock(self, lock = True):
		if lock: Stream.LockThread.acquire()

	@classmethod
	def unlock(self, lock = True):
		if lock: Stream.LockThread.release()

	##############################################################################
	# SETTINGS
	##############################################################################

	@classmethod
	def settingsFilters(self, category, attribute):
		return Filters.instance().data(category = category, attribute = attribute)

	@classmethod
	def settingsLayout(self, label, category, attribute):
		if label == Stream.LabelSettings:
			label = Layout.data(category = category, attribute = attribute)
		elif label == Stream.LabelForce:
			label = Layout.data(category = category, attribute = attribute)
			if label == Stream.LabelHidden: label = Stream.LabelForce
		return label

	@classmethod
	def settingsFormat(self):
		layoutColor = True
		layoutBold = True
		if tools.Settings.getBoolean('label.stream.style'):
			layoutColor = tools.Settings.getBoolean('label.stream.style.color')
			layoutBold = tools.Settings.getBoolean('label.stream.style.bold')
		if layoutColor and layoutBold: return Stream.FormatDecorate
		elif layoutColor: return Stream.FormatColor
		elif layoutBold: return Stream.FormatBold
		else: return Stream.FormatBasic

	##############################################################################
	# DIALOG
	##############################################################################

	def dialog(self):
		try:
			interface.Loader.show()

			items = []
			label = Stream.LabelDetails

			none = interface.Format.italic(33112)
			yes = interface.Translation.string(33341)
			no = interface.Translation.string(33342)

			# Video Details
			items.append({
				'title' : 35709,
				'items' : [
					{'title' : 33889, 'value' : self.videoQuality(label = label, default = none)},
					{'title' : 35714, 'value' : self.videoResolution(label = label, default = none)},
					{'title' : 35713, 'value' : self.videoAspect(label = label, default = none)},
					{'title' : 33127, 'value' : self.videoCodec(label = label, default = none)},
					{'title' : 35711, 'value' : self.videoRange(label = label, default = none)},
					{'title' : 35710, 'value' : self.videoDepth(label = label, default = none)},
					{'title' : 35712, 'value' : self.video3d(label = label, default = none)},
				]
			})

			# Audio Details
			items.append({
				'title' : 35716,
				'items' : [
					{'title' : 35717, 'value' : self.audioType(label = label, default = none)},
					{'title' : 33129, 'value' : self.audioChannels(label = label, default = none)},
					{'title' : 35718, 'value' : self.audioSystem(label = label, default = none)},
					{'title' : 33130, 'value' : self.audioCodec(label = label, default = none)},
					{'title' : 35038, 'value' : self.audioLanguage(label = label, default = none, sort = True)},
				]
			})

			# Subtitle Details
			items.append({
				'title' : 35720,
				'items' : [
					{'title' : 35721, 'value' : self.subtitleType(label = label, default = none)},
					{'title' : 35722, 'value' : self.subtitleLanguage(label = label, default = none, sort = True)},
				]
			})

			# Release Details
			items.append({
				'title' : 35730,
				'items' : [
					{'title' : 35731, 'value' : self.releaseType(label = label, default = none)},
					{'title' : 35736, 'value' : self.releaseFormat(label = label, default = none)},
					{'title' : 35732, 'value' : self.releaseEdition(label = label, default = none)},
					{'title' : 35733, 'value' : self.releaseNetwork(label = label, default = none)},
					{'title' : 35734, 'value' : self.releaseGroup(label = label, default = none)},
					{'title' : 33243, 'value' : self.releaseUploader(label = label, default = none)},
				]
			})

			# File Details
			items.append({
				'title' : 35723,
				'items' : [
					{'title' : 35724, 'value' : self.fileName(default = none)},
					{'title' : 32056, 'value' : self.fileExtra(default = none)},
					{'title' : 35726, 'value' : self.fileSize(label = label, default = none)},
					{'title' : 33133, 'value' : self.fileBandwidth(label = label, default = none)},
					{'title' : 35727, 'value' : self.fileContainer(label = label, default = none)},
					{'title' : 35728, 'value' : self.filePack(label = label, default = none)},
					{'title' : 35725, 'value' : self.hash(label = label, default = none)},
				]
			})

			# Source Details
			items.append({
				'title' : 35735,
				'items' : [
					{'title' : 33890, 'value' : self.sourceType(label = label, default = none)},
					{'title' : 33189, 'value' : self.sourcePeers(label = label, default = none, separate = True)},
					{'title' : 35407, 'value' : self.sourceTime(label = label, default = none, time = Stream.TimeDuration)},
					{'title' : 35399, 'value' : self.sourcePopularity(label = label)},
					{'title' : 35737, 'value' : self.sourceOrigin(label = label, default = none, orion = None)},
					{'title' : 35395, 'value' : self.sourceProvider(default = none)},
					{'title' : 35396, 'value' : self.sourcePublisher(default = none)},
					{'title' : 35738, 'value' : self.sourceHoster(default = none)},
				]
			})

			# Access Details
			items.append({
				'title' : 35739,
				'items' : [
					{'title' : 36356, 'value' : yes if self.accessTypeOffline() else no},
					{'title' : 35740, 'value' : yes if self.accessTypeDirect() else no},
					{'title' : 35707, 'value' : yes if self.accessTypeMember() else no},
					{'title' : 35741, 'value' : yes if self.accessTypeOpen(account = True) else no},
					{'title' : 35742, 'value' : yes if self.accessTypeOrion() else no},
					{'title' : 35743, 'value' : self.accessDebrid(label = label, default = no, account = True)},
					{'title' : 35744, 'value' : self.accessCache(label = label, default = no, account = True)},
				]
			})

			# Link Details
			link = self.link()
			linkLabel = interface.Translation.string(33381)
			if len(link) == 1: linkItems = [{'title' : linkLabel, 'value' : link[0]}]
			else: linkItems = [{'title' : '%s %d' % (linkLabel, i + 1), 'value' : link[i]} for i in range(len(link))]
			items.append({
				'title' : 32349,
				'items' : linkItems,
			})

			# Dialog
			interface.Loader.hide()
			interface.Dialog.information(title = 33415, items = items, copy = True)
		except:
			interface.Loader.hide()
			tools.Logger.error()

	##############################################################################
	# THRESHOLD
	##############################################################################

	@classmethod
	def threshold(self, key1, key2 = None, key3 = None):
		if key1 == 'title' and not Stream.Threshold['settings']:
			Stream.LockOther.acquire()
			if not Stream.Threshold['settings']: # Check again during multi-threading.
				setting = self.thresholdName()
				difference = Stream.Threshold['title']['base']
				if setting >= 50: difference = 1 - difference
				Stream.Threshold['title']['base'] = (((setting - 50) / 100.0) * difference * 2) + Stream.Threshold['title']['base']
				Stream.Threshold['title']['short']['length2'] = int(Stream.Threshold['title']['short']['length'] * 1.3)
				Stream.Threshold['title']['short']['double'] = Stream.Threshold['title']['base'] * Stream.Threshold['title']['short']['multiplier'] * Stream.Threshold['title']['concatenated']['start']
				Stream.Threshold['title']['long']['single'] = Stream.Threshold['title']['base'] * Stream.Threshold['title']['long']['multiplier']
				Stream.Threshold['title']['long']['double'] = Stream.Threshold['title']['long']['single'] * Stream.Threshold['title']['concatenated']['start']
				Stream.Threshold['title']['long']['concatenated'] = Stream.Threshold['title']['base'] * Stream.Threshold['title']['concatenated']['multiplier']
				Stream.Threshold['title']['strict'] = min(Stream.Threshold['title']['maximum'], Stream.Threshold['title']['base'] * Stream.Threshold['title']['strict'])
				Stream.Threshold['settings'] = True
			Stream.LockOther.release()
		result = Stream.Threshold[key1]
		try:
			result = result[key2]
			try: result = result[key3]
			except: pass
		except: pass
		return result

	@classmethod
	def thresholdName(self):
		return tools.Settings.getInteger('scrape.filter.threshold')

	@classmethod
	def thresholdNameDefault(self):
		return int(tools.Settings.raw(id = 'scrape.filter.threshold', parameter = tools.Settings.ParameterDefault))

	@classmethod
	def thresholdNameLenient(self):
		return self.thresholdName() < self.thresholdNameDefault()

	@classmethod
	def thresholdNameStrict(self):
		return self.thresholdName() > self.thresholdNameDefault()

	'''
		FUNCTION:
			Retrieves the custom fakeness threshold for validating if streams are fake uploads.
		RETURNS:
			The size threshold (integer).
	'''
	def thresholdFake(self):
		return self.mThreshold['fake']

	'''
		FUNCTION:
			Sets a custom fakeness threshold for validating if streams are fake uploads.
		PARAMETERS:
			value (integer): The size threshold in bytes.
	'''
	def thresholdFakeSet(self, value):
		self.mThreshold['fake'] = value

	'''
		FUNCTION:
			Retrieves the custom size threshold for validating minimum file sizes.
		RETURNS:
			The size threshold (integer).
	'''
	def thresholdSize(self, type = None, media = None, pack = None, default = False):
		if type is None:
			if media:
				if tools.Media.isFilm(media): type = 'movie'
				elif tools.Media.isSerie(media): type = 'show' if pack else 'episode'
			if type is None: type = 'common'
		result = self.mThreshold['size'][type]
		if result is None and default: result = self.threshold('size', type)
		return result

	'''
		FUNCTION:
			Sets a custom size threshold for validating minimum file sizes.
		PARAMETERS:
			value (integer): The size threshold in bytes.
	'''
	def thresholdSizeSet(self, value, type = None, media = None, pack = None):
		if type is None:
			if media:
				if tools.Media.isFilm(media): type = 'movie'
				elif tools.Media.isSerie(media): type = 'show' if pack else 'episode'
			if type is None: type = 'common'
		self.mThreshold['size'][type] = value

	'''
		FUNCTION:
			Retrieves the custom time threshold for validating the maximum age.
		RETURNS:
			The time/age threshold (integer).
	'''
	def thresholdTime(self):
		return self.mThreshold['time']

	'''
		FUNCTION:
			Sets a custom time threshold for validating the maximum age.
		PARAMETERS:
			value (integer): The time/age threshold in seconds.
	'''
	def thresholdTimeSet(self, value):
		self.mThreshold['time'] = value

	'''
		FUNCTION:
			Retrieves the custom peer threshold for validating minimum torrent peers.
		RETURNS:
			The peer threshold (integer).
	'''
	def thresholdPeers(self):
		return self.mThreshold['peers']

	'''
		FUNCTION:
			Sets a custom peer threshold for validating minimum torrent peers.
		PARAMETERS:
			value (integer): The peer threshold.
	'''
	def thresholdPeersSet(self, value):
		self.mThreshold['peers'] = value

	'''
		FUNCTION:
			Retrieves the custom seed threshold for validating minimum torrent seeds.
		RETURNS:
			The seed threshold (integer).
	'''
	def thresholdSeeds(self):
		return self.mThreshold['seeds']

	'''
		FUNCTION:
			Sets a custom seed threshold for validating minimum torrent seeds.
		PARAMETERS:
			value (integer): The seed threshold.
	'''
	def thresholdSeedsSet(self, value):
		self.mThreshold['seeds'] = value

	'''
		FUNCTION:
			Retrieves the custom leech threshold for validating minimum torrent leeches.
		RETURNS:
			The leech threshold (integer).
	'''
	def thresholdLeeches(self):
		return self.mThreshold['leeches']

	'''
		FUNCTION:
			Sets a custom leech threshold for validating minimum torrent leeches.
		PARAMETERS:
			value (integer): The leech threshold.
	'''
	def thresholdLeechesSet(self, value):
		self.mThreshold['leeches'] = value

	##############################################################################
	# PARAMETER
	##############################################################################

	@classmethod
	def _parameter(self, category, attribute):
		return category + attribute.capitalize()

	def parameter(self, category, attribute, **kwargs):
		return getattr(self, self._parameter(category = category, attribute = attribute))(**kwargs)

	def parameterSet(self, category, attribute, **kwargs):
		return getattr(self, self._parameter(category = category, attribute = attribute) + 'Set')(**kwargs)

	##############################################################################
	# VALID
	##############################################################################

	# guidance (None/dictionary): If previously extracted data structure.
	# lock (boolean): Whether or not to use a global lock to only allow a single thread to execute the load() function at any give time, improving the overall execution time.
	@classmethod
	def valid(self,
		data,
		media,
		niche = None,
		title = None,
		titleCollection = None,
		titleEpisode = None,
		year = None,
		time = None,
		season = None,
		episode = None,
		number = None,
		language = None,
		country = None,
		network = None,
		studio = None,
		pack = None,

		numberCollection = None,
		fileRaw = None,
		filePack = None,
		fileSize = None,
		sourceType = None,
		sourceTime = None,
		sourcePeers = None,
		sourceSeeds = None,
		sourceLeeches = None,

		quick = True,
		lock = True,
		deviation = True,
		guidance = None,
		native = None,

		validateAdjust = None,
		validateTitle = True,
		validateYear = True,
		validateShow = True,
		validateSeason = True,
		validateEpisode = True,
		validateRelease = True,
		validateKeyword = True,
		validateFormat = True,
		validateSize = True,
		validateTime = True,
		validatePeers = True,
		validateSeeds = True,
		validateLeeches = True,

		thresholdSize = None,
		thresholdTime = None,
		thresholdPeers = None,
		thresholdSeeds = None,
		thresholdLeeches = None,

		none = True,
	):
		data = self.cleanBasic(data)
		title = self.cleanEncode(title)
		return self.__valid(
			data = data,
			media = media,
			niche = niche,
			title = title,
			titleCollection = titleCollection,
			titleEpisode = titleEpisode,
			year = year,
			time = time,
			season = season,
			episode = episode,
			number = number,
			language = language,
			country = country,
			network = network,
			studio = studio,
			pack = pack,

			numberCollection = numberCollection,
			fileRaw = fileRaw,
			filePack = filePack,
			fileSize = fileSize,
			sourceType = sourceType,
			sourceTime = sourceTime,
			sourcePeers = sourcePeers,
			sourceSeeds = sourceSeeds,
			sourceLeeches = sourceLeeches,

			quick = quick,
			lock = lock,
			deviation = deviation,
			guidance = guidance,
			native = native,

			validateAdjust = validateAdjust,
			validateTitle = validateTitle,
			validateYear = validateYear,
			validateShow = validateShow,
			validateSeason = validateSeason,
			validateEpisode = validateEpisode,
			validateRelease = validateRelease,
			validateKeyword = validateKeyword,
			validateFormat = validateFormat,
			validateSize = validateSize,
			validateTime = validateTime,
			validatePeers = validatePeers,
			validateSeeds = validateSeeds,
			validateLeeches = validateLeeches,

			thresholdSize = thresholdSize,
			thresholdTime = thresholdTime,
			thresholdPeers = thresholdPeers,
			thresholdSeeds = thresholdSeeds,
			thresholdLeeches = thresholdLeeches,

			none = none,
		)

	def _valid(self,
		data = None,
		media = None,
		niche = None,
		title = None,
		titleCollection = None,
		titleEpisode = None,
		year = None,
		time = None,
		season = None,
		episode = None,
		number = None,
		language = None,
		country = None,
		network = None,
		studio = None,
		pack = None,

		filePack = None,

		quick = True,
		lock = True,
		deviation = True,

		validateAdjust = None,
		validateTitle = True,
		validateYear = True,
		validateShow = True,
		validateSeason = True,
		validateEpisode = True,
		validateRelease = None,
		validateKeyword = None,
		validateFormat = None,
		validateSize = None,
		validateTime = None,
		validatePeers = None,
		validateSeeds = None,
		validateLeeches = None,

		thresholdSize = None,
		thresholdTime = None,
		thresholdPeers = None,
		thresholdSeeds = None,
		thresholdLeeches = None,

		none = True,
	):
		return self.__valid(
			data = data if data else self.fileName(),

			media = media if media else self.metaMedia(),
			niche = niche if niche else self.metaNiche(),
			title = title if title else self.metaTitle(),
			titleCollection = titleCollection if titleCollection else self.metaTitle(title = Stream.TitleCollection),
			titleEpisode = titleEpisode if titleEpisode else self.metaTitle(title = Stream.TitleEpisode),
			year = year if year else self.metaYear(),
			time = time if time else self.metaTime(),
			season = season if season else self.metaSeason(),
			episode = episode if episode else self.metaEpisode(),
			number = number if number else self.metaNumber(),
			language = language if language else self.metaLanguage(),
			country = country if country else self.metaCountry(),
			network = network if network else self.metaNetwork(),
			studio = studio if studio else self.metaStudio(),
			pack = pack if pack else self.metaPack(),

			numberCollection = self.numberCollection(),
			fileRaw = self.fileName(exact = Stream.ExactRaw),
			filePack = filePack if filePack else self.filePack(),
			fileSize = self.fileSize(),
			sourceType = self.sourceType(),
			sourceTime = self.sourceTime(time = Stream.TimeNone),
			sourcePeers = self.sourcePeers(),
			sourceSeeds = self.sourceSeeds(),
			sourceLeeches = self.sourceLeeches(),

			quick = quick,
			lock = lock,
			deviation = deviation,
			guidance = self.data(),
			native = self.infoLanguage(),

			validateAdjust = validateAdjust,
			validateTitle = validateTitle,
			validateYear = validateYear,
			validateShow = validateShow,
			validateSeason = validateSeason,
			validateEpisode = validateEpisode,
			validateRelease = self.validationRelease() if validateRelease is None else validateRelease,
			validateKeyword = self.validationKeyword() if validateKeyword is None else validateKeyword,
			validateFormat = self.validationFormat() if validateFormat is None else validateFormat,
			validateSize = self.validationSize() if validateSize is None else validateSize,
			validateTime = self.validationTime() if validateTime is None else validateTime,
			validatePeers = self.validationPeers() if validatePeers is None else validatePeers,
			validateSeeds = self.validationSeeds() if validateSeeds is None else validateSeeds,
			validateLeeches = self.validationLeeches() if validateLeeches is None else validateLeeches,

			thresholdSize = self.thresholdSize(media = self.metaMedia(), pack = self.filePack(), default = True) if thresholdSize is None else thresholdSize,
			thresholdTime = self.thresholdTime() if thresholdTime is None else thresholdTime,
			thresholdPeers = self.thresholdPeers() if thresholdPeers is None else thresholdPeers,
			thresholdSeeds = self.thresholdSeeds() if thresholdSeeds is None else thresholdSeeds,
			thresholdLeeches = self.thresholdLeeches() if thresholdLeeches is None else thresholdLeeches,

			none = none,
		)

	@classmethod
	def __valid(self,
		data,
		media,
		niche,
		title,
		titleCollection,
		titleEpisode,
		year,
		time,
		season,
		episode,
		number,
		language,
		country,
		network,
		studio,
		pack,

		numberCollection,
		fileRaw,
		filePack,
		fileSize,
		sourceType,
		sourceTime,
		sourcePeers,
		sourceSeeds,
		sourceLeeches,

		quick,
		lock,
		deviation,
		guidance,
		native,

		validateAdjust,
		validateTitle,
		validateYear,
		validateShow,
		validateSeason,
		validateEpisode,
		validateRelease,
		validateKeyword,
		validateFormat,
		validateSize,
		validateTime,
		validatePeers,
		validateSeeds,
		validateLeeches,

		thresholdSize,
		thresholdTime,
		thresholdPeers,
		thresholdSeeds,
		thresholdLeeches,

		none,
	):
		if none and data is None: return True
		self.lock(lock)

		# File Size
		if validateSize and not self.__fileSizeValid(fileSize, threshold = thresholdSize):
			self.unlock(lock)
			return False

		# Source Time/Age
		if validateTime and not self.__sourceTimeValid(sourceTime, threshold = thresholdTime):
			self.unlock(lock)
			return False

		# Source Peers
		if validateSeeds and not self.__sourceSeedsValid(sourceSeeds, threshold = thresholdSeeds):
			self.unlock(lock)
			return False
		if validateLeeches and not self.__sourceLeechesValid(sourceLeeches, threshold = thresholdLeeches):
			self.unlock(lock)
			return False
		if validatePeers and (sourcePeers is not None or sourceSeeds is not None or sourceLeeches is not None):
			if sourcePeers is None:
				sourcePeers = 0
				try: sourcePeers += sourceSeeds
				except: pass
				try: sourcePeers += sourceLeeches
				except: pass
			if not self.__sourcePeersValid(sourcePeers, threshold = thresholdPeers):
				self.unlock(lock)
				return False

		# Invalid Release
		if validateRelease:
			if not self.__releaseValid(data = data, media = media, title = title, year = year, language = language, country = country, network = network, studio = studio, time = time, pack = pack, numberCollection = numberCollection, filePack = filePack, sourceTime = sourceTime):
				self.unlock(lock)
				return False

		# Title Keywords
		if validateKeyword and self.__titleProhibited(data = data, title = title, special = self.metaSpecial(season = season, episode = episode)):
			self.unlock(lock)
			return False

		# File Format
		if validateFormat and not self.fileNameValid(data = data, raw = fileRaw, type = sourceType):
			self.unlock(lock)
			return False

		# Show Number
		if tools.Media.isSerie(media):
			if validateShow and (validateSeason or validateEpisode):
				if not self.__numberSpecialValid(data = data, title = titleEpisode, niche = niche, real = guidance['number'] if guidance else None, season = season if validateSeason else None, episode = episode if validateEpisode else None, number = number, pack = pack, filePack = filePack):
					self.unlock(lock)
					return False

		# Year
		if validateYear:
			if self.__yearValid(media = media, year = year, data = data, pack = pack, filePack = filePack, deviation = deviation) is False:
				self.unlock(lock)
				return False

		# Title
		if validateTitle:
			validation = {}
			if not self.__titleValid(data = data, media = media, title = title, titleCollection = titleCollection, year = year, language = language, country = country, network = network, studio = studio, quick = quick, guidance = guidance, native = native, adjust = validateAdjust, result = validation):
				self.unlock(lock)
				return False

			# Do not include seasons/episodes for movies, even if the title matches.
			# Only do this if the matched title was not the primary title (aka > 1), to reduce processing power.
			# Eg: "Gran Turismo 2023" has an alias "Gran Turismo: Based on a True Story", which will be processed to "Based on a True Story".
			# Hence, this will match: "Based.on.a.True.Story.2023.S01.WEB-DL.1080p.PCOK.HDREZKA.STUDIO"
			if tools.Media.isFilm(media) and validation and validation['index'] > 1 and self.numberShowContains(data = data, niche = niche, pack = False, exclude = True, basic = True):
				self.unlock(lock)
				return False

		self.unlock(lock)
		return True

	@classmethod
	def validName(self,
		data,
		media,
		niche = None,
		title = None,
		titleCollection = None,
		titleEpisode = None,
		year = None,
		season = None,
		episode = None,
		number = None,
		language = None,
		country = None,
		network = None,
		studio = None,

		quick = True,
		lock = True,
		deviation = True,
		guidance = None,
		native = None,

		validateAdjust = None,
		validateTitle = True,
		validateYear = True,
		validateShow = True,
		validateSeason = True,
		validateEpisode = True,
	):
		return self.valid(
			data = data,
			media = media,
			niche = niche,
			title = title,
			titleCollection = titleCollection,
			titleEpisode = titleEpisode,
			year = year,
			season = season,
			episode = episode,
			number = number,
			language = language,
			country = country,
			network = network,
			studio = studio,

			quick = quick,
			lock = lock,
			deviation = deviation,
			guidance = guidance,
			native = native,

			validateAdjust = validateAdjust,
			validateTitle = validateTitle,
			validateYear = validateYear,
			validateShow = validateShow,
			validateSeason = validateSeason,
			validateEpisode = validateEpisode,
			validateRelease = False,
			validateKeyword = False,
			validateFormat = False,
			validateSize = False,
			validateTime = False,
			validatePeers = False,
			validateSeeds = False,
			validateLeeches = False,
		)

	def _validName(self,
		data = None,
		media = None,
		niche = None,
		title = None,
		titleCollection = None,
		titleEpisode = None,
		year = None,
		season = None,
		episode = None,
		number = None,
		language = None,
		country = None,
		network = None,
		studio = None,

		quick = True,
		lock = True,
		deviation = True,

		validateAdjust = None,
		validateTitle = True,
		validateYear = True,
		validateShow = True,
		validateSeason = True,
		validateEpisode = True,
	):
		return self._valid(
			data = data,

			media = media,
			niche = niche,
			title = title,
			titleCollection = titleCollection,
			titleEpisode = titleEpisode,
			year = year,
			season = season,
			episode = episode,
			number = number,
			language = language,
			country = country,
			network = network,
			studio = studio,

			quick = quick,
			lock = lock,
			deviation = deviation,

			validateAdjust = validateAdjust,
			validateTitle = validateTitle,
			validateYear = validateYear,
			validateShow = validateShow,
			validateSeason = validateSeason,
			validateEpisode = validateEpisode,
			validateRelease = False,
			validateKeyword = False,
			validateFormat = False,
			validateSize = False,
			validateTime = False,
			validatePeers = False,
			validateSeeds = False,
			validateLeeches = False,
		)

	##############################################################################
	# INVALID
	##############################################################################

	@classmethod
	def invalid(self):
		return Stream.InvalidData

	@classmethod
	def invalidExtract(self):
		return Stream.InvalidExtract

	@classmethod
	def invalidExtractSet(self, extract):
		Stream.InvalidExtract = extract

	@classmethod
	def invalidate(self, id = None, link = None, hash = None, name = None, provider = None, invalid = None):
		return self.__invalidate(id = id, link = link, hash = hash, name = name, provider = provider, invalid = invalid)

	def _invalidate(self, invalid = None):
		return self.__invalidate(id = self.idOrionStream(), link = self.link(), hash = self.hashes(structure = False), name = self.fileName(), provider = self.sourceProvider(), invalid = invalid)

	@classmethod
	def __invalidate(self, id = None, link = None, hash = None, name = None, provider = None, invalid = None):
		data = {}
		if id: data['id'] = id
		if link:
			if tools.Tools.isArray(link):
				link = [i for i in link if not network.Networker.linkIsMagnet(i)]
				if link: data['link'] = link
			elif not network.Networker.linkIsMagnet(link): data['link'] = link
		if hash:
			if tools.Tools.isArray(hash): data['hash'] = [i.lower() for i in hash]
			else: data['hash'] = hash.lower()

		if data:
			if name: data['name'] = name
			if provider: data['provider'] = provider
			if invalid: data['invalid'] = invalid
			Stream.InvalidData.append(data)
			return True
		return False

	@classmethod
	def invalidClear(self):
		Stream.InvalidData = []
		Stream.InvalidExtract = None

	##############################################################################
	# ID
	##############################################################################

	'''
		FUNCTION:
			Retrieves a specific ID.
		PARAMETERS:
			category (string): The category of ID to retrieve. Or the default best one if not specified.
			type (string): The type of ID to retrieve. Or the default best one if not specified.
		RETURNS:
			The ID (string).
	'''
	def id(self, category = IdNone, type = IdNone):
		id = None
		try:
			if category is Stream.IdNone:
				id = self.mData['id'][Stream.IdCategoryGaia][Stream.IdTypeStream]
				if not id: id = self.mData['id'][Stream.IdCategoryOrion][Stream.IdTypeStream]
			else:
				value = self.mData['id'][category]
				if type is Stream.IdNone: id = self.idAny(value)
				else: id = value[type]
		except: pass
		return id

	'''
		FUNCTION:
			Sets a specific ID.
		PARAMETERS:
			category (string): The category of ID to set.
			type (string): The type of ID to set.
			value (string): The ID value.
	'''
	def idSet(self, category, type, value):
		self.mData['id'][category][type] = value

	'''
		FUNCTION:
			Checks wether the specified ID was set. Or the default best one if not specified.
		PARAMETERS:
			category (string): The category of ID to check.
			type (string): The type of ID to check.
		RETURNS:
			If the ID was set (boolean).
	'''
	def idHas(self, category = IdNone, type = IdNone):
		try:
			if type == Stream.IdNone:
				if self.mData['id'][Stream.IdCategoryGaia][Stream.IdTypeStream]: return True
				elif self.mData['id'][Stream.IdCategoryOrion][Stream.IdTypeStream]: return True
			else:
				value = self.mData['id'][category]
				if type is Stream.IdNone: value = self.idAny(value)
				else: value = value[type]
				return True if value else False
		except: pass
		return False

	'''
		FUNCTION:
			Determines the default ID type for IMDb/TMDb/TVDB/Trakt.
		PARAMETERS:
			type (string/None): The set type or None.
		RETURNS:
			The default ID type (string).
	'''
	def idDefault(self, type):
		if type is Stream.IdNone: type = Stream.IdDefaultMovie if self.metaMediaMovie() else Stream.IdDefaultShow
		return type

	'''
		FUNCTION:
			Retrieves the first ID that is not None from the dictionary.
		PARAMETERS:
			ids (string): The category of ID to check.
		RETURNS:
			If first valid ID (string).
	'''
	def idAny(self, ids):
		for id in ids.values():
			if not id is None: return id
		return None

	'''
		FUNCTION:
			Generate an unique ID from different parts/components.
		PARAMETERS:
			provider (string): The provider ID.
			orion (boolean): Wether or not the link comes from Orion.
			link (string): The source link. Only used if no other/ID/hash was provided.
			hash (string): The file hash.
			local (string): Some local ID used by the site/API.
			universal (string): Some universal ID, such as a UUID or GUID, typically used by usenet sites.
			collection (string): Collection ID, typically used by usenet sites.
			item (string): Some item value.
		RETURNS:
			The generated ID (string).
	'''
	@classmethod
	def idGenerate(self, provider = None, orion = None, link = None, hash = None, local = None, universal = None, collection = None, item = None):
		return self.__idGenerate(
			provider = provider,
			orion = orion,
			link = link,
			hash = hash,
			local = local,
			universal = universal,
			collection = collection,
			item = item,
		)

	# NB: If ever we add more attributes here, make sure to also update idGaiaItemGenerate().
	def _idGenerate(self, provider = None, orion = None, link = None, hash = None, local = None, universal = None, collection = None, item = None):
		return self.__idGenerate(
			provider = None if provider is False else provider if provider else self.providerId(),
			orion = None if orion is False else orion if orion else self.accessTypeOrion(),
			link = None if link is False else link if link else self.linkPrimary(),
			hash = None if hash is False else hash if hash else self.hash(),
			local = None if local is False else local if local else self.idProviderLocal(),
			universal = None if universal is False else universal if universal else self.idProviderUniversal(),
			collection = None if collection is False else collection if collection else self.idProviderCollection(),
			item = None if item is False else item if item else self.idProviderItem(),
		)

	@classmethod
	def __idGenerate(self, provider = None, orion = None, link = None, hash = None, local = None, universal = None, collection = None, item = None):
		parameters = locals()
		parts = []
		for type in Stream.IdOrder:
			if parameters[type]:
				if type == Stream.IdExtraLink:
					if not(hash or local or universal or collection or item):
						link = tools.Regex.remove(data = link, expression = '^((?:ht|f)tps?:\/\/)', all = True)
						try: parts.append(tools.Converter.unicode(link))
						except: pass
				else:
					try: parts.append(tools.Converter.unicode(parameters[type]))
					except: pass
		return tools.Identifier.generate(*parts)

	##############################################################################
	# ID GAIA
	##############################################################################

	'''
		FUNCTION:
			Retrieves the Gaia ID.
		PARAMETERS:
			type (string): The type of ID.
		RETURNS:
			The ID (string).
	'''
	def idGaia(self, type = IdTypeStream):
		if type == Stream.IdTypeItem: return self.idGaiaItem()
		else: return self.idGaiaStream()

	'''
		FUNCTION:
			Sets the Gaia ID.
		PARAMETERS:
			type (string): The type of ID.
		PARAMETERS:
			value (string): The ID.
	'''
	def idGaiaSet(self, value, type = IdTypeStream):
		if type == Stream.IdTypeItem: self.idGaiaItemSet(value = value)
		else: self.idGaiaStreamSet(value = value)

	'''
		FUNCTION:
			Checks wether the Gaia ID was set.
		PARAMETERS:
			type (string): The type of ID.
		RETURNS:
			If the ID was set (boolean).
	'''
	def idGaiaHas(self, type = IdTypeStream):
		if type == Stream.IdTypeItem: return self.idGaiaItemHas()
		else: return self.idGaiaStreamHas()

	'''
		FUNCTION:
			Generates and sets the Gaia ID.
		PARAMETERS:
			type (string): The type of ID. None, to generate both IDs.
		PARAMETERS:
			value (string): The ID.
	'''
	def idGaiaGenerate(self, type = None):
		id = None
		if type is None or type == Stream.IdTypeItem: id = self.idGaiaItemGenerate()
		if type is None or type == Stream.IdTypeStream: id = self.idGaiaStreamGenerate()
		return id

	##############################################################################
	# ID GAIA ITEM
	##############################################################################

	'''
		FUNCTION:
			Retrieves the Gaia item ID.
			The item ID is used to uniquely idetify a stream object in Gaia, even if it comes from another provider.
			The item ID contains no provider-specific and is only calculated from the hash or link.
			The item ID can therefore be used to pick a specific stream (during eg binge watching or history retrieval), irrespective of the provider it comes from.
		RETURNS:
			The ID (string).
	'''
	def idGaiaItem(self):
		return self.id(category = Stream.IdCategoryGaia, type = Stream.IdTypeItem)

	'''
		FUNCTION:
			Sets the Gaia item ID.
		PARAMETERS:
			value (string): The ID.
	'''
	def idGaiaItemSet(self, value):
		self.idSet(category = Stream.IdCategoryGaia, type = Stream.IdTypeItem, value = value)

	'''
		FUNCTION:
			Checks wether the Gaia item ID was set.
		RETURNS:
			If the ID was set (boolean).
	'''
	def idGaiaItemHas(self):
		return self.idHas(category = Stream.IdCategoryGaia, type = Stream.IdTypeItem)

	'''
		FUNCTION:
			Generates and sets the Gaia item ID.
		PARAMETERS:
			value (string): The ID.
	'''
	def idGaiaItemGenerate(self):
		value = self._idGenerate(provider = False, orion = False, link = None, hash = None, local = False, universal = False, collection = False, item = False)
		self.idGaiaItemSet(value = value)
		return value

	##############################################################################
	# ID GAIA STREAM
	##############################################################################

	'''
		FUNCTION:
			Retrieves the Gaia stream ID.
			The stream ID is used to uniquely idetify a stream object in Gaia amongst duplicates from other providers.
			The stream ID contains provider-specific data and is therefore different amongst providers, even if the hash or link is the same.
		RETURNS:
			The ID (string).
	'''
	def idGaiaStream(self):
		return self.id(category = Stream.IdCategoryGaia, type = Stream.IdTypeStream)

	'''
		FUNCTION:
			Sets the Gaia stream ID.
		PARAMETERS:
			value (string): The ID.
	'''
	def idGaiaStreamSet(self, value):
		self.idSet(category = Stream.IdCategoryGaia, type = Stream.IdTypeStream, value = value)

	'''
		FUNCTION:
			Checks wether the Gaia stream ID was set.
		RETURNS:
			If the ID was set (boolean).
	'''
	def idGaiaStreamHas(self):
		return self.idHas(category = Stream.IdCategoryGaia, type = Stream.IdTypeStream)

	'''
		FUNCTION:
			Generates and sets the Gaia stream ID.
		PARAMETERS:
			value (string): The ID.
	'''
	def idGaiaStreamGenerate(self):
		value = self._idGenerate()
		self.idGaiaStreamSet(value = value)
		return value

	##############################################################################
	# ID ORION
	##############################################################################

	'''
		FUNCTION:
			Retrieves the Orion ID.
		RETURNS:
			The ID (string).
	'''
	def idOrion(self):
		return self.idOrionStream()

	'''
		FUNCTION:
			Sets the Orion ID.
		PARAMETERS:
			value (string): The ID.
	'''
	def idOrionSet(self, value):
		self.idOrionStreamSet(value = value)

	'''
		FUNCTION:
			Checks wether the Orion ID was set.
		RETURNS:
			If the ID was set (boolean).
	'''
	def idOrionHas(self):
		return self.idOrionStreamHas()

	##############################################################################
	# ID ORION STREAM
	##############################################################################

	'''
		FUNCTION:
			Retrieves the Orion stream ID.
		RETURNS:
			The ID (string).
	'''
	def idOrionStream(self):
		return self.id(category = Stream.IdCategoryOrion, type = Stream.IdTypeStream)

	'''
		FUNCTION:
			Sets the Orion stream ID.
		PARAMETERS:
			value (string): The ID.
	'''
	def idOrionStreamSet(self, value):
		self.idSet(category = Stream.IdCategoryOrion, type = Stream.IdTypeStream, value = value)

	'''
		FUNCTION:
			Checks wether the Orion stream ID was set.
		RETURNS:
			If the ID was set (boolean).
	'''
	def idOrionStreamHas(self):
		return self.idHas(category = Stream.IdCategoryOrion, type = Stream.IdTypeStream)

	##############################################################################
	# ID ORION
	##############################################################################

	'''
		FUNCTION:
			Retrieves the Orion item ID (movie or episode).
		RETURNS:
			The ID (string).
	'''
	def idOrionItem(self):
		return self.idOrionMovie() if self.metaMediaMovie() else self.idOrionEpisode()

	'''
		FUNCTION:
			Sets the Orion item ID (movie or episode).
		PARAMETERS:
			value (string): The ID.
	'''
	def idOrionItemSet(self, value):
		if self.metaMediaMovie(): self.idOrionMovieSet(value = value)
		else: self.idOrionEpisodeSet(value = value)

	'''
		FUNCTION:
			Checks wether the Orion item ID (movie or episode) was set.
		RETURNS:
			If the ID was set (boolean).
	'''
	def idOrionItemHas(self):
		return self.idOrionMovieHas() if self.metaMediaMovie() else self.idOrionEpisodeHas()

	##############################################################################
	# ID ORION MOVIE
	##############################################################################

	'''
		FUNCTION:
			Retrieves the Orion movie ID.
		RETURNS:
			The ID (string).
	'''
	def idOrionMovie(self):
		return self.id(category = Stream.IdCategoryOrion, type = Stream.IdTypeMovie)

	'''
		FUNCTION:
			Sets the Orion movie ID.
		PARAMETERS:
			value (string): The ID.
	'''
	def idOrionMovieSet(self, value):
		self.idSet(category = Stream.IdCategoryOrion, type = Stream.IdTypeMovie, value = value)

	'''
		FUNCTION:
			Checks wether the Orion movie ID was set.
		RETURNS:
			If the ID was set (boolean).
	'''
	def idOrionMovieHas(self):
		return self.idHas(category = Stream.IdCategoryOrion, type = Stream.IdTypeMovie)

	##############################################################################
	# ID ORION COLLECTION
	##############################################################################

	'''
		FUNCTION:
			Retrieves the Orion collection ID.
		RETURNS:
			The ID (string).
	'''
	def idOrionCollection(self):
		return self.id(category = Stream.IdCategoryOrion, type = Stream.IdTypeCollection)

	'''
		FUNCTION:
			Sets the Orion collection ID.
		PARAMETERS:
			value (string): The ID.
	'''
	def idOrionCollectionSet(self, value):
		self.idSet(category = Stream.IdCategoryOrion, type = Stream.IdTypeCollection, value = value)

	'''
		FUNCTION:
			Checks wether the Orion collection ID was set.
		RETURNS:
			If the ID was set (boolean).
	'''
	def idOrionCollectionHas(self):
		return self.idHas(category = Stream.IdCategoryOrion, type = Stream.IdTypeCollection)

	##############################################################################
	# ID ORION SHOW
	##############################################################################

	'''
		FUNCTION:
			Retrieves the Orion show ID.
		RETURNS:
			The ID (string).
	'''
	def idOrionShow(self):
		return self.id(category = Stream.IdCategoryOrion, type = Stream.IdTypeShow)

	'''
		FUNCTION:
			Sets the Orion show ID.
		PARAMETERS:
			value (string): The ID.
	'''
	def idOrionShowSet(self, value):
		self.idSet(category = Stream.IdCategoryOrion, type = Stream.IdTypeShow, value = value)

	'''
		FUNCTION:
			Checks wether the Orion show ID was set.
		RETURNS:
			If the ID was set (boolean).
	'''
	def idOrionShowHas(self):
		return self.idHas(category = Stream.IdCategoryOrion, type = Stream.IdTypeShow)

	##############################################################################
	# ID ORION SEASON
	##############################################################################

	'''
		FUNCTION:
			Retrieves the Orion season ID.
		RETURNS:
			The ID (string).
	'''
	def idOrionSeason(self):
		return self.id(category = Stream.IdCategoryOrion, type = Stream.IdTypeSeason)

	'''
		FUNCTION:
			Sets the Orion season ID.
		PARAMETERS:
			value (string): The ID.
	'''
	def idOrionSeasonSet(self, value):
		self.idSet(category = Stream.IdCategoryOrion, type = Stream.IdTypeSeason, value = value)

	'''
		FUNCTION:
			Checks wether the Orion season ID was set.
		RETURNS:
			If the ID was set (boolean).
	'''
	def idOrionSeasonHas(self):
		return self.idHas(category = Stream.IdCategoryOrion, type = Stream.IdTypeSeason)

	##############################################################################
	# ID ORION EPISODE
	##############################################################################

	'''
		FUNCTION:
			Retrieves the Orion episode ID.
		RETURNS:
			The ID (string).
	'''
	def idOrionEpisode(self):
		return self.id(category = Stream.IdCategoryOrion, type = Stream.IdTypeEpisode)

	'''
		FUNCTION:
			Sets the Orion episode ID.
		PARAMETERS:
			value (string): The ID.
	'''
	def idOrionEpisodeSet(self, value):
		self.idSet(category = Stream.IdCategoryOrion, type = Stream.IdTypeEpisode, value = value)

	'''
		FUNCTION:
			Checks wether the Orion episode ID was set.
		RETURNS:
			If the ID was set (boolean).
	'''
	def idOrionEpisodeHas(self):
		return self.idHas(category = Stream.IdCategoryOrion, type = Stream.IdTypeEpisode)

	##############################################################################
	# ID ORION DATA
	##############################################################################

	'''
		FUNCTION:
			Retrieves the Orion data ID.
		RETURNS:
			The ID (string).
	'''
	def idOrionData(self):
		return self.id(category = Stream.IdCategoryOrion, type = Stream.IdTypeData)

	'''
		FUNCTION:
			Sets the Orion data ID.
		PARAMETERS:
			value (string): The ID.
	'''
	def idOrionDataSet(self, value):
		self.idSet(category = Stream.IdCategoryOrion, type = Stream.IdTypeData, value = value)

	'''
		FUNCTION:
			Checks wether the Orion data ID was set.
		RETURNS:
			If the ID was set (boolean).
	'''
	def idOrionDataHas(self):
		return self.idHas(category = Stream.IdCategoryOrion, type = Stream.IdTypeData)

	'''
		FUNCTION:
			Generates an ID with the given attributes.
		RETURNS:
			The ID (string).
	'''
	@classmethod
	def idOrionDataGenerate(self,
		link				= None,
		hash				= None,

		videoQuality		= None,
		videoCodec			= None,
		video3d				= None,

		audioType			= None,
		audioSystem			= None,
		audioCodec			= None,
		audioChannels		= None,
		audioLanguage		= None,

		subtitleType		= None,
		subtitleLanguage	= None,

		fileName			= None,
		fileSize			= None,
		filePack			= None,

		releaseType			= None,
		releaseFormat		= None,
		releaseEdition		= None,
		releaseGroup		= None,

		sourceType			= None,
		sourceTime			= None,
		sourceSeeds			= None,

		sourceOrigin		= None,
		sourceProvider		= None,
		sourceHoster		= None,
	):
		parameters = locals()

		# gaiaremove - should be changed if Orion updates their DB in the future.
		parameters['filePack'] = bool(parameters['filePack'])

		# gaiaremove - pack sizes are esitmated. Exclude for now.
		# Update: we now use the size, since we want to update the incorrectly estimated file size from Orion.
		#parameters['fileSize'] = None

		# The trackers/ports can differ in magnet links. Eg: TorrentApi mostly returns different tracker ports on each request.
		if parameters['hash']: parameters['link'] = None

		keys = sorted(parameters.keys())
		data = []

		for key in keys:
			if not key == 'self':
				value = parameters[key]
				if value is None: value = ''
				elif tools.Tools.isArray(value): value = '-'.join(value)
				elif not tools.Tools.isString(value): value = str(value)
				data.append(value)
		return tools.Hash.sha256('_'.join(data).lower())

	##############################################################################
	# ID PROVIDER LOCAL
	##############################################################################

	'''
		FUNCTION:
			Retrieves the provider local ID.
		RETURNS:
			The ID (string).
	'''
	def idProviderLocal(self):
		return self.id(category = Stream.IdCategoryProvider, type = Stream.IdTypeLocal)

	'''
		FUNCTION:
			Sets the provider local ID.
		PARAMETERS:
			value (string): The ID.
	'''
	def idProviderLocalSet(self, value):
		self.idSet(category = Stream.IdCategoryProvider, type = Stream.IdTypeLocal, value = value)

	'''
		FUNCTION:
			Checks wether the provider local ID was set.
		RETURNS:
			If the ID was set (boolean).
	'''
	def idProviderLocalHas(self):
		return self.idHas(category = Stream.IdCategoryProvider, type = Stream.IdTypeLocal)

	##############################################################################
	# ID PROVIDER UNIVERSAL
	##############################################################################

	'''
		FUNCTION:
			Retrieves the provider universal ID.
		RETURNS:
			The ID (string).
	'''
	def idProviderUniversal(self):
		return self.id(category = Stream.IdCategoryProvider, type = Stream.IdTypeUniversal)

	'''
		FUNCTION:
			Sets the provider universal ID.
		PARAMETERS:
			value (string): The ID.
	'''
	def idProviderUniversalSet(self, value):
		self.idSet(category = Stream.IdCategoryProvider, type = Stream.IdTypeUniversal, value = value)

	'''
		FUNCTION:
			Checks wether the provider universal ID was set.
		RETURNS:
			If the ID was set (boolean).
	'''
	def idProviderUniversalHas(self):
		return self.idHas(category = Stream.IdCategoryProvider, type = Stream.IdTypeUniversal)

	##############################################################################
	# ID PROVIDER COLLECTION
	##############################################################################

	'''
		FUNCTION:
			Retrieves the provider collection ID.
		RETURNS:
			The ID (string).
	'''
	def idProviderCollection(self):
		return self.id(category = Stream.IdCategoryProvider, type = Stream.IdTypeCollection)

	'''
		FUNCTION:
			Sets the provider collection ID.
		PARAMETERS:
			value (string): The ID.
	'''
	def idProviderCollectionSet(self, value):
		self.idSet(category = Stream.IdCategoryProvider, type = Stream.IdTypeCollection, value = value)

	'''
		FUNCTION:
			Checks wether the provider collection ID was set.
		RETURNS:
			If the ID was set (boolean).
	'''
	def idProviderCollectionHas(self):
		return self.idHas(category = Stream.IdCategoryProvider, type = Stream.IdTypeCollection)

	##############################################################################
	# ID PROVIDER ITEM
	##############################################################################

	'''
		FUNCTION:
			Retrieves the provider item ID.
		RETURNS:
			The ID (string).
	'''
	def idProviderItem(self):
		return self.id(category = Stream.IdCategoryProvider, type = Stream.IdTypeItem)

	'''
		FUNCTION:
			Sets the provider item ID.
		PARAMETERS:
			value (string): The ID.
	'''
	def idProviderItemSet(self, value):
		self.idSet(category = Stream.IdCategoryProvider, type = Stream.IdTypeItem, value = value)

	'''
		FUNCTION:
			Checks wether the provider item ID was set.
		RETURNS:
			If the ID was set (boolean).
	'''
	def idProviderItemHas(self):
		return self.idHas(category = Stream.IdCategoryProvider, type = Stream.IdTypeItem)

	##############################################################################
	# ID IMDB
	##############################################################################

	'''
		FUNCTION:
			Retrieves the IMDb ID.
		PARAMETERS:
			type (string): The ID type.
		RETURNS:
			The ID (string).
	'''
	def idImdb(self, type = IdNone):
		return self.id(category = Stream.IdCategoryImdb, type = type)

	'''
		FUNCTION:
			Sets the IMDb ID.
		PARAMETERS:
			value (string): The ID.
			type (string): The ID type.
	'''
	def idImdbSet(self, value, type = IdNone):
		self.idSet(category = Stream.IdCategoryImdb, type = self.idDefault(type), value = value)

	'''
		FUNCTION:
			Checks wether the IMDb ID was set.
		PARAMETERS:
			type (string): The ID type.
		RETURNS:
			If the ID was set (boolean).
	'''
	def idImdbHas(self, type = IdNone):
		return self.idHas(category = Stream.IdCategoryImdb, type = type)

	##############################################################################
	# ID TMDB
	##############################################################################

	'''
		FUNCTION:
			Retrieves the TMDb ID.
		PARAMETERS:
			type (string): The ID type.
		RETURNS:
			The ID (string).
	'''
	def idTmdb(self, type = IdNone):
		return self.id(category = Stream.IdCategoryTmdb, type = type)

	'''
		FUNCTION:
			Sets the TMDb ID.
		PARAMETERS:
			value (string): The ID.
			type (string): The ID type.
	'''
	def idTmdbSet(self, value, type = IdNone):
		self.idSet(category = Stream.IdCategoryTmdb, type = type, value = value)

	'''
		FUNCTION:
			Checks wether the TMDb ID was set.
		PARAMETERS:
			type (string): The ID type.
		RETURNS:
			If the ID was set (boolean).
	'''
	def idTmdbHas(self, type = IdNone):
		return self.idHas(category = Stream.IdCategoryTmdb, type = type)

	##############################################################################
	# ID TVDB
	##############################################################################

	'''
		FUNCTION:
			Retrieves the TVDb ID.
		PARAMETERS:
			type (string): The ID type.
		RETURNS:
			The ID (string).
	'''
	def idTvdb(self, type = IdNone):
		return self.id(category = Stream.IdCategoryTvdb, type = type)

	'''
		FUNCTION:
			Sets the TVDb ID.
		PARAMETERS:
			value (string): The ID.
			type (string): The ID type.
	'''
	def idTvdbSet(self, value, type = IdNone):
		self.idSet(category = Stream.IdCategoryTvdb, type = type, value = value)

	'''
		FUNCTION:
			Checks wether the TVDb ID was set.
		PARAMETERS:
			type (string): The ID type.
		RETURNS:
			If the ID was set (boolean).
	'''
	def idTvdbHas(self, type = IdNone):
		return self.idHas(category = Stream.IdCategoryTvdb, type = type)

	##############################################################################
	# ID TRAKT
	##############################################################################

	'''
		FUNCTION:
			Retrieves the Trakt ID.
		PARAMETERS:
			type (string): The ID type.
		RETURNS:
			The ID (string).
	'''
	def idTrakt(self, type = IdNone):
		return self.id(category = Stream.IdCategoryTrakt, type = type)

	'''
		FUNCTION:
			Sets the Trakt ID.
		PARAMETERS:
			value (string): The ID.
			type (string): The ID type.
	'''
	def idTraktSet(self, value, type = IdNone):
		self.idSet(category = Stream.IdCategoryTrakt, type = type, value = value)

	'''
		FUNCTION:
			Checks wether the Trakt ID was set.
		PARAMETERS:
			type (string): The ID type.
		RETURNS:
			If the ID was set (boolean).
	'''
	def idTraktHas(self, type = IdNone):
		return self.idHas(category = Stream.IdCategoryTrakt, type = type)

	##############################################################################
	# ID SLUG
	##############################################################################

	'''
		FUNCTION:
			Retrieves the slug ID (as found on Trakt).
		PARAMETERS:
			type (string): The ID type.
		RETURNS:
			The ID (string).
	'''
	def idSlug(self, type = IdNone):
		return self.id(category = Stream.IdCategorySlug, type = type)

	'''
		FUNCTION:
			Sets the slug ID.
		PARAMETERS:
			value (string): The ID.
			type (string): The ID type.
	'''
	def idSlugSet(self, value, type = IdNone):
		self.idSet(category = Stream.IdCategorySlug, type = type, value = value)

	'''
		FUNCTION:
			Checks wether the slug ID was set.
		PARAMETERS:
			type (string): The ID type.
		RETURNS:
			If the ID was set (boolean).
	'''
	def idSlugHas(self, type = IdNone):
		return self.idHas(category = Stream.IdCategorySlug, type = type)

	##############################################################################
	# META MEDIA
	##############################################################################

	'''
		FUNCTION:
			Retrieves the target media type.
		RETURNS:
			The media type (string).
	'''
	def metaMedia(self):
		return self.mData['meta']['media']

	'''
		FUNCTION:
			Sets the target media type.
		PARAMETERS:
			value (string): The media type.
	'''
	def metaMediaSet(self, value):
		self.mData['meta']['media'] = value

	'''
		FUNCTION:
			Checks if the media type is a movie.
		RETURNS:
			If the media type is a movie. (boolean).
	'''
	def metaMediaMovie(self):
		return tools.Media.isFilm(self.mData['meta']['media'])

	'''
		FUNCTION:
			Checks if the media type is a show.
		RETURNS:
			If the media type is a show. (boolean).
	'''
	def metaMediaShow(self):
		return tools.Media.isSerie(self.mData['meta']['media'])

	##############################################################################
	# META NICHE
	##############################################################################

	'''
		FUNCTION:
			Retrieves the media niche type.
		RETURNS:
			The media niche type (list).
	'''
	def metaNiche(self):
		return self.mData['meta']['niche']

	'''
		FUNCTION:
			Sets the target media niche type.
		PARAMETERS:
			value (string): The media niche type.
	'''
	def metaNicheSet(self, value):
		self.mData['meta']['niche'] = tools.Media.stringFrom(value) if value else None

	'''
		FUNCTION:
			Checks if the media niche type is Anime.
		RETURNS:
			If the media niche type is Anime. (boolean).
	'''
	def metaNicheAnime(self):
		return tools.Media.isAnime(self.mData['meta']['niche'])

	'''
		FUNCTION:
			Checks if the media niche type is Donghua.
		RETURNS:
			If the media niche type is Donghua. (boolean).
	'''
	def metaNicheDonghua(self):
		return tools.Media.isDonghua(self.mData['meta']['niche'])

	@classmethod
	def metaNicheIs(self, niche):
		if niche: return tools.Media.isAnime(niche) or tools.Media.isDonghua(niche)
		return False

	##############################################################################
	# META TITLE
	##############################################################################

	'''
		FUNCTION:
			Retrieves the target title.
		PARAMETERS:
			title (string/list): The type of title.
		RETURNS:
			The title (list).
	'''
	def metaTitle(self, title = TitleDefault):
		try:
			if title == Stream.TitleNone: return self.mData['meta']['title']
			else: return self.mData['meta']['title'][title]
		except: return None

	'''
		FUNCTION:
			Sets the target title.
		PARAMETERS:
			value (string/list): The title.
	'''
	def metaTitleSet(self, value):
		try: value = value['processed']
		except: pass
		if not tools.Tools.isDictionary(value):
			if not tools.Tools.isArray(value): value = [value]
			value = {Stream.TitleAll : value}
		self.mData['meta']['title'] = value

	'''
		FUNCTION:
			Check if a specific title exists.
		PARAMETERS:
			title (string/list): The type of title.
		RETURNS:
			If the title exists (boolean).
	'''
	def metaTitleHas(self, title = TitleDefault):
		return bool(self.metaTitle(title = title))

	##############################################################################
	# META YEAR
	##############################################################################

	'''
		FUNCTION:
			Retrieves the target year.
		RETURNS:
			The year (string).
	'''
	def metaYear(self):
		return self.mData['meta']['year']

	'''
		FUNCTION:
			Sets the target year.
		PARAMETERS:
			value (string): The year.
	'''
	def metaYearSet(self, value):
		self.mData['meta']['year'] = value

	##############################################################################
	# META TIME
	##############################################################################

	'''
		FUNCTION:
			Retrieves the target release time.
		RETURNS:
			The release time (integer).
	'''
	def metaTime(self):
		return self.mData['meta']['time']

	'''
		FUNCTION:
			Sets the target release time.
		PARAMETERS:
			value (integer): The release time.
	'''
	def metaTimeSet(self, value):
		self.mData['meta']['time'] = value

	##############################################################################
	# META SEASON
	##############################################################################

	'''
		FUNCTION:
			Retrieves the target season number.
			This is the target number, the extracted number should be retrieved with numberSeason() instead.
		RETURNS:
			The season number (None/integer).
	'''
	def metaSeason(self):
		return self.mData['meta']['season']

	'''
		FUNCTION:
			Sets the target season number.
			This is the target number, the extracted number should be set with numberSeasonSet() instead.
		PARAMETERS:
			value (integer): The season number.
	'''
	def metaSeasonSet(self, value):
		self.mData['meta']['season'] = value

	##############################################################################
	# META EPISODE
	##############################################################################

	'''
		FUNCTION:
			Retrieves the target episode number.
			This is the target number, the extracted number should be retrieved with numberEpisode() instead.
		RETURNS:
			The episode number (None/integer).
	'''
	def metaEpisode(self):
		return self.mData['meta']['episode']

	'''
		FUNCTION:
			Sets the target episode number.
			This is the target number, the extracted number should be set with numberEpisodeSet() instead.
		PARAMETERS:
			value (integer): The episode number.
	'''
	def metaEpisodeSet(self, value):
		self.mData['meta']['episode'] = value

	##############################################################################
	# META SPECIAL
	##############################################################################

	'''
		FUNCTION:
			Wether or not this is a special episode.
		RETURNS:
			If the episode is special (boolean).
	'''
	@classmethod
	def metaSpecial(self, season = None, episode = None):
		return self.__metaSpecial(season = season, episode = episode)

	def _metaSpecial(self, none = True, quick = True, adjust = None):
		return self.__metaSpecial(season = self.metaSeason(), episode = self.metaEpisode())

	@classmethod
	def __metaSpecial(self, season, episode):
		return season == 0 or episode == 0

	##############################################################################
	# META NUMBER
	##############################################################################

	'''
		FUNCTION:
			Retrieves the target alternative/pack season and episode numbers.
		RETURNS:
			The numbers (None/dictionary).
	'''
	def metaNumber(self):
		return self.mData['meta']['number']

	'''
		FUNCTION:
			Sets the target alternative/pack season and episode numbers.
		PARAMETERS:
			value (dictionary): The numbers.
	'''
	def metaNumberSet(self, value):
		self.mData['meta']['number'] = value

	##############################################################################
	# META LANGUAGE
	##############################################################################

	'''
		FUNCTION:
			Retrieves the original language of the title.
		PARAMETERS:
			audioType (None/True/string): The audio type. For dubbed audio None is returned.
			single (None/True/False): Return a single language or all available languages.
		RETURNS:
			The original language.
	'''
	def metaLanguage(self, audioType = None, single = False):
		if audioType:
			if audioType is True: audioType = self.audioType()
			if audioType in Stream.AudioTypeDubbeds: return None
		language = self.mData['meta']['language']
		if language: return language[0] if single else language
		else: return None

	'''
		FUNCTION:
			Sets the original language of the title.
		PARAMETERS:
			value (string/list): The original language code.
	'''
	def metaLanguageSet(self, value):
		if value and not tools.Tools.isArray(value): value = [value]
		self.mData['meta']['language'] = value

	##############################################################################
	# META COUNTRY
	##############################################################################

	'''
		FUNCTION:
			Retrieves the original country of the title.
		PARAMETERS:
			single (None/True/False): Return a single country or all available countries.
		RETURNS:
			The original country.
	'''
	def metaCountry(self, single = False):
		country = self.mData['meta']['country']
		if country: return country[0] if single else country
		else: return None

	'''
		FUNCTION:
			Sets the original country of the title.
		PARAMETERS:
			value (string/list): The original country code.
	'''
	def metaCountrySet(self, value):
		if value and not tools.Tools.isArray(value): value = [value]
		self.mData['meta']['country'] = value

	##############################################################################
	# META NETWORK
	##############################################################################

	'''
		FUNCTION:
			Retrieves the network of the title.
		PARAMETERS:
			single (None/True/False): Return a single network or all available networks.
		RETURNS:
			The network.
	'''
	def metaNetwork(self, single = False):
		network = self.mData['meta']['network']
		if network: return network[0] if single else network
		else: return None

	'''
		FUNCTION:
			Sets the network of the title.
		PARAMETERS:
			value (string/list): The network.
	'''
	def metaNetworkSet(self, value):
		if value and not tools.Tools.isArray(value): value = [value]
		self.mData['meta']['network'] = value

	##############################################################################
	# META STUDIO
	##############################################################################

	'''
		FUNCTION:
			Retrieves the studio of the title.
		PARAMETERS:
			single (None/True/False): Return a single studio or all available studios.
		RETURNS:
			The studio.
	'''
	def metaStudio(self, single = False):
		studio = self.mData['meta']['studio']
		if studio: return studio[0] if single else studio
		else: return None

	'''
		FUNCTION:
			Sets the studio of the title.
		PARAMETERS:
			value (string/list): The studio.
	'''
	def metaStudioSet(self, value):
		if value and not tools.Tools.isArray(value): value = [value]
		self.mData['meta']['studio'] = value

	##############################################################################
	# META DURATION
	##############################################################################

	'''
		FUNCTION:
			Retrieves the target video duration in seconds.
		PARAMETERS:
			default (boolean): Wether or not to return the default/estimated duration if the exact duration is not known.
		RETURNS:
			Video duration (integer).
	'''
	def metaDuration(self, default = False):
		result = self.mData['meta']['duration']
		if not result and default: result = self.metaDurationDefault(media = self.metaMedia())
		return result

	'''
		FUNCTION:
			Sets the target video duration in seconds.
		PARAMETERS:
			value (integer): The video duration in seconds.
	'''
	def metaDurationSet(self, value):
		self.mData['meta']['duration'] = value

	'''
		FUNCTION:
			Estimate the video duration if the exact duration is not known.
		PARAMETERS:
			media (dictionary): The media type.
		PARAMETERS:
			value (integer): The video duration in seconds.
	'''
	@classmethod
	def metaDurationDefault(self, media):
		if tools.Media.isFilm(media): return Stream.DurationMovie
		elif tools.Media.isSerie(media): return Stream.DurationShow
		return Stream.DurationUnknown

	##############################################################################
	# META PACK
	##############################################################################

	'''
		FUNCTION:
			Retrieves the target movie collection or show pack details.
		RETURNS:
			Pack data (dictionary).
	'''
	def metaPack(self, *keys):
		return self.mData['meta']['pack']

	'''
		FUNCTION:
			Sets the target movie collection or show pack details.
		PARAMETERS:
			value (dictionary): The details.
	'''
	def metaPackSet(self, value):
		self.mData['meta']['pack'] = value

	'''
		FUNCTION:
			Helper function to extract values from a reduced pack dictionary.
	'''
	@classmethod
	def _metaPack(self, pack, *keys):
		return self._metaPackExtract(pack, None, *keys)

	'''
		FUNCTION:
			Helper function to extract values from a reduced pack dictionary.
	'''
	@classmethod
	def _metaPackList(self, pack, *keys):
		return self._metaPackExtract(pack, [], *keys)

	'''
		FUNCTION:
			Helper function to extract values from a reduced pack dictionary.
	'''
	@classmethod
	def _metaPackNumber(self, pack, *keys):
		return self._metaPackExtract(pack, 0, *keys)

	'''
		FUNCTION:
			Helper function to extract values from a reduced pack dictionary.
	'''
	@classmethod
	def _metaPackExtract(self, pack, default, *keys):
		if keys and pack:
			for i in keys:
				if tools.Tools.isArray(i):
					temp = []
					for j in i:
						try: temp.append(pack[j])
						except: pass
					pack = temp
				else:
					try: pack = pack[i]
					except: return default
		return pack

	##############################################################################
	# TITLE
	##############################################################################

	'''
		FUNCTION:
			Checks wether the file name matches one of the titles.
			Can be called on an instance (without the data parameter), or on the class (with the data parameter).
		PARAMETERS:
			data (string): The file name.
			title (string/list): The title.
			titleCollection (string): The collection title.
			year (None/integer): The year is availble (for stripping purposes).
			none (boolean): If True, file names that are unknown (None) are accepted as valid.
			quick (boolean): If True, do a quick basic check to remove clearly incorrect file names, before doing a more extensive validation.
			guidance (None/dictionary): If previously extracted data structure.
			native (None/list): The languages of the provider or source used to detect additional language name translations.
			adjust (None/float): An additional adjustmment multiplier to multiply the destination ratio limits with.
			result (None/dictionary): If a dictionary is passed in, it will contain the index and name of the matched title.
		RETURNS:
			Wether the file name is valid (boolean).
	'''
	@classmethod
	def titleValid(self, data, media, title, titleCollection = None, year = None, language = None, country = None, network = None, studio = None, none = True, quick = True, guidance = None, native = None, adjust = None, result = None):
		data = self.cleanBasic(data)
		title = self.cleanEncode(title)
		return self.__titleValid(data = data, media = media, title = title, titleCollection = titleCollection, year = year, none = none, quick = quick, guidance = guidance, native = native, adjust = adjust, result = result)

	def _titleValid(self, none = True, quick = True, adjust = None, result = None):
		return self.__titleValid(data = self.fileName(), media = self.metaMedia(), title = self.metaTitle(title = Stream.TitleAll), titleCollection = self.metaTitle(title = Stream.TitleCollection), year = self.metaYear(), language = self.metaLanguage(), country = self.metaCountry(), network = self.metaNetwork(), studio = self.metaStudio(), none = none, quick = quick, guidance = self.data(), native = self.infoLanguage(), adjust = adjust, result = result)

	@classmethod
	def __titleValid(self, data, media, title, titleCollection = None, year = None, language = None, country = None, network = None, studio = None, none = True, quick = True, guidance = None, native = None, adjust = None, pack = None, reevaluate = True, result = None):
		def __titleConcatenate(title1, title2, suffix = False):
			# If titles are very similar, remove them from each other, otherwise they will match too easily with levenshtein.
			# Eg: "star wars the last jedi" and "star wars the last jedi 3d"
			title1Trimmed = title1.replace(title2, '').strip()
			title2Trimmed = title2.replace(title1, '').strip()

			concatenated = title1Trimmed + ' ' + title2Trimmed
			if concatenated == title1 or concatenated == title2: concatenated = None

			# Do not use the country code as a concatenated title, since it is too short and creates too many false positives.
			# Eg: "The Great (US)" -> "US"
			if suffix and concatenated:
				titleAdjusted = concatenated.replace(title1, '').strip()
				if len(titleAdjusted) <= 2: concatenated = None
				else:
					titleAdjusted = concatenated.replace(title2, '').strip()
					if len(titleAdjusted) <= 2: concatenated = None

			return concatenated

		def __titleMatch(threshold, titles, name, number, strict = False, adjust = 1, obfuscated = False, result = None):
			# Speed up scraping by not redoing the matching already done previously.
			# More info under self._titleMatch().
			id = 'generic_' + str(len(titles)) + '_'
			if tools.Tools.isArray(titles): id += str(titles[:3]) + '_' + str(titles[-1])
			else: id += str(titles)
			id += '_' + str(name) + '_' + str(threshold) + '_' + str(number) + '_' + str(strict) + '_' + str(adjust) + '_' + str(obfuscated)
			try:
				match = Stream.TitleMatches[id]
				result.update(match['result'])
				return match['match']
			except:
				match = __titleMatchExecute(threshold = threshold, titles = titles, name = name, number = number, strict = strict, adjust = adjust, obfuscated = obfuscated, result = result)
				Stream.TitleMatches[id] = {'match' : match, 'result' : result}
				return match

		def __titleMatchExecute(threshold, titles, name, number, strict = False, adjust = 1, obfuscated = False, result = None):
			try:
				if not tools.Tools.isArray(titles): titles = [titles]

				thresholdBase = min(1, threshold['base'] * adjust)
				thresholdMaximum = threshold['maximum']
				thresholdShortLength = threshold['short']['length']

				# For titles without spaces and abbreviations.
				if strict:
					# Do not use vector similarity here, since it requires words/spaces.
					thresholdStrict = min(1, Stream.Threshold['title']['strict'] * adjust)
					thresholdShortLength2 = threshold['short']['length2']

					for i in range(len(titles)):
						title = titles[i]
						thresholdNew = thresholdStrict
						if strict == 1 and len(title) <= thresholdShortLength and len(name) < thresholdShortLength2: thresholdNew = thresholdBase

						ratio = self._titleMatchJaro(title, name)
						if ratio >= thresholdNew:
							if not result is None: result.update({'index' : i, 'title' : title})
							return True
				else:
					thresholdShortMultiplier = threshold['short']['multiplier']
					thresholdShortDouble = min(1, threshold['short']['double'] * adjust)
					thresholdShortLetter = threshold['short']['letter']

					thresholdLongLength = threshold['long']['length']
					thresholdLongSingle = min(1, threshold['long']['single'] * adjust)
					thresholdLongDouble = min(1, threshold['long']['double'] * adjust)
					thresholdLongConcatenated = min(1, threshold['long']['concatenated'] * adjust)

					title = None
					aliased = False
					for i in range(len(titles)):
						alias = i

						# Do not treat later titles as aliases if they are just a variation from the original title that contains a unicode character.
						# Eg: with titles ['Shōgun', 'Shogun', ...] the 2nd title should not be treated as an alias.
						if alias and not aliased and not tools.Tools.stringAscii(title): # Title from previous iteration.
							aliased = True
							alias = False

						title = titles[i]
						length = len(title)

						# English alias titles with a single word can lead to incorrect titles being detected.
						# Eg: "Hijack" 2023 (has a GB alias "Kingdom").
						# Eg (invalid): The Kingdom S01E03 1080p HEVC x265-MeGusta[eztv re]
						# Eg (invalid): Kingdom.2019.S01.1080p.NF.WEBRip.DD5.1.x264-MZABI
						exception = bool(alias and tools.Tools.stringAscii(title) and title.count(' ') == 0)

						# Still allow similar aliases.
						if exception:
							# Eg: "Terminator" vs "The Terminator" vs "Terminator 1"
							if title in titles[0]: exception = False

							# Eg: "The Man with the Iron Heart 2017" vs "HHhH 2017" vs "HHhH: The Man with the Iron Heart"
							if exception and media == tools.Media.Movie:
								counter = 0
								for j in titles:
									if title in j:
										counter += 1
										if counter >= 2:
											exception = False
											break

						# Very short titles (eg: "9 (2009)")
						if length <= thresholdShortLength:
							ratio = self._titleMatchLevenshtein(title, name)
							if ratio >= min(thresholdMaximum, thresholdBase * (thresholdShortMultiplier + (length * thresholdShortLetter))):
								if not result is None: result.update({'index' : i, 'title' : title})
								return True

						# Very long titles (eg: Il cacciatore e la regina di ghiaccio).
						elif length >= thresholdLongLength and length >= thresholdLongLength:
							ratio = self._titleMatchLevenshtein(title, name)
							if ratio >= thresholdLongSingle:
								# We could increase the global thresholdLongSingle threshold (eg: 1.05 - 1.1), but this affects other titles as well. Eg: "mkvCinemas live - Hotel Transylvania 3 Summer Vacation 2018"
								if ratio >= (thresholdLongSingle * 1.1):
									if not result is None: result.update({'index' : i, 'title' : title})
									return True

							# Combine the original title with a foreign title (eg: Il cacciatore e la regina di ghiaccio - The Huntsman Winter's War).
							# Important to "titles[0].startswith(title)" instead of "titles[0] == title".
							# This ensures that collection titles are not used, eg: do not concatenate "The Lord of the Rings" and "The Lord of the Rings: The Two Towers".
							elif not titles[0].startswith(title) and not titles[0].endswith(title) and ratio >= thresholdLongDouble:
								titleConcatenated = __titleConcatenate(titles[0], title)
								if titleConcatenated:
									ratio = self._titleMatchLevenshtein(titleConcatenated, name)
									if ratio >= thresholdLongConcatenated:
										if not result is None: result.update({'index' : i, 'title' : title})
										return True

								titleConcatenated = __titleConcatenate(title, titles[0])
								if titleConcatenated:
									ratio = self._titleMatchLevenshtein(titleConcatenated, name)
									if ratio >= thresholdLongConcatenated:
										if not result is None: result.update({'index' : i, 'title' : title})
										return True

						# Medium length titles.
						else:
							if exception:
								ratio = 0
							elif obfuscated:
								ratio = self._titleMatchLevenshtein(title, name)
								if length < 5: ratio *= 1.1 # Short titles, eg: "Dune" vs "Du00ne".
							else:
								ratio = self._titleMatchJaccard(title, name)

							if ratio >= thresholdBase:
								allow = obfuscated or ratio >= (thresholdBase * 1.3)
								if not allow:
									if length < 20:
										# For titles that are very similar, but the words are in a differrent order.
										# Eg [valid]: "george orwell 1984" vs "1984 george orwell"
										# Do not make too lenient, for close matches.
										# Eg [invalid]: "love and death" vs "love death and robots"
										titleSorted = sorted(title.split(' '))
										nameSorted = sorted(name.split(' '))
										common = set(titleSorted) & set(nameSorted)
										titleBasic = ' '.join(list(common) + list(set(titleSorted) - set(common)))
										nameBasic = ' '.join(list(common) + list(set(nameSorted) - set(common)))
										allow = self._titleMatchLevenshtein(titleBasic, nameBasic) > (thresholdBase * 1.1)
									else:
										# Long titles.
										# Eg: "xma xtreme martial arts" vs "xma xtreme martial arts docdvdrip"
										allow = True

								if allow:
									if not result is None: result.update({'index' : i, 'title' : title})
									return True

							# Combine the original title with a foreign title (eg: Il cacciatore e la regina di ghiaccio - The Huntsman Winter's War).
							# Important to "titles[0].startswith(title)" instead of "titles[0] == title".
							# This ensures that collection titles are not used, eg: do not concatenate "The Lord of the Rings" and "The Lord of the Rings: The Two Towers".
							# Also check the Levenshtein distance for unicode titles.
							# Eg (Łowca i Królowa Lodu): owca-i-krolowa-lodu-the-huntsman-winter039s-war-2016-extended-pldub-720p-bluray-x264-dts-kit-mkv-mp4
							elif not titles[0].startswith(title) and not titles[0].endswith(title):
								allow = ratio >= thresholdShortDouble

								# Eg: owca-i-krolowa-lodu-the-huntsman-winter039s-war-2016-extended-pldub-720p-bluray-x264-dts-kit-mkv-mp4
								# Eg: lowca-i-krolowa-lodu-lektor-pl-hd-the-huntsman-winter039s-war-2016
								if not allow:
									nameStripped = nameOriginal = name.replace(' ', '')
									try: nameStripped = nameStripped.replace(titles[0].replace(' ', ''), '')
									except: pass
									try: nameStripped = nameStripped.replace(titles[1].replace(' ', ''), '')
									except: pass
									if nameStripped and not nameStripped == nameOriginal:
										thresholdConcatenated = thresholdShortDouble
										if len(nameStripped) < 300: thresholdConcatenated *= 1.3
										allow = self._titleMatchLevenshtein(title, nameStripped) >= thresholdConcatenated

								# Do not concatenated very similar titles, as it might lead to too many false positives with Levenshtein.
								# Eg: "star wars the last jedi" + "star wars 8 the last jedi"
								# Eg: Film Theory: How Star Wars Theories KILLED Star Wars: The Last Jedi!
								if allow and self._titleMatchLevenshtein(titles[0], title) < 0.8:
									titleConcatenated = __titleConcatenate(titles[0], title, suffix = True)

									if titleConcatenated:
										thresholdExtra = 1.0

										# Eg: Hijack 2023.
										# Eg: Concatenated title: "hijack kingdom" - file name: "last kingdom"
										# Eg: "star trek the original series" vs "star trek the animated series" vs "star trek la serie original"
										# Eg: star-trek-the-animated-series-s01e01-pl-720p-mp4
										if titleConcatenated.count(' ') <= 1 or (titles[0].count(' ') <= 1 and title.count(' ') <= 1): thresholdExtra = 1.3
										elif 'serie' in title: thresholdExtra = 1.3

										# Eg (Love & Death): Love.Death.and.Robots.S01.1080p.WEBRip.x265-RARBM
										ratio = self._titleMatchLevenshtein(titleConcatenated, name)
										if ratio >= thresholdLongConcatenated * thresholdExtra:
											if not result is None: result.update({'index' : i, 'title' : title})
											return True

									titleConcatenated = __titleConcatenate(title, titles[0], suffix = True)
									if titleConcatenated:
										ratio = self._titleMatchLevenshtein(titleConcatenated, name)
										if ratio >= thresholdLongConcatenated:
											if not result is None: result.update({'index' : i, 'title' : title})
											return True
			except:
				tools.Logger.error()
			return False

		try:
			if adjust is None: adjust = 1
			if pack is None: pack = bool(adjust)

			threshold = self.threshold('title')
			if threshold['base'] == 0: return True

			if none and (not data or not title): return True
			if quick and not self.__titleValidQuick(data = data, title = title, none = none): return False

			isMovie = tools.Media.isFilm(media)
			isShow = tools.Media.isSerie(media)

			expressionSpaces = self._cacheId('_titleValid_spaces', re.compile, '\s+', flags = Stream.ExpressionFlags)
			titles = self._titleProcessTitle(title, language = language, country = country, network = network, studio = studio)
			titlesCollection = self._titleProcessTitle(titleCollection)
			titlesCleaned = titles['cleaned']

			nameYear = None
			nameCleaned = nameOriginal = self.cleanOther(data, titles = titlesCleaned)

			length = len(titlesCleaned[0])
			index = indexYear = self.yearIndex(nameCleaned, year = year, offset = length) # Try predefined year, important for titles that are only years (eg: "1917" or "1984").
			if index is None: index = indexYear = self.yearIndex(nameCleaned, offset = length) # Try if the year is incorrect eg: (2019 instead of 2020).
			if isShow:
				indexShow = self.numberShowIndex(nameCleaned, exclude = True, special = True)
				if index is None or (not indexShow is None and indexShow < indexYear): index = indexShow
			if not index is None:
				if year:
					yearKey = str(year)
					for i in titlesCleaned:
						if yearKey in i:
							nameYear = nameCleaned[:index + 5]
							break
				if not reevaluate or index > 0: nameCleaned = nameCleaned[:index]
			if not nameCleaned: return False

			# Some collections have the same name as the first movie in the collection.
			# Eg: "Taken" or "Hotel Transylvania" or "Toy Story"
			# Do not use the collection name for matching.
			# Eg: Hotel Transylvania [Cam][Latino][wWw EliteTorrent BiZ] CAM 2.0
			collectionException = False
			if isMovie and not index and guidance and not guidance['file']['pack'] and titleCollection and title.count(titleCollection[0]) == 1:
				try:
					# Only remove the last occurance in the list.
					# If the collection name appears somewhere at ther start of the list, it is also the normal movie title ("Taken" movie vs "Taken" collection).
					indexCollection = len(title) - 1 - title[::-1].index(titleCollection[0])
					if indexCollection >= 3:
						collectionException = True
						titleNew = tools.Tools.copy(title)
						del titleNew[indexCollection]
						titles = self._titleProcessTitle(titleNew, language = language, country = country, network = network, studio = studio)
						titlesCleaned = titles['cleaned']

						# Various replacements in _titleProcessTitle() can cause another title to be reduced to the collection title.
						# Filter these out afterwards.
						try: indexCollection = len(titlesCleaned) - 1 - titlesCleaned[::-1].index(titlesCollection['cleaned'][0])
						except: indexCollection = 0
						while indexCollection >= 3:
							del titlesCleaned[indexCollection]
							try: indexCollection = len(titlesCleaned) - 1 - titlesCleaned[::-1].index(titlesCollection['cleaned'][0])
							except: indexCollection = 0
				except: pass

			# For titles that can also be seen as a year number.
			# Eg: 1984 Nineteen Eighty Four
			if nameYear:
				found = __titleMatch(threshold = threshold, titles = titlesCleaned, name = nameYear, number = None, adjust = adjust, result = result)
				if found: return found

			# Some titles include the "3D" keyword, which gets removed by cleanKeyword().
			# This can cause the title length to be reduced to a point where false positive matches happen.
			# Eg: [ToonsHub] ONE PIECE 3D! Trap Coaster S01E01 1080p B-Global WEB-DL AAC2.0 H.264 (ONE PIECE 3D: Gekisou! Trap Coaster, Multi-Subs)
			# Reduces to: "one piece 3d trap coaster" and after cleanKeyword() to "one piece", which will now be allowed for the main "One Piece" series.
			_3d = '[GAIA3D]'
			nameStripped = self._expressionReplace(id = 'titleValid_3d', data = nameCleaned, expression = u'.{0,25}(\s3d\s)[a-z\d\s]{0,25}(?:season|episode|s\d+|\d+|$)', replace = _3d)
			if len(nameStripped) == len(nameCleaned): _3d = None # Avoid replacement below if it does not contain the 3D keyword.

			# full = False:
			#  1. Do not remove release groups, since they can match an invalid title (eg: pheonix or legend).
			#  2. Do not remove languages, since codes can be confused with words (eg: the word "no" should not be considered Norwegian).
			nameStripped = self.cleanKeyword(nameStripped, exclude = titlesCleaned, encode = False, split = Stream.SplitRight, pack = pack, full = False, guidance = guidance, native = native)
			if _3d: nameStripped = nameStripped.replace(_3d, ' 3d ')

			# If the file name starts with the release network.
			#	Eg: Discovery.Channel.Xtreme.Martial.Arts.720p.HDTV.x264-DHD
			#	Eg: Discovery.Xtreme.Martial.Arts
			if not nameStripped:
				if guidance and guidance['release']['network']:
					nameStripped = self.releaseNetworkClean(nameCleaned, guidance = guidance['release']['network'], split = Stream.SplitLeft, exclude = titlesCleaned)

			# Keywords are before the title. Try stripping from the other side.
			if not nameStripped or (not any(i in nameStripped for i in titles['split']) and any(i in nameCleaned for i in titles['split'])):
				nameStripped = self.cleanKeyword(nameCleaned, exclude = titlesCleaned, encode = False, split = Stream.SplitLeft, pack = pack, full = False, guidance = guidance, native = native)

			# Remove prefixes with a "name/domain presents ..."
			# Eg: Vectronic Presents Ava (2020) 1080p.WEB-DL.EVO x264.NL Subs Ingebakken
			nameStripped = self._expressionReplace(id = 'titleValid_prefix', data = nameStripped, expression = u'^(.{1,30}' + Stream.ExpressionSymbol + u'presents?' + Stream.ExpressionSymbol + u').*', exclude = titlesCleaned)

			# Important to only remove the ignore words AFTER the name was stripped.
			# Otherwise words that appear both in the ignore list and in the metadata/guidance, and are before the year or season number, are removed too early.
			#	Eg: Avatar DVD Rip (2009) 720x480
			# cleanIgnore would remove "dvd" and leave "rip" behind.
			nameStripped = self.cleanIgnore(nameStripped, ignore = titles['ignore'])

			# Detect if a movie contains an episode number (eg: Avatar vs Avatar The Last Airbender).
			# Only detect here instead of before cleanKeyword(), since sometimes random characters at the end of the file name, or a release group (eg: T4P3), can be incorrectly detected as an episode number.
			if isMovie:
				indexShow = self.numberShowIndex(nameStripped, exclude = True, episode = False) # Do not search for episode numbers, since movies can contain keywords like "Part 2".
				if not indexShow is None and indexShow >= 0: return False

			nameStripped = self.numberShowClean(data = nameStripped, exclude = titlesCleaned, encode = False, split = Stream.SplitRight)

			titlesLanguageless = titlesCleaned
			languages = None
			if guidance:
				languages = []
				if guidance['audio']['language']: languages.extend(guidance['audio']['language'])
				if guidance['subtitle']['language']: languages.extend(guidance['subtitle']['language'])

				# Some alias titles contain the language code.
				# Eg: "Toy Story 3" -> "Histoire de jouets 3"
				# Which causes language keywords not be be removed.
				# Eg: Toy Story FRENCH
				# Do not do this for the first few titles, since they might contain language codes as part of their actual titel.
				if languages:
					languageFound = False
					for i in titlesCleaned[:5]:
						if any(i.endswith(j) for j in languages):
							languageFound = True
							break
					if not languageFound: titlesLanguageless = [i for i in titlesLanguageless if not any(i.endswith(j) for j in languages)]

			# Only include languages that do not appear in the title (use: exclude = titlesCleaned).
			# Otherwise "The French Dispatch" is stripped down to "The Dispatch", and title validadtion then fails.
			nameStripped = self.languageClean(data = nameStripped, exclude = titlesLanguageless, split = Stream.SplitNone, guidance = languages, native = native) # Do not split here, since language codes (eg "no") might cause too much stripping.

			# Ignore release keywords.
			# Eg: Taken-1 -2 -3-Unrated-Extended--Liam-Neeson-Action-2008-2014-Eng-Ita-Multi-Subs-..
			# Taken has an alias "Taken 1 Unrated", resulting in the keyword "unrated" not to be removed from the title.
			# Only do this during reevaluation.
			if not reevaluate:
				for i in ['unrated', 'uncensored', 'remastered', 'extended', 'collection', 'version', 'edition', 'collector', 'director', 'ece']:
					if not i in titlesCleaned[0]:
						nameStripped = self._expressionReplace(id = '_titleValid_ignore_' + i, data = nameStripped, expression = u'(' + i + Stream.ExpressionSymbolEnd + u').*')

			# Remove trailing spaces.
			nameStripped = nameStripped.strip()

			# Replace collection sets with the actual number from the title (eg "Toy Story Triology" -> "Toy Story 3").
			# Use the full name for matching, since the collection keyword might be behind other metadata keywords being removed by split.
			# Do not do this if the entire title is digits (eg: 1917).
			number = titles['number']

			# Do not do this for episodes, since episode titles might contain a number.
		 	# Eg: Episode 1
			# Eg: Chapter 3
			collection = False
			if isMovie:
				# Only do this if not file pack keywords were detected, since the keyword might be combined with the number
				# The Terminator 5 Movie Collection - EX RM DC 1984-2015 Eng Subs 720p [H264-mp4]
				# This means there are 5 movies in the pack, not that this is the 5th Terminator.
				try: collection = bool(guidance['file']['pack'])
				except: pass

				if number:
					# Ignore show packs for movies.
					# Eg: TAKEN: Complete TV Series Season 1-2
					# Note that there are packs that contain both the TV show and the movies.
					if self._cacheId('_titleValid_tv1', re.compile, '%s(series?|seasons?)%s' % (Stream.ExpressionSymbolStart, Stream.ExpressionSymbolEnd), flags = Stream.ExpressionFlags).search(data):
						if not self._cacheId('_titleValid_tv2', re.compile, '%s(films?|movies?)%s' % (Stream.ExpressionSymbolStart, Stream.ExpressionSymbolEnd), flags = Stream.ExpressionFlags).search(data):
							# Allow if a year range or a keyword is is included.
							# Eg: THE TERMINATOR - Complete Series (1984 - 2015)
							# Eg: TAKEN: Complete TV Series Season 1-2, 1,2,3 TRILOGY: 720p x264
							# "full = False" to exclude "complete".
							# Eg: TAKEN.Complete.Series.avi [~PiXelpiMpS~]
							if not self._expressionMatchType(id = '_titleValid_tv3', data = data, expression = self._filePackExpression(full = False)):
								return False

				if collection and number:
					# Extract the pack number range.
					# Eg: Taken.1-3.2008-2014.HDRip.Isl.Texti
					# If the number is not in range, return False, else remove the range from the name
					ranged = self._cacheId('_titleValid_range1', re.compile, '%s(?:(\d)(?:%s?-%s?(\d))+|(?:(\d)%s){2,})(?!%s+\d%s)%s' % (Stream.ExpressionSymbolStart, Stream.ExpressionSeparator, Stream.ExpressionSeparator, Stream.ExpressionSeparator, Stream.ExpressionSeparator, Stream.ExpressionSeparator, Stream.ExpressionSymbolEnd), flags = Stream.ExpressionFlags).search(data)
					if ranged:
						ranged = [int(i) for i in ranged.groups() if i]
						if len(ranged) == 2: ranged = list(range(ranged[0], ranged[1] + 1))
						if int(number) in ranged:
							nameCollection = nameStripped
							replaceCollection = 'GAIACOLLECTIONUMBER'
							for i in ranged:
								# Make sure to only replace standalone digits.
								# Otherwise the "1"  might be rermoved from a year "1995".
								#nameStripped = nameStripped.replace(' ' + str(i), '')
								nameStripped = self._cacheId('_titleValid_range2_' + str(i), re.compile, '\s(%s)(?:$|\s)' % i, flags = Stream.ExpressionFlags).sub(' ', nameStripped)
								nameCollection = self._cacheId('_titleValid_range3_' + str(i), re.compile, '\s(%s)(?:$|\s)' % i, flags = Stream.ExpressionFlags).sub(' %s ' % replaceCollection, nameCollection)

							# Allow collections to be matched, evenn if no collection title was passsed.
							# Eg (Toy Story 3): Toy.Story.1-3.1995-2010.1080p.BluRay.x264.DTS.AC3.3Audio-HDWinG
							nameCollection = self._cacheId('_titleValid_range4', re.compile, '((?:\s%s)+)' % replaceCollection, flags = Stream.ExpressionFlags).sub(' %s' % number, nameCollection)
							if nameCollection and not nameCollection == nameStripped:
								indexYear = self.yearIndex(nameCollection)
								if indexYear: nameCollection = nameCollection[:indexYear]
								if nameCollection and not nameCollection == nameStripped:
									found = __titleMatch(threshold = threshold, titles = titlesCleaned, name = nameCollection, number = number, adjust = adjust, result = result)
									if found: return found
						else:
							# If the title is not the collection title, ignore the range.
							# Eg: Star.Wars.The.Last.Jedi.2017.1-3.HDCAM.Rip.x264.AC3-DTOne-Exclusive.mkv
							if titlesCleaned[0] == titlesCollection or not __titleMatch(threshold = threshold, titles = titlesCleaned[0], name = nameStripped, number = number, adjust = adjust, result = result): return False

					# Number that is part of the collection keywords.
					# Eg: Terminator 5-Film Collection (1984-2015) ~ TombDoc
					# Eg: Harry Potter [8] eight Movies Collection [Dual Audio-ENG-HINDI]2
					match = self._cacheId('_titleValid_single', re.compile, '%s(\d)%s+(?:(?:one|two|three|four|five|six|seven|eight|nine|ten)%s+)?(?:films?|movies?)%s' % (Stream.ExpressionSymbolStart, Stream.ExpressionSymbolStart, Stream.ExpressionSymbolEnd, Stream.ExpressionSymbolEnd), flags = Stream.ExpressionFlags).search(data)
					if match:
						nameStripped = nameStripped.replace(' ' + str(match.group(1)), '')
					elif not ranged:
						# For single movies that contain pack keywords.
						# Eg: Taken 2 2012 COMPLETE BLURAY-PCH
						if not nameStripped.replace(' ', '').isdigit():
							if not self._expressionMatch(id = '_titleValid_unrange1_' + number, data = nameStripped, expression = '(?:^|\s)(0*' + number + ')(?:$|\s)', internal = True):
								if self._expressionMatch(id = '_titleValid_unrange2', data = nameStripped, expression = '(?:^|\s)(\d)(?:$|\s)'): return False

				elif not collection:
					if not nameStripped.replace(' ', '').isdigit():
						if number:
							# Has the incorrect number.
							# "Toy Story 3" vs "Toy Story 2".
							if not self._expressionMatch(id = '_titleValid_number1_' + number, data = nameStripped, expression = '(?:^|\s)(0*' + number + ')(?:$|\s)', internal = True):
								if self._expressionMatch(id = '_titleValid_number2', data = nameStripped, expression = '(?:^|\s)(\d)(?:$|\s)'): return False

								# Title: "Toy Story 3", Name: "Toy Story"
								# Only do this if the year does not match.
								# Eg: Toy Story 2010 TS XviD PrisM
								# This should be valid for "Toy Story 3". The number was not added to the file name, but the year is correct.
								elif not number == '1' and year and not str(year) in nameOriginal:
									if self._expressionMatch(id = '_titleValid_number3_' + number, data = titlesCleaned[0], expression = '(?:^|\s)(0*' + number + ')(?:$|\s)', internal = True) and not self._expressionMatch(id = '_titleValid_number4_' + number, data = nameStripped, expression = '[^1-9](0*' + number + ')(?:$|\s)', internal = True):
										matched = False
										if titlesCollection: matched = __titleMatch(threshold = threshold, titles = titlesCollection['cleaned'], name = nameStripped, number = number, adjust = adjust, result = result)
										else: matched = __titleMatch(threshold = threshold, titles = titlesCleaned, name = nameStripped, number = number, adjust = adjust, result = result)
										if matched and not self._expressionMatch(id = '_titleValid_number5', data = nameStripped, expression = 'i+'): return False

							nameStripped = self._expressionReplace(id = '_titleValid_number6_' + number, data = nameStripped, expression = '(0+' + number + ')', replace = number, internal = True) # Replace number with leading 0s (03 -> 3).
							nameStripped = self._expressionReplace(id = '_titleValid_number7_' + number, data = nameStripped, expression = '(?!' + number + ')(\d+)', exclude = titlesCleaned, internal = True) # Remove other standalone numbers, except the detected number. Important to exclude, otherwise titles with numbers are removed (eg: "1917").

							expressionPack = self._filePackExpression(collection = True)
							if ((guidance and guidance['file']['pack'])) or (not guidance and self._expressionMatch(id = '_titleValid_number8', data = data, expression = expressionPack)):
								try:
									if not nameStripped.endswith(number):
										nameStripped = self._expressionReplace(id = '_titleValid_number9', data = nameStripped, expression = expressionPack) + ' ' + number
								except: pass
							elif titles['suffix']:
								# Strip everything after the number, but only if the title ends in the number (suffix) and does not appear somewhere in between.
								# Use the last occurance of the number:
								#	Eg: 3.Toy.Story.3.2010.BD1080P.X264.AC3.Mandarin&English.CHS-ENG.Adans
								nameStripped = self._expressionReplace(id = '_titleValid_number10_' + number, data = nameStripped, expression = '.*%s+%s(%s+.*$)' % (Stream.ExpressionSymbol, number, Stream.ExpressionSymbol), internal = True)

						elif number is None:
							# If the title does not contain a number while the file name contains a number.
							# Eg: Searching for "Deadpool", but gettings file names with "Deadpool 2".
							extracts = self._expressionExtractMultiple(data = nameStripped, expression = Stream.ExpressionSymbolStart + '(\d+)' + Stream.ExpressionSymbolEnd)
							if extracts:
								temp = []
								for extract in extracts:
									# Ignore the number 1.
									#	Eg: Avatar #1 Movie
									#	Eg: Deadpool 1 (2016)
									#if int(extract) <= 1: continue
									# Update: We now remove the number 1 from the name below.
									if int(extract) <= 0: continue

									found = False
									expression = Stream.ExpressionSymbolStart + '(' + extract + ')' + Stream.ExpressionSymbolEnd
									for title in titlesCleaned:
										if self._expressionMatch(id = '_titleValid_number11_' + extract, data = title, expression = expression, internal = True):
											found = True
											break
									if not found: temp.append(extract)

								if temp:
									# Do not return False for episodes, since there might be additional numbers (eg: pack numbers or some weird episode number format).
									#	Eg: Juego de Tronos 8×1 HDTV 1080p
									#	Eg: cmav99.com@权利的游戏第八季全集1-6.Game.of.Thrones.S08E01-06.未删减完整版1080p中英字幕.无水印
									# Do not return False for movie packs.
									#	Eg: Harry Potter [8] eight Movies Collection [Dual Audio-ENG-HINDI]2
									if not(len(temp) == 1 and temp[0] == '1'):
										if ((guidance and not guidance['file']['pack'])) or (not guidance and not self._expressionMatch(id = '_titleValid_number12', data = data, expression = self._filePackExpression(collection = True))): return False

									nameStripped = self._expressionReplace(id = '_titleValid_number13_' + str(temp), data = nameStripped, expression = ['(' + i + ')' for i in temp], internal = True)

			# Remove duplicate show numbers.
			# Only do this for shows, not movies.
			# Eg: [Lost]: Lost S01 av 1 Lost.S01E01.720p.DD5.1.BluRay.n zb (1/935)
			# Eg: [Hotel Transylvania 3: Summer Vacation]: Hotel Transylvania The Series S01E01 720p HDrip X264 Dual Audio [English-Hindi] 720p 2.0
			if isShow: nameStripped = self._cacheId('_titleValid_show', re.compile, Stream.ExpressionSymbolStart + '(s\d+(?:e\d+)?)' + Stream.ExpressionSymbolEnd, flags = Stream.ExpressionFlags).sub('', nameStripped)

			# Remove any remaining spaces.
			nameStripped = expressionSpaces.sub(' ', nameStripped).strip()

			# For names that obfuscate alphabetics with numbers.
			# This is mostly for hoster files.
			#	Eg: Mul5an.2020.1080p.BluRay.x265-RARBG-MaxRls.mp4 1.70 GB | HEVC
			#	Eg: du00ne.2021.1080p.web.hevc.x265-MaxRls.mkv
			# Match 3 or more characters to exclude abbreviations.
			#	Eg: Star Trek DS9
			# Some names are obfuscated with symbols (eg: 1-91-7.2019.1080p). Symbols are replaced with spaces and will be handled by the spaceless match below.
			obfuscated = False
			#expressionObfuscated = '(?:[a-z\p{L}]{3,}\d|\d[a-z\p{L}]{3,})' # \p{L} does not seem to work in Python.
			expressionObfuscated = Stream.ExpressionSymbol.lstrip('[').rstrip(']')
			expressionObfuscated = '(?:[^\W\d' + expressionObfuscated + ']{3,}\d{1,2}|\d{1,2}[^\W\d' + expressionObfuscated + ']{3,}|[^\W\d' + expressionObfuscated + ']{1,}\d{1,2}[^\W\d' + expressionObfuscated + ']{1,})'
			if self._expressionMatch(id = '_titleValid_obfuscated1', data = nameStripped, expression = expressionObfuscated):
				if not self._expressionMatch(id = '_titleValid_obfuscated2', data = titlesCleaned[0], expression = expressionObfuscated):
					obfuscated = True

			# Try for the first time.
			found = __titleMatch(threshold = threshold, titles = titlesCleaned, name = nameStripped, number = number, adjust = adjust, obfuscated = obfuscated, result = result)
			if found: return found

			# Try removing the network name.
			# Eg [Discovery]: HDTV.Discovery.Xtreme.Martial.Arts.x264.720p.AC3.mkv
			if guidance and guidance['release']['network']:
				nameNetwork = self.releaseNetworkClean(nameStripped, guidance = guidance['release']['network'], split = Stream.SplitLeft, exclude = titlesCleaned)
				if not nameNetwork == nameStripped:
					found = __titleMatch(threshold = threshold, titles = titlesCleaned, name = nameNetwork, number = number, adjust = adjust, obfuscated = obfuscated, result = result)
					if found: return found

			# In case the year appears twice, try removing up to the first one (second year was removed the first time).
			indexYear = self.yearIndex(nameStripped)
			if indexYear:
				nameStripped = nameStripped[:indexYear]
				found = __titleMatch(threshold = threshold, titles = titlesCleaned, name = nameStripped, number = number, adjust = adjust, obfuscated = obfuscated, result = result)
				if found: return found

			# Roman numbers
			if self._expressionMatch(id = '_titleValid_roman1', data = nameStripped, expression = 'i+'):
				# Replace roman with arabic numerals (Movie II -> Movie 2).
				if number:
					nameStripped = self._expressionReplace(id = '_titleValid_roman2_' + number, data = nameStripped, expression = '(i{' + number + '})', replace = number, internal = True)
					nameStripped = self._expressionReplace(id = '_titleValid_roman3', data = nameStripped, expression = '(i+)')
					nameStripped = expressionSpaces.sub(' ', nameStripped).strip()
					found = __titleMatch(threshold = threshold, titles = titlesCleaned, name = nameStripped, number = number, adjust = adjust, obfuscated = obfuscated, result = result)
					if found: return found

				# Remove roman number ranges for collections.
				else:
					nameStripped = self._expressionReplace(id = '_titleValid_roman4', data = nameStripped, expression = '([ivx]+)', replace = '')
					found = __titleMatch(threshold = threshold, titles = titlesCleaned, name = nameStripped, number = number, adjust = adjust, obfuscated = obfuscated, result = result)
					if found: return found

			# Try matching a few non-ASCII characters.
			# Sh&Aring;gun.2024.S01E03.WEB.x264-TORRENTGALAXY
			# Eg: Shgun.2024.S01E03.Tomorrow.Is.Tomorrow.720p.DSNP.WEB-DL.DDP5.1.H
			# Eg: Shōgun.2024.S01E03.Tomorrow.Is.Tomorrow.720p.DSNP.WEB-DL.DDP5.1.
			# Eg: Sh&Aring;gun.2024.S01E03.Tomorrow.Is.Tomorrow.720p.DSNP.WEB-DL.DDP5.1
			# Eg: Shggun 2024 S01E03 Tomorrow Is Tomorrow 1080p DSNP WEB-DL DDP5 1 H 264-NTb
			# Eg: Shogun.2024.S01E03.1080p.WEB.H264-SuccessfulCrab[TGx]
			if titles['utf'] and self._cacheId('__titleValid_utf_' + titles['utf'], re.compile, titles['utf'], flags = Stream.ExpressionFlags).search(nameStripped):
				found = __titleMatch(threshold = threshold, titles = [titlesCleaned[0]], name = nameStripped, number = number, adjust = adjust, obfuscated = True, result = result)
				if found: return found

			# Try by removing all non-ASCII characters (ç?©å...·æEUR»å?¨å\'~3.Toy.Story.3.è<±è¯­.2010.720p.mkv).
			if not str(year) in titlesCleaned:
				nameAscii = self._cacheId('__titleValid_ascii', re.compile, '[^\x00-\x7F]+', flags = Stream.ExpressionFlags).sub('', nameStripped)
				nameAscii = expressionSpaces.sub(' ', nameAscii).strip()
				if not nameAscii == nameStripped:
					nameAscii = expressionSpaces.sub(' ', nameAscii).strip()
					found = __titleMatch(threshold = threshold, titles = titlesCleaned, name = nameAscii, number = number, adjust = adjust, obfuscated = obfuscated, result = result)
					if found: return found

			# Try by removing all spaces.
			# Do this if there is number in the name. Eg (Toy Story 3): d-toystory3-1080p.mkv
			# Do not do this if there is not number in the name. Eg (Star Wars The Last Jedi): STR.WRS.mp4
			if not collectionException or (number and number in nameStripped):
				nameSpaceless = nameStripped.replace(' ', '')
				if titles['spaceless']:
					nameSplit = nameStripped.split(' ')
					wordLength1 = [len(i) for i in nameSplit]
					wordLength1 = (float(sum(wordLength1)) / len(wordLength1)) if wordLength1 else 0
					wordLength2 = [len(i) for i in nameSplit if len(i) > 3]
					wordLength2 = (float(sum(wordLength2)) / len(wordLength2)) if wordLength2 else 0
					wordException = wordLength1 < 4 and wordLength2 < 5

					found = __titleMatch(threshold = threshold, titles = titles['spaceless'], name = nameSpaceless, number = number, adjust = adjust + (0.2 if wordException else 0), obfuscated = obfuscated, strict = 1, result = result)
					if found: return found

					# For dash-separated titles.
					# Eg: The Office (IL) is called "HaMisrad" on Trakt/TVDb, but "Ha-Misrad" on IMDb.
					# Increase adjust to accomodate short abbreviations at the end of the title.
					# Eg (Star Trek): Star Trek NG Season 1
					if titles['spacenone']:
						if not nameSpaceless == nameStripped:
							found = __titleMatch(threshold = threshold, titles = titles['spacenone'], name = nameSpaceless, number = number, adjust = adjust + 0.2, obfuscated = obfuscated, strict = 1, result = result)
							if found: return found
				else:
					# Single word titles.
					# Important for filenames from hosters.
					# Eg: "1 91 7" ("1-91-7.2019.1080p.bluray.x264-wutang-MaxRls.mkv 7.00 GB")
					if not nameSpaceless == nameStripped:
						found = __titleMatch(threshold = threshold, titles = titlesCleaned, name = nameSpaceless, number = number, adjust = adjust, obfuscated = obfuscated, strict = 1, result = result)
						if found: return found

			# Try the abbrivation of the first title.
			if titles['abbreviation']:
				found = __titleMatch(threshold = threshold, titles = titles['abbreviation'], name = nameStripped, number = number, adjust = adjust, obfuscated = obfuscated, strict = 2, result = result)
				if found: return found

				# Eg: G-O-T.s08e01.web.h264-RBB.mp4
				found = __titleMatch(threshold = threshold, titles = titles['abbreviation'], name = nameStripped.replace(' ', ''), number = number, adjust = adjust, obfuscated = obfuscated, strict = 2, result = result)
				if found: return found

			# Try with duplicate keywords removed.
			# Eg: 【首发于高清影视之家 】X[简繁英字幕] X 2022 1080p BluRay DTS x265-10bit-ENTHD
			# Changes to: "x x"
			nameUnique = ' '.join(tools.Tools.listUnique(nameStripped.split(' ')))
			if nameUnique and not nameUnique == nameStripped:
				found = __titleMatch(threshold = threshold, titles = titlesCleaned, name = nameUnique, number = number, adjust = adjust, obfuscated = obfuscated, result = result)
				if found: return found

			# Try by removing names or other keywords between the title and the year.
			# Eg: 9 (Shane Acker, 2009) [BDRip 1080p - Ita Eng AC3 - Sub Ita Eng]
			# Eg: Аватар / Avatar (Джеймс Кэмерон / James Cameron) [2009, США, боевик, приключения, фантастика, BDRip 1080p] [Collector&quots Cut] Dub + Sub Rus, Eng + Original Eng
			if year:
				# Do not do this if there are multiple years in the name:
				# Eg: 神奇女侠1984(中英双字幕) Wonder Woman 1984 2020 IMAX WEB-1080p X264 AAC..
				strip = True
				if not collection:
					years = self._cacheId('_titleValid_keywords_1', re.compile, self._expressionFormatCommon(Stream.ExpressionYearGroup), flags = Stream.ExpressionFlags).findall(data)
					if years:
						years = tools.Tools.listUnique([int(i) for i in years if i])
						if len(years) > 1: strip = False

				if strip:
					nameKeywords = self._cacheId('_titleValid_keywords2_' + str(year), re.compile, '.*?[\(\[\{](.*?)' + str(year), flags = Stream.ExpressionFlags).search(data)
					if nameKeywords:
						nameKeywords = nameKeywords.group(1)
						nameKeywords = self._cacheId('_titleValid_keywords3', re.compile, Stream.ExpressionSymbol.replace('\\s', ''), flags = Stream.ExpressionFlags).sub('', nameKeywords)
						nameKeywords = nameKeywords.lower().split()
						nameKeywordless = nameStripped
						for i in nameKeywords:
							if len(i) > 3: nameKeywordless = nameKeywordless.replace(i, '')
						nameKeywordless = nameKeywordless.replace('  ', ' ').strip()
						if nameKeywordless and not nameKeywordless == nameStripped:
							found = __titleMatch(threshold = threshold, titles = titlesCleaned, name = nameKeywordless, number = number, adjust = adjust, obfuscated = obfuscated, result = result)
							if found: return found

			if titlesCollection:
				# Names with weird collection names.
				# Eg: 007 James Bond - The Daniel Craig Collection (2006-2015) ~ TombDoc
				# Eg: James Bond Daniel Craig Collection (2006-2021) BluRay 1080p x264 [Hindi - Englisg] DD5.1 - Msubs ~ Ranvijay
				# Eg: 007.James.Bond.Xmas.Full.Collection.1962-2025.DVDRip.Xvid.HuN-Arny
				if reevaluate and guidance and guidance['file']['pack'] and len(titlesCollection['split']) > 1:
					def __titleReplace(data):
						# Remove only if space before/after.
						# Otherwise it might replace characters inside a word, instead of whole words.
						return data.replace(i + ' ', '').replace(' ' + i, '')

					packKeyword = nameCleaned
					for i in nameStripped.split(' '):
						packKeyword = packKeyword.replace(i + ' ', '').replace(' ' + i, '')
					packKeyword = packKeyword.replace('the ', '')
					packKeyword = [i for i in packKeyword.split(' ') if i]

					packLabel = nameCleaned
					if titlesCollection['split']:
						# Only include words AFTER the first title word.
						# Eg: Global Deejays - The Collection (Taken From Superstar Part 1).2011[www.lokotorrents.com][mp3]
						# Do not cut away "Global Deejays".
						# Only do this for long prefixes.
						# Eg: SB James Bond 007 The Complete Collection 1962-2021		-> "SB"
						# Eg: Best Of James Bond 30th Anniversary Collection			-> "Best Of"
						try:
							index = packLabel.index(titlesCollection['split'][0])
							if index > 10: packLabel = packLabel[index:]
						except: pass
					for i in titlesCollection['split']:
						packLabel = packLabel.replace(i + ' ', '').replace(' ' + i, '')
					for i in packKeyword:
						packLabel = packLabel.replace(i + ' ', '').replace(' ' + i, '')

					packLabel = packLabel.split(' ')
					packLabel = [i for i in packLabel if i]

					# Ignore and pack keywords BEFORE the word "chronicles".
					#	Terminator.The.Sarah.Connor.Chronicles.2008.COMPLETE.SERIES.720p.BluRay.x265.10bit-GalaxyTV[TGx]
					#	Terminator - The Sarah Connor Chronicles - Complete Series (2 Seasons)[eztv REPACK]TVRip XVIDmp3 [cedar]
					try: packLabel = packLabel[packLabel.index('chronicles') + 1:]
					except: pass

					if packLabel:
						nameUnpacked = nameStripped
						for i in packLabel:
							nameUnpacked = nameUnpacked.replace(i + ' ', '').replace(' ' + i, '')
						nameUnpacked = ' '.join(nameUnpacked.strip().split(' ')) # Remove excess spaces.
						if nameUnpacked:
							found = __titleMatch(threshold = threshold, titles = titlesCollection['cleaned'], name = nameUnpacked, number = number, adjust = adjust, obfuscated = obfuscated, result = result)
							if found: return found

				# Try the abbrivation for collections.
				# Eg: TLOTR2-The Two Towers 2002 NL-subs xvid.avi
				# Eg: L.O.T.R.The.Two.Towers.2002.1080p.X264.anoxmous
				if titlesCollection['abbreviation']:
					collection = titlesCollection['cleaned'][0]
					abbreviation = titlesCollection['abbreviation']
					abbreviations = [abbreviation, ' '.join(abbreviation)]
					if collection.startswith('the '): abbreviations.extend([i.lstrip('t') for i in abbreviations])

					titleStripped = titlesCleaned[0].replace(collection, '').strip()
					titlesExtra = []
					for i in abbreviations:
						i = i.strip()
						titlesExtra.append(i)
						titlesExtra.append(i + ' ' + titleStripped)

					nameCollection = self._cacheId('_titleValid_collection1', re.compile, abbreviation + Stream.ExpressionSeparator + '*\d{1,2}', flags = Stream.ExpressionFlags).sub(abbreviation, nameStripped) # Replace TLOTR2 with TLOTR

					found = __titleMatch(threshold = threshold, titles = titlesExtra, name = nameCollection, number = number, adjust = adjust, obfuscated = obfuscated, strict = 2, result = result)
					if found: return found

			# Country, network or studio included in the title.
			# Use strict, to avoid false positives for short country codes or network abbreviations. Eg: "the office in"
			if titles['extended']:
				found = __titleMatch(threshold = threshold, titles = titles['extended'], name = nameStripped, number = number, adjust = adjust + 0.05, obfuscated = obfuscated, strict = 2, result = result)
				if found: return found

			# Many filenames from Zooqle contain titles from 2-4 different languages. These are to long too match with the sequence algorithms.
			# Check 'found' otherewise 'star wars the last jedi' and 'the last jedi' are considered different titles.
			# Eg: Амели / Le Fabuleux Destin d\'Amelie Poulain / Amelie from Montmartre (Жан-Пьер Жене / Jean-Pierre Jeunet) [2001 г., комедия, мелодрама, драма, BDRip-AVC] Dub 720p
			count = 0
			words = 0
			found = []
			remaining = set(nameCleaned.split(' '))
			for i in titlesCleaned:
				if i in nameCleaned and not any(i.startswith(j) or j.startswith(i) or i.endswith(j) or j.endswith(i) for j in found):
					found.append(i)
					count += 1
					words += len(i.split())
					remaining = remaining - set(i.split(' ')) # Remove title words from the remaining file name words.
					if count >= threshold['concatenated']['count'] and words >= threshold['concatenated']['matched'] and len(remaining) <= threshold['concatenated']['unmatched']:
						return True

			if reevaluate:
				# Remove any language/country/network/studio from the title and try again.
				# Eg: "Disney Toy Story 3 (2010) Norsk Tale - Nicemaniac" -> "Toy Story 3 (2010) Norsk Tale - Nicemaniac"
				removals = []
				if language:
					if not tools.Tools.isArray(language): language = [language]
					for i in language: removals.extend([i, tools.Language.name(i)])
				if country:
					if not tools.Tools.isArray(country): country = [country]
					for i in country: removals.extend([i, tools.Country.name(i)])
				if network:
					if not tools.Tools.isArray(network): network = [network]
					removals.extend(network)
				if studio:
					if not tools.Tools.isArray(studio): studio = [studio]
					removals.extend(studio)
				if network or studio:
					extras = [['disney'], ['pixar'], ['amazon'], ['apple'], ['fox', 'fx']]
					for i in ((network or []) + (studio or [])):
						for j in extras:
							if self._cacheId('_titleValid_release1_' + str(i), re.compile, '%s(%s)%s' % (Stream.ExpressionSymbolStart, '|'.join(j), Stream.ExpressionSymbolEnd), flags = Stream.ExpressionFlags).search(i):
								removals.extend(j)
				if removals:
					removals = [tools.Tools.replaceNotAlphaNumeric(i.lower(), replace = Stream.ExpressionSymbol + '*') for i in removals if i]
					removals = [i for i in removals if not self._cacheId('_titleValid_release2_' + str(i), re.compile, '%s(%s)%s' % (Stream.ExpressionSymbolStart, i, Stream.ExpressionSymbolEnd), flags = Stream.ExpressionFlags).search(title[0])]
					dataNew = self._cacheId('_titleValid_release3_' + str(removals), re.compile, '%s(%s)%s' % (Stream.ExpressionSymbolStart, '|'.join(removals), Stream.ExpressionSymbolEnd), flags = Stream.ExpressionFlags).sub('', data)
					if dataNew and not dataNew == data:
						if self.__titleValid(data = dataNew, media = media, title = title, titleCollection = titleCollection, year = year, language = language, country = country, network = network, studio = studio, none = none, quick = quick, guidance = guidance, adjust = adjust, reevaluate = False, result = result): return True

				# If there is a single slash, try everything before it.
				# Eg: den-of-thieves/openload
				if '/' in data:
					dataNew = data.split('/')[0]
					if dataNew and not dataNew == data:
						if self.__titleValid(data = dataNew, media = media, title = title, titleCollection = titleCollection, year = year, language = language, country = country, network = network, studio = studio, none = none, quick = quick, guidance = guidance, adjust = adjust, reevaluate = False, result = result): return True

				# For names with quote parts in them, especially for usenet file names.
				# Eg: DVDRips "Avatar.2009.DVDRip.x264-DJ.par2" yEnc (1/1)]
				# Eg: (YEz:/D5;8GKVvgem) - "Avatar (2009)DVDr Avi (NL subs).nzb" yEnc (1/2)]
				# Eg: [BayiSubs] The King's Avatar - 02 [480p]V2 [01/11] - "[BayiSubs] The King's Avatar - 02 [480p]V2.mkv.001" yEnc (1/82)
				dataNew = self._cacheId('_titleValid_usenet1', re.compile, '"(.*?)"', flags = Stream.ExpressionFlags).search(data)
				if dataNew:
					dataNew = dataNew.group(1)
					if not dataNew or dataNew == data:
						dataNew = self._cacheId('_titleValid_usenet2', re.compile, '^[\[\(].*?[\]\)]\s*(.*?)$', flags = Stream.ExpressionFlags).search(data)
						if dataNew:
							dataNew = dataNew.group(1)
				if dataNew and not dataNew == data:
					return self.__titleValid(data = dataNew, media = media, title = title, titleCollection = titleCollection, year = year, language = language, country = country, network = network, studio = studio, none = none, quick = quick, guidance = guidance, adjust = adjust, reevaluate = False, result = result)

				# By default the file pack keywords are removed and do NOT split the file name.
				# In some cases we should not split it:
				#	Eg: The Lord of the Rings - Extended Trilogy The Two Towers
				# But in some cases we should split it
				#	Eg: The Lord of the Rings Collection By Bluewater
				if pack:
					namePack1 = self.filePackClean(data = nameCleaned, exclude = titlesCleaned, encode = False, guidance = guidance['file']['pack'] if guidance else None, split = Stream.SplitRight)
					namePack2 = self.filePackClean(data = nameCleaned, exclude = titlesCleaned, encode = False, guidance = guidance['file']['pack'] if guidance else None, split = Stream.SplitNone)
					if namePack1 == namePack2:
						namePack1 = self.releaseEditionClean(data = nameCleaned, exclude = titlesCleaned, encode = False, guidance = guidance['release']['edition'] if guidance else None, split = Stream.SplitRight)
						namePack2 = self.releaseEditionClean(data = nameCleaned, exclude = titlesCleaned, encode = False, guidance = guidance['release']['edition'] if guidance else None, split = Stream.SplitNone)
					if not namePack1 == namePack2:
						return self.__titleValid(data = data, media = media, title = title, titleCollection = titleCollection, year = year, language = language, country = country, network = network, studio = studio, none = none, quick = quick, guidance = guidance, adjust = adjust, pack = False, reevaluate = False, result = result)

				# If all else fails, remove all unicode characters and try again.
				# Some Chinese titles even have the show keywords and the show number in Mandarin.
				# Eg: 冰Y火Z歌：权L的Y戏.第八季.Game.of.Thrones.S08E01.HD1080P.X264.AAC.English.CHS-ENG.ZiMuWu
				dataNew = ''.join([i if ord(i) < 128 else ' ' for i in data])
				if not data == dataNew:
					# Do not do this if only individual letters or words remain.
					# Eg: "[www.domp4.cc]机x玩j.2022.HD1080p.国语中字.mp4" -> "机x玩j" -> "x j"
					# Still allow short titles.
					# Eg: "首发于高清影视之家 】X[简繁英字幕] X 2022 1080p BluRay DTS x265-10bit-ENTHD" -> "x"
					found = False
					nameNew = (''.join([i if ord(i) < 128 else ' ' for i in nameStripped])).split(' ')
					nameNew = [i for i in nameNew if i]
					for i in titlesCleaned:
						if len(i) < 3 and i in nameNew:
							found = True
							nameNew = [j for j in nameNew if not i == j]
					if any(len(i) > 3 for i in nameNew) or (found and not nameNew):
						return self.__titleValid(data = dataNew, media = media, title = title, titleCollection = titleCollection, year = year, language = language, country = country, network = network, studio = studio, none = none, quick = quick, guidance = guidance, adjust = adjust, pack = False, reevaluate = False, result = result)

		except: tools.Logger.error()

		return False

	'''
		FUNCTION:
			Does a quick check wether the file name matches one of the titles.
			Does just a basic check which can be used to filter out clearly wrong file names, before calling the more extensive titleValid().
			Can be called on an instance (without the value parameter), or on the class (with the value parameter).
		PARAMETERS:
			data (string): The file name.
			title (string/list): The title.
			none (boolean): If True, file names that are unknown (None) are accepted as valid.
			full (boolean): If True, ALL words of the title must appear in the file name. If False, ANY word of the title must appear in the file name.
		RETURNS:
			Wether the file name is valid (boolean).
	'''
	@classmethod
	def titleValidQuick(self, data, title, none = True, full = False):
		data = self.cleanBasic(data)
		title = self.cleanEncode(title)
		return self.__titleValidQuick(data = data, title = title, none = none, full = full)

	def _titleValidQuick(self, none = True, full = False):
		return self.__titleValidQuick(data = self.fileName(), title = self.metaTitle(), none = none, full = full)

	@classmethod
	def __titleValidQuick(self, data, title, none = True, full = False):
		try:
			if none and (not data or not title): return True
			title = self._titleProcessTitle(title)
			data = self._titleProcessName(data, ignore = title['ignore'])
			dataSplit = data['split']

			# Allow obfuscated names (eg: Mul5an).
			obfuscated = []
			for i in dataSplit:
				new = ''.join('' if j.isdigit() else j for j in i)
				if new and not i == new: obfuscated.append(new)
			dataSplit.extend(obfuscated)

			if full:
				if set(title['split']).issubset(dataSplit):
					return True
			else:
				for i in title['cleaned']:
					if any(d in i for d in dataSplit):
						return True

				for i in title['ascii']:
					if i in data['cleaned']:
						return True

				# For file names without spaces.
				# Eg: GameOfThrones S01E02 FR-ENG.mkv
				for i in title['spaceless']:
					if i in data['spaceless']:
						return True

				if title['abbreviation']:
					abbreviation = title['abbreviation']
					if any(d in abbreviation for d in dataSplit):
						return True

				if title['utf']:
					dataNew = tools.Tools.replaceNotAlphaNumeric(data['cleaned'])
					if not data == data['cleaned'] and self._cacheId('titleValidQuick_' + title['utf'], re.compile, title['utf'], flags = Stream.ExpressionFlags).search(data['cleaned']):
						return True
		except:
			tools.Logger.error()
		return False

	'''
		FUNCTION:
			Finds the first valid file name from a list that matches a title.
			In an ideal case, we would want to calculate an absolute matching ratio value for each file name and then pick the highest one.
			However, since there are many different ratios calculated for each file name, it is difficult to combine them into a single value.
			Instead, we iteratively start with strict matching requirements and then reduce the required ration until we find a match.
			NB: This function is therefore not efficient and should be used sparingly, like matching the files of a single torrent from the debrid handler.
		PARAMETERS:
			data (list/list-of-lists): The list of file names. Or a list with multiple values (e: file name and path) for each file.
			title (string/list): The title.
			year (string/list): The year.
			none (boolean): If True, file names that are unknown (None) are accepted as valid.
			quick (boolean): If True, do a quick basic check to remove clearly incorrect file names, before doing a more extensive validation.
			filter (boolean): If True, filter out file names with incorrect extensions to speed up the validation (eg: jpg, srt, etc).
			exclude (boolean): If True, the titleProhibited() is called to exclude file names that contain specific unwanted keywords.
			valid (None/list): When a list is passed in, indexes of files that match but do not pass titleProhibited() are added to it.
		RETURNS:
			The index of the first valid file name or None if none is valid (integer/None).
	'''
	@classmethod
	def titlesValid(self, data, media, title, year = None, none = True, filter = True, quick = True, exclude = True, valid = None):
		# This function can take very long (30-60 secs) to execute, eg: from RealDebrid selectList().
		# Eg: Harry Potter and the Sorcerer's Stone, when played from a collection pack.
		# This is because the adjust threshold is too high and does not match anything, while decrease is very small, resulting in many iterations.

		data = tools.Tools.copy(data) # Because we edit it below.
		for i in range(len(data)):
			if not tools.Tools.isArray(data[i]):
				data[i] = [data[i]]

		# Further reduce time by eliminating incorrect file extensions.
		if filter:
			extensions = ['png', 'jpg', 'jpeg', 'bmp', 'gif', 'tiff', 'webp', 'cbr', 'cbz', 'pdf', 'm4b', 'azw3', 'mobi', 'djvu', 'zip', 'rar', '7z', '7zip', 'exe', 'apk', 'jar', 'deb', 'msi', 'css', 'js', 'htm', 'html', 'php', 'txt', 'nfo', 'srt', 'sub', 'idx', 'ac3', 'ac4']
			expression = '\.(%s)$' % ('|'.join(extensions))
			expression = self._cacheId('titlesValid', re.compile, expression, flags = Stream.ExpressionFlags)

			temp = []
			for i1 in data:
				temp2 = []
				for i2 in i1:
					if not expression.search(i2): temp2.append(i2)
				temp.append(temp2)
			data = temp

		start = Stream.Threshold['title']['multiple']['start']
		decrease = Stream.Threshold['title']['multiple']['decrease']

		# This is slow, especially if there are a lot of titles to match against, since in most cases titleValid() only triggers between adjust = [1.0, 1.3].
		# Instead of scanning from the highest (2.0) to the lowest (1.0), start from the lowest and work your way up.
		# This reduces the time from 32 secs down to 4 secs.
		'''
		adjust = start
		while adjust >= 1:
			for i in range(len(data)):
				for j in range(len(data[i])):
					if data[i][j] and self.titleValid(data = data[i][j], media = media, title = title, year = year, none = none, quick = quick, adjust = adjust):
						if not valid is None and not i in valid: valid.append(i)
						if not exclude or not self.titleProhibited(data = data[i][j], title = title): return i
			adjust -= decrease
		'''

		adjust = 1
		match = None
		valids = []
		while adjust <= start:
			found = False
			valids.append([])
			for i in range(len(data)):
				for j in range(len(data[i])):
					if data[i][j] and self.titleValid(data = data[i][j], media = media, title = title, year = year, none = none, quick = quick, adjust = adjust):
						valids[-1].append(i)
						if not exclude or not self.titleProhibited(data = data[i][j], title = title):
							match = i
							found = True
							break
					else: data[i][j] = None # Avoid matching this again with a higher adjust which will return False in any case.
				if found: break
			if not found: break # Not found, meaning scanning any further with a higher adjust will also not match any titles.
			adjust += decrease

		if not valid is None and valids:
			for i in reversed(valids):
				if i:
					valid.extend(tools.Tools.listUnique(i))
					break

		return match

	@classmethod
	def _titleMatch(self, function, value1, value2):
		# Doing string matching can take a lot of processing power.
		# Especially if the titles are long and there are many alias titles to match against.
		# Eg: "Lord of the Rings" or "The Hobbit" can take 10+ mins on low-end devices with 25 providers and 1000+ links, with most time spend on title-filename matching, typically providers also time out due to the scrape time limit.
		# On high-end devices this is a lot less noticeable. Although slower, it is still fast enough to not cause a scrape timeout.
		# These functions are called multiple times with the same values.
		# Cache them so that they only have to be calculated once.
		# This is also heavily impacted by many invalid filenames having to be matched, only to be rejected afterwards.
		# Caching these values can easily save 50%+ on the total scraping time.

		id = str(function) + '_' + str(value1) + '_' + str(value2)
		try:
			return Stream.TitleMatches[id]
		except:
			value = function(value1, value2)
			Stream.TitleMatches[id] = value
			return value

	@classmethod
	def _titleMatchLevenshtein(self, value1, value2):
		return self._titleMatch(function = tools.Matcher.levenshtein, value1 = value1, value2 = value2)

	@classmethod
	def _titleMatchJaccard(self, value1, value2):
		return self._titleMatch(function = tools.Matcher.jaccard, value1 = value1, value2 = value2)

	@classmethod
	def _titleMatchJaro(self, value1, value2):
		return self._titleMatch(function = tools.Matcher.jaro, value1 = value1, value2 = value2)

	@classmethod
	def _titleMatchClear(self):
		Stream.TitleMatches = {}

	'''
		FUNCTION:
			Checks wether the file name should be excluded, such as trailers, samples, reviewes, and more.
			Can be called on an instance (without the data parameter), or on the class (with the data parameter).
		PARAMETERS:
			data (string): The file name.
			title (string/list): The title.
			special (boolean): If it is a special episode which should allow certain keywords (eg: extras).
			exception (boolean): Allow prohibition types that are part of ExceptionProhibition.
			type (boolean): Return the prohibition type instead of a boolean value.
		RETURNS:
			Wether the file name should be excluded (boolean).
	'''
	@classmethod
	def titleProhibited(self, data, title = None, special = False, exception = True, type = False):
		return self.__titleProhibited(data = data, title = title, special = special, exception = exception, type = type)

	def _titleProhibited(self, exception = True, type = False):
		return self.__titleProhibited(data = self.fileName(), title = self.metaTitle(), special = self.metaSpecial(), exception = exception, type = type)

	@classmethod
	def __titleProhibited(self, data, title = None, special = False, exception = True, type = False):
		if not data: return False

		if special:
			expression = Stream.ExpressionProhibition
			expressions = [expression['expression'][i] for i in range(len(expression['expression'])) if expression['expression'][i][0] in expression['special']]
			expression['expression'] = expressions
		else:
			expression = Stream.ExpressionProhibition

		if exception:
			expression = tools.Tools.copy(expression)
			for i in Stream.ExceptionProhibition.keys():
				for j in range(len(expression)):
					if expression['expression'][j][0] == i:
						expression['expression'][j] = (expression['expression'][j][0], expression['expression'][j][1].replace('{precede}', ''))
						break

		expression = self._expressionFormatExpression(id = 'titleProhibited1_' + str(special) + '_' + str(exception), type = Stream.ExpressionSequential, expression = expression)
		result = self._expressionMatchType(id = 'titleProhibited2_', data = data, expression = expression, exclude = title)

		if exception and result in Stream.ExceptionProhibition: result = Stream.ProhibitionNone
		if not type: result = bool(result) # Make bool, since otherwise None might be returned, which has a different meaning in exclusionKeywordUpdate().
		return result

	@classmethod
	def _titleProcessTitle(self, title, language = None, country = None, network = None, studio = None):
		def __titleProcessTitle(title, language, country, network, studio):
			try:
				if tools.Tools.isTuple(title): title = list(title)
				elif not tools.Tools.isList(title): title = [title]
				title = titleAll = tools.Tools.copy(title)
				ignore = self._titleIgnore(title)

				split = []
				for i in range(len(title)):
					title[i] = self.cleanOther(title[i], file = False, titles = title)
					split.extend(title[i].split(' '))

				# Remove duplicates and keep order.
				title = tools.Tools.listUnique(title)
				split = tools.Tools.listUnique(split)

				# Do not include spaceless titles that are too short or end in an abbreviation.
				# Otherwise there are too many false positives.
				# Eg (The Original Series): Star Trek TOS -> startrektos
				# Eg (The Animated Series): Star Trek TAS -> startrektas
				spacenone = []
				spaceless = []
				for i in range(len(title)):
					j = titleAll[i]
					if len(j) > 3:
						j = j.split()[-1]
						if len(j) > 3 or not j.isupper():
							k = title[i].replace(' ', '')
							if k in title: spacenone.append(k)
							else: spaceless.append(k)

				abbreviation = self._titleAbbreviation(title[0])
				if not abbreviation or len(abbreviation) <= 1 or (len(abbreviation) >= 5 and abbreviation in title): abbreviation = None

				ascii = []
				try:
					for i in title:
						j = str(i.encode('ascii', errors = 'ignore'), 'utf-8')
						if not j in title and len(j) >= len(i) * 0.75: ascii.append(j)
				except: tools.Logger.error()

				utf = None
				charAscii = []
				charUtf = []
				try:
					for i in title[0]:
						if i.encode('ascii', errors = 'ignore'): charAscii.append(i)
						else: charUtf.append(i)
				except: tools.Logger.error()
				lengthHalf = len(title[0]) * 0.5
				lengthAsccii = len(charAscii)
				lengthUtf = len(charUtf)
				if lengthAsccii > 0 and lengthUtf > 0 and lengthAsccii >= lengthHalf and lengthUtf <= lengthHalf:
					titleUtf = title[0]
					for i in charUtf: titleUtf = titleUtf.replace(i, '(?:.?|&.{2,8};)')
					if not titleUtf == title[0]: utf = titleUtf

				number = None
				suffix = False
				for i in title:
					extract = self._expressionExtractMultiple(data = i, expression = '(?:^|\s|\:|\-\–)(\d)(?:$|[^a-z\d])', internal = True)
					if extract:
						if len(extract) == 1:
							number = extract[0] # Do not use the number if multiple ones are detected (eg: 9-1-1).
							suffix = i.endswith(number)
						break

				# Add country and network for title validation.
				# Eg: The Office US/UK/IL/PL/etc.
				first = title[0]
				extended = []
				if country:
					if tools.Tools.isArray(country): country = country[0]
					extended.append(first + ' ' + country.lower())
					name = tools.Country.name(country)
					if name: extended.append(first + ' ' + name.lower())
				if network:
					if tools.Tools.isArray(network): network = network[0]
					if len(network) < 10 and network.count(' ') <= 1:
						network = network.lower()
						extended.append(first + ' ' + network)
						extended.append(network + ' ' + first)
				if studio:
					if tools.Tools.isArray(studio): studio = studio[0]
					if len(studio) < 10 and studio.count(' ') <= 1:
						studio = studio.lower()
						extended.append(first + ' ' + studio)
						extended.append(studio + ' ' + first)

				return {
					'cleaned' : title,
					'ignore' : ignore,
					'number' : number,
					'suffix' : suffix,
					'split' : split,
					'spacenone' : spacenone,
					'spaceless' : spaceless,
					'extended' : extended,
					'abbreviation' : abbreviation,
					'ascii' : ascii,
					'utf' : utf,
				}
			except:
				tools.Logger.error()
		if not title: return title

		return self._cacheId('_titleProcessTitle_' + self._cacheIdMinimize(title, language, country, network, studio), __titleProcessTitle, title, language, country, network, studio)

	@classmethod
	def _titleProcessName(self, name, ignore = None):
		def __titleProcessName(name, ignore = None):
			name = self.cleanOther(name, ignore = ignore)
			return {
				'cleaned' : name,
				'split' : name.split(' '),
				'spaceless' : name.replace(' ', ''),
			}
		return self._cacheId('_titleProcessName_' + name + '_' + str(len(ignore) if ignore else 0), __titleProcessName, name, ignore)

	@classmethod
	def _titleAbbreviation(self, title):
		return ''.join(i[0] for i in title.split())

	@classmethod
	def _titleIgnore(self, titles):
		def __titleIgnore(titles):
			# Use the base, to avoid extracting values from inside a word.
			# Eg: Avatar has a title: "Avatar Edicion Coleccionista"
			# Eg: Do not exlcude "ecc" from "Avatar ECC 2009 RUS BDRip 2400 XviD AC3 [MGT]"
			base = '(?:(?:^|[^a-z])%s(?:$|[^a-z]))'
			expression = [(i, base % i) for i in Stream.ExpressionIgnore]
			ignore = self._expressionMatchMultiple(id = '__titleIgnore_' + titles[0], data = titles, expression = expression, internal = True)
			if ignore: result = [i for i in Stream.ExpressionIgnore if not i in ignore]
			else: result = Stream.ExpressionIgnore
			return ['(' + i + ')' for i in result]
		return self._cacheIdInternal('_titleIgnore_' + titles[0], __titleIgnore, titles)

	'''
		FUNCTION:
			Remove episode titles that are too general to be used for scraping or title validation.
			Eg: 'IV' or 'Episode 3'
		PARAMETERS:
			titles (string/list): The episode titles.
		RETURNS:
			The filtered titles (string/list).
	'''
	@classmethod
	def titleEpisodeIgnore(self, titles):
		if not titles: return titles
		single = not tools.Tools.isArray(titles)
		if single: titles = [titles]

		episodes = [episode[1]['episode'] for episode in Stream.ExpressionShow['language']]
		expression = self._cacheId('titleEpisodeIgnore', re.compile, '^((?:' + '|'.join(episodes) + ')' + Stream.ExpressionSeparator + '*)?(\d{1,4}|M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3}))?$', flags = Stream.ExpressionFlags)

		result = []
		for title in titles:
			if not expression.search(title): result.append(title)

		if single: return result[0] if result else None
		else: return result

	##############################################################################
	# YEAR
	##############################################################################

	'''
		FUNCTION:
			Extracts the year(s) from a string.
		PARAMETERS:
			data (string): The file name.
			clean (boolean): Wether or not to clean the data before processing.
		RETURNS:
			The years (list).
	'''
	@classmethod
	def yearExtract(self, data, clean = True):
		def _yearExtract(data, clean = True):
			if not data: return None
			if clean: data = self.cleanBasic(data)
			result = self._expressionExtractMultiple(data = data, expression = self._yearExpression())
			return [int(i) for i in result]
		return self._cache(_yearExtract, data = data, clean = clean)

	'''
		FUNCTION:
			Finds the first index of a year.
		PARAMETERS:
			data (string): The file name.
			year (None/integer): An optional year to look for.
		RETURNS:
			 The index of the year (None/integer).
	'''
	@classmethod
	def yearIndex(self, data, year = None, offset = None):
		matches = self._cacheId('yearIndex' + str(year), re.compile, self._yearExpression(year = year), flags = Stream.ExpressionFlags).finditer(data)
		if matches:
			index = -1
			first = -1
			if offset is None: offset = 0

			# In case the year appears multiple times, take the first occurance (eg: "1991 to 1995").
			# If the distance between the years is greater than 10, take the last occurance (typically if the year is at the start of the file name).
			for match in matches:
				first = match.start()
				if index < 0 and match.start() >= offset:
					index = match.start()
					break
			if index < 0: index = first
			if index >= 0: return index
		return None

	'''
		FUNCTION:
			Checks wether the file name matches the year.
			Can be called on an instance (without the value parameter), or on the class (with the value parameter).
		PARAMETERS:
			data (string): The file name.
			year (integer/list/tuple/dictionary): The year. If a list/tuple/dictionary is provided, a year range is assumed.
			pack (boolean): Wether or not it is a file pack.
			deviation (boolean): Wether or not to allow a one year deviation (eg: when looking for 2010, also check for 2009 and 2011).
		RETURNS:
			True if the year is correct. False if the year is incorrect. None if no year is in the file name.
	'''
	@classmethod
	def yearValid(self, data, year, media = None, pack = None, filePack = None, deviation = False):
		return self.__yearValid(data = data, year = year, media = media, pack = pack, filePack = filePack, deviation = deviation)

	def _yearValid(self, deviation = False):
		year = None
		if self.metaMediaShow():
			year = self._metaPackList(self.metaPack(), 'year', 'values')
		if not year: year = self.metaYear()
		return self.__yearValid(data = self.fileName(), year = year, media = self.metaMedia(), pack = self.metaPack(), filePack = self.filePack(), deviation = deviation)

	@classmethod
	def __yearValid(self, data, year, media = None, pack = None, filePack = None, deviation = False):
		if not data: return None
		extract = self.yearExtract(data = data)
		if not year: return True

		def __yearValid(extract, years):
			# Do not always accept a year simply because it falls into the range.
			# Another show with the same title might be released years apart.
			# Eg: One Piece (1999 - 2025+)
			# Eg: One Piece (2023 - ?)
			# Eg (invalid for the 1999 show): One.Piece.2023.S01E01.Romance.Dawn.720p.NF.WEB-DL.DDP5.1.Atmos.x264-CMRG[TGx]
			# If the difference between the extracted year and the show's year range is too great, assume it is a different show.
			# Only do this for shows. Movie collections can deviate.
			# Eg (No Time to Die 2021): James Bond Daniel Craig Collection (2006-2025) BluRay 1080p x264
			if tools.Media.isSerie(media):
				if len(extract) == 1:
					if abs(extract[0] - years[0]) < 10: return True
				else:
					if abs(extract[0] - years[0]) < 10 and abs(extract[-1] - years[-1]) < 10: return True
					elif abs(extract[0] - years[0]) <= 3 or abs(extract[-1] - years[-1]) <= 3: return True
				return False
			return True

		if extract:
			# Year range for shows.
			if tools.Tools.isArray(year):
				yearStart = year[0]
				yearEnd = year[-1]

				if yearStart in extract or yearEnd in extract: return __yearValid(extract, year)
				elif not pack and deviation and ((yearStart + 1) in extract or (yearStart - 1) in extract or (yearEnd + 1) in extract or (yearEnd - 1) in extract): return __yearValid(extract, year)
				elif pack and min(extract) >= yearStart and max(extract) <= yearEnd: return __yearValid(extract, year) # Year ranges for file packs.
			else:
				if year in extract: return __yearValid(extract, [year])
				elif not pack and deviation and ((year + 1) in extract or (year - 1) in extract): return __yearValid(extract, [year])
				elif pack: # Year ranges for file packs.
					# Only do for shows.
					# Use the start/end date, instead of the years list, since the years list can contain the special season year, which might be dated years after the actual release.
					# Do not allow for "The Office (IL) 2010": The Office (TV Series 2005–2013) 1080p AMZN WEB-DL x265 HEVC AAC 5.1 ESub
					# Update: Also do for movies (eg "S.W.A.T" 2003 - part of pack 2003-2017 - "S.W.A.T.2019.HC.HDRip.XviD.AC3-EVO")
					show = tools.Media.isShow(self._metaPack(pack, 'media'))
					years = self._metaPack(pack, 'year', 'range')

					# Add "and show" and (show or not years) for S.W.A.T. movies/shows/collections (check tester.py).
					if years and years[0] and show:
						if not years[1] or max(extract) <= years[1]:
							if min(extract) >= years[0]: return __yearValid(extract, years) # Continuing shows to not have an end year.
							elif deviation and min(extract) >= (years[0] - 1): return __yearValid(extract, years) # Only add deviation for start year. Eg (released in 1966): Star Trek S01E01 (1965) BDRip x264 [=Faith=]
					else:
						single = len(extract) == 1
						if single and (show or not years or filePack):
							if year <= extract[0]: return __yearValid(extract, years) # Single year. Eg: "Title Collection 2021".
						elif single and not filePack and deviation and ((year + 1) == extract[0] or (year - 1) == extract[0]):
							return __yearValid(extract, years)
						else: # Year range. Eg: "Title Collection 1964-2021"
							if year >= min(extract) and year <= max(extract): return __yearValid(extract, years)
			return False

		return None

	@classmethod
	def _yearExpression(self, year = None):
		if year is None: year = self._expressionFormatCommon(Stream.ExpressionYear)
		else: year = str(year)
		year = '(' + year + ')'
		return self._expressionFormatCommon(Stream.ExpressionSymbolStart + year + Stream.ExpressionSymbolEnd)

	##############################################################################
	# NUMBER COLLECTION
	##############################################################################

	'''
		FUNCTION:
			Retrieves the movie collection numbers.
		PARAMETERS:
			count (boolean): Return the count instead of the lisst.
		RETURNS:
			Collection numbers (list/integer): [1, 2, 3, 4].
	'''
	def numberCollection(self, count = False):
		value = self.mData['number']['collection']
		if count: value = self.numberCollectionCount(value)
		return value

	'''
		FUNCTION:
			Sets the movie collection numbers.
		PARAMETERS:
			number (None/integer/list/tuple): The collection numbers.
	'''
	def numberCollectionSet(self, number = None):
		if not tools.Tools.isArray(number): number = [number]
		self.mData['number']['collection'] = number

	'''
		FUNCTION:
			Extracts the movie collection numbers from a string.
			Multiple and consecutive numbers are also extracted.
		PARAMETERS:
			data (string): The file name.
			filePack (enumeration/boolean): Wether or not a pack was already detected.
			pack (dictionary): The movie or show pack count.
			clean (boolean): Clean the data string before processing.
		RETURNS:
			Collection numbers (list): [2, 3, 4].
			If no specific number was found, but there are keywords indicating that it is a collection, this is returned: [-1].
	'''
	@classmethod
	def numberCollectionExtract(self, data, filePack = None, pack = None, clean = True):
		def _numberCollectionYears(value, pack, ranged = False):
			result = None
			if pack:
				try:
					temp = []

					years = self._metaPack(pack, 'year', 'values')
					years = tools.Tools.copy(years) # Copy, because we edit it below and the pack dictionary (reference) is shared across streams.

					if ranged:
						try: index1 = years.index(value[0])
						except: index1 = None
						if not index1 is None:
							years[0] = 0 # In case the pack has multiple movies released during the same year.
							try: index2 = years.index(value[-1])
							except: index2 = None
							if not index2 is None: temp = list(range(index1 + 1, index2 + 2))
					else:
						for i in value:
							try: index = years.index(i)
							except: continue
							temp.append(index + 1)
							years[index] = 0 # In case the pack has multiple movies released during the same year.

					if temp: result = temp
				except: tools.Logger.error()
			return result

		def _numberCollectionExtract(data, filePack, pack, clean):
			result = None
			try:
				if filePack is False: return result
				data = self.cleanEncode(data)
				if clean: data = self.cleanBasic(data)
				if not data: return result

				# Specific keywords (eg: "trilogy").
				if not result:
					try:
						expression = self._expressionFormatExpression(id = 'numberCollectionExtract1', type = Stream.ExpressionSequential, expression = {'keyword' : Stream.ExpressionFilePack['keyword'], 'expression' : Stream.ExpressionFilePack['collection']})
						value = self._expressionMatchType(id = 'numberCollectionExtract2', data = data, expression = expression)
						if value: result = list(range(1, value + 1))
					except: tools.Logger.error()

				# Number range (eg: "1-4").
				if not result:
					try:
						value = self._cacheId('numberCollectionExtract3', re.compile, lambda : self._expressionFormatCommon(Stream.ExpressionNumberRange % tuple(['\d'] * 2)), flags = Stream.ExpressionFlags).search(data)
						if value:
							value = list(range(int(value.group(1)), int(value.group(2)) + 1))
							if value and tools.Tools.listConsecutive(value): result = value # Only if numbers are consecutive (eg: ignore "DD 5.1").
					except: tools.Logger.error()

				# Number list (eg: "1, 2, 3, 4").
				if not result:
					try:
						value = self._cacheId('numberCollectionExtract4', re.compile, lambda : self._expressionFormatCommon(Stream.ExpressionNumberList % tuple(['\d'] * 10)), flags = Stream.ExpressionFlags).search(data)
						if value:
							value = [int(i) for i in value.groups() if i]
							if value and tools.Tools.listConsecutive(value) and not(len(value) == 1 and value[0] == 1): result = value # Only if numbers are consecutive. Check length to exclude "DD5 1" and "[5.1 en]".
					except: tools.Logger.error()

				# Roman number range (eg: "I-VI").
				if not result:
					try:
						value = self._cacheId('numberCollectionExtract5', re.compile, lambda : self._expressionFormatCommon(Stream.ExpressionNumberRange % tuple(['[ivx]+'] * 2)), flags = Stream.ExpressionFlags).search(data)
						if value:
							value = list(range(tools.Converter.roman(value.group(1)), tools.Converter.roman(value.group(2)) + 1))
							if value and tools.Tools.listConsecutive(value): result = value # Only if numbers are consecutive.
					except: tools.Logger.error()

				# Roman number list (eg: "I, II, III, IV").
				if not result:
					try:
						value = self._cacheId('numberCollectionExtract6', re.compile, lambda : self._expressionFormatCommon(Stream.ExpressionNumberList % tuple(['[ivx]+'] * 10)), flags = Stream.ExpressionFlags).search(data)
						if value:
							value = [tools.Converter.roman(i) for i in value.groups() if i]
							if value and not None in value and tools.Tools.listConsecutive(value): result = value # Only if numbers are consecutive.
					except: tools.Logger.error()

				# Single count (eg: "5 Films").
				if not result:
					try:
						# ([1-9]\d*): exclude preceeding zeros. Eg: 007 - James Bond
						value = self._cacheId('numberCollectionExtract7', re.compile, lambda : self._expressionFormatCommon('{symbol}([1-9]\d*){separator}(?:movie|film)s?'), flags = Stream.ExpressionFlags).search(data)
						if value:
							value = int(value.group(1))
							if value: result = list(range(1, value + 1))
					except: tools.Logger.error()

				# Year range (eg: "2005-2010").
				if not result:
					try:
						value = self._cacheId('numberCollectionExtract8', re.compile, lambda : self._expressionFormatCommon('{symbol_start}(?<!%s[\-\–\s\_\.\,])(?<!%s[\-\–\s\_\.\,][\-\–\s\_\.\,])(%s){separator}*(?:[\-\–\s\_\.]|to){separator}*(%s)(?![\-\–\s\_\.\,]+%s){symbol_end}' % tuple([Stream.ExpressionYear] * 5)), flags = Stream.ExpressionFlags).search(data)
						if value:
							value = [int(i) for i in value.groups() if i]
							if pack: result = _numberCollectionYears(value = value, pack = pack, ranged = True)
							if not result:
								value = len(tools.Tools.listUnique(value)) # Duplicate years (eg: 1984.1984.2160p.AIUpscale.HEVC)
								if value == 2: result = [Stream.NumberPack]
					except: tools.Logger.error()

				# Year list (eg: "2005, 2007, 2010").
				if not result:
					try:
						value = self._cacheId('numberCollectionExtract9', re.compile, lambda : self._expressionFormatCommon('{symbol_start}(?:(%s)\s*[\s\,\.\+\&]\s*)(?:(%s)\s*[\s\,\.\+\&]\s*)?(?:(%s)\s*[\s\,\.\+\&]\s*)?(?:(%s)\s*[\s\,\.\+\&]\s*)?(?:(%s)\s*[\s\,\.\+\&]\s*)?(?:(%s)\s*[\s\,\.\+\&]\s*)?(?:(%s)\s*[\s\,\.\+\&]\s*)?(?:(%s)\s*[\s\,\.\+\&]\s*)?(?:(%s)\s*[\s\,\.\+\&]\s*)?(?:(%s)(?:\s*[\s\,\.\+\&]\s*)?)?{symbol_end}' % tuple([Stream.ExpressionYear] *  10)), flags = Stream.ExpressionFlags).search(data)
						if value:
							value = [int(i) for i in value.groups() if i]
							if pack: result = _numberCollectionYears(value = value, pack = pack)
							if not result:
								value = len(tools.Tools.listUnique(value)) # Duplicate years (eg: 1984.1984.2160p.AIUpscale.HEVC)
								if value > 1: result = [Stream.NumberPack] * value
					except: tools.Logger.error()

				if not result and filePack: result = [Stream.NumberPack]
			except: tools.Logger.error()
			return result
		return self._cache(_numberCollectionExtract, data = data, filePack = filePack, pack = pack, clean = clean)

	'''
		FUNCTION:
			Determine the number of movies in the collection.
		PARAMETERS:
			number (list): The extracted collection numbers.
		RETURNS:
			Collection count (integer/None).
	'''
	@classmethod
	def numberCollectionCount(self, number):
		if number:
			count = len(number)
			if (count > 1 or not number[0] == Stream.NumberPack): return count
		return None

	##############################################################################
	# NUMBER SHOW
	##############################################################################

	'''
		FUNCTION:
			Retrieves the season and episode numbers.
		RETURNS:
			Season and episode numbers (dictionary): {'season' : [1], 'episode' : [2, 3, 4]}.
	'''
	def numberShow(self):
		return self.mData['number']

	'''
		FUNCTION:
			Sets the season and episode numbers.
		PARAMETERS:
			season (None/integer/list/tuple): The season numbers.
			episode (None/integer/list/tuple): The episode numbers..
			show (None/dictionary): The season and episode numbers.
	'''
	def numberShowSet(self, season = None, episode = None, show = None):
		if show:
			self.mData['number'] = show
		else:
			if not tools.Tools.isArray(season): season = [season]
			self.mData['number']['season'] = season
			if not tools.Tools.isArray(episode): episode = [episode]
			self.mData['number']['episode'] = episode

	'''
		FUNCTION:
			Determines the pack type from the number of season and episodes.
		PARAMETERS:
			number (dictionary): The extracted season and episode numbers.
			pack (None/dictionary): The pack count of season and episodes.
		RETURNS:
			The pack type (string).
	'''
	@classmethod
	def numberShowPack(self, number, pack = None):
		seasonCount = len(number['season'])
		episodeCount = len(number['episode'])
		if Stream.NumberPack in number['season'] or seasonCount > 1: return Stream.FilePackShow
		elif Stream.NumberPack in number['episode'] or (seasonCount == 1 and episodeCount == 0): return Stream.FilePackSeason
		elif episodeCount > 1:
			# If the actual count is know (eg: 10), the file name contains episode numbers (eg: Season 5 Episode 1 - 10), and both those values are equal, assume it is a season pack.
			# If the actual count is not known or greater than the number in the file name, assume it is an episode pack.
			if seasonCount == 0 and episodeCount > 0: return Stream.FilePackEpisode
			elif seasonCount > 0:
				if pack and seasonCount == 1:
					count = self._metaPackNumber(pack, 'count', 'season', number['season'][0])
					if count > 0 and count <= episodeCount: return Stream.FilePackSeason
				return Stream.FilePackEpisode
		else: return Stream.FilePackNone

	'''
		FUNCTION:
			Extracts the season and episode numbers from a string.
			Multiple and consecutive season and episode numbers are also extracted.
		PARAMETERS:
			data (string): The file name.
			niche (string/list): Important for Anime/Donghua for special rules.
			show (boolean): Wether or not to extract season-episode numbers combinations (eg: S01E01, S01E01-E02).
			season (boolean): Wether or not to extract season numbers only (eg: S01, S01-S10).
			episode (boolean): Wether or not to extract episode numbers only (eg: E01, E01-E05).
			clean (boolean): Clean the data string before processing.
			exclude (boolean): Wether or not to exclude certain keywords.
			basic (boolean): Wether or not to only extract using basic expressions and ingore advanced fallback options if the expressions did not return anything.
		RETURNS:
			Season and episode numbers (dictionary): {'season' : [1], 'episode' : [2, 3, 4]}.
			If no specific season/episode was found, but there are keywords indicating that it is a collection (containing the entire show), this is returned: {'season' : [-1], 'episode' : []}.
	'''
	@classmethod
	def numberShowExtract(self, data, niche = None, show = True, season = True, episode = True, clean = True, exclude = False, basic = False):
		def _numberShowExtract(data, niche = None, show = True, season = True, episode = True, clean = True, exclude = False, basic = False):
			def __numberShowExtract(type, data, niche = None, show = True, season = True, episode = True, clean = True, exclude = False, basic = False):
				result = {'season' : [], 'episode' : []}
				expression = self._numberShowExpression(type = type, season = None, episode = None, basic = basic)
				if exclude: data = self._expressionReplace(data = data, expression = Stream.ExpressionShow['exclude'])

				# NB: multi = True, which will evaluate all expressions and pick the one that is best, instead of picking the first one.
				# Otherwise one language might have a partial match whereas a later language might be better.
				extract = self._expressionExtract(data = data, expression = expression, multi = True)

				if extract:
					group = Stream.ExpressionShow[type]['group']
					groupSeason = group['season'] if 'season' in group else ()
					groupEpisode = group['episode'] if 'episode' in group else ()

					if not groupSeason is None and groupEpisode is None:
						groupEpisode = tuple(i for i in range(len(extract)) if not i in groupSeason)
					if not groupEpisode is None and groupSeason is None:
						groupSeason = tuple(i for i in range(len(extract)) if not i in groupEpisode)

					if not groupSeason is None:
						for group in groupSeason:
							try: result['season'].append(int(extract[group]))
							except: pass
					if not groupEpisode is None:
						for group in groupEpisode:
							try: result['episode'].append(int(extract[group]))
							except: pass

					# If the gap between episodes is too large, assume it is not a range.
					# Eg: Doctor Who (2005) - Season 1-4 - BluRay 1080P-ShortbreHD Doctor Who (2005) - S03E07 - 42.mkv
					# Otherwise this would detect S03, E07-E42.
					# Do not do this for anime, otherwise season-absolute numbers will not work.
					# Eg: One.Piece.S03E78-92.1999-2011.Mkv.WEBDLMux.1080p.Ita.Jap.Aac.Subs.ProgettoOnePiece
					if len(result['episode']) == 2 and (not niche or not self.metaNicheIs(niche = niche)):
						difference = abs(result['episode'][0] - result['episode'][1])
						if (result['episode'][0] > 1 and difference > 3) or (difference > 100): del result['episode'][-1]

				return result

			result = {'season' : [], 'episode' : []}
			data = self.cleanEncode(data)
			if clean: data = self.cleanBasic(data)
			if not data: return result

			# Some Russian (eg NoNameClub) have backward order.
			# Eg: Игра престолов / Game of Thrones (Сезон 3 полный (10)) (2013) WEB-DLRip (AlexFilm)
			# Eg: Игра престолов / Game of Thrones (2011) HDTVRip (1 сезон, 1-10 серия из 10) (LostFilm)
			types = []

			# Also include show expressions when only searching for the season/episode.
			# This is neccessary for the new "backward" expressions.
			# If not adding show expressions when only looking for the season/episode, can lead to incorrect detection.
			# Eg: Search for season only will detect season 5 instead of 3: Игра престолов / Game of Thrones (2011) HDTVRip (3 сезон, 5 серия) (LostFilm)
			#if show:
			if show or season or episode: types.extend(['show_forward', 'show_backward'])
			if season: types.extend(['season_forward', 'season_backward'])
			if episode: types.extend(['episode_forward', 'episode_backward'])

			for type in types:
				sub = self._cache(__numberShowExtract, type = type, data = data, niche = niche, show = show, season = season, episode = episode, clean = clean, exclude = exclude, basic = basic)
				result['season'].extend(sub['season'])
				result['episode'].extend(sub['episode'])
				if len(sub['season']) > 0: break
				if len(sub['episode']) > 0: break

			result['season'] = self._numberShowProcess(values = result['season'], data = data, niche = niche)
			result['episode'] = self._numberShowProcess(values = result['episode'], data = data, niche = niche)

			if not basic:
				if not result['season'] and not result['episode']:
					for expression in self._filePackExpression(show = True):
						if self._expressionMatch(id = 'numberShowExtract1_' + expression[0], data = data, expression = expression[-1]):
							result['season'] = [Stream.NumberPack]

				if show and not result['season'] and not result['episode']:
					extract = self._expressionExtract(data = data, expression = Stream.ExpressionShow['special'])
					if extract and len(extract) == 2:
						result['season'] = [int(extract[0])]
						result['episode'] = [int(extract[1])]

			return result

		return self._cache(_numberShowExtract, data = data, niche = niche, show = show, season = season, episode = episode, clean = clean, exclude = exclude, basic = basic)

	'''
		FUNCTION:
			Finds the first index of a season or episode number.
		PARAMETERS:
			data (string): The file name.
			exclude (boolean): Wether or not to exclude certain keywords.
			special (boolean): Wether or not to search for special episode formats (eg: 101 for S01E01).
			episode (boolean): Wether or not to search for episode numbers (without a season number).
		RETURNS:
			 The index of the first season or episode number (None/integer).
	'''
	@classmethod
	def numberShowIndex(self, data, exclude = False, special = False, episode = True, prefix = True):
		if exclude: data = self._expressionReplace(data = data, expression = Stream.ExpressionShow['exclude'])
		types = ['show_forward', 'show_backward', 'season_forward', 'season_backward']
		if episode: types.extend(['episode_forward', 'episode_backward'])
		for type in types:
			expression = self._numberShowExpression(type = type, season = None, episode = None, count = 1, prefix = prefix)
			expression = '(' + ('|'.join(expression)) + ')'
			matches = self._cacheId('numberShowIndex_1_' + type, re.compile, expression, flags = Stream.ExpressionFlags).search(data)
			if matches:
				index = matches.start()
				if index >= 0: return index
		if special:
			for type in types:
				matches = self._cacheId('numberShowIndex_2_' + type, re.compile, Stream.ExpressionShow['special'], flags = Stream.ExpressionFlags).search(data)
				if matches:
					index = matches.start()
					if index >= 0: return index
		return None

	'''
		FUNCTION:
			Determines of the file name contains show numbers.
		PARAMETERS:
			data (string): The file name.
			niche (string/list): Important for Anime/Donghua for special rules.
			show (boolean): Wether or not to extract season-episode numbers combinations (eg: S01E01, S01E01-E02).
			season (boolean): Wether or not to extract season numbers only (eg: S01, S01-S10).
			episode (boolean): Wether or not to extract episode numbers only (eg: E01, E01-E05).
			clean (boolean): Clean the data string before processing.
			exclude (boolean): Wether or not to exclude certain keywords.
			basic (boolean): Wether or not to only extract using basic expressions and ingore advanced fallback options if the expressions did not return anything.
			pack (boolean): Wether or not to include entire packs.
		RETURNS:
			 True if it is a show stream. False if it is not.
	'''
	@classmethod
	def numberShowContains(self, data, niche = None, show = True, season = True, episode = True, clean = False, exclude = False, basic = False, language = True, pack = False):
		number = self.numberShowExtract(data = data, niche = niche, show = show, season = season, episode = episode, clean = clean, exclude = exclude, basic = basic)
		if number and len(number['season']) > 0 and (pack or not Stream.NumberPack in number['season']): return True
		return False

	'''
		FUNCTION:
			Validates if a file name contains the correct season and/or episode numbers.
			Multiple and consecutive season and episode numbers are also matched.
			Can be called on an instance (without the value parameter), or on the class (with the value parameter).
		PARAMETERS:
			data (string): The file name.
			real (None/dictionary): Previously detected season and episode numbers.
			season (None/integer): Match a specific season number. None for not matching the season.
			episode (None/integer): Match a specific episode number. None for not matching the episode.
			number (None/dictionary): Match alternative/pack numbers. None for not matching alternative numbers.
			pack (None/dictionary): The show pack details.
			alternative (boolean): Check alternative episode numbers.
			single (boolean): Only match a single episode and packs.
			clean (boolean): Clean the data string before processing.
		RETURNS:
			True if the number is correct. False if the number is incorrect. None if no number is in the file name.
	'''
	@classmethod
	def numberShowValid(self, data = None, niche = None, real = None, season = None, episode = None, number = None, pack = None, filePack = None, alternative = None, single = False, clean = True):
		return self.__numberShowValid(data = data, niche = niche, real = real, season = season, episode = episode, number = number, pack = pack, filePack = filePack, alternative = alternative, single = single, clean = clean)

	def _numberShowValid(self, alternative = None, single = False):
		return self.__numberShowValid(data = self.fileName(), niche = self.metaNiche(), real = self.numberShow(), season = self.metaSeason(), episode = self.metaEpisode(), number = self.metaNumber(), pack = self.metaPack(), filePack = self.filePack(), alternative = alternative, single = single, clean = False)

	@classmethod
	def __numberShowValid(self, data = None, niche = None, real = None, season = None, episode = None, number = None, pack = None, filePack = None, alternative = None, single = False, clean = True):
		if not data and not real: return None
		if data and clean and not real: data = self.cleanBasic(data)
		if not season is None and not episode is None:
			if not real:
				for type in ['show_forward', 'show_backward']:
					expression = self._numberShowExpression(type = type, season = season, episode = episode)
					if self._expressionMatch(id = 'numberShowValid1_' + str(season) + '_' +  str(episode), data = data, expression = expression): return True
				real = self.numberShowExtract(data = data, niche = niche, show = True, season = False, episode = False) # For ranges.
			try: maximum = max(real['season'])
			except: maximum = -1

			# If the filename contains a season greater than the max season of the season. Probably a different show with the same name that has a different season count.
			# Use the "standard" count and not the "official" count, since there can be unreleased seasons on TVDb that are not on Trakt and will therefore not be labeled as official.
			# Or Trakt uses absolute numbering, while TVDb has season numbering (eg: Dragon Ball Super).
			if maximum > 0 and pack and self._metaPackNumber(pack, 'count', 'standard', 'season') < maximum: return None
			elif Stream.NumberPack in real['season'] and not(season == 0 or episode == 0) and not single: return True
			elif season in real['season'] and (episode in real['episode'] or (not real['episode'] and not single)): return True
			elif not real['season'] and season == 1 and episode in real['episode']: return True # If there is not season number, only episode numbers. Eg: Novela Jesus [Capítulo 001 ao 042].
			elif not real['season'] and not real['episode']: return None

		elif not season is None:
			if not real:
				for type in ['season_forward', 'season_backward']:
					expression = self._numberShowExpression(type = type, season = season, episode = None)
					if self._expressionMatch(id = 'numberShowValid2_' + str(season), data = data, expression = expression): return True
				real = self.numberShowExtract(data = data, niche = niche, show = False, season = True, episode = False) # For ranges.
			try: maximum = max(real['season'])
			except: maximum = -1

			# If the filename contains a season greater than the max season of the season. Probably a different show with the same name that has a different season count.
			# Use the "standard" count and not the "official" count, since there can be unreleased seasons on TVDb that are not on Trakt and will therefore not be labeled as official.
			# Or Trakt uses absolute numbering, while TVDb has season numbering (eg: Dragon Ball Super).
			if maximum > 0 and pack and self._metaPackNumber(pack, 'count', 'standard', 'season') < maximum: return None
			elif Stream.NumberPack in real['season']: return True
			elif season in real['season'] and not real['episode']: return True # not real['episode']: Exclude incorrect episode numbers when searching for packs where the episode is set to None. Eg: S01E01 or S01E00 when searching S01 packs for S01E02.
			elif not real['season']: return None

		elif not episode is None:
			if not real:
				for type in ['episode_forward', 'episode_backward']:
					expression = self._numberShowExpression(type = type, season = None, episode = episode)
					if self._expressionMatch(id = 'numberShowValid3_' + str(episode), data = data, expression = expression): return True
				real = self.numberShowExtract(data = data, niche = niche, show = False, season = False, episode = True) # For ranges.
			if Stream.NumberPack in real['season'] and not single: return True
			elif episode in real['episode']: return True
			elif not real['episode']: return None

		else:
			if not real:
				for type in ['show_forward', 'show_backward']:
					expression = self._numberShowExpression(type = type, season = season, episode = episode)
					if self._expressionMatch(id = 'numberShowValid4', data = data, expression = expression): return True
				real = self.numberShowExtract(data = data, niche = niche, show = True, season = False, episode = False) # For ranges.
			if Stream.NumberPack in real['season']: return True

		if ((alternative is True) or (alternative is None and self.metaNicheIs(niche = niche))) and number:
			# Try alternative season numbers, such as the season-absolute numbers used by Trakt.
			# Eg: One Piece S03E01 (standard) vs S03E78 (Trakt)
			# Do not use the TVDb numbers, since they can be far off and result in too many false-positives.
			# Eg: One Piece S06E09
			seasoned = number.get('season')
			if seasoned:
				for i in seasoned:
					if not(i[0] == season and i[1] == episode):
						if self.__numberShowValid(data = data, niche = niche, real = real, season = i[0], episode = i[1], number = number, pack = pack, filePack = filePack, single = single, alternative = False, clean = False): return True

			# Only accept sequential/absolute numbers for individual episodes, but not S01 season packs.
			# S01 packs are essentially always a normal season pack, not an absolute season pack that contains all episodes for the show.
			if not filePack:
				sequential = number.get('sequential')
				if sequential:
					if self.__numberShowValid(data = data, niche = niche, real = real, season = sequential[0], episode = sequential[1], number = number, pack = pack, filePack = filePack, single = single, alternative = False, clean = False): return True

		return False

	'''
		FUNCTION:
			Cleans a file name from season and episode keywords.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			split (None/string): If SplitRight/SplitLeft, cuts off the string after/before the first found keyword. If None, simply remove the keyword and keep the rest of the string intact.
		RETURNS:
			The cleaned file name (string).
	'''
	@classmethod
	def numberShowClean(self, data, exclude = None, encode = True, split = SplitNone):
		if not data: return data
		if encode: exclude = self.cleanEncode(exclude)
		expression = {'keyword' : {}, 'expression' : [(i, '(' + i[1]['full'] + ')') for i in Stream.ExpressionShow['language']]}
		count = self._expressionCount(expression)
		expression = self._expressionFormatKeyword(id = 'numberShowClean', expression = expression, exclude = exclude)
		return self._expressionReplace(id = 'numberShowClean_' + self._cacheIdMinimize(exclude), data = data, expression = expression, exclude = exclude, count = count, split = split)

	@classmethod
	def _numberShowExpression(self, type, season = None, episode = None, count = None, prefix = True, basic = False):
		def __numberShowExpression(type, season = None, episode = None, count = None, prefix = True, basic = False):
			result = []

			# NB: Add (?!\d) to fixed numbers. Otherwise 12x3 will match possibility for S2 or S2E3.
			if season is None: season = Stream.ExpressionShow['number']
			elif tools.Tools.isArray(season): season = ('(?:%s)' % '|'.join(season)) + Stream.ExpressionNumberSucceed
			else: season = str(season) + Stream.ExpressionNumberSucceed
			if episode is None: episode = Stream.ExpressionShow['number']
			elif tools.Tools.isArray(episode): episode = ('(?:%s)' % '|'.join(episode)) + Stream.ExpressionNumberSucceed
			else: episode = str(episode) + Stream.ExpressionNumberSucceed

			disc = Stream.ExpressionShow['disc']
			prefix = Stream.ExpressionShow['prefix'] if prefix else ''
			divider = Stream.ExpressionShow['divider']
			ordinal = Stream.ExpressionShow['ordinal']
			unordinal = Stream.ExpressionShow['unordinal']
			nonalphabet = Stream.ExpressionShow['nonalphabet']
			description = Stream.ExpressionShow['description']
			duration = Stream.ExpressionShow['duration']
			custom = Stream.ExpressionShow['custom']
			if count is None: count = Stream.ExpressionShow['groups']

			if type == 'show': type = ['show_forward', 'show_backward']
			elif type == 'season': type = ['season_forward', 'season_backward']
			elif type == 'episode': type = ['episode_forward', 'episode_backward']
			elif not tools.Tools.isArray(type): type = [type]

			languages = [Stream.ExpressionShow['language'][0]] if basic else Stream.ExpressionShow['language']

			for t in type:
				main = Stream.ExpressionShow[t]['main']
				repeat = Stream.ExpressionShow[t]['repeat']
				for language in languages:
					keyword = {
						'range' : language[1]['range'],
						'conjunction' : language[1]['conjunction'],
						'season_label' : language[1]['season'],
						'episode_label' : language[1]['episode'],
						'season_number' : season,
						'episode_number' : episode,
						'ordinal' : ordinal % language[1]['ordinal'],
						'unordinal' : unordinal % language[1]['ordinal'],
						'disc' : disc,
						'prefix' : prefix,
						'divider' : divider,
						'nonalphabet' : nonalphabet,
						'description' : description,
						'duration' : duration,
						'custom' : custom,
					}
					mainPart = self._expressionFormatCommon(expression = main, keyword = keyword)
					repeatPart = self._expressionFormatCommon(expression = repeat, keyword = keyword) * count
					result.append(mainPart + repeatPart)

			return result
		return self._cache(__numberShowExpression, type = type, season = season, episode = episode, count = count, prefix = prefix, basic = basic)

	@classmethod
	def _numberShowProcess(self, values, data, niche = None):
		# Remove invalid values.
		values = [i for i in values if not i is None]

		# Exclude non-consecutive numbers that are not separated by a word, comma, hyphen, etc.
		# Eg: Season 4 5.1 AC3
		# Eg: Season 3 64 Episodes
		# Still allow:
		# Eg: The Office (Seasons 1 4) COMPLETE
		# Eg: The Office Season 1 9
		# Eg: The Office Seasons 1 9 COMPLETE XviD IPT
		# Eg: The Office Complete Season 1 9 [F4S7]
		if len(values) > 0:
			consecutive = True
			for i in range(1, len(values)):
				difference = abs(values[i] - values[i - 1])
				if difference > 1:
					consecutive = False
					break
			if not consecutive:
				limit = 150
				if self.metaNicheIs(niche = niche): limit = 3000 # Eg: One Piece Collection 1-648 + 4 Movies

				for i in range(1, len(values)):
					if abs(values[i] - values[i - 1]) > limit: # Exclude excessive ranges.
						values = values[:i - 1]
						break
					if bool(re.search('%d[\s\.\(\[\{]%d' % (values[i - 1], values[i]), data, flags = Stream.ExpressionFlags)):
						if not bool(re.search('%d[\s\.\-]%d[\s\.\-]*(?:$|complet|[\)\]\}\(\[\{])' % (values[i - 1], values[i]), data, flags = Stream.ExpressionFlags)):
							values = values[:i]
							break

		# Remove duplicates.
		# Only do this after the consecutive check to first trim duplicate ranges (eg: Season 1-7 1 2 3 4 5 6 7).
		values = list(set(values))

		# Sort.
		values.sort()

		# Fill in ranges.
		if len(values) > 0 and values[-1] > values[0]:
			values = [i for i in range(values[0], values[-1] + 1)]

		return values

	##############################################################################
	# NUMBER SPECIAL
	##############################################################################

	'''
		FUNCTION:
			Validates if a file name contains the correct season and/or episode numbers or the episode title.
			The problem with special episodes:
				1. The order from TVDb is not always the same as the file names. Eg: TVDb says S00E10, but the file name has S00E11 (but contains the correct video).
				2. TVDb has all special episodes under S00, but some sites list them as SxxE00. Eg: TVDb says S00E10, but the file name has S05E00.
				3. Some special episodes only have the episode title, but not the season/episode number.
				Eg:
					[TVDb] Game of Thrones S00E51 The Last Watch
					[File Name] Game.of.Thrones.S00E41.The.Last.Watch.AMZN.WEB-DL.AAC2.0.H.264-NTG-BUYMORE
					[File Name] game.of.thrones.s08e00.the.last.watch.web.h264-memento-BUYMORE
			Try the season/episode number first, and then try the episode title.
			Multiple and consecutive season and episode numbers are also matched.
			Can be called on an instance (without the value parameter), or on the class (with the value parameter).
		PARAMETERS:
			data (string): The file name.
			real (None/dictionary): Previously detected season and episode numbers.
			season (None/integer): Match a specific season number. None for not matching the season.
			episode (None/integer): Match a specific episode number. None for not matching the episode.
			number (None/dictionary): Match alternative/pack numbers. None for not matching alternative numbers.
			pack (None/dictionary): The show pack details.
			alternative (boolean): Check alternative episode numbers.
			clean (boolean): Clean the data string before processing.
		RETURNS:
			True if the number is correct. False if the number is incorrect. None if no number is in the file name.
	'''
	@classmethod
	def numberSpecialValid(self, data, title, niche = None, real = None, season = None, episode = None, number = None, pack = None, filePack = None, alternative = None, clean = True):
		return self.__numberSpecialValid(data = data, title = title, niche = niche, real = real, season = season, episode = episode, number = number, pack = pack, filePack = filePack, alternative = alternative, clean = clean)

	def _numberSpecialValid(self, alternative = None):
		return self.__numberSpecialValid(data = self.fileName(), title = self.metaTitle(title = Stream.TitleEpisode), niche = self.metaNiche(), real = self.numberShow(), season = self.metaSeason(), episode = self.metaEpisode(), number = self.metaNumber(), pack = self.metaPack(), filePack = self.filePack(), alternative = alternative, clean = False)

	@classmethod
	def __numberSpecialValid(self, data, title, niche, real, season, episode, number = None, pack = None, filePack = None, alternative = None, none = True, clean = True):
		if not real:
			if clean: data = self.cleanBasic(data)
			if not season is None and not episode is None:
				real = self.numberShowExtract(data = data, niche = niche, show = True, season = True, episode = True) # Test all (not just full show number) for searchValidate() in web.py.
			elif not season is None:
				real = self.numberShowExtract(data = data, niche = niche, show = False, season = True, episode = False)
			elif not episode is None:
				real = self.numberShowExtract(data = data, niche = niche, show = False, season = False, episode = True)
			else:
				real = self.numberShowExtract(data = data, niche = niche, show = False, season = False, episode = False)

		# First try the season/episode number.
		if self.__numberShowValid(data = data, niche = niche, real = real, season = season, episode = episode, number = number, pack = pack, filePack = filePack, alternative = alternative, clean = clean): return True

		# Then try the episode title.
		if title and season == 0 and (0 in real['season'] or 0 in real['episode'] or not real['season'] or not real['episode']):
			# Only do a quick title match, since the main title is in there and the title is cut off after the number, which leads to an invalid match. Eg: "<show title> <number> <episode title>".
			if self.__titleValidQuick(data = data, title = title, none = none, full = True): return True

		# Allow for filenames that have some extra episodes from another season.
		# Eg: The Office (UK) only has 2 seasons, but on IMDb they list 3 seasons, where the final season only contains 2 special episodes (which are part of the Specials season on Trakt/TVDb).
		# Eg: The Office UK S01-S03 (2001-) + David Brent
		if real and pack:
			seasons = real.get('season', [])
			if seasons and seasons[0] == 1:
				if self._metaPackNumber(pack, 'count', 'total', 'special') > 0:
					total = self._metaPackNumber(pack, 'count', 'total', 'season')
					if len(seasons) == total and seasons[-1] == total: return True

		return False

	##############################################################################
	# NUMBER SEASON
	##############################################################################

	'''
		FUNCTION:
			Retrieves the season numbers.
		RETURNS:
			Season numbers (list): [2, 3, 4].
	'''
	def numberSeason(self):
		return self.mData['number']['season']

	'''
		FUNCTION:
			Sets the season numbers.
		PARAMETERS:
			season (integer/list/tuple): The season numbers.
	'''
	def numberSeasonSet(self, season):
		if not tools.Tools.isArray(season): season = [season]
		self.mData['number']['season'] = season

	'''
		FUNCTION:
			Extracts the season numbers from a string.
			Multiple and consecutive season numbers are also extracted.
		PARAMETERS:
			data (string): The file name.
			niche (string/list): Important for Anime/Donghua for special rules.
			show (boolean): Extract season-episode numbers combinations (eg: S01E01, S01E01-E02) instead of only standalone season numbers.
			clean (boolean): Clean the data string before processing.
		RETURNS:
			Season numbers (list): [2, 3, 4].
	'''
	@classmethod
	def numberSeasonExtract(self, data, niche = None, show = False, clean = True):
		return self.numberShowExtract(data = data, niche = niche, show = show, season = True, episode = False, clean = clean)['season']

	'''
		FUNCTION:
			Validates if a file name contains the correct season numbers.
			Multiple and consecutive season numbers are also matched.
			Can be called on an instance (without the value parameter), or on the class (with the value parameter).
		PARAMETERS:
			data (string): The file name.
			season (integer): Match a specific season number.
			number (None/dictionary): Match alternative/pack numbers.
			pack (None/dictionary): The show pack details.
			alternative (boolean): Check alternative episode numbers.
			clean (boolean): Clean the data string before processing.
		RETURNS:
			 True if the number is correct. False if the number is incorrect. None if no number is in the file name.
	'''
	@classmethod
	def numberSeasonValid(self, data, season, number = None, pack = None, filePack = None, niche = None, alternative = None, clean = True):
		return self.__numberSeasonValid(data = data, season = season, number = number, pack = pack, filePack = filePack, niche = niche, alternative = alternative, clean = clean)

	def _numberSeasonValid(self, season, alternative = None):
		return self.__numberSeasonValid(data = self.fileName(), season = season, number = self.metaNumber(), pack = self.metaPack(), filePack = self.filePack(), niche = self.metaNiche(), alternative = alternative, clean = False)

	@classmethod
	def __numberSeasonValid(self, data, season, number = None, pack = None, filePack = None, niche = None, alternative = None, clean = True):
		return self.__numberShowValid(data = data, season = season, number = number, pack = pack, filePack = filePack, niche = niche, alternative = alternative, clean = clean)

	##############################################################################
	# NUMBER EPISODE
	##############################################################################

	'''
		FUNCTION:
			Retrieves the episode numbers.
		RETURNS:
			Episode numbers (list): [2, 3, 4].
	'''
	def numberEpisode(self):
		return self.mData['number']['episode']

	'''
		FUNCTION:
			Sets the episode numbers.
		PARAMETERS:
			episode (integer/list/tuple): The episode numbers.
	'''
	def numberEpisodeSet(self, episode):
		if not tools.Tools.isArray(episode): episode = [episode]
		self.mData['number']['episode'] = episode

	'''
		FUNCTION:
			Extracts the episode numbers from a string.
			Multiple and consecutive episode numbers are also extracted.
		PARAMETERS:
			data (string): The file name.
			niche (string/list): Important for Anime/Donghua for special rules.
			show (boolean): Extract season-episode numbers combinations (eg: S01E01, S01E01-E02) instead of only standalone episode numbers.
			clean (boolean): Clean the data string before processing.
		RETURNS:
			Season numbers (list): [2, 3, 4].
	'''
	@classmethod
	def numberEpisodeExtract(self, data, niche = None, show = False, clean = True):
		return self.numberShowExtract(data = data, niche = niche, show = show, season = False, episode = True, clean = clean)['episode']

	'''
		FUNCTION:
			Validates if a file name contains the correct season numbers.
			Multiple and consecutive season numbers are also matched.
			Can be called on an instance (without the value parameter), or on the class (with the value parameter).
		PARAMETERS:
			data (string): The file name.
			episode (integer): Match a specific episode number.
			number (None/dictionary): Match alternative/pack numbers.
			pack (None/dictionary): The show pack details.
			alternative (boolean): Check alternative episode numbers.
			clean (boolean): Clean the data string before processing.
		RETURNS:
			 True if the number is correct. False if the number is incorrect. None if no number is in the file name.
	'''
	@classmethod
	def numberEpisodeValid(self, data, episode, number = None, pack = None, filePack = None, niche = None, alternative = None, clean = True):
		return self.__numberEpisodeValid(data = data, episode = episode, number = number, pack = pack, filePack = filePack, niche = niche, alternative = alternative, clean = clean)

	def _numberEpisodeValid(self, episode, alternative = None):
		return self.__numberEpisodeValid(data = self.fileName(), episode = episode, number = self.metaNumber(), pack = self.metaPack(), filePack = self.filePack(), niche = self.metaNiche(), alternative = alternative, clean = False)

	@classmethod
	def __numberEpisodeValid(self, data, episode, number = None, pack = None, filePack = None, niche = None, alternative = None, clean = True):
		return self.__numberShowValid(data = data, episode = episode, number = number, pack = pack, filePack = filePack, niche = niche, alternative = alternative, clean = clean)

	##############################################################################
	# LANGUAGE
	##############################################################################

	'''
		FUNCTION:
			Retrieves the audio and subtitle languages.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
			universal (boolean): Whether or not to include the universal language.
			sort (boolean): Whether or not to sort the languages according to the user's preferences.
		RETURNS:
			The languages (list).
	'''
	def language(self, format = FormatNone, label = LabelNone, default = None, universal = False, sort = False):
		value = []
		audio = self.mData['audio']['language']
		if audio: value += audio
		subtitle = self.mData['subtitle']['language']
		if subtitle: value += subtitle
		if not value: return default

		if not universal: value = [i for i in value if not i == tools.Language.UniversalCode]
		value = tools.Tools.listUnique(value)

		multiple = label == Stream.LabelSettings
		label = self.settingsLayout(label, 'audio', 'language')
		if sort: value = self.languageSort(value = value, default = self.metaLanguage(single = True), label = True, copy = True)
		return self.languageConvert(value = value, format = format, label = label, multiple = multiple, default = self.audioDefault())

	@classmethod
	def languageSort(self, value, default = None, label = False, copy = False):
		def _languageSort(value, default = None, label = False):
			try:
				if value is None: return value

				value = [tools.Language.language(i) for i in value]

				# First sort by frequency and then alphabetically by name.
				value = sorted(value, key = lambda i : (-i[tools.Language.Frequency], i[tools.Language.Name][tools.Language.NameEnglish]))
				value = [i[tools.Language.Code][tools.Language.CodePrimary] for i in value]

				# Place all languages from that country before English.
				# For instance, and Indian movie might be released in Tamil, but a Hindi version is also released.
				# In this case, Hindi should be placed before English.
				# Eg: Rocketry - The Nambi Effect (2022)
				if default:
					languages = []
					country = tools.Language.country(default)
					if country:
						languages = tools.Language.languages(universal = False, country = country)
						if languages:
							languages = sorted(languages, key = lambda i : -i[tools.Language.Frequency])
							languages = [i[tools.Language.Code][tools.Language.CodePrimary] for i in languages]
							default = [default] + languages
				else:
					default = []

				preferences = default
				if label:
					# Sort for showing in the interface.
					# Place original language first, followed by the user's preferences, and then English.
					preferences += tools.Language.settingsCode() + [tools.Language.EnglishCode]
				else:
					# Sort for internal use (eg: submitted to Orion).
					# Place the original language and English first.
					preferences += [tools.Language.EnglishCode]

				preferences = [i for i in preferences if i and i in value]
				value = tools.Tools.listUnique(preferences + value)
			except: tools.Logger.error()
			return value

		result = self._cache(_languageSort, value = value, default = default, label = label)

		# NB: Copy the value in some cases, otherwise if the returned list is edited, the cached version (which might be used later) is also changed.
		# This can cause default languages (with a semi-transparent flag) to not show in the stream window right after a new scrape (not the case if the window is reloaded).
		if copy: result = tools.Tools.copy(result)

		return result

	@classmethod
	def languageConvert(self, value, format = FormatNone, label = LabelNone, multiple = False, default = None):
		if value is None or (format == Stream.FormatNone and label == Stream.LabelNone): return value

		value = [tools.Language.language(i) for i in value]

		if multiple:
			if Stream.SettingsLanguage is None:
				Stream.SettingsLanguage = tools.Settings.getInteger('label.stream.language.limit') if tools.Settings.getBoolean('label.stream.language') else 0
			if Stream.SettingsLanguage > 1 and len(value) >= Stream.SettingsLanguage:
				return interface.Translation.string(35035)

		if format == Stream.FormatKodi:
			value = [i[tools.Language.Code][tools.Language.CodeSecondary] for i in value]
		else:
			def _languageColor(value, color):
				if color: return interface.Format.fontColor(value, color = interface.Format.colorDisabled())
				else: return value

			if default: defaults = [i[tools.Language.Code][tools.Language.CodePrimary] in default for i in value]
			else: defaults = [False] * len(value)

			if label == Stream.LabelShort: value = '-'.join([_languageColor(value[i][tools.Language.Code][tools.Language.CodePrimary].upper(), defaults[i]) for i in range(len(value))])
			elif label == Stream.LabelMedium: value = '-'.join([_languageColor(value[i][tools.Language.Code][tools.Language.CodeSecondary].upper(), defaults[i]) for i in range(len(value))])
			elif label == Stream.LabelLong: value = ', '.join([_languageColor(value[i][tools.Language.Name][tools.Language.NameEnglish], defaults[i]) for i in range(len(value))])
			elif label == Stream.LabelDetails: value = ', '.join([value[i][tools.Language.Name][tools.Language.NameEnglish] for i in range(len(value))])

		return value

	@classmethod
	def languageLabels(self):
		def _languageLabels():
			result = tools.Tools.copy(Stream.LabelLanguage)
			languages = tools.Language.languages(universal = False)
			for language in languages:
				result[language[tools.Language.Code][tools.Language.CodePrimary]] = {Stream.LabelShort : language[tools.Language.Code][tools.Language.CodePrimary].upper(), Stream.LabelMedium : language[tools.Language.Code][tools.Language.CodeSecondary].upper(), Stream.LabelLong : language[tools.Language.Name][tools.Language.NameEnglish] }
			return result
		return self._cache(_languageLabels)

	@classmethod
	def languageOrders(self):
		def _languageOrders():
			result = {}
			languages = tools.Language.languages(universal = False)

			sorting = sorted(languages, key = lambda i : i[tools.Language.Frequency], reverse = True)
			sorting = [language[tools.Language.Code][tools.Language.CodePrimary] for language in sorting]
			sorting.remove(tools.Language.EnglishCode)
			sorting.insert(0, tools.Language.EnglishCode)

			alphabetic = sorted(languages, key = lambda i : i[tools.Language.Code][tools.Language.CodePrimary])
			alphabetic = [language[tools.Language.Code][tools.Language.CodePrimary] for language in alphabetic]

			languages = {language[tools.Language.Code][tools.Language.CodePrimary] : language for language in languages}
			for i in range(len(alphabetic)):
				code = languages[alphabetic[i]][tools.Language.Code][tools.Language.CodePrimary]
				result[code] = { Stream.OrderInterface : i + 1, Stream.OrderSorting : sorting.index(code) + 1 }

			return result
		return self._cache(_languageOrders)

	'''
		FUNCTION:
			Extracts the audio and subtitle languages from a string.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			clean (boolean): Wether or not to clean the data before processing.
			default (sNone/tring): The code of the original language of the title, that is, the default language to use if no specific language is detected.
			native (None/list): The languages of the provider or source used to detect additional language name translations.
		RETURNS:
			The languages (dictionary): {'audio' : ['lang1', 'lang2'], 'subtitle' : ['lang1', 'lang2']}.
	'''
	@classmethod
	def languageExtract(self, data, exclude = None, encode = True, clean = True, default = None, native = None):
		def _languageExtract(data, exclude, clean, encode, default):
			result = {'audio' : [], 'subtitle' : [], 'default' : []}

			try:
				def find(list, value, start = None, end = None):
					try: return list.index(value, 0 if start is None else start, len(list) if end is None else end)
					except: return -1

				if not data: return result

				if clean: data = self.cleanBasic(data)
				dataOriginal = data
				dataLower = data.lower()

				languagesCommon = self._languageKeyword(common = True, native = native)
				languagesUncommon = self._languageKeyword(common = False, native = native)
				languages = languagesCommon + languagesUncommon
				languagesExpression = [(i['code'], i['expression']) for i in languages]

				# Remove cut-off words.
				# If it is at the end of the file name, starts with an uppercase and ends with lowercase.
				# Eg: Game of Thrones (2011) Complete (1080p BluRay x265 HEVC 10bit Tr
				# This probably was "TrueHD"
				data = self._cacheId('languageExtract1', re.compile, lambda : self._expressionFormatCommon('{separator}([A-Z][a-z])$')).sub('', data)

				# Replace domain names.
				# Eg: Mulan [720p][Subtitulado][wWw.EliteTorrent.SE]
				# Eg: Mulan [DVD_BR][Latino][wWw.EliteTorrent.NL])
				# Eg: Avatar 2009 PROPER TS XviD Subtitulado www loco com ar
				# Eg: Avatar (2009) PROPER TS XviD-MAXSPEED www torentz 3xforum ro
				data = self._cacheId('languageExtract2', re.compile, 'w{3}[\s\.](?:[a-z\d]{3,}[\s\.]){1,2}[a-z]{2,3}', flags = Stream.ExpressionFlags).sub('', data)

				# Removing leading domain names without www.
				# Eg: [ Torrent9.cz ] Avatar (2009) x264 1080p VFF DTS [email protected] - VFHD.mkv
				# Eg: [aletorrenty pl] AVATAR_3D 2009 1080p H-SBS BDRip 48FPS-Sonda [AT-TEAM]
				data = self._cacheId('languageExtract3', re.compile, lambda : self._expressionFormatCommon('^{brackets_start}{separator}*(?!lektor|napisy)[a-z\d]{{4,}}[\.\s][a-z]{{2,3}}{separator}*{brackets_end}'), flags = Stream.ExpressionFlags).sub('', data)
				data = self._cacheId('languageExtract4', re.compile, lambda : self._expressionFormatCommon('{brackets_start}{separator}*(?!lektor|napisy)[a-z\d]{{4,}}[\.\s][a-z]{{2,3}}{separator}*{brackets_end}$'), flags = Stream.ExpressionFlags).sub('', data)

				# Ignore the Spanish word "el", sinec it will be detected as Greek.
				# Eg: Avatar (2009) V.Extendida 4K UHDRip 2160p El_Ranero
				data = self._cacheId('languageExtract5', re.compile, lambda : self._expressionFormatCommon('{separator}(el)(\'|[\-\–\_\.][a-z]+$)'), flags = Stream.ExpressionFlags).sub(r' \2', data)

				# Remove upload names.
				# Eg: AVATAR 2009 DVD9 Rip By Antony_GR
				# Eg: Avatar Extended 2009 by ErikB.NL
				# Eg: Avatar Extended (2009) BRRip Avi by MaximE NL
				# Eg: Nineteen Eighty-Four (1984), by George Orwell
				data = self._cacheId('languageExtract6', re.compile, lambda : self._expressionFormatCommon('{separator}by{separator}[a-z\d]{{2,}}{separator}(?<![a-z\d])[a-z]{{2,3}}(?![a-z\d])'), flags = Stream.ExpressionFlags).sub('', data)

				# Replace multiples, sometimes found in Russian titles.
				# Eg: Game.of.Thrones.S01.1080p.BDRemux.3xRus.Ukr.2xEng.HDCLUB
				# Ignore multiple subtitles.
				# Eg: The Terminator.Extended Edition.1984.DVDRip-AVC.8xRus.Eng.5xSubs.mkv
				data = self._cacheId('languageExtract7', re.compile, '\d+x(sub)', flags = Stream.ExpressionFlags).sub(r' separator \1', data)
				data = self._cacheId('languageExtract8', re.compile, '\d+x([a-z])', flags = Stream.ExpressionFlags).sub(r'\1', data)

				# Add a space between channels and language/codec.
				# Eg: The Terminator 1 REMASTERED (1984) [BD RIP/1080p/5.1Eng/5.1Fre/Eng,Fre subs]
				# Exclude numbering.
				# Eg: "ONE PIECE S03 4TH VOYAGE" -> "ONE PIECE S03 4 TH VOYAGE" -> Thai (th)
				data = self._cacheId('languageExtract9', re.compile, '(\d' + Stream.ExpressionSymbol + '\d)([a-z0-9]{2,})(?<!st|nd|rd|th)', flags = Stream.ExpressionFlags).sub(r'\1 \2', data)

				# Add a space between language/codec and channels.
				# Eg: 터미네이터1.The.Terminator.1984.1080p.BR..DTS.Kor5.1.Eng-joon.mkv
				data = self._cacheId('languageExtract10', re.compile, '([a-z0-9]{2,})(\d' + Stream.ExpressionSymbol + '\d)', flags = Stream.ExpressionFlags).sub(r'\1 \2', data)

				# Split combined keywords.
				# Eg: The Terminator (1984) BGAUDIO.BGSUB.DVD5-KING OF STORM
				# Eg: Taken.2008.1080p.RoHardSubbed-DjLucifer
				data = self._cacheId('languageExtract11', re.compile, '([a-z]{2,3})(audio|dual|dub|hard|soft)([a-z]*%s)' % Stream.ExpressionSymbolEnd, flags = Stream.ExpressionFlags).sub(r'\1 \2 \3', data)

				# Split combined keywords.
				# Eg: The Terminator.Extended Edition.1984.DUALRUS.DVDRip.XviD.AC3
				data = self._cacheId('languageExtract12', re.compile, '(audio|dual)([a-z]{2,3})', flags = Stream.ExpressionFlags).sub(r'\1 \2', data)

				# Split combined languages.
				# Eg: The Terminator (1984) BDRemux 1080p [Remastered] 4xUkrEng Sub UkrEng [Hurtom].mkv
				# NB: Do not split if it is at the end of the file name, since those are mostly release groups.
				# Eg (JoyBel -> Joy Bel -> Belarusian): The Big Bang Theory Season 1 S01 Complete 1080p x265 HEVC JoyBel
				data = self._cacheId('languageExtract13', re.compile, '(?![Bb][Ll][Uu][Rr][Aa][Yy])([A-Z][a-z]{2})(?![Ss][Uu][Bb])([A-Z][a-z]{2})' + Stream.ExpressionSymbol, flags = re.UNICODE).sub(r'\1 \2 ', data)

				# Exclude "Na'Vi", fictional language/people in Avatar.
				# Eg: Avatar (w/Hardcoded Na'vi English Subs) [HDRip.4.iPod] -- VoV
				data = self._cacheId('languageExtract14', re.compile, Stream.ExpressionSeparator + 'na' + Stream.ExpressionSymbol + 'vi' + Stream.ExpressionSeparator, flags = Stream.ExpressionFlags).sub(' navi ', data)

				# Remove the titles from the file name, in order to reduce false detection if a language appears in the title.
				# Eg: The English Patient
				# Eg: Juego de Tronos
				if exclude:
					if encode: exclude = self.cleanEncode(exclude)
					if not tools.Tools.isArray(exclude): exclude = [exclude]

					titleReplace = 'GAIATITLEREPLACEGAIA'
					titleAny = 'GAIATITLEANYGAIA'

					# Replace "and" and "&".
					# Eg: Movie is called "Peter Pan & Wendy", but file names mostly use "Peter Pan and Wendy".
					temp = []
					for ex in exclude:
						if ' and ' in ex.lower():
							temp.append(ex.replace(' and ', ' & ').replace(' And ', ' & ').replace(' AND ', ' & '))
						if ' & ' in ex:
							# The & is often replaced with another character (eg: i, a, E, etc).
							# Match any single character.
							temp.append(ex.replace(' & ', ' and '))
							temp.append(ex.replace(' & ', ' %s ' % titleAny))
					if temp:
						# NB: Do not extend the passed-by-reference list here.
						# Otherwise scrape can get stuck in _releaseTypeExclude(), since the list has changed.
						#exclude.extend(temp)
						exclude = tools.Tools.listUnique(exclude + temp)

					for ex in exclude:
						if len(ex) >= 4 and ex.count('.') < 2: # Exclude acronyms. Eg "The Creator" has an alias "A.I.".
							ex = self._cacheId('languageExtract15', re.compile, Stream.ExpressionSymbol + '+', flags = Stream.ExpressionFlags).sub(titleReplace, ex)
							ex = ex.replace(titleReplace, '\s*.?\s*') # Allow additional spaces instead of a single character. Eg: "Operation Fortune: Ruse de guerre"
							ex = ex.replace(titleAny, '.') # Allow additional spaces instead of a single character. Eg: "Operation Fortune: Ruse de guerre"
							data = self._cacheIdInternal('languageExtract16' + ex, re.compile, '(%s)' % ex, flags = Stream.ExpressionFlags).sub('', data)

				# Replace separators.
				# Eg: [DVDRIP][Eng][Spa Subs]
				data = self._cacheId('languageExtract17', re.compile, Stream.ExpressionSubtitleSeparator, flags = Stream.ExpressionFlags).sub(' separator ', data)

				# Replace slash separators for subtitles with fixed subtitle keyword.
				# Eg: Taken 2008 DVDr [eng/spanish] [swe/dan sub]
				# Eg: "swe/dan sub" -> "swesub dan sub"
				match = self._cacheId('languageExtract18', re.compile, lambda : self._expressionFormatCommon('((?:[a-z]{{2,3}}{separator}?\/{separator}?)+[a-z]{{2,3}}){separator}+' + Stream.ExpressionSubtitle), flags = Stream.ExpressionFlags).search(data)
				if match: data = data.replace(match.group(1), match.group(1).replace('/', 'sub '))

				# Replace slash separators.
				# Eg: The Terminator 1 REMASTERED (1984) [BD RIP/1080p/5.1Eng/5.1Fre/Eng,Fre subs]
				# Eg: Alfred Hitchcock - The wrong man [1956] [ENG/FRA/ESP Subtitles]
				match = self._cacheId('languageExtract19', re.compile, '\/.*?[^a-z\/].*?', flags = Stream.ExpressionFlags).search(data)
				if match: data = self._cacheId('languageExtract20', re.compile, '\/', flags = Stream.ExpressionFlags).sub(' separator ', data)

				# Replace alternative separators.
				# Eg: [P] The Terminator (1984) 1080p x264 (DD5 1) NL Subs (P2H)
				# Eg: Terminator Quadrilogy - BluRay 1080p x264 Rip ENG - French Dutch Engels Subs
				if dataOriginal.count(' ') > 3 or dataOriginal.count('.') > 3 or dataOriginal.count('-') > 3: data = self._cacheId('languageExtract21', re.compile, '[\(\)\[\]\{\}]', flags = Stream.ExpressionFlags).sub(' separator ', data)

				# Replace audio and subtitle pairs.
				# Eg: [aletorrenty pl] AVATAR_3D (2009) [60FPS 1080p H-OU DTS-HD MA 5.1 AC3 BluRay x264-Sonda] [Lektor i Napisy PL] [AT-TEAM]
				data = self._cacheId('languageExtract22', re.compile, '(?:' + Stream.ExpressionAudio +'|lektor)' + Stream.ExpressionSeparator + '(?:and|with|i|\+)' + Stream.ExpressionSeparator + self._expressionFormatCommon(Stream.ExpressionSubtitle) + Stream.ExpressionSeparator + '([a-z]{2,})', flags = Stream.ExpressionFlags).sub(r' audio \1 subtitle \1', data)

				# Replace any strings that can cause conflict with language keywords.
				# Eg: Game Of Thrones S01 Complete 1080p MultiSubs-DunHD No Rars!
				# "No Rars" is detected as Norwegian.
				data = self._cacheId('languageExtract23', re.compile, lambda : self._expressionFormatCommon(Stream.ExpressionSubtitleExclude), flags = Stream.ExpressionFlags).sub('', data)

				# Replace cutoff multi subtitles.
				data = self._cacheId('languageExtract24', re.compile, lambda : self._expressionFormatCommon(Stream.ExpressionSubtitleCutoffMulti), flags = Stream.ExpressionFlags).sub('multisubs', data)

				# Ignore cutoff subtitle keywords.
				# Eg: Game Of Thrones Season 1 Complete 1080p BluRay 7GB English Subti..
				# "Subti" will incorrectly be detected as Vietnamese (Tiếng Việt) subtitles.
				match = self._cacheId('languageExtract25', re.compile, lambda : self._expressionFormatCommon(Stream.ExpressionSubtitleCutoff), flags = Stream.ExpressionFlags).search(data)
				if match: data = data.replace(match.group(1), 'subtitle')

				# Remove trailing cutoffs with ..., where the cut word might be detected as a language.
				# Eg: Game.of.Thrones.Seasons.1-6.S01-S06.Complete.720p.BluRay.x265.HE..
				data = self._cacheId('languageExtract26', re.compile, lambda : self._expressionFormatCommon(Stream.ExpressionSubtitleTrailing), flags = Stream.ExpressionFlags).sub('', data)

				# Replace separated single-letter subs (eg e-subs -> esubs)
				match = self._cacheId('languageExtract27', re.compile, lambda : '(' + self._expressionFormatCommon(Stream.ExpressionSubtitleSingle) + ')', flags = Stream.ExpressionFlags).search(data)
				if match:
					# Ignore single characters that are probably the release group.
					# Eg (SUBS.K-Z.): Shogun.S01E03.Domani.e.un.altro.giorno.WebDL.2160p.Hevc.HDR.E-AC3.ITA.ENG.SUBS.K-Z.mkv
					if not self._cacheId('languageExtract28', re.compile, 'subs?[^a-z][a-z][^a-z]', flags = Stream.ExpressionFlags).search(match.group(1)):
						data = data.replace(match.group(2), tools.Tools.replaceNotAlpha(data = match.group(2), replace = ''))

				# Replace dual keywords (contain both audio and subtitle).
				for key, value in Stream.ExpressionSubtitleDual.items():
					data = self._cacheId('languageExtract29', re.compile, Stream.ExpressionSymbolStart + '(' + ('|'.join(value)) + ')' + Stream.ExpressionSymbolEnd, flags = Stream.ExpressionFlags).sub(' %s audio %s subtitle ' % (key, key), data)

				# Replace dubbed keywords, since they are detected in AudioType (VF -> French) and later removed from the string.
				data = self._cacheId('languageExtract30', re.compile, Stream.ExpressionSymbolStart + '(' + ('|'.join(Stream.ExpressionAudioFrench)) + ')' + Stream.ExpressionSymbolEnd, flags = Stream.ExpressionFlags).sub(' audio french audio ', data)
				data = self._cacheId('languageExtract31', re.compile, Stream.ExpressionSymbolStart + '(' + ('|'.join(Stream.ExpressionAudioPolish)) + ')' + Stream.ExpressionSymbolEnd, flags = Stream.ExpressionFlags).sub(' audio polish audio ', data)

				# If the keyword "NORDiC" appears, it almost always means they are nordic subtitles, instead of nordic audio.
				# In very few cases "NORDiC" refers to audio and can even appear next to an audio keyword (eg: "NORDiC.AAC").
				# However, even with an audio keyword next to it (eg: "DTS.NORDIC+ENG.ISL.DVDR"), in most cases it still refers to subtitles.
				# So always assume they are subtitles.
				# If another language is present (eg: "Swedish, Nordic+Eng subs"), it typically means the language is audio, and "NORDiC" are the subtitles.
				data = self._cacheId('languageExtract32', re.compile, Stream.ExpressionSymbolStart + '(' + ('|'.join(Stream.ExpressionAudioNordic[0])) + ')' + Stream.ExpressionSymbolEnd, flags = Stream.ExpressionFlags).sub(' subtitle ' + Stream.ExpressionAudioNordic[1] + ' subtitle ', data)

				# Replace Hz and kpbs keywords.
				# Eg: AVATAR (2009) Extended Collector\'s Cut 1080p BluRay x264 AVC [Org Hindi BD 5 1 448Kbps + English DD 5.1] ESubs ~ Tiberiumsun69 ...
				data = self._cacheId('languageExtract33', re.compile, '(\d+(?:\.\d+)?(?:hz|kbps))', flags = Stream.ExpressionFlags).sub(' audio ', data)

				# Replace audio keywords.
				# Repalce with "a-u-d-i-o" and not "audio", since that is a keyword that will be replaced itself.
				# Order is also important (channels last) due to overlappping keywords.
				expression = []
				expression.extend(self._audioTypeKeyword())
				expression.extend(self._audioCodecKeyword())
				expression.extend(self._audioSystemKeyword())
				expression.extend(self._audioChannelsKeyword())
				expression.append(Stream.ExpressionAudio)
				expression = '(?=' + Stream.ExpressionSymbolStart + '(' + ('|'.join([i for i in expression])) + ')' + Stream.ExpressionSymbolEnd + ')'
				matches = self._cacheId('languageExtract34', re.compile, expression, flags = Stream.ExpressionFlags).finditer(data)
				if matches:
					for match in matches:
						for group in match.groups():
							if group: data = data.replace(group, ' a-u-d-i-o ')

				# Replace subtitle keywords.
				expressionSubtitle = self._expressionFormatCommon(Stream.ExpressionSubtitleExtended)
				expression = Stream.ExpressionSymbolStart + '(' + expressionSubtitle + ')' + Stream.ExpressionSymbolEnd
				data = self._cacheId('languageExtract35', re.compile, expression, flags = Stream.ExpressionFlags).sub(' s-u-b-t-i-t-l-e ', data)

				data = data.replace('a-u-d-i-o', 'audio').replace('s-u-b-t-i-t-l-e', 'subtitle')
				parts = self.cleanSplit(data = data, single = ['i', 'v', 'x'], number = True) # Allow single characters that are roman numbers, to not mark "I - VI" as Vietnamese.

				# Add a separator before fixed subtitle keywords (eg SWESUB), to make sure other language keywords before that are not assumed to be subtitles.
				# Eg: Valley.Of.Tears.S01.HEBREW.ENSUBBED.1080p.HMAX.WEBRip.DD5.1.x264-NTG[eztv.re]
				separators = []
				for i in range(len(parts)):
					other = [Stream.ExpressionSubtitleFixed]
					other.extend(Stream.ExpressionSubtitleFrench)
					other.extend(Stream.ExpressionSubtitleSpanish)
					for j in other:
						match = self._cacheId('languageExtract36', re.compile, lambda : self._expressionFormatCommon(j), flags = Stream.ExpressionFlags).search(parts[i])
						if match:
							separators.append(i)
							break
				counter = 0
				for i in separators:
					parts.insert(i + counter, 'separator')
					counter += 1
				count = len(parts)
				labels = [None] * count

				# Replace "US" with "EN".
				# Eg: Terminator (1984) (J Cameron)-Remastered-BrDrip-HD [email protected] 263[)(]E-AC3 5.1-(US-FR)+US_sub-PreRC3
				# If "US" is too early in the filename, it probably means the U.S. version of a movie/show.
				if 'us' in parts:
					index = []
					try: index.append(parts.index('audio'))
					except: pass
					try: index.append(parts.index('subtitle'))
					except: pass
					if index:
						index = min(index)
						for i in range(index, len(parts)):
							if parts[i] == 'us': parts[i] = 'en'

				# Find multi subtitle keywords (eg msubs or multi-sub).
				expressionMulti1 = self._cacheId('languageExtract37', re.compile, '^' + Stream.ExpressionSubtitleMulti + expressionSubtitle + '$', flags = Stream.ExpressionFlags)
				expressionMulti2 = self._cacheId('languageExtract38', re.compile, '^' + Stream.ExpressionSubtitleMulti + '$', flags = Stream.ExpressionFlags)
				for i in range(count):
					if expressionMulti1.search(parts[i]):
						labels[i] = {'type' : 'subtitle', 'language' : tools.Language.UniversalCode}
					elif i < (count - 1) and expressionMulti2.search(parts[i]):
						if parts[i + 1] == 'subtitle':
							labels[i] = {'type' : 'subtitle', 'language' : tools.Language.UniversalCode}

				# Find the fixed subtitle keywords (eg SWESUB).
				languagesParts = []
				languagesExpressions = []
				for i in range(count):
					other = ['sub']
					other.extend(Stream.ExpressionSubtitleFrench)
					other.extend(Stream.ExpressionSubtitleSpanish)
					if any(j in parts[i] for j in other) and not labels[i]:
						languagesParts.append((i, parts[i]))
				for language in languagesCommon:
					if language['code'] == tools.Language.EnglishCode:
						languagesExpressions.append((language['code'], '(?:e|' + language['expression'] + ')'))
					else:
						languagesExpressions.append((language['code'], language['expression']))

						# Include country to allow for fixed country subs.
						# Eg: Game.of.Thrones.S01.Retail.DKsubs
						languagesExpressions.append((language['code'], language['country']))

						# Allow excluded keywords for fixed subtitles.
						# Eg: issub
						for ex in language['exclude']:
							languagesExpressions.append((language['code'], ex))

				languagesString = ' '.join([i[1] for i in languagesParts])
				match = self._expressionMatchMultiple(id = 'languageExtract39', data = languagesString, expression = languagesExpressions, count = len(languagesParts), start = '(?:\s|^)' + expressionSubtitle + '*', end = expressionSubtitle + '*(?:\s|$)', full = True)
				if match:
					for i in match:
						index = languagesString[:i[2] + 1].count(' ')
						labels[languagesParts[index][0]] = {'type' : 'subtitle', 'language' : i[0]}

				# Replace any fixed-language subtitle that went undetected.
				# Eg: Days.of.Darkness.2007.DVDRip.XviD-Mp3.V.O.Sub.Spanish.[www.BajandoXvid.com].avi
				# "O.Sub" becomes "osubtitle" but does not match any language.
				for i in range(count):
					if parts[i] and 'subtitle' in parts[i]:
						parts[i] = 'subtitle'

				# Find the fixed dubbed keywords (eg RUDUB).
				# Eg: The.Old.Man.s01.WEBRip.XviD.RuDub.tv
				expressionDubbed = self._expressionFormatCommon(Stream.ExpressionAudioType['keyword']['dubbed'])
				languagesParts = []
				languagesExpressions = []
				for i in range(count):
					other = ['dub']
					if any(j in parts[i] for j in other) and not labels[i]:
						languagesParts.append((i, parts[i]))
				for language in languagesCommon:
					languagesExpressions.append((language['code'], language['expression']))
				languagesString = ' '.join([i[1] for i in languagesParts])
				match = self._expressionMatchMultiple(id = 'languageExtract40', data = languagesString, expression = languagesExpressions, count = len(languagesParts), start = '(?:\s|^)' + expressionDubbed + '*', end = expressionDubbed + '*(?:\s|$)', full = True)
				if match:
					for i in match:
						index = languagesString[:i[2] + 1].count(' ')
						labels[languagesParts[index][0]] = {'type' : 'audio', 'language' : i[0]}

				# Mark standalone keywords.
				languagesParts = []
				for i in range(count):
					if not labels[i]:
						if parts[i] == 'audio':
							labels[i] = {'type' : 'audio', 'language' : None}
						elif parts[i] == 'subtitle':
							labels[i] = {'type' : 'subtitle', 'language' : None}
						if not parts[i] == 'separator':
							languagesParts.append((i, parts[i]))

				# Mark standalone keywords.
				# Do everything with one expression, since it is faster than matching each part individually.
				languagesString = ' '.join([i[1] for i in languagesParts])

				# Add "native" to the ID, since different expressions can be generated based on the native language.
				# More keywords are added and we therefore do not want to use the cached compiled expression from the ones without "native".
				try: del native[tools.Language.UniversalCode] # Universal providers do not add any extra language-specific keywords and we do not want to include it in the ID.
				except: pass
				expressionId = str(native)
				match = self._expressionMatchMultiple(id = 'languageExtract41_' + expressionId, data = languagesString, expression = languagesExpression, count = len(languagesParts), start = '(?:\s|^)(?<!team' + Stream.ExpressionSeparator + ')', end = '(?:\s|$)', full = True)
				if match:
					for i in match:
						index = languagesString[:i[2] + 1].count(' ')

						# Do not detect occasional/uncommon languages if their code appears at the front/end of the string, since it probably means something else.
						isPrefix = False
						isSuffix = False
						if not tools.Language.language(i[0])[tools.Language.Frequency] == tools.Language.FrequencyCommon:
							# Eg: bs-Candyman.2021.720p.AMZN.WEB-DL.DDP5.1.H.264-ANThELIa.mkv.html
							isPrefix = index == 0 and dataLower.startswith(i[0])

							# Cut-off extension.
							# Eg: Game.Of.Thrones.S08E01.iNTERNAL.HDTV.x264-TURBO.mk
							isSuffix = index == (len(labels) - 1) and dataLower.endswith(i[0])

						if not isPrefix and not isSuffix:
							if languagesParts[index][1] == 'uk': labels[languagesParts[index][0]] = {'type' : 'special', 'language' : i[0]}
							else: labels[languagesParts[index][0]] = {'type' : None, 'language' : i[0]}

				# Process the "UK" keyword.
				# In many cases "UK" means it is a movie/series from the U.K.
				# In other cases it can mean Ukrainian.
				# Only assume it is Ukrainian if the keyword is surrounded by audio/subtitle/language keywords.
				for i in range(len(labels)):
					if labels[i] and labels[i]['type'] == 'special':
						wrap = []
						try: wrap.append(labels[i - 1])
						except: pass
						try: wrap.append(labels[i + 1])
						except: pass
						wrapped = False
						for j in wrap:
							if j and (j['type'] in ['audio', 'subtitle'] or j['language']):
								wrapped = True
								break
						if not wrapped:
							for j in range(len(parts)):
								if parts[j] == labels[i]['language']:
									parts[j] = None
									break
							labels[i] = None

				# If there are 2 language keywords separated by some other keyword, assume it is a separator.
				# Eg: Game Of Thrones S01E01 (DD5.1 720p ENG+NL Subs) Hornigold TBS
				# Otherwise "720p" gets trimmed and "ENG+NL" is assumed to be the audio due to "DD5.1".
				for i in range(1, count - 1):
					if not labels[i] and labels[i - 1] and labels[i + 1]:
						parts[i] = 'separator'

				# Make sure that the sequence: audio language subtitle, the language is associated with the subtitles and not the audio.
				# Eg: Avatar.2009.Extended.Cut.1080p.DTS.5.1.NL.Subs.x264
				for i in range(1, count - 1):
					if labels[i - 1] and labels[i - 1]['type'] == 'audio' and not labels[i - 1]['language']:
						if labels[i + 1] and labels[i + 1]['type'] == 'subtitle' and not labels[i + 1]['language']:
							if labels[i] and not labels[i]['type'] and labels[i]['language']:
								if (i + 2) >= count or not labels[i + 2]:
									labels.insert(i, None)
									parts.insert(i, 'separator')
									count += 1
									break

				# Sometimes the non-English episode title is in the file name.
				# These languages (Spanish, Portuguese, Italian, French) often contain 2-letter words that can be confused with a language code.
				# Eg ("fa" is detected as Persian): Foundation.S02E09.Molto.tempo.fa.non.troppo.lontano.ITA.ENG.2160p.ATVP.WEB-DL.DDP5.1.HDR.HEVC-MeM.GP.mkv
				counter = 0
				for i in range(count):
					if labels[i] and labels[i]['language']: counter += 1
				if counter > 1:
					for i in range(count):
						if labels[i] and labels[i]['language'] and parts[i] and len(parts[i]) == 2:
							empty = True
							for j in range(i - 1, max(i - 3, 0), -1):
								if labels[j]:
									empty = False
									break
							if empty:
								for j in range(i + 1, min(i + 3, count), 1):
									if labels[j]:
										empty = False
										break
							if empty:
								labels[i] = None

				# Removing leading and trailing separators, whih can cause detection problems.
				if parts:
					if parts[0] == 'separator': parts[0] = None
					if parts[-1] == 'separator': parts[-1] = None

				# Mark separators.
				# Must be after matching languages, since it uses the language labels.
				subtitleHas = 'subtitle' in parts or any([i for i in labels if i and i['type'] == 'subtitle'])
				for i in range(count):
					if not labels[i]:
						if parts[i] == 'separator':
							if not subtitleHas:
								labels[i] = {'type' : 'audio', 'language' : None}
							elif find(parts, 'subtitle', start = i + 1) >= 0 and find(parts, 'audio', end = i - 1) < 0 and find(parts, 'audio', start = i + 1) < 0:
								language = False
								other = False
								for j in range(i):
									if labels[j] and labels[j]['language']: language = True
									elif labels[j] and labels[j]['type'] == 'audio': other = True
									elif labels[j] and labels[j]['type'] == 'subtitle': break
								if language: labels[i] = {'type' : 'audio', 'language' : None}
								elif other and len([k for k in labels if k and k['language']]) == 1: labels[i] = {'type' : 'subtitle', 'language' : None}
							elif find(parts, 'audio', start = i + 1) >= 0 and find(parts, 'subtitle', end = i - 1) < 0:
								language = False
								other = False
								try:
									if parts[i - 1] == 'audio':
										if parts[i + 1] == 'audio': other = True
										elif not parts[i + 1] == 'subtitle' and not parts[i + 1] == 'subtitle': other = True
								except: pass
								if not other:
									for j in range(i):
										if labels[j] and labels[j]['language']: language = True
										elif labels[j] and labels[j]['type'] == 'subtitle': other = True
										elif labels[j] and labels[j]['type'] == 'audio': break
								if language: labels[i] = {'type' : 'subtitle', 'language' : None}
								elif other: labels[i] = {'type' : 'audio', 'language' : None}
							elif find(parts, 'subtitle', start = i + 1) >= 0:
								# Makes sure that the language is associated with the subtitle and not the audio.
								# [Anime Time] Demon Slayer - Kimetsu no Yaiba [BD][Dual Audio][1080p][HEVC 10bit x265][AAC][Eng Sub] [Batch]
								try: language = labels[i + 1] and labels[i + 1]['language']
								except: language = False
								labels.insert(i, {'type' : 'subtitle', 'language' : None})
						else:
							labels[i] = {'type' : 'other', 'language' : None}

				labels = [i for i in labels if i]
				count = len(labels)

				# Trim keywords.
				temp = []
				for i in range(count):
					if labels[i]['language']:
						temp.append(labels[i])
					elif i < (count - 1) and labels[i]['type'] in ['audio', 'subtitle', 'other']:
						if labels[i]['type'] == labels[i + 1]['type']:
							hasType = False
							for j in temp:
								if j['type'] == labels[i]['type']:
									hasType = True
									break
							if hasType: i += 1
							else: temp.append(labels[i])
						elif labels[i + 1]['language']:
							temp.append(labels[i])
						elif labels[i + 1]['type'] in ['subtitle', 'other']:
							temp.append(labels[i])
					elif i == 0 or labels[i - 1]['language']:
						temp.append(labels[i])
				labels = temp

				if len(labels) > 0 and labels[0]['type'] == 'other': del labels[0]
				if len(labels) > 0 and labels[-1]['type'] == 'other': del labels[-1]

				labels = [i for i in labels if i]
				count = len(labels)

				audioFirst = -1
				subtitleFirst = -1
				for i in range(count):
					if audioFirst < 0 and labels[i]['type'] == 'audio':
						audioFirst = i
						if subtitleFirst >= 0: break
					elif subtitleFirst < 0 and labels[i]['type'] == 'subtitle':
						subtitleFirst = i
						if audioFirst >= 0: break

				audioLast = -1
				subtitleLast = -1
				for i in range(count):
					index = count - i - 1
					if audioLast < 0 and labels[index]['type'] == 'audio':
						audioLast = index
						if subtitleLast >= 0: break
					elif subtitleLast < 0 and labels[index]['type'] == 'subtitle':
						subtitleLast = index
						if audioLast >= 0: break

				audioHas = audioFirst >= 0
				subtitleHas = subtitleFirst >= 0
				if audioLast < subtitleFirst and audioFirst == audioLast:
					if subtitleFirst == subtitleLast and audioLast > 0:
						subtitleFirst = audioLast
					else:
						found = False
						for i in range(subtitleFirst, count):
							if labels[i]['language']:
								found = True
								break
						if found: audioLast = subtitleFirst
				if subtitleLast < audioFirst and subtitleFirst == subtitleLast and subtitleFirst >= 0:
					if audioFirst == audioLast and subtitleLast > 0:
						audioFirst = subtitleLast
					else:
						found = False
						for i in range(audioFirst, count):
							if labels[i]['language']:
								found = True
								break
						if found: subtitleLast = audioFirst

				if not audioHas:
					for i in range(0, subtitleFirst):
						if labels[i]['language']:
							audioHas = True
							audioFirst = 0
							break
					if not audioHas and subtitleLast >= 0:
						has = False
						for i in range(0, subtitleLast):
							if labels[i]['language']:
								has = True
								break
						if has:
							for i in range(subtitleLast, count):
								if labels[i]['language']:
									audioHas = True
									audioFirst = 0
									break

				if not subtitleHas:
					for i in range(0, audioFirst):
						if labels[i]['language']:
							subtitleHas = True
							subtitleFirst = 0
							break
					if not subtitleHas and audioLast >= 0:
						has = False
						for i in range(0, audioLast):
							if labels[i]['language']:
								has = True
								break
						if has:
							for i in range(audioLast, count):
								if labels[i]['language']:
									subtitleHas = True
									subtitleFirst = 0
									break

				if audioHas and subtitleHas:
					if audioLast <= subtitleFirst:
						# Eg: The Terminator (1984) REMASTERED 720p x264 DD 5.1 EN NL Subs [Asian Torrenz]
						# Eg: Game of Thrones S01 1080p BluRay-RMZ x264-belex DualAudio eng+ptbr+subs
						if subtitleFirst - audioLast == 3:
							if not labels[audioLast + 1]['type'] and labels[audioLast + 1]['language']:
								if not labels[audioLast + 2]['type'] and labels[audioLast + 2]['language']:
									if self._cacheId('languageExtract_dual_audio', re.compile, lambda : self._expressionFormatCommon(Stream.ExpressionAudioDual), flags = Stream.ExpressionFlags).search(data):
										labels[audioLast + 1]['type'] = 'audio'
										labels[audioLast + 2]['type'] = 'audio'
									else:
										labels[audioLast + 1]['type'] = 'subtitle'
										labels[audioLast + 2]['type'] = 'subtitle'

						if audioFirst == audioLast:
							other = False
							for j in range(audioLast, subtitleFirst):
								if labels[j]['type'] == 'other':
									other = True
									break
							if not other: audioLast = subtitleFirst

						for i in range(0, audioLast):
							if not labels[i]['language'] or labels[i]['type'] == 'special': labels[i]['type'] = 'audio'

						audioLast = max(0, audioLast) # If -1

						# Avatar 3D SBS [BluRay 1080p][DTS-AC3 5.1 Castellano_DTS English + Subs. Español][2009]
						subtitleLanguage = None
						if audioHas:
							subtitleLanguage = False
							for j in range(audioLast, count):
								if labels[j]['type'] == 'subtitle' and not labels[j]['language']:
									for k in range(j, count):
										if labels[k]['language']:
											subtitleLanguage = True
											break
									break

						# If a language appears more than once, assume it is audio + subtitle, even if there are no audio keywords.
						# Eg: Avatar 3D - Extended Collectors Edition - Sigourney Weaver 2009 Bluray x264 rip ENG - Dutch Engels Subs
						counter = {}
						subtitleStandalone = False
						for label in labels:
							if label['language']:
								try: counter[label['language']] += 1
								except: counter[label['language']] = 1
							elif label['type'] == 'subtitle':
								subtitleStandalone = True

						# Only do this if there is a standalone subtitle keyword (aka subtitle keyword without a language asocciated with it).
						# Eg: www.1TamilMV.click - Rocketry - The Nambi Effect (2022) TRUE WEB-DL - 1080p HQ - HEVC - UNTOUCHED - (DD+ 5.1 - 640Kbps) [Tam + Tel + Kan + Mal] - ESub.mkv
						# Eg: [{'type': 'audio', 'language': None}, {'type': 'audio', 'language': None}, {'type': None, 'language': 'ta'}, {'type': None, 'language': 'te'}, {'type': None, 'language': 'kn'}, {'type': None, 'language': 'ml'}, {'type': 'subtitle', 'language': 'en'}]
						if not subtitleLanguage is True and subtitleStandalone:
							for i in range(count - 1, audioLast - 1, -1):
								language = labels[i]['language']
								if language:
									if counter[language] > 0:
										labels[i]['type'] = 'subtitle'
										counter[language] = -1
									else:
										labels[i]['type'] = 'audio'
					elif subtitleLast <= audioFirst and subtitleLast > 0:
						if subtitleFirst == subtitleLast: subtitleLast = audioFirst

						# Amelie[2001]BRrip[French][Eng Subs][Ac3-5.1]-=[CaLvIn]=-
						special1 = audioLast - 2 == subtitleFirst

						# Joker (2019).SD.H264.sub.ita.eng.Ac3-5.1.swe.dut.eng-MIRCrew
						special2 = False
						for i in range(audioLast, count):
							if labels[i]['language']:
								special2 = True
								break

						if special1:
							for i in range(0, subtitleFirst):
								if labels[i]['language'] and (not labels[i]['type'] or labels[i]['type'] == 'other'): labels[i]['type'] = 'audio'
						else:
							for i in range(0, subtitleLast):
								if labels[i]['language'] and (not labels[i]['type'] or labels[i]['type'] == 'other'): labels[i]['type'] = 'subtitle'

						for i in range(audioLast, count):
							if labels[i]['language'] and (not labels[i]['type'] or labels[i]['type'] == 'other'): labels[i]['type'] = 'audio'

						if special1 or special2:
							for i in range(subtitleLast, audioLast):
								if labels[i]['language']: labels[i]['type'] = 'subtitle'
						else:
							for i in range(subtitleLast + 1, audioLast):
								if labels[i]['language']: labels[i]['type'] = 'audio'
				elif audioHas:
					labels = [{'type' : 'audio', 'language' : i['language']} for i in labels if i['language']]
				elif subtitleHas:
					labels = [{'type' : 'subtitle', 'language' : i['language']} for i in labels if i['language']]
				else:
					labels = [{'type' : 'audio', 'language' : i['language']} for i in labels if i['language']]

				labels = [i for i in labels if not i['type'] == 'other']

				# Mark the rest with the previous type.
				previous = 'audio'
				for label in labels:
					if label['type']: previous = label['type']
					if label['language']:
						if not label['type']: label['type'] = previous
						if label['type'] in result: result[label['type']].append(label['language'])

				# If subtitle keywords exist without a language, add the universal code.
				if len(result['subtitle']) == 0 and 'subtitle' in parts:
					result['subtitle'].append(tools.Language.UniversalCode)

				if exclude:
					languagesCode = {i['code'] : i for i in languages}
					expression1 = self._cacheId('languageExtract42', re.compile, '\.')
					expression2 = self._cacheId('languageExtract43', re.compile, '\s+')

					for ex in exclude:
						# Abbriviations (eg M.S. -> MS)
						excludeShort = ex
						excludeShort = expression1.sub('', excludeShort)
						excludeShort = tools.Tools.replaceNotAlphaNumeric(excludeShort, ' ')
						excludeShort = expression2.sub(' ', excludeShort)
						excludeDifferent = not excludeShort == ex

						for type in ['audio', 'subtitle']:
							delete = []
							length = len(result[type])
							for i in range(length):
								language = result[type][i]
								if not language == tools.Language.UniversalCode:
									# Only remove the language if the specific keyword appears in the title, instead of the entire expression.
									# For instance, the French expressions contains 'french|fra|fr'.
									# Removing the lanaguage if the expression matches, will remove it if ANY of the keywords in the expression match.
									#	Title: Den fabelagtige Amelie fra Montmartre
									#	Filename: Amelie.2001.DTS.FR.DD.PL.PAL.DVDR-SNTY
									# Matching the entire expression would remove French as the audio language, since one of the alternative titles contain the word "fra".
									# Instead, we extract the keyword (eg: "fr") and only remove it if it appears in the title, irrespective of the other keywords int he expression (eg: "fra").
									# Only do this if the word is not followed by an audio or subtitle keyword, otherwise this won't detect the French audio language:
									#	Il Favoloso Mondo di Amélie (2001) Ita Ac3 Fra Aac BrRip 1080p [TNT Village]
									# Previous code:
									#	expression = Stream.ExpressionSymbolStart + languagesCode[language]['expression'] + '(?:=sub|' + Stream.ExpressionSymbolEnd + ')'
									#	if self._cacheId('languageExtract17' + languagesCode[language]['code'], re.compile, expression, flags = Stream.ExpressionFlags).search(ex) or (excludeDifferent and self._cacheId('languageExtract14' + languagesCode[language]['code'], re.compile, expression, flags = Stream.ExpressionFlags).search(excludeShort)):
									#		if result[type].count(language) == 1: ...
									expression = '(' + Stream.ExpressionSymbolStart + languagesCode[language]['expression'] + '(?:=subs?|' + Stream.ExpressionSymbolEnd + '))'
									found = True
									excludes = [ex]
									if not ex == excludeShort: excludes.append(excludeShort)

									# Only exclude if the language does not appear in the filename more than once.
									#	Eg: [ OxTorrent sh ] The French Dispatch 2021 720p FRENCH HDTS MD x264-CZ530
									# Once where are here, the "data" variable should already have stripped the title:
									#	Eg: [ OxTorrent sh ]  2021 720p FRENCH HDTS MD x264-CZ530
									expressioned = self._cacheId('languageExtract44_' + languagesCode[language]['code'], re.compile, expression, flags = Stream.ExpressionFlags)
									if not expressioned.search(data):
										for j in range(len(excludes)):
											groups = expressioned.search(excludes[j])
											if groups:
												groups = groups.groups()
												for group in groups:
													group = group.strip().lower()
													for k in range(len(parts)):
														if group == parts[k]:
															audio = False
															try: audio = parts[k - 1] in ['audio', 'subtitle']
															except: pass
															if not audio:
																try: audio = parts[k + 1] in ['audio', 'subtitle']
																except: pass
																if not audio:
																	found = False
																	break
													else: continue # Continue if the inner loop wasn't broken.
													break # Inner loop was broken, break the outer.
												else: continue # Continue if the inner loop wasn't broken.
												break # Inner loop was broken, break the outer.

									if not found:
										if result[type].count(language) == 1:
											delete.append(i)
										else:
											for j in range(i + 1, length):
												if result[type][j] == language:
													delete.append(j)

							delete = list(set(delete))
							result[type] = [result[type][i] for i in range(length) if not i in delete]

				# Assume the original title language if not language was detected.
				if len(result['audio']) == 0 and default and not default in result['audio']:
					result['audio'].append(default)
					result['default'].append(default)

				# Some names contain only 1 language and marked as dual.
				# In such a case, assume the second language is English.
				# Only do this if a single audio language is detected in the name.
				seen = set()
				result['audio'] = [i for i in result['audio'] if not i in seen and not seen.add(i)]
				if len(result['audio']) == 1:
					dualExpression = self._cacheId('languageExtract_dual_audio', re.compile, lambda : self._expressionFormatCommon(Stream.ExpressionAudioDual), flags = Stream.ExpressionFlags)
					if dualExpression.search(data):
						excluded = False
						if exclude:
							for ex in exclude:
								if dualExpression.search(ex):
									excluded = True
									break
						if not excluded:
							if default and not default in result['audio']:
								result['audio'].append(default)
								result['default'].append(default)
							else:
								result['audio'].append(tools.Language.EnglishCode)
								result['default'].append(tools.Language.EnglishCode)

				for type in ['audio', 'subtitle', 'default']:
					seen = set()
					result[type] = [i for i in result[type] if not i in seen and not seen.add(i)]

			except:
				tools.Logger.error()

			return result

		return self._cache(_languageExtract, data = data, exclude = exclude, clean = clean, encode = encode, default = default)

	'''
		FUNCTION:
			Detects the languages from a code or name string.
		PARAMETERS:
			data (string): The language code or name.
		RETURNS:
			The language (list): ['lang1', 'lang2'].
	'''
	@classmethod
	def languageDetect(self, data):
		def _languageDetect(data):
			result = []
			if not tools.Tools.isArray(data): data = [data]
			for value in data:
				value = tools.Language.language(value)
				if value: result.append(value[tools.Language.Code][tools.Language.CodePrimary])
			seen = set()
			result = [i for i in result if not i in seen and not seen.add(i)]
			return result
		return self._cache(_languageDetect, data = data)

	'''
		FUNCTION:
			Adds an audio or subtitle language to existing results and removes duplicates.
		PARAMETERS:
			language (list): A list of already extracted languages.
			addition (None/string/list): The subtitle languages to add.
			detect (boolean): Wether or not to detect the language from the audio/subtitle parameters, or if they are already in ISO 2-letter code format.
			prepend (boolean): If True, prepends the new value. Otherwise appends it.
		RETURNS:
			The language (list): ['lang1', 'lang2'].
	'''
	@classmethod
	def languageMerge(self, language, addition = None, detect = True, prepend = True):
		if detect: addition = self.languageDetect(data = addition)
		if not addition: return language
		if language is None: language = []
		if prepend: language = addition + language
		else: language = language + addition
		seen = set()
		language = [i for i in language if not i in seen and not seen.add(i)]
		return language

	'''
		FUNCTION:
			Cleans a file name from language keywords.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			guidance (None/string): The already detected languages. Speeds up the cleaning by only removing previously detected keywords, instead of scanning through all keywords.
			native (None/list): The languages of the provider or source used to detect additional language name translations.
			split (None/string): If SplitRight/SplitLeft, cuts off the string after/before the first found keyword. If None, simply remove the keyword and keep the rest of the string intact.
		RETURNS:
			The cleaned file name (string).
	'''
	@classmethod
	def languageClean(self, data, exclude = None, encode = True, guidance = None, native = None, split = SplitNone):
		if not data: return data
		if encode: exclude = self.cleanEncode(exclude)
		expression = self._languageKeyword(native = native)
		expression = {'keyword' : {}, 'expression' : [(i['code'], '(' + ('|'.join(i['keyword'])) + ')') for i in expression]}
		expression['expression'].append(('other', '(' + ('|'.join(Stream.ExpressionAudioOther)) + ')'))
		count = self._expressionCount(expression)

		# Important to "standalone = True", otherwise partial words are also matched.
		# This means that in the title "james camerons avatar", the "es" in "james" is detected as Spanish.
		# This in turn will make a file name "avatar spanish" not match.
		expression = self._expressionFormatKeyword(id = 'languageClean', expression = expression, exclude = exclude, guidance = guidance, standalone = True)

		return self._expressionReplace(id = 'languageClean_' + str(guidance), data = data, expression = expression, exclude = exclude, count = count, split = split, internal = True)

	@classmethod
	def _languageKeyword(self, common = True, native = None):
		def __languageKeywordReplace(keyword, value, replacement):
			seen = set()
			keyword = [i.lower() for i in keyword]
			keyword = [i for i in keyword if not i in seen and not seen.add(i)]
			for j in range(len(keyword)):
				if keyword[j] == value:
					keyword[j] = replacement
					break
			return keyword

		def __languageKeyword(common, native):
			result = []
			replace = '-n-a-m-e-'
			languages = tools.Language.languages(universal = False)
			if common: languages = [i for i in languages if i[tools.Language.Frequency] >= tools.Language.FrequencyOccasional]
			else: languages = [i for i in languages if i[tools.Language.Frequency] == tools.Language.FrequencyUncommon]
			languages = sorted(languages, key = lambda i : i[tools.Language.Frequency], reverse = True)
			exp = self._cacheId('_languageKeyword1', re.compile, '[^a-z\-\–\s]+', flags = Stream.ExpressionFlags)

			endingName = '(?:$|' + Stream.ExpressionBracketsEnd + '$|' + Stream.ExpressionFileSeparator + ')'
			endingExtension = '(?:' + endingName + '|[\.\-\–\_\s](?:mkv|webm|avi|mp(?:4|e?g)|mov|iso|rar|zip)' + endingName + ')'
			endingExclude = '(?!' + endingExtension + ')'
			endingGroup = '(?!' + Stream.ExpressionSeparator + '[a-z0-9]+' + endingExtension + ')' + endingExclude

			if native and not tools.Tools.isArray(native): native = [native]

			for language in languages:
				frequency = language[tools.Language.Frequency]
				keyword = []

				# Note that if a "native" language is passed in, the keywords will be different from the ones that do not have a native language.
				# This means that the keyword matching in languageExtract() -> languageExtract19_ -> will have to compile different expressions.
				# We therefore have 2 alternatives:
				#	1. Add all language-name-translations by default to the keywords. This will only have to compile one set of expressions (faster), but more keywords have to be matched (slower).
				#	2. Only add language-name-translations for native providers. Less keywords have to be matched (faster), but separate expression sets have to be compiled (slower).
				# When there are very few streams, option 1 performs slightly faster.
				# When there are many streams, option 2 performs slightly faster.
				# For now we use option 2, since most users will not have language-specific providers enabled and option 1 will therefore be a worse idea.

				namesCommon = [language[tools.Language.Name][tools.Language.NameEnglish], language[tools.Language.Name][tools.Language.NameNative]]
				if frequency == tools.Language.FrequencyCommon: names = list(language[tools.Language.Name].values())
				else: names = namesCommon

				# Add all names for the language of the provider.
				# Eg: A French provider should also add the French names of languages (not just the English and native names).
				if native:
					for i in native:
						try: names.append(language[tools.Language.Name][i])
						except: pass

				keyword.extend(names)

				if common:
					keyword.extend(language[tools.Language.Code])

					# Eg: Use "Esp" for Spanish.
					# Only do this for English and native names. Otherwise the word "all" is detected as German 'Allemand'.
					keyword.extend([i[:3] for i in namesCommon])

					if frequency == tools.Language.FrequencyCommon:
						# If there are multiple subtitles, they might be marked with a number.
						# Eg: Terminator - Quadrilogy - HD BluRay 1080p x264 Rip ENG - SUBS eng1 eng2 dut fre ger tur slv bul dan pol por spa srp swe gre rus alb bos rum ara heb ita zwe ( mka)
						keyword.extend([i + '\d' for i in language[tools.Language.Code]])

						# Important for eg Greek (Gr Subs).
						keyword.extend([i[:2] for i in namesCommon])

				country = language[tools.Language.Country]
				codePrimary = language[tools.Language.Code][tools.Language.CodePrimary]
				if codePrimary == 'en':
					keyword.append('ing') # Spanish abbreviation.
					keyword.extend([i + 'e' for i in Stream.ExpressionSubtitleFrench])
					keyword.extend([i + 'a' for i in Stream.ExpressionSubtitleFrench])
					keyword.extend([i + 'an' for i in Stream.ExpressionSubtitleFrench])
					keyword.extend(Stream.ExpressionAudioEnglish)
				elif codePrimary == 'fr':
					keyword.extend(Stream.ExpressionAudioFrench)
					keyword.extend(Stream.ExpressionSubtitleFrench)
					keyword.extend([i + 'f' for i in Stream.ExpressionSubtitleFrench])
				elif codePrimary == 'es':
					keyword.extend(Stream.ExpressionAudioSpanish)
					keyword.extend(Stream.ExpressionSubtitleSpanish)
				elif codePrimary == 'pt':
					keyword.extend(Stream.ExpressionAudioPortuguese)
				elif codePrimary == 'de':
					keyword.extend(Stream.ExpressionAudioGerman)
				elif codePrimary == 'pl':
					keyword.extend(Stream.ExpressionAudioPolish)
				elif codePrimary == 'zh':
					keyword.extend(Stream.ExpressionAudioChinese)
				elif codePrimary == 'ru':
					keyword.extend(Stream.ExpressionAudioRussian)
				elif codePrimary == 'ar':
					keyword.extend(Stream.ExpressionAudioArabic)
				elif codePrimary == 'az':
					keyword.extend(Stream.ExpressionAudioAzerbaijani)
				elif codePrimary == 'cs':
					keyword.append(country)
				elif codePrimary == 'hi':
					keyword.extend(Stream.ExpressionAudioHindi)
					# Exclude 'Hi-Def'.
					# Eg: The Terminator 1-4 Hi-Def Collection
					keyword = __languageKeywordReplace(keyword = keyword, value = 'hi', replacement = 'hi(?!\sdef)')
				elif codePrimary == 'vi':
					# Exclude roman numbers.
					# Eg: The Terminator Collection I - VI (1984-2019)
					keyword = __languageKeywordReplace(keyword = keyword, value = 'vi', replacement = '(?<!\s[ivx]\s)vi(?!\s[ivx]\s)')
				elif codePrimary == 'fi':
					# Exclude 'Sci-Fi' and 'Hi-Fi'.
					# Eg: The Terminator Anthology (1984 2015) HEVC 720p SCI FI ARC
					# Eg: L'ile.De.Nim.[Cam.French.Hi-Fi.Stereo.HQ.Xvid.Quebec.Scen
					keyword = __languageKeywordReplace(keyword = keyword, value = 'fi', replacement = '(?<![ch]i.)fi')
				elif codePrimary == 'ku':
					# Exclude 'Sci-Fi' and 'Hi-Fi'.
					# Eg: The Office Season 1. Healthcare x264 PS3 Xbox360 Compat[OG-KU]
					keyword = __languageKeywordReplace(keyword = keyword, value = 'ku', replacement = '(?<!og.)ku')
				elif codePrimary == 'hu':
					# "Hun" is also a uploader/group from way back.
					# Only use Hun if it does not appear at the end of the string, which is most likley means the uploader/group.
					# Eg: The.Terminator.1984.Open.Matte.1080p.AMZN.WEB-DL.DD5.1.H.264.HUN-GS88
					# Eg: The.Terminator.1984.1080p.Remastered.Bluray.Remux.AVC.DTS-HD.MA.HUN-KuNgZi
					# Eg: Terminator.Pentalogy.1984-2015.1080p.mHD.BluRay.x264.Hun-AlexBox
					keyword = __languageKeywordReplace(keyword = keyword, value = 'hun', replacement = 'hun' + endingGroup)
				elif codePrimary == 'bg':
					# "BG" is also a release group.
					# Eg: Avatar.2009.iTALiAN.Extended.Collectors.Edition.AC3.Sub-Ita.BDRip.Hx264-BG.mkv
					keyword = __languageKeywordReplace(keyword = keyword, value = 'bg', replacement = 'bg' + endingGroup)
				elif codePrimary == 'bs':
					# "BS" is also a release group.
					# Eg: Nineteen.Eighty-Four.1984.720p.WEB-DL.AAC2.0.H.264-BS [PublicHD]
					# Eg: Nineteen.Eighty-Four.1984.720p.WEB-DL.AAC2.0.H.264-BS.mkv
					keyword = __languageKeywordReplace(keyword = keyword, value = 'bs', replacement = 'bs' + endingGroup)
				elif codePrimary == 'bn':
					# "BEN" is also a release group.
					# Eg: Nineteen.Eighty-Four.1984.BDRip-AVC.BEN-BEN.mkv
					# Eg: Maggie.Moores.2023.2160p.Multi.Sub.DD5.1.HDR.x265.MP4-BEN.THE.MEN
					keyword = __languageKeywordReplace(keyword = keyword, value = 'ben', replacement = 'ben(?!.the.men)' + endingGroup)
				elif codePrimary == 'te':
					# Eg: The.Terminator.1984.BDRip-AVC.Sem-te.mkv
					keyword = __languageKeywordReplace(keyword = keyword, value = 'te', replacement = '(?<!sem.)te')
				elif codePrimary == 'nl':
					# Eg: Avatar (Extended Collectors Edition) (2009) 1080p BluRay X264 Du
					keyword = __languageKeywordReplace(keyword = keyword, value = 'du', replacement = 'du' + endingExclude)
				elif codePrimary == 'th':
					# TH can be a release group.
					# Eg: (ilmiotorrent.netsons.org).Avatar.2009.iTALiAN.MD.DVDRip.XViD-TH
					keyword = __languageKeywordReplace(keyword = keyword, value = 'th', replacement = 'th' + endingExclude)
				elif codePrimary == 'be':
					# Eg: Avatar 2009 FRENCH TS xvid MD ac3 SUBFORCED (condom be)
					keyword = __languageKeywordReplace(keyword = keyword, value = 'be', replacement = 'be' + endingExclude)
				elif codePrimary == 'ht':
					# Eg: The Last of Us.S01E02.Infected.MULTi.1080p.HMAX.WEB-DL.DDP5.1.x264-Ralf - PSOTNIK HT.mkv
					keyword = __languageKeywordReplace(keyword = keyword, value = 'ht', replacement = 'ht' + endingExclude)
				elif codePrimary == 'sq':
					# SHQ = Super High Quality
					# Eg: Avatar(2009)TS SHQ 720p-[Spanish+Sub)-[ESPADESCARGAS]
					keyword = [i for i in keyword if not i.lower() == 'shq']
				elif codePrimary == 'ms':
					# Do not use "mal" abbreviation from "Malay", since it is also the ISO code for "Malayalam".
					# Eg: www.1TamilMV.click - Rocketry - The Nambi Effect (2022) TRUE WEB-DL - 1080p HQ - HEVC - UNTOUCHED - (DD+ 5.1 - 640Kbps) [Tam + Tel + Kan + Mal] - ESub.mkv
					keyword = [i for i in keyword if not i.lower() == 'mal']
				elif codePrimary == 'my':
					# "my" is a too common English word.
					# Eg: 【高清剧集网发布 www.DDHDTV.com】我的媳夫[全11集][中文字幕].Mr.Bride.My.Darling.S01.1080p.Hami.WEB-DL.AAC2.0.H.264-Hami
					keyword = [i for i in keyword if not i.lower() == 'my']
				elif codePrimary == 'tn':
					# Eg: The Office (UK) Seasons 1 and 2 Complete Box Set [Eng Subs][NetflixRip][NVEnc H265][AAC 2Ch]
					keyword = [i for i in keyword if not i.lower() == 'set']

				# Eg: VOSTENG or VFSTEN
				if frequency == tools.Language.FrequencyCommon:
					codeSecondary = language[tools.Language.Code][tools.Language.CodeSecondary]
					keyword.extend([i + codePrimary for i in Stream.ExpressionSubtitleFrench])
					keyword.extend([i + codeSecondary for i in Stream.ExpressionSubtitleFrench])

				keyword.extend([tools.Converter.unicodeNormalize(i) for i in names])

				for i in names:
					special = exp.sub(replace, i)
					if not special == replace: # If not the entire name.
						# Only do this if not too many characters are replaced.
						# If too many characters are replaced, it can match any kind of unicode substring.
						# Eg: Коми кыв
						# Eg: മലയാളം
						lengthUnicoded = len(i)
						lengthAsccii = len(special.replace(replace, ''))
						if (lengthAsccii / lengthUnicoded) > 0.7: keyword.append(special.replace(replace, '[^\\x00-\\x7F]{1,4}'))

				keyword = [i.lower() for i in keyword if i]

				# Exclude common words.
				exclude = []
				temp = []
				for i in keyword:
					if i in Stream.AudioExcluded: exclude.append(i)
					else: temp.append(i)
				keyword = temp

				# Do not use list(set()), since it doees not preserve order.
				seen = set()
				keyword = [i for i in keyword if not i in seen and not seen.add(i)]

				for i in range(len(keyword)):
					try: keyword[i] = tools.Converter.unicode(keyword[i])
					except:
						try: keyword[i] = keyword[i].decode('latin-1')
						except: pass

				expression = '(?:' + ('|'.join(keyword)) + ')'
				result.append({'code' : codePrimary, 'country' : country, 'keyword' : keyword, 'expression' : expression, 'exclude' : exclude})
			return result
		return self._cache(__languageKeyword, common = common, native = native)

	##############################################################################
	# LINK ORIGINAL
	##############################################################################

	'''
		FUNCTION:
			Retrieves the link(s).
		PARAMETERS:
			index (None/integer): If None, all links are returned. Otherwise an index can be provided to retrieve a specific link.
			generate (boolean): Generate a magnet link if the links do not have one and the hash is avialable. Useful for eg YGG streams.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The link(s) (string/list).
	'''
	def link(self, index = None, generate = False, default = None):
		value = self.mData['link']['original']

		if generate and self.sourceTypeTorrent():
			hash = self.hash()
			if hash:
				magnet = False
				if value:
					for i in value:
						if network.Container(i).torrentIsMagnet():
							magnet = True
							break
				if not magnet:
					if not value: value = []
					else: value = tools.Tools.copy(value)
					magnet = network.Container(hash).torrentMagnetCreate(title = self.fileName(), version = network.Container.VersionAll)
					if magnet: value.append(magnet)

		if not value: return default
		if not index is None:
			try: return value[index]
			except: return default
		return value

	'''
		FUNCTION:
			Retrieves the primary link.
		PARAMETERS:
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The primary link (string).
	'''
	def linkPrimary(self, default = None):
		return self.link(index = 0, default = default)

	'''
		FUNCTION:
			Retrieves the secondary link.
		PARAMETERS:
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The secondary link (string).
	'''
	def linkSecondary(self, default = None):
		return self.link(index = 1, default = default)

	'''
		FUNCTION:
			Retrieves the tertiary link.
		PARAMETERS:
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The tertiary link (string).
	'''
	def linkTertiary(self, default = None):
		return self.link(index = 2, default = default)

	'''
		FUNCTION:
			Sets the link(s).
		PARAMETERS:
			value (string/list): The link(s).
			hoster (boolean): Extract the hoster from the links.
	'''
	def linkSet(self, value, hoster = False):
		if not tools.Tools.isArray(value): value = [value] if value else []
		self.mData['link']['original'] = value
		if hoster and not self.sourceHoster():
			 hoster = self.sourceHosterExtract(self.mData['link']['original'])
			 if hoster: self.sourceHosterSet(hoster)

	'''
		FUNCTION:
			Adds a link(s).
		PARAMETERS:
			value (string/list): The link(s).
			prepend (boolean): Add to the front of the list instead of the end.
			hoster (boolean): Extract the hoster from the links.
	'''
	def linkAdd(self, value, prepend = False, hoster = False):
		if not tools.Tools.isArray(value): value = [value] if value else []
		if not tools.Tools.isArray(self.mData['link']['original']): self.mData['link']['original'] = []
		if prepend:
			index = 0
			for i in value:
				self.mData['link']['original'].insert(index, i)
				index += 1
		else:
			self.mData['link']['original'].extend(value)
		if hoster and not self.sourceHoster():
			 hoster = self.sourceHosterExtract(self.mData['link']['original'])
			 if hoster: self.sourceHosterSet(hoster)

	'''
		FUNCTION:
			Clean the link.
		PARAMETERS:
			value (string/list): The link(s).
		RETURN:
			The cleaned link (string).
	'''
	@classmethod
	def linkClean(self, value):
		if not value: return value
		if not tools.Tools.isArray(value): value = [value]

		for i in range(len(value)):
			value[i] = self.linkCleanMagnet(value[i])

		return value

	'''
		FUNCTION:
			Decode base32 encoded hashes in magnet links.
		PARAMETERS:
			value (string): The link.
		RETURN:
			The cleaned link (string).
	'''
	@classmethod
	def linkCleanMagnet(self, value):
		if value and network.Networker.linkIsMagnet(value):
			# Some magnet links contain base32 encoded hashes.
			# The hash might be base32 encoded on one site, but not on another. Not sure if this always applies.
			# Decode if base32.
			# Realdebrid also has problems with cache lookups if base32.
			# Eg: Game of Thrones S04E01 720p HDTV x264-KILLERS [eztv]
			#	PopcornTime: 6EBA7MA2HG2JZ2RPBV4MPMURQKSEIBTA
			#	ThePirateBay: F1020FB01A39B49CEA2F0D78C7B29182A4440660
			# Also replace &amp; with &, and URL-encode parameters.
			container = network.Container(link = value, download = False)
			value = container.torrentMagnetClean()
		return value

	'''
		FUNCTION:
			Change the name in magnet links if not present or incomplete.
	'''
	def linkRename(self):
		name = self.fileName()
		if name:
			link = self.mData['link']['original']
			if link:
				for i in range(len(link)):
					if link[i] and network.Networker.linkIsMagnet(link[i]):
						link[i] = network.Container(link = link[i], download = False).torrentMagnetRename(title = name, encode = True, replace = None)
				self.mData['link']['original'] = link

	'''
		FUNCTION:
			Checks wether the link is valid.
		PARAMETERS:
			data (string): The link.
			type (string): The source type.
		RETURNS:
			Wether the link is valid (boolean).
	'''
	@classmethod
	def linkValid(self, data, type = None):
		return self.__linkValid(data = data, type = type)

	def _linkValid(self):
		return self.__linkValid(data = self.link(), type = self.sourceType())

	@classmethod
	def __linkValid(self, data, type = None):
		def __linkValid(data, type):
			if not data: return False
			elif not tools.Tools.isArray(data): data = [data]

			for link in data:
				if network.Networker.linkIsMagnet(link = link):
					# Malformed magnet link.
					if not self.hashExtract(data = link): return False

				elif network.Networker.linkIs(link = link, magnet = False):
					linkLower = link.lower()

					try: domain = network.Networker.linkDomain(link = link, subdomain = False, topdomain = False, ip = False).lower()
					except: domain = None

					try: subdomain = network.Networker.linkDomain(link = link, subdomain = True, topdomain = False, ip = False).lower().replace(domain, '').strip('.')
					except: subdomain = None

					try: extension = network.Networker.linkExtension(link = link).lower().replace('.', '').strip()
					except: extension = None

					if domain:

						# IMDb, trailer, and subntitle links (TheCrew - 2DDL).
						#	https://www.imdb.com/title/tt6264654
						#	https://www.imdb.com/video/vi3038887961
						#	https://trailers.to/video/dbgo/imdb/tt9347730
						#	https://subscene.com/subtitles/the-northman/english/2773221
						if domain in ['imdb', 'trakt', 'themoviedb', 'thetvdb', 'rottentomatoes', 'trailer', 'trailers', 'traileraddict', 'comingsoon', 'subscene']: return False

						# 2DDL links (TheCrew - 2DDL).
						#	https://img.2ddl.it/images/bIAYT.png
						#	https://2ddl.it/p/dmca
						#	https://2ddl.it/p/rss-feed
						#	https://2ddl.it/type/scene
						#	https://2ddl.it/type/p2p
						#	https://2ddl.it/author/integer
						#	https://2ddl.it/free-guy-2021-1080p-bluray-x265-rarbg/#respond
						if domain in ['2ddl', 'twoddl']: return False

						# Other links
						#	https://ronangelo.com/frontier/
						#	https://wordpress.org
						if domain in ['ronangelo', 'wordpress']: return False

						# Affiliate links (TheCrew - 2DDL).
						if domain in ['nordvpn', 'expressvpn', 'surfshark', 'ipvanish', 'privatevpn', 'ivacy']: return False

						# Guard or paste links (TheCrew - 2DDL).
						#	https://guard.li/folder/f90ac6bf
						#	https://linkguard.org/folder/5ba498cc
						#	https://controlc.com/0bc67004
						#	https://paste2.org/gsImNOKH
						#	https://pastebin.com/
						#	https://justpaste.it
						#	https://i.postimg.cc/MHcQc5mB/The-Green-Knight-2021-1080p-WEBRip-x264-RARBG-Max-Rls-mp4-thumbs.png
						#	https://www.xvinlink.com/?a_fid=TwoDDL
						#	http://new.myvideolinks.net/wp-login.php?redirect_to=http%3A%2F%2Fnew.myvideolinks.net%2F2022%2F05%2F12%2Fthe-northman-2022-1080p-webrip-1600mb-dd5-1-x264-galaxyrg%2F
						# NB: Do not exclude here. Rather add them to core.py block list.
						# Only exclude if the link cannot contain a valid file (eg: IMDb or affiliate link).
						#if domain in ['guard', 'linkguard', 'controlc', 'paste2', 'pastebin', 'justpaste', 'postimg', 'xvinlink', 'myvideolinks']: return False

					# Invalid extensions (TheCrew - 2DDL).
					# Check external hoster providers: source_utils.is_host_valid(url, hostDict)
					# NB: Do not remove archives and parts here, since that is done in exclusionFormat().
					extensions = ['png', 'jpg', 'jpeg', 'bmp', 'gif', 'tiff', 'webp', 'cbr', 'cbz', 'pdf', 'm4b', 'azw3', 'mobi', 'djvu', 'exe', 'apk', 'jar', 'deb', 'msi', 'css', 'js', 'txt', 'srt', 'sub', 'idx']
					if extension and extension in extensions: return False

					# Extensions succeeded by web extension.
					# https://rapidgator.net/file/0fdfd1558879f43b8018f1563d99ea0e/English.srt.html
					extensionsWeb = ['.htm', '.html', '.php']
					for e in extensions:
						for w in extensionsWeb:
							if linkLower.endswith('.' + e + w): return False

					# Do not do these for usenet, since many valid file names contain them.
					if not type == Stream.SourceTypeUsenet:
						if extension and extension in ['nfo']: return False

					# Pure domain without subdomain, path, or parameters (TheCrew - 2DDL).
					# Check parameters, since:
					#	https://1fichier.com/?ka6h8eaus1uwlmcw9r91
					# Also check for URL fragments:
					#	https://mega.nz/#!Gbh1CCAQ!HyalkK3Vw6D_VrlPg_Of7d6bpeJwUYGie3VlRdr9sHE
					if not network.Networker.linkPath(link = link) and not network.Networker.linkParameters(link = link) and not network.Networker.linkFragments(link = link) and (not subdomain or len(subdomain) < 5 or subdomain == domain): return False
				else:
					return False

			return True

		return self._cache(__linkValid, data = data, type = type)

	##############################################################################
	# LINK PROVIDER
	##############################################################################

	'''
		FUNCTION:
			Retrieves the provider resolved link.
		PARAMETERS:
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The provider resolved link (string).
	'''
	def linkProvider(self, default = None):
		value = self.mData['link']['provider']
		if not value: return default
		return value

	'''
		FUNCTION:
			Sets the provider resolved link.
		PARAMETERS:
			value (string): The provider resolved link.
			hoster (boolean): Extract the hoster from the links.
	'''
	def linkProviderSet(self, value, hoster = False):
		self.mData['link']['provider'] = value
		if hoster and not self.sourceResolved():
			 hoster = self.sourceResolvedExtract(value)
			 if hoster: self.sourceResolvedSet(hoster)

	##############################################################################
	# LINK STREAM
	##############################################################################

	'''
		FUNCTION:
			Retrieves the debrid resolved streaming link.
			Same as streamLink().
		PARAMETERS:
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The debrid resolved streaming link (string).
	'''
	def linkStream(self, default = None):
		value = self.streamLink()
		if not value: return default
		return value

	##############################################################################
	# LINK RESOLVED
	##############################################################################

	'''
		FUNCTION:
			Retrieves the resolved link.
			First tries to retrieve the debrid resolved link. If not availble, the providere ressolved link is retrieved. If not availble, the primary link is returned.
		PARAMETERS:
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The resolved link (string).
	'''
	def linkResolved(self, original = True, provider = True, stream = True, default = None):
		value = None
		if stream: value = self.linkStream(default = default)
		if not value and provider: value = self.linkProvider(default = default)
		if not value and original: value = self.linkPrimary(default = default)
		if not value: return default
		return value

	##############################################################################
	# HASH
	##############################################################################

	'''
		FUNCTION:
			Retrieves the hash.
		PARAMETERS:
			type (string): The type of the hash to retrieve. Or the default best one if not specified.
			algorithm (string): The algorithm of the hash to retrieve. Or the default best one if not specified.
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The hash (string).
	'''
	def hash(self, type = HashTypeDefault, algorithtm = HashAlgorithmDefault, format = FormatNone, label = LabelNone, default = None):
		try:
			value = None
			hash = self.mData['hash']

			if type and algorithtm:
				try: value = hash[type][algorithtm]
				except: pass
			elif type:
				hash = hash[type]
				for algorithm in Stream.HashAlgorithmOrder:
					if algorithm in hash and hash[algorithm]:
						value = hash[algorithm]
						break
			else:
				for type in Stream.HashTypeOrder:
					for algorithm in Stream.HashAlgorithmOrder:
						if algorithm in hash[type] and hash[type][algorithm]:
							value = hash[type][algorithm]
							break
					if value: break

			if value is None: return default
			if not label == Stream.LabelNone: value = '%s (%s %s)' % (value.upper(), type.capitalize(), algorithm.capitalize() if algorithm == Stream.HashAlgorithmUnknown else algorithm.upper())
			return value
		except:tools.Logger.error()

	def hashes(self, structure = False):
		try:
			hash = self.mData['hash']
			if structure: return hash
			return [j for i in hash.values() for j in i.values() if i and j]
		except:tools.Logger.error()

	def hashContainer(self, algorithtm = HashAlgorithmDefault, format = FormatNone, label = LabelNone, default = None):
		return self.hash(type = Stream.HashTypeContainer, algorithtm = algorithtm, format = format, label = label, default = default)

	def hashContainerUnknown(self, algorithtm = HashAlgorithmDefault, format = FormatNone, label = LabelNone, default = None):
		return self.hash(type = Stream.HashTypeContainer, algorithtm = Stream.HashAlgorithmUnknown, format = format, label = label, default = default)

	def hashContainerMd5(self, format = FormatNone, label = LabelNone, default = None):
		return self.hash(type = Stream.HashTypeContainer, algorithtm = Stream.HashAlgorithmMd5, format = format, label = label, default = default)

	def hashContainerSha1(self, format = FormatNone, label = LabelNone, default = None):
		return self.hash(type = Stream.HashTypeContainer, algorithtm = Stream.HashAlgorithmSha1, format = format, label = label, default = default)

	def hashContainerSha256(self, format = FormatNone, label = LabelNone, default = None):
		return self.hash(type = Stream.HashTypeContainer, algorithtm = Stream.HashAlgorithmSha256, format = format, label = label, default = default)

	def hashContainerSha512(self, format = FormatNone, label = LabelNone, default = None):
		return self.hash(type = Stream.HashTypeContainer, algorithtm = Stream.HashAlgorithmSha512, format = format, label = label, default = default)

	def hashFile(self, algorithtm = HashAlgorithmDefault, format = FormatNone, label = LabelNone, default = None):
		return self.hash(type = Stream.HashTypeFile, algorithtm = algorithtm, format = format, label = label, default = default)

	def hashFileUnknown(self, format = FormatNone, label = LabelNone, default = None):
		return self.hash(type = Stream.HashTypeFile, algorithtm = Stream.HashAlgorithmUnknown, format = format, label = label, default = default)

	def hashFileMd5(self, format = FormatNone, label = LabelNone, default = None):
		return self.hash(type = Stream.HashTypeFile, algorithtm = Stream.HashAlgorithmMd5, format = format, label = label, default = default)

	def hashFileSha1(self, format = FormatNone, label = LabelNone, default = None):
		return self.hash(type = Stream.HashTypeFile, algorithtm = Stream.HashAlgorithmSha1, format = format, label = label, default = default)

	def hashFileSha256(self, format = FormatNone, label = LabelNone, default = None):
		return self.hash(type = Stream.HashTypeFile, algorithtm = Stream.HashAlgorithmSha256, format = format, label = label, default = default)

	def hashFileSha512(self, format = FormatNone, label = LabelNone, default = None):
		return self.hash(type = Stream.HashTypeFile, algorithtm = Stream.HashAlgorithmSha512, format = format, label = label, default = default)

	def hashOther(self, algorithtm = HashAlgorithmDefault, format = FormatNone, label = LabelNone, default = None):
		return self.hash(type = Stream.HashTypeOther, algorithtm = algorithtm, format = format, label = label, default = default)

	def hashOtherUnknown(self, format = FormatNone, label = LabelNone, default = None):
		return self.hash(type = Stream.HashTypeOther, algorithtm = Stream.HashAlgorithmUnknown, format = format, label = label, default = default)

	def hashOtherMd5(self, format = FormatNone, label = LabelNone, default = None):
		return self.hash(type = Stream.HashTypeOther, algorithtm = Stream.HashAlgorithmMd5, format = format, label = label, default = default)

	def hashOtherSha1(self, format = FormatNone, label = LabelNone, default = None):
		return self.hash(type = Stream.HashTypeOther, algorithtm = Stream.HashAlgorithmSha1, format = format, label = label, default = default)

	def hashOtherSha256(self, format = FormatNone, label = LabelNone, default = None):
		return self.hash(type = Stream.HashTypeOther, algorithtm = Stream.HashAlgorithmSha256, format = format, label = label, default = default)

	def hashOtherSha512(self, format = FormatNone, label = LabelNone, default = None):
		return self.hash(type = Stream.HashTypeOther, algorithtm = Stream.HashAlgorithmSha512, format = format, label = label, default = default)

	'''
		FUNCTION:
			Sets the hash.
		PARAMETERS:
			value (string): The hash.
			type (string): The type of the hash. If not provided, HashTypeOther is assumed.
			algorithm (string): The algorithm of the hash. If not provided, the algorithm is determined from the length of the hash.
		RETURNS:
			The extracted and processed value that was set (string/None).
	'''
	def hashSet(self, value, type = HashAlgorithmDefault, algorithtm = HashAlgorithmDefault):
		value = value.lower() if value else value
		if not type: type = Stream.HashTypeOther
		if not algorithtm: algorithtm = self.hashAlgorithm(value)
		self.mData['hash'][type][algorithtm] = value
		return value

	def hashContainerSet(self, value, algorithtm = HashAlgorithmDefault):
		return self.hashSet(type = Stream.HashTypeContainer, algorithtm = algorithtm, value = value)

	def hashContainerUnknownSet(self, value):
		return self.hashSet(type = Stream.HashTypeContainer, algorithtm = Stream.HashAlgorithmUnknown, value = value)

	def hashContainerMd5Set(self, value):
		return self.hashSet(type = Stream.HashTypeContainer, algorithtm = Stream.HashAlgorithmMd5, value = value)

	def hashContainerSha1Set(self, value):
		return self.hashSet(type = Stream.HashTypeContainer, algorithtm = Stream.HashAlgorithmSha1, value = value)

	def hashContainerSha256Set(self, value):
		return self.hashSet(type = Stream.HashTypeContainer, algorithtm = Stream.HashAlgorithmSha256, value = value)

	def hashContainerSha512Set(self, value):
		return self.hashSet(type = Stream.HashTypeContainer, algorithtm = Stream.HashAlgorithmSha512, value = value)

	def hashFileSet(self, value, algorithtm = HashAlgorithmDefault):
		return self.hashSet(type = Stream.HashTypeFile, algorithtm = algorithtm, value = value)

	def hashFileUnknownSet(self, value):
		return self.hashSet(type = Stream.HashTypeFile, algorithtm = Stream.HashAlgorithmUnknown, value = value)

	def hashFileMd5Set(self, value):
		return self.hashSet(type = Stream.HashTypeFile, algorithtm = Stream.HashAlgorithmMd5, value = value)

	def hashFileSha1Set(self, value):
		return self.hashSet(type = Stream.HashTypeFile, algorithtm = Stream.HashAlgorithmSha1, value = value)

	def hashFileSha256Set(self, value):
		return self.hashSet(type = Stream.HashTypeFile, algorithtm = Stream.HashAlgorithmSha256, value = value)

	def hashFileSha512Set(self, value):
		return self.hashSet(type = Stream.HashTypeFile, algorithtm = Stream.HashAlgorithmSha512, value = value)

	def hashOtherSet(self, value, algorithtm = HashAlgorithmDefault):
		return self.hashSet(type = Stream.HashTypeOther, algorithtm = algorithtm, value = value)

	def hashOtherUnknownSet(self, value):
		return self.hashSet(type = Stream.HashTypeOther, algorithtm = Stream.HashAlgorithmUnknown, value = value)

	def hashOtherMd5Set(self, value):
		return self.hashSet(type = Stream.HashTypeOther, algorithtm = Stream.HashAlgorithmMd5, value = value)

	def hashOtherSha1Set(self, value):
		return self.hashSet(type = Stream.HashTypeOther, algorithtm = Stream.HashAlgorithmSha1, value = value)

	def hashOtherSha256Set(self, value):
		return self.hashSet(type = Stream.HashTypeOther, algorithtm = Stream.HashAlgorithmSha256, value = value)

	def hashOtherSha512Set(self, value):
		return self.hashSet(type = Stream.HashTypeOther, algorithtm = Stream.HashAlgorithmSha512, value = value)

	'''
		FUNCTION:
			Extracts the hash from a torrent magnet.
		PARAMETERS:
			data (string): The torrent magnet.
		RETURNS:
			The hash info (dictionary/None) {'type' : 'xxx', 'algorithm' : 'xxx', 'hash' : 'xxx'}.
	'''
	@classmethod
	def hashExtract(self, data):
		if data:
			if not tools.Tools.isArray(data): data = [data]
			for d in data:
				container = network.Container(link = d, download = False)
				if container.torrentIsMagnet():
					hash = container.hash()
					if hash: return {'type' : Stream.HashTypeContainer, 'algorithm' : self.hashAlgorithm(hash), 'hash' : hash.lower()}
		return None

	'''
		FUNCTION:
			Determines the hash algorithm based on the length of the hash.
		PARAMETERS:
			data (string): The hash.
		RETURNS:
			The hash algorithm (string).
	'''
	@classmethod
	def hashAlgorithm(self, data):
		if data:
			length = len(data.strip())
			for key, value in Stream.HashLength.items():
				if length == value: return key
			return Stream.HashAlgorithmUnknown
		return None

	##############################################################################
	# VIDEO QUALITY
	##############################################################################

	'''
		FUNCTION:
			Retrieves the video quality.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			exact (enumeration): Wether or not return the estimated/inexact video quality if the exact video quality is not available.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The video quality (string).
	'''
	def videoQuality(self, format = FormatNone, label = LabelNone, exact = ExactAuto, default = None):
		value = self.exact(exact = exact, data = self.mData['video']['quality'])
		if value is None: return default
		if format == Stream.FormatKodi:
			value = Stream.KodiVideoQuality[value]
		else:
			original = value
			label = self.settingsLayout(label, 'video', 'quality')
			value = self._label(value = value, values = Stream.LabelVideoQuality, format = format, label = label)
			value = self._decorate(value = value, format = format, bold = True, color = self.videoQualityColor, colorvalue = original)
		return value

	'''
		FUNCTION:
			Sets the video quality.
		PARAMETERS:
			value (string): The video quality.
			extract (boolean): Wether to extract the value or accept the raw value as is.
			exact (enumeration): Wether or not the video quality is estimated/inexact, or otherwise an exact video quality.
		RETURNS:
			The extracted and processed value that was set (string/None).
	'''
	def videoQualitySet(self, value, extract = True, exact = ExactYes):
		value = self.videoQualityExtract(data = value, clean = False) if extract else value
		self.exactSet(exact = exact, data = self.mData['video']['quality'], value = value)
		return value

	'''
		FUNCTION:
			Extracts the release type from a string.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			clean (boolean): Wether or not to clean the data before processing.
		RETURNS:
			The release type (string).
	'''
	@classmethod
	def videoQualityExtract(self, data, exclude = None, encode = True, default = True, clean = True):
		if clean: data = self.cleanBasic(data)
		if not data: return Stream.VideoQualityDefault if default is True else default
		if encode: exclude = self.cleanEncode(exclude)

		result = self._expressionNestedMatch(id = 'videoQualityExtract', data = data, type = Stream.ExpressionNonsequential, expression = Stream.ExpressionVideoQuality, exclude = exclude)
		if not result and exclude: # If nothing is found, try without the title exclusions.
			result = self._expressionNestedMatch(id = 'videoQualityExtract', data = data, type = Stream.ExpressionNonsequential, expression = Stream.ExpressionVideoQuality)
		if not result and default: result = Stream.VideoQualityDefault if default is True else default
		return result

	'''
		FUNCTION:
			Cleans a file name from video quality keywords.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			guidance (None/string): The already detected video quality. Speeds up the cleaning by only removing previously detected keywords, instead of scanning through all keywords.
			split (None/string): If SplitRight/SplitLeft, cuts off the string after/before the first found keyword. If None, simply remove the keyword and keep the rest of the string intact.
		RETURNS:
			The cleaned file name (string).
	'''
	@classmethod
	def videoQualityClean(self, data, exclude = None, encode = True, guidance = None, split = SplitNone):
		if not data: return data
		if encode: exclude = self.cleanEncode(exclude)
		expression = self._expressionNestedLinear(id = 'videoQualityClean1', expression = Stream.ExpressionVideoQuality)
		count = self._expressionCount(expression) * 4
		expression = self._expressionFormatKeyword(id = 'videoQualityClean2', expression = expression, exclude = exclude, guidance = guidance)
		return self._expressionReplace(id = 'videoQualityClean_' + str(guidance), data = data, expression = expression, count = count, split = split)

	'''
		FUNCTION:
			Retrieve the gradient color for the video quality.
		PARAMETERS:
			value (string): The video quality.
		RETURNS:
			The video quality color (string).
	'''
	@classmethod
	def videoQualityColor(self, value):
		return self._cache(interface.Format.colorQuality, value)

	'''
		FUNCTION:
			Checks if the video quality is in a specific category (ultra, hd, sd, scr, cam).
		PARAMETERS:
			category (None/string): An optional category to match, which returns a boolean. If not provided, the category instead of a boolean is returned.
			exact (enumeration): Wether or not return the estimated/inexact video quality if the exact video quality is not available.
		RETURNS:
			The video quality category (string/boolean).
	'''
	def videoQualityCategory(self, category = None, exact = ExactAuto):
		result = Stream.CategoryVideoQuality[self.videoQuality(exact = exact)]
		if category: return result == category
		else: return result

	##############################################################################
	# VIDEO RESOLUTION
	##############################################################################

	'''
		FUNCTION:
			Retrieves the video resolution.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			exact (enumeration): Wether or not return the estimated/inexact video resolution if the exact video resolution is not available.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The video resolution (dictionary).
	'''
	def videoResolution(self, format = FormatNone, label = LabelNone, exact = ExactAuto, default = None):
		value = self.exact(exact = exact, data = self.mData['video']['resolution'], sub = Stream.VideoHeight)
		if value is None: return default
		if format == Stream.FormatKodi:
			return value[Stream.VideoWidth], value[Stream.VideoHeight]
		if value[Stream.VideoWidth] is None and value[Stream.VideoHeight] is None: return default
		elif not format == Stream.FormatNone or not label == Stream.LabelNone:
			original = value
			if label == Stream.LabelLong or label == Stream.LabelDetails: value = '{width} x {height}'.format(**value)
			elif label == Stream.LabelMedium or label == Stream.LabelShort: value = '{width}x{height}'.format(**value)
			value = self._decorate(value = value, format = format, color = self.videoResolutionColor, colorvalue = original)
		return value

	'''
		FUNCTION:
			Sets the video resolution.
			Either set the resolution or the width/height.
		PARAMETERS:
			resolution (dictionary): The video resolution.
			width (None/integer): The resolution width.
			height (None/integer): The resolution height.
			exact (enumeration): Wether or not the video resolution is estimated/inexact, or otherwise an exact video resolution.
		RETURNS:
			The extracted and processed value that was set (dictionary/None).
	'''
	def videoResolutionSet(self, resolution = None, width = None, height = None, exact = ExactYes):
		type = 'inexact' if exact is Stream.ExactNo else 'exact'
		if not resolution is None:
			if tools.Tools.isString(resolution):
				resolution = self.videoResolutionExtract(data = resolution, resolution = True)
			if tools.Tools.isDictionary(resolution):
				width = resolution[Stream.VideoWidth]
				height = resolution[Stream.VideoHeight]
		if not width is None: self.mData['video']['resolution'][type][Stream.VideoWidth] = int(width)
		if not height is None: self.mData['video']['resolution'][type][Stream.VideoHeight] = int(height)
		return self.mData['video']['resolution'][type] if self.mData['video']['resolution'][type][Stream.VideoWidth] or self.mData['video']['resolution'][type][Stream.VideoHeight] else None

	'''
		FUNCTION:
			Extracts the video resolution from a string.
			It extracts the video quality and then estimates the resolution from it.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching (eg: "Cam (2018) 1080p" should not match CAM1080).
			default (boolean/string): Wether or not to return the default quality if no quality could be detected. Alternatively a default video quality string can be used.
			clean (boolean): Wether or not to clean the data before processing.
			resolution (boolean): Wether or not the data is a resolution string. If True, the data is a resolution striong (eg: 1920 x 1080). If False, the data is assumed to be a file name or quyality.
		RETURNS:
			The video quality (string).
	'''
	@classmethod
	def videoResolutionExtract(self, data, exclude = None, default = True, clean = True, resolution = False):
		if resolution:
			value = self._cacheId('videoResolutionExtract', re.compile, '(\d+)\s*[x\*]\s*(\d+)', flags = Stream.ExpressionFlags).search(data)
			if value:
				try:
					result = {
						Stream.VideoWidth : int(value.group(1)),
						Stream.VideoHeight : int(value.group(2)),
					}
					return result
				except: tools.Logger.error()
		quality = self.videoQualityExtract(data = data, exclude = exclude, default = default, clean = clean)
		return self.videoResolutionConvert(quality = quality, default = default)

	'''
		FUNCTION:
			Converts the video quality to the video resolution, or vice versa.
			Either set the quality, the resolution, or the width/height.
		PARAMETERS:
			quality (None/string): Converts the quality to the resolution.
			resolution (dictionary): Converts the resolution to the quality.
			width (None/integer): Converts the width resolution to the quality.
			height (None/integer): Converts the height resolution to the quality.
			default (boolean/string): Wether or not to return the default resolution if no resolution could be detected. Alternatively a default video quality string can be used.
		RETURNS:
			The video quality (string) or the video resolution (dictionary).
	'''
	@classmethod
	def videoResolutionConvert(self, quality = None, resolution = None, width = None, height = None, default = False):
		try:
			if quality:
				quality = quality.lower()

				for i in Stream.VideoResolution:
					if i[0] == quality: return i[1]

				quality = self.videoQualityExtract(data = quality, default = False, clean = False)
				for i in Stream.VideoResolution:
					if i[0] == quality: return i[1]

				quality = Stream.VideoResolutionDefault if default is True else default
				for i in Stream.VideoResolution:
					if i[0] == quality: return i[1]

				return None
			else:
				if resolution:
					if width is None: width = resolution[Stream.VideoWidth]
					if height is None: height = resolution[Stream.VideoHeight]

				# Technically the resolution should be determined from the height before looking at the width.
				# However, many files are marked as eg 1080p with aa resolution of 1920x840.
				# Mark this as 1080p and not 720p, by first looking at the width and then the height.

				if width:
					for i in Stream.VideoResolution:
						if not i[0] == Stream.VideoQualityNone and width >= i[1][Stream.VideoWidth] - Stream.VideoResolutionThreshold: return i[0]

				if height:
					for i in Stream.VideoResolution:
						if not i[0] == Stream.VideoQualityNone and height >= i[1][Stream.VideoHeight] - Stream.VideoResolutionThreshold: return i[0]

				if default: return Stream.VideoResolutionDefault if default is True else default
				else: return None
		except:
			tools.Logger.error()

	'''
		FUNCTION:
			Cleans a file name from video resultion keywords.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			split (None/string): If SplitRight/SplitLeft, cuts off the string after/before the first found keyword. If None, simply remove the keyword and keep the rest of the string intact.
		RETURNS:
			The cleaned file name (string).
	'''
	@classmethod
	def videoResolutionClean(self, data, exclude = None, encode = True, split = SplitNone):
		if not data: return data
		if encode: exclude = self.cleanEncode(exclude)
		expression = self._cacheId('videoResolutionClean', self._expressionFormatCommon, expression = Stream.ExpressionVideoResolution)
		return self._expressionReplace(id = 'videoResolutionClean', data = data, expression = expression, exclude = exclude, count = 1, split = split)

	'''
		FUNCTION:
			Retrieve the gradient color for the video resolution.
		PARAMETERS:
			value (string): The video quality.
		RETURNS:
			The video resolution color (string).
	'''
	@classmethod
	def videoResolutionColor(self, value):
		return self.videoQualityColor(value = value)

	##############################################################################
	# VIDEO WIDTH
	##############################################################################

	'''
		FUNCTION:
			Retrieves the video resolution width.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			exact (enumeration): Wether or not return the estimated/inexact video width if the exact video width is not available.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The video resolution width (integer).
	'''
	def videoWidth(self, format = FormatNone, label = LabelNone, exact = ExactAuto, default = None):
		value = self.exactSub(exact = exact, data = self.mData['video']['resolution'], sub = Stream.VideoWidth)
		if value is None: return default
		return value

	'''
		FUNCTION:
			Sets the video resolution width.
		PARAMETERS:
			value (integer): The resolution width.
			exact (enumeration): Wether or not the video width is estimated/inexact, or otherwise an exact video width.
		RETURNS:
			The extracted and processed value that was set (integer/None).
	'''
	def videoWidthSet(self, value, exact = ExactYes):
		if not value is None:
			value = int(value)
			self.exactSubSet(exact = exact, data = self.mData['video']['resolution'], value = value, sub = Stream.VideoWidth)
		return value

	##############################################################################
	# VIDEO HEIGHT
	##############################################################################

	'''
		FUNCTION:
			Retrieves the video resolution height.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			exact (enumeration): Wether or not return the estimated/inexact video height if the exact video height is not available.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The video resolution height (integer).
	'''
	def videoHeight(self, format = FormatNone, label = LabelNone, exact = ExactAuto, default = None):
		value = self.exactSub(exact = exact, data = self.mData['video']['resolution'], sub = Stream.VideoHeight)
		if value is None: return default
		return value

	'''
		FUNCTION:
			Sets the video resolution height.
		PARAMETERS:
			value (integer): The resolution height.
			exact (enumeration): Wether or not the video height is estimated/inexact, or otherwise an exact video height.
		RETURNS:
			The extracted and processed value that was set (integer/None).
	'''
	def videoHeightSet(self, value, exact = ExactYes):
		if not value is None:
			value = int(value)
			self.exactSubSet(exact = exact, data = self.mData['video']['resolution'], value = value, sub = Stream.VideoHeight)
		return value

	##############################################################################
	# VIDEO ASPECT
	##############################################################################

	'''
		FUNCTION:
			Retrieves the video aspect ratio.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			exact (enumeration): Wether or not return the estimated/inexact aspect ratio if the exact aspect ratio is not available.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The video aspect ratio (float).
	'''
	def videoAspect(self, format = FormatNone, label = LabelNone, exact = ExactAuto, default = None):
		value = self.exact(exact = exact, data = self.mData['video']['aspect'])
		if value is None: return default
		if format == Stream.FormatKodi:
			value = tools.Math.closest(list = Stream.KodiVideoAspect, value = value)
		elif not format == Stream.FormatNone or not label == Stream.LabelNone:
			original = self.videoQuality(exact = exact)
			if label == Stream.LabelLong: value = '%.2f : 1' % value
			elif label == Stream.LabelMedium: value = '%.2f:1' % value
			elif label == Stream.LabelShort: value = '%.2f' % value
			value = self._decorate(value = value, format = format, color = self.videoAspectColor, colorvalue = original)
		return value

	'''
		FUNCTION:
			Sets the video aspect ratio.
		PARAMETERS:
			value (float): The video aspect ratio.
			exact (enumeration): Wether or not the aspect ratio is estimated/inexact, or otherwise an exact aspect ratio.
		RETURNS:
			The extracted and processed value that was set (float/None).
	'''
	def videoAspectSet(self, value, exact = ExactYes):
		if value: value = round(value, 2)
		self.exactSet(exact = exact, data = self.mData['video']['aspect'], value = value)
		return value

	'''
		FUNCTION:
			Extracts the video aspect ratio from a string.
			It extracts the video quality, converts it to a resolution, and then estimates the aspect ratio from it.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			default (boolean/string): Wether or not to return the default aspect ratio if no aspect ratio could be detected.
			clean (boolean): Wether or not to clean the data before processing.
		RETURNS:
			The video aspect ratio (float).
	'''
	@classmethod
	def videoAspectExtract(self, data, exclude = None, default = True, clean = True):
		resolution = self.videoResolutionExtract(data = data, exclude = exclude, default = default, clean = clean)
		return self.videoAspectConvert(resolution = resolution, default = default)

	'''
		FUNCTION:
			Converts the video quality or resolution to the video aspect ratio.
			Either set the quality, the resolution, or the width/height.
		PARAMETERS:
			quality (None/string): Converts the quality to the resolution.
			resolution (dictionary): Converts the resolution to the quality.
			width (None/integer): Converts the width resolution to the quality.
			height (None/integer): Converts the height resolution to the quality.
			default (boolean/string): Wether or not to return the default aspect ratio if no aspect ratio could be detected. Alternatively a default aspect ratio float can be used.
		RETURNS:
			The video aspect ratio (float).
	'''
	@classmethod
	def videoAspectConvert(self, quality = None, resolution = None, width = None, height = None, default = False):
		if quality and (width is None or height is None):
			resolution = self.videoResolutionConvert(quality = quality, default = default)
		if resolution:
			if width is None: width = resolution[Stream.VideoWidth]
			if height is None: height = resolution[Stream.VideoHeight]
		if not width or not height: return None
		ratio = width / float(height)
		return tools.Math.closest(list = Stream.VideoAspect, value = ratio)

	'''
		FUNCTION:
			Retrieve the gradient color for the video aspect ratio.
		PARAMETERS:
			value (string): The video quality.
		RETURNS:
			The video aspect ratio color (string).
	'''
	@classmethod
	def videoAspectColor(self, value):
		return self.videoQualityColor(value = value)

	##############################################################################
	# VIDEO CODEC
	##############################################################################

	'''
		FUNCTION:
			Retrieves the video codec.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The video codec (string).
	'''
	def videoCodec(self, format = FormatNone, label = LabelNone, default = None):
		value = self.mData['video']['codec']
		if value is None: return default
		if format == Stream.FormatKodi:
			value = Stream.KodiVideoCodec[value]
		else:
			label = self.settingsLayout(label, 'video', 'codec')
			value = self._label(value = value, values = Stream.LabelVideoCodec, format = format, label = label)
		return value

	'''
		FUNCTION:
			Sets the video codec.
		PARAMETERS:
			value (string): The video codec.
			extract (boolean): Wether to extract the value or accept the raw value as is.
		RETURNS:
			The extracted and processed value that was set (string/None).
	'''
	def videoCodecSet(self, value, extract = True):
		value = self.videoCodecExtract(data = value, clean = False) if extract else value
		self.mData['video']['codec'] = value
		return value

	'''
		FUNCTION:
			Extracts the video codec from a string.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			clean (boolean): Wether or not to clean the data before processing.
		RETURNS:
			The video codec (string).
	'''
	@classmethod
	def videoCodecExtract(self, data, exclude = None, encode = True, clean = True):
		if not data: return None
		if clean: data = self.cleanBasic(data)
		if encode: exclude = self.cleanEncode(exclude)

		expression = self._expressionFormatExpression(id = 'videoCodecExtract', type = Stream.ExpressionSequential, expression = Stream.ExpressionVideoCodec)
		return self._expressionMatchType(id = 'videoCodecExtract', data = data, expression = expression, exclude = exclude)

	'''
		FUNCTION:
			Cleans a file name from video codec keywords.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			guidance (None/string): The already detected video codec. Speeds up the cleaning by only removing previously detected keywords, instead of scanning through all keywords.
			split (None/string): If SplitRight/SplitLeft, cuts off the string after/before the first found keyword. If None, simply remove the keyword and keep the rest of the string intact.
		RETURNS:
			The cleaned file name (string).
	'''
	@classmethod
	def videoCodecClean(self, data, exclude = None, encode = True, guidance = None, split = SplitNone):
		if not data: return data
		if encode: exclude = self.cleanEncode(exclude)
		count = self._expressionCount(Stream.ExpressionVideoCodec)
		expression = self._expressionFormatKeyword(id = 'videoCodecClean', expression = Stream.ExpressionVideoCodec, guidance = guidance)
		return self._expressionReplace(id = 'videoCodecClean_' + str(guidance), data = data, expression = expression, exclude = exclude, count = count, split = split)

	##############################################################################
	# VIDEO DEPTH
	##############################################################################

	'''
		FUNCTION:
			Retrieves the video bit depth.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The video bit depth (string).
	'''
	def videoDepth(self, format = FormatNone, label = LabelNone, default = None):
		value = self.mData['video']['depth']
		if value is None: return default
		label = self.settingsLayout(label, 'video', 'depth')
		value = self._label(value = value, values = Stream.LabelVideoDepth, format = format, label = label)
		value = self._decorate(value = value, format = format, color = self.videoDepthColor, colorvalue = self.mData['video']['depth'])
		return value

	'''
		FUNCTION:
			Sets the video bit depth.
		PARAMETERS:
			value (string): The video bit depth.
			extract (boolean): Wether to extract the value or accept the raw value as is.
		RETURNS:
			The extracted and processed value that was set (string/None).
	'''
	def videoDepthSet(self, value, extract = True):
		value = self.videoDepthExtract(data = value, clean = False) if extract else value
		self.mData['video']['depth'] = value
		return value

	'''
		FUNCTION:
			Extracts the video bit depth from a string.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			clean (boolean): Wether or not to clean the data before processing.
		RETURNS:
			The video bit depth (string).
	'''
	@classmethod
	def videoDepthExtract(self, data, exclude = None, encode = True, clean = True):
		if not data: return None
		if tools.Tools.isNumber(data): data = str(data) + Stream.VideoDepthBit
		if clean: data = self.cleanBasic(data)
		if encode: exclude = self.cleanEncode(exclude)

		expression = self._expressionFormatExpression(id = 'videoDepthExtract', type = Stream.ExpressionSequential, expression = Stream.ExpressionVideoDepth)
		return self._expressionMatchType(id = 'videoDepthExtract', data = data, expression = expression, exclude = exclude)

	'''
		FUNCTION:
			Cleans a file name from video bit depth keywords.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			guidance (None/string): The already detected video bit depth. Speeds up the cleaning by only removing previously detected keywords, instead of scanning through all keywords.
			split (None/string): If SplitRight/SplitLeft, cuts off the string after/before the first found keyword. If None, simply remove the keyword and keep the rest of the string intact.
		RETURNS:
			The cleaned file name (string).
	'''
	@classmethod
	def videoDepthClean(self, data, exclude = None, encode = True, guidance = None, split = SplitNone):
		if not data: return data
		if encode: exclude = self.cleanEncode(exclude)
		count = self._expressionCount(Stream.ExpressionVideoDepth)
		expression = self._expressionFormatKeyword(id = 'videoDepthClean', expression = Stream.ExpressionVideoDepth, guidance = guidance)
		return self._expressionReplace(id = 'videoDepthClean_' + str(guidance), data = data, expression = expression, exclude = exclude, count = count, split = split)

	'''
		FUNCTION:
			Retrieve the gradient color for the video depth.
		PARAMETERS:
			value (string): The video depth.
		RETURNS:
			The video depth color (string).
	'''
	@classmethod
	def videoDepthColor(self, value):
		return self._color(value = value, values = Stream.ExpressionVideoDepth)

	##############################################################################
	# VIDEO RANGE
	##############################################################################

	'''
		FUNCTION:
			Retrieves the video dynamic range technique.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The video dynamic range technique (string).
	'''
	def videoRange(self, format = FormatNone, label = LabelNone, default = None):
		value = self.mData['video']['range']
		if value is None: return default
		label = self.settingsLayout(label, 'video', 'range')
		value = self._label(value = value, values = Stream.LabelVideoRange, format = format, label = label)
		value = self._decorate(value = value, format = format, color = self.videoRangeColor, colorvalue = self.mData['video']['range'])
		return value

	'''
		FUNCTION:
			Sets the video dynamic range technique.
		PARAMETERS:
			value (string): The video dynamic range technique.
			extract (boolean): Wether to extract the value or accept the raw value as is.
		RETURNS:
			The extracted and processed value that was set (string/None).
	'''
	def videoRangeSet(self, value, extract = True):
		value = self.videoRangeExtract(data = value, clean = False) if extract else value
		self.mData['video']['range'] = value
		return value

	'''
		FUNCTION:
			Determines if the video range is Dolby Vision.
		RETURNS:
			If the video range is Dolby Vision (boolean).
	'''
	def videoRangeDolby(self):
		range = self.videoRange()
		return range and range in Stream.VideoRangeDolby

	'''
		FUNCTION:
			Extracts the video dynamic range technique from a string.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			clean (boolean): Wether or not to clean the data before processing.
		RETURNS:
			The video dynamic range technique (string).
	'''
	@classmethod
	def videoRangeExtract(self, data, exclude = None, encode = True, clean = True):
		if not data: return None
		if clean: data = self.cleanBasic(data)
		if encode: exclude = self.cleanEncode(exclude)

		expression = self._expressionFormatExpression(id = 'videoRangeExtract', type = Stream.ExpressionNonsequential, expression = Stream.ExpressionVideoRange)
		return self._expressionMatchType(id = 'videoRangeExtract', data = data, expression = expression, exclude = exclude)

	'''
		FUNCTION:
			Cleans a file name from video dynamic range technique keywords.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			guidance (None/string): The already detected video dynamic range technique. Speeds up the cleaning by only removing previously detected keywords, instead of scanning through all keywords.
			split (None/string): If SplitRight/SplitLeft, cuts off the string after/before the first found keyword. If None, simply remove the keyword and keep the rest of the string intact.
		RETURNS:
			The cleaned file name (string).
	'''
	@classmethod
	def videoRangeClean(self, data, exclude = None, encode = True, guidance = None, split = SplitNone):
		if not data: return data
		if encode: exclude = self.cleanEncode(exclude)
		count = self._expressionCount(Stream.ExpressionVideoRange)
		expression = self._expressionFormatKeyword(id = 'videoRangeClean', expression = Stream.ExpressionVideoRange, guidance = guidance)
		return self._expressionReplace(id = 'videoRangeClean_' + str(guidance), data = data, expression = expression, exclude = exclude, count = count, split = split)

	'''
		FUNCTION:
			Retrieve the gradient color for the video range.
		PARAMETERS:
			value (string): The video range.
		RETURNS:
			The video range color (string).
	'''
	@classmethod
	def videoRangeColor(self, value):
		return self._color(value = value, values = Stream.ExpressionVideoRange)

	##############################################################################
	# VIDEO 3D
	##############################################################################

	'''
		FUNCTION:
			Retrieves the video 3D type.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The video 3D type (string).
	'''
	def video3d(self, format = FormatNone, label = LabelNone, default = None):
		value = self.mData['video']['3d']
		if value is None: return default
		if format == Stream.FormatKodi:
			value = Stream.KodiVideo3d[value]
		elif not label == Stream.LabelNone:
			label = self.settingsLayout(label, 'video', '3d')
			value2 = value
			value = self._label(value = value, values = Stream.LabelVideo3d, format = format, label = label)
			general = self._label(value = Stream.Video3d, values = Stream.LabelVideo3d, format = format, label = label)
			if label == Stream.LabelMedium: value = general if value2 == Stream.Video3d or value2 == Stream.Video3dStereo else (general + '-' + value)
			value = self._decorate(value = value, format = format, color = self.video3dColor, colorvalue = self.mData['video']['3d'])
		return value

	'''
		FUNCTION:
			Sets the video 3D type.
		PARAMETERS:
			value (string): The video 3D type.
			extract (boolean): Wether to extract the value or accept the raw value as is.
		RETURNS:
			The extracted and processed value that was set (string/None).
	'''
	def video3dSet(self, value, extract = True):
		value = self.video3dExtract(data = value, clean = False) if extract else value
		self.mData['video']['3d'] = value
		return value

	'''
		FUNCTION:
			Extracts the video 3D type from a string.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			clean (boolean): Wether or not to clean the data before processing.
		RETURNS:
			The video 3D type (string).
	'''
	@classmethod
	def video3dExtract(self, data, exclude = None, encode = True, clean = True):
		if not data: return None
		if data is True: return Stream.Video3d
		if clean: data = self.cleanBasic(data)
		if exclude:
			if encode: exclude = self.cleanEncode(exclude)
			exclude = self._video3dExclude(exclude)
		expression = self._expressionFormatExpression(id = 'video3dExtract', type = Stream.ExpressionSequential, expression = Stream.ExpressionVideo3d)
		return self._expressionMatchType(id = 'video3dExtract', data = data, expression = expression, exclude = exclude)

	'''
		FUNCTION:
			Cleans a file name from video 3D keywords.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			guidance (None/string): The already detected video 3D. Speeds up the cleaning by only removing previously detected keywords, instead of scanning through all keywords.
			split (None/string): If SplitRight/SplitLeft, cuts off the string after/before the first found keyword. If None, simply remove the keyword and keep the rest of the string intact.
		RETURNS:
			The cleaned file name (string).
	'''
	@classmethod
	def video3dClean(self, data, exclude = None, encode = True, guidance = None, split = SplitNone):
		if not data: return data
		if exclude:
			if encode: exclude = self.cleanEncode(exclude)
			exclude = self._video3dExclude(exclude)
		count = self._expressionCount(Stream.ExpressionVideo3d)
		expression = self._expressionFormatKeyword(id = 'video3dClean', expression = Stream.ExpressionVideo3d, guidance = guidance)
		expression = list(expression)
		expression.append(Stream.ExpressionVideo3d['keyword']['standalone'])
		return self._expressionReplace(id = 'video3dClean_' + str(guidance), data = data, expression = expression, exclude = exclude, count = count, split = split)

	'''
		FUNCTION:
			Retrieve the gradient color for the video 3D.
		PARAMETERS:
			value (string): The video 3D.
		RETURNS:
			The video 3D color (string).
	'''
	@classmethod
	def video3dColor(self, value):
		return interface.Format.colorPoor()

	'''
		FUNCTION:
			Cleans a exclude titles from 3D keywords.
			Many alternative titles include the edition (eg Avatar 3D).
			Remove those edition keywords first, otherwise it won't match due to exclude.
	'''
	@classmethod
	def _video3dExclude(self, exclude = None):
		def __video3dExclude(exclude):
			if exclude:
				expression = self._expressionFormatKeyword(id = 'video3dClean', expression = Stream.ExpressionVideo3d)
				expressionVersion1 = self._video3dStandalone(wrap = True)
				expressionVersion2 = self._video3dStandalone(wrap = False)
				temp = []
				if not tools.Tools.isArray(exclude): exclude = [exclude]
				for data in exclude:
					if self._expressionMatch(id = '_video3dExclude1', data = data, expression = expressionVersion1):
						data = self._expressionReplace(id = 'video3dClean1', data = data, expression = expression)
						data = self._expressionReplace(id = 'video3dClean2', data = data, expression = expressionVersion2)
						temp.append(self._cacheId('_video3dExclude2', re.compile, '\s+', flags = Stream.ExpressionFlags).sub(' ', data).strip())
					else:
						temp.append(data)
				seen = set()
				exclude = [i for i in temp if not (i in seen or seen.add(i))]
			return exclude
		return self._cache(__video3dExclude, exclude = exclude)

	@classmethod
	def _video3dStandalone(self, wrap = True):
		result = '(' + self._expressionFormatCommon(Stream.ExpressionVideo3d['keyword']['standalone']) + ')'
		if wrap: result = Stream.ExpressionSymbolStart + result + Stream.ExpressionSymbolEnd
		return result

	##############################################################################
	# AUDIO TYPE
	##############################################################################

	'''
		FUNCTION:
			Retrieves the audio type.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			original (boolean): Whether or not to return the type if it is original.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The audio type (string).
	'''
	def audioType(self, format = FormatNone, label = LabelNone, original = True, default = None):
		value = self.mData['audio']['type']
		if value is None: return default
		if not original and value == Stream.AudioTypeOriginal: return default
		if not label == Stream.LabelNone:
			label = self.settingsLayout(label, 'audio', 'type')
			value = self._label(value = value, values = Stream.LabelAudioType, format = format, label = label)
			value = self._decorate(value = value, format = format, uppercase = True, color = self.audioTypeColor, colorvalue = self.mData['audio']['type'])
		return value

	'''
		FUNCTION:
			Sets the audio type.
		PARAMETERS:
			value (string): The audio type.
			extract (boolean): Wether to extract the value or accept the raw value as is.
		RETURNS:
			The extracted and processed value that was set (string/None).
	'''
	def audioTypeSet(self, value, extract = True):
		value = self.audioTypeExtract(data = value, clean = False) if extract else value
		self.mData['audio']['type'] = value
		return value

	'''
		FUNCTION:
			Extracts the audio type from a string.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			clean (boolean): Wether or not to clean the data before processing.
		RETURNS:
			The audio type (string).
	'''
	@classmethod
	def audioTypeExtract(self, data, exclude = None, encode = True, clean = True):
		if not data: return None
		if clean: data = self.cleanBasic(data)
		if encode: exclude = self.cleanEncode(exclude)

		expression = self._expressionFormatExpression(id = 'audioTypeExtract1', type = Stream.ExpressionSequential, expression = Stream.ExpressionAudioType)
		result = self._expressionMatchType(id = 'audioTypeExtract2', data = data, expression = expression, exclude = exclude)

		# Find the fixed dubbed keywords (eg RUDUB).
		# Eg: The.Old.Man.s01.WEBRip.XviD.RuDub.tv
		if not result:
			languagesCommon = self._languageKeyword(common = True)
			expressionDubbed = self._expressionFormatCommon(Stream.ExpressionAudioType['keyword']['dubbed'])
			languagesExpressions = []
			for language in languagesCommon:
				languagesExpressions.append((language['code'], language['expression']))
			match = self._expressionMatchMultiple(id = 'audioTypeExtract3', data = data, expression = languagesExpressions, end = expressionDubbed, full = True)
			if match: result = Stream.AudioTypeDubbed

		if not result: result = Stream.AudioTypeDefault
		return result

	'''
		FUNCTION:
			Cleans a file name from audio type keywords.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			guidance (None/string): The already detected audio type. Speeds up the cleaning by only removing previously detected keywords, instead of scanning through all keywords.
			split (None/string): If SplitRight/SplitLeft, cuts off the string after/before the first found keyword. If None, simply remove the keyword and keep the rest of the string intact.
		RETURNS:
			The cleaned file name (string).
	'''
	@classmethod
	def audioTypeClean(self, data, exclude = None, encode = True, guidance = None, split = SplitNone):
		if not data: return data
		if encode: exclude = self.cleanEncode(exclude)
		count = self._expressionCount(Stream.ExpressionAudioType)
		return self._expressionReplace(id = 'audioTypeClean_' + str(guidance), data = data, expression = self._audioTypeKeyword(guidance = guidance), exclude = exclude, count = count, split = split)

	'''
		FUNCTION:
			Retrieve the color for the audio type.
		PARAMETERS:
			value (string): The audio type.
		RETURNS:
			The audio type color (string).
	'''
	@classmethod
	def audioTypeColor(self, value):
		if value in Stream.AudioTypeDubbeds: return interface.Format.colorPoor()
		elif value in Stream.AudioTypeRecordings: return interface.Format.colorBad()
		return None

	@classmethod
	def _audioTypeKeyword(self, guidance = None):
		return self._expressionFormatKeyword(id = '_audioTypeKeyword', expression = Stream.ExpressionAudioType, guidance = guidance)

	##############################################################################
	# AUDIO CHANNELS
	##############################################################################

	'''
		FUNCTION:
			Retrieves the number of audio channels.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The number of audio channels (integer).
	'''
	def audioChannels(self, format = FormatNone, label = LabelNone, default = None):
		value = self.mData['audio']['channels']
		if value is None: return default
		if format == Stream.FormatKodi:
			value = Stream.KodiAudioChannels[value]
		elif not label == Stream.LabelNone:
			label = self.settingsLayout(label, 'audio', 'channels')
			value = self._label(value = value, values = Stream.LabelAudioChannels, format = format, label = label)
		return value

	'''
		FUNCTION:
			Sets the number of audio channels.
		PARAMETERS:
			value (integer): The number of audio channels.
			extract (boolean): Wether to extract the value or accept the raw value as is.
		RETURNS:
			The extracted and processed value that was set (integer/None).
	'''
	def audioChannelsSet(self, value, extract = True):
		value = self.audioChannelsExtract(data = value, clean = False) if extract else value
		self.mData['audio']['channels'] = value
		return value

	'''
		FUNCTION:
			Extracts the number of audio channels from a string.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			clean (boolean): Wether or not to clean the data before processing.
		RETURNS:
			The number of audio channels (integer).
	'''
	@classmethod
	def audioChannelsExtract(self, data, exclude = None, encode = True, clean = True):
		if not data: return None
		if tools.Tools.isNumber(data): return data
		if clean: data = self.cleanBasic(data)
		if encode: exclude = self.cleanEncode(exclude)
		expression = self._expressionFormatExpression(id = 'audioChannelsExtract', type = Stream.ExpressionSequential, expression = Stream.ExpressionAudioChannels)
		return self._expressionMatchType(id = 'audioChannelsExtract', data = data, expression = expression, exclude = exclude)

	'''
		FUNCTION:
			Cleans a file name from audio channel keywords.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			guidance (None/integer): The already detected audio channels. Speeds up the cleaning by only removing previously detected keywords, instead of scanning through all keywords.
			split (None/string): If SplitRight/SplitLeft, cuts off the string after/before the first found keyword. If None, simply remove the keyword and keep the rest of the string intact.
		RETURNS:
			The cleaned file name (string).
	'''
	@classmethod
	def audioChannelsClean(self, data, exclude = None, encode = True, guidance = None, split = SplitNone):
		if not data: return data
		if encode: exclude = self.cleanEncode(exclude)
		count = self._expressionCount(Stream.ExpressionAudioChannels)
		return self._expressionReplace(id = 'audioChannelsClean_' + str(guidance), data = data, expression = self._audioChannelsKeyword(guidance = guidance), exclude = exclude, count = count, split = split)

	@classmethod
	def _audioChannelsKeyword(self, guidance = None):
		return self._expressionFormatKeyword(id = '_audioChannelsKeyword', expression = Stream.ExpressionAudioChannels, guidance = guidance, group = True)

	##############################################################################
	# AUDIO SYSTEM
	##############################################################################

	'''
		FUNCTION:
			Retrieves the audio system.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The audio system (string).
	'''
	def audioSystem(self, format = FormatNone, label = LabelNone, default = None):
		value = self.mData['audio']['system']
		if value is None: return default
		if not label == Stream.LabelNone:
			label = self.settingsLayout(label, 'audio', 'system')
			value = self._label(value = value, values = Stream.LabelAudioSystem, format = format, label = label)
		return value

	'''
		FUNCTION:
			Sets the audio system.
		PARAMETERS:
			value (string): The audio system or the audio codec.
			extract (boolean): Wether to extract the value or accept the raw value as is.
		RETURNS:
			The extracted and processed value that was set (string/None).
	'''
	def audioSystemSet(self, value, extract = True):
		if extract:
			value = self.audioSystemExtract(data = value, clean = False)
		else:
			try: value = Stream.AudioCodecSystem[value]
			except: pass
		self.mData['audio']['system'] = value
		return value

	'''
		FUNCTION:
			Extracts the audio system from a string.
		PARAMETERS:
			data (string): The file name.
			codec (None/string/boolean): The already extracted audio codec to use for detecting the audio system. If True, the audio codec will be extracted. If False/None, no audio codec is extracted and only the system is extracted.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			clean (boolean): Wether or not to clean the data before processing.
		RETURNS:
			The audio system (string).
	'''
	@classmethod
	def audioSystemExtract(self, data, codec = True, exclude = None, encode = True, clean = True):
		if not data: return None
		if clean: data = self.cleanBasic(data)
		if encode: exclude = self.cleanEncode(exclude)

		if codec:
			if codec is True: codec = self.audioCodecExtract(data = data, exclude = exclude, clean = False)
			try: return Stream.AudioCodecSystem[codec]
			except: pass

		expression = self._expressionFormatExpression(id = 'audioSystemExtract', type = Stream.ExpressionSequential, expression = Stream.ExpressionAudioSystem)
		return self._expressionMatchType(id = 'audioSystemExtract', data = data, expression = expression, exclude = exclude)

	'''
		FUNCTION:
			Cleans a file name from audio system keywords.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			guidance (None/integer): The already detected audio system. Speeds up the cleaning by only removing previously detected keywords, instead of scanning through all keywords.
			split (None/string): If SplitRight/SplitLeft, cuts off the string after/before the first found keyword. If None, simply remove the keyword and keep the rest of the string intact.
		RETURNS:
			The cleaned file name (string).
	'''
	@classmethod
	def audioSystemClean(self, data, exclude = None, encode = True, guidance = None, split = SplitNone):
		if not data: return data
		if encode: exclude = self.cleanEncode(exclude)
		count = self._expressionCount(Stream.ExpressionVideoQuality)
		return self._expressionReplace(id = 'audioSystemClean_' + str(guidance), data = data, expression = self._audioSystemKeyword(guidance = guidance), exclude = exclude, count = count, split = split)

	@classmethod
	def _audioSystemKeyword(self, guidance = None):
		return self._expressionFormatKeyword(id = '_audioSystemKeyword', expression = Stream.ExpressionAudioSystem, guidance = guidance)

	##############################################################################
	# AUDIO CODEC
	##############################################################################

	'''
		FUNCTION:
			Retrieves the audio codec.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			system (boolean): Whether or not to return the system and codec combination.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The audio codec (string).
	'''
	def audioCodec(self, format = FormatNone, label = LabelNone, system = False, default = None):
		if system:
			system = self.audioSystem(format = format, label = label)
			codec = self.audioCodec(format = format, label = label)
			if system is None and codec is None: return default
			if format is None and label is None: return [system, codec]
			if self.audioSystem() in Stream.PrefixAudioSystem:
				return self._label(value = codec, prefix = system, format = format, label = label)
			else:
				return codec
		else:
			value = self.mData['audio']['codec']
			if value is None: return default
			if format == Stream.FormatKodi:
				value = Stream.KodiAudioCodec[value]
			elif not label == Stream.LabelNone:
				label = self.settingsLayout(label, 'audio', 'codec')
				value = self._label(value = value, values = Stream.LabelAudioCodec, format = format, label = label)
			return value

	'''
		FUNCTION:
			Sets the audio codec.
		PARAMETERS:
			value (string): The audio codec.
			extract (boolean): Wether to extract the value or accept the raw value as is.
		RETURNS:
			The extracted and processed value that was set (string/None).
	'''
	def audioCodecSet(self, value, extract = True):
		value = self.audioCodecExtract(data = value, clean = False) if extract else value
		self.mData['audio']['codec'] = value
		return value

	'''
		FUNCTION:
			Extracts the audio codec from a string.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			clean (boolean): Wether or not to clean the data before processing.
		RETURNS:
			The audio codec (string).
	'''
	@classmethod
	def audioCodecExtract(self, data, exclude = None, encode = True, clean = True):
		if not data: return None
		if clean: data = self.cleanBasic(data)
		if encode: exclude = self.cleanEncode(exclude)
		expression = self._expressionFormatExpression(id = 'audioCodecExtract', type = Stream.ExpressionSequential, expression = Stream.ExpressionAudioCodec)
		return self._expressionMatchType(id = 'audioCodecExtract', data = data, expression = expression, exclude = exclude)

	'''
		FUNCTION:
			Cleans a file name from audio codec keywords.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			guidance (None/string): The already detected audio codec. Speeds up the cleaning by only removing previously detected keywords, instead of scanning through all keywords.
			split (None/string): If SplitRight/SplitLeft, cuts off the string after/before the first found keyword. If None, simply remove the keyword and keep the rest of the string intact.
		RETURNS:
			The cleaned file name (string).
	'''
	@classmethod
	def audioCodecClean(self, data, exclude = None, encode = True, guidance = None, split = SplitNone):
		if not data: return data
		if encode: exclude = self.cleanEncode(exclude)
		count = self._expressionCount(Stream.ExpressionAudioCodec)
		return self._expressionReplace(id = 'audioCodecClean_' + str(guidance), data = data, expression = self._audioCodecKeyword(guidance = guidance), exclude = exclude, count = count, split = split)

	@classmethod
	def _audioCodecKeyword(self, guidance = None):
		return self._expressionFormatKeyword(id = '_audioCodecKeyword', expression = Stream.ExpressionAudioCodec, guidance = guidance)

	##############################################################################
	# AUDIO LANGUAGE
	##############################################################################

	'''
		FUNCTION:
			Retrieves the audio languages.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
			universal (boolean): Whether or not to include the universal language.
			sort (boolean): Whether or not to sort the languages according to the user's preferences.
		RETURNS:
			The audio languages (list).
	'''
	def audioLanguage(self, format = FormatNone, label = LabelNone, default = None, universal = False, sort = True):
		value = self.mData['audio']['language']
		if not value: return default
		if not universal: value = [i for i in value if not i == tools.Language.UniversalCode]

		multiple = label == Stream.LabelSettings
		label = self.settingsLayout(label, 'audio', 'language')
		if sort: value = self.languageSort(value = value, default = self.metaLanguage(single = True), label = True, copy = True)
		return self.languageConvert(value = value, format = format, label = label, multiple = multiple, default = self.audioDefault())

	'''
		FUNCTION:
			Sets the audio languages.
		PARAMETERS:
			value (string/list): The audio languages.
			extract (boolean): Wether to extract the value or accept the raw value as is.
			exact (enumeration): Wether or not the language is exact.
			native (None/list): The languages of the provider or source used to detect additional language name translations.
		RETURNS:
			The extracted and processed value that was set (list/None).
	'''
	def audioLanguageSet(self, value, extract = True, exact = ExactYes, native = None):
		if extract:
			language = self.languageDetect(data = value)
			if language or tools.Tools.isArray(value): value = language
			else:
				value, valueDefault = self.audioLanguageExtract(data = value, clean = False, default = self.metaLanguage(single = True, audioType = True), native = native if native else self.infoLanguage(), full = True)
				if valueDefault: self.audioDefaultSet(valueDefault)

		if not value: value = None
		elif not tools.Tools.isArray(value): value = [value]

		if exact == Stream.ExactNo: value = self.languageMerge(language = self.mData['audio']['language'], addition = value, detect = False)

		self.mData['audio']['language'] = value
		return value

	'''
		FUNCTION:
			Extracts the audio languages from a string.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			clean (boolean): Wether or not to clean the data before processing.
			default (None/string): The code of the original language of the title, that is, the default language to use if no specific language is detected.
			native (None/list): The languages of the provider or source used to detect additional language name translations.
			full (boolean): Wether or not both the fixed and assumed/default languages should be returned.
		RETURNS:
			The audio languages (list).
	'''
	@classmethod
	def audioLanguageExtract(self, data, exclude = None, encode = True, clean = True, default = None, native = None, full = False):
		if not data: return None
		result = self.languageExtract(data = data, exclude = exclude, encode = encode, clean = clean, default = default, native = native)
		if full: return result['audio'], result['default']
		else: return result['audio']

	'''
		FUNCTION:
			Cleans a file name from audio language keywords.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			language (boolean): Whether or not to clean language keywords. Otherwise only audio keywords are removed.
			guidance (None/string): The already detected audio language. Speeds up the cleaning by only removing previously detected keywords, instead of scanning through all keywords.
			native (None/list): The languages of the provider or source used to detect additional language name translations.
			split (None/string): If SplitRight/SplitLeft, cuts off the string after/before the first found keyword. If None, simply remove the keyword and keep the rest of the string intact.
		RETURNS:
			The cleaned file name (string).
	'''
	@classmethod
	def audioLanguageClean(self, data, exclude = None, encode = True, language = True, guidance = None, native = None, split = SplitNone):
		if not data: return data
		if encode: exclude = self.cleanEncode(exclude)
		data = self._expressionReplace(id = 'audioLanguageClean_' + str(guidance), data = data, expression = '(' + Stream.ExpressionAudio + ')', exclude = exclude, split = split)
		if language: data = self.languageClean(data = data, exclude = exclude, encode = encode, guidance = guidance, native = native)
		return data

	##############################################################################
	# AUDIO DEFAULT
	##############################################################################

	'''
		FUNCTION:
			Retrieves the audio languages that were assumed by default based on the language the title was released in.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
			universal (boolean): Whether or not to include the universal language.
		RETURNS:
			The audio languages (list).
	'''
	def audioDefault(self, format = FormatNone, label = LabelNone, default = None, universal = False):
		value = self.mData['audio']['default']
		if not value: return default
		if not universal: value = [i for i in value if not i == tools.Language.UniversalCode]

		multiple = label == Stream.LabelSettings
		label = self.settingsLayout(label, 'audio', 'language')
		return self.languageConvert(value = value, format = format, label = label, multiple = multiple)

	'''
		FUNCTION:
			Sets the assumed audio languages.
		PARAMETERS:
			value (string/list): The audio languages.
		RETURNS:
			The extracted and processed value that was set (list/None).
	'''
	def audioDefaultSet(self, value):
		if not value: value = None
		elif not tools.Tools.isArray(value): value = [value]
		self.mData['audio']['default'] = value
		return value

	##############################################################################
	# SUBTITLE TYPE
	##############################################################################

	'''
		FUNCTION:
			Retrieves the subtitle type.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The subtitle type (string).
	'''
	def subtitleType(self, format = FormatNone, label = LabelNone, default = None):
		value = self.mData['subtitle']['type']
		if value is None: return default
		if not label == Stream.LabelNone:
			label = self.settingsLayout(label, 'subtitle', 'type')
			value = self._label(value = value, values = Stream.LabelSubtitleType, format = format, label = label)
			value = self._decorate(value = value, format = format, uppercase = True, color = self.subtitleTypeColor, colorvalue = self.mData['subtitle']['type'])
		return value

	'''
		FUNCTION:
			Sets the subtitle type.
		PARAMETERS:
			value (string): The subtitle type.
			extract (boolean): Wether to extract the value or accept the raw value as is.
		RETURNS:
			The extracted and processed value that was set (string/None).
	'''
	def subtitleTypeSet(self, value, extract = True):
		value = self.subtitleTypeExtract(data = value, clean = False) if extract else value
		self.mData['subtitle']['type'] = value
		return value

	'''
		FUNCTION:
			Sets the default subtitle type if suubtitle languages aare present.
	'''
	def subtitleTypeDetect(self):
		if not self.mData['subtitle']['type'] and self.subtitleLanguage(): self.subtitleTypeSet(value = Stream.SubtitleTypeDefault, extract = False)

	'''
		FUNCTION:
			Extracts the subtitle type from a string.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			clean (boolean): Wether or not to clean the data before processing.
		RETURNS:
			The subtitle type (string).
	'''
	@classmethod
	def subtitleTypeExtract(self, data, exclude = None, encode = True, clean = True):
		if not data: return None
		if clean: data = self.cleanBasic(data)
		if encode: exclude = self.cleanEncode(exclude)
		expression = self._expressionFormatExpression(id = 'subtitleTypeExtract', type = Stream.ExpressionSequential, expression = Stream.ExpressionSubtitleType)
		return self._expressionMatchType(id = 'subtitleTypeExtract', data = data, expression = expression, exclude = exclude)

	'''
		FUNCTION:
			Cleans a file name from subtitle type keywords.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			guidance (None/string): The already detected subtitle type. Speeds up the cleaning by only removing previously detected keywords, instead of scanning through all keywords.
			split (None/string): If SplitRight/SplitLeft, cuts off the string after/before the first found keyword. If None, simply remove the keyword and keep the rest of the string intact.
		RETURNS:
			The cleaned file name (string).
	'''
	@classmethod
	def subtitleTypeClean(self, data, exclude = None, encode = True, guidance = None, split = SplitNone):
		if not data: return data
		if encode: exclude = self.cleanEncode(exclude)
		count = self._expressionCount(Stream.ExpressionSubtitleType)
		return self._expressionReplace(id = 'subtitleTypeClean_' + str(guidance), data = data, expression = self._subtitleTypeKeyword(guidance = guidance), exclude = exclude, count = count, split = split)

	'''
		FUNCTION:
			Retrieve the color for the subtitle type.
		PARAMETERS:
			value (string): The subtitle type.
		RETURNS:
			The subtitle type color (string).
	'''
	@classmethod
	def subtitleTypeColor(self, value):
		return interface.Format.colorBad() if value == Stream.SubtitleTypeHard else None

	@classmethod
	def _subtitleTypeKeyword(self, guidance = None):
		return self._expressionFormatKeyword(id = '_subtitleTypeKeyword', expression = Stream.ExpressionSubtitleType, guidance = guidance)

	##############################################################################
	# SUBTITLE LANGUAGE
	##############################################################################

	'''
		FUNCTION:
			Retrieves the subtitle languages.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
			universal (boolean): Whether or not to include the universal language.
			sort (boolean): Whether or not to sort the languages according to the user's preferences.
		RETURNS:
			The subtitle languages (list).
	'''
	def subtitleLanguage(self, format = FormatNone, label = LabelNone, default = None, universal = False, sort = False):
		value = self.mData['subtitle']['language']
		if not value: return default
		if not universal:
			value = [i for i in value if not i == tools.Language.UniversalCode]
			if not value: return default

		multiple = label == Stream.LabelSettings
		label = self.settingsLayout(label, 'subtitle', 'language')
		if sort: value = self.languageSort(value = value, default = self.metaLanguage(single = True), label = True, copy = True)
		return self.languageConvert(value = value, format = format, label = label, multiple = multiple)

	'''
		FUNCTION:
			Sets the subtitle languages.
		PARAMETERS:
			value (string/list): The subtitle languages.
			extract (boolean): Wether to extract the value or accept the raw value as is.
			exact (enumeration): Wether or not the language is exact.
			type (boolean): Set the default subtitle type if not already present.
			native (None/list): The languages of the provider or source used to detect additional language name translations.
		RETURNS:
			The extracted and processed value that was set (list/None).
	'''
	def subtitleLanguageSet(self, value, extract = True, exact = ExactYes, type = True, native = None):
		if extract:
			language = self.languageDetect(data = value)
			if language or tools.Tools.isArray(value): value = language
			elif value: value = self.subtitleLanguageExtract(data = value + ' subtitle', clean = False, default = self.metaLanguage(single = True), native = native if native else self.infoLanguage()) # Add the "subtitle" keyword, otherwise single-language strings are detected as audio.

		if not value: value = None
		elif not tools.Tools.isArray(value): value = [value]

		if exact == Stream.ExactNo: value = self.languageMerge(language = self.mData['subtitle']['language'], addition = value, detect = False)

		self.mData['subtitle']['language'] = value
		if type: self.subtitleTypeDetect()
		return value

	'''
		FUNCTION:
			Extracts the subtitle languages from a string.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			clean (boolean): Wether or not to clean the data before processing.
			default (None/string): The code of the original language of the title, that is, the default language to use if no specific language is detected.
			native (None/list): The languages of the provider or source used to detect additional language name translations.
		RETURNS:
			The subtitlesubtitle languages (list).
	'''
	@classmethod
	def subtitleLanguageExtract(self, data, exclude = None, encode = True, clean = True, default = None, native = None):
		if not data: return None
		return self.languageExtract(data = data, exclude = exclude, encode = encode, clean = clean, default = default, native = native)['subtitle']

	'''
		FUNCTION:
			Cleans a file name from subtitle language keywords.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			language (boolean): Whether or not to clean language keywords. Otherwise only subtitle keywords are removed.
			guidance (None/string): The already detected subtitle language. Speeds up the cleaning by only removing previously detected keywords, instead of scanning through all keywords.
			native (None/list): The languages of the provider or source used to detect additional language name translations.
			split (None/string): If SplitRight/SplitLeft, cuts off the string after/before the first found keyword. If None, simply remove the keyword and keep the rest of the string intact.
		RETURNS:
			The cleaned file name (string).
	'''
	@classmethod
	def subtitleLanguageClean(self, data, exclude = None, encode = True, language = True, guidance = None, native = None, split = SplitNone):
		if not data: return data
		if encode: exclude = self.cleanEncode(exclude)
		expression = self._expressionFormatCommon(expression = Stream.ExpressionSubtitleExtended)
		data = self._expressionReplace(id = 'subtitleLanguageClean_' + str(guidance), data = data, expression = '(' + expression + ')', exclude = exclude, split = split)
		if language: data = self.languageClean(data = data, exclude = exclude, encode = encode, guidance = guidance, native = native)
		return data

	##############################################################################
	# RELEASE VALID
	##############################################################################

	'''
		FUNCTION:
			Checks wether the stream should be excluded, based on the release date and other attributes.
			Can be called on an instance (without the data parameter), or on the class (with the data parameter).
		PARAMETERS:
			data (string): The file name.
			media (string): The media type.
			title (string/array): The title.
			year (integer/array): The year.
			language (string/array): The original language of the title.
			country (string/array): The original country of the title.
			network (string/array): The release network of the title.
			studio (string/array): The release studio of the title.
			time (integer): The release time.
			pack (dictionary): The movie collection or show pack data.
			numberCollection (list): The extracted movie collection numbers.
			filePack (string): The extracted file pack.
			sourceTime (integer): The extracted source time.
		RETURNS:
			Wether the file name should be excluded (boolean).
	'''
	@classmethod
	def releaseValid(self, data, media = None, title = None, year = None, language = None, country = None, network = None, studio = None, time = None, pack = None, filePack = None, numberCollection = None, sourceTime = None):
		return self.__releaseValid(data = data, media = media, title = title, year = year, language = language, country = country, network = network, studio = studio, time = time, pack = pack, filePack = filePack, numberCollection = numberCollection, sourceTime = sourceTime)

	def _releaseValid(self):
		return self.__releaseValid(data = self.fileName(), media = self.metaMedia(), title = self.metaTitle(), year = self.metaYear(), language = self.metaLanguage(), country = self.metaCountry(), network = self.metaNetwork(), studio = self.metaStudio(), time = self.metaTime(), pack = self.metaPack(), filePack = self.filePack(), numberCollection = self.numberCollection(), sourceTime = self.sourceTime(time = Stream.TimeNone))

	@classmethod
	def __releaseValid(self, data, media = None, title = None, year = None, language = None, country = None, network = None, studio = None, time = None, pack = None, filePack = None, numberCollection = None, sourceTime = None):
		valid = self.__releaseValidTime(data = data, media = media, time = time, filePack = filePack, sourceTime = sourceTime)
		if not valid is None: return valid

		valid = self.__releaseValidCollection(data = data, media = media, title = title, year = year, pack = pack, numberCollection = numberCollection, filePack = filePack)
		if not valid is None: return valid

		valid = self.__releaseValidCountry(data = data, media = media, title = title, year = year, language = language, country = country, network = network, studio = studio)
		if not valid is None: return valid

		return True

	@classmethod
	def __releaseValidTime(self, data, media = None, time = None, filePack = None, sourceTime = None):
		try:
			if filePack:
				# Sometimes the source time is incorrect.
				# Eg: 9154202579
				if sourceTime and (sourceTime - tools.Time.timestamp()) > 86400: return False

				# If the file pack was released BEFORE the actual episode or movie premiered.
				# Eg: An old movie collection published 2 years ago should not be accepted as a pack for a new movie belonging to the collection that only premiered a few weeks ago.
				# Allow some leniency, in case some titles are leaked before their official date.
				if time and sourceTime and (time - sourceTime) > (259200 if tools.Media.isSerie(media) else 604800): return False
		except: tools.Logger.error()
		return None

	@classmethod
	def __releaseValidCollection(self, data, media = None, title = None, year = None, pack = None, numberCollection = None, filePack = None):
		# Ignore movie collections if the new movie number is not in the file name.
		try:
			if title and pack and tools.Media.isFilm(media):
				numbers = [j for j in numberCollection if not j == Stream.NumberPack] if numberCollection else None

				if numbers:
					titleFull = title
					try: title = title[Stream.TitleAll]
					except: pass
					if tools.Tools.isString(title): title = [title]
					title = [tools.Tools.replaceNotAlphaNumeric(j.lower()) for j in title]
					if tools.Tools.isInteger(year): year = [year]

					number = None
					if not number:
						movies = self._metaPack(pack, 'title')
						if movies:
							for i in reversed(range(len(movies))):
								titles = movies[i]
								if titles:
									titles = [tools.Tools.replaceNotAlphaNumeric(j.lower()) for j in titles if j]
									if any(j in title for j in titles):
										number = i
										break

					if not number and year:
						movies = self._metaPack(pack, 'year', 'values')
						if movies:
							for i in reversed(range(len(movies))):
								years = movies[i]
								if years:
									if years in year:
										number = i
										break

					if number and not number in numbers:
						# Sometimes a number range is added to the filename that only has a single title.
						# Eg: Star Wars The Last Jedi (2017) 1-3 HDCAM Rip: X264 AC3: DTOne
						if self.__yearValid(data = data, media = media, year = year, pack = pack, filePack = filePack) and self.__titleValidQuick(data = data, title = titleFull): return True
						else: return False
				else:
					# Sometimes episodes and show/season packs are returned for movie collections, which might not be filtered out with the title and/or year.
					# Eg: S.W.A.T. (2003 - movie - part of S.W.A.T. collection) - S.W.A.T. (2017 - movie - part of S.W.A.T. collection) - S.W.A.T. (2017 - show)
					# Validation might therefore allow the file names below for the movies, since the title matches, the year (2017) is valid for the movie collection, and the keywords (eg "Complete") are seen as collection keywords.
					#	S.W.A.T. Season 2 Complete 720p x265
					#	S.W.A.T.2017.S07E06.1080p.WEB.h264-ETHEL[EZTVx.to].mkv
					# Hence, we have to manually check here if it contains show/episode numbers in order to exclude them.
					# This might take a little bit more processing power, but will only be done with movies that are part of a collection.
					if self.numberShowContains(data = data, show = True, season = True, episode = True, clean = False, basic = True): return False

		except: tools.Logger.error()
		return None

	@classmethod
	def __releaseValidCountry(self, data, media = None, title = None, year = None, language = None, country = None, network = None, studio = None):
		# Different shows with the same name can be release in different countries.
		# Eg: The Office US/UK/PL/IN/etc.
		# The shows are differantiated in one of the following ways:
		#	1. Country code (most of the time).
		#	2. Release year.
		#	3. Network/studio name.
		#	4. Some do not contain any identifying info and can therefore not be distiguished from one another.
		# Be very careful extracting the country code and from where in the filename to extract it.
		# 2-digit codes could be used for something else than a country:
		#	1. Codes that are not countries, eg "HD".
		#	2. Codes that are audio/sub languages, eg "PL" for Polish audio language.
		#	3. TLD at the start/end of the filename, eg "Lektor.PL".
		# Rather be too lenient and include some incorrect links, instead of being too strict and filtering out too many links.
		try:
			# Only do this for shows, since movies do not typically have this and we want to avoid excessive filtering.
			if data and (media is None or tools.Media.isSerie(media)):
				try: title = title[Stream.TitleAll]
				except: pass
				if country and tools.Tools.isArray(country): country = country[0]

				def releaseCountry(title, country):
					palceholder = 'GAIACOUNTRYGAIA'
					special = ['us', 'usa', 'uk', 'gb']
					separatorStart = '(?:%s|%s)' % (Stream.ExpressionSeparatorBasic, Stream.ExpressionBracketsStart)
					separatorEnd = '(?:$|%s|%s)' % (Stream.ExpressionSeparatorBasic, Stream.ExpressionBracketsEnd)

					# Do not include the "Pilot" episode title. Eg: 9-1-1-s01e01-pilot-pl-1080p-web-dl-dd5-1-x264-ralf-mkv
					lookup = []
					for i in range(len(title)):
						j = title[i].lower()
						if i == 1 or not j == 'pilot':
							# replaceNotAlphaNumeric() iterates over the characters, causing issues if a single char is replaced by a longer string of all non-alphas.
							# Eg: ドラゴンボール超[スーパー]
							j = tools.Tools.replaceNotAlphaNumeric(j, replace = palceholder)
							j = j.replace(palceholder, Stream.ExpressionSeparatorBasic + '*')
							lookup.append(j)
					lookup = '(?:%s)' % '|'.join(lookup)

					countries = tools.Tools.copy(country) if tools.Tools.isArray(country) else [country]
					countries = [i.lower() for i in countries]
					if 'us' in countries: countries.append('usa')
					if 'uk' in countries or 'gb' in countries: countries.extend(['uk', 'gb'])

					for i in country if tools.Tools.isArray(country) else [country]:
						name = tools.Country.name(i)
						if name:
							name = tools.Tools.replaceNotAlphaNumeric(name.lower(), replace = palceholder)
							name = name.replace(palceholder, Stream.ExpressionSeparatorBasic + '*')
							countries.append(name)

					countries = tools.Tools.listUnique(countries)

					# Check at the end of the filename.
					# Only do this for country codes that are not the same as language codes.
					common = []
					for i in special:
						if i in countries:
							common.append(i)

					check = '|'.join([''.join(['%s%s*' % (j, Stream.ExpressionSeparatorBasic) for j in i]) if i in special else i for i in countries])

					# Extra keywords.
					extra = []
					if 'in' in countries: extra.append('hindi')
					if extra: check += '|' + '|'.join(extra)

					# Ignore mutiple languages at the end.
					# Eg: The Office Season 1 SE NO DK FI
					check = '(?:%s)' % check
					check += '(?!%s[a-z]{2}(?:$|%s))' % (Stream.ExpressionSeparatorBasic, Stream.ExpressionSeparatorBasic)

					# Ignore single language at the end.
					# Eg: S03.One.Piece.PT
					check += '(?!$)'

					expression1 = '^%s*%s%s*%s' % (Stream.ExpressionSymbol, check, Stream.ExpressionSymbol, lookup)

					# Do not allow the code to be placed right after an episode number.
					# Eg: star-trek-the-original-series-s01e01-pl-hdtv-xvid-ac3-mifumindo
					# Eg: westworld-s02e09-pl-480p-web-dl-xvid-kitt
					#expression2 = '%s(?:%s*(?:(?:%s|%s|s(?:eason|eries?)?|ep?(?:isode)?|complete%s*(?:show|series?|seasons?)?|web%s*rip|%s|\d)*)%s*){1,3}%s*(?<!s\de\d)(?<!s\d{2}e\d{2})(?<!s\d{2}e\d{3})%s+%s%s+' % (lookup, separatorStart, Stream.ExpressionYearSingle, Stream.ExpressionYearMultiple, Stream.ExpressionSeparatorBasic, Stream.ExpressionSeparatorBasic, Stream.ExpressionSeparatorBasic, separatorEnd, Stream.ExpressionSeparatorBasic, separatorStart, check, separatorEnd)
					expression2 = '%s(?:%s*(?:(?:%s|%s|%s|\d)*)%s*){1,3}%s+%s%s+' % (lookup, separatorStart, Stream.ExpressionYearSingle, Stream.ExpressionYearMultiple, Stream.ExpressionSeparatorBasic, separatorEnd, separatorStart, check, separatorEnd)
					expression2 = expression2.replace('{{', '{').replace('}}', '}') # Years digit range {{2}}.

					if common:
						common = '|'.join([''.join(['%s%s*' % (j, Stream.ExpressionSeparatorBasic) for j in i]) for i in common])
						expression3 = '%s(?:%s)%s$' % (Stream.ExpressionBracketsStart, common, Stream.ExpressionBracketsEnd)
						return '(%s|%s|%s)' % (expression1, expression2, expression3)
					else:
						return '(%s|%s)' % (expression1, expression2)

				# First try the country of release.
				if title and country:
					if self._cacheId('releaseCountry_' + self._cacheIdMinimize(title, country), re.compile, lambda : releaseCountry(title = title, country = country), flags = Stream.ExpressionFlags).search(data): return True

				# Second try the year.
				# Only do a basic check. Advanced checking is already done in yearValid().
				if year:
					def releaseYear(year):
						return '((?:^|%s|%s)+%s(?:$|%s|%s)+)' % (Stream.ExpressionSeparatorBasic, Stream.ExpressionBracketsStart, str(year), Stream.ExpressionSeparatorBasic, Stream.ExpressionBracketsEnd)
					if self._cacheId('releaseYear_%s' % str(year), re.compile, lambda : releaseYear(year = year), flags = Stream.ExpressionFlags).search(data): return True

				# Third try the network/studio.
				if network or studio:
					def releaseNetwork(network, studio):
						lookup = []
						if network:
							lookup.extend(network[:2])

							# Add networks without the number.
							# Eg: Also add "BBC" if the network is "BBC Two". Or "ITV1".
							# Ignore non-abbreviations, otherwise it might be too generic.
							# Eg: Channel 4 or Film 4
							numbers = ['1', '2', '3', '4', '5', 'One', 'Two', 'Three', 'Four', 'Five']
							for i in lookup:
								i = i.split(' ')
								if len(i) > 1 and i[0].isupper() and i[-1] in numbers:
									lookup.append(i[0])
						if studio:
							lookup.extend(studio[:2])
						lookup = '|'.join([tools.Tools.replaceNotAlphaNumeric(i.lower(), replace = Stream.ExpressionSeparatorBasic + '*') for i in lookup])
						return '((?:^|%s|%s)+%s(?:$|%s|%s)+)' % (Stream.ExpressionSeparatorBasic, Stream.ExpressionBracketsStart, lookup, Stream.ExpressionSeparatorBasic, Stream.ExpressionBracketsEnd)
					if self._cacheId('releaseNetwork_%s_%s' % (str(network[0] if network else None), str(studio[0] if studio else None)), re.compile, lambda : releaseNetwork(network = network, studio = studio), flags = Stream.ExpressionFlags).search(data): return True

				# Fourthly try to extract the country code from the filename.
				# Be careful, since the codes can be TLDs or audio/sub languages as well.
				# Only accept the country if it is very close to the title in the filename.
				# Only use large countries, or countries known to make their own versions of shows.
				if title:
					def releaseForeign(title, country):
						countries = ['us', 'gb', 'ca', 'au', 'nz', 'de', 'fr', 'es', 'pt', 'br', 'in', 'tr', 'ru', 'jp', 'kr', 'cn', 'mx', 'sa', 'pl', 'it', 'nl', 'il', 'ar', 'at', 'be', 'bg', 'cz', 'dk', 'fi', 'gr', 'hu', 'ie', 'my', 'no', 'ph', 'ro', 'se', 'th', 'tw', 'ua', 'vn', 'za']
						if country:
							lookup = tools.Tools.copy(country)
							if 'usa' in lookup: lookup.append('us')
							if 'uk' in lookup: lookup.append('gb')
							for i in lookup:
								try: del countries[i]
								except: pass
						return releaseCountry(title = title, country = countries)
					if self._cacheId('releaseForeign_' + self._cacheIdMinimize(title, country), re.compile, lambda : releaseForeign(title = title, country = country), flags = Stream.ExpressionFlags).search(data): return False

		except: tools.Logger.error()
		return None

	##############################################################################
	# RELEASE TYPE
	##############################################################################

	'''
		FUNCTION:
			Retrieves the release type.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The release type (string).
	'''
	def releaseType(self, format = FormatNone, label = LabelNone, default = None):
		value = self.mData['release']['type']
		if value is None: return default
		label = self.settingsLayout(label, 'release', 'type')
		return self._label(value = value, values = Stream.LabelReleaseType, format = format, label = label)

	'''
		FUNCTION:
			Sets the release type.
		PARAMETERS:
			value (string): The release type.
			extract (boolean): Wether to extract the value or accept the raw value as is.
		RETURNS:
			The extracted and processed value that was set (string/None).
	'''
	def releaseTypeSet(self, value, extract = True):
		value = self.releaseTypeExtract(data = value, clean = False) if extract else value
		self.mData['release']['type'] = value
		return value

	'''
		FUNCTION:
			Extracts the release type from a string.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			clean (boolean): Wether or not to clean the data before processing.
		RETURNS:
			The release type (string).
	'''
	@classmethod
	def releaseTypeExtract(self, data, exclude = None, encode = True, clean = True):
		if not data: return None
		if clean: data = self.cleanBasic(data)
		if exclude:
			if encode: exclude = self.cleanEncode(exclude)
			exclude = self._releaseTypeExclude(exclude)
		return self._expressionNestedMatch(id = 'releaseTypeExtract', data = data, type = Stream.ExpressionSequential, expression = Stream.ExpressionReleaseType, exclude = exclude, exhaustive = True)

	'''
		FUNCTION:
			Cleans a file name from release type keywords.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			guidance (None/string): The already detected release type. Speeds up the cleaning by only removing previously detected keywords, instead of scanning through all keywords.
			split (None/string): If SplitRight/SplitLeft, cuts off the string after/before the first found keyword. If None, simply remove the keyword and keep the rest of the string intact.
		RETURNS:
			The cleaned file name (string).
	'''
	@classmethod
	def releaseTypeClean(self, data, exclude = None, encode = True, guidance = None, split = SplitNone):
		if not data: return data
		if exclude:
			if encode: exclude = self.cleanEncode(exclude)
			exclude = self._releaseTypeExclude(exclude)
		expression = self._expressionNestedLinear(id = 'releaseTypeClean', expression = Stream.ExpressionReleaseType)
		count = self._expressionCount(expression)
		expression = self._expressionFormatKeyword(id = 'releaseTypeClean', expression = expression, group = True, guidance = guidance)
		return self._expressionReplace(id = 'releaseTypeClean_' + str(guidance), data = data, expression = expression, exclude = exclude, count = count, split = split)

	'''
		FUNCTION:
			Cleans a exclude titles from release type keywords.
			Many alternative titles include the keywords (eg The Terminator BluRay).
			Remove those keywords first, otherwise it won't match due to exclude.
	'''
	@classmethod
	def _releaseTypeExclude(self, exclude = None):
		def __releaseTypeExclude(exclude):
			if exclude:
				expression = self._expressionFormatKeyword(id = 'releaseTypeClean', expression = Stream.ExpressionReleaseType)
				expressionVersion1 = self._releaseTypeStandalone(wrap = True)
				expressionVersion2 = self._releaseTypeStandalone(wrap = False)
				temp = []
				if not tools.Tools.isArray(exclude): exclude = [exclude]
				for data in exclude:
					if self._expressionMatch(id = '_releaseTypeExclude1', data = data, expression = expressionVersion1, exclude = exclude[0]):
						data = self._expressionReplace(id = 'releaseTypeClean1', data = data, expression = expression)
						data = self._expressionReplace(id = 'releaseTypeClean2', data = data, expression = expressionVersion2)
						temp.append(self._cacheId('_releaseTypeExclude2', re.compile, '\s+', flags = Stream.ExpressionFlags).sub(' ', data).strip())
					else:
						temp.append(data)
				seen = set()
				exclude = [i for i in temp if not (i in seen or seen.add(i))]
			return exclude
		return self._cache(__releaseTypeExclude, exclude = exclude)

	@classmethod
	def _releaseTypeStandalone(self, wrap = True):
		result = []
		for i in ['hd', 'mux', 'vhs', 'dvd', 'bluray']:
			result.append(self._expressionFormatCommon(Stream.ExpressionReleaseType['keyword'][i]))
		result = '(' + '|'.join(result) + ')'
		if wrap: result = Stream.ExpressionSymbolStart + result + Stream.ExpressionSymbolEnd
		return result

	##############################################################################
	# RELEASE FORMAT
	##############################################################################

	'''
		FUNCTION:
			Retrieves the release format.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The release format (string).
	'''
	def releaseFormat(self, format = FormatNone, label = LabelNone, default = None):
		value = self.mData['release']['format']
		if value is None: return default
		if not label == Stream.LabelNone:
			label = self.settingsLayout(label, 'release', 'format')
			value = self._label(value = value, values = Stream.LabelReleaseFormat, format = format, label = label)
			value = self._decorate(value = value, format = format, uppercase = True, color = self.releaseFormatColor, colorvalue = self.mData['release']['format'])
		return value

	'''
		FUNCTION:
			Sets the release format.
		PARAMETERS:
			value (string): The release format.
			extract (boolean): Wether to extract the value or accept the raw value as is.
		RETURNS:
			The extracted and processed value that was set (string/None).
	'''
	def releaseFormatSet(self, value, extract = True):
		value = self.releaseFormatExtract(data = value, clean = False) if extract else value
		self.mData['release']['format'] = value
		return value

	'''
		FUNCTION:
			Extracts the release format from a string.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			clean (boolean): Wether or not to clean the data before processing.
		RETURNS:
			The release format (string).
	'''
	@classmethod
	def releaseFormatExtract(self, data, exclude = None, encode = True, clean = True):
		if not data: return None
		if clean: data = self.cleanBasic(data)
		if exclude:
			if encode: exclude = self.cleanEncode(exclude)
			exclude = self._releaseFormatExclude(exclude)
		expression = self._expressionFormatExpression(id = 'releaseFormatExtract', type = Stream.ExpressionSequential, expression = Stream.ExpressionReleaseFormat, exhaustive = True)
		return self._expressionMatchType(id = 'releaseFormatExtract', data = data, expression = expression, exclude = exclude)

	'''
		FUNCTION:
			Cleans a file name from release format keywords.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			guidance (None/string): The already detected release format. Speeds up the cleaning by only removing previously detected keywords, instead of scanning through all keywords.
			split (None/string): If SplitRight/SplitLeft, cuts off the string after/before the first found keyword. If None, simply remove the keyword and keep the rest of the string intact.
		RETURNS:
			The cleaned file name (string).
	'''
	@classmethod
	def releaseFormatClean(self, data, exclude = None, encode = True, guidance = None, split = SplitNone):
		if not data: return data
		if exclude:
			if encode: exclude = self.cleanEncode(exclude)
			exclude = self._releaseFormatExclude(exclude)
		count = self._expressionCount(Stream.ExpressionReleaseFormat)
		expression = self._expressionFormatKeyword(id = 'releaseFormatClean', expression = Stream.ExpressionReleaseFormat, group = True, guidance = guidance)
		return self._expressionReplace(id = 'releaseFormatClean_' + str(guidance), data = data, expression = expression, exclude = exclude, count = count, split = split)

	'''
		FUNCTION:
			Retrieve the color for the release format.
		PARAMETERS:
			value (string): The release format.
		RETURNS:
			The file release format (string).
	'''
	@classmethod
	def releaseFormatColor(self, value):
		if value: return interface.Format.colorMedium()
		return None

	'''
		FUNCTION:
			Cleans a exclude titles from release formats keywords.
			Many alternative titles include the keywords (eg Terminator 1 Remastered).
			Remove those keywords first, otherwise it won't match due to exclude.
	'''
	@classmethod
	def _releaseFormatExclude(self, exclude = None):
		def __releaseFormatExclude(exclude):
			if exclude:
				expression = self._expressionFormatKeyword(id = 'releaseFormatClean', expression = Stream.ExpressionReleaseFormat)
				expressionVersion1 = self._releaseFormatStandalone(wrap = True)
				expressionVersion2 = self._releaseFormatStandalone(wrap = False)
				temp = []
				if not tools.Tools.isArray(exclude): exclude = [exclude]
				for data in exclude:
					if self._expressionMatch(id = '_releaseFormatExclude1', data = data, expression = expressionVersion1, exclude = exclude[0]):
						data = self._expressionReplace(id = 'releaseFormatClean1', data = data, expression = expression)
						data = self._expressionReplace(id = 'releaseFormatClean2', data = data, expression = expressionVersion2)
						temp.append(self._cacheId('_releaseFormatExclude2', re.compile, '\s+', flags = Stream.ExpressionFlags).sub(' ', data).strip())
					else:
						temp.append(data)
				seen = set()
				exclude = [i for i in temp if not (i in seen or seen.add(i))]
			return exclude
		return self._cache(__releaseFormatExclude, exclude = exclude)

	@classmethod
	def _releaseFormatStandalone(self, wrap = True):
		result = '(' + '|'.join(self._expressionFormatKeyword(id = 'releaseFormatStandalone', expression = Stream.ExpressionReleaseFormat)) + ')'
		if wrap: result = Stream.ExpressionSymbolStart + result + Stream.ExpressionSymbolEnd
		return result

	##############################################################################
	# RELEASE EDITION
	##############################################################################

	'''
		FUNCTION:
			Retrieves the release edition.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The release edition (string).
	'''
	def releaseEdition(self, format = FormatNone, label = LabelNone, default = None):
		value = self.mData['release']['edition']
		if value is None: return default
		label = self.settingsLayout(label, 'release', 'edition')
		value = self._label(value = value, values = Stream.LabelReleaseEdition, format = format, label = label)
		value = self._decorate(value = value, format = format, uppercase = True, color = self.releaseEditionColor)
		return value

	'''
		FUNCTION:
			Sets the release edition.
		PARAMETERS:
			value (string): The release edition.
			extract (boolean): Wether to extract the value or accept the raw value as is.
		RETURNS:
			The extracted and processed value that was set (string/None).
	'''
	def releaseEditionSet(self, value, extract = True):
		value = self.releaseEditionExtract(data = value, clean = False) if extract else value
		self.mData['release']['edition'] = value
		return value

	'''
		FUNCTION:
			Extracts the release edition from a string.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			clean (boolean): Wether or not to clean the data before processing.
		RETURNS:
			The release edition (string).
	'''
	@classmethod
	def releaseEditionExtract(self, data, exclude = None, encode = True, clean = True):
		if not data: return None
		if clean: data = self.cleanBasic(data)
		if exclude:
			if encode: exclude = self.cleanEncode(exclude)
			exclude = self._releaseEditionExclude(exclude)
		expression = self._expressionFormatExpression(id = 'releaseEditionExtract', type = Stream.ExpressionSequential, expression = Stream.ExpressionReleaseEdition, exhaustive = True)
		return self._expressionMatchType(id = 'releaseEditionExtract', data = data, expression = expression, exclude = exclude)

	'''
		FUNCTION:
			Cleans a file name from release edition keywords.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			guidance (None/string): The already detected release edition. Speeds up the cleaning by only removing previously detected keywords, instead of scanning through all keywords.
			split (None/string): If SplitRight/SplitLeft, cuts off the string after/before the first found keyword. If None, simply remove the keyword and keep the rest of the string intact.
		RETURNS:
			The cleaned file name (string).
	'''
	@classmethod
	def releaseEditionClean(self, data, exclude = None, encode = True, guidance = None, split = SplitNone):
		if not data: return data
		if exclude:
			if encode: exclude = self.cleanEncode(exclude)
			exclude = self._releaseEditionExclude(exclude)
		count = self._expressionCount(Stream.ExpressionReleaseEdition)
		expression = self._expressionFormatKeyword(id = 'releaseEditionClean', expression = Stream.ExpressionReleaseEdition, guidance = guidance)
		result = self._expressionReplace(id = 'releaseEditionClean1_' + str(guidance), data = data, expression = expression, exclude = exclude, count = count, split = split)
		result = self._expressionReplace(id = 'releaseEditionClean2', data = result, expression = self._releaseEditionVersion(wrap = False, standalone = True), exclude = exclude, count = 1, split = split)
		return result

	'''
		FUNCTION:
			Retrieve the color for the release edition.
		RETURNS:
			The file release edition (string).
	'''
	@classmethod
	def releaseEditionColor(self):
		def _releaseEditionColor():
			return interface.Format.colorLighter(color = interface.Format.colorPoor())
		return self._cache(_releaseEditionColor)

	'''
		FUNCTION:
			Cleans a exclude titles from release edition keywords.
			Many alternative titles include the edition (eg Avatar Extended Edition).
			Remove those edition keywords first, otherwise it won't match due to exclude.
	'''
	@classmethod
	def _releaseEditionExclude(self, exclude = None):
		def __releaseEditionExclude(exclude):
			if exclude:
				expression = self._expressionFormatKeyword(id = 'releaseEditionClean', expression = Stream.ExpressionReleaseEdition)
				expressionVersion1 = self._releaseEditionVersion(wrap = True)
				expressionVersion2 = self._releaseEditionVersion(wrap = False)
				temp = []
				if not tools.Tools.isArray(exclude): exclude = [exclude]
				for data in exclude:
					# Only do this if a "version" keyword is present, in order to avoid standalone words (eg "The Bill Collector" vs "Avatar Extended Collectors Edition").
					if self._expressionMatch(id = '_releaseEditionExclude1', data = data, expression = expressionVersion1):
						data = self._expressionReplace(id = 'releaseEditionClean1', data = data, expression = expression)
						data = self._expressionReplace(id = 'releaseEditionClean2', data = data, expression = expressionVersion2)
						temp.append(self._cacheId('_releaseEditionExclude2', re.compile, '\s+', flags = Stream.ExpressionFlags).sub(' ', data).strip())
					else:
						temp.append(data)
				seen = set()
				exclude = [i for i in temp if not (i in seen or seen.add(i))]
			return exclude
		return self._cache(__releaseEditionExclude, exclude = exclude)

	@classmethod
	def _releaseEditionVersion(self, wrap = True, standalone = False):
		result = '(' + Stream.ExpressionReleaseEdition['keyword']['version'] + '|' + self._expressionFormatCommon(Stream.ExpressionReleaseEdition['keyword']['extra']) + (('|' + self._expressionFormatCommon(Stream.ExpressionReleaseEdition['keyword']['standalone'])) if standalone else '') + ')'
		if wrap: result = Stream.ExpressionSymbolStart + result + Stream.ExpressionSymbolEnd
		return result

	##############################################################################
	# RELEASE NETWORK
	##############################################################################

	'''
		FUNCTION:
			Retrieves the release network.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The release network (string).
	'''
	def releaseNetwork(self, format = FormatNone, label = LabelNone, default = None):
		value = self.mData['release']['network']
		if value is None: return default
		label = self.settingsLayout(label, 'release', 'network')
		return self._label(value = value, values = Stream.LabelReleaseNetwork, format = format, label = label)

	'''
		FUNCTION:
			Sets the release network.
		PARAMETERS:
			value (string): The release network.
			extract (boolean): Wether to extract the value or accept the raw value as is.
		RETURNS:
			The extracted and processed value that was set (string/None).
	'''
	def releaseNetworkSet(self, value, extract = True):
		value = self.releaseNetworkExtract(data = value, clean = False) if extract else value
		self.mData['release']['network'] = value
		return value

	'''
		FUNCTION:
			Extracts the release network from a string.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			clean (boolean): Wether or not to clean the data before processing.
		RETURNS:
			The release network (string).
	'''
	@classmethod
	def releaseNetworkExtract(self, data, exclude = None, encode = True, clean = True):
		if not data: return None
		if clean: data = self.cleanBasic(data)
		if encode: exclude = self.cleanEncode(exclude)

		# During exclude, the negative lookahead to determine if the detected "network" is at the end of the string (aka a release group), also negates title exclusions that end with the word.
		# Eg (release group - do not detect RED as network): The 2017 Billboard Music Awards S2017 HDTV x264-RED
		# However, if the title to be excluded also ENDS in the network keyword (eg: "RED"), it will not be excluded, since the {group} expression states that the string cannot end in the given keyword.
		# Eg: RED.2010.REPACK.720p.WEB.H264-STRONTiUM[ettv]   exclude : ['RED']
		# Hence, remove the {group} from exlcusion matching.
		def _releaseNetworkExtract1(exp): return exp.replace(self._cacheId('_releaseNetworkExtractExclude1', self._expressionFormatCommon, Stream.ExpressionReleaseNetwork['keyword']['group']), '')
		def _releaseNetworkExtract2(exp): return exp.replace(self._cacheId('_releaseNetworkExtractExclude2', self._expressionFormatCommon, Stream.ExpressionReleaseNetworkCase['keyword']['group']), '')

		expression = self._expressionFormatExpression(id = 'releaseNetworkExtract1', type = Stream.ExpressionNonsequential, expression = Stream.ExpressionReleaseNetwork, exhaustive = True)
		result = self._expressionMatchType(id = 'releaseNetworkExtract1', data = data, expression = expression, exclude = exclude, exclusion = _releaseNetworkExtract1)

		if not result:
			expression = self._expressionFormatExpression(id = 'releaseNetworkExtract2', type = Stream.ExpressionNonsequential, expression = Stream.ExpressionReleaseNetworkCase, exhaustive = True)
			result = self._expressionMatchType(id = 'releaseNetworkExtract2', data = data, expression = expression, exclude = exclude, exclusion = _releaseNetworkExtract2, flags = Stream.ExpressionFlagsCase)

		return result

	'''
		FUNCTION:
			Cleans a file name from release network keywords.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			guidance (None/string): The already detected release network. Speeds up the cleaning by only removing previously detected keywords, instead of scanning through all keywords.
			split (None/string): If SplitRight/SplitLeft, cuts off the string after/before the first found keyword. If None, simply remove the keyword and keep the rest of the string intact.
		RETURNS:
			The cleaned file name (string).
	'''
	@classmethod
	def releaseNetworkClean(self, data, exclude = None, encode = True, guidance = None, split = SplitNone):
		if not data: return data
		if encode: exclude = self.cleanEncode(exclude)

		def _releaseNetworkClean1(data, exclude, split):
			count = self._expressionCount(Stream.ExpressionReleaseNetwork)
			expression = self._expressionFormatKeyword(id = 'releaseNetworkClean1', expression = Stream.ExpressionReleaseNetwork, guidance = guidance)
			return self._expressionReplace(id = 'releaseNetworkClean1_' + str(guidance), data = data, expression = expression, exclude = exclude, count = count, split = split)

		def _releaseNetworkClean2(data, exclude, split):
			count = self._expressionCount(Stream.ExpressionReleaseNetworkCase)
			expression = self._expressionFormatKeyword(id = 'releaseNetworkClean2', expression = Stream.ExpressionReleaseNetworkCase, guidance = guidance)
			return self._expressionReplace(id = 'releaseNetworkClean2_' + str(guidance), data = data, expression = expression, exclude = exclude, count = count, split = split, flags = Stream.ExpressionFlagsCase)

		data = _releaseNetworkClean1(data = data, exclude = exclude, split = split)
		data = _releaseNetworkClean2(data = data, exclude = exclude, split = split)
		return data

	##############################################################################
	# RELEASE GROUP
	##############################################################################

	'''
		FUNCTION:
			Retrieves the release group.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The release group (string/list).
	'''
	def releaseGroup(self, format = FormatNone, label = LabelNone, default = None):
		value = self.mData['release']['group']
		if value is None: return default
		x=label
		label = self.settingsLayout(label, 'release', 'group')
		value = self._label(value = value, values = Stream.LabelReleaseGroup, format = format, label = label, separator = '-')
		value = self._decorate(value = value, format = format, uppercase = True)
		return value

	'''
		FUNCTION:
			Sets the release group.
		PARAMETERS:
			value (string/list): The release group.
			extract (boolean): Wether to extract the value or accept the raw value as is.
		RETURNS:
			The extracted and processed value that was set (string/None).
	'''
	def releaseGroupSet(self, value, extract = True):
		if extract: value = self.releaseGroupExtract(data = value, clean = False)
		if value and not tools.Tools.isArray(value): value = [value]
		self.mData['release']['group'] = value
		return value

	'''
		FUNCTION:
			Extracts the release group from a string.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			clean (boolean): Wether or not to clean the data before processing.
		RETURNS:
			The release group (list).
	'''
	@classmethod
	def releaseGroupExtract(self, data, exclude = None, encode = True, clean = True):
		if not data: return None
		if clean: data = self.cleanBasic(data)
		if encode: exclude = self.cleanEncode(exclude)

		# Various ways of trying to reduce the computational time by splitting the file name does not really work.
		# Only taking the last 30% or 50% of the file name saves about 5% time.
		# However, some groups are at the start or middle of the file name.
		# Trying to eg first test the last half of the file name and only test the first half if no or a single group is found, actually makes everything slower.
		# For now, test the entire file name in one go.
		# Extracting the release groups takes about 0.002‬ secs on a fast CPU (4 seconds for 2000 file names).

		expression = self._expressionFormatExpression(id = 'releaseGroupExtract', type = Stream.ExpressionSequential, expression = Stream.ExpressionReleaseGroup, full = False, keyword = True)
		return self._expressionMatchMultiple(id = 'releaseGroupExtract', data = data, expression = expression, exclude = exclude, count = Stream.ReleaseGroupCount, order = True, start = True, end = True)

	'''
		FUNCTION:
			Cleans a file name from release group keywords.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			guidance (None/string): The already detected release group. Speeds up the cleaning by only removing previously detected keywords, instead of scanning through all keywords.
			split (None/string): If SplitRight/SplitLeft, cuts off the string after/before the first found keyword. If None, simply remove the keyword and keep the rest of the string intact.
		RETURNS:
			The cleaned file name (string).
	'''
	@classmethod
	def releaseGroupClean(self, data, exclude = None, encode = True, guidance = None, split = SplitNone):
		# Order keywords according to length, so that long keywords are removed before short ones ("Napisy PL" before "PL").
		if not data: return data
		if encode: exclude = self.cleanEncode(exclude)
		expression = self._expressionFormatKeyword(id = 'releaseGroupClean', expression = Stream.ExpressionReleaseGroup, guidance = guidance, order = True, group = True)
		return self._expressionReplace(id = 'releaseGroupClean_' + str(guidance), data = data, expression = expression, exclude = exclude, split = split)

	##############################################################################
	# RELEASE UPLOADER
	##############################################################################

	'''
		FUNCTION:
			Retrieves the release uploader.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The release uploader (string).
	'''
	def releaseUploader(self, format = FormatNone, label = LabelNone, default = None):
		value = self.mData['release']['uploader']
		if value is None: return default
		label = self.settingsLayout(label, 'release', 'uploader')
		value = self._label(value = value, format = format, label = label)
		value = self._decorate(value = value, format = format, uppercase = True)
		return value

	'''
		FUNCTION:
			Sets the release uploader.
		PARAMETERS:
			value (string): The release uploader.
		RETURNS:
			The extracted and processed value that was set (string/None).
	'''
	def releaseUploaderSet(self, value):
		try: value = value.strip()
		except: pass
		self.mData['release']['uploader'] = value
		return value

	##############################################################################
	# FILE NAME
	##############################################################################

	'''
		FUNCTION:
			Retrieves the file name.
		PARAMETERS:
			default (various): The default value to return if the attribute is not set.
			generate (boolean): Return a custom generate file name if no file name is available.
			exact (enumeration): Wether or not return the generated/inexact file name if the exact file name is not available.
		RETURNS:
			The file name (string).
	'''
	def fileName(self, default = None, generate = False, exact = ExactAuto):
		value = self.exact(exact = exact, data = self.mData['file']['name'])
		if value is None:
			if generate: return self.fileNameGenerate()
			else: return default
		return value

	'''
		FUNCTION:
			Sets the file name.
		PARAMETERS:
			value (string): The file name.
			exact (enumeration): Wether or not the file name is generated/inexact, or otherwise an exact file name.
		RETURNS:
			The extracted and processed value that was set (string/None).
	'''
	def fileNameSet(self, value, exact = ExactYes):
		if value is True: value = self.fileNameGenerate()
		self.exactSet(exact = exact, data = self.mData['file']['name'], value = value)
		return value

	'''
		FUNCTION:
			Extracts the file name from a link if available.
		PARAMETERS:
			data (string): The link.
		RETURNS:
			The file name (None/string).
	'''
	@classmethod
	def fileNameExtract(self, data):
		def _fileNameExtract(name, original = None, full = True):
			try:
				# https://putlockers.fm/watch/dVnLqOed-dune-2021/userload.html
				match = self._cacheId('fileNameExtract1', re.compile, '\/watch\/[a-z0-9]{5,}\-(.*?)\/[a-z0-9]+(?:$|\.htm)', flags = Stream.ExpressionFlags).search(original)
				if match:
					name = match.group(1)
					full = False
				else:
					# https://iwaatch.com/server1/Dune/movie_720.mp4/eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJ2YWxpZGF0ZSIsInN1YiI6IjgzLjk3LjIzLjIwIn0.WafpTGDPL8dq7f5lxlcdaSTFnppao6WEr3RvR64-iRkrO7gRqhw0jGwztF6HVg0l4PuYiz_D4yHOPdYCOKc-xQ
					match = self._cacheId('fileNameExtract2', re.compile, 'iwaatch.com\/server\d+\/(.*?\/.*?)\/', flags = Stream.ExpressionFlags).search(original)
					if match:
						name = match.group(1).replace('movie_', '').replace('show_', '').replace('episode_', '').replace('/', '_')
						full = False

				# Mega and others do not have file names.
				# https://mega.nz/#!afxVWYLQ!wFNHcI2mN8JYVnd-cGW5mpsQR2bg9ID43POYmPDcMTk
				# https://downace.com/n7wL
				# https://tny.so/Vmdm34
				# http://fumacrom.com/29PZC
				# http://gosafedomain.eu/HVK2sVo
				# https://paste2.org/gsImNOKH
				if self._cacheId('fileNameExtract3', re.compile, '(mega|downace|tny|fumacrom|gosafedomain|paste\d*)\.[a-z]{2,5}\/', flags = Stream.ExpressionFlags).search(original):
					return None

				elif not self._cacheId('fileNameExtract4', re.compile, '[.-_\s]', flags = Stream.ExpressionFlags).search(name):
					return None

				# For links with a lot of remaining parameters. Like googlevideos links that are incorrectly split on the last /, since it contains the mime (eg: video/mp4).
				# https://redirector.googlevideo.com/videoplayback?id=77d2a520f352e14e&itag=22&source=picasa&begin=0&requiressl=yes&mm=30&mn=sn-4g5e6nsz&ms=nxu&mv=u&mvi=1&pl=24&sc=yes&ei=WqVGXb3jCayS8gP_lpHoBQ&susc=ph&app=fife&mime=video/mp4&cnr=14
				elif name.count('&') > 3:
					return None

				# https://iwaatch.com:3000/server1/It_Chapter_Two/movie_1080.mp4/eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiJ2YWxpZGF0ZSIsInN1YiI6IjgyLjEwMi4xNi4xNDcifQ.Ub1uN8LHXEAoCsUG-cxu9lU9EPjW78cTIi1hZzXBIBs-MkwF24p7oXeWF-Y1EMSp7dXR1JBak29DdZy4VY-cog
				elif len(name) > 150:
					return None

				elif self._cacheId('fileNameExtract5', re.compile, '^[a-z0-9]*$').search(name) or self._cacheId('fileNameExtract6', re.compile, '^[a-z0-9]{16,}$', flags = Stream.ExpressionFlags).search(name) or self._cacheId('fileNameExtract7', re.compile, '^[0-9]{6,}$', flags = Stream.ExpressionFlags).search(name):
					return None

				# https://www.fembed.com/v/dk05nuxn3e8kqn3.html
				elif self._cacheId('fileNameExtract8', re.compile, '^(embed(ded)?[\-\_]?)?([a-z0-9]|' + Stream.ExpressionSymbol + '){10,15}(\.[a-z0-9]{1,2}ml)?([\-\_]?\d{3,5}x\d{3,5})?\.html?$', flags = Stream.ExpressionFlags).search(name):
					return None

				# https://vidcloud9.com/load.php?id=MjUzMzEz&title=Game+of+Thrones+-+Season+8+Episode+2+-+A+Knight+of+The+Seven+Kingdoms&typesub=SUB&sub=L2dhbWUtb2YtdGhyb25lcy1zZWFzb24tOC1lcGlzb2RlLTIvZ2FtZS1vZi10aHJvbmVzLXNlYXNvbi04LWVwaXNvZGUtMi52dHQ=&cover=Y292ZXIvZ2FtZS1vZi10aHJvbmVzLXNlYXNvbi04LnBuZw==
				# https://database.gdriveplayer.us/player.php?imdb=tt11138512
				# https://api.123movie.cc/imdb.php?imdb=tt11138512&server=vcu
				# https://www.2embed.ru/embed/imdb/movie?id=tt11138512
				elif self._cacheId('fileNameExtrac9', re.compile, '^(load(?:server)?|go|download|stream(?:ing)?|player|watch|vid(?:eo)?|movie|show|episode|imdb|embed(?:ded)?|vshare|skyvids?|veoh|vip)(\.(php|html?))?$', flags = Stream.ExpressionFlags).search(name):
					return None

				# Base64
				# http://alltube.tv/film/to-rozdzial-2-it-chapter-two-2019/89467?http://alltube.pl/link/bWlkPTg5NDY3Jmhvc3Rpbmc9Y2xpcHdhdGNoaW5nJmlkPXBzMDFlZWoyY3V3NiZsb2dpbj1za2FuaW8=
				elif self._cacheId('fileNameExtract10', re.compile, '^[a-z0-9\+\/\=]{64,}$', flags = Stream.ExpressionFlags).search(name):
					return None

				if name:
					# https://easyload.io/e/MbXDWenVd1?c1_file=https://sub.movie-series.net/joker/joker.vtt&c1_label=English
					# https://sbplay1.com/e/lafko7zela8b?caption_1=https://sub.movie-series.net/free-guy/free-guy.vtt&sub_1=English
					# There are too many domains with different parameters after the .vtt, so instead extract everything before the vtt.
					# name = self._cacheId('fileNameExtract11', re.compile, '(&(c\d+_label|sub_\d+|default).*?)$', flags = Stream.ExpressionFlags).sub('', name)
					match = self._cacheId('fileNameExtract11', re.compile, '(.*?\.vtt)[&?]', flags = Stream.ExpressionFlags).search(name)
					if match: name = match.group(1)

					# Remove trailing extensions.
					name = self._cacheId('fileNameExtract12', re.compile, '(\.(?:html?|php|txt|torrent|nzb))$', flags = Stream.ExpressionFlags).sub('', name)

					if full:
						# https://www.youtube.com/embed/2B0RpUGss2c
						# https://mediashore.org/v/6wlwgh0gqr-q72y
						if self._cacheId('fileNameExtract13', re.compile, '^[a-z0-9\&\!\-]{10,15}$', flags = Stream.ExpressionFlags).search(name):
							return None

					# Is hash or timestamp.
					if self._cacheId('fileNameExtract14', re.compile, '^(\d{8,}|[0-9a-f]{32,})$', flags = Stream.ExpressionFlags).search(name):
						return None

			except: tools.Logger.error()

			return name

		if not data: return data
		if not tools.Tools.isArray(data): data = [data]

		for original in data:
			container = network.Container(link = original, download = False)
			if container.torrentIsMagnet():
				name = container.torrentName()
			else:
				name = original.rsplit('|')[0].rsplit('/', 1)[-1].rsplit('?')[0]
				name = _fileNameExtract(name = name, original = original)

				if not name:
					parameters = network.Networker.linkParameters(original)
					if parameters:
						for parameter in ['title', 'name', 'file']:
							if parameter in parameters:
								name = _fileNameExtract(name = parameters[parameter], original = original, full = False)
								if name: break
			if name: return name
		return None

	'''
		FUNCTION:
			Generate a file name for metadata.
		PARAMETERS:
			metadata (boolean): Add metadata info to the end.
			prefix (boolean): Add Gaia prefix to the start.
			raw (boolean): Return the raw title without year, season, episode, or metadata.
		RETURNS:
			The file name (string).
	'''
	def fileNameGenerate(self, metadata = True, prefix = False, raw = False):
		title = self.metaTitle(title = Stream.TitleMain)
		title = title[0] if tools.Tools.isArray(title) else title
		if raw: return title

		year = self.metaYear()
		if year: title += u' (%d)' % year

		season = self.numberSeason()
		episode = self.numberEpisode()
		if season:
			if self.filePack():
				try: title += ' S%02d' % int(season[0])
				except: pass
			elif episode:
				try: title += ' S%02dE%02d' % (int(season[0]), int(episode[0]))
				except: pass

		if metadata:
			metadata = []
			quality = self.videoQuality(label = Stream.LabelMedium, exact = Stream.ExactYes) # Only use the exact video quality, since we do not want to pollute the file name with inexact metadata.
			try: quality = quality.replace('HD ', '').replace('SD ', '').replace('SCR ', '').replace('CAM ', '') # Can be None.
			except: pass
			metadata.append(quality)
			metadata.append(self.video3d(label = Stream.LabelMedium))
			metadata.append(self.videoCodec(label = Stream.LabelShort))
			metadata.append(self.audioCodec(label = Stream.LabelShort, system = True))
			metadata.append(self.audioChannels(label = Stream.LabelShort))
			metadata.append(self.releaseType(label = Stream.LabelShort))
			metadata.append(self.releaseFormat(label = Stream.LabelShort))
			metadata.append(self.releaseGroup(label = Stream.LabelShort))
			metadata.append(self.releaseEdition(label = Stream.LabelLong))
			metadata = [i for i in metadata if i]
			if len(metadata) > 0: title += ' [%s]' % (', '.join(metadata))
			container = self.fileContainer()
			if container: title += '.' + container

		if prefix: title = u'[%s] %s' % (tools.System.name().upper(), title)
		return title

	'''
		FUNCTION:
			Checks if the file name is incomplete or was cut off.
		PARAMETERS:
			data (string): The file name.
		RETURNS:
			If the file name is incomplete (boolean).
	'''
	@classmethod
	def fileNameIncomplete(self, data):
		return self.__fileNameIncomplete(data = data)

	def _fileNameIncomplete(self):
		return self.__fileNameIncomplete(data = self.fileName())

	@classmethod
	def __fileNameIncomplete(self, data):
		return bool(data and self._cacheId('fileNameIncomplete', re.compile, Stream.ExpressionFileNameIncomplete, flags = Stream.ExpressionFlags).search(data))

	'''
		FUNCTION:
			Checks wether the file name, format, and extension is valid.
		PARAMETERS:
			data (string): The file name.
			raw (string): The raw unprocessed file name.
			type (string): The source type.
			none (string): The value if there is not file name.
		RETURNS:
			Wether the file name is valid (boolean).
	'''
	@classmethod
	def fileNameValid(self, data, raw = None, type = None, none = True):
		return self.__fileNameValid(data = data, raw = raw, type = type, none = none)

	def _fileNameValid(self, none = True):
		return self.__fileNameValid(data = self.fileName(), raw = self.fileName(exact = Stream.ExactRaw), type = self.sourceType(), none = none)

	@classmethod
	def __fileNameValid(self, data, raw = None, type = None, none = True):
		def __fileNameValid(data, raw, type, none):
			if not data: return none

			try: extension = data.split('.')[-1].lower().replace('.', '').strip()
			except: extension = None

			if extension:

				# In case the type is not set or a usenet file name is used by a torrent/hoster.
				# Use the raw file name, since the normal file name is cleaned.
				if self._expressionMatch(id = 'fileNameValid1', data = raw if raw else data, expression = Stream.ExpressionSymbolStart + '(yenc|nzb)' + Stream.ExpressionSymbolEnd):
					type = Stream.SourceTypeUsenet

				# Archives
				if extension in ['iso', 'udf', 'img', 'nrg', 'dmg']: return False

				# Archives
				# Do not do these for usenet, since valid files can contain them.
				if not type == Stream.SourceTypeUsenet:
					if extension in ['rar', 'zip', 'zipx', '7z', 's7z', '7zip', 'tar', 'gz']: return False

					# .par2
					# .part1
					# .r01
					if self._expressionMatch(id = 'fileNameValid2', data = extension, expression = '^(part?\d*|r\d{2,3})$'): return False

					# .001
					# Only for long file names, otherwise it might flag correct names.
					# Eg: Dune.2021
					# Eg: James.Bond.007
					# Exclude 100+:
					# Eg: Avatar.2009.Extended.Collectors.Edition.DTS-HD.DTS.MULTISUBS.108
					if len(data) > 20 and self._expressionMatch(id = 'fileNameValid3', data = extension, expression = '^(0\d{2})$'): return False

			return True

		return self._cache(__fileNameValid, data = data, raw = raw, type = type, none = none)

	##############################################################################
	# FILE EXTRA
	##############################################################################

	'''
		FUNCTION:
			Retrieves the file extra.
		PARAMETERS:
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The file extra (string).
	'''
	def fileExtra(self, default = None):
		value = self.mData['file']['extra']
		if value is None: return default
		return value

	'''
		FUNCTION:
			Sets the file extra.
		PARAMETERS:
			value (string): The file extra.
		RETURNS:
			The extracted and processed value that was set (string/None).
	'''
	def fileExtraSet(self, value):
		self.mData['file']['extra'] = value if value else None
		return value

	##############################################################################
	# FILE SIZE
	##############################################################################

	'''
		FUNCTION:
			Retrieves the file size.
		PARAMETERS:
			format (string): The formatting applied to the result.
			label (string): The type or unit label to use.
			estimate (boolean): Wether or not to estimate file sizes for packs.
			duration (None/integer): The duration of the video in seconds. If not passed, the duration previously set in the object will be used.
			pack (None/integer): The movie or episode pack count. If not passed, the count previously set in the object will be used.
			exact (enumeration): Wether or not return the estimated/inexact file size if the exact file size is not available.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The file size (integer/string).
	'''
	def fileSize(self, format = FormatNone, label = LabelNone, estimate = True, duration = None, pack = None, exact = ExactAuto, default = None, internal = False):
		estimateBlock = estimate is None

		# If auto, first lookup the exact value.
		# If the value is not available, the inexact value will be retrieved below.
		# This allows for estimated files sizes to be displayed for Emby/Jellyfin transcoded streams.
		if exact is Stream.ExactAuto: value = self.exact(exact = Stream.ExactYes, data = self.mData['file']['size'])
		else: value = self.exact(exact = exact, data = self.mData['file']['size'])

		# If it is not a file pack and there is an exact size, do not estimate.
		# Eg: some indexers do not have an exact file size for this file, whereas other indexers do have the size.
		# 	Deja.Vu.2006.BDRip.4K.UHD.x264.10Mb.60FPS.AAC.6Ch-BakiG
		# If the exact size is not available, it will be extracted from the file name.
		# Hence, there will be an exact size of 9.0GB and an inexact size of 10MB. Do not create an estimated label in this case, otherwise it will show as +-11kbps.
		if estimate and not self.filePack() and value: estimate = False

		if value is None:
			if exact is Stream.ExactAuto:
				value = self.exact(exact = Stream.ExactNo, data = self.mData['file']['size'])
				if value: estimate = True
			if value is None:
				if internal: return default, estimate
				else: return default
		elif estimate is True:
			# If file pack was detected, but it is actually not part of any pack.
			# Eg: Uncut.Gems.2019.US.Criterion.Collection.UHD.BDRemux.2160p-rutracker.mkv

			if not pack and not (self._metaPackNumber(self.metaPack(), 'count', 'total', 'episode') if self.metaMediaShow() else self._metaPackNumber(self.metaPack(), 'count', 'total')):
				estimate = False
			else:
				estimated = self.exact(exact = Stream.ExactNo, data = self.mData['file']['size'])
				if estimated:
					value = estimated
				else:
					estimated = None
					if self.filePack():
						if not duration: duration = self.metaDuration()
						if not pack: pack = self.metaPack()
						estimated = self._fileSizeEstimate(value = value, media = self.metaMedia(), number = self.numberShow() if self.metaMediaShow() else self.numberCollection(), duration = duration, pack = pack)
					if estimated is None: estimate = False
					else: value = estimated

		if not format == Stream.FormatNone or not label == Stream.LabelNone:
			if not duration: duration = self.metaDuration(default = estimate)
			value2 = value
			label = self.settingsLayout(label, 'file', 'size')
			value = self._label(value = value, format = format, label = label)
			if not value is None:
				from lib.modules.convert import ConverterSize
				value = ConverterSize(value).stringOptimal()
				if estimate:
					estimator = interface.Font.icon(icon = interface.Font.IconEstimator)
					if label == Stream.LabelMedium: value = '%s%s' % (estimator, value)
					elif label == Stream.LabelLong or label == Stream.LabelDetails: value = '%s %s' % (estimator, value)
				if label == Stream.LabelDetails and estimate and not estimateBlock:
					full = self.fileSize(format = format, label = label, estimate = None, pack = pack, duration = duration, default = default)
					value = value + ' (' + full + ')'
				if label == Stream.LabelShort or label == Stream.LabelMedium: value = value.replace(' ', '')
				value = self._decorate(value = value, format = format, color = self.fileSizeColor, colorvalue = value2, colormedia = self.metaMedia(), colorduration = duration)
		if internal: return value, estimate
		else: return value

	'''
		FUNCTION:
			Sets the file size.
			The size can be the number of bytes or a formatted size string.
		PARAMETERS:
			value (integer/string): The file size.
			extract (boolean): Wether to extract the value or accept the raw value as is.
			exact (enumeration): Wether or not the file size is estimated/inexact, or otherwise an exact file size.
			estimate (boolean): Wether or not to estimate file sizes for packs.
			duration (None/integer): The movie or episode. If not passed, the duration previously set in the object will be used.
			pack (None/integer): The movie or show pack count. If not passed, the pack previously set in the object will be used.
		RETURNS:
			The extracted and processed value that was set (integer/None).
	'''
	def fileSizeSet(self, value, extract = True, exact = ExactYes, estimate = True, duration = None, pack = None):
		value = self.fileSizeExtract(data = value, clean = False) if extract else value
		if exact is Stream.ExactNo:
			self.mData['file']['size']['inexact'] = value
		else:
			self.mData['file']['size']['exact'] = value
			if self.mData['file']['size']['inexact'] is None and self.filePack():
				if not duration: duration = self.metaDuration()
				if not pack: pack = self.metaPack()
				self.mData['file']['size']['inexact'] = self._fileSizeEstimate(value = value, media = self.metaMedia(), number = self.numberShow() if self.metaMediaShow() else self.numberCollection(), duration = duration, pack = pack)
		return value

	'''
		FUNCTION:
			Checks wether the file size is greater than a minimum threshold.
			Can be called on an instance (without the value parameter), or on the class (with the value parameter).
		PARAMETERS:
			data (integer): The file size.
			none (boolean): If True, file sizes that are unknown (None) are accepted as valid.
			threshold (None/integer): A custom seed threshold. If None, uses the default threshold.
		RETURNS:
			Wether the file size is valid (boolean).
	'''
	@classmethod
	def fileSizeValid(self, data, none = True, threshold = None):
		return self.__fileSizeValid(data = data, none = none, threshold = threshold)

	def _fileSizeValid(self, none = True, exact = ExactYes):
		# NB: Do not estimate the file size if there is an exact and inexact file size available (eg: from Orion).
		return self.__fileSizeValid(data = self.fileSize(exact = exact, estimate = False), none = none, threshold = self.thresholdSize(media = self.metaMedia(), pack = self.filePack(), default = True))

	@classmethod
	def __fileSizeValid(self, data, none = True, threshold = None):
		if data is None: return none
		return data >= (self.threshold('size', 'common') if threshold is None else threshold)

	'''
		FUNCTION:
			Extracts the file size from a string.
			The size can be the number of bytes or a formatted size string.
		PARAMETERS:
			data (string): The string.
			clean (boolean): Wether or not to clean the data before processing.
			name (boolean): Wether or not the data attribute is a file name or not.
			threshold (integer): The minimum file size extracted from the file name that should be accepted.
		RETURNS:
			The file size in bytes (integer).
	'''
	@classmethod
	def fileSizeExtract(self, data, clean = True, name = False, threshold = None):
		if not data: return None
		result = None
		if tools.Tools.isString(data):
			if clean: data = self.cleanBasic(data)
			if name:
				match = self._cacheId('fileSizeExtract1', re.compile, Stream.ExpressionFileSize, flags = Stream.ExpressionFlags).search(data)
				if match:
					result = match.group(1)
					from lib.modules.convert import ConverterSize
					result = ConverterSize(result).value()
			else:
				match = self._cacheId('fileSizeExtract2', re.compile, '^\s*([\d\,\.]+)\s*$', flags = Stream.ExpressionFlags).search(data)
				if match:
					match = self._cacheId('fileSizeExtract3', re.compile, '[\,\.\s]', flags = Stream.ExpressionFlags).sub('', match.group(1))
					result = int(match)
				else:
					from lib.modules.convert import ConverterSize
					result = ConverterSize(data).value()
		elif tools.Tools.isFloat(data):
			result = int(data)
		elif tools.Tools.isInteger(data):
			result = data

		# If file size is exactly 0, assume that it has a different value, but the site does not have it (eg: SubTorrent).
		if result == 0: result = None

		# Ignore small file sizes extracted from file names, since it is probably not the correct size.
		# 	Deja.Vu.2006.BDRip.4K.UHD.x264.10Mb.60FPS.AAC.6Ch-BakiG (actual file size is 9.0GB).
		if name and result:
			if threshold is None: threshold = self.threshold('size', 'common')
			if threshold:
				threshold = min(threshold, 20971520)
				if result < threshold: result = None

		return result

	'''
		FUNCTION:
			Cleans a file name from file size keywords.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			split (None/string): If SplitRight/SplitLeft, cuts off the string after/before the first found keyword. If None, simply remove the keyword and keep the rest of the string intact.
		RETURNS:
			The cleaned file name (string).
	'''
	@classmethod
	def fileSizeClean(self, data, exclude = None, encode = True, split = SplitNone):
		if not data: return data
		if encode: exclude = self.cleanEncode(exclude)
		return self._expressionReplace(id = 'fileSizeClean', data = data, expression = Stream.ExpressionFileSize, exclude = exclude, split = split)

	'''
		FUNCTION:
			Retrieve the gradient color for the file size.
		PARAMETERS:
			value (integer): The file size.
			duration (None/integer): Optional duration in seconds.
			media (None/string): Optional media type.
		RETURNS:
			The file size color (string).
	'''
	@classmethod
	def fileSizeColor(self, value, duration = None, media = None):
		if duration is None: duration = self.metaDurationDefault(media = media)
		return self.fileBandwidthColor(value = int((value / duration) * 8.0) if value and duration else None, duration = duration, media = media)

	@classmethod
	def _fileSizeSettings(self):
		result = Filters.instance().data(category = Filters.CategoryFile, attribute = Filters.AttributeSize)
		if result:
			if not result[Filters.ValueMaximum]: return None
			result = [result[Filters.ValueMinimum], result[Filters.ValueMaximum]]
		return result

	@classmethod
	def _fileSizeEstimate(self, value, media = None, number = None, duration = None, pack = None):
		try:
			if not value or not pack: return value

			totalCount = 0
			totalDuration = 0

			if tools.Tools.isInteger(pack):
				totalCount = pack
			else:
				if tools.Media.isMovie(media): # Movie pack
					count = self._metaPack(pack, 'count', 'total')

					if number and len(number) == 1 and number[0] == Stream.NumberPack: number = list(range(1, count + 1))# Movie pack with unknown number.
					if number:
						totalCount = len(number)

						durations = self._metaPackList(pack, 'duration', 'values', number)
						durations = [i for i in durations if not i is None]
						if durations: totalDuration += sum(durations)

						# Movies without a duration.
						count = len(durations)
						if totalCount > count: totalDuration += (totalCount - count) * (self._metaPackNumber(pack, 'duration', 'mean') or Stream.DurationMovie)
					else:
						totalCount = count
				else:
					if not Stream.NumberPack in number['season'] and len(number['season']) <= 1 and len(number['episode']) > 0: # Episode pack.
						totalCount = len(number['episode'])
						if len(number['season']) == 0: # Only contains episode numbers, but no season number.
							totalDuration += totalCount * (self._metaPackNumber(pack, 'duration', 'mean') or Stream.DurationShow)
						else:
							season = number['season'][0]

							durations = self._metaPackList(pack, 'duration', 'episode', season, number['episode'])
							durations = [i for i in durations if not i is None]
							if durations: totalDuration += sum(durations)

							# Specials often do not have a duration. Use default values.
							count = len(durations)
							if totalCount > count: totalDuration += (totalCount - count) * (Stream.DurationSpecial if season == 0 else (self._metaPackNumber(pack, 'duration', 'mean') or Stream.DurationShow))
					else:
						mean = self._metaPackNumber(pack, 'duration', 'mean') or Stream.DurationShow
						for i in number['season']:
							if i == Stream.NumberPack: # Show packs.
								totalCount += self._metaPackNumber(pack, 'count', 'official', 'episode')
								totalDuration += self._metaPackNumber(pack, 'duration', 'total')
							else: # Season packs.
								count = self._metaPackNumber(pack, 'count', 'season', i)
								if count:
									totalCount += count
									temp = self._metaPackNumber(pack, 'duration', 'season', i)
									if temp: totalDuration += temp
									else: totalDuration += Stream.DurationSpecial if i == 0 else mean # Specials often do not have a duration. Use default values.
								else: # Season not found. Use the mean season count.
									totalCount += self._metaPackNumber(pack, 'count', 'official', 'mean')

			if duration and totalDuration: result = value * (duration / float(totalDuration))
			else: result = value / float(totalCount or 1)
			return int(round(result))
		except:
			tools.Logger.error()
			return None

	##############################################################################
	# FILE BANDWIDTH
	##############################################################################

	'''
		FUNCTION:
			Retrieves the file bandwidth/speed in bits/second instead of the file size in bytes.
		PARAMETERS:
			format (string): The formatting applied to the result.
			label (string): The type or unit label to use.
			estimate (boolean): Wether or not to estimate file sizes for packs.
			duration (None/integer): The duration of the video in seconds. If not passed, the duration previously set in the object will be used.
			pack (None/integer): The movie or show pack count. If not passed, the pack previously set in the object will be used.
			exact (enumeration): Wether or not return the estimated/inexact file size if the exact file size is not available.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The file bandwidth (integer/string).
	'''
	def fileBandwidth(self, format = FormatNone, label = LabelNone, estimate = True, pack = None, duration = None, exact = ExactAuto, default = None):
		value, estimate = self.fileSize(estimate = estimate, pack = pack, duration = duration, exact = exact, internal = True)
		if value is None: return default
		if not duration: duration = self.metaDuration(default = estimate)
		if not duration: return default
		value = int((value * 8.0) / duration)

		if not format == Stream.FormatNone or not label == Stream.LabelNone:
			value2 = value
			label = self.settingsLayout(label, 'file', 'bandwidth')
			value = self._label(value = value, format = format, label = label)
			if not value is None:
				from lib.modules.convert import ConverterSpeed
				value = ConverterSpeed(value = value, unit = ConverterSpeed.Bit).stringOptimal(unit = ConverterSpeed.Bit, notation = ConverterSpeed.SpeedLetter)
				if estimate:
					estimator = interface.Font.icon(icon = interface.Font.IconEstimator)
					if label == Stream.LabelMedium: value = '%s%s' % (estimator, value)
					elif label == Stream.LabelLong or label == Stream.LabelDetails: value = '%s %s' % (estimator, value)
				if label == Stream.LabelShort or label == Stream.LabelMedium: value = value.replace(' ', '')
				value = self._decorate(value = value.title(), format = format, color = self.fileBandwidthColor, colorvalue = value2, colormedia = self.metaMedia(), colorduration = duration)

		return value

	'''
		FUNCTION:
			Retrieve the gradient color for the file bandwidth.
		PARAMETERS:
			value (integer): The file bandwidth.
			duration (None/integer): Optional duration in seconds.
			media (None/string): Optional media type.
		RETURNS:
			The file bandwidth color (string).
	'''
	@classmethod
	def fileBandwidthColor(self, value, duration = None, media = None):
		minimum, maximum, count, step = self._cacheId('fileBandwidthColor1', self._fileBandwidthRange, duration, media)
		colors = self._cacheId('fileBandwidthColor2', interface.Format.colorGradientDecrease, count)

		if not value: return colors[0]
		value = min(value - minimum, maximum)
		value = int(value / float(step))

		return interface.Format.colorGradientPick(value, colors)

	@classmethod
	def _fileBandwidthRange(self, duration, media, size = False):
		if duration is None: duration = self.metaDurationDefault(media = media)

		settings = None
		settingsBandwidth = self._fileBandwidthSettings()
		if size or not settingsBandwidth:
			settings = self._fileSizeSettings()
			if settings: settings = [(settings[0] / duration) * 8.0, (settings[1] / duration) * 8.0] # Create a new array, otherwise the _fileSizeSettings values are edited (passed by reference).
		if not settings: settings = settingsBandwidth

		# If custom filters were set, use those as range.
		# Otherwise use the existing speedtest, or if also not available, fall back to hardcoded range.
		if settings:
			minimum = settings[0]
			maximum = settings[1]
		else:
			from lib.modules.speedtest import SpeedTester
			speedtest = SpeedTester.result()
			if speedtest:
				minimum = int(speedtest * 0.7)
				maximum = speedtest
			else:
				minimum = Stream.FileBandwidthMinimum
				maximum = Stream.FileBandwidthMaximum

		# Multiply with larger number that the colors for files that are close to optimal/highest size are greener instead of orange/red.
		# Values that are the same as the internet speed should be green-yellowish.
		maximum = int(maximum * 2.0)

		count = Stream.FileBandwidthCount
		step = int((maximum - minimum) / float(count))

		return minimum, maximum, count, step

	@classmethod
	def _fileBandwidthSettings(self):
		result = Filters.instance().data(category = Filters.CategoryFile, attribute = Filters.AttributeBandwidth)
		if result:
			if not result[Filters.ValueMaximum]: return None
			result = [result[Filters.ValueMinimum], result[Filters.ValueMaximum]]
		return result

	##############################################################################
	# FILE CONTAINER
	##############################################################################

	'''
		FUNCTION:
			Retrieves the file container.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The file container (string).
	'''
	def fileContainer(self, format = FormatNone, label = LabelNone, default = None):
		value = self.mData['file']['container']
		if value is None: return default
		label = self.settingsLayout(label, 'file', 'container')
		return self._label(value = value, values = Stream.LabelFileContainer, format = format, label = label)

	'''
		FUNCTION:
			Sets the file container.
		PARAMETERS:
			value (string): The file container.
			extract (boolean): Wether to extract the value or accept the raw value as is.
		RETURNS:
			The extracted and processed value that was set (string/None).
	'''
	def fileContainerSet(self, value, extract = True):
		value = self.fileContainerExtract(data = value, clean = False) if extract else value
		self.mData['file']['container'] = value
		return value

	'''
		FUNCTION:
			Extracts the file container from a string.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			clean (boolean): Wether or not to clean the data before processing.
		RETURNS:
			The file container (string).
	'''
	@classmethod
	def fileContainerExtract(self, data, exclude = None, encode = True, clean = True):
		if not data: return None
		if clean: data = self.cleanBasic(data)
		if encode: exclude = self.cleanEncode(exclude)

		expression = self._expressionFormatExpression(id = 'fileContainerExtract', type = Stream.ExpressionSequential, expression = Stream.ExpressionFileContainer)
		return self._expressionMatchType(id = 'fileContainerExtract', data = data, expression = expression, exclude = exclude)

	'''
		FUNCTION:
			Cleans a file name from file container keywords.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			guidance (None/string): The already detected file container. Speeds up the cleaning by only removing previously detected keywords, instead of scanning through all keywords.
			split (None/string): If SplitRight/SplitLeft, cuts off the string after/before the first found keyword. If None, simply remove the keyword and keep the rest of the string intact.
		RETURNS:
			The cleaned file name (string).
	'''
	@classmethod
	def fileContainerClean(self, data, exclude = None, encode = True, guidance = None, split = SplitNone):
		if not data: return data
		if encode: exclude = self.cleanEncode(exclude)
		count = self._expressionCount(Stream.ExpressionFileContainer)
		expression = self._expressionFormatKeyword(id = 'fileContainerClean_' + str(guidance), expression = Stream.ExpressionFileContainer, guidance = guidance)
		return self._expressionReplace(id = 'fileContainerClean', data = data, expression = expression, exclude = exclude, count = count, split = split)

	##############################################################################
	# FILE PACK
	##############################################################################

	'''
		FUNCTION:
			Retrieves the file pack type.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			boolean (boolean): Return a boolean instead of the file pack type.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The file pack type (string).
	'''
	def filePack(self, format = FormatNone, label = LabelNone, boolean = False, default = None):
		value = self.mData['file']['pack']
		if boolean: return True if value else False
		if value is None or (not label == Stream.LabelNone and value == Stream.FilePackInternal): return default
		label = self.settingsLayout(label, 'file', 'pack')
		value = self._label(value = value, values = Stream.LabelFilePack, format = format, label = label)
		value = self._decorate(value = value, format = format, uppercase = True, bold = True, color = self.filePackColor)
		return value

	'''
		FUNCTION:
			Sets the file pack type.
		PARAMETERS:
			value (string): The file pack type.
			number (None/dictionary): The extracted season and episode numbers.
			extract (boolean): Wether to extract the value or accept the raw value as is.
		RETURNS:
			The extracted and processed value that was set (string/None).
	'''
	def filePackSet(self, value, number = None, extract = True):
		if value is Stream.FilePackDisabled:
			self.mData['file']['pack'] = Stream.FilePackNone
		else:
			value = self.filePackExtract(data = value, number = number, pack = self.metaPack(), clean = False) if extract and not value else value
			self.mData['file']['pack'] = value
		return value

	'''
		FUNCTION:
			Extracts the file pack type from a string.
		PARAMETERS:
			data (string): The file name.
			number (None/dictionary): The extracted season and episode numbers.
			pack (None/dictionary): The movie or show pack count.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			clean (boolean): Wether or not to clean the data before processing.
		RETURNS:
			The file pack type (string).
	'''
	@classmethod
	def filePackExtract(self, data, number = None, pack = None, exclude = None, encode = True, clean = True):
		if not data: return None

		if number and (number['season'] or number['episode']):
			pack = self.numberShowPack(number = number, pack = pack)
			return pack

		if clean: data = self.cleanBasic(data)
		if encode: exclude = self.cleanEncode(exclude)

		result, match = self._expressionMatchType(id = 'filePackExtract1', data = data, expression = self._filePackExpression(), exclude = exclude, extract = True)

		if result == Stream.FilePackYear:
			match = list(match.groups())[1:]
			match = [int(i) for i in match if i]
			match = len(tools.Tools.listUnique(match)) # Duplicate years (eg: 1984.1984.2160p.AIUpscale.HEVC)
			if match > 1: result = Stream.FilePackCollection
			else: result = None

		if result:
			if self._expressionMatch(id = 'filePackExtract2', data = data, expression = Stream.ExpressionFilePack['exception'], exclude = exclude):
				# If there is no pack or the pack is 1, it probably means that it is not part of a pack, and the detected keyword means something else.
				#	Eg: The.Northman.2022.COMPLETE.UHD.BLURAY-B0MBARDiERS
				# Only do this if the "complete" keyword is the only pack keyword and there is no date range.
				if not pack or (tools.Tools.isInteger(pack) and pack <= 1) or (tools.Tools.isDictionary(pack) and (self._metaPackNumber(pack, 'count', 'total', 'episode') if tools.Media.isShow(self._metaPackNumber(pack, 'media')) else self._metaPackNumber(pack, 'count', 'total')) <= 1):
					if not self._expressionMatch(id = 'filePackExtract3', data = data, expression = self._expressionFormatCommon(Stream.ExpressionFilePack['completeless']), exclude = exclude):
						if not self._expressionMatch(id = 'filePackExtract4', data = data, expression = self._expressionFormatCommon(Stream.ExpressionYearMultiple), exclude = exclude):
							return None

				# Regex lookbehind cannot have a variable number of negations, but needs a fixed number.
				# Eg (plus at thew end): (?<!' + ExpressionYear + ExpressionSeparator + '+)'
				# Eg: James Bond 007 Complete Collection 720p BluRay Dual Audio (1962 -2025) [2.0 en,hi 720p]
				# Replace duplicate symbols with a single one.
				data = self._cacheId('filePackExtract5', re.compile, Stream.ExpressionSymbol + '{2,}', flags = Stream.ExpressionFlags).sub(' ', data)
				if self._expressionMatch(id = 'filePackExtract6', data = data, expression = Stream.ExpressionYearSingle, exclude = exclude): return None

		return result

	'''
		FUNCTION:
			Cleans a file name from file pack keywords.
		PARAMETERS:
			data (string): The file name.
			exclude (None/string/list/tuple): If set, exclude titles from matching.
			encode (boolean): Unicode encode the excludes titles. This should only be done if this function is called externally. If the function is called internally, encoding should be disbaled for efficieny (only done once at the start).
			guidance (None/string): The already detected file pack. Speeds up the cleaning by only removing previously detected keywords, instead of scanning through all keywords.
			split (None/string): If SplitRight/SplitLeft, cuts off the string after/before the first found keyword. If None, simply remove the keyword and keep the rest of the string intact.
		RETURNS:
			The cleaned file name (string).
	'''
	@classmethod
	def filePackClean(self, data, exclude = None, encode = True, guidance = None, split = SplitNone):
		if not data: return data
		if encode: exclude = self.cleanEncode(exclude)
		count = self._expressionCount(Stream.ExpressionFilePack)
		expression = self._expressionFormatKeyword(id = 'filePackClean_' + str(guidance), expression = Stream.ExpressionFilePack, guidance = guidance)
		return self._expressionReplace(id = 'filePackClean', data = data, expression = expression, exclude = exclude, count = count, split = split)

	'''
		FUNCTION:
			Retrieve the color for the file pack.
		RETURNS:
			The file pack color (string).
	'''
	@classmethod
	def filePackColor(self):
		def _filePackColor():
			return interface.Format.colorLighter(color = interface.Format.colorAlternative(), change = 0.5)
		return self._cacheId('filePackColor', _filePackColor)

	@classmethod
	def _filePackExpression(self, collection = False, show = False, full = True):
		def __filePackExpression(collection, show, full):
			expression = tools.Tools.copy(Stream.ExpressionFilePack)
			expression['expression'] = list(expression['expression'])
			if show:
				for item in Stream.ExpressionShow['language']:
					expression['expression'].append((item[0], item[1]['pack']))
			else:
				expression['expression'].append((Stream.FilePackYear, Stream.ExpressionYearGroupMultiple))

			if not full:
				for i in range(len(expression['expression'])):
					expression['expression'][i] = (expression['expression'][i][0], expression['expression'][i][1].replace('{complete}|', ''))

			result = self._expressionFormatExpression(id = '_filePackExpression_' + str(show) + '_' + str(full), type = Stream.ExpressionSequential, expression = expression)

			if collection: result = result[-1][1]
			return result

		return self._cache(__filePackExpression, collection = collection, show = show, full = full)

	##############################################################################
	# SOURCE TYPE
	##############################################################################

	'''
		FUNCTION:
			Retrieves the source type.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The source type (string).
	'''
	def sourceType(self, format = FormatNone, label = LabelNone, default = None):
		value = self.mData['source']['type']
		if value is None: return default
		label = self.settingsLayout(label, 'source', 'type')
		value = self._label(value = value, values = Stream.LabelSourceType, format = format, label = label)
		value = self._decorate(value = value, format = format, bold = True, uppercase = True, color = self.sourceTypeColor)
		return value

	'''
		FUNCTION:
			Sets the source type.
		PARAMETERS:
			value (string): The source type.
		RETURNS:
			The extracted and processed value that was set (string/None).
	'''
	def sourceTypeSet(self, value):
		self.mData['source']['type'] = value
		return value

	'''
		FUNCTION:
			Checks if the source is local.
		RETURNS:
			If it is a local stresourceam (boolean).
	'''
	def sourceTypeLocal(self):
		return self.mData['source']['type'] == Stream.SourceTypeLocal

	'''
		FUNCTION:
			Checks if the source is premium.
		RETURNS:
			If it is a premium source (boolean).
	'''
	def sourceTypePremium(self):
		return self.mData['source']['type'] == Stream.SourceTypePremium

	'''
		FUNCTION:
			Checks if the source is torrent.
		RETURNS:
			If it is a torrent source (boolean).
	'''
	def sourceTypeTorrent(self):
		return self.mData['source']['type'] == Stream.SourceTypeTorrent

	'''
		FUNCTION:
			Checks if the source is usenet.
		RETURNS:
			If it is a usenet source (boolean).
	'''
	def sourceTypeUsenet(self):
		return self.mData['source']['type'] == Stream.SourceTypeUsenet

	'''
		FUNCTION:
			Checks if the source is hoster.
		RETURNS:
			If it is a hoster source (boolean).
	'''
	def sourceTypeHoster(self):
		return self.mData['source']['type'] == Stream.SourceTypeHoster

	'''
		FUNCTION:
			Retrieve the color for the source types.
		RETURNS:
			The source type color (string).
	'''
	@classmethod
	def sourceTypeColor(self):
		return interface.Format.colorMain()

	##############################################################################
	# SOURCE MODE
	##############################################################################

	'''
		FUNCTION:
			Retrieves the source type (torrent or usenet) or otherwise the hoster, publisher, or provider.
			This is used as the "source" to eg find the source is supported by a debrid service.
		PARAMETERS:
			all (boolean): If False, returns the best mode. If True, returns all modes. External providers often have mixed up the sourceHoster and sourcePublisher, so it might be useful to check all of them.
		RETURNS:
			The source mode (string).
	'''
	def sourceMode(self, all = False):
		if all:
			result = [self.sourceType()]
			try: result.append(self.sourceResolved().lower())
			except: pass
			try: result.append(self.sourceHoster().lower())
			except: pass
			try: result.append(self.sourcePublisher().lower())
			except: pass
			try: result.append(self.sourceProvider().lower())
			except: pass
			return result
		else:
			type = self.sourceType()
			if type == Stream.SourceTypeTorrent or type == Stream.SourceTypeUsenet:
				return type
			else:
				try: return self.sourceResolved().lower()
				except:
					try: return self.sourceHoster().lower()
					except:
						try: return self.sourcePublisher().lower()
						except:
							try: return self.sourceProvider().lower()
							except: pass
		return None

	##############################################################################
	# SOURCE PEERS
	##############################################################################

	'''
		FUNCTION:
			Retrieves the number of torrent peers (seeds + leeches).
		PARAMETERS:
			format (string): The formatting applied to the result.
			label (string): The type or unit label to use.
			exact (enumeration): Wether or not return the estimated/inexact seeds if the exact seeds are not available.
			default (various): The default value to return if the attribute is not set.
			separate (boolean): Instead of returning the total peers, return the seeds and leeches separately.
			zero (boolean): Use 0 as the value if it is None.
			uppercase (boolean): Make the output label upper case.
		RETURNS:
			The number of torrent peers (integer/string).
	'''
	def sourcePeers(self, format = FormatNone, label = LabelNone, exact = ExactAuto, default = None, separate = False, zero = False, uppercase = False):
		if not self.sourceTypeTorrent(): return default

		seeds = self.sourceSeeds(exact = exact, default = default, zero = zero)
		leeches = self.sourceLeeches(exact = exact, default = default, zero = zero)
		if seeds is None and leeches is None: return default

		value = None
		if not separate:
			val = 0
			try: val += seeds
			except: pass # In case of None
			try: val +=leeches
			except: pass # In case of None
			value = val

		label = self.settingsLayout(label, 'source', 'peers')
		if label == Stream.LabelHidden: return None
		if not label == Stream.LabelNone:
			if separate:
				value = '%s (%s)' % (self.sourceSeeds(format = format, label = label, zero = True), self.sourceLeeches(format = format, label = label, zero = True))
			else:
				value2 = value
				unit = interface.Translation.string(33190 if value == 1 else 33191)
				if label == Stream.LabelLong or label == Stream.LabelDetails: value = '%d %s' % (value, unit)
				else:
					if value < 1000: value = str(value)
					else:
						value = value / 1000.0
						value = (('%%.%df' % (1 if round(value, 0) < 10 else 0)) % value) + 'K' # Make sure 9999 is not rounded to 10.0K.
					if label == Stream.LabelMedium: value = '%s %s' % (value, unit)
					else: value = '%s %s' % (str(value), unit[0])
				value = self._decorate(value = value, format = format, uppercase = uppercase, color = self.sourcecPeersColor, colorvalue = value2)

		return value

	'''
		FUNCTION:
			Checks wether the number of peers is greater than a minimum threshold.
			Can be called on an instance (without the value parameter), or on the class (with the value parameter).
		PARAMETERS:
			value (integer): The number of peers.
			none (boolean): If True, sepeered counts that are unknown (None) are accepted as valid.
			threshold (None/integer): A custom peer threshold. If None, uses the default threshold.
		RETURNS:
			Wether the peer count is valid (boolean).
	'''
	@classmethod
	def sourcePeersValid(self, data, none = True, threshold = None):
		return self.__sourcePeersValid(data = data, none = none, threshold = threshold)

	def _sourcePeersValid(self, none = True, exact = ExactYes):
		return self.__sourcePeersValid(data = self.sourcePeers(exact = exact), none = none, threshold = self.thresholdPeers())

	@classmethod
	def __sourcePeersValid(self, data, none = True, threshold = None):
		if data is None: return none
		return data >= (self.threshold('peers') if threshold is None else threshold)

	'''
		FUNCTION:
			Adjust the number of seeds or leeches.
			Some sites, like iBit, sometimes have very large values (eg: 4,294,967,295), whicch are probably incorrect.
		PARAMETERS:
			value (integer): The torrent peers.
		RETURNS:
			The adjusted count (integer).
	'''
	@classmethod
	def sourcePeersAdjust(self, value):
		if value and value > 1000000000: return None
		return value

	'''
		FUNCTION:
			Retrieve the gradient color for the torrent peers.
		PARAMETERS:
			value (integer): The torrent peers.
		RETURNS:
			The torrent peers color (string).
	'''
	@classmethod
	def sourcecPeersColor(self, value):
		colors = self._cacheId('sourcecPeersColor', interface.Format.colorGradientIncrease, 100)
		return colors[-1 if value >= len(colors) else int(value)]

	##############################################################################
	# SOURCE SEEDS
	##############################################################################

	'''
		FUNCTION:
			Retrieves the number of torrent seeds.
		PARAMETERS:
			format (string): The formatting applied to the result.
			label (string): The type or unit label to use.
			exact (enumeration): Wether or not return the estimated/inexact seeds if the exact seeds are not available.
			default (various): The default value to return if the attribute is not set.
			zero (boolean): Use 0 as the value if it is None.
			uppercase (boolean): Make the output label upper case.
		RETURNS:
			The number of torrent seeds (integer/string).
	'''
	def sourceSeeds(self, format = FormatNone, label = LabelNone, exact = ExactAuto, default = None, zero = False, uppercase = False):
		if not self.sourceTypeTorrent(): return default
		value = self.exact(exact = exact, data = self.mData['source']['peers']['seeds'])
		if value is None:
			if zero: value = 0
			else: return default
		label = self.settingsLayout(label, 'source', 'peers')
		if label == Stream.LabelHidden: return None

		if not label == Stream.LabelNone:
			value2 = value
			unit = interface.Translation.string(35706 if value == 1 else 33204)
			if label == Stream.LabelLong or label == Stream.LabelDetails: value = '%d %s' % (value, unit)
			else:
				if value < 1000: value = str(value)
				else:
					value = value / 1000.0
					value = (('%%.%df' % (1 if round(value, 0) < 10 else 0)) % value) + 'K' # Make sure 9999 is not rounded to 10.0K.
				if label == Stream.LabelMedium: value = '%s %s' % (value, unit)
				else: value = '%s %s' % (str(value), unit[0])
			value = self._decorate(value = value, format = format, uppercase = uppercase, color = self.sourceSeedsColor, colorvalue = value2)

		return value

	'''
		FUNCTION:
			Sets the number of torrent seeds.
		PARAMETERS:
			value (integer/string): The number of seeds as an integer or a string from which the number will be extracted.
			extract (boolean): Wether to extract the value or accept the raw value as is.
			exact (enumeration): Wether or not the seeds are estimated/inexact, or otherwise exact seeds.
		RETURNS:
			The extracted and processed value that was set (integer/None).
	'''
	def sourceSeedsSet(self, value, extract = True, exact = ExactYes):
		value = self.sourceSeedsExtract(data = value) if extract else value
		value = self.sourcePeersAdjust(value = value)
		self.exactSet(exact = exact, data = self.mData['source']['peers']['seeds'], value = value)
		return value

	'''
		FUNCTION:
			Sets the number of torrent seeds as maximum between the current and new value.
		PARAMETERS:
			value (integer/string): The number of seeds as an integer or a string from which the number will be extracted.
			extract (boolean): Wether to extract the value or accept the raw value as is.
	'''
	def sourceSeedsIncrease(self, value, extract = True):
		if value:
			value = self.sourceSeedsExtract(data = value) if extract else value
			if value:
				exact = self.mData['source']['peers']['seeds']['exact']
				if exact is None:
					inexact = self.mData['source']['peers']['seeds']['inexact']
					if inexact is None: self.mData['source']['peers']['seeds']['inexact'] = value
					else: self.mData['source']['peers']['seeds']['inexact'] = max(value, inexact)
				else:
					self.mData['source']['peers']['seeds']['exact'] = max(value, exact)

	'''
		FUNCTION:
			Checks wether the number of seeds is greater than a minimum threshold.
			Can be called on an instance (without the value parameter), or on the class (with the value parameter).
		PARAMETERS:
			value (integer): The number of seeds.
			none (boolean): If True, seed counts that are unknown (None) are accepted as valid.
			threshold (None/integer): A custom seed threshold. If None, uses the default threshold.
		RETURNS:
			Wether the seed count is valid (boolean).
	'''
	@classmethod
	def sourceSeedsValid(self, data, none = True, threshold = None):
		return self.__sourceSeedsValid(data = data, none = none, threshold = threshold)

	def _sourceSeedsValid(self, none = True, exact = ExactYes):
		return self.__sourceSeedsValid(data = self.sourceSeeds(exact = exact), none = none, threshold = self.thresholdSeeds())

	@classmethod
	def __sourceSeedsValid(self, data, none = True, threshold = None):
		if data is None: return none
		return data >= (self.threshold('seeds') if threshold is None else threshold)

	'''
		FUNCTION:
			Extracts the number of torrent seeds from a string.
			Searches for a number which can be separated by dots or commas (eg: "1,256 Seeds").
		PARAMETERS:
			data (string): The string.
		RETURNS:
			The number of seeds (integer).
	'''
	@classmethod
	def sourceSeedsExtract(self, data):
		if data is None: return None
		if tools.Tools.isString(data):
			try:
				data = self._cacheId('sourceSeedsExtract1', re.compile, Stream.ExpressionNumberGroup, flags = Stream.ExpressionFlags).search(data)
				data = self._cacheId('sourceSeedsExtract2', re.compile, Stream.ExpressionNumberSeparator, flags = Stream.ExpressionFlags).sub('', data.group(1))
				return int(data)
			except: return None
		return data

	'''
		FUNCTION:
			Retrieve the gradient color for the torrent seeds.
		PARAMETERS:
			value (integer): The torrent seeds.
		RETURNS:
			The torrent seeds color (string).
	'''
	@classmethod
	def sourceSeedsColor(self, value):
		colors = self._cacheId('sourceSeedsColor', interface.Format.colorGradientIncrease, 50)
		return colors[-1 if value >= len(colors) else int(value)]

	##############################################################################
	# SOURCE LEECHES
	##############################################################################

	'''
		FUNCTION:
			Retrieves the number of torrent leeches.
		PARAMETERS:
			format (string): The formatting applied to the result.
			label (string): The type or unit label to use.
			exact (enumeration): Wether or not return the estimated/inexact leeches if the exact leeches are not available.
			default (various): The default value to return if the attribute is not set.
			zero (boolean): Use 0 as the value if it is None.
			uppercase (boolean): Make the output label upper case.
		RETURNS:
			The number of torrent leeches (integer/string).
	'''
	def sourceLeeches(self, format = FormatNone, label = LabelNone, exact = ExactAuto, default = None, zero = False, uppercase = False):
		if not self.sourceTypeTorrent(): return default
		value = self.exact(exact = exact, data = self.mData['source']['peers']['leeches'])
		if value is None:
			if zero: value = 0
			else: return default
		label = self.settingsLayout(label, 'source', 'peers')
		if label == Stream.LabelHidden: return None

		if not label == Stream.LabelNone:
			value2 = value
			unit = interface.Translation.string(33125 if value == 1 else 33126)
			if label == Stream.LabelLong or label == Stream.LabelDetails: value = '%d %s' % (value, unit)
			else:
				if value < 1000: value = str(value)
				else:
					value = value / 1000.0
					value = (('%%.%df' % (1 if round(value, 0) < 10 else 0)) % value) + 'K' # Make sure 9999 is not rounded to 10.0K.
				if label == Stream.LabelMedium: value = '%s %s' % (value, unit)
				else: value = '%s %s' % (str(value), unit[0])
			value = self._decorate(value = value, format = format, uppercase = uppercase, color = self.sourceLeechesColor, colorvalue = value2)

		return value

	'''
		FUNCTION:
			Sets the number of torrent leeches.
		PARAMETERS:
			value (integer/string): The number of leeches as an integer or a string from which the number will be extracted.
			extract (boolean): Wether to extract the value or accept the raw value as is.
			exact (enumeration): Wether or not the leeches aare estimated/inexact, or otherwise exact leeches.
		RETURNS:
			The extracted and processed value that was set (integer/None).
	'''
	def sourceLeechesSet(self, value, extract = True, exact = ExactYes):
		value = self.sourceLeechesExtract(data = value) if extract else value
		value = self.sourcePeersAdjust(value = value)
		self.exactSet(exact = exact, data = self.mData['source']['peers']['leeches'], value = value)
		return value

	'''
		FUNCTION:
			Sets the number of torrent leeches as maximum between the current and new value.
		PARAMETERS:
			value (integer/string): The number of leeches as an integer or a string from which the number will be extracted.
			extract (boolean): Wether to extract the value or accept the raw value as is.
	'''
	def sourceLeechesIncrease(self, value, extract = True):
		if value:
			value = self.sourceLeechesExtract(data = value) if extract else value
			if value:
				exact = self.mData['source']['peers']['leeches']['exact']
				if exact is None:
					inexact = self.mData['source']['peers']['leeches']['inexact']
					if inexact is None: self.mData['source']['peers']['leeches']['inexact'] = value
					else: self.mData['source']['peers']['leeches']['inexact'] = max(value, inexact)
				else:
					self.mData['source']['peers']['leeches']['exact'] = max(value, exact)

	'''
		FUNCTION:
			Checks wether the number of leeches is greater than a minimum threshold.
			Can be called on an instance (without the value parameter), or on the class (with the value parameter).
		PARAMETERS:
			value (integer): The number of leeches.
			none (boolean): If True, leeche counts that are unknown (None) are accepted as valid.
			threshold (None/integer): A custom leeche threshold. If None, uses the default threshold.
		RETURNS:
			Wether the leeche count is valid (boolean).
	'''
	@classmethod
	def sourceLeechesValid(self, data, none = True, threshold = None):
		return self.__sourceLeechesValid(data = data, none = none, threshold = threshold)

	def _sourceLeechesValid(self, none = True, exact = ExactYes):
		return self.__sourceLeechesValid(data = self.sourceLeeches(exact = exact), none = none, threshold = self.thresholdLeeches())

	@classmethod
	def __sourceLeechesValid(self, data, none = True, threshold = None):
		if data is None: return none
		return data >= (self.threshold('leeches') if threshold is None else threshold)

	'''
		FUNCTION:
			Extracts the number of torrent leeches from a string.
			Searches for a number which can be separated by dots or commas (eg: "1,256 Leeches").
		PARAMETERS:
			data (string): The string.
		RETURNS:
			The number of leeches (integer).
	'''
	@classmethod
	def sourceLeechesExtract(self, data):
		if data is None: return None
		if tools.Tools.isString(data):
			try:
				data = self._cacheId('sourceLeechesExtract1', re.compile, Stream.ExpressionNumberGroup, flags = Stream.ExpressionFlags).search(data)
				data = self._cacheId('sourceLeechesExtract2', re.compile, Stream.ExpressionNumberSeparator, flags = Stream.ExpressionFlags).sub('', data.group(1))
				return int(data)
			except: return None
		return data

	'''
		FUNCTION:
			Retrieve the gradient color for the torrent leeches.
		PARAMETERS:
			value (integer): The torrent leeches.
		RETURNS:
			The torrent leeches color (string).
	'''
	@classmethod
	def sourceLeechesColor(self, value):
		colors = self._cacheId('sourceLeechesColor', interface.Format.colorGradientIncrease, 500)
		return colors[-1 if value >= len(colors) else int(value)]

	##############################################################################
	# SOURCE TIME
	##############################################################################

	'''
		FUNCTION:
			Retrieves the source time.
		PARAMETERS:
			format (string): The formatting applied to the result.
			label (string): The type or unit label to use.
			time (string): The unit the results will be formatted to. A custom date-time can also be used.
			new (boolean/integer): Whether or not to use the "New" keyword for ages less than 1 day. If an integer is provided, it is used as the day threshold.
			exact (enumeration): Wether or not return the estimated/inexact time if the exact time is not available.
			default (various): The default value to return if the attribute is not set.
			uppercase (boolean): Make the output label upper case.
		RETURNS:
			The source time (integer/string).
	'''
	def sourceTime(self, format = FormatNone, label = LabelNone, time = TimeDefault, new = False, exact = ExactAuto, default = None, uppercase = False):
		value = self.exact(exact = exact, data = self.mData['source']['time'])
		if value is None: return default
		original = value
		label = self.settingsLayout(label, 'source', 'time')
		if label == Stream.LabelHidden: return None

		if new:
			if new is True: new = 1
			new = new * Stream.DurationDay
			if tools.Time.timestamp() - value <= new:
				value = interface.Translation.string(35447)
				if not format == Stream.FormatNone:
					value = self._decorate(value = value, format = format, uppercase = uppercase, color = self.sourceTimeColor, colorvalue = 0)
				return value

		value2 = None
		if time == Stream.TimeSeconds:
			value = tools.Time.timestamp() - value
		elif time == Stream.TimeDays:
			from lib.modules.convert import ConverterDuration
			value = value2 = ConverterDuration(tools.Time.timestamp() - value, unit = ConverterDuration.UnitSecond).value(unit = ConverterDuration.UnitDay)
		elif not format == Stream.FormatNone or not label == Stream.LabelNone:
			if time == Stream.TimeDuration:
				from lib.modules.convert import ConverterDuration
				durationFormat = ConverterDuration.FormatClockLong
				if label == Stream.LabelDetails: durationFormat = ConverterDuration.FormatWordLong
				elif label == Stream.LabelLong: durationFormat = ConverterDuration.FormatWordOptimal
				elif label == Stream.LabelMedium: durationFormat = ConverterDuration.FormatAbbreviationOptimal
				elif label == Stream.LabelShort: durationFormat = ConverterDuration.FormatInitialOptimal
				duration = tools.Time.timestamp() - value
				value = value = ConverterDuration(duration, unit = ConverterDuration.UnitSecond)
				if duration <= Stream.DurationDay: value = value.string(format = durationFormat, seconds = False, capitalize = True)
				else: value = value.string(format = durationFormat, hours = False, minutes = False, seconds = False, capitalize = True)
			else:
				value = tools.Time.format(value, format = tools.Time.FormatDateTime if time == Stream.TimeDate else time)

		if not format == Stream.FormatNone or not label == Stream.LabelNone:
			unit = None
			if time == Stream.TimeSeconds: unit = interface.Translation.string(35630 if value == 1 else 32405)
			if time == Stream.TimeDays: unit = interface.Translation.string(35028 if value == 1 else 33347)
			if unit and not label == Stream.LabelNone:
				if label == Stream.LabelLong or label == Stream.LabelDetails: value = '%d %s' % (value, unit)
				elif label == Stream.LabelMedium: value = '%d %s' % (value, unit[0])
				else: value = '%d%s' % (value, unit[0])
			if not format == Stream.FormatNone:
				if value2 is None:
					from lib.modules.convert import ConverterDuration
					value2 = ConverterDuration(tools.Time.timestamp() - original, unit = ConverterDuration.UnitSecond).value(unit = ConverterDuration.UnitDay)
				value = self._decorate(value = value, format = format, uppercase = uppercase, color = self.sourceTimeColor, colorvalue = value2)

		return value

	'''
		FUNCTION:
			Sets the source time.
			The time can be a timestamp, time string, duration string, or the number of days.
		PARAMETERS:
			value (integer/string): The source time.
			exact (enumeration): Wether or not the time is an estimate/inexact, or otherwise an exact time.
			extract (boolean): Wether to extract the value or accept the raw value as is.
			format (string): Custom date/time format string.
		RETURNS:
			The extracted and processed value that was set (integer/None).
	'''
	def sourceTimeSet(self, value, exact = ExactYes, extract = True, format = None):
		value = self.sourceTimeExtract(data = value, format = format) if extract else value
		self.exactSet(exact = exact, data = self.mData['source']['time'], value = value)
		return value

	'''
		FUNCTION:
			Checks wether the source is less than a maximum threshold.
			Can be called on an instance (without the value parameter), or on the class (with the value parameter).
		PARAMETERS:
			data (integer): The source age in seconds.
			none (boolean): If True, times that are unknown (None) are accepted as valid.
			threshold (None/integer): A custom time threshold. If None, uses the default threshold.
		RETURNS:
			Wether the source time is valid (boolean).
	'''
	@classmethod
	def sourceTimeValid(self, data, none = True, threshold = None):
		return self.__sourceTimeValid(data = data, none = none, threshold = threshold)

	def _sourceTimeValid(self, none = True, exact = ExactYes):
		return self.__sourceTimeValid(data = self.sourceTime(time = Stream.TimeNone, exact = exact), none = none, threshold = self.thresholdTime())

	@classmethod
	def __sourceTimeValid(self, data, none = True, threshold = None):
		if none and data is None: return True
		threshold = self.threshold('time') if threshold is None else threshold
		if threshold: return (tools.Time.timestamp() - data) <= threshold
		else: return True

	'''
		FUNCTION:
			Extracts the source time from a string.
			The time can be a timestamp, time string, duration string, or the number of days.
		PARAMETERS:
			data (string): The string.
			format (string): Custom date/time format string.
		RETURNS:
			The timestamp (integer).
	'''
	@classmethod
	def sourceTimeExtract(self, data, format = None):
		if not data: return None # Do not return "data", because it can be an empty string as well.
		result = data
		if tools.Tools.isString(result):

			result = self._cacheId('sourceTimeExtract1', re.compile, '\d(th|nd|rd)', flags = Stream.ExpressionFlags).sub('', result) # Remove suffixes that cannot be matched with Python date formats.
			result = result.strip()
			try:
				# Make sure this does not include dates (eg: 01.02.2010 or 01.02.10). Allow strings like "1234 seeds".
				match = self._cacheId('sourceTimeExtract2', re.compile, '^\s*(\d+(?:[\,\.\s]\d{3})*)\s*$', flags = Stream.ExpressionFlags).search(result)
				if match: # Timestamp or number of days string.
					match = self._cacheId('sourceTimeExtract3', re.compile, Stream.ExpressionNumberSeparator, flags = Stream.ExpressionFlags).sub('', match.group(1))
					result = int(match)
				else: # Duration or time formatted string.
					from lib.modules.convert import ConverterDuration
					result = self._cacheId('sourceTimeExtract4', re.compile, 'ago', flags = Stream.ExpressionFlags).sub('', result).strip()
					time = ConverterDuration(result).value(unit = ConverterDuration.UnitSecond)
					if time:
						time = tools.Time.timestamp() - time
					else:
						from lib.modules.convert import ConverterTime
						try: time = ConverterTime(result, format = format).timestamp()
						except: pass
					time = int(time)
					return time if time > 0 else None # If something goes wrong, time == 0.
			except: return None

		if result < 20000: # Assuming it is the number of days.
			from lib.modules.convert import ConverterDuration
			result = tools.Time.timestamp() - ConverterDuration(result, unit = ConverterDuration.UnitDay).value(unit = ConverterDuration.UnitSecond)
		elif result < 1000000000: # Assuming it is the number of seconds.
			result = tools.Time.timestamp() - result
		elif result > 100000000000: # Assuming it is a timestamp in milliseconds.
			result = int(result / 1000)
		else: # Assuming it is a timestamp.
			pass

		# Before 1980. Something went wrong with conversion, or the timeformat is weird.
		if result and result < 315532800:
			try: tools.Logger.log('Something went wrong when interpreting the source time. Input: "%s" -> Output: "%s". Resetting the time to none.' % (str(data), str(result)))
			except: pass
			result = None

		return result

	'''
		FUNCTION:
			Retrieve the gradient color for the source time.
		PARAMETERS:
			value (integer): The source time.
		RETURNS:
			The source time color (string).
	'''
	@classmethod
	def sourceTimeColor(self, value):
		from lib.modules.convert import ConverterDuration
		colors = self._cacheId('sourceTimeColor', interface.Format.colorGradientDecrease, 730)
		if value > 1000000000: value = ConverterDuration(tools.Time.timestamp() - value, unit = ConverterDuration.UnitSecond).value(unit = ConverterDuration.UnitDay)
		return colors[-1 if value >= len(colors) else int(value)]

	##############################################################################
	# SOURCE APPROVAL
	##############################################################################

	'''
		FUNCTION:
			Retrieves the source approval.
		PARAMETERS:
			format (string): The formatting applied to the result.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The source approval (float/string).
	'''
	def sourceApproval(self, format = FormatNone, label = LabelNone, default = 0.5):
		value = self.mData['source']['approval']
		if value is None:
			if default is None: return default
			else: value = default
		label = self.settingsLayout(label, 'source', 'popularity')
		if label == Stream.LabelHidden: return None

		if not format == Stream.FormatNone or not label == Stream.LabelNone:
			value2 = value
			value = str(int(round(value * 100)))
			if label == Stream.LabelLong: value = '+%s%%' % value
			elif label == Stream.LabelMedium or label == Stream.LabelShort or label == Stream.LabelDetails: value = '%s%%' % value
			value = self._decorate(value = value, format = format, color = self.sourcePopularityColor, colorvalue = value2)

		return value

	'''
		FUNCTION:
			Sets the source approval.
		PARAMETERS:
			value (float/integer): The source approval.
		RETURNS:
			The extracted and processed value that was set (float/None).
	'''
	def sourceApprovalSet(self, value):
		self.mData['source']['approval'] = value
		return value

	##############################################################################
	# SOURCE POPULARITY
	##############################################################################

	'''
		FUNCTION:
			Retrieves the source popularity.
		PARAMETERS:
			format (string): The formatting applied to the result.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The source popularity (float/string).
	'''
	def sourcePopularity(self, format = FormatNone, label = LabelNone, default = 0.5):
		value = self.mData['source']['popularity']
		if value is None:
			if default is None: return default
			else: value = default
		label = self.settingsLayout(label, 'source', 'popularity')
		if label == Stream.LabelHidden: return None

		if not format == Stream.FormatNone or not label == Stream.LabelNone:
			value2 = value
			value = str(int(round(value * 100)))
			if label == Stream.LabelLong: value = '+%s%%' % value
			elif label == Stream.LabelMedium or label == Stream.LabelShort or label == Stream.LabelDetails: value = '%s%%' % value
			value = self._decorate(value = value, format = format, color = self.sourcePopularityColor, colorvalue = value2)

		return value

	'''
		FUNCTION:
			Sets the source popularity.
		PARAMETERS:
			value (float/integer): The source popularity.
		RETURNS:
			The extracted and processed value that was set (float/None).
	'''
	def sourcePopularitySet(self, value):
		if not value is None:
			if value > 1: value /= 100.0
			value = float(value)
		self.mData['source']['popularity'] = value
		return value

	'''
		FUNCTION:
			Retrieve the gradient color for the source popularity.
		PARAMETERS:
			value (integer): The source popularity.
		RETURNS:
			The source popularity color (string).
	'''
	@classmethod
	def sourcePopularityColor(self, value):
		colors = self._cacheId('sourcePopularityColor', interface.Format.colorGradientIncrease, 90)
		value = int(round(value * 100))
		return colors[-1 if value >= len(colors) else int(value)]

	'''
		FUNCTION:
			Calculates the source popularity based of certain attributes.
		PARAMETERS:
			seeds (None/integer): The number of seeds if available.
			leeches (None/integer): The number of leeches if available.
			time (None/integer): The source time if available.
			approval (None/integer): An extra approval value between 0 (not popular) and 1 (popular).
		RETURNS:
			The source popularity (float).
	'''
	def sourcePopularityCalculate(self, seeds = None, leeches = None, time = None, approval = None):
		try:
			popularity = 0
			ratioApproval = Stream.SourcePopularityRatio['approval']

			if seeds is None: seeds = self.sourceSeeds()
			if leeches is None: leeches = self.sourceLeeches()
			if time is None: time = self.sourceTime(time = Stream.TimeDays)
			if approval is None: approval = self.sourceApproval()

			if not seeds is None or not leeches is None or time or approval:
				if not seeds is None or not leeches is None:
					ratioSeeds = Stream.SourcePopularityRatio['seeds']
					ratioLeeches = Stream.SourcePopularityRatio['leeches']
					if not approval:
						half = ratioApproval / 2.0
						ratioSeeds += half
						ratioLeeches += half
					try: popularity += ratioSeeds * (seeds / float(Stream.SourcePopularityLimit['seeds']))
					except: pass
					try: popularity += ratioLeeches * (leeches / float(Stream.SourcePopularityLimit['leeches']))
					except: pass

					# Check min() here instead of doing it above, like:
					#	popularity += ratioSeeds * min(1, seeds / 100.0)
					# In order to allow either seeds or leeches to exceed 1 before being reduced below.
					# Some sites, like YggTorrent, have many seeds but only 0-2 leeches. Checking min() above would give a low value, since only the seeds part will be at its max and the leeches part will be 0.
					popularity = min(ratioSeeds + ratioLeeches, popularity)
				elif time:
					ratioTime = Stream.SourcePopularityRatio['time']
					limitTime = float(Stream.SourcePopularityLimit['time'])
					try: popularity += ratioTime * max(0, min(1, (limitTime - time) / limitTime))
					except: pass
				if approval:
					if not seeds and not leeches and not time: ratioApproval = 1.0
					popularity += ratioApproval * max(0, min(1, approval))
			else:
				popularity = None

			if not popularity is None:
				# Streams with a lot of missing metadata should not have a high popularity.
				# Eg: A torrent without peers and time should not exceed 30%.
				if self.sourceTypeTorrent():
					if seeds is None and leeches is None:
						popularity = min(popularity, 0.3)
						if time is None: popularity -= 0.15
				elif self.sourceTypeUsenet():
					if time is None: popularity -= 0.1
				elif self.sourceTypeHoster():
					popularity -= 0.1
					if time is None: popularity -= 0.1

				popularity = max(0, min(popularity, 1))

			self.sourcePopularitySet(popularity)
			return popularity
		except:
			tools.Logger.error()

	##############################################################################
	# SOURCE ORIGIN
	##############################################################################

	'''
		FUNCTION:
			Retrieves the source origin.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			gaia (boolean): Whether or not to return the origin if it is Gaia.
			orion (boolean/None): Whether or not to return the origin as Orion if the source came from Orion. If None, use a combination of Orion and the actual origin.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The source origin (string).
	'''
	def sourceOrigin(self, format = FormatNone, label = LabelNone, gaia = True, orion = False, default = None):
		value = self.mData['source']['origin']
		if value is None and orion is False: return default
		if not gaia and value.lower() == 'gaia': return default

		if not orion is False and self.accessTypeOrion():
			from lib.modules import orionoid
			value = orionoid.Orionoid.Name
		if value is None: return default

		label = self.settingsLayout(label, 'source', 'origin')
		if value:
			if label == Stream.LabelShort or label == Stream.LabelMedium:
				value = self._cacheId('sourceOrigin', re.compile, '(scraper.*)', flags = Stream.ExpressionFlags).sub('', value)
			if not label == Stream.LabelNone:
				value = value.capitalize().replace('scraper', 'Scraper')

		value = self._label(value = value, default = Stream.LabelSourceOrigin, format = format, label = label)
		if format == Stream.FormatDecorate:
			value = self._decorate(value = value, format = format, bold = True, uppercase = True, color = self.sourceOriginColor)

		if self.accessTypeOrion() and orion is None and not label == Stream.LabelNone:
			value2 = self.sourceOrigin(format = format, label = label, gaia = gaia, orion = False, default = None)
			if value2 and not value == value2: value = '%s (%s)' % (value, value2)

		return value

	'''
		FUNCTION:
			Sets the source origin.
		PARAMETERS:
			value (string): The source origin.
		RETURNS:
			The extracted and processed value that was set (string/None).
	'''
	def sourceOriginSet(self, value):
		self.mData['source']['origin'] = value
		return value

	'''
		FUNCTION:
			Checks if the origin is external.
		RETURNS:
			Whether the source origin is external (boolean).
	'''
	def sourceOriginExternal(self):
		return not self.mData['source']['origin'] or not self.mData['source']['origin'] == tools.System.name()

	'''
		FUNCTION:
			Retrieve the color for the origin.
		RETURNS:
			The origin color (string).
	'''
	@classmethod
	def sourceOriginColor(self):
		return interface.Format.colorTertiary()

	'''
		FUNCTION:
			Returns the icon name for the origin.
		PARAMETERS:
			orion (boolean): Whether or not to return the origin as Orion if the source came from Orion.
			extension (boolean): Whether or not to add the file extension.
		RETURNS:
			The origin icon name (string).
	'''
	def sourceOriginIcon(self, orion = True, extension = False):
		origin = self.sourceOrigin(orion = orion)
		icon = origin.lower() if origin else None
		if extension and icon: icon += '.png'
		return icon

	##############################################################################
	# SOURCE PROVIDER
	##############################################################################

	'''
		FUNCTION:
			Retrieves the source provider.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			origin (boolean): Whether or not to add the origin as a prefix.
			gaia (boolean): Whether or not to return the origin if it is Gaia. Only used if origin is True.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The source provider (string).
	'''
	def sourceProvider(self, format = FormatNone, label = LabelNone, origin = False, gaia = False, default = None):
		value = self.mData['source']['provider']
		if value is None: return default
		prefix = None
		if origin: prefix = self.sourceOrigin(label = label, gaia = gaia)
		label = self.settingsLayout(label, 'source', 'provider')
		value = self._label(value = value, default = Stream.LabelSourceProvider, format = format, label = label, prefix = prefix, process = '-')
		value = self._decorate(value = value, format = format, bold = True, uppercase = True)
		return value

	'''
		FUNCTION:
			Sets the source provider.
		PARAMETERS:
			value (string): The source provider.
		RETURNS:
			The extracted and processed value that was set (string/None).
	'''
	def sourceProviderSet(self, value):
		self.mData['source']['provider'] = value
		return value

	@classmethod
	def sourceProviderLabels(self):
		def _sourceProviderLabels():
			from lib.providers.core.manager import Manager
			providers = self._cache(Manager.providers, enabled = True)
			result = tools.Tools.copy(Stream.LabelSourceProvider)
			for pro in providers:
				result[pro['label']] = {Stream.LabelShort : pro['label'], Stream.LabelMedium : pro['label'], Stream.LabelLong : pro['label'] }
			return result
		return self._cache(_sourceProviderLabels)

	@classmethod
	def sourceProviderOrders(self):
		def _sourceProviderOrders():
			from lib.providers.core.manager import Manager
			providers = self._cache(Manager.providers, enabled = True)
			providers = sorted(providers, key = lambda i : i['label'])
			result = {}
			for i in range(len(providers)):
				result[providers[i]['label']] = { Stream.OrderInterface : i + 1, Stream.OrderSorting : i + 1 }
			return result
		return self._cache(_sourceProviderOrders)

	##############################################################################
	# SOURCE PUBLISHER
	##############################################################################

	'''
		FUNCTION:
			Retrieves the source publisher.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			same (boolean): Whether or not to return the publisher if it is the same as the provider.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The source publisher (string).
	'''
	def sourcePublisher(self, format = FormatNone, label = LabelNone, same = True, default = None):
		value = self.mData['source']['publisher']
		if value is None: return default
		label = self.settingsLayout(label, 'source', 'publisher')
		value = self._labelDomain(value = value, label = label)

		if not same:
			provider = self.sourceProvider()
			if provider:
				valueLower = value.lower()
				providerLower = provider.lower()
				if valueLower in providerLower or providerLower in valueLower: return default

				try:
					if Stream.SourcePublisherAlias[valueLower] in providerLower: return default
				except: pass
				try:
					if Stream.SourcePublisherAlias[providerLower] in valueLower: return default
				except: pass

		value = self._label(value = value, default = Stream.LabelSourcePublisher, format = format, label = label, process = True)
		value = self._decorate(value = value, format = format, bold = True, uppercase = True)
		return value

	'''
		FUNCTION:
			Sets the source publisher.
		PARAMETERS:
			value (string): The source publisher.
		RETURNS:
			The extracted and processed value that was set (string/None).
	'''
	def sourcePublisherSet(self, value):
		self.mData['source']['publisher'] = value
		return value

	##############################################################################
	# SOURCE HOSTER
	##############################################################################

	'''
		FUNCTION:
			Retrieves the source hoster.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			same (boolean): Whether or not to return the hoster if it is the same as the publisher or provider.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The source hoster (string).
	'''
	def sourceHoster(self, format = FormatNone, label = LabelNone, same = True, default = None):
		value = self.mData['source']['hoster']
		if value is None: return default
		label = self.settingsLayout(label, 'source', 'hoster')
		value = self._labelDomain(value = value, label = label)

		if not same:
			valueLower = value.lower()
			provider = self.sourceProvider()
			if provider:
				providerLower = provider.lower()
				if valueLower in providerLower or providerLower in valueLower: return default
			publisher = self.sourcePublisher()
			if publisher:
				publisherLower = publisher.lower()
				if valueLower in publisherLower or publisherLower in valueLower: return default

			try:
				if Stream.SourcePublisherAlias[valueLower] in providerLower: return default
			except: pass
			try:
				if Stream.SourcePublisherAlias[providerLower] in valueLower: return default
			except: pass
			try:
				if Stream.SourcePublisherAlias[valueLower] in publisherLower: return default
			except: pass
			try:
				if Stream.SourcePublisherAlias[publisherLower] in valueLower: return default
			except: pass

		value = self._label(value = value, default = Stream.LabelSourceHoster, format = format, label = label, process = True)
		value = self._decorate(value = value, format = format, bold = True, uppercase = True)
		return value

	'''
		FUNCTION:
			Sets the source hoster.
		PARAMETERS:
			value (string): The source hoster.
		RETURNS:
			The extracted and processed value that was set (string/None).
	'''
	def sourceHosterSet(self, value):
		self.mData['source']['hoster'] = value
		return value

	'''
		FUNCTION:
			Extracts the source hoster domain from a link.
		PARAMETERS:
			data (string): The link.
		RETURNS:
			The source hoster (string).
	'''
	@classmethod
	def sourceHosterExtract(self, data):
		if not data: return None
		if not tools.Tools.isArray(data): data = [data]
		for d in data:
			domain = network.Networker.linkDomain(link = d, subdomain = False, topdomain = True, ip = True)
			if domain: return domain
		return None

	##############################################################################
	# SOURCE RESOLVED
	##############################################################################

	'''
		FUNCTION:
			Retrieves the source resolved hoster.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			same (boolean): Whether or not to return the hoster if it is the same as the publisher, provider, or hoster.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The source hoster (string).
	'''
	def sourceResolved(self, format = FormatNone, label = LabelNone, same = True, default = None):
		value = self.mData['source']['resolved']
		if value is None: return default
		label = self.settingsLayout(label, 'source', 'hoster')
		value = self._labelDomain(value = value, label = label)

		if not same:
			valueLower = value.lower()
			provider = self.sourceProvider()
			if provider:
				providerLower = provider.lower()
				if valueLower in providerLower or providerLower in valueLower: return default
			publisher = self.sourcePublisher()
			if publisher:
				publisherLower = publisher.lower()
				if valueLower in publisherLower or publisherLower in valueLower: return default
			hoster = self.sourceHoster()
			if hoster:
				hosterLower = hoster.lower()
				if valueLower in hosterLower or hosterLower in valueLower: return default

			try:
				if Stream.SourcePublisherAlias[valueLower] in providerLower: return default
			except: pass
			try:
				if Stream.SourcePublisherAlias[providerLower] in valueLower: return default
			except: pass
			try:
				if Stream.SourcePublisherAlias[valueLower] in publisherLower: return default
			except: pass
			try:
				if Stream.SourcePublisherAlias[publisherLower] in valueLower: return default
			except: pass
			try:
				if Stream.SourcePublisherAlias[valueLower] in hosterLower: return default
			except: pass
			try:
				if Stream.SourcePublisherAlias[hosterLower] in valueLower: return default
			except: pass

		value = self._label(value = value, default = Stream.LabelSourceHoster, format = format, label = label, process = True)
		value = self._decorate(value = value, format = format, bold = True, uppercase = True)
		return value

	'''
		FUNCTION:
			Sets the source resolved hoster.
		PARAMETERS:
			value (string): The source resolved hoster.
		RETURNS:
			The extracted and processed value that was set (string/None).
	'''
	def sourceResolvedSet(self, value):
		self.mData['source']['resolved'] = value
		return value

	'''
		FUNCTION:
			Extracts the source resolved hoster domain from a link.
		PARAMETERS:
			data (string): The link.
		RETURNS:
			The source resolved hoster (string).
	'''
	@classmethod
	def sourceResolvedExtract(self, data):
		if not data: return None
		if not tools.Tools.isArray(data): data = [data]
		for d in data:
			domain = network.Networker.linkDomain(link = d, subdomain = False, topdomain = True, ip = True)
			if domain: return domain
		return None

	##############################################################################
	# ACCESS TYPE
	##############################################################################

	'''
		FUNCTION:
			Retrieves the access type.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			derive (boolean): Wether or not to derive the access type from other metadata attributes.
			exclusive (boolean): Wether or not to return a single type or all types applicable.
			account (boolean): Wether or not to only include debrid services for which the user has an account.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The access type (string).
	'''
	def accessType(self, format = FormatNone, label = LabelNone, derive = True, exclusive = True, account = False, default = None):
		original = label
		label = self.settingsLayout(label, 'access', 'type')

		if label == Stream.LabelNone:
			value = self.mData['access']['type']
			if derive:
				value = tools.Tools.copy(value)
				if value[Stream.AccessTypeOffline] is None and self.accessTypeOffline(): value[Stream.AccessTypeOffline] = True
				if value[Stream.AccessTypeDirect] is None and self.accessTypeDirect(derive = derive): value[Stream.AccessTypeDirect] = True
				if value[Stream.AccessTypeCache] is None and self.accessTypeCache(derive = derive, account = account): value[Stream.AccessTypeCache] = True
				if value[Stream.AccessTypeDebrid] is None and self.accessTypeDebrid(derive = derive, account = account): value[Stream.AccessTypeDebrid] = True
				if value[Stream.AccessTypeOpen] is None and self.accessTypeOpen(derive = derive, account = account): value[Stream.AccessTypeOpen] = True
			return value
		else:
			value = None
			color = None
			result = []
			if self.accessTypeDirect(derive = derive):
				value = self._label(value = Stream.AccessTypeDirect, values = Stream.LabelAccessType, format = format, label = label)
				value = self._decorate(value = value, format = format, bold = True, uppercase = True, color = self.accessTypeDirectColor, colortype = self.sourceType())
				result.append(value)
				if exclusive: return result[0]
			if self.accessTypeCache(derive = derive, account = account):
				result.append(self.accessCache(format = format, label = original, account = account))
				if exclusive: return result[0]
			if self.accessTypeDebrid(derive = derive, account = account):
				result.append(self.accessDebrid(format = format, label = original, account = account))
				if exclusive: return result[0]
			if self.accessTypeMember():
				value = self._label(value = Stream.AccessTypeMember, values = Stream.LabelAccessType, format = format, label = label)
				value = self._decorate(value = value, format = format, bold = True, uppercase = True, color = self.accessTypeMemberColor)
				result.append(value)
				if exclusive: return result[0]
			if self.accessTypeOpen(derive = derive, account = account):
				value = self._label(value = Stream.AccessTypeOpen, values = Stream.LabelAccessType, format = format, label = label)
				value = self._decorate(value = value, format = format, bold = True, uppercase = True, color = self.accessTypeOpenColor)
				result.append(value)
				if exclusive: return result[0]
			if self.accessTypeOffline():
				value = self._label(value = Stream.AccessTypeOffline, values = Stream.LabelAccessType, format = format, label = label)
				value = self._decorate(value = value, format = format, bold = True, uppercase = True, color = self.accessTypeOfflineColor)
				result.append(value)
				if exclusive: return result[0]
			result = [i for i in result if i]
			return result

	'''
		FUNCTION:
			Sets the access type.
		PARAMETERS:
			value (boolean/dictionary): The access type of all types. If the type is set, it is the access type status (boolean) instead.
			type (None/string): The debrid access type. If not set, the value is assumed to be a dicitionary containing multiple access types.
	'''
	def accessTypeSet(self, value = True, type = None):
		if tools.Tools.isDictionary(value): self.mData['access']['type'].update(value)
		elif type: self.mData['access']['type'][type] = value

	'''
		FUNCTION:
			Checks if the access type has already been set.
		PARAMETERS:
			type (string): The access type.
		RETURNS:
			If the access type has been set (boolean).
	'''
	def accessTypeHas(self, type):
		return not self.mData['access']['type'][type] is None

	'''
		FUNCTION:
			Checks if the access type has debrid.
		PARAMETERS:
			derive (boolean): Wether or not to derive the access type from other metadata attributes.
			account (boolean): Wether or not to only include debrid services for which the user has an account.
		RETURNS:
			If it is a debrid access type (boolean).
	'''
	def accessTypeDebrid(self, derive = True, account = False):
		return self.mData['access']['type'][Stream.AccessTypeDebrid] or (derive and self.accessDebridAny(account = account))

	'''
		FUNCTION:
			Sets the access debrid type.
		PARAMETERS:
			value (boolean/dictionary): The access debrid type.
	'''
	def accessTypeDebridSet(self, value = True):
		self.accessTypeSet(type = Stream.AccessTypeDebrid, value = value)

	'''
		FUNCTION:
			Checks if the access type is cached.
		PARAMETERS:
			derive (boolean): Wether or not to derive the access type from other metadata attributes.
			account (boolean): Wether or not to only include debrid services for which the user has an account.
		RETURNS:
			If it is a cached access type (boolean).
	'''
	def accessTypeCache(self, derive = True, account = False):
		return self.mData['access']['type'][Stream.AccessTypeCache] or (derive and self.accessCacheAny(account = account))

	'''
		FUNCTION:
			Sets the access cache type.
		PARAMETERS:
			value (boolean/dictionary): The access cache type.
	'''
	def accessTypeCacheSet(self, value = True):
		self.accessTypeSet(type = Stream.AccessTypeCache, value = value)

	'''
		FUNCTION:
			Checks if the access type is direct.
		PARAMETERS:
			derive (boolean): Wether or not to derive the access type from other metadata attributes.
		RETURNS:
			If it is a direct access type (boolean).
	'''
	def accessTypeDirect(self, derive = True):
		return self.mData['access']['type'][Stream.AccessTypeDirect] or (derive and (self.sourceTypeLocal() or self.sourceTypePremium()))

	'''
		FUNCTION:
			Sets the access direct type.
		PARAMETERS:
			value (boolean/dictionary): The access direct type.
	'''
	def accessTypeDirectSet(self, value = True):
		self.accessTypeSet(type = Stream.AccessTypeDirect, value = value)

	'''
		FUNCTION:
			Checks if the access type is member.
		RETURNS:
			If it is an member access type (boolean).
	'''
	def accessTypeMember(self):
		return self.mData['access']['type'][Stream.AccessTypeMember]

	'''
		FUNCTION:
			Sets the access member type.
		PARAMETERS:
			value (boolean/dictionary): The access member type.
	'''
	def accessTypeMemberSet(self, value = True):
		self.accessTypeSet(type = Stream.AccessTypeMember, value = value)

	'''
		FUNCTION:
			Checks if the access type is open.
		PARAMETERS:
			derive (boolean): Wether or not to derive the access type from other metadata attributes.
			account (boolean): Wether or not to only include debrid services for which the user has an account.
		RETURNS:
			If it is an open access type (boolean).
	'''
	def accessTypeOpen(self, derive = True, account = False):
		return self.mData['access']['type'][Stream.AccessTypeOpen] or (derive and not self.accessTypeMember() and not self.accessTypeDirect(derive = derive) and not self.accessTypeDebrid(derive = derive, account = account) and not self.accessTypeCache(derive = derive, account = account))

	'''
		FUNCTION:
			Sets the access open type.
		PARAMETERS:
			value (boolean/dictionary): The access open type.
	'''
	def accessTypeOpenSet(self, value = True):
		self.accessTypeSet(type = Stream.AccessTypeOpen, value = value)

	'''
		FUNCTION:
			Checks if the access type is offline (stream comes from an offline provider).
		RETURNS:
			If it is an offline access type (boolean).
	'''
	def accessTypeOffline(self):
		return self.mData['access']['type'][Stream.AccessTypeOffline]

	'''
		FUNCTION:
			Sets the access offline type.
		PARAMETERS:
			value (boolean/dictionary): The access offlines type.
	'''
	def accessTypeOfflineSet(self, value = True):
		self.accessTypeSet(type = Stream.AccessTypeOffline, value = value)

	'''
		FUNCTION:
			Checks if the access type is from Orion.
		RETURNS:
			If it is an Orion access type (boolean).
	'''
	def accessTypeOrion(self):
		return self.mData['access']['type'][Stream.AccessTypeOrion]

	'''
		FUNCTION:
			Sets the access Orion type.
		PARAMETERS:
			value (boolean/dictionary): The access Orion type.
	'''
	def accessTypeOrionSet(self, value = True):
		self.accessTypeSet(type = Stream.AccessTypeOrion, value = value)

	'''
		FUNCTION:
			Retrieve the color for direct access.
		PARAMETERS:
			type (string): The access type.
		RETURNS:
			The direct color (string).
	'''
	@classmethod
	def accessTypeDirectColor(self, type = None):
		def _accessTypeDirectColor(type):
			color = interface.Format.colorSpecial()
			if type == Stream.SourceTypeLocal: color = interface.Format.colorDarker(color = color, change = 0.1)
			elif type == Stream.SourceTypePremium: color = interface.Format.colorDarker(color = color, change = 0.05)
			else: color = interface.Format.colorLighter(color = color, change = 0.05)
			return color
		return self._cacheId('accessTypeDirectColor', _accessTypeDirectColor, type)

	'''
		FUNCTION:
			Retrieve the color for member access.
		RETURNS:
			The member color (string).
	'''
	@classmethod
	def accessTypeMemberColor(self):
		def _accessTypeMemberColor():
			return interface.Format.colorLighter(color = interface.Format.colorSpecial(), change = 0.1)
		return self._cacheId('accessTypeMemberColor', _accessTypeMemberColor)

	'''
		FUNCTION:
			Retrieve the color for open access.
		RETURNS:
			The open color (string).
	'''
	@classmethod
	def accessTypeOpenColor(self):
		def _accessTypeOpenColor():
			return interface.Format.colorLighter(color = interface.Format.colorSpecial(), change = 0.2)
		return self._cacheId('accessTypeOpenColor', _accessTypeOpenColor)


	'''
		FUNCTION:
			Retrieve the color for offline access.
		RETURNS:
			The offline color (string).
	'''
	@classmethod
	def accessTypeOfflineColor(self):
		def _accessTypeOfflineColor():
			return interface.Format.colorLighter(color = interface.Format.colorSpecial(), change = 0.6)
		return self._cacheId('accessTypeOfflineColor', _accessTypeOfflineColor)

	##############################################################################
	# ACCESS DEBRID
	##############################################################################

	'''
		FUNCTION:
			Retrieves the access debrid service.
		PARAMETERS:
			id (None/string/boolean): The debrid service ID. If None, returns all services.
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			account (boolean): Wether or not to only include debrid services for which the user has an account.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The access debrid service (list).
	'''
	def accessDebrid(self, id = None, format = FormatNone, label = LabelNone, account = False, default = None):
		value = self.mData['access']['debrid']
		if id:
			try: value = value[id]
			except: return default

		if account and value:
			self._accessDebridInitialize()
			if id: value = id in Stream.AccessDebridHandles
			else: value = {k : v for k, v in value.items() if k in Stream.AccessDebridHandles}

		original = label
		label = self.settingsLayout(label, 'access', 'debrid')
		if not label == Stream.LabelNone:
			self._accessDebridInitialize()
			value = [k for k, v in value.items() if v]
			if not value: return default
			value = self._accessDebridSort(value)
			if label == Stream.LabelDetails:
				value = self._label(value = value, values = self.LabelAccessDebrid, format = format, label = label)
			else:
				prefix = self._label(value = Stream.AccessTypeDebrid, values = Stream.LabelAccessType, format = format, label = self.settingsLayout(original, 'access', 'type'))
				value = self._label(value = value, values = self.LabelAccessDebrid, format = format, label = Stream.LabelShort if prefix else label, prefix = prefix, single = Stream.AccessDebridSingle)
			value = self._decorate(value = value, format = format, bold = True, uppercase = True, color = self.accessDebridColor)

		return value

	'''
		FUNCTION:
			Sets the access debrid service.
		PARAMETERS:
			value (boolean/dictionary): The access debrid of all services. If the ID is set, it is the access status (boolean) instead.
			id (None/string): The debrid service ID. If not set, the value is assumed to be a dicitionary containing multiple services.
	'''
	def accessDebridSet(self, value = True, id = None):
		if tools.Tools.isDictionary(value): self.mData['access']['debrid'].update(value)
		elif id: self.mData['access']['debrid'][id] = value

	'''
		FUNCTION:
			Checks if the debrid service has already been set.
		PARAMETERS:
			id (string): The debrid service ID.
		RETURNS:
			If the debrid service has been set (boolean).
	'''
	def accessDebridHas(self, id):
		return not self.mData['access']['debrid'][id] is None

	'''
		FUNCTION:
			Checks if any of the debrid services are supported.
		PARAMETERS:
			account (boolean): Wether or not to only include debrid services for which the user has an account.
		RETURNS:
			If the stream is debrid (boolean).
	'''
	def accessDebridAny(self, account = False):
		if account:
			self._accessDebridInitialize()
			result = [v for k, v in self.mData['access']['debrid'].items() if k in Stream.AccessDebridHandles]
		else:
			result = list(self.mData['access']['debrid'].values())
		return any(result)

	'''
		FUNCTION:
			Counts how many debrid services there are.
		PARAMETERS:
			account (boolean): Wether or not to only include debrid services for which the user has an account.
		RETURNS:
			The number of debrid services (integer).
	'''
	def accessDebridCount(self, account = False):
		if account:
			self._accessDebridInitialize()
			result = [1 for k, v in self.mData['access']['debrid'].items() if v and k in Stream.AccessDebridHandles]
		else:
			result = [1 for i in self.mData['access']['debrid'].values() if i]
		return sum(result)

	'''
		FUNCTION:
			Checks if the access is available through Premiumize.
		RETURNS:
			If it is debrid access (boolean).
	'''
	def accessDebridPremiumize(self):
		return self.mData['access']['debrid'][Stream.AccessDebridPremiumize]

	'''
		FUNCTION:
			Checks if the access is available through OffCloud.
		RETURNS:
			If it is debrid access (boolean).
	'''
	def accessDebridOffcloud(self):
		return self.mData['access']['debrid'][Stream.AccessDebridOffcloud]

	'''
		FUNCTION:
			Checks if the access is available through TorBox.
		RETURNS:
			If it is debrid access (boolean).
	'''
	def accessDebridTorbox(self):
		return self.mData['access']['debrid'][Stream.AccessDebridTorbox]

	'''
		FUNCTION:
			Checks if the access is available through EasyDebrid.
		RETURNS:
			If it is debrid access (boolean).
	'''
	def accessDebridEasydebrid(self):
		return self.mData['access']['debrid'][Stream.AccessDebridEasydebrid]

	'''
		FUNCTION:
			Checks if the access is available through RealDebrid.
		RETURNS:
			If it is debrid access (boolean).
	'''
	def accessDebridRealdebrid(self):
		return self.mData['access']['debrid'][Stream.AccessDebridRealdebrid]

	'''
		FUNCTION:
			Checks if the access is available through DebridLink.
		RETURNS:
			If it is debrid access (boolean).
	'''
	def accessDebridDebridLink(self):
		return self.mData['access']['debrid'][Stream.AccessDebridDebridlink]

	'''
		FUNCTION:
			Checks if the access is available through AllDebrid.
		RETURNS:
			If it is debrid access (boolean).
	'''
	def accessDebridAlldebrid(self):
		return self.mData['access']['debrid'][Stream.AccessDebridAlldebrid]

	'''
		FUNCTION:
			Checks if the access is available through LinkSnappy.
		RETURNS:
			If it is debrid access (boolean).
	'''
	def accessDebridLinksnappy(self):
		return self.mData['access']['debrid'][Stream.AccessDebridLinksnappy]

	'''
		FUNCTION:
			Checks if the access is available through MegaDebrid.
		RETURNS:
			If it is debrid access (boolean).
	'''
	def accessDebridMegadebrid(self):
		return self.mData['access']['debrid'][Stream.AccessDebridMegadebrid]

	'''
		FUNCTION:
			Checks if the access is available through RapidPremium.
		RETURNS:
			If it is debrid access (boolean).
	'''
	def accessDebridRapidpremium(self):
		return self.mData['access']['debrid'][Stream.AccessDebridRapidpremium]

	'''
		FUNCTION:
			Checks if the access is available through SimplyDebrid.
		RETURNS:
			If it is debrid access (boolean).
	'''
	def accessDebridSimplydebrid(self):
		return self.mData['access']['debrid'][Stream.AccessDebridSimplydebrid]

	'''
		FUNCTION:
			Checks if the access is available through Smoozed.
		RETURNS:
			If it is debrid access (boolean).
	'''
	def accessDebridSmoozed(self):
		return self.mData['access']['debrid'][Stream.AccessDebridSmoozed]

	'''
		FUNCTION:
			Retrieve the color for debrid access.
		RETURNS:
			The debrid color (string).
	'''
	@classmethod
	def accessDebridColor(self):
		def _accessDebridColor():
			return interface.Format.colorLighter(color = interface.Format.colorSpecial(), change = 0.15)
		return self._cacheId('accessDebridColor', _accessDebridColor)

	@classmethod
	def _accessDebridInitialize(self):
		if Stream.AccessDebridHandles is None:
			Stream.LockOther.acquire()
			if Stream.AccessDebridHandles is None:
				from lib.debrid import Debrid
				from lib.modules.handler import Handler

				handles = []
				instances = Handler.debrids()
				for instance in instances:
					meta = Debrid.meta(id = instance.serviceId())
					if meta and not meta['id'] in handles:
						handles.append(meta['id'])
						Stream.LabelAccessDebrid[meta['id']] = { Stream.LabelShort : meta['abbreviation'], Stream.LabelMedium : meta['acronym'], Stream.LabelLong : meta['name'] }

				Stream.AccessDebridHandles = handles
				Stream.AccessDebridSingle = len(handles) <= 1

			Stream.LockOther.release()

	@classmethod
	def _accessDebridSort(self, values):
		return sorted(values, key = lambda i : Stream.OrderAccessDebrid[i][Stream.OrderSorting])

	##############################################################################
	# ACCESS CACHE
	##############################################################################

	'''
		FUNCTION:
			Retrieves the access cache status for debrid services.
			If the status is True, the status was looked up and it is cached.
			If the status is False, the status was looked up and it is not cached.
			If the status is None, the status was not yet looked up.
		PARAMETERS:
			id (None/string/boolean): The debrid service ID. If None, returns all services.
			time (None/integer): The duration in seconds from now, or the timestamp, after which the cache status is considered to be outdated and nothing will be returned.
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			exact (enumeration): Wether or not to return the latests or outdated cache status.
			account (boolean): Wether or not to only include debrid services for which the user has an account.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The access cache statuses (dictionary/string).
	'''
	def accessCache(self, id = None, time = None, format = FormatNone, label = LabelNone, exact = ExactAuto, account = False, default = None):
		if time and time < 1000000000: time = tools.Time.timestamp() - time
		if id:
			try:
				if time:
					checked = self.exact(exact = Stream.ExactTime, data = self.mData['access']['cache'][id])
					if checked and checked < time: return default
				value = self.exact(exact = exact, data = self.mData['access']['cache'][id])
			except: return default
		else:
			temp = {}
			for key in self.mData['access']['cache'].keys():
				if time:
					checked = self.exact(exact = Stream.ExactTime, data = self.mData['access']['cache'][key])
					if checked and checked < time:
						temp[key] = None
						continue
				temp[key] = self.exact(exact = exact, data = self.mData['access']['cache'][key])
			value = temp

		if account and value:
			self._accessDebridInitialize()
			if id: value = id in Stream.AccessDebridHandles
			else: value = {k : v for k, v in value.items() if k in Stream.AccessDebridHandles}

		original = label
		label = self.settingsLayout(label, 'access', 'cache')

		if not label == Stream.LabelNone:
			self._accessDebridInitialize()
			value = [k for k, v in value.items() if v]

			if not value: return default
			value = self._accessDebridSort(value)
			if label == Stream.LabelDetails:
				value = self._label(value = value, values = self.LabelAccessDebrid, default = self.LabelAccessCache, format = format, label = label)
			else:
				# As of Novemeber 2024, RealDebrid, DebridLink, and AllDebrid do not support cache lookups anymore.
				# The cache still works, but the lookup API endpoint has been removed.
				# Still use the inexact/outdated cache status coming from Orion, but decorate it with a lighter color.
				color = None
				if format == Stream.FormatDecorate or format == Stream.FormatColor:
					color = self.accessDebridColor()
					color = {
						Stream.AccessDebridRealdebrid : color,
						Stream.AccessDebridDebridlink : color,
						Stream.AccessDebridAlldebrid : color,
					}

				prefix = self._label(value = Stream.AccessTypeCache, values = Stream.LabelAccessType, format = format, label = self.settingsLayout(original, 'access', 'type'))
				value = self._label(value = value, values = self.LabelAccessDebrid, default = self.LabelAccessCache, format = format, label = Stream.LabelShort if prefix else label, prefix = prefix, single = Stream.AccessDebridSingle, color = color)

			value = self._decorate(value = value, format = format, bold = True, uppercase = True, color = self.accessCacheColor)
		return value

	'''
		FUNCTION:
			Sets the access cache status.
		PARAMETERS:
			value (boolean/dictionary): The cached statuses of all services. If the ID is set, it is the cached status (boolean) instead.
			id (None/string): The debrid service ID. If not set, the value is assumed to be a dicitionary containing multiple services.
			time (None/True/integer): The time the debrid cache status was last checked. if True, use the current timestamp.
			exact (enumeration): Wether or not the stauts is the latests or outdated.
			force (boolean): Force the update of the value. If True, the value is updated irrespective of it being True or False. If False, the value is only updated if it is True.
	'''
	def accessCacheSet(self, value = True, id = None, time = None, exact = ExactYes, force = True):
		if time is True: time = tools.Time.timestamp()
		if tools.Tools.isArray(id):
			if force or value:
				for i in id:
					self.accessCacheSet(value = value, id = i, time = time, exact = exact)
		elif tools.Tools.isDictionary(value):
			if force:
				for k, v in value.items():
					self.exactSet(exact = exact, data = self.mData['access']['cache'][k], value = v)
					if time: self.exactSet(exact = Stream.ExactTime, data = self.mData['access']['cache'][k], value = time)
			else:
				for k, v in value.items():
					if v:
						self.exactSet(exact = exact, data = self.mData['access']['cache'][k], value = v)
						if time: self.exactSet(exact = Stream.ExactTime, data = self.mData['access']['cache'][k], value = time)
		elif id:
			if force or value:
				self.exactSet(exact = exact, data = self.mData['access']['cache'][id], value = value)
				if time: self.exactSet(exact = Stream.ExactTime, data = self.mData['access']['cache'][id], value = time)

	'''
		FUNCTION:
			Checks if the cache status has already been looked up for a debrid service.
		PARAMETERS:
			id (string/list): The debrid service ID.
			time (None/integer): The duration in seconds from now, or the timestamp, after which the cache status is considered to be outdated.
			exact (enumeration): Wether or not the stauts is the latests or outdated.
		RETURNS:
			If cache status has been looked up (boolean).
	'''
	def accessCacheHas(self, id, time = None, exact = ExactAuto):
		if time and time < 1000000000: time = tools.Time.timestamp() - time

		if tools.Tools.isArray(id):
			for i in id:
				if time:
					checked = self.exact(exact = Stream.ExactTime, data = self.mData['access']['cache'][i])
					if checked and checked < time: return False
				if self.exact(exact = exact, data = self.mData['access']['cache'][i]) is None:
					return False
			return True
		else:
			if time:
				checked = self.exact(exact = Stream.ExactTime, data = self.mData['access']['cache'][id])
				if checked and checked < time: return False
			return not self.exact(exact = exact, data = self.mData['access']['cache'][id]) is None

	'''
		FUNCTION:
			Checks if the cache status has expired, that is, looked up too long ago.
		PARAMETERS:
			id (string/list): The debrid service ID.
			time (integer): The duration in seconds from now, or the timestamp, after which the cache status is considered to be outdated.
			none (boolean): Consider time values of None to be expired, that is, not time was previously set.
		RETURNS:
			If cache status has expired.
	'''
	def accessCacheExpired(self, id, time, none = True):
		if time < 1000000000: time = tools.Time.timestamp() - time
		checked = self.exact(exact = Stream.ExactTime, data = self.mData['access']['cache'][id])
		if (none and checked is None) or (checked and checked < time): return True
		return False

	'''
		FUNCTION:
			Checks if any of the debrid services are cached.
		PARAMETERS:
			account (boolean): Wether or not to only include debrid services for which the user has an account.
			exact (enumeration): Wether or not the stauts is the latests or outdated.
		RETURNS:
			If the stream is cached (boolean).
	'''
	def accessCacheAny(self, account = False, exact = ExactAuto):
		if account:
			self._accessDebridInitialize()
			for key, value in self.mData['access']['cache'].items():
				if key in Stream.AccessDebridHandles and self.exact(exact = exact, data = value): return True
		else:
			for value in self.mData['access']['cache'].values():
				if self.exact(exact = exact, data = value): return True
		return False

	'''
		FUNCTION:
			Counts how many of the debrid services are cached.
		PARAMETERS:
			account (boolean): Wether or not to only include debrid services for which the user has an account.
			exact (enumeration): Wether or not the stauts is the latests or outdated.
		RETURNS:
			The number of cached services (integer).
	'''
	def accessCacheCount(self, account = False, exact = ExactAuto):
		count = 0
		if account:
			self._accessDebridInitialize()
			for key, value in self.mData['access']['cache'].items():
				if key in Stream.AccessDebridHandles and self.exact(exact = exact, data = value): count += 1
		else:
			for value in self.mData['access']['cache'].values():
				if self.exact(exact = exact, data = value): count += 1
		return count

	'''
		FUNCTION:
			Checks if the access is cached on Premiumize.
		PARAMETERS:
			exact (enumeration): Wether or not the stauts is the latests or outdated.
		RETURNS:
			If it is cached access (boolean).
	'''
	def accessCachePremiumize(self, exact = ExactAuto):
		return self.exact(exact = exact, data = self.mData['access']['cache'][Stream.AccessDebridPremiumize])

	'''
		FUNCTION:
			Checks if the access is cached on OffCloud.
		PARAMETERS:
			exact (enumeration): Wether or not the stauts is the latests or outdated.
		RETURNS:
			If it is cached access (boolean/None).
	'''
	def accessCacheOffcloud(self, exact = ExactAuto):
		return self.exact(exact = exact, data = self.mData['access']['cache'][Stream.AccessDebridOffcloud])

	'''
		FUNCTION:
			Checks if the access is cached on TorBox.
		PARAMETERS:
			exact (enumeration): Wether or not the stauts is the latests or outdated.
		RETURNS:
			If it is cached access (boolean/None).
	'''
	def accessCacheTorbox(self, exact = ExactAuto):
		return self.exact(exact = exact, data = self.mData['access']['cache'][Stream.AccessDebridTorbox])

	'''
		FUNCTION:
			Checks if the access is cached on EasyDebrid.
		PARAMETERS:
			exact (enumeration): Wether or not the stauts is the latests or outdated.
		RETURNS:
			If it is cached access (boolean/None).
	'''
	def accessCacheEasydebrid(self, exact = ExactAuto):
		return self.exact(exact = exact, data = self.mData['access']['cache'][Stream.AccessDebridEasydebrid])

	'''
		FUNCTION:
			Checks if the access is cached on RealDebrid.
		PARAMETERS:
			exact (enumeration): Wether or not the stauts is the latests or outdated.
		RETURNS:
			If it is cached access (boolean/None).
	'''
	def accessCacheRealdebrid(self, exact = ExactAuto):
		return self.exact(exact = exact, data = self.mData['access']['cache'][Stream.AccessDebridRealdebrid])

	'''
		FUNCTION:
			Checks if the access is cached on DebridLink.
		PARAMETERS:
			exact (enumeration): Wether or not the stauts is the latests or outdated.
		RETURNS:
			If it is cached access (boolean/None).
	'''
	def accessCacheDebridlink(self, exact = ExactAuto):
		return self.exact(exact = exact, data = self.mData['access']['cache'][Stream.AccessDebridDebridlink])

	'''
		FUNCTION:
			Checks if the access is cached on AllDebrid.
		PARAMETERS:
			exact (enumeration): Wether or not the stauts is the latests or outdated.
		RETURNS:
			If it is cached access (boolean/None).
	'''
	def accessCacheAlldebrid(self, exact = ExactAuto):
		return self.exact(exact = exact, data = self.mData['access']['cache'][Stream.AccessDebridAlldebrid])

	'''
		FUNCTION:
			Checks if the access is cached on LinkSnappy.
		PARAMETERS:
			exact (enumeration): Wether or not the stauts is the latests or outdated.
		RETURNS:
			If it is cached access (boolean/None).
	'''
	def accessCacheLinksnappy(self, exact = ExactAuto):
		return self.exact(exact = exact, data = self.mData['access']['cache'][Stream.AccessDebridLinksnappy])

	'''
		FUNCTION:
			Checks if the access is cached on MegaDebrid.
		PARAMETERS:
			exact (enumeration): Wether or not the stauts is the latests or outdated.
		RETURNS:
			If it is cached access (boolean/None).
	'''
	def accessCacheMegadebrid(self, exact = ExactAuto):
		return self.exact(exact = exact, data = self.mData['access']['cache'][Stream.AccessDebridMegadebrid])

	'''
		FUNCTION:
			Checks if the access is cached on RapidPremium.
		PARAMETERS:
			exact (enumeration): Wether or not the stauts is the latests or outdated.
		RETURNS:
			If it is cached access (boolean/None).
	'''
	def accessCacheRapidpremium(self, exact = ExactAuto):
		return self.exact(exact = exact, data = self.mData['access']['cache'][Stream.AccessDebridRapidpremium])

	'''
		FUNCTION:
			Checks if the access is cached on SimplyDebrid.
		PARAMETERS:
			exact (enumeration): Wether or not the stauts is the latests or outdated.
		RETURNS:
			If it is cached access (boolean/None).
	'''
	def accessCacheSimplydebrid(self, exact = ExactAuto):
		return self.exact(exact = exact, data = self.mData['access']['cache'][Stream.AccessDebridSimplydebrid])

	'''
		FUNCTION:
			Checks if the access is cached on Smoozed.
		PARAMETERS:
			exact (enumeration): Wether or not the stauts is the latests or outdated.
		RETURNS:
			If it is cached access (boolean/None).
	'''
	def accessCacheSmoozed(self, exact = ExactAuto):
		return self.exact(exact = exact, data = self.mData['access']['cache'][Stream.AccessDebridSmoozed])

	'''
		FUNCTION:
			Retrieve the color for cached streams.
		RETURNS:
			The cached color (string).
	'''
	@classmethod
	def accessCacheColor(self):
		return self._cacheId('accessCacheColor', interface.Format.colorSpecial)

	##############################################################################
	# ACCESS USAGE
	##############################################################################

	'''
		FUNCTION:
			Retrieves the access debrid usage.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set
		RETURNS:
			The access debrid usage (list).
	'''
	def accessUsage(self, format = FormatNone, label = LabelNone, default = None):
		try:
			if Stream.SettingsUsage is None:
				Stream.SettingsUsage = {
					'premiumize' : {
						'enabled' : tools.Settings.getBoolean('label.stream.premiumize'),
						'cost' : tools.Settings.getInteger('label.stream.premiumize.cost'),
						'usage' : tools.Settings.getInteger('label.stream.premiumize.usage'),
					},
					'easynews' : {
						'enabled' : tools.Settings.getBoolean('label.stream.easynews'),
						'usage' : tools.Settings.getInteger('label.stream.easynews.usage'),
					},
				}

			result = []
			label = self.settingsLayout(label, 'access', 'usage')

			if Stream.SettingsUsage['premiumize']['enabled']:
				from lib import debrid
				core = debrid.premiumize.Core()
				if core.accountValid():

					def _premiumizeUsage():
						return core.account()['usage']
					def _premiumizeService(mode):
						try: return core.service(mode)
						except: return None
					def _premiumizeSupport(mode):
						return debrid.premiumize.Handle().supported(mode)

					source = None
					if self.accessCachePremiumize():
						source = debrid.premiumize.Core.ServiceCloud
					elif self.sourceType() == Stream.SourceTypePremium:
						try:
							if self.sourceProvider().lower() == debrid.premiumize.Core.Id:
								source = debrid.premiumize.Core.ServiceCloud
						except: pass
					else:
						modes = self.sourceMode(all = True)
						for mode in modes:
							if self._cache(_premiumizeSupport, mode):
								source = mode
								break

					if source:

						# Cost
						if Stream.SettingsUsage['premiumize']['cost'] > 0:
							value = self._cache(_premiumizeService, source)
							if value:
								value = self._decorate(value = value['usage']['factor']['description'], format = format, color = self.accessUsageColor, colorvalue = value['usage']['factor']['value'], colorminimum = 1, colormaximum = 5, colorinverse = True)
								result.append(value + ' ' + self._label(value = Stream.AccessUsageCost, values = Stream.LabelAccessUsage, format = format, label = label))

						# Usage
						usage = Stream.SettingsUsage['premiumize']['usage']
						if usage > 0:
							values = self._cache(_premiumizeUsage)
							value = None
							color = None
							inverse = None

							if usage == 1: value = values['remaining']['description']
							elif usage == 2: value = values['remaining']['points']
							elif usage == 3: value = values['remaining']['size']['description']
							elif usage == 4: value = values['consumed']['description']
							elif usage == 5: value = values['consumed']['points']
							elif usage == 6: value = values['consumed']['size']['description']

							if usage == 3 or usage == 6:
								color = ((core.UsageBytes - values['consumed']['size']['bytes']) / float(core.UsageBytes)) * 100.0
								inverse = False
							else:
								color = values['consumed']['percentage']
								inverse = True

							if value:
								value = self._decorate(value = str(value), format = format, color = self.accessUsageColor, colorvalue = color, colorminimum = 0, colormaximum = 100, colorinverse = inverse)
								result.append(value + ' ' + self._label(value = Stream.AccessUsageRemaining if usage <= 3 else Stream.AccessUsageConsumed, values = Stream.LabelAccessUsage, format = format, label = label))

			if Stream.SettingsUsage['easynews']['enabled'] and self.sourceType() == Stream.SourceTypePremium:
				from lib import debrid
				if self.sourceProvider() == debrid.easynews.Core.Name:
					core = debrid.easynews.Core()
					if core.accountValid():

						def _easynewsUsage():
							return core.account()['usage']

						# Usage
						usage = Stream.SettingsUsage['easynews']['usage']
						if usage > 0:
							values = self._cache(_easynewsUsage)
							value = None
							color = None
							inverse = None

							if usage == 1: value = values['remaining']['description']
							elif usage == 2: value = values['remaining']['size']['description']
							elif usage == 3: value = values['consumed']['description']
							elif usage == 4: value = values['consumed']['size']['description']

							if usage == 2 or usage == 4:
								try: color = ((values['total']['size']['bytes'] - values['consumed']['size']['bytes']) / float(values['total']['size']['bytes'])) * 100.0
								except: color = 100 # Unlimited
								inverse = False
							else:
								color = values['consumed']['percentage']
								inverse = True

							if value:
								value = self._decorate(value = str(value), format = format, color = self.accessUsageColor, colorvalue = color, colorminimum = 0, colormaximum = 100, colorinverse = inverse)
								result.append(value + ' ' + self._label(value = Stream.AccessUsageRemaining if usage <= 2 else Stream.AccessUsageConsumed, values = Stream.LabelAccessUsage, format = format, label = label))
			return result
		except:
			tools.Logger.error()

	'''
		FUNCTION:
			Retrieve the gradient color for the access usage.
		PARAMETERS:
			value (integer): The access usage.
		RETURNS:
			The access usage color (string).
	'''
	@classmethod
	def accessUsageColor(self, value, minimum = 0, maximum = 1, inverse = False):
		count = maximum - minimum
		colors = self._cacheId('accessUsageColor', interface.Format.colorGradientIncrease, count)
		value = int(round(value))
		if inverse: value = maximum - value
		return colors[-1 if value >= len(colors) else int(value)]

	##############################################################################
	# SEGMENT
	##############################################################################

	'''
		FUNCTION:
			Retrieves the NZB segment IDs.
		PARAMETERS:
			best (boolean): Try to retrieve the best segment ID. Tries to get the first segment ID, then the largest segment ID, or otherwise the first ID from the list.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The NZB segment IDs (dictionary).
	'''
	def segment(self, best = False, default = None):
		if best:
			value = self.segmentFirst()
			if not value: value = self.segmentLargest()
			if not value: value = self.segmentList(index = 0)
		else:
			try: value = self.mData['segment']
			except: value = None
		if not value: return default
		return value

	'''
		FUNCTION:
			Retrieves the first NZB segment ID.
		PARAMETERS:
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The first NZB segment ID (None/string).
	'''
	def segmentFirst(self, default = None):
		try: value = self.mData['segment']['first']
		except: value = None
		if not value: return default
		return value

	'''
		FUNCTION:
			Retrieves the largest NZB segment ID.
		PARAMETERS:
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The largest NZB segment ID (None/string).
	'''
	def segmentLargest(self, default = None):
		try: value = self.mData['segment']['largest']
		except: value = None
		if not value: return default
		return value

	'''
		FUNCTION:
			Retrieves the list of NZB segments IDs.
		PARAMETERS:
			index (None/integer): Retrieves the ID of a segment at a specific index.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The list of NZB segments IDs (None/list).
	'''
	def segmentList(self, index = None, default = None):
		try: value = self.mData['segment']['list']
		except: value = None
		if not index is None:
			try: value = value[index]
			except: value = None
		if not value: return default
		return value

	'''
		FUNCTION:
			Sets the NZB segments.
		PARAMETERS:
			value (dictionary): The NZB segment dictionary.
	'''
	def segmentSet(self, value):
		self.mData['segment'] = value

	'''
		FUNCTION:
			Sets the ID of the first NZB segment.
		PARAMETERS:
			value (string): The first NZB segment ID.
	'''
	def segmentFirstSet(self, value):
		if not self.mData['segment']: self.mData['segment'] = {}
		self.mData['segment']['first'] = value

	'''
		FUNCTION:
			Sets the ID of the largest NZB segment.
		PARAMETERS:
			value (string): The largest NZB segment ID.
	'''
	def segmentLargestSet(self, value):
		if not self.mData['segment']: self.mData['segment'] = {}
		self.mData['segment']['largest'] = value

	'''
		FUNCTION:
			Sets the list of NZB segments IDs.
		PARAMETERS:
			value (list): The list of NZB segments IDs.
	'''
	def segmentListSet(self, value):
		if not self.mData['segment']: self.mData['segment'] = {}
		self.mData['segment']['list'] = value

	##############################################################################
	# PROVIDER
	##############################################################################

	'''
		FUNCTION:
			Retrieves the scraping provider.
		PARAMETERS:
			load (boolean): Wether or not to load the provider if not available.
		RETURNS:
			The provider (dictionary).
	'''
	def provider(self, load = True):
		if load and not self.mData['provider']['data']: self.providerLoad()
		return self.mData['provider']['data']

	'''
		FUNCTION:
			Retrieves the scraping provider ID.
		PARAMETERS:
			load (boolean): Wether or not to load the provider if not available.
		RETURNS:
			The provider ID (string).
	'''
	def providerId(self):
		return self.mData['provider']['id']

	'''
		FUNCTION:
			Retrieves the scraping provider name.
		PARAMETERS:
			load (boolean): Wether or not to load the provider if not available.
		RETURNS:
			The provider name (string).
	'''
	def providerName(self, load = True):
		if load and not self.mData['provider']['data']: self.providerLoad()
		try: return self.mData['provider']['data']['name']
		except: return None

	'''
		FUNCTION:
			Retrieves the scraping provider object.
		PARAMETERS:
			load (boolean): Wether or not to load the provider if not available.
		RETURNS:
			The provider object (object).
	'''
	def providerObject(self, load = True):
		if load and not self.mData['provider']['data']: self.providerLoad()
		try: return self.mData['provider']['data']
		except: return None

	'''
		FUNCTION:
			Sets the scraping provider.
		PARAMETERS:
			value (string/object): The provider.
	'''
	def providerSet(self, value):
		if tools.Tools.isString(value):
			self.mData['provider']['id'] = value
		else:
			self.mData['provider']['id'] = value['id']
			self.mData['provider']['data'] = value

	'''
		FUNCTION:
			Loads the provider object from the ID.
		RETURNS:
			If the loading was successful (boolean).
	'''
	def providerLoad(self):
		if self.mData['provider']['id'] and not self.mData['provider']['data']:
			from lib.providers.core.manager import Manager
			provider = Manager.provider(id = self.mData['provider']['id'])
			if not provider: provider = Manager.provider(description = self.mData['provider']['id']) # Use "description" to do a fuzzy lookup.
			if provider:
				self.mData['provider']['data'] = provider
				return True
		return False

	'''
		FUNCTION:
			Unloads the provider object.
		RETURNS:
			The provider object (object).
	'''
	def providerUnload(self):
		result = self.mData['provider']['data']
		self.mData['provider']['data'] = None
		return result

	'''
		FUNCTION:
			Realoads the provider with an existing object.
		PARAMETERS:
			data (boolean): The provider object.
	'''
	def providerReload(self, data):
		self.mData['provider']['data'] = data

	##############################################################################
	# STREAM
	##############################################################################

	'''
		FUNCTION:
			Retrieves the resolved stream data.
		RETURNS:
			The resolved stream data (dictionary).
	'''
	def stream(self):
		return self.mData['stream']

	'''
		FUNCTION:
			Retrieves the resolved stream success status.
		RETURNS:
			The resolved stream success status (None/boolean).
	'''
	def streamSuccess(self):
		try: return self.mData['stream']['success']
		except: return None

	'''
		FUNCTION:
			Retrieves the resolved stream error.
		RETURNS:
			The resolved stream error (None/string).
	'''
	def streamError(self):
		try: return self.mData['stream']['error']
		except: return None

	'''
		FUNCTION:
			Retrieves the resolved stream notification.
		RETURNS:
			The resolved stream notification (None/boolean).
	'''
	def streamNotification(self):
		try: return self.mData['stream']['notification']
		except: return None

	'''
		FUNCTION:
			Retrieves the resolved stream ID.
		RETURNS:
			The resolved stream ID (None/string).
	'''
	def streamId(self):
		try: return self.mData['stream']['id']
		except: return None

	'''
		FUNCTION:
			Retrieves the resolved stream link.
		RETURNS:
			The resolved stream link (None/string).
	'''
	def streamLink(self):
		try: return self.mData['stream']['link']
		except: return None

	'''
		FUNCTION:
			Retrieves the resolved stream items.
		RETURNS:
			The resolved stream items (None/string).
	'''
	def streamItems(self):
		try: return self.mData['stream']['items']
		except: return None

	'''
		FUNCTION:
			Retrieves the resolved stream category.
		RETURNS:
			The resolved stream category (None/string).
	'''
	def streamCategory(self):
		try: return self.mData['stream']['category']
		except: return None

	'''
		FUNCTION:
			Retrieves the resolved stream handle.
		RETURNS:
			The resolved stream category (None/object).
	'''
	def streamHandle(self):
		try: return self.mData['stream']['handle']
		except: return None

	'''
		FUNCTION:
			Sets the resolved stream data.
		PARAMETERS:
			value (dictionary): The resolved stream data.
	'''
	def streamSet(self, value):
		self.mData['stream'] = value

	'''
		FUNCTION:
			Sets the resolved stream link.
		PARAMETERS:
			value (dictionary): The resolved stream link.
	'''
	def streamLinkSet(self, value):
		self.mData['stream']['link'] = value

	##############################################################################
	# VALIDATION RELEASE
	##############################################################################

	'''
		FUNCTION:
			Whether or not the release should be validated.
		RETURNS:
			The validation (boolean).
	'''
	def validationRelease(self):
		return self.mData['validation']['release']

	'''
		FUNCTION:
			Sets whether or not the release should be validated.
		PARAMETERS:
			value (boolean): The validation.
	'''
	def validationReleaseSet(self, value = True):
		self.mData['validation']['release'] = value

	##############################################################################
	# VALIDATION KEYWORD
	##############################################################################

	'''
		FUNCTION:
			Whether or not keywords should be validated.
		RETURNS:
			The validation (boolean).
	'''
	def validationKeyword(self):
		return self.mData['validation']['keyword']

	'''
		FUNCTION:
			Sets whether or not keywords should be validated.
		PARAMETERS:
			value (boolean): The validation.
	'''
	def validationKeywordSet(self, value = True):
		self.mData['validation']['keyword'] = value

	##############################################################################
	# VALIDATION FORMAT
	##############################################################################

	'''
		FUNCTION:
			Whether or not file formats should be validated.
		RETURNS:
			The validation (boolean).
	'''
	def validationFormat(self):
		return self.mData['validation']['format']

	'''
		FUNCTION:
			Sets whether or not file formats should be validated.
		PARAMETERS:
			value (boolean): The validation.
	'''
	def validationFormatSet(self, value = True):
		self.mData['validation']['format'] = value

	##############################################################################
	# VALIDATION FAKE
	##############################################################################

	'''
		FUNCTION:
			Whether or not fakeness should be validated.
		RETURNS:
			The validation (boolean).
	'''
	def validationFake(self):
		return self.mData['validation']['fake']

	'''
		FUNCTION:
			Sets whether or not fakeness should be validated.
		PARAMETERS:
			value (boolean): The validation.
	'''
	def validationFakeSet(self, value = True):
		self.mData['validation']['fake'] = value

	##############################################################################
	# VALIDATION SIZE
	##############################################################################

	'''
		FUNCTION:
			Whether or not file sizes should be validated.
		RETURNS:
			The validation (boolean).
	'''
	def validationSize(self):
		return self.mData['validation']['size']

	'''
		FUNCTION:
			Sets whether or not file sizes should be validated.
		PARAMETERS:
			value (boolean): The validation.
	'''
	def validationSizeSet(self, value = True):
		self.mData['validation']['size'] = value

	##############################################################################
	# VALIDATION TIME
	##############################################################################

	'''
		FUNCTION:
			Whether or not source times should be validated.
		RETURNS:
			The validation (boolean).
	'''
	def validationTime(self):
		return self.mData['validation']['time']

	'''
		FUNCTION:
			Sets whether or not source times should be validated.
		PARAMETERS:
			value (boolean): The validation.
	'''
	def validationTimeSet(self, value = True):
		self.mData['validation']['time'] = value

	##############################################################################
	# VALIDATION PEERS
	##############################################################################

	'''
		FUNCTION:
			Whether or not source peers should be validated.
		RETURNS:
			The validation (boolean).
	'''
	def validationPeers(self):
		return self.mData['validation']['peers']

	'''
		FUNCTION:
			Sets whether or not source peers should be validated.
		PARAMETERS:
			value (boolean): The validation.
	'''
	def validationPeersSet(self, value = True):
		self.mData['validation']['peers'] = value

	##############################################################################
	# VALIDATION SEEDS
	##############################################################################

	'''
		FUNCTION:
			Whether or not source seeds should be validated.
		RETURNS:
			The validation (boolean).
	'''
	def validationSeeds(self):
		return self.mData['validation']['seeds']

	'''
		FUNCTION:
			Sets whether or not source seeds should be validated.
		PARAMETERS:
			value (boolean): The validation.
	'''
	def validationSeedsSet(self, value = True):
		self.mData['validation']['seeds'] = value

	##############################################################################
	# VALIDATION LEECHES
	##############################################################################

	'''
		FUNCTION:
			Whether or not source leeches should be validated.
		RETURNS:
			The validation (boolean).
	'''
	def validationLeeches(self):
		return self.mData['validation']['leeches']

	'''
		FUNCTION:
			Sets whether or not source leeches should be validated.
		PARAMETERS:
			value (boolean): The validation.
	'''
	def validationLeechesSet(self, value = True):
		self.mData['validation']['leeches'] = value

	##############################################################################
	# EXCLUSION
	##############################################################################

	'''
		FUNCTION:
			Checks whether or not this stream is excluded for any reason.
		RETURNS:
			The exclusion (boolean).
	'''
	def exclusion(self):
		return self.exclusionDuplicate() or self.exclusionRelease() or self.exclusionKeyword() or self.exclusionMetadata() or self.exclusionFormat() or self.exclusionFake() or self.exclusionSupport() or self.exclusionBlocked() or self.exclusionCaptcha() or self.exclusionPrecheckInaccessible()

	'''
		FUNCTION:
			Initialize various objects required by exclusion filtering.
	'''
	@classmethod
	def exclusionInitialize(self):
		if Stream.ExclusionData is None:
			from lib.modules.core import Core
			from lib.modules.handler import Handler

			core = Core.instance()
			core.servicesExternal() # Make sure the dictionary is intialized.

			Stream.ExclusionData = {
				'core' : core,
				'filters' : Filters.instance(),
				'handle' : {
					'direct' : Handler(type = Handler.TypeDirect),
					'torrent' : Handler(type = Handler.TypeTorrent),
					'usenet' : Handler(type = Handler.TypeUsenet),
					'hoster' : Handler(type = Handler.TypeHoster),
				}
			}
		return Stream.ExclusionData

	'''
		FUNCTION:
			Update exclusion values, except duplicates and precheck (which have to be done manually at the end).
	'''
	def exclusionUpdate(self):
		self.exclusionReleaseUpdate()
		self.exclusionKeywordUpdate()
		self.exclusionMetadataUpdate()
		self.exclusionFormatUpdate()
		self.exclusionFakeUpdate()
		self.exclusionSupportUpdate()
		self.exclusionBlockedUpdate()
		self.exclusionCaptchaUpdate()

	##############################################################################
	# EXCLUSION LINK
	##############################################################################

	def exclusionLink(self):
		if not self.link():
			self.debug(reason = 'No Link', name = self.fileName(), extra = self.sourceProvider())
			return True
		return False

	##############################################################################
	# EXCLUSION DUPLICATE
	##############################################################################

	'''
		FUNCTION:
			Checks whether or not this stream is excluded because it is a duplicate.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The duplicate exclusion (boolean/string).
	'''
	def exclusionDuplicate(self, format = FormatNone, label = LabelNone, default = None):
		value = self.mData['exclusion']['duplicate']
		if value is None: return default
		if not format == Stream.FormatNone or not label == Stream.LabelNone:
			if not value: return default
			if self.settingsFilters('exclusion', 'duplicate') == Manager.ExclusionInclude: return default
			label = self.settingsLayout(label, 'exclusion', 'duplicate')
			value = self._label(value = Stream.ExclusionDuplicate, values = Stream.LabelExclusion, format = format, label = label)
			value = self._decorate(value = value, format = format, bold = True, color = self.exclusionDuplicateColor)
		return value

	'''
		FUNCTION:
			Sets whether or not this stream is duplicate excluded.
		PARAMETERS:
			value (boolean/string): The duplicate status.
	'''
	def exclusionDuplicateSet(self, value = True):
		self.mData['exclusion']['duplicate'] = value

	'''
		FUNCTION:
			Checks whether or not the duplicate exclusion has been set yet.
		RETURNS:
			If the duplicate exclusion has been set (boolean).
	'''
	def exclusionDuplicateHas(self):
		return not self.mData['exclusion']['duplicate'] is None

	'''
		FUNCTION:
			Retrieve the color for the duplicate exclusion.
		RETURNS:
			The duplicate color (string).
	'''
	@classmethod
	def exclusionDuplicateColor(self):
		return interface.Format.colorPoor()

	##############################################################################
	# EXCLUSION RELEASE
	##############################################################################

	'''
		FUNCTION:
			Checks if the stream is excluded because it has invalid release attributes.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The release exclusion (boolean/string).
	'''
	def exclusionRelease(self, format = FormatNone, label = LabelNone, default = None):
		value = self.mData['exclusion']['release']
		if value is None: return default
		if not format == Stream.FormatNone or not label == Stream.LabelNone:
			if not value: return default
			if self.settingsFilters('exclusion', 'release') == Manager.ExclusionInclude: return default
			label = self.settingsLayout(label, 'exclusion', 'release')
			value = self._label(value = Stream.ExclusionRelease, values = Stream.LabelExclusion, format = format, label = label)
			value = self._decorate(value = value, format = format, bold = True, color = self.exclusionReleaseColor)
		return value

	'''
		FUNCTION:
			Sets whether or not this stream is release excluded.
		PARAMETERS:
			value (boolean): The release status.
	'''
	def exclusionReleaseSet(self, value = True):
		self.mData['exclusion']['release'] = value

	'''
		FUNCTION:
			Checks whether or not the release exclusion has been set yet.
		RETURNS:
			If the release exclusion has been set (boolean).
	'''
	def exclusionReleaseHas(self):
		return not self.mData['exclusion']['release'] is None

	'''
		FUNCTION:
			Calculate if the stream is release excluded.
	'''
	def exclusionReleaseUpdate(self):
		try:
			# NB: Check the release as an exclusion.
			# Do not check the release in load() already.
			# Because many providers do not have a sourceTime.
			# Only during duplicate filtering, are the attributes from different providers combined.
			# Only then will the sourceTime be available to check.

			release = False

			if self.validationRelease() and not self.releaseValid(): release = True

			self.exclusionReleaseSet(value = release)
			if release:
				self.invalidate(invalid = Stream.InvalidRelease)
				self.debug(reason = 'Invalid Release', link = self.linkPrimary(), name = self.fileName(), extra = self.sourceTime())
		except: tools.Logger.error()

	'''
		FUNCTION:
			Retrieve the color for the release exclusion.
		RETURNS:
			The release color (string).
	'''
	@classmethod
	def exclusionReleaseColor(self):
		return interface.Format.colorPoor()

	##############################################################################
	# EXCLUSION KEYWORD
	##############################################################################

	'''
		FUNCTION:
			Checks if the stream is excluded because of prohibited keywords.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
			exception (boolean): Whether or not to allow exceptions for some prohibition types.
		RETURNS:
			The keyword exclusion (boolean/string).
	'''
	def exclusionKeyword(self, format = FormatNone, label = LabelNone, default = None, exception = True):
		value = self.mData['exclusion']['keyword']
		if value is None: return default
		if not format == Stream.FormatNone or not label == Stream.LabelNone:
			if not value: return default
			filter = self.settingsFilters('exclusion', 'keyword')
			if filter == Manager.ExclusionInclude: return default
			if filter == Manager.ExclusionExclude and exception and value in Stream.ExceptionProhibition: return default
			label = self.settingsLayout(label, 'exclusion', 'keyword')
			if value is True: value = self._label(value = Stream.ExclusionKeyword, values = Stream.LabelExclusion, format = format, label = label)
			else: value = self._label(value = value, values = Stream.LabelProhibition, format = format, label = label)
			value = self._decorate(value = value, format = format, bold = True, color = self.exclusionKeywordColor)
		elif exception and value in Stream.ExceptionProhibition:
			value = default
		return value

	'''
		FUNCTION:
			Sets whether or not this stream is keyword excluded.
		PARAMETERS:
			value (boolean/string): The keyword status. Can also be a Prohibition enum.
	'''
	def exclusionKeywordSet(self, value = True):
		self.mData['exclusion']['keyword'] = value

	'''
		FUNCTION:
			Checks whether or not the keyword exclusion has been set yet.
		PARAMETERS:
			exception (boolean): Whether or not to allow exceptions for some prohibition types.
		RETURNS:
			If the keyword exclusion has been set (boolean).
	'''
	def exclusionKeywordHas(self, exception = True):
		result = self.mData['exclusion']['keyword']
		return not result is None and (not exception or not result in Stream.ExceptionProhibition)

	'''
		FUNCTION:
			Calculate if the stream is keyword excluded.
	'''
	def exclusionKeywordUpdate(self):
		try:
			keyword = False

			if self.validationKeyword():
				keyword = self.titleProhibited(exception = False, type = True)
				if keyword is None: keyword = False

			self.exclusionKeywordSet(value = keyword)
			if keyword and not keyword in Stream.ExceptionProhibition:
				self.invalidate(invalid = Stream.InvalidKeyword)
				self.debug(reason = 'Prohibited Keywords', link = self.linkPrimary(), name = self.fileName())
		except: tools.Logger.error()

	'''
		FUNCTION:
			Retrieve the color for the keyword exclusion.
		RETURNS:
			The keyword color (string).
	'''
	@classmethod
	def exclusionKeywordColor(self):
		return interface.Format.colorMedium()

	##############################################################################
	# EXCLUSION METADATA
	##############################################################################

	'''
		FUNCTION:
			Checks if the stream is excluded because it has invalid metadata attributes.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The metadata exclusion (boolean/string).
	'''
	def exclusionMetadata(self, format = FormatNone, label = LabelNone, default = None):
		value = self.mData['exclusion']['metadata']
		if value is None: return default
		if not format == Stream.FormatNone or not label == Stream.LabelNone:
			if not value: return default
			if self.settingsFilters('exclusion', 'metadata') == Manager.ExclusionInclude: return default
			label = self.settingsLayout(label, 'exclusion', 'metadata')
			value = self._label(value = Stream.ExclusionMetadata, values = Stream.LabelExclusion, format = format, label = label)
			value = self._decorate(value = value, format = format, bold = True, color = self.exclusionMetadataColor)
		return value

	'''
		FUNCTION:
			Sets whether or not this stream is metadata excluded.
		PARAMETERS:
			value (boolean): The metadata status.
	'''
	def exclusionMetadataSet(self, value = True):
		self.mData['exclusion']['metadata'] = value

	'''
		FUNCTION:
			Checks whether or not the metadata exclusion has been set yet.
		RETURNS:
			If the metadata exclusion has been set (boolean).
	'''
	def exclusionMetadataHas(self):
		return not self.mData['exclusion']['metadata'] is None

	'''
		FUNCTION:
			Calculate if the stream is metadata excluded.
	'''
	def exclusionMetadataUpdate(self):
		try:
			invalid = None
			reason = None
			extra = None

			# File Size
			if self.validationSize() and not(self.fileSizeValid(exact = Stream.ExactYes, none = True) or self.fileSizeValid(exact = Stream.ExactNo, none = False)):
				invalid = Stream.InvalidSize
				reason = 'File Size'
				extra = self.fileSize()

			# Source Time
			elif self.validationTime() and not(self.sourceTimeValid(exact = Stream.ExactYes, none = True) or self.sourceTimeValid(exact = Stream.ExactNo, none = False)):
				invalid = Stream.InvalidTime
				reason = 'Source Time'
				extra = self.sourceTime()

			# Source Seeds
			elif self.validationSeeds() and not(self.sourceSeedsValid(exact = Stream.ExactYes, none = True) or self.sourceSeedsValid(exact = Stream.ExactNo, none = False)):
				invalid = Stream.InvalidSeed
				reason = 'Seeds'
				extra = self.sourceSeeds()

			# Source Leeches
			elif self.validationLeeches() and not(self.sourceLeechesValid(exact = Stream.ExactYes, none = True) or self.sourceLeechesValid(exact = Stream.ExactNo, none = False)):
				invalid = Stream.InvalidLeech
				reason = 'Leeches'
				extra = self.sourceLeeches()

			# Source Peers
			elif self.validationPeers() and not(self.sourcePeersValid(exact = Stream.ExactYes, none = True) or self.sourcePeersValid(exact = Stream.ExactNo, none = False)):
				invalid = Stream.InvalidPeer
				reason = 'Peers'
				extra = self.sourceLeeches()

			self.exclusionMetadataSet(value = bool(reason))
			if reason:
				self.invalidate(invalid = invalid)
				self.debug(reason = 'Invalid ' + reason, link = self.linkPrimary(), name = self.fileName(), extra = extra)
		except: tools.Logger.error()

	'''
		FUNCTION:
			Retrieve the color for the metadata exclusion.
		RETURNS:
			The metadata color (string).
	'''
	@classmethod
	def exclusionMetadataColor(self):
		return interface.Format.colorPoor()

	##############################################################################
	# EXCLUSION FORMAT
	##############################################################################

	'''
		FUNCTION:
			Checks if the stream is excluded because it has an invalid file format or extension.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The format exclusion (boolean/string).
	'''
	def exclusionFormat(self, format = FormatNone, label = LabelNone, default = None):
		value = self.mData['exclusion']['format']
		if value is None: return default
		if not format == Stream.FormatNone or not label == Stream.LabelNone:
			if not value: return default
			if self.settingsFilters('exclusion', 'format') == Manager.ExclusionInclude: return default
			label = self.settingsLayout(label, 'exclusion', 'format')
			value = self._label(value = Stream.ExclusionFormat, values = Stream.LabelExclusion, format = format, label = label)
			value = self._decorate(value = value, format = format, bold = True, color = self.exclusionFormatColor)
		return value

	'''
		FUNCTION:
			Sets whether or not this stream is format excluded.
		PARAMETERS:
			value (boolean): The format status.
	'''
	def exclusionFormatSet(self, value = True):
		self.mData['exclusion']['format'] = value

	'''
		FUNCTION:
			Checks whether or not the format exclusion has been set yet.
		RETURNS:
			If the format exclusion has been set (boolean).
	'''
	def exclusionFormatHas(self):
		return not self.mData['exclusion']['format'] is None

	'''
		FUNCTION:
			Calculate if the stream is format excluded.
	'''
	def exclusionFormatUpdate(self):
		try:
			format = False

			if self.validationFormat() and not self.fileNameValid():
				format = True

			self.exclusionFormatSet(value = format)
			if format:
				self.invalidate(invalid = Stream.InvalidFormat)
				self.debug(reason = 'Invalid File Format', link = self.linkPrimary(), name = self.fileName())
		except: tools.Logger.error()

	'''
		FUNCTION:
			Retrieve the color for the format exclusion.
		RETURNS:
			The format color (string).
	'''
	@classmethod
	def exclusionFormatColor(self):
		return interface.Format.colorBad()

	##############################################################################
	# EXCLUSION FAKE
	##############################################################################

	'''
		FUNCTION:
			Checks if the stream is excluded because it is probably a fake upload.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The fake exclusion (boolean/string).
	'''
	def exclusionFake(self, format = FormatNone, label = LabelNone, default = None):
		value = self.mData['exclusion']['fake']
		if value is None: return default
		if not format == Stream.FormatNone or not label == Stream.LabelNone:
			if not value: return default
			if self.settingsFilters('exclusion', 'fake') == Manager.ExclusionInclude: return default
			label = self.settingsLayout(label, 'exclusion', 'fake')
			value = self._label(value = Stream.ExclusionFake, values = Stream.LabelExclusion, format = format, label = label)
			value = self._decorate(value = value, format = format, bold = True, color = self.exclusionFakeColor)
		return value

	'''
		FUNCTION:
			Sets whether or not this stream is fake excluded.
		PARAMETERS:
			value (boolean): The fake status.
	'''
	def exclusionFakeSet(self, value = True):
		self.mData['exclusion']['fake'] = value

	'''
		FUNCTION:
			Checks whether or not the fake exclusion has been set yet.
		RETURNS:
			If the fake exclusion has been set (boolean).
	'''
	def exclusionFakeHas(self):
		return not self.mData['exclusion']['fake'] is None

	'''
		FUNCTION:
			Calculate if the stream is format excluded.
	'''
	def exclusionFakeUpdate(self, threshold = None):
		try:
			fake = False

			if self.validationFake():
				'''
					Fakes typically have these characteristics.
						1. Shows a +- 2min video with an Xvid logo asking the user to visit a link in a ReadMe file.
						2. 500MB - 800MB (mostly around 650MB).
						3. Uploaded before most other releases. Often uplaoded at the same time as CAM/SCR, but claiming to be a proper HD rip.
						4. Restricted to SD - HD1080, and an occasional HD4K. Also not CAM/SCR, probably because people will not download those often.
						5. Typically has a decent number of seeds, at least when newley uploaded, around 20+.
						6. Seems this is only for movies, not sure if there are fake show/episode uploads.
						7. Contains "1080p" or "720p" or no quality for SD.
						8. File name is relativley short, with the title + year, followed by a few metadata attributes.
						9. Mostly ends with a release group, but not always.
						10. Mostly contains x265/x264, but not always.
						11. Mostly does not contain an audio quality, but not always.
						12. Mostly contains a release type (BluRay, BRRip, WEBRip, WEB-DL, DVDRip), but not always.
						13. Seems to be restricted to torrent. But not sure.
						14. Does not contain the file size (eg "900MB") in the file name. If the file size is contained, it is probably a legit upload, except if it also contains the keywoird "Full".
					Fake:
						The French Dispatch 2021 BDRip 2160p X265			637MB - HD4K
						No Time to Die.2021.1080p.BRRip.x265-POKO			738MB - HD1080
						No Time to Die.2021.1080p.BRRip.x265-CIVOP			738MB - HD1080
						No Time to Die.2021.1080p BluRay x264 DTS-JYK		575MB - HD1080
						No Time to Die.2021.1080p.BRRip.x264-Classics		574MB - HD1080
						No Time to Die (2021) 1080p BluRay H264-AMIABLE		668MB - HD1080
						No Time to Die (2021) [1080p] [WEBRip]ETRG]			669MB - HD1080
						Dune [2021].1080p.BluRay.H.265-heroskeep			623MB - HD1080
						Dune.2021.1080p BluRay x264 DTS-HD Regraded			696MB - HD1080
						No Time to Die 2021 720p.BluRay.x264-GUACAMOLE		631MB - HD720
						No Time to Die.2021.720p.WEBRip.x264-GalaxyRG		676MB - HD720
						No Time to Die.2021.720p.WEB-DL.x264-worldmkv		676MB - HD720
						No Time to Die.2021.WEBRip x264 AAC-ETRG			676MB - SD
						No Time to Die.(2021) BluRay.x264-x0r				676MB - SD
						No Time to Die..2021.BrRip x264-HECOHAT				676MB - SD
						No Time to Die..2021.DVDRip x264					676MB - SD
					Legit:
						www.TamilBlasters.vip - No Time To Die (2021) [HDRip - x264 - AAC - [Tamil (HQ Line Audio)] - 400MB].mkv			440MB - HD720
						No Time to Die 2021 720p AMZN WEBRip x264 AAC 900MB - ShortRips.mkv													956MB - HD720
						No.Time.To.Die.2021.AMZN.WEBRip.700MB.h264.MP4-Microflix[TGx]														700MB - SD
						Dune.2021.HDRip.XviD.B4ND1T69																						762MB - SD
				'''

				fakeness = 0

				# NB: If we ever check episodes as well, make sure that not too many are labeled as fake.
				# Eg (Lapumia provider):
				#	Game.of.Thrones.S08E01.WEBRip.x264-ION10
				#	Game of Thrones 2019 - S08E01 (720p)
				#	Game of Thrones 2019 - S08E01 (1080p)
				#	Game.of.Thrones.S08E01.1080p.WEB-DL.DUAL-LAPUMiA
				if self.sourceTypeTorrent() and self.metaMediaMovie():
					# Ignore non-universal providers, since they almost always have valid links, but they might adhere to the characteristics below.
					infoLanguage = self.infoLanguage()
					if not infoLanguage or (len(infoLanguage) == 1 and infoLanguage[0] == tools.Language.UniversalCode):
						fileSize = self.fileSize()
						if fileSize and fileSize >= 524288000 and fileSize <= 838860800:
							fileName = self.fileName()
							if fileName:
								videoQuality = self.videoQuality()
								if videoQuality and not Stream.VideoQualityScr in videoQuality and not Stream.VideoQualityCam in videoQuality:
									releaseGroup = self.releaseGroup()

									audioLanguage = self.audioLanguage()
									if audioLanguage:
										audioDefault = self.audioDefault()
										if audioDefault: audioLanguage = [i for i in audioLanguage if not i in audioDefault] # Ignore if the language is the assumed default language.
										# Ignore English, since some fakes contain only Eng.
										# Avatar (2009) Dvdrip xvid [ Eng ] fxg
										# Avatar (2009) English DVDRip XviD-BeStDivX
										try: audioLanguage.remove('en')
										except: pass

									values = [
										self.videoCodec() in [Stream.VideoCodecH264, Stream.VideoCodecH265],
										not self.video3d(),

										not self.audioType(original = False),
										not self.audioChannels(),
										not self.audioSystem(),
										not self.audioCodec(),
										not audioLanguage,

										not self.subtitleType(),
										not self.subtitleLanguage(),

										self.releaseType(),
										not self.releaseEdition(),
										not self.releaseNetwork(),
										releaseGroup,

										not self.fileContainer(),
									]
									values = [1 if i else -1 for i in values]

									fakeness = sum(values) / float(len(values))
									fakeness = max(0, min(1, fakeness))

									lengthMinimum = 10
									lengthMaximum = 40
									metadata = self._cacheId('fake1', re.compile, '(.*?)(?:' + Stream.ExpressionYear + '|4k|2160p|1080p|720p|x26[45]|brrip|bluray|webrip|web-dl|dvdrip).*', flags = Stream.ExpressionFlags).search(fileName)
									if metadata: metadata = fileName.replace(metadata.group(1), '')
									else: metadata = fileName
									length = len(metadata)
									if length < lengthMinimum or length > lengthMaximum: length = 0
									else: length = 1

									fakeness = (0.6 * fakeness) + (0.4 * length)

									# Contains a file size in the file name. Almost always a proper upload.
									# 0.2 is too little, eg: Encanto.2021.720p.WEBRip.800MB.x264-GalaxyRG
									#if self.fileSize(exact = Stream.ExactNo): fakeness -= 0.2 # Do not do this, since inexact file sizes are only extracted if there is no exact file size.
									if self.fileSizeExtract(data = fileName, clean = False, name = True): fakeness -= 0.3

									# Contains the "Full" keyword.
									# Seems to mostly be fake.
									# Avatar (2009) 1080p.BluRay.x264.Full 553MB
									full = self._cacheId('fake2', re.compile, Stream.ExpressionSeparator + 'full(?!' + Stream.ExpressionSeparator + '*hd)(?:$|' + Stream.ExpressionSeparator + ')', flags = Stream.ExpressionFlags).search(fileName)
									if full: fakeness += 0.3

									# If there is a release format, it is probably not fake.
									# Avatar.2009.PROPER.REPACK.BDrip.XviD-ORC
									if self.releaseFormat(): fakeness -= 0.3

									# If there is a release edition, it is probably not fake.
									# Avatar-Extended Collector's Edition [2009]-480p-BRrip-x264-StyLishSaLH
									if self.releaseEdition(): fakeness -= 0.3

									# If it contains a language, it is probably legit.
									# [ Torrent911 com ] Encanto 2021 TRUEFRENCH HDRip XviD EXTREME
									languageAudio = self.audioLanguage()
									if languageAudio:
										languageDefault = self.audioDefault()
										if languageDefault: languageAudio = [i for i in languageAudio if i not in languageDefault] # Ignore default languages.
									if languageAudio or self.subtitleLanguage(): fakeness -= 0.2

									# If 10bit or HDR are in the filename, it is probably legit.
									# Dune.2021.720p.10bit.WEBRip.6CH.x265.HEVC-PSA
									if self.videoDepth() or self.videoRange(): fakeness -= 0.2

									# If there are multiple release groups, it is probably legit.
									if releaseGroup and len(releaseGroup) >= 2: fakeness -= 0.2

									if self.filePack(): fakeness -= 0.2

				if threshold is None:
					threshold = self.thresholdFake()
					if threshold is None: threshold = self.threshold('fake')

				fake = fakeness >= threshold

			self.exclusionFakeSet(value = fake)
			if fake:
				self.invalidate(invalid = Stream.InvalidFake)
				self.debug(reason = 'Fake Upload', link = self.linkPrimary(), name = self.fileName())
		except: tools.Logger.error()

	'''
		FUNCTION:
			Retrieve the color for the fake exclusion.
		RETURNS:
			The fake color (string).
	'''
	@classmethod
	def exclusionFakeColor(self):
		return interface.Format.colorPoor()

	##############################################################################
	# EXCLUSION SUPPORT
	##############################################################################

	'''
		FUNCTION:
			Checks if the stream is excluded because it does not have a supported handler.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The support exclusion (boolean/string).
	'''
	def exclusionSupport(self, format = FormatNone, label = LabelNone, default = None):
		value = self.mData['exclusion']['support']
		if value is None: return default
		if not format == Stream.FormatNone or not label == Stream.LabelNone:
			if not value: return default
			if self.settingsFilters('exclusion', 'support') == Manager.ExclusionInclude: return default
			label = self.settingsLayout(label, 'exclusion', 'support')
			value = self._label(value = Stream.ExclusionSupport, values = Stream.LabelExclusion, format = format, label = label)
			value = self._decorate(value = value, format = format, bold = True, color = self.exclusionSupportColor)
		return value

	'''
		FUNCTION:
			Sets whether or not this stream is support excluded.
		PARAMETERS:
			value (boolean): The support status.
	'''
	def exclusionSupportSet(self, value = True):
		self.mData['exclusion']['support'] = value

	'''
		FUNCTION:
			Checks whether or not the support exclusion has been set yet.
		RETURNS:
			If the support exclusion has been set (boolean).
	'''
	def exclusionSupportHas(self):
		return not self.mData['exclusion']['support'] is None

	'''
		FUNCTION:
			Calculate if the stream is support excluded.
	'''
	def exclusionSupportUpdate(self):
		try:
			supported = False
			data = self.exclusionInitialize()

			if self.accessCacheAny(account = True): # Always include cached streams.
				supported = True
			elif self.sourceTypeLocal():
				supported = True
			elif self.sourceTypeTorrent():
				if data['handle']['torrent'].supported(self): supported = True
			elif self.sourceTypeUsenet():
				if data['handle']['usenet'].supported(self): supported = True
			elif self.accessTypeDirect():
				if data['handle']['direct'].supported(self): supported = True
			elif self.sourceOriginExternal() and not self.sourceHoster():
				supported = True # Different link might be returned when the scraper resolves the link.
			elif self.sourceHoster():
				if data['handle']['hoster'].supported(self):
					supported = True
				else:
					# Only use the provider if it has a custom resolve() function.
					# That is, the link can change after being passed to resolve() and we can therefore not assume support before resolve() is execute.
					provider = data['core'].sourceExternal(stream = self)
					if provider and provider.resolver(): supported = True

			unsupported = not supported
			self.exclusionSupportSet(value = unsupported)
			if unsupported:
				# Do not call: self.invalidate()
				self.debug(reason = 'Unsupported Link', link = self.linkPrimary(), extra = self.sourceProvider())
		except: tools.Logger.error()

	'''
		FUNCTION:
			Retrieve the color for the support exclusion.
		RETURNS:
			The support color (string).
	'''
	@classmethod
	def exclusionSupportColor(self):
		return interface.Format.colorBad()

	##############################################################################
	# EXCLUSION BLOCKED
	##############################################################################

	'''
		FUNCTION:
			Checks if the stream is excluded because it is a blocked hoster.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The blocked exclusion (boolean/string).
	'''
	def exclusionBlocked(self, format = FormatNone, label = LabelNone, default = None):
		value = self.mData['exclusion']['blocked']
		if value is None: return default
		if not format == Stream.FormatNone or not label == Stream.LabelNone:
			if not value: return default
			if self.settingsFilters('exclusion', 'blocked') == Manager.ExclusionInclude: return default
			label = self.settingsLayout(label, 'exclusion', 'blocked')
			value = self._label(value = Stream.ExclusionBlocked, values = Stream.LabelExclusion, format = format, label = label)
			value = self._decorate(value = value, format = format, bold = True, color = self.exclusionBlockedColor)
		return value

	'''
		FUNCTION:
			Sets whether or not this stream is blocked excluded.
		PARAMETERS:
			value (boolean): The the blocked status.
	'''
	def exclusionBlockedSet(self, value = True):
		self.mData['exclusion']['blocked'] = value

	'''
		FUNCTION:
			Checks whether or not the blocked exclusion has been set yet.
		RETURNS:
			If the blocked exclusion has been set (boolean).
	'''
	def exclusionBlockedHas(self):
		return not self.mData['exclusion']['blocked'] is None

	'''
		FUNCTION:
			Calculate if the stream is blocked excluded.
	'''
	def exclusionBlockedUpdate(self):
		try:
			blocked = False

			if self.sourceTypeHoster():
				data = self.exclusionInitialize()
				hosters = data['core'].hostersBlocked()

				blocked = self.sourceHoster() in hosters
				if not blocked:
					link = self.linkPrimary()
					if link:
						link = link.lower()
						domainFull = network.Networker.linkDomain(link = link, subdomain = False, topdomain = True, ip = False)
						if domainFull:
							blocked = domainFull in hosters
							if not blocked:
								domainPlain = network.Networker.linkDomain(link = link, subdomain = False, topdomain = False, ip = False)
								if domainPlain: blocked = domainPlain in hosters

			self.exclusionBlockedSet(value = blocked)
			if blocked:
				self.invalidate(invalid = Stream.InvalidBlocked)
				self.debug(reason = 'Blocked Hoster', link = self.linkPrimary(), extra = self.sourceHoster())
		except: tools.Logger.error()

	'''
		FUNCTION:
			Retrieve the color for the blocked exclusion.
		RETURNS:
			The blocked color (string).
	'''
	@classmethod
	def exclusionBlockedColor(self):
		return interface.Format.colorBad()

	##############################################################################
	# EXCLUSION CAPTCHA
	##############################################################################

	'''
		FUNCTION:
			Checks if the stream is excluded because it has a captcha.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The captcha exclusion (boolean/string).
	'''
	def exclusionCaptcha(self, format = FormatNone, label = LabelNone, default = None):
		value = self.mData['exclusion']['captcha']
		if value is None: return default
		if not format == Stream.FormatNone or not label == Stream.LabelNone:
			if not value: return default
			if self.settingsFilters('exclusion', 'captcha') == Manager.ExclusionInclude: return default
			label = self.settingsLayout(label, 'exclusion', 'captcha')
			value = self._label(value = Stream.ExclusionCaptcha, values = Stream.LabelExclusion, format = format, label = label)
			value = self._decorate(value = value, format = format, bold = True, color = self.exclusionCaptchaColor)
		return value

	'''
		FUNCTION:
			Sets whether or not this stream is captcha excluded.
		PARAMETERS:
			value (boolean): The the captcha status.
	'''
	def exclusionCaptchaSet(self, value = True):
		self.mData['exclusion']['captcha'] = value

	'''
		FUNCTION:
			Checks whether or not the captcha exclusion has been set yet.
		RETURNS:
			If the captcha exclusion has been set (boolean).
	'''
	def exclusionCaptchaHas(self):
		return not self.mData['exclusion']['captcha'] is None

	'''
		FUNCTION:
			Calculate if the stream is blocked excluded.
	'''
	def exclusionCaptchaUpdate(self):
		try:
			captcha = False

			if self.sourceTypeHoster() and self.accessTypeOpen(account = True):
				data = self.exclusionInitialize()
				hosters = data['core'].hostersCaptcha()
				captcha = self.sourceHoster() in hosters

			self.exclusionCaptchaSet(value = captcha)
			if captcha:
				# Do not call: self.invalidate()
				self.debug(reason = 'Captcha Protected', link = self.linkPrimary(), name = self.sourceHoster())
		except: tools.Logger.error()

	'''
		FUNCTION:
			Retrieve the color for the captcha exclusion.
		RETURNS:
			The captcha color (string).
	'''
	@classmethod
	def exclusionCaptchaColor(self):
		return interface.Format.colorMedium()

	##############################################################################
	# EXCLUSION PRECHECK
	##############################################################################

	'''
		FUNCTION:
			Checks if the stream is excluded because the precheck failed.
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			The precheck exclusion (boolean/string).
	'''
	def exclusionPrecheck(self, format = FormatNone, label = LabelNone, default = None):
		value = self.mData['exclusion']['precheck']
		if value is None: return default
		if not format == Stream.FormatNone or not label == Stream.LabelNone:
			original = value
			label = self.settingsLayout(label, 'exclusion', 'precheck')
			if self.settingsFilters('exclusion', 'precheck') == Manager.ExclusionInclude: return default
			value = self._label(value = Stream.ExclusionPrecheck, values = Stream.LabelExclusion, format = format, label = label)
			value = self._decorate(value = value, format = format, bold = True, color = self.exclusionPrecheckColor, colorvalue = original)
		return value

	'''
		FUNCTION:
			Sets whether or not this stream is precheck excluded.
		PARAMETERS:
			value (boolean): The precheck status.
	'''
	def exclusionPrecheckSet(self, value = True):
		self.mData['exclusion']['precheck'] = value

	'''
		FUNCTION:
			Checks whether or not the precheck exclusion has been set yet.
		RETURNS:
			If the precheck exclusion has been set (boolean).
	'''
	def exclusionPrecheckHas(self):
		return not self.mData['exclusion']['precheck'] is None

	'''
		FUNCTION:
			Checks whether or not the stream precheck is inaccessible.
		RETURNS:
			If the stream is inaccessible (boolean).
	'''
	def exclusionPrecheckInaccessible(self):
		return self.mData['exclusion']['precheck'] in [network.Networker.StatusOffline, network.Networker.StatusCloudflare]

	'''
		FUNCTION:
			Retrieve the color for the precheck exclusion.
		RETURNS:
			The precheck color (string).
	'''
	@classmethod
	def exclusionPrecheckColor(self, value = None):
		if value == network.Networker.StatusOnline: return interface.Format.colorExcellent()
		elif value == network.Networker.StatusOffline: return interface.Format.colorBad()
		elif value == network.Networker.StatusCloudflare: return interface.Format.colorPoor()
		else: return interface.Format.colorMedium()

	##############################################################################
	# INFO TERMINATION
	##############################################################################

	'''
		FUNCTION:
			Retrieves the termination status.
		PARAMETERS:
			index (None/integer): The index of the condition to retrieve. If None, retrieves all conditions.
		RETURNS:
			The termination status (list/boolean).
	'''
	def infoTermination(self, index = None):
		value = self.mData['info']['termination']
		if not index is None:
			try: value = value[index]
			except: value = None
		return value

	'''
		FUNCTION:
			Sets the termination status.
		PARAMETERS:
			value (list/boolean): The termination status.
			index (None/integer): The index of the condition to set. If None, sets all conditions.
	'''
	def infoTerminationSet(self, value = True, index = None):
		if index is None:
			if not tools.Tools.isArray(value): value = [value]
			self.mData['info']['termination'] = value
		else:
			self.mData['info']['termination'].insert(index, value)

	'''
		FUNCTION:
			Clears the termination status.
	'''
	def infoTerminationClear(self):
		self.infoTerminationSet(value = [])

	'''
		FUNCTION:
			Checks if the termination status has been set yet.
		PARAMETERS:
			index (None/integer): The index of the condition to retrieve. If None, retrieves all conditions.
		RETURNS:
			If the termination status has been set (boolean).
	'''
	def infoTerminationHas(self, index = None):
		value = self.mData['info']['termination']
		if index is None:
			value = True if bool(value) else False
		else:
			try: value = value[index]
			except: value = None
			value = False if value is None else True
		return value

	##############################################################################
	# INFO EXACT
	##############################################################################

	'''
		FUNCTION:
			Checks if the stream is a result of an exact search (through the "Exact" feature in the search menu).
		RETURNS:
			If exact (boolean).
	'''
	def infoExact(self):
		return self.mData['info']['exact']

	'''
		FUNCTION:
			Sets if the stream is a result of an exact search.
		PARAMETERS:
			value (boolean): If exact.
	'''
	def infoExactSet(self, value = True):
		self.mData['info']['exact'] = value

	'''
		FUNCTION:
			Checks whether or not the exact search was set yet.
		RETURNS:
			If the exact search was set (boolean).
	'''
	def infoExactHas(self):
		return not self.mData['info']['exact'] is None

	##############################################################################
	# INFO CUSTOM
	##############################################################################

	'''
		FUNCTION:
			Checks if the stream was customly added (through the "Add Link" feature in the context menu).
		PARAMETERS:
			format (string): The format of the returned value.
			label (string): The type or unit label to use.
			default (various): The default value to return if the attribute is not set.
		RETURNS:
			If custom (boolean/string).
	'''
	def infoCustom(self, format = FormatNone, label = LabelNone, default = None):
		value = self.mData['info']['custom']
		if value is None: return default
		if not format == Stream.FormatNone or not label == Stream.LabelNone:
			if not value: return default
			label = self.settingsLayout(label, 'info', 'custom')
			value = self._label(value = Stream.InfoCustom, values = Stream.LabelInfo, format = format, label = label)
			value = self._decorate(value = value, format = format, bold = True, color = self.infoCustomColor)
		return value

	'''
		FUNCTION:
			Sets if the stream was customly added.
		PARAMETERS:
			value (boolean): If custom.
	'''
	def infoCustomSet(self, value = True):
		self.mData['info']['custom'] = value

	'''
		FUNCTION:
			Checks whether or not custom was set yet.
		RETURNS:
			If custom was set (boolean).
	'''
	def infoCustomHas(self):
		return not self.mData['info']['custom'] is None

	'''
		FUNCTION:
			Retrieve the color for custom info.
		RETURNS:
			The info color (string).
	'''
	@classmethod
	def infoCustomColor(self):
		return interface.Format.colorMedium()

	##############################################################################
	# INFO SORT
	##############################################################################

	'''
		FUNCTION:
			Retrieves the sort attribute.
		RETURNS:
			The sort attribute (string).
	'''
	def infoSort(self):
		return self.mData['info']['sort']

	'''
		FUNCTION:
			Sets the sort attribute.
		PARAMETERS:
			value (string): The sort attribute.
	'''
	def infoSortSet(self, value = True):
		self.mData['info']['sort'] = value

	'''
		FUNCTION:
			Checks whether or not the sort attribute has been set yet.
		RETURNS:
			If the sort attribute has been set (boolean).
	'''
	def infoSortHas(self):
		return not self.mData['info']['sort'] is None

	##############################################################################
	# INFO LANGUAGE
	##############################################################################

	'''
		FUNCTION:
			Retrieves the languages of the source/provider.
			These languages are used as additional language name variations to detect the language from the file name.
			For instance, streams coming from a French provider might use the French translation of language names (eg: Portugais or Allemand).
		RETURNS:
			The languages (list).
	'''
	def infoLanguage(self):
		return self.mData['info']['language']

	'''
		FUNCTION:
			Sets the provider languages.
		PARAMETERS:
			value (string/list): The languages.
	'''
	def infoLanguageSet(self, value):
		if value and not tools.Tools.isArray(value): value = [value]
		self.mData['info']['language'] = value

	'''
		FUNCTION:
			Checks whether or not the provider languages have been set yet.
		RETURNS:
			If the provider languages has been set (boolean).
	'''
	def infoLanguageHas(self):
		return not self.mData['info']['language'] is None

	##############################################################################
	# INFO QUERY
	##############################################################################

	'''
		FUNCTION:
			Retrieves the query with which the stream was scraped.
		PARAMETERS:
			keys (string): Subattributes to access.
		RETURNS:
			The query (dictionary/string).
	'''
	def infoQuery(self, *keys):
		value = self.mData['info']['query']
		if value and keys: value = tools.Tools.dictionaryGet(dictionary = value, keys = list(keys))
		return value

	'''
		FUNCTION:
			Retrieves the query search string used to do the scraping.
		RETURNS:
			The query (string).
	'''
	def infoQuerySearch(self):
		return self.infoQuery('search')

	'''
		FUNCTION:
			Sets the query with which the stream was scraped.
		PARAMETERS:
			value (dictionary): The query dictionary.
	'''
	def infoQuerySet(self, value):
		self.mData['info']['query'] = value

	'''
		FUNCTION:
			Checks whether or not the query has been set yet.
		RETURNS:
			If the query has been set (boolean).
	'''
	def infoQueryHas(self):
		return not self.mData['info']['query'] is None

	##############################################################################
	# INFO CACHE
	##############################################################################

	'''
		FUNCTION:
			Retrieves if the stream was retrieved from cache or was scraped.
		PARAMETERS:
			expired (boolean): If True, return the raw value. If False, return None if the cache expired, else the raw value.
		RETURNS:
			The cache (boolean/string).
	'''
	def infoCache(self, expired = True):
		value = self.mData['info']['cache']
		if expired: return value
		return None if value == Stream.AccessCacheExpired else value

	'''
		FUNCTION:
			Sets if the stream was retrieved from cache or was scraped.
		PARAMETERS:
			value (boolean/string): The cache.
	'''
	def infoCacheSet(self, value = True):
		self.mData['info']['cache'] = value

	'''
		FUNCTION:
			Checks whether or not the cache has been set yet.
		RETURNS:
			If the cache has been set (boolean).
	'''
	def infoCacheHas(self):
		return not self.mData['info']['cache'] is None

	'''
		FUNCTION:
			Marks the cache status as expired.
	'''
	def infoCacheExpire(self):
		self.infoCacheSet(value = Stream.AccessCacheExpired)

	'''
		FUNCTION:
			Checks whether or not the cache has expired.
		RETURNS:
			If the cache has expired (boolean).
	'''
	def infoCacheExpired(self):
		return self.mData['info']['cache'] == Stream.AccessCacheExpired

	##############################################################################
	# INFO IDENTIFIER
	##############################################################################

	'''
		FUNCTION:
			Retrieves if the stream was already check for identifiers/hashes against Orion.
		RETURNS:
			The identifier (boolean).
	'''
	def infoIdentifier(self):
		return self.mData['info']['identifier']

	'''
		FUNCTION:
			Sets if the stream was check for identifiers/hashes against Orion.
		PARAMETERS:
			value (boolean): The identifier.
	'''
	def infoIdentifierSet(self, value = True):
		self.mData['info']['identifier'] = value

	'''
		FUNCTION:
			Checks whether or not the identifiers/hashes have been set yet.
		RETURNS:
			If the identifier has been set (boolean).
	'''
	def infoIdentifierHas(self):
		return not self.mData['info']['identifier'] is None

	##############################################################################
	# CLEAN
	##############################################################################

	@classmethod
	def clean(self, data, exclude = None, encode = True, native = None, split = SplitNone, full = True):
		data = self.cleanBasic(data)
		data = self.cleanKeyword(data, exclude = exclude, encode = encode, native = native, split = split, full = full)
		data = self.cleanOther(data)
		return data

	'''
		FUNCTION:
			Clean a file name from basic keywords that do not form part of the file name.
		PARAMETERS:
			data (string): The file name.
			html (boolean): Clean HTML entities.
			usenet (boolean/None): Clean usenet labels/metadata. If None, will do a usenet clean if some keywords (like yEnc) appear in the name.
			process (function): Optional function to process the file name.
		RETURNS:
			The file name (string).
	'''
	@classmethod
	def cleanBasic(self, data, html = True, usenet = None, process = None):
		if not data: return data

		# URL decode
		from lib.modules import network
		data = network.Networker.linkUnquote(data = data, plus = False)

		# Must be after URL decode.
		# Important for show number validation.
		# Eg: The "à" in: Faites Entrer l\'Accusé | INTEGRALE | Saison 01 à 7 | WEB-DL | x264 [AMIRAL]
		try: data = tools.Converter.unicode(data)
		except: pass
		data = data.strip()

		# Category trailers
		data = self._cacheId('cleanBasic1', re.compile, u'\s*(?:»|\||\u00BB)\s*(?:movies?|tv(?:[\s\-]?shows?)?|television|anime|games?|other|misc(?:ellaneous)?).*$', flags = Stream.ExpressionFlags).sub('', data) # Expression must be unicode string.
		data = self._cacheId('cleanBasic2', re.compile, u'\s*-\s*(?:movies?|tv(?:[\s\-]?shows?)?|television|anime|games?|other|misc(?:ellaneous)?)\s*$', flags = Stream.ExpressionFlags).sub('', data)

		# Remove the yellow star at the end of the name.
		# Some uploaders seem to add this to make their torrents stand out.
		# The star is shown on some sites (eg uploader on mazemaze16 on 1337x), but other sites (eg ThePirateBay) removes it.
		# Eg: Tenet.2020.1080p.HDRip.X264-EVO[TGx] ⭐
		# https://www.reddit.com/r/duckietv/comments/c0lje7/yellow_star_in_torrent_listings/
		try: data = data.rstrip('⭐')
		except: pass

		# Replace new line characters.
		# The last "long space" is \x8D which is the "Reverse Line Feed".
		# Eg (char after &Aring;): Sh&Aring;gun.2024.S01E03.WEB.x264-TORRENTGALAXY
		try: data = data.replace('\n', '').replace('\r', '').replace('', '')
		except: tools.Logger.error()

		if html:
			# Clean and decode HTML
			# Eg: "Am&eacute;lie (2001) BDRip 1080p DTS multi HighCode-PHD" -> "Amélie (2001) BDRip 1080p DTS multi HighCode-PHD"
			# Sometimes the ; is missing, remove it manually.
			# Eg: [Extended Collector&quots Cut]
			data = network.Networker.htmlDecode(data).replace('&quot', '\'')

			# Incorrectly formated apostrophe HTML entity.
			# Eg: owca-i-krolowa-lodu-the-huntsman-winter039s-war-2016-extended-pldub-720p-bluray-x264-dts-kit-mkv-mp4
			# Eg: the huntsman: winter&#039;s war (2016) hc - 1080p hdtc - 1 85gb - shaa...
			# Eg: the-huntsman-winter039s-war-2016-plsubbed-720p-web-dl-xvid-ac3-mx-avi-mp4
			# the huntsman winter 039 s war 2016 720p hdcam [mic audio] zi t ctrc  » movies
			data = self._cacheId('cleanBasic3', re.compile, u'([^\d])(?:0|&amp;|&?#)39[\s\;]?s', flags = Stream.ExpressionFlags).sub(r'\1\'s', data)

		# Clean usenet keywords.
		if not usenet is False: data = self.cleanUsenet(data = data, force = usenet is True)

		# Remove brackets enclosing the data.
		# Must be after usenet clean.
		# Eg: (Star Wars. The last Jedi.2017- French)
		# Ignore if only internal brackets:
		# Eg: [LostYears] Demon Slayer: Kimetsu no Yaiba - S01 (BD 1080p Hi10P AAC) [Dual Audio]
		match = self._cacheId('cleanBasic4', re.compile, '^\(([^\(\)]*?)\)$', flags = Stream.ExpressionFlags).search(data)
		if not match:
			match = self._cacheId('cleanBasic5', re.compile, '^\[([^\[\]]*?)\]$', flags = Stream.ExpressionFlags).search(data)
			if not match: match = self._cacheId('cleanBasic6', re.compile, '^\{([^\{\}]*?)\}$', flags = Stream.ExpressionFlags).search(data)
		if match:
			try:
				match = match.group(1)
				if match: data = match
			except: pass

		# Duplicate spaces.
		data = self._cacheId('cleanBasic7', re.compile, '\s+', flags = Stream.ExpressionFlags).sub(' ', data).strip()

		# Custom process function.
		if process: data = process(data)

		return data

	@classmethod
	def cleanKeyword(self, data, exclude = None, encode = True, guidance = None, native = None, split = SplitNone, pack = False, full = True):
		if guidance:
			# We do this:
			#	if dataNew: data = dataNew
			# Since we wang to ignore cuts off to much that nothing is remaining.
			# Eg: If the file name staarts with "Disney ...", the releaseNetwork cleaner will return an empty string. In that case, split the opposite side.
			# Eg: Disney Pixars Ultimate Collection Boxset+Bonus Toy Story 3- dvds to xvid by The_Stig@T.F.R

			splitOpposite = Stream.SplitNone
			if split == Stream.SplitLeft: splitOpposite = Stream.SplitRight
			elif split == Stream.SplitRight: splitOpposite = Stream.SplitLeft

			# Clean show keywords.
			if full:
				dataNew = self.numberShowClean(data = data, exclude = exclude, encode = encode, split = split)
				if dataNew: data = dataNew
				elif not split == splitOpposite: data = self.numberShowClean(data = data, exclude = exclude, encode = encode, split = splitOpposite)

			# Clean video keywords.
			value = guidance['video']['quality']
			if tools.Tools.isDictionary(value): value = [i for i in value.values() if i]
			if value:
				dataNew = self.videoQualityClean(data = data, exclude = exclude, encode = encode, guidance = value, split = split)
				if dataNew: data = dataNew
				elif not split == splitOpposite: data = self.videoQualityClean(data = data, exclude = exclude, encode = encode, guidance = value, split = splitOpposite)
			dataNew = self.videoResolutionClean(data = data, exclude = exclude, encode = encode, split = split)
			if dataNew: data = dataNew
			elif not split == splitOpposite: data = self.videoResolutionClean(data = data, exclude = exclude, encode = encode, split = splitOpposite)
			if guidance['video']['codec']:
				dataNew = self.videoCodecClean(data = data, exclude = exclude, encode = encode, guidance = guidance['video']['codec'], split = split)
				if dataNew: data = dataNew
				elif not split == splitOpposite: data = self.videoCodecClean(data = data, exclude = exclude, encode = encode, guidance = guidance['video']['codec'], split = splitOpposite)
			if guidance['video']['depth']:
				dataNew = self.videoDepthClean(data = data, exclude = exclude, encode = encode, guidance = guidance['video']['depth'], split = split)
				if dataNew: data = dataNew
				elif not split == splitOpposite: data = self.videoDepthClean(data = data, exclude = exclude, encode = encode, guidance = guidance['video']['depth'], split = splitOpposite)
			if guidance['video']['range']:
				dataNew = self.videoRangeClean(data = data, exclude = exclude, encode = encode, guidance = guidance['video']['range'], split = split)
				if dataNew: data = dataNew
				elif not split == splitOpposite: data = self.videoRangeClean(data = data, exclude = exclude, encode = encode, guidance = guidance['video']['range'], split = splitOpposite)
			if guidance['video']['3d']:
				dataNew = self.video3dClean(data = data, exclude = exclude, encode = encode, guidance = guidance['video']['3d'], split = split)
				if dataNew: data = dataNew
				elif not split == splitOpposite: data = self.video3dClean(data = data, exclude = exclude, encode = encode, guidance = guidance['video']['3d'], split = splitOpposite)

			# Clean audio keywords.
			if guidance['audio']['codec']:
				dataNew = self.audioCodecClean(data = data, exclude = exclude, encode = encode, guidance = guidance['audio']['codec'], split = split) # Remove codec first, because channels/system expression also contain the codec.
				if dataNew: data = dataNew
				elif not split == splitOpposite: data = self.audioCodecClean(data = data, exclude = exclude, encode = encode, guidance = guidance['audio']['codec'], split = splitOpposite)
			if guidance['audio']['type']:
				dataNew = self.audioTypeClean(data = data, exclude = exclude, encode = encode, guidance = guidance['audio']['type'], split = split)
				if dataNew: data = dataNew
				elif not split == splitOpposite: data = self.audioTypeClean(data = data, exclude = exclude, encode = encode, guidance = guidance['audio']['type'], split = splitOpposite)
			if guidance['audio']['channels']:
				dataNew = self.audioChannelsClean(data = data, exclude = exclude, encode = encode, guidance = guidance['audio']['channels'], split = split)
				if dataNew: data = dataNew
				elif not split == splitOpposite: data = self.audioChannelsClean(data = data, exclude = exclude, encode = encode, guidance = guidance['audio']['channels'], split = splitOpposite)
			if guidance['audio']['system']:
				dataNew = self.audioSystemClean(data = data, exclude = exclude, encode = encode, guidance = guidance['audio']['system'], split = split)
				if dataNew: data = dataNew
				elif not split == splitOpposite: data = self.audioSystemClean(data = data, exclude = exclude, encode = encode, guidance = guidance['audio']['system'], split = splitOpposite)
			dataNew = self.audioLanguageClean(data = data, exclude = exclude, encode = encode, language = False, native = native, split = split)
			if dataNew: data = dataNew
			elif not split == splitOpposite: data = self.audioLanguageClean(data = data, exclude = exclude, encode = encode, language = False, native = native, split = splitOpposite)

			# Clean subtitle keywords.
			if guidance['subtitle']['type']:
				dataNew = self.subtitleTypeClean(data = data, exclude = exclude, encode = encode, guidance = guidance['subtitle']['type'], split = split)
				if dataNew: data = dataNew
				elif not split == splitOpposite: data = self.subtitleTypeClean(data = data, exclude = exclude, encode = encode, guidance = guidance['subtitle']['type'], split = splitOpposite)
			dataNew = self.subtitleLanguageClean(data = data, exclude = exclude, encode = encode, language = False, native = native, split = split)
			if dataNew: data = dataNew
			elif not split == splitOpposite: data = self.subtitleLanguageClean(data = data, exclude = exclude, encode = encode, language = False, native = native, split = splitOpposite)

			# Clean file keywords.
			dataNew = self.fileSizeClean(data = data, exclude = exclude, encode = encode, split = split)
			if dataNew: data = dataNew
			elif not split == splitOpposite: data = self.fileSizeClean(data = data, exclude = exclude, encode = encode, split = splitOpposite)
			if guidance['file']['container']:
				dataNew = self.fileContainerClean(data = data, exclude = exclude, encode = encode, guidance = guidance['file']['container'], split = split)
				if dataNew: data = dataNew
				elif not split == splitOpposite: data = self.fileContainerClean(data = data, exclude = exclude, encode = encode, guidance = guidance['file']['container'], split = splitOpposite)
			if guidance['file']['pack']:
				dataNew = self.filePackClean(data = data, exclude = exclude, encode = encode, guidance = guidance['file']['pack'], split = Stream.SplitNone if pack else split) # Only remove, but do not split if it is a pack, because the keywords are sometimes in the middle of the name (eg: The Lord of the Rings - Extended Trilogy The Return of the King).
				if dataNew: data = dataNew
				elif not split == splitOpposite: data = self.filePackClean(data = data, exclude = exclude, encode = encode, guidance = guidance['file']['pack'], split = splitOpposite)

			# Clean release keywords.
			if guidance['release']['type']:
				dataNew = self.releaseTypeClean(data = data, exclude = exclude, encode = encode, guidance = guidance['release']['type'], split = split)
				if dataNew: data = dataNew
				elif not split == splitOpposite: data = self.releaseTypeClean(data = data, exclude = exclude, encode = encode, guidance = guidance['release']['type'], split = splitOpposite)
			if guidance['release']['format']:
				dataNew = self.releaseFormatClean(data = data, exclude = exclude, encode = encode, guidance = guidance['release']['format'], split = split)
				if dataNew: data = dataNew
				elif not split == splitOpposite: data = self.releaseFormatClean(data = data, exclude = exclude, encode = encode, guidance = guidance['release']['format'], split = splitOpposite)
			if guidance['release']['edition']:
				dataNew = self.releaseEditionClean(data = data, exclude = exclude, encode = encode, guidance = guidance['release']['edition'], split = Stream.SplitNone if pack else split) # Only remove, but do not split if it is a pack, because the keywords are sometimes in the middle of the name (eg: The Lord of the Rings - Extended Trilogy The Return of the King).
				if dataNew: data = dataNew
				elif not split == splitOpposite: data = self.releaseEditionClean(data = data, exclude = exclude, encode = encode, guidance = guidance['release']['edition'], split = splitOpposite)
			if guidance['release']['network']:
				dataNew = self.releaseNetworkClean(data = data, exclude = exclude, encode = encode, guidance = guidance['release']['network'], split = split)
				if dataNew: data = dataNew
				elif not split == splitOpposite: data = self.releaseNetworkClean(data = data, exclude = exclude, encode = encode, guidance = guidance['release']['network'], split = splitOpposite)
			if full and guidance['release']['group']:
				dataNew = self.releaseGroupClean(data = data, exclude = exclude, encode = encode, guidance = guidance['release']['group'], split = split)
				if dataNew: data = dataNew
				elif not split == splitOpposite: data = self.releaseGroupClean(data = data, exclude = exclude, encode = encode, guidance = guidance['release']['group'], split = splitOpposite)

			# Clean language keywords.
			if full and (guidance['audio']['language'] or guidance['subtitle']['language']):
				languages = []
				if guidance['audio']['language']: languages.extend(guidance['audio']['language'])
				if guidance['subtitle']['language']: languages.extend(guidance['subtitle']['language'])
				data = self.languageClean(data = data, exclude = exclude, encode = encode, guidance = languages, native = native, split = split)
		else:
			# Clean show keywords.
			if full:
				data = self.numberShowClean(data = data, exclude = exclude, encode = encode, split = split)
				if not data: return data

			# Clean video keywords.
			data = self.videoQualityClean(data = data, exclude = exclude, encode = encode, split = split)
			if not data: return data
			data = self.videoResolutionClean(data = data, exclude = exclude, encode = encode, split = split)
			if not data: return data
			data = self.videoCodecClean(data = data, exclude = exclude, encode = encode, split = split)
			if not data: return data
			data = self.videoDepthClean(data = data, exclude = exclude, encode = encode, split = split)
			if not data: return data
			data = self.videoRangeClean(data = data, exclude = exclude, encode = encode, split = split)
			if not data: return data
			data = self.video3dClean(data = data, exclude = exclude, encode = encode, split = split)
			if not data: return data

			# Clean audio keywords.
			data = self.audioCodecClean(data = data, exclude = exclude, encode = encode, split = split) # Remove codec first, because channels/system expression also contain the codec.
			if not data: return data
			data = self.audioTypeClean(data = data, exclude = exclude, encode = encode, split = split)
			if not data: return data
			data = self.audioChannelsClean(data = data, exclude = exclude, encode = encode, split = split)
			if not data: return data
			data = self.audioSystemClean(data = data, exclude = exclude, encode = encode, split = split)
			if not data: return data
			data = self.audioLanguageClean(data = data, exclude = exclude, encode = encode, language = False, native = native, split = split)
			if not data: return data

			# Clean subtitle keywords.
			data = self.subtitleTypeClean(data = data, exclude = exclude, encode = encode, split = split)
			if not data: return data
			data = self.subtitleLanguageClean(data = data, exclude = exclude, encode = encode, language = False, native = native, split = split)
			if not data: return data

			# Clean file keywords.
			data = self.fileSizeClean(data = data, exclude = exclude, encode = encode, split = split)
			if not data: return data
			data = self.fileContainerClean(data = data, exclude = exclude, encode = encode, split = split)
			if not data: return data
			data = self.filePackClean(data = data, exclude = exclude, encode = encode, split = Stream.SplitNone if pack else split) # Only remove, but do not split if it is a pack, because the keywords are sometimes in the middle of the name (eg: The Lord of the Rings - Extended Trilogy The Return of the King).
			if not data: return data

			# Clean release keywords.
			data = self.releaseTypeClean(data = data, exclude = exclude, encode = encode, split = split)
			if not data: return data
			data = self.releaseFormatClean(data = data, exclude = exclude, encode = encode, split = split)
			if not data: return data
			data = self.releaseEditionClean(data = data, exclude = exclude, encode = encode, split = Stream.SplitNone if pack else split) # Only remove, but do not split if it is a pack, because the keywords are sometimes in the middle of the name (eg: The Lord of the Rings - Extended Trilogy The Return of the King).
			if not data: return data
			data = self.releaseNetworkClean(data = data, exclude = exclude, encode = encode, split = split)
			if not data: return data

			# Clean language keywords.
			if full:
				data = self.languageClean(data = data, exclude = exclude, encode = encode, native = native, split = split)
				if not data: return data

			# Clean release keywords.
			if full: data = self.releaseGroupClean(data = data, exclude = exclude, encode = encode, split = split) # Do last, since ity takes the longest. Reduce the length of data.

		return data

	@classmethod
	def cleanOther(self, data, ignore = None, file = True, titles = None):
		# Remove special trailing word.
		# Eg: toy-story-3/movdivx
		match = self._cacheId('cleanOther0', re.compile, '(?:[a-z\d]+[\-\–\_\.])+(?:[a-z\d])?(\/[a-z\d]+$)', flags = Stream.ExpressionFlags).search(data)
		if match: data = data.replace(match.groups(1)[0], '')

		# Apostrophes gone wrong.
		# The Huntsman: WinterâEUR(TM)s War (2016) 1080p HC HDRip 1 9GB - MkvCage
		# The Huntsman: Winterâ?(TM)s War (2016) 1080p HC HDRip 1.9GB - MkvCage
		# The Huntsman: Winterâ(TM)s War (2016) 1080p WEB-DL 1.9GB - MkvCage Movies - Action
		data = self._cacheId('cleanOther1', re.compile, r'â(eur|.)\(tm\)', flags = Stream.ExpressionFlags).sub('', data)

		# Leading 18+.
		# 18+ Deadpool 2016 Movies HDCam XviD New Clean Audio +Sample ?rDX
		data = self._cacheId('cleanOther2', re.compile, '^18\+', flags = Stream.ExpressionFlags).sub('', data)

		if file:
			# Remove Polish audio/sub indicators.
			data = self._cacheId('cleanOther3', re.compile, '((?:lektor|napisy)' + Stream.ExpressionSymbolStart + 'pl' + Stream.ExpressionSymbolEnd + ')', flags = Stream.ExpressionFlags).sub('', data)

			# Remove leading domain names.
			prefix = '^' + Stream.ExpressionSymbol + '*(?:access|acesse)?' + Stream.ExpressionSymbol + '*'
			data = self._cacheId('cleanOther4', re.compile, prefix + '([\[\(\{]\s*([a-z0-9\-\–]+\.){1,2}[a-z0-9]{2,5}\s*[\]\)\}]' + Stream.ExpressionSymbol + '*@?)', flags = Stream.ExpressionFlags).sub('', data) # (ilmiotorrent.netsons.org).Avatar.2009.iTALiAN.MD.DVDRip.XViD-TH
			data = self._cacheId('cleanOther5', re.compile, prefix + '(w{2}[w\d]\.([a-z0-9\-\–]+\.){1,2}[a-z0-9]{2,5}' + Stream.ExpressionSymbol + '*@?)', flags = Stream.ExpressionFlags).sub('', data) #  www.Scenetime.com - Star Trek Picard S01E02 iNTERNAL 1080p HEVC x265-MeGusta
			data = self._cacheId('cleanOther6', re.compile, prefix + '(w{2}[w\d]\s([a-z0-9\-\–]+\s)[a-z0-9]{2,3}' + Stream.ExpressionSymbol + '*@?)', flags = Stream.ExpressionFlags).sub('', data) # www Scenetime com - Star Trek Picard S01E02 iNTERNAL 1080p HEVC x265-MeGusta
			data = self._cacheId('cleanOther7', re.compile, prefix + '(([a-z0-9]+(?:\-\–[a-z0-9]+)?\.)(com|net|org|xyz|eu|us|cc|co|to|co\.uk|nl|de|pl|pe|es|jp)' + Stream.ExpressionSymbol + '*@?)(?:@|' + Stream.ExpressionSymbol + ')', flags = Stream.ExpressionFlags).sub('', data) # (only do this for common TLD): TamilRockers.com - The Huntsman Winters War (2016) English 720p HDRip x264 ESubs 850MB
			data = self._cacheId('cleanOther8', re.compile, prefix + '([a-z0-9]+[\.\-\–\_\s](com|net|org|co\.uk)' + Stream.ExpressionSymbol + '*@?)(?:@|' + Stream.ExpressionSymbol + ')', flags = Stream.ExpressionFlags).sub('', data) # (only do this for common TLD): TamilRockers.com - The Huntsman Winters War (2016) English 720p HDRip x264 ESubs 850MB

			# Remove long leading numbers and timestamps.
			# Eg: 152369_-1623594926-Dune--BDremux
			data = self._cacheId('cleanOther9', re.compile, '^(\d{6,}[\s\-\–\_\.\,]+)+', flags = Stream.ExpressionFlags).sub('', data)

			# Remove any uploader names. Do after domains, since uploader can also appear in the domain (eg: tamilrockers.lu).
			# Eg: TwoDDL_Wonder.2017.1080.WEB-DL.DD5.1.H264-CMRG.mkv
			# Eg: [SSR Movies - Avatar (2009) EXTENDED Dual Audio [Hindi 2 0 - English 2 0] 720p BluRay x264 1.4GB ESubs]
			data = self._cacheId('cleanOther10', re.compile, '(twoddl|(?:twoddl[\-\–\_\.]*)?veto|tamilrockers|hdfree4u|downloadhub|extramovies|torrents?\d*|ssr[\-\–\_\.\s]*movies?)(?:\.(?:com|net|org|xyz|eu|us|cc|co|to|io|co\.uk|nl|de|pl|pe|es|jp|click|wiki|red))?', flags = Stream.ExpressionFlags).sub('', data)

			# Remove leading keywords or numbers.
			# Eg: cocain-candyman.2021.bdrip.x264.mkv
			# Eg: blow-candyman.2021.720p.bluray.x264.www.RapidMovieZ.com.mkv [2.70 GB]]
			# Eg: 4Candyman 2021 720p WEBRip x264-MaxRls.mkv
			# Eg: 09. Star Wars The Last Jedi (2017)
			# Do not cut an actual number in the title.
			# Eg: 3 Days of Darkness (Pinoy Indie Film 2007) XViD DVDRip-RiZAL
			if titles:
				expression = self._cacheId('cleanOther11', re.compile, '^\s*' + Stream.ExpressionSymbol + '*(cocain|blow|heroin|0\d{1,2}|\d{3,}|(?<!\d)\d{1,2}(?!' + Stream.ExpressionSeparatorBasic + '))', flags = Stream.ExpressionFlags)
				found = False
				for title in titles:
					match = expression.search(title)
					if match and match.group(1):
						found = True
						break
				if not found: data = expression.sub('', data)

		# Remove leading bracket words.
		# [Hakata Ramen] Star Trek Picard S01E02 CBS Web-Dl 1080p x265~GodZilla
		data = self._cacheId('cleanOther12', re.compile, '^([\[\(\{][\s\.\-\–\_a-z0-9]+[\]\)\}])', flags = Stream.ExpressionFlags).sub('', data)

		if file:
			# Remove weird leading bracket words, mostly used in Chinese names.
			# Eg: 【更多高清电影访问 】一九八四 1984[简繁双语字幕] Nineteen Eighty-Four 1984 CC BluRay 1080p LPCM 1 0 x264-BB ...
			# Eg: 【更多高清电影访问 www.BBQDDQ.com】一九八四 1984[简繁双语字幕].Nineteen.Eighty-Four.1984.CC.BluRay.1080p.LPCM.1.0.x264-BBQDDQ 14.13 GB
			data = self._cacheId('cleanOther13', re.compile, '^(【.*?】\s*一?)', flags = Stream.ExpressionFlags).sub('', data)

			# Remove usenet keywords.
			data = self.cleanUsenet(data)

		# Remove fractions.
		# Eg:  ç²¾ç?µæ--...ç¤¾3 ç-¯ç<,å??æoe? Hotel Transylvania 3 Summer Vacation 2018 1080p-å¤©å¤©ç¾?å?§ ...
		try: data = self._cacheId('cleanOther14', re.compile, r"[\u00BC-\u00BE\u2150-\u215E]").sub(' ', data)
		except: pass

		# Replace apostrophes with empty instead of space.
		data = self._cacheId('cleanOther15', re.compile, '[\'`]', flags = Stream.ExpressionFlags).sub('', data)

		# Remove special characters.
		# Do not use [^\w\d], since it removes unicode alpha characters.
		# \p is not supported in Python's re module.
		# Use Python's builtin function instead.
		#data = self._cacheId('cleanOther16', re.compile, '[^\w\d]', flags = Stream.ExpressionFlags).sub(' ', data)
		#data = self._cacheId('cleanOther16', re.compile, '[^\p{L}|\p{N}|\p{Z}{2,}|\s]+', flags = Stream.ExpressionFlags).sub(' ', data)
		data = self._cacheId('cleanOther16', re.compile, Stream.ExpressionSymbol, flags = Stream.ExpressionFlags).sub(' ', data)

		data = tools.Tools.replaceNotAlphaNumeric(data = data, replace = ' ')

		# Remove ignore keywords.
		if ignore: data = self.cleanIgnore(data = data, ignore = ignore)

		# Remove duplicate spaces.
		data = self._cacheId('cleanOther17', re.compile, '\s+', flags = Stream.ExpressionFlags).sub(' ', data).strip()

		# Lower case.
		data = data.lower()

		return data

	@classmethod
	def cleanIgnore(self, data, ignore = True):
		if ignore is True:
			ignore = ['(%s)' % i for i in Stream.ExpressionIgnore]
			id = 'all'
		elif ignore:
			id = ignore # Important, otherwise incorrect cached expressions are used in _expressionReplace (eg: "original" and "series" are filtered from "Star Trek The Original Series" although they are not in the ignore list passed to this function).
		return self._expressionReplace(id = 'cleanIgnore_' + tools.Converter.unicode(id), data = data, expression = ignore)

	@classmethod
	def cleanSplit(self, data, single = True, number = True):
		data = data.lower()
		data = re.sub(Stream.ExpressionSymbolAlternative, ' ', data, flags = Stream.ExpressionFlags)
		data = data.split()
		data = [i for i in data if i and (not number or not i.isdigit())]
		if single is True: data = [i for i in data if len(i) > 1]
		elif tools.Tools.isArray(single): data = [i for i in data if len(i) > 1 or i in single]
		return data

	@classmethod
	def cleanEncode(self, data):
		if data:
			if tools.Tools.isTuple(data):
				data = list(data)
			if tools.Tools.isList(data):
				#data = tools.Tools.copy(data)
				for i in range(len(data)):
					try: data[i] = data[i].decode('utf-8')
					except: pass
			else:
				try: data = data.decode('utf-8')
				except: pass
		return data

	# Cleans the filename from usenet metadata/labels.
	@classmethod
	def cleanUsenet(self, data, force = False):
		if data and (force or self._cacheId('cleanUsenet1', re.compile, Stream.ExpressionUsenetName, flags = Stream.ExpressionFlags).search(data)):
			threshold = Stream.Threshold['filename'] * len(data)

			# Leading NZB part numbers.
			# Eg: [001/102] - "Wonder.2017.720p.BluRay.HebSubs.x264-GECKOS.par2" yEnc
			# NB: do not end with ".*$" (without quotes), because otherwise PHP removes the ENTIRE end part of the string (although other regex editors do not do it.):
			# Eg: [02/21] - "Star.Trek.Discovery.S01E01.The.Vulcan.Hello.1080p.NF.WEB-DL.DD5.1.x264-AJP69.part01.rar" - 1.22 GB - yEnc
			# NB: Also remove the trailing ".*$" from other string-removals, since they have thtee same problem (eg: domain removal).
			# Also remove everything before the NZB part numbers. Only do this if it appears in the first half of the string.
			# Eg:  Crionics Post buS LN 01-6 562x.1.5.piRRB.p0801.2.nosaeS.dlrowtseW[01/36] - "Westworld.Season.2.1080p.BRRip.5.1.x265 6-10 NL Sub.par2" yEnc
			# Eg: Westworld.S02E09.German.Dubbed.WEB.x264-ATAX - "59306846fb5f4893f286f3e4e9.nfo" - (01/14) yEnc
			# Use one of the following: [xxx/xxx], [x{1,3}], [x{5,}], otherwise years are matched.
			# Eg: Westworld (2016) Season 2 S02 (1080p AMZN WEB-DL x265 HEVC 10bit AAC 5 1 ...
			# For long titles it can appear in thte first half, for short titles in the first third.
			# Eg: Toy Story Trilogy (1995-2010) [TnT24.Info]
			# Eg: Titanic (1997/2012) *3D+2D* [Bluray - Untouched] [2xBD-50]
			# Eg: Crionics Post buS LN 01-6 562x.1.5.piRRB.p0801.2.nosaeS.dlrowtseW[01/36] - "Westworld.Season.2.1080p.BRRip.5.1.x265 6-10 NL Sub.par2" yEnc
			# Ignore single numbers.
			# Eg: Lost S01E01 Pilot (1) by KnightHiryuu [h33t] [KnightHiryuu] » TV shows'
			# (?!\d\-\d) to ignore collections.
			# Eg: Toy Story (1-3)1080p BluRay Collection

			data = data.strip()

			# Remove duplicate filenames.
			# Game.of.Thrones.S08.E05.1080pWEB-DL.AVi.H.264-UNVEiL - [02/70] - "Game.of.Thrones.S08.E05.1080pWEB-DL.AVi.H.264-UNVEiL.part01.rar" yEnc (1/41)
			# Game.of.Thrones.S08.E05.1080pWEB-DL.AVi.H.264-MASON [02/70] - "Game.of.Thrones.S08.E05.1080pWEB-DL.AVi.H.264-MASON.part01.rar" yEnc (1/41)
			match = self._cacheId('cleanUsenet2', re.compile, u'(.+?)(?:%s|%s)*"(\\1+.*?)(?:%s)?"' % (Stream.ExpressionUsenetSeparator, Stream.ExpressionUsenetNumber, Stream.ExpressionUsenetExtension), flags = Stream.ExpressionFlags).search(data)
			if match:
				match = match.groups(1)
				if match:
					# Prefer longer parts.
					match = sorted(match, key = len)
					match.reverse()
					for part in match:
						if part and len(part) > threshold:
							data = part.strip()
							break

			# Extract from quotes.
			# Must be after duplicate removal.
			# Only do it if the remaining parts are small enough
			# [00/10] - "Game.of.Thrones.S08E05.1080p.WEB.x264-ADRENALiNE[ettv].part0.nzb" yEnc (1/1)
			match = self._cacheId('cleanUsenet3', re.compile, Stream.ExpressionUsenetQuotes, flags = Stream.ExpressionFlags).search(data)
			if match:
				match = match.groups(1)[0]
				if match and len(match) > threshold and len(data.replace(match, '')) < (len(match) * 1.2): data = match

			# Remove prefix.
			data = self._cacheId('cleanUsenet4', re.compile, u'^(%s%s*)' % (Stream.ExpressionUsenetNumber, Stream.ExpressionUsenetSeparator), flags = Stream.ExpressionFlags).sub('', data)

			# Remove other leading stuff.
			data = self._cacheId('cleanUsenet5', re.compile, '^' + Stream.ExpressionSymbol + '*([\[\(\{]full[\]\)\}])', flags = Stream.ExpressionFlags).sub('', data,) # [FULL]-[#a.b.moovee@EFNet]-[ The.Huntsman.Winters.War.2016.NTSC.DVDR-JFKDVD ]-[001/120] "huntsman.ww.jfkdvd.nfo" yEnc
			data = self._cacheId('cleanUsenet6', re.compile, '^' + Stream.ExpressionSymbol + '*([\[\(\{].*?@.*?[\]\)\}])', flags = Stream.ExpressionFlags).sub('', data) # [FULL]-[#a.b.moovee@EFNet]-[ The.Huntsman.Winters.War.2016.NTSC.DVDR-JFKDVD ]-[001/120] "huntsman.ww.jfkdvd.nfo" yEnc

			# Remove non-duplicate quotes.
			match = self._cacheId('cleanUsenet7', re.compile, u'^%s(?:$|%s*(?:%s))' % (Stream.ExpressionUsenetQuotes, Stream.ExpressionUsenetSeparator, u'|'.join([Stream.ExpressionUsenetYenc, Stream.ExpressionUsenetNumber, Stream.ExpressionUsenetSize])), flags = Stream.ExpressionFlags).search(data)
			if match: data = match.groups(1)[0]

			# Remove suffix.
			data = self._cacheId('cleanUsenet8', re.compile, u'(%s*(?:%s))+' % (Stream.ExpressionUsenetSeparator, u'|'.join([Stream.ExpressionUsenetYenc, Stream.ExpressionUsenetNumber, Stream.ExpressionUsenetSize, Stream.ExpressionUsenetFile])), flags = Stream.ExpressionFlags).sub('', data)

			# Remove extension.
			data = self._cacheId('cleanUsenet9', re.compile, u'(%s)$' % Stream.ExpressionUsenetExtension, flags = Stream.ExpressionFlags).sub('', data)

			# Strip separators.
			data = self._cacheId('cleanUsenet10', re.compile, u'^%s+' % (Stream.ExpressionUsenetSeparator), flags = Stream.ExpressionFlags).sub('', data)
			data = self._cacheId('cleanUsenet11', re.compile, u'%s+$' % (Stream.ExpressionUsenetSeparator2), flags = Stream.ExpressionFlags).sub('', data) # Do not strip ... from end of file name.

			# Strip brackets.
			match = self._cacheId('cleanUsenet12', re.compile, u'^%s*\[%s*(.+?)%s*\]%s*$' % (Stream.ExpressionUsenetSeparator, Stream.ExpressionUsenetSeparator, Stream.ExpressionUsenetSeparator, Stream.ExpressionUsenetSeparator), flags = Stream.ExpressionFlags).search(data)
			if match: data = match.groups(1)[0]

		return data

	##############################################################################
	# LABEL
	##############################################################################

	@classmethod
	def labelNumber(self, value, separator = False, format = FormatDecorate, label = LabelSettings):
		label = self.settingsLayout(label, Manager.CategoryGeneral, Manager.AttributeNumber)
		if label == Stream.LabelHidden: return ''
		if not value: value = 0
		if label == Stream.LabelShort: layout = '%d'
		elif label == Stream.LabelMedium: layout = '%01d'
		elif label == Stream.LabelLong: layout = '%03d'
		value = layout % value
		value = self._decorate(value = value, format = format, bold = True)
		if separator: value += self.labelSeparator()
		return value

	def labelSingle(self, duration = None, format = FormatDecorate, label = LabelSettings):
		return self._labelProcess([
			self.videoQuality(label = label, format = format),
			self.sourceType(label = label, format = format),
			self.accessType(label = label, format = format, account = True, exclusive = True),
			self.accessUsage(label = label, format = format),
			self.filePack(label = label, format = format),
			self.releaseEdition(label = label, format = format),

			self.infoCustom(label = label, format = format),

			self.exclusionFormat(label = label, format = format),
			self.exclusionSupport(label = label, format = format),
			self.exclusionMetadata(label = label, format = format),
			self.exclusionBlocked(label = label, format = format),
			self.exclusionFake(label = label, format = format),
			self.exclusionRelease(label = label, format = format),
			self.exclusionKeyword(label = label, format = format, exception = True),
			self.exclusionDuplicate(label = label, format = format),
			self.exclusionCaptcha(label = label, format = format),
			self.exclusionPrecheck(label = label, format = format),

			self.sourceOrigin(label = label, format = format, orion = True),
			self.sourceProvider(label = label, format = format),
			self.sourcePublisher(label = label, format = format, same = False) if self.sourceTypeHoster() else None, # Only do this for hosters, otherwise it will show the domain of mirror sites.
			self.sourceHoster(label = label, format = format, same = False) if not self.sourceTypePremium() else None, # Do not show Premiumize subservers.

			self.videoCodec(label = label, format = format),
			self.videoRange(label = label),
			self.videoDepth(label = label),
			self.video3d(label = label, format = format),

			self.audioChannels(label = label),
			self.audioCodec(label = label, system = True),
			self.audioType(label = label, format = format, original = False),
			self.audioLanguage(label = label, format = format, sort = True),

			self.subtitleType(label = label, format = format),
			self.subtitleLanguage(label = label, format = format, sort = True),

			self.fileBandwidth(label = label, format = format, duration = duration),
			self.fileSize(label = label, format = format, duration = duration),

			self.sourcePeers(label = label, format = format),
			self.sourceTime(label = label, format = format, time = Stream.TimeDuration, new = True),
			self.sourcePopularity(label = label, format = format),

			self.releaseType(label = label, format = format),
			self.releaseFormat(label = label, format = format),
			self.releaseNetwork(label = label, format = format),
			self.releaseGroup(label = label, format = format),
			self.releaseUploader(label = label, format = format),
			self.fileContainer(label = label, format = format)

		], format = format, fill = False)

	def labelTop(self, duration = None, format = FormatDecorate, label = LabelSettings):
		return self._labelProcess([
			self.videoQuality(label = label, format = format),
			self.sourceType(label = label, format = format),

			self.infoCustom(label = label, format = format),

			self.exclusionFormat(label = label, format = format),
			self.exclusionSupport(label = label, format = format),
			self.exclusionMetadata(label = label, format = format),
			self.exclusionBlocked(label = label, format = format),
			self.exclusionFake(label = label, format = format),
			self.exclusionRelease(label = label, format = format),
			self.exclusionKeyword(label = label, format = format, exception = True),
			self.exclusionDuplicate(label = label, format = format),
			self.exclusionCaptcha(label = label, format = format),
			self.exclusionPrecheck(label = label, format = format),

			self.sourceOrigin(label = label, format = format, orion = True),
			self.sourceProvider(label = label, format = format),
			self.sourcePublisher(label = label, format = format, same = False) if self.sourceTypeHoster() else None, # Only do this for hosters, otherwise it will show the domain of mirror sites.,
			self.sourceHoster(label = label, format = format, same = False) if not self.sourceTypePremium() else None, # Do not show Premiumize subservers.

			self.fileBandwidth(label = label, format = format, duration = duration),
			self.fileSize(label = label, format = format, duration = duration),

			self.sourcePeers(label = label, format = format),
			self.sourceTime(label = label, format = format, time = Stream.TimeDuration, new = True),
			self.sourcePopularity(label = label, format = format),
		], format = format, fill = False)

	def labelBottom(self, format = FormatDecorate, label = LabelSettings):
		return self._labelProcess([
			self.accessType(label = label, format = format, account = True, exclusive = True),
			self.accessUsage(label = label, format = format),
			self.filePack(label = label, format = format),
			self.releaseEdition(label = label, format = format),

			self.videoCodec(label = label, format = format),
			self.videoRange(label = label),
			self.videoDepth(label = label),
			self.video3d(label = label, format = format),

			self.audioChannels(label = label),
			self.audioCodec(label = label, system = True),
			self.audioType(label = label, format = format, original = False),
			self.audioLanguage(label = label, format = format, sort = True),

			self.subtitleType(label = label, format = format),
			self.subtitleLanguage(label = label, format = format, sort = True),

			self.releaseType(label = label, format = format),
			self.releaseFormat(label = label, format = format),
			self.releaseNetwork(label = label, format = format),
			self.releaseGroup(label = label, format = format),
			self.releaseUploader(label = label, format = format),
			self.fileContainer(label = label, format = format)
		], format = format, fill = False)

	def labelExclusion(self, custom = True, format_ = True, support = True, metadata = True, blocked = True, fake = True, release = True, keyword = True, duplicate = True, captcha = True, precheck = True, format = FormatDecorate, label = LabelSettings):
		return self._labelProcess([
			self.infoCustom(label = label, format = format) if custom else None,
			self.exclusionFormat(label = label, format = format) if format_ else None,
			self.exclusionSupport(label = label, format = format) if support else None,
			self.exclusionMetadata(label = label, format = format) if valid else None,
			self.exclusionBlocked(label = label, format = format) if blocked else None,
			self.exclusionFake(label = label, format = format) if fake else None,
			self.exclusionRelease(label = label, format = format, exception = True) if release else None,
			self.exclusionKeyword(label = label, format = format) if keyword else None,
			self.exclusionDuplicate(label = label, format = format) if duplicate else None,
			self.exclusionCaptcha(label = label, format = format) if captcha else None,
			self.exclusionPrecheck(label = label, format = format) if precheck else None,
		], format = format)

	def labelSource(self, origin = True, provider = True, publisher = True, hoster = True, exclusion = False, custom = False, format_ = True, support = True, metadata = True, blocked = True, fake = True, release = True, keyword = True, duplicate = True, captcha = True, precheck = True, extra = None, format = FormatDecorate, label = LabelSettings):
		return self._labelProcess([
			extra if extra else None,
			self.sourceOrigin(label = label, format = format, orion = True),
			self.sourceProvider(label = label, format = format) if provider else None,
			self.sourcePublisher(label = label, format = format, same = False) if publisher and self.sourceTypeHoster() else None, # Only do this for hosters, otherwise it will show the domain of mirror sites.
			self.sourceHoster(label = label, format = format, same = False) if hoster and not self.sourceTypePremium() else None, # Do not show Premiumize subservers.

			self.infoCustom(label = label, format = format) if not extra is None and custom else None,

			self.exclusionFormat(label = label, format = format) if not extra is None and exclusion and format_ else None,
			self.exclusionSupport(label = label, format = format) if not extra is None and exclusion and support else None,
			self.exclusionMetadata(label = label, format = format) if not extra is None and exclusion and metadata else None,
			self.exclusionBlocked(label = label, format = format) if not extra is None and exclusion and blocked else None,
			self.exclusionFake(label = label, format = format) if not extra is None and exclusion and fake else None,
			self.exclusionRelease(label = label, format = format) if not extra is None and exclusion and release else None,
			self.exclusionKeyword(label = label, format = format, exception = False) if not extra is None and exclusion and keyword else None,
			self.exclusionDuplicate(label = label, format = format) if not extra is None and exclusion and duplicate else None,
			self.exclusionCaptcha(label = label, format = format) if not extra is None and exclusion and captcha else None,
			self.exclusionPrecheck(label = label, format = format) if not extra is None and exclusion and precheck else None,
		], format = format)

	def labelAccess(self, access = True, usage = True, label = LabelSettings, format = FormatDecorate):
		return self._labelProcess([
			self.accessType(label = label, format = format, account = True, exclusive = False) if access else None,
			self.accessUsage(label = label, format = format) if usage else None,
		], format = format)

	def labelType(self, source = True, access = True, usage = True, label = LabelSettings, format = FormatDecorate):
		return self._labelProcess([
			self.sourceType(label = label, format = format) if source else None,
			self.accessType(label = label, format = format, account = True, exclusive = True) if access else None,
			self.accessUsage(label = label, format = format) if usage else None,
		], format = format)

	def labelRelease(self, pack = True, exclusion = True, edition = True, type = True, custom = True, format_ = True, network = True, group = True, uploader = True, container = True, format = FormatDecorate, label = LabelSettings):
		return self._labelProcess([
			self.filePack(label = label, format = format) if pack else None,

			self.infoCustom(label = label, format = format) if custom else None,

			self.exclusionFormat(label = label, format = format) if exclusion else None,
			self.exclusionSupport(label = label, format = format) if exclusion else None,
			self.exclusionMetadata(label = label, format = format) if exclusion else None,
			self.exclusionBlocked(label = label, format = format) if exclusion else None,
			self.exclusionFake(label = label, format = format) if exclusion else None,
			self.exclusionRelease(label = label, format = format) if exclusion else None,
			self.exclusionKeyword(label = label, format = format, exception = False) if exclusion else None,
			self.exclusionDuplicate(label = label, format = format) if exclusion else None,
			self.exclusionCaptcha(label = label, format = format) if exclusion else None,
			self.exclusionPrecheck(label = label, format = format) if exclusion else None,

			self.releaseEdition(label = label, format = format) if edition else None,
			self.releaseFormat(label = label, format = format) if format_ else None,
			self.releaseType(label = label, format = format) if type else None,
			self.releaseNetwork(label = label, format = format) if network else None,
			self.fileContainer(label = label, format = format) if container else None,
			self.releaseGroup(label = label, format = format) if group else None,
			self.releaseUploader(label = label, format = format) if uploader else None,
		], format = format)

	def labelVideo(self, quality = True, codec = True, _3d = True, _3dPlain = False, range = True, depth = True, format = FormatDecorate, label = LabelSettings):
		return self._labelProcess([
			self.videoQuality(label = label, format = format) if quality else None,
			self.videoCodec(label = label, format = format) if codec else None,
			self.videoRange(label = label) if range else None,
			self.videoDepth(label = label) if depth else None,
			(self.video3d(label = Stream.LabelShort, format = Stream.FormatBold) if _3dPlain else self.video3d(label = label, format = format)) if _3d else None,
		], format = format)

	def labelLanguage(self, language = True, label = LabelSettings, format = FormatDecorate):
		return self._labelProcess([
			self.language(label = label, format = format, sort = True) if language else None,
		], format = format)

	def labelAudio(self, channels = True, codec = True, type = True, language = True, format = FormatDecorate, label = LabelSettings):
		return self._labelProcess([
			self.audioChannels(label = label) if channels else None,
			self.audioCodec(label = label, system = True) if codec else None,
			self.audioType(label = label, format = format, original = False) if type else None,
			self.audioLanguage(label = label, format = format, sort = True) if language else None,
		], format = format)

	def labelSubtitle(self, type = True, language = True, label = LabelSettings, format = FormatDecorate):
		return self._labelProcess([
			self.subtitleType(label = label, format = format) if type else None,
			self.subtitleLanguage(label = label, format = format, sort = True) if language else None,
		], format = format)

	def labelSize(self, bandwidth = True, size = True, duration = None, format = FormatDecorate, label = LabelSettings):
		return self._labelProcess([
			self.fileSize(label = label, format = format, duration = duration) if size else None,
		], format = format)

	def labelBandwidth(self, bandwidth = True, size = True, duration = None, format = FormatDecorate, label = LabelSettings):
		label = [
			self.fileBandwidth(label = label, format = format, duration = duration) if bandwidth else None,
			self.fileSize(label = label, format = format, duration = duration) if size else None,
		]
		label = [i for i in label if i]
		if label: label = label[:1] # Only pick one
		return self._labelProcess(label, format = format)

	def labelPeers(self, peers = True, format = FormatDecorate, label = LabelSettings):
		return self._labelProcess([
			self.sourcePeers(label = label, format = format) if peers else None,
		], format = format)

	def labelSeeds(self, seeds = True, format = FormatDecorate, label = LabelSettings):
		return self._labelProcess([
			self.sourceSeeds(label = label, format = format) if seeds else None,
		], format = format)

	def labelLeeches(self, leeches = True, format = FormatDecorate, label = LabelSettings):
		return self._labelProcess([
			self.sourceLeeches(label = label, format = format) if leeches else None,
		], format = format)

	def labelTime(self, time = True, new = True, format = FormatDecorate, label = LabelSettings):
		return self._labelProcess([
			self.sourceTime(label = label, format = format, time = Stream.TimeDuration, new = new) if time else None,
		], format = format)

	def labelPopularity(self, popularity = True, format = FormatDecorate, label = LabelSettings):
		return self._labelProcess([
			self.sourcePopularity(label = label, format = format) if popularity else None,
		], format = format)

	@classmethod
	def labelSeparator(self, bold = True, color = True, format = None):
		def _labelSeparator(bold, color, format):
			if format:
				bold = format == Stream.FormatDecorate or format == Stream.FormatBold
				color = format == Stream.FormatDecorate or format == Stream.FormatColor
			return interface.Format.font(interface.Format.iconSeparator(color = False, pad = True), bold = bold, color = interface.Format.colorDisabled() if color else None, translate = False)
		return self._cache(_labelSeparator, bold = bold, color = color, format = format)

	@classmethod
	def _labelFill(self, value = None, bold = True, color = True):
		def __labelFill(bold, color):
			return interface.Format.font(interface.Format.iconSeparator(color = False, pad = False) * 5, bold = bold, color = interface.Format.colorDisabled() if color else None, translate = False)
		if value: return value
		else: return self._cache(__labelFill, bold = bold, color = color)

	@classmethod
	def _labelSeparate(self, items = None, bold = True, color = True):
		separator = self.labelSeparator(bold = bold, color = color)
		if items:
			result = []
			for item in items:
				if item:
					if tools.Tools.isArray(item): result.extend(item)
					else: result.append(item)
			return separator.join(result)
		else: return items

	@classmethod
	def _labelProcess(self, items, format = FormatDecorate, fill = True):
		bold = format == Stream.FormatDecorate or format == Stream.FormatBold
		color = format == Stream.FormatDecorate or format == Stream.FormatColor
		value = self._labelSeparate(items = items, bold = bold, color = color)
		if fill and not value: value = self._labelFill(value = value, bold = bold, color = color)
		return value

	@classmethod
	def _label(self, value, values = None, default = None, format = FormatNone, label = LabelNone, prefix = None, suffix = None, single = False, process = False, separator = None, color = None):
		try:
			def __label(value, values, label, prefix, suffix, single, process = False, separator = None, color = None):
				try:
					if label == Stream.LabelForce: label = values[Stream.LabelDefault][Layout.settingsInterface()]
					if label == Stream.LabelHidden: return None # Not elif, since LabelForce could return LabelHidden.

					if not value is None:
						if tools.Tools.isArray(value):
							if single and (prefix or suffix): value = ''
							elif values:
								if color: value = (separator if not separator is None else '' if label == Stream.LabelShort else '-').join([interface.Format.fontColor(values[i][label], color = color.get(i)) for i in value])
								else: value = (separator if not separator is None else '' if label == Stream.LabelShort else '-').join([values[i][label] for i in value])
							else: value = (separator if not separator is None else '' if label == Stream.LabelShort else '-').join(value)
						elif values:
							value = values[value][label]

					if process:
						if process is True: value = ''.join(i for i in value if i.isalnum())
						else: value = ''.join(i for i in value if i.isalnum() or i in process)
						if label in Stream.LabelLength: value = value[:Stream.LabelLength[label]]
						value = value.capitalize()

					if color:
						if prefix: value = prefix + (('-' + value) if value else '')
						if suffix: value = ((value + '-') if value else '') + suffix
					else:
						if prefix: value = prefix + (((' ' if (' ' in value or ' ' in prefix) else '-') + value) if value else '')
						if suffix: value = ((value + (' ' if (' ' in value or ' ' in prefix) else '-')) if value else '') + suffix

					return value
				except:
					tools.Logger.error()

			if not format == Stream.FormatKodi and not label == Stream.LabelNone:
				if separator is None: separator = ', ' if label == Stream.LabelDetails else None
				if (values or default) and label == Stream.LabelDetails:
					info = []
					if not default: default = values
					default = default[Stream.LabelDefault]
					for i in [Stream.LabelInfo1, Stream.LabelInfo2]:
						if default[i]:
							info.append(__label(value = value, values = values, label = default[i], prefix = prefix, suffix = suffix, single = single, process = process, separator = separator, color = color))
					value = ''
					info = [i for i in info if i]
					length = len(info)
					if length >= 1: value += info[0]
					if length >= 2: value += ' (' + info[1] + ')'
				else:
					value = __label(value = value, values = values, label = label, prefix = prefix, suffix = suffix, single = single, process = process, separator = separator, color = color)
			return value
		except:
			tools.Logger.error()
			return ''

	@classmethod
	def _labelDomain(self, value, label = LabelNone):
		if not label == Stream.LabelNone and value and '.' in value:
			value = network.Networker.linkDomain(link = value, subdomain = False, topdomain = False, ip = True)
			value = self._cacheId('_labelDomain', re.compile, Stream.ExpressionSymbol, flags = Stream.ExpressionFlags).sub('', value)
		return value

	##############################################################################
	# DECORATE
	##############################################################################

	@classmethod
	def _color(self, value, values = None, color = None):
		gradient = None
		if not value is None and not values is None:
			if tools.Tools.isDictionary(values) and 'expression' in values: values = values['expression']
			index = 0
			count = len(values)
			for i in range(count):
				if values[i][0] == value:
					index = i
					break
			gradient = self._cacheId('_color' + str(count), interface.Format.colorGradientIncrease, count = count)[index]
		return gradient

	@classmethod
	def _decorate(self, value, format, bold = False, uppercase = False, color = None, **kwargs):
		if format == Stream.FormatNone or format == Stream.FormatKodi: return value
		if (format == Stream.FormatDecorate or format == Stream.FormatColor) and color:
			if kwargs: color = color(**{tools.Tools.stringRemovePrefix(key, 'color') : value for key, value in kwargs.items()})
			else: color = color()
		else: color = None
		if format == Stream.FormatBasic or format == Stream.FormatColor: bold = False
		return interface.Format.font(value, color = color, bold = bold, uppercase = uppercase)

	##############################################################################
	# EXPRESSION
	##############################################################################

	@classmethod
	def _expressionFormat(self, expression, keyword):
		if tools.Tools.isArray(expression): return tuple(self._expressionFormatEscape(i).format(**keyword) for i in expression)
		else: return self._expressionFormatEscape(expression).format(**keyword)

	@classmethod
	def _expressionFormatEscape(self, expression):
		return expression.replace('\{', '\{{').replace('\{{{', '\{{').replace('\}', '\}}').replace('\}}}', '\}}')

	@classmethod
	def _expressionFormatPrecede(self):
		if Stream.ExpressionPrecede is None:
			expressions = []
			for i in Stream.ExpressionPrecedeSeparator:
				for j in Stream.ExpressionPrecedeSet:
					expressions.append(j % i)
				for k in Stream.ExpressionPrecedeKeyword:
					for j in Stream.ExpressionPrecedeSet:
						expressions.append(j % (i + Stream.ExpressionSeparator + k))
			Stream.ExpressionPrecede = ''.join(expressions)
		return Stream.ExpressionPrecede

	@classmethod
	def _expressionFormatReplacement(self):
		if Stream.ExpressionReplacement is None:
			Stream.ExpressionReplacement = {
				'symbol' : Stream.ExpressionSymbol,
				'symbol_start' : Stream.ExpressionSymbolStart,
				'symbol_end' : Stream.ExpressionSymbolEnd,

				'glyph' : Stream.ExpressionGlyph,
				'glyph_start' : Stream.ExpressionGlyphStart,
				'glyph_end' : Stream.ExpressionGlyphEnd,

				'separator' : Stream.ExpressionSeparator,
				'separator_extra' : Stream.ExpressionSeparatorExtra,

				'brackets' : Stream.ExpressionBrackets,
				'brackets_start' : Stream.ExpressionBracketsStart,
				'brackets_end' : Stream.ExpressionBracketsEnd,

				'precede' : self._expressionFormatPrecede(),
			}
		return Stream.ExpressionReplacement

	@classmethod
	def _expressionFormatCommon(self, expression, keyword = None):
		if not keyword: keyword = {}
		keyword.update(self._expressionFormatReplacement())
		for i in range(4):
			try: expression = self._expressionFormat(expression = expression, keyword = keyword)
			except: break
		return expression

	@classmethod
	def _expressionFormatExpression(self, type, expression, exclude = None, exhaustive = False, full = True, keyword = False, id = None, flags = None):
		def __expressionFormatExpression(idSub, type, expression, exclude, exhaustive, full, keyword, flags):
			addKeyword = full or keyword or (exclude and not exhaustive)
			idSub = (idSub + '__expressionFormatExpression' + tools.Converter.unicode(type) + tools.Converter.unicode(addKeyword)) if idSub else None
			expression = self._cacheId(idSub, self._expressionFormatPrepare, type = type, expression = expression, addExpression = True, addKeyword = addKeyword)
			if exclude: expression = tuple(i for i in expression if not self._expressionMatch(id = idSub + '_' + tools.Converter.unicode(i) + '_' + tools.Converter.unicode(exhaustive), data = exclude, expression = i['expression' if exhaustive else 'keyword'])) # Do not pass "flags" to the exclude regex.
			return tuple((i['type'], i['keyword' if keyword else 'expression']) for i in expression)
		idMain = (id + '_expressionFormatExpression' + tools.Converter.unicode(type) + tools.Converter.unicode(exclude) + tools.Converter.unicode(exhaustive) + tools.Converter.unicode(full) + tools.Converter.unicode(1 if keyword else 0)) if id else None
		return self._cacheId(idMain, __expressionFormatExpression, idSub = id, type = type, expression = expression, exclude = exclude, exhaustive = exhaustive, full = full, keyword = keyword, flags = flags)

	@classmethod
	def _expressionFormatKeyword(self, expression, exclude = None, order = False, full = True, group = False, guidance = None, id = None, standalone = False, flags = None):
		def __expressionFormatKeyword(idSub, expression, exclude, order, full, group, guidance, flags):
			idSub = (idSub + '__expressionFormatExpression' + tools.Converter.unicode(group) + tools.Converter.unicode(guidance)) if idSub else None
			expression = self._cacheId(idSub, self._expressionFormatPrepare, type = Stream.ExpressionSequential, expression = expression, group = group, guidance = guidance, addExpression = full, addKeyword = True)
			if order: expression = sorted(expression, key = lambda i : len(i['type']), reverse = True)
			expression = tuple(i['keyword'] for i in expression)
			if exclude:
				if standalone: expression = tuple(i for i in expression if not self._expressionMatch(id = idSub + '_' + tools.Converter.unicode(i), data = exclude, expression = Stream.ExpressionSymbolStart + i + Stream.ExpressionSymbolEnd)) # Do not pass "flags" to the exclude regex.
				else: expression = tuple(i for i in expression if not self._expressionMatch(id = idSub + '_' + tools.Converter.unicode(i), data = exclude, expression = i)) # Do not pass "flags" to the exclude regex.
			return expression
		idMain = (id + '_expressionFormatExpression' + tools.Converter.unicode(exclude) + tools.Converter.unicode(order) + tools.Converter.unicode(full) + tools.Converter.unicode(group) + tools.Converter.unicode(guidance)) if id else None
		return self._cacheId(idMain, __expressionFormatKeyword, idSub = id, expression = expression, exclude = exclude, order = order, full = full, group = group, guidance = guidance, flags = flags)

	@classmethod
	def _expressionFormatPrepare(self, type, expression, group = False, guidance = None, addExpression = True, addKeyword = True):
		result = []
		keyword = expression['keyword']
		expression = expression['expression']

		guidanceHas = False
		if guidance:
			guidanceHas = True
			# Must be copied, since extracted results are sent as guidance in load() and we remove items from it.
			if tools.Tools.isArray(guidance): guidance = tools.Tools.copy(guidance)
			else: guidance = [guidance]

		for item in expression:
			if not guidanceHas or item[0] in guidance:
				if guidanceHas: guidance.remove(item[0])
				if tools.Tools.isArray(item[1][0]):
					values1 = item[1][0]
					values2 = item[1][1] if len(item[1]) > 1 else [None]
					for value1 in values1:
						for value2 in values2:
							values = [value1]
							if value2: values.append(value2)
							result.append({
								'type' : item[0],
								'expression' : self._expressionGroup(type = type, values = values, keyword = keyword) if addExpression else None,
								'keyword' : self._expressionGroupKeyword(values = values, keyword = keyword, group = group) if addKeyword else None,
							})
				else:
					values = item[1]
					if not tools.Tools.isArray(values): values = [values]
					result.append({
						'type' : item[0],
						'expression' : self._expressionGroup(type = type, values = values, keyword = keyword) if addExpression else None,
						'keyword' : self._expressionGroupKeyword(values = values, keyword = keyword, group = group) if addKeyword else None,
					})

				if guidanceHas and len(guidance) == 0: break
		return result

	@classmethod
	def _expressionGroup(self, type, values, keyword = None):
		count = len(values)
		replacement = {'value' + tools.Converter.unicode(i + 1) : self._expressionFormatCommon(expression = values[i], keyword = keyword) for i in range(count)}
		return self._expressionFormatCommon(expression = Stream.ExpressionGroup[type][count], keyword = replacement)

	@classmethod
	def _expressionGroupKeyword(self, values, keyword = None, group = False):
		count = len(values)
		replacement = {'value' + tools.Converter.unicode(i + 1) : self._expressionFormatCommon(expression = values[i], keyword = keyword) for i in range(count)}
		result = self._expressionFormatCommon(expression = Stream.ExpressionGroup[Stream.ExpressionKeyword][count], keyword = replacement)
		if group: result = '(' + result + ')'
		return result

	@classmethod
	def _expressionCount(self, expression):
		counts = []
		for e1 in expression['expression']:
			e1 = e1[1]
			count1 = 0
			count2 = 0
			if tools.Tools.isArray(e1):
				if tools.Tools.isArray(e1[0]):
					for e2 in e1:
						count2 = max(count2, len(e2))
				else:
					count1 = max(count1, len(e1))
			else:
				count1 = max(count1, 1)
			counts.append(count1 + count2)
		return max(counts)

	@classmethod
	def _expressionExtract(self, data, expression, multi = False, internal = False, flags = None):
		cacher = self._cacheInternal if internal else self._cache
		result = None
		count = 0
		if not tools.Tools.isArray(expression): expression = [expression]
		if flags is None: flags = Stream.ExpressionFlags
		for e in expression:
			extraction = cacher(re.compile, e, flags = flags)
			extraction = extraction.search(data)
			if extraction:
				resultNew = extraction.groups()
				if not multi: return resultNew
				countNew = len([i for i in resultNew if not i is None])
				if countNew > count:
					count = countNew
					result = resultNew
		return result

	@classmethod
	def _expressionExtractMultiple(self, data, expression, internal = False, flags = None):
		cacher = self._cacheInternal if internal else self._cache
		result = []
		count = 0
		if not tools.Tools.isArray(expression): expression = [expression]
		if flags is None: flags = Stream.ExpressionFlags
		for e in expression:
			matches = cacher(re.compile, '(?=' + e + ')', flags = flags).finditer(data)
			if matches:
				for match in matches:
					groups = match.groups()
					for group in groups:
						if group and not group in result: result.append(group)
		return result

	@classmethod
	def _expressionMatch(self, data, expression, exclude = None, id = None, internal = False, flags = None):
		try:
			cacher = self._cacheIdInternal if internal else self._cacheId
			if not tools.Tools.isArray(data): data = [data]
			if not tools.Tools.isArray(expression): expression = [expression]
			if exclude:
				if not tools.Tools.isArray(exclude): exclude = [exclude]
				exclude = [i.lower() for i in exclude]
			if flags is None: flags = Stream.ExpressionFlags
			for d in data:
				for i in range(len(expression)):
					e = expression[i]
					idSub = (id + '_expressionMatch_' + str(i)) if id else None
					if cacher(idSub, re.compile, e, flags = Stream.ExpressionFlags).search(d):
						if not exclude or not(any([x in e for x in exclude]) or self._expressionMatch(id = idSub, data = exclude, expression = e, exclude = None, flags = Stream.ExpressionFlags)): # Do not pass "flags" to the exclude regex.
							return True
			return False
		except:
			tools.Logger.error()

	@classmethod
	def _expressionMatchType(self, data, expression, exclude = None, id = None, internal = False, extract = False, exclusion = None, flags = None):
		cacher = self._cacheIdInternal if internal else self._cacheId
		if not tools.Tools.isArray(data): data = [data]
		if not tools.Tools.isArray(expression[0]): expression = [expression]
		if exclude:
			if not tools.Tools.isArray(exclude): exclude = [exclude]
			exclude = [i.lower() for i in exclude]
		if flags is None: flags = Stream.ExpressionFlags
		for d in data:
			for i in range(len(expression)):
				e = expression[i]
				idSub = (id + '_expressionMatchType_' + str(i)) if id else None
				result = cacher(idSub, re.compile, e[1], flags = flags).search(d)
				if result:
					if not exclude or not(any([x in str(e[0]) for x in exclude]) or self._expressionMatch(id = idSub, data = exclude, expression = exclusion(e[1]) if exclusion else e[1], exclude = None, flags = Stream.ExpressionFlags)): # Do not pass "flags" to the exclude regex.
						if extract: return e[0], result
						else: return e[0]
		if extract: return None, None
		else: return None

	@classmethod
	def _expressionMatchMultiple(self, data, expression, exclude = None, count = None, order = False, start = False, end = False, full = False, id = None, internal = False, flags = None):
		try:
			cacher = self._cacheIdInternal if internal else self._cacheId
			if not tools.Tools.isArray(data): data = [data]
			if not tools.Tools.isArray(expression[0]): expression = [expression]
			if count is None: count = len(expression)
			if flags is None: flags = Stream.ExpressionFlags

			expressionSymbol = self._cacheId('_expressionMatchMultiple', re.compile, Stream.ExpressionSymbol)
			counter = 0
			done = False
			result = []

			limit = Stream.ExpressionGroups - 1
			chunks = [expression[i:i + limit] for i in range(0, len(expression), limit)]

			if start is True: start = Stream.ExpressionSymbolStart
			elif not start: start = ''

			if end is True: end = Stream.ExpressionSymbolEnd
			elif not end: end = ''
			for d in data:

				# Testing each expression individually takes too long.
				# Create a large expression with multiple sub-expressions as groups and match them all at once.
				for c in range(len(chunks)):
					chunk = chunks[c]
					idSub = ('_expressionMatchMultiple_' + id + '_' + tools.Converter.unicode(c)) if id else None
					base = '(?=' + start + '(?:' + ('|'.join(['(' + x[1] + ')' for x in chunk])) + ')' + end + ')' # (?=) important to allow overlapping groups.
					matches = cacher(idSub, re.compile, base, flags = flags).finditer(d)

					if matches:
						for match in matches:
							groups = match.groups()
							index = -1
							for i in range(len(groups)):
								counter += 1
								if groups[i]:
									index += 1

									found = False
									if not full:
										for j in range(len(result)):
											if result[j][0] == chunk[i][0]:
												found = True
												break
											if self._expressionMatch(data = expressionSymbol.sub(' ', result[j][1]), expression = chunk[i][1], exclude = None, flags = flags) or self._expressionMatch(data = expressionSymbol.sub(' ', chunk[i][1]), expression = result[j][1], exclude = None, flags = flags):
												if len(chunk[i][0]) > len(result[j][0]): del result[j]
												else: found = True
												break

									if not found:
										if not exclude or not self._expressionMatch(data = exclude, expression = chunk[i][1], exclude = None, flags = Stream.ExpressionFlags): # Do not pass "flags" to the exclude regex.
											result.append((chunk[i][0], chunk[i][1], match.start(index)))
											if not done: # Continue to scan matches that were already extracted.
												size = len(result)
												county = 0
												if tools.Tools.isArray(count):
													for k in count:
														if k[0] <= counter: county = k[1]
														else: break
												else:
													county = count
												if size >= county:
													done = True
													# break # Continue to scan matches that were already extracted.
							if done: break
					if done: break

			if order: result.sort(key = lambda i : i[2])
			if not full: result = [i[0] for i in result]

			return None if len(result) == 0 else result
		except:
			tools.Logger.error()
			return None

	@classmethod
	def _expressionNestedMatch(self, id, data, type, expression, exclude = None, exhaustive = False, internal = False, flags = None):
		cacher = self._cacheIdInternal if internal else self._cacheId
		if flags is None: flags = Stream.ExpressionFlags
		for i in expression['expression']:
			key = i[0]
			cache = '_expressionNestedMatch' + id + key + tools.Converter.unicode(i) # Add i to ID as well, since key might appear multiple times (eg {hd}).
			if key: subexpression = cacher('1' + cache, self._expressionFormatCommon, expression = key, keyword = expression['keyword'])
			if not key or cacher('2' + cache, re.compile, subexpression, flags = flags).search(data):
				subexpression = self._expressionFormatExpression(id = '3' + cache, type = type, expression = {'expression' : i[1], 'keyword' : expression['keyword']}, exhaustive = exhaustive, flags = flags)
				result = self._expressionMatchType(id = '4' + cache, data = data, expression = subexpression, exclude = exclude, flags = flags)
				if result: return result
		return None

	@classmethod
	def _expressionNestedLinear(self, id, expression, internal = False):
		cacher = self._cacheIdInternal if internal else self._cacheId
		def __expressionNestedLinear(expression):
			result = []
			for i in expression['expression']:
				result.extend(i[1])
			return {'expression' : result, 'keyword' : expression['keyword']}
		return cacher('_expressionNestedLinear' + id, __expressionNestedLinear, expression)

	@classmethod
	def _expressionReplace(self, data, expression, exclude = None, count = None, replace = None, id = None, split = SplitNone, internal = False, flags = None):
		try:
			cacher = self._cacheIdInternal if internal else self._cacheId
			single = not tools.Tools.isArray(data)
			if single: data = [data]
			if not tools.Tools.isArray(expression): expression = [expression]
			if not replace: replace = ''
			if flags is None: flags = Stream.ExpressionFlags

			# Python's re module only supports 100 named groups.
			import math
			limit = int(math.floor((Stream.ExpressionGroups - 1) / (count if count else 1)))
			length = len(expression)
			chunks = [expression[i:i + limit] for i in range(0, length, limit)]

			for i in range(len(data)):
				for c in range(len(chunks)):
					chunk = chunks[c]
					idSub = ('_expressionReplace' + id + '_' + (tools.Converter.unicode(chunk) if length == 1 else tools.Converter.unicode(length)) + '_' + tools.Converter.unicode(c)) if id else None
					expression = '(?=' + Stream.ExpressionSymbolStart + '(?:' + ('|'.join([x for x in chunk])) + ')' + Stream.ExpressionSymbolEnd + ')'
					matches = cacher(idSub, re.compile, expression, flags = flags).finditer(data[i])

					# Important to check match.groups() here.
					# If no groups match, match will still return true for the full match.
					# Only replace if groups matched.
					if matches:
						index = 0
						for match in matches:
							groups = match.groups()
							for j in range(len(groups)):
								group = groups[j]
								if group:
									if not exclude or not self._expressionMatch(data = exclude, expression = Stream.ExpressionSymbolStart + re.escape(group) + Stream.ExpressionSymbolEnd, exclude = None, flags = Stream.ExpressionFlags): # Do not pass "flags" to the exclude regex.
										if split:
											#data[i] = data[i][:match.start()] if split == Stream.SplitRight else data[i][match.start():]
											#data[i] = data[i][:match.start(1)] if split == Stream.SplitRight else data[i][match.end(1):]

											# Accomodate overlapping matches.
											# Eg: "multi sub" and "sub" detected individually.
											if split == Stream.SplitRight:
												data[i] = data[i][:match.start(j + 1) + index]
												index = match.start(j + 1)
											else:
												data[i] = data[i][match.end(j + 1) - index:]
												index = match.end(j + 1)
										else:
											# Do not use re.sub, since it replaces the entire full match, not the group match.
											#else: data[i] = data[i].replace(group, replace)

											# Do not use Python's replace(), since it does not accomodate symbols before and after.
											# Eg: Removing the Arabic language keyword "ar", will change "Avatar" -> "Avat".
											#else: data[i] = re.sub(Stream.ExpressionSymbolStart + '(' + group + ')' + Stream.ExpressionSymbolEnd, '', data[i], flags = flags)

											# Instead use the index of the match and remove substrings.
											start = match.start(j + 1)
											end = match.end(j + 1)
											size = end - start

											# Do not just remove, since there might be overlapping groups.
											# Replace with the null character and later remove all null characters after all group replacements are done.
											data[i] = data[i][:start] + ('\0' * size) + data[i][end:]

				data[i] = self._cacheId('_expressionReplace_null', re.compile, '\0+', flags = flags).sub(replace, data[i])

			return data[0] if single else data
		except:
			tools.Logger.error()

	##############################################################################
	# HEADERS
	##############################################################################

	'''
		FUNCTION:
			Tries to load metadata from the HTTP and file headers.
		PARAMETERS:
			link (string): The link to use for metadata retrieval.
			timeout (integer): The timeout in seconds for retrieving the headers.
			force (boolean): Whether or not to retrieve headers if the file name is already set.
		RETURNS:
			If the headers were retrieved successfully (boolean).
	'''
	def headers(self, link, timeout = 30, force = True):
		if force or not self.fileName():
			timeoutHttp = int(timeout / 3.0)
			timeoutFile = timeout - timeoutHttp
			if self.headersHttp(link, timeout = timeoutHttp):
				self.headersFile(link, timeout = timeoutFile)
				return True
		return False

	'''
		FUNCTION:
			Tries to load metadata from the HTTP headers.
		PARAMETERS:
			link (string): The link to use for metadata retrieval.
			timeout (integer): The timeout in seconds for retrieving the headers.
			force (boolean): Whether or not to retrieve headers if the file name is already set.
		RETURNS:
			If the headers were retrieved successfully (boolean).
	'''
	def headersHttp(self, link, timeout = 30, force = True):
		try:
			if force or (not self.fileName() or not self.fileSize()):
				response = network.Networker().request(method = network.Networker.MethodHead, link = link, timeout = timeout)
				return self.load(metaMedia = self.metaMedia(), link = link, fileName = response['meta']['name'], fileSize = response['meta']['size'])
		except:
			tools.Logger.error()
		return False

	'''
		FUNCTION:
			Tries to load metadata from the file headers.
		PARAMETERS:
			link (string): The link to use for metadata retrieval.
			timeout (integer): The timeout in seconds for retrieving the headers.
		RETURNS:
			If the headers were retrieved successfully (boolean).
	'''
	def headersFile(self, link, timeout = 30):
		try:
			fileName = None
			fileSize = None
			videoCodec = None
			videoWidth = None
			videoHeight = None
			audioChannels = None
			audioCodec = None
			subtitleType = None

			if tools.Tools.isString(link):
				if tools.File.exists(link):
					size = tools.File.size(link)

			meta = Extractor().extract(link, timeout = timeout)
			if meta:
				# File
				if not fileName and 'name' in meta:
					fileName = meta['name']
				if not fileSize and 'size' in meta:
					fileSize = meta['size']

				# Video
				if 'video' in meta:
					if 'width' in meta['video']: videoWidth = meta['video']['width']
					if 'height' in meta['video']: videoHeight = meta['video']['height']
					if 'codec' in meta['video']: videoCodec = meta['video']['codec']

				# Audio
				if 'audio' in meta:
					if 'codec' in meta['audio']: audioCodec = meta['audio']['codec']
					if 'channels' in meta['audio']: audioChannels = meta['audio']['channels']

				# Subtitle
				if 'subtitle' in meta and meta['subtitle']:
					subtitleType = Stream.SubtitleTypeSoft

			videoResolution = {Stream.VideoWidth : videoWidth, Stream.VideoHeight : videoHeight} if videoWidth or videoHeight else None
			return self.load(metaMedia = self.metaMedia(), link = link, fileName = fileName, fileSize = fileSize, videoResolution = videoResolution, videoCodec = videoCodec, audioChannels = audioChannels, audioCodec = audioCodec, subtitleType = subtitleType)
		except:
			tools.Logger.error()
		return False


class Manager(object):

	ModeManual			= 'manual'
	ModeAutomatic		= 'automatic'
	ModeNone			= None
	ModeDefault			= ModeManual

	OptionSelection		= 'selection'	# List of options that can be enabled or disabled (eg: video codec).
	OptionRange			= 'range'		# Options with a minimum and maximum value (eg: file size).
	OptionKeyword		= 'keyword'		# Options with including and excluding keywords (eg: file name).
	OptionSort			= 'sort'		# Options for sorting.
	OptionNumber		= 'number'		# Number input.
	OptionExclusion		= 'exclusion'	# Include/exclude/label options.

	ValueUnknown		= None
	ValueMinimum		= 'minimum'
	ValueMaximum		= 'maximum'
	ValueInclude		= 'include'
	ValueExclude		= 'exclude'

	ExclusionInclude	= 'include'
	ExclusionExclude	= 'exclude'
	ExclusionLabel		= 'label'

	CategoryGeneral		= 'general'
	CategoryExclusion	= 'exclusion'
	CategoryInfo		= 'info'
	CategoryVideo		= 'video'
	CategoryAudio		= 'audio'
	CategorySubtitle	= 'subtitle'
	CategoryRelease		= 'release'
	CategoryFile		= 'file'
	CategorySource		= 'source'
	CategoryAccess		= 'access'

	AttributeSort		= 'sort'
	AttributeLimit		= 'limit'
	AttributeNumber		= 'number'
	AttributeMedia		= 'media'
	AttributeBandwidth	= 'bandwidth'
	AttributeType		= 'type'
	AttributeQuality	= 'quality'
	AttributeResolution	= 'resolution'
	AttributeAspect		= 'aspect'
	AttributeCodec		= 'codec'
	AttributeDepth		= 'depth'
	AttributeRange		= 'range'
	Attribute3d			= '3d'
	AttributeChannels	= 'channels'
	AttributeSystem		= 'system'
	AttributeLanguage	= 'language'
	AttributeEdition	= 'edition'
	AttributeNetwork	= 'network'
	AttributeGroup		= 'group'
	AttributeUploader	= 'uploader'
	AttributeName		= 'name'
	AttributeSize		= 'size'
	AttributeContainer	= 'container'
	AttributePack		= 'pack'
	AttributePeers		= 'peers'
	AttributeSeeds		= 'seeds'
	AttributeLeeches	= 'leeches'
	AttributeTime		= 'time'
	AttributePopularity	= 'popularity'
	AttributeOrigin		= 'origin'
	AttributeProvider	= 'provider'
	AttributePublisher	= 'publisher'
	AttributeHoster		= 'hoster'
	AttributeDirect		= 'direct'
	AttributeMember		= 'member'
	AttributeOpen		= 'open'
	AttributeOrion		= 'orion'
	AttributeDebrid		= 'debrid'
	AttributeCache		= 'cache'
	AttributeCost		= 'cost'
	AttributeUsage		= 'usage'
	AttributeDuplicate	= 'duplicate'
	AttributeRelease	= 'release'
	AttributeKeyword	= 'keyword'
	AttributeMetadata	= 'metadata'
	AttributeFormat		= 'format'
	AttributeFake		= 'fake'
	AttributeSupport	= 'support'
	AttributeBlocked	= 'blocked'
	AttributeCaptcha	= 'captcha'
	AttributePrecheck	= 'precheck'
	AttributeCustom		= 'custom'

	SortAlphabet		= 'alphabet'	# A to Z
	SortBest			= 'best'		# Best to Worst
	SortFrequency		= 'frequency'	# Common to Uncommon
	SortNumber			= 'number'		# Highest to Lowest
	SortSize			= 'size'		# Largest to Smallest
	SortAge				= 'age'			# Newest to Oldest
	SortLanguage		= 'language'	# Common to Uncommon, and Language Settings

	SortForward			= 'forward'
	SortBackward		= 'backward'
	SortStart			= 'start'
	SortEnd				= 'end'
	SortSettings		= 'settings'	# Sort according to some settings values.

	SortLabel = {
		SortAlphabet	: {SortForward : 33134, SortBackward : 33135, SortStart : 33146, SortEnd : 33147},
		SortBest		: {SortForward : 33136, SortBackward : 33137},
		SortFrequency	: {SortForward : 33138, SortBackward : 33139},
		SortNumber		: {SortForward : 33140, SortBackward : 33141, SortStart : 33152, SortEnd : 33153},
		SortSize		: {SortForward : 33142, SortBackward : 33143, SortStart : 33154, SortEnd : 33155},
		SortAge			: {SortForward : 33144, SortBackward : 33145, SortStart : 33156, SortEnd : 33157},
		SortLanguage	: {SortForward : 33138, SortBackward : 33139, SortSettings : 35047},
	}

	Title	= 35477
	Options	= None

	##############################################################################
	# CONSTRUCTOR
	##############################################################################

	def __init__(self,
		back = False,
		actions = None,

		data = None,
		limit = None,

		enabledSort = False,
		enabledLimit = False,
		enabledNumber = False,
		enabledMedia = False,
		enabledExclusion = False,
	):
		self.mInterface = False
		self.mBack = back
		self.mActions = actions
		self.mLimit = limit
		self.mEnabled = {
			Manager.CategoryGeneral : {
				Manager.AttributeSort : enabledSort,
				Manager.AttributeLimit : enabledLimit,
				Manager.AttributeNumber : enabledNumber,
				Manager.AttributeMedia : enabledMedia,
			},
			Manager.CategoryExclusion : {
				Manager.AttributeDuplicate : enabledExclusion,
				Manager.AttributeRelease : enabledExclusion,
				Manager.AttributeKeyword : enabledExclusion,
				Manager.AttributeMetadata : enabledExclusion,
				Manager.AttributeFormat : enabledExclusion,
				Manager.AttributeFake : enabledExclusion,
				Manager.AttributeSupport : enabledExclusion,
				Manager.AttributeBlocked : enabledExclusion,
				Manager.AttributeCaptcha : enabledExclusion,
				Manager.AttributePrecheck : enabledExclusion,
			},
		}
		self.mData = None
		self._dataReset(data)

	##############################################################################
	# GENERAL
	##############################################################################

	def show(self):
		items = self._filterItems()
		interface.Loader.hide()
		result = interface.Dialog.information(title = Manager.Title, items = items, refresh = self._filterItems, reselect = True)
		if result is False: return result # From Termination - Remove
		return self._dataTo(self.mData)

	@classmethod
	def reset(self, settings = True):
		if settings:
			Manager.Options = None

	##############################################################################
	# DATA
	##############################################################################

	def data(self, category = None, attribute = None):
		if category is None and attribute is None: return self.mData
		try: return self.mData[category][attribute]
		except:
			# Only use the default value for the general and exclusion category (everywhere where filters are not "All") instead of returning None.
			# Otherwise duplicate links will show by default if the user did not change the filter settings.
			# Do not return the default values for other categories, since returning None makes filtering more efficient.
			if category == Manager.CategoryExclusion or category == Manager.CategoryGeneral:
				try: return self._dataDefault()[category][attribute]
				except: pass
		return None

	def _dataSet(self, category, attribute, value):
		if not category in self.mData: self.mData[category] = {}
		self.mData[category][attribute] = value

	def _dataReset(self, data = None):
		result = {}
		if data: result.update(self._dataFrom(data))
		self.mData = result

	def _dataDefault(self):
		result = {}
		for category, option in self._options().items():
			result[category] = {}
			for attribute in option['attribute'].keys():
				result[category][attribute] = self._optionDefault(category = category, attribute = attribute)
		return result

	def _dataDefaultIs(self, data):
		default = self._dataDefault()
		for category, options in self._dataFrom(data).items():
			for attribute, option in options.items():
				if not option == default[category][attribute]: return False
		return True

	@classmethod
	def _dataTo(self, items):
		# NB: Create a copy of the dictionary and do not edit "items" directly.
		# Otherwise "self.mData" will be edited (passed by reference).
		items = tools.Tools.copy(items)
		for category, attributes in items.items():
			for id, values in attributes.items():
				if tools.Tools.isDictionary(values):
					# When converting to JSON (to store values in settings or global filters), all non-string keys get converted to string.
					# Eg: audio channels {2 : True} converts to '{"2" : true}'.
					# Instead save the values as a list of dictionaries and convert back when read in again.
					items[category][id] = [{'id' : key, 'value' : value} for key, value in values.items()]
				elif tools.Tools.isArray(values) and len(values) == 0:
					# Do not store empty lists, since when it is loaded again, we will not know if it is empty or not yet set (aka default settings value).
					items[category][id] = [None]
		return items

	@classmethod
	def _dataFrom(self, items):
		if items:
			for category, attributes in items.items():
				for id, values in attributes.items():
					if values:
						if values == [None]: values = []
						try: values = {value['id'] : value['value'] for value in values}
						except: pass
						try: values = self._dataNone(values)
						except: pass
						items[category][id] = values
		return items

	@classmethod
	def _dataNone(self, values):
		return {None if key == 'null' else key : self._dataNone(value) if tools.Tools.isDictionary(value) else value for key, value in values.items()}

	##############################################################################
	# FORMAT
	##############################################################################

	@classmethod
	def _formatTime(self, value, label = False, inverse = False):
		if label: return '%d %s' % (value, interface.Translation.string(35028 if value == 1 else 33347))
		else: return value

	@classmethod
	def _formatFileSize(self, value, label = False, inverse = False):
		from lib.modules.convert import ConverterSize, ConverterSpeed
		if label: return ConverterSize(value).stringOptimal()
		elif inverse: return int(ConverterSpeed(value, unit = ConverterSpeed.Byte).value(unit = ConverterSpeed.ByteMega))
		else: return ConverterSpeed(value, unit = ConverterSpeed.ByteMega).value(unit = ConverterSpeed.Byte)

	@classmethod
	def _formatSourcePeers(self, value, label = False, inverse = False):
		if label: return '%d %s' % (value, interface.Translation.string(33190 if value == 1 else 33191))
		else: return value

	@classmethod
	def _formatSourcePopularity(self, value, label = False, inverse = False):
		if label: return '%.0f%%' % (value * 100)
		elif inverse: return int(value * 100.0)
		else: return min(1.0, max(0.0, value / 100.0))

	@classmethod
	def _formatGeneralDebrid(self, value, label = False, inverse = False):
		if label: return '%.0fx' % value
		else: return value

	@classmethod
	def _formatFileBandwidth(self, value, label = False, inverse = False):
		from lib.modules.convert import ConverterSpeed
		if label: return ConverterSpeed(value, unit = ConverterSpeed.Bit).stringOptimal(unit = ConverterSpeed.Bit, notation = ConverterSpeed.SpeedLetter)
		elif inverse: return round(ConverterSpeed(value, unit = ConverterSpeed.Bit).value(unit = ConverterSpeed.BitMega), 1)
		else: return ConverterSpeed(value, unit = ConverterSpeed.BitMega).value(unit = ConverterSpeed.Bit)

	##############################################################################
	# HELP
	##############################################################################

	def _helpFilters(self):
		items = [
			{'type' : 'text', 'value' : 34060},
		]
		for category, option in self._options().items():
			entries = []
			for attribute, value in option['attribute'].items():
				if self._optionEnabled(category = category, attribute = attribute) and value['filter']['visible'] and 'help' in value:
					entries.append({'title' : value['title'], 'value' : value['help']})
			if entries:
				items.append({'type' : 'title', 'value' : option['title']})
				items.append({'type' : 'list', 'value' : entries})
		return interface.Dialog.details(title = Manager.Title, items = items)

	def _helpSort(self):
		return interface.Dialog.details(title = self._option(category = Manager.CategoryGeneral, attribute = Manager.AttributeSort)['title'], items = [
			{'type' : 'text', 'value' : 34185},
			{'type' : 'text', 'value' : 34186},
			{'type' : 'list', 'value' : [
				{'value' : 34187},
				{'value' : 34188},
				{'value' : 34189},
			], 'number' : True},
			{'type' : 'text', 'value' : 34204},
			{'type' : 'list', 'value' : [
				{'value' : interface.Format.iconJoin(['HD1080', '8CH', '8.2GB'])},
				{'value' : interface.Format.iconJoin(['HD1080', '8CH', '4.6GB'])},
				{'value' : interface.Format.iconJoin(['HD1080', '6CH', '5.3GB'])},
				{'value' : interface.Format.iconJoin(['HD1080', '2CH', '1.2GB'])},
				{'value' : interface.Format.iconJoin(['HD720', '8CH', '3.6GB'])},
				{'value' : interface.Format.iconJoin(['HD720', '6CH', '3.8GB'])},
				{'value' : interface.Format.iconJoin(['HD720', '2CH', '1.2GB'])},
			], 'number' : True},
		])

	##############################################################################
	# ACTION
	##############################################################################

	@classmethod
	def _actionLanguage(self, items):
		settings = self._actionLanguageSettings()
		for i in range(len(items)):
			items[i]['value'] = items[i]['id'] is Manager.ValueUnknown or items[i]['id'] in settings

	@classmethod
	def _actionLanguageSettings(self):
		return tools.Language.settingsCode()

	@classmethod
	def _actionSpeedTest(self):
		from lib.modules.convert import ConverterSpeed
		from lib.modules.speedtest import SpeedTester
		speedtester = SpeedTester.select(full = False)
		if speedtester: return 0, speedtester.download(unit = ConverterSpeed.BitMega)
		return None # Canceled

	##############################################################################
	# OPTION
	##############################################################################

	def _option(self, category, attribute, *args):
		result = self._optionBasic(category, attribute, *args)
		result = self._optionResolve(result)
		return result

	def _optionBasic(self, category, attribute, *args):
		result = self._options()[category]['attribute'][attribute]
		if args:
			try: result = tools.Tools.dictionaryGet(result, list(args))
			except: result = None
		return result

	def _optionResolve(self, data):
		if tools.Tools.isFunction(data):
			if self.mInterface: interface.Loader.show()
			data = Stream._cache(data)
			if self.mInterface: interface.Loader.hide()
		return data

	def _optionHas(self, category, attribute, *args):
		try:
			result = self._options()[category]['attribute'][attribute]
			if args:
				for arg in args:
					result = result[arg]
					result = self._optionResolve(result)
			return True
		except: return False

	def _optionTitle(self, category, attribute):
		return interface.Translation.string(self._option(category, attribute, 'title'))

	def _optionEnabled(self, category, attribute):
		try: enabled = self.mEnabled[category][attribute]
		except: enabled = True
		return enabled

	def _options(self):
		if Manager.Options is None:
			limit = self.mLimit
			if limit is None:
				# Loading times of many streams can be VERY slow on low-end devices.
				# Adjust the limit based on the hardware specs.
				# Keep this value low, the user can always change the value manually.
				performance = tools.Hardware.performanceType()
				if performance == tools.Hardware.PerformanceBad: limit = 100
				elif performance == tools.Hardware.PerformancePoor: limit = 200
				elif performance == tools.Hardware.PerformanceMedium: limit = 300
				elif performance == tools.Hardware.PerformanceGood: limit = 400
				else: limit = 500

			# NB: For some "label" and order" attributes (language and providers), there are functions.
			# These functions can be executed immediately:
			#	'label' : Stream.sourceProviderLabels()
			# However, this will always execute the function even if they are not used by the caller.
			# On fast devices, this can add 1 sec loading time when the filter/termination/layout dialogs are opened, and 5+ secs on slow devices.
			# Leave the attribute as a function pointer (without executing the function):
			#	'label' : Stream.sourceProviderLabels
			# Then the function is only executed when needed using _optionResolve().
			# Reduces loading time 5 fold.
			# Function that are involved:
			#	Stream.sourceProviderLabels
			#	Stream.sourceProviderOrders
			#	Stream.languageLabels
			#	Stream.languageOrders

			Manager.Options = {
				Manager.CategoryGeneral : {
					'title' : 35847,
					'attribute' : {
						Manager.AttributeSort : {
							'title' : 35402,
							'help' : 34037,
							'level' : 0,
							'filter' : {
								'enabled'	: True,
								'internal'	: True,
								'type'		: Manager.OptionSort,
							},
							'sort' : {
								'enabled'	: False,
							},
							'layout' : {
								'enabled'	: False,
							},
						},
						Manager.AttributeLimit : {
							'title' : 33480,
							'help' : 34402,
							'level' : 1,
							'filter' : {
								'enabled'	: True,
								'internal'	: True,
								'type'		: Manager.OptionNumber,
								'places'	: 0,
								'default'	: {'value' : limit, 'label' : 35221},
							},
							'sort' : {
								'enabled'	: False,
							},
							'layout' : {
								'enabled'	: False,
							},
						},
						Manager.AttributeNumber : {
							'title' : 35421,
							'help' : None,
							'level' : 1,
							'filter' : {
								'enabled'	: False,
							},
							'sort' : {
								'enabled'	: False,
							},
							'layout' : {
								'enabled'	: True,
								'default'	: {'value' : Stream.LabelShort},
							},
						},
						Manager.AttributeMedia : {
							'title' : 33158,
							'help' : 34392,
							'level' : 0,
							'label' : {
								Stream.LabelDefault		: {Stream.LabelSettings1 : Stream.LabelLong, Stream.LabelSettings2 : None},
								tools.Media.Movie	: {Stream.LabelLong : interface.Translation.string(32001)},
								tools.Media.Show	: {Stream.LabelLong : interface.Translation.string(32002)},
							},
							'order' : {
								tools.Media.Movie	: {Stream.OrderInterface : 1},
								tools.Media.Show	: {Stream.OrderInterface : 1},
							},
							'filter' : {
								'enabled'	: True,
								'internal'	: True,
								'unknown'	: False,
								'type'		: Manager.OptionSelection,
							},
							'sort' : {
								'enabled'	: False,
							},
							'layout' : {
								'enabled'	: False,
							},
						},
					},
				},
				Manager.CategoryExclusion : {
					'title' : 35480,
					'attribute' : {
						Manager.AttributeDuplicate : {
							'title' : 35450,
							'help' : 34362,
							'level' : 3,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionExclusion,
								'default'	: {'value' : Manager.ExclusionExclude},
							},
							'sort' : {
								'enabled'	: False,
							},
							'layout' : {
								'enabled'	: True,
								'default'	: {'value' : Stream.LabelMedium},
							},
						},
						Manager.AttributeRelease : {
							'title' : 33312,
							'help' : 34105,
							'level' : 3,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionExclusion,
								'default'	: {'value' : Manager.ExclusionExclude},
							},
							'sort' : {
								'enabled'	: False,
							},
							'layout' : {
								'enabled'	: True,
								'default'	: {'value' : Stream.LabelMedium},
							},
						},
						Manager.AttributeKeyword : {
							'title' : 36130,
							'help' : 34493,
							'level' : 3,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionExclusion,
								'default'	: {'value' : Manager.ExclusionExclude},
							},
							'sort' : {
								'enabled'	: False,
							},
							'layout' : {
								'enabled'	: True,
								'default'	: {'value' : Stream.LabelMedium},
							},
						},
						Manager.AttributeMetadata : {
							'title' : 36131,
							'help' : 34494,
							'level' : 3,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionExclusion,
								'default'	: {'value' : Manager.ExclusionExclude},
							},
							'sort' : {
								'enabled'	: False,
							},
							'layout' : {
								'enabled'	: True,
								'default'	: {'value' : Stream.LabelMedium},
							},
						},
						Manager.AttributeFormat : {
							'title' : 36133,
							'help' : 34496,
							'level' : 3,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionExclusion,
								'default'	: {'value' : Manager.ExclusionExclude},
							},
							'sort' : {
								'enabled'	: False,
							},
							'layout' : {
								'enabled'	: True,
								'default'	: {'value' : Stream.LabelMedium},
							},
						},
						Manager.AttributeFake : {
							'title' : 36132,
							'help' : 34495,
							'level' : 3,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionExclusion,
								'default'	: {'value' : Manager.ExclusionExclude},
							},
							'sort' : {
								'enabled'	: False,
							},
							'layout' : {
								'enabled'	: True,
								'default'	: {'value' : Stream.LabelMedium},
							},
						},
						Manager.AttributeSupport : {
							'title' : 35451,
							'help' : 34363,
							'level' : 3,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionExclusion,
								'default'	: {'value' : Manager.ExclusionExclude},
							},
							'sort' : {
								'enabled'	: False,
							},
							'layout' : {
								'enabled'	: True,
								'default'	: {'value' : Stream.LabelMedium},
							},
						},
						Manager.AttributeBlocked : {
							'title' : 33123,
							'help' : 34359,
							'level' : 3,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionExclusion,
								'default'	: {'value' : Manager.ExclusionExclude},
							},
							'sort' : {
								'enabled'	: False,
							},
							'layout' : {
								'enabled'	: True,
								'default'	: {'value' : Stream.LabelMedium},
							},
						},
						Manager.AttributeCaptcha : {
							'title' : 33195,
							'help' : 34018,
							'level' : 3,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionExclusion,
								'default'	: {'value' : Manager.ExclusionExclude},
							},
							'sort' : {
								'enabled'	: False,
							},
							'layout' : {
								'enabled'	: True,
								'default'	: {'value' : Stream.LabelMedium},
							},
						},
						Manager.AttributePrecheck : {
							'title' : 33269,
							'help' : 34064,
							'level' : 3,
							'filter' : {
								'enabled'	: tools.System.developer(version = False),
								'type'		: Manager.OptionExclusion,
								'default'	: {'value' : Manager.ExclusionExclude},
							},
							'sort' : {
								'enabled'	: False,
							},
							'layout' : {
								'enabled'	: True,
								'default'	: {'value' : Stream.LabelMedium},
							},
						},
					},
				},
				Manager.CategoryInfo : {
					'title' : 35371,
					'attribute' : {
						Manager.AttributeCustom : {
							'title' : 35370,
							'help' : 34474,
							'level' : 3,
							'filter' : {
								'enabled'	: False,
							},
							'sort' : {
								'enabled'	: False,
							},
							'layout' : {
								'enabled'	: True,
								'default'	: {'value' : Stream.LabelMedium},
							},
						},
					},
				},
				Manager.CategoryVideo : {
					'title' : 33120,
					'attribute' : {
						Manager.AttributeQuality : {
							'title' : 33889,
							'help' : 34026,
							'level' : 0,
							'label' : Stream.LabelVideoQuality,
							'order' : Stream.OrderVideoQuality,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionSelection,
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortBest,
							},
							'layout' : {
								'enabled'	: True,
								'default'	: {'value' : Stream.LabelHidden},
							},
						},
						Manager.AttributeResolution : {
							'title' : 35714,
							'help' : 34152,
							'level' : 3,
							'filter' : {
								'enabled'	: False,
							},
							'sort' : {
								'enabled'	: False,
							},
							'layout' : {
								'enabled'	: False,
							},
						},
						Manager.AttributeAspect : {
							'title' : 35713,
							'help' : 34153,
							'level' : 3,
							'filter' : {
								'enabled'	: False,
							},
							'sort' : {
								'enabled'	: False,
							},
							'layout' : {
								'enabled'	: False,
							},
						},
						Manager.AttributeCodec : {
							'title' : 33127,
							'help' : 34027,
							'level' : 1,
							'label' : Stream.LabelVideoCodec,
							'order' : Stream.OrderVideoCodec,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionSelection,
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortBest,
							},
							'layout' : {
								'enabled'	: True,
							},
						},
						Manager.AttributeRange : {
							'title' : 35711,
							'help' : 34029,
							'level' : 2,
							'label' : Stream.LabelVideoRange,
							'order' : Stream.OrderVideoRange,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionSelection,
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortBest,
							},
							'layout' : {
								'enabled'	: True,
							},
						},
						Manager.AttributeDepth : {
							'title' : 35710,
							'help' : 34028,
							'level' : 2,
							'label' : Stream.LabelVideoDepth,
							'order' : Stream.OrderVideoDepth,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionSelection,
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortBest,
							},
							'layout' : {
								'enabled'	: True,
							},
						},
						Manager.Attribute3d : {
							'title' : 35712,
							'help' : 34231,
							'level' : 1,
							'label' : Stream.LabelVideo3d,
							'order' : Stream.OrderVideo3d,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionSelection,
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortBest,
							},
							'layout' : {
								'enabled'	: True,
							},
						},
					},
				},
			 	Manager.CategoryAudio : {
					'title' : 33121,
					'attribute' : {
						Manager.AttributeType : {
							'title' : 35717,
							'help' : 34229,
							'level' : 1,
							'label' : Stream.LabelAudioType,
							'order' : Stream.OrderAudioType,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionSelection,
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortBest,
							},
							'layout' : {
								'enabled'	: True,
							},
						},
						Manager.AttributeChannels : {
							'title' : 33129,
							'help' : 34030,
							'level' : 0,
							'label' : Stream.LabelAudioChannels,
							'order' : Stream.OrderAudioChannels,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionSelection,
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortBest,
							},
							'layout' : {
								'enabled'	: True,
							},
						},
						Manager.AttributeSystem : {
							'title' : 35718,
							'help' : 34230,
							'level' : 1,
							'label' : Stream.LabelAudioSystem,
							'order' : Stream.OrderAudioSystem,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionSelection,
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortBest,
							},
							'layout' : {
								'enabled'	: True,
							},
						},
						Manager.AttributeCodec : {
							'title' : 33130,
							'help' : 34031,
							'level' : 1,
							'label' : Stream.LabelAudioCodec,
							'order' : Stream.OrderAudioCodec,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionSelection,
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortBest,
							},
							'layout' : {
								'enabled'	: True,
							},
						},
						Manager.AttributeLanguage : {
							'title' : 35038,
							'help' : 34190,
							'level' : 0,
							'label' : Stream.languageLabels,
							'order' : Stream.languageOrders,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionSelection,
								'action'	: [(35056, Manager._actionLanguage)],
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortLanguage,
								'settings'	: Manager._actionLanguageSettings,
							},
							'layout' : {
								'enabled'	: True,
							},
						},
					},
				},
				Manager.CategorySubtitle : {
					'title' : 33122,
					'attribute' : {
						Manager.AttributeType : {
							'title' : 35721,
							'help' : 34032,
							'level' : 1,
							'label' : Stream.LabelSubtitleType,
							'order' : Stream.OrderSubtitleType,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionSelection,
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortBest,
							},
							'layout' : {
								'enabled'	: True,
							},
						},
						Manager.AttributeLanguage : {
							'title' : 35722,
							'help' : 34033,
							'level' : 0,
							'label' : Stream.languageLabels,
							'order' : Stream.languageOrders,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionSelection,
								'action'	: [(35056, Manager._actionLanguage)],
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortLanguage,
								'settings'	: Manager._actionLanguageSettings,
							},
							'layout' : {
								'enabled'	: True,
							},
						},
					},
				},
				Manager.CategoryRelease : {
					'title' : 35165,
					'attribute' : {
						Manager.AttributeType : {
							'title' : 35731,
							'help' : 34178,
							'level' : 2,
							'label' : Stream.LabelReleaseType,
							'order' : Stream.OrderReleaseType,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionSelection,
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortBest,
							},
							'layout' : {
								'enabled'	: True,
							},
						},
						Manager.AttributeFormat : {
							'title' : 35736,
							'help' : 34225,
							'level' : 2,
							'label' : Stream.LabelReleaseFormat,
							'order' : Stream.OrderReleaseFormat,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionSelection,
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortBest,
							},
							'layout' : {
								'enabled'	: True,
							},
						},
						Manager.AttributeEdition : {
							'title' : 35732,
							'help' : 34179,
							'level' : 2,
							'label' : Stream.LabelReleaseEdition,
							'order' : Stream.OrderReleaseEdition,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionSelection,
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortBest,
							},
							'layout' : {
								'enabled'	: True,
							},
						},
						Manager.AttributeNetwork : {
							'title' : 35733,
							'help' : 34180,
							'level' : 3,
							'label' : Stream.LabelReleaseNetwork,
							'order' : Stream.OrderReleaseNetwork,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionSelection,
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortFrequency,
							},
							'layout' : {
								'enabled'	: True,
							},
						},
						Manager.AttributeGroup : {
							'title' : 35734,
							'help' : 34181,
							'level' : 3,
							'label' : Stream.LabelReleaseGroup,
							'order' : Stream.OrderReleaseGroup,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionSelection,
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortAlphabet,
							},
							'layout' : {
								'enabled'	: True,
								'default'	: {'value' : Stream.LabelHidden},
							},
						},
						Manager.AttributeUploader : {
							'title' : 33243,
							'help' : 34183,
							'level' : 3,
							'label' : Stream.LabelReleaseUploader,
							'filter' : {
								'enabled'	: False,
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortAlphabet,
							},
							'layout' : {
								'enabled'	: True,
								'default'	: {'value' : Stream.LabelHidden},
							},
						},
					},
				},
				Manager.CategoryFile : {
					'title' : 35481,
					'attribute' : {
						Manager.AttributeContainer : {
							'title' : 35727,
							'help' : 34251,
							'level' : 2,
							'label' : Stream.LabelFileContainer,
							'order' : Stream.OrderFileContainer,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionSelection,
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortBest,
							},

							'layout' : {
								'enabled'	: True,
							},
						},
						Manager.AttributePack : {
							'title' : 35728,
							'help' : 34252,
							'level' : 1,
							'label' : Stream.LabelFilePack,
							'order' : Stream.OrderFilePack,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionSelection,
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortFrequency,
							},
							'layout' : {
								'enabled'	: True,
							},
						},
						Manager.AttributeSize : {
							'title' : 35726,
							'help' : 34232,
							'level' : 1,
							'label' : Stream.LabelFileSize,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionRange,
								'function'	: Manager._formatFileSize,
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortSize,
								'inverse'	: True,
							},
							'layout' : {
								'enabled'	: True,
							},
						},
						Manager.AttributeBandwidth : {
							'title' : 33133,
							'help' : 34023,
							'level' : 1,
							'label' : Stream.LabelFileBandwidth,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionRange,
								'places'	: 1,
								'function'	: Manager._formatFileBandwidth,
								'action'	: [(33030, Manager._actionSpeedTest)],
							},
							'sort' : {
								'enabled'	: False,
							},
							'layout' : {
								'enabled'	: True,
							},
						},
						Manager.AttributeName : {
							'title' : 35724,
							'help' : 34348,
							'level' : 2,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionKeyword,
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortAlphabet,
							},
							'layout' : {
								'enabled'	: False,
							},
						},
					},
				},
				Manager.CategorySource : {
					'title' : 33188,
					'attribute' : {
						Manager.AttributeType : {
							'title' : 33890,
							'help' : 34020,
							'level' : 0,
							'label' : Stream.LabelSourceType,
							'order' : Stream.OrderSourceType,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionSelection,
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortBest,
							},
							'layout' : {
								'enabled'	: True,
							},
						},
						Manager.AttributePeers : {
							'title' : 33189,
							'help' : 34021,
							'level' : 2,
							'label' : Stream.LabelSourcePeers,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionRange,
								'function'	: Manager._formatSourcePeers,
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortNumber,
								'inverse'	: True,
							},
							'layout' : {
								'enabled'	: True,
							},
						},
						Manager.AttributeSeeds : {
							'title' : 33185,
							'help' : 34210,
							'level' : 3,
							'filter' : {
								'enabled'	: False,
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortNumber,
								'inverse'	: True,
							},
							'layout' : {
								'enabled'	: False,
							},
						},
						Manager.AttributeLeeches : {
							'title' : 33186,
							'help' : 34211,
							'level' : 3,
							'filter' : {
								'enabled'	: False,
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortNumber,
								'inverse'	: True,
							},
							'layout' : {
								'enabled'	: False,
							},
						},
						Manager.AttributeTime : {
							'title' : 35407,
							'help' : 34022,
							'level' : 2,
							'label' : Stream.LabelSourceTime,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionRange,
								'function'	: Manager._formatTime,
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortAge,
							},
							'layout' : {
								'enabled'	: True,
							},
						},
						Manager.AttributePopularity : {
							'title' : 35399,
							'help' : 34391,
							'level' : 2,
							'label' : Stream.LabelSourcePopularity,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionRange,
								'places'	: 2,
								'function'	: Manager._formatSourcePopularity,
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortNumber,
								'inverse'	: True,
							},
							'layout' : {
								'enabled'	: True,
							},
						},
						Manager.AttributeOrigin : {
							'title' : 35737,
							'help' : 34394,
							'level' : 3,
							'label' : Stream.LabelSourceOrigin,
							'filter' : {
								'enabled'	: False,
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortAlphabet,
							},
							'layout' : {
								'enabled'	: True,
							},
						},
						Manager.AttributeProvider : {
							'title' : 35395,
							'help' : 34395,
							'level' : 3,
							'label' : Stream.sourceProviderLabels,
							'order' : Stream.sourceProviderOrders,
							'filter' : {
								'enabled'	: False,
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortAlphabet,
							},
							'layout' : {
								'enabled'	: True,
							},
						},
						Manager.AttributePublisher : {
							'title' : 35396,
							'help' : 34396,
							'level' : 2,
							'label' : Stream.LabelSourcePublisher,
							'filter' : {
								'enabled'	: False,
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortAlphabet,
							},
							'layout' : {
								'enabled'	: True,
							},
						},
						Manager.AttributeHoster : {
							'title' : 35738,
							'help' : 34397,
							'level' : 2,
							'label' : Stream.LabelSourceHoster,
							'filter' : {
								'enabled'	: False,
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortAlphabet,
							},
							'layout' : {
								'enabled'	: True,
							},
						},
					},
				},
				Manager.CategoryAccess : {
					'title' : 33187,
					'attribute' : {
						Manager.AttributeType : {
							'title' : 35745,
							'help' : 34016,
							'level' : 2,
							'label' : Stream.LabelAccessType,
							'order' : Stream.OrderAccessType,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionSelection,
								'unknown'	: False,
								'parameter'	: {'account' : True},
							},
							'sort' : {
								'enabled'	: True,
								'type'		: Manager.SortBest,
								'parameter'	: {'account' : True},
							},
							'layout' : {
								'enabled'	: True,
							},
						},
						Manager.AttributeDirect : {
							'title' : 35740,
							'level' : 3,
							'filter' : {
								'enabled'	: False,
							},
							'sort' : {
								'enabled'	: False,
							},
							'layout' : {
								'enabled'	: False,
							},
						},
						Manager.AttributeMember : {
							'title' : 35707,
							'level' : 3,
							'filter' : {
								'enabled'	: False,
							},
							'sort' : {
								'enabled'	: False,
							},
							'layout' : {
								'enabled'	: False,
							},
						},
						Manager.AttributeOpen : {
							'title' : 35741,
							'level' : 3,
							'filter' : {
								'enabled'	: False,
							},
							'sort' : {
								'enabled'	: False,
							},
							'layout' : {
								'enabled'	: False,
							},
						},
						Manager.AttributeOrion : {
							'title' : 35742,
							'level' : 3,
							'filter' : {
								'enabled'	: False,
							},
							'sort' : {
								'enabled'	: False,
							},
							'layout' : {
								'enabled'	: False,
							},
						},
						Manager.AttributeDebrid : {
							'title' : 35743,
							'level' : 3,
							'label'	: Stream.LabelAccessDebrid,
							'filter' : {
								'enabled'	: False,
								'parameter'	: {'account' : True},
							},
							'sort' : {
								'enabled'	: False,
								'parameter'	: {'account' : True},
							},
							'layout' : {
								'enabled'	: True,
							},
						},
						Manager.AttributeCache : {
							'title' : 35744,
							'help' : 34024,
							'level' : 2,
							'label'	: Stream.LabelAccessCache,
							'order'	: Stream.OrderAccessCache,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionSelection,
								'inverse'	: True,
								'unknown'	: False,
								'parameter'	: {'account' : True},
							},
							'sort' : {
								'enabled'	: True,
								'parameter'	: {'account' : True},
							},
							'layout' : {
								'enabled'	: True,
							},
						},
						Manager.AttributeCost : {
							'title' : 33212,
							'help' : 34017,
							'level' : 2,
							'filter' : {
								'enabled'	: True,
								'type'		: Manager.OptionNumber,
								'default'	: {'label' : 33112},
								'function'	: Manager._formatGeneralDebrid,
							},
							'sort' : {
								'enabled'	: False,
							},
							'layout' : {
								'enabled'	: False,
							},
						},
						Manager.AttributeUsage : {
							'title' : 33213,
							'help' : None,
							'level' : 2,
							'label'	: Stream.LabelAccessUsage,
							'filter' : {
								'enabled'	: False,
							},
							'sort' : {
								'enabled'	: False,
							},
							'layout' : {
								'enabled'	: True,
							},
						},
					},
				},
			}

			level = tools.Settings.level()
			for category, option in Manager.Options.items():
				for attribute, value in option['attribute'].items():
					value['filter']['visible'] = value['filter']['enabled'] and value['level'] <= level
					value['sort']['visible'] = value['sort']['enabled'] and value['level'] <= level

		return Manager.Options

	def _optionOrder(self, category, attribute, order = Stream.OrderSorting, limit = None, reverse = False):
		result = self._option(category, attribute, 'order')
		result = [{'id' : key, 'order' : value[order]} for key, value in result.items() if not value[order] is None]
		result = [value['id'] for value in sorted(result, key = lambda i : i['order'], reverse = reverse)]
		if not limit is None:
			if not tools.Tools.isArray(limit): limit = [limit]
			temp = []
			for value in result:
				if value in limit: break
				temp.append(value)
			result = temp
		return result

	def _optionDefault(self, category, attribute, default = True):
		result = None

		type = self._option(category, attribute, 'filter', 'type')
		if self._optionHas(category, attribute, 'filter', 'default', 'value'):
			result = self._option(category, attribute, 'filter', 'default', 'value')
		else:
			if self._option(category, attribute, 'filter', 'inverse'): default = False

			if type == Manager.OptionSort:
				result = [
					# Firstly group by video quality. Move 4K links to the top.
					{
						'category'	: Manager.CategoryVideo,
						'attribute'	: Manager.AttributeQuality,
						'order'		: self._optionOrder(category = Manager.CategoryVideo, attribute = Manager.AttributeQuality),
					},
					# Within the video quality grouping, move local and premium sources to the top.
					{
						'category'	: Manager.CategorySource,
						'attribute'	: Manager.AttributeType,
						'order'		: [Stream.SourceTypeLocal, Stream.SourceTypePremium],
					},
					# Move cached and direct links to the top.
					{
						'category'	: Manager.CategoryAccess,
						'attribute'	: Manager.AttributeType,
						'order'		: [Stream.AccessTypeCache, Stream.AccessTypeDirect],
					},
					# Move better video codecs to the top.
					{
						'category'	: Manager.CategoryVideo,
						'attribute'	: Manager.AttributeCodec,
						'order'		: self._optionOrder(category = Manager.CategoryVideo, attribute = Manager.AttributeCodec),
					},
					# Move HDR links to the top.
					{
						'category'	: Manager.CategoryVideo,
						'attribute'	: Manager.AttributeRange,
						'order'		: self._optionOrder(category = Manager.CategoryVideo, attribute = Manager.AttributeRange),
					},
					# Move surround sound to the top.
					{
						'category'	: Manager.CategoryAudio,
						'attribute'	: Manager.AttributeChannels,
						'order'		: self._optionOrder(category = Manager.CategoryAudio, attribute = Manager.AttributeChannels, limit = Stream.AudioChannels5),
					},
					# Move Dolby and DTS links to the top.
					# NB: Do not do this, since it will put all Dolby content before DTS content.
					# Rather use the audio codec to make Atmos and DTS:X links appear at the top.
					#{
					#	'category'	: Manager.CategoryAudio,
					#	'attribute'	: Manager.AttributeSystem,
					#	'order'		: self._optionOrder(category = Manager.CategoryAudio, attribute = Manager.AttributeSystem),
					#},
					# Move better audio codecs to the top.
					# Only sort by Dolby and DTS, so that AAC 8CH are moved down.
					{
						'category'	: Manager.CategoryAudio,
						'attribute'	: Manager.AttributeCodec,
						'order'		: self._optionOrder(category = Manager.CategoryAudio, attribute = Manager.AttributeCodec, limit = [Stream.AudioCodecAac, Stream.AudioCodecHeaac, Stream.AudioCodecLcaac]),
					},
					# Move more audio channels to the top.
					{
						'category'	: Manager.CategoryAudio,
						'attribute'	: Manager.AttributeChannels,
						'order'		: self._optionOrder(category = Manager.CategoryAudio, attribute = Manager.AttributeChannels),
					},
					# Move higher video depth to the top.
					{
						'category'	: Manager.CategoryVideo,
						'attribute'	: Manager.AttributeDepth,
						'order'		: self._optionOrder(category = Manager.CategoryVideo, attribute = Manager.AttributeDepth),
					},
					# Move larger file sizes to the top.
					{
						'category'	: Manager.CategoryFile,
						'attribute'	: Manager.AttributeSize,
						'order'		: [Manager.SortStart, Manager.SortEnd],
					},
					# Move packs to the top, since they are better for binge.
					{
						'category'	: Manager.CategoryFile,
						'attribute'	: Manager.AttributePack,
						'order'		: self._optionOrder(category = Manager.CategoryFile, attribute = Manager.AttributePack),
					},
					# Sort remaining audio codecs.
					{
						'category'	: Manager.CategoryAudio,
						'attribute'	: Manager.AttributeCodec,
						'order'		: self._optionOrder(category = Manager.CategoryAudio, attribute = Manager.AttributeCodec),
					},
					# Finally, put debrid in front of member in front of open links.
					{
						'category'	: Manager.CategoryAccess,
						'attribute'	: Manager.AttributeType,
						'order'		: [Stream.AccessTypeDebrid, Stream.AccessTypeMember, Stream.AccessTypeOpen],
					},
				]
			else:
				if type == Manager.OptionSelection:
					order = self._option(category, attribute, 'order')
					if order: result = {key : default for key, value in order.items() if not value[Stream.OrderInterface] is None}
				elif type == Manager.OptionRange:
					result = {Manager.ValueMinimum : 0, Manager.ValueMaximum : 0}
				elif type == Manager.OptionKeyword:
					result = {Manager.ValueInclude : None, Manager.ValueExclude : None}
				if result:
					unknown = self._option(category, attribute, 'filter', 'unknown')
					if unknown is None or unknown is True: result[Manager.ValueUnknown] = default

		return result

	def _optionCurrent(self, category, attribute, default = True):
		current = self.data(category = category, attribute = attribute)
		if default or current is None:
			value = self._optionDefault(category = category, attribute = attribute)
			if not current is None:
				if tools.Tools.isDictionary(current):
						try:
							for key, val in current.items():
								value[key] = val
						except: pass
				else:
					value = current
		else:
			value = current
		return value

	def _optionLabel(self, category, attribute):
		type = self._option(category, attribute, 'filter', 'type')
		order = self._option(category, attribute, 'order')

		label = None
		if type == Manager.OptionSort:
			current = self._optionCurrent(category = category, attribute = attribute, default = False)
			label = interface.Translation.string(33112 if len(current) == 0 else 33564 if self._optionDefault(category = category, attribute = attribute) == current else 35233)
		else:
			default = self._option(category, attribute, 'filter', 'default', 'label')
			if not default: default = 33029

			current = self._optionCurrent(category = category, attribute = attribute)
			if type == Manager.OptionSelection:
				count = len([key for key, value in order.items() if not value[Stream.OrderInterface] is None])

				unknown = self._option(category, attribute, 'filter', 'unknown')
				if unknown is None or unknown is True: count += 1 # +1 for unknown.

				total = count
				if current: total = sum([1 for key, value in current.items() if value and (key is Manager.ValueUnknown or (key in order and not order[key][Stream.OrderInterface] is None))])
				if total == 0: label = interface.Translation.string(33112)
				elif total == count: label = interface.Translation.string(default)
				else: label = '%s (%d)' % (interface.Translation.string(35233), total)
			elif type == Manager.OptionRange:
				label = interface.Translation.string(default if not current or (current[Manager.ValueUnknown] and not current[Manager.ValueMinimum] and not current[Manager.ValueMaximum]) else 35233)
			elif type == Manager.OptionKeyword:
				label = interface.Translation.string(default if not current or (current[Manager.ValueUnknown] and not current[Manager.ValueInclude] and not current[Manager.ValueExclude]) else 35233)
			elif type == Manager.OptionExclusion:
				return interface.Translation.string(33115 if current == Manager.ExclusionExclude else 33114 if current == Manager.ExclusionInclude else 36129)
			else:
				if not current: # Check both None and 0 (for number input).
					label = default
				else:
					function = self._optionBasic(category, attribute, 'filter', 'function')
					if function: label = function(value = current, label = True)
					else: label = tools.Converter.unicode(current)

		return label

	def _optionValue(self, category, attribute, enabled = True, default = True):
		current = self._optionCurrent(category = category, attribute = attribute, default = default)
		if not current: return current

		if enabled:
			if tools.Tools.isDictionary(current):
				type = self._option(category, attribute, 'filter', 'type')
				unkown = 1 if Manager.ValueUnknown in current else 0
				if type == Manager.OptionSelection:
					order = self._option(category, attribute, 'order')
					current = {key : value  for key, value in current.items() if value and (key is Manager.ValueUnknown or (not key in order or not Stream.OrderInterface in order[key] or not order[key][Stream.OrderInterface] is None))}
					if order: # If all are selected, return None to avoid the expensive filtering process.
						keys = [key for key, value in order.items() if (not Stream.OrderInterface in value or not value[Stream.OrderInterface] is None)]
						if len(keys) == len(current) - unkown: current = None
				elif type == Manager.OptionRange:
					if unkown and not current[Manager.ValueMinimum] and not current[Manager.ValueMaximum]: current = None
				elif type == Manager.OptionKeyword:
					if unkown and not current[Manager.ValueInclude] and not current[Manager.ValueExclude]: current = None

		return current

	def _optionAction(self, category, attribute):
		value = self._optionDialog(category = category, attribute = attribute)
		self._dataSet(category = category, attribute = attribute, value = value)
		return value

	def _optionDialog(self, category, attribute):
		self.mInterface = True
		result = None
		type = self._option(category, attribute, 'filter', 'type')
		if type == Manager.OptionSelection: result = self._optionDialogSelection(category = category, attribute = attribute)
		elif type == Manager.OptionRange: result = self._optionDialogRange(category = category, attribute = attribute)
		elif type == Manager.OptionKeyword: result = self._optionDialogKeyword(category = category, attribute = attribute)
		elif type == Manager.OptionSort: result = self._optionDialogSort(category = category, attribute = attribute)
		elif type == Manager.OptionNumber: result = self._optionDialogNumber(category = category, attribute = attribute)
		elif type == Manager.OptionExclusion: result = self._optionDialogExclusion(category = category, attribute = attribute)
		self.mInterface = False
		return result

	def _optionDialogNumber(self, category, attribute, default = True):
		title = self._option(category, attribute, 'title')
		type = self._option(category, attribute, 'filter', 'type')
		places = self._option(category, attribute, 'filter', 'places')
		value = self._optionValue(category = category, attribute = attribute)

		value = interface.Dialog.input(type = interface.Dialog.InputNumeric, title = title, default = value)

		if default and not value: return 0 # Return 0 as an unlimited value

		if not places is None: value = round(value, places)
		if not places: value = int(value)
		return value

	def _optionDialogExclusion(self, category, attribute, default = True):
		value = self._optionValue(category = category, attribute = attribute)
		if value == Manager.ExclusionExclude: return Manager.ExclusionInclude
		elif value == Manager.ExclusionInclude: return Manager.ExclusionLabel
		else: return Manager.ExclusionExclude

	def _optionDialogSelection(self, category, attribute):
		title = self._option(category, attribute, 'title')
		label = self._option(category, attribute, 'label')
		order = self._option(category, attribute, 'order')
		type = self._option(category, attribute, 'filter', 'type')
		action = self._option(category, attribute, 'filter', 'action')
		unknown = self._option(category, attribute, 'filter', 'unknown')
		inverse = self._option(category, attribute, 'filter', 'inverse')

		main = label[Stream.LabelDefault][Stream.LabelSettings1]
		prefix = label[Stream.LabelDefault][Stream.LabelSettings2]
		prefixHas = prefix and not prefix == Stream.LabelHidden

		entries = []
		for key, value in label.items():
			if not key == Stream.LabelDefault:
				try:
					ord = order[key][Stream.OrderInterface]
					if ord is None: continue
				except: ord = key
				entry = {'id' : key, 'label' : value[main], 'value' : True, 'order' : ord}
				if prefixHas: entry['prefix'] = value[prefix]
				entries.append(entry)

		entries = sorted(entries, key = lambda i : i['order'])
		if unknown is None or unknown is True: entries.insert(0, {'id' : Manager.ValueUnknown, 'label' : interface.Format.fontItalic(35748), 'value' : True})

		items = self._optionValue(category = category, attribute = attribute, enabled = False)
		if items:
			for i in range(len(entries)):
				try: entries[i]['value'] = items[entries[i]['id']]
				except: pass

		default = True
		if self._optionHas(category, attribute, 'filter', 'default', 'value'):
			default = self._option(category, attribute, 'filter', 'default', 'value')
		if inverse: default = not default

		options = [interface.Dialog.ToggleBack, (interface.Dialog.ToggleDefault, default), interface.Dialog.ToggleInverse, interface.Dialog.ToggleEnable, interface.Dialog.ToggleDisable]
		if action: options.extend(action)

		return interface.Dialog.toggle(title = title, items = entries, options = options, cancel = False)

	def _optionDialogRange(self, category, attribute):
		title = self._option(category, attribute, 'title')
		action = self._option(category, attribute, 'filter', 'action')
		places = self._option(category, attribute, 'filter', 'places')
		function = self._optionBasic(category, attribute, 'filter', 'function')

		def _functionConvert(value, places):
			if places is None: return int(value)
			else: return round(float(value), places)

		if not function:
			def _functionDummy(value, label = False, inverse = False):
				return value
			function = _functionDummy

		enabled = interface.Format.fontColor(32301, interface.Format.colorExcellent())
		disabled = interface.Format.fontColor(32302, interface.Format.colorBad())

		items = self._optionValue(category = category, attribute = attribute, enabled = False)

		try: offset = len(action)
		except: offset = 0

		choice = None
		while True:
			entries = [
				interface.Dialog.prefixBack(interface.Format.fontBold(35374), bold = True),
				interface.Dialog.prefixNext(interface.Format.fontBold(33564), bold = True),
			]
			if action:
				for i in action:
					entries.append(interface.Dialog.prefixNext(interface.Format.fontBold(i[0]), bold = True))
			entries.extend([
				'',
				'%s: %s' % (interface.Format.fontItalic(35748), enabled if items[Manager.ValueUnknown] else disabled),
				'%s: %s' % (interface.Translation.string(35304), interface.Format.fontColor(function(value = items[Manager.ValueMinimum], label = True), interface.Format.colorExcellent()) if items[Manager.ValueMinimum] else disabled),
				'%s: %s' % (interface.Translation.string(35305), interface.Format.fontColor(function(value = items[Manager.ValueMaximum], label = True), interface.Format.colorExcellent()) if items[Manager.ValueMaximum] else disabled),
			])

			choice = interface.Dialog.select(title = title, items = entries, selection = choice)
			if choice <= 0:
				break
			elif choice == 1:
				items = self._optionDefault(category = category, attribute = attribute)
			elif choice == 3 + offset:
				items[Manager.ValueUnknown] = not items[Manager.ValueUnknown]
			elif choice == 4 + offset:
				default = None
				if items[Manager.ValueMinimum]: default = function(value = _functionConvert(items[Manager.ValueMinimum], places), inverse = True)
				items[Manager.ValueMinimum] = interface.Dialog.input(title = 35304, type = interface.Dialog.InputNumeric, default = default)
				try: items[Manager.ValueMinimum] = function(value = _functionConvert(items[Manager.ValueMinimum], places))
				except: items[Manager.ValueMinimum] = 0
			elif choice == 5 + offset:
				default = None
				if items[Manager.ValueMaximum]: default = function(value = _functionConvert(items[Manager.ValueMaximum], places), inverse = True)
				items[Manager.ValueMaximum] = interface.Dialog.input(title = 35305, type = interface.Dialog.InputNumeric, default = default)
				try: items[Manager.ValueMaximum] = function(value = _functionConvert(items[Manager.ValueMaximum], places))
				except: items[Manager.ValueMaximum] = 0
			elif offset:
				choice -= 2
				try: minimum, maxium = action[choice][1]()
				except: continue # Canceled
				try: items[Manager.ValueMinimum] = function(value = _functionConvert(minimum, places))
				except: items[Manager.ValueMinimum] = 0
				try: items[Manager.ValueMaximum] = function(value = _functionConvert(maxium, places))
				except: items[Manager.ValueMaximum] = 0

		return items

	def _optionDialogKeyword(self, category, attribute):
		def _keywords(title, items):
			choice = None
			while True:
				entries = [
					interface.Dialog.prefixBack(interface.Format.fontBold(35374), bold = True),
					interface.Dialog.prefixNext(interface.Format.fontBold(33564), bold = True),
					interface.Dialog.prefixNext(interface.Format.fontBold(35069), bold = True),
					'',
				]
				if items: entries.extend(items)
				else: items = []

				choice = interface.Dialog.select(title = title, items = entries, selection = choice)
				if choice <= 0:
					break
				elif choice == 1:
					items = None
				elif choice == 2:
					keyword = interface.Dialog.input(title = 33271)
					if keyword: items.append(keyword)
				elif choice > 3:
					del items[choice - 4]

			return items

		title = self._option(category, attribute, 'title')

		enabled = interface.Format.fontColor(32301, interface.Format.colorExcellent())
		disabled = interface.Format.fontColor(32302, interface.Format.colorBad())
		keyword = interface.Translation.string(33271)
		keywords = interface.Translation.string(35484)

		items = self._optionValue(category = category, attribute = attribute, enabled = False)

		choice = None
		while True:
			try: countInclude = len(items[Manager.ValueInclude])
			except: countInclude = 0
			try: countExclude = len(items[Manager.ValueExclude])
			except: countExclude = 0
			entries = [
				interface.Dialog.prefixBack(interface.Format.fontBold(35374), bold = True),
				interface.Dialog.prefixNext(interface.Format.fontBold(33564), bold = True),
				'',
				'%s: %s' % (interface.Format.fontItalic(35748), enabled if items[Manager.ValueUnknown] else disabled),
				'%s: %s' % (interface.Translation.string(35482), interface.Format.fontColor('%d %s' % (countInclude, keyword if countInclude == 1 else keywords), interface.Format.colorExcellent()) if items[Manager.ValueInclude] else disabled),
				'%s: %s' % (interface.Translation.string(35483), interface.Format.fontColor('%d %s' % (countExclude, keyword if countExclude == 1 else keywords), interface.Format.colorExcellent()) if items[Manager.ValueExclude] else disabled),
			]

			choice = interface.Dialog.select(title = title, items = entries, selection = choice)
			if choice <= 0:
				break
			elif choice == 1:
				items = self._optionDefault(category = category, attribute = attribute)
			elif choice == 3:
				items[Manager.ValueUnknown] = not items[Manager.ValueUnknown]
			elif choice == 4:
				items[Manager.ValueInclude] = _keywords(title = 35482, items = items[Manager.ValueInclude])
			elif choice == 5:
				items[Manager.ValueExclude] = _keywords(title = 35483, items = items[Manager.ValueExclude])

		return items

	def _optionDialogSort(self, category, attribute):
		title = self._option(category, attribute, 'title')
		options = self._sortOptions()

		items = self._optionValue(category = category, attribute = attribute, enabled = False)
		if not items: items = []

		filters = ' ' + interface.Translation.string(35477)
		choiceMain = None
		while True:
			entriesMain = [
				interface.Dialog.prefixBack(interface.Format.fontBold(35374), bold = True),
				interface.Dialog.prefixNext(interface.Format.fontBold(33239), bold = True),
				interface.Dialog.prefixNext(interface.Format.fontBold(33564), bold = True),
				interface.Dialog.prefixNext(interface.Format.fontBold(33013), bold = True),
				interface.Dialog.prefixNext(interface.Format.fontBold(35069), bold = True),
			]
			if len(items) > 0: entriesMain.append('')
			entriesMain.extend(['%d. %s %s' % (i + 1, interface.Format.fontBold('[%s]' % interface.Translation.string(options[items[i]['category']]['title']).replace(filters, '')), self._optionTitle(category = items[i]['category'], attribute = items[i]['attribute'])) for i in range(len(items))])

			offsetMain = len(entriesMain)
			try: offsetMain -= entriesMain[::-1].index('')
			except: pass

			choiceMain = interface.Dialog.select(title = title, items = entriesMain, selection = choiceMain)
			if choiceMain <= 0: # Back
				break
			elif choiceMain == 1: # Help
				self._helpSort()
			elif choiceMain == 2: # Defaults
				items = self._optionDefault(category = category, attribute = attribute)
			elif choiceMain == 3: # Clear
				items = []
			elif choiceMain == 4 and choiceMain < len(items) + offsetMain: # Add
				def _sortAction(category, attribute):
					items.append({'category' : category, 'attribute' : attribute, 'order' : []})

				entriesParameter = [
					{'title' : interface.Dialog.prefixBack(35374), 'close' : True, 'return' : False},
				]
				for cat, option in options.items():
					entriesSub = []
					for att, value in option['attribute'].items():
						entriesSub.append({
							'title' : value['title'],
							'close' : True,
							'return' : True,
							'action' : _sortAction,
							'parameters' : {'category' : cat, 'attribute' : att},
						})
					if entriesSub: entriesParameter.append({'title' : option['title'], 'items' : entriesSub})

				choiceParameter = interface.Dialog.information(title = title, items = entriesParameter, reselect = True)
				if choiceParameter is None:
					cancel = True
					break
				elif choiceParameter is False:
					continue
				choiceMain = len(items) - 1 + offsetMain

			if choiceMain >= offsetMain: # Specific Parameter (if and not elif, since we want to jump from adding a new parameter to this option).
				indexParameter = choiceMain - offsetMain
				choiceParameter = None
				cancel = False

				while True:
					item = items[indexParameter]
					order = item['order']
					sortParameter = self._option(item['category'], item['attribute'], 'sort', 'type')
					entriesParameter = [
						interface.Dialog.prefixBack(interface.Format.fontBold(35374), bold = True),
						interface.Dialog.prefixNext(interface.Format.fontBold(35406), bold = True),
						interface.Dialog.prefixNext(interface.Format.fontBold(35403), bold = True),
						interface.Dialog.prefixNext(interface.Format.fontBold(35404), bold = True),
						interface.Dialog.prefixNext(interface.Format.fontBold(33013), bold = True),
						interface.Dialog.prefixNext(interface.Format.fontBold(35069), bold = True),
						'',
					]

					sortSettings = False
					if sortParameter:
						entriesParameter.extend([
							interface.Dialog.prefixNext(interface.Format.fontBold(Manager.SortLabel[sortParameter][Manager.SortForward]), bold = True),
							interface.Dialog.prefixNext(interface.Format.fontBold(Manager.SortLabel[sortParameter][Manager.SortBackward]), bold = True),
						])
						try:
							entriesParameter.append(interface.Dialog.prefixNext(interface.Format.fontBold(Manager.SortLabel[sortParameter][Manager.SortSettings]), bold = True))
							sortSettings = True
						except: pass
						entriesParameter.append('')

					try:
						labelParameter = self._option(item['category'], item['attribute'], 'label')
						labelPrefix = labelParameter[Stream.LabelDefault][Stream.LabelSettings2]
						labelMain = labelParameter[Stream.LabelDefault][Stream.LabelSettings1]
						for i in range(len(order)):
							prefix = ''
							if not labelPrefix == Stream.LabelHidden:
								prefix = labelParameter[order[i]][labelPrefix]
								if prefix.upper() in ['B', 'I', 'CR']: prefix = '%s\1' % prefix
								prefix = ' ' + interface.Format.fontBold('[%s]' % prefix)
							entriesParameter.append('%d.%s %s' % (i + 1, prefix, labelParameter[order[i]][labelMain]))
					except:
						if sortParameter:
							labelParameter = {
								Manager.SortStart : {Stream.LabelLong : interface.Translation.string(Manager.SortLabel[sortParameter][Manager.SortStart])},
								Manager.SortEnd : {Stream.LabelLong : interface.Translation.string(Manager.SortLabel[sortParameter][Manager.SortEnd])},
							}
							labelPrefix = None
							labelMain = Stream.LabelLong
							entriesParameter.extend(['%d. %s' % (i + 1, labelParameter[order[i]][labelMain]) for i in range(len(order))])

					entriesParameter.append('%d. %s' % (len(order) + 1, interface.Format.fontItalic(35491)))

					offsetParameter = len(entriesParameter) - entriesParameter[::-1].index('')
					choiceParameter = interface.Dialog.select(title = title, items = entriesParameter, selection = choiceParameter)

					if choiceParameter < 0: # Cancel
						cancel = True
						break
					elif choiceParameter == 0: # Back
						break
					elif choiceParameter == 1: # Remove
						del items[indexParameter]
						break
					elif choiceParameter == 2: # Move Up
						items.insert(max(0, indexParameter - 1), items.pop(indexParameter))
						choiceMain = max(0, choiceMain - offsetMain - 1) + offsetMain
						break
					elif choiceParameter == 3: # Move Down
						items.insert(min(len(items) - 1, indexParameter + 1), items.pop(indexParameter))
						choiceMain = min(len(entriesMain) - 1, choiceMain + 1)
						break
					elif choiceParameter == 4: # Clear
						items[indexParameter]['order'] = []
						continue
					elif choiceParameter == 5: # Add
						try: order = self._optionOrder(category = item['category'], attribute = item['attribute'], order = Stream.OrderInterface)
						except: order = [Manager.SortStart, Manager.SortEnd]
						entriesValue = [
							interface.Dialog.prefixBack(interface.Format.fontBold(35374), bold = True),
							'',
						]
						try:
							for value in order:
								prefix = labelParameter[value][labelPrefix]
								if prefix.upper() in ['B', 'I', 'CR']: prefix = '%s\1' % prefix
								entriesValue.append('%s %s' % (interface.Format.fontBold('[%s]' % prefix), labelParameter[value][labelMain]))
						except:
							entriesValue.extend([labelParameter[value][labelMain] for value in order])
						choiceValue = interface.Dialog.select(title = title, items = entriesValue)
						if choiceValue < 0:
							cancel = True
							break
						elif choiceValue >= 2:
							indexValue = choiceValue - 2
							try: items[indexParameter]['order'].remove(order[indexValue])
							except: pass
							items[indexParameter]['order'].append(order[indexValue])
					elif sortParameter and choiceParameter >= offsetParameter - 3 - int(sortSettings) and choiceParameter <= offsetParameter - 2 - int(sortSettings):
						reverse = choiceParameter == offsetParameter - 2 - int(sortSettings)
						try: order = self._optionOrder(category = item['category'], attribute = item['attribute'], order = Stream.OrderSorting, reverse = reverse)
						except: order = [Manager.SortEnd, Manager.SortStart] if reverse else [Manager.SortStart, Manager.SortEnd]
						items[indexParameter]['order'] = order
					elif sortParameter and sortSettings and choiceParameter == offsetParameter - 2:
						items[indexParameter]['order'] = self._option(item['category'], item['attribute'], 'sort', 'settings')
					elif choiceParameter >= offsetParameter and choiceParameter < len(order) + offsetParameter: # Specific Value
						indexValue = choiceParameter - offsetParameter
						entriesValue = [
							interface.Dialog.prefixBack(interface.Format.fontBold(35374), bold = True),
							interface.Dialog.prefixNext(interface.Format.fontBold(35406), bold = True),
							interface.Dialog.prefixNext(interface.Format.fontBold(35403), bold = True),
							interface.Dialog.prefixNext(interface.Format.fontBold(35404), bold = True),
						]
						choiceValue = interface.Dialog.select(title = title, items = entriesValue)
						if choiceValue < 0:
							cancel = True
							break
						else:
							if choiceValue == 1: # Remove
								del items[indexParameter]['order'][indexValue]
								choiceParameter = indexValue + offsetParameter
							elif choiceValue == 2: # Move Up
								index = max(0, indexValue - 1)
								items[indexParameter]['order'].insert(index, items[indexParameter]['order'].pop(indexValue))
								choiceParameter = index + offsetParameter
							elif choiceValue == 3: # Move Down
								index = min(len(items[indexParameter]['order']) - 1, indexValue + 1)
								items[indexParameter]['order'].insert(index, items[indexParameter]['order'].pop(indexValue))
								choiceParameter = index + offsetParameter

				if cancel: break

		return items

	##############################################################################
	# PROCESS
	##############################################################################

	def process(self, items, filter = True, sort = True, exclude = True, limit = True, filters = None, duration = None):
		count = {
			'initial' : len(items),
			'final' : None,

			Manager.AttributeDuplicate : None,
			Manager.AttributeRelease : None,
			Manager.AttributeKeyword : None,
			Manager.AttributeMetadata : None,
			Manager.AttributeFormat : None,
			Manager.AttributeFake : None,
			Manager.AttributeSupport : None,
			Manager.AttributeBlocked : None,
			Manager.AttributeCaptcha : None,
			Manager.AttributePrecheck : None,

			'exclusion' : None,
			'filter' : None,
			'sort' : None,
			'limit' : None,
		}

		# Check "not is False" since it is None by default.
		if exclude:
			if self.excludeDuplicate():
				items = [item for item in items if not item['stream'].exclusionDuplicate()]
				count[Manager.AttributeDuplicate] = len(items)

			if self.excludeRelease(): # NB: Must be after duplicate filtering, since it uses the combined stream metadata.
				items = [item for item in items if not item['stream'].exclusionRelease()]
				count[Manager.AttributeRelease] = len(items)

			if self.excludeKeyword():
				items = [item for item in items if not item['stream'].exclusionKeyword()]
				count[Manager.AttributeKeyword] = len(items)

			if self.excludeFormat():
				items = [item for item in items if not item['stream'].exclusionFormat()]
				count[Manager.AttributeFormat] = len(items)

			if self.excludeMetadata():
				items = [item for item in items if not item['stream'].exclusionMetadata()]
				count[Manager.AttributeMetadata] = len(items)

			if self.excludeFake():
				items = [item for item in items if not item['stream'].exclusionFake()]
				count[Manager.AttributeFake] = len(items)

			if self.excludeSupport():
				items = [item for item in items if not item['stream'].exclusionSupport()]
				count[Manager.AttributeSupport] = len(items)

			if self.excludeBlocked():
				items = [item for item in items if not item['stream'].exclusionBlocked()]
				count[Manager.AttributeBlocked] = len(items)

			if self.excludeCaptcha():
				items = [item for item in items if not item['stream'].exclusionCaptcha()]
				count[Manager.AttributeCaptcha] = len(items)

			if self.excludePrecheck():
				items = [item for item in items if not item['stream'].exclusionPrecheckInaccessible()]
				count[Manager.AttributePrecheck] = len(items)

			count['exclusion'] = len(items)

		if filter:
			items = self.filter(items = items, filters = filters, duration = duration)
			count['filter'] = len(items)

		if sort:
			items = self.sort(items = items)
			count['sort'] = len(items)

		if limit:
			items = self.limit(items = items)
			count['limit'] = len(items)

		count['final'] = len(items)
		return count, items

	##############################################################################
	# FILTER
	##############################################################################

	def filter(self, items, filters = None, duration = None):
		for category, options in self._options().items():
			for attribute, option in options['attribute'].items():
				if option['filter']['enabled'] and (not 'internal' in option['filter'] or not option['filter']['internal']):
					items = self._filterParameter(items = items, category = category, attribute = attribute, filters = filters, duration = duration)
		return items

	def _filterParameter(self, items, category, attribute, filters = None, duration = None):
		try:
			if not category == Manager.CategoryExclusion: # Handled by process().
				if filters is None: filters = self.data(category = category, attribute = attribute)
				if category == Manager.CategoryAccess and attribute == Manager.AttributeCost:
					items = self._filterCost(items = items, category = category, attribute = attribute, filters = filters)
				elif category == Manager.CategoryAccess and attribute == Manager.AttributeCache:
					items = self._filterCache(items = items, category = category, attribute = attribute, filters = filters)
				elif filters:
					unknown = Manager.ValueUnknown in filters and filters[Manager.ValueUnknown]
					if Manager.ValueMinimum in filters:
						items = self._filterLimit(items = items, category = category, attribute = attribute, filters = filters, unknown = unknown, duration = duration)
					elif Manager.ValueInclude in filters:
						items = self._filterKeyword(items = items, category = category, attribute = attribute, filters = filters, unknown = unknown)
					else:
						items = self._filterOption(items = items, category = category, attribute = attribute, filters = filters, unknown = unknown)
		except: tools.Logger.error()
		return items

	def _filterCost(self, items, category, attribute, filters):
		try:
			cost = self.data(category = Manager.CategoryAccess, attribute = Manager.AttributeCost)
			if cost and cost > 0:
				from lib.debrid.premiumize import Core, Handle
				core = Core()
				handle = Handle()
				if core.accountValid():
					filter = []
					for i in items:
						if handle.supported(i):
							try:
								try: service = i['stream'].sourceHoster().lower().rsplit('.', 1)[0]
								except: service = i['stream'].sourceType()
								factor = core.service(service)['usage']['factor']['value']
							except: factor = None
							if factor is None or factor <= cost: filter.append(i)
						else: filter.append(i)
					items = filter
		except:
			tools.Logger.error()
		return items

	def _filterCache(self, items, category, attribute, filters):
		try:
			access = self.data(category = Manager.CategoryAccess, attribute = Manager.AttributeType)
			if access is None or Stream.AccessTypeCache in access:
				filter = []
				for item in items:
					type = item['stream'].sourceType()
					if type in Stream.OrderAccessCache:
						cache = item['stream'].accessCacheAny(account = True)
						if cache or (not cache and (not filters or not type in filters or not filters[type])):
							filter.append(item)
					else:
						filter.append(item)
				return filter
			else:
				return items
		except:
			tools.Logger.error()
			return items

	def _filterOption(self, items, category, attribute, filters, unknown):
		try:
			filters = {k : v for k, v in filters.items() if v}
			filter = []
			for item in items:
				extra = self._option(category, attribute, 'sort', 'parameter')
				if not extra: extra = {}
				value = item['stream'].parameter(category = category, attribute = attribute, **extra)
				if tools.Tools.isArray(value):
					if (value and any(v in filters for v in value)) or (not value and unknown):
						filter.append(item)
				elif tools.Tools.isDictionary(value):
					if (value and any(k in filters for k, v in value.items() if v)) or (not value and unknown):
						filter.append(item)
				elif (value and value in filters) or (not value and unknown):
					filter.append(item)
			return filter
		except:
			tools.Logger.error()
			return items

	def _filterLimit(self, items, category, attribute, filters, unknown, duration = None):
		try:
			filter = []
			minimum = filters[Manager.ValueMinimum]
			maximum = filters[Manager.ValueMaximum]

			if category == Manager.CategoryFile and attribute == Manager.AttributeBandwidth:
				if not duration and items: duration = items[0]['stream'].metaDuration(default = True)
				if duration:
					multiplier = duration / 8.0 # 8 bits to bytes
					minimum *= multiplier
					maximum *= multiplier
				category = Manager.CategoryFile
				attribute = Manager.AttributeSize

			for item in items:
				extra = self._option(category, attribute, 'sort', 'parameter')
				if not extra: extra = {}
				value = item['stream'].parameter(category = category, attribute = attribute, **extra)
				if not value is None: # Check for None, since "0 peers" is not equivalent to "None".
					if (not minimum or value >= minimum) and (not maximum or value <= maximum):
						filter.append(item)
				elif unknown:
					filter.append(item)
			return filter
		except:
			tools.Logger.error()
			return items

	def _filterKeyword(self, items, category, attribute, filters, unknown):
		try:
			filter = []
			include = filters[Manager.ValueInclude]
			if include: include = [value.lower() for value in include]
			exclude = filters[Manager.ValueExclude]
			if exclude: exclude = [value.lower() for value in exclude]
			for item in items:
				extra = self._option(category, attribute, 'sort', 'parameter')
				if not extra: extra = {}
				value = item['stream'].parameter(category = category, attribute = attribute, **extra)
				if value:
					value = value.lower()
					if (not include or any(v in value for v in include)) and (not exclude or not any(v in value for v in exclude)):
						filter.append(item)
				elif unknown:
					filter.append(item)
			return filter
		except:
			tools.Logger.error()
			return items

	def _filterItems(self):
		result = [
			{'title' : interface.Dialog.prefixBack(35374 if self.mBack else 33486), 'close' : True},
			{'title' : interface.Dialog.prefixNext(33239), 'action' : self._helpFilters},
			{'title' : interface.Dialog.prefixNext(33564), 'action' : self._dataReset},
		]
		if self.mActions: result.extend(self.mActions)

		for category, options in self._options().items():
			items = []
			for attribute, option in options['attribute'].items():
				if option['filter']['visible']:
					if self._optionEnabled(category = category, attribute = attribute):
						items.append({
							'title' : option['title'],
							'value' : self._optionLabel(category = category, attribute = attribute),
							'action' : self._optionAction,
							'parameters' : {'category' : category, 'attribute' : attribute},
						})
			if items: result.append({'title' : options['title'], 'items' : items})

		return result

	##############################################################################
	# SORT
	##############################################################################

	'''
		FUNCTION:
			Sorts the streams according to the custom sorting attributes.
			The sorting works as follows:
				1. Generate a numeric value for each of the sorting parameters that the user specified.
					a. For discrete parameters (eg: video quality or codec), the numeric value is the index position of the value in the user's specified order.
					b. For number parameters (eg: file size, age, or popularity), the numeric value is the number itself.
					c. For alphabetic parameters (eg: file name), the alphanumeric string gets converted into a numeric representation, that is each character is converted to its position in the UTF table.
				2. Each of the numeric values for the parameters get converted into a string, that is a string containing numeric characters.
				3. For each stream, the numeric strings for all specified parameters are then concatenated according to the parameter order specified by the user.
				4. These long strings are then used to sort the list of streams.
			For example:
				If we first sort according to quality and then the number of seeds, having the following streams:
					HD1080 20 seeds
					HD720 15 seeds
					HD1080 52 seeds
					HD720 2 seeds
				Their represenations are as follows (parameters are separated with dashes for illustration purposes only):
					HD1080 20 seeds: "09-20"
					HD720 15 seeds: "10-15"
					HD1080 52 seeds: "09-52"
					HD720 2 seeds: "10-02"
				Note that the numeric values are padded so that all of them belonging to the same type have the same length.
				Values that are sorted in inverse order (eg: file size or seeds from highest to lowest) get subtracted from the maximum to invert them.
				Hence the above representation will actually be (max - value + 1, eg: 52 - 20 + 1 = 33):
					HD1080 20 seeds: "09-33"
					HD720 15 seeds: "10-38"
					HD1080 52 seeds: "09-01"
					HD720 2 seeds: "10-51"
				The streams are then sorted as:
					HD1080 52 seeds: "0901"
					HD1080 20 seeds: "0933"
					HD720 15 seeds: "1038"
					HD720 2 seeds: "1051"
		RETURNS:
			The sorted list of streams.
	'''
	def sort(self, items):
		try:
			parameters = self._optionCurrent(category = Manager.CategoryGeneral, attribute = Manager.AttributeSort)
			if parameters:
				# Generate numeric sorting representations for each parameter.
				for i in range(len(parameters)):
					category = parameters[i]['category']
					attribute = parameters[i]['attribute']
					order = parameters[i]['order']

					extra = self._option(category, attribute, 'sort', 'parameter')
					if not extra: extra = {}

					if len(order) > 0 and order[0] in [Manager.SortStart, Manager.SortEnd]:
						if self._option(category, attribute, 'sort', 'type') == Manager.SortAlphabet:
							length = 0
							for item in items:
								parameter = item['stream'].parameter(category = category, attribute = attribute, **extra)
								if parameter:
									parameter = len(parameter)
									if parameter > length: length = parameter
							length += 1
							length *= 5 # Each unicode character represented by 5 digits.
							inverse = order[0] == Manager.SortEnd
							if self._option(category, attribute, 'sort', 'inverse'): inverse = not inverse
							parameters[i]['sort'] = {'format_alphabet' : '%%-%ds' % length, 'inverse' : inverse, 'length' : length}
						else:
							maximum = 0
							multiplier = 1
							for item in items:
								parameter = item['stream'].parameter(category = category, attribute = attribute, **extra)
								if not parameter is None and parameter > maximum: maximum = parameter
							if maximum <= 1: # Fractional values like popularity.
								multiplier = 10000
								maximum *= multiplier
							maximum += 1
							length = len(str(maximum))
							inverse = order[0] == Manager.SortEnd
							if self._option(category, attribute, 'sort', 'inverse'): inverse = not inverse
							parameters[i]['sort'] = {'format_number' : '%%0%dd' % length, 'inverse' : inverse, 'multiplier' : multiplier, 'maximum' : maximum, 'length' : length}
					else:
						length = len(str(len(order)))
						format = '%%0%dd' % length
						parameters[i]['sort'] = {order[j] : (format % (j + 1)) for j in range(len(order))}
					parameters[i]['sort'][None] = '9' * length

				# Create a combined sorting representation for all parameters for each stream.
				for i in range(len(items)):
					sortValue = ''
					for parameter in parameters:
						category = parameter['category']
						attribute = parameter['attribute']
						sort = parameter['sort']

						extra = self._option(category, attribute, 'sort', 'parameter')
						if not extra: extra = {}

						parameter = items[i]['stream'].parameter(category = category, attribute = attribute, **extra)
						if 'format_alphabet' in sort or 'format_number' in sort:
							if parameter:
								if 'format_alphabet' in sort:
									sortSub = sort['format_alphabet'] % parameter.lower()
									sortSub = tools.Converter.number(string = sortSub, pad = True, inverse = sort['inverse'])
								else:
									if sort['inverse']: parameter = sort['maximum'] - parameter
									sortSub = sort['format_number'] % (parameter * sort['multiplier'])
							else:
								sortSub = sort[None] # Always place unknown values last.
						else:
							try:
								if tools.Tools.isDictionary(parameter): # For dictionaries with multiple keys and boolean values (eg: accessType).
									parameter = [k for k, v in parameter.items() if v]

								if tools.Tools.isArray(parameter):
									sortSub = sort[None]
									for param in parameter:
										try:
											if sort[param] < sortSub: sortSub = sort[param]
										except: pass
								else:
									sortSub = sort[parameter]
							except:
								sortSub = sort[None]
						sortValue += sortSub
					items[i]['stream'].infoSortSet(sortValue)

				# Sort the streams according to the sorting representation.
				items = sorted(items, key = lambda i : i['stream'].infoSort())

		except:
			tools.Logger.error()
		return items

	def _sortOptions(self):
		options = {}
		for cat, option in self._options().items():
			options[cat] = {'title' : option['title'], 'attribute' : {}}
			for att, value in option['attribute'].items():
				if value['sort']['visible']:
					options[cat]['attribute'][att] = value
		return options

	##############################################################################
	# EXCLUDE
	##############################################################################

	def exclude(self, items, duplicate = True):
		try:
			if duplicate: items = self._excludeDuplicate(items = items)
		except: tools.Logger.error()
		return items

	def _excludeDuplicate(self, items):
		def _excludeDuplicatePeers(streams):
			try:
				missing = False
				seedsGlobal = []
				seedsOrion = []
				leechesGlobal = []
				leechesOrion = []

				for item in streams:
					stream = item['stream']
					seeds = stream.sourceSeeds()
					leeches = stream.sourceLeeches()
					if seeds is None or leeches is None: missing = True

					if stream.accessTypeOrion():
						if not seeds is None: seedsOrion.append(seeds)
						if not leeches is None: leechesOrion.append(leeches)
					else:
						if not seeds is None: seedsGlobal.append(seeds)
						if not leeches is None: leechesGlobal.append(leeches)

				if missing:
					seeds = None
					leeches = None
					if seedsGlobal or leechesGlobal:
						if seedsGlobal: seeds = max(seedsGlobal)
						if leechesGlobal: leeches = max(leechesGlobal)
					elif seedsOrion or leechesOrion:
						if seedsOrion: seeds = max(seedsOrion)
						if leechesOrion: leeches = max(leechesOrion)

					for item in streams:
						stream = item['stream']
						if stream.sourceSeeds() is None: stream.sourceSeedsSet(value = seeds)
						if stream.sourceLeeches() is None: stream.sourceLeechesSet(value = leeches)
			except: tools.Logger.error()

		def _excludeDuplicateTime(streams):
			try:
				missing = False
				timeExact = None
				timeInexact = None

				for item in streams:
					stream = item['stream']
					exact = stream.sourceTime(exact = Stream.ExactYes)
					inexact = stream.sourceTime(exact = Stream.ExactNo)
					if exact is None: missing = True

					if not timeExact and exact: timeExact = exact
					if not timeInexact and inexact: timeInexact = inexact

				if missing:
					if timeExact:
						for item in streams:
							stream = item['stream']
							if not stream.sourceTime(exact = Stream.ExactYes): stream.sourceTimeSet(value = timeExact, exact = Stream.ExactYes)
					elif timeInexact:
						for item in streams:
							stream = item['stream']
							if not stream.sourceTime(exact = Stream.ExactNo): stream.sourceTimeSet(value = timeInexact, exact = Stream.ExactNo)
			except: tools.Logger.error()

		def _excludeDuplicateSize(streams):
			try:
				missing = False
				sizeExact = None
				sizeInexact = None

				for item in streams:
					stream = item['stream']

					# Always recalculate the size of Orion links, since they still have old streams with incorrectly estimated pack sizes.
					if stream.filePack() and stream.idOrion():
						exact = None
						inexact = None
					else:
						exact = stream.fileSize(exact = Stream.ExactYes, estimate = False)
						inexact = stream.fileSize(exact = Stream.ExactNo, estimate = False)

					if exact is None: missing = True

					if not sizeExact and exact: sizeExact = exact
					if not sizeInexact and inexact: sizeInexact = inexact

				if missing:
					if sizeExact:
						for item in streams:
							stream = item['stream']
							orion = stream.filePack() and stream.idOrion()
							if not stream.fileSize(exact = Stream.ExactYes, estimate = False) or orion:
								stream.fileSizeSet(value = sizeExact, exact = Stream.ExactYes)
								if orion: stream.fileSizeSet(value = sizeInexact, exact = Stream.ExactNo)
					elif sizeInexact:
						for item in streams:
							stream = item['stream']
							orion = stream.filePack() and stream.idOrion()
							if not stream.fileSize(exact = Stream.ExactNo, estimate = False) or orion:
								stream.fileSizeSet(value = sizeInexact, exact = Stream.ExactNo)
			except: tools.Logger.error()

		def _excludeDuplicateCache(streams):
			try:
				cacheExact = None
				cacheInexact = None
				cacheTime = None

				for item in streams:
					stream = item['stream']
					exact = stream.accessCache(exact = Stream.ExactYes)
					inexact = stream.accessCache(exact = Stream.ExactNo)
					time = stream.accessCache(exact = Stream.ExactTime)

					if exact:
						if cacheExact is None:
							cacheExact = tools.Tools.copy(exact)
						else:
							for k, v in cacheExact.items():
								if v is None: cacheExact[k] = exact[k]
					if inexact:
						if cacheInexact is None:
							cacheInexact = tools.Tools.copy(inexact)
						else:
							for k, v in cacheInexact.items():
								if v is None: cacheInexact[k] = inexact[k]
					if time:
						if cacheTime is None:
							cacheTime = tools.Tools.copy(time)
						else:
							for k, v in cacheTime.items():
								if v is None: cacheTime[k] = time[k]

				if cacheExact: cacheExact = {k : v for k, v in cacheExact.items() if not v is None}
				if cacheInexact: cacheInexact = {k : v for k, v in cacheInexact.items() if not v is None}
				if cacheTime: cacheTime = {k : v for k, v in cacheTime.items() if not v is None}

				if cacheExact:
					for item in streams:
						item['stream'].accessCacheSet(value = cacheExact, exact = Stream.ExactYes)
				elif cacheInexact:
					for item in streams:
						item['stream'].accessCacheSet(value = cacheInexact, exact = Stream.ExactNo)

				if cacheTime:
					for item in streams:
						item['stream'].accessCacheSet(value = cacheTime, exact = Stream.ExactTime)
			except: tools.Logger.error()

		def _excludeDuplicatePopularity(streams):
			try:
				for item in streams:
					item['stream'].sourcePopularityCalculate()
			except: tools.Logger.error()

		result = []
		try:
			# Firstly group duplicate streams by hash/link.
			duplicates = {i : {} for i in Stream.OrderSourceType.keys()}
			for item in items:
				# NB: Only remove duplicates if their source is the same. This ensures that links from direct sources are not removed (eg: Premiumize Direct vs Premiumize Torrent).
				stream = item['stream']
				type = stream.sourceType()
				hash = stream.hash()
				link = stream.link()

				try: premium = stream.sourceTypePremium()
				except: premium = False

				key = None
				if type == Stream.SourceTypeTorrent and hash:
					key = hash
				elif link:
					link = link[0]
					container = network.Container(link)
					if container.torrentIsMagnet():
						link = container.torrentMagnetBase() # Clean magnet from trackers, name, domain, etc.
					else:
						link = network.Networker.linkClean(link) # Clean link from HTTP headers.
						if premium:
							# Parallel searches of premium services often returns the same file on different servers. Only check the URL path and ignore the domain.
							# Also use the parameters for Emby/Jellyfin that might have the same path for different streams, but the parameters differ.
							path = network.Networker.linkPath(link)
							parameters = network.Networker.linkParameters(link)

							link = path
							if parameters:
								# Make sure the parameters always have the same order.
								parameters = sorted(parameters.items())
								link += '?' + ('&'.join([i[0] + '=' + i[1] for i in parameters])).strip('&')

					if link: key = link.lower()

				if key is None:
					result.append(item)
				else:
					if not key in duplicates[type]: duplicates[type][key] = {'items' : []}
					duplicates[type][key]['items'].append(item)

			# Secondly determine the main/most-important link from each duplicate subset.
			for type, group in duplicates.items():
				for key, streams in group.items():
					streams = streams['items']
					main = None

					# If there is an Orion link, prefer it.
					for item in streams:
						if item['stream'].accessTypeOrion():
							main = item

					# Else perfer the stream with the longest file name or the most attributes.
					if main is None:
						nameIndex = -1
						nameSize = -1
						incompleteIndex = -1
						incompleteSize = -1
						dataIndex = -1
						dataSize = -1

						for i in range(len(streams)):
							stream = streams[i]['stream']
							fileName = stream.fileName()
							if fileName:
								size = len(fileName)
								if stream.fileNameIncomplete():
									if size > incompleteSize:
										incompleteSize = size
										incompleteIndex = i
								else:
									if size > nameSize:
										nameSize = size
										nameIndex = i
							size = stream.dataCount()
							if size > dataSize:
								dataSize = size
								dataIndex = i

						# Prefer the longest full file name first, then prefer the longest cut-off file name second, and if no file name is available, use the one with the most data attributes.
						if nameIndex >= 0: main = streams[nameIndex]
						elif incompleteIndex >= 0: main = streams[incompleteIndex]
						elif dataIndex >= 0: main = streams[dataIndex]
						else: main = streams[0]

					# Set the duplicate status.
					for item in streams:
						item['stream'].exclusionDuplicateSet(value = True)
					main['stream'].exclusionDuplicateSet(value = False)

					if len(streams) > 1:
						# Update the peers for streams that do not have them.
						# Ignore Orion peers if possible, since those values might be outdated.
						if type == Stream.SourceTypeTorrent: _excludeDuplicatePeers(streams)

						# Update the source time for streams that do not have one.
						_excludeDuplicateTime(streams)

						# Update the file size for streams that do not have one.
						_excludeDuplicateSize(streams)

						# Update the debrid cache status for streams that do not have one.
						_excludeDuplicateCache(streams)

						# Update the popularity, since the peers and source time might have changed, which might also change the popularity.
						_excludeDuplicatePopularity(streams)

					# Add streams to result.
					result.extend(streams)
		except: tools.Logger.error()
		return result

	def excludeDuplicate(self):
		return self.data(category = Settings.CategoryExclusion, attribute = Settings.AttributeDuplicate) == Settings.ExclusionExclude

	def excludeRelease(self):
		return self.data(category = Settings.CategoryExclusion, attribute = Settings.AttributeRelease) == Settings.ExclusionExclude

	def excludeKeyword(self):
		return self.data(category = Settings.CategoryExclusion, attribute = Settings.AttributeKeyword) == Settings.ExclusionExclude

	def excludeMetadata(self):
		return self.data(category = Settings.CategoryExclusion, attribute = Settings.AttributeMetadata) == Settings.ExclusionExclude

	def excludeFormat(self):
		return self.data(category = Settings.CategoryExclusion, attribute = Settings.AttributeFormat) == Settings.ExclusionExclude

	def excludeFake(self):
		return self.data(category = Settings.CategoryExclusion, attribute = Settings.AttributeFake) == Settings.ExclusionExclude

	def excludeSupport(self):
		return self.data(category = Settings.CategoryExclusion, attribute = Settings.AttributeSupport) == Settings.ExclusionExclude

	def excludeBlocked(self):
		return self.data(category = Settings.CategoryExclusion, attribute = Settings.AttributeBlocked) == Settings.ExclusionExclude

	def excludeCaptcha(self):
		return self.data(category = Settings.CategoryExclusion, attribute = Settings.AttributeCaptcha) == Settings.ExclusionExclude

	def excludePrecheck(self):
		return self.data(category = Settings.CategoryExclusion, attribute = Settings.AttributePrecheck) == Settings.ExclusionExclude

	##############################################################################
	# LIMIT
	##############################################################################

	def limit(self, items):
		limit = self.data(category = Manager.CategoryGeneral, attribute = Manager.AttributeLimit)
		if limit: items = items[:limit]
		return items

	def limitValue(self):
		return self.data(category = Manager.CategoryGeneral, attribute = Manager.AttributeLimit)


class Settings(Manager):

	SettingFilterManual		= 'scrape.filter.configuration'
	SettingFilterAutomatic	= 'playback.autoplay.configuration'
	SettingAutoplayEnabled	= 'playback.autoplay.enabled'
	SettingAutoplayFilter	= 'playback.autoplay.filter'

	Instance				= {}

	##############################################################################
	# CONSTRUCTOR
	##############################################################################

	def __init__(self, mode = Manager.ModeNone):
		self.mMode = self.settingsMode() if mode == Manager.ModeNone else mode
		self.mSettings = self.settingsFilter() if mode == Manager.ModeNone else self.settingsId(self.mMode)
		Manager.__init__(self,
			data = self.settingsGet(),
			enabledSort = True,
			enabledLimit = True,
			enabledMedia = False,
			enabledExclusion = True,
		)

	@classmethod
	def instance(self, mode = Manager.ModeNone):
		modeNone = mode == Manager.ModeNone # Otherwise when autoplay is enabled with reusing the manual filters, it does not load the manual filter settings, but the autoplay filter settings instead.
		mode = self.settingsMode() if mode == Manager.ModeNone else mode
		if not mode in Settings.Instance: Settings.Instance[mode] = Settings(mode = Manager.ModeNone if modeNone else mode)
		return Settings.Instance[mode]

	@classmethod
	def reset(self, settings = True):
		if settings:
			Settings.Instance = {}

	##############################################################################
	# GENERAL
	##############################################################################

	def show(self, settings = True):
		data = Manager.show(self)
		self.settingsSet(data)
		if settings: self.settingsLaunch()

	##############################################################################
	# SETTINGS
	##############################################################################

	def settingsGet(self):
		return tools.Settings.getData(id = self.mSettings)

	def settingsSet(self, data):
		default = self._dataDefaultIs(data = data)
		tools.Settings.setData(id = self.mSettings, value = data, label = 33564 if default else 35233)

	def settingsLaunch(self):
		tools.Settings.launchData(self.settingsId(self.mMode))

	@classmethod
	def settingsId(self, mode):
		return Settings.SettingFilterAutomatic if mode == Manager.ModeAutomatic else Settings.SettingFilterManual

	@classmethod
	def settingsMode(self):
		return Manager.ModeAutomatic if tools.Settings.getBoolean(Settings.SettingAutoplayEnabled) else Manager.ModeManual

	@classmethod
	def settingsModeManual(self):
		return not self.settingsModeAutomatic()

	@classmethod
	def settingsModeAutomatic(self):
		return tools.Settings.getBoolean(Settings.SettingAutoplayEnabled)

	@classmethod
	def settingsFilter(self):
		return self.settingsId(Manager.ModeAutomatic if tools.Settings.getBoolean(Settings.SettingAutoplayEnabled) and tools.Settings.getInteger(Settings.SettingAutoplayFilter) == 1 else Manager.ModeManual)

	@classmethod
	def settingsFilterDefault(self):
		settings = self.settingsFilter()
		return tools.Settings.defaultIs(settings) or tools.Settings.getDataLabel(settings) == interface.Translation.string(33564)


class Filters(Manager):

	Property	= 'GaiaFilters'

	Instance	= {}

	##############################################################################
	# CONSTRUCTOR
	##############################################################################

	def __init__(self, mode = Manager.ModeNone):
		data = self.settingsGet()
		if data is None: data = Settings.instance(mode = mode).settingsGet() # Specifically check for None, since the Default option changes the data to {}.
		Manager.__init__(self,
			data = data,
			enabledSort = True,
			enabledLimit = True,
			enabledMedia = False,
			enabledExclusion = True,
		)

	@classmethod
	def instance(self, mode = Manager.ModeNone):
		modeNone = mode == Manager.ModeNone # Otherwise when autoplay is enabled with reusing the manual filters, it does not load the manual filter settings, but the autoplay filter settings instead.
		mode = Settings.settingsMode() if mode == Manager.ModeNone else mode
		if not mode in Filters.Instance: Filters.Instance[mode] = Filters(mode = Manager.ModeNone if modeNone else mode)
		return Filters.Instance[mode]

	@classmethod
	def reset(self, settings = True):
		if settings:
			Filters.Instance = {}

	##############################################################################
	# GENERAL
	##############################################################################

	def show(self):
		data = Manager.show(self)
		self.settingsSet(data)

	@classmethod
	def clear(self): # Needs to be static.
		self.settingsClear()

	##############################################################################
	# SETTINGS
	##############################################################################

	def settingsGet(self):
		from lib.modules import window
		return tools.Converter.jsonFrom(window.Window.propertyGlobal(property = Filters.Property))

	def settingsSet(self, data):
		from lib.modules import window
		window.Window.propertyGlobalSet(property = Filters.Property, value = data)

	@classmethod
	def settingsClear(self):
		from lib.modules import window
		window.Window.propertyGlobalClear(property = Filters.Property)


class Termination(object):

	ModeAny			= 'any'
	ModeOverwrite	= 'overwrite'
	ModeManual		= Manager.ModeManual
	ModeAutomatic	= Manager.ModeAutomatic

	ExpressionOr	= 'or'
	ExpressionAnd	= 'and'

	DefaultLimit	= 200

	IdEnabled		= 'scrape.termination.preemption'
	IdNotification	= 'scrape.termination.preemption.notification'
	IdMode			= 'scrape.termination.preemption.mode'
	IdExpression	= 'scrape.termination.preemption.expression'
	IdCondition		= 'scrape.termination.preemption.condition'

	Instance		= None

	##############################################################################
	# CONSTRUCTOR
	##############################################################################

	def __init__(self):
		self.mEnabled = self.settingsEnabled()
		self.mNotification = None
		self.mMode = None
		self.mExpression = None
		self.mData = []
		if self.mEnabled:
			self.mNotification = self.settingsNotification()
			self.mMode = self.settingsMode()
			self.mExpression = self.settingsExpression()
			self.mData = self.settingsGet()
			if self.mData is None: self._conditionsReset()

	@classmethod
	def instance(self):
		if Termination.Instance is None: Termination.Instance = Termination()
		return Termination.Instance

	@classmethod
	def reset(self, settings = True):
		if settings:
			Termination.Instance = None

	##############################################################################
	# GENERAL
	##############################################################################

	def show(self, settings = False):
		interface.Loader.hide()
		interface.Dialog.information(title = 33882, items = self._conditions(), refresh = self._conditions, reselect = True)
		self.settingsUpdate()
		if settings: self.settingsLaunch()

	def enabled(self):
		return self.mEnabled

	def mode(self):
		return self.mMode

	def notification(self):
		return self.mNotification

	##############################################################################
	# SETTINGS
	##############################################################################

	def settingsGet(self):
		data = tools.Settings.getDataList(id = Termination.IdCondition, default = None)
		if data:
			for i in range(len(data)):
				data[i] = Manager._dataFrom(data[i])
		return data

	def settingsSet(self, data):
		label = 33564 if data == self._conditionsDefault() else ('%s (%d)' % (interface.Translation.string(35233), len(data)))
		tools.Settings.setData(id = Termination.IdCondition, value = data, label = label)

	def settingsUpdate(self):
		self.settingsSet(self.mData)

	def settingsLaunch(self):
		tools.Settings.launchData(Termination.IdCondition)

	@classmethod
	def settingsEnabled(self):
		return tools.Settings.getBoolean(Termination.IdEnabled)

	@classmethod
	def settingsMode(self):
		mode = tools.Settings.getInteger(Termination.IdMode)
		if mode == 0: return Termination.ModeAny
		elif mode == 1: return Termination.ModeManual
		elif mode == 2: return Termination.ModeAutomatic
		elif mode == 3: return Termination.ModeOverwrite
		else: return Termination.ModeAny

	@classmethod
	def settingsExpression(self):
		return Termination.ExpressionOr if tools.Settings.getInteger(Termination.IdExpression) == 0 else Termination.ExpressionAnd

	@classmethod
	def settingsNotification(self):
		return tools.Settings.getBoolean(Termination.IdNotification)

	##############################################################################
	# PROCESS
	##############################################################################

	def process(self, items, duration = None):
		try:
			if self.mData:
				expression = self.settingsExpression()
				for i in range(len(self.mData)):
					check = [item for item in items if not item['stream'].infoTerminationHas(index = i) and not item['stream'].exclusion()]

					for item in check: item['stream'].infoTerminationSet(index = i, value = False)
					manager = self._conditionsManager(data = self.mData[i])
					count, check = manager.process(items = items, duration = duration, limit = False)
					for item in check: item['stream'].infoTerminationSet(index = i, value = True)

					if sum([int(bool(item['stream'].infoTermination(index = i))) for item in items]) >= manager.limitValue():
						if expression == Termination.ExpressionOr: return True
					else:
						if expression == Termination.ExpressionAnd: return False

				return False if expression == Termination.ExpressionOr else True
		except: tools.Logger.error()
		return False

	##############################################################################
	# HELP
	##############################################################################

	def _help(self):
		condition = ' ' + interface.Translation.string(33197)
		word = interface.Format.fontBold(interface.Translation.string(33113 if self.mExpression == Termination.ExpressionOr else 33029).lower())
		bool = interface.Format.fontBold(interface.Translation.string(33118 if self.mExpression == Termination.ExpressionOr else 33872).lower())
		interface.Dialog.details(title = 33882, items = [
			{'type' : 'text', 'value' : interface.Translation.string(34202) % (word, bool.upper())},
			{'type' : 'text', 'value' : 34203},
			{'type' : 'list', 'value' : [
				{'title' : condition + '1', 'value' : 34368},
				{'title' : condition + '2', 'value' : 34369},
			]},
			{'type' : 'text', 'value' : interface.Translation.string(34370) % bool},
		])

	##############################################################################
	# CONDITION
	##############################################################################

	def _conditions(self):
		items = [
			{'title' : interface.Dialog.prefixBack(33486), 'close' : True},
			{'title' : interface.Dialog.prefixNext(33239), 'action' : self._help},
			{'title' : interface.Dialog.prefixNext(33564), 'action' : self._conditionsReset},
			{'title' : interface.Dialog.prefixNext(33013), 'action' : self._conditionsClear},
			{'title' : interface.Dialog.prefixNext(35069), 'action' : self._conditionsAdd},
		]
		count = len(self.mData)
		if count > 0:
			prefix = interface.Format.font('[%s] ' % interface.Translation.string(33873 if self.mExpression == Termination.ExpressionOr else 33872), uppercase = True, bold = True)
			items.append('')
			for i in range(count):
				title = '%s %d' % (interface.Translation.string(33197), i + 1)
				if i > 0: title = prefix + title
				items.append({'title' : title, 'action' : self._conditionEdit, 'parameters' : {'index' : i}, 'bold' : False})
		return items

	def _conditionsClear(self):
		self.mData = []

	def _conditionsDefault(self):
		return [self._conditionDefault()]

	def _conditionsReset(self):
		self._conditionsClear()
		self.mData = self._conditionsDefault()

	def _conditionsAdd(self):
		self.mData.append(self._conditionDefault())
		self._conditionEdit()

	def _conditionsManager(self, actions = None, data = None):
		return Manager(back = True, actions = actions, data = data, limit = Termination.DefaultLimit, enabledLimit = True, enabledMedia = True)

	def _conditionRemove(self, index):
		self.mData.pop(index)

	def _conditionDefault(self):
		manager = self._conditionsManager()
		manager._dataSet(category = Manager.CategoryGeneral, attribute = Manager.AttributeLimit, value = Termination.DefaultLimit)
		return manager.data()

	def _conditionEdit(self, index = None):
		if index is None: index = len(self.mData) - 1
		manager = self._conditionsManager(actions = [{
			'title' : interface.Dialog.prefixNext(35406),
			'action' : self._conditionRemove,
			'parameters' : {'index' : index},
			'close' : True,
			'return' : False,
		}], data = self.mData[index])
		result = manager.show()
		if not result is False: self.mData[index] = result # Do not do this if Remove is called.


class Layout(object):

	Instance = None

	SettingLayout		= 'label.stream.layout'
	SettingInterface	= 'interface.stream.interface'

	SettingData			= {}

	##############################################################################
	# CONSTRUCTOR
	##############################################################################

	def __init__(self):
		self.mData = None

	@classmethod
	def reset(self, settings = True):
		if settings:
			Layout.Instance = None
			Layout.SettingData = {}

	##############################################################################
	# GENERAL
	##############################################################################

	def _type(self, label):
		if label == Stream.LabelHidden: return 32302
		elif label == Stream.LabelShort: return 35110
		elif label == Stream.LabelMedium: return 33999
		elif label == Stream.LabelLong: return 35162

	def _next(self, label):
		if label == Stream.LabelHidden: return Stream.LabelShort
		elif label == Stream.LabelShort: return Stream.LabelMedium
		elif label == Stream.LabelMedium: return Stream.LabelLong
		elif label == Stream.LabelLong: return Stream.LabelHidden

	def _default(self):
		self.mData = self._dataDefault()

	def _help(self):
		interface.Dialog.details(title = 35055, items = [
			{'type' : 'text', 'value' : 34506},
			{'type' : 'list', 'value' : [
				{'title' : 32302, 'value' : 34507},
				{'title' : 35110, 'value' : 34508},
				{'title' : 33999, 'value' : 34509},
				{'title' : 35162, 'value' : 34510},
			]},
		])

	def _items(self):
		data = self.mData
		if not data: data = self._dataDefault()

		result = [
			{'title' : interface.Dialog.prefixBack(33486), 'close' : True},
			{'title' : interface.Dialog.prefixNext(33239), 'action' : self._help},
			{'title' : interface.Dialog.prefixNext(33564), 'action' : self._default},
		]

		manager = Manager(enabledNumber = True)
		for category, option in manager._options().items():
			items = []
			for attribute, value in option['attribute'].items():
				if value['layout']['enabled']:
					items.append({'title' : value['title'], 'action' : self._dataSet, 'value' : self._type(data[category][attribute]), 'parameters' : {'category' : category, 'attribute' : attribute}})
			if items: result.append({'title' : option['title'], 'items' : items})

		return result

	##############################################################################
	# SETTINGS
	##############################################################################

	@classmethod
	def settingsInterface(self):
		try:
			return Layout.SettingData[Layout.SettingInterface]
		except:
			layout = tools.Settings.getInteger(Layout.SettingInterface)
			if layout == 0: label = Stream.LabelList1
			elif layout == 1: label = Stream.LabelList2
			elif layout == 2: label = Stream.LabelList3
			else: label = Stream.LabelList4
			Layout.SettingData[Layout.SettingInterface] = label
			return label

	def _settings(self):
		return tools.Settings.getData(Layout.SettingLayout)

	def _settingsUpdate(self):
		# Reset to {}, and not the default values, since we want to adjust the default values, depending on which navigation type the user specified in the settings.
		default = not self.mData or self.mData == self._dataDefault()
		label = interface.Translation.string(33564 if default else 35233)
		tools.Settings.setData(id = Layout.SettingLayout, value = {} if default else self.mData, label = label)

	def _settingsLaunch(self):
		tools.Settings.launchData(Layout.SettingLayout)

	##############################################################################
	# DATA
	##############################################################################

	@classmethod
	def data(self, category, attribute):
		# Use a try-catch statement, since it is faster than an if-statement.
		try:
			data = Layout.Instance._data()
		except:
			Layout.Instance = self()
			data = Layout.Instance._data()
		return data[category][attribute]

	def _data(self):
		if self.mData is None:
			self.mData = self._settings()
			if not self.mData: self.mData = self._dataDefault()
		return self.mData

	def _dataSet(self, category, attribute):
		if self.mData is None: self.mData = {}
		self.mData[category][attribute] = self._next(self.mData[category][attribute])

	def _dataDefault(self):
		label = self.settingsInterface()
		result = {}
		manager = Manager(enabledNumber = True)
		for category, option in manager._options().items():
			items = {}
			for attribute, value in option['attribute'].items():
				if value['layout']['enabled']:
					try: default = value['layout']['default']['value']
					except: default = manager._optionResolve(value['label'])[Stream.LabelDefault][label]
					items[attribute] = default
			if items: result[category] = items

		return result

	##############################################################################
	# SHOW
	##############################################################################

	def show(self, settings = False):
		self._data()
		interface.Dialog.information(title = 35055, refresh = self._items, reselect = True)
		self._settingsUpdate()
		if settings: self._settingsLaunch()


# Online resources:
#	MetaInfo: +- 50KB
#	FFmpeg: +- 300KB - 400KB
#	Manual: +- 250KB
#	Samba/Network: 3MB
class Extractor(object):

	CommandInitialized = False
	CommandMediainfo = None
	CommandFfmpeg = None

	SizeOnline = 2097152 # 1MB - 1MB is too little for most files.
	SizeLocal = 5242880 # 5MB

	def __init__(self, sizeMaximum = SizeOnline): # sizeMaximum is the maximum size to retrive if the file is online.
		import math

		self.mTemporaryPath = None
		self.mSizeMaximum = sizeMaximum
		if self.mSizeMaximum <= sizeMaximum:
			self.mSizeChunk = int(math.floor(self.mSizeMaximum / 4))
		else:
			self.mSizeChunk = int(math.floor(self.mSizeMaximum / 8))

		if not Extractor.CommandInitialized:
			Extractor.CommandMediainfo = self.__detectMediainfo()
			if Extractor.CommandMediainfo:
				Extractor.CommandMediainfo += self.__parametersMediainfo()
			Extractor.CommandFfmpeg = self.__detectFfmpeg()
			if Extractor.CommandFfmpeg:
				Extractor.CommandFfmpeg += self.__parametersFfmpeg()
			Extractor.CommandInitialized = True

	def __del__(self):
		self.__stop()
		self.__delete()

	def __delete(self):
		if self.mTemporaryPath:
			return tools.File.delete(self.mTemporaryPath, force = True)
		return False

	def __emptyDictionary(self, dictionary):
		return len(dictionary) == 0

	def __concatenateDictionary(self, dictionary1, dictionary2, dictionary3):
		if not dictionary1: dictionary1 = {}
		if not dictionary2: dictionary2 = {}
		if not dictionary3: dictionary3 = {}

		# Only updates values if non-exisitng. Updates from back to front.
		dictionary = tools.Tools.dictionaryMerge(dictionary3, dictionary2)
		dictionary = tools.Tools.dictionaryMerge(dictionary, dictionary1)
		return dictionary

	def __fullStream(self, metadata):
		return not metadata == None and 'video' in metadata and 'audio' in metadata

	def __execute(self, command, timeout = 30):
		try:
			self.mProcess = None
			self.mResult = None
			def run():
				try:
					self.mProcess = tools.Subprocess.open(command, communicate = False)
					self.mResult = self.mProcess.stdout.read()
					self.mResult = tools.Converter.unicode(self.mResult)
				except: pass

			thread = Pool.thread(target = run)
			thread.start()
			thread.join(timeout)
			if thread.is_alive():
				try:
					self.__stop()
					thread.join()
				except: pass

			return self.mResult if self.mResult else ''
		except:
			return ''

	def __stop(self):
		try:
			import signal
			processId = self.mProcess.pid
			self.mProcess.terminate()
			self.mProcess.kill()
			os.killpg(processId, signal.SIGKILL) # Force kill by OS, aka Ctrl-C.
		except:
			pass

	def __detectMediainfo(self):
		result = self.__execute('mediainfo').lower()
		if 'mediainfo' in result and '--help' in result: # Nativley installed
			return 'mediainfo'
		elif tools.Extension.installed(id = tools.Extension.IdGaiaBinaries, enabled = True):
			import sys

			prefix = None
			path = path = os.path.join(tools.System.pathBinaries(), 'resources', 'data', 'mediainfo')

			if sys.platform == 'win32' or sys.platform == 'win64' or sys.platform == 'windows':
				path = os.path.join(path, 'windows', 'mediainfo.exe')
			elif sys.platform == 'darwin' or sys.platform == 'mac' or sys.platform == 'macosx':
				path = os.path.join(path, 'mac', 'mediainfo')
			else:
				# LD_LIBRARY_PATH to load the libraries from same directory instead of common library path.
				import platform
				machine = platform.machine().lower()
				architecture, _ = platform.architecture()
				architecture = architecture.lower()

				name = ''
				bits = ''
				if 'arm' in machine or 'arch' in machine: name = 'arm'
				if '64' in architecture or '64' in machine: bits = '64'
				else: bits = '32'
				path = os.path.join(path, 'linux' + name + bits)
				prefix = 'LD_LIBRARY_PATH=' + path
				path = os.path.join(path, 'mediainfo')

			if os.path.exists(path):
				if prefix: path = prefix + ' ' + path
				result = self.__execute(path).lower()
				if 'mediainfo' in result and '--help' in result: return path
		return None

	def __detectFfmpeg(self):
		if 'ffprobe version' in self.__execute('ffprobe'): # Nativley installed
			return 'ffprobe'
		else:
			return None

	def __parametersMediainfo(self):
		return ' --Output=JSON --Full "%s"'

	def __parametersFfmpeg(self):
		return ' -loglevel quiet -print_format json -show_format -show_streams -show_error "%s"'

	def __extractChunked(self, link, single = False, timeout = 30, networked = False):
		result = None
		self.mTemporaryPath = tools.System.temporaryRandom(directory = 'metadata')

		result = None
		if networked:
			tools.File.copy(link, self.mTemporaryPath, Extractor.SizeLocal)
		else:
			data = ''
			while len(data) < self.mSizeMaximum:
				dataNew = network.Networker().requestBytes(link = link, range = (len(data), self.mSizeChunk), timeout = timeout)
				if dataNew:
					data += dataNew
					f = open(self.mTemporaryPath, 'w+')
					f.write(data)
					f.close()

					result = self.extractMediainfo(self.mTemporaryPath, timeout = timeout)
					if not self.__fullStream(result):
						result = self.extractFfmpeg(self.mTemporaryPath, timeout = timeout)
						if not self.__fullStream(result):
							result = self.extractHachoir(self.mTemporaryPath)
					if self.__fullStream(result):
						break
				else:
					break
				if single:
					break

		if not self.__fullStream(result):
			result1 = self.extractMediainfo(self.mTemporaryPath, timeout = timeout)
			result2 = self.extractFfmpeg(self.mTemporaryPath, timeout = timeout)
			result3 = self.extractHachoir(self.mTemporaryPath)
			result = self.__concatenateDictionary(result1, result2, result3)

		# Will only show the info of the downloaded chunk, instead of the actual file.
		if 'size' in result:
			del result['size']
		if 'name' in result:
			del result['name']

		self.__delete()
		return result

	def extract(self, pathOrLink, timeout = 30):
		result = {}
		if not tools.Tools.isString(pathOrLink):
			return result

		try:
			if tools.File.network(pathOrLink):
				result = self.__extractChunked(link = pathOrLink, networked = True)
			else:
				isLink = pathOrLink.startswith('http:') or pathOrLink.startswith('https:') or pathOrLink.startswith('ftp:') or pathOrLink.startswith('ftps:')
				if isLink:
					# Do not use MediaInfo and FFmpeg both, since they are both slow. Rather fallback to manual.
					timer = tools.Time(start = True)
					if Extractor.CommandMediainfo:
						result = self.extractMediainfo(pathOrLink, timeout = timeout)
					elif Extractor.CommandFfmpeg:
						result = self.extractMediainfo(pathOrLink, timeout = timeout)
					ellapsed = timer.elapsed()

					if not result or self.__emptyDictionary(result):
						timeout = int(timeout / 2)
						result = self.__extractChunked(pathOrLink, single = (ellapsed > timeout), timeout = timeout)

				else:
					result1 = self.extractMediainfo(pathOrLink, timeout = timeout)
					result2 = self.extractFfmpeg(pathOrLink, timeout = timeout)
					result3 = self.extractHachoir(pathOrLink)
					result = self.__concatenateDictionary(result1, result2, result3)
		except:
			tools.Logger.error()
		return result

	def extractMediainfo(self, pathOrLink, timeout = 30):
		if not Extractor.CommandMediainfo:
			return None
		try:
			data = self.__execute(Extractor.CommandMediainfo % pathOrLink, timeout = timeout)
			return self.__parseMediainfo(data)
		except:
			return None

	def extractFfmpeg(self, pathOrLink, timeout = 30):
		if not Extractor.CommandFfmpeg:
			return None
		try:
			data = self.__execute(Extractor.CommandFfmpeg % pathOrLink, timeout = timeout)
			data = tools.Converter.jsonFrom(data)
			return self.__parseFfmpeg(data)
		except:
			return None

	def extractHachoir(self, path):
		try:
			return self.__parseHachoir(path)
		except:
			return None

	def __parseMediainfo(self, data):
		try:
			info = {'video' : {}, 'audio' : {}, 'subtitle' : {}}
			data = tools.Converter.jsonFrom(data)

			for track in data['media']['track']:
				# General
				if track['@type'] == 'General':
					try:
						value = track['FileNameExtension']
						if value: info['name'] = value
					except: pass

					try:
						value = track['FileSize']
						if value: info['size'] = int(value)
					except: pass

					try:
						value = track['Format_Extensions']
						if value: info['container'] = value
					except: pass

					try:
						value = track['Duration']
						if value: info['duration'] = int(value)
					except: pass

					try:
						value = track['OverallBitRate']
						if value: info['bitrate'] = int(value)
					except: pass

					try:
						value = track['InternetMediaType']
						if value: info['mime'] = value
					except: pass

				# Video
				elif track['@type'] == 'Video':
					if not 'mime' in info['video'] or not info['video']['mime']:
						try:
							value = track['InternetMediaType']
							if value: info['video']['mime'] = value
						except: pass

					if not 'width' in info['video'] or not info['video']['width']:
						try:
							value = track['Width']
							if value: info['video']['width'] = int(value)
						except: pass

					if not 'height' in info['video'] or not info['video']['height']:
						try:
							value = track['Height']
							if value: info['video']['height'] = int(value)
						except: pass

					if not 'codec' in info['video'] or not info['video']['codec']:
						try:
							value = track['Format_Commercial']
							if not value: value = ''
							extra = track['Format_String']
							if extra and not extra in value: value = (value + ' ' + extra).strip()
							if value: info['video']['codec'] = value
						except: pass

					if not 'aspectratio' in info['video'] or not info['video']['aspectratio']:
						try:
							value = track['DisplayAspectRatio']
							if value: info['video']['aspectratio'] = round(float(value), 3)
						except: pass

					if not 'bitrate' in info['video'] or not info['video']['bitrate']:
						try:
							value = track['BitRate']
							if value: info['video']['bitrate'] = int(value)
						except: pass

					if not 'bitdepth' in info['video'] or not info['video']['bitdepth']:
						try:
							value = track['BitDepth']
							if value: info['video']['bitdepth'] = int(value)
						except: pass

					if not 'framerate' in info['video'] or not info['video']['framerate']:
						try:
							value = track['FrameRate']
							if value: info['video']['framerate'] = round(float(value), 3)
						except: pass

					if not 'framecount' in info['video'] or not info['video']['framecount']:
						try:
							value = track['FrameCount']
							if value: info['video']['framecount'] = int(value)
						except: pass

				# Audio
				elif track['@type'] == 'Audio':
					if not 'mime' in info['audio'] or not info['audio']['mime']:
						try:
							value = track['InternetMediaType']
							if value: info['audio']['mime'] = value
						except: pass

					if not 'channels' in info['audio'] or not info['audio']['channels']:
						try:
							value = track['Channels']
							if value: info['audio']['channels'] = int(value)
						except: pass

					if not 'codec' in info['audio'] or not info['audio']['codec']:
						try:
							value = track['Format_Commercial']
							if not value: value = ''
							extra = track['Format_String']
							if extra and not extra in value: value = (value + ' ' + extra).strip()
							if value: info['audio']['codec'] = value
						except: pass

					if not 'bitrate' in info['audio'] or not info['audio']['bitrate']:
						try:
							value = track['BitRate']
							if value: info['audio']['bitrate'] = int(value)
						except: pass

					if not 'samplerate' in info['audio'] or not info['audio']['samplerate']:
						try:
							value = track['SamplingRate']
							if value: info['audio']['samplerate'] = int(value)
						except: pass

					if not 'language' in info['audio']: info['audio']['language'] = []
					try:
						value = track['Language']
						if value: info['audio']['language'].append(value)
					except: pass

				# Subtitle
				elif track['@type'] == 'Text':
					if not 'language' in info['subtitle']: info['subtitle']['language'] = []
					try:
						value = track['Language']
						if value: info['subtitle']['language'].append(value)
					except: pass

			# Partial Files
			for track in data['media']['track']:
				# General
				if track['@type'] == 'General':
					if not 'codec' in info['video'] or not info['video']['codec']:
						try:
							value = track['Video_Format_List']
							if value: info['video']['codec'] = value
						except: pass
					if not 'codec' in info['audio'] or not info['audio']['codec']:
						try:
							value = track['Audio_Format_List']
							if value: info['audio']['codec'] = value
						except: pass

			if self.__emptyDictionary(info):
				info = None
			return info
		except:
			return None

	def __parseFfmpeg(self, data):
		try:
			info = {}
			indexVideo = None
			indexAudio = None
			indexSubtitle = None

			try:
				for item in data['streams']:
					if item['codec_type'] == 'video':
						indexVideo = item['index']
						break
			except: pass

			try:
				for item in data['streams']:
					if item['codec_type'] == 'audio':
						indexAudio = item['index']
						break
			except: pass

			try:
				for item in data['streams']:
					if item['codec_type'] == 'subtitle':
						indexSubtitle = item['index']
						break
			except: pass

			# File

			try: info['name'] = os.path.basename(data['format']['filename'])
			except: pass
			try: info['container'] = data['format']['format_name']
			except: pass
			try: info['size'] = int(data['format']['size'])
			except: pass
			try: info['duration'] = int(data['format']['duration'])
			except: pass
			try: info['bitrate'] = int(data['format']['bit_rate'])
			except: pass

			# Video

			if not indexVideo == None:
				infoVideo = {}
				try: infoVideo['codec'] = data['streams'][indexVideo]['codec_name']
				except: pass
				try: infoVideo['bitrate'] = int(data['streams'][indexVideo]['bit_rate'])
				except: pass
				try: infoVideo['width'] = int(data['streams'][indexVideo]['width'])
				except: pass
				try: infoVideo['height'] = int(data['streams'][indexVideo]['height'])
				except: pass
				try:
					aspectratio = data['streams'][indexVideo]['display_aspect_ratio']
					aspectratio = aspectratio.split(':')
					aspectratio = float(aspectratio[0]) / float(aspectratio[1])
					aspectratio = round(aspectratio, 3)
					infoVideo['aspectratio'] = aspectratio
				except: pass
				try:
					framerate = data['streams'][indexVideo]['r_frame_rate']
					framerate = framerate.split('/')
					framerate = float(framerate[0]) / float(framerate[1])
					framerate = round(framerate, 3)
					infoVideo['framerate'] = framerate
				except: pass
				try: infoVideo['framecount'] = int(data['streams'][indexVideo]['nb_read_frames'])
				except: pass
				if not self.__emptyDictionary(infoVideo):
					info['video'] = infoVideo

			# Audio

			if not indexAudio == None:
				infoAudio = {}
				try: infoAudio['codec'] = data['streams'][indexAudio]['codec_name']
				except: pass
				try: infoAudio['bitrate'] = int(data['streams'][indexAudio]['bit_rate'])
				except: pass
				try: infoAudio['channels'] = int(data['streams'][indexAudio]['channels'])
				except: pass
				try: infoAudio['samplerate'] = int(data['streams'][indexAudio]['sample_rate'])
				except: pass
				if not self.__emptyDictionary(infoAudio):
					info['audio'] = infoAudio

			# Subtitle

			if not indexSubtitle == None:
				info['subtitle'] = True

			if self.__emptyDictionary(info):
				info = None
			return info
		except:
			return None

	def __parseHachoir(self, path):
		try:
			from lib.modules.external import Importer
			HachoirParser = Importer.moduleHachoirParser()
			HachoirMetadata = Importer.moduleHachoirMetadata()

			info = {}
			parser = HachoirParser(tools.Converter.unicode(path))
			if parser:
				try: metadata = HachoirMetadata(parser)
				except: metadata = None
				if metadata:

					# File

					for item in metadata:

						if item.key == 'filename':
							try: info['name'] = os.path.basename(item.values[0].value)
							except: pass
						elif item.key == 'title' and (not 'name' in info or not info['name'] or info['name'] == ''):
							try: info['name'] = item.values[0].value
							except: pass
						elif item.key == 'file_type':
							try: info['container'] = item.values[0].value
							except: pass
						elif item.key == 'mime_type':
							try: info['mime'] = item.values[0].value
							except: pass
						elif item.key == 'file_size':
							try: info['size'] = item.values[0].value
							except: pass
						elif item.key == 'duration':
							try: info['duration'] = int(item.values[0].value.total_seconds())
							except: pass
						elif item.key == 'bit_rate':
							try: info['bitrate'] = item.values[0].value
							except: pass

					try: groups = metadata.groups()
					except: groups = None

					if groups:
						for key, value in groups.items():

							# Video

							if 'video' in key:
								infoVideo = {}
								for item in value:
									if item.key == 'compression':
										try: infoVideo['codec'] = item.values[0].value
										except: pass
									if item.key == 'bit_rate':
										try: infoVideo['bitrate'] = int(item.values[0].value)
										except: pass
									if item.key == 'width':
										try: infoVideo['width'] = int(item.values[0].value)
										except: pass
									if item.key == 'height':
										try: infoVideo['height'] = int(item.values[0].value)
										except: pass
									if item.key == 'aspect_ratio':
										try: infoVideo['aspectratio'] = item.values[0].value
										except: pass
									if item.key == 'frame_rate':
										try: infoVideo['framerate'] = round(item.values[0].value, 3)
										except: pass
								if not self.__emptyDictionary(infoVideo):
									info['video'] = infoVideo

							# Audio

							if 'audio' in key:
								infoAudio = {}
								for item in value:
									if item.key == 'compression':
										try: infoAudio['codec'] = item.values[0].value
										except: pass
									if item.key == 'bit_rate':
										try: infoAudio['bitrate'] = int(item.values[0].value)
										except: pass
									if item.key == 'nb_channel':
										try: infoAudio['channels'] = int(item.values[0].value)
										except: pass
									if item.key == 'sample_rate':
										try: infoAudio['samplerate'] = int(item.values[0].value)
										except: pass
								if not self.__emptyDictionary(infoAudio):
									info['audio'] = infoAudio

							# Subtitle

							if 'subtitle' in key:
								info['subtitle'] = True

			# Hachoir only closes files in Python 3, not in Python 2. Manually close it, otherwise the file cannot be deleted.
			# https://bitbucket.org/haypo/hachoir/issues/33/open-file-handles-never-closed
			try: parser.stream._input.close()
			except: pass

			if self.__emptyDictionary(info): info = None
			return info
		except:
			return None
