diff --git a/DeleteSamples.py b/DeleteSamples.py index 5d9abe99..03956f6c 100755 --- a/DeleteSamples.py +++ b/DeleteSamples.py @@ -32,8 +32,6 @@ import os import sys import nzbtomedia -from nzbtomedia.nzbToMediaUtil import joinPath - def is_sample(filePath, inputName, maxSampleSize, SampleIDs): # 200 MB in bytes @@ -103,7 +101,7 @@ if os.environ.has_key('NZBOP_SCRIPTDIR') and not os.environ['NZBOP_VERSION'][0:5 for dirpath, dirnames, filenames in os.walk(os.environ['NZBPP_DIRECTORY']): for file in filenames: - filePath = joinPath(dirpath, file) + filePath = os.path.join(dirpath, file) fileName, fileExtension = os.path.splitext(file) if fileExtension in mediaContainer: # If the file is a video file diff --git a/ResetDateTime.py b/ResetDateTime.py index d5d88f02..fc2df369 100755 --- a/ResetDateTime.py +++ b/ResetDateTime.py @@ -15,7 +15,6 @@ import os import sys import nzbtomedia -from nzbtomedia.nzbToMediaUtil import joinPath if os.environ.has_key('NZBOP_SCRIPTDIR') and not os.environ['NZBOP_VERSION'][0:5] < '11.0': print "Script triggered from NZBGet (11.0 or later)." @@ -67,7 +66,7 @@ if os.environ.has_key('NZBOP_SCRIPTDIR') and not os.environ['NZBOP_VERSION'][0:5 directory = os.path.normpath(os.environ['NZBPP_DIRECTORY']) for dirpath, dirnames, filenames in os.walk(directory): for file in filenames: - filepath = joinPath(dirpath, file) + filepath = os.path.join(dirpath, file) print "reseting datetime for file", filepath try: os.utime(filepath, None) diff --git a/TorrentToMedia.py b/TorrentToMedia.py index bd59afb7..0a29a832 100755 --- a/TorrentToMedia.py +++ b/TorrentToMedia.py @@ -4,7 +4,6 @@ import os import time import shutil import sys -import platform import nzbtomedia from subprocess import Popen @@ -55,7 +54,7 @@ def processTorrent(inputDirectory, inputName, inputCategory, inputHash, inputID, if inputCategory == "": inputCategory = "UNCAT" - outputDestination = os.path.normpath(nzbtomedia.joinPath(nzbtomedia. OUTPUTDIRECTORY, inputCategory, nzbtomedia.sanitizeFileName(inputName))) + outputDestination = os.path.normpath(nzbtomedia.os.path.join(nzbtomedia.OUTPUTDIRECTORY, inputCategory, nzbtomedia.sanitizeName(inputName))) logger.info("Output directory set to: %s" % (outputDestination)) @@ -74,27 +73,25 @@ def processTorrent(inputDirectory, inputName, inputCategory, inputHash, inputID, if nzbtomedia.CFG["HeadPhones"][inputCategory]: nzbtomedia.NOFLATTEN.extend(nzbtomedia.CFG["HeadPhones"].sections) # Make sure we preserve folder structure for HeadPhones. - outputDestinationMaster = outputDestination # Save the original, so we can change this within the loop below, and reset afterwards. now = datetime.datetime.now() inputFiles = nzbtomedia.listMediaFiles(inputDirectory) logger.debug("Found %s files in %s" % (str(len(inputFiles)), inputDirectory)) for inputFile in inputFiles: - fileDirPath = os.path.dirname(inputFile) + filePath = os.path.dirname(inputFile) fileName, fileExt = os.path.splitext(os.path.basename(inputFile)) fullFileName = os.path.basename(inputFile) + targetFile = nzbtomedia.os.path.join(outputDestination, fullFileName) if inputCategory in nzbtomedia.NOFLATTEN: - if not fileDirPath == outputDestinationMaster: - outputDestination = nzbtomedia.joinPath(outputDestinationMaster, fileDirPath) # join this extra directory to output. - logger.debug("Setting outputDestination to %s to preserve folder structure" % (outputDestination)) - - targetDirectory = nzbtomedia.joinPath(outputDestination, fullFileName) + if not os.path.basename(filePath) in outputDestination: + targetFile = nzbtomedia.os.path.join(nzbtomedia.os.path.join(outputDestination, os.path.basename(filePath)), fullFileName) + logger.debug("Setting outputDestination to %s to preserve folder structure" % (os.path.dirname(targetFile))) if root == 1: if not foundFile: logger.debug("Looking for %s in: %s" % (inputName, fullFileName)) - if (nzbtomedia.sanitizeFileName(inputName) in nzbtomedia.sanitizeFileName(fullFileName)) or (nzbtomedia.sanitizeFileName(fileName) in nzbtomedia.sanitizeFileName(inputName)): + if (nzbtomedia.sanitizeName(inputName) in nzbtomedia.sanitizeName(fullFileName)) or (nzbtomedia.sanitizeName(fileName) in nzbtomedia.sanitizeName(inputName)): foundFile = True logger.debug("Found file %s that matches Torrent Name %s" % (fullFileName, inputName)) else: @@ -115,19 +112,14 @@ def processTorrent(inputDirectory, inputName, inputCategory, inputHash, inputID, if Torrent_NoLink == 0: try: - nzbtomedia.copy_link(inputFile, targetDirectory, nzbtomedia.USELINK, outputDestination) - copy_list.append([inputFile, nzbtomedia.joinPath(outputDestination, fullFileName)]) + nzbtomedia.copy_link(inputFile, targetFile, nzbtomedia.USELINK) + nzbtomedia.rmReadOnly(targetFile) except: - logger.error("Failed to link file: %s" % (fullFileName)) - - outputDestination = outputDestinationMaster # Reset here. + logger.error("Failed to link: %s to %s" % (inputFile, targetFile)) if not inputCategory in nzbtomedia.NOFLATTEN: #don't flatten hp in case multi cd albums, and we need to copy this back later. nzbtomedia.flatten(outputDestination) - if platform.system() == 'Windows': # remove Read Only flag from files in Windows. - nzbtomedia.remove_read_only(outputDestination) - if nzbtomedia.CFG[section][inputCategory]['extract'] == 1: logger.debug('Checking for archives to extract in directory: %s' % (outputDestination)) nzbtomedia.extractFiles(outputDestination) @@ -148,7 +140,6 @@ def processTorrent(inputDirectory, inputName, inputCategory, inputHash, inputID, else: logger.warning("Found no media files in %s" % outputDestination) - # Only these sections can handling failed downloads so make sure everything else gets through without the check for failed if not nzbtomedia.CFG['CouchPotato','SickBeard','NzbDrone'][inputCategory]: status = 0 @@ -208,7 +199,7 @@ def external_script(outputDestination, torrentName, torrentLabel): for dirpath, dirnames, filenames in os.walk(outputDestination): for file in filenames: - filePath = nzbtomedia.joinPath(dirpath, file) + filePath = nzbtomedia.os.path.join(dirpath, file) fileName, fileExtension = os.path.splitext(file) if fileExtension in nzbtomedia.USER_SCRIPT_MEDIAEXTENSIONS or "ALL" in nzbtomedia.USER_SCRIPT_MEDIAEXTENSIONS: @@ -261,7 +252,7 @@ def external_script(outputDestination, torrentName, torrentLabel): num_files_new = 0 for dirpath, dirnames, filenames in os.walk(outputDestination): for file in filenames: - filePath = nzbtomedia.joinPath(dirpath, file) + filePath = nzbtomedia.os.path.join(dirpath, file) fileName, fileExtension = os.path.splitext(file) if fileExtension in nzbtomedia.USER_SCRIPT_MEDIAEXTENSIONS or nzbtomedia.USER_SCRIPT_MEDIAEXTENSIONS == "ALL": @@ -306,7 +297,7 @@ def main(args): for section, subsection in nzbtomedia.SUBSECTIONS.items(): for category in subsection: if nzbtomedia.CFG[section][category].isenabled(): - dirNames = nzbtomedia.get_dirnames(section, category) + dirNames = nzbtomedia.getDirs(section, category) for dirName in dirNames: clientAgent = 'manual' inputHash = None diff --git a/libs/beets/__init__.py b/libs/beets/__init__.py new file mode 100644 index 00000000..17651f4b --- /dev/null +++ b/libs/beets/__init__.py @@ -0,0 +1,26 @@ +# This file is part of beets. +# Copyright 2013, Adrian Sampson. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. + +# This particular version has been slightly modified to work with headphones +# https://github.com/rembo10/headphones + +__version__ = '1.3.4' +__author__ = 'Adrian Sampson ' + +import beets.library +from beets.util import confit + +Library = beets.library.Library + +config = confit.LazyConfig('beets', __name__) diff --git a/libs/beets/autotag/__init__.py b/libs/beets/autotag/__init__.py new file mode 100644 index 00000000..a3696354 --- /dev/null +++ b/libs/beets/autotag/__init__.py @@ -0,0 +1,247 @@ +# This file is part of beets. +# Copyright 2013, Adrian Sampson. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. + +"""Facilities for automatically determining files' correct metadata. +""" +import os +import logging +import re + +from beets import library, mediafile, config +from beets.util import sorted_walk, ancestry, displayable_path + +# Parts of external interface. +from .hooks import AlbumInfo, TrackInfo, AlbumMatch, TrackMatch +from .match import tag_item, tag_album +from .match import recommendation + +# Global logger. +log = logging.getLogger('beets') + +# Constants for directory walker. +MULTIDISC_MARKERS = (r'dis[ck]', r'cd') +MULTIDISC_PAT_FMT = r'^(.*%s[\W_]*)\d' + + +# Additional utilities for the main interface. + +def albums_in_dir(path): + """Recursively searches the given directory and returns an iterable + of (paths, items) where paths is a list of directories and items is + a list of Items that is probably an album. Specifically, any folder + containing any media files is an album. + """ + collapse_pat = collapse_paths = collapse_items = None + + for root, dirs, files in sorted_walk(path, + ignore=config['ignore'].as_str_seq(), + logger=log): + # Get a list of items in the directory. + items = [] + for filename in files: + try: + i = library.Item.from_path(os.path.join(root, filename)) + except mediafile.FileTypeError: + pass + except mediafile.UnreadableFileError: + log.warn(u'unreadable file: {0}'.format( + displayable_path(filename)) + ) + else: + items.append(i) + + # If we're currently collapsing the constituent directories in a + # multi-disc album, check whether we should continue collapsing + # and add the current directory. If so, just add the directory + # and move on to the next directory. If not, stop collapsing. + if collapse_paths: + if (not collapse_pat and collapse_paths[0] in ancestry(root)) or \ + (collapse_pat and + collapse_pat.match(os.path.basename(root))): + # Still collapsing. + collapse_paths.append(root) + collapse_items += items + continue + else: + # Collapse finished. Yield the collapsed directory and + # proceed to process the current one. + if collapse_items: + yield collapse_paths, collapse_items + collapse_pat = collapse_paths = collapse_items = None + + # Check whether this directory looks like the *first* directory + # in a multi-disc sequence. There are two indicators: the file + # is named like part of a multi-disc sequence (e.g., "Title Disc + # 1") or it contains no items but only directories that are + # named in this way. + start_collapsing = False + for marker in MULTIDISC_MARKERS: + marker_pat = re.compile(MULTIDISC_PAT_FMT % marker, re.I) + match = marker_pat.match(os.path.basename(root)) + + # Is this directory the root of a nested multi-disc album? + if dirs and not items: + # Check whether all subdirectories have the same prefix. + start_collapsing = True + subdir_pat = None + for subdir in dirs: + # The first directory dictates the pattern for + # the remaining directories. + if not subdir_pat: + match = marker_pat.match(subdir) + if match: + subdir_pat = re.compile(r'^%s\d' % + re.escape(match.group(1)), re.I) + else: + start_collapsing = False + break + + # Subsequent directories must match the pattern. + elif not subdir_pat.match(subdir): + start_collapsing = False + break + + # If all subdirectories match, don't check other + # markers. + if start_collapsing: + break + + # Is this directory the first in a flattened multi-disc album? + elif match: + start_collapsing = True + # Set the current pattern to match directories with the same + # prefix as this one, followed by a digit. + collapse_pat = re.compile(r'^%s\d' % + re.escape(match.group(1)), re.I) + break + + # If either of the above heuristics indicated that this is the + # beginning of a multi-disc album, initialize the collapsed + # directory and item lists and check the next directory. + if start_collapsing: + # Start collapsing; continue to the next iteration. + collapse_paths = [root] + collapse_items = items + continue + + # If it's nonempty, yield it. + if items: + yield [root], items + + # Clear out any unfinished collapse. + if collapse_paths and collapse_items: + yield collapse_paths, collapse_items + +def apply_item_metadata(item, track_info): + """Set an item's metadata from its matched TrackInfo object. + """ + item.artist = track_info.artist + item.artist_sort = track_info.artist_sort + item.artist_credit = track_info.artist_credit + item.title = track_info.title + item.mb_trackid = track_info.track_id + if track_info.artist_id: + item.mb_artistid = track_info.artist_id + # At the moment, the other metadata is left intact (including album + # and track number). Perhaps these should be emptied? + +def apply_metadata(album_info, mapping): + """Set the items' metadata to match an AlbumInfo object using a + mapping from Items to TrackInfo objects. + """ + for item, track_info in mapping.iteritems(): + # Album, artist, track count. + if track_info.artist: + item.artist = track_info.artist + else: + item.artist = album_info.artist + item.albumartist = album_info.artist + item.album = album_info.album + + # Artist sort and credit names. + item.artist_sort = track_info.artist_sort or album_info.artist_sort + item.artist_credit = track_info.artist_credit or \ + album_info.artist_credit + item.albumartist_sort = album_info.artist_sort + item.albumartist_credit = album_info.artist_credit + + # Release date. + for prefix in '', 'original_': + if config['original_date'] and not prefix: + # Ignore specific release date. + continue + + for suffix in 'year', 'month', 'day': + key = prefix + suffix + value = getattr(album_info, key) or 0 + + # If we don't even have a year, apply nothing. + if suffix == 'year' and not value: + break + + # Otherwise, set the fetched value (or 0 for the month + # and day if not available). + item[key] = value + + # If we're using original release date for both fields, + # also set item.year = info.original_year, etc. + if config['original_date']: + item[suffix] = value + + # Title. + item.title = track_info.title + + if config['per_disc_numbering']: + item.track = track_info.medium_index or track_info.index + item.tracktotal = track_info.medium_total or len(album_info.tracks) + else: + item.track = track_info.index + item.tracktotal = len(album_info.tracks) + + # Disc and disc count. + item.disc = track_info.medium + item.disctotal = album_info.mediums + + # MusicBrainz IDs. + item.mb_trackid = track_info.track_id + item.mb_albumid = album_info.album_id + if track_info.artist_id: + item.mb_artistid = track_info.artist_id + else: + item.mb_artistid = album_info.artist_id + item.mb_albumartistid = album_info.artist_id + item.mb_releasegroupid = album_info.releasegroup_id + + # Compilation flag. + item.comp = album_info.va + + # Miscellaneous metadata. + for field in ('albumtype', + 'label', + 'asin', + 'catalognum', + 'script', + 'language', + 'country', + 'albumstatus', + 'media', + 'albumdisambig'): + value = getattr(album_info, field) + if value is not None: + item[field] = value + if track_info.disctitle is not None: + item.disctitle = track_info.disctitle + + # Headphones seal of approval + item.comments = 'tagged by headphones/beets' diff --git a/libs/beets/autotag/hooks.py b/libs/beets/autotag/hooks.py new file mode 100644 index 00000000..74c8cf82 --- /dev/null +++ b/libs/beets/autotag/hooks.py @@ -0,0 +1,545 @@ +# This file is part of beets. +# Copyright 2013, Adrian Sampson. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. + +"""Glue between metadata sources and the matching logic.""" +import logging +from collections import namedtuple +import re + +from beets import plugins +from beets import config +from beets.autotag import mb +from beets.util import levenshtein +from unidecode import unidecode + +log = logging.getLogger('beets') + + +# Classes used to represent candidate options. + +class AlbumInfo(object): + """Describes a canonical release that may be used to match a release + in the library. Consists of these data members: + + - ``album``: the release title + - ``album_id``: MusicBrainz ID; UUID fragment only + - ``artist``: name of the release's primary artist + - ``artist_id`` + - ``tracks``: list of TrackInfo objects making up the release + - ``asin``: Amazon ASIN + - ``albumtype``: string describing the kind of release + - ``va``: boolean: whether the release has "various artists" + - ``year``: release year + - ``month``: release month + - ``day``: release day + - ``label``: music label responsible for the release + - ``mediums``: the number of discs in this release + - ``artist_sort``: name of the release's artist for sorting + - ``releasegroup_id``: MBID for the album's release group + - ``catalognum``: the label's catalog number for the release + - ``script``: character set used for metadata + - ``language``: human language of the metadata + - ``country``: the release country + - ``albumstatus``: MusicBrainz release status (Official, etc.) + - ``media``: delivery mechanism (Vinyl, etc.) + - ``albumdisambig``: MusicBrainz release disambiguation comment + - ``artist_credit``: Release-specific artist name + - ``data_source``: The original data source (MusicBrainz, Discogs, etc.) + - ``data_url``: The data source release URL. + + The fields up through ``tracks`` are required. The others are + optional and may be None. + """ + def __init__(self, album, album_id, artist, artist_id, tracks, asin=None, + albumtype=None, va=False, year=None, month=None, day=None, + label=None, mediums=None, artist_sort=None, + releasegroup_id=None, catalognum=None, script=None, + language=None, country=None, albumstatus=None, media=None, + albumdisambig=None, artist_credit=None, original_year=None, + original_month=None, original_day=None, data_source=None, + data_url=None): + self.album = album + self.album_id = album_id + self.artist = artist + self.artist_id = artist_id + self.tracks = tracks + self.asin = asin + self.albumtype = albumtype + self.va = va + self.year = year + self.month = month + self.day = day + self.label = label + self.mediums = mediums + self.artist_sort = artist_sort + self.releasegroup_id = releasegroup_id + self.catalognum = catalognum + self.script = script + self.language = language + self.country = country + self.albumstatus = albumstatus + self.media = media + self.albumdisambig = albumdisambig + self.artist_credit = artist_credit + self.original_year = original_year + self.original_month = original_month + self.original_day = original_day + self.data_source = data_source + self.data_url = data_url + + # Work around a bug in python-musicbrainz-ngs that causes some + # strings to be bytes rather than Unicode. + # https://github.com/alastair/python-musicbrainz-ngs/issues/85 + def decode(self, codec='utf8'): + """Ensure that all string attributes on this object, and the + constituent `TrackInfo` objects, are decoded to Unicode. + """ + for fld in ['album', 'artist', 'albumtype', 'label', 'artist_sort', + 'catalognum', 'script', 'language', 'country', + 'albumstatus', 'albumdisambig', 'artist_credit', 'media']: + value = getattr(self, fld) + if isinstance(value, str): + setattr(self, fld, value.decode(codec, 'ignore')) + + if self.tracks: + for track in self.tracks: + track.decode(codec) + +class TrackInfo(object): + """Describes a canonical track present on a release. Appears as part + of an AlbumInfo's ``tracks`` list. Consists of these data members: + + - ``title``: name of the track + - ``track_id``: MusicBrainz ID; UUID fragment only + - ``artist``: individual track artist name + - ``artist_id`` + - ``length``: float: duration of the track in seconds + - ``index``: position on the entire release + - ``medium``: the disc number this track appears on in the album + - ``medium_index``: the track's position on the disc + - ``medium_total``: the number of tracks on the item's disc + - ``artist_sort``: name of the track artist for sorting + - ``disctitle``: name of the individual medium (subtitle) + - ``artist_credit``: Recording-specific artist name + + Only ``title`` and ``track_id`` are required. The rest of the fields + may be None. The indices ``index``, ``medium``, and ``medium_index`` + are all 1-based. + """ + def __init__(self, title, track_id, artist=None, artist_id=None, + length=None, index=None, medium=None, medium_index=None, + medium_total=None, artist_sort=None, disctitle=None, + artist_credit=None, data_source=None, data_url=None): + self.title = title + self.track_id = track_id + self.artist = artist + self.artist_id = artist_id + self.length = length + self.index = index + self.medium = medium + self.medium_index = medium_index + self.medium_total = medium_total + self.artist_sort = artist_sort + self.disctitle = disctitle + self.artist_credit = artist_credit + self.data_source = data_source + self.data_url = data_url + + # As above, work around a bug in python-musicbrainz-ngs. + def decode(self, codec='utf8'): + """Ensure that all string attributes on this object are decoded + to Unicode. + """ + for fld in ['title', 'artist', 'medium', 'artist_sort', 'disctitle', + 'artist_credit']: + value = getattr(self, fld) + if isinstance(value, str): + setattr(self, fld, value.decode(codec, 'ignore')) + + +# Candidate distance scoring. + +# Parameters for string distance function. +# Words that can be moved to the end of a string using a comma. +SD_END_WORDS = ['the', 'a', 'an'] +# Reduced weights for certain portions of the string. +SD_PATTERNS = [ + (r'^the ', 0.1), + (r'[\[\(]?(ep|single)[\]\)]?', 0.0), + (r'[\[\(]?(featuring|feat|ft)[\. :].+', 0.1), + (r'\(.*?\)', 0.3), + (r'\[.*?\]', 0.3), + (r'(, )?(pt\.|part) .+', 0.2), +] +# Replacements to use before testing distance. +SD_REPLACE = [ + (r'&', 'and'), +] + +def _string_dist_basic(str1, str2): + """Basic edit distance between two strings, ignoring + non-alphanumeric characters and case. Comparisons are based on a + transliteration/lowering to ASCII characters. Normalized by string + length. + """ + str1 = unidecode(str1) + str2 = unidecode(str2) + str1 = re.sub(r'[^a-z0-9]', '', str1.lower()) + str2 = re.sub(r'[^a-z0-9]', '', str2.lower()) + if not str1 and not str2: + return 0.0 + return levenshtein(str1, str2) / float(max(len(str1), len(str2))) + +def string_dist(str1, str2): + """Gives an "intuitive" edit distance between two strings. This is + an edit distance, normalized by the string length, with a number of + tweaks that reflect intuition about text. + """ + if str1 == None and str2 == None: return 0.0 + if str1 == None or str2 == None: return 1.0 + + str1 = str1.lower() + str2 = str2.lower() + + # Don't penalize strings that move certain words to the end. For + # example, "the something" should be considered equal to + # "something, the". + for word in SD_END_WORDS: + if str1.endswith(', %s' % word): + str1 = '%s %s' % (word, str1[:-len(word)-2]) + if str2.endswith(', %s' % word): + str2 = '%s %s' % (word, str2[:-len(word)-2]) + + # Perform a couple of basic normalizing substitutions. + for pat, repl in SD_REPLACE: + str1 = re.sub(pat, repl, str1) + str2 = re.sub(pat, repl, str2) + + # Change the weight for certain string portions matched by a set + # of regular expressions. We gradually change the strings and build + # up penalties associated with parts of the string that were + # deleted. + base_dist = _string_dist_basic(str1, str2) + penalty = 0.0 + for pat, weight in SD_PATTERNS: + # Get strings that drop the pattern. + case_str1 = re.sub(pat, '', str1) + case_str2 = re.sub(pat, '', str2) + + if case_str1 != str1 or case_str2 != str2: + # If the pattern was present (i.e., it is deleted in the + # the current case), recalculate the distances for the + # modified strings. + case_dist = _string_dist_basic(case_str1, case_str2) + case_delta = max(0.0, base_dist - case_dist) + if case_delta == 0.0: + continue + + # Shift our baseline strings down (to avoid rematching the + # same part of the string) and add a scaled distance + # amount to the penalties. + str1 = case_str1 + str2 = case_str2 + base_dist = case_dist + penalty += weight * case_delta + + return base_dist + penalty + +class Distance(object): + """Keeps track of multiple distance penalties. Provides a single + weighted distance for all penalties as well as a weighted distance + for each individual penalty. + """ + def __init__(self): + self._penalties = {} + + weights_view = config['match']['distance_weights'] + self._weights = {} + for key in weights_view.keys(): + self._weights[key] = weights_view[key].as_number() + + + # Access the components and their aggregates. + + @property + def distance(self): + """Return a weighted and normalized distance across all + penalties. + """ + dist_max = self.max_distance + if dist_max: + return self.raw_distance / self.max_distance + return 0.0 + + @property + def max_distance(self): + """Return the maximum distance penalty (normalization factor). + """ + dist_max = 0.0 + for key, penalty in self._penalties.iteritems(): + dist_max += len(penalty) * self._weights[key] + return dist_max + + @property + def raw_distance(self): + """Return the raw (denormalized) distance. + """ + dist_raw = 0.0 + for key, penalty in self._penalties.iteritems(): + dist_raw += sum(penalty) * self._weights[key] + return dist_raw + + def items(self): + """Return a list of (key, dist) pairs, with `dist` being the + weighted distance, sorted from highest to lowest. Does not + include penalties with a zero value. + """ + list_ = [] + for key in self._penalties: + dist = self[key] + if dist: + list_.append((key, dist)) + # Convert distance into a negative float we can sort items in + # ascending order (for keys, when the penalty is equal) and + # still get the items with the biggest distance first. + return sorted(list_, key=lambda (key, dist): (0-dist, key)) + + + # Behave like a float. + + def __cmp__(self, other): + return cmp(self.distance, other) + + def __float__(self): + return self.distance + def __sub__(self, other): + return self.distance - other + + def __rsub__(self, other): + return other - self.distance + + + # Behave like a dict. + + def __getitem__(self, key): + """Returns the weighted distance for a named penalty. + """ + dist = sum(self._penalties[key]) * self._weights[key] + dist_max = self.max_distance + if dist_max: + return dist / dist_max + return 0.0 + + def __iter__(self): + return iter(self.items()) + + def __len__(self): + return len(self.items()) + + def keys(self): + return [key for key, _ in self.items()] + + def update(self, dist): + """Adds all the distance penalties from `dist`. + """ + if not isinstance(dist, Distance): + raise ValueError( + '`dist` must be a Distance object. It is: %r' % dist) + for key, penalties in dist._penalties.iteritems(): + self._penalties.setdefault(key, []).extend(penalties) + + + # Adding components. + + def _eq(self, value1, value2): + """Returns True if `value1` is equal to `value2`. `value1` may + be a compiled regular expression, in which case it will be + matched against `value2`. + """ + if isinstance(value1, re._pattern_type): + return bool(value1.match(value2)) + return value1 == value2 + + def add(self, key, dist): + """Adds a distance penalty. `key` must correspond with a + configured weight setting. `dist` must be a float between 0.0 + and 1.0, and will be added to any existing distance penalties + for the same key. + """ + if not 0.0 <= dist <= 1.0: + raise ValueError( + '`dist` must be between 0.0 and 1.0. It is: %r' % dist) + self._penalties.setdefault(key, []).append(dist) + + def add_equality(self, key, value, options): + """Adds a distance penalty of 1.0 if `value` doesn't match any + of the values in `options`. If an option is a compiled regular + expression, it will be considered equal if it matches against + `value`. + """ + if not isinstance(options, (list, tuple)): + options = [options] + for opt in options: + if self._eq(opt, value): + dist = 0.0 + break + else: + dist = 1.0 + self.add(key, dist) + + def add_expr(self, key, expr): + """Adds a distance penalty of 1.0 if `expr` evaluates to True, + or 0.0. + """ + if expr: + self.add(key, 1.0) + else: + self.add(key, 0.0) + + def add_number(self, key, number1, number2): + """Adds a distance penalty of 1.0 for each number of difference + between `number1` and `number2`, or 0.0 when there is no + difference. Use this when there is no upper limit on the + difference between the two numbers. + """ + diff = abs(number1 - number2) + if diff: + for i in range(diff): + self.add(key, 1.0) + else: + self.add(key, 0.0) + + def add_priority(self, key, value, options): + """Adds a distance penalty that corresponds to the position at + which `value` appears in `options`. A distance penalty of 0.0 + for the first option, or 1.0 if there is no matching option. If + an option is a compiled regular expression, it will be + considered equal if it matches against `value`. + """ + if not isinstance(options, (list, tuple)): + options = [options] + unit = 1.0 / (len(options) or 1) + for i, opt in enumerate(options): + if self._eq(opt, value): + dist = i * unit + break + else: + dist = 1.0 + self.add(key, dist) + + def add_ratio(self, key, number1, number2): + """Adds a distance penalty for `number1` as a ratio of `number2`. + `number1` is bound at 0 and `number2`. + """ + number = float(max(min(number1, number2), 0)) + if number2: + dist = number / number2 + else: + dist = 0.0 + self.add(key, dist) + + def add_string(self, key, str1, str2): + """Adds a distance penalty based on the edit distance between + `str1` and `str2`. + """ + dist = string_dist(str1, str2) + self.add(key, dist) + + +# Structures that compose all the information for a candidate match. + +AlbumMatch = namedtuple('AlbumMatch', ['distance', 'info', 'mapping', + 'extra_items', 'extra_tracks']) + +TrackMatch = namedtuple('TrackMatch', ['distance', 'info']) + + +# Aggregation of sources. + +def album_for_mbid(release_id): + """Get an AlbumInfo object for a MusicBrainz release ID. Return None + if the ID is not found. + """ + try: + return mb.album_for_id(release_id) + except mb.MusicBrainzAPIError as exc: + exc.log(log) + +def track_for_mbid(recording_id): + """Get a TrackInfo object for a MusicBrainz recording ID. Return None + if the ID is not found. + """ + try: + return mb.track_for_id(recording_id) + except mb.MusicBrainzAPIError as exc: + exc.log(log) + +def albums_for_id(album_id): + """Get a list of albums for an ID.""" + candidates = [album_for_mbid(album_id)] + candidates.extend(plugins.album_for_id(album_id)) + return filter(None, candidates) + +def tracks_for_id(track_id): + """Get a list of tracks for an ID.""" + candidates = [track_for_mbid(track_id)] + candidates.extend(plugins.track_for_id(track_id)) + return filter(None, candidates) + +def album_candidates(items, artist, album, va_likely): + """Search for album matches. ``items`` is a list of Item objects + that make up the album. ``artist`` and ``album`` are the respective + names (strings), which may be derived from the item list or may be + entered by the user. ``va_likely`` is a boolean indicating whether + the album is likely to be a "various artists" release. + """ + out = [] + + # Base candidates if we have album and artist to match. + if artist and album: + try: + out.extend(mb.match_album(artist, album, len(items))) + except mb.MusicBrainzAPIError as exc: + exc.log(log) + + # Also add VA matches from MusicBrainz where appropriate. + if va_likely and album: + try: + out.extend(mb.match_album(None, album, len(items))) + except mb.MusicBrainzAPIError as exc: + exc.log(log) + + # Candidates from plugins. + out.extend(plugins.candidates(items, artist, album, va_likely)) + + return out + +def item_candidates(item, artist, title): + """Search for item matches. ``item`` is the Item to be matched. + ``artist`` and ``title`` are strings and either reflect the item or + are specified by the user. + """ + out = [] + + # MusicBrainz candidates. + if artist and title: + try: + out.extend(mb.match_track(artist, title)) + except mb.MusicBrainzAPIError as exc: + exc.log(log) + + # Plugin candidates. + out.extend(plugins.item_candidates(item, artist, title)) + + return out diff --git a/libs/beets/autotag/match.py b/libs/beets/autotag/match.py new file mode 100644 index 00000000..a4bc47fa --- /dev/null +++ b/libs/beets/autotag/match.py @@ -0,0 +1,456 @@ +# This file is part of beets. +# Copyright 2013, Adrian Sampson. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. + +"""Matches existing metadata with canonical information to identify +releases and tracks. +""" +from __future__ import division + +import datetime +import logging +import re +from munkres import Munkres + +from beets import plugins +from beets import config +from beets.util import plurality +from beets.util.enumeration import enum +from beets.autotag import hooks + +# Recommendation enumeration. +recommendation = enum('none', 'low', 'medium', 'strong', name='recommendation') + +# Artist signals that indicate "various artists". These are used at the +# album level to determine whether a given release is likely a VA +# release and also on the track level to to remove the penalty for +# differing artists. +VA_ARTISTS = (u'', u'various artists', u'various', u'va', u'unknown') + +# Global logger. +log = logging.getLogger('beets') + + +# Primary matching functionality. + +def current_metadata(items): + """Extract the likely current metadata for an album given a list of its + items. Return two dictionaries: + - The most common value for each field. + - Whether each field's value was unanimous (values are booleans). + """ + assert items # Must be nonempty. + + likelies = {} + consensus = {} + fields = ['artist', 'album', 'albumartist', 'year', 'disctotal', + 'mb_albumid', 'label', 'catalognum', 'country', 'media', + 'albumdisambig'] + for key in fields: + values = [getattr(item, key) for item in items if item] + likelies[key], freq = plurality(values) + consensus[key] = (freq == len(values)) + + # If there's an album artist consensus, use this for the artist. + if consensus['albumartist'] and likelies['albumartist']: + likelies['artist'] = likelies['albumartist'] + + return likelies, consensus + +def assign_items(items, tracks): + """Given a list of Items and a list of TrackInfo objects, find the + best mapping between them. Returns a mapping from Items to TrackInfo + objects, a set of extra Items, and a set of extra TrackInfo + objects. These "extra" objects occur when there is an unequal number + of objects of the two types. + """ + # Construct the cost matrix. + costs = [] + for item in items: + row = [] + for i, track in enumerate(tracks): + row.append(track_distance(item, track)) + costs.append(row) + + # Find a minimum-cost bipartite matching. + matching = Munkres().compute(costs) + + # Produce the output matching. + mapping = dict((items[i], tracks[j]) for (i, j) in matching) + extra_items = list(set(items) - set(mapping.keys())) + extra_items.sort(key=lambda i: (i.disc, i.track, i.title)) + extra_tracks = list(set(tracks) - set(mapping.values())) + extra_tracks.sort(key=lambda t: (t.index, t.title)) + return mapping, extra_items, extra_tracks + +def track_index_changed(item, track_info): + """Returns True if the item and track info index is different. Tolerates + per disc and per release numbering. + """ + return item.track not in (track_info.medium_index, track_info.index) + +def track_distance(item, track_info, incl_artist=False): + """Determines the significance of a track metadata change. Returns a + Distance object. `incl_artist` indicates that a distance component should + be included for the track artist (i.e., for various-artist releases). + """ + dist = hooks.Distance() + + # Length. + if track_info.length: + diff = abs(item.length - track_info.length) - \ + config['match']['track_length_grace'].as_number() + dist.add_ratio('track_length', diff, + config['match']['track_length_max'].as_number()) + + # Title. + dist.add_string('track_title', item.title, track_info.title) + + # Artist. Only check if there is actually an artist in the track data. + if incl_artist and track_info.artist and \ + item.artist.lower() not in VA_ARTISTS: + dist.add_string('track_artist', item.artist, track_info.artist) + + # Track index. + if track_info.index and item.track: + dist.add_expr('track_index', track_index_changed(item, track_info)) + + # Track ID. + if item.mb_trackid: + dist.add_expr('track_id', item.mb_trackid != track_info.track_id) + + # Plugins. + dist.update(plugins.track_distance(item, track_info)) + + return dist + +def distance(items, album_info, mapping): + """Determines how "significant" an album metadata change would be. + Returns a Distance object. `album_info` is an AlbumInfo object + reflecting the album to be compared. `items` is a sequence of all + Item objects that will be matched (order is not important). + `mapping` is a dictionary mapping Items to TrackInfo objects; the + keys are a subset of `items` and the values are a subset of + `album_info.tracks`. + """ + likelies, _ = current_metadata(items) + + dist = hooks.Distance() + + # Artist, if not various. + if not album_info.va: + dist.add_string('artist', likelies['artist'], album_info.artist) + + # Album. + dist.add_string('album', likelies['album'], album_info.album) + + # Current or preferred media. + if album_info.media: + # Preferred media options. + patterns = config['match']['preferred']['media'].as_str_seq() + options = [re.compile(r'(\d+x)?(%s)' % pat, re.I) for pat in patterns] + if options: + dist.add_priority('media', album_info.media, options) + # Current media. + elif likelies['media']: + dist.add_equality('media', album_info.media, likelies['media']) + + # Mediums. + if likelies['disctotal'] and album_info.mediums: + dist.add_number('mediums', likelies['disctotal'], album_info.mediums) + + # Prefer earliest release. + if album_info.year and config['match']['preferred']['original_year']: + # Assume 1889 (earliest first gramophone discs) if we don't know the + # original year. + original = album_info.original_year or 1889 + diff = abs(album_info.year - original) + diff_max = abs(datetime.date.today().year - original) + dist.add_ratio('year', diff, diff_max) + # Year. + elif likelies['year'] and album_info.year: + if likelies['year'] in (album_info.year, album_info.original_year): + # No penalty for matching release or original year. + dist.add('year', 0.0) + elif album_info.original_year: + # Prefer matchest closest to the release year. + diff = abs(likelies['year'] - album_info.year) + diff_max = abs(datetime.date.today().year - + album_info.original_year) + dist.add_ratio('year', diff, diff_max) + else: + # Full penalty when there is no original year. + dist.add('year', 1.0) + + # Preferred countries. + patterns = config['match']['preferred']['countries'].as_str_seq() + options = [re.compile(pat, re.I) for pat in patterns] + if album_info.country and options: + dist.add_priority('country', album_info.country, options) + # Country. + elif likelies['country'] and album_info.country: + dist.add_string('country', likelies['country'], album_info.country) + + # Label. + if likelies['label'] and album_info.label: + dist.add_string('label', likelies['label'], album_info.label) + + # Catalog number. + if likelies['catalognum'] and album_info.catalognum: + dist.add_string('catalognum', likelies['catalognum'], + album_info.catalognum) + + # Disambiguation. + if likelies['albumdisambig'] and album_info.albumdisambig: + dist.add_string('albumdisambig', likelies['albumdisambig'], + album_info.albumdisambig) + + # Album ID. + if likelies['mb_albumid']: + dist.add_equality('album_id', likelies['mb_albumid'], + album_info.album_id) + + # Tracks. + dist.tracks = {} + for item, track in mapping.iteritems(): + dist.tracks[track] = track_distance(item, track, album_info.va) + dist.add('tracks', dist.tracks[track].distance) + + # Missing tracks. + for i in range(len(album_info.tracks) - len(mapping)): + dist.add('missing_tracks', 1.0) + + # Unmatched tracks. + for i in range(len(items) - len(mapping)): + dist.add('unmatched_tracks', 1.0) + + # Plugins. + dist.update(plugins.album_distance(items, album_info, mapping)) + + return dist + +def match_by_id(items): + """If the items are tagged with a MusicBrainz album ID, returns an + AlbumInfo object for the corresponding album. Otherwise, returns + None. + """ + # Is there a consensus on the MB album ID? + albumids = [item.mb_albumid for item in items if item.mb_albumid] + if not albumids: + log.debug('No album IDs found.') + return None + + # If all album IDs are equal, look up the album. + if bool(reduce(lambda x,y: x if x==y else (), albumids)): + albumid = albumids[0] + log.debug('Searching for discovered album ID: ' + albumid) + return hooks.album_for_mbid(albumid) + else: + log.debug('No album ID consensus.') + +def _recommendation(results): + """Given a sorted list of AlbumMatch or TrackMatch objects, return a + recommendation based on the results' distances. + + If the recommendation is higher than the configured maximum for + an applied penalty, the recommendation will be downgraded to the + configured maximum for that penalty. + """ + if not results: + # No candidates: no recommendation. + return recommendation.none + + # Basic distance thresholding. + min_dist = results[0].distance + if min_dist < config['match']['strong_rec_thresh'].as_number(): + # Strong recommendation level. + rec = recommendation.strong + elif min_dist <= config['match']['medium_rec_thresh'].as_number(): + # Medium recommendation level. + rec = recommendation.medium + elif len(results) == 1: + # Only a single candidate. + rec = recommendation.low + elif results[1].distance - min_dist >= \ + config['match']['rec_gap_thresh'].as_number(): + # Gap between first two candidates is large. + rec = recommendation.low + else: + # No conclusion. Return immediately. Can't be downgraded any further. + return recommendation.none + + # Downgrade to the max rec if it is lower than the current rec for an + # applied penalty. + keys = set(min_dist.keys()) + if isinstance(results[0], hooks.AlbumMatch): + for track_dist in min_dist.tracks.values(): + keys.update(track_dist.keys()) + max_rec_view = config['match']['max_rec'] + for key in keys: + if key in max_rec_view.keys(): + max_rec = max_rec_view[key].as_choice({ + 'strong': recommendation.strong, + 'medium': recommendation.medium, + 'low': recommendation.low, + 'none': recommendation.none, + }) + rec = min(rec, max_rec) + + return rec + +def _add_candidate(items, results, info): + """Given a candidate AlbumInfo object, attempt to add the candidate + to the output dictionary of AlbumMatch objects. This involves + checking the track count, ordering the items, checking for + duplicates, and calculating the distance. + """ + log.debug('Candidate: %s - %s' % (info.artist, info.album)) + + # Don't duplicate. + if info.album_id in results: + log.debug('Duplicate.') + return + + # Find mapping between the items and the track info. + mapping, extra_items, extra_tracks = assign_items(items, info.tracks) + + # Get the change distance. + dist = distance(items, info, mapping) + + # Skip matches with ignored penalties. + penalties = [key for _, key in dist] + for penalty in config['match']['ignored'].as_str_seq(): + if penalty in penalties: + log.debug('Ignored. Penalty: %s' % penalty) + return + + log.debug('Success. Distance: %f' % dist) + results[info.album_id] = hooks.AlbumMatch(dist, info, mapping, + extra_items, extra_tracks) + +def tag_album(items, search_artist=None, search_album=None, + search_id=None): + """Bundles together the functionality used to infer tags for a + set of items comprised by an album. Returns everything relevant: + - The current artist. + - The current album. + - A list of AlbumMatch objects. The candidates are sorted by + distance (i.e., best match first). + - A recommendation. + If search_artist and search_album or search_id are provided, then + they are used as search terms in place of the current metadata. + """ + # Get current metadata. + likelies, consensus = current_metadata(items) + cur_artist = likelies['artist'] + cur_album = likelies['album'] + log.debug('Tagging %s - %s' % (cur_artist, cur_album)) + + # The output result (distance, AlbumInfo) tuples (keyed by MB album + # ID). + candidates = {} + + # Search by explicit ID. + if search_id is not None: + log.debug('Searching for album ID: ' + search_id) + search_cands = hooks.albums_for_id(search_id) + + # Use existing metadata or text search. + else: + # Try search based on current ID. + id_info = match_by_id(items) + if id_info: + _add_candidate(items, candidates, id_info) + rec = _recommendation(candidates.values()) + log.debug('Album ID match recommendation is ' + str(rec)) + if candidates and not config['import']['timid']: + # If we have a very good MBID match, return immediately. + # Otherwise, this match will compete against metadata-based + # matches. + if rec == recommendation.strong: + log.debug('ID match.') + return cur_artist, cur_album, candidates.values(), rec + + # Search terms. + if not (search_artist and search_album): + # No explicit search terms -- use current metadata. + search_artist, search_album = cur_artist, cur_album + log.debug(u'Search terms: %s - %s' % (search_artist, search_album)) + + # Is this album likely to be a "various artist" release? + va_likely = ((not consensus['artist']) or + (search_artist.lower() in VA_ARTISTS) or + any(item.comp for item in items)) + log.debug(u'Album might be VA: %s' % str(va_likely)) + + # Get the results from the data sources. + search_cands = hooks.album_candidates(items, search_artist, + search_album, va_likely) + + log.debug(u'Evaluating %i candidates.' % len(search_cands)) + for info in search_cands: + _add_candidate(items, candidates, info) + + # Sort and get the recommendation. + candidates = sorted(candidates.itervalues()) + rec = _recommendation(candidates) + return cur_artist, cur_album, candidates, rec + +def tag_item(item, search_artist=None, search_title=None, + search_id=None): + """Attempts to find metadata for a single track. Returns a + `(candidates, recommendation)` pair where `candidates` is a list of + TrackMatch objects. `search_artist` and `search_title` may be used + to override the current metadata for the purposes of the MusicBrainz + title; likewise `search_id`. + """ + # Holds candidates found so far: keys are MBIDs; values are + # (distance, TrackInfo) pairs. + candidates = {} + + # First, try matching by MusicBrainz ID. + trackid = search_id or item.mb_trackid + if trackid: + log.debug('Searching for track ID: ' + trackid) + for track_info in hooks.tracks_for_id(trackid): + dist = track_distance(item, track_info, incl_artist=True) + candidates[track_info.track_id] = \ + hooks.TrackMatch(dist, track_info) + # If this is a good match, then don't keep searching. + rec = _recommendation(candidates.values()) + if rec == recommendation.strong and not config['import']['timid']: + log.debug('Track ID match.') + return candidates.values(), rec + + # If we're searching by ID, don't proceed. + if search_id is not None: + if candidates: + return candidates.values(), rec + else: + return [], recommendation.none + + # Search terms. + if not (search_artist and search_title): + search_artist, search_title = item.artist, item.title + log.debug(u'Item search terms: %s - %s' % (search_artist, search_title)) + + # Get and evaluate candidate metadata. + for track_info in hooks.item_candidates(item, search_artist, search_title): + dist = track_distance(item, track_info, incl_artist=True) + candidates[track_info.track_id] = hooks.TrackMatch(dist, track_info) + + # Sort by distance and return with recommendation. + log.debug('Found %i candidates.' % len(candidates)) + candidates = sorted(candidates.itervalues()) + rec = _recommendation(candidates) + return candidates, rec diff --git a/libs/beets/autotag/mb.py b/libs/beets/autotag/mb.py new file mode 100644 index 00000000..779ec4b3 --- /dev/null +++ b/libs/beets/autotag/mb.py @@ -0,0 +1,390 @@ +# This file is part of beets. +# Copyright 2013, Adrian Sampson. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. + +"""Searches for albums in the MusicBrainz database. +""" +import logging +import musicbrainzngs +import re +import traceback +from urlparse import urljoin + +import beets.autotag.hooks +import beets +from beets import util +from beets import config + +SEARCH_LIMIT = 5 +VARIOUS_ARTISTS_ID = '89ad4ac3-39f7-470e-963a-56509c546377' +BASE_URL = 'http://musicbrainz.org/' + +musicbrainzngs.set_useragent('beets', beets.__version__, + 'http://beets.radbox.org/') + +class MusicBrainzAPIError(util.HumanReadableException): + """An error while talking to MusicBrainz. The `query` field is the + parameter to the action and may have any type. + """ + def __init__(self, reason, verb, query, tb=None): + self.query = query + super(MusicBrainzAPIError, self).__init__(reason, verb, tb) + + def get_message(self): + return u'"{0}" in {1} with query {2}'.format( + self._reasonstr(), self.verb, repr(self.query) + ) + +log = logging.getLogger('beets') + +RELEASE_INCLUDES = ['artists', 'media', 'recordings', 'release-groups', + 'labels', 'artist-credits', 'aliases'] +TRACK_INCLUDES = ['artists', 'aliases'] + +def track_url(trackid): + return urljoin(BASE_URL, 'recording/' + trackid) + +def album_url(albumid): + return urljoin(BASE_URL, 'release/' + albumid) + +def configure(): + """Set up the python-musicbrainz-ngs module according to settings + from the beets configuration. This should be called at startup. + """ + musicbrainzngs.set_hostname(config['musicbrainz']['host'].get(unicode)) + musicbrainzngs.set_rate_limit( + config['musicbrainz']['ratelimit_interval'].as_number(), + config['musicbrainz']['ratelimit'].get(int), + ) + +def _preferred_alias(aliases): + """Given an list of alias structures for an artist credit, select + and return the user's preferred alias alias or None if no matching + alias is found. + """ + if not aliases: + return + + # Only consider aliases that have locales set. + aliases = [a for a in aliases if 'locale' in a] + + # Search configured locales in order. + for locale in config['import']['languages'].as_str_seq(): + # Find matching primary aliases for this locale. + matches = [a for a in aliases if a['locale'] == locale and 'primary' in a] + # Skip to the next locale if we have no matches + if not matches: + continue + + return matches[0] + +def _flatten_artist_credit(credit): + """Given a list representing an ``artist-credit`` block, flatten the + data into a triple of joined artist name strings: canonical, sort, and + credit. + """ + artist_parts = [] + artist_sort_parts = [] + artist_credit_parts = [] + for el in credit: + if isinstance(el, basestring): + # Join phrase. + artist_parts.append(el) + artist_credit_parts.append(el) + artist_sort_parts.append(el) + + else: + alias = _preferred_alias(el['artist'].get('alias-list', ())) + + # An artist. + if alias: + cur_artist_name = alias['alias'] + else: + cur_artist_name = el['artist']['name'] + artist_parts.append(cur_artist_name) + + # Artist sort name. + if alias: + artist_sort_parts.append(alias['sort-name']) + elif 'sort-name' in el['artist']: + artist_sort_parts.append(el['artist']['sort-name']) + else: + artist_sort_parts.append(cur_artist_name) + + # Artist credit. + if 'name' in el: + artist_credit_parts.append(el['name']) + else: + artist_credit_parts.append(cur_artist_name) + + return ( + ''.join(artist_parts), + ''.join(artist_sort_parts), + ''.join(artist_credit_parts), + ) + +def track_info(recording, index=None, medium=None, medium_index=None, + medium_total=None): + """Translates a MusicBrainz recording result dictionary into a beets + ``TrackInfo`` object. Three parameters are optional and are used + only for tracks that appear on releases (non-singletons): ``index``, + the overall track number; ``medium``, the disc number; + ``medium_index``, the track's index on its medium; ``medium_total``, + the number of tracks on the medium. Each number is a 1-based index. + """ + info = beets.autotag.hooks.TrackInfo( + recording['title'], + recording['id'], + index=index, + medium=medium, + medium_index=medium_index, + medium_total=medium_total, + data_url=track_url(recording['id']), + ) + + if recording.get('artist-credit'): + # Get the artist names. + info.artist, info.artist_sort, info.artist_credit = \ + _flatten_artist_credit(recording['artist-credit']) + + # Get the ID and sort name of the first artist. + artist = recording['artist-credit'][0]['artist'] + info.artist_id = artist['id'] + + if recording.get('length'): + info.length = int(recording['length']) / (1000.0) + + info.decode() + return info + +def _set_date_str(info, date_str, original=False): + """Given a (possibly partial) YYYY-MM-DD string and an AlbumInfo + object, set the object's release date fields appropriately. If + `original`, then set the original_year, etc., fields. + """ + if date_str: + date_parts = date_str.split('-') + for key in ('year', 'month', 'day'): + if date_parts: + date_part = date_parts.pop(0) + try: + date_num = int(date_part) + except ValueError: + continue + + if original: + key = 'original_' + key + setattr(info, key, date_num) + +def album_info(release): + """Takes a MusicBrainz release result dictionary and returns a beets + AlbumInfo object containing the interesting data about that release. + """ + # Get artist name using join phrases. + artist_name, artist_sort_name, artist_credit_name = \ + _flatten_artist_credit(release['artist-credit']) + + # Basic info. + track_infos = [] + index = 0 + for medium in release['medium-list']: + disctitle = medium.get('title') + for track in medium['track-list']: + # Basic information from the recording. + index += 1 + ti = track_info( + track['recording'], + index, + int(medium['position']), + int(track['position']), + len(medium['track-list']), + ) + ti.disctitle = disctitle + + # Prefer track data, where present, over recording data. + if track.get('title'): + ti.title = track['title'] + if track.get('artist-credit'): + # Get the artist names. + ti.artist, ti.artist_sort, ti.artist_credit = \ + _flatten_artist_credit(track['artist-credit']) + ti.artist_id = track['artist-credit'][0]['artist']['id'] + if track.get('length'): + ti.length = int(track['length']) / (1000.0) + + track_infos.append(ti) + + info = beets.autotag.hooks.AlbumInfo( + release['title'], + release['id'], + artist_name, + release['artist-credit'][0]['artist']['id'], + track_infos, + mediums=len(release['medium-list']), + artist_sort=artist_sort_name, + artist_credit=artist_credit_name, + data_source='MusicBrainz', + data_url=album_url(release['id']), + ) + info.va = info.artist_id == VARIOUS_ARTISTS_ID + info.asin = release.get('asin') + info.releasegroup_id = release['release-group']['id'] + info.country = release.get('country') + info.albumstatus = release.get('status') + + # Build up the disambiguation string from the release group and release. + disambig = [] + if release['release-group'].get('disambiguation'): + disambig.append(release['release-group'].get('disambiguation')) + if release.get('disambiguation'): + disambig.append(release.get('disambiguation')) + info.albumdisambig = u', '.join(disambig) + + # Release type not always populated. + if 'type' in release['release-group']: + reltype = release['release-group']['type'] + if reltype: + info.albumtype = reltype.lower() + + # Release dates. + release_date = release.get('date') + release_group_date = release['release-group'].get('first-release-date') + if not release_date: + # Fall back if release-specific date is not available. + release_date = release_group_date + _set_date_str(info, release_date, False) + _set_date_str(info, release_group_date, True) + + # Label name. + if release.get('label-info-list'): + label_info = release['label-info-list'][0] + if label_info.get('label'): + label = label_info['label']['name'] + if label != '[no label]': + info.label = label + info.catalognum = label_info.get('catalog-number') + + # Text representation data. + if release.get('text-representation'): + rep = release['text-representation'] + info.script = rep.get('script') + info.language = rep.get('language') + + # Media (format). + if release['medium-list']: + first_medium = release['medium-list'][0] + info.media = first_medium.get('format') + + info.decode() + return info + +def match_album(artist, album, tracks=None, limit=SEARCH_LIMIT): + """Searches for a single album ("release" in MusicBrainz parlance) + and returns an iterator over AlbumInfo objects. May raise a + MusicBrainzAPIError. + + The query consists of an artist name, an album name, and, + optionally, a number of tracks on the album. + """ + # Build search criteria. + criteria = {'release': album.lower()} + if artist is not None: + criteria['artist'] = artist.lower() + else: + # Various Artists search. + criteria['arid'] = VARIOUS_ARTISTS_ID + if tracks is not None: + criteria['tracks'] = str(tracks) + + # Abort if we have no search terms. + if not any(criteria.itervalues()): + return + + try: + res = musicbrainzngs.search_releases(limit=limit, **criteria) + except musicbrainzngs.MusicBrainzError as exc: + raise MusicBrainzAPIError(exc, 'release search', criteria, + traceback.format_exc()) + for release in res['release-list']: + # The search result is missing some data (namely, the tracks), + # so we just use the ID and fetch the rest of the information. + albuminfo = album_for_id(release['id']) + if albuminfo is not None: + yield albuminfo + +def match_track(artist, title, limit=SEARCH_LIMIT): + """Searches for a single track and returns an iterable of TrackInfo + objects. May raise a MusicBrainzAPIError. + """ + criteria = { + 'artist': artist.lower(), + 'recording': title.lower(), + } + + if not any(criteria.itervalues()): + return + + try: + res = musicbrainzngs.search_recordings(limit=limit, **criteria) + except musicbrainzngs.MusicBrainzError as exc: + raise MusicBrainzAPIError(exc, 'recording search', criteria, + traceback.format_exc()) + for recording in res['recording-list']: + yield track_info(recording) + +def _parse_id(s): + """Search for a MusicBrainz ID in the given string and return it. If + no ID can be found, return None. + """ + # Find the first thing that looks like a UUID/MBID. + match = re.search('[a-f0-9]{8}(-[a-f0-9]{4}){3}-[a-f0-9]{12}', s) + if match: + return match.group() + +def album_for_id(albumid): + """Fetches an album by its MusicBrainz ID and returns an AlbumInfo + object or None if the album is not found. May raise a + MusicBrainzAPIError. + """ + albumid = _parse_id(albumid) + if not albumid: + log.error('Invalid MBID.') + return + try: + res = musicbrainzngs.get_release_by_id(albumid, + RELEASE_INCLUDES) + except musicbrainzngs.ResponseError: + log.debug('Album ID match failed.') + return None + except musicbrainzngs.MusicBrainzError as exc: + raise MusicBrainzAPIError(exc, 'get release by ID', albumid, + traceback.format_exc()) + return album_info(res['release']) + +def track_for_id(trackid): + """Fetches a track by its MusicBrainz ID. Returns a TrackInfo object + or None if no track is found. May raise a MusicBrainzAPIError. + """ + trackid = _parse_id(trackid) + if not trackid: + log.error('Invalid MBID.') + return + try: + res = musicbrainzngs.get_recording_by_id(trackid, TRACK_INCLUDES) + except musicbrainzngs.ResponseError: + log.debug('Track ID match failed.') + return None + except musicbrainzngs.MusicBrainzError as exc: + raise MusicBrainzAPIError(exc, 'get recording by ID', trackid, + traceback.format_exc()) + return track_info(res['recording']) diff --git a/libs/beets/config_default.yaml b/libs/beets/config_default.yaml new file mode 100644 index 00000000..d35368ea --- /dev/null +++ b/libs/beets/config_default.yaml @@ -0,0 +1,102 @@ +library: library.db +directory: ~/Music + +import: + write: yes + copy: yes + move: no + delete: no + resume: ask + incremental: no + quiet_fallback: skip + none_rec_action: ask + timid: no + log: + autotag: yes + quiet: no + singletons: no + default_action: apply + languages: [] + detail: no + flat: no + group_albums: no + +clutter: ["Thumbs.DB", ".DS_Store"] +ignore: [".*", "*~", "System Volume Information"] +replace: + '[\\/]': _ + '^\.': _ + '[\x00-\x1f]': _ + '[<>:"\?\*\|]': _ + '\.$': _ + '\s+$': '' + '^\s+': '' +path_sep_replace: _ +art_filename: cover +max_filename_length: 0 + +plugins: [] +pluginpath: [] +threaded: yes +color: yes +timeout: 5.0 +per_disc_numbering: no +verbose: no +terminal_encoding: utf8 +original_date: no +id3v23: no + +ui: + terminal_width: 80 + length_diff_thresh: 10.0 + +list_format_item: $artist - $album - $title +list_format_album: $albumartist - $album +time_format: '%Y-%m-%d %H:%M:%S' + +paths: + default: $albumartist/$album%aunique{}/$track $title + singleton: Non-Album/$artist/$title + comp: Compilations/$album%aunique{}/$track $title + +statefile: state.pickle + +musicbrainz: + host: musicbrainz.org + ratelimit: 1 + ratelimit_interval: 1.0 + +match: + strong_rec_thresh: 0.04 + medium_rec_thresh: 0.25 + rec_gap_thresh: 0.25 + max_rec: + missing_tracks: medium + unmatched_tracks: medium + distance_weights: + source: 2.0 + artist: 3.0 + album: 3.0 + media: 1.0 + mediums: 1.0 + year: 1.0 + country: 0.5 + label: 0.5 + catalognum: 0.5 + albumdisambig: 0.5 + album_id: 5.0 + tracks: 2.0 + missing_tracks: 0.9 + unmatched_tracks: 0.6 + track_title: 3.0 + track_artist: 2.0 + track_index: 1.0 + track_length: 2.0 + track_id: 5.0 + preferred: + countries: [] + media: [] + original_year: no + ignored: [] + track_length_grace: 10 + track_length_max: 30 diff --git a/libs/beets/dbcore/__init__.py b/libs/beets/dbcore/__init__.py new file mode 100644 index 00000000..b4f80fb9 --- /dev/null +++ b/libs/beets/dbcore/__init__.py @@ -0,0 +1,20 @@ +# This file is part of beets. +# Copyright 2014, Adrian Sampson. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. + +"""DBCore is an abstract database package that forms the basis for beets' +Library. +""" +from .db import Model, Database +from .query import Query, FieldQuery, MatchQuery, AndQuery, OrQuery +from .types import Type diff --git a/libs/beets/dbcore/db.py b/libs/beets/dbcore/db.py new file mode 100644 index 00000000..cbdaf5a7 --- /dev/null +++ b/libs/beets/dbcore/db.py @@ -0,0 +1,727 @@ +# This file is part of beets. +# Copyright 2014, Adrian Sampson. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. + +"""The central Model and Database constructs for DBCore. +""" +import time +import os +from collections import defaultdict +import threading +import sqlite3 +import contextlib + +import beets +from beets.util.functemplate import Template +from .query import MatchQuery + + + +# Abstract base for model classes. + + +class Model(object): + """An abstract object representing an object in the database. Model + objects act like dictionaries (i.e., the allow subscript access like + ``obj['field']``). The same field set is available via attribute + access as a shortcut (i.e., ``obj.field``). Three kinds of attributes are + available: + + * **Fixed attributes** come from a predetermined list of field + names. These fields correspond to SQLite table columns and are + thus fast to read, write, and query. + * **Flexible attributes** are free-form and do not need to be listed + ahead of time. + * **Computed attributes** are read-only fields computed by a getter + function provided by a plugin. + + Access to all three field types is uniform: ``obj.field`` works the + same regardless of whether ``field`` is fixed, flexible, or + computed. + + Model objects can optionally be associated with a `Library` object, + in which case they can be loaded and stored from the database. Dirty + flags are used to track which fields need to be stored. + """ + + # Abstract components (to be provided by subclasses). + + _table = None + """The main SQLite table name. + """ + + _flex_table = None + """The flex field SQLite table name. + """ + + _fields = {} + """A mapping indicating available "fixed" fields on this type. The + keys are field names and the values are Type objects. + """ + + _bytes_keys = () + """Keys whose values should be stored as raw bytes blobs rather than + strings. + """ + + _search_fields = () + """The fields that should be queried by default by unqualified query + terms. + """ + + @classmethod + def _getters(cls): + """Return a mapping from field names to getter functions. + """ + # We could cache this if it becomes a performance problem to + # gather the getter mapping every time. + raise NotImplementedError() + + def _template_funcs(self): + """Return a mapping from function names to text-transformer + functions. + """ + # As above: we could consider caching this result. + raise NotImplementedError() + + + # Basic operation. + + def __init__(self, db=None, **values): + """Create a new object with an optional Database association and + initial field values. + """ + self._db = db + self._dirty = set() + self._values_fixed = {} + self._values_flex = {} + + # Initial contents. + self.update(values) + self.clear_dirty() + + def __repr__(self): + return '{0}({1})'.format( + type(self).__name__, + ', '.join('{0}={1!r}'.format(k, v) for k, v in dict(self).items()), + ) + + def clear_dirty(self): + """Mark all fields as *clean* (i.e., not needing to be stored to + the database). + """ + self._dirty = set() + + def _check_db(self, need_id=True): + """Ensure that this object is associated with a database row: it + has a reference to a database (`_db`) and an id. A ValueError + exception is raised otherwise. + """ + if not self._db: + raise ValueError('{0} has no database'.format(type(self).__name__)) + if need_id and not self.id: + raise ValueError('{0} has no id'.format(type(self).__name__)) + + + # Essential field accessors. + + def __getitem__(self, key): + """Get the value for a field. Raise a KeyError if the field is + not available. + """ + getters = self._getters() + if key in getters: # Computed. + return getters[key](self) + elif key in self._fields: # Fixed. + return self._values_fixed.get(key) + elif key in self._values_flex: # Flexible. + return self._values_flex[key] + else: + raise KeyError(key) + + def __setitem__(self, key, value): + """Assign the value for a field. + """ + source = self._values_fixed if key in self._fields \ + else self._values_flex + old_value = source.get(key) + source[key] = value + if old_value != value: + self._dirty.add(key) + + def __delitem__(self, key): + """Remove a flexible attribute from the model. + """ + if key in self._values_flex: # Flexible. + del self._values_flex[key] + self._dirty.add(key) # Mark for dropping on store. + elif key in self._getters(): # Computed. + raise KeyError('computed field {0} cannot be deleted'.format(key)) + elif key in self._fields: # Fixed. + raise KeyError('fixed field {0} cannot be deleted'.format(key)) + else: + raise KeyError('no such field {0}'.format(key)) + + def keys(self, computed=False): + """Get a list of available field names for this object. The + `computed` parameter controls whether computed (plugin-provided) + fields are included in the key list. + """ + base_keys = list(self._fields) + self._values_flex.keys() + if computed: + return base_keys + self._getters().keys() + else: + return base_keys + + + # Act like a dictionary. + + def update(self, values): + """Assign all values in the given dict. + """ + for key, value in values.items(): + self[key] = value + + def items(self): + """Iterate over (key, value) pairs that this object contains. + Computed fields are not included. + """ + for key in self: + yield key, self[key] + + def get(self, key, default=None): + """Get the value for a given key or `default` if it does not + exist. + """ + if key in self: + return self[key] + else: + return default + + def __contains__(self, key): + """Determine whether `key` is an attribute on this object. + """ + return key in self.keys(True) + + def __iter__(self): + """Iterate over the available field names (excluding computed + fields). + """ + return iter(self.keys()) + + + # Convenient attribute access. + + def __getattr__(self, key): + if key.startswith('_'): + raise AttributeError('model has no attribute {0!r}'.format(key)) + else: + try: + return self[key] + except KeyError: + raise AttributeError('no such field {0!r}'.format(key)) + + def __setattr__(self, key, value): + if key.startswith('_'): + super(Model, self).__setattr__(key, value) + else: + self[key] = value + + def __delattr__(self, key): + if key.startswith('_'): + super(Model, self).__delattr__(key) + else: + del self[key] + + + # Database interaction (CRUD methods). + + def store(self): + """Save the object's metadata into the library database. + """ + self._check_db() + + # Build assignments for query. + assignments = '' + subvars = [] + for key in self._fields: + if key != 'id' and key in self._dirty: + self._dirty.remove(key) + assignments += key + '=?,' + value = self[key] + # Wrap path strings in buffers so they get stored + # "in the raw". + if key in self._bytes_keys and isinstance(value, str): + value = buffer(value) + subvars.append(value) + assignments = assignments[:-1] # Knock off last , + + with self._db.transaction() as tx: + # Main table update. + if assignments: + query = 'UPDATE {0} SET {1} WHERE id=?'.format( + self._table, assignments + ) + subvars.append(self.id) + tx.mutate(query, subvars) + + # Modified/added flexible attributes. + for key, value in self._values_flex.items(): + if key in self._dirty: + self._dirty.remove(key) + tx.mutate( + 'INSERT INTO {0} ' + '(entity_id, key, value) ' + 'VALUES (?, ?, ?);'.format(self._flex_table), + (self.id, key, value), + ) + + # Deleted flexible attributes. + for key in self._dirty: + tx.mutate( + 'DELETE FROM {0} ' + 'WHERE entity_id=? AND key=?'.format(self._flex_table), + (self.id, key) + ) + + self.clear_dirty() + + def load(self): + """Refresh the object's metadata from the library database. + """ + self._check_db() + stored_obj = self._db._get(type(self), self.id) + assert stored_obj is not None, "object {0} not in DB".format(self.id) + self.update(dict(stored_obj)) + self.clear_dirty() + + def remove(self): + """Remove the object's associated rows from the database. + """ + self._check_db() + with self._db.transaction() as tx: + tx.mutate( + 'DELETE FROM {0} WHERE id=?'.format(self._table), + (self.id,) + ) + tx.mutate( + 'DELETE FROM {0} WHERE entity_id=?'.format(self._flex_table), + (self.id,) + ) + + def add(self, db=None): + """Add the object to the library database. This object must be + associated with a database; you can provide one via the `db` + parameter or use the currently associated database. + + The object's `id` and `added` fields are set along with any + current field values. + """ + if db: + self._db = db + self._check_db(False) + + with self._db.transaction() as tx: + new_id = tx.mutate( + 'INSERT INTO {0} DEFAULT VALUES'.format(self._table) + ) + self.id = new_id + self.added = time.time() + + # Mark every non-null field as dirty and store. + for key in self: + if self[key] is not None: + self._dirty.add(key) + self.store() + + + # Formatting and templating. + + @classmethod + def _format(cls, key, value, for_path=False): + """Format a value as the given field for this model. + """ + # Format the value as a string according to its type, if any. + if key in cls._fields: + value = cls._fields[key].format(value) + # Formatting must result in a string. To deal with + # Python2isms, implicitly convert ASCII strings. + assert isinstance(value, basestring), \ + u'field formatter must produce strings' + if isinstance(value, bytes): + value = value.decode('utf8', 'ignore') + + elif not isinstance(value, unicode): + # Fallback formatter. Convert to unicode at all cost. + if value is None: + value = u'' + elif isinstance(value, basestring): + if isinstance(value, bytes): + value = value.decode('utf8', 'ignore') + else: + value = unicode(value) + + if for_path: + sep_repl = beets.config['path_sep_replace'].get(unicode) + for sep in (os.path.sep, os.path.altsep): + if sep: + value = value.replace(sep, sep_repl) + + return value + + def _get_formatted(self, key, for_path=False): + """Get a field value formatted as a string (`unicode` object) + for display to the user. If `for_path` is true, then the value + will be sanitized for inclusion in a pathname (i.e., path + separators will be removed from the value). + """ + return self._format(key, self.get(key), for_path) + + def _formatted_mapping(self, for_path=False): + """Get a mapping containing all values on this object formatted + as human-readable strings. + """ + # In the future, this could be made "lazy" to avoid computing + # fields unnecessarily. + out = {} + for key in self.keys(True): + out[key] = self._get_formatted(key, for_path) + return out + + def evaluate_template(self, template, for_path=False): + """Evaluate a template (a string or a `Template` object) using + the object's fields. If `for_path` is true, then no new path + separators will be added to the template. + """ + # Build value mapping. + mapping = self._formatted_mapping(for_path) + + # Get template functions. + funcs = self._template_funcs() + + # Perform substitution. + if isinstance(template, basestring): + template = Template(template) + return template.substitute(mapping, funcs) + + + # Parsing. + + @classmethod + def _parse(cls, key, string): + """Parse a string as a value for the given key. + """ + if not isinstance(string, basestring): + raise TypeError("_parse() argument must be a string") + + typ = cls._fields.get(key) + if typ: + return typ.parse(string) + else: + # Fall back to unparsed string. + return string + + + +# Database controller and supporting interfaces. + + +class Results(object): + """An item query result set. Iterating over the collection lazily + constructs LibModel objects that reflect database rows. + """ + def __init__(self, model_class, rows, db, query=None): + """Create a result set that will construct objects of type + `model_class`, which should be a subclass of `LibModel`, out of + the query result mapping in `rows`. The new objects are + associated with the database `db`. If `query` is provided, it is + used as a predicate to filter the results for a "slow query" that + cannot be evaluated by the database directly. + """ + self.model_class = model_class + self.rows = rows + self.db = db + self.query = query + + def __iter__(self): + """Construct Python objects for all rows that pass the query + predicate. + """ + for row in self.rows: + # Get the flexible attributes for the object. + with self.db.transaction() as tx: + flex_rows = tx.query( + 'SELECT * FROM {0} WHERE entity_id=?'.format( + self.model_class._flex_table + ), + (row['id'],) + ) + values = dict(row) + values.update( + dict((row['key'], row['value']) for row in flex_rows) + ) + + # Construct the Python object and yield it if it passes the + # predicate. + obj = self.model_class(self.db, **values) + if not self.query or self.query.match(obj): + yield obj + + def __len__(self): + """Get the number of matching objects. + """ + if self.query: + # A slow query. Fall back to testing every object. + count = 0 + for obj in self: + count += 1 + return count + + else: + # A fast query. Just count the rows. + return len(self.rows) + + def __nonzero__(self): + """Does this result contain any objects? + """ + return bool(len(self)) + + def __getitem__(self, n): + """Get the nth item in this result set. This is inefficient: all + items up to n are materialized and thrown away. + """ + it = iter(self) + try: + for i in range(n): + it.next() + return it.next() + except StopIteration: + raise IndexError('result index {0} out of range'.format(n)) + + def get(self): + """Return the first matching object, or None if no objects + match. + """ + it = iter(self) + try: + return it.next() + except StopIteration: + return None + + +class Transaction(object): + """A context manager for safe, concurrent access to the database. + All SQL commands should be executed through a transaction. + """ + def __init__(self, db): + self.db = db + + def __enter__(self): + """Begin a transaction. This transaction may be created while + another is active in a different thread. + """ + with self.db._tx_stack() as stack: + first = not stack + stack.append(self) + if first: + # Beginning a "root" transaction, which corresponds to an + # SQLite transaction. + self.db._db_lock.acquire() + return self + + def __exit__(self, exc_type, exc_value, traceback): + """Complete a transaction. This must be the most recently + entered but not yet exited transaction. If it is the last active + transaction, the database updates are committed. + """ + with self.db._tx_stack() as stack: + assert stack.pop() is self + empty = not stack + if empty: + # Ending a "root" transaction. End the SQLite transaction. + self.db._connection().commit() + self.db._db_lock.release() + + def query(self, statement, subvals=()): + """Execute an SQL statement with substitution values and return + a list of rows from the database. + """ + cursor = self.db._connection().execute(statement, subvals) + return cursor.fetchall() + + def mutate(self, statement, subvals=()): + """Execute an SQL statement with substitution values and return + the row ID of the last affected row. + """ + cursor = self.db._connection().execute(statement, subvals) + return cursor.lastrowid + + def script(self, statements): + """Execute a string containing multiple SQL statements.""" + self.db._connection().executescript(statements) + + +class Database(object): + """A container for Model objects that wraps an SQLite database as + the backend. + """ + _models = () + """The Model subclasses representing tables in this database. + """ + + def __init__(self, path): + self.path = path + + self._connections = {} + self._tx_stacks = defaultdict(list) + + # A lock to protect the _connections and _tx_stacks maps, which + # both map thread IDs to private resources. + self._shared_map_lock = threading.Lock() + + # A lock to protect access to the database itself. SQLite does + # allow multiple threads to access the database at the same + # time, but many users were experiencing crashes related to this + # capability: where SQLite was compiled without HAVE_USLEEP, its + # backoff algorithm in the case of contention was causing + # whole-second sleeps (!) that would trigger its internal + # timeout. Using this lock ensures only one SQLite transaction + # is active at a time. + self._db_lock = threading.Lock() + + # Set up database schema. + for model_cls in self._models: + self._make_table(model_cls._table, model_cls._fields) + self._make_attribute_table(model_cls._flex_table) + + + # Primitive access control: connections and transactions. + + def _connection(self): + """Get a SQLite connection object to the underlying database. + One connection object is created per thread. + """ + thread_id = threading.current_thread().ident + with self._shared_map_lock: + if thread_id in self._connections: + return self._connections[thread_id] + else: + # Make a new connection. + conn = sqlite3.connect( + self.path, + timeout=beets.config['timeout'].as_number(), + ) + + # Access SELECT results like dictionaries. + conn.row_factory = sqlite3.Row + + self._connections[thread_id] = conn + return conn + + @contextlib.contextmanager + def _tx_stack(self): + """A context manager providing access to the current thread's + transaction stack. The context manager synchronizes access to + the stack map. Transactions should never migrate across threads. + """ + thread_id = threading.current_thread().ident + with self._shared_map_lock: + yield self._tx_stacks[thread_id] + + def transaction(self): + """Get a :class:`Transaction` object for interacting directly + with the underlying SQLite database. + """ + return Transaction(self) + + + # Schema setup and migration. + + def _make_table(self, table, fields): + """Set up the schema of the database. `fields` is a mapping + from field names to `Type`s. Columns are added if necessary. + """ + # Get current schema. + with self.transaction() as tx: + rows = tx.query('PRAGMA table_info(%s)' % table) + current_fields = set([row[1] for row in rows]) + + field_names = set(fields.keys()) + if current_fields.issuperset(field_names): + # Table exists and has all the required columns. + return + + if not current_fields: + # No table exists. + columns = [] + for name, typ in fields.items(): + columns.append('{0} {1}'.format(name, typ.sql)) + setup_sql = 'CREATE TABLE {0} ({1});\n'.format(table, + ', '.join(columns)) + + else: + # Table exists does not match the field set. + setup_sql = '' + for name, typ in fields.items(): + if name in current_fields: + continue + setup_sql += 'ALTER TABLE {0} ADD COLUMN {1} {2};\n'.format( + table, name, typ.sql + ) + + with self.transaction() as tx: + tx.script(setup_sql) + + def _make_attribute_table(self, flex_table): + """Create a table and associated index for flexible attributes + for the given entity (if they don't exist). + """ + with self.transaction() as tx: + tx.script(""" + CREATE TABLE IF NOT EXISTS {0} ( + id INTEGER PRIMARY KEY, + entity_id INTEGER, + key TEXT, + value TEXT, + UNIQUE(entity_id, key) ON CONFLICT REPLACE); + CREATE INDEX IF NOT EXISTS {0}_by_entity + ON {0} (entity_id); + """.format(flex_table)) + + + # Querying. + + def _fetch(self, model_cls, query, order_by=None): + """Fetch the objects of type `model_cls` matching the given + query. The query may be given as a string, string sequence, a + Query object, or None (to fetch everything). If provided, + `order_by` is a SQLite ORDER BY clause for sorting. + """ + where, subvals = query.clause() + + sql = "SELECT * FROM {0} WHERE {1}".format( + model_cls._table, + where or '1', + ) + if order_by: + sql += " ORDER BY {0}".format(order_by) + with self.transaction() as tx: + rows = tx.query(sql, subvals) + + return Results(model_cls, rows, self, None if where else query) + + def _get(self, model_cls, id): + """Get a Model object by its id or None if the id does not + exist. + """ + return self._fetch(model_cls, MatchQuery('id', id)).get() diff --git a/libs/beets/dbcore/query.py b/libs/beets/dbcore/query.py new file mode 100644 index 00000000..4c888302 --- /dev/null +++ b/libs/beets/dbcore/query.py @@ -0,0 +1,494 @@ +# This file is part of beets. +# Copyright 2014, Adrian Sampson. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. + +"""The Query type hierarchy for DBCore. +""" +import re +from beets import util +from datetime import datetime, timedelta + + +class Query(object): + """An abstract class representing a query into the item database. + """ + def clause(self): + """Generate an SQLite expression implementing the query. + Return a clause string, a sequence of substitution values for + the clause, and a Query object representing the "remainder" + Returns (clause, subvals) where clause is a valid sqlite + WHERE clause implementing the query and subvals is a list of + items to be substituted for ?s in the clause. + """ + return None, () + + def match(self, item): + """Check whether this query matches a given Item. Can be used to + perform queries on arbitrary sets of Items. + """ + raise NotImplementedError + + +class FieldQuery(Query): + """An abstract query that searches in a specific field for a + pattern. Subclasses must provide a `value_match` class method, which + determines whether a certain pattern string matches a certain value + string. Subclasses may also provide `col_clause` to implement the + same matching functionality in SQLite. + """ + def __init__(self, field, pattern, fast=True): + self.field = field + self.pattern = pattern + self.fast = fast + + def col_clause(self): + return None, () + + def clause(self): + if self.fast: + return self.col_clause() + else: + # Matching a flexattr. This is a slow query. + return None, () + + @classmethod + def value_match(cls, pattern, value): + """Determine whether the value matches the pattern. Both + arguments are strings. + """ + raise NotImplementedError() + + def match(self, item): + return self.value_match(self.pattern, item.get(self.field)) + + +class MatchQuery(FieldQuery): + """A query that looks for exact matches in an item field.""" + def col_clause(self): + return self.field + " = ?", [self.pattern] + + @classmethod + def value_match(cls, pattern, value): + return pattern == value + + +class StringFieldQuery(FieldQuery): + """A FieldQuery that converts values to strings before matching + them. + """ + @classmethod + def value_match(cls, pattern, value): + """Determine whether the value matches the pattern. The value + may have any type. + """ + return cls.string_match(pattern, util.as_string(value)) + + @classmethod + def string_match(cls, pattern, value): + """Determine whether the value matches the pattern. Both + arguments are strings. Subclasses implement this method. + """ + raise NotImplementedError() + + +class SubstringQuery(StringFieldQuery): + """A query that matches a substring in a specific item field.""" + def col_clause(self): + search = '%' + (self.pattern.replace('\\','\\\\').replace('%','\\%') + .replace('_','\\_')) + '%' + clause = self.field + " like ? escape '\\'" + subvals = [search] + return clause, subvals + + @classmethod + def string_match(cls, pattern, value): + return pattern.lower() in value.lower() + + +class RegexpQuery(StringFieldQuery): + """A query that matches a regular expression in a specific item + field. + """ + @classmethod + def string_match(cls, pattern, value): + try: + res = re.search(pattern, value) + except re.error: + # Invalid regular expression. + return False + return res is not None + + +class BooleanQuery(MatchQuery): + """Matches a boolean field. Pattern should either be a boolean or a + string reflecting a boolean. + """ + def __init__(self, field, pattern, fast=True): + super(BooleanQuery, self).__init__(field, pattern, fast) + if isinstance(pattern, basestring): + self.pattern = util.str2bool(pattern) + self.pattern = int(self.pattern) + + +class BytesQuery(MatchQuery): + """Match a raw bytes field (i.e., a path). This is a necessary hack + to work around the `sqlite3` module's desire to treat `str` and + `unicode` equivalently in Python 2. Always use this query instead of + `MatchQuery` when matching on BLOB values. + """ + def __init__(self, field, pattern): + super(BytesQuery, self).__init__(field, pattern) + + # Use a buffer representation of the pattern for SQLite + # matching. This instructs SQLite to treat the blob as binary + # rather than encoded Unicode. + if isinstance(self.pattern, basestring): + # Implicitly coerce Unicode strings to their bytes + # equivalents. + if isinstance(self.pattern, unicode): + self.pattern = self.pattern.encode('utf8') + self.buf_pattern = buffer(self.pattern) + elif isinstance(self.pattern, buffer): + self.buf_pattern = self.pattern + self.pattern = bytes(self.pattern) + + def col_clause(self): + return self.field + " = ?", [self.buf_pattern] + + +class NumericQuery(FieldQuery): + """Matches numeric fields. A syntax using Ruby-style range ellipses + (``..``) lets users specify one- or two-sided ranges. For example, + ``year:2001..`` finds music released since the turn of the century. + """ + def _convert(self, s): + """Convert a string to a numeric type (float or int). If the + string cannot be converted, return None. + """ + # This is really just a bit of fun premature optimization. + try: + return int(s) + except ValueError: + try: + return float(s) + except ValueError: + return None + + def __init__(self, field, pattern, fast=True): + super(NumericQuery, self).__init__(field, pattern, fast) + + parts = pattern.split('..', 1) + if len(parts) == 1: + # No range. + self.point = self._convert(parts[0]) + self.rangemin = None + self.rangemax = None + else: + # One- or two-sided range. + self.point = None + self.rangemin = self._convert(parts[0]) + self.rangemax = self._convert(parts[1]) + + def match(self, item): + value = getattr(item, self.field) + if isinstance(value, basestring): + value = self._convert(value) + + if self.point is not None: + return value == self.point + else: + if self.rangemin is not None and value < self.rangemin: + return False + if self.rangemax is not None and value > self.rangemax: + return False + return True + + def col_clause(self): + if self.point is not None: + return self.field + '=?', (self.point,) + else: + if self.rangemin is not None and self.rangemax is not None: + return (u'{0} >= ? AND {0} <= ?'.format(self.field), + (self.rangemin, self.rangemax)) + elif self.rangemin is not None: + return u'{0} >= ?'.format(self.field), (self.rangemin,) + elif self.rangemax is not None: + return u'{0} <= ?'.format(self.field), (self.rangemax,) + else: + return '1', () + + +class CollectionQuery(Query): + """An abstract query class that aggregates other queries. Can be + indexed like a list to access the sub-queries. + """ + def __init__(self, subqueries=()): + self.subqueries = subqueries + + # Act like a sequence. + def __len__(self): + return len(self.subqueries) + def __getitem__(self, key): + return self.subqueries[key] + def __iter__(self): + return iter(self.subqueries) + def __contains__(self, item): + return item in self.subqueries + + def clause_with_joiner(self, joiner): + """Returns a clause created by joining together the clauses of + all subqueries with the string joiner (padded by spaces). + """ + clause_parts = [] + subvals = [] + for subq in self.subqueries: + subq_clause, subq_subvals = subq.clause() + if not subq_clause: + # Fall back to slow query. + return None, () + clause_parts.append('(' + subq_clause + ')') + subvals += subq_subvals + clause = (' ' + joiner + ' ').join(clause_parts) + return clause, subvals + + +class AnyFieldQuery(CollectionQuery): + """A query that matches if a given FieldQuery subclass matches in + any field. The individual field query class is provided to the + constructor. + """ + def __init__(self, pattern, fields, cls): + self.pattern = pattern + self.fields = fields + self.query_class = cls + + subqueries = [] + for field in self.fields: + subqueries.append(cls(field, pattern, True)) + super(AnyFieldQuery, self).__init__(subqueries) + + def clause(self): + return self.clause_with_joiner('or') + + def match(self, item): + for subq in self.subqueries: + if subq.match(item): + return True + return False + + +class MutableCollectionQuery(CollectionQuery): + """A collection query whose subqueries may be modified after the + query is initialized. + """ + def __setitem__(self, key, value): + self.subqueries[key] = value + + def __delitem__(self, key): + del self.subqueries[key] + + +class AndQuery(MutableCollectionQuery): + """A conjunction of a list of other queries.""" + def clause(self): + return self.clause_with_joiner('and') + + def match(self, item): + return all([q.match(item) for q in self.subqueries]) + + +class OrQuery(MutableCollectionQuery): + """A conjunction of a list of other queries.""" + def clause(self): + return self.clause_with_joiner('or') + + def match(self, item): + return any([q.match(item) for q in self.subqueries]) + + +class TrueQuery(Query): + """A query that always matches.""" + def clause(self): + return '1', () + + def match(self, item): + return True + + +class FalseQuery(Query): + """A query that never matches.""" + def clause(self): + return '0', () + + def match(self, item): + return False + + + +# Time/date queries. + + +def _to_epoch_time(date): + """Convert a `datetime` object to an integer number of seconds since + the (local) Unix epoch. + """ + epoch = datetime.fromtimestamp(0) + delta = date - epoch + try: + return int(delta.total_seconds()) + except AttributeError: + # datetime.timedelta.total_seconds() is not available on Python 2.6 + return delta.seconds + delta.days * 24 * 3600 + + +def _parse_periods(pattern): + """Parse a string containing two dates separated by two dots (..). + Return a pair of `Period` objects. + """ + parts = pattern.split('..', 1) + if len(parts) == 1: + instant = Period.parse(parts[0]) + return (instant, instant) + else: + start = Period.parse(parts[0]) + end = Period.parse(parts[1]) + return (start, end) + + +class Period(object): + """A period of time given by a date, time and precision. + + Example: 2014-01-01 10:50:30 with precision 'month' represents all + instants of time during January 2014. + """ + + precisions = ('year', 'month', 'day') + date_formats = ('%Y', '%Y-%m', '%Y-%m-%d') + + def __init__(self, date, precision): + """Create a period with the given date (a `datetime` object) and + precision (a string, one of "year", "month", or "day"). + """ + if precision not in Period.precisions: + raise ValueError('Invalid precision ' + str(precision)) + self.date = date + self.precision = precision + + @classmethod + def parse(cls, string): + """Parse a date and return a `Period` object or `None` if the + string is empty. + """ + if not string: + return None + ordinal = string.count('-') + if ordinal >= len(cls.date_formats): + raise ValueError('date is not in one of the formats ' + + ', '.join(cls.date_formats)) + date_format = cls.date_formats[ordinal] + date = datetime.strptime(string, date_format) + precision = cls.precisions[ordinal] + return cls(date, precision) + + def open_right_endpoint(self): + """Based on the precision, convert the period to a precise + `datetime` for use as a right endpoint in a right-open interval. + """ + precision = self.precision + date = self.date + if 'year' == self.precision: + return date.replace(year=date.year + 1, month=1) + elif 'month' == precision: + if (date.month < 12): + return date.replace(month=date.month + 1) + else: + return date.replace(year=date.year + 1, month=1) + elif 'day' == precision: + return date + timedelta(days=1) + else: + raise ValueError('unhandled precision ' + str(precision)) + + +class DateInterval(object): + """A closed-open interval of dates. + + A left endpoint of None means since the beginning of time. + A right endpoint of None means towards infinity. + """ + + def __init__(self, start, end): + if start is not None and end is not None and not start < end: + raise ValueError("start date {0} is not before end date {1}" + .format(start, end)) + self.start = start + self.end = end + + @classmethod + def from_periods(cls, start, end): + """Create an interval with two Periods as the endpoints. + """ + end_date = end.open_right_endpoint() if end is not None else None + start_date = start.date if start is not None else None + return cls(start_date, end_date) + + def contains(self, date): + if self.start is not None and date < self.start: + return False + if self.end is not None and date >= self.end: + return False + return True + + def __str__(self): + return'[{0}, {1})'.format(self.start, self.end) + + +class DateQuery(FieldQuery): + """Matches date fields stored as seconds since Unix epoch time. + + Dates can be specified as ``year-month-day`` strings where only year + is mandatory. + + The value of a date field can be matched against a date interval by + using an ellipsis interval syntax similar to that of NumericQuery. + """ + def __init__(self, field, pattern, fast=True): + super(DateQuery, self).__init__(field, pattern, fast) + start, end = _parse_periods(pattern) + self.interval = DateInterval.from_periods(start, end) + + def match(self, item): + timestamp = float(item[self.field]) + date = datetime.utcfromtimestamp(timestamp) + return self.interval.contains(date) + + _clause_tmpl = "{0} {1} ?" + + def col_clause(self): + clause_parts = [] + subvals = [] + + if self.interval.start: + clause_parts.append(self._clause_tmpl.format(self.field, ">=")) + subvals.append(_to_epoch_time(self.interval.start)) + + if self.interval.end: + clause_parts.append(self._clause_tmpl.format(self.field, "<")) + subvals.append(_to_epoch_time(self.interval.end)) + + if clause_parts: + # One- or two-sided interval. + clause = ' AND '.join(clause_parts) + else: + # Match any date. + clause = '1' + return clause, subvals diff --git a/libs/beets/dbcore/types.py b/libs/beets/dbcore/types.py new file mode 100644 index 00000000..165c0b60 --- /dev/null +++ b/libs/beets/dbcore/types.py @@ -0,0 +1,140 @@ +# This file is part of beets. +# Copyright 2014, Adrian Sampson. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. + +"""Representation of type information for DBCore model fields. +""" +from . import query +from beets.util import str2bool + + + +# Abstract base. + + +class Type(object): + """An object encapsulating the type of a model field. Includes + information about how to store the value in the database, query, + format, and parse a given field. + """ + + sql = None + """The SQLite column type for the value. + """ + + query = None + """The `Query` subclass to be used when querying the field. + """ + + def format(self, value): + """Given a value of this type, produce a Unicode string + representing the value. This is used in template evaluation. + """ + raise NotImplementedError() + + def parse(self, string): + """Parse a (possibly human-written) string and return the + indicated value of this type. + """ + raise NotImplementedError() + + + +# Reusable types. + + +class Integer(Type): + """A basic integer type. + """ + sql = u'INTEGER' + query = query.NumericQuery + + def format(self, value): + return unicode(value or 0) + + def parse(self, string): + try: + return int(string) + except ValueError: + return 0 + + +class PaddedInt(Integer): + """An integer field that is formatted with a given number of digits, + padded with zeroes. + """ + def __init__(self, digits): + self.digits = digits + + def format(self, value): + return u'{0:0{1}d}'.format(value or 0, self.digits) + + +class ScaledInt(Integer): + """An integer whose formatting operation scales the number by a + constant and adds a suffix. Good for units with large magnitudes. + """ + def __init__(self, unit, suffix=u''): + self.unit = unit + self.suffix = suffix + + def format(self, value): + return u'{0}{1}'.format((value or 0) // self.unit, self.suffix) + + +class Id(Integer): + """An integer used as the row key for a SQLite table. + """ + sql = u'INTEGER PRIMARY KEY' + + +class Float(Type): + """A basic floating-point type. + """ + sql = u'REAL' + query = query.NumericQuery + + def format(self, value): + return u'{0:.1f}'.format(value or 0.0) + + def parse(self, string): + try: + return float(string) + except ValueError: + return 0.0 + + +class String(Type): + """A Unicode string type. + """ + sql = u'TEXT' + query = query.SubstringQuery + + def format(self, value): + return unicode(value) if value else u'' + + def parse(self, string): + return string + + +class Boolean(Type): + """A boolean type. + """ + sql = u'INTEGER' + query = query.BooleanQuery + + def format(self, value): + return unicode(bool(value)) + + def parse(self, string): + return str2bool(string) diff --git a/libs/beets/importer.py b/libs/beets/importer.py new file mode 100644 index 00000000..f997770c --- /dev/null +++ b/libs/beets/importer.py @@ -0,0 +1,1030 @@ +# This file is part of beets. +# Copyright 2013, Adrian Sampson. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. + +"""Provides the basic, interface-agnostic workflow for importing and +autotagging music files. +""" +from __future__ import print_function + +import os +import logging +import pickle +import itertools +from collections import defaultdict + +from beets import autotag +from beets import library +from beets import dbcore +from beets import plugins +from beets import util +from beets import config +from beets.util import pipeline +from beets.util import syspath, normpath, displayable_path +from beets.util.enumeration import enum +from beets import mediafile + +action = enum( + 'SKIP', 'ASIS', 'TRACKS', 'MANUAL', 'APPLY', 'MANUAL_ID', + 'ALBUMS', name='action' +) + +QUEUE_SIZE = 128 +SINGLE_ARTIST_THRESH = 0.25 +VARIOUS_ARTISTS = u'Various Artists' + +# Global logger. +log = logging.getLogger('beets') + +class ImportAbort(Exception): + """Raised when the user aborts the tagging operation. + """ + pass + + +# Utilities. + +def _duplicate_check(lib, task): + """Check whether an album already exists in the library. Returns a + list of Album objects (empty if no duplicates are found). + """ + assert task.choice_flag in (action.ASIS, action.APPLY) + artist, album = task.chosen_ident() + + if artist is None: + # As-is import with no artist. Skip check. + return [] + + found_albums = [] + cur_paths = set(i.path for i in task.items if i) + for album_cand in lib.albums(dbcore.MatchQuery('albumartist', artist)): + if album_cand.album == album: + # Check whether the album is identical in contents, in which + # case it is not a duplicate (will be replaced). + other_paths = set(i.path for i in album_cand.items()) + if other_paths == cur_paths: + continue + found_albums.append(album_cand) + return found_albums + +def _item_duplicate_check(lib, task): + """Check whether an item already exists in the library. Returns a + list of Item objects. + """ + assert task.choice_flag in (action.ASIS, action.APPLY) + artist, title = task.chosen_ident() + + found_items = [] + query = dbcore.AndQuery(( + dbcore.MatchQuery('artist', artist), + dbcore.MatchQuery('title', title), + )) + for other_item in lib.items(query): + # Existing items not considered duplicates. + if other_item.path == task.item.path: + continue + found_items.append(other_item) + return found_items + +def _infer_album_fields(task): + """Given an album and an associated import task, massage the + album-level metadata. This ensures that the album artist is set + and that the "compilation" flag is set automatically. + """ + assert task.is_album + assert task.items + + changes = {} + + if task.choice_flag == action.ASIS: + # Taking metadata "as-is". Guess whether this album is VA. + plur_albumartist, freq = util.plurality( + [i.albumartist or i.artist for i in task.items]) + if freq == len(task.items) or (freq > 1 and + float(freq) / len(task.items) >= SINGLE_ARTIST_THRESH): + # Single-artist album. + changes['albumartist'] = plur_albumartist + changes['comp'] = False + else: + # VA. + changes['albumartist'] = VARIOUS_ARTISTS + changes['comp'] = True + + elif task.choice_flag == action.APPLY: + # Applying autotagged metadata. Just get AA from the first + # item. + for item in task.items: + if item is not None: + first_item = item + break + else: + assert False, "all items are None" + if not first_item.albumartist: + changes['albumartist'] = first_item.artist + if not first_item.mb_albumartistid: + changes['mb_albumartistid'] = first_item.mb_artistid + + else: + assert False + + # Apply new metadata. + for item in task.items: + if item is not None: + for k, v in changes.iteritems(): + setattr(item, k, v) + +def _resume(): + """Check whether an import should resume and return a boolean or the + string 'ask' indicating that the user should be queried. + """ + return config['import']['resume'].as_choice([True, False, 'ask']) + +def _open_state(): + """Reads the state file, returning a dictionary.""" + try: + with open(config['statefile'].as_filename()) as f: + return pickle.load(f) + except (IOError, EOFError): + return {} +def _save_state(state): + """Writes the state dictionary out to disk.""" + try: + with open(config['statefile'].as_filename(), 'w') as f: + pickle.dump(state, f) + except IOError as exc: + log.error(u'state file could not be written: %s' % unicode(exc)) + + +# Utilities for reading and writing the beets progress file, which +# allows long tagging tasks to be resumed when they pause (or crash). +PROGRESS_KEY = 'tagprogress' +def progress_set(toppath, paths): + """Record that tagging for the given `toppath` was successful up to + `paths`. If paths is None, then clear the progress value (indicating + that the tagging completed). + """ + state = _open_state() + if PROGRESS_KEY not in state: + state[PROGRESS_KEY] = {} + + if paths is None: + # Remove progress from file. + if toppath in state[PROGRESS_KEY]: + del state[PROGRESS_KEY][toppath] + else: + state[PROGRESS_KEY][toppath] = paths + + _save_state(state) +def progress_get(toppath): + """Get the last successfully tagged subpath of toppath. If toppath + has no progress information, returns None. + """ + state = _open_state() + if PROGRESS_KEY not in state: + return None + return state[PROGRESS_KEY].get(toppath) + + +# Similarly, utilities for manipulating the "incremental" import log. +# This keeps track of all directories that were ever imported, which +# allows the importer to only import new stuff. +HISTORY_KEY = 'taghistory' +def history_add(paths): + """Indicate that the import of the album in `paths` is completed and + should not be repeated in incremental imports. + """ + state = _open_state() + if HISTORY_KEY not in state: + state[HISTORY_KEY] = set() + + state[HISTORY_KEY].add(tuple(paths)) + + _save_state(state) +def history_get(): + """Get the set of completed path tuples in incremental imports. + """ + state = _open_state() + if HISTORY_KEY not in state: + return set() + return state[HISTORY_KEY] + + +# Abstract session class. + +class ImportSession(object): + """Controls an import action. Subclasses should implement methods to + communicate with the user or otherwise make decisions. + """ + def __init__(self, lib, logfile, paths, query): + """Create a session. `lib` is a Library object. `logfile` is a + file-like object open for writing or None if no logging is to be + performed. Either `paths` or `query` is non-null and indicates + the source of files to be imported. + """ + self.lib = lib + self.logfile = logfile + self.paths = paths + self.query = query + + # Normalize the paths. + if self.paths: + self.paths = map(normpath, self.paths) + + def _amend_config(self): + """Make implied changes the importer configuration. + """ + # FIXME: Maybe this function should not exist and should instead + # provide "decision wrappers" like "should_resume()", etc. + iconfig = config['import'] + + # Incremental and progress are mutually exclusive. + if iconfig['incremental']: + iconfig['resume'] = False + + # When based on a query instead of directories, never + # save progress or try to resume. + if self.query is not None: + iconfig['resume'] = False + iconfig['incremental'] = False + + # Copy and move are mutually exclusive. + if iconfig['move']: + iconfig['copy'] = False + + # Only delete when copying. + if not iconfig['copy']: + iconfig['delete'] = False + + def tag_log(self, status, paths): + """Log a message about a given album to logfile. The status should + reflect the reason the album couldn't be tagged. + """ + if self.logfile: + print(u'{0} {1}'.format(status, displayable_path(paths)), + file=self.logfile) + self.logfile.flush() + + def log_choice(self, task, duplicate=False): + """Logs the task's current choice if it should be logged. If + ``duplicate``, then this is a secondary choice after a duplicate was + detected and a decision was made. + """ + paths = task.paths if task.is_album else [task.item.path] + if duplicate: + # Duplicate: log all three choices (skip, keep both, and trump). + if task.remove_duplicates: + self.tag_log('duplicate-replace', paths) + elif task.choice_flag in (action.ASIS, action.APPLY): + self.tag_log('duplicate-keep', paths) + elif task.choice_flag is (action.SKIP): + self.tag_log('duplicate-skip', paths) + else: + # Non-duplicate: log "skip" and "asis" choices. + if task.choice_flag is action.ASIS: + self.tag_log('asis', paths) + elif task.choice_flag is action.SKIP: + self.tag_log('skip', paths) + + def should_resume(self, path): + raise NotImplementedError + + def choose_match(self, task): + raise NotImplementedError + + def resolve_duplicate(self, task): + raise NotImplementedError + + def choose_item(self, task): + raise NotImplementedError + + def run(self): + """Run the import task. + """ + self._amend_config() + + # Set up the pipeline. + if self.query is None: + stages = [read_tasks(self)] + else: + stages = [query_tasks(self)] + if config['import']['singletons']: + # Singleton importer. + if config['import']['autotag']: + stages += [item_lookup(self), item_query(self)] + else: + stages += [item_progress(self)] + else: + # Whole-album importer. + if config['import']['group_albums']: + # Split directory tasks into one task for each album + stages += [group_albums(self)] + if config['import']['autotag']: + # Only look up and query the user when autotagging. + stages += [initial_lookup(self), user_query(self)] + else: + # When not autotagging, just display progress. + stages += [show_progress(self)] + stages += [apply_choices(self)] + for stage_func in plugins.import_stages(): + stages.append(plugin_stage(self, stage_func)) + stages += [manipulate_files(self)] + stages += [finalize(self)] + pl = pipeline.Pipeline(stages) + + # Run the pipeline. + try: + if config['threaded']: + pl.run_parallel(QUEUE_SIZE) + else: + pl.run_sequential() + except ImportAbort: + # User aborted operation. Silently stop. + pass + + +# The importer task class. + +class ImportTask(object): + """Represents a single set of items to be imported along with its + intermediate state. May represent an album or a single item. + """ + def __init__(self, toppath=None, paths=None, items=None): + self.toppath = toppath + self.paths = paths + self.items = items + self.sentinel = False + self.remove_duplicates = False + self.is_album = True + self.choice_flag = None + + @classmethod + def done_sentinel(cls, toppath): + """Create an ImportTask that indicates the end of a top-level + directory import. + """ + obj = cls(toppath) + obj.sentinel = True + return obj + + @classmethod + def progress_sentinel(cls, toppath, paths): + """Create a task indicating that a single directory in a larger + import has finished. This is only required for singleton + imports; progress is implied for album imports. + """ + obj = cls(toppath, paths) + obj.sentinel = True + return obj + + @classmethod + def item_task(cls, item): + """Creates an ImportTask for a single item.""" + obj = cls() + obj.item = item + obj.is_album = False + return obj + + def set_candidates(self, cur_artist, cur_album, candidates, rec): + """Sets the candidates for this album matched by the + `autotag.tag_album` method. + """ + assert self.is_album + assert not self.sentinel + self.cur_artist = cur_artist + self.cur_album = cur_album + self.candidates = candidates + self.rec = rec + + def set_null_candidates(self): + """Set the candidates to indicate no album match was found. + """ + self.cur_artist = None + self.cur_album = None + self.candidates = None + self.rec = None + + def set_item_candidates(self, candidates, rec): + """Set the match for a single-item task.""" + assert not self.is_album + assert self.item is not None + self.candidates = candidates + self.rec = rec + + def set_choice(self, choice): + """Given an AlbumMatch or TrackMatch object or an action constant, + indicates that an action has been selected for this task. + """ + assert not self.sentinel + # Not part of the task structure: + assert choice not in (action.MANUAL, action.MANUAL_ID) + assert choice != action.APPLY # Only used internally. + if choice in (action.SKIP, action.ASIS, action.TRACKS, action.ALBUMS): + self.choice_flag = choice + self.match = None + else: + if self.is_album: + assert isinstance(choice, autotag.AlbumMatch) + else: + assert isinstance(choice, autotag.TrackMatch) + self.choice_flag = action.APPLY # Implicit choice. + self.match = choice + + def save_progress(self): + """Updates the progress state to indicate that this album has + finished. + """ + if self.sentinel and self.paths is None: + # "Done" sentinel. + progress_set(self.toppath, None) + elif self.sentinel or self.is_album: + # "Directory progress" sentinel for singletons or a real + # album task, which implies the same. + progress_set(self.toppath, self.paths) + + def save_history(self): + """Save the directory in the history for incremental imports. + """ + if self.is_album and self.paths and not self.sentinel: + history_add(self.paths) + + + # Logical decisions. + + def should_write_tags(self): + """Should new info be written to the files' metadata?""" + if self.choice_flag == action.APPLY: + return True + elif self.choice_flag in (action.ASIS, action.TRACKS, action.SKIP): + return False + else: + assert False + + def should_skip(self): + """After a choice has been made, returns True if this is a + sentinel or it has been marked for skipping. + """ + return self.sentinel or self.choice_flag == action.SKIP + + + # Convenient data. + + def chosen_ident(self): + """Returns identifying metadata about the current choice. For + albums, this is an (artist, album) pair. For items, this is + (artist, title). May only be called when the choice flag is ASIS + (in which case the data comes from the files' current metadata) + or APPLY (data comes from the choice). + """ + assert self.choice_flag in (action.ASIS, action.APPLY) + if self.is_album: + if self.choice_flag is action.ASIS: + return (self.cur_artist, self.cur_album) + elif self.choice_flag is action.APPLY: + return (self.match.info.artist, self.match.info.album) + else: + if self.choice_flag is action.ASIS: + return (self.item.artist, self.item.title) + elif self.choice_flag is action.APPLY: + return (self.match.info.artist, self.match.info.title) + + def imported_items(self): + """Return a list of Items that should be added to the library. + If this is an album task, return the list of items in the + selected match or everything if the choice is ASIS. If this is a + singleton task, return a list containing the item. + """ + if self.is_album: + if self.choice_flag == action.ASIS: + return list(self.items) + elif self.choice_flag == action.APPLY: + return self.match.mapping.keys() + else: + assert False + else: + return [self.item] + + + # Utilities. + + def prune(self, filename): + """Prune any empty directories above the given file. If this + task has no `toppath` or the file path provided is not within + the `toppath`, then this function has no effect. Similarly, if + the file still exists, no pruning is performed, so it's safe to + call when the file in question may not have been removed. + """ + if self.toppath and not os.path.exists(filename): + util.prune_dirs(os.path.dirname(filename), + self.toppath, + clutter=config['clutter'].as_str_seq()) + + +# Full-album pipeline stages. + +def read_tasks(session): + """A generator yielding all the albums (as ImportTask objects) found + in the user-specified list of paths. In the case of a singleton + import, yields single-item tasks instead. + """ + # Look for saved progress. + if _resume(): + resume_dirs = {} + for path in session.paths: + resume_dir = progress_get(path) + if resume_dir: + + # Either accept immediately or prompt for input to decide. + if _resume() is True: + do_resume = True + log.warn('Resuming interrupted import of %s' % path) + else: + do_resume = session.should_resume(path) + + if do_resume: + resume_dirs[path] = resume_dir + else: + # Clear progress; we're starting from the top. + progress_set(path, None) + + # Look for saved incremental directories. + if config['import']['incremental']: + incremental_skipped = 0 + history_dirs = history_get() + + for toppath in session.paths: + # Check whether the path is to a file. + if config['import']['singletons'] and \ + not os.path.isdir(syspath(toppath)): + try: + item = library.Item.from_path(toppath) + except mediafile.UnreadableFileError: + log.warn(u'unreadable file: {0}'.format( + util.displayable_path(toppath) + )) + continue + yield ImportTask.item_task(item) + continue + + # A flat album import merges all items into one album. + if config['import']['flat'] and not config['import']['singletons']: + all_items = [] + for _, items in autotag.albums_in_dir(toppath): + all_items += items + yield ImportTask(toppath, toppath, all_items) + yield ImportTask.done_sentinel(toppath) + continue + + # Produce paths under this directory. + if _resume(): + resume_dir = resume_dirs.get(toppath) + for path, items in autotag.albums_in_dir(toppath): + # Skip according to progress. + if _resume() and resume_dir: + # We're fast-forwarding to resume a previous tagging. + if path == resume_dir: + # We've hit the last good path! Turn off the + # fast-forwarding. + resume_dir = None + continue + + # When incremental, skip paths in the history. + if config['import']['incremental'] and tuple(path) in history_dirs: + log.debug(u'Skipping previously-imported path: %s' % + displayable_path(path)) + incremental_skipped += 1 + continue + + # Yield all the necessary tasks. + if config['import']['singletons']: + for item in items: + yield ImportTask.item_task(item) + yield ImportTask.progress_sentinel(toppath, path) + else: + yield ImportTask(toppath, path, items) + + # Indicate the directory is finished. + yield ImportTask.done_sentinel(toppath) + + # Show skipped directories. + if config['import']['incremental'] and incremental_skipped: + log.info(u'Incremental import: skipped %i directories.' % + incremental_skipped) + +def query_tasks(session): + """A generator that works as a drop-in-replacement for read_tasks. + Instead of finding files from the filesystem, a query is used to + match items from the library. + """ + if config['import']['singletons']: + # Search for items. + for item in session.lib.items(session.query): + yield ImportTask.item_task(item) + + else: + # Search for albums. + for album in session.lib.albums(session.query): + log.debug('yielding album %i: %s - %s' % + (album.id, album.albumartist, album.album)) + items = list(album.items()) + yield ImportTask(None, [album.item_dir()], items) + +def initial_lookup(session): + """A coroutine for performing the initial MusicBrainz lookup for an + album. It accepts lists of Items and yields + (items, cur_artist, cur_album, candidates, rec) tuples. If no match + is found, all of the yielded parameters (except items) are None. + """ + task = None + while True: + task = yield task + if task.should_skip(): + continue + + plugins.send('import_task_start', session=session, task=task) + + log.debug('Looking up: %s' % displayable_path(task.paths)) + task.set_candidates( + *autotag.tag_album(task.items) + ) + +def user_query(session): + """A coroutine for interfacing with the user about the tagging + process. + + The coroutine accepts an ImportTask objects. It uses the + session's ``choose_match`` method to determine the ``action`` for + this task. Depending on the action additional stages are exectuted + and the processed task is yielded. + + It emits the ``import_task_choice`` event for plugins. Plugins have + acces to the choice via the ``taks.choice_flag`` property and may + choose to change it. + """ + recent = set() + task = None + while True: + task = yield task + if task.should_skip(): + continue + + # Ask the user for a choice. + choice = session.choose_match(task) + task.set_choice(choice) + session.log_choice(task) + plugins.send('import_task_choice', session=session, task=task) + + # As-tracks: transition to singleton workflow. + if task.choice_flag is action.TRACKS: + # Set up a little pipeline for dealing with the singletons. + def emitter(task): + for item in task.items: + yield ImportTask.item_task(item) + yield ImportTask.progress_sentinel(task.toppath, task.paths) + + ipl = pipeline.Pipeline([ + emitter(task), + item_lookup(session), + item_query(session), + ]) + task = pipeline.multiple(ipl.pull()) + continue + + # As albums: group items by albums and create task for each album + if task.choice_flag is action.ALBUMS: + def emitter(task): + yield task + + ipl = pipeline.Pipeline([ + emitter(task), + group_albums(session), + initial_lookup(session), + user_query(session) + ]) + task = pipeline.multiple(ipl.pull()) + continue + + # Check for duplicates if we have a match (or ASIS). + if task.choice_flag in (action.ASIS, action.APPLY): + ident = task.chosen_ident() + # The "recent" set keeps track of identifiers for recently + # imported albums -- those that haven't reached the database + # yet. + if ident in recent or _duplicate_check(session.lib, task): + session.resolve_duplicate(task) + session.log_choice(task, True) + recent.add(ident) + +def show_progress(session): + """This stage replaces the initial_lookup and user_query stages + when the importer is run without autotagging. It displays the album + name and artist as the files are added. + """ + task = None + while True: + task = yield task + if task.should_skip(): + continue + + log.info(displayable_path(task.paths)) + + # Behave as if ASIS were selected. + task.set_null_candidates() + task.set_choice(action.ASIS) + +def apply_choices(session): + """A coroutine for applying changes to albums and singletons during + the autotag process. + """ + task = None + while True: + task = yield task + if task.should_skip(): + continue + + items = task.imported_items() + # Clear IDs in case the items are being re-tagged. + for item in items: + item.id = None + item.album_id = None + + # Change metadata. + if task.should_write_tags(): + if task.is_album: + autotag.apply_metadata( + task.match.info, task.match.mapping + ) + else: + autotag.apply_item_metadata(task.item, task.match.info) + plugins.send('import_task_apply', session=session, task=task) + + # Infer album-level fields. + if task.is_album: + _infer_album_fields(task) + + # Find existing item entries that these are replacing (for + # re-imports). Old album structures are automatically cleaned up + # when the last item is removed. + task.replaced_items = defaultdict(list) + for item in items: + dup_items = session.lib.items( + dbcore.query.BytesQuery('path', item.path) + ) + for dup_item in dup_items: + task.replaced_items[item].append(dup_item) + log.debug('replacing item %i: %s' % + (dup_item.id, displayable_path(item.path))) + log.debug('%i of %i items replaced' % (len(task.replaced_items), + len(items))) + + # Find old items that should be replaced as part of a duplicate + # resolution. + duplicate_items = [] + if task.remove_duplicates: + if task.is_album: + for album in _duplicate_check(session.lib, task): + duplicate_items += album.items() + else: + duplicate_items = _item_duplicate_check(session.lib, task) + log.debug('removing %i old duplicated items' % + len(duplicate_items)) + + # Delete duplicate files that are located inside the library + # directory. + task.duplicate_paths = [] + for duplicate_path in [i.path for i in duplicate_items]: + if session.lib.directory in util.ancestry(duplicate_path): + # Mark the path for deletion in the manipulate_files + # stage. + task.duplicate_paths.append(duplicate_path) + + # Add items -- before path changes -- to the library. We add the + # items now (rather than at the end) so that album structures + # are in place before calls to destination(). + with session.lib.transaction(): + # Remove old items. + for replaced in task.replaced_items.itervalues(): + for item in replaced: + item.remove() + for item in duplicate_items: + item.remove() + + # Add new ones. + if task.is_album: + # Add an album. + album = session.lib.add_album(items) + task.album_id = album.id + else: + # Add tracks. + for item in items: + session.lib.add(item) + +def plugin_stage(session, func): + """A coroutine (pipeline stage) that calls the given function with + each non-skipped import task. These stages occur between applying + metadata changes and moving/copying/writing files. + """ + task = None + while True: + task = yield task + if task.should_skip(): + continue + func(session, task) + + # Stage may modify DB, so re-load cached item data. + for item in task.imported_items(): + item.load() + +def manipulate_files(session): + """A coroutine (pipeline stage) that performs necessary file + manipulations *after* items have been added to the library. + """ + task = None + while True: + task = yield task + if task.should_skip(): + continue + + # Remove duplicate files marked for deletion. + if task.remove_duplicates: + for duplicate_path in task.duplicate_paths: + log.debug(u'deleting replaced duplicate %s' % + util.displayable_path(duplicate_path)) + util.remove(duplicate_path) + util.prune_dirs(os.path.dirname(duplicate_path), + session.lib.directory) + + # Move/copy/write files. + items = task.imported_items() + # Save the original paths of all items for deletion and pruning + # in the next step (finalization). + task.old_paths = [item.path for item in items] + for item in items: + if config['import']['move']: + # Just move the file. + item.move(False) + elif config['import']['copy']: + # If it's a reimport, move in-library files and copy + # out-of-library files. Otherwise, copy and keep track + # of the old path. + old_path = item.path + if task.replaced_items[item]: + # This is a reimport. Move in-library files and copy + # out-of-library files. + if session.lib.directory in util.ancestry(old_path): + item.move(False) + # We moved the item, so remove the + # now-nonexistent file from old_paths. + task.old_paths.remove(old_path) + else: + item.move(True) + else: + # A normal import. Just copy files and keep track of + # old paths. + item.move(True) + + if config['import']['write'] and task.should_write_tags(): + try: + item.write() + except library.FileOperationError as exc: + log.error(exc) + + # Save new paths. + with session.lib.transaction(): + for item in items: + item.store() + + # Plugin event. + plugins.send('import_task_files', session=session, task=task) + +def finalize(session): + """A coroutine that finishes up importer tasks. In particular, the + coroutine sends plugin events, deletes old files, and saves + progress. This is a "terminal" coroutine (it yields None). + """ + while True: + task = yield + if task.should_skip(): + if _resume(): + task.save_progress() + if config['import']['incremental']: + task.save_history() + continue + + items = task.imported_items() + + # Announce that we've added an album. + if task.is_album: + album = session.lib.get_album(task.album_id) + plugins.send('album_imported', + lib=session.lib, album=album) + else: + for item in items: + plugins.send('item_imported', + lib=session.lib, item=item) + + # When copying and deleting originals, delete old files. + if config['import']['copy'] and config['import']['delete']: + new_paths = [os.path.realpath(item.path) for item in items] + for old_path in task.old_paths: + # Only delete files that were actually copied. + if old_path not in new_paths: + util.remove(syspath(old_path), False) + task.prune(old_path) + + # When moving, prune empty directories containing the original + # files. + elif config['import']['move']: + for old_path in task.old_paths: + task.prune(old_path) + + # Update progress. + if _resume(): + task.save_progress() + if config['import']['incremental']: + task.save_history() + + +# Singleton pipeline stages. + +def item_lookup(session): + """A coroutine used to perform the initial MusicBrainz lookup for + an item task. + """ + task = None + while True: + task = yield task + if task.should_skip(): + continue + + plugins.send('import_task_start', session=session, task=task) + + task.set_item_candidates(*autotag.tag_item(task.item)) + +def item_query(session): + """A coroutine that queries the user for input on single-item + lookups. + """ + task = None + recent = set() + while True: + task = yield task + if task.should_skip(): + continue + + choice = session.choose_item(task) + task.set_choice(choice) + session.log_choice(task) + plugins.send('import_task_choice', session=session, task=task) + + # Duplicate check. + if task.choice_flag in (action.ASIS, action.APPLY): + ident = task.chosen_ident() + if ident in recent or _item_duplicate_check(session.lib, task): + session.resolve_duplicate(task) + session.log_choice(task, True) + recent.add(ident) + +def item_progress(session): + """Skips the lookup and query stages in a non-autotagged singleton + import. Just shows progress. + """ + task = None + log.info('Importing items:') + while True: + task = yield task + if task.should_skip(): + continue + + log.info(displayable_path(task.item.path)) + task.set_null_candidates() + task.set_choice(action.ASIS) + + +def group_albums(session): + """Group the items of a task by albumartist and album name and create a new + task for each album. Yield the tasks as a multi message. + """ + def group(item): + return (item.albumartist or item.artist, item.album) + + task = None + while True: + task = yield task + if task.should_skip(): + continue + tasks = [] + for _, items in itertools.groupby(task.items, group): + tasks.append(ImportTask(items=list(items))) + tasks.append(ImportTask.progress_sentinel(task.toppath, task.paths)) + + task = pipeline.multiple(tasks) diff --git a/libs/beets/library.py b/libs/beets/library.py new file mode 100644 index 00000000..94559430 --- /dev/null +++ b/libs/beets/library.py @@ -0,0 +1,1216 @@ +# This file is part of beets. +# Copyright 2013, Adrian Sampson. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. + +"""The core data store and collection logic for beets. +""" +import os +import re +import sys +import logging +import shlex +import unicodedata +import time +from unidecode import unidecode +from beets.mediafile import MediaFile, MutagenError +from beets import plugins +from beets import util +from beets.util import bytestring_path, syspath, normpath, samefile +from beets.util.functemplate import Template +from beets import dbcore +from beets.dbcore import types +import beets + + + +# Library-specific query types. + + +class PathQuery(dbcore.FieldQuery): + """A query that matches all items under a given path.""" + def __init__(self, field, pattern, fast=True): + super(PathQuery, self).__init__(field, pattern, fast) + + # Match the path as a single file. + self.file_path = util.bytestring_path(util.normpath(pattern)) + # As a directory (prefix). + self.dir_path = util.bytestring_path(os.path.join(self.file_path, '')) + + def match(self, item): + return (item.path == self.file_path) or \ + item.path.startswith(self.dir_path) + + def clause(self): + dir_pat = buffer(self.dir_path + '%') + file_blob = buffer(self.file_path) + return '({0} = ?) || ({0} LIKE ?)'.format(self.field), \ + (file_blob, dir_pat) + + +class SingletonQuery(dbcore.Query): + """Matches either singleton or non-singleton items.""" + def __init__(self, sense): + self.sense = sense + + def clause(self): + if self.sense: + return "album_id ISNULL", () + else: + return "NOT album_id ISNULL", () + + def match(self, item): + return (not item.album_id) == self.sense + + + +# Library-specific field types. + + +class DateType(types.Type): + sql = u'REAL' + query = dbcore.query.DateQuery + + def format(self, value): + return time.strftime(beets.config['time_format'].get(unicode), + time.localtime(value or 0)) + + def parse(self, string): + try: + # Try a formatted date string. + return time.mktime( + time.strptime(string, beets.config['time_format'].get(unicode)) + ) + except ValueError: + # Fall back to a plain timestamp number. + try: + return float(string) + except ValueError: + return 0.0 + + +class PathType(types.Type): + sql = u'BLOB' + query = PathQuery + + def format(self, value): + return util.displayable_path(value) + + def parse(self, string): + return normpath(bytestring_path(string)) + + + +# Model field lists. + + +# Fields in the "items" database table; all the metadata available for +# items in the library. These are used directly in SQL; they are +# vulnerable to injection if accessible to the user. +# Each tuple has the following values: +# - The name of the field. +# - The (Python) type of the field. +# - Is the field writable? +# - Does the field reflect an attribute of a MediaFile? +ITEM_FIELDS = [ + ('id', types.Id(), False, False), + ('path', PathType(), False, False), + ('album_id', types.Integer(), False, False), + + ('title', types.String(), True, True), + ('artist', types.String(), True, True), + ('artist_sort', types.String(), True, True), + ('artist_credit', types.String(), True, True), + ('album', types.String(), True, True), + ('albumartist', types.String(), True, True), + ('albumartist_sort', types.String(), True, True), + ('albumartist_credit', types.String(), True, True), + ('genre', types.String(), True, True), + ('composer', types.String(), True, True), + ('grouping', types.String(), True, True), + ('year', types.PaddedInt(4), True, True), + ('month', types.PaddedInt(2), True, True), + ('day', types.PaddedInt(2), True, True), + ('track', types.PaddedInt(2), True, True), + ('tracktotal', types.PaddedInt(2), True, True), + ('disc', types.PaddedInt(2), True, True), + ('disctotal', types.PaddedInt(2), True, True), + ('lyrics', types.String(), True, True), + ('comments', types.String(), True, True), + ('bpm', types.Integer(), True, True), + ('comp', types.Boolean(), True, True), + ('mb_trackid', types.String(), True, True), + ('mb_albumid', types.String(), True, True), + ('mb_artistid', types.String(), True, True), + ('mb_albumartistid', types.String(), True, True), + ('albumtype', types.String(), True, True), + ('label', types.String(), True, True), + ('acoustid_fingerprint', types.String(), True, True), + ('acoustid_id', types.String(), True, True), + ('mb_releasegroupid', types.String(), True, True), + ('asin', types.String(), True, True), + ('catalognum', types.String(), True, True), + ('script', types.String(), True, True), + ('language', types.String(), True, True), + ('country', types.String(), True, True), + ('albumstatus', types.String(), True, True), + ('media', types.String(), True, True), + ('albumdisambig', types.String(), True, True), + ('disctitle', types.String(), True, True), + ('encoder', types.String(), True, True), + ('rg_track_gain', types.Float(), True, True), + ('rg_track_peak', types.Float(), True, True), + ('rg_album_gain', types.Float(), True, True), + ('rg_album_peak', types.Float(), True, True), + ('original_year', types.PaddedInt(4), True, True), + ('original_month', types.PaddedInt(2), True, True), + ('original_day', types.PaddedInt(2), True, True), + + ('length', types.Float(), False, True), + ('bitrate', types.ScaledInt(1000, u'kbps'), False, True), + ('format', types.String(), False, True), + ('samplerate', types.ScaledInt(1000, u'kHz'), False, True), + ('bitdepth', types.Integer(), False, True), + ('channels', types.Integer(), False, True), + ('mtime', DateType(), False, False), + ('added', DateType(), False, False), +] +ITEM_KEYS_WRITABLE = [f[0] for f in ITEM_FIELDS if f[3] and f[2]] +ITEM_KEYS_META = [f[0] for f in ITEM_FIELDS if f[3]] +ITEM_KEYS = [f[0] for f in ITEM_FIELDS] + +# Database fields for the "albums" table. +# The third entry in each tuple indicates whether the field reflects an +# identically-named field in the items table. +ALBUM_FIELDS = [ + ('id', types.Id(), False), + ('artpath', PathType(), False), + ('added', DateType(), True), + + ('albumartist', types.String(), True), + ('albumartist_sort', types.String(), True), + ('albumartist_credit', types.String(), True), + ('album', types.String(), True), + ('genre', types.String(), True), + ('year', types.PaddedInt(4), True), + ('month', types.PaddedInt(2), True), + ('day', types.PaddedInt(2), True), + ('tracktotal', types.PaddedInt(2), True), + ('disctotal', types.PaddedInt(2), True), + ('comp', types.Boolean(), True), + ('mb_albumid', types.String(), True), + ('mb_albumartistid', types.String(), True), + ('albumtype', types.String(), True), + ('label', types.String(), True), + ('mb_releasegroupid', types.String(), True), + ('asin', types.String(), True), + ('catalognum', types.String(), True), + ('script', types.String(), True), + ('language', types.String(), True), + ('country', types.String(), True), + ('albumstatus', types.String(), True), + ('media', types.String(), True), + ('albumdisambig', types.String(), True), + ('rg_album_gain', types.Float(), True), + ('rg_album_peak', types.Float(), True), + ('original_year', types.PaddedInt(4), True), + ('original_month', types.PaddedInt(2), True), + ('original_day', types.PaddedInt(2), True), +] +ALBUM_KEYS = [f[0] for f in ALBUM_FIELDS] +ALBUM_KEYS_ITEM = [f[0] for f in ALBUM_FIELDS if f[2]] + + +# Default search fields for each model. +ALBUM_DEFAULT_FIELDS = ('album', 'albumartist', 'genre') +ITEM_DEFAULT_FIELDS = ALBUM_DEFAULT_FIELDS + ('artist', 'title', 'comments') + + +# Special path format key. +PF_KEY_DEFAULT = 'default' + + +# Logger. +log = logging.getLogger('beets') +if not log.handlers: + log.addHandler(logging.StreamHandler()) +log.propagate = False # Don't propagate to root handler. + + +# A little SQL utility. +def _orelse(exp1, exp2): + """Generates an SQLite expression that evaluates to exp1 if exp1 is + non-null and non-empty or exp2 otherwise. + """ + return ('(CASE {0} WHEN NULL THEN {1} ' + 'WHEN "" THEN {1} ' + 'ELSE {0} END)').format(exp1, exp2) + + + +# Exceptions. + + +class FileOperationError(Exception): + """Indicates an error when interacting with a file on disk. + Possibilities include an unsupported media type, a permissions + error, and an unhandled Mutagen exception. + """ + def __init__(self, path, reason): + """Create an exception describing an operation on the file at + `path` with the underlying (chained) exception `reason`. + """ + super(FileOperationError, self).__init__(path, reason) + self.path = path + self.reason = reason + + def __unicode__(self): + """Get a string representing the error. Describes both the + underlying reason and the file path in question. + """ + return u'{0}: {1}'.format( + util.displayable_path(self.path), + unicode(self.reason) + ) + + def __str__(self): + return unicode(self).encode('utf8') + + +class ReadError(FileOperationError): + """An error while reading a file (i.e. in `Item.read`). + """ + def __unicode__(self): + return u'error reading ' + super(ReadError, self).__unicode__() + + +class WriteError(FileOperationError): + """An error while writing a file (i.e. in `Item.write`). + """ + def __unicode__(self): + return u'error writing ' + super(WriteError, self).__unicode__() + + + +# Item and Album model classes. + + +class LibModel(dbcore.Model): + """Shared concrete functionality for Items and Albums. + """ + _bytes_keys = ('path', 'artpath') + + def _template_funcs(self): + funcs = DefaultTemplateFunctions(self, self._db).functions() + funcs.update(plugins.template_funcs()) + return funcs + + def store(self): + super(LibModel, self).store() + plugins.send('database_change', lib=self._db) + + def remove(self): + super(LibModel, self).remove() + plugins.send('database_change', lib=self._db) + + def add(self, lib=None): + super(LibModel, self).add(lib) + plugins.send('database_change', lib=self._db) + + +class Item(LibModel): + _fields = dict((name, typ) for (name, typ, _, _) in ITEM_FIELDS) + _table = 'items' + _flex_table = 'item_attributes' + _search_fields = ITEM_DEFAULT_FIELDS + + @classmethod + def _getters(cls): + return plugins.item_field_getters() + + @classmethod + def from_path(cls, path): + """Creates a new item from the media file at the specified path. + """ + # Initiate with values that aren't read from files. + i = cls(album_id=None) + i.read(path) + i.mtime = i.current_mtime() # Initial mtime. + return i + + def __setitem__(self, key, value): + """Set the item's value for a standard field or a flexattr. + """ + # Encode unicode paths and read buffers. + if key == 'path': + if isinstance(value, unicode): + value = bytestring_path(value) + elif isinstance(value, buffer): + value = str(value) + + if key in ITEM_KEYS_WRITABLE: + self.mtime = 0 # Reset mtime on dirty. + + super(Item, self).__setitem__(key, value) + + def update(self, values): + """Sett all key/value pairs in the mapping. If mtime is + specified, it is not reset (as it might otherwise be). + """ + super(Item, self).update(values) + if self.mtime == 0 and 'mtime' in values: + self.mtime = values['mtime'] + + def get_album(self): + """Get the Album object that this item belongs to, if any, or + None if the item is a singleton or is not associated with a + library. + """ + if not self._db: + return None + return self._db.get_album(self) + + + # Interaction with file metadata. + + def read(self, read_path=None): + """Read the metadata from the associated file. If read_path is + specified, read metadata from that file instead. + + Raises a `ReadError` if the file could not be read. + """ + if read_path is None: + read_path = self.path + else: + read_path = normpath(read_path) + try: + f = MediaFile(syspath(read_path)) + except (OSError, IOError) as exc: + raise ReadError(read_path, exc) + + for key in ITEM_KEYS_META: + value = getattr(f, key) + if isinstance(value, (int, long)): + # Filter values wider than 64 bits (in signed + # representation). SQLite cannot store them. + # py26: Post transition, we can use: + # value.bit_length() > 63 + if abs(value) >= 2 ** 63: + value = 0 + setattr(self, key, value) + + # Database's mtime should now reflect the on-disk value. + if read_path == self.path: + self.mtime = self.current_mtime() + + self.path = read_path + + def write(self): + """Write the item's metadata to the associated file. + + Can raise either a `ReadError` or a `WriteError`. + """ + try: + f = MediaFile(syspath(self.path)) + except (OSError, IOError) as exc: + raise ReadError(self.path, exc) + + plugins.send('write', item=self) + + for key in ITEM_KEYS_WRITABLE: + setattr(f, key, self[key]) + try: + f.save(id3v23=beets.config['id3v23'].get(bool)) + except (OSError, IOError, MutagenError) as exc: + raise WriteError(self.path, exc) + + # The file has a new mtime. + self.mtime = self.current_mtime() + plugins.send('after_write', item=self) + + + # Files themselves. + + def move_file(self, dest, copy=False): + """Moves or copies the item's file, updating the path value if + the move succeeds. If a file exists at ``dest``, then it is + slightly modified to be unique. + """ + if not util.samefile(self.path, dest): + dest = util.unique_path(dest) + if copy: + util.copy(self.path, dest) + plugins.send("item_copied", item=self, source=self.path, + destination=dest) + else: + util.move(self.path, dest) + plugins.send("item_moved", item=self, source=self.path, + destination=dest) + + # Either copying or moving succeeded, so update the stored path. + self.path = dest + + def current_mtime(self): + """Returns the current mtime of the file, rounded to the nearest + integer. + """ + return int(os.path.getmtime(syspath(self.path))) + + + # Model methods. + + def remove(self, delete=False, with_album=True): + """Removes the item. If `delete`, then the associated file is + removed from disk. If `with_album`, then the item's album (if + any) is removed if it the item was the last in the album. + """ + super(Item, self).remove() + + # Remove the album if it is empty. + if with_album: + album = self.get_album() + if album and not album.items(): + album.remove(delete, False) + + # Send a 'item_removed' signal to plugins + plugins.send('item_removed', item=self) + + # Delete the associated file. + if delete: + util.remove(self.path) + util.prune_dirs(os.path.dirname(self.path), self._db.directory) + + self._db._memotable = {} + + def move(self, copy=False, basedir=None, with_album=True): + """Move the item to its designated location within the library + directory (provided by destination()). Subdirectories are + created as needed. If the operation succeeds, the item's path + field is updated to reflect the new location. + + If copy is True, moving the file is copied rather than moved. + + basedir overrides the library base directory for the + destination. + + If the item is in an album, the album is given an opportunity to + move its art. (This can be disabled by passing + with_album=False.) + + The item is stored to the database if it is in the database, so + any dirty fields prior to the move() call will be written as a + side effect. You probably want to call save() to commit the DB + transaction. + """ + self._check_db() + dest = self.destination(basedir=basedir) + + # Create necessary ancestry for the move. + util.mkdirall(dest) + + # Perform the move and store the change. + old_path = self.path + self.move_file(dest, copy) + self.store() + + # If this item is in an album, move its art. + if with_album: + album = self.get_album() + if album: + album.move_art(copy) + album.store() + + # Prune vacated directory. + if not copy: + util.prune_dirs(os.path.dirname(old_path), self._db.directory) + + + # Templating. + + def _formatted_mapping(self, for_path=False): + """Get a mapping containing string-formatted values from either + this item or the associated album, if any. + """ + mapping = super(Item, self)._formatted_mapping(for_path) + + # Merge in album-level fields. + album = self.get_album() + if album: + for key in album.keys(True): + if key in ALBUM_KEYS_ITEM or key not in ITEM_KEYS: + mapping[key] = album._get_formatted(key, for_path) + + # Use the album artist if the track artist is not set and + # vice-versa. + if not mapping['artist']: + mapping['artist'] = mapping['albumartist'] + if not mapping['albumartist']: + mapping['albumartist'] = mapping['artist'] + + return mapping + + def destination(self, fragment=False, basedir=None, platform=None, + path_formats=None): + """Returns the path in the library directory designated for the + item (i.e., where the file ought to be). fragment makes this + method return just the path fragment underneath the root library + directory; the path is also returned as Unicode instead of + encoded as a bytestring. basedir can override the library's base + directory for the destination. + """ + self._check_db() + platform = platform or sys.platform + basedir = basedir or self._db.directory + path_formats = path_formats or self._db.path_formats + + # Use a path format based on a query, falling back on the + # default. + for query, path_format in path_formats: + if query == PF_KEY_DEFAULT: + continue + query = get_query(query, type(self)) + if query.match(self): + # The query matches the item! Use the corresponding path + # format. + break + else: + # No query matched; fall back to default. + for query, path_format in path_formats: + if query == PF_KEY_DEFAULT: + break + else: + assert False, "no default path format" + if isinstance(path_format, Template): + subpath_tmpl = path_format + else: + subpath_tmpl = Template(path_format) + + # Evaluate the selected template. + subpath = self.evaluate_template(subpath_tmpl, True) + + # Prepare path for output: normalize Unicode characters. + if platform == 'darwin': + subpath = unicodedata.normalize('NFD', subpath) + else: + subpath = unicodedata.normalize('NFC', subpath) + # Truncate components and remove forbidden characters. + subpath = util.sanitize_path(subpath, self._db.replacements) + # Encode for the filesystem. + if not fragment: + subpath = bytestring_path(subpath) + + # Preserve extension. + _, extension = os.path.splitext(self.path) + if fragment: + # Outputting Unicode. + extension = extension.decode('utf8', 'ignore') + subpath += extension.lower() + + # Truncate too-long components. + maxlen = beets.config['max_filename_length'].get(int) + if not maxlen: + # When zero, try to determine from filesystem. + maxlen = util.max_filename_length(self._db.directory) + subpath = util.truncate_path(subpath, maxlen) + + if fragment: + return subpath + else: + return normpath(os.path.join(basedir, subpath)) + + +class Album(LibModel): + """Provides access to information about albums stored in a + library. Reflects the library's "albums" table, including album + art. + """ + _fields = dict((name, typ) for (name, typ, _) in ALBUM_FIELDS) + _table = 'albums' + _flex_table = 'album_attributes' + _search_fields = ALBUM_DEFAULT_FIELDS + + @classmethod + def _getters(cls): + # In addition to plugin-provided computed fields, also expose + # the album's directory as `path`. + getters = plugins.album_field_getters() + getters['path'] = Album.item_dir + return getters + + def __setitem__(self, key, value): + """Set the value of an album attribute.""" + if key == 'artpath': + if isinstance(value, unicode): + value = bytestring_path(value) + elif isinstance(value, buffer): + value = bytes(value) + super(Album, self).__setitem__(key, value) + + def items(self): + """Returns an iterable over the items associated with this + album. + """ + return self._db.items(dbcore.MatchQuery('album_id', self.id)) + + def remove(self, delete=False, with_items=True): + """Removes this album and all its associated items from the + library. If delete, then the items' files are also deleted + from disk, along with any album art. The directories + containing the album are also removed (recursively) if empty. + Set with_items to False to avoid removing the album's items. + """ + super(Album, self).remove() + + # Delete art file. + if delete: + artpath = self.artpath + if artpath: + util.remove(artpath) + + # Remove (and possibly delete) the constituent items. + if with_items: + for item in self.items(): + item.remove(delete, False) + + def move_art(self, copy=False): + """Move or copy any existing album art so that it remains in the + same directory as the items. + """ + old_art = self.artpath + if not old_art: + return + + new_art = self.art_destination(old_art) + if new_art == old_art: + return + + new_art = util.unique_path(new_art) + log.debug('moving album art %s to %s' % (old_art, new_art)) + if copy: + util.copy(old_art, new_art) + else: + util.move(old_art, new_art) + self.artpath = new_art + + # Prune old path when moving. + if not copy: + util.prune_dirs(os.path.dirname(old_art), + self._db.directory) + + def move(self, copy=False, basedir=None): + """Moves (or copies) all items to their destination. Any album + art moves along with them. basedir overrides the library base + directory for the destination. The album is stored to the + database, persisting any modifications to its metadata. + """ + basedir = basedir or self._db.directory + + # Ensure new metadata is available to items for destination + # computation. + self.store() + + # Move items. + items = list(self.items()) + for item in items: + item.move(copy, basedir=basedir, with_album=False) + + # Move art. + self.move_art(copy) + self.store() + + def item_dir(self): + """Returns the directory containing the album's first item, + provided that such an item exists. + """ + item = self.items().get() + if not item: + raise ValueError('empty album') + return os.path.dirname(item.path) + + def art_destination(self, image, item_dir=None): + """Returns a path to the destination for the album art image + for the album. `image` is the path of the image that will be + moved there (used for its extension). + + The path construction uses the existing path of the album's + items, so the album must contain at least one item or + item_dir must be provided. + """ + image = bytestring_path(image) + item_dir = item_dir or self.item_dir() + + filename_tmpl = Template(beets.config['art_filename'].get(unicode)) + subpath = self.evaluate_template(filename_tmpl, True) + subpath = util.sanitize_path(subpath, + replacements=self._db.replacements) + subpath = bytestring_path(subpath) + + _, ext = os.path.splitext(image) + dest = os.path.join(item_dir, subpath + ext) + + return bytestring_path(dest) + + def set_art(self, path, copy=True): + """Sets the album's cover art to the image at the given path. + The image is copied (or moved) into place, replacing any + existing art. + """ + path = bytestring_path(path) + oldart = self.artpath + artdest = self.art_destination(path) + + if oldart and samefile(path, oldart): + # Art already set. + return + elif samefile(path, artdest): + # Art already in place. + self.artpath = path + return + + # Normal operation. + if oldart == artdest: + util.remove(oldart) + artdest = util.unique_path(artdest) + if copy: + util.copy(path, artdest) + else: + util.move(path, artdest) + self.artpath = artdest + + def store(self): + """Update the database with the album information. The album's + tracks are also updated. + """ + # Get modified track fields. + track_updates = {} + for key in ALBUM_KEYS_ITEM: + if key in self._dirty: + track_updates[key] = self[key] + + with self._db.transaction(): + super(Album, self).store() + if track_updates: + for item in self.items(): + for key, value in track_updates.items(): + item[key] = value + item.store() + + + +# Query construction and parsing helpers. + + +PARSE_QUERY_PART_REGEX = re.compile( + # Non-capturing optional segment for the keyword. + r'(?:' + r'(\S+?)' # The field key. + r'(? (None, 'stapler', SubstringQuery) + 'color:red' -> ('color', 'red', SubstringQuery) + ':^Quiet' -> (None, '^Quiet', RegexpQuery) + 'color::b..e' -> ('color', 'b..e', RegexpQuery) + + Prefixes may be "escaped" with a backslash to disable the keying + behavior. + """ + part = part.strip() + match = PARSE_QUERY_PART_REGEX.match(part) + + assert match # Regex should always match. + key = match.group(1) + term = match.group(2).replace('\:', ':') + + # Match the search term against the list of prefixes. + for pre, query_class in prefixes.items(): + if term.startswith(pre): + return key, term[len(pre):], query_class + + # No matching prefix: use type-based or fallback/default query. + query_class = query_classes.get(key, default_class) + return key, term, query_class + + +def construct_query_part(query_part, model_cls): + """Create a query from a single query component, `query_part`, for + querying instances of `model_cls`. Return a `Query` instance. + """ + # Shortcut for empty query parts. + if not query_part: + return dbcore.query.TrueQuery() + + # Set up and parse the string. + query_classes = dict((k, t.query) for (k, t) in model_cls._fields.items()) + prefixes = {':': dbcore.query.RegexpQuery} + prefixes.update(plugins.queries()) + key, pattern, query_class = \ + parse_query_part(query_part, query_classes, prefixes) + + # No key specified. + if key is None: + if os.sep in pattern and 'path' in model_cls._fields: + # This looks like a path. + return PathQuery('path', pattern) + elif issubclass(query_class, dbcore.FieldQuery): + # The query type matches a specific field, but none was + # specified. So we use a version of the query that matches + # any field. + return dbcore.query.AnyFieldQuery(pattern, + model_cls._search_fields, + query_class) + else: + # Other query type. + return query_class(pattern) + + key = key.lower() + + # Singleton query (not a real field). + if key == 'singleton': + return SingletonQuery(util.str2bool(pattern)) + + # Other field. + else: + return query_class(key.lower(), pattern, key in model_cls._fields) + + +def query_from_strings(query_cls, model_cls, query_parts): + """Creates a collection query of type `query_cls` from a list of + strings in the format used by parse_query_part. `model_cls` + determines how queries are constructed from strings. + """ + subqueries = [] + for part in query_parts: + subqueries.append(construct_query_part(part, model_cls)) + if not subqueries: # No terms in query. + subqueries = [dbcore.query.TrueQuery()] + return query_cls(subqueries) + + +def get_query(val, model_cls): + """Takes a value which may be None, a query string, a query string + list, or a Query object, and returns a suitable Query object. + `model_cls` is the subclass of Model indicating which entity this + is a query for (i.e., Album or Item) and is used to determine which + fields are searched. + """ + # Convert a single string into a list of space-separated + # criteria. + if isinstance(val, basestring): + # A bug in Python < 2.7.3 prevents correct shlex splitting of + # Unicode strings. + # http://bugs.python.org/issue6988 + if isinstance(val, unicode): + val = val.encode('utf8') + val = [s.decode('utf8') for s in shlex.split(val)] + + if val is None: + return dbcore.query.TrueQuery() + elif isinstance(val, list) or isinstance(val, tuple): + return query_from_strings(dbcore.AndQuery, model_cls, val) + elif isinstance(val, dbcore.Query): + return val + else: + raise ValueError('query must be None or have type Query or str') + + + +# The Library: interface to the database. + + +class Library(dbcore.Database): + """A database of music containing songs and albums. + """ + _models = (Item, Album) + + def __init__(self, path='library.blb', + directory='~/Music', + path_formats=((PF_KEY_DEFAULT, + '$artist/$album/$track $title'),), + replacements=None): + if path != ':memory:': + self.path = bytestring_path(normpath(path)) + super(Library, self).__init__(path) + + self.directory = bytestring_path(normpath(directory)) + self.path_formats = path_formats + self.replacements = replacements + + self._memotable = {} # Used for template substitution performance. + + + # Adding objects to the database. + + def add(self, obj): + """Add the :class:`Item` or :class:`Album` object to the library + database. Return the object's new id. + """ + obj.add(self) + self._memotable = {} + return obj.id + + def add_album(self, items): + """Create a new album consisting of a list of items. The items + are added to the database if they don't yet have an ID. Return a + new :class:`Album` object. + """ + # Create the album structure using metadata from the first item. + values = dict((key, items[0][key]) for key in ALBUM_KEYS_ITEM) + album = Album(self, **values) + + # Add the album structure and set the items' album_id fields. + # Store or add the items. + with self.transaction(): + album.add(self) + for item in items: + item.album_id = album.id + if item.id is None: + item.add(self) + else: + item.store() + + return album + + + # Querying. + + def _fetch(self, model_cls, query, order_by=None): + """Parse a query and fetch. + """ + return super(Library, self)._fetch( + model_cls, get_query(query, model_cls), order_by + ) + + def albums(self, query=None): + """Get a sorted list of :class:`Album` objects matching the + given query. + """ + order = '{0}, album'.format( + _orelse("albumartist_sort", "albumartist") + ) + return self._fetch(Album, query, order) + + def items(self, query=None): + """Get a sorted list of :class:`Item` objects matching the given + query. + """ + order = '{0}, album, disc, track'.format( + _orelse("artist_sort", "artist") + ) + return self._fetch(Item, query, order) + + + # Convenience accessors. + + def get_item(self, id): + """Fetch an :class:`Item` by its ID. Returns `None` if no match is + found. + """ + return self._get(Item, id) + + def get_album(self, item_or_id): + """Given an album ID or an item associated with an album, return + an :class:`Album` object for the album. If no such album exists, + returns `None`. + """ + if isinstance(item_or_id, int): + album_id = item_or_id + else: + album_id = item_or_id.album_id + if album_id is None: + return None + return self._get(Album, album_id) + + + +# Default path template resources. + + +def _int_arg(s): + """Convert a string argument to an integer for use in a template + function. May raise a ValueError. + """ + return int(s.strip()) + + +class DefaultTemplateFunctions(object): + """A container class for the default functions provided to path + templates. These functions are contained in an object to provide + additional context to the functions -- specifically, the Item being + evaluated. + """ + _prefix = 'tmpl_' + + def __init__(self, item=None, lib=None): + """Paramaterize the functions. If `item` or `lib` is None, then + some functions (namely, ``aunique``) will always evaluate to the + empty string. + """ + self.item = item + self.lib = lib + + def functions(self): + """Returns a dictionary containing the functions defined in this + object. The keys are function names (as exposed in templates) + and the values are Python functions. + """ + out = {} + for key in self._func_names: + out[key[len(self._prefix):]] = getattr(self, key) + return out + + @staticmethod + def tmpl_lower(s): + """Convert a string to lower case.""" + return s.lower() + + @staticmethod + def tmpl_upper(s): + """Covert a string to upper case.""" + return s.upper() + + @staticmethod + def tmpl_title(s): + """Convert a string to title case.""" + return s.title() + + @staticmethod + def tmpl_left(s, chars): + """Get the leftmost characters of a string.""" + return s[0:_int_arg(chars)] + + @staticmethod + def tmpl_right(s, chars): + """Get the rightmost characters of a string.""" + return s[-_int_arg(chars):] + + @staticmethod + def tmpl_if(condition, trueval, falseval=u''): + """If ``condition`` is nonempty and nonzero, emit ``trueval``; + otherwise, emit ``falseval`` (if provided). + """ + try: + condition = _int_arg(condition) + except ValueError: + condition = condition.strip() + if condition: + return trueval + else: + return falseval + + @staticmethod + def tmpl_asciify(s): + """Translate non-ASCII characters to their ASCII equivalents. + """ + return unidecode(s) + + @staticmethod + def tmpl_time(s, format): + """Format a time value using `strftime`. + """ + cur_fmt = beets.config['time_format'].get(unicode) + return time.strftime(format, time.strptime(s, cur_fmt)) + + def tmpl_aunique(self, keys=None, disam=None): + """Generate a string that is guaranteed to be unique among all + albums in the library who share the same set of keys. A fields + from "disam" is used in the string if one is sufficient to + disambiguate the albums. Otherwise, a fallback opaque value is + used. Both "keys" and "disam" should be given as + whitespace-separated lists of field names. + """ + # Fast paths: no album, no item or library, or memoized value. + if not self.item or not self.lib: + return u'' + if self.item.album_id is None: + return u'' + memokey = ('aunique', keys, disam, self.item.album_id) + memoval = self.lib._memotable.get(memokey) + if memoval is not None: + return memoval + + keys = keys or 'albumartist album' + disam = disam or 'albumtype year label catalognum albumdisambig' + keys = keys.split() + disam = disam.split() + + album = self.lib.get_album(self.item) + if not album: + # Do nothing for singletons. + self.lib._memotable[memokey] = u'' + return u'' + + # Find matching albums to disambiguate with. + subqueries = [] + for key in keys: + value = getattr(album, key) + subqueries.append(dbcore.MatchQuery(key, value)) + albums = self.lib.albums(dbcore.AndQuery(subqueries)) + + # If there's only one album to matching these details, then do + # nothing. + if len(albums) == 1: + self.lib._memotable[memokey] = u'' + return u'' + + # Find the first disambiguator that distinguishes the albums. + for disambiguator in disam: + # Get the value for each album for the current field. + disam_values = set([getattr(a, disambiguator) for a in albums]) + + # If the set of unique values is equal to the number of + # albums in the disambiguation set, we're done -- this is + # sufficient disambiguation. + if len(disam_values) == len(albums): + break + + else: + # No disambiguator distinguished all fields. + res = u' {0}'.format(album.id) + self.lib._memotable[memokey] = res + return res + + # Flatten disambiguation value into a string. + disam_value = album._get_formatted(disambiguator, True) + res = u' [{0}]'.format(disam_value) + self.lib._memotable[memokey] = res + return res + + +# Get the name of tmpl_* functions in the above class. +DefaultTemplateFunctions._func_names = \ + [s for s in dir(DefaultTemplateFunctions) + if s.startswith(DefaultTemplateFunctions._prefix)] diff --git a/libs/beets/mediafile.py b/libs/beets/mediafile.py new file mode 100644 index 00000000..301e0f37 --- /dev/null +++ b/libs/beets/mediafile.py @@ -0,0 +1,1672 @@ +# This file is part of beets. +# Copyright 2014, Adrian Sampson. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. + +"""Handles low-level interfacing for files' tags. Wraps Mutagen to +automatically detect file types and provide a unified interface for a +useful subset of music files' tags. + +Usage: + + >>> f = MediaFile('Lucy.mp3') + >>> f.title + u'Lucy in the Sky with Diamonds' + >>> f.artist = 'The Beatles' + >>> f.save() + +A field will always return a reasonable value of the correct type, even +if no tag is present. If no value is available, the value will be false +(e.g., zero or the empty string). + +Internally ``MediaFile`` uses ``MediaField`` descriptors to access the +data from the tags. In turn ``MediaField`` uses a number of +``StorageStyle`` strategies to handle format specific logic. +""" +import mutagen +import mutagen.mp3 +import mutagen.oggopus +import mutagen.oggvorbis +import mutagen.mp4 +import mutagen.flac +import mutagen.monkeysaudio +import mutagen.asf +import datetime +import re +import base64 +import math +import struct +import imghdr +import os +import logging +import traceback +from beets.util.enumeration import enum + +__all__ = ['UnreadableFileError', 'FileTypeError', 'MediaFile'] + + + +# Logger. +log = logging.getLogger('beets') + + + +# Exceptions. + +class UnreadableFileError(Exception): + """Indicates a file that MediaFile can't read. + """ + pass + +class FileTypeError(UnreadableFileError): + """Raised for files that don't seem to have a type MediaFile + supports. + """ + pass + +class MutagenError(UnreadableFileError): + """Raised when Mutagen fails unexpectedly---probably due to a bug. + """ + + + +# Constants. + +# Human-readable type names. +TYPES = { + 'mp3': 'MP3', + 'aac': 'AAC', + 'alac': 'ALAC', + 'ogg': 'OGG', + 'opus': 'Opus', + 'flac': 'FLAC', + 'ape': 'APE', + 'wv': 'WavPack', + 'mpc': 'Musepack', + 'asf': 'Windows Media', +} + + + +# Utility. + +def _safe_cast(out_type, val): + """Try to covert val to out_type but never raise an exception. If + the value can't be converted, then a sensible default value is + returned. out_type should be bool, int, or unicode; otherwise, the + value is just passed through. + """ + if out_type == int: + if val is None: + return 0 + elif isinstance(val, int) or isinstance(val, float): + # Just a number. + return int(val) + else: + # Process any other type as a string. + if not isinstance(val, basestring): + val = unicode(val) + # Get a number from the front of the string. + val = re.match(r'[0-9]*', val.strip()).group(0) + if not val: + return 0 + else: + return int(val) + + elif out_type == bool: + if val is None: + return False + else: + try: + # Should work for strings, bools, ints: + return bool(int(val)) + except ValueError: + return False + + elif out_type == unicode: + if val is None: + return u'' + else: + if isinstance(val, str): + return val.decode('utf8', 'ignore') + elif isinstance(val, unicode): + return val + else: + return unicode(val) + + elif out_type == float: + if val is None: + return 0.0 + elif isinstance(val, int) or isinstance(val, float): + return float(val) + else: + if not isinstance(val, basestring): + val = unicode(val) + val = re.match(r'[\+-]?[0-9\.]*', val.strip()).group(0) + if not val: + return 0.0 + else: + return float(val) + + else: + return val + + + +# Image coding for ASF/WMA. + +def _unpack_asf_image(data): + """Unpack image data from a WM/Picture tag. Return a tuple + containing the MIME type, the raw image data, a type indicator, and + the image's description. + + This function is treated as "untrusted" and could throw all manner + of exceptions (out-of-bounds, etc.). We should clean this up + sometime so that the failure modes are well-defined. + """ + type, size = struct.unpack_from(" 0: + gain = math.log10(maxgain / 1000.0) * -10 + else: + # Invalid gain value found. + gain = 0.0 + + # SoundCheck stores peak values as the actual value of the sample, + # and again separately for the left and right channels. We need to + # convert this to a percentage of full scale, which is 32768 for a + # 16 bit sample. Once again, we play it safe by using the larger of + # the two values. + peak = max(soundcheck[6:8]) / 32768.0 + + return round(gain, 2), round(peak, 6) + +def _sc_encode(gain, peak): + """Encode ReplayGain gain/peak values as a Sound Check string. + """ + # SoundCheck stores the peak value as the actual value of the + # sample, rather than the percentage of full scale that RG uses, so + # we do a simple conversion assuming 16 bit samples. + peak *= 32768.0 + + # SoundCheck stores absolute RMS values in some unknown units rather + # than the dB values RG uses. We can calculate these absolute values + # from the gain ratio using a reference value of 1000 units. We also + # enforce the maximum value here, which is equivalent to about + # -18.2dB. + g1 = min(round((10 ** (gain / -10)) * 1000), 65534) + # Same as above, except our reference level is 2500 units. + g2 = min(round((10 ** (gain / -10)) * 2500), 65534) + + # The purpose of these values are unknown, but they also seem to be + # unused so we just use zero. + uk = 0 + values = (g1, g1, g2, g2, uk, uk, peak, peak, uk, uk) + return (u' %08X' * 10) % values + + + +# Cover art and other images. + + +def _image_mime_type(data): + """Return the MIME type of the image data (a bytestring). + """ + kind = imghdr.what(None, h=data) + if kind in ['gif', 'jpeg', 'png', 'tiff', 'bmp']: + return 'image/{0}'.format(kind) + elif kind == 'pgm': + return 'image/x-portable-graymap' + elif kind == 'pbm': + return 'image/x-portable-bitmap' + elif kind == 'ppm': + return 'image/x-portable-pixmap' + elif kind == 'xbm': + return 'image/x-xbitmap' + else: + return 'image/x-{0}'.format(kind) + + +class Image(object): + """Strucuture representing image data and metadata that can be + stored and retrieved from tags. + + The structure has four properties. + * ``data`` The binary data of the image + * ``desc`` An optional descritpion of the image + * ``type`` A string denoting the type in relation to the music. + Must be one of the ``TYPES`` enum. + * ``mime_type`` Read-only property that contains the mime type of + the binary data + """ + TYPES = enum([ + 'other', + 'icon', + 'other icon', + 'front', + 'back', + 'leaflet', + 'media', + 'lead artist', + 'artist', + 'conductor', + 'group', + 'composer', + 'lyricist', + 'recording location', + 'recording session', + 'performance', + 'screen capture', + 'fish', + 'illustration', + 'artist logo', + 'publisher logo', + ], name='TageImage.TYPES') + + def __init__(self, data, desc=None, type=None): + self.data = data + self.desc = desc + if isinstance(type, int): + type = self.TYPES[type] + self.type = type + + @property + def mime_type(self): + if self.data: + return _image_mime_type(self.data) + + @property + def type_index(self): + if self.type is None: + return None + return list(self.TYPES).index(self.type) + + + +# StorageStyle classes describe strategies for accessing values in +# Mutagen file objects. + +class StorageStyle(object): + """A strategy for storing a value for a certain tag format (or set + of tag formats). This basic StorageStyle describes simple 1:1 + mapping from raw values to keys in a Mutagen file object; subclasses + describe more sophisticated translations or format-specific access + strategies. + + MediaFile uses a StorageStyle via two methods: ``get()`` and + ``set()``. It passes a Mutagen file object to each. + + Internally, the StorageStyle implements ``get()`` and ``set()`` + using two steps that may be overridden by subtypes. To get a value, + the StorageStyle first calls ``fetch()`` to retrieve the value + corresponding to a key and then ``deserialize()`` to convert the raw + Mutagen value to a consumable Python value. Similarly, to set a + field, we call ``serialize()`` to encode the value and then + ``store()`` to assign the result into the Mutagen object. + + Each StorageStyle type has a class-level `formats` attribute that is + a list of strings indicating the formats that the style applies to. + MediaFile only uses StorageStyles that apply to the correct type for + a given audio file. + """ + + formats = ['FLAC', 'OggOpus', 'OggTheora', 'OggSpeex', 'OggVorbis', + 'OggFlac', 'APEv2File', 'WavPack', 'Musepack', 'MonkeysAudio'] + """List of mutagen classes the StorageStyle can handle. + """ + + def __init__(self, key, as_type=unicode, suffix=None, float_places=2): + """Create a basic storage strategy. Parameters: + + - `key`: The key on the Mutagen file object used to access the + field's data. + - `as_type`: The Python type that the value is stored as + internally (`unicode`, `int`, `bool`, or `bytes`). + - `suffix`: When `as_type` is a string type, append this before + storing the value. + - `float_places`: When the value is a floating-point number and + encoded as a string, the number of digits to store after the + decimal point. + """ + self.key = key + self.as_type = as_type + self.suffix = suffix + self.float_places = float_places + + # Convert suffix to correct string type. + if self.suffix and self.as_type is unicode: + self.suffix = self.as_type(self.suffix) + + # Getter. + + def get(self, mutagen_file): + """Get the value for the field using this style. + """ + return self.deserialize(self.fetch(mutagen_file)) + + def fetch(self, mutagen_file): + """Retrieve the raw value of for this tag from the Mutagen file + object. + """ + try: + return mutagen_file[self.key][0] + except KeyError: + return None + + def deserialize(self, mutagen_value): + """Given a raw value stored on a Mutagen object, decode and + return the represented value. + """ + if self.suffix and isinstance(mutagen_value, unicode) \ + and mutagen_value.endswith(self.suffix): + return mutagen_value[:-len(self.suffix)] + else: + return mutagen_value + + # Setter. + + def set(self, mutagen_file, value): + """Assign the value for the field using this style. + """ + self.store(mutagen_file, self.serialize(value)) + + def store(self, mutagen_file, value): + """Store a serialized value in the Mutagen file object. + """ + mutagen_file[self.key] = [value] + + def serialize(self, value): + """Convert the external Python value to a type that is suitable for + storing in a Mutagen file object. + """ + if isinstance(value, float) and self.as_type is unicode: + value = u'{0:.{1}f}'.format(value, self.float_places) + value = self.as_type(value) + elif self.as_type is unicode: + if isinstance(value, bool): + # Store bools as 1/0 instead of True/False. + value = unicode(int(bool(value))) + elif isinstance(value, str): + value = value.decode('utf8', 'ignore') + else: + value = unicode(value) + else: + value = self.as_type(value) + + if self.suffix: + value += self.suffix + + return value + + +class ListStorageStyle(StorageStyle): + """Abstract storage style that provides access to lists. + + The ListMediaField descriptor uses a ListStorageStyle via two + methods: ``get_list()`` and ``set_list()``. It passes a Mutagen file + object to each. + + Subclasses may overwrite ``fetch`` and ``store``. ``fetch`` must + return a (possibly empty) list and ``store`` receives a serialized + list of values as the second argument. + + The `serialize` and `deserialize` methods (from the base + `StorageStyle`) are still called with individual values. This class + handles packing and unpacking the values into lists. + """ + def get(self, mutagen_file): + """Get the first value in the field's value list. + """ + try: + return self.get_list(mutagen_file)[0] + except IndexError: + return None + + def get_list(self, mutagen_file): + """Get a list of all values for the field using this style. + """ + return [self.deserialize(item) for item in self.fetch(mutagen_file)] + + def fetch(self, mutagen_file): + """Get the list of raw (serialized) values. + """ + try: + return mutagen_file[self.key] + except KeyError: + return [] + + def set(self, mutagen_file, value): + """Set an individual value as the only value for the field using + this style. + """ + self.set_list(mutagen_file, [value]) + + def set_list(self, mutagen_file, values): + """Set all values for the field using this style. `values` + should be an iterable. + """ + self.store(mutagen_file, [self.serialize(value) for value in values]) + + def store(self, mutagen_file, values): + """Set the list of all raw (serialized) values for this field. + """ + mutagen_file[self.key] = values + + +class SoundCheckStorageStyleMixin(object): + """A mixin for storage styles that read and write iTunes SoundCheck + analysis values. The object must have an `index` field that + indicates which half of the gain/peak pair---0 or 1---the field + represents. + """ + def get(self, mutagen_file): + data = self.fetch(mutagen_file) + if data is None: + return 0 + else: + return _sc_decode(data)[self.index] + + def set(self, mutagen_file, value): + data = self.fetch(mutagen_file) + if data is None: + gain_peak = [0, 0] + else: + gain_peak = list(_sc_decode(data)) + gain_peak[self.index] = value or 0 + data = self.serialize(_sc_encode(*gain_peak)) + self.store(mutagen_file, data) + + +class ASFStorageStyle(ListStorageStyle): + """A general storage style for Windows Media/ASF files. + """ + formats = ['ASF'] + + def deserialize(self, data): + if isinstance(data, mutagen.asf.ASFBaseAttribute): + data = data.value + return data + + +class MP4StorageStyle(StorageStyle): + """A general storage style for MPEG-4 tags. + """ + formats = ['MP4'] + + def serialize(self, value): + value = super(MP4StorageStyle, self).serialize(value) + if self.key.startswith('----:') and isinstance(value, unicode): + value = value.encode('utf8') + return value + + +class MP4TupleStorageStyle(MP4StorageStyle): + """A style for storing values as part of a pair of numbers in an + MPEG-4 file. + """ + def __init__(self, key, index=0, **kwargs): + super(MP4TupleStorageStyle, self).__init__(key, **kwargs) + self.index = index + + def deserialize(self, mutagen_value): + items = mutagen_value or [] + packing_length = 2 + return list(items) + [0] * (packing_length - len(items)) + + def get(self, mutagen_file): + return super(MP4TupleStorageStyle, self).get(mutagen_file)[self.index] + + def set(self, mutagen_file, value): + if value is None: + value = 0 + items = self.deserialize(self.fetch(mutagen_file)) + items[self.index] = int(value) + self.store(mutagen_file, items) + + +class MP4ListStorageStyle(ListStorageStyle, MP4StorageStyle): + pass + + +class MP4SoundCheckStorageStyle(SoundCheckStorageStyleMixin, MP4StorageStyle): + def __init__(self, index=0, **kwargs): + super(MP4SoundCheckStorageStyle, self).__init__(**kwargs) + self.index = index + +class MP4BoolStorageStyle(MP4StorageStyle): + """A style for booleans in MPEG-4 files. (MPEG-4 has an atom type + specifically for representing booleans.) + """ + def get(self, mutagen_file): + try: + return mutagen_file[self.key] + except KeyError: + return None + + def get_list(self, mutagen_file): + raise NotImplementedError('MP4 bool storage does not support lists') + + def set(self, mutagen_file, value): + mutagen_file[self.key] = value + + def set_list(self, mutagen_file, values): + raise NotImplementedError('MP4 bool storage does not support lists') + + +class MP4ImageStorageStyle(MP4ListStorageStyle): + """Store images as MPEG-4 image atoms. Values are `Image` objects. + """ + def __init__(self, **kwargs): + super(MP4ImageStorageStyle, self).__init__(key='covr', **kwargs) + + def deserialize(self, data): + return Image(data) + + def serialize(self, image): + if image.mime_type == 'image/png': + kind = mutagen.mp4.MP4Cover.FORMAT_PNG + elif image.mime_type == 'image/jpeg': + kind = mutagen.mp4.MP4Cover.FORMAT_JPEG + else: + raise ValueError('MP4 files only supports PNG and JPEG images') + return mutagen.mp4.MP4Cover(image.data, kind) + + +class MP3StorageStyle(StorageStyle): + """Store data in ID3 frames. + """ + formats = ['MP3'] + + def __init__(self, key, id3_lang=None, **kwargs): + """Create a new ID3 storage style. `id3_lang` is the value for + the language field of newly created frames. + """ + self.id3_lang = id3_lang + super(MP3StorageStyle, self).__init__(key, **kwargs) + + def fetch(self, mutagen_file): + try: + return mutagen_file[self.key].text[0] + except KeyError: + return None + + def store(self, mutagen_file, value): + frame = mutagen.id3.Frames[self.key](encoding=3, text=[value]) + mutagen_file.tags.setall(self.key, [frame]) + + +class MP3ListStorageStyle(ListStorageStyle, MP3StorageStyle): + """Store lists of data in multiple ID3 frames. + """ + def fetch(self, mutagen_file): + try: + return mutagen_file[self.key].text + except KeyError: + return [] + + def store(self, mutagen_file, values): + frame = mutagen.id3.Frames[self.key](encoding=3, text=values) + mutagen_file.tags.setall(self.key, [frame]) + + +class MP3UFIDStorageStyle(MP3StorageStyle): + """Store data in a UFID ID3 frame with a particular owner. + """ + def __init__(self, owner, **kwargs): + self.owner = owner + super(MP3UFIDStorageStyle, self).__init__('UFID:' + owner, **kwargs) + + def fetch(self, mutagen_file): + try: + return mutagen_file[self.key].data + except KeyError: + return None + + def store(self, mutagen_file, value): + frames = mutagen_file.tags.getall(self.key) + for frame in frames: + # Replace existing frame data. + if frame.owner == self.owner: + frame.data = value + else: + # New frame. + frame = mutagen.id3.UFID(owner=self.owner, data=value) + mutagen_file.tags.setall(self.key, [frame]) + + +class MP3DescStorageStyle(MP3StorageStyle): + """Store data in a TXXX (or similar) ID3 frame. The frame is + selected based its ``desc`` field. + """ + def __init__(self, desc=u'', key='TXXX', **kwargs): + self.description = desc + super(MP3DescStorageStyle, self).__init__(key=key, **kwargs) + + def store(self, mutagen_file, value): + frames = mutagen_file.tags.getall(self.key) + if self.key != 'USLT': + value = [value] + + # try modifying in place + found = False + for frame in frames: + if frame.desc.lower() == self.description.lower(): + frame.text = value + found = True + + # need to make a new frame? + if not found: + frame = mutagen.id3.Frames[self.key]( + desc=str(self.description), text=value, encoding=3) + if self.id3_lang: + frame.lang = self.id3_lang + mutagen_file.tags.add(frame) + + def fetch(self, mutagen_file): + for frame in mutagen_file.tags.getall(self.key): + if frame.desc.lower() == self.description.lower(): + if self.key == 'USLT': + return frame.text + try: + return frame.text[0] + except IndexError: + return None + + +class MP3SlashPackStorageStyle(MP3StorageStyle): + """Store value as part of pair that is serialized as a slash- + separated string. + """ + def __init__(self, key, pack_pos=0, **kwargs): + super(MP3SlashPackStorageStyle, self).__init__(key, **kwargs) + self.pack_pos = pack_pos + + def _fetch_unpacked(self, mutagen_file): + data = self.fetch(mutagen_file) or '' + items = unicode(data).split('/') + packing_length = 2 + return list(items) + [None] * (packing_length - len(items)) + + def get(self, mutagen_file): + return self._fetch_unpacked(mutagen_file)[self.pack_pos] or 0 + + def set(self, mutagen_file, value): + items = self._fetch_unpacked(mutagen_file) + items[self.pack_pos] = value + if items[0] is None: + items[0] = 0 + if items[1] is None: + items.pop() # Do not store last value + self.store(mutagen_file, '/'.join(map(unicode, items))) + + +class MP3ImageStorageStyle(ListStorageStyle, MP3StorageStyle): + """Converts between APIC frames and ``Image`` instances. + + The `get_list` method inherited from ``ListStorageStyle`` returns a + list of ``Image``s. Similarily the `set_list` method accepts a + list of ``Image``s as its ``values`` arguemnt. + """ + def __init__(self): + super(MP3ImageStorageStyle, self).__init__(key='APIC') + self.as_type = str + + def deserialize(self, apic_frame): + """Convert APIC frame into Image.""" + return Image(data=apic_frame.data, desc=apic_frame.desc, + type=apic_frame.type) + + def fetch(self, mutagen_file): + return mutagen_file.tags.getall(self.key) + + def store(self, mutagen_file, frames): + mutagen_file.tags.setall(self.key, frames) + + def serialize(self, image): + """Return an APIC frame populated with data from ``image``. + """ + assert isinstance(image, Image) + frame = mutagen.id3.Frames[self.key]() + frame.data = image.data + frame.mime = image.mime_type + frame.desc = (image.desc or u'').encode('utf8') + frame.encoding = 3 # UTF-8 encoding of desc + frame.type = image.type_index or 3 # front cover + return frame + + +class MP3SoundCheckStorageStyle(SoundCheckStorageStyleMixin, + MP3DescStorageStyle): + def __init__(self, index=0, **kwargs): + super(MP3SoundCheckStorageStyle, self).__init__(**kwargs) + self.index = index + + +class ASFImageStorageStyle(ListStorageStyle): + """Store images packed into Windows Media/ASF byte array attributes. + Values are `Image` objects. + """ + formats = ['ASF'] + + def __init__(self): + super(ASFImageStorageStyle, self).__init__(key='WM/Picture') + + def deserialize(self, asf_picture): + mime, data, type, desc = _unpack_asf_image(asf_picture.value) + return Image(data, desc=desc, type=type) + + def serialize(self, image): + pic = mutagen.asf.ASFByteArrayAttribute() + pic.value = _pack_asf_image(image.mime_type, image.data, + type=image.type_index or 3, + description=image.desc or u'') + return pic + + +class VorbisImageStorageStyle(ListStorageStyle): + """Store images in Vorbis comments. Both legacy COVERART fields and + modern METADATA_BLOCK_PICTURE tags are supported. Data is + base64-encoded. Values are `Image` objects. + """ + formats = ['OggOpus', 'OggTheora', 'OggSpeex', 'OggVorbis', + 'OggFlac', 'APEv2File', 'WavPack', 'Musepack', 'MonkeysAudio'] + + def __init__(self): + super(VorbisImageStorageStyle, self).__init__( + key='metadata_block_picture') + self.as_type = str + + def fetch(self, mutagen_file): + images = [] + if 'metadata_block_picture' not in mutagen_file: + # Try legacy COVERART tags. + if 'coverart' in mutagen_file: + for data in mutagen_file['coverart']: + images.append(Image(base64.b64decode(data))) + return images + for data in mutagen_file["metadata_block_picture"]: + try: + pic = mutagen.flac.Picture(base64.b64decode(data)) + except (TypeError, AttributeError): + continue + images.append(Image(data=pic.data, desc=pic.desc, + type=pic.type)) + return images + + def store(self, mutagen_file, image_data): + # Strip all art, including legacy COVERART. + if 'coverart' in mutagen_file: + del mutagen_file['coverart'] + if 'coverartmime' in mutagen_file: + del mutagen_file['coverartmime'] + super(VorbisImageStorageStyle, self).store(mutagen_file, image_data) + + def serialize(self, image): + """Turn a Image into a base64 encoded FLAC picture block. + """ + pic = mutagen.flac.Picture() + pic.data = image.data + pic.type = image.type_index or 3 # Front cover + pic.mime = image.mime_type + pic.desc = image.desc or u'' + return base64.b64encode(pic.write()) + + +class FlacImageStorageStyle(ListStorageStyle): + """Converts between ``mutagen.flac.Picture`` and ``Image`` instances. + """ + formats = ['FLAC'] + + def __init__(self): + super(FlacImageStorageStyle, self).__init__(key='') + + def fetch(self, mutagen_file): + return mutagen_file.pictures + + def deserialize(self, flac_picture): + return Image(data=flac_picture.data, desc=flac_picture.desc, + type=flac_picture.type) + + def store(self, mutagen_file, pictures): + """``pictures`` is a list of mutagen.flac.Picture instances. + """ + mutagen_file.clear_pictures() + for pic in pictures: + mutagen_file.add_picture(pic) + + def serialize(self, image): + """Turn a Image into a mutagen.flac.Picture. + """ + pic = mutagen.flac.Picture() + pic.data = image.data + pic.type = image.type_index or 3 # Front cover + pic.mime = image.mime_type + pic.desc = image.desc or u'' + return pic + + + +# MediaField is a descriptor that represents a single logical field. It +# aggregates several StorageStyles describing how to access the data for +# each file type. + +class MediaField(object): + """A descriptor providing access to a particular (abstract) metadata + field. + """ + def __init__(self, *styles, **kwargs): + """Creates a new MediaField. + + - `styles`: `StorageStyle` instances that describe the strategy + for reading and writing the field in particular formats. + There must be at least one style for each possible file + format. + - `out_type`: the type of the value that should be returned when + getting this property. + """ + self.out_type = kwargs.get('out_type', unicode) + self._styles = styles + + def styles(self, mutagen_file): + """Yields the list of storage styles of this field that can + handle the MediaFile's format. + """ + for style in self._styles: + if mutagen_file.__class__.__name__ in style.formats: + yield style + + def __get__(self, mediafile, owner=None): + out = None + for style in self.styles(mediafile.mgfile): + out = style.get(mediafile.mgfile) + if out: + break + return _safe_cast(self.out_type, out) + + def __set__(self, mediafile, value): + if value is None: + value = self._none_value() + for style in self.styles(mediafile.mgfile): + style.set(mediafile.mgfile, value) + + def _none_value(self): + """Get an appropriate "null" value for this field's type. This + is used internally when setting the field to None. + """ + if self.out_type == int: + return 0 + elif self.out_type == float: + return 0.0 + elif self.out_type == bool: + return False + elif self.out_type == unicode: + return u'' + + +class ListMediaField(MediaField): + """Property descriptor that retrieves a list of multiple values from + a tag. + + Uses ``get_list`` and set_list`` methods of its ``StorageStyle`` + strategies to do the actual work. + """ + def __get__(self, mediafile, _): + values = [] + for style in self.styles(mediafile.mgfile): + values.extend(style.get_list(mediafile.mgfile)) + return [_safe_cast(self.out_type, value) for value in values] + + def __set__(self, mediafile, values): + for style in self.styles(mediafile.mgfile): + style.set_list(mediafile.mgfile, values) + + def single_field(self): + """Returns a ``MediaField`` descriptor that gets and sets the + first item. + """ + options = {'out_type': self.out_type} + return MediaField(*self._styles, **options) + + +class DateField(MediaField): + """Descriptor that handles serializing and deserializing dates + + The getter parses value from tags into a ``datetime.date`` instance + and setter serializes such an instance into a string. + + For granular access to year, month, and day, use the ``*_field`` + methods to create corresponding `DateItemField`s. + """ + def __init__(self, *date_styles, **kwargs): + """``date_styles`` is a list of ``StorageStyle``s to store and + retrieve the whole date from. The ``year`` option is an + additional list of fallback styles for the year. The year is + always set on this style, but is only retrieved if the main + storage styles do not return a value. + """ + super(DateField, self).__init__(*date_styles) + year_style = kwargs.get('year', None) + if year_style: + self._year_field = MediaField(*year_style) + + def __get__(self, mediafile, owner=None): + year, month, day = self._get_date_tuple(mediafile) + try: + return datetime.date( + year or datetime.MINYEAR, + month or 1, + day or 1 + ) + except ValueError: # Out of range values. + return datetime.date.min + + def __set__(self, mediafile, date): + self._set_date_tuple(mediafile, date.year, date.month, date.day) + + def _get_date_tuple(self, mediafile): + """Get a 3-item sequence representing the date consisting of a + year, month, and day number. Each number is either an integer or + None. + """ + # Get the underlying data and split on hyphens. + datestring = super(DateField, self).__get__(mediafile, None) + datestring = re.sub(r'[Tt ].*$', '', unicode(datestring)) + items = unicode(datestring).split('-') + + # Ensure that we have exactly 3 components, possibly by + # truncating or padding. + items = items[:3] + if len(items) < 3: + items += [None] * (3 - len(items)) + + # Use year field if year is missing. + if not items[0] and hasattr(self, '_year_field'): + items[0] = self._year_field.__get__(mediafile) + + # Convert each component to an integer if possible. + return [_safe_cast(int, item) for item in items] + + def _set_date_tuple(self, mediafile, year, month=None, day=None): + """Set the value of the field given a year, month, and day + number. Each number can be an integer or None to indicate an + unset component. + """ + date = [year or 0] + if month: + date.append(month) + if month and day: + date.append(day) + date = map(unicode, date) + super(DateField, self).__set__(mediafile, '-'.join(date)) + + if hasattr(self, '_year_field'): + self._year_field.__set__(mediafile, year) + + def year_field(self): + return DateItemField(self, 0) + + def month_field(self): + return DateItemField(self, 1) + + def day_field(self): + return DateItemField(self, 2) + + +class DateItemField(MediaField): + """Descriptor that gets and sets constituent parts of a `DateField`: + the month, day, or year. + """ + def __init__(self, date_field, item_pos): + self.date_field = date_field + self.item_pos = item_pos + + def __get__(self, mediafile, _): + return self.date_field._get_date_tuple(mediafile)[self.item_pos] + + def __set__(self, mediafile, value): + items = self.date_field._get_date_tuple(mediafile) + items[self.item_pos] = value + self.date_field._set_date_tuple(mediafile, *items) + + +class CoverArtField(MediaField): + """A descriptor that provides access to the *raw image data* for the + first image on a file. This is used for backwards compatibility: the + full `ImageListField` provides richer `Image` objects. + """ + def __init__(self): + pass + + def __get__(self, mediafile, _): + try: + return mediafile.images[0].data + except IndexError: + return None + + def __set__(self, mediafile, data): + if data: + mediafile.images = [Image(data=data)] + else: + mediafile.images = [] + + +class ImageListField(MediaField): + """Descriptor to access the list of images embedded in tags. + + The getter returns a list of `Image` instances obtained from + the tags. The setter accepts a list of `Image` instances to be + written to the tags. + """ + def __init__(self): + # The storage styles used here must implement the + # `ListStorageStyle` interface and get and set lists of + # `Image`s. + super(ImageListField, self).__init__( + MP3ImageStorageStyle(), + MP4ImageStorageStyle(), + ASFImageStorageStyle(), + VorbisImageStorageStyle(), + FlacImageStorageStyle(), + ) + + def __get__(self, mediafile, _): + images = [] + for style in self.styles(mediafile.mgfile): + images.extend(style.get_list(mediafile.mgfile)) + return images + + def __set__(self, mediafile, images): + for style in self.styles(mediafile.mgfile): + style.set_list(mediafile.mgfile, images) + + + +# MediaFile is a collection of fields. + + +class MediaFile(object): + """Represents a multimedia file on disk and provides access to its + metadata. + """ + def __init__(self, path): + """Constructs a new MediaFile reflecting the file at path. May + throw UnreadableFileError. + """ + self.path = path + + unreadable_exc = ( + mutagen.mp3.error, + mutagen.id3.error, + mutagen.flac.error, + mutagen.monkeysaudio.MonkeysAudioHeaderError, + mutagen.mp4.error, + mutagen.oggopus.error, + mutagen.oggvorbis.error, + mutagen.ogg.error, + mutagen.asf.error, + mutagen.apev2.error, + ) + try: + self.mgfile = mutagen.File(path) + except unreadable_exc as exc: + log.debug(u'header parsing failed: {0}'.format(unicode(exc))) + raise UnreadableFileError('Mutagen could not read file') + except IOError as exc: + if type(exc) == IOError: + # This is a base IOError, not a subclass from Mutagen or + # anywhere else. + raise + else: + log.debug(traceback.format_exc()) + raise MutagenError('Mutagen raised an exception') + except Exception as exc: + # Isolate bugs in Mutagen. + log.debug(traceback.format_exc()) + log.error('uncaught Mutagen exception in open: {0}'.format(exc)) + raise MutagenError('Mutagen raised an exception') + + if self.mgfile is None: # Mutagen couldn't guess the type + raise FileTypeError('file type unsupported by Mutagen') + elif type(self.mgfile).__name__ == 'M4A' or \ + type(self.mgfile).__name__ == 'MP4': + # This hack differentiates AAC and ALAC until we find a more + # deterministic approach. Mutagen only sets the sample rate + # for AAC files. See: + # https://github.com/sampsyo/beets/pull/295 + if hasattr(self.mgfile.info, 'sample_rate') and \ + self.mgfile.info.sample_rate > 0: + self.type = 'aac' + else: + self.type = 'alac' + elif type(self.mgfile).__name__ == 'ID3' or \ + type(self.mgfile).__name__ == 'MP3': + self.type = 'mp3' + elif type(self.mgfile).__name__ == 'FLAC': + self.type = 'flac' + elif type(self.mgfile).__name__ == 'OggOpus': + self.type = 'opus' + elif type(self.mgfile).__name__ == 'OggVorbis': + self.type = 'ogg' + elif type(self.mgfile).__name__ == 'MonkeysAudio': + self.type = 'ape' + elif type(self.mgfile).__name__ == 'WavPack': + self.type = 'wv' + elif type(self.mgfile).__name__ == 'Musepack': + self.type = 'mpc' + elif type(self.mgfile).__name__ == 'ASF': + self.type = 'asf' + else: + raise FileTypeError('file type %s unsupported by MediaFile' % + type(self.mgfile).__name__) + + # add a set of tags if it's missing + if self.mgfile.tags is None: + self.mgfile.add_tags() + + def save(self, id3v23=False): + """Write the object's tags back to the file. + + By default, MP3 files are saved with ID3v2.4 tags. You can use + the older ID3v2.3 standard by specifying the `id3v23` option. + """ + kwargs = {} + if id3v23 and self.type == 'mp3': + id3 = self.mgfile + if hasattr(id3, 'tags'): + # In case this is an MP3 object, not an ID3 object. + id3 = id3.tags + id3.update_to_v23() + kwargs['v2_version'] = 3 + + # Isolate bugs in Mutagen. + try: + self.mgfile.save(**kwargs) + except (IOError, OSError): + # Propagate these through: they don't represent Mutagen bugs. + raise + except Exception as exc: + log.debug(traceback.format_exc()) + log.error('uncaught Mutagen exception in save: {0}'.format(exc)) + raise MutagenError('Mutagen raised an exception') + + def delete(self): + """Remove the current metadata tag from the file. + """ + try: + self.mgfile.delete() + except NotImplementedError: + # For Mutagen types that don't support deletion (notably, + # ASF), just delete each tag individually. + for tag in self.mgfile.keys(): + del self.mgfile[tag] + + + # Field definitions. + + title = MediaField( + MP3StorageStyle('TIT2'), + MP4StorageStyle("\xa9nam"), + StorageStyle('TITLE'), + ASFStorageStyle('Title'), + ) + artist = MediaField( + MP3StorageStyle('TPE1'), + MP4StorageStyle("\xa9ART"), + StorageStyle('ARTIST'), + ASFStorageStyle('Author'), + ) + album = MediaField( + MP3StorageStyle('TALB'), + MP4StorageStyle("\xa9alb"), + StorageStyle('ALBUM'), + ASFStorageStyle('WM/AlbumTitle'), + ) + genres = ListMediaField( + MP3ListStorageStyle('TCON'), + MP4ListStorageStyle("\xa9gen"), + ListStorageStyle('GENRE'), + ASFStorageStyle('WM/Genre'), + ) + genre = genres.single_field() + + composer = MediaField( + MP3StorageStyle('TCOM'), + MP4StorageStyle("\xa9wrt"), + StorageStyle('COMPOSER'), + ASFStorageStyle('WM/Composer'), + ) + grouping = MediaField( + MP3StorageStyle('TIT1'), + MP4StorageStyle("\xa9grp"), + StorageStyle('GROUPING'), + ASFStorageStyle('WM/ContentGroupDescription'), + ) + track = MediaField( + MP3SlashPackStorageStyle('TRCK', pack_pos=0), + MP4TupleStorageStyle('trkn', index=0), + StorageStyle('TRACK'), + StorageStyle('TRACKNUMBER'), + ASFStorageStyle('WM/TrackNumber'), + out_type=int, + ) + tracktotal = MediaField( + MP3SlashPackStorageStyle('TRCK', pack_pos=1), + MP4TupleStorageStyle('trkn', index=1), + StorageStyle('TRACKTOTAL'), + StorageStyle('TRACKC'), + StorageStyle('TOTALTRACKS'), + ASFStorageStyle('TotalTracks'), + out_type=int, + ) + disc = MediaField( + MP3SlashPackStorageStyle('TPOS', pack_pos=0), + MP4TupleStorageStyle('disk', index=0), + StorageStyle('DISC'), + StorageStyle('DISCNUMBER'), + ASFStorageStyle('WM/PartOfSet'), + out_type=int, + ) + disctotal = MediaField( + MP3SlashPackStorageStyle('TPOS', pack_pos=1), + MP4TupleStorageStyle('disk', index=1), + StorageStyle('DISCTOTAL'), + StorageStyle('DISCC'), + StorageStyle('TOTALDISCS'), + ASFStorageStyle('TotalDiscs'), + out_type=int, + ) + lyrics = MediaField( + MP3DescStorageStyle(key='USLT'), + MP4StorageStyle("\xa9lyr"), + StorageStyle('LYRICS'), + ASFStorageStyle('WM/Lyrics'), + ) + comments = MediaField( + MP3DescStorageStyle(key='COMM'), + MP4StorageStyle("\xa9cmt"), + StorageStyle('DESCRIPTION'), + StorageStyle('COMMENT'), + ASFStorageStyle('WM/Comments'), + ) + bpm = MediaField( + MP3StorageStyle('TBPM'), + MP4StorageStyle('tmpo', as_type=int), + StorageStyle('BPM'), + ASFStorageStyle('WM/BeatsPerMinute'), + out_type=int, + ) + comp = MediaField( + MP3StorageStyle('TCMP'), + MP4BoolStorageStyle('cpil'), + StorageStyle('COMPILATION'), + ASFStorageStyle('WM/IsCompilation', as_type=bool), + out_type=bool, + ) + albumartist = MediaField( + MP3StorageStyle('TPE2'), + MP4StorageStyle('aART'), + StorageStyle('ALBUM ARTIST'), + StorageStyle('ALBUMARTIST'), + ASFStorageStyle('WM/AlbumArtist'), + ) + albumtype = MediaField( + MP3DescStorageStyle(u'MusicBrainz Album Type'), + MP4StorageStyle('----:com.apple.iTunes:MusicBrainz Album Type'), + StorageStyle('MUSICBRAINZ_ALBUMTYPE'), + ASFStorageStyle('MusicBrainz/Album Type'), + ) + label = MediaField( + MP3StorageStyle('TPUB'), + MP4StorageStyle('----:com.apple.iTunes:Label'), + MP4StorageStyle('----:com.apple.iTunes:publisher'), + StorageStyle('LABEL'), + StorageStyle('PUBLISHER'), # Traktor + ASFStorageStyle('WM/Publisher'), + ) + artist_sort = MediaField( + MP3StorageStyle('TSOP'), + MP4StorageStyle("soar"), + StorageStyle('ARTISTSORT'), + ASFStorageStyle('WM/ArtistSortOrder'), + ) + albumartist_sort = MediaField( + MP3DescStorageStyle(u'ALBUMARTISTSORT'), + MP4StorageStyle("soaa"), + StorageStyle('ALBUMARTISTSORT'), + ASFStorageStyle('WM/AlbumArtistSortOrder'), + ) + asin = MediaField( + MP3DescStorageStyle(u'ASIN'), + MP4StorageStyle("----:com.apple.iTunes:ASIN"), + StorageStyle('ASIN'), + ASFStorageStyle('MusicBrainz/ASIN'), + ) + catalognum = MediaField( + MP3DescStorageStyle(u'CATALOGNUMBER'), + MP4StorageStyle("----:com.apple.iTunes:CATALOGNUMBER"), + StorageStyle('CATALOGNUMBER'), + ASFStorageStyle('WM/CatalogNo'), + ) + disctitle = MediaField( + MP3StorageStyle('TSST'), + MP4StorageStyle("----:com.apple.iTunes:DISCSUBTITLE"), + StorageStyle('DISCSUBTITLE'), + ASFStorageStyle('WM/SetSubTitle'), + ) + encoder = MediaField( + MP3StorageStyle('TENC'), + MP4StorageStyle("\xa9too"), + StorageStyle('ENCODEDBY'), + StorageStyle('ENCODER'), + ASFStorageStyle('WM/EncodedBy'), + ) + script = MediaField( + MP3DescStorageStyle(u'Script'), + MP4StorageStyle("----:com.apple.iTunes:SCRIPT"), + StorageStyle('SCRIPT'), + ASFStorageStyle('WM/Script'), + ) + language = MediaField( + MP3StorageStyle('TLAN'), + MP4StorageStyle("----:com.apple.iTunes:LANGUAGE"), + StorageStyle('LANGUAGE'), + ASFStorageStyle('WM/Language'), + ) + country = MediaField( + MP3DescStorageStyle('MusicBrainz Album Release Country'), + MP4StorageStyle("----:com.apple.iTunes:MusicBrainz Album " + "Release Country"), + StorageStyle('RELEASECOUNTRY'), + ASFStorageStyle('MusicBrainz/Album Release Country'), + ) + albumstatus = MediaField( + MP3DescStorageStyle(u'MusicBrainz Album Status'), + MP4StorageStyle("----:com.apple.iTunes:MusicBrainz Album Status"), + StorageStyle('MUSICBRAINZ_ALBUMSTATUS'), + ASFStorageStyle('MusicBrainz/Album Status'), + ) + media = MediaField( + MP3StorageStyle('TMED'), + MP4StorageStyle("----:com.apple.iTunes:MEDIA"), + StorageStyle('MEDIA'), + ASFStorageStyle('WM/Media'), + ) + albumdisambig = MediaField( + # This tag mapping was invented for beets (not used by Picard, etc). + MP3DescStorageStyle(u'MusicBrainz Album Comment'), + MP4StorageStyle("----:com.apple.iTunes:MusicBrainz Album Comment"), + StorageStyle('MUSICBRAINZ_ALBUMCOMMENT'), + ASFStorageStyle('MusicBrainz/Album Comment'), + ) + + # Release date. + date = DateField( + MP3StorageStyle('TDRC'), + MP4StorageStyle("\xa9day"), + StorageStyle('DATE'), + ASFStorageStyle('WM/Year'), + year=(StorageStyle('YEAR'),)) + + year = date.year_field() + month = date.month_field() + day = date.day_field() + + # *Original* release date. + original_date = DateField( + MP3StorageStyle('TDOR'), + MP4StorageStyle('----:com.apple.iTunes:ORIGINAL YEAR'), + StorageStyle('ORIGINALDATE'), + ASFStorageStyle('WM/OriginalReleaseYear')) + + original_year = original_date.year_field() + original_month = original_date.month_field() + original_day = original_date.day_field() + + # Nonstandard metadata. + artist_credit = MediaField( + MP3DescStorageStyle(u'Artist Credit'), + MP4StorageStyle("----:com.apple.iTunes:Artist Credit"), + StorageStyle('ARTIST_CREDIT'), + ASFStorageStyle('beets/Artist Credit'), + ) + albumartist_credit = MediaField( + MP3DescStorageStyle(u'Album Artist Credit'), + MP4StorageStyle("----:com.apple.iTunes:Album Artist Credit"), + StorageStyle('ALBUMARTIST_CREDIT'), + ASFStorageStyle('beets/Album Artist Credit'), + ) + + # Legacy album art field + art = CoverArtField() + + # Image list + images = ImageListField() + + # MusicBrainz IDs. + mb_trackid = MediaField( + MP3UFIDStorageStyle(owner='http://musicbrainz.org'), + MP4StorageStyle('----:com.apple.iTunes:MusicBrainz Track Id'), + StorageStyle('MUSICBRAINZ_TRACKID'), + ASFStorageStyle('MusicBrainz/Track Id'), + ) + mb_albumid = MediaField( + MP3DescStorageStyle(u'MusicBrainz Album Id'), + MP4StorageStyle('----:com.apple.iTunes:MusicBrainz Album Id'), + StorageStyle('MUSICBRAINZ_ALBUMID'), + ASFStorageStyle('MusicBrainz/Album Id'), + ) + mb_artistid = MediaField( + MP3DescStorageStyle(u'MusicBrainz Artist Id'), + MP4StorageStyle('----:com.apple.iTunes:MusicBrainz Artist Id'), + StorageStyle('MUSICBRAINZ_ARTISTID'), + ASFStorageStyle('MusicBrainz/Artist Id'), + ) + mb_albumartistid = MediaField( + MP3DescStorageStyle(u'MusicBrainz Album Artist Id'), + MP4StorageStyle('----:com.apple.iTunes:MusicBrainz Album Artist Id'), + StorageStyle('MUSICBRAINZ_ALBUMARTISTID'), + ASFStorageStyle('MusicBrainz/Album Artist Id'), + ) + mb_releasegroupid = MediaField( + MP3DescStorageStyle(u'MusicBrainz Release Group Id'), + MP4StorageStyle('----:com.apple.iTunes:MusicBrainz Release Group Id'), + StorageStyle('MUSICBRAINZ_RELEASEGROUPID'), + ASFStorageStyle('MusicBrainz/Release Group Id'), + ) + + # Acoustid fields. + acoustid_fingerprint = MediaField( + MP3DescStorageStyle(u'Acoustid Fingerprint'), + MP4StorageStyle('----:com.apple.iTunes:Acoustid Fingerprint'), + StorageStyle('ACOUSTID_FINGERPRINT'), + ASFStorageStyle('Acoustid/Fingerprint'), + ) + acoustid_id = MediaField( + MP3DescStorageStyle(u'Acoustid Id'), + MP4StorageStyle('----:com.apple.iTunes:Acoustid Id'), + StorageStyle('ACOUSTID_ID'), + ASFStorageStyle('Acoustid/Id'), + ) + + # ReplayGain fields. + rg_track_gain = MediaField( + MP3DescStorageStyle(u'REPLAYGAIN_TRACK_GAIN', + float_places=2, suffix=u' dB'), + MP3DescStorageStyle(u'replaygain_track_gain', + float_places=2, suffix=u' dB'), + MP3SoundCheckStorageStyle(key='COMM', index=0, desc=u'iTunNORM', + id3_lang='eng'), + MP4StorageStyle(key='----:com.apple.iTunes:replaygain_track_gain', + float_places=2, suffix=b' dB'), + MP4SoundCheckStorageStyle(key='----:com.apple.iTunes:iTunNORM', + index=0), + StorageStyle(u'REPLAYGAIN_TRACK_GAIN', + float_places=2, suffix=u' dB'), + ASFStorageStyle(u'replaygain_track_gain', + float_places=2, suffix=u' dB'), + out_type=float + ) + rg_album_gain = MediaField( + MP3DescStorageStyle(u'REPLAYGAIN_ALBUM_GAIN', + float_places=2, suffix=u' dB'), + MP3DescStorageStyle(u'replaygain_album_gain', + float_places=2, suffix=u' dB'), + MP4SoundCheckStorageStyle(key='----:com.apple.iTunes:iTunNORM', + index=1), + StorageStyle(u'REPLAYGAIN_ALBUM_GAIN', + float_places=2, suffix=u' dB'), + ASFStorageStyle(u'replaygain_album_gain', + float_places=2, suffix=u' dB'), + out_type=float + ) + rg_track_peak = MediaField( + MP3DescStorageStyle(u'REPLAYGAIN_TRACK_PEAK', + float_places=6), + MP3DescStorageStyle(u'replaygain_track_peak', + float_places=6), + MP3SoundCheckStorageStyle(key='COMM', index=1, desc=u'iTunNORM', + id3_lang='eng'), + MP4StorageStyle('----:com.apple.iTunes:replaygain_track_peak', + float_places=6), + MP4SoundCheckStorageStyle(key='----:com.apple.iTunes:iTunNORM', + index=1), + StorageStyle(u'REPLAYGAIN_TRACK_PEAK', + float_places=6), + ASFStorageStyle(u'replaygain_track_peak', + float_places=6), + out_type=float, + ) + rg_album_peak = MediaField( + MP3DescStorageStyle(u'REPLAYGAIN_ALBUM_PEAK', + float_places=6), + MP3DescStorageStyle(u'replaygain_album_peak', + float_places=6), + MP4StorageStyle('----:com.apple.iTunes:replaygain_album_peak', + float_places=6), + StorageStyle(u'REPLAYGAIN_ALBUM_PEAK', + float_places=6), + ASFStorageStyle(u'replaygain_album_peak', + float_places=6), + out_type=float, + ) + + @property + def length(self): + """The duration of the audio in seconds (a float).""" + return self.mgfile.info.length + + @property + def samplerate(self): + """The audio's sample rate (an int).""" + if hasattr(self.mgfile.info, 'sample_rate'): + return self.mgfile.info.sample_rate + elif self.type == 'opus': + # Opus is always 48kHz internally. + return 48000 + return 0 + + @property + def bitdepth(self): + """The number of bits per sample in the audio encoding (an int). + Only available for certain file formats (zero where + unavailable). + """ + if hasattr(self.mgfile.info, 'bits_per_sample'): + return self.mgfile.info.bits_per_sample + return 0 + + @property + def channels(self): + """The number of channels in the audio (an int).""" + if isinstance(self.mgfile.info, mutagen.mp3.MPEGInfo): + return { + mutagen.mp3.STEREO: 2, + mutagen.mp3.JOINTSTEREO: 2, + mutagen.mp3.DUALCHANNEL: 2, + mutagen.mp3.MONO: 1, + }[self.mgfile.info.mode] + if hasattr(self.mgfile.info, 'channels'): + return self.mgfile.info.channels + return 0 + + @property + def bitrate(self): + """The number of bits per seconds used in the audio coding (an + int). If this is provided explicitly by the compressed file + format, this is a precise reflection of the encoding. Otherwise, + it is estimated from the on-disk file size. In this case, some + imprecision is possible because the file header is incorporated + in the file size. + """ + if hasattr(self.mgfile.info, 'bitrate') and self.mgfile.info.bitrate: + # Many formats provide it explicitly. + return self.mgfile.info.bitrate + else: + # Otherwise, we calculate bitrate from the file size. (This + # is the case for all of the lossless formats.) + if not self.length: + # Avoid division by zero if length is not available. + return 0 + size = os.path.getsize(self.path) + return int(size * 8 / self.length) + + @property + def format(self): + """A string describing the file format/codec.""" + return TYPES[self.type] diff --git a/libs/beets/plugins.py b/libs/beets/plugins.py new file mode 100644 index 00000000..6a58777c --- /dev/null +++ b/libs/beets/plugins.py @@ -0,0 +1,359 @@ +# This file is part of beets. +# Copyright 2013, Adrian Sampson. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. + +"""Support for beets plugins.""" + +import logging +import traceback +from collections import defaultdict + +import beets +from beets import mediafile + +PLUGIN_NAMESPACE = 'beetsplug' + +# Plugins using the Last.fm API can share the same API key. +LASTFM_KEY = '2dc3914abf35f0d9c92d97d8f8e42b43' + +# Global logger. +log = logging.getLogger('beets') + + +# Managing the plugins themselves. + +class BeetsPlugin(object): + """The base class for all beets plugins. Plugins provide + functionality by defining a subclass of BeetsPlugin and overriding + the abstract methods defined here. + """ + def __init__(self, name=None): + """Perform one-time plugin setup. + """ + _add_media_fields(self.item_fields()) + self.import_stages = [] + self.name = name or self.__module__.split('.')[-1] + self.config = beets.config[self.name] + if not self.template_funcs: + self.template_funcs = {} + if not self.template_fields: + self.template_fields = {} + if not self.album_template_fields: + self.album_template_fields = {} + + def commands(self): + """Should return a list of beets.ui.Subcommand objects for + commands that should be added to beets' CLI. + """ + return () + + def queries(self): + """Should return a dict mapping prefixes to Query subclasses. + """ + return {} + + def track_distance(self, item, info): + """Should return a Distance object to be added to the + distance for every track comparison. + """ + return beets.autotag.hooks.Distance() + + def album_distance(self, items, album_info, mapping): + """Should return a Distance object to be added to the + distance for every album-level comparison. + """ + return beets.autotag.hooks.Distance() + + def candidates(self, items, artist, album, va_likely): + """Should return a sequence of AlbumInfo objects that match the + album whose items are provided. + """ + return () + + def item_candidates(self, item, artist, title): + """Should return a sequence of TrackInfo objects that match the + item provided. + """ + return () + + def item_fields(self): + """Returns field descriptors to be added to the MediaFile class, + in the form of a dictionary whose keys are field names and whose + values are descriptor (e.g., MediaField) instances. The Library + database schema is not (currently) extended. + """ + return {} + + def album_for_id(self, album_id): + """Return an AlbumInfo object or None if no matching release was + found. + """ + return None + + def track_for_id(self, track_id): + """Return a TrackInfo object or None if no matching release was + found. + """ + return None + + + listeners = None + + @classmethod + def register_listener(cls, event, func): + """Add a function as a listener for the specified event. (An + imperative alternative to the @listen decorator.) + """ + if cls.listeners is None: + cls.listeners = defaultdict(list) + cls.listeners[event].append(func) + + @classmethod + def listen(cls, event): + """Decorator that adds a function as an event handler for the + specified event (as a string). The parameters passed to function + will vary depending on what event occurred. + + The function should respond to named parameters. + function(**kwargs) will trap all arguments in a dictionary. + Example: + + >>> @MyPlugin.listen("imported") + >>> def importListener(**kwargs): + >>> pass + """ + def helper(func): + if cls.listeners is None: + cls.listeners = defaultdict(list) + cls.listeners[event].append(func) + return func + return helper + + template_funcs = None + template_fields = None + album_template_fields = None + + @classmethod + def template_func(cls, name): + """Decorator that registers a path template function. The + function will be invoked as ``%name{}`` from path format + strings. + """ + def helper(func): + if cls.template_funcs is None: + cls.template_funcs = {} + cls.template_funcs[name] = func + return func + return helper + + @classmethod + def template_field(cls, name): + """Decorator that registers a path template field computation. + The value will be referenced as ``$name`` from path format + strings. The function must accept a single parameter, the Item + being formatted. + """ + def helper(func): + if cls.template_fields is None: + cls.template_fields = {} + cls.template_fields[name] = func + return func + return helper + +_classes = set() +def load_plugins(names=()): + """Imports the modules for a sequence of plugin names. Each name + must be the name of a Python module under the "beetsplug" namespace + package in sys.path; the module indicated should contain the + BeetsPlugin subclasses desired. + """ + for name in names: + modname = '%s.%s' % (PLUGIN_NAMESPACE, name) + try: + try: + namespace = __import__(modname, None, None) + except ImportError as exc: + # Again, this is hacky: + if exc.args[0].endswith(' ' + name): + log.warn('** plugin %s not found' % name) + else: + raise + else: + for obj in getattr(namespace, name).__dict__.values(): + if isinstance(obj, type) and issubclass(obj, BeetsPlugin) \ + and obj != BeetsPlugin and obj not in _classes: + _classes.add(obj) + + except: + log.warn('** error loading plugin %s' % name) + log.warn(traceback.format_exc()) + +_instances = {} +def find_plugins(): + """Returns a list of BeetsPlugin subclass instances from all + currently loaded beets plugins. Loads the default plugin set + first. + """ + load_plugins() + plugins = [] + for cls in _classes: + # Only instantiate each plugin class once. + if cls not in _instances: + _instances[cls] = cls() + plugins.append(_instances[cls]) + return plugins + + +# Communication with plugins. + +def commands(): + """Returns a list of Subcommand objects from all loaded plugins. + """ + out = [] + for plugin in find_plugins(): + out += plugin.commands() + return out + +def queries(): + """Returns a dict mapping prefix strings to Query subclasses all loaded + plugins. + """ + out = {} + for plugin in find_plugins(): + out.update(plugin.queries()) + return out + +def track_distance(item, info): + """Gets the track distance calculated by all loaded plugins. + Returns a Distance object. + """ + from beets.autotag.hooks import Distance + dist = Distance() + for plugin in find_plugins(): + dist.update(plugin.track_distance(item, info)) + return dist + +def album_distance(items, album_info, mapping): + """Returns the album distance calculated by plugins.""" + from beets.autotag.hooks import Distance + dist = Distance() + for plugin in find_plugins(): + dist.update(plugin.album_distance(items, album_info, mapping)) + return dist + +def candidates(items, artist, album, va_likely): + """Gets MusicBrainz candidates for an album from each plugin. + """ + out = [] + for plugin in find_plugins(): + out.extend(plugin.candidates(items, artist, album, va_likely)) + return out + +def item_candidates(item, artist, title): + """Gets MusicBrainz candidates for an item from the plugins. + """ + out = [] + for plugin in find_plugins(): + out.extend(plugin.item_candidates(item, artist, title)) + return out + +def album_for_id(album_id): + """Get AlbumInfo objects for a given ID string. + """ + out = [] + for plugin in find_plugins(): + res = plugin.album_for_id(album_id) + if res: + out.append(res) + return out + +def track_for_id(track_id): + """Get TrackInfo objects for a given ID string. + """ + out = [] + for plugin in find_plugins(): + res = plugin.track_for_id(track_id) + if res: + out.append(res) + return out + +def template_funcs(): + """Get all the template functions declared by plugins as a + dictionary. + """ + funcs = {} + for plugin in find_plugins(): + if plugin.template_funcs: + funcs.update(plugin.template_funcs) + return funcs + +def _add_media_fields(fields): + """Adds a {name: descriptor} dictionary of fields to the MediaFile + class. Called during the plugin initialization. + """ + for key, value in fields.iteritems(): + setattr(mediafile.MediaFile, key, value) + +def import_stages(): + """Get a list of import stage functions defined by plugins.""" + stages = [] + for plugin in find_plugins(): + if hasattr(plugin, 'import_stages'): + stages += plugin.import_stages + return stages + + +# New-style (lazy) plugin-provided fields. + +def item_field_getters(): + """Get a dictionary mapping field names to unary functions that + compute the field's value. + """ + funcs = {} + for plugin in find_plugins(): + if plugin.template_fields: + funcs.update(plugin.template_fields) + return funcs + +def album_field_getters(): + """As above, for album fields. + """ + funcs = {} + for plugin in find_plugins(): + if plugin.album_template_fields: + funcs.update(plugin.album_template_fields) + return funcs + + +# Event dispatch. + +def event_handlers(): + """Find all event handlers from plugins as a dictionary mapping + event names to sequences of callables. + """ + all_handlers = defaultdict(list) + for plugin in find_plugins(): + if plugin.listeners: + for event, handlers in plugin.listeners.items(): + all_handlers[event] += handlers + return all_handlers + +def send(event, **arguments): + """Sends an event to all assigned event listeners. Event is the + name of the event to send, all other named arguments go to the + event handler(s). + + Returns a list of return values from the handlers. + """ + log.debug('Sending event: %s' % event) + return [handler(**arguments) for handler in event_handlers()[event]] diff --git a/libs/beets/ui/__init__.py b/libs/beets/ui/__init__.py new file mode 100644 index 00000000..2df74ea7 --- /dev/null +++ b/libs/beets/ui/__init__.py @@ -0,0 +1,980 @@ +# This file is part of beets. +# Copyright 2014, Adrian Sampson. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. + +"""This module contains all of the core logic for beets' command-line +interface. To invoke the CLI, just call beets.ui.main(). The actual +CLI commands are implemented in the ui.commands module. +""" +from __future__ import print_function + +import locale +import optparse +import textwrap +import sys +from difflib import SequenceMatcher +import logging +import sqlite3 +import errno +import re +import struct +import traceback + +from beets import library +from beets import plugins +from beets import util +from beets.util.functemplate import Template +from beets import config +from beets.util import confit +from beets.autotag import mb + + +# On Windows platforms, use colorama to support "ANSI" terminal colors. + +if sys.platform == 'win32': + try: + import colorama + except ImportError: + pass + else: + colorama.init() + + + +# Constants. + + +PF_KEY_QUERIES = { + 'comp': 'comp:true', + 'singleton': 'singleton:true', +} + +# UI exception. Commands should throw this in order to display +# nonrecoverable errors to the user. +class UserError(Exception): + pass + +# Main logger. +log = logging.getLogger('beets') + + + +# Utilities. + + +def _encoding(): + """Tries to guess the encoding used by the terminal.""" + # Configured override? + encoding = config['terminal_encoding'].get() + if encoding: + return encoding + + # Determine from locale settings. + try: + return locale.getdefaultlocale()[1] or 'utf8' + except ValueError: + # Invalid locale environment variable setting. To avoid + # failing entirely for no good reason, assume UTF-8. + return 'utf8' + + +def decargs(arglist): + """Given a list of command-line argument bytestrings, attempts to + decode them to Unicode strings. + """ + return [s.decode(_encoding()) for s in arglist] + + +def print_(*strings): + """Like print, but rather than raising an error when a character + is not in the terminal's encoding's character set, just silently + replaces it. + """ + if strings: + if isinstance(strings[0], unicode): + txt = u' '.join(strings) + else: + txt = ' '.join(strings) + else: + txt = u'' + if isinstance(txt, unicode): + txt = txt.encode(_encoding(), 'replace') + print(txt) + + +def input_(prompt=None): + """Like `raw_input`, but decodes the result to a Unicode string. + Raises a UserError if stdin is not available. The prompt is sent to + stdout rather than stderr. A printed between the prompt and the + input cursor. + """ + # raw_input incorrectly sends prompts to stderr, not stdout, so we + # use print() explicitly to display prompts. + # http://bugs.python.org/issue1927 + if prompt: + if isinstance(prompt, unicode): + prompt = prompt.encode(_encoding(), 'replace') + print(prompt, end=' ') + + try: + resp = raw_input() + except EOFError: + raise UserError('stdin stream ended while input required') + + return resp.decode(sys.stdin.encoding or 'utf8', 'ignore') + + +def input_options(options, require=False, prompt=None, fallback_prompt=None, + numrange=None, default=None, max_width=72): + """Prompts a user for input. The sequence of `options` defines the + choices the user has. A single-letter shortcut is inferred for each + option; the user's choice is returned as that single, lower-case + letter. The options should be provided as lower-case strings unless + a particular shortcut is desired; in that case, only that letter + should be capitalized. + + By default, the first option is the default. `default` can be provided to + override this. If `require` is provided, then there is no default. The + prompt and fallback prompt are also inferred but can be overridden. + + If numrange is provided, it is a pair of `(high, low)` (both ints) + indicating that, in addition to `options`, the user may enter an + integer in that inclusive range. + + `max_width` specifies the maximum number of columns in the + automatically generated prompt string. + """ + # Assign single letters to each option. Also capitalize the options + # to indicate the letter. + letters = {} + display_letters = [] + capitalized = [] + first = True + for option in options: + # Is a letter already capitalized? + for letter in option: + if letter.isalpha() and letter.upper() == letter: + found_letter = letter + break + else: + # Infer a letter. + for letter in option: + if not letter.isalpha(): + continue # Don't use punctuation. + if letter not in letters: + found_letter = letter + break + else: + raise ValueError('no unambiguous lettering found') + + letters[found_letter.lower()] = option + index = option.index(found_letter) + + # Mark the option's shortcut letter for display. + if not require and ((default is None and not numrange and first) or + (isinstance(default, basestring) and + found_letter.lower() == default.lower())): + # The first option is the default; mark it. + show_letter = '[%s]' % found_letter.upper() + is_default = True + else: + show_letter = found_letter.upper() + is_default = False + + # Colorize the letter shortcut. + show_letter = colorize('turquoise' if is_default else 'blue', + show_letter) + + # Insert the highlighted letter back into the word. + capitalized.append( + option[:index] + show_letter + option[index + 1:] + ) + display_letters.append(found_letter.upper()) + + first = False + + # The default is just the first option if unspecified. + if require: + default = None + elif default is None: + if numrange: + default = numrange[0] + else: + default = display_letters[0].lower() + + # Make a prompt if one is not provided. + if not prompt: + prompt_parts = [] + prompt_part_lengths = [] + if numrange: + if isinstance(default, int): + default_name = str(default) + default_name = colorize('turquoise', default_name) + tmpl = '# selection (default %s)' + prompt_parts.append(tmpl % default_name) + prompt_part_lengths.append(len(tmpl % str(default))) + else: + prompt_parts.append('# selection') + prompt_part_lengths.append(len(prompt_parts[-1])) + prompt_parts += capitalized + prompt_part_lengths += [len(s) for s in options] + + # Wrap the query text. + prompt = '' + line_length = 0 + for i, (part, length) in enumerate(zip(prompt_parts, + prompt_part_lengths)): + # Add punctuation. + if i == len(prompt_parts) - 1: + part += '?' + else: + part += ',' + length += 1 + + # Choose either the current line or the beginning of the next. + if line_length + length + 1 > max_width: + prompt += '\n' + line_length = 0 + + if line_length != 0: + # Not the beginning of the line; need a space. + part = ' ' + part + length += 1 + + prompt += part + line_length += length + + # Make a fallback prompt too. This is displayed if the user enters + # something that is not recognized. + if not fallback_prompt: + fallback_prompt = 'Enter one of ' + if numrange: + fallback_prompt += '%i-%i, ' % numrange + fallback_prompt += ', '.join(display_letters) + ':' + + resp = input_(prompt) + while True: + resp = resp.strip().lower() + + # Try default option. + if default is not None and not resp: + resp = default + + # Try an integer input if available. + if numrange: + try: + resp = int(resp) + except ValueError: + pass + else: + low, high = numrange + if low <= resp <= high: + return resp + else: + resp = None + + # Try a normal letter input. + if resp: + resp = resp[0] + if resp in letters: + return resp + + # Prompt for new input. + resp = input_(fallback_prompt) + + +def input_yn(prompt, require=False): + """Prompts the user for a "yes" or "no" response. The default is + "yes" unless `require` is `True`, in which case there is no default. + """ + sel = input_options( + ('y', 'n'), require, prompt, 'Enter Y or N:' + ) + return sel == 'y' + + +def human_bytes(size): + """Formats size, a number of bytes, in a human-readable way.""" + suffices = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB', 'HB'] + for suffix in suffices: + if size < 1024: + return "%3.1f %s" % (size, suffix) + size /= 1024.0 + return "big" + + +def human_seconds(interval): + """Formats interval, a number of seconds, as a human-readable time + interval using English words. + """ + units = [ + (1, 'second'), + (60, 'minute'), + (60, 'hour'), + (24, 'day'), + (7, 'week'), + (52, 'year'), + (10, 'decade'), + ] + for i in range(len(units) - 1): + increment, suffix = units[i] + next_increment, _ = units[i + 1] + interval /= float(increment) + if interval < next_increment: + break + else: + # Last unit. + increment, suffix = units[-1] + interval /= float(increment) + + return "%3.1f %ss" % (interval, suffix) + + +def human_seconds_short(interval): + """Formats a number of seconds as a short human-readable M:SS + string. + """ + interval = int(interval) + return u'%i:%02i' % (interval // 60, interval % 60) + + +# ANSI terminal colorization code heavily inspired by pygments: +# http://dev.pocoo.org/hg/pygments-main/file/b2deea5b5030/pygments/console.py +# (pygments is by Tim Hatch, Armin Ronacher, et al.) +COLOR_ESCAPE = "\x1b[" +DARK_COLORS = ["black", "darkred", "darkgreen", "brown", "darkblue", + "purple", "teal", "lightgray"] +LIGHT_COLORS = ["darkgray", "red", "green", "yellow", "blue", + "fuchsia", "turquoise", "white"] +RESET_COLOR = COLOR_ESCAPE + "39;49;00m" +def _colorize(color, text): + """Returns a string that prints the given text in the given color + in a terminal that is ANSI color-aware. The color must be something + in DARK_COLORS or LIGHT_COLORS. + """ + if color in DARK_COLORS: + escape = COLOR_ESCAPE + "%im" % (DARK_COLORS.index(color) + 30) + elif color in LIGHT_COLORS: + escape = COLOR_ESCAPE + "%i;01m" % (LIGHT_COLORS.index(color) + 30) + else: + raise ValueError('no such color %s', color) + return escape + text + RESET_COLOR + + +def colorize(color, text): + """Colorize text if colored output is enabled. (Like _colorize but + conditional.) + """ + if config['color']: + return _colorize(color, text) + else: + return text + + +def _colordiff(a, b, highlight='red', minor_highlight='lightgray'): + """Given two values, return the same pair of strings except with + their differences highlighted in the specified color. Strings are + highlighted intelligently to show differences; other values are + stringified and highlighted in their entirety. + """ + if not isinstance(a, basestring) or not isinstance(b, basestring): + # Non-strings: use ordinary equality. + a = unicode(a) + b = unicode(b) + if a == b: + return a, b + else: + return colorize(highlight, a), colorize(highlight, b) + + if isinstance(a, bytes) or isinstance(b, bytes): + # A path field. + a = util.displayable_path(a) + b = util.displayable_path(b) + + a_out = [] + b_out = [] + + matcher = SequenceMatcher(lambda x: False, a, b) + for op, a_start, a_end, b_start, b_end in matcher.get_opcodes(): + if op == 'equal': + # In both strings. + a_out.append(a[a_start:a_end]) + b_out.append(b[b_start:b_end]) + elif op == 'insert': + # Right only. + b_out.append(colorize(highlight, b[b_start:b_end])) + elif op == 'delete': + # Left only. + a_out.append(colorize(highlight, a[a_start:a_end])) + elif op == 'replace': + # Right and left differ. Colorise with second highlight if + # it's just a case change. + if a[a_start:a_end].lower() != b[b_start:b_end].lower(): + color = highlight + else: + color = minor_highlight + a_out.append(colorize(color, a[a_start:a_end])) + b_out.append(colorize(color, b[b_start:b_end])) + else: + assert(False) + + return u''.join(a_out), u''.join(b_out) + + +def colordiff(a, b, highlight='red'): + """Colorize differences between two values if color is enabled. + (Like _colordiff but conditional.) + """ + if config['color']: + return _colordiff(a, b, highlight) + else: + return unicode(a), unicode(b) + + +def color_diff_suffix(a, b, highlight='red'): + """Colorize the differing suffix between two strings.""" + a, b = unicode(a), unicode(b) + if not config['color']: + return a, b + + # Fast path. + if a == b: + return a, b + + # Find the longest common prefix. + first_diff = None + for i in range(min(len(a), len(b))): + if a[i] != b[i]: + first_diff = i + break + else: + first_diff = min(len(a), len(b)) + + # Colorize from the first difference on. + return a[:first_diff] + colorize(highlight, a[first_diff:]), \ + b[:first_diff] + colorize(highlight, b[first_diff:]) + + +def get_path_formats(subview=None): + """Get the configuration's path formats as a list of query/template + pairs. + """ + path_formats = [] + subview = subview or config['paths'] + for query, view in subview.items(): + query = PF_KEY_QUERIES.get(query, query) # Expand common queries. + path_formats.append((query, Template(view.get(unicode)))) + return path_formats + + +def get_replacements(): + """Confit validation function that reads regex/string pairs. + """ + replacements = [] + for pattern, repl in config['replace'].get(dict).items(): + repl = repl or '' + try: + replacements.append((re.compile(pattern), repl)) + except re.error: + raise UserError( + u'malformed regular expression in replace: {0}'.format( + pattern + ) + ) + return replacements + + +def get_plugin_paths(): + """Get the list of search paths for plugins from the config file. + The value for "pluginpath" may be a single string or a list of + strings. + """ + pluginpaths = config['pluginpath'].get() + if isinstance(pluginpaths, basestring): + pluginpaths = [pluginpaths] + if not isinstance(pluginpaths, list): + raise confit.ConfigTypeError( + u'pluginpath must be string or a list of strings' + ) + return map(util.normpath, pluginpaths) + + +def _pick_format(album, fmt=None): + """Pick a format string for printing Album or Item objects, + falling back to config options and defaults. + """ + if fmt: + return fmt + if album: + return config['list_format_album'].get(unicode) + else: + return config['list_format_item'].get(unicode) + + +def print_obj(obj, lib, fmt=None): + """Print an Album or Item object. If `fmt` is specified, use that + format string. Otherwise, use the configured template. + """ + album = isinstance(obj, library.Album) + fmt = _pick_format(album, fmt) + if isinstance(fmt, Template): + template = fmt + else: + template = Template(fmt) + print_(obj.evaluate_template(template)) + + +def term_width(): + """Get the width (columns) of the terminal.""" + fallback = config['ui']['terminal_width'].get(int) + + # The fcntl and termios modules are not available on non-Unix + # platforms, so we fall back to a constant. + try: + import fcntl + import termios + except ImportError: + return fallback + + try: + buf = fcntl.ioctl(0, termios.TIOCGWINSZ, ' ' * 4) + except IOError: + return fallback + try: + height, width = struct.unpack('hh', buf) + except struct.error: + return fallback + return width + + +FLOAT_EPSILON = 0.01 +def _field_diff(field, old, new): + """Given two Model objects, format their values for `field` and + highlight changes among them. Return a human-readable string. If the + value has not changed, return None instead. + """ + oldval = old.get(field) + newval = new.get(field) + + # If no change, abort. + if isinstance(oldval, float) and isinstance(newval, float) and \ + abs(oldval - newval) < FLOAT_EPSILON: + return None + elif oldval == newval: + return None + + # Get formatted values for output. + oldstr = old._get_formatted(field) + newstr = new._get_formatted(field) + + # For strings, highlight changes. For others, colorize the whole + # thing. + if isinstance(oldval, basestring): + oldstr, newstr = colordiff(oldval, newval) + else: + oldstr, newstr = colorize('red', oldstr), colorize('red', newstr) + + return u'{0} -> {1}'.format(oldstr, newstr) + + +def show_model_changes(new, old=None, fields=None, always=False): + """Given a Model object, print a list of changes from its pristine + version stored in the database. Return a boolean indicating whether + any changes were found. + + `old` may be the "original" object to avoid using the pristine + version from the database. `fields` may be a list of fields to + restrict the detection to. `always` indicates whether the object is + always identified, regardless of whether any changes are present. + """ + old = old or new._db._get(type(new), new.id) + + # Build up lines showing changed fields. + changes = [] + for field in old: + # Subset of the fields. Never show mtime. + if field == 'mtime' or (fields and field not in fields): + continue + + # Detect and show difference for this field. + line = _field_diff(field, old, new) + if line: + changes.append(u' {0}: {1}'.format(field, line)) + + # New fields. + for field in set(new) - set(old): + changes.append(u' {0}: {1}'.format( + field, + colorize('red', new._get_formatted(field)) + )) + + # Print changes. + if changes or always: + print_obj(old, old._db) + if changes: + print_(u'\n'.join(changes)) + + return bool(changes) + + + +# Subcommand parsing infrastructure. + + +# This is a fairly generic subcommand parser for optparse. It is +# maintained externally here: +# http://gist.github.com/462717 +# There you will also find a better description of the code and a more +# succinct example program. + +class Subcommand(object): + """A subcommand of a root command-line application that may be + invoked by a SubcommandOptionParser. + """ + def __init__(self, name, parser=None, help='', aliases=(), hide=False): + """Creates a new subcommand. name is the primary way to invoke + the subcommand; aliases are alternate names. parser is an + OptionParser responsible for parsing the subcommand's options. + help is a short description of the command. If no parser is + given, it defaults to a new, empty OptionParser. + """ + self.name = name + self.parser = parser or optparse.OptionParser() + self.aliases = aliases + self.help = help + self.hide = hide + +class SubcommandsOptionParser(optparse.OptionParser): + """A variant of OptionParser that parses subcommands and their + arguments. + """ + # A singleton command used to give help on other subcommands. + _HelpSubcommand = Subcommand('help', optparse.OptionParser(), + help='give detailed help on a specific sub-command', + aliases=('?',)) + + def __init__(self, *args, **kwargs): + """Create a new subcommand-aware option parser. All of the + options to OptionParser.__init__ are supported in addition + to subcommands, a sequence of Subcommand objects. + """ + # The subcommand array, with the help command included. + self.subcommands = list(kwargs.pop('subcommands', [])) + self.subcommands.append(self._HelpSubcommand) + + # A more helpful default usage. + if 'usage' not in kwargs: + kwargs['usage'] = """ + %prog COMMAND [ARGS...] + %prog help COMMAND""" + + # Super constructor. + optparse.OptionParser.__init__(self, *args, **kwargs) + + # Adjust the help-visible name of each subcommand. + for subcommand in self.subcommands: + subcommand.parser.prog = '%s %s' % \ + (self.get_prog_name(), subcommand.name) + + # Our root parser needs to stop on the first unrecognized argument. + self.disable_interspersed_args() + + def add_subcommand(self, cmd): + """Adds a Subcommand object to the parser's list of commands. + """ + self.subcommands.append(cmd) + + # Add the list of subcommands to the help message. + def format_help(self, formatter=None): + # Get the original help message, to which we will append. + out = optparse.OptionParser.format_help(self, formatter) + if formatter is None: + formatter = self.formatter + + # Subcommands header. + result = ["\n"] + result.append(formatter.format_heading('Commands')) + formatter.indent() + + # Generate the display names (including aliases). + # Also determine the help position. + disp_names = [] + help_position = 0 + subcommands = [c for c in self.subcommands if not c.hide] + for subcommand in subcommands: + name = subcommand.name + if subcommand.aliases: + name += ' (%s)' % ', '.join(subcommand.aliases) + disp_names.append(name) + + # Set the help position based on the max width. + proposed_help_position = len(name) + formatter.current_indent + 2 + if proposed_help_position <= formatter.max_help_position: + help_position = max(help_position, proposed_help_position) + + # Add each subcommand to the output. + for subcommand, name in zip(subcommands, disp_names): + # Lifted directly from optparse.py. + name_width = help_position - formatter.current_indent - 2 + if len(name) > name_width: + name = "%*s%s\n" % (formatter.current_indent, "", name) + indent_first = help_position + else: + name = "%*s%-*s " % (formatter.current_indent, "", + name_width, name) + indent_first = 0 + result.append(name) + help_width = formatter.width - help_position + help_lines = textwrap.wrap(subcommand.help, help_width) + result.append("%*s%s\n" % (indent_first, "", help_lines[0])) + result.extend(["%*s%s\n" % (help_position, "", line) + for line in help_lines[1:]]) + formatter.dedent() + + # Concatenate the original help message with the subcommand + # list. + return out + "".join(result) + + def _subcommand_for_name(self, name): + """Return the subcommand in self.subcommands matching the + given name. The name may either be the name of a subcommand or + an alias. If no subcommand matches, returns None. + """ + for subcommand in self.subcommands: + if name == subcommand.name or \ + name in subcommand.aliases: + return subcommand + return None + + def parse_args(self, a=None, v=None): + """Like OptionParser.parse_args, but returns these four items: + - options: the options passed to the root parser + - subcommand: the Subcommand object that was invoked + - suboptions: the options passed to the subcommand parser + - subargs: the positional arguments passed to the subcommand + """ + options, args = optparse.OptionParser.parse_args(self, a, v) + subcommand, suboptions, subargs = self._parse_sub(args) + return options, subcommand, suboptions, subargs + + def _parse_sub(self, args): + """Given the `args` left unused by a typical OptionParser + `parse_args`, return the invoked subcommand, the subcommand + options, and the subcommand arguments. + """ + if not args: + # No command given. + self.print_help() + self.exit() + else: + cmdname = args.pop(0) + subcommand = self._subcommand_for_name(cmdname) + if not subcommand: + self.error('unknown command ' + cmdname) + + suboptions, subargs = subcommand.parser.parse_args(args) + + if subcommand is self._HelpSubcommand: + if subargs: + # particular + cmdname = subargs[0] + helpcommand = self._subcommand_for_name(cmdname) + if not helpcommand: + self.error('no command named {0}'.format(cmdname)) + helpcommand.parser.print_help() + self.exit() + else: + # general + self.print_help() + self.exit() + + return subcommand, suboptions, subargs + + +optparse.Option.ALWAYS_TYPED_ACTIONS += ('callback',) +def vararg_callback(option, opt_str, value, parser): + """Callback for an option with variable arguments. + Manually collect arguments right of a callback-action + option (ie. with action="callback"), and add the resulting + list to the destination var. + + Usage: + parser.add_option("-c", "--callback", dest="vararg_attr", + action="callback", callback=vararg_callback) + + Details: + http://docs.python.org/2/library/optparse.html#callback-example-6-variable + -arguments + """ + value = [value] + + def floatable(str): + try: + float(str) + return True + except ValueError: + return False + + for arg in parser.rargs: + # stop on --foo like options + if arg[:2] == "--" and len(arg) > 2: + break + # stop on -a, but not on -3 or -3.0 + if arg[:1] == "-" and len(arg) > 1 and not floatable(arg): + break + value.append(arg) + + del parser.rargs[:len(value) - 1] + setattr(parser.values, option.dest, value) + + + +# The main entry point and bootstrapping. + + +def _load_plugins(): + """Load the plugins specified in the configuration. + """ + # Add plugin paths. + import beetsplug + beetsplug.__path__ = get_plugin_paths() + beetsplug.__path__ + + # For backwards compatibility. + sys.path += get_plugin_paths() + + # Load requested plugins. + plugins.load_plugins(config['plugins'].as_str_seq()) + plugins.send("pluginload") + + +def _configure(args): + """Parse the command line, load configuration files (including + loading any indicated plugins), and return the invoked subcomand, + the subcommand options, and the subcommand arguments. + """ + # Temporary: Migrate from 1.0-style configuration. + from beets.ui import migrate + migrate.automigrate() + + # Get the default subcommands. + from beets.ui.commands import default_commands + + # Construct the root parser. + commands = list(default_commands) + commands.append(migrate.migrate_cmd) # Temporary. + parser = SubcommandsOptionParser(subcommands=commands) + parser.add_option('-l', '--library', dest='library', + help='library database file to use') + parser.add_option('-d', '--directory', dest='directory', + help="destination music directory") + parser.add_option('-v', '--verbose', dest='verbose', action='store_true', + help='print debugging information') + parser.add_option('-c', '--config', dest='config', + help='path to configuration file') + + # Parse the command-line! + options, args = optparse.OptionParser.parse_args(parser, args) + + # Add any additional config files specified with --config. This + # special handling lets specified plugins get loaded before we + # finish parsing the command line. + if getattr(options, 'config', None) is not None: + config_path = options.config + del options.config + config.set_file(config_path) + config.set_args(options) + + # Now add the plugin commands to the parser. + _load_plugins() + for cmd in plugins.commands(): + parser.add_subcommand(cmd) + + # Parse the remainder of the command line with loaded plugins. + return parser._parse_sub(args) + + +def _raw_main(args): + """A helper function for `main` without top-level exception + handling. + """ + subcommand, suboptions, subargs = _configure(args) + + # Open library file. + dbpath = config['library'].as_filename() + try: + lib = library.Library( + dbpath, + config['directory'].as_filename(), + get_path_formats(), + get_replacements(), + ) + except sqlite3.OperationalError: + raise UserError(u"database file {0} could not be opened".format( + util.displayable_path(dbpath) + )) + plugins.send("library_opened", lib=lib) + + # Configure the logger. + if config['verbose'].get(bool): + log.setLevel(logging.DEBUG) + else: + log.setLevel(logging.INFO) + log.debug(u'data directory: {0}\n' + u'library database: {1}\n' + u'library directory: {2}' + .format( + util.displayable_path(config.config_dir()), + util.displayable_path(lib.path), + util.displayable_path(lib.directory), + ) + ) + + # Configure the MusicBrainz API. + mb.configure() + + # Invoke the subcommand. + subcommand.func(lib, suboptions, subargs) + plugins.send('cli_exit', lib=lib) + + +def main(args=None): + """Run the main command-line interface for beets. Includes top-level + exception handlers that print friendly error messages. + """ + try: + _raw_main(args) + except UserError as exc: + message = exc.args[0] if exc.args else None + log.error(u'error: {0}'.format(message)) + sys.exit(1) + except util.HumanReadableException as exc: + exc.log(log) + sys.exit(1) + except library.FileOperationError as exc: + # These errors have reasonable human-readable descriptions, but + # we still want to log their tracebacks for debugging. + log.debug(traceback.format_exc()) + log.error(exc) + sys.exit(1) + except confit.ConfigError as exc: + log.error(u'configuration error: {0}'.format(exc)) + sys.exit(1) + except IOError as exc: + if exc.errno == errno.EPIPE: + # "Broken pipe". End silently. + pass + else: + raise + except KeyboardInterrupt: + # Silently ignore ^C except in verbose mode. + log.debug(traceback.format_exc()) diff --git a/libs/beets/ui/commands.py b/libs/beets/ui/commands.py new file mode 100644 index 00000000..e7e631a4 --- /dev/null +++ b/libs/beets/ui/commands.py @@ -0,0 +1,1415 @@ +# This file is part of beets. +# Copyright 2014, Adrian Sampson. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. + +"""This module provides the default commands for beets' command-line +interface. +""" +from __future__ import print_function + +import logging +import os +import time +import itertools +import codecs +import platform + +import beets +from beets import ui +from beets.ui import print_, input_, decargs +from beets import autotag +from beets.autotag import recommendation +from beets.autotag import hooks +from beets import plugins +from beets import importer +from beets import util +from beets.util import syspath, normpath, ancestry, displayable_path +from beets.util.functemplate import Template +from beets import library +from beets import config +from beets.util.confit import _package_path + +# Global logger. +log = logging.getLogger('beets') + +# The list of default subcommands. This is populated with Subcommand +# objects that can be fed to a SubcommandsOptionParser. +default_commands = [] + + + +# Utilities. + + +def _do_query(lib, query, album, also_items=True): + """For commands that operate on matched items, performs a query + and returns a list of matching items and a list of matching + albums. (The latter is only nonempty when album is True.) Raises + a UserError if no items match. also_items controls whether, when + fetching albums, the associated items should be fetched also. + """ + if album: + albums = list(lib.albums(query)) + items = [] + if also_items: + for al in albums: + items += al.items() + + else: + albums = [] + items = list(lib.items(query)) + + if album and not albums: + raise ui.UserError('No matching albums found.') + elif not album and not items: + raise ui.UserError('No matching items found.') + + return items, albums + + +# fields: Shows a list of available fields for queries and format strings. + +fields_cmd = ui.Subcommand('fields', + help='show fields available for queries and format strings') + +def fields_func(lib, opts, args): + def _print_rows(names): + print(" " + "\n ".join(names)) + + def _show_plugin_fields(album): + plugin_fields = [] + for plugin in plugins.find_plugins(): + if album: + fdict = plugin.album_template_fields + else: + fdict = plugin.template_fields + plugin_fields += fdict.keys() + if plugin_fields: + print("Template fields from plugins:") + _print_rows(plugin_fields) + + print("Item fields:") + _print_rows(library.ITEM_KEYS) + _show_plugin_fields(False) + + print("\nAlbum fields:") + _print_rows(library.ALBUM_KEYS) + _show_plugin_fields(True) + +fields_cmd.func = fields_func +default_commands.append(fields_cmd) + + +# import: Autotagger and importer. + +VARIOUS_ARTISTS = u'Various Artists' + +# Importer utilities and support. + +def disambig_string(info): + """Generate a string for an AlbumInfo or TrackInfo object that + provides context that helps disambiguate similar-looking albums and + tracks. + """ + disambig = [] + if info.data_source and info.data_source != 'MusicBrainz': + disambig.append(info.data_source) + + if isinstance(info, hooks.AlbumInfo): + if info.media: + if info.mediums > 1: + disambig.append(u'{0}x{1}'.format( + info.mediums, info.media + )) + else: + disambig.append(info.media) + if info.year: + disambig.append(unicode(info.year)) + if info.country: + disambig.append(info.country) + if info.label: + disambig.append(info.label) + if info.albumdisambig: + disambig.append(info.albumdisambig) + + if disambig: + return u', '.join(disambig) + +def dist_string(dist): + """Formats a distance (a float) as a colorized similarity percentage + string. + """ + out = '%.1f%%' % ((1 - dist) * 100) + if dist <= config['match']['strong_rec_thresh'].as_number(): + out = ui.colorize('green', out) + elif dist <= config['match']['medium_rec_thresh'].as_number(): + out = ui.colorize('yellow', out) + else: + out = ui.colorize('red', out) + return out + +def penalty_string(distance, limit=None): + """Returns a colorized string that indicates all the penalties + applied to a distance object. + """ + penalties = [] + for key in distance.keys(): + key = key.replace('album_', '') + key = key.replace('track_', '') + key = key.replace('_', ' ') + penalties.append(key) + if penalties: + if limit and len(penalties) > limit: + penalties = penalties[:limit] + ['...'] + return ui.colorize('yellow', '(%s)' % ', '.join(penalties)) + +def show_change(cur_artist, cur_album, match): + """Print out a representation of the changes that will be made if an + album's tags are changed according to `match`, which must be an AlbumMatch + object. + """ + def show_album(artist, album): + if artist: + album_description = u' %s - %s' % (artist, album) + elif album: + album_description = u' %s' % album + else: + album_description = u' (unknown album)' + print_(album_description) + + def format_index(track_info): + """Return a string representing the track index of the given + TrackInfo or Item object. + """ + if isinstance(track_info, hooks.TrackInfo): + index = track_info.index + medium_index = track_info.medium_index + medium = track_info.medium + mediums = match.info.mediums + else: + index = medium_index = track_info.track + medium = track_info.disc + mediums = track_info.disctotal + if config['per_disc_numbering']: + if mediums > 1: + return u'{0}-{1}'.format(medium, medium_index) + else: + return unicode(medium_index) + else: + return unicode(index) + + # Identify the album in question. + if cur_artist != match.info.artist or \ + (cur_album != match.info.album and + match.info.album != VARIOUS_ARTISTS): + artist_l, artist_r = cur_artist or '', match.info.artist + album_l, album_r = cur_album or '', match.info.album + if artist_r == VARIOUS_ARTISTS: + # Hide artists for VA releases. + artist_l, artist_r = u'', u'' + + artist_l, artist_r = ui.colordiff(artist_l, artist_r) + album_l, album_r = ui.colordiff(album_l, album_r) + + print_("Correcting tags from:") + show_album(artist_l, album_l) + print_("To:") + show_album(artist_r, album_r) + else: + print_(u"Tagging:\n {0.artist} - {0.album}".format(match.info)) + + # Data URL. + if match.info.data_url: + print_('URL:\n %s' % match.info.data_url) + + # Info line. + info = [] + # Similarity. + info.append('(Similarity: %s)' % dist_string(match.distance)) + # Penalties. + penalties = penalty_string(match.distance) + if penalties: + info.append(penalties) + # Disambiguation. + disambig = disambig_string(match.info) + if disambig: + info.append(ui.colorize('lightgray', '(%s)' % disambig)) + print_(' '.join(info)) + + # Tracks. + pairs = match.mapping.items() + pairs.sort(key=lambda (_, track_info): track_info.index) + + # Build up LHS and RHS for track difference display. The `lines` list + # contains ``(lhs, rhs, width)`` tuples where `width` is the length (in + # characters) of the uncolorized LHS. + lines = [] + medium = disctitle = None + for item, track_info in pairs: + + # Medium number and title. + if medium != track_info.medium or disctitle != track_info.disctitle: + media = match.info.media or 'Media' + if match.info.mediums > 1 and track_info.disctitle: + lhs = '%s %s: %s' % (media, track_info.medium, + track_info.disctitle) + elif match.info.mediums > 1: + lhs = '%s %s' % (media, track_info.medium) + elif track_info.disctitle: + lhs = '%s: %s' % (media, track_info.disctitle) + else: + lhs = None + if lhs: + lines.append((lhs, '', 0)) + medium, disctitle = track_info.medium, track_info.disctitle + + # Titles. + new_title = track_info.title + if not item.title.strip(): + # If there's no title, we use the filename. + cur_title = displayable_path(os.path.basename(item.path)) + lhs, rhs = cur_title, new_title + else: + cur_title = item.title.strip() + lhs, rhs = ui.colordiff(cur_title, new_title) + lhs_width = len(cur_title) + + # Track number change. + cur_track, new_track = format_index(item), format_index(track_info) + if cur_track != new_track: + if item.track in (track_info.index, track_info.medium_index): + color = 'lightgray' + else: + color = 'red' + if (cur_track + new_track).count('-') == 1: + lhs_track, rhs_track = ui.colorize(color, cur_track), \ + ui.colorize(color, new_track) + else: + color = 'red' + lhs_track, rhs_track = ui.color_diff_suffix(cur_track, + new_track) + templ = ui.colorize(color, u' (#') + u'{0}' + \ + ui.colorize(color, u')') + lhs += templ.format(lhs_track) + rhs += templ.format(rhs_track) + lhs_width += len(cur_track) + 4 + + # Length change. + if item.length and track_info.length and \ + abs(item.length - track_info.length) > \ + config['ui']['length_diff_thresh'].as_number(): + cur_length = ui.human_seconds_short(item.length) + new_length = ui.human_seconds_short(track_info.length) + lhs_length, rhs_length = ui.color_diff_suffix(cur_length, + new_length) + templ = ui.colorize('red', u' (') + u'{0}' + \ + ui.colorize('red', u')') + lhs += templ.format(lhs_length) + rhs += templ.format(rhs_length) + lhs_width += len(cur_length) + 3 + + # Penalties. + penalties = penalty_string(match.distance.tracks[track_info]) + if penalties: + rhs += ' %s' % penalties + + if lhs != rhs: + lines.append((' * %s' % lhs, rhs, lhs_width)) + elif config['import']['detail']: + lines.append((' * %s' % lhs, '', lhs_width)) + + # Print each track in two columns, or across two lines. + col_width = (ui.term_width() - len(''.join([' * ', ' -> ']))) // 2 + if lines: + max_width = max(w for _, _, w in lines) + for lhs, rhs, lhs_width in lines: + if not rhs: + print_(lhs) + elif max_width > col_width: + print_(u'%s ->\n %s' % (lhs, rhs)) + else: + pad = max_width - lhs_width + print_(u'%s%s -> %s' % (lhs, ' ' * pad, rhs)) + + # Missing and unmatched tracks. + if match.extra_tracks: + print_('Missing tracks:') + for track_info in match.extra_tracks: + line = ' ! %s (#%s)' % (track_info.title, format_index(track_info)) + if track_info.length: + line += ' (%s)' % ui.human_seconds_short(track_info.length) + print_(ui.colorize('yellow', line)) + if match.extra_items: + print_('Unmatched tracks:') + for item in match.extra_items: + line = ' ! %s (#%s)' % (item.title, format_index(item)) + if item.length: + line += ' (%s)' % ui.human_seconds_short(item.length) + print_(ui.colorize('yellow', line)) + +def show_item_change(item, match): + """Print out the change that would occur by tagging `item` with the + metadata from `match`, a TrackMatch object. + """ + cur_artist, new_artist = item.artist, match.info.artist + cur_title, new_title = item.title, match.info.title + + if cur_artist != new_artist or cur_title != new_title: + cur_artist, new_artist = ui.colordiff(cur_artist, new_artist) + cur_title, new_title = ui.colordiff(cur_title, new_title) + + print_("Correcting track tags from:") + print_(" %s - %s" % (cur_artist, cur_title)) + print_("To:") + print_(" %s - %s" % (new_artist, new_title)) + + else: + print_("Tagging track: %s - %s" % (cur_artist, cur_title)) + + # Data URL. + if match.info.data_url: + print_('URL:\n %s' % match.info.data_url) + + # Info line. + info = [] + # Similarity. + info.append('(Similarity: %s)' % dist_string(match.distance)) + # Penalties. + penalties = penalty_string(match.distance) + if penalties: + info.append(penalties) + # Disambiguation. + disambig = disambig_string(match.info) + if disambig: + info.append(ui.colorize('lightgray', '(%s)' % disambig)) + print_(' '.join(info)) + +def _summary_judment(rec): + """Determines whether a decision should be made without even asking + the user. This occurs in quiet mode and when an action is chosen for + NONE recommendations. Return an action or None if the user should be + queried. May also print to the console if a summary judgment is + made. + """ + if config['import']['quiet']: + if rec == recommendation.strong: + return importer.action.APPLY + else: + action = config['import']['quiet_fallback'].as_choice({ + 'skip': importer.action.SKIP, + 'asis': importer.action.ASIS, + }) + + elif rec == recommendation.none: + action = config['import']['none_rec_action'].as_choice({ + 'skip': importer.action.SKIP, + 'asis': importer.action.ASIS, + 'ask': None, + }) + + else: + return None + + if action == importer.action.SKIP: + print_('Skipping.') + elif action == importer.action.ASIS: + print_('Importing as-is.') + return action + +def choose_candidate(candidates, singleton, rec, cur_artist=None, + cur_album=None, item=None, itemcount=None): + """Given a sorted list of candidates, ask the user for a selection + of which candidate to use. Applies to both full albums and + singletons (tracks). Candidates are either AlbumMatch or TrackMatch + objects depending on `singleton`. for albums, `cur_artist`, + `cur_album`, and `itemcount` must be provided. For singletons, + `item` must be provided. + + Returns the result of the choice, which may SKIP, ASIS, TRACKS, or + MANUAL or a candidate (an AlbumMatch/TrackMatch object). + """ + # Sanity check. + if singleton: + assert item is not None + else: + assert cur_artist is not None + assert cur_album is not None + + # Zero candidates. + if not candidates: + if singleton: + print_("No matching recordings found.") + opts = ('Use as-is', 'Skip', 'Enter search', 'enter Id', + 'aBort') + else: + print_("No matching release found for {0} tracks." + .format(itemcount)) + print_('For help, see: ' + 'http://beets.readthedocs.org/en/latest/faq.html#nomatch') + opts = ('Use as-is', 'as Tracks', 'Group albums', 'Skip', + 'Enter search', 'enter Id', 'aBort') + sel = ui.input_options(opts) + if sel == 'u': + return importer.action.ASIS + elif sel == 't': + assert not singleton + return importer.action.TRACKS + elif sel == 'e': + return importer.action.MANUAL + elif sel == 's': + return importer.action.SKIP + elif sel == 'b': + raise importer.ImportAbort() + elif sel == 'i': + return importer.action.MANUAL_ID + elif sel == 'g': + return importer.action.ALBUMS + else: + assert False + + # Is the change good enough? + bypass_candidates = False + if rec != recommendation.none: + match = candidates[0] + bypass_candidates = True + + while True: + # Display and choose from candidates. + require = rec <= recommendation.low + + if not bypass_candidates: + # Display list of candidates. + print_(u'Finding tags for {0} "{1} - {2}".'.format( + u'track' if singleton else u'album', + item.artist if singleton else cur_artist, + item.title if singleton else cur_album, + )) + + print_(u'Candidates:') + for i, match in enumerate(candidates): + # Index, metadata, and distance. + line = [ + u'{0}.'.format(i + 1), + u'{0} - {1}'.format( + match.info.artist, + match.info.title if singleton else match.info.album, + ), + u'({0})'.format(dist_string(match.distance)), + ] + + # Penalties. + penalties = penalty_string(match.distance, 3) + if penalties: + line.append(penalties) + + # Disambiguation + disambig = disambig_string(match.info) + if disambig: + line.append(ui.colorize('lightgray', '(%s)' % disambig)) + + print_(' '.join(line)) + + # Ask the user for a choice. + if singleton: + opts = ('Skip', 'Use as-is', 'Enter search', 'enter Id', + 'aBort') + else: + opts = ('Skip', 'Use as-is', 'as Tracks', 'Group albums', + 'Enter search', 'enter Id', 'aBort') + sel = ui.input_options(opts, numrange=(1, len(candidates))) + if sel == 's': + return importer.action.SKIP + elif sel == 'u': + return importer.action.ASIS + elif sel == 'm': + pass + elif sel == 'e': + return importer.action.MANUAL + elif sel == 't': + assert not singleton + return importer.action.TRACKS + elif sel == 'b': + raise importer.ImportAbort() + elif sel == 'i': + return importer.action.MANUAL_ID + elif sel == 'g': + return importer.action.ALBUMS + else: # Numerical selection. + match = candidates[sel - 1] + if sel != 1: + # When choosing anything but the first match, + # disable the default action. + require = True + bypass_candidates = False + + # Show what we're about to do. + if singleton: + show_item_change(item, match) + else: + show_change(cur_artist, cur_album, match) + + # Exact match => tag automatically if we're not in timid mode. + if rec == recommendation.strong and not config['import']['timid']: + return match + + # Ask for confirmation. + if singleton: + opts = ('Apply', 'More candidates', 'Skip', 'Use as-is', + 'Enter search', 'enter Id', 'aBort') + else: + opts = ('Apply', 'More candidates', 'Skip', 'Use as-is', + 'as Tracks', 'Group albums', 'Enter search', 'enter Id', + 'aBort') + default = config['import']['default_action'].as_choice({ + 'apply': 'a', + 'skip': 's', + 'asis': 'u', + 'none': None, + }) + if default is None: + require = True + sel = ui.input_options(opts, require=require, default=default) + if sel == 'a': + return match + elif sel == 'g': + return importer.action.ALBUMS + elif sel == 's': + return importer.action.SKIP + elif sel == 'u': + return importer.action.ASIS + elif sel == 't': + assert not singleton + return importer.action.TRACKS + elif sel == 'e': + return importer.action.MANUAL + elif sel == 'b': + raise importer.ImportAbort() + elif sel == 'i': + return importer.action.MANUAL_ID + +def manual_search(singleton): + """Input either an artist and album (for full albums) or artist and + track name (for singletons) for manual search. + """ + artist = input_('Artist:') + name = input_('Track:' if singleton else 'Album:') + return artist.strip(), name.strip() + +def manual_id(singleton): + """Input an ID, either for an album ("release") or a track ("recording"). + """ + prompt = u'Enter {0} ID:'.format('recording' if singleton else 'release') + return input_(prompt).strip() + +class TerminalImportSession(importer.ImportSession): + """An import session that runs in a terminal. + """ + def choose_match(self, task): + """Given an initial autotagging of items, go through an interactive + dance with the user to ask for a choice of metadata. Returns an + AlbumMatch object, ASIS, or SKIP. + """ + # Show what we're tagging. + print_() + print_(displayable_path(task.paths, u'\n') + + u' ({0} items)'.format(len(task.items))) + + # Take immediate action if appropriate. + action = _summary_judment(task.rec) + if action == importer.action.APPLY: + match = task.candidates[0] + show_change(task.cur_artist, task.cur_album, match) + return match + elif action is not None: + return action + + # Loop until we have a choice. + candidates, rec = task.candidates, task.rec + while True: + # Ask for a choice from the user. + choice = choose_candidate(candidates, False, rec, task.cur_artist, + task.cur_album, itemcount=len(task.items)) + + # Choose which tags to use. + if choice in (importer.action.SKIP, importer.action.ASIS, + importer.action.TRACKS, importer.action.ALBUMS): + # Pass selection to main control flow. + return choice + elif choice is importer.action.MANUAL: + # Try again with manual search terms. + search_artist, search_album = manual_search(False) + _, _, candidates, rec = autotag.tag_album( + task.items, search_artist, search_album + ) + elif choice is importer.action.MANUAL_ID: + # Try a manually-entered ID. + search_id = manual_id(False) + if search_id: + _, _, candidates, rec = autotag.tag_album( + task.items, search_id=search_id + ) + else: + # We have a candidate! Finish tagging. Here, choice is an + # AlbumMatch object. + assert isinstance(choice, autotag.AlbumMatch) + return choice + + def choose_item(self, task): + """Ask the user for a choice about tagging a single item. Returns + either an action constant or a TrackMatch object. + """ + print_() + print_(task.item.path) + candidates, rec = task.candidates, task.rec + + # Take immediate action if appropriate. + action = _summary_judment(task.rec) + if action == importer.action.APPLY: + match = candidates[0] + show_item_change(task.item, match) + return match + elif action is not None: + return action + + while True: + # Ask for a choice. + choice = choose_candidate(candidates, True, rec, item=task.item) + + if choice in (importer.action.SKIP, importer.action.ASIS): + return choice + elif choice == importer.action.TRACKS: + assert False # TRACKS is only legal for albums. + elif choice == importer.action.MANUAL: + # Continue in the loop with a new set of candidates. + search_artist, search_title = manual_search(True) + candidates, rec = autotag.tag_item(task.item, search_artist, + search_title) + elif choice == importer.action.MANUAL_ID: + # Ask for a track ID. + search_id = manual_id(True) + if search_id: + candidates, rec = autotag.tag_item(task.item, + search_id=search_id) + else: + # Chose a candidate. + assert isinstance(choice, autotag.TrackMatch) + return choice + + def resolve_duplicate(self, task): + """Decide what to do when a new album or item seems similar to one + that's already in the library. + """ + log.warn("This %s is already in the library!" % + ("album" if task.is_album else "item")) + + if config['import']['quiet']: + # In quiet mode, don't prompt -- just skip. + log.info('Skipping.') + sel = 's' + else: + sel = ui.input_options( + ('Skip new', 'Keep both', 'Remove old') + ) + + if sel == 's': + # Skip new. + task.set_choice(importer.action.SKIP) + elif sel == 'k': + # Keep both. Do nothing; leave the choice intact. + pass + elif sel == 'r': + # Remove old. + task.remove_duplicates = True + else: + assert False + + def should_resume(self, path): + return ui.input_yn(u"Import of the directory:\n{0}\n" + "was interrupted. Resume (Y/n)?" + .format(displayable_path(path))) + +# The import command. + +def import_files(lib, paths, query): + """Import the files in the given list of paths or matching the + query. + """ + # Check the user-specified directories. + for path in paths: + fullpath = syspath(normpath(path)) + if not config['import']['singletons'] and not os.path.isdir(fullpath): + raise ui.UserError(u'not a directory: {0}'.format( + displayable_path(path))) + elif config['import']['singletons'] and not os.path.exists(fullpath): + raise ui.UserError(u'no such file: {0}'.format( + displayable_path(path))) + + # Check parameter consistency. + if config['import']['quiet'] and config['import']['timid']: + raise ui.UserError("can't be both quiet and timid") + + # Open the log. + if config['import']['log'].get() is not None: + logpath = config['import']['log'].as_filename() + try: + logfile = codecs.open(syspath(logpath), 'a', 'utf8') + except IOError: + raise ui.UserError(u"could not open log file for writing: %s" % + displayable_path(logpath)) + print(u'import started', time.asctime(), file=logfile) + else: + logfile = None + + # Never ask for input in quiet mode. + if config['import']['resume'].get() == 'ask' and \ + config['import']['quiet']: + config['import']['resume'] = False + + session = TerminalImportSession(lib, logfile, paths, query) + try: + session.run() + finally: + # If we were logging, close the file. + if logfile: + print(u'', file=logfile) + logfile.close() + + # Emit event. + plugins.send('import', lib=lib, paths=paths) + +import_cmd = ui.Subcommand('import', help='import new music', + aliases=('imp', 'im')) +import_cmd.parser.add_option('-c', '--copy', action='store_true', + default=None, help="copy tracks into library directory (default)") +import_cmd.parser.add_option('-C', '--nocopy', action='store_false', + dest='copy', help="don't copy tracks (opposite of -c)") +import_cmd.parser.add_option('-w', '--write', action='store_true', + default=None, help="write new metadata to files' tags (default)") +import_cmd.parser.add_option('-W', '--nowrite', action='store_false', + dest='write', help="don't write metadata (opposite of -w)") +import_cmd.parser.add_option('-a', '--autotag', action='store_true', + dest='autotag', help="infer tags for imported files (default)") +import_cmd.parser.add_option('-A', '--noautotag', action='store_false', + dest='autotag', + help="don't infer tags for imported files (opposite of -a)") +import_cmd.parser.add_option('-p', '--resume', action='store_true', + default=None, help="resume importing if interrupted") +import_cmd.parser.add_option('-P', '--noresume', action='store_false', + dest='resume', help="do not try to resume importing") +import_cmd.parser.add_option('-q', '--quiet', action='store_true', + dest='quiet', help="never prompt for input: skip albums instead") +import_cmd.parser.add_option('-l', '--log', dest='log', + help='file to log untaggable albums for later review') +import_cmd.parser.add_option('-s', '--singletons', action='store_true', + help='import individual tracks instead of full albums') +import_cmd.parser.add_option('-t', '--timid', dest='timid', + action='store_true', help='always confirm all actions') +import_cmd.parser.add_option('-L', '--library', dest='library', + action='store_true', help='retag items matching a query') +import_cmd.parser.add_option('-i', '--incremental', dest='incremental', + action='store_true', help='skip already-imported directories') +import_cmd.parser.add_option('-I', '--noincremental', dest='incremental', + action='store_false', help='do not skip already-imported directories') +import_cmd.parser.add_option('--flat', dest='flat', + action='store_true', help='import an entire tree as a single album') +import_cmd.parser.add_option('-g', '--group-albums', dest='group_albums', + action='store_true', help='group tracks in a folder into seperate albums') +def import_func(lib, opts, args): + config['import'].set_args(opts) + + # Special case: --copy flag suppresses import_move (which would + # otherwise take precedence). + if opts.copy: + config['import']['move'] = False + + if opts.library: + query = decargs(args) + paths = [] + else: + query = None + paths = args + if not paths: + raise ui.UserError('no path specified') + + import_files(lib, paths, query) +import_cmd.func = import_func +default_commands.append(import_cmd) + + +# list: Query and show library contents. + +def list_items(lib, query, album, fmt): + """Print out items in lib matching query. If album, then search for + albums instead of single items. + """ + tmpl = Template(ui._pick_format(album, fmt)) + if album: + for album in lib.albums(query): + ui.print_obj(album, lib, tmpl) + else: + for item in lib.items(query): + ui.print_obj(item, lib, tmpl) + +list_cmd = ui.Subcommand('list', help='query the library', aliases=('ls',)) +list_cmd.parser.add_option('-a', '--album', action='store_true', + help='show matching albums instead of tracks') +list_cmd.parser.add_option('-p', '--path', action='store_true', + help='print paths for matched items or albums') +list_cmd.parser.add_option('-f', '--format', action='store', + help='print with custom format', default=None) +def list_func(lib, opts, args): + if opts.path: + fmt = '$path' + else: + fmt = opts.format + list_items(lib, decargs(args), opts.album, fmt) +list_cmd.func = list_func +default_commands.append(list_cmd) + + +# update: Update library contents according to on-disk tags. + +def update_items(lib, query, album, move, pretend): + """For all the items matched by the query, update the library to + reflect the item's embedded tags. + """ + with lib.transaction(): + items, _ = _do_query(lib, query, album) + + # Walk through the items and pick up their changes. + affected_albums = set() + for item in items: + # Item deleted? + if not os.path.exists(syspath(item.path)): + ui.print_obj(item, lib) + ui.print_(ui.colorize('red', u' deleted')) + if not pretend: + item.remove(True) + affected_albums.add(item.album_id) + continue + + # Did the item change since last checked? + if item.current_mtime() <= item.mtime: + log.debug(u'skipping %s because mtime is up to date (%i)' % + (displayable_path(item.path), item.mtime)) + continue + + # Read new data. + try: + item.read() + except Exception as exc: + log.error(u'error reading {0}: {1}'.format( + displayable_path(item.path), exc)) + continue + + # Special-case album artist when it matches track artist. (Hacky + # but necessary for preserving album-level metadata for non- + # autotagged imports.) + if not item.albumartist: + old_item = lib.get_item(item.id) + if old_item.albumartist == old_item.artist == item.artist: + item.albumartist = old_item.albumartist + item._dirty.discard('albumartist') + + # Check for and display changes. + changed = ui.show_model_changes(item, + fields=library.ITEM_KEYS_META) + + # Save changes. + if not pretend: + if changed: + # Move the item if it's in the library. + if move and lib.directory in ancestry(item.path): + item.move() + + item.store() + affected_albums.add(item.album_id) + else: + # The file's mtime was different, but there were no + # changes to the metadata. Store the new mtime, + # which is set in the call to read(), so we don't + # check this again in the future. + item.store() + + # Skip album changes while pretending. + if pretend: + return + + # Modify affected albums to reflect changes in their items. + for album_id in affected_albums: + if album_id is None: # Singletons. + continue + album = lib.get_album(album_id) + if not album: # Empty albums have already been removed. + log.debug('emptied album %i' % album_id) + continue + first_item = album.items().get() + + # Update album structure to reflect an item in it. + for key in library.ALBUM_KEYS_ITEM: + album[key] = first_item[key] + album.store() + + # Move album art (and any inconsistent items). + if move and lib.directory in ancestry(first_item.path): + log.debug('moving album %i' % album_id) + album.move() + +update_cmd = ui.Subcommand('update', + help='update the library', aliases=('upd','up',)) +update_cmd.parser.add_option('-a', '--album', action='store_true', + help='match albums instead of tracks') +update_cmd.parser.add_option('-M', '--nomove', action='store_false', + default=True, dest='move', help="don't move files in library") +update_cmd.parser.add_option('-p', '--pretend', action='store_true', + help="show all changes but do nothing") +update_cmd.parser.add_option('-f', '--format', action='store', + help='print with custom format', default=None) +def update_func(lib, opts, args): + update_items(lib, decargs(args), opts.album, opts.move, opts.pretend) +update_cmd.func = update_func +default_commands.append(update_cmd) + + +# remove: Remove items from library, delete files. + +def remove_items(lib, query, album, delete): + """Remove items matching query from lib. If album, then match and + remove whole albums. If delete, also remove files from disk. + """ + # Get the matching items. + items, albums = _do_query(lib, query, album) + + # Show all the items. + for item in items: + ui.print_obj(item, lib) + + # Confirm with user. + print_() + if delete: + prompt = 'Really DELETE %i files (y/n)?' % len(items) + else: + prompt = 'Really remove %i items from the library (y/n)?' % \ + len(items) + if not ui.input_yn(prompt, True): + return + + # Remove (and possibly delete) items. + with lib.transaction(): + for obj in (albums if album else items): + obj.remove(delete) + +remove_cmd = ui.Subcommand('remove', + help='remove matching items from the library', aliases=('rm',)) +remove_cmd.parser.add_option("-d", "--delete", action="store_true", + help="also remove files from disk") +remove_cmd.parser.add_option('-a', '--album', action='store_true', + help='match albums instead of tracks') +def remove_func(lib, opts, args): + remove_items(lib, decargs(args), opts.album, opts.delete) +remove_cmd.func = remove_func +default_commands.append(remove_cmd) + + +# stats: Show library/query statistics. + +def show_stats(lib, query, exact): + """Shows some statistics about the matched items.""" + items = lib.items(query) + + total_size = 0 + total_time = 0.0 + total_items = 0 + artists = set() + albums = set() + + for item in items: + if exact: + total_size += os.path.getsize(item.path) + else: + total_size += int(item.length * item.bitrate / 8) + total_time += item.length + total_items += 1 + artists.add(item.artist) + albums.add(item.album) + + size_str = '' + ui.human_bytes(total_size) + if exact: + size_str += ' ({0} bytes)'.format(total_size) + + print_("""Tracks: {0} +Total time: {1} ({2:.2f} seconds) +Total size: {3} +Artists: {4} +Albums: {5}""".format(total_items, ui.human_seconds(total_time), total_time, + size_str, len(artists), len(albums))) + +stats_cmd = ui.Subcommand('stats', + help='show statistics about the library or a query') +stats_cmd.parser.add_option('-e', '--exact', action='store_true', + help='get exact file sizes') +def stats_func(lib, opts, args): + show_stats(lib, decargs(args), opts.exact) +stats_cmd.func = stats_func +default_commands.append(stats_cmd) + + +# version: Show current beets version. + +def show_version(lib, opts, args): + print_('beets version %s' % beets.__version__) + # Show plugins. + names = [p.name for p in plugins.find_plugins()] + if names: + print_('plugins:', ', '.join(names)) + else: + print_('no plugins loaded') +version_cmd = ui.Subcommand('version', + help='output version information') +version_cmd.func = show_version +default_commands.append(version_cmd) + + +# modify: Declaratively change metadata. + +def modify_items(lib, mods, dels, query, write, move, album, confirm): + """Modifies matching items according to key=value assignments.""" + # Parse key=value specifications into a dictionary. + model_cls = library.Album if album else library.Item + fsets = {} + for mod in mods: + key, value = mod.split('=', 1) + fsets[key] = model_cls._parse(key, value) + + # Get the items to modify. + items, albums = _do_query(lib, query, album, False) + objs = albums if album else items + + # Apply changes *temporarily*, preview them, and collect modified + # objects. + print_('Modifying %i %ss.' % (len(objs), 'album' if album else 'item')) + changed = set() + for obj in objs: + for field, value in fsets.iteritems(): + obj[field] = value + for field in dels: + del obj[field] + if ui.show_model_changes(obj): + changed.add(obj) + + # Still something to do? + if not changed: + print_('No changes to make.') + return + + # Confirm action. + if confirm: + extra = ' and write tags' if write else '' + if not ui.input_yn('Really modify%s (Y/n)?' % extra): + return + + # Apply changes to database. + with lib.transaction(): + for obj in changed: + if move: + cur_path = obj.path + if lib.directory in ancestry(cur_path): # In library? + log.debug('moving object %s' % cur_path) + obj.move() + + obj.store() + + # Apply tags if requested. + if write: + if album: + changed_items = itertools.chain(*(a.items() for a in changed)) + else: + changed_items = changed + for item in changed_items: + try: + item.write() + except library.FileOperationError as exc: + log.error(exc) + +modify_cmd = ui.Subcommand('modify', + help='change metadata fields', aliases=('mod',)) +modify_cmd.parser.add_option('-M', '--nomove', action='store_false', + default=True, dest='move', help="don't move files in library") +modify_cmd.parser.add_option('-w', '--write', action='store_true', + default=None, help="write new metadata to files' tags (default)") +modify_cmd.parser.add_option('-W', '--nowrite', action='store_false', + dest='write', help="don't write metadata (opposite of -w)") +modify_cmd.parser.add_option('-a', '--album', action='store_true', + help='modify whole albums instead of tracks') +modify_cmd.parser.add_option('-y', '--yes', action='store_true', + help='skip confirmation') +modify_cmd.parser.add_option('-f', '--format', action='store', + help='print with custom format', default=None) +def modify_func(lib, opts, args): + args = decargs(args) + mods = [] + dels = [] + query = [] + for arg in args: + if arg.endswith('!') and '=' not in arg and ':' not in arg: + dels.append(arg[:-1]) + elif '=' in arg: + mods.append(arg) + else: + query.append(arg) + if not mods and not dels: + raise ui.UserError('no modifications specified') + write = opts.write if opts.write is not None else \ + config['import']['write'].get(bool) + modify_items(lib, mods, dels, query, write, opts.move, opts.album, + not opts.yes) +modify_cmd.func = modify_func +default_commands.append(modify_cmd) + + +# move: Move/copy files to the library or a new base directory. + +def move_items(lib, dest, query, copy, album): + """Moves or copies items to a new base directory, given by dest. If + dest is None, then the library's base directory is used, making the + command "consolidate" files. + """ + items, albums = _do_query(lib, query, album, False) + objs = albums if album else items + + action = 'Copying' if copy else 'Moving' + entity = 'album' if album else 'item' + log.info('%s %i %ss.' % (action, len(objs), entity)) + for obj in objs: + log.debug('moving: %s' % obj.path) + + obj.move(copy, basedir=dest) + obj.store() + +move_cmd = ui.Subcommand('move', + help='move or copy items', aliases=('mv',)) +move_cmd.parser.add_option('-d', '--dest', metavar='DIR', dest='dest', + help='destination directory') +move_cmd.parser.add_option('-c', '--copy', default=False, action='store_true', + help='copy instead of moving') +move_cmd.parser.add_option('-a', '--album', default=False, action='store_true', + help='match whole albums instead of tracks') +def move_func(lib, opts, args): + dest = opts.dest + if dest is not None: + dest = normpath(dest) + if not os.path.isdir(dest): + raise ui.UserError('no such directory: %s' % dest) + + move_items(lib, dest, decargs(args), opts.copy, opts.album) +move_cmd.func = move_func +default_commands.append(move_cmd) + + +# write: Write tags into files. + +def write_items(lib, query, pretend): + """Write tag information from the database to the respective files + in the filesystem. + """ + items, albums = _do_query(lib, query, False, False) + + for item in items: + # Item deleted? + if not os.path.exists(syspath(item.path)): + log.info(u'missing file: {0}'.format( + util.displayable_path(item.path) + )) + continue + + # Get an Item object reflecting the "clean" (on-disk) state. + try: + clean_item = library.Item.from_path(item.path) + except Exception as exc: + log.error(u'error reading {0}: {1}'.format( + displayable_path(item.path), exc + )) + continue + + # Check for and display changes. + changed = ui.show_model_changes(item, clean_item, + library.ITEM_KEYS_WRITABLE, always=True) + if changed and not pretend: + try: + item.write() + except library.FileOperationError as exc: + log.error(exc) + +write_cmd = ui.Subcommand('write', help='write tag information to files') +write_cmd.parser.add_option('-p', '--pretend', action='store_true', + help="show all changes but do nothing") +def write_func(lib, opts, args): + write_items(lib, decargs(args), opts.pretend) +write_cmd.func = write_func +default_commands.append(write_cmd) + + +# config: Show and edit user configuration. + +config_cmd = ui.Subcommand('config', + help='show or edit the user configuration') +config_cmd.parser.add_option('-p', '--paths', action='store_true', + help='show files that configuration was loaded from') +config_cmd.parser.add_option('-e', '--edit', action='store_true', + help='edit user configuration with $EDITOR') +config_cmd.parser.add_option('-d', '--defaults', action='store_true', + help='include the default configuration') +def config_func(lib, opts, args): + # Make sure lazy configuration is loaded + config.resolve() + + # Print paths. + if opts.paths: + filenames = [] + for source in config.sources: + if not opts.defaults and source.default: + continue + if source.filename: + filenames.append(source.filename) + + # In case the user config file does not exist, prepend it to the + # list. + user_path = config.user_config_path() + if user_path not in filenames: + filenames.insert(0, user_path) + + for filename in filenames: + print(filename) + + # Open in editor. + elif opts.edit: + path = config.user_config_path() + + if 'EDITOR' in os.environ: + editor = os.environ['EDITOR'] + args = [editor, editor, path] + elif platform.system() == 'Darwin': + args = ['open', 'open', '-n', path] + elif platform.system() == 'Windows': + # On windows we can execute arbitrary files. The os will + # take care of starting an appropriate application + args = [path, path] + else: + # Assume Unix + args = ['xdg-open', 'xdg-open', path] + + try: + os.execlp(*args) + except OSError: + raise ui.UserError("Could not edit configuration. Please" + "set the EDITOR environment variable.") + + # Dump configuration. + else: + print(config.dump(full=opts.defaults)) + +config_cmd.func = config_func +default_commands.append(config_cmd) + + +# completion: print completion script + +completion_cmd = ui.Subcommand('completion', + help='print shell script that provides command line completion') +def print_completion(*args): + for line in completion_script(default_commands + plugins.commands()): + print(line, end='') + if not (os.path.isfile(u'/etc/bash_completion') or + os.path.isfile(u'/usr/share/bash-completion/bash_completion') or + os.path.isfile(u'/usr/share/local/bash-completion/bash_completion')): + log.warn(u'Warning: Unable to find the bash-completion package. ' + u'Command line completion might not work.') + +def completion_script(commands): + """Yield the full completion shell script as strings. + + ``commands`` is alist of ``ui.Subcommand`` instances to generate + completion data for. + """ + base_script = os.path.join(_package_path('beets.ui'), 'completion_base.sh') + with open(base_script, 'r') as base_script: + yield base_script.read() + + options = {} + aliases = {} + command_names = [] + + # Collect subcommands + for cmd in commands: + name = cmd.name + command_names.append(name) + + for alias in cmd.aliases: + aliases[alias] = name + + options[name] = {'flags': [], 'opts': []} + for opts in cmd.parser._get_all_options()[1:]: + if opts.action in ('store_true', 'store_false'): + option_type = 'flags' + else: + option_type = 'opts' + + options[name][option_type].extend( + opts._short_opts + opts._long_opts + ) + + # Add global options + options['_global'] = { + 'flags': ['-v', '--verbose'], + 'opts': '-l --library -c --config -d --directory -h --help'.split(' ') + } + + # Help subcommand + command_names.append('help') + + # Add flags common to all commands + options['_common'] = { + 'flags': ['-h', '--help'] + } + + # Start generating the script + yield "_beet() {\n" + + # Command names + yield " local commands='%s'\n" % ' '.join(command_names) + yield "\n" + + # Command aliases + yield " local aliases='%s'\n" % ' '.join(aliases.keys()) + for alias, cmd in aliases.items(): + yield " local alias__%s=%s\n" % (alias, cmd) + yield '\n' + + # Fields + yield " fields='%s'\n" % ' '.join( + set(library.ITEM_KEYS + library.ALBUM_KEYS)) + + # Command options + for cmd, opts in options.items(): + for option_type, option_list in opts.items(): + if option_list: + option_list = ' '.join(option_list) + yield " local %s__%s='%s'\n" % (option_type, cmd, option_list) + + yield ' _beet_dispatch\n' + yield '}\n' + + +completion_cmd.func = print_completion +completion_cmd.hide = True +default_commands.append(completion_cmd) diff --git a/libs/beets/ui/completion_base.sh b/libs/beets/ui/completion_base.sh new file mode 100644 index 00000000..ce3fb6e2 --- /dev/null +++ b/libs/beets/ui/completion_base.sh @@ -0,0 +1,162 @@ +# This file is part of beets. +# Copyright (c) 2014, Thomas Scholtes. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. + + + +# Completion for the `beet` command +# ================================= +# +# Load this script to complete beets subcommands, options, and +# queries. +# +# If a beets command is found on the command line it completes filenames and +# the subcommand's options. Otherwise it will complete global options and +# subcommands. If the previous option on the command line expects an argument, +# it also completes filenames or directories. Options are only +# completed if '-' has already been typed on the command line. +# +# Note that completion of plugin commands only works for those plugins +# that were enabled when running `beet completion`. It does not check +# plugins dynamically +# +# Currently, only Bash 3.2 and newer is supported and the +# `bash-completion` package is requied. +# +# TODO +# ---- +# +# * There are some issues with arguments that are quoted on the command line. +# +# * Complete arguments for the `--format` option by expanding field variables. +# +# beet ls -f "$tit[TAB] +# beet ls -f "$title +# +# * Support long options with `=`, e.g. `--config=file`. Debian's bash +# completion package can handle this. +# + + +# Determines the beets subcommand and dispatches the completion +# accordingly. +_beet_dispatch() { + local cur prev cmd= + + COMPREPLY=() + _get_comp_words_by_ref -n : cur prev + + # Look for the beets subcommand + local arg + for (( i=1; i < COMP_CWORD; i++ )); do + arg="${COMP_WORDS[i]}" + if _list_include_item "${opts___global}" $arg; then + ((i++)) + elif [[ "$arg" != -* ]]; then + cmd="$arg" + break + fi + done + + # Replace command shortcuts + if [[ -n $cmd ]] && _list_include_item "$aliases" "$cmd"; then + eval "cmd=\$alias__$cmd" + fi + + case $cmd in + help) + COMPREPLY+=( $(compgen -W "$commands" -- $cur) ) + ;; + list|remove|move|update|write|stats) + _beet_complete_query + ;; + "") + _beet_complete_global + ;; + *) + _beet_complete + ;; + esac +} + + +# Adds option and file completion to COMPREPLY for the subcommand $cmd +_beet_complete() { + if [[ $cur == -* ]]; then + local opts flags completions + eval "opts=\$opts__$cmd" + eval "flags=\$flags__$cmd" + completions="${flags___common} ${opts} ${flags}" + COMPREPLY+=( $(compgen -W "$completions" -- $cur) ) + else + _filedir + fi +} + + +# Add global options and subcommands to the completion +_beet_complete_global() { + case $prev in + -h|--help) + # Complete commands + COMPREPLY+=( $(compgen -W "$commands" -- $cur) ) + return + ;; + -l|--library|-c|--config) + # Filename completion + _filedir + return + ;; + -d|--directory) + # Directory completion + _filedir -d + return + ;; + esac + + if [[ $cur == -* ]]; then + local completions="$opts___global $flags___global" + COMPREPLY+=( $(compgen -W "$completions" -- $cur) ) + elif [[ -n $cur ]] && _list_include_item "$aliases" "$cur"; then + local cmd + eval "cmd=\$alias__$cur" + COMPREPLY+=( "$cmd" ) + else + COMPREPLY+=( $(compgen -W "$commands" -- $cur) ) + fi +} + +_beet_complete_query() { + local opts + eval "opts=\$opts__$cmd" + + if [[ $cur == -* ]] || _list_include_item "$opts" "$prev"; then + _beet_complete + elif [[ $cur != \'* && $cur != \"* && + $cur != *:* ]]; then + # Do not complete quoted queries or those who already have a field + # set. + compopt -o nospace + COMPREPLY+=( $(compgen -S : -W "$fields" -- $cur) ) + return 0 + fi +} + +# Returns true if the space separated list $1 includes $2 +_list_include_item() { + [[ " $1 " == *[[:space:]]$2[[:space:]]* ]] +} + +# This is where beets dynamically adds the _beet function. This +# function sets the variables $flags, $opts, $commands, and $aliases. +complete -o filenames -F _beet beet diff --git a/libs/beets/ui/migrate.py b/libs/beets/ui/migrate.py new file mode 100644 index 00000000..784d7c82 --- /dev/null +++ b/libs/beets/ui/migrate.py @@ -0,0 +1,401 @@ +# This file is part of beets. +# Copyright 2013, Adrian Sampson. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. + +"""Conversion from legacy (pre-1.1) configuration to Confit/YAML +configuration. +""" +import os +import ConfigParser +import codecs +import yaml +import logging +import time +import itertools +import re + +import beets +from beets import util +from beets import ui +from beets.util import confit + +CONFIG_PATH_VAR = 'BEETSCONFIG' +DEFAULT_CONFIG_FILENAME_UNIX = '.beetsconfig' +DEFAULT_CONFIG_FILENAME_WINDOWS = 'beetsconfig.ini' +DEFAULT_LIBRARY_FILENAME_UNIX = '.beetsmusic.blb' +DEFAULT_LIBRARY_FILENAME_WINDOWS = 'beetsmusic.blb' +WINDOWS_BASEDIR = os.environ.get('APPDATA') or '~' + +OLD_CONFIG_SUFFIX = '.old' +PLUGIN_NAMES = { + 'rdm': 'random', + 'fuzzy_search': 'fuzzy', +} +AUTO_KEYS = ('automatic', 'autofetch', 'autoembed', 'autoscrub') +IMPORTFEEDS_PREFIX = 'feeds_' +CONFIG_MIGRATED_MESSAGE = u""" +You appear to be upgrading from beets 1.0 (or earlier) to 1.1. Your +configuration file has been migrated automatically to: +{newconfig} +Edit this file to configure beets. You might want to remove your +old-style ".beetsconfig" file now. See the documentation for more +details on the new configuration system: +http://beets.readthedocs.org/page/reference/config.html +""".strip() +DB_MIGRATED_MESSAGE = u'Your database file has also been copied to:\n{newdb}' +YAML_COMMENT = '# Automatically migrated from legacy .beetsconfig.\n\n' + +log = logging.getLogger('beets') + +# An itertools recipe. +def grouper(n, iterable): + args = [iter(iterable)] * n + return itertools.izip_longest(*args) + +def _displace(fn): + """Move a file aside using a timestamp suffix so a new file can be + put in its place. + """ + util.move( + fn, + u'{0}.old.{1}'.format(fn, int(time.time())), + True + ) + +def default_paths(): + """Produces the appropriate default config and library database + paths for the current system. On Unix, this is always in ~. On + Windows, tries ~ first and then $APPDATA for the config and library + files (for backwards compatibility). + """ + windows = os.path.__name__ == 'ntpath' + if windows: + windata = os.environ.get('APPDATA') or '~' + + # Shorthand for joining paths. + def exp(*vals): + return os.path.expanduser(os.path.join(*vals)) + + config = exp('~', DEFAULT_CONFIG_FILENAME_UNIX) + if windows and not os.path.exists(config): + config = exp(windata, DEFAULT_CONFIG_FILENAME_WINDOWS) + + libpath = exp('~', DEFAULT_LIBRARY_FILENAME_UNIX) + if windows and not os.path.exists(libpath): + libpath = exp(windata, DEFAULT_LIBRARY_FILENAME_WINDOWS) + + return config, libpath + +def get_config(): + """Using the same logic as beets 1.0, locate and read the + .beetsconfig file. Return a ConfigParser instance or None if no + config is found. + """ + default_config, default_libpath = default_paths() + if CONFIG_PATH_VAR in os.environ: + configpath = os.path.expanduser(os.environ[CONFIG_PATH_VAR]) + else: + configpath = default_config + + config = ConfigParser.SafeConfigParser() + if os.path.exists(util.syspath(configpath)): + with codecs.open(configpath, 'r', encoding='utf-8') as f: + config.readfp(f) + return config, configpath + else: + return None, configpath + +def flatten_config(config): + """Given a ConfigParser, flatten the values into a dict-of-dicts + representation where each section gets its own dictionary of values. + """ + out = confit.OrderedDict() + for section in config.sections(): + sec_dict = out[section] = confit.OrderedDict() + for option in config.options(section): + sec_dict[option] = config.get(section, option, True) + return out + +def transform_value(value): + """Given a string read as the value of a config option, return a + massaged version of that value (possibly with a different type). + """ + # Booleans. + if value.lower() in ('false', 'no', 'off'): + return False + elif value.lower() in ('true', 'yes', 'on'): + return True + + # Integers. + try: + return int(value) + except ValueError: + pass + + # Floats. + try: + return float(value) + except ValueError: + pass + + return value + +def transform_data(data): + """Given a dict-of-dicts representation of legacy config data, tweak + the data into a new form. This new form is suitable for dumping as + YAML. + """ + out = confit.OrderedDict() + + for section, pairs in data.items(): + if section == 'beets': + # The "main" section. In the new config system, these values + # are in the "root": no section at all. + for key, value in pairs.items(): + value = transform_value(value) + + if key.startswith('import_'): + # Importer config is now under an "import:" key. + if 'import' not in out: + out['import'] = confit.OrderedDict() + out['import'][key[7:]] = value + + elif key == 'plugins': + # Renamed plugins. + plugins = value.split() + new_plugins = [PLUGIN_NAMES.get(p, p) for p in plugins] + out['plugins'] = ' '.join(new_plugins) + + elif key == 'replace': + # YAMLy representation for character replacements. + replacements = confit.OrderedDict() + for pat, repl in grouper(2, value.split()): + if repl == '': + repl = '' + replacements[pat] = repl + out['replace'] = replacements + + elif key == 'pluginpath': + # Used to be a colon-separated string. Now a list. + out['pluginpath'] = value.split(':') + + else: + out[key] = value + + elif pairs: + # Other sections (plugins, etc). + sec_out = out[section] = confit.OrderedDict() + for key, value in pairs.items(): + + # Standardized "auto" option. + if key in AUTO_KEYS: + key = 'auto' + + # Unnecessary : hack in queries. + if section == 'paths': + key = key.replace('_', ':') + + # Changed option names for importfeeds plugin. + if section == 'importfeeds': + if key.startswith(IMPORTFEEDS_PREFIX): + key = key[len(IMPORTFEEDS_PREFIX):] + + sec_out[key] = transform_value(value) + + return out + +class Dumper(yaml.SafeDumper): + """A PyYAML Dumper that represents OrderedDicts as ordinary mappings + (in order, of course). + """ + # From http://pyyaml.org/attachment/ticket/161/use_ordered_dict.py + def represent_mapping(self, tag, mapping, flow_style=None): + value = [] + node = yaml.MappingNode(tag, value, flow_style=flow_style) + if self.alias_key is not None: + self.represented_objects[self.alias_key] = node + best_style = True + if hasattr(mapping, 'items'): + mapping = list(mapping.items()) + for item_key, item_value in mapping: + node_key = self.represent_data(item_key) + node_value = self.represent_data(item_value) + if not (isinstance(node_key, yaml.ScalarNode) and \ + not node_key.style): + best_style = False + if not (isinstance(node_value, yaml.ScalarNode) and \ + not node_value.style): + best_style = False + value.append((node_key, node_value)) + if flow_style is None: + if self.default_flow_style is not None: + node.flow_style = self.default_flow_style + else: + node.flow_style = best_style + return node +Dumper.add_representer(confit.OrderedDict, Dumper.represent_dict) + +def migrate_config(replace=False): + """Migrate a legacy beetsconfig file to a new-style config.yaml file + in an appropriate place. If `replace` is enabled, then any existing + config.yaml will be moved aside. Otherwise, the process is aborted + when the file exists. + """ + + # Load legacy configuration data, if any. + config, configpath = get_config() + if not config: + log.debug(u'no config file found at {0}'.format( + util.displayable_path(configpath) + )) + return + + # Get the new configuration file path and possibly move it out of + # the way. + destfn = os.path.join(beets.config.config_dir(), confit.CONFIG_FILENAME) + if os.path.exists(destfn): + if replace: + log.debug(u'moving old config aside: {0}'.format( + util.displayable_path(destfn) + )) + _displace(destfn) + else: + # File exists and we won't replace it. We're done. + return + + log.debug(u'migrating config file {0}'.format( + util.displayable_path(configpath) + )) + + # Convert the configuration to a data structure ready to be dumped + # as the new Confit file. + data = transform_data(flatten_config(config)) + + # Encode result as YAML. + yaml_out = yaml.dump( + data, + Dumper=Dumper, + default_flow_style=False, + indent=4, + width=1000, + ) + # A ridiculous little hack to add some whitespace between "sections" + # in the YAML output. I hope this doesn't break any YAML syntax. + yaml_out = re.sub(r'(\n\w+:\n [^-\s])', '\n\\1', yaml_out) + yaml_out = YAML_COMMENT + yaml_out + + # Write the data to the new config destination. + log.debug(u'writing migrated config to {0}'.format( + util.displayable_path(destfn) + )) + with open(destfn, 'w') as f: + f.write(yaml_out) + return destfn + +def migrate_db(replace=False): + """Copy the beets library database file to the new location (e.g., + from ~/.beetsmusic.blb to ~/.config/beets/library.db). + """ + _, srcfn = default_paths() + destfn = beets.config['library'].as_filename() + + if not os.path.exists(srcfn) or srcfn == destfn: + # Old DB does not exist or we're configured to point to the same + # database. Do nothing. + return + + if os.path.exists(destfn): + if replace: + log.debug(u'moving old database aside: {0}'.format( + util.displayable_path(destfn) + )) + _displace(destfn) + else: + return + + log.debug(u'copying database from {0} to {1}'.format( + util.displayable_path(srcfn), util.displayable_path(destfn) + )) + util.copy(srcfn, destfn) + return destfn + +def migrate_state(replace=False): + """Copy the beets runtime state file from the old path (i.e., + ~/.beetsstate) to the new path (i.e., ~/.config/beets/state.pickle). + """ + srcfn = os.path.expanduser(os.path.join('~', '.beetsstate')) + if not os.path.exists(srcfn): + return + + destfn = beets.config['statefile'].as_filename() + if os.path.exists(destfn): + if replace: + _displace(destfn) + else: + return + + log.debug(u'copying state file from {0} to {1}'.format( + util.displayable_path(srcfn), util.displayable_path(destfn) + )) + util.copy(srcfn, destfn) + return destfn + + +# Automatic migration when beets starts. + +def automigrate(): + """Migrate the configuration, database, and state files. If any + migration occurs, print out a notice with some helpful next steps. + """ + config_fn = migrate_config() + db_fn = migrate_db() + migrate_state() + + if config_fn: + ui.print_(ui.colorize('fuchsia', u'MIGRATED CONFIGURATION')) + + ui.print_(CONFIG_MIGRATED_MESSAGE.format( + newconfig=util.displayable_path(config_fn)) + ) + if db_fn: + ui.print_(DB_MIGRATED_MESSAGE.format( + newdb=util.displayable_path(db_fn) + )) + + ui.input_(ui.colorize('fuchsia', u'Press ENTER to continue:')) + ui.print_() + + +# CLI command for explicit migration. + +migrate_cmd = ui.Subcommand('migrate', help='convert legacy config') +def migrate_func(lib, opts, args): + """Explicit command for migrating files. Existing files in each + destination are moved aside. + """ + config_fn = migrate_config(replace=True) + if config_fn: + log.info(u'Migrated configuration to: {0}'.format( + util.displayable_path(config_fn) + )) + db_fn = migrate_db(replace=True) + if db_fn: + log.info(u'Migrated library database to: {0}'.format( + util.displayable_path(db_fn) + )) + state_fn = migrate_state(replace=True) + if state_fn: + log.info(u'Migrated state file to: {0}'.format( + util.displayable_path(state_fn) + )) +migrate_cmd.func = migrate_func diff --git a/libs/beets/util/__init__.py b/libs/beets/util/__init__.py new file mode 100644 index 00000000..f5810ff3 --- /dev/null +++ b/libs/beets/util/__init__.py @@ -0,0 +1,618 @@ +# This file is part of beets. +# Copyright 2013, Adrian Sampson. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. + +"""Miscellaneous utility functions.""" +from __future__ import division + +import os +import sys +import re +import shutil +import fnmatch +from collections import defaultdict +import traceback +import subprocess + +MAX_FILENAME_LENGTH = 200 +WINDOWS_MAGIC_PREFIX = u'\\\\?\\' + +class HumanReadableException(Exception): + """An Exception that can include a human-readable error message to + be logged without a traceback. Can preserve a traceback for + debugging purposes as well. + + Has at least two fields: `reason`, the underlying exception or a + string describing the problem; and `verb`, the action being + performed during the error. + + If `tb` is provided, it is a string containing a traceback for the + associated exception. (Note that this is not necessary in Python 3.x + and should be removed when we make the transition.) + """ + error_kind = 'Error' # Human-readable description of error type. + + def __init__(self, reason, verb, tb=None): + self.reason = reason + self.verb = verb + self.tb = tb + super(HumanReadableException, self).__init__(self.get_message()) + + def _gerund(self): + """Generate a (likely) gerund form of the English verb. + """ + if ' ' in self.verb: + return self.verb + gerund = self.verb[:-1] if self.verb.endswith('e') else self.verb + gerund += 'ing' + return gerund + + def _reasonstr(self): + """Get the reason as a string.""" + if isinstance(self.reason, unicode): + return self.reason + elif isinstance(self.reason, basestring): # Byte string. + return self.reason.decode('utf8', 'ignore') + elif hasattr(self.reason, 'strerror'): # i.e., EnvironmentError + return self.reason.strerror + else: + return u'"{0}"'.format(unicode(self.reason)) + + def get_message(self): + """Create the human-readable description of the error, sans + introduction. + """ + raise NotImplementedError + + def log(self, logger): + """Log to the provided `logger` a human-readable message as an + error and a verbose traceback as a debug message. + """ + if self.tb: + logger.debug(self.tb) + logger.error(u'{0}: {1}'.format(self.error_kind, self.args[0])) + +class FilesystemError(HumanReadableException): + """An error that occurred while performing a filesystem manipulation + via a function in this module. The `paths` field is a sequence of + pathnames involved in the operation. + """ + def __init__(self, reason, verb, paths, tb=None): + self.paths = paths + super(FilesystemError, self).__init__(reason, verb, tb) + + def get_message(self): + # Use a nicer English phrasing for some specific verbs. + if self.verb in ('move', 'copy', 'rename'): + clause = u'while {0} {1} to {2}'.format( + self._gerund(), + displayable_path(self.paths[0]), + displayable_path(self.paths[1]) + ) + elif self.verb in ('delete', 'write', 'create', 'read'): + clause = u'while {0} {1}'.format( + self._gerund(), + displayable_path(self.paths[0]) + ) + else: + clause = u'during {0} of paths {1}'.format( + self.verb, u', '.join(displayable_path(p) for p in self.paths) + ) + + return u'{0} {1}'.format(self._reasonstr(), clause) + +def normpath(path): + """Provide the canonical form of the path suitable for storing in + the database. + """ + path = syspath(path, prefix=False) + path = os.path.normpath(os.path.abspath(os.path.expanduser(path))) + return bytestring_path(path) + +def ancestry(path): + """Return a list consisting of path's parent directory, its + grandparent, and so on. For instance: + + >>> ancestry('/a/b/c') + ['/', '/a', '/a/b'] + + The argument should *not* be the result of a call to `syspath`. + """ + out = [] + last_path = None + while path: + path = os.path.dirname(path) + + if path == last_path: + break + last_path = path + + if path: # don't yield '' + out.insert(0, path) + return out + +def sorted_walk(path, ignore=(), logger=None): + """Like `os.walk`, but yields things in case-insensitive sorted, + breadth-first order. Directory and file names matching any glob + pattern in `ignore` are skipped. If `logger` is provided, then + warning messages are logged there when a directory cannot be listed. + """ + # Make sure the path isn't a Unicode string. + path = bytestring_path(path) + + # Get all the directories and files at this level. + try: + contents = os.listdir(syspath(path)) + except OSError as exc: + if logger: + logger.warn(u'could not list directory {0}: {1}'.format( + displayable_path(path), exc.strerror + )) + return + dirs = [] + files = [] + for base in contents: + base = bytestring_path(base) + + # Skip ignored filenames. + skip = False + for pat in ignore: + if fnmatch.fnmatch(base, pat): + skip = True + break + if skip: + continue + + # Add to output as either a file or a directory. + cur = os.path.join(path, base) + if os.path.isdir(syspath(cur)): + dirs.append(base) + else: + files.append(base) + + # Sort lists (case-insensitive) and yield the current level. + dirs.sort(key=bytes.lower) + files.sort(key=bytes.lower) + yield (path, dirs, files) + + # Recurse into directories. + for base in dirs: + cur = os.path.join(path, base) + # yield from sorted_walk(...) + for res in sorted_walk(cur, ignore, logger): + yield res + +def mkdirall(path): + """Make all the enclosing directories of path (like mkdir -p on the + parent). + """ + for ancestor in ancestry(path): + if not os.path.isdir(syspath(ancestor)): + try: + os.mkdir(syspath(ancestor)) + except (OSError, IOError) as exc: + raise FilesystemError(exc, 'create', (ancestor,), + traceback.format_exc()) + +def fnmatch_all(names, patterns): + """Determine whether all strings in `names` match at least one of + the `patterns`, which should be shell glob expressions. + """ + for name in names: + matches = False + for pattern in patterns: + matches = fnmatch.fnmatch(name, pattern) + if matches: + break + if not matches: + return False + return True + +def prune_dirs(path, root=None, clutter=('.DS_Store', 'Thumbs.db')): + """If path is an empty directory, then remove it. Recursively remove + path's ancestry up to root (which is never removed) where there are + empty directories. If path is not contained in root, then nothing is + removed. Glob patterns in clutter are ignored when determining + emptiness. If root is not provided, then only path may be removed + (i.e., no recursive removal). + """ + path = normpath(path) + if root is not None: + root = normpath(root) + + ancestors = ancestry(path) + if root is None: + # Only remove the top directory. + ancestors = [] + elif root in ancestors: + # Only remove directories below the root. + ancestors = ancestors[ancestors.index(root)+1:] + else: + # Remove nothing. + return + + # Traverse upward from path. + ancestors.append(path) + ancestors.reverse() + for directory in ancestors: + directory = syspath(directory) + if not os.path.exists(directory): + # Directory gone already. + continue + if fnmatch_all(os.listdir(directory), clutter): + # Directory contains only clutter (or nothing). + try: + shutil.rmtree(directory) + except OSError: + break + else: + break + +def components(path): + """Return a list of the path components in path. For instance: + + >>> components('/a/b/c') + ['a', 'b', 'c'] + + The argument should *not* be the result of a call to `syspath`. + """ + comps = [] + ances = ancestry(path) + for anc in ances: + comp = os.path.basename(anc) + if comp: + comps.append(comp) + else: # root + comps.append(anc) + + last = os.path.basename(path) + if last: + comps.append(last) + + return comps + +def _fsencoding(): + """Get the system's filesystem encoding. On Windows, this is always + UTF-8 (not MBCS). + """ + encoding = sys.getfilesystemencoding() or sys.getdefaultencoding() + if encoding == 'mbcs': + # On Windows, a broken encoding known to Python as "MBCS" is + # used for the filesystem. However, we only use the Unicode API + # for Windows paths, so the encoding is actually immaterial so + # we can avoid dealing with this nastiness. We arbitrarily + # choose UTF-8. + encoding = 'utf8' + return encoding + +def bytestring_path(path): + """Given a path, which is either a str or a unicode, returns a str + path (ensuring that we never deal with Unicode pathnames). + """ + # Pass through bytestrings. + if isinstance(path, str): + return path + + # On Windows, remove the magic prefix added by `syspath`. This makes + # ``bytestring_path(syspath(X)) == X``, i.e., we can safely + # round-trip through `syspath`. + if os.path.__name__ == 'ntpath' and path.startswith(WINDOWS_MAGIC_PREFIX): + path = path[len(WINDOWS_MAGIC_PREFIX):] + + # Try to encode with default encodings, but fall back to UTF8. + try: + return path.encode(_fsencoding()) + except (UnicodeError, LookupError): + return path.encode('utf8') + +def displayable_path(path, separator=u'; '): + """Attempts to decode a bytestring path to a unicode object for the + purpose of displaying it to the user. If the `path` argument is a + list or a tuple, the elements are joined with `separator`. + """ + if isinstance(path, (list, tuple)): + return separator.join(displayable_path(p) for p in path) + elif isinstance(path, unicode): + return path + elif not isinstance(path, str): + # A non-string object: just get its unicode representation. + return unicode(path) + + try: + return path.decode(_fsencoding(), 'ignore') + except (UnicodeError, LookupError): + return path.decode('utf8', 'ignore') + +def syspath(path, prefix=True): + """Convert a path for use by the operating system. In particular, + paths on Windows must receive a magic prefix and must be converted + to Unicode before they are sent to the OS. To disable the magic + prefix on Windows, set `prefix` to False---but only do this if you + *really* know what you're doing. + """ + # Don't do anything if we're not on windows + if os.path.__name__ != 'ntpath': + return path + + if not isinstance(path, unicode): + # Beets currently represents Windows paths internally with UTF-8 + # arbitrarily. But earlier versions used MBCS because it is + # reported as the FS encoding by Windows. Try both. + try: + path = path.decode('utf8') + except UnicodeError: + # The encoding should always be MBCS, Windows' broken + # Unicode representation. + encoding = sys.getfilesystemencoding() or sys.getdefaultencoding() + path = path.decode(encoding, 'replace') + + # Add the magic prefix if it isn't already there + if prefix and not path.startswith(WINDOWS_MAGIC_PREFIX): + path = WINDOWS_MAGIC_PREFIX + path + + return path + +def samefile(p1, p2): + """Safer equality for paths.""" + return shutil._samefile(syspath(p1), syspath(p2)) + +def remove(path, soft=True): + """Remove the file. If `soft`, then no error will be raised if the + file does not exist. + """ + path = syspath(path) + if soft and not os.path.exists(path): + return + try: + os.remove(path) + except (OSError, IOError) as exc: + raise FilesystemError(exc, 'delete', (path,), traceback.format_exc()) + +def copy(path, dest, replace=False): + """Copy a plain file. Permissions are not copied. If `dest` already + exists, raises a FilesystemError unless `replace` is True. Has no + effect if `path` is the same as `dest`. Paths are translated to + system paths before the syscall. + """ + if samefile(path, dest): + return + path = syspath(path) + dest = syspath(dest) + if not replace and os.path.exists(dest): + raise FilesystemError('file exists', 'copy', (path, dest)) + try: + shutil.copyfile(path, dest) + except (OSError, IOError) as exc: + raise FilesystemError(exc, 'copy', (path, dest), + traceback.format_exc()) + +def move(path, dest, replace=False): + """Rename a file. `dest` may not be a directory. If `dest` already + exists, raises an OSError unless `replace` is True. Has no effect if + `path` is the same as `dest`. If the paths are on different + filesystems (or the rename otherwise fails), a copy is attempted + instead, in which case metadata will *not* be preserved. Paths are + translated to system paths. + """ + if samefile(path, dest): + return + path = syspath(path) + dest = syspath(dest) + if os.path.exists(dest) and not replace: + raise FilesystemError('file exists', 'rename', (path, dest), + traceback.format_exc()) + + # First, try renaming the file. + try: + os.rename(path, dest) + except OSError: + # Otherwise, copy and delete the original. + try: + shutil.copyfile(path, dest) + os.remove(path) + except (OSError, IOError) as exc: + raise FilesystemError(exc, 'move', (path, dest), + traceback.format_exc()) + +def unique_path(path): + """Returns a version of ``path`` that does not exist on the + filesystem. Specifically, if ``path` itself already exists, then + something unique is appended to the path. + """ + if not os.path.exists(syspath(path)): + return path + + base, ext = os.path.splitext(path) + match = re.search(r'\.(\d)+$', base) + if match: + num = int(match.group(1)) + base = base[:match.start()] + else: + num = 0 + while True: + num += 1 + new_path = '%s.%i%s' % (base, num, ext) + if not os.path.exists(new_path): + return new_path + +# Note: The Windows "reserved characters" are, of course, allowed on +# Unix. They are forbidden here because they cause problems on Samba +# shares, which are sufficiently common as to cause frequent problems. +# http://msdn.microsoft.com/en-us/library/windows/desktop/aa365247.aspx +CHAR_REPLACE = [ + (re.compile(ur'[\\/]'), u'_'), # / and \ -- forbidden everywhere. + (re.compile(ur'^\.'), u'_'), # Leading dot (hidden files on Unix). + (re.compile(ur'[\x00-\x1f]'), u''), # Control characters. + (re.compile(ur'[<>:"\?\*\|]'), u'_'), # Windows "reserved characters". + (re.compile(ur'\.$'), u'_'), # Trailing dots. + (re.compile(ur'\s+$'), u''), # Trailing whitespace. +] +def sanitize_path(path, replacements=None): + """Takes a path (as a Unicode string) and makes sure that it is + legal. Returns a new path. Only works with fragments; won't work + reliably on Windows when a path begins with a drive letter. Path + separators (including altsep!) should already be cleaned from the + path components. If replacements is specified, it is used *instead* + of the default set of replacements; it must be a list of (compiled + regex, replacement string) pairs. + """ + replacements = replacements or CHAR_REPLACE + + comps = components(path) + if not comps: + return '' + for i, comp in enumerate(comps): + for regex, repl in replacements: + comp = regex.sub(repl, comp) + comps[i] = comp + return os.path.join(*comps) + +def truncate_path(path, length=MAX_FILENAME_LENGTH): + """Given a bytestring path or a Unicode path fragment, truncate the + components to a legal length. In the last component, the extension + is preserved. + """ + comps = components(path) + + out = [c[:length] for c in comps] + base, ext = os.path.splitext(comps[-1]) + if ext: + # Last component has an extension. + base = base[:length - len(ext)] + out[-1] = base + ext + + return os.path.join(*out) + +def str2bool(value): + """Returns a boolean reflecting a human-entered string.""" + if value.lower() in ('yes', '1', 'true', 't', 'y'): + return True + else: + return False + +def as_string(value): + """Convert a value to a Unicode object for matching with a query. + None becomes the empty string. Bytestrings are silently decoded. + """ + if value is None: + return u'' + elif isinstance(value, buffer): + return str(value).decode('utf8', 'ignore') + elif isinstance(value, str): + return value.decode('utf8', 'ignore') + else: + return unicode(value) + +def levenshtein(s1, s2): + """A nice DP edit distance implementation from Wikibooks: + http://en.wikibooks.org/wiki/Algorithm_implementation/Strings/ + Levenshtein_distance#Python + """ + if len(s1) < len(s2): + return levenshtein(s2, s1) + if not s1: + return len(s2) + + previous_row = xrange(len(s2) + 1) + for i, c1 in enumerate(s1): + current_row = [i + 1] + for j, c2 in enumerate(s2): + insertions = previous_row[j + 1] + 1 + deletions = current_row[j] + 1 + substitutions = previous_row[j] + (c1 != c2) + current_row.append(min(insertions, deletions, substitutions)) + previous_row = current_row + + return previous_row[-1] + +def plurality(objs): + """Given a sequence of comparable objects, returns the object that + is most common in the set and the frequency of that object. The + sequence must contain at least one object. + """ + # Calculate frequencies. + freqs = defaultdict(int) + for obj in objs: + freqs[obj] += 1 + + if not freqs: + raise ValueError('sequence must be non-empty') + + # Find object with maximum frequency. + max_freq = 0 + res = None + for obj, freq in freqs.items(): + if freq > max_freq: + max_freq = freq + res = obj + + return res, max_freq + +def cpu_count(): + """Return the number of hardware thread contexts (cores or SMT + threads) in the system. + """ + # Adapted from the soundconverter project: + # https://github.com/kassoulet/soundconverter + if sys.platform == 'win32': + try: + num = int(os.environ['NUMBER_OF_PROCESSORS']) + except (ValueError, KeyError): + num = 0 + elif sys.platform == 'darwin': + try: + num = int(os.popen('sysctl -n hw.ncpu').read()) + except ValueError: + num = 0 + else: + try: + num = os.sysconf('SC_NPROCESSORS_ONLN') + except (ValueError, OSError, AttributeError): + num = 0 + if num >= 1: + return num + else: + return 1 + +def command_output(cmd): + """Wraps the `subprocess` module to invoke a command (given as a + list of arguments starting with the command name) and collect + stdout. The stderr stream is ignored. May raise + `subprocess.CalledProcessError` or an `OSError`. + + This replaces `subprocess.check_output`, which isn't available in + Python 2.6 and which can have problems if lots of output is sent to + stderr. + """ + with open(os.devnull, 'w') as devnull: + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=devnull) + stdout, _ = proc.communicate() + if proc.returncode: + raise subprocess.CalledProcessError(proc.returncode, cmd) + return stdout + +def max_filename_length(path, limit=MAX_FILENAME_LENGTH): + """Attempt to determine the maximum filename length for the + filesystem containing `path`. If the value is greater than `limit`, + then `limit` is used instead (to prevent errors when a filesystem + misreports its capacity). If it cannot be determined (e.g., on + Windows), return `limit`. + """ + if hasattr(os, 'statvfs'): + try: + res = os.statvfs(path) + except OSError: + return limit + return min(res[9], limit) + else: + return limit diff --git a/libs/beets/util/artresizer.py b/libs/beets/util/artresizer.py new file mode 100644 index 00000000..6e367a0a --- /dev/null +++ b/libs/beets/util/artresizer.py @@ -0,0 +1,188 @@ +# This file is part of beets. +# Copyright 2013, Fabrice Laporte +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. + +"""Abstraction layer to resize images using PIL, ImageMagick, or a +public resizing proxy if neither is available. +""" +import urllib +import subprocess +import os +from tempfile import NamedTemporaryFile +import logging +from beets import util + +# Resizing methods +PIL = 1 +IMAGEMAGICK = 2 +WEBPROXY = 3 + +PROXY_URL = 'http://images.weserv.nl/' + +log = logging.getLogger('beets') + + +def resize_url(url, maxwidth): + """Return a proxied image URL that resizes the original image to + maxwidth (preserving aspect ratio). + """ + return '{0}?{1}'.format(PROXY_URL, urllib.urlencode({ + 'url': url.replace('http://',''), + 'w': str(maxwidth), + })) + + +def temp_file_for(path): + """Return an unused filename with the same extension as the + specified path. + """ + ext = os.path.splitext(path)[1] + with NamedTemporaryFile(suffix=ext, delete=False) as f: + return f.name + + +def pil_resize(maxwidth, path_in, path_out=None): + """Resize using Python Imaging Library (PIL). Return the output path + of resized image. + """ + path_out = path_out or temp_file_for(path_in) + from PIL import Image + log.debug(u'artresizer: PIL resizing {0} to {1}'.format( + util.displayable_path(path_in), util.displayable_path(path_out) + )) + + try: + im = Image.open(util.syspath(path_in)) + size = maxwidth, maxwidth + im.thumbnail(size, Image.ANTIALIAS) + im.save(path_out) + return path_out + except IOError: + log.error(u"PIL cannot create thumbnail for '{0}'".format( + util.displayable_path(path_in) + )) + return path_in + + +def im_resize(maxwidth, path_in, path_out=None): + """Resize using ImageMagick's ``convert`` tool. + tool. Return the output path of resized image. + """ + path_out = path_out or temp_file_for(path_in) + log.debug(u'artresizer: ImageMagick resizing {0} to {1}'.format( + util.displayable_path(path_in), util.displayable_path(path_out) + )) + + # "-resize widthxheight>" shrinks images with dimension(s) larger + # than the corresponding width and/or height dimension(s). The > + # "only shrink" flag is prefixed by ^ escape char for Windows + # compatibility. + try: + util.command_output([ + 'convert', util.syspath(path_in), + '-resize', '{0}x^>'.format(maxwidth), path_out + ]) + except subprocess.CalledProcessError: + log.warn(u'artresizer: IM convert failed for {0}'.format( + util.displayable_path(path_in) + )) + return path_in + return path_out + + +BACKEND_FUNCS = { + PIL: pil_resize, + IMAGEMAGICK: im_resize, +} + + +class Shareable(type): + """A pseudo-singleton metaclass that allows both shared and + non-shared instances. The ``MyClass.shared`` property holds a + lazily-created shared instance of ``MyClass`` while calling + ``MyClass()`` to construct a new object works as usual. + """ + def __init__(cls, name, bases, dict): + super(Shareable, cls).__init__(name, bases, dict) + cls._instance = None + + @property + def shared(cls): + if cls._instance is None: + cls._instance = cls() + return cls._instance + + +class ArtResizer(object): + """A singleton class that performs image resizes. + """ + __metaclass__ = Shareable + + def __init__(self, method=None): + """Create a resizer object for the given method or, if none is + specified, with an inferred method. + """ + self.method = method or self._guess_method() + log.debug(u"artresizer: method is {0}".format(self.method)) + + def resize(self, maxwidth, path_in, path_out=None): + """Manipulate an image file according to the method, returning a + new path. For PIL or IMAGEMAGIC methods, resizes the image to a + temporary file. For WEBPROXY, returns `path_in` unmodified. + """ + if self.local: + func = BACKEND_FUNCS[self.method] + return func(maxwidth, path_in, path_out) + else: + return path_in + + def proxy_url(self, maxwidth, url): + """Modifies an image URL according the method, returning a new + URL. For WEBPROXY, a URL on the proxy server is returned. + Otherwise, the URL is returned unmodified. + """ + if self.local: + return url + else: + return resize_url(url, maxwidth) + + @property + def local(self): + """A boolean indicating whether the resizing method is performed + locally (i.e., PIL or IMAGEMAGICK). + """ + return self.method in BACKEND_FUNCS + + @staticmethod + def _guess_method(): + """Determine which resizing method to use. Returns PIL, + IMAGEMAGICK, or WEBPROXY depending on available dependencies. + """ + # Try importing PIL. + try: + __import__('PIL', fromlist=['Image']) + return PIL + except ImportError: + pass + + # Try invoking ImageMagick's "convert". + try: + out = util.command_output(['convert', '--version']) + if 'imagemagick' in out.lower(): + # system32/convert.exe may be interfering + return IMAGEMAGICK + except (subprocess.CalledProcessError, OSError): + pass + + # Fall back to Web proxy method. + return WEBPROXY diff --git a/libs/beets/util/bluelet.py b/libs/beets/util/bluelet.py new file mode 100644 index 00000000..9d9432f2 --- /dev/null +++ b/libs/beets/util/bluelet.py @@ -0,0 +1,617 @@ +"""Extremely simple pure-Python implementation of coroutine-style +asynchronous socket I/O. Inspired by, but inferior to, Eventlet. +Bluelet can also be thought of as a less-terrible replacement for +asyncore. + +Bluelet: easy concurrency without all the messy parallelism. +""" +import socket +import select +import sys +import types +import errno +import traceback +import time +import collections + + +# A little bit of "six" (Python 2/3 compatibility): cope with PEP 3109 syntax +# changes. + +PY3 = sys.version_info[0] == 3 +if PY3: + def _reraise(typ, exc, tb): + raise exc.with_traceback(tb) +else: + exec(""" +def _reraise(typ, exc, tb): + raise typ, exc, tb +""") + + +# Basic events used for thread scheduling. + +class Event(object): + """Just a base class identifying Bluelet events. An event is an + object yielded from a Bluelet thread coroutine to suspend operation + and communicate with the scheduler. + """ + pass + +class WaitableEvent(Event): + """A waitable event is one encapsulating an action that can be + waited for using a select() call. That is, it's an event with an + associated file descriptor. + """ + def waitables(self): + """Return "waitable" objects to pass to select(). Should return + three iterables for input readiness, output readiness, and + exceptional conditions (i.e., the three lists passed to + select()). + """ + return (), (), () + + def fire(self): + """Called when an associated file descriptor becomes ready + (i.e., is returned from a select() call). + """ + pass + +class ValueEvent(Event): + """An event that does nothing but return a fixed value.""" + def __init__(self, value): + self.value = value + +class ExceptionEvent(Event): + """Raise an exception at the yield point. Used internally.""" + def __init__(self, exc_info): + self.exc_info = exc_info + +class SpawnEvent(Event): + """Add a new coroutine thread to the scheduler.""" + def __init__(self, coro): + self.spawned = coro + +class JoinEvent(Event): + """Suspend the thread until the specified child thread has + completed. + """ + def __init__(self, child): + self.child = child + +class KillEvent(Event): + """Unschedule a child thread.""" + def __init__(self, child): + self.child = child + +class DelegationEvent(Event): + """Suspend execution of the current thread, start a new thread and, + once the child thread finished, return control to the parent + thread. + """ + def __init__(self, coro): + self.spawned = coro + +class ReturnEvent(Event): + """Return a value the current thread's delegator at the point of + delegation. Ends the current (delegate) thread. + """ + def __init__(self, value): + self.value = value + +class SleepEvent(WaitableEvent): + """Suspend the thread for a given duration. + """ + def __init__(self, duration): + self.wakeup_time = time.time() + duration + + def time_left(self): + return max(self.wakeup_time - time.time(), 0.0) + +class ReadEvent(WaitableEvent): + """Reads from a file-like object.""" + def __init__(self, fd, bufsize): + self.fd = fd + self.bufsize = bufsize + + def waitables(self): + return (self.fd,), (), () + + def fire(self): + return self.fd.read(self.bufsize) + +class WriteEvent(WaitableEvent): + """Writes to a file-like object.""" + def __init__(self, fd, data): + self.fd = fd + self.data = data + + def waitable(self): + return (), (self.fd,), () + + def fire(self): + self.fd.write(self.data) + + +# Core logic for executing and scheduling threads. + +def _event_select(events): + """Perform a select() over all the Events provided, returning the + ones ready to be fired. Only WaitableEvents (including SleepEvents) + matter here; all other events are ignored (and thus postponed). + """ + # Gather waitables and wakeup times. + waitable_to_event = {} + rlist, wlist, xlist = [], [], [] + earliest_wakeup = None + for event in events: + if isinstance(event, SleepEvent): + if not earliest_wakeup: + earliest_wakeup = event.wakeup_time + else: + earliest_wakeup = min(earliest_wakeup, event.wakeup_time) + elif isinstance(event, WaitableEvent): + r, w, x = event.waitables() + rlist += r + wlist += w + xlist += x + for waitable in r: + waitable_to_event[('r', waitable)] = event + for waitable in w: + waitable_to_event[('w', waitable)] = event + for waitable in x: + waitable_to_event[('x', waitable)] = event + + # If we have a any sleeping threads, determine how long to sleep. + if earliest_wakeup: + timeout = max(earliest_wakeup - time.time(), 0.0) + else: + timeout = None + + # Perform select() if we have any waitables. + if rlist or wlist or xlist: + rready, wready, xready = select.select(rlist, wlist, xlist, timeout) + else: + rready, wready, xready = (), (), () + if timeout: + time.sleep(timeout) + + # Gather ready events corresponding to the ready waitables. + ready_events = set() + for ready in rready: + ready_events.add(waitable_to_event[('r', ready)]) + for ready in wready: + ready_events.add(waitable_to_event[('w', ready)]) + for ready in xready: + ready_events.add(waitable_to_event[('x', ready)]) + + # Gather any finished sleeps. + for event in events: + if isinstance(event, SleepEvent) and event.time_left() == 0.0: + ready_events.add(event) + + return ready_events + +class ThreadException(Exception): + def __init__(self, coro, exc_info): + self.coro = coro + self.exc_info = exc_info + def reraise(self): + _reraise(self.exc_info[0], self.exc_info[1], self.exc_info[2]) + +SUSPENDED = Event() # Special sentinel placeholder for suspended threads. + +class Delegated(Event): + """Placeholder indicating that a thread has delegated execution to a + different thread. + """ + def __init__(self, child): + self.child = child + +def run(root_coro): + """Schedules a coroutine, running it to completion. This + encapsulates the Bluelet scheduler, which the root coroutine can + add to by spawning new coroutines. + """ + # The "threads" dictionary keeps track of all the currently- + # executing and suspended coroutines. It maps coroutines to their + # currently "blocking" event. The event value may be SUSPENDED if + # the coroutine is waiting on some other condition: namely, a + # delegated coroutine or a joined coroutine. In this case, the + # coroutine should *also* appear as a value in one of the below + # dictionaries `delegators` or `joiners`. + threads = {root_coro: ValueEvent(None)} + + # Maps child coroutines to delegating parents. + delegators = {} + + # Maps child coroutines to joining (exit-waiting) parents. + joiners = collections.defaultdict(list) + + def complete_thread(coro, return_value): + """Remove a coroutine from the scheduling pool, awaking + delegators and joiners as necessary and returning the specified + value to any delegating parent. + """ + del threads[coro] + + # Resume delegator. + if coro in delegators: + threads[delegators[coro]] = ValueEvent(return_value) + del delegators[coro] + + # Resume joiners. + if coro in joiners: + for parent in joiners[coro]: + threads[parent] = ValueEvent(None) + del joiners[coro] + + def advance_thread(coro, value, is_exc=False): + """After an event is fired, run a given coroutine associated with + it in the threads dict until it yields again. If the coroutine + exits, then the thread is removed from the pool. If the coroutine + raises an exception, it is reraised in a ThreadException. If + is_exc is True, then the value must be an exc_info tuple and the + exception is thrown into the coroutine. + """ + try: + if is_exc: + next_event = coro.throw(*value) + else: + next_event = coro.send(value) + except StopIteration: + # Thread is done. + complete_thread(coro, None) + except: + # Thread raised some other exception. + del threads[coro] + raise ThreadException(coro, sys.exc_info()) + else: + if isinstance(next_event, types.GeneratorType): + # Automatically invoke sub-coroutines. (Shorthand for + # explicit bluelet.call().) + next_event = DelegationEvent(next_event) + threads[coro] = next_event + + def kill_thread(coro): + """Unschedule this thread and its (recursive) delegates. + """ + # Collect all coroutines in the delegation stack. + coros = [coro] + while isinstance(threads[coro], Delegated): + coro = threads[coro].child + coros.append(coro) + + # Complete each coroutine from the top to the bottom of the + # stack. + for coro in reversed(coros): + complete_thread(coro, None) + + # Continue advancing threads until root thread exits. + exit_te = None + while threads: + try: + # Look for events that can be run immediately. Continue + # running immediate events until nothing is ready. + while True: + have_ready = False + for coro, event in list(threads.items()): + if isinstance(event, SpawnEvent): + threads[event.spawned] = ValueEvent(None) # Spawn. + advance_thread(coro, None) + have_ready = True + elif isinstance(event, ValueEvent): + advance_thread(coro, event.value) + have_ready = True + elif isinstance(event, ExceptionEvent): + advance_thread(coro, event.exc_info, True) + have_ready = True + elif isinstance(event, DelegationEvent): + threads[coro] = Delegated(event.spawned) # Suspend. + threads[event.spawned] = ValueEvent(None) # Spawn. + delegators[event.spawned] = coro + have_ready = True + elif isinstance(event, ReturnEvent): + # Thread is done. + complete_thread(coro, event.value) + have_ready = True + elif isinstance(event, JoinEvent): + threads[coro] = SUSPENDED # Suspend. + joiners[event.child].append(coro) + have_ready = True + elif isinstance(event, KillEvent): + threads[coro] = ValueEvent(None) + kill_thread(event.child) + have_ready = True + + # Only start the select when nothing else is ready. + if not have_ready: + break + + # Wait and fire. + event2coro = dict((v,k) for k,v in threads.items()) + for event in _event_select(threads.values()): + # Run the IO operation, but catch socket errors. + try: + value = event.fire() + except socket.error as exc: + if isinstance(exc.args, tuple) and \ + exc.args[0] == errno.EPIPE: + # Broken pipe. Remote host disconnected. + pass + else: + traceback.print_exc() + # Abort the coroutine. + threads[event2coro[event]] = ReturnEvent(None) + else: + advance_thread(event2coro[event], value) + + except ThreadException as te: + # Exception raised from inside a thread. + event = ExceptionEvent(te.exc_info) + if te.coro in delegators: + # The thread is a delegate. Raise exception in its + # delegator. + threads[delegators[te.coro]] = event + del delegators[te.coro] + else: + # The thread is root-level. Raise in client code. + exit_te = te + break + + except: + # For instance, KeyboardInterrupt during select(). Raise + # into root thread and terminate others. + threads = {root_coro: ExceptionEvent(sys.exc_info())} + + # If any threads still remain, kill them. + for coro in threads: + coro.close() + + # If we're exiting with an exception, raise it in the client. + if exit_te: + exit_te.reraise() + + +# Sockets and their associated events. + +class SocketClosedError(Exception): + pass + +class Listener(object): + """A socket wrapper object for listening sockets. + """ + def __init__(self, host, port): + """Create a listening socket on the given hostname and port. + """ + self._closed = False + self.host = host + self.port = port + self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + self.sock.bind((host, port)) + self.sock.listen(5) + + def accept(self): + """An event that waits for a connection on the listening socket. + When a connection is made, the event returns a Connection + object. + """ + if self._closed: + raise SocketClosedError() + return AcceptEvent(self) + + def close(self): + """Immediately close the listening socket. (Not an event.) + """ + self._closed = True + self.sock.close() + +class Connection(object): + """A socket wrapper object for connected sockets. + """ + def __init__(self, sock, addr): + self.sock = sock + self.addr = addr + self._buf = b'' + self._closed = False + + def close(self): + """Close the connection.""" + self._closed = True + self.sock.close() + + def recv(self, size): + """Read at most size bytes of data from the socket.""" + if self._closed: + raise SocketClosedError() + + if self._buf: + # We already have data read previously. + out = self._buf[:size] + self._buf = self._buf[size:] + return ValueEvent(out) + else: + return ReceiveEvent(self, size) + + def send(self, data): + """Sends data on the socket, returning the number of bytes + successfully sent. + """ + if self._closed: + raise SocketClosedError() + return SendEvent(self, data) + + def sendall(self, data): + """Send all of data on the socket.""" + if self._closed: + raise SocketClosedError() + return SendEvent(self, data, True) + + def readline(self, terminator=b"\n", bufsize=1024): + """Reads a line (delimited by terminator) from the socket.""" + if self._closed: + raise SocketClosedError() + + while True: + if terminator in self._buf: + line, self._buf = self._buf.split(terminator, 1) + line += terminator + yield ReturnEvent(line) + break + data = yield ReceiveEvent(self, bufsize) + if data: + self._buf += data + else: + line = self._buf + self._buf = b'' + yield ReturnEvent(line) + break + +class AcceptEvent(WaitableEvent): + """An event for Listener objects (listening sockets) that suspends + execution until the socket gets a connection. + """ + def __init__(self, listener): + self.listener = listener + + def waitables(self): + return (self.listener.sock,), (), () + + def fire(self): + sock, addr = self.listener.sock.accept() + return Connection(sock, addr) + +class ReceiveEvent(WaitableEvent): + """An event for Connection objects (connected sockets) for + asynchronously reading data. + """ + def __init__(self, conn, bufsize): + self.conn = conn + self.bufsize = bufsize + + def waitables(self): + return (self.conn.sock,), (), () + + def fire(self): + return self.conn.sock.recv(self.bufsize) + +class SendEvent(WaitableEvent): + """An event for Connection objects (connected sockets) for + asynchronously writing data. + """ + def __init__(self, conn, data, sendall=False): + self.conn = conn + self.data = data + self.sendall = sendall + + def waitables(self): + return (), (self.conn.sock,), () + + def fire(self): + if self.sendall: + return self.conn.sock.sendall(self.data) + else: + return self.conn.sock.send(self.data) + + +# Public interface for threads; each returns an event object that +# can immediately be "yield"ed. + +def null(): + """Event: yield to the scheduler without doing anything special. + """ + return ValueEvent(None) + +def spawn(coro): + """Event: add another coroutine to the scheduler. Both the parent + and child coroutines run concurrently. + """ + if not isinstance(coro, types.GeneratorType): + raise ValueError('%s is not a coroutine' % str(coro)) + return SpawnEvent(coro) + +def call(coro): + """Event: delegate to another coroutine. The current coroutine + is resumed once the sub-coroutine finishes. If the sub-coroutine + returns a value using end(), then this event returns that value. + """ + if not isinstance(coro, types.GeneratorType): + raise ValueError('%s is not a coroutine' % str(coro)) + return DelegationEvent(coro) + +def end(value=None): + """Event: ends the coroutine and returns a value to its + delegator. + """ + return ReturnEvent(value) + +def read(fd, bufsize=None): + """Event: read from a file descriptor asynchronously.""" + if bufsize is None: + # Read all. + def reader(): + buf = [] + while True: + data = yield read(fd, 1024) + if not data: + break + buf.append(data) + yield ReturnEvent(''.join(buf)) + return DelegationEvent(reader()) + + else: + return ReadEvent(fd, bufsize) + +def write(fd, data): + """Event: write to a file descriptor asynchronously.""" + return WriteEvent(fd, data) + +def connect(host, port): + """Event: connect to a network address and return a Connection + object for communicating on the socket. + """ + addr = (host, port) + sock = socket.create_connection(addr) + return ValueEvent(Connection(sock, addr)) + +def sleep(duration): + """Event: suspend the thread for ``duration`` seconds. + """ + return SleepEvent(duration) + +def join(coro): + """Suspend the thread until another, previously `spawn`ed thread + completes. + """ + return JoinEvent(coro) + +def kill(coro): + """Halt the execution of a different `spawn`ed thread. + """ + return KillEvent(coro) + + +# Convenience function for running socket servers. + +def server(host, port, func): + """A coroutine that runs a network server. Host and port specify the + listening address. func should be a coroutine that takes a single + parameter, a Connection object. The coroutine is invoked for every + incoming connection on the listening socket. + """ + def handler(conn): + try: + yield func(conn) + finally: + conn.close() + + listener = Listener(host, port) + try: + while True: + conn = yield listener.accept() + yield spawn(handler(conn)) + except KeyboardInterrupt: + pass + finally: + listener.close() diff --git a/libs/beets/util/confit.py b/libs/beets/util/confit.py new file mode 100644 index 00000000..cf8b3629 --- /dev/null +++ b/libs/beets/util/confit.py @@ -0,0 +1,900 @@ +# This file is part of Confit. +# Copyright 2014, Adrian Sampson. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. + +"""Worry-free YAML configuration files. +""" +from __future__ import unicode_literals +import platform +import os +import pkgutil +import sys +import yaml +import types +try: + from collections import OrderedDict +except ImportError: + from ordereddict import OrderedDict + +UNIX_DIR_VAR = 'XDG_CONFIG_HOME' +UNIX_DIR_FALLBACK = '~/.config' +WINDOWS_DIR_VAR = 'APPDATA' +WINDOWS_DIR_FALLBACK = '~\\AppData\\Roaming' +MAC_DIR = '~/Library/Application Support' + +CONFIG_FILENAME = 'config.yaml' +DEFAULT_FILENAME = 'config_default.yaml' +ROOT_NAME = 'root' + +YAML_TAB_PROBLEM = "found character '\\t' that cannot start any token" + + +# Utilities. + +PY3 = sys.version_info[0] == 3 +STRING = str if PY3 else unicode +BASESTRING = str if PY3 else basestring +NUMERIC_TYPES = (int, float) if PY3 else (int, float, long) +TYPE_TYPES = (type,) if PY3 else (type, types.ClassType) + +def iter_first(sequence): + """Get the first element from an iterable or raise a ValueError if + the iterator generates no values. + """ + it = iter(sequence) + try: + if PY3: + return next(it) + else: + return it.next() + except StopIteration: + raise ValueError() + + +# Exceptions. + +class ConfigError(Exception): + """Base class for exceptions raised when querying a configuration. + """ + +class NotFoundError(ConfigError): + """A requested value could not be found in the configuration trees. + """ + +class ConfigTypeError(ConfigError, TypeError): + """The value in the configuration did not match the expected type. + """ + +class ConfigValueError(ConfigError, ValueError): + """The value in the configuration is illegal.""" + +class ConfigReadError(ConfigError): + """A configuration file could not be read.""" + def __init__(self, filename, reason=None): + self.filename = filename + self.reason = reason + + message = 'file {0} could not be read'.format(filename) + if isinstance(reason, yaml.scanner.ScannerError) and \ + reason.problem == YAML_TAB_PROBLEM: + # Special-case error message for tab indentation in YAML markup. + message += ': found tab character at line {0}, column {1}'.format( + reason.problem_mark.line + 1, + reason.problem_mark.column + 1, + ) + elif reason: + # Generic error message uses exception's message. + message += ': {0}'.format(reason) + + super(ConfigReadError, self).__init__(message) + + +# Views and sources. + +class ConfigSource(dict): + """A dictionary augmented with metadata about the source of the + configuration. + """ + def __init__(self, value, filename=None, default=False): + super(ConfigSource, self).__init__(value) + if filename is not None and not isinstance(filename, BASESTRING): + raise TypeError('filename must be a string or None') + self.filename = filename + self.default = default + + def __repr__(self): + return 'ConfigSource({0}, {1}, {2})'.format( + super(ConfigSource, self).__repr__(), + repr(self.filename), + repr(self.default) + ) + + @classmethod + def of(self, value): + """Given either a dictionary or a `ConfigSource` object, return + a `ConfigSource` object. This lets a function accept either type + of object as an argument. + """ + if isinstance(value, ConfigSource): + return value + elif isinstance(value, dict): + return ConfigSource(value) + else: + raise TypeError('source value must be a dict') + +class ConfigView(object): + """A configuration "view" is a query into a program's configuration + data. A view represents a hypothetical location in the configuration + tree; to extract the data from the location, a client typically + calls the ``view.get()`` method. The client can access children in + the tree (subviews) by subscripting the parent view (i.e., + ``view[key]``). + """ + + name = None + """The name of the view, depicting the path taken through the + configuration in Python-like syntax (e.g., ``foo['bar'][42]``). + """ + + def resolve(self): + """The core (internal) data retrieval method. Generates (value, + source) pairs for each source that contains a value for this + view. May raise ConfigTypeError if a type error occurs while + traversing a source. + """ + raise NotImplementedError + + def first(self): + """Return a (value, source) pair for the first object found for + this view. This amounts to the first element returned by + `resolve`. If no values are available, a NotFoundError is + raised. + """ + pairs = self.resolve() + try: + return iter_first(pairs) + except ValueError: + raise NotFoundError("{0} not found".format(self.name)) + + def exists(self): + """Determine whether the view has a setting in any source. + """ + try: + self.first() + except NotFoundError: + return False + return True + + def add(self, value): + """Set the *default* value for this configuration view. The + specified value is added as the lowest-priority configuration + data source. + """ + raise NotImplementedError + + def set(self, value): + """*Override* the value for this configuration view. The + specified value is added as the highest-priority configuration + data source. + """ + raise NotImplementedError + + def root(self): + """The RootView object from which this view is descended. + """ + raise NotImplementedError + + def __repr__(self): + return '' % self.name + + def __getitem__(self, key): + """Get a subview of this view.""" + return Subview(self, key) + + def __setitem__(self, key, value): + """Create an overlay source to assign a given key under this + view. + """ + self.set({key: value}) + + def set_args(self, namespace): + """Overlay parsed command-line arguments, generated by a library + like argparse or optparse, onto this view's value. + """ + args = {} + for key, value in namespace.__dict__.items(): + if value is not None: # Avoid unset options. + args[key] = value + self.set(args) + + # Magical conversions. These special methods make it possible to use + # View objects somewhat transparently in certain circumstances. For + # example, rather than using ``view.get(bool)``, it's possible to + # just say ``bool(view)`` or use ``view`` in a conditional. + + def __str__(self): + """Gets the value for this view as a byte string.""" + return str(self.get()) + + def __unicode__(self): + """Gets the value for this view as a unicode string. (Python 2 + only.) + """ + return unicode(self.get()) + + def __nonzero__(self): + """Gets the value for this view as a boolean. (Python 2 only.) + """ + return self.__bool__() + + def __bool__(self): + """Gets the value for this view as a boolean. (Python 3 only.) + """ + return bool(self.get()) + + # Dictionary emulation methods. + + def keys(self): + """Returns a list containing all the keys available as subviews + of the current views. This enumerates all the keys in *all* + dictionaries matching the current view, in contrast to + ``view.get(dict).keys()``, which gets all the keys for the + *first* dict matching the view. If the object for this view in + any source is not a dict, then a ConfigTypeError is raised. The + keys are ordered according to how they appear in each source. + """ + keys = [] + + for dic, _ in self.resolve(): + try: + cur_keys = dic.keys() + except AttributeError: + raise ConfigTypeError( + '{0} must be a dict, not {1}'.format( + self.name, type(dic).__name__ + ) + ) + + for key in cur_keys: + if key not in keys: + keys.append(key) + + return keys + + def items(self): + """Iterates over (key, subview) pairs contained in dictionaries + from *all* sources at this view. If the object for this view in + any source is not a dict, then a ConfigTypeError is raised. + """ + for key in self.keys(): + yield key, self[key] + + def values(self): + """Iterates over all the subviews contained in dictionaries from + *all* sources at this view. If the object for this view in any + source is not a dict, then a ConfigTypeError is raised. + """ + for key in self.keys(): + yield self[key] + + # List/sequence emulation. + + def all_contents(self): + """Iterates over all subviews from collections at this view from + *all* sources. If the object for this view in any source is not + iterable, then a ConfigTypeError is raised. This method is + intended to be used when the view indicates a list; this method + will concatenate the contents of the list from all sources. + """ + for collection, _ in self.resolve(): + try: + it = iter(collection) + except TypeError: + raise ConfigTypeError( + '{0} must be an iterable, not {1}'.format( + self.name, type(collection).__name__ + ) + ) + for value in it: + yield value + + # Validation and conversion. + + def get(self, typ=None): + """Returns the canonical value for the view, checked against the + passed-in type. If the value is not an instance of the given + type, a ConfigTypeError is raised. May also raise a + NotFoundError. + """ + value, _ = self.first() + + if typ is not None: + if not isinstance(typ, TYPE_TYPES): + raise TypeError('argument to get() must be a type') + + if not isinstance(value, typ): + raise ConfigTypeError( + "{0} must be of type {1}, not {2}".format( + self.name, typ.__name__, type(value).__name__ + ) + ) + + return value + + def as_filename(self): + """Get a string as a normalized as an absolute, tilde-free path. + + Relative paths are relative to the configuration directory (see + the `config_dir` method) if they come from a file. Otherwise, + they are relative to the current working directory. This helps + attain the expected behavior when using command-line options. + """ + path, source = self.first() + if not isinstance(path, BASESTRING): + raise ConfigTypeError('{0} must be a filename, not {1}'.format( + self.name, type(path).__name__ + )) + path = os.path.expanduser(STRING(path)) + + if not os.path.isabs(path) and source.filename: + # From defaults: relative to the app's directory. + path = os.path.join(self.root().config_dir(), path) + + return os.path.abspath(path) + + def as_choice(self, choices): + """Ensure that the value is among a collection of choices and + return it. If `choices` is a dictionary, then return the + corresponding value rather than the value itself (the key). + """ + value = self.get() + + if value not in choices: + raise ConfigValueError( + '{0} must be one of {1}, not {2}'.format( + self.name, repr(list(choices)), repr(value) + ) + ) + + if isinstance(choices, dict): + return choices[value] + else: + return value + + def as_number(self): + """Ensure that a value is of numeric type.""" + value = self.get() + if isinstance(value, NUMERIC_TYPES): + return value + raise ConfigTypeError( + '{0} must be numeric, not {1}'.format( + self.name, type(value).__name__ + ) + ) + + def as_str_seq(self): + """Get the value as a list of strings. The underlying configured + value can be a sequence or a single string. In the latter case, + the string is treated as a white-space separated list of words. + """ + value = self.get() + if isinstance(value, bytes): + value = value.decode('utf8', 'ignore') + + if isinstance(value, STRING): + return value.split() + else: + try: + return list(value) + except TypeError: + raise ConfigTypeError( + '{0} must be a whitespace-separated string or ' + 'a list'.format(self.name) + ) + + def flatten(self): + """Create a hierarchy of OrderedDicts containing the data from + this view, recursively reifying all views to get their + represented values. + """ + od = OrderedDict() + for key, view in self.items(): + try: + od[key] = view.flatten() + except ConfigTypeError: + od[key] = view.get() + return od + + +class RootView(ConfigView): + """The base of a view hierarchy. This view keeps track of the + sources that may be accessed by subviews. + """ + def __init__(self, sources): + """Create a configuration hierarchy for a list of sources. At + least one source must be provided. The first source in the list + has the highest priority. + """ + self.sources = list(sources) + self.name = ROOT_NAME + + def add(self, obj): + self.sources.append(ConfigSource.of(obj)) + + def set(self, value): + self.sources.insert(0, ConfigSource.of(value)) + + def resolve(self): + return ((dict(s), s) for s in self.sources) + + def clear(self): + """Remove all sources from this configuration.""" + del self.sources[:] + + def root(self): + return self + + +class Subview(ConfigView): + """A subview accessed via a subscript of a parent view.""" + def __init__(self, parent, key): + """Make a subview of a parent view for a given subscript key. + """ + self.parent = parent + self.key = key + + # Choose a human-readable name for this view. + if isinstance(self.parent, RootView): + self.name = '' + else: + self.name = self.parent.name + if not isinstance(self.key, int): + self.name += '.' + if isinstance(self.key, int): + self.name += '#{0}'.format(self.key) + elif isinstance(self.key, BASESTRING): + self.name += '{0}'.format(self.key) + else: + self.name += '{0}'.format(repr(self.key)) + + def resolve(self): + for collection, source in self.parent.resolve(): + try: + value = collection[self.key] + except IndexError: + # List index out of bounds. + continue + except KeyError: + # Dict key does not exist. + continue + except TypeError: + # Not subscriptable. + raise ConfigTypeError( + "{0} must be a collection, not {1}".format( + self.parent.name, type(collection).__name__ + ) + ) + yield value, source + + def set(self, value): + self.parent.set({self.key: value}) + + def add(self, value): + self.parent.add({self.key: value}) + + def root(self): + return self.parent.root() + + +# Config file paths, including platform-specific paths and in-package +# defaults. + +# Based on get_root_path from Flask by Armin Ronacher. +def _package_path(name): + """Returns the path to the package containing the named module or + None if the path could not be identified (e.g., if + ``name == "__main__"``). + """ + loader = pkgutil.get_loader(name) + if loader is None or name == '__main__': + return None + + if hasattr(loader, 'get_filename'): + filepath = loader.get_filename(name) + else: + # Fall back to importing the specified module. + __import__(name) + filepath = sys.modules[name].__file__ + + return os.path.dirname(os.path.abspath(filepath)) + +def config_dirs(): + """Return a platform-specific list of candidates for user + configuration directories on the system. + + The candidates are in order of priority, from highest to lowest. The + last element is the "fallback" location to be used when no + higher-priority config file exists. + """ + paths = [] + + if platform.system() == 'Darwin': + paths.append(MAC_DIR) + paths.append(UNIX_DIR_FALLBACK) + if UNIX_DIR_VAR in os.environ: + paths.append(os.environ[UNIX_DIR_VAR]) + + elif platform.system() == 'Windows': + paths.append(WINDOWS_DIR_FALLBACK) + if WINDOWS_DIR_VAR in os.environ: + paths.append(os.environ[WINDOWS_DIR_VAR]) + + else: + # Assume Unix. + paths.append(UNIX_DIR_FALLBACK) + if UNIX_DIR_VAR in os.environ: + paths.append(os.environ[UNIX_DIR_VAR]) + + # Expand and deduplicate paths. + out = [] + for path in paths: + path = os.path.abspath(os.path.expanduser(path)) + if path not in out: + out.append(path) + return out + + +# YAML loading. + +class Loader(yaml.SafeLoader): + """A customized YAML loader. This loader deviates from the official + YAML spec in a few convenient ways: + + - All strings as are Unicode objects. + - All maps are OrderedDicts. + - Strings can begin with % without quotation. + """ + # All strings should be Unicode objects, regardless of contents. + def _construct_unicode(self, node): + return self.construct_scalar(node) + + # Use ordered dictionaries for every YAML map. + # From https://gist.github.com/844388 + def construct_yaml_map(self, node): + data = OrderedDict() + yield data + value = self.construct_mapping(node) + data.update(value) + + def construct_mapping(self, node, deep=False): + if isinstance(node, yaml.MappingNode): + self.flatten_mapping(node) + else: + raise yaml.constructor.ConstructorError( + None, None, + 'expected a mapping node, but found %s' % node.id, + node.start_mark + ) + + mapping = OrderedDict() + for key_node, value_node in node.value: + key = self.construct_object(key_node, deep=deep) + try: + hash(key) + except TypeError as exc: + raise yaml.constructor.ConstructorError( + 'while constructing a mapping', + node.start_mark, 'found unacceptable key (%s)' % exc, + key_node.start_mark + ) + value = self.construct_object(value_node, deep=deep) + mapping[key] = value + return mapping + + # Allow bare strings to begin with %. Directives are still detected. + def check_plain(self): + plain = super(Loader, self).check_plain() + return plain or self.peek() == '%' + +Loader.add_constructor('tag:yaml.org,2002:str', Loader._construct_unicode) +Loader.add_constructor('tag:yaml.org,2002:map', Loader.construct_yaml_map) +Loader.add_constructor('tag:yaml.org,2002:omap', Loader.construct_yaml_map) + +def load_yaml(filename): + """Read a YAML document from a file. If the file cannot be read or + parsed, a ConfigReadError is raised. + """ + try: + with open(filename, 'r') as f: + return yaml.load(f, Loader=Loader) + except (IOError, yaml.error.YAMLError) as exc: + raise ConfigReadError(filename, exc) + + +# YAML dumping. + +class Dumper(yaml.SafeDumper): + """A PyYAML Dumper that represents OrderedDicts as ordinary mappings + (in order, of course). + """ + # From http://pyyaml.org/attachment/ticket/161/use_ordered_dict.py + def represent_mapping(self, tag, mapping, flow_style=None): + value = [] + node = yaml.MappingNode(tag, value, flow_style=flow_style) + if self.alias_key is not None: + self.represented_objects[self.alias_key] = node + best_style = False + if hasattr(mapping, 'items'): + mapping = list(mapping.items()) + for item_key, item_value in mapping: + node_key = self.represent_data(item_key) + node_value = self.represent_data(item_value) + if not (isinstance(node_key, yaml.ScalarNode) + and not node_key.style): + best_style = False + if not (isinstance(node_value, yaml.ScalarNode) + and not node_value.style): + best_style = False + value.append((node_key, node_value)) + if flow_style is None: + if self.default_flow_style is not None: + node.flow_style = self.default_flow_style + else: + node.flow_style = best_style + return node + + def represent_list(self, data): + """If a list has less than 4 items, represent it in inline style + (i.e. comma separated, within square brackets). + """ + node = super(Dumper, self).represent_list(data) + length = len(data) + if self.default_flow_style is None and length < 4: + node.flow_style = True + elif self.default_flow_style is None: + node.flow_style = False + return node + + def represent_bool(self, data): + """Represent bool as 'yes' or 'no' instead of 'true' or 'false'. + """ + if data: + value = 'yes' + else: + value = 'no' + return self.represent_scalar('tag:yaml.org,2002:bool', value) + + def represent_none(self, data): + """Represent a None value with nothing instead of 'none'. + """ + return self.represent_scalar('tag:yaml.org,2002:null', '') + +Dumper.add_representer(OrderedDict, Dumper.represent_dict) +Dumper.add_representer(bool, Dumper.represent_bool) +Dumper.add_representer(type(None), Dumper.represent_none) +Dumper.add_representer(list, Dumper.represent_list) + +def restore_yaml_comments(data, default_data): + """Scan default_data for comments (we include empty lines in our + definition of comments) and place them before the same keys in data. + Only works with comments that are on one or more own lines, i.e. + not next to a yaml mapping. + """ + comment_map = dict() + default_lines = iter(default_data.splitlines()) + for line in default_lines: + if not line: + comment = "\n" + elif line.startswith("#"): + comment = "{0}\n".format(line) + else: + continue + while True: + line = next(default_lines) + if line and not line.startswith("#"): + break + comment += "{0}\n".format(line) + key = line.split(':')[0].strip() + comment_map[key] = comment + out_lines = iter(data.splitlines()) + out_data = "" + for line in out_lines: + key = line.split(':')[0].strip() + if key in comment_map: + out_data += comment_map[key] + out_data += "{0}\n".format(line) + return out_data + + +# Main interface. + +class Configuration(RootView): + def __init__(self, appname, modname=None, read=True): + """Create a configuration object by reading the + automatically-discovered config files for the application for a + given name. If `modname` is specified, it should be the import + name of a module whose package will be searched for a default + config file. (Otherwise, no defaults are used.) Pass `False` for + `read` to disable automatic reading of all discovered + configuration files. Use this when creating a configuration + object at module load time and then call the `read` method + later. + """ + super(Configuration, self).__init__([]) + self.appname = appname + self.modname = modname + + self._env_var = '{0}DIR'.format(self.appname.upper()) + + if read: + self.read() + + def user_config_path(self): + """Points to the location of the user configuration. + + The file may not exist. + """ + return os.path.join(self.config_dir(), CONFIG_FILENAME) + + def _add_user_source(self): + """Add the configuration options from the YAML file in the + user's configuration directory (given by `config_dir`) if it + exists. + """ + filename = self.user_config_path() + if os.path.isfile(filename): + self.add(ConfigSource(load_yaml(filename) or {}, filename)) + + def _add_default_source(self): + """Add the package's default configuration settings. This looks + for a YAML file located inside the package for the module + `modname` if it was given. + """ + if self.modname: + pkg_path = _package_path(self.modname) + if pkg_path: + filename = os.path.join(pkg_path, DEFAULT_FILENAME) + if os.path.isfile(filename): + self.add(ConfigSource(load_yaml(filename), filename, True)) + + def read(self, user=True, defaults=True): + """Find and read the files for this configuration and set them + as the sources for this configuration. To disable either + discovered user configuration files or the in-package defaults, + set `user` or `defaults` to `False`. + """ + if user: + self._add_user_source() + if defaults: + self._add_default_source() + + def config_dir(self): + """Get the path to the user configuration directory. The + directory is guaranteed to exist as a postcondition (one may be + created if none exist). + + If the application's ``...DIR`` environment variable is set, it + is used as the configuration directory. Otherwise, + platform-specific standard configuration locations are searched + for a ``config.yaml`` file. If no configuration file is found, a + fallback path is used. + """ + # If environment variable is set, use it. + if self._env_var in os.environ: + appdir = os.environ[self._env_var] + appdir = os.path.abspath(os.path.expanduser(appdir)) + if os.path.isfile(appdir): + raise ConfigError('{0} must be a directory'.format( + self._env_var + )) + + else: + # Search platform-specific locations. If no config file is + # found, fall back to the final directory in the list. + for confdir in config_dirs(): + appdir = os.path.join(confdir, self.appname) + if os.path.isfile(os.path.join(appdir, CONFIG_FILENAME)): + break + + # Ensure that the directory exists. + if not os.path.isdir(appdir): + os.makedirs(appdir) + return appdir + + def set_file(self, filename): + """Parses the file as YAML and inserts it into the configuration + sources with highest priority. + """ + filename = os.path.abspath(filename) + self.set(ConfigSource(load_yaml(filename), filename)) + + def dump(self, full=True): + """Dump the Configuration object to a YAML file. + + The order of the keys is determined from the default + configuration file. All keys not in the default configuration + will be appended to the end of the file. + + :param filename: The file to dump the configuration to, or None + if the YAML string should be returned instead + :type filename: unicode + :param full: Dump settings that don't differ from the defaults + as well + """ + if full: + out_dict = self.flatten() + else: + # Exclude defaults when flattening. + sources = [s for s in self.sources if not s.default] + out_dict = RootView(sources).flatten() + + yaml_out = yaml.dump(out_dict, Dumper=Dumper, + default_flow_style=None, indent=4, + width=1000) + + # Restore comments to the YAML text. + default_source = None + for source in self.sources: + if source.default: + default_source = source + break + if default_source: + with open(default_source.filename, 'r') as fp: + default_data = fp.read() + yaml_out = restore_yaml_comments(yaml_out, default_data) + + return yaml_out + + +class LazyConfig(Configuration): + """A Configuration at reads files on demand when it is first + accessed. This is appropriate for using as a global config object at + the module level. + """ + def __init__(self, appname, modname=None): + super(LazyConfig, self).__init__(appname, modname, False) + self._materialized = False # Have we read the files yet? + self._lazy_prefix = [] # Pre-materialization calls to set(). + self._lazy_suffix = [] # Calls to add(). + + def read(self, user=True, defaults=True): + self._materialized = True + super(LazyConfig, self).read(user, defaults) + + def resolve(self): + if not self._materialized: + # Read files and unspool buffers. + self.read() + self.sources += self._lazy_suffix + self.sources[:0] = self._lazy_prefix + return super(LazyConfig, self).resolve() + + def add(self, value): + super(LazyConfig, self).add(value) + if not self._materialized: + # Buffer additions to end. + self._lazy_suffix += self.sources + del self.sources[:] + + def set(self, value): + super(LazyConfig, self).set(value) + if not self._materialized: + # Buffer additions to beginning. + self._lazy_prefix[:0] = self.sources + del self.sources[:] + + def clear(self): + """Remove all sources from this configuration.""" + del self.sources[:] + self._lazy_suffix = [] + self._lazy_prefix = [] diff --git a/libs/beets/util/enumeration.py b/libs/beets/util/enumeration.py new file mode 100644 index 00000000..e6ec0766 --- /dev/null +++ b/libs/beets/util/enumeration.py @@ -0,0 +1,178 @@ +# This file is part of beets. +# Copyright 2013, Adrian Sampson. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. + +"""A metaclass for enumerated types that really are types. + +You can create enumerations with `enum(values, [name])` and they work +how you would expect them to. + + >>> from enumeration import enum + >>> Direction = enum('north east south west', name='Direction') + >>> Direction.west + Direction.west + >>> Direction.west == Direction.west + True + >>> Direction.west == Direction.east + False + >>> isinstance(Direction.west, Direction) + True + >>> Direction[3] + Direction.west + >>> Direction['west'] + Direction.west + >>> Direction.west.name + 'west' + >>> Direction.north < Direction.west + True + +Enumerations are classes; their instances represent the possible values +of the enumeration. Because Python classes must have names, you may +provide a `name` parameter to `enum`; if you don't, a meaningless one +will be chosen for you. +""" +import random + +class Enumeration(type): + """A metaclass whose classes are enumerations. + + The `values` attribute of the class is used to populate the + enumeration. Values may either be a list of enumerated names or a + string containing a space-separated list of names. When the class + is created, it is instantiated for each name value in `values`. + Each such instance is the name of the enumerated item as the sole + argument. + + The `Enumerated` class is a good choice for a superclass. + """ + + def __init__(cls, name, bases, dic): + super(Enumeration, cls).__init__(name, bases, dic) + + if 'values' not in dic: + # Do nothing if no values are provided (i.e., with + # Enumerated itself). + return + + # May be called with a single string, in which case we split on + # whitespace for convenience. + values = dic['values'] + if isinstance(values, basestring): + values = values.split() + + # Create the Enumerated instances for each value. We have to use + # super's __setattr__ here because we disallow setattr below. + super(Enumeration, cls).__setattr__('_items_dict', {}) + super(Enumeration, cls).__setattr__('_items_list', []) + for value in values: + item = cls(value, len(cls._items_list)) + cls._items_dict[value] = item + cls._items_list.append(item) + + def __getattr__(cls, key): + try: + return cls._items_dict[key] + except KeyError: + raise AttributeError("enumeration '" + cls.__name__ + + "' has no item '" + key + "'") + + def __setattr__(cls, key, val): + raise TypeError("enumerations do not support attribute assignment") + + def __getitem__(cls, key): + if isinstance(key, int): + return cls._items_list[key] + else: + return getattr(cls, key) + + def __len__(cls): + return len(cls._items_list) + + def __iter__(cls): + return iter(cls._items_list) + + def __nonzero__(cls): + # Ensures that __len__ doesn't get called before __init__ by + # pydoc. + return True + +class Enumerated(object): + """An item in an enumeration. + + Contains instance methods inherited by enumerated objects. The + metaclass is preset to `Enumeration` for your convenience. + + Instance attributes: + name -- The name of the item. + index -- The index of the item in its enumeration. + + >>> from enumeration import Enumerated + >>> class Garment(Enumerated): + ... values = 'hat glove belt poncho lederhosen suspenders' + ... def wear(self): + ... print('now wearing a ' + self.name) + ... + >>> Garment.poncho.wear() + now wearing a poncho + """ + + __metaclass__ = Enumeration + + def __init__(self, name, index): + self.name = name + self.index = index + + def __str__(self): + return type(self).__name__ + '.' + self.name + + def __repr__(self): + return str(self) + + def __cmp__(self, other): + if type(self) is type(other): + # Note that we're assuming that the items are direct + # instances of the same Enumeration (i.e., no fancy + # subclassing), which is probably okay. + return cmp(self.index, other.index) + else: + return NotImplemented + +def enum(*values, **kwargs): + """Shorthand for creating a new Enumeration class. + + Call with enumeration values as a list, a space-delimited string, or + just an argument list. To give the class a name, pass it as the + `name` keyword argument. Otherwise, a name will be chosen for you. + + The following are all equivalent: + + enum('pinkie ring middle index thumb') + enum('pinkie', 'ring', 'middle', 'index', 'thumb') + enum(['pinkie', 'ring', 'middle', 'index', 'thumb']) + """ + + if ('name' not in kwargs) or kwargs['name'] is None: + # Create a probably-unique name. It doesn't really have to be + # unique, but getting distinct names each time helps with + # identification in debugging. + name = 'Enumeration' + hex(random.randint(0,0xfffffff))[2:].upper() + else: + name = kwargs['name'] + + if len(values) == 1: + # If there's only one value, we have a couple of alternate calling + # styles. + if isinstance(values[0], basestring) or hasattr(values[0], '__iter__'): + values = values[0] + + return type(name, (Enumerated,), {'values': values}) diff --git a/libs/beets/util/functemplate.py b/libs/beets/util/functemplate.py new file mode 100644 index 00000000..0fce41e5 --- /dev/null +++ b/libs/beets/util/functemplate.py @@ -0,0 +1,561 @@ +# This file is part of beets. +# Copyright 2013, Adrian Sampson. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. + +"""This module implements a string formatter based on the standard PEP +292 string.Template class extended with function calls. Variables, as +with string.Template, are indicated with $ and functions are delimited +with %. + +This module assumes that everything is Unicode: the template and the +substitution values. Bytestrings are not supported. Also, the templates +always behave like the ``safe_substitute`` method in the standard +library: unknown symbols are left intact. + +This is sort of like a tiny, horrible degeneration of a real templating +engine like Jinja2 or Mustache. +""" +from __future__ import print_function + +import re +import ast +import dis +import types + +SYMBOL_DELIM = u'$' +FUNC_DELIM = u'%' +GROUP_OPEN = u'{' +GROUP_CLOSE = u'}' +ARG_SEP = u',' +ESCAPE_CHAR = u'$' + +VARIABLE_PREFIX = '__var_' +FUNCTION_PREFIX = '__func_' + +class Environment(object): + """Contains the values and functions to be substituted into a + template. + """ + def __init__(self, values, functions): + self.values = values + self.functions = functions + + +# Code generation helpers. + +def ex_lvalue(name): + """A variable load expression.""" + return ast.Name(name, ast.Store()) + +def ex_rvalue(name): + """A variable store expression.""" + return ast.Name(name, ast.Load()) + +def ex_literal(val): + """An int, float, long, bool, string, or None literal with the given + value. + """ + if val is None: + return ast.Name('None', ast.Load()) + elif isinstance(val, (int, float, long)): + return ast.Num(val) + elif isinstance(val, bool): + return ast.Name(str(val), ast.Load()) + elif isinstance(val, basestring): + return ast.Str(val) + raise TypeError('no literal for {0}'.format(type(val))) + +def ex_varassign(name, expr): + """Assign an expression into a single variable. The expression may + either be an `ast.expr` object or a value to be used as a literal. + """ + if not isinstance(expr, ast.expr): + expr = ex_literal(expr) + return ast.Assign([ex_lvalue(name)], expr) + +def ex_call(func, args): + """A function-call expression with only positional parameters. The + function may be an expression or the name of a function. Each + argument may be an expression or a value to be used as a literal. + """ + if isinstance(func, basestring): + func = ex_rvalue(func) + + args = list(args) + for i in range(len(args)): + if not isinstance(args[i], ast.expr): + args[i] = ex_literal(args[i]) + + return ast.Call(func, args, [], None, None) + +def compile_func(arg_names, statements, name='_the_func', debug=False): + """Compile a list of statements as the body of a function and return + the resulting Python function. If `debug`, then print out the + bytecode of the compiled function. + """ + func_def = ast.FunctionDef( + name, + ast.arguments( + [ast.Name(n, ast.Param()) for n in arg_names], + None, None, + [ex_literal(None) for _ in arg_names], + ), + statements, + [], + ) + mod = ast.Module([func_def]) + ast.fix_missing_locations(mod) + + prog = compile(mod, '', 'exec') + + # Debug: show bytecode. + if debug: + dis.dis(prog) + for const in prog.co_consts: + if isinstance(const, types.CodeType): + dis.dis(const) + + the_locals = {} + exec prog in {}, the_locals + return the_locals[name] + + +# AST nodes for the template language. + +class Symbol(object): + """A variable-substitution symbol in a template.""" + def __init__(self, ident, original): + self.ident = ident + self.original = original + + def __repr__(self): + return u'Symbol(%s)' % repr(self.ident) + + def evaluate(self, env): + """Evaluate the symbol in the environment, returning a Unicode + string. + """ + if self.ident in env.values: + # Substitute for a value. + return env.values[self.ident] + else: + # Keep original text. + return self.original + + def translate(self): + """Compile the variable lookup.""" + expr = ex_rvalue(VARIABLE_PREFIX + self.ident.encode('utf8')) + return [expr], set([self.ident.encode('utf8')]), set() + +class Call(object): + """A function call in a template.""" + def __init__(self, ident, args, original): + self.ident = ident + self.args = args + self.original = original + + def __repr__(self): + return u'Call(%s, %s, %s)' % (repr(self.ident), repr(self.args), + repr(self.original)) + + def evaluate(self, env): + """Evaluate the function call in the environment, returning a + Unicode string. + """ + if self.ident in env.functions: + arg_vals = [expr.evaluate(env) for expr in self.args] + try: + out = env.functions[self.ident](*arg_vals) + except Exception as exc: + # Function raised exception! Maybe inlining the name of + # the exception will help debug. + return u'<%s>' % unicode(exc) + return unicode(out) + else: + return self.original + + def translate(self): + """Compile the function call.""" + varnames = set() + funcnames = set([self.ident.encode('utf8')]) + + arg_exprs = [] + for arg in self.args: + subexprs, subvars, subfuncs = arg.translate() + varnames.update(subvars) + funcnames.update(subfuncs) + + # Create a subexpression that joins the result components of + # the arguments. + arg_exprs.append(ex_call( + ast.Attribute(ex_literal(u''), 'join', ast.Load()), + [ex_call( + 'map', + [ + ex_rvalue('unicode'), + ast.List(subexprs, ast.Load()), + ] + )], + )) + + subexpr_call = ex_call( + FUNCTION_PREFIX + self.ident.encode('utf8'), + arg_exprs + ) + return [subexpr_call], varnames, funcnames + +class Expression(object): + """Top-level template construct: contains a list of text blobs, + Symbols, and Calls. + """ + def __init__(self, parts): + self.parts = parts + + def __repr__(self): + return u'Expression(%s)' % (repr(self.parts)) + + def evaluate(self, env): + """Evaluate the entire expression in the environment, returning + a Unicode string. + """ + out = [] + for part in self.parts: + if isinstance(part, basestring): + out.append(part) + else: + out.append(part.evaluate(env)) + return u''.join(map(unicode, out)) + + def translate(self): + """Compile the expression to a list of Python AST expressions, a + set of variable names used, and a set of function names. + """ + expressions = [] + varnames = set() + funcnames = set() + for part in self.parts: + if isinstance(part, basestring): + expressions.append(ex_literal(part)) + else: + e, v, f = part.translate() + expressions.extend(e) + varnames.update(v) + funcnames.update(f) + return expressions, varnames, funcnames + + +# Parser. + +class ParseError(Exception): + pass + +class Parser(object): + """Parses a template expression string. Instantiate the class with + the template source and call ``parse_expression``. The ``pos`` field + will indicate the character after the expression finished and + ``parts`` will contain a list of Unicode strings, Symbols, and Calls + reflecting the concatenated portions of the expression. + + This is a terrible, ad-hoc parser implementation based on a + left-to-right scan with no lexing step to speak of; it's probably + both inefficient and incorrect. Maybe this should eventually be + replaced with a real, accepted parsing technique (PEG, parser + generator, etc.). + """ + def __init__(self, string): + self.string = string + self.pos = 0 + self.parts = [] + + # Common parsing resources. + special_chars = (SYMBOL_DELIM, FUNC_DELIM, GROUP_OPEN, GROUP_CLOSE, + ARG_SEP, ESCAPE_CHAR) + special_char_re = re.compile(ur'[%s]|$' % + u''.join(re.escape(c) for c in special_chars)) + + def parse_expression(self): + """Parse a template expression starting at ``pos``. Resulting + components (Unicode strings, Symbols, and Calls) are added to + the ``parts`` field, a list. The ``pos`` field is updated to be + the next character after the expression. + """ + text_parts = [] + + while self.pos < len(self.string): + char = self.string[self.pos] + + if char not in self.special_chars: + # A non-special character. Skip to the next special + # character, treating the interstice as literal text. + next_pos = ( + self.special_char_re.search(self.string[self.pos:]).start() + + self.pos + ) + text_parts.append(self.string[self.pos:next_pos]) + self.pos = next_pos + continue + + if self.pos == len(self.string) - 1: + # The last character can never begin a structure, so we + # just interpret it as a literal character (unless it + # terminates the expression, as with , and }). + if char not in (GROUP_CLOSE, ARG_SEP): + text_parts.append(char) + self.pos += 1 + break + + next_char = self.string[self.pos + 1] + if char == ESCAPE_CHAR and next_char in \ + (SYMBOL_DELIM, FUNC_DELIM, GROUP_CLOSE, ARG_SEP): + # An escaped special character ($$, $}, etc.). Note that + # ${ is not an escape sequence: this is ambiguous with + # the start of a symbol and it's not necessary (just + # using { suffices in all cases). + text_parts.append(next_char) + self.pos += 2 # Skip the next character. + continue + + # Shift all characters collected so far into a single string. + if text_parts: + self.parts.append(u''.join(text_parts)) + text_parts = [] + + if char == SYMBOL_DELIM: + # Parse a symbol. + self.parse_symbol() + elif char == FUNC_DELIM: + # Parse a function call. + self.parse_call() + elif char in (GROUP_CLOSE, ARG_SEP): + # Template terminated. + break + elif char == GROUP_OPEN: + # Start of a group has no meaning hear; just pass + # through the character. + text_parts.append(char) + self.pos += 1 + else: + assert False + + # If any parsed characters remain, shift them into a string. + if text_parts: + self.parts.append(u''.join(text_parts)) + + def parse_symbol(self): + """Parse a variable reference (like ``$foo`` or ``${foo}``) + starting at ``pos``. Possibly appends a Symbol object (or, + failing that, text) to the ``parts`` field and updates ``pos``. + The character at ``pos`` must, as a precondition, be ``$``. + """ + assert self.pos < len(self.string) + assert self.string[self.pos] == SYMBOL_DELIM + + if self.pos == len(self.string) - 1: + # Last character. + self.parts.append(SYMBOL_DELIM) + self.pos += 1 + return + + next_char = self.string[self.pos + 1] + start_pos = self.pos + self.pos += 1 + + if next_char == GROUP_OPEN: + # A symbol like ${this}. + self.pos += 1 # Skip opening. + closer = self.string.find(GROUP_CLOSE, self.pos) + if closer == -1 or closer == self.pos: + # No closing brace found or identifier is empty. + self.parts.append(self.string[start_pos:self.pos]) + else: + # Closer found. + ident = self.string[self.pos:closer] + self.pos = closer + 1 + self.parts.append(Symbol(ident, + self.string[start_pos:self.pos])) + + else: + # A bare-word symbol. + ident = self._parse_ident() + if ident: + # Found a real symbol. + self.parts.append(Symbol(ident, + self.string[start_pos:self.pos])) + else: + # A standalone $. + self.parts.append(SYMBOL_DELIM) + + def parse_call(self): + """Parse a function call (like ``%foo{bar,baz}``) starting at + ``pos``. Possibly appends a Call object to ``parts`` and update + ``pos``. The character at ``pos`` must be ``%``. + """ + assert self.pos < len(self.string) + assert self.string[self.pos] == FUNC_DELIM + + start_pos = self.pos + self.pos += 1 + + ident = self._parse_ident() + if not ident: + # No function name. + self.parts.append(FUNC_DELIM) + return + + if self.pos >= len(self.string): + # Identifier terminates string. + self.parts.append(self.string[start_pos:self.pos]) + return + + if self.string[self.pos] != GROUP_OPEN: + # Argument list not opened. + self.parts.append(self.string[start_pos:self.pos]) + return + + # Skip past opening brace and try to parse an argument list. + self.pos += 1 + args = self.parse_argument_list() + if self.pos >= len(self.string) or \ + self.string[self.pos] != GROUP_CLOSE: + # Arguments unclosed. + self.parts.append(self.string[start_pos:self.pos]) + return + + self.pos += 1 # Move past closing brace. + self.parts.append(Call(ident, args, self.string[start_pos:self.pos])) + + def parse_argument_list(self): + """Parse a list of arguments starting at ``pos``, returning a + list of Expression objects. Does not modify ``parts``. Should + leave ``pos`` pointing to a } character or the end of the + string. + """ + # Try to parse a subexpression in a subparser. + expressions = [] + + while self.pos < len(self.string): + subparser = Parser(self.string[self.pos:]) + subparser.parse_expression() + + # Extract and advance past the parsed expression. + expressions.append(Expression(subparser.parts)) + self.pos += subparser.pos + + if self.pos >= len(self.string) or \ + self.string[self.pos] == GROUP_CLOSE: + # Argument list terminated by EOF or closing brace. + break + + # Only other way to terminate an expression is with ,. + # Continue to the next argument. + assert self.string[self.pos] == ARG_SEP + self.pos += 1 + + return expressions + + def _parse_ident(self): + """Parse an identifier and return it (possibly an empty string). + Updates ``pos``. + """ + remainder = self.string[self.pos:] + ident = re.match(ur'\w*', remainder).group(0) + self.pos += len(ident) + return ident + +def _parse(template): + """Parse a top-level template string Expression. Any extraneous text + is considered literal text. + """ + parser = Parser(template) + parser.parse_expression() + + parts = parser.parts + remainder = parser.string[parser.pos:] + if remainder: + parts.append(remainder) + return Expression(parts) + + +# External interface. + +class Template(object): + """A string template, including text, Symbols, and Calls. + """ + def __init__(self, template): + self.expr = _parse(template) + self.original = template + self.compiled = self.translate() + + def __eq__(self, other): + return self.original == other.original + + def interpret(self, values={}, functions={}): + """Like `substitute`, but forces the interpreter (rather than + the compiled version) to be used. The interpreter includes + exception-handling code for missing variables and buggy template + functions but is much slower. + """ + return self.expr.evaluate(Environment(values, functions)) + + def substitute(self, values={}, functions={}): + """Evaluate the template given the values and functions. + """ + try: + res = self.compiled(values, functions) + except: # Handle any exceptions thrown by compiled version. + res = self.interpret(values, functions) + return res + + def translate(self): + """Compile the template to a Python function.""" + expressions, varnames, funcnames = self.expr.translate() + + argnames = [] + for varname in varnames: + argnames.append(VARIABLE_PREFIX.encode('utf8') + varname) + for funcname in funcnames: + argnames.append(FUNCTION_PREFIX.encode('utf8') + funcname) + + func = compile_func( + argnames, + [ast.Return(ast.List(expressions, ast.Load()))], + ) + + def wrapper_func(values={}, functions={}): + args = {} + for varname in varnames: + args[VARIABLE_PREFIX + varname] = values[varname] + for funcname in funcnames: + args[FUNCTION_PREFIX + funcname] = functions[funcname] + parts = func(**args) + return u''.join(parts) + + return wrapper_func + + +# Performance tests. + +if __name__ == '__main__': + import timeit + _tmpl = Template(u'foo $bar %baz{foozle $bar barzle} $bar') + _vars = {'bar': 'qux'} + _funcs = {'baz': unicode.upper} + interp_time = timeit.timeit('_tmpl.interpret(_vars, _funcs)', + 'from __main__ import _tmpl, _vars, _funcs', + number=10000) + print(interp_time) + comp_time = timeit.timeit('_tmpl.substitute(_vars, _funcs)', + 'from __main__ import _tmpl, _vars, _funcs', + number=10000) + print(comp_time) + print('Speedup:', interp_time / comp_time) diff --git a/libs/beets/util/pipeline.py b/libs/beets/util/pipeline.py new file mode 100644 index 00000000..c64454ff --- /dev/null +++ b/libs/beets/util/pipeline.py @@ -0,0 +1,454 @@ +# This file is part of beets. +# Copyright 2013, Adrian Sampson. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. + +"""Simple but robust implementation of generator/coroutine-based +pipelines in Python. The pipelines may be run either sequentially +(single-threaded) or in parallel (one thread per pipeline stage). + +This implementation supports pipeline bubbles (indications that the +processing for a certain item should abort). To use them, yield the +BUBBLE constant from any stage coroutine except the last. + +In the parallel case, the implementation transparently handles thread +shutdown when the processing is complete and when a stage raises an +exception. KeyboardInterrupts (^C) are also handled. + +When running a parallel pipeline, it is also possible to use +multiple coroutines for the same pipeline stage; this lets you speed +up a bottleneck stage by dividing its work among multiple threads. +To do so, pass an iterable of coroutines to the Pipeline constructor +in place of any single coroutine. +""" +from __future__ import print_function + +import Queue +from threading import Thread, Lock +import sys +import types + +BUBBLE = '__PIPELINE_BUBBLE__' +POISON = '__PIPELINE_POISON__' + +DEFAULT_QUEUE_SIZE = 16 + +def _invalidate_queue(q, val=None, sync=True): + """Breaks a Queue such that it never blocks, always has size 1, + and has no maximum size. get()ing from the queue returns `val`, + which defaults to None. `sync` controls whether a lock is + required (because it's not reentrant!). + """ + def _qsize(len=len): + return 1 + def _put(item): + pass + def _get(): + return val + + if sync: + q.mutex.acquire() + + try: + q.maxsize = 0 + q._qsize = _qsize + q._put = _put + q._get = _get + q.not_empty.notifyAll() + q.not_full.notifyAll() + + finally: + if sync: + q.mutex.release() + +class CountedQueue(Queue.Queue): + """A queue that keeps track of the number of threads that are + still feeding into it. The queue is poisoned when all threads are + finished with the queue. + """ + def __init__(self, maxsize=0): + Queue.Queue.__init__(self, maxsize) + self.nthreads = 0 + self.poisoned = False + + def acquire(self): + """Indicate that a thread will start putting into this queue. + Should not be called after the queue is already poisoned. + """ + with self.mutex: + assert not self.poisoned + assert self.nthreads >= 0 + self.nthreads += 1 + + def release(self): + """Indicate that a thread that was putting into this queue has + exited. If this is the last thread using the queue, the queue + is poisoned. + """ + with self.mutex: + self.nthreads -= 1 + assert self.nthreads >= 0 + if self.nthreads == 0: + # All threads are done adding to this queue. Poison it + # when it becomes empty. + self.poisoned = True + + # Replacement _get invalidates when no items remain. + _old_get = self._get + def _get(): + out = _old_get() + if not self.queue: + _invalidate_queue(self, POISON, False) + return out + + if self.queue: + # Items remain. + self._get = _get + else: + # No items. Invalidate immediately. + _invalidate_queue(self, POISON, False) + +class MultiMessage(object): + """A message yielded by a pipeline stage encapsulating multiple + values to be sent to the next stage. + """ + def __init__(self, messages): + self.messages = messages +def multiple(messages): + """Yield multiple([message, ..]) from a pipeline stage to send + multiple values to the next pipeline stage. + """ + return MultiMessage(messages) + +def _allmsgs(obj): + """Returns a list of all the messages encapsulated in obj. If obj + is a MultiMessage, returns its enclosed messages. If obj is BUBBLE, + returns an empty list. Otherwise, returns a list containing obj. + """ + if isinstance(obj, MultiMessage): + return obj.messages + elif obj == BUBBLE: + return [] + else: + return [obj] + +class PipelineThread(Thread): + """Abstract base class for pipeline-stage threads.""" + def __init__(self, all_threads): + super(PipelineThread, self).__init__() + self.abort_lock = Lock() + self.abort_flag = False + self.all_threads = all_threads + self.exc_info = None + + def abort(self): + """Shut down the thread at the next chance possible. + """ + with self.abort_lock: + self.abort_flag = True + + # Ensure that we are not blocking on a queue read or write. + if hasattr(self, 'in_queue'): + _invalidate_queue(self.in_queue, POISON) + if hasattr(self, 'out_queue'): + _invalidate_queue(self.out_queue, POISON) + + def abort_all(self, exc_info): + """Abort all other threads in the system for an exception. + """ + self.exc_info = exc_info + for thread in self.all_threads: + thread.abort() + +class FirstPipelineThread(PipelineThread): + """The thread running the first stage in a parallel pipeline setup. + The coroutine should just be a generator. + """ + def __init__(self, coro, out_queue, all_threads): + super(FirstPipelineThread, self).__init__(all_threads) + self.coro = coro + self.out_queue = out_queue + self.out_queue.acquire() + + self.abort_lock = Lock() + self.abort_flag = False + + def run(self): + try: + while True: + with self.abort_lock: + if self.abort_flag: + return + + # Get the value from the generator. + try: + msg = self.coro.next() + except StopIteration: + break + + # Send messages to the next stage. + for msg in _allmsgs(msg): + with self.abort_lock: + if self.abort_flag: + return + self.out_queue.put(msg) + + except: + self.abort_all(sys.exc_info()) + return + + # Generator finished; shut down the pipeline. + self.out_queue.release() + +class MiddlePipelineThread(PipelineThread): + """A thread running any stage in the pipeline except the first or + last. + """ + def __init__(self, coro, in_queue, out_queue, all_threads): + super(MiddlePipelineThread, self).__init__(all_threads) + self.coro = coro + self.in_queue = in_queue + self.out_queue = out_queue + self.out_queue.acquire() + + def run(self): + try: + # Prime the coroutine. + self.coro.next() + + while True: + with self.abort_lock: + if self.abort_flag: + return + + # Get the message from the previous stage. + msg = self.in_queue.get() + if msg is POISON: + break + + with self.abort_lock: + if self.abort_flag: + return + + # Invoke the current stage. + out = self.coro.send(msg) + + # Send messages to next stage. + for msg in _allmsgs(out): + with self.abort_lock: + if self.abort_flag: + return + self.out_queue.put(msg) + + except: + self.abort_all(sys.exc_info()) + return + + # Pipeline is shutting down normally. + self.out_queue.release() + +class LastPipelineThread(PipelineThread): + """A thread running the last stage in a pipeline. The coroutine + should yield nothing. + """ + def __init__(self, coro, in_queue, all_threads): + super(LastPipelineThread, self).__init__(all_threads) + self.coro = coro + self.in_queue = in_queue + + def run(self): + # Prime the coroutine. + self.coro.next() + + try: + while True: + with self.abort_lock: + if self.abort_flag: + return + + # Get the message from the previous stage. + msg = self.in_queue.get() + if msg is POISON: + break + + with self.abort_lock: + if self.abort_flag: + return + + # Send to consumer. + self.coro.send(msg) + + except: + self.abort_all(sys.exc_info()) + return + +class Pipeline(object): + """Represents a staged pattern of work. Each stage in the pipeline + is a coroutine that receives messages from the previous stage and + yields messages to be sent to the next stage. + """ + def __init__(self, stages): + """Makes a new pipeline from a list of coroutines. There must + be at least two stages. + """ + if len(stages) < 2: + raise ValueError('pipeline must have at least two stages') + self.stages = [] + for stage in stages: + if isinstance(stage, (list, tuple)): + self.stages.append(stage) + else: + # Default to one thread per stage. + self.stages.append((stage,)) + + def run_sequential(self): + """Run the pipeline sequentially in the current thread. The + stages are run one after the other. Only the first coroutine + in each stage is used. + """ + list(self.pull()) + + def run_parallel(self, queue_size=DEFAULT_QUEUE_SIZE): + """Run the pipeline in parallel using one thread per stage. The + messages between the stages are stored in queues of the given + size. + """ + queues = [CountedQueue(queue_size) for i in range(len(self.stages)-1)] + threads = [] + + # Set up first stage. + for coro in self.stages[0]: + threads.append(FirstPipelineThread(coro, queues[0], threads)) + + # Middle stages. + for i in range(1, len(self.stages)-1): + for coro in self.stages[i]: + threads.append(MiddlePipelineThread( + coro, queues[i-1], queues[i], threads + )) + + # Last stage. + for coro in self.stages[-1]: + threads.append( + LastPipelineThread(coro, queues[-1], threads) + ) + + # Start threads. + for thread in threads: + thread.start() + + # Wait for termination. The final thread lasts the longest. + try: + # Using a timeout allows us to receive KeyboardInterrupt + # exceptions during the join(). + while threads[-1].isAlive(): + threads[-1].join(1) + + except: + # Stop all the threads immediately. + for thread in threads: + thread.abort() + raise + + finally: + # Make completely sure that all the threads have finished + # before we return. They should already be either finished, + # in normal operation, or aborted, in case of an exception. + for thread in threads[:-1]: + thread.join() + + for thread in threads: + exc_info = thread.exc_info + if exc_info: + # Make the exception appear as it was raised originally. + raise exc_info[0], exc_info[1], exc_info[2] + + def pull(self): + """Yield elements from the end of the pipeline. Runs the stages + sequentially until the last yields some messages. Each of the messages + is then yielded by ``pulled.next()``. If the pipeline has a consumer, + that is the last stage does not yield any messages, then pull will not + yield any messages. Only the first coroutine in each stage is used + """ + coros = [stage[0] for stage in self.stages] + + # "Prime" the coroutines. + for coro in coros[1:]: + coro.next() + + # Begin the pipeline. + for out in coros[0]: + msgs = _allmsgs(out) + for coro in coros[1:]: + next_msgs = [] + for msg in msgs: + out = coro.send(msg) + next_msgs.extend(_allmsgs(out)) + msgs = next_msgs + for msg in msgs: + yield msg + +# Smoke test. +if __name__ == '__main__': + import time + + # Test a normally-terminating pipeline both in sequence and + # in parallel. + def produce(): + for i in range(5): + print('generating %i' % i) + time.sleep(1) + yield i + def work(): + num = yield + while True: + print('processing %i' % num) + time.sleep(2) + num = yield num*2 + def consume(): + while True: + num = yield + time.sleep(1) + print('received %i' % num) + ts_start = time.time() + Pipeline([produce(), work(), consume()]).run_sequential() + ts_seq = time.time() + Pipeline([produce(), work(), consume()]).run_parallel() + ts_par = time.time() + Pipeline([produce(), (work(), work()), consume()]).run_parallel() + ts_end = time.time() + print('Sequential time:', ts_seq - ts_start) + print('Parallel time:', ts_par - ts_seq) + print('Multiply-parallel time:', ts_end - ts_par) + print() + + # Test a pipeline that raises an exception. + def exc_produce(): + for i in range(10): + print('generating %i' % i) + time.sleep(1) + yield i + def exc_work(): + num = yield + while True: + print('processing %i' % num) + time.sleep(3) + if num == 3: + raise Exception() + num = yield num * 2 + def exc_consume(): + while True: + num = yield + #if num == 4: + # raise Exception() + print('received %i' % num) + Pipeline([exc_produce(), exc_work(), exc_consume()]).run_parallel(1) diff --git a/libs/beets/vfs.py b/libs/beets/vfs.py new file mode 100644 index 00000000..235f3604 --- /dev/null +++ b/libs/beets/vfs.py @@ -0,0 +1,48 @@ +# This file is part of beets. +# Copyright 2013, Adrian Sampson. +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. + +"""A simple utility for constructing filesystem-like trees from beets +libraries. +""" +from collections import namedtuple +from beets import util + +Node = namedtuple('Node', ['files', 'dirs']) + +def _insert(node, path, itemid): + """Insert an item into a virtual filesystem node.""" + if len(path) == 1: + # Last component. Insert file. + node.files[path[0]] = itemid + else: + # In a directory. + dirname = path[0] + rest = path[1:] + if dirname not in node.dirs: + node.dirs[dirname] = Node({}, {}) + _insert(node.dirs[dirname], rest, itemid) + +def libtree(lib): + """Generates a filesystem-like directory tree for the files + contained in `lib`. Filesystem nodes are (files, dirs) named + tuples in which both components are dictionaries. The first + maps filenames to Item ids. The second maps directory names to + child node tuples. + """ + root = Node({}, {}) + for item in lib.items(): + dest = item.destination(fragment=True) + parts = util.components(dest) + _insert(root, parts, item.id) + return root diff --git a/libs/mutagen/__init__.py b/libs/mutagen/__init__.py new file mode 100644 index 00000000..28febab3 --- /dev/null +++ b/libs/mutagen/__init__.py @@ -0,0 +1,263 @@ +# mutagen aims to be an all purpose media tagging library +# Copyright (C) 2005 Michael Urman +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. + + +"""Mutagen aims to be an all purpose tagging library. + +:: + + import mutagen.[format] + metadata = mutagen.[format].Open(filename) + +`metadata` acts like a dictionary of tags in the file. Tags are generally a +list of string-like values, but may have additional methods available +depending on tag or format. They may also be entirely different objects +for certain keys, again depending on format. +""" + +version = (1, 22) +"""Version tuple.""" + +version_string = ".".join(map(str, version)) +"""Version string.""" + + +import warnings + +import mutagen._util + + +class Metadata(object): + """An abstract dict-like object. + + Metadata is the base class for many of the tag objects in Mutagen. + """ + + def __init__(self, *args, **kwargs): + if args or kwargs: + self.load(*args, **kwargs) + + def load(self, *args, **kwargs): + raise NotImplementedError + + def save(self, filename=None): + """Save changes to a file.""" + + raise NotImplementedError + + def delete(self, filename=None): + """Remove tags from a file.""" + + raise NotImplementedError + + +class FileType(mutagen._util.DictMixin): + """An abstract object wrapping tags and audio stream information. + + Attributes: + + * info -- stream information (length, bitrate, sample rate) + * tags -- metadata tags, if any + + Each file format has different potential tags and stream + information. + + FileTypes implement an interface very similar to Metadata; the + dict interface, save, load, and delete calls on a FileType call + the appropriate methods on its tag data. + """ + + info = None + tags = None + filename = None + _mimes = ["application/octet-stream"] + + def __init__(self, filename=None, *args, **kwargs): + if filename is None: + warnings.warn("FileType constructor requires a filename", + DeprecationWarning) + else: + self.load(filename, *args, **kwargs) + + def load(self, filename, *args, **kwargs): + raise NotImplementedError + + def __getitem__(self, key): + """Look up a metadata tag key. + + If the file has no tags at all, a KeyError is raised. + """ + + if self.tags is None: + raise KeyError(key) + else: + return self.tags[key] + + def __setitem__(self, key, value): + """Set a metadata tag. + + If the file has no tags, an appropriate format is added (but + not written until save is called). + """ + + if self.tags is None: + self.add_tags() + self.tags[key] = value + + def __delitem__(self, key): + """Delete a metadata tag key. + + If the file has no tags at all, a KeyError is raised. + """ + + if self.tags is None: + raise KeyError(key) + else: + del(self.tags[key]) + + def keys(self): + """Return a list of keys in the metadata tag. + + If the file has no tags at all, an empty list is returned. + """ + + if self.tags is None: + return [] + else: + return self.tags.keys() + + def delete(self, filename=None): + """Remove tags from a file.""" + + if self.tags is not None: + if filename is None: + filename = self.filename + else: + warnings.warn( + "delete(filename=...) is deprecated, reload the file", + DeprecationWarning) + return self.tags.delete(filename) + + def save(self, filename=None, **kwargs): + """Save metadata tags.""" + + if filename is None: + filename = self.filename + else: + warnings.warn( + "save(filename=...) is deprecated, reload the file", + DeprecationWarning) + if self.tags is not None: + return self.tags.save(filename, **kwargs) + else: + raise ValueError("no tags in file") + + def pprint(self): + """Print stream information and comment key=value pairs.""" + + stream = "%s (%s)" % (self.info.pprint(), self.mime[0]) + try: + tags = self.tags.pprint() + except AttributeError: + return stream + else: + return stream + ((tags and "\n" + tags) or "") + + def add_tags(self): + """Adds new tags to the file. + + Raises if tags already exist. + """ + + raise NotImplementedError + + @property + def mime(self): + """A list of mime types""" + + mimes = [] + for Kind in type(self).__mro__: + for mime in getattr(Kind, '_mimes', []): + if mime not in mimes: + mimes.append(mime) + return mimes + + @staticmethod + def score(filename, fileobj, header): + raise NotImplementedError + + +def File(filename, options=None, easy=False): + """Guess the type of the file and try to open it. + + The file type is decided by several things, such as the first 128 + bytes (which usually contains a file type identifier), the + filename extension, and the presence of existing tags. + + If no appropriate type could be found, None is returned. + + :param options: Sequence of :class:`FileType` implementations, defaults to + all included ones. + + :param easy: If the easy wrappers should be returnd if available. + For example :class:`EasyMP3 ` instead + of :class:`MP3 `. + """ + + if options is None: + from mutagen.asf import ASF + from mutagen.apev2 import APEv2File + from mutagen.flac import FLAC + if easy: + from mutagen.easyid3 import EasyID3FileType as ID3FileType + else: + from mutagen.id3 import ID3FileType + if easy: + from mutagen.mp3 import EasyMP3 as MP3 + else: + from mutagen.mp3 import MP3 + from mutagen.oggflac import OggFLAC + from mutagen.oggspeex import OggSpeex + from mutagen.oggtheora import OggTheora + from mutagen.oggvorbis import OggVorbis + from mutagen.oggopus import OggOpus + if easy: + from mutagen.trueaudio import EasyTrueAudio as TrueAudio + else: + from mutagen.trueaudio import TrueAudio + from mutagen.wavpack import WavPack + if easy: + from mutagen.easymp4 import EasyMP4 as MP4 + else: + from mutagen.mp4 import MP4 + from mutagen.musepack import Musepack + from mutagen.monkeysaudio import MonkeysAudio + from mutagen.optimfrog import OptimFROG + options = [MP3, TrueAudio, OggTheora, OggSpeex, OggVorbis, OggFLAC, + FLAC, APEv2File, MP4, ID3FileType, WavPack, Musepack, + MonkeysAudio, OptimFROG, ASF, OggOpus] + + if not options: + return None + + fileobj = open(filename, "rb") + try: + header = fileobj.read(128) + # Sort by name after score. Otherwise import order affects + # Kind sort order, which affects treatment of things with + # equals scores. + results = [(Kind.score(filename, fileobj, header), Kind.__name__) + for Kind in options] + finally: + fileobj.close() + results = zip(results, options) + results.sort() + (score, name), Kind = results[-1] + if score > 0: + return Kind(filename) + else: + return None diff --git a/libs/mutagen/_constants.py b/libs/mutagen/_constants.py new file mode 100644 index 00000000..f5ecd90c --- /dev/null +++ b/libs/mutagen/_constants.py @@ -0,0 +1,197 @@ +"""Constants used by Mutagen.""" + +GENRES = [ + u"Blues", + u"Classic Rock", + u"Country", + u"Dance", + u"Disco", + u"Funk", + u"Grunge", + u"Hip-Hop", + u"Jazz", + u"Metal", + u"New Age", + u"Oldies", + u"Other", + u"Pop", + u"R&B", + u"Rap", + u"Reggae", + u"Rock", + u"Techno", + u"Industrial", + u"Alternative", + u"Ska", + u"Death Metal", + u"Pranks", + u"Soundtrack", + u"Euro-Techno", + u"Ambient", + u"Trip-Hop", + u"Vocal", + u"Jazz+Funk", + u"Fusion", + u"Trance", + u"Classical", + u"Instrumental", + u"Acid", + u"House", + u"Game", + u"Sound Clip", + u"Gospel", + u"Noise", + u"Alt. Rock", + u"Bass", + u"Soul", + u"Punk", + u"Space", + u"Meditative", + u"Instrumental Pop", + u"Instrumental Rock", + u"Ethnic", + u"Gothic", + u"Darkwave", + u"Techno-Industrial", + u"Electronic", + u"Pop-Folk", + u"Eurodance", + u"Dream", + u"Southern Rock", + u"Comedy", + u"Cult", + u"Gangsta Rap", + u"Top 40", + u"Christian Rap", + u"Pop/Funk", + u"Jungle", + u"Native American", + u"Cabaret", + u"New Wave", + u"Psychedelic", + u"Rave", + u"Showtunes", + u"Trailer", + u"Lo-Fi", + u"Tribal", + u"Acid Punk", + u"Acid Jazz", + u"Polka", + u"Retro", + u"Musical", + u"Rock & Roll", + u"Hard Rock", + u"Folk", + u"Folk-Rock", + u"National Folk", + u"Swing", + u"Fast-Fusion", + u"Bebop", + u"Latin", + u"Revival", + u"Celtic", + u"Bluegrass", + u"Avantgarde", + u"Gothic Rock", + u"Progressive Rock", + u"Psychedelic Rock", + u"Symphonic Rock", + u"Slow Rock", + u"Big Band", + u"Chorus", + u"Easy Listening", + u"Acoustic", + u"Humour", + u"Speech", + u"Chanson", + u"Opera", + u"Chamber Music", + u"Sonata", + u"Symphony", + u"Booty Bass", + u"Primus", + u"Porn Groove", + u"Satire", + u"Slow Jam", + u"Club", + u"Tango", + u"Samba", + u"Folklore", + u"Ballad", + u"Power Ballad", + u"Rhythmic Soul", + u"Freestyle", + u"Duet", + u"Punk Rock", + u"Drum Solo", + u"A Cappella", + u"Euro-House", + u"Dance Hall", + u"Goa", + u"Drum & Bass", + u"Club-House", + u"Hardcore", + u"Terror", + u"Indie", + u"BritPop", + u"Afro-Punk", + u"Polsk Punk", + u"Beat", + u"Christian Gangsta Rap", + u"Heavy Metal", + u"Black Metal", + u"Crossover", + u"Contemporary Christian", + u"Christian Rock", + u"Merengue", + u"Salsa", + u"Thrash Metal", + u"Anime", + u"JPop", + u"Synthpop", + u"Abstract", + u"Art Rock", + u"Baroque", + u"Bhangra", + u"Big Beat", + u"Breakbeat", + u"Chillout", + u"Downtempo", + u"Dub", + u"EBM", + u"Eclectic", + u"Electro", + u"Electroclash", + u"Emo", + u"Experimental", + u"Garage", + u"Global", + u"IDM", + u"Illbient", + u"Industro-Goth", + u"Jam Band", + u"Krautrock", + u"Leftfield", + u"Lounge", + u"Math Rock", + u"New Romantic", + u"Nu-Breakz", + u"Post-Punk", + u"Post-Rock", + u"Psytrance", + u"Shoegaze", + u"Space Rock", + u"Trop Rock", + u"World Music", + u"Neoclassical", + u"Audiobook", + u"Audio Theatre", + u"Neue Deutsche Welle", + u"Podcast", + u"Indie Rock", + u"G-Funk", + u"Dubstep", + u"Garage Rock", + u"Psybient", +] +"""The ID3v1 genre list.""" diff --git a/libs/mutagen/_id3frames.py b/libs/mutagen/_id3frames.py new file mode 100644 index 00000000..c6130f6b --- /dev/null +++ b/libs/mutagen/_id3frames.py @@ -0,0 +1,1842 @@ +# Copyright (C) 2005 Michael Urman +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. + +from zlib import error as zlibError +from warnings import warn +from struct import unpack + +from mutagen._id3util import ( + ID3Warning, ID3JunkFrameError, ID3BadCompressedData, + ID3EncryptionUnsupportedError, ID3BadUnsynchData, unsynch) +from mutagen._id3specs import ( + BinaryDataSpec, StringSpec, Latin1TextSpec, EncodedTextSpec, ByteSpec, + EncodingSpec, ASPIIndexSpec, SizedIntegerSpec, IntegerSpec, + VolumeAdjustmentsSpec, VolumePeakSpec, VolumeAdjustmentSpec, + ChannelSpec, MultiSpec, SynchronizedTextSpec, KeyEventSpec, TimeStampSpec, + EncodedNumericPartTextSpec, EncodedNumericTextSpec) + + +def is_valid_frame_id(frame_id): + return frame_id.isalnum() and frame_id.isupper() + + +class Frame(object): + """Fundamental unit of ID3 data. + + ID3 tags are split into frames. Each frame has a potentially + different structure, and so this base class is not very featureful. + """ + + FLAG23_ALTERTAG = 0x8000 + FLAG23_ALTERFILE = 0x4000 + FLAG23_READONLY = 0x2000 + FLAG23_COMPRESS = 0x0080 + FLAG23_ENCRYPT = 0x0040 + FLAG23_GROUP = 0x0020 + + FLAG24_ALTERTAG = 0x4000 + FLAG24_ALTERFILE = 0x2000 + FLAG24_READONLY = 0x1000 + FLAG24_GROUPID = 0x0040 + FLAG24_COMPRESS = 0x0008 + FLAG24_ENCRYPT = 0x0004 + FLAG24_UNSYNCH = 0x0002 + FLAG24_DATALEN = 0x0001 + + _framespec = [] + + def __init__(self, *args, **kwargs): + if len(args) == 1 and len(kwargs) == 0 and \ + isinstance(args[0], type(self)): + other = args[0] + for checker in self._framespec: + try: + val = checker.validate(self, getattr(other, checker.name)) + except ValueError as e: + e.message = "%s: %s" % (checker.name, e.message) + raise + setattr(self, checker.name, val) + else: + for checker, val in zip(self._framespec, args): + setattr(self, checker.name, checker.validate(self, val)) + for checker in self._framespec[len(args):]: + try: + validated = checker.validate( + self, kwargs.get(checker.name, None)) + except ValueError as e: + e.message = "%s: %s" % (checker.name, e.message) + raise + setattr(self, checker.name, validated) + + def _get_v23_frame(self, **kwargs): + """Returns a frame copy which is suitable for writing into a v2.3 tag. + + kwargs get passed to the specs. + """ + + new_kwargs = {} + for checker in self._framespec: + name = checker.name + value = getattr(self, name) + new_kwargs[name] = checker._validate23(self, value, **kwargs) + return type(self)(**new_kwargs) + + @property + def HashKey(self): + """An internal key used to ensure frame uniqueness in a tag""" + + return self.FrameID + + @property + def FrameID(self): + """ID3v2 three or four character frame ID""" + + return type(self).__name__ + + def __repr__(self): + """Python representation of a frame. + + The string returned is a valid Python expression to construct + a copy of this frame. + """ + kw = [] + for attr in self._framespec: + kw.append('%s=%r' % (attr.name, getattr(self, attr.name))) + return '%s(%s)' % (type(self).__name__, ', '.join(kw)) + + def _readData(self, data): + odata = data + for reader in self._framespec: + if len(data): + try: + value, data = reader.read(self, data) + except UnicodeDecodeError: + raise ID3JunkFrameError + else: + raise ID3JunkFrameError + setattr(self, reader.name, value) + if data.strip('\x00'): + warn('Leftover data: %s: %r (from %r)' % ( + type(self).__name__, data, odata), + ID3Warning) + + def _writeData(self): + data = [] + for writer in self._framespec: + data.append(writer.write(self, getattr(self, writer.name))) + return ''.join(data) + + def pprint(self): + """Return a human-readable representation of the frame.""" + return "%s=%s" % (type(self).__name__, self._pprint()) + + def _pprint(self): + return "[unrepresentable data]" + + @classmethod + def fromData(cls, id3, tflags, data): + """Construct this ID3 frame from raw string data.""" + + if id3._V24 <= id3.version: + if tflags & (Frame.FLAG24_COMPRESS | Frame.FLAG24_DATALEN): + # The data length int is syncsafe in 2.4 (but not 2.3). + # However, we don't actually need the data length int, + # except to work around a QL 0.12 bug, and in that case + # all we need are the raw bytes. + datalen_bytes = data[:4] + data = data[4:] + if tflags & Frame.FLAG24_UNSYNCH or id3.f_unsynch: + try: + data = unsynch.decode(data) + except ValueError, err: + if id3.PEDANTIC: + raise ID3BadUnsynchData('%s: %r' % (err, data)) + if tflags & Frame.FLAG24_ENCRYPT: + raise ID3EncryptionUnsupportedError + if tflags & Frame.FLAG24_COMPRESS: + try: + data = data.decode('zlib') + except zlibError, err: + # the initial mutagen that went out with QL 0.12 did not + # write the 4 bytes of uncompressed size. Compensate. + data = datalen_bytes + data + try: + data = data.decode('zlib') + except zlibError, err: + if id3.PEDANTIC: + raise ID3BadCompressedData('%s: %r' % (err, data)) + + elif id3._V23 <= id3.version: + if tflags & Frame.FLAG23_COMPRESS: + usize, = unpack('>L', data[:4]) + data = data[4:] + if tflags & Frame.FLAG23_ENCRYPT: + raise ID3EncryptionUnsupportedError + if tflags & Frame.FLAG23_COMPRESS: + try: + data = data.decode('zlib') + except zlibError, err: + if id3.PEDANTIC: + raise ID3BadCompressedData('%s: %r' % (err, data)) + + frame = cls() + frame._rawdata = data + frame._flags = tflags + frame._readData(data) + return frame + + def __hash__(self): + raise TypeError("Frame objects are unhashable") + + +class FrameOpt(Frame): + """A frame with optional parts. + + Some ID3 frames have optional data; this class extends Frame to + provide support for those parts. + """ + + _optionalspec = [] + + def __init__(self, *args, **kwargs): + super(FrameOpt, self).__init__(*args, **kwargs) + for spec in self._optionalspec: + if spec.name in kwargs: + validated = spec.validate(self, kwargs[spec.name]) + setattr(self, spec.name, validated) + else: + break + + def _readData(self, data): + odata = data + for reader in self._framespec: + if len(data): + value, data = reader.read(self, data) + else: + raise ID3JunkFrameError + setattr(self, reader.name, value) + if data: + for reader in self._optionalspec: + if len(data): + value, data = reader.read(self, data) + else: + break + setattr(self, reader.name, value) + if data.strip('\x00'): + warn('Leftover data: %s: %r (from %r)' % ( + type(self).__name__, data, odata), + ID3Warning) + + def _writeData(self): + data = [] + for writer in self._framespec: + data.append(writer.write(self, getattr(self, writer.name))) + for writer in self._optionalspec: + try: + data.append(writer.write(self, getattr(self, writer.name))) + except AttributeError: + break + return ''.join(data) + + def __repr__(self): + kw = [] + for attr in self._framespec: + kw.append('%s=%r' % (attr.name, getattr(self, attr.name))) + for attr in self._optionalspec: + if hasattr(self, attr.name): + kw.append('%s=%r' % (attr.name, getattr(self, attr.name))) + return '%s(%s)' % (type(self).__name__, ', '.join(kw)) + + +class TextFrame(Frame): + """Text strings. + + Text frames support casts to unicode or str objects, as well as + list-like indexing, extend, and append. + + Iterating over a TextFrame iterates over its strings, not its + characters. + + Text frames have a 'text' attribute which is the list of strings, + and an 'encoding' attribute; 0 for ISO-8859 1, 1 UTF-16, 2 for + UTF-16BE, and 3 for UTF-8. If you don't want to worry about + encodings, just set it to 3. + """ + + _framespec = [ + EncodingSpec('encoding'), + MultiSpec('text', EncodedTextSpec('text'), sep=u'\u0000'), + ] + + def __str__(self): + return self.__unicode__().encode('utf-8') + + def __unicode__(self): + return u'\u0000'.join(self.text) + + def __eq__(self, other): + if isinstance(other, str): + return str(self) == other + elif isinstance(other, unicode): + return unicode(self) == other + return self.text == other + + __hash__ = Frame.__hash__ + + def __getitem__(self, item): + return self.text[item] + + def __iter__(self): + return iter(self.text) + + def append(self, value): + """Append a string.""" + + return self.text.append(value) + + def extend(self, value): + """Extend the list by appending all strings from the given list.""" + + return self.text.extend(value) + + def _pprint(self): + return " / ".join(self.text) + + +class NumericTextFrame(TextFrame): + """Numerical text strings. + + The numeric value of these frames can be gotten with unary plus, e.g.:: + + frame = TLEN('12345') + length = +frame + """ + + _framespec = [ + EncodingSpec('encoding'), + MultiSpec('text', EncodedNumericTextSpec('text'), sep=u'\u0000'), + ] + + def __pos__(self): + """Return the numerical value of the string.""" + return int(self.text[0]) + + +class NumericPartTextFrame(TextFrame): + """Multivalue numerical text strings. + + These strings indicate 'part (e.g. track) X of Y', and unary plus + returns the first value:: + + frame = TRCK('4/15') + track = +frame # track == 4 + """ + + _framespec = [ + EncodingSpec('encoding'), + MultiSpec('text', EncodedNumericPartTextSpec('text'), sep=u'\u0000'), + ] + + def __pos__(self): + return int(self.text[0].split("/")[0]) + + +class TimeStampTextFrame(TextFrame): + """A list of time stamps. + + The 'text' attribute in this frame is a list of ID3TimeStamp + objects, not a list of strings. + """ + + _framespec = [ + EncodingSpec('encoding'), + MultiSpec('text', TimeStampSpec('stamp'), sep=u','), + ] + + def __str__(self): + return self.__unicode__().encode('utf-8') + + def __unicode__(self): + return ','.join([stamp.text for stamp in self.text]) + + def _pprint(self): + return " / ".join([stamp.text for stamp in self.text]) + + +class UrlFrame(Frame): + """A frame containing a URL string. + + The ID3 specification is silent about IRIs and normalized URL + forms. Mutagen assumes all URLs in files are encoded as Latin 1, + but string conversion of this frame returns a UTF-8 representation + for compatibility with other string conversions. + + The only sane way to handle URLs in MP3s is to restrict them to + ASCII. + """ + + _framespec = [Latin1TextSpec('url')] + + def __str__(self): + return self.url.encode('utf-8') + + def __unicode__(self): + return self.url + + def __eq__(self, other): + return self.url == other + + __hash__ = Frame.__hash__ + + def _pprint(self): + return self.url + + +class UrlFrameU(UrlFrame): + + @property + def HashKey(self): + return '%s:%s' % (self.FrameID, self.url) + + +class TALB(TextFrame): + "Album" + + +class TBPM(NumericTextFrame): + "Beats per minute" + + +class TCOM(TextFrame): + "Composer" + + +class TCON(TextFrame): + """Content type (Genre) + + ID3 has several ways genres can be represented; for convenience, + use the 'genres' property rather than the 'text' attribute. + """ + + from mutagen._constants import GENRES + GENRES = GENRES + + def __get_genres(self): + genres = [] + import re + genre_re = re.compile(r"((?:\((?P[0-9]+|RX|CR)\))*)(?P.+)?") + for value in self.text: + # 255 possible entries in id3v1 + if value.isdigit() and int(value) < 256: + try: + genres.append(self.GENRES[int(value)]) + except IndexError: + genres.append(u"Unknown") + elif value == "CR": + genres.append(u"Cover") + elif value == "RX": + genres.append(u"Remix") + elif value: + newgenres = [] + genreid, dummy, genrename = genre_re.match(value).groups() + + if genreid: + for gid in genreid[1:-1].split(")("): + if gid.isdigit() and int(gid) < len(self.GENRES): + gid = unicode(self.GENRES[int(gid)]) + newgenres.append(gid) + elif gid == "CR": + newgenres.append(u"Cover") + elif gid == "RX": + newgenres.append(u"Remix") + else: + newgenres.append(u"Unknown") + + if genrename: + # "Unescaping" the first parenthesis + if genrename.startswith("(("): + genrename = genrename[1:] + if genrename not in newgenres: + newgenres.append(genrename) + + genres.extend(newgenres) + + return genres + + def __set_genres(self, genres): + if isinstance(genres, basestring): + genres = [genres] + self.text = map(self.__decode, genres) + + def __decode(self, value): + if isinstance(value, str): + enc = EncodedTextSpec._encodings[self.encoding][0] + return value.decode(enc) + else: + return value + + genres = property(__get_genres, __set_genres, None, + "A list of genres parsed from the raw text data.") + + def _pprint(self): + return " / ".join(self.genres) + + +class TCOP(TextFrame): + "Copyright (c)" + + +class TCMP(NumericTextFrame): + "iTunes Compilation Flag" + + +class TDAT(TextFrame): + "Date of recording (DDMM)" + + +class TDEN(TimeStampTextFrame): + "Encoding Time" + + +class TDES(TextFrame): + "iTunes Podcast Description" + + +class TDOR(TimeStampTextFrame): + "Original Release Time" + + +class TDLY(NumericTextFrame): + "Audio Delay (ms)" + + +class TDRC(TimeStampTextFrame): + "Recording Time" + + +class TDRL(TimeStampTextFrame): + "Release Time" + + +class TDTG(TimeStampTextFrame): + "Tagging Time" + + +class TENC(TextFrame): + "Encoder" + + +class TEXT(TextFrame): + "Lyricist" + + +class TFLT(TextFrame): + "File type" + + +class TGID(TextFrame): + "iTunes Podcast Identifier" + + +class TIME(TextFrame): + "Time of recording (HHMM)" + + +class TIT1(TextFrame): + "Content group description" + + +class TIT2(TextFrame): + "Title" + + +class TIT3(TextFrame): + "Subtitle/Description refinement" + + +class TKEY(TextFrame): + "Starting Key" + + +class TLAN(TextFrame): + "Audio Languages" + + +class TLEN(NumericTextFrame): + "Audio Length (ms)" + + +class TMED(TextFrame): + "Source Media Type" + + +class TMOO(TextFrame): + "Mood" + + +class TOAL(TextFrame): + "Original Album" + + +class TOFN(TextFrame): + "Original Filename" + + +class TOLY(TextFrame): + "Original Lyricist" + + +class TOPE(TextFrame): + "Original Artist/Performer" + + +class TORY(NumericTextFrame): + "Original Release Year" + + +class TOWN(TextFrame): + "Owner/Licensee" + + +class TPE1(TextFrame): + "Lead Artist/Performer/Soloist/Group" + + +class TPE2(TextFrame): + "Band/Orchestra/Accompaniment" + + +class TPE3(TextFrame): + "Conductor" + + +class TPE4(TextFrame): + "Interpreter/Remixer/Modifier" + + +class TPOS(NumericPartTextFrame): + "Part of set" + + +class TPRO(TextFrame): + "Produced (P)" + + +class TPUB(TextFrame): + "Publisher" + + +class TRCK(NumericPartTextFrame): + "Track Number" + + +class TRDA(TextFrame): + "Recording Dates" + + +class TRSN(TextFrame): + "Internet Radio Station Name" + + +class TRSO(TextFrame): + "Internet Radio Station Owner" + + +class TSIZ(NumericTextFrame): + "Size of audio data (bytes)" + + +class TSO2(TextFrame): + "iTunes Album Artist Sort" + + +class TSOA(TextFrame): + "Album Sort Order key" + + +class TSOC(TextFrame): + "iTunes Composer Sort" + + +class TSOP(TextFrame): + "Perfomer Sort Order key" + + +class TSOT(TextFrame): + "Title Sort Order key" + + +class TSRC(TextFrame): + "International Standard Recording Code (ISRC)" + + +class TSSE(TextFrame): + "Encoder settings" + + +class TSST(TextFrame): + "Set Subtitle" + + +class TYER(NumericTextFrame): + "Year of recording" + + +class TXXX(TextFrame): + """User-defined text data. + + TXXX frames have a 'desc' attribute which is set to any Unicode + value (though the encoding of the text and the description must be + the same). Many taggers use this frame to store freeform keys. + """ + + _framespec = [ + EncodingSpec('encoding'), + EncodedTextSpec('desc'), + MultiSpec('text', EncodedTextSpec('text'), sep=u'\u0000'), + ] + + @property + def HashKey(self): + return '%s:%s' % (self.FrameID, self.desc) + + def _pprint(self): + return "%s=%s" % (self.desc, " / ".join(self.text)) + + +class WCOM(UrlFrameU): + "Commercial Information" + + +class WCOP(UrlFrame): + "Copyright Information" + + +class WFED(UrlFrame): + "iTunes Podcast Feed" + + +class WOAF(UrlFrame): + "Official File Information" + + +class WOAR(UrlFrameU): + "Official Artist/Performer Information" + + +class WOAS(UrlFrame): + "Official Source Information" + + +class WORS(UrlFrame): + "Official Internet Radio Information" + + +class WPAY(UrlFrame): + "Payment Information" + + +class WPUB(UrlFrame): + "Official Publisher Information" + + +class WXXX(UrlFrame): + """User-defined URL data. + + Like TXXX, this has a freeform description associated with it. + """ + + _framespec = [ + EncodingSpec('encoding'), + EncodedTextSpec('desc'), + Latin1TextSpec('url'), + ] + + @property + def HashKey(self): + return '%s:%s' % (self.FrameID, self.desc) + + +class PairedTextFrame(Frame): + """Paired text strings. + + Some ID3 frames pair text strings, to associate names with a more + specific involvement in the song. The 'people' attribute of these + frames contains a list of pairs:: + + [['trumpet', 'Miles Davis'], ['bass', 'Paul Chambers']] + + Like text frames, these frames also have an encoding attribute. + """ + + _framespec = [ + EncodingSpec('encoding'), + MultiSpec('people', + EncodedTextSpec('involvement'), + EncodedTextSpec('person')) + ] + + def __eq__(self, other): + return self.people == other + + __hash__ = Frame.__hash__ + + +class TIPL(PairedTextFrame): + "Involved People List" + + +class TMCL(PairedTextFrame): + "Musicians Credits List" + + +class IPLS(TIPL): + "Involved People List" + + +class BinaryFrame(Frame): + """Binary data + + The 'data' attribute contains the raw byte string. + """ + + _framespec = [BinaryDataSpec('data')] + + def __eq__(self, other): + return self.data == other + + __hash__ = Frame.__hash__ + + +class MCDI(BinaryFrame): + "Binary dump of CD's TOC" + + +class ETCO(Frame): + """Event timing codes.""" + + _framespec = [ + ByteSpec("format"), + KeyEventSpec("events"), + ] + + def __eq__(self, other): + return self.events == other + + __hash__ = Frame.__hash__ + + +class MLLT(Frame): + """MPEG location lookup table. + + This frame's attributes may be changed in the future based on + feedback from real-world use. + """ + + _framespec = [ + SizedIntegerSpec('frames', 2), + SizedIntegerSpec('bytes', 3), + SizedIntegerSpec('milliseconds', 3), + ByteSpec('bits_for_bytes'), + ByteSpec('bits_for_milliseconds'), + BinaryDataSpec('data'), + ] + + def __eq__(self, other): + return self.data == other + + __hash__ = Frame.__hash__ + + +class SYTC(Frame): + """Synchronised tempo codes. + + This frame's attributes may be changed in the future based on + feedback from real-world use. + """ + + _framespec = [ + ByteSpec("format"), + BinaryDataSpec("data"), + ] + + def __eq__(self, other): + return self.data == other + + __hash__ = Frame.__hash__ + + +class USLT(Frame): + """Unsynchronised lyrics/text transcription. + + Lyrics have a three letter ISO language code ('lang'), a + description ('desc'), and a block of plain text ('text'). + """ + + _framespec = [ + EncodingSpec('encoding'), + StringSpec('lang', 3), + EncodedTextSpec('desc'), + EncodedTextSpec('text'), + ] + + @property + def HashKey(self): + return '%s:%s:%r' % (self.FrameID, self.desc, self.lang) + + def __str__(self): + return self.text.encode('utf-8') + + def __unicode__(self): + return self.text + + def __eq__(self, other): + return self.text == other + + __hash__ = Frame.__hash__ + + +class SYLT(Frame): + """Synchronised lyrics/text.""" + + _framespec = [ + EncodingSpec('encoding'), + StringSpec('lang', 3), + ByteSpec('format'), + ByteSpec('type'), + EncodedTextSpec('desc'), + SynchronizedTextSpec('text'), + ] + + @property + def HashKey(self): + return '%s:%s:%r' % (self.FrameID, self.desc, self.lang) + + def __eq__(self, other): + return str(self) == other + + __hash__ = Frame.__hash__ + + def __str__(self): + return "".join([text for (text, time) in self.text]).encode('utf-8') + + +class COMM(TextFrame): + """User comment. + + User comment frames have a descrption, like TXXX, and also a three + letter ISO language code in the 'lang' attribute. + """ + + _framespec = [ + EncodingSpec('encoding'), + StringSpec('lang', 3), + EncodedTextSpec('desc'), + MultiSpec('text', EncodedTextSpec('text'), sep=u'\u0000'), + ] + + @property + def HashKey(self): + return '%s:%s:%r' % (self.FrameID, self.desc, self.lang) + + def _pprint(self): + return "%s=%r=%s" % (self.desc, self.lang, " / ".join(self.text)) + + +class RVA2(Frame): + """Relative volume adjustment (2). + + This frame is used to implemented volume scaling, and in + particular, normalization using ReplayGain. + + Attributes: + + * desc -- description or context of this adjustment + * channel -- audio channel to adjust (master is 1) + * gain -- a + or - dB gain relative to some reference level + * peak -- peak of the audio as a floating point number, [0, 1] + + When storing ReplayGain tags, use descriptions of 'album' and + 'track' on channel 1. + """ + + _framespec = [ + Latin1TextSpec('desc'), + ChannelSpec('channel'), + VolumeAdjustmentSpec('gain'), + VolumePeakSpec('peak'), + ] + + _channels = ["Other", "Master volume", "Front right", "Front left", + "Back right", "Back left", "Front centre", "Back centre", + "Subwoofer"] + + @property + def HashKey(self): + return '%s:%s' % (self.FrameID, self.desc) + + def __eq__(self, other): + try: + return ((str(self) == other) or + (self.desc == other.desc and + self.channel == other.channel and + self.gain == other.gain and + self.peak == other.peak)) + except AttributeError: + return False + + __hash__ = Frame.__hash__ + + def __str__(self): + return "%s: %+0.4f dB/%0.4f" % ( + self._channels[self.channel], self.gain, self.peak) + + +class EQU2(Frame): + """Equalisation (2). + + Attributes: + method -- interpolation method (0 = band, 1 = linear) + desc -- identifying description + adjustments -- list of (frequency, vol_adjustment) pairs + """ + + _framespec = [ + ByteSpec("method"), + Latin1TextSpec("desc"), + VolumeAdjustmentsSpec("adjustments"), + ] + + def __eq__(self, other): + return self.adjustments == other + + __hash__ = Frame.__hash__ + + @property + def HashKey(self): + return '%s:%s' % (self.FrameID, self.desc) + + +# class RVAD: unsupported +# class EQUA: unsupported + + +class RVRB(Frame): + """Reverb.""" + + _framespec = [ + SizedIntegerSpec('left', 2), + SizedIntegerSpec('right', 2), + ByteSpec('bounce_left'), + ByteSpec('bounce_right'), + ByteSpec('feedback_ltl'), + ByteSpec('feedback_ltr'), + ByteSpec('feedback_rtr'), + ByteSpec('feedback_rtl'), + ByteSpec('premix_ltr'), + ByteSpec('premix_rtl'), + ] + + def __eq__(self, other): + return (self.left, self.right) == other + + __hash__ = Frame.__hash__ + + +class APIC(Frame): + """Attached (or linked) Picture. + + Attributes: + + * encoding -- text encoding for the description + * mime -- a MIME type (e.g. image/jpeg) or '-->' if the data is a URI + * type -- the source of the image (3 is the album front cover) + * desc -- a text description of the image + * data -- raw image data, as a byte string + + Mutagen will automatically compress large images when saving tags. + """ + + _framespec = [ + EncodingSpec('encoding'), + Latin1TextSpec('mime'), + ByteSpec('type'), + EncodedTextSpec('desc'), + BinaryDataSpec('data'), + ] + + def __eq__(self, other): + return self.data == other + + __hash__ = Frame.__hash__ + + @property + def HashKey(self): + return '%s:%s' % (self.FrameID, self.desc) + + def _pprint(self): + return "%s (%s, %d bytes)" % ( + self.desc, self.mime, len(self.data)) + + +class PCNT(Frame): + """Play counter. + + The 'count' attribute contains the (recorded) number of times this + file has been played. + + This frame is basically obsoleted by POPM. + """ + + _framespec = [IntegerSpec('count')] + + def __eq__(self, other): + return self.count == other + + __hash__ = Frame.__hash__ + + def __pos__(self): + return self.count + + def _pprint(self): + return unicode(self.count) + + +class POPM(FrameOpt): + """Popularimeter. + + This frame keys a rating (out of 255) and a play count to an email + address. + + Attributes: + + * email -- email this POPM frame is for + * rating -- rating from 0 to 255 + * count -- number of times the files has been played (optional) + """ + + _framespec = [ + Latin1TextSpec('email'), + ByteSpec('rating'), + ] + + _optionalspec = [IntegerSpec('count')] + + @property + def HashKey(self): + return '%s:%s' % (self.FrameID, self.email) + + def __eq__(self, other): + return self.rating == other + + __hash__ = FrameOpt.__hash__ + + def __pos__(self): + return self.rating + + def _pprint(self): + return "%s=%r %r/255" % ( + self.email, getattr(self, 'count', None), self.rating) + + +class GEOB(Frame): + """General Encapsulated Object. + + A blob of binary data, that is not a picture (those go in APIC). + + Attributes: + + * encoding -- encoding of the description + * mime -- MIME type of the data or '-->' if the data is a URI + * filename -- suggested filename if extracted + * desc -- text description of the data + * data -- raw data, as a byte string + """ + + _framespec = [ + EncodingSpec('encoding'), + Latin1TextSpec('mime'), + EncodedTextSpec('filename'), + EncodedTextSpec('desc'), + BinaryDataSpec('data'), + ] + + @property + def HashKey(self): + return '%s:%s' % (self.FrameID, self.desc) + + def __eq__(self, other): + return self.data == other + + __hash__ = Frame.__hash__ + + +class RBUF(FrameOpt): + """Recommended buffer size. + + Attributes: + + * size -- recommended buffer size in bytes + * info -- if ID3 tags may be elsewhere in the file (optional) + * offset -- the location of the next ID3 tag, if any + + Mutagen will not find the next tag itself. + """ + + _framespec = [SizedIntegerSpec('size', 3)] + + _optionalspec = [ + ByteSpec('info'), + SizedIntegerSpec('offset', 4), + ] + + def __eq__(self, other): + return self.size == other + + __hash__ = FrameOpt.__hash__ + + def __pos__(self): + return self.size + + +class AENC(FrameOpt): + """Audio encryption. + + Attributes: + + * owner -- key identifying this encryption type + * preview_start -- unencrypted data block offset + * preview_length -- number of unencrypted blocks + * data -- data required for decryption (optional) + + Mutagen cannot decrypt files. + """ + + _framespec = [ + Latin1TextSpec('owner'), + SizedIntegerSpec('preview_start', 2), + SizedIntegerSpec('preview_length', 2), + ] + + _optionalspec = [BinaryDataSpec('data')] + + @property + def HashKey(self): + return '%s:%s' % (self.FrameID, self.owner) + + def __str__(self): + return self.owner.encode('utf-8') + + def __unicode__(self): + return self.owner + + def __eq__(self, other): + return self.owner == other + + __hash__ = FrameOpt.__hash__ + + +class LINK(FrameOpt): + """Linked information. + + Attributes: + + * frameid -- the ID of the linked frame + * url -- the location of the linked frame + * data -- further ID information for the frame + """ + + _framespec = [ + StringSpec('frameid', 4), + Latin1TextSpec('url'), + ] + + _optionalspec = [BinaryDataSpec('data')] + + @property + def HashKey(self): + try: + return "%s:%s:%s:%r" % ( + self.FrameID, self.frameid, self.url, self.data) + except AttributeError: + return "%s:%s:%s" % (self.FrameID, self.frameid, self.url) + + def __eq__(self, other): + try: + return (self.frameid, self.url, self.data) == other + except AttributeError: + return (self.frameid, self.url) == other + + __hash__ = FrameOpt.__hash__ + + +class POSS(Frame): + """Position synchronisation frame + + Attribute: + + * format -- format of the position attribute (frames or milliseconds) + * position -- current position of the file + """ + + _framespec = [ + ByteSpec('format'), + IntegerSpec('position'), + ] + + def __pos__(self): + return self.position + + def __eq__(self, other): + return self.position == other + + __hash__ = Frame.__hash__ + + +class UFID(Frame): + """Unique file identifier. + + Attributes: + + * owner -- format/type of identifier + * data -- identifier + """ + + _framespec = [ + Latin1TextSpec('owner'), + BinaryDataSpec('data'), + ] + + @property + def HashKey(self): + return '%s:%s' % (self.FrameID, self.owner) + + def __eq__(s, o): + if isinstance(o, UFI): + return s.owner == o.owner and s.data == o.data + else: + return s.data == o + + __hash__ = Frame.__hash__ + + def _pprint(self): + isascii = ord(max(self.data)) < 128 + if isascii: + return "%s=%s" % (self.owner, self.data) + else: + return "%s (%d bytes)" % (self.owner, len(self.data)) + + +class USER(Frame): + """Terms of use. + + Attributes: + + * encoding -- text encoding + * lang -- ISO three letter language code + * text -- licensing terms for the audio + """ + + _framespec = [ + EncodingSpec('encoding'), + StringSpec('lang', 3), + EncodedTextSpec('text'), + ] + + @property + def HashKey(self): + return '%s:%r' % (self.FrameID, self.lang) + + def __str__(self): + return self.text.encode('utf-8') + + def __unicode__(self): + return self.text + + def __eq__(self, other): + return self.text == other + + __hash__ = Frame.__hash__ + + def _pprint(self): + return "%r=%s" % (self.lang, self.text) + + +class OWNE(Frame): + """Ownership frame.""" + + _framespec = [ + EncodingSpec('encoding'), + Latin1TextSpec('price'), + StringSpec('date', 8), + EncodedTextSpec('seller'), + ] + + def __str__(self): + return self.seller.encode('utf-8') + + def __unicode__(self): + return self.seller + + def __eq__(self, other): + return self.seller == other + + __hash__ = Frame.__hash__ + + +class COMR(FrameOpt): + """Commercial frame.""" + + _framespec = [ + EncodingSpec('encoding'), + Latin1TextSpec('price'), + StringSpec('valid_until', 8), + Latin1TextSpec('contact'), + ByteSpec('format'), + EncodedTextSpec('seller'), + EncodedTextSpec('desc'), + ] + + _optionalspec = [ + Latin1TextSpec('mime'), + BinaryDataSpec('logo'), + ] + + @property + def HashKey(self): + return '%s:%s' % (self.FrameID, self._writeData()) + + def __eq__(self, other): + return self._writeData() == other._writeData() + + __hash__ = FrameOpt.__hash__ + + +class ENCR(Frame): + """Encryption method registration. + + The standard does not allow multiple ENCR frames with the same owner + or the same method. Mutagen only verifies that the owner is unique. + """ + + _framespec = [ + Latin1TextSpec('owner'), + ByteSpec('method'), + BinaryDataSpec('data'), + ] + + @property + def HashKey(self): + return "%s:%s" % (self.FrameID, self.owner) + + def __str__(self): + return self.data + + def __eq__(self, other): + return self.data == other + + __hash__ = Frame.__hash__ + + +class GRID(FrameOpt): + """Group identification registration.""" + + _framespec = [ + Latin1TextSpec('owner'), + ByteSpec('group'), + ] + + _optionalspec = [BinaryDataSpec('data')] + + @property + def HashKey(self): + return '%s:%s' % (self.FrameID, self.group) + + def __pos__(self): + return self.group + + def __str__(self): + return self.owner.encode('utf-8') + + def __unicode__(self): + return self.owner + + def __eq__(self, other): + return self.owner == other or self.group == other + + __hash__ = FrameOpt.__hash__ + + +class PRIV(Frame): + """Private frame.""" + + _framespec = [ + Latin1TextSpec('owner'), + BinaryDataSpec('data'), + ] + + @property + def HashKey(self): + return '%s:%s:%s' % ( + self.FrameID, self.owner, self.data.decode('latin1')) + + def __str__(self): + return self.data + + def __eq__(self, other): + return self.data == other + + def _pprint(self): + isascii = ord(max(self.data)) < 128 + if isascii: + return "%s=%s" % (self.owner, self.data) + else: + return "%s (%d bytes)" % (self.owner, len(self.data)) + + __hash__ = Frame.__hash__ + + +class SIGN(Frame): + """Signature frame.""" + + _framespec = [ + ByteSpec('group'), + BinaryDataSpec('sig'), + ] + + @property + def HashKey(self): + return '%s:%c:%s' % (self.FrameID, self.group, self.sig) + + def __str__(self): + return self.sig + + def __eq__(self, other): + return self.sig == other + + __hash__ = Frame.__hash__ + + +class SEEK(Frame): + """Seek frame. + + Mutagen does not find tags at seek offsets. + """ + + _framespec = [IntegerSpec('offset')] + + def __pos__(self): + return self.offset + + def __eq__(self, other): + return self.offset == other + + __hash__ = Frame.__hash__ + + +class ASPI(Frame): + """Audio seek point index. + + Attributes: S, L, N, b, and Fi. For the meaning of these, see + the ID3v2.4 specification. Fi is a list of integers. + """ + _framespec = [ + SizedIntegerSpec("S", 4), + SizedIntegerSpec("L", 4), + SizedIntegerSpec("N", 2), + ByteSpec("b"), + ASPIIndexSpec("Fi"), + ] + + def __eq__(self, other): + return self.Fi == other + + __hash__ = Frame.__hash__ + + +Frames = dict([(k, v) for (k, v) in globals().items() + if len(k) == 4 and isinstance(v, type) and + issubclass(v, Frame)]) +"""All supported ID3v2 frames, keyed by frame name.""" + +del(k) +del(v) + + +# ID3v2.2 frames +class UFI(UFID): + "Unique File Identifier" + + +class TT1(TIT1): + "Content group description" + + +class TT2(TIT2): + "Title" + + +class TT3(TIT3): + "Subtitle/Description refinement" + + +class TP1(TPE1): + "Lead Artist/Performer/Soloist/Group" + + +class TP2(TPE2): + "Band/Orchestra/Accompaniment" + + +class TP3(TPE3): + "Conductor" + + +class TP4(TPE4): + "Interpreter/Remixer/Modifier" + + +class TCM(TCOM): + "Composer" + + +class TXT(TEXT): + "Lyricist" + + +class TLA(TLAN): + "Audio Language(s)" + + +class TCO(TCON): + "Content Type (Genre)" + + +class TAL(TALB): + "Album" + + +class TPA(TPOS): + "Part of set" + + +class TRK(TRCK): + "Track Number" + + +class TRC(TSRC): + "International Standard Recording Code (ISRC)" + + +class TYE(TYER): + "Year of recording" + + +class TDA(TDAT): + "Date of recording (DDMM)" + + +class TIM(TIME): + "Time of recording (HHMM)" + + +class TRD(TRDA): + "Recording Dates" + + +class TMT(TMED): + "Source Media Type" + + +class TFT(TFLT): + "File Type" + + +class TBP(TBPM): + "Beats per minute" + + +class TCP(TCMP): + "iTunes Compilation Flag" + + +class TCR(TCOP): + "Copyright (C)" + + +class TPB(TPUB): + "Publisher" + + +class TEN(TENC): + "Encoder" + + +class TSS(TSSE): + "Encoder settings" + + +class TOF(TOFN): + "Original Filename" + + +class TLE(TLEN): + "Audio Length (ms)" + + +class TSI(TSIZ): + "Audio Data size (bytes)" + + +class TDY(TDLY): + "Audio Delay (ms)" + + +class TKE(TKEY): + "Starting Key" + + +class TOT(TOAL): + "Original Album" + + +class TOA(TOPE): + "Original Artist/Perfomer" + + +class TOL(TOLY): + "Original Lyricist" + + +class TOR(TORY): + "Original Release Year" + + +class TXX(TXXX): + "User-defined Text" + + +class WAF(WOAF): + "Official File Information" + + +class WAR(WOAR): + "Official Artist/Performer Information" + + +class WAS(WOAS): + "Official Source Information" + + +class WCM(WCOM): + "Commercial Information" + + +class WCP(WCOP): + "Copyright Information" + + +class WPB(WPUB): + "Official Publisher Information" + + +class WXX(WXXX): + "User-defined URL" + + +class IPL(IPLS): + "Involved people list" + + +class MCI(MCDI): + "Binary dump of CD's TOC" + + +class ETC(ETCO): + "Event timing codes" + + +class MLL(MLLT): + "MPEG location lookup table" + + +class STC(SYTC): + "Synced tempo codes" + + +class ULT(USLT): + "Unsychronised lyrics/text transcription" + + +class SLT(SYLT): + "Synchronised lyrics/text" + + +class COM(COMM): + "Comment" + + +#class RVA(RVAD) +#class EQU(EQUA) + + +class REV(RVRB): + "Reverb" + + +class PIC(APIC): + """Attached Picture. + + The 'mime' attribute of an ID3v2.2 attached picture must be either + 'PNG' or 'JPG'. + """ + _framespec = [EncodingSpec('encoding'), StringSpec('mime', 3), + ByteSpec('type'), EncodedTextSpec('desc'), + BinaryDataSpec('data')] + + +class GEO(GEOB): + "General Encapsulated Object" + + +class CNT(PCNT): + "Play counter" + + +class POP(POPM): + "Popularimeter" + + +class BUF(RBUF): + "Recommended buffer size" + + +class CRM(Frame): + """Encrypted meta frame""" + _framespec = [Latin1TextSpec('owner'), Latin1TextSpec('desc'), + BinaryDataSpec('data')] + + def __eq__(self, other): + return self.data == other + __hash__ = Frame.__hash__ + + +class CRA(AENC): + "Audio encryption" + + +class LNK(LINK): + """Linked information""" + _framespec = [StringSpec('frameid', 3), Latin1TextSpec('url')] + _optionalspec = [BinaryDataSpec('data')] + + +Frames_2_2 = dict([(k, v) for (k, v) in globals().items() + if len(k) == 3 and isinstance(v, type) and + issubclass(v, Frame)]) + +del k +del v diff --git a/libs/mutagen/_id3specs.py b/libs/mutagen/_id3specs.py new file mode 100644 index 00000000..32ef3afe --- /dev/null +++ b/libs/mutagen/_id3specs.py @@ -0,0 +1,465 @@ +# Copyright (C) 2005 Michael Urman +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. + +import struct +from struct import unpack, pack +from warnings import warn + +from mutagen._id3util import ID3JunkFrameError, ID3Warning, BitPaddedInt + + +class Spec(object): + def __init__(self, name): + self.name = name + + def __hash__(self): + raise TypeError("Spec objects are unhashable") + + def _validate23(self, frame, value, **kwargs): + """Return a possibly modified value which, if written, + results in valid id3v2.3 data. + """ + + return value + + +class ByteSpec(Spec): + def read(self, frame, data): + return ord(data[0]), data[1:] + + def write(self, frame, value): + return chr(value) + + def validate(self, frame, value): + if value is not None: + chr(value) + return value + + +class IntegerSpec(Spec): + def read(self, frame, data): + return int(BitPaddedInt(data, bits=8)), '' + + def write(self, frame, value): + return BitPaddedInt.to_str(value, bits=8, width=-1) + + def validate(self, frame, value): + return value + + +class SizedIntegerSpec(Spec): + def __init__(self, name, size): + self.name, self.__sz = name, size + + def read(self, frame, data): + return int(BitPaddedInt(data[:self.__sz], bits=8)), data[self.__sz:] + + def write(self, frame, value): + return BitPaddedInt.to_str(value, bits=8, width=self.__sz) + + def validate(self, frame, value): + return value + + +class EncodingSpec(ByteSpec): + def read(self, frame, data): + enc, data = super(EncodingSpec, self).read(frame, data) + if enc < 16: + return enc, data + else: + return 0, chr(enc)+data + + def validate(self, frame, value): + if 0 <= value <= 3: + return value + if value is None: + return None + raise ValueError('Invalid Encoding: %r' % value) + + def _validate23(self, frame, value, **kwargs): + # only 0, 1 are valid in v2.3, default to utf-16 + return min(1, value) + + +class StringSpec(Spec): + def __init__(self, name, length): + super(StringSpec, self).__init__(name) + self.len = length + + def read(s, frame, data): + return data[:s.len], data[s.len:] + + def write(s, frame, value): + if value is None: + return '\x00' * s.len + else: + return (str(value) + '\x00' * s.len)[:s.len] + + def validate(s, frame, value): + if value is None: + return None + if isinstance(value, basestring) and len(value) == s.len: + return value + raise ValueError('Invalid StringSpec[%d] data: %r' % (s.len, value)) + + +class BinaryDataSpec(Spec): + def read(self, frame, data): + return data, '' + + def write(self, frame, value): + return str(value) + + def validate(self, frame, value): + return str(value) + + +class EncodedTextSpec(Spec): + # Okay, seriously. This is private and defined explicitly and + # completely by the ID3 specification. You can't just add + # encodings here however you want. + _encodings = ( + ('latin1', '\x00'), + ('utf16', '\x00\x00'), + ('utf_16_be', '\x00\x00'), + ('utf8', '\x00') + ) + + def read(self, frame, data): + enc, term = self._encodings[frame.encoding] + ret = '' + if len(term) == 1: + if term in data: + data, ret = data.split(term, 1) + else: + offset = -1 + try: + while True: + offset = data.index(term, offset+1) + if offset & 1: + continue + data, ret = data[0:offset], data[offset+2:] + break + except ValueError: + pass + + if len(data) < len(term): + return u'', ret + return data.decode(enc), ret + + def write(self, frame, value): + enc, term = self._encodings[frame.encoding] + return value.encode(enc) + term + + def validate(self, frame, value): + return unicode(value) + + +class MultiSpec(Spec): + def __init__(self, name, *specs, **kw): + super(MultiSpec, self).__init__(name) + self.specs = specs + self.sep = kw.get('sep') + + def read(self, frame, data): + values = [] + while data: + record = [] + for spec in self.specs: + value, data = spec.read(frame, data) + record.append(value) + if len(self.specs) != 1: + values.append(record) + else: + values.append(record[0]) + return values, data + + def write(self, frame, value): + data = [] + if len(self.specs) == 1: + for v in value: + data.append(self.specs[0].write(frame, v)) + else: + for record in value: + for v, s in zip(record, self.specs): + data.append(s.write(frame, v)) + return ''.join(data) + + def validate(self, frame, value): + if value is None: + return [] + if self.sep and isinstance(value, basestring): + value = value.split(self.sep) + if isinstance(value, list): + if len(self.specs) == 1: + return [self.specs[0].validate(frame, v) for v in value] + else: + return [ + [s.validate(frame, v) for (v, s) in zip(val, self.specs)] + for val in value] + raise ValueError('Invalid MultiSpec data: %r' % value) + + def _validate23(self, frame, value, **kwargs): + if len(self.specs) != 1: + return [[s._validate23(frame, v, **kwargs) + for (v, s) in zip(val, self.specs)] + for val in value] + + spec = self.specs[0] + + # Merge single text spec multispecs only. + # (TimeStampSpec beeing the exception, but it's not a valid v2.3 frame) + if not isinstance(spec, EncodedTextSpec) or \ + isinstance(spec, TimeStampSpec): + return value + + value = [spec._validate23(frame, v, **kwargs) for v in value] + if kwargs.get("sep") is not None: + return [spec.validate(frame, kwargs["sep"].join(value))] + return value + + +class EncodedNumericTextSpec(EncodedTextSpec): + pass + + +class EncodedNumericPartTextSpec(EncodedTextSpec): + pass + + +class Latin1TextSpec(EncodedTextSpec): + def read(self, frame, data): + if '\x00' in data: + data, ret = data.split('\x00', 1) + else: + ret = '' + return data.decode('latin1'), ret + + def write(self, data, value): + return value.encode('latin1') + '\x00' + + def validate(self, frame, value): + return unicode(value) + + +class ID3TimeStamp(object): + """A time stamp in ID3v2 format. + + This is a restricted form of the ISO 8601 standard; time stamps + take the form of: + YYYY-MM-DD HH:MM:SS + Or some partial form (YYYY-MM-DD HH, YYYY, etc.). + + The 'text' attribute contains the raw text data of the time stamp. + """ + + import re + + def __init__(self, text): + if isinstance(text, ID3TimeStamp): + text = text.text + self.text = text + + __formats = ['%04d'] + ['%02d'] * 5 + __seps = ['-', '-', ' ', ':', ':', 'x'] + + def get_text(self): + parts = [self.year, self.month, self.day, + self.hour, self.minute, self.second] + pieces = [] + for i, part in enumerate(iter(iter(parts).next, None)): + pieces.append(self.__formats[i] % part + self.__seps[i]) + return u''.join(pieces)[:-1] + + def set_text(self, text, splitre=re.compile('[-T:/.]|\s+')): + year, month, day, hour, minute, second = \ + splitre.split(text + ':::::')[:6] + for a in 'year month day hour minute second'.split(): + try: + v = int(locals()[a]) + except ValueError: + v = None + setattr(self, a, v) + + text = property(get_text, set_text, doc="ID3v2.4 date and time.") + + def __str__(self): + return self.text + + def __repr__(self): + return repr(self.text) + + def __cmp__(self, other): + return cmp(self.text, other.text) + + __hash__ = object.__hash__ + + def encode(self, *args): + return self.text.encode(*args) + + +class TimeStampSpec(EncodedTextSpec): + def read(self, frame, data): + value, data = super(TimeStampSpec, self).read(frame, data) + return self.validate(frame, value), data + + def write(self, frame, data): + return super(TimeStampSpec, self).write(frame, + data.text.replace(' ', 'T')) + + def validate(self, frame, value): + try: + return ID3TimeStamp(value) + except TypeError: + raise ValueError("Invalid ID3TimeStamp: %r" % value) + + +class ChannelSpec(ByteSpec): + (OTHER, MASTER, FRONTRIGHT, FRONTLEFT, BACKRIGHT, BACKLEFT, FRONTCENTRE, + BACKCENTRE, SUBWOOFER) = range(9) + + +class VolumeAdjustmentSpec(Spec): + def read(self, frame, data): + value, = unpack('>h', data[0:2]) + return value/512.0, data[2:] + + def write(self, frame, value): + return pack('>h', int(round(value * 512))) + + def validate(self, frame, value): + if value is not None: + try: + self.write(frame, value) + except struct.error: + raise ValueError("out of range") + return value + + +class VolumePeakSpec(Spec): + def read(self, frame, data): + # http://bugs.xmms.org/attachment.cgi?id=113&action=view + peak = 0 + bits = ord(data[0]) + bytes = min(4, (bits + 7) >> 3) + # not enough frame data + if bytes + 1 > len(data): + raise ID3JunkFrameError + shift = ((8 - (bits & 7)) & 7) + (4 - bytes) * 8 + for i in range(1, bytes+1): + peak *= 256 + peak += ord(data[i]) + peak *= 2 ** shift + return (float(peak) / (2**31-1)), data[1+bytes:] + + def write(self, frame, value): + # always write as 16 bits for sanity. + return "\x10" + pack('>H', int(round(value * 32768))) + + def validate(self, frame, value): + if value is not None: + try: + self.write(frame, value) + except struct.error: + raise ValueError("out of range") + return value + + +class SynchronizedTextSpec(EncodedTextSpec): + def read(self, frame, data): + texts = [] + encoding, term = self._encodings[frame.encoding] + while data: + l = len(term) + try: + value_idx = data.index(term) + except ValueError: + raise ID3JunkFrameError + value = data[:value_idx].decode(encoding) + if len(data) < value_idx + l + 4: + raise ID3JunkFrameError + time, = struct.unpack(">I", data[value_idx+l:value_idx+l+4]) + texts.append((value, time)) + data = data[value_idx+l+4:] + return texts, "" + + def write(self, frame, value): + data = [] + encoding, term = self._encodings[frame.encoding] + for text, time in frame.text: + text = text.encode(encoding) + term + data.append(text + struct.pack(">I", time)) + return "".join(data) + + def validate(self, frame, value): + return value + + +class KeyEventSpec(Spec): + def read(self, frame, data): + events = [] + while len(data) >= 5: + events.append(struct.unpack(">bI", data[:5])) + data = data[5:] + return events, data + + def write(self, frame, value): + return "".join([struct.pack(">bI", *event) for event in value]) + + def validate(self, frame, value): + return value + + +class VolumeAdjustmentsSpec(Spec): + # Not to be confused with VolumeAdjustmentSpec. + def read(self, frame, data): + adjustments = {} + while len(data) >= 4: + freq, adj = struct.unpack(">Hh", data[:4]) + data = data[4:] + freq /= 2.0 + adj /= 512.0 + adjustments[freq] = adj + adjustments = adjustments.items() + adjustments.sort() + return adjustments, data + + def write(self, frame, value): + value.sort() + return "".join([struct.pack(">Hh", int(freq * 2), int(adj * 512)) + for (freq, adj) in value]) + + def validate(self, frame, value): + return value + + +class ASPIIndexSpec(Spec): + def read(self, frame, data): + if frame.b == 16: + format = "H" + size = 2 + elif frame.b == 8: + format = "B" + size = 1 + else: + warn("invalid bit count in ASPI (%d)" % frame.b, ID3Warning) + return [], data + + indexes = data[:frame.N * size] + data = data[frame.N * size:] + return list(struct.unpack(">" + format * frame.N, indexes)), data + + def write(self, frame, values): + if frame.b == 16: + format = "H" + elif frame.b == 8: + format = "B" + else: + raise ValueError("frame.b must be 8 or 16") + return struct.pack(">" + format * frame.N, *values) + + def validate(self, frame, values): + return values diff --git a/libs/mutagen/_id3util.py b/libs/mutagen/_id3util.py new file mode 100644 index 00000000..de82e36a --- /dev/null +++ b/libs/mutagen/_id3util.py @@ -0,0 +1,176 @@ +# Copyright (C) 2005 Michael Urman +# 2013 Christoph Reiter +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. + + +class error(Exception): + pass + + +class ID3NoHeaderError(error, ValueError): + pass + + +class ID3BadUnsynchData(error, ValueError): + pass + + +class ID3BadCompressedData(error, ValueError): + pass + + +class ID3TagError(error, ValueError): + pass + + +class ID3UnsupportedVersionError(error, NotImplementedError): + pass + + +class ID3EncryptionUnsupportedError(error, NotImplementedError): + pass + + +class ID3JunkFrameError(error, ValueError): + pass + + +class ID3Warning(error, UserWarning): + pass + + +class unsynch(object): + @staticmethod + def decode(value): + output = [] + safe = True + append = output.append + for val in value: + if safe: + append(val) + safe = val != '\xFF' + else: + if val >= '\xE0': + raise ValueError('invalid sync-safe string') + elif val != '\x00': + append(val) + safe = True + if not safe: + raise ValueError('string ended unsafe') + return ''.join(output) + + @staticmethod + def encode(value): + output = [] + safe = True + append = output.append + for val in value: + if safe: + append(val) + if val == '\xFF': + safe = False + elif val == '\x00' or val >= '\xE0': + append('\x00') + append(val) + safe = val != '\xFF' + else: + append(val) + safe = True + if not safe: + append('\x00') + return ''.join(output) + + +class _BitPaddedMixin(object): + + def as_str(self, width=4, minwidth=4): + return self.to_str(self, self.bits, self.bigendian, width, minwidth) + + @staticmethod + def to_str(value, bits=7, bigendian=True, width=4, minwidth=4): + mask = (1 << bits) - 1 + + if width != -1: + index = 0 + bytes_ = bytearray(width) + try: + while value: + bytes_[index] = value & mask + value >>= bits + index += 1 + except IndexError: + raise ValueError('Value too wide (>%d bytes)' % width) + else: + # PCNT and POPM use growing integers + # of at least 4 bytes (=minwidth) as counters. + bytes_ = bytearray() + append = bytes_.append + while value: + append(value & mask) + value >>= bits + bytes_ = bytes_.ljust(minwidth, "\x00") + + if bigendian: + bytes_.reverse() + return str(bytes_) + + @staticmethod + def has_valid_padding(value, bits=7): + """Whether the padding bits are all zero""" + + assert bits <= 8 + + mask = (((1 << (8 - bits)) - 1) << bits) + + if isinstance(value, (int, long)): + while value: + if value & mask: + return False + value >>= 8 + elif isinstance(value, str): + for byte in value: + if ord(byte) & mask: + return False + else: + raise TypeError + + return True + + +class BitPaddedInt(int, _BitPaddedMixin): + + def __new__(cls, value, bits=7, bigendian=True): + + mask = (1 << (bits)) - 1 + numeric_value = 0 + shift = 0 + + if isinstance(value, (int, long)): + while value: + numeric_value += (value & mask) << shift + value >>= 8 + shift += bits + elif isinstance(value, str): + if bigendian: + value = reversed(value) + for byte in value: + numeric_value += (ord(byte) & mask) << shift + shift += bits + else: + raise TypeError + + if isinstance(numeric_value, long): + self = long.__new__(BitPaddedLong, numeric_value) + else: + self = int.__new__(BitPaddedInt, numeric_value) + + self.bits = bits + self.bigendian = bigendian + return self + + +class BitPaddedLong(long, _BitPaddedMixin): + pass diff --git a/libs/mutagen/_util.py b/libs/mutagen/_util.py new file mode 100644 index 00000000..2c8e1a56 --- /dev/null +++ b/libs/mutagen/_util.py @@ -0,0 +1,349 @@ +# Copyright 2006 Joe Wreschnig +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +"""Utility classes for Mutagen. + +You should not rely on the interfaces here being stable. They are +intended for internal use in Mutagen only. +""" + +import struct + +from fnmatch import fnmatchcase + + +class DictMixin(object): + """Implement the dict API using keys() and __*item__ methods. + + Similar to UserDict.DictMixin, this takes a class that defines + __getitem__, __setitem__, __delitem__, and keys(), and turns it + into a full dict-like object. + + UserDict.DictMixin is not suitable for this purpose because it's + an old-style class. + + This class is not optimized for very large dictionaries; many + functions have linear memory requirements. I recommend you + override some of these functions if speed is required. + """ + + def __iter__(self): + return iter(self.keys()) + + def has_key(self, key): + try: + self[key] + except KeyError: + return False + else: + return True + __contains__ = has_key + + iterkeys = lambda self: iter(self.keys()) + + def values(self): + return map(self.__getitem__, self.keys()) + itervalues = lambda self: iter(self.values()) + + def items(self): + return zip(self.keys(), self.values()) + iteritems = lambda s: iter(s.items()) + + def clear(self): + map(self.__delitem__, self.keys()) + + def pop(self, key, *args): + if len(args) > 1: + raise TypeError("pop takes at most two arguments") + try: + value = self[key] + except KeyError: + if args: + return args[0] + else: + raise + del(self[key]) + return value + + def popitem(self): + try: + key = self.keys()[0] + return key, self.pop(key) + except IndexError: + raise KeyError("dictionary is empty") + + def update(self, other=None, **kwargs): + if other is None: + self.update(kwargs) + other = {} + + try: + map(self.__setitem__, other.keys(), other.values()) + except AttributeError: + for key, value in other: + self[key] = value + + def setdefault(self, key, default=None): + try: + return self[key] + except KeyError: + self[key] = default + return default + + def get(self, key, default=None): + try: + return self[key] + except KeyError: + return default + + def __repr__(self): + return repr(dict(self.items())) + + def __cmp__(self, other): + if other is None: + return 1 + else: + return cmp(dict(self.items()), other) + + __hash__ = object.__hash__ + + def __len__(self): + return len(self.keys()) + + +class DictProxy(DictMixin): + def __init__(self, *args, **kwargs): + self.__dict = {} + super(DictProxy, self).__init__(*args, **kwargs) + + def __getitem__(self, key): + return self.__dict[key] + + def __setitem__(self, key, value): + self.__dict[key] = value + + def __delitem__(self, key): + del(self.__dict[key]) + + def keys(self): + return self.__dict.keys() + + +class cdata(object): + """C character buffer to Python numeric type conversions.""" + + from struct import error + error = error + + short_le = staticmethod(lambda data: struct.unpack('h', data)[0]) + ushort_be = staticmethod(lambda data: struct.unpack('>H', data)[0]) + + int_le = staticmethod(lambda data: struct.unpack('i', data)[0]) + uint_be = staticmethod(lambda data: struct.unpack('>I', data)[0]) + + longlong_le = staticmethod(lambda data: struct.unpack('q', data)[0]) + ulonglong_be = staticmethod(lambda data: struct.unpack('>Q', data)[0]) + + to_short_le = staticmethod(lambda data: struct.pack('h', data)) + to_ushort_be = staticmethod(lambda data: struct.pack('>H', data)) + + to_int_le = staticmethod(lambda data: struct.pack('i', data)) + to_uint_be = staticmethod(lambda data: struct.pack('>I', data)) + + to_longlong_le = staticmethod(lambda data: struct.pack('q', data)) + to_ulonglong_be = staticmethod(lambda data: struct.pack('>Q', data)) + + bitswap = ''.join([chr(sum([((val >> i) & 1) << (7-i) for i in range(8)])) + for val in range(256)]) + del(i) + del(val) + + test_bit = staticmethod(lambda value, n: bool((value >> n) & 1)) + + +def lock(fileobj): + """Lock a file object 'safely'. + + That means a failure to lock because the platform doesn't + support fcntl or filesystem locks is not considered a + failure. This call does block. + + Returns whether or not the lock was successful, or + raises an exception in more extreme circumstances (full + lock table, invalid file). + """ + + try: + import fcntl + except ImportError: + return False + else: + try: + fcntl.lockf(fileobj, fcntl.LOCK_EX) + except IOError: + # FIXME: There's possibly a lot of complicated + # logic that needs to go here in case the IOError + # is EACCES or EAGAIN. + return False + else: + return True + + +def unlock(fileobj): + """Unlock a file object. + + Don't call this on a file object unless a call to lock() + returned true. + """ + + # If this fails there's a mismatched lock/unlock pair, + # so we definitely don't want to ignore errors. + import fcntl + fcntl.lockf(fileobj, fcntl.LOCK_UN) + + +def insert_bytes(fobj, size, offset, BUFFER_SIZE=2**16): + """Insert size bytes of empty space starting at offset. + + fobj must be an open file object, open rb+ or + equivalent. Mutagen tries to use mmap to resize the file, but + falls back to a significantly slower method if mmap fails. + """ + + assert 0 < size + assert 0 <= offset + locked = False + fobj.seek(0, 2) + filesize = fobj.tell() + movesize = filesize - offset + fobj.write('\x00' * size) + fobj.flush() + try: + try: + import mmap + map = mmap.mmap(fobj.fileno(), filesize + size) + try: + map.move(offset + size, offset, movesize) + finally: + map.close() + except (ValueError, EnvironmentError, ImportError): + # handle broken mmap scenarios + locked = lock(fobj) + fobj.truncate(filesize) + + fobj.seek(0, 2) + padsize = size + # Don't generate an enormous string if we need to pad + # the file out several megs. + while padsize: + addsize = min(BUFFER_SIZE, padsize) + fobj.write("\x00" * addsize) + padsize -= addsize + + fobj.seek(filesize, 0) + while movesize: + # At the start of this loop, fobj is pointing at the end + # of the data we need to move, which is of movesize length. + thismove = min(BUFFER_SIZE, movesize) + # Seek back however much we're going to read this frame. + fobj.seek(-thismove, 1) + nextpos = fobj.tell() + # Read it, so we're back at the end. + data = fobj.read(thismove) + # Seek back to where we need to write it. + fobj.seek(-thismove + size, 1) + # Write it. + fobj.write(data) + # And seek back to the end of the unmoved data. + fobj.seek(nextpos) + movesize -= thismove + + fobj.flush() + finally: + if locked: + unlock(fobj) + + +def delete_bytes(fobj, size, offset, BUFFER_SIZE=2**16): + """Delete size bytes of empty space starting at offset. + + fobj must be an open file object, open rb+ or + equivalent. Mutagen tries to use mmap to resize the file, but + falls back to a significantly slower method if mmap fails. + """ + + locked = False + assert 0 < size + assert 0 <= offset + fobj.seek(0, 2) + filesize = fobj.tell() + movesize = filesize - offset - size + assert 0 <= movesize + try: + if movesize > 0: + fobj.flush() + try: + import mmap + map = mmap.mmap(fobj.fileno(), filesize) + try: + map.move(offset, offset + size, movesize) + finally: + map.close() + except (ValueError, EnvironmentError, ImportError): + # handle broken mmap scenarios + locked = lock(fobj) + fobj.seek(offset + size) + buf = fobj.read(BUFFER_SIZE) + while buf: + fobj.seek(offset) + fobj.write(buf) + offset += len(buf) + fobj.seek(offset + size) + buf = fobj.read(BUFFER_SIZE) + fobj.truncate(filesize - size) + fobj.flush() + finally: + if locked: + unlock(fobj) + + +def utf8(data): + """Convert a basestring to a valid UTF-8 str.""" + + if isinstance(data, str): + return data.decode("utf-8", "replace").encode("utf-8") + elif isinstance(data, unicode): + return data.encode("utf-8") + else: + raise TypeError("only unicode/str types can be converted to UTF-8") + + +def dict_match(d, key, default=None): + try: + return d[key] + except KeyError: + for pattern, value in d.iteritems(): + if fnmatchcase(key, pattern): + return value + return default diff --git a/libs/mutagen/_vorbis.py b/libs/mutagen/_vorbis.py new file mode 100644 index 00000000..4ee8da4a --- /dev/null +++ b/libs/mutagen/_vorbis.py @@ -0,0 +1,254 @@ +# Vorbis comment support for Mutagen +# Copyright 2005-2006 Joe Wreschnig +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. + +"""Read and write Vorbis comment data. + +Vorbis comments are freeform key/value pairs; keys are +case-insensitive ASCII and values are Unicode strings. A key may have +multiple values. + +The specification is at http://www.xiph.org/vorbis/doc/v-comment.html. +""" + +import sys + +from cStringIO import StringIO + +import mutagen +from mutagen._util import DictMixin, cdata + + +def is_valid_key(key): + """Return true if a string is a valid Vorbis comment key. + + Valid Vorbis comment keys are printable ASCII between 0x20 (space) + and 0x7D ('}'), excluding '='. + """ + for c in key: + if c < " " or c > "}" or c == "=": + return False + else: + return bool(key) + +istag = is_valid_key + + +class error(IOError): + pass + + +class VorbisUnsetFrameError(error): + pass + + +class VorbisEncodingError(error): + pass + + +class VComment(mutagen.Metadata, list): + """A Vorbis comment parser, accessor, and renderer. + + All comment ordering is preserved. A VComment is a list of + key/value pairs, and so any Python list method can be used on it. + + Vorbis comments are always wrapped in something like an Ogg Vorbis + bitstream or a FLAC metadata block, so this loads string data or a + file-like object, not a filename. + + Attributes: + vendor -- the stream 'vendor' (i.e. writer); default 'Mutagen' + """ + + vendor = u"Mutagen " + mutagen.version_string + + def __init__(self, data=None, *args, **kwargs): + # Collect the args to pass to load, this lets child classes + # override just load and get equivalent magic for the + # constructor. + if data is not None: + if isinstance(data, str): + data = StringIO(data) + elif not hasattr(data, 'read'): + raise TypeError("VComment requires string data or a file-like") + self.load(data, *args, **kwargs) + + def load(self, fileobj, errors='replace', framing=True): + """Parse a Vorbis comment from a file-like object. + + Keyword arguments: + errors: + 'strict', 'replace', or 'ignore'. This affects Unicode decoding + and how other malformed content is interpreted. + framing -- if true, fail if a framing bit is not present + + Framing bits are required by the Vorbis comment specification, + but are not used in FLAC Vorbis comment blocks. + + """ + try: + vendor_length = cdata.uint_le(fileobj.read(4)) + self.vendor = fileobj.read(vendor_length).decode('utf-8', errors) + count = cdata.uint_le(fileobj.read(4)) + for i in xrange(count): + length = cdata.uint_le(fileobj.read(4)) + try: + string = fileobj.read(length).decode('utf-8', errors) + except (OverflowError, MemoryError): + raise error("cannot read %d bytes, too large" % length) + try: + tag, value = string.split('=', 1) + except ValueError, err: + if errors == "ignore": + continue + elif errors == "replace": + tag, value = u"unknown%d" % i, string + else: + raise VorbisEncodingError, err, sys.exc_info()[2] + try: + tag = tag.encode('ascii', errors) + except UnicodeEncodeError: + raise VorbisEncodingError("invalid tag name %r" % tag) + else: + if is_valid_key(tag): + self.append((tag, value)) + if framing and not ord(fileobj.read(1)) & 0x01: + raise VorbisUnsetFrameError("framing bit was unset") + except (cdata.error, TypeError): + raise error("file is not a valid Vorbis comment") + + def validate(self): + """Validate keys and values. + + Check to make sure every key used is a valid Vorbis key, and + that every value used is a valid Unicode or UTF-8 string. If + any invalid keys or values are found, a ValueError is raised. + """ + + if not isinstance(self.vendor, unicode): + try: + self.vendor.decode('utf-8') + except UnicodeDecodeError: + raise ValueError + + for key, value in self: + try: + if not is_valid_key(key): + raise ValueError + except: + raise ValueError("%r is not a valid key" % key) + if not isinstance(value, unicode): + try: + value.encode("utf-8") + except: + raise ValueError("%r is not a valid value" % value) + else: + return True + + def clear(self): + """Clear all keys from the comment.""" + del(self[:]) + + def write(self, framing=True): + """Return a string representation of the data. + + Validation is always performed, so calling this function on + invalid data may raise a ValueError. + + Keyword arguments: + framing -- if true, append a framing bit (see load) + """ + + self.validate() + + f = StringIO() + f.write(cdata.to_uint_le(len(self.vendor.encode('utf-8')))) + f.write(self.vendor.encode('utf-8')) + f.write(cdata.to_uint_le(len(self))) + for tag, value in self: + comment = "%s=%s" % (tag, value.encode('utf-8')) + f.write(cdata.to_uint_le(len(comment))) + f.write(comment) + if framing: + f.write("\x01") + return f.getvalue() + + def pprint(self): + return "\n".join(["%s=%s" % (k.lower(), v) for k, v in self]) + + +class VCommentDict(VComment, DictMixin): + """A VComment that looks like a dictionary. + + This object differs from a dictionary in two ways. First, + len(comment) will still return the number of values, not the + number of keys. Secondly, iterating through the object will + iterate over (key, value) pairs, not keys. Since a key may have + multiple values, the same value may appear multiple times while + iterating. + + Since Vorbis comment keys are case-insensitive, all keys are + normalized to lowercase ASCII. + """ + + def __getitem__(self, key): + """A list of values for the key. + + This is a copy, so comment['title'].append('a title') will not + work. + + """ + key = key.lower().encode('ascii') + values = [value for (k, value) in self if k.lower() == key] + if not values: + raise KeyError(key) + else: + return values + + def __delitem__(self, key): + """Delete all values associated with the key.""" + key = key.lower().encode('ascii') + to_delete = filter(lambda x: x[0].lower() == key, self) + if not to_delete: + raise KeyError(key) + else: + map(self.remove, to_delete) + + def __contains__(self, key): + """Return true if the key has any values.""" + key = key.lower().encode('ascii') + for k, value in self: + if k.lower() == key: + return True + else: + return False + + def __setitem__(self, key, values): + """Set a key's value or values. + + Setting a value overwrites all old ones. The value may be a + list of Unicode or UTF-8 strings, or a single Unicode or UTF-8 + string. + + """ + + key = key.encode('ascii') + if not isinstance(values, list): + values = [values] + try: + del(self[key]) + except KeyError: + pass + for value in values: + self.append((key, value)) + + def keys(self): + """Return all keys in the comment.""" + return self and list(set([k.lower() for k, v in self])) + + def as_dict(self): + """Return a copy of the comment data in a real dict.""" + return dict([(key, self[key]) for key in self.keys()]) diff --git a/libs/mutagen/apev2.py b/libs/mutagen/apev2.py new file mode 100644 index 00000000..aa1e00e6 --- /dev/null +++ b/libs/mutagen/apev2.py @@ -0,0 +1,525 @@ +# An APEv2 tag reader +# +# Copyright 2005 Joe Wreschnig +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +"""APEv2 reading and writing. + +The APEv2 format is most commonly used with Musepack files, but is +also the format of choice for WavPack and other formats. Some MP3s +also have APEv2 tags, but this can cause problems with many MP3 +decoders and taggers. + +APEv2 tags, like Vorbis comments, are freeform key=value pairs. APEv2 +keys can be any ASCII string with characters from 0x20 to 0x7E, +between 2 and 255 characters long. Keys are case-sensitive, but +readers are recommended to be case insensitive, and it is forbidden to +multiple keys which differ only in case. Keys are usually stored +title-cased (e.g. 'Artist' rather than 'artist'). + +APEv2 values are slightly more structured than Vorbis comments; values +are flagged as one of text, binary, or an external reference (usually +a URI). + +Based off the format specification found at +http://wiki.hydrogenaudio.org/index.php?title=APEv2_specification. +""" + +__all__ = ["APEv2", "APEv2File", "Open", "delete"] + +import struct +from cStringIO import StringIO + +from mutagen import Metadata, FileType +from mutagen._util import DictMixin, cdata, utf8, delete_bytes + + +def is_valid_apev2_key(key): + return (2 <= len(key) <= 255 and min(key) >= ' ' and max(key) <= '~' and + key not in ["OggS", "TAG", "ID3", "MP+"]) + +# There are three different kinds of APE tag values. +# "0: Item contains text information coded in UTF-8 +# 1: Item contains binary information +# 2: Item is a locator of external stored information [e.g. URL] +# 3: reserved" +TEXT, BINARY, EXTERNAL = range(3) + +HAS_HEADER = 1L << 31 +HAS_NO_FOOTER = 1L << 30 +IS_HEADER = 1L << 29 + + +class error(IOError): + pass + + +class APENoHeaderError(error, ValueError): + pass + + +class APEUnsupportedVersionError(error, ValueError): + pass + + +class APEBadItemError(error, ValueError): + pass + + +class _APEv2Data(object): + # Store offsets of the important parts of the file. + start = header = data = footer = end = None + # Footer or header; seek here and read 32 to get version/size/items/flags + metadata = None + # Actual tag data + tag = None + + version = None + size = None + items = None + flags = 0 + + # The tag is at the start rather than the end. A tag at both + # the start and end of the file (i.e. the tag is the whole file) + # is not considered to be at the start. + is_at_start = False + + def __init__(self, fileobj): + self.__find_metadata(fileobj) + self.metadata = max(self.header, self.footer) + if self.metadata is None: + return + self.__fill_missing(fileobj) + self.__fix_brokenness(fileobj) + if self.data is not None: + fileobj.seek(self.data) + self.tag = fileobj.read(self.size) + + def __find_metadata(self, fileobj): + # Try to find a header or footer. + + # Check for a simple footer. + try: + fileobj.seek(-32, 2) + except IOError: + fileobj.seek(0, 2) + return + if fileobj.read(8) == "APETAGEX": + fileobj.seek(-8, 1) + self.footer = self.metadata = fileobj.tell() + return + + # Check for an APEv2 tag followed by an ID3v1 tag at the end. + try: + fileobj.seek(-128, 2) + if fileobj.read(3) == "TAG": + + fileobj.seek(-35, 1) # "TAG" + header length + if fileobj.read(8) == "APETAGEX": + fileobj.seek(-8, 1) + self.footer = fileobj.tell() + return + + # ID3v1 tag at the end, maybe preceded by Lyrics3v2. + # (http://www.id3.org/lyrics3200.html) + # (header length - "APETAGEX") - "LYRICS200" + fileobj.seek(15, 1) + if fileobj.read(9) == 'LYRICS200': + fileobj.seek(-15, 1) # "LYRICS200" + size tag + try: + offset = int(fileobj.read(6)) + except ValueError: + raise IOError + + fileobj.seek(-32 - offset - 6, 1) + if fileobj.read(8) == "APETAGEX": + fileobj.seek(-8, 1) + self.footer = fileobj.tell() + return + + except IOError: + pass + + # Check for a tag at the start. + fileobj.seek(0, 0) + if fileobj.read(8) == "APETAGEX": + self.is_at_start = True + self.header = 0 + + def __fill_missing(self, fileobj): + fileobj.seek(self.metadata + 8) + self.version = fileobj.read(4) + self.size = cdata.uint_le(fileobj.read(4)) + self.items = cdata.uint_le(fileobj.read(4)) + self.flags = cdata.uint_le(fileobj.read(4)) + + if self.header is not None: + self.data = self.header + 32 + # If we're reading the header, the size is the header + # offset + the size, which includes the footer. + self.end = self.data + self.size + fileobj.seek(self.end - 32, 0) + if fileobj.read(8) == "APETAGEX": + self.footer = self.end - 32 + elif self.footer is not None: + self.end = self.footer + 32 + self.data = self.end - self.size + if self.flags & HAS_HEADER: + self.header = self.data - 32 + else: + self.header = self.data + else: + raise APENoHeaderError("No APE tag found") + + # exclude the footer from size + if self.footer is not None: + self.size -= 32 + + def __fix_brokenness(self, fileobj): + # Fix broken tags written with PyMusepack. + if self.header is not None: + start = self.header + else: + start = self.data + fileobj.seek(start) + + while start > 0: + # Clean up broken writing from pre-Mutagen PyMusepack. + # It didn't remove the first 24 bytes of header. + try: + fileobj.seek(-24, 1) + except IOError: + break + else: + if fileobj.read(8) == "APETAGEX": + fileobj.seek(-8, 1) + start = fileobj.tell() + else: + break + self.start = start + + +class APEv2(DictMixin, Metadata): + """A file with an APEv2 tag. + + ID3v1 tags are silently ignored and overwritten. + """ + + filename = None + + def __init__(self, *args, **kwargs): + self.__casemap = {} + self.__dict = {} + super(APEv2, self).__init__(*args, **kwargs) + # Internally all names are stored as lowercase, but the case + # they were set with is remembered and used when saving. This + # is roughly in line with the standard, which says that keys + # are case-sensitive but two keys differing only in case are + # not allowed, and recommends case-insensitive + # implementations. + + def pprint(self): + """Return tag key=value pairs in a human-readable format.""" + items = self.items() + items.sort() + return "\n".join(["%s=%s" % (k, v.pprint()) for k, v in items]) + + def load(self, filename): + """Load tags from a filename.""" + self.filename = filename + fileobj = open(filename, "rb") + try: + data = _APEv2Data(fileobj) + finally: + fileobj.close() + if data.tag: + self.clear() + self.__casemap.clear() + self.__parse_tag(data.tag, data.items) + else: + raise APENoHeaderError("No APE tag found") + + def __parse_tag(self, tag, count): + fileobj = StringIO(tag) + + for i in range(count): + size_data = fileobj.read(4) + # someone writes wrong item counts + if not size_data: + break + size = cdata.uint_le(size_data) + flags = cdata.uint_le(fileobj.read(4)) + + # Bits 1 and 2 bits are flags, 0-3 + # Bit 0 is read/write flag, ignored + kind = (flags & 6) >> 1 + if kind == 3: + raise APEBadItemError("value type must be 0, 1, or 2") + key = value = fileobj.read(1) + while key[-1:] != '\x00' and value: + value = fileobj.read(1) + key += value + if key[-1:] == "\x00": + key = key[:-1] + value = fileobj.read(size) + self[key] = APEValue(value, kind) + + def __getitem__(self, key): + if not is_valid_apev2_key(key): + raise KeyError("%r is not a valid APEv2 key" % key) + key = key.encode('ascii') + return self.__dict[key.lower()] + + def __delitem__(self, key): + if not is_valid_apev2_key(key): + raise KeyError("%r is not a valid APEv2 key" % key) + key = key.encode('ascii') + del(self.__dict[key.lower()]) + + def __setitem__(self, key, value): + """'Magic' value setter. + + This function tries to guess at what kind of value you want to + store. If you pass in a valid UTF-8 or Unicode string, it + treats it as a text value. If you pass in a list, it treats it + as a list of string/Unicode values. If you pass in a string + that is not valid UTF-8, it assumes it is a binary value. + + If you need to force a specific type of value (e.g. binary + data that also happens to be valid UTF-8, or an external + reference), use the APEValue factory and set the value to the + result of that:: + + from mutagen.apev2 import APEValue, EXTERNAL + tag['Website'] = APEValue('http://example.org', EXTERNAL) + """ + + if not is_valid_apev2_key(key): + raise KeyError("%r is not a valid APEv2 key" % key) + key = key.encode('ascii') + + if not isinstance(value, _APEValue): + # let's guess at the content if we're not already a value... + if isinstance(value, unicode): + # unicode? we've got to be text. + value = APEValue(utf8(value), TEXT) + elif isinstance(value, list): + # list? text. + value = APEValue("\0".join(map(utf8, value)), TEXT) + else: + try: + value.decode("utf-8") + except UnicodeError: + # invalid UTF8 text, probably binary + value = APEValue(value, BINARY) + else: + # valid UTF8, probably text + value = APEValue(value, TEXT) + self.__casemap[key.lower()] = key + self.__dict[key.lower()] = value + + def keys(self): + return [self.__casemap.get(key, key) for key in self.__dict.keys()] + + def save(self, filename=None): + """Save changes to a file. + + If no filename is given, the one most recently loaded is used. + + Tags are always written at the end of the file, and include + a header and a footer. + """ + + filename = filename or self.filename + try: + fileobj = open(filename, "r+b") + except IOError: + fileobj = open(filename, "w+b") + data = _APEv2Data(fileobj) + + if data.is_at_start: + delete_bytes(fileobj, data.end - data.start, data.start) + elif data.start is not None: + fileobj.seek(data.start) + # Delete an ID3v1 tag if present, too. + fileobj.truncate() + fileobj.seek(0, 2) + + # "APE tags items should be sorted ascending by size... This is + # not a MUST, but STRONGLY recommended. Actually the items should + # be sorted by importance/byte, but this is not feasible." + tags = [v._internal(k) for k, v in self.items()] + tags.sort(lambda a, b: cmp(len(a), len(b))) + num_tags = len(tags) + tags = "".join(tags) + + header = "APETAGEX%s%s" % ( + # version, tag size, item count, flags + struct.pack("<4I", 2000, len(tags) + 32, num_tags, + HAS_HEADER | IS_HEADER), + "\0" * 8) + fileobj.write(header) + + fileobj.write(tags) + + footer = "APETAGEX%s%s" % ( + # version, tag size, item count, flags + struct.pack("<4I", 2000, len(tags) + 32, num_tags, + HAS_HEADER), + "\0" * 8) + fileobj.write(footer) + fileobj.close() + + def delete(self, filename=None): + """Remove tags from a file.""" + filename = filename or self.filename + fileobj = open(filename, "r+b") + try: + data = _APEv2Data(fileobj) + if data.start is not None and data.size is not None: + delete_bytes(fileobj, data.end - data.start, data.start) + finally: + fileobj.close() + self.clear() + + +Open = APEv2 + + +def delete(filename): + """Remove tags from a file.""" + try: + APEv2(filename).delete() + except APENoHeaderError: + pass + + +def APEValue(value, kind): + """APEv2 tag value factory. + + Use this if you need to specify the value's type manually. Binary + and text data are automatically detected by APEv2.__setitem__. + """ + if kind == TEXT: + return APETextValue(value, kind) + elif kind == BINARY: + return APEBinaryValue(value, kind) + elif kind == EXTERNAL: + return APEExtValue(value, kind) + else: + raise ValueError("kind must be TEXT, BINARY, or EXTERNAL") + + +class _APEValue(object): + def __init__(self, value, kind): + self.kind = kind + self.value = value + + def __len__(self): + return len(self.value) + + def __str__(self): + return self.value + + # Packed format for an item: + # 4B: Value length + # 4B: Value type + # Key name + # 1B: Null + # Key value + def _internal(self, key): + return "%s%s\0%s" % ( + struct.pack("<2I", len(self.value), self.kind << 1), + key, self.value) + + def __repr__(self): + return "%s(%r, %d)" % (type(self).__name__, self.value, self.kind) + + +class APETextValue(_APEValue): + """An APEv2 text value. + + Text values are Unicode/UTF-8 strings. They can be accessed like + strings (with a null seperating the values), or arrays of strings.""" + + def __unicode__(self): + return unicode(str(self), "utf-8") + + def __iter__(self): + """Iterate over the strings of the value (not the characters)""" + return iter(unicode(self).split("\0")) + + def __getitem__(self, index): + return unicode(self).split("\0")[index] + + def __len__(self): + return self.value.count("\0") + 1 + + def __cmp__(self, other): + return cmp(unicode(self), other) + + __hash__ = _APEValue.__hash__ + + def __setitem__(self, index, value): + values = list(self) + values[index] = value.encode("utf-8") + self.value = "\0".join(values).encode("utf-8") + + def pprint(self): + return " / ".join(self) + + +class APEBinaryValue(_APEValue): + """An APEv2 binary value.""" + + def pprint(self): + return "[%d bytes]" % len(self) + + +class APEExtValue(_APEValue): + """An APEv2 external value. + + External values are usually URI or IRI strings. + """ + def pprint(self): + return "[External] %s" % unicode(self) + + +class APEv2File(FileType): + class _Info(object): + length = 0 + bitrate = 0 + + def __init__(self, fileobj): + pass + + @staticmethod + def pprint(): + return "Unknown format with APEv2 tag." + + def load(self, filename): + self.filename = filename + self.info = self._Info(open(filename, "rb")) + try: + self.tags = APEv2(filename) + except error: + self.tags = None + + def add_tags(self): + if self.tags is None: + self.tags = APEv2() + else: + raise ValueError("%r already has tags: %r" % (self, self.tags)) + + @staticmethod + def score(filename, fileobj, header): + try: + fileobj.seek(-160, 2) + except IOError: + fileobj.seek(0) + footer = fileobj.read() + filename = filename.lower() + return (("APETAGEX" in footer) - header.startswith("ID3")) diff --git a/libs/mutagen/asf.py b/libs/mutagen/asf.py new file mode 100644 index 00000000..fab5559b --- /dev/null +++ b/libs/mutagen/asf.py @@ -0,0 +1,704 @@ +# Copyright 2006-2007 Lukas Lalinsky +# Copyright 2005-2006 Joe Wreschnig +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +"""Read and write ASF (Window Media Audio) files.""" + +__all__ = ["ASF", "Open"] + +import struct +from mutagen import FileType, Metadata +from mutagen._util import insert_bytes, delete_bytes, DictMixin + + +class error(IOError): + pass + + +class ASFError(error): + pass + + +class ASFHeaderError(error): + pass + + +class ASFInfo(object): + """ASF stream information.""" + + def __init__(self): + self.length = 0.0 + self.sample_rate = 0 + self.bitrate = 0 + self.channels = 0 + + def pprint(self): + s = "Windows Media Audio %d bps, %s Hz, %d channels, %.2f seconds" % ( + self.bitrate, self.sample_rate, self.channels, self.length) + return s + + +class ASFTags(list, DictMixin, Metadata): + """Dictionary containing ASF attributes.""" + + def pprint(self): + return "\n".join(["%s=%s" % (k, v) for k, v in self]) + + def __getitem__(self, key): + """A list of values for the key. + + This is a copy, so comment['title'].append('a title') will not + work. + + """ + values = [value for (k, value) in self if k == key] + if not values: + raise KeyError(key) + else: + return values + + def __delitem__(self, key): + """Delete all values associated with the key.""" + to_delete = filter(lambda x: x[0] == key, self) + if not to_delete: + raise KeyError(key) + else: + map(self.remove, to_delete) + + def __contains__(self, key): + """Return true if the key has any values.""" + for k, value in self: + if k == key: + return True + else: + return False + + def __setitem__(self, key, values): + """Set a key's value or values. + + Setting a value overwrites all old ones. The value may be a + list of Unicode or UTF-8 strings, or a single Unicode or UTF-8 + string. + + """ + if not isinstance(values, list): + values = [values] + try: + del(self[key]) + except KeyError: + pass + for value in values: + if key in _standard_attribute_names: + value = unicode(value) + elif not isinstance(value, ASFBaseAttribute): + if isinstance(value, basestring): + value = ASFUnicodeAttribute(value) + elif isinstance(value, bool): + value = ASFBoolAttribute(value) + elif isinstance(value, int): + value = ASFDWordAttribute(value) + elif isinstance(value, long): + value = ASFQWordAttribute(value) + self.append((key, value)) + + def keys(self): + """Return all keys in the comment.""" + return self and set(zip(*self)[0]) + + def as_dict(self): + """Return a copy of the comment data in a real dict.""" + d = {} + for key, value in self: + d.setdefault(key, []).append(value) + return d + + +class ASFBaseAttribute(object): + """Generic attribute.""" + TYPE = None + + def __init__(self, value=None, data=None, language=None, + stream=None, **kwargs): + self.language = language + self.stream = stream + if data: + self.value = self.parse(data, **kwargs) + else: + self.value = value + + def data_size(self): + raise NotImplementedError + + def __repr__(self): + name = "%s(%r" % (type(self).__name__, self.value) + if self.language: + name += ", language=%d" % self.language + if self.stream: + name += ", stream=%d" % self.stream + name += ")" + return name + + def render(self, name): + name = name.encode("utf-16-le") + "\x00\x00" + data = self._render() + return (struct.pack(" 0: + texts.append(data[pos:end].decode("utf-16-le").strip("\x00")) + else: + texts.append(None) + pos = end + title, author, copyright, desc, rating = texts + for key, value in dict( + Title=title, + Author=author, + Copyright=copyright, + Description=desc, + Rating=rating + ).items(): + if value is not None: + asf.tags[key] = value + + def render(self, asf): + def render_text(name): + value = asf.tags.get(name, []) + if value: + return value[0].encode("utf-16-le") + "\x00\x00" + else: + return "" + texts = map(render_text, _standard_attribute_names) + data = struct.pack(" 0xFFFF or value.TYPE == GUID) + if (value.language is None and value.stream is None and + name not in self.to_extended_content_description and + not library_only): + self.to_extended_content_description[name] = value + elif (value.language is None and value.stream is not None and + name not in self.to_metadata and not library_only): + self.to_metadata[name] = value + else: + self.to_metadata_library.append((name, value)) + + # Add missing objects + if not self.content_description_obj: + self.content_description_obj = \ + ContentDescriptionObject() + self.objects.append(self.content_description_obj) + if not self.extended_content_description_obj: + self.extended_content_description_obj = \ + ExtendedContentDescriptionObject() + self.objects.append(self.extended_content_description_obj) + if not self.header_extension_obj: + self.header_extension_obj = \ + HeaderExtensionObject() + self.objects.append(self.header_extension_obj) + if not self.metadata_obj: + self.metadata_obj = \ + MetadataObject() + self.header_extension_obj.objects.append(self.metadata_obj) + if not self.metadata_library_obj: + self.metadata_library_obj = \ + MetadataLibraryObject() + self.header_extension_obj.objects.append(self.metadata_library_obj) + + # Render the header + data = "".join([obj.render(self) for obj in self.objects]) + data = (HeaderObject.GUID + + struct.pack(" self.size: + insert_bytes(fileobj, size - self.size, self.size) + if size < self.size: + delete_bytes(fileobj, self.size - size, 0) + fileobj.seek(0) + fileobj.write(data) + finally: + fileobj.close() + + self.size = size + self.num_objects = len(self.objects) + + def __read_file(self, fileobj): + header = fileobj.read(30) + if len(header) != 30 or header[:16] != HeaderObject.GUID: + raise ASFHeaderError("Not an ASF file.") + + self.extended_content_description_obj = None + self.content_description_obj = None + self.header_extension_obj = None + self.metadata_obj = None + self.metadata_library_obj = None + + self.size, self.num_objects = struct.unpack(" u'\x7f': + enc = 3 + id3.add(mutagen.id3.TXXX(encoding=enc, text=value, desc=desc)) + else: + frame.text = value + + def deleter(id3, key): + del(id3[frameid]) + + cls.RegisterKey(key, getter, setter, deleter) + + def __init__(self, filename=None): + self.__id3 = ID3() + if filename is not None: + self.load(filename) + + load = property(lambda s: s.__id3.load, + lambda s, v: setattr(s.__id3, 'load', v)) + + save = property(lambda s: s.__id3.save, + lambda s, v: setattr(s.__id3, 'save', v)) + + delete = property(lambda s: s.__id3.delete, + lambda s, v: setattr(s.__id3, 'delete', v)) + + filename = property(lambda s: s.__id3.filename, + lambda s, fn: setattr(s.__id3, 'filename', fn)) + + size = property(lambda s: s.__id3.size, + lambda s, fn: setattr(s.__id3, 'size', s)) + + def __getitem__(self, key): + key = key.lower() + func = dict_match(self.Get, key, self.GetFallback) + if func is not None: + return func(self.__id3, key) + else: + raise EasyID3KeyError("%r is not a valid key" % key) + + def __setitem__(self, key, value): + key = key.lower() + if isinstance(value, basestring): + value = [value] + func = dict_match(self.Set, key, self.SetFallback) + if func is not None: + return func(self.__id3, key, value) + else: + raise EasyID3KeyError("%r is not a valid key" % key) + + def __delitem__(self, key): + key = key.lower() + func = dict_match(self.Delete, key, self.DeleteFallback) + if func is not None: + return func(self.__id3, key) + else: + raise EasyID3KeyError("%r is not a valid key" % key) + + def keys(self): + keys = [] + for key in self.Get.keys(): + if key in self.List: + keys.extend(self.List[key](self.__id3, key)) + elif key in self: + keys.append(key) + if self.ListFallback is not None: + keys.extend(self.ListFallback(self.__id3, "")) + return keys + + def pprint(self): + """Print tag key=value pairs.""" + strings = [] + for key in sorted(self.keys()): + values = self[key] + for value in values: + strings.append("%s=%s" % (key, value)) + return "\n".join(strings) + + +Open = EasyID3 + + +def genre_get(id3, key): + return id3["TCON"].genres + + +def genre_set(id3, key, value): + try: + frame = id3["TCON"] + except KeyError: + id3.add(mutagen.id3.TCON(encoding=3, text=value)) + else: + frame.encoding = 3 + frame.genres = value + + +def genre_delete(id3, key): + del(id3["TCON"]) + + +def date_get(id3, key): + return [stamp.text for stamp in id3["TDRC"].text] + + +def date_set(id3, key, value): + id3.add(mutagen.id3.TDRC(encoding=3, text=value)) + + +def date_delete(id3, key): + del(id3["TDRC"]) + + +def performer_get(id3, key): + people = [] + wanted_role = key.split(":", 1)[1] + try: + mcl = id3["TMCL"] + except KeyError: + raise KeyError(key) + for role, person in mcl.people: + if role == wanted_role: + people.append(person) + if people: + return people + else: + raise KeyError(key) + + +def performer_set(id3, key, value): + wanted_role = key.split(":", 1)[1] + try: + mcl = id3["TMCL"] + except KeyError: + mcl = mutagen.id3.TMCL(encoding=3, people=[]) + id3.add(mcl) + mcl.encoding = 3 + people = [p for p in mcl.people if p[0] != wanted_role] + for v in value: + people.append((wanted_role, v)) + mcl.people = people + + +def performer_delete(id3, key): + wanted_role = key.split(":", 1)[1] + try: + mcl = id3["TMCL"] + except KeyError: + raise KeyError(key) + people = [p for p in mcl.people if p[0] != wanted_role] + if people == mcl.people: + raise KeyError(key) + elif people: + mcl.people = people + else: + del(id3["TMCL"]) + + +def performer_list(id3, key): + try: + mcl = id3["TMCL"] + except KeyError: + return [] + else: + return list(set("performer:" + p[0] for p in mcl.people)) + + +def musicbrainz_trackid_get(id3, key): + return [id3["UFID:http://musicbrainz.org"].data.decode('ascii')] + + +def musicbrainz_trackid_set(id3, key, value): + if len(value) != 1: + raise ValueError("only one track ID may be set per song") + value = value[0].encode('ascii') + try: + frame = id3["UFID:http://musicbrainz.org"] + except KeyError: + frame = mutagen.id3.UFID(owner="http://musicbrainz.org", data=value) + id3.add(frame) + else: + frame.data = value + + +def musicbrainz_trackid_delete(id3, key): + del(id3["UFID:http://musicbrainz.org"]) + + +def website_get(id3, key): + urls = [frame.url for frame in id3.getall("WOAR")] + if urls: + return urls + else: + raise EasyID3KeyError(key) + + +def website_set(id3, key, value): + id3.delall("WOAR") + for v in value: + id3.add(mutagen.id3.WOAR(url=v)) + + +def website_delete(id3, key): + id3.delall("WOAR") + + +def gain_get(id3, key): + try: + frame = id3["RVA2:" + key[11:-5]] + except KeyError: + raise EasyID3KeyError(key) + else: + return [u"%+f dB" % frame.gain] + + +def gain_set(id3, key, value): + if len(value) != 1: + raise ValueError( + "there must be exactly one gain value, not %r.", value) + gain = float(value[0].split()[0]) + try: + frame = id3["RVA2:" + key[11:-5]] + except KeyError: + frame = mutagen.id3.RVA2(desc=key[11:-5], gain=0, peak=0, channel=1) + id3.add(frame) + frame.gain = gain + + +def gain_delete(id3, key): + try: + frame = id3["RVA2:" + key[11:-5]] + except KeyError: + pass + else: + if frame.peak: + frame.gain = 0.0 + else: + del(id3["RVA2:" + key[11:-5]]) + + +def peak_get(id3, key): + try: + frame = id3["RVA2:" + key[11:-5]] + except KeyError: + raise EasyID3KeyError(key) + else: + return [u"%f" % frame.peak] + + +def peak_set(id3, key, value): + if len(value) != 1: + raise ValueError( + "there must be exactly one peak value, not %r.", value) + peak = float(value[0]) + if peak >= 2 or peak < 0: + raise ValueError("peak must be => 0 and < 2.") + try: + frame = id3["RVA2:" + key[11:-5]] + except KeyError: + frame = mutagen.id3.RVA2(desc=key[11:-5], gain=0, peak=0, channel=1) + id3.add(frame) + frame.peak = peak + + +def peak_delete(id3, key): + try: + frame = id3["RVA2:" + key[11:-5]] + except KeyError: + pass + else: + if frame.gain: + frame.peak = 0.0 + else: + del(id3["RVA2:" + key[11:-5]]) + + +def peakgain_list(id3, key): + keys = [] + for frame in id3.getall("RVA2"): + keys.append("replaygain_%s_gain" % frame.desc) + keys.append("replaygain_%s_peak" % frame.desc) + return keys + +for frameid, key in { + "TALB": "album", + "TBPM": "bpm", + "TCMP": "compilation", # iTunes extension + "TCOM": "composer", + "TCOP": "copyright", + "TENC": "encodedby", + "TEXT": "lyricist", + "TLEN": "length", + "TMED": "media", + "TMOO": "mood", + "TIT2": "title", + "TIT3": "version", + "TPE1": "artist", + "TPE2": "performer", + "TPE3": "conductor", + "TPE4": "arranger", + "TPOS": "discnumber", + "TPUB": "organization", + "TRCK": "tracknumber", + "TOLY": "author", + "TSO2": "albumartistsort", # iTunes extension + "TSOA": "albumsort", + "TSOC": "composersort", # iTunes extension + "TSOP": "artistsort", + "TSOT": "titlesort", + "TSRC": "isrc", + "TSST": "discsubtitle", +}.iteritems(): + EasyID3.RegisterTextKey(key, frameid) + +EasyID3.RegisterKey("genre", genre_get, genre_set, genre_delete) +EasyID3.RegisterKey("date", date_get, date_set, date_delete) +EasyID3.RegisterKey( + "performer:*", performer_get, performer_set, performer_delete, + performer_list) +EasyID3.RegisterKey("musicbrainz_trackid", musicbrainz_trackid_get, + musicbrainz_trackid_set, musicbrainz_trackid_delete) +EasyID3.RegisterKey("website", website_get, website_set, website_delete) +EasyID3.RegisterKey("website", website_get, website_set, website_delete) +EasyID3.RegisterKey( + "replaygain_*_gain", gain_get, gain_set, gain_delete, peakgain_list) +EasyID3.RegisterKey("replaygain_*_peak", peak_get, peak_set, peak_delete) + +# At various times, information for this came from +# http://musicbrainz.org/docs/specs/metadata_tags.html +# http://bugs.musicbrainz.org/ticket/1383 +# http://musicbrainz.org/doc/MusicBrainzTag +for desc, key in { + u"MusicBrainz Artist Id": "musicbrainz_artistid", + u"MusicBrainz Album Id": "musicbrainz_albumid", + u"MusicBrainz Album Artist Id": "musicbrainz_albumartistid", + u"MusicBrainz TRM Id": "musicbrainz_trmid", + u"MusicIP PUID": "musicip_puid", + u"MusicMagic Fingerprint": "musicip_fingerprint", + u"MusicBrainz Album Status": "musicbrainz_albumstatus", + u"MusicBrainz Album Type": "musicbrainz_albumtype", + u"MusicBrainz Album Release Country": "releasecountry", + u"MusicBrainz Disc Id": "musicbrainz_discid", + u"ASIN": "asin", + u"ALBUMARTISTSORT": "albumartistsort", + u"BARCODE": "barcode", +}.iteritems(): + EasyID3.RegisterTXXXKey(key, desc) + + +class EasyID3FileType(ID3FileType): + """Like ID3FileType, but uses EasyID3 for tags.""" + ID3 = EasyID3 diff --git a/libs/mutagen/easymp4.py b/libs/mutagen/easymp4.py new file mode 100644 index 00000000..3abacccc --- /dev/null +++ b/libs/mutagen/easymp4.py @@ -0,0 +1,266 @@ +# Copyright 2009 Joe Wreschnig +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. + +from mutagen import Metadata +from mutagen._util import DictMixin, dict_match, utf8 +from mutagen.mp4 import MP4, MP4Tags, error, delete + +__all__ = ["EasyMP4Tags", "EasyMP4", "delete", "error"] + + +class EasyMP4KeyError(error, KeyError, ValueError): + pass + + +class EasyMP4Tags(DictMixin, Metadata): + """A file with MPEG-4 iTunes metadata. + + Like Vorbis comments, EasyMP4Tags keys are case-insensitive ASCII + strings, and values are a list of Unicode strings (and these lists + are always of length 0 or 1). + + If you need access to the full MP4 metadata feature set, you should use + MP4, not EasyMP4. + """ + + Set = {} + Get = {} + Delete = {} + List = {} + + def __init__(self, *args, **kwargs): + self.__mp4 = MP4Tags(*args, **kwargs) + self.load = self.__mp4.load + self.save = self.__mp4.save + self.delete = self.__mp4.delete + + filename = property(lambda s: s.__mp4.filename, + lambda s, fn: setattr(s.__mp4, 'filename', fn)) + + @classmethod + def RegisterKey(cls, key, + getter=None, setter=None, deleter=None, lister=None): + """Register a new key mapping. + + A key mapping is four functions, a getter, setter, deleter, + and lister. The key may be either a string or a glob pattern. + + The getter, deleted, and lister receive an MP4Tags instance + and the requested key name. The setter also receives the + desired value, which will be a list of strings. + + The getter, setter, and deleter are used to implement __getitem__, + __setitem__, and __delitem__. + + The lister is used to implement keys(). It should return a + list of keys that are actually in the MP4 instance, provided + by its associated getter. + """ + key = key.lower() + if getter is not None: + cls.Get[key] = getter + if setter is not None: + cls.Set[key] = setter + if deleter is not None: + cls.Delete[key] = deleter + if lister is not None: + cls.List[key] = lister + + @classmethod + def RegisterTextKey(cls, key, atomid): + """Register a text key. + + If the key you need to register is a simple one-to-one mapping + of MP4 atom name to EasyMP4Tags key, then you can use this + function:: + + EasyMP4Tags.RegisterTextKey("artist", "\xa9ART") + """ + def getter(tags, key): + return tags[atomid] + + def setter(tags, key, value): + tags[atomid] = value + + def deleter(tags, key): + del(tags[atomid]) + + cls.RegisterKey(key, getter, setter, deleter) + + @classmethod + def RegisterIntKey(cls, key, atomid, min_value=0, max_value=2**16-1): + """Register a scalar integer key. + """ + + def getter(tags, key): + return map(unicode, tags[atomid]) + + def setter(tags, key, value): + clamp = lambda x: int(min(max(min_value, x), max_value)) + tags[atomid] = map(clamp, map(int, value)) + + def deleter(tags, key): + del(tags[atomid]) + + cls.RegisterKey(key, getter, setter, deleter) + + @classmethod + def RegisterIntPairKey(cls, key, atomid, min_value=0, max_value=2**16-1): + def getter(tags, key): + ret = [] + for (track, total) in tags[atomid]: + if total: + ret.append(u"%d/%d" % (track, total)) + else: + ret.append(unicode(track)) + return ret + + def setter(tags, key, value): + clamp = lambda x: int(min(max(min_value, x), max_value)) + data = [] + for v in value: + try: + tracks, total = v.split("/") + tracks = clamp(int(tracks)) + total = clamp(int(total)) + except (ValueError, TypeError): + tracks = clamp(int(v)) + total = min_value + data.append((tracks, total)) + tags[atomid] = data + + def deleter(tags, key): + del(tags[atomid]) + + cls.RegisterKey(key, getter, setter, deleter) + + @classmethod + def RegisterFreeformKey(cls, key, name, mean="com.apple.iTunes"): + """Register a text key. + + If the key you need to register is a simple one-to-one mapping + of MP4 freeform atom (----) and name to EasyMP4Tags key, then + you can use this function:: + + EasyMP4Tags.RegisterFreeformKey( + "musicbrainz_artistid", "MusicBrainz Artist Id") + """ + atomid = "----:%s:%s" % (mean, name) + + def getter(tags, key): + return [s.decode("utf-8", "replace") for s in tags[atomid]] + + def setter(tags, key, value): + tags[atomid] = map(utf8, value) + + def deleter(tags, key): + del(tags[atomid]) + + cls.RegisterKey(key, getter, setter, deleter) + + def __getitem__(self, key): + key = key.lower() + func = dict_match(self.Get, key) + if func is not None: + return func(self.__mp4, key) + else: + raise EasyMP4KeyError("%r is not a valid key" % key) + + def __setitem__(self, key, value): + key = key.lower() + if isinstance(value, basestring): + value = [value] + func = dict_match(self.Set, key) + if func is not None: + return func(self.__mp4, key, value) + else: + raise EasyMP4KeyError("%r is not a valid key" % key) + + def __delitem__(self, key): + key = key.lower() + func = dict_match(self.Delete, key) + if func is not None: + return func(self.__mp4, key) + else: + raise EasyMP4KeyError("%r is not a valid key" % key) + + def keys(self): + keys = [] + for key in self.Get.keys(): + if key in self.List: + keys.extend(self.List[key](self.__mp4, key)) + elif key in self: + keys.append(key) + return keys + + def pprint(self): + """Print tag key=value pairs.""" + strings = [] + for key in sorted(self.keys()): + values = self[key] + for value in values: + strings.append("%s=%s" % (key, value)) + return "\n".join(strings) + +for atomid, key in { + '\xa9nam': 'title', + '\xa9alb': 'album', + '\xa9ART': 'artist', + 'aART': 'albumartist', + '\xa9day': 'date', + '\xa9cmt': 'comment', + 'desc': 'description', + '\xa9grp': 'grouping', + '\xa9gen': 'genre', + 'cprt': 'copyright', + 'soal': 'albumsort', + 'soaa': 'albumartistsort', + 'soar': 'artistsort', + 'sonm': 'titlesort', + 'soco': 'composersort', +}.items(): + EasyMP4Tags.RegisterTextKey(key, atomid) + +for name, key in { + 'MusicBrainz Artist Id': 'musicbrainz_artistid', + 'MusicBrainz Track Id': 'musicbrainz_trackid', + 'MusicBrainz Album Id': 'musicbrainz_albumid', + 'MusicBrainz Album Artist Id': 'musicbrainz_albumartistid', + 'MusicIP PUID': 'musicip_puid', + 'MusicBrainz Album Status': 'musicbrainz_albumstatus', + 'MusicBrainz Album Type': 'musicbrainz_albumtype', + 'MusicBrainz Release Country': 'releasecountry', +}.items(): + EasyMP4Tags.RegisterFreeformKey(key, name) + +for name, key in { + "tmpo": "bpm", +}.items(): + EasyMP4Tags.RegisterIntKey(key, name) + +for name, key in { + "trkn": "tracknumber", + "disk": "discnumber", +}.items(): + EasyMP4Tags.RegisterIntPairKey(key, name) + + +class EasyMP4(MP4): + """Like :class:`MP4 `, + but uses :class:`EasyMP4Tags` for tags. + + :ivar info: :class:`MP4Info ` + :ivar tags: :class:`EasyMP4Tags` + """ + + MP4Tags = EasyMP4Tags + + Get = EasyMP4Tags.Get + Set = EasyMP4Tags.Set + Delete = EasyMP4Tags.Delete + List = EasyMP4Tags.List + RegisterTextKey = EasyMP4Tags.RegisterTextKey + RegisterKey = EasyMP4Tags.RegisterKey diff --git a/libs/mutagen/flac.py b/libs/mutagen/flac.py new file mode 100644 index 00000000..f8e014bc --- /dev/null +++ b/libs/mutagen/flac.py @@ -0,0 +1,833 @@ +# FLAC comment support for Mutagen +# Copyright 2005 Joe Wreschnig +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. + +"""Read and write FLAC Vorbis comments and stream information. + +Read more about FLAC at http://flac.sourceforge.net. + +FLAC supports arbitrary metadata blocks. The two most interesting ones +are the FLAC stream information block, and the Vorbis comment block; +these are also the only ones Mutagen can currently read. + +This module does not handle Ogg FLAC files. + +Based off documentation available at +http://flac.sourceforge.net/format.html +""" + +__all__ = ["FLAC", "Open", "delete"] + +import struct +from cStringIO import StringIO +from _vorbis import VCommentDict +from mutagen import FileType +from mutagen._util import insert_bytes +from mutagen.id3 import BitPaddedInt +import sys +if sys.version_info >= (2, 6): + from functools import reduce + + +class error(IOError): + pass + + +class FLACNoHeaderError(error): + pass + + +class FLACVorbisError(ValueError, error): + pass + + +def to_int_be(string): + """Convert an arbitrarily-long string to a long using big-endian + byte order.""" + return reduce(lambda a, b: (a << 8) + ord(b), string, 0L) + + +class StrictFileObject(object): + """Wraps a file-like object and raises an exception if the requested + amount of data to read isn't returned.""" + + def __init__(self, fileobj): + self._fileobj = fileobj + for m in ["close", "tell", "seek", "write", "name"]: + if hasattr(fileobj, m): + setattr(self, m, getattr(fileobj, m)) + + def read(self, size=-1): + data = self._fileobj.read(size) + if size >= 0 and len(data) != size: + raise error("file said %d bytes, read %d bytes" % ( + size, len(data))) + return data + + def tryread(self, *args): + return self._fileobj.read(*args) + + +class MetadataBlock(object): + """A generic block of FLAC metadata. + + This class is extended by specific used as an ancestor for more specific + blocks, and also as a container for data blobs of unknown blocks. + + Attributes: + + * data -- raw binary data for this block + """ + + _distrust_size = False + + def __init__(self, data): + """Parse the given data string or file-like as a metadata block. + The metadata header should not be included.""" + if data is not None: + if not isinstance(data, StrictFileObject): + if isinstance(data, str): + data = StringIO(data) + elif not hasattr(data, 'read'): + raise TypeError( + "StreamInfo requires string data or a file-like") + data = StrictFileObject(data) + self.load(data) + + def load(self, data): + self.data = data.read() + + def write(self): + return self.data + + @staticmethod + def writeblocks(blocks): + """Render metadata block as a byte string.""" + data = [] + codes = [[block.code, block.write()] for block in blocks] + codes[-1][0] |= 128 + for code, datum in codes: + byte = chr(code) + if len(datum) > 2**24: + raise error("block is too long to write") + length = struct.pack(">I", len(datum))[-3:] + data.append(byte + length + datum) + return "".join(data) + + @staticmethod + def group_padding(blocks): + """Consolidate FLAC padding metadata blocks. + + The overall size of the rendered blocks does not change, so + this adds several bytes of padding for each merged block.""" + paddings = filter(lambda x: isinstance(x, Padding), blocks) + map(blocks.remove, paddings) + # total padding size is the sum of padding sizes plus 4 bytes + # per removed header. + size = sum([padding.length for padding in paddings]) + padding = Padding() + padding.length = size + 4 * (len(paddings) - 1) + blocks.append(padding) + + +class StreamInfo(MetadataBlock): + """FLAC stream information. + + This contains information about the audio data in the FLAC file. + Unlike most stream information objects in Mutagen, changes to this + one will rewritten to the file when it is saved. Unless you are + actually changing the audio stream itself, don't change any + attributes of this block. + + Attributes: + + * min_blocksize -- minimum audio block size + * max_blocksize -- maximum audio block size + * sample_rate -- audio sample rate in Hz + * channels -- audio channels (1 for mono, 2 for stereo) + * bits_per_sample -- bits per sample + * total_samples -- total samples in file + * length -- audio length in seconds + """ + + code = 0 + + def __eq__(self, other): + try: + return (self.min_blocksize == other.min_blocksize and + self.max_blocksize == other.max_blocksize and + self.sample_rate == other.sample_rate and + self.channels == other.channels and + self.bits_per_sample == other.bits_per_sample and + self.total_samples == other.total_samples) + except: + return False + + __hash__ = MetadataBlock.__hash__ + + def load(self, data): + self.min_blocksize = int(to_int_be(data.read(2))) + self.max_blocksize = int(to_int_be(data.read(2))) + self.min_framesize = int(to_int_be(data.read(3))) + self.max_framesize = int(to_int_be(data.read(3))) + # first 16 bits of sample rate + sample_first = to_int_be(data.read(2)) + # last 4 bits of sample rate, 3 of channels, first 1 of bits/sample + sample_channels_bps = to_int_be(data.read(1)) + # last 4 of bits/sample, 36 of total samples + bps_total = to_int_be(data.read(5)) + + sample_tail = sample_channels_bps >> 4 + self.sample_rate = int((sample_first << 4) + sample_tail) + if not self.sample_rate: + raise error("A sample rate value of 0 is invalid") + self.channels = int(((sample_channels_bps >> 1) & 7) + 1) + bps_tail = bps_total >> 36 + bps_head = (sample_channels_bps & 1) << 4 + self.bits_per_sample = int(bps_head + bps_tail + 1) + self.total_samples = bps_total & 0xFFFFFFFFFL + self.length = self.total_samples / float(self.sample_rate) + + self.md5_signature = to_int_be(data.read(16)) + + def write(self): + f = StringIO() + f.write(struct.pack(">I", self.min_blocksize)[-2:]) + f.write(struct.pack(">I", self.max_blocksize)[-2:]) + f.write(struct.pack(">I", self.min_framesize)[-3:]) + f.write(struct.pack(">I", self.max_framesize)[-3:]) + + # first 16 bits of sample rate + f.write(struct.pack(">I", self.sample_rate >> 4)[-2:]) + # 4 bits sample, 3 channel, 1 bps + byte = (self.sample_rate & 0xF) << 4 + byte += ((self.channels - 1) & 7) << 1 + byte += ((self.bits_per_sample - 1) >> 4) & 1 + f.write(chr(byte)) + # 4 bits of bps, 4 of sample count + byte = ((self.bits_per_sample - 1) & 0xF) << 4 + byte += (self.total_samples >> 32) & 0xF + f.write(chr(byte)) + # last 32 of sample count + f.write(struct.pack(">I", self.total_samples & 0xFFFFFFFFL)) + # MD5 signature + sig = self.md5_signature + f.write(struct.pack( + ">4I", (sig >> 96) & 0xFFFFFFFFL, (sig >> 64) & 0xFFFFFFFFL, + (sig >> 32) & 0xFFFFFFFFL, sig & 0xFFFFFFFFL)) + return f.getvalue() + + def pprint(self): + return "FLAC, %.2f seconds, %d Hz" % (self.length, self.sample_rate) + + +class SeekPoint(tuple): + """A single seek point in a FLAC file. + + Placeholder seek points have first_sample of 0xFFFFFFFFFFFFFFFFL, + and byte_offset and num_samples undefined. Seek points must be + sorted in ascending order by first_sample number. Seek points must + be unique by first_sample number, except for placeholder + points. Placeholder points must occur last in the table and there + may be any number of them. + + Attributes: + + * first_sample -- sample number of first sample in the target frame + * byte_offset -- offset from first frame to target frame + * num_samples -- number of samples in target frame + """ + + def __new__(cls, first_sample, byte_offset, num_samples): + return super(cls, SeekPoint).__new__( + cls, (first_sample, byte_offset, num_samples)) + + first_sample = property(lambda self: self[0]) + byte_offset = property(lambda self: self[1]) + num_samples = property(lambda self: self[2]) + + +class SeekTable(MetadataBlock): + """Read and write FLAC seek tables. + + Attributes: + + * seekpoints -- list of SeekPoint objects + """ + + __SEEKPOINT_FORMAT = '>QQH' + __SEEKPOINT_SIZE = struct.calcsize(__SEEKPOINT_FORMAT) + + code = 3 + + def __init__(self, data): + self.seekpoints = [] + super(SeekTable, self).__init__(data) + + def __eq__(self, other): + try: + return (self.seekpoints == other.seekpoints) + except (AttributeError, TypeError): + return False + + __hash__ = MetadataBlock.__hash__ + + def load(self, data): + self.seekpoints = [] + sp = data.tryread(self.__SEEKPOINT_SIZE) + while len(sp) == self.__SEEKPOINT_SIZE: + self.seekpoints.append(SeekPoint( + *struct.unpack(self.__SEEKPOINT_FORMAT, sp))) + sp = data.tryread(self.__SEEKPOINT_SIZE) + + def write(self): + f = StringIO() + for seekpoint in self.seekpoints: + packed = struct.pack( + self.__SEEKPOINT_FORMAT, + seekpoint.first_sample, seekpoint.byte_offset, + seekpoint.num_samples) + f.write(packed) + return f.getvalue() + + def __repr__(self): + return "<%s seekpoints=%r>" % (type(self).__name__, self.seekpoints) + + +class VCFLACDict(VCommentDict): + """Read and write FLAC Vorbis comments. + + FLACs don't use the framing bit at the end of the comment block. + So this extends VCommentDict to not use the framing bit. + """ + + code = 4 + _distrust_size = True + + def load(self, data, errors='replace', framing=False): + super(VCFLACDict, self).load(data, errors=errors, framing=framing) + + def write(self, framing=False): + return super(VCFLACDict, self).write(framing=framing) + + +class CueSheetTrackIndex(tuple): + """Index for a track in a cuesheet. + + For CD-DA, an index_number of 0 corresponds to the track + pre-gap. The first index in a track must have a number of 0 or 1, + and subsequently, index_numbers must increase by 1. Index_numbers + must be unique within a track. And index_offset must be evenly + divisible by 588 samples. + + Attributes: + + * index_number -- index point number + * index_offset -- offset in samples from track start + """ + + def __new__(cls, index_number, index_offset): + return super(cls, CueSheetTrackIndex).__new__( + cls, (index_number, index_offset)) + + index_number = property(lambda self: self[0]) + index_offset = property(lambda self: self[1]) + + +class CueSheetTrack(object): + """A track in a cuesheet. + + For CD-DA, track_numbers must be 1-99, or 170 for the + lead-out. Track_numbers must be unique within a cue sheet. There + must be atleast one index in every track except the lead-out track + which must have none. + + Attributes: + + * track_number -- track number + * start_offset -- track offset in samples from start of FLAC stream + * isrc -- ISRC code + * type -- 0 for audio, 1 for digital data + * pre_emphasis -- true if the track is recorded with pre-emphasis + * indexes -- list of CueSheetTrackIndex objects + """ + + def __init__(self, track_number, start_offset, isrc='', type_=0, + pre_emphasis=False): + self.track_number = track_number + self.start_offset = start_offset + self.isrc = isrc + self.type = type_ + self.pre_emphasis = pre_emphasis + self.indexes = [] + + def __eq__(self, other): + try: + return (self.track_number == other.track_number and + self.start_offset == other.start_offset and + self.isrc == other.isrc and + self.type == other.type and + self.pre_emphasis == other.pre_emphasis and + self.indexes == other.indexes) + except (AttributeError, TypeError): + return False + + __hash__ = object.__hash__ + + def __repr__(self): + return ("<%s number=%r, offset=%d, isrc=%r, type=%r, " + "pre_emphasis=%r, indexes=%r)>") % ( + type(self).__name__, self.track_number, self.start_offset, + self.isrc, self.type, self.pre_emphasis, self.indexes) + + +class CueSheet(MetadataBlock): + """Read and write FLAC embedded cue sheets. + + Number of tracks should be from 1 to 100. There should always be + exactly one lead-out track and that track must be the last track + in the cue sheet. + + Attributes: + + * media_catalog_number -- media catalog number in ASCII + * lead_in_samples -- number of lead-in samples + * compact_disc -- true if the cuesheet corresponds to a compact disc + * tracks -- list of CueSheetTrack objects + * lead_out -- lead-out as CueSheetTrack or None if lead-out was not found + """ + + __CUESHEET_FORMAT = '>128sQB258xB' + __CUESHEET_SIZE = struct.calcsize(__CUESHEET_FORMAT) + __CUESHEET_TRACK_FORMAT = '>QB12sB13xB' + __CUESHEET_TRACK_SIZE = struct.calcsize(__CUESHEET_TRACK_FORMAT) + __CUESHEET_TRACKINDEX_FORMAT = '>QB3x' + __CUESHEET_TRACKINDEX_SIZE = struct.calcsize(__CUESHEET_TRACKINDEX_FORMAT) + + code = 5 + + media_catalog_number = '' + lead_in_samples = 88200 + compact_disc = True + + def __init__(self, data): + self.tracks = [] + super(CueSheet, self).__init__(data) + + def __eq__(self, other): + try: + return (self.media_catalog_number == other.media_catalog_number and + self.lead_in_samples == other.lead_in_samples and + self.compact_disc == other.compact_disc and + self.tracks == other.tracks) + except (AttributeError, TypeError): + return False + + __hash__ = MetadataBlock.__hash__ + + def load(self, data): + header = data.read(self.__CUESHEET_SIZE) + media_catalog_number, lead_in_samples, flags, num_tracks = \ + struct.unpack(self.__CUESHEET_FORMAT, header) + self.media_catalog_number = media_catalog_number.rstrip('\0') + self.lead_in_samples = lead_in_samples + self.compact_disc = bool(flags & 0x80) + self.tracks = [] + for i in range(num_tracks): + track = data.read(self.__CUESHEET_TRACK_SIZE) + start_offset, track_number, isrc_padded, flags, num_indexes = \ + struct.unpack(self.__CUESHEET_TRACK_FORMAT, track) + isrc = isrc_padded.rstrip('\0') + type_ = (flags & 0x80) >> 7 + pre_emphasis = bool(flags & 0x40) + val = CueSheetTrack( + track_number, start_offset, isrc, type_, pre_emphasis) + for j in range(num_indexes): + index = data.read(self.__CUESHEET_TRACKINDEX_SIZE) + index_offset, index_number = struct.unpack( + self.__CUESHEET_TRACKINDEX_FORMAT, index) + val.indexes.append( + CueSheetTrackIndex(index_number, index_offset)) + self.tracks.append(val) + + def write(self): + f = StringIO() + flags = 0 + if self.compact_disc: + flags |= 0x80 + packed = struct.pack( + self.__CUESHEET_FORMAT, self.media_catalog_number, + self.lead_in_samples, flags, len(self.tracks)) + f.write(packed) + for track in self.tracks: + track_flags = 0 + track_flags |= (track.type & 1) << 7 + if track.pre_emphasis: + track_flags |= 0x40 + track_packed = struct.pack( + self.__CUESHEET_TRACK_FORMAT, track.start_offset, + track.track_number, track.isrc, track_flags, + len(track.indexes)) + f.write(track_packed) + for index in track.indexes: + index_packed = struct.pack( + self.__CUESHEET_TRACKINDEX_FORMAT, + index.index_offset, index.index_number) + f.write(index_packed) + return f.getvalue() + + def __repr__(self): + return ("<%s media_catalog_number=%r, lead_in=%r, compact_disc=%r, " + "tracks=%r>") % ( + type(self).__name__, self.media_catalog_number, + self.lead_in_samples, self.compact_disc, self.tracks) + + +class Picture(MetadataBlock): + """Read and write FLAC embed pictures. + + Attributes: + + * type -- picture type (same as types for ID3 APIC frames) + * mime -- MIME type of the picture + * desc -- picture's description + * width -- width in pixels + * height -- height in pixels + * depth -- color depth in bits-per-pixel + * colors -- number of colors for indexed palettes (like GIF), + 0 for non-indexed + * data -- picture data + """ + + code = 6 + _distrust_size = True + + def __init__(self, data=None): + self.type = 0 + self.mime = u'' + self.desc = u'' + self.width = 0 + self.height = 0 + self.depth = 0 + self.colors = 0 + self.data = '' + super(Picture, self).__init__(data) + + def __eq__(self, other): + try: + return (self.type == other.type and + self.mime == other.mime and + self.desc == other.desc and + self.width == other.width and + self.height == other.height and + self.depth == other.depth and + self.colors == other.colors and + self.data == other.data) + except (AttributeError, TypeError): + return False + + __hash__ = MetadataBlock.__hash__ + + def load(self, data): + self.type, length = struct.unpack('>2I', data.read(8)) + self.mime = data.read(length).decode('UTF-8', 'replace') + length, = struct.unpack('>I', data.read(4)) + self.desc = data.read(length).decode('UTF-8', 'replace') + (self.width, self.height, self.depth, + self.colors, length) = struct.unpack('>5I', data.read(20)) + self.data = data.read(length) + + def write(self): + f = StringIO() + mime = self.mime.encode('UTF-8') + f.write(struct.pack('>2I', self.type, len(mime))) + f.write(mime) + desc = self.desc.encode('UTF-8') + f.write(struct.pack('>I', len(desc))) + f.write(desc) + f.write(struct.pack('>5I', self.width, self.height, self.depth, + self.colors, len(self.data))) + f.write(self.data) + return f.getvalue() + + def __repr__(self): + return "<%s '%s' (%d bytes)>" % (type(self).__name__, self.mime, + len(self.data)) + + +class Padding(MetadataBlock): + """Empty padding space for metadata blocks. + + To avoid rewriting the entire FLAC file when editing comments, + metadata is often padded. Padding should occur at the end, and no + more than one padding block should be in any FLAC file. Mutagen + handles this with MetadataBlock.group_padding. + """ + + code = 1 + + def __init__(self, data=""): + super(Padding, self).__init__(data) + + def load(self, data): + self.length = len(data.read()) + + def write(self): + try: + return "\x00" * self.length + # On some 64 bit platforms this won't generate a MemoryError + # or OverflowError since you might have enough RAM, but it + # still generates a ValueError. On other 64 bit platforms, + # this will still succeed for extremely large values. + # Those should never happen in the real world, and if they + # do, writeblocks will catch it. + except (OverflowError, ValueError, MemoryError): + raise error("cannot write %d bytes" % self.length) + + def __eq__(self, other): + return isinstance(other, Padding) and self.length == other.length + + __hash__ = MetadataBlock.__hash__ + + def __repr__(self): + return "<%s (%d bytes)>" % (type(self).__name__, self.length) + + +class FLAC(FileType): + """A FLAC audio file. + + Attributes: + + * info -- stream information (length, bitrate, sample rate) + * tags -- metadata tags, if any + * cuesheet -- CueSheet object, if any + * seektable -- SeekTable object, if any + * pictures -- list of embedded pictures + """ + + _mimes = ["audio/x-flac", "application/x-flac"] + + METADATA_BLOCKS = [StreamInfo, Padding, None, SeekTable, VCFLACDict, + CueSheet, Picture] + """Known metadata block types, indexed by ID.""" + + @staticmethod + def score(filename, fileobj, header): + return (header.startswith("fLaC") + + filename.lower().endswith(".flac") * 3) + + def __read_metadata_block(self, fileobj): + byte = ord(fileobj.read(1)) + size = to_int_be(fileobj.read(3)) + code = byte & 0x7F + last_block = bool(byte & 0x80) + + try: + block_type = self.METADATA_BLOCKS[code] or MetadataBlock + except IndexError: + block_type = MetadataBlock + + if block_type._distrust_size: + # Some jackass is writing broken Metadata block length + # for Vorbis comment blocks, and the FLAC reference + # implementaton can parse them (mostly by accident), + # so we have to too. Instead of parsing the size + # given, parse an actual Vorbis comment, leaving + # fileobj in the right position. + # http://code.google.com/p/mutagen/issues/detail?id=52 + # ..same for the Picture block: + # http://code.google.com/p/mutagen/issues/detail?id=106 + block = block_type(fileobj) + else: + data = fileobj.read(size) + block = block_type(data) + block.code = code + + if block.code == VCFLACDict.code: + if self.tags is None: + self.tags = block + else: + raise FLACVorbisError("> 1 Vorbis comment block found") + elif block.code == CueSheet.code: + if self.cuesheet is None: + self.cuesheet = block + else: + raise error("> 1 CueSheet block found") + elif block.code == SeekTable.code: + if self.seektable is None: + self.seektable = block + else: + raise error("> 1 SeekTable block found") + self.metadata_blocks.append(block) + return not last_block + + def add_tags(self): + """Add a Vorbis comment block to the file.""" + if self.tags is None: + self.tags = VCFLACDict() + self.metadata_blocks.append(self.tags) + else: + raise FLACVorbisError("a Vorbis comment already exists") + + add_vorbiscomment = add_tags + + def delete(self, filename=None): + """Remove Vorbis comments from a file. + + If no filename is given, the one most recently loaded is used. + """ + if filename is None: + filename = self.filename + for s in list(self.metadata_blocks): + if isinstance(s, VCFLACDict): + self.metadata_blocks.remove(s) + self.tags = None + self.save() + break + + vc = property(lambda s: s.tags, doc="Alias for tags; don't use this.") + + def load(self, filename): + """Load file information from a filename.""" + + self.metadata_blocks = [] + self.tags = None + self.cuesheet = None + self.seektable = None + self.filename = filename + fileobj = StrictFileObject(open(filename, "rb")) + try: + self.__check_header(fileobj) + while self.__read_metadata_block(fileobj): + pass + finally: + fileobj.close() + + try: + self.metadata_blocks[0].length + except (AttributeError, IndexError): + raise FLACNoHeaderError("Stream info block not found") + + @property + def info(self): + return self.metadata_blocks[0] + + def add_picture(self, picture): + """Add a new picture to the file.""" + self.metadata_blocks.append(picture) + + def clear_pictures(self): + """Delete all pictures from the file.""" + self.metadata_blocks = filter(lambda b: b.code != Picture.code, + self.metadata_blocks) + + @property + def pictures(self): + """List of embedded pictures""" + return filter(lambda b: b.code == Picture.code, self.metadata_blocks) + + def save(self, filename=None, deleteid3=False): + """Save metadata blocks to a file. + + If no filename is given, the one most recently loaded is used. + """ + + if filename is None: + filename = self.filename + f = open(filename, 'rb+') + + try: + # Ensure we've got padding at the end, and only at the end. + # If adding makes it too large, we'll scale it down later. + self.metadata_blocks.append(Padding('\x00' * 1020)) + MetadataBlock.group_padding(self.metadata_blocks) + + header = self.__check_header(f) + # "fLaC" and maybe ID3 + available = self.__find_audio_offset(f) - header + data = MetadataBlock.writeblocks(self.metadata_blocks) + + # Delete ID3v2 + if deleteid3 and header > 4: + available += header - 4 + header = 4 + + if len(data) > available: + # If we have too much data, see if we can reduce padding. + padding = self.metadata_blocks[-1] + newlength = padding.length - (len(data) - available) + if newlength > 0: + padding.length = newlength + data = MetadataBlock.writeblocks(self.metadata_blocks) + assert len(data) == available + + elif len(data) < available: + # If we have too little data, increase padding. + self.metadata_blocks[-1].length += (available - len(data)) + data = MetadataBlock.writeblocks(self.metadata_blocks) + assert len(data) == available + + if len(data) != available: + # We couldn't reduce the padding enough. + diff = (len(data) - available) + insert_bytes(f, diff, header) + + f.seek(header - 4) + f.write("fLaC" + data) + + # Delete ID3v1 + if deleteid3: + try: + f.seek(-128, 2) + except IOError: + pass + else: + if f.read(3) == "TAG": + f.seek(-128, 2) + f.truncate() + finally: + f.close() + + def __find_audio_offset(self, fileobj): + byte = 0x00 + while not (byte & 0x80): + byte = ord(fileobj.read(1)) + size = to_int_be(fileobj.read(3)) + try: + block_type = self.METADATA_BLOCKS[byte & 0x7F] + except IndexError: + block_type = None + + if block_type and block_type._distrust_size: + # See comments in read_metadata_block; the size can't + # be trusted for Vorbis comment blocks and Picture block + block_type(fileobj) + else: + fileobj.read(size) + return fileobj.tell() + + def __check_header(self, fileobj): + size = 4 + header = fileobj.read(4) + if header != "fLaC": + size = None + if header[:3] == "ID3": + size = 14 + BitPaddedInt(fileobj.read(6)[2:]) + fileobj.seek(size - 4) + if fileobj.read(4) != "fLaC": + size = None + if size is None: + raise FLACNoHeaderError( + "%r is not a valid FLAC file" % fileobj.name) + return size + + +Open = FLAC + + +def delete(filename): + """Remove tags from a file.""" + FLAC(filename).delete() diff --git a/libs/mutagen/id3.py b/libs/mutagen/id3.py new file mode 100644 index 00000000..27d30e90 --- /dev/null +++ b/libs/mutagen/id3.py @@ -0,0 +1,919 @@ +# id3 support for mutagen +# Copyright (C) 2005 Michael Urman +# 2006 Lukas Lalinsky +# 2013 Christoph Reiter +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. + +"""ID3v2 reading and writing. + +This is based off of the following references: + +* http://id3.org/id3v2.4.0-structure +* http://id3.org/id3v2.4.0-frames +* http://id3.org/id3v2.3.0 +* http://id3.org/id3v2-00 +* http://id3.org/ID3v1 + +Its largest deviation from the above (versions 2.3 and 2.2) is that it +will not interpret the / characters as a separator, and will almost +always accept null separators to generate multi-valued text frames. + +Because ID3 frame structure differs between frame types, each frame is +implemented as a different class (e.g. TIT2 as mutagen.id3.TIT2). Each +frame's documentation contains a list of its attributes. + +Since this file's documentation is a little unwieldy, you are probably +interested in the :class:`ID3` class to start with. +""" + +__all__ = ['ID3', 'ID3FileType', 'Frames', 'Open', 'delete'] + +import struct + +from struct import unpack, pack, error as StructError + +import mutagen +from mutagen._util import insert_bytes, delete_bytes, DictProxy + +from mutagen._id3util import * +from mutagen._id3frames import * +from mutagen._id3specs import * + + +class ID3(DictProxy, mutagen.Metadata): + """A file with an ID3v2 tag. + + Attributes: + + * version -- ID3 tag version as a tuple + * unknown_frames -- raw frame data of any unknown frames found + * size -- the total size of the ID3 tag, including the header + """ + + PEDANTIC = True + version = (2, 4, 0) + + filename = None + size = 0 + __flags = 0 + __readbytes = 0 + __crc = None + __unknown_version = None + + _V24 = (2, 4, 0) + _V23 = (2, 3, 0) + _V22 = (2, 2, 0) + _V11 = (1, 1) + + def __init__(self, *args, **kwargs): + self.unknown_frames = [] + super(ID3, self).__init__(*args, **kwargs) + + def __fullread(self, size): + try: + if size < 0: + raise ValueError('Requested bytes (%s) less than zero' % size) + if size > self.__filesize: + raise EOFError('Requested %#x of %#x (%s)' % ( + long(size), long(self.__filesize), self.filename)) + except AttributeError: + pass + data = self.__fileobj.read(size) + if len(data) != size: + raise EOFError + self.__readbytes += size + return data + + def load(self, filename, known_frames=None, translate=True, v2_version=4): + """Load tags from a filename. + + Keyword arguments: + + * filename -- filename to load tag data from + * known_frames -- dict mapping frame IDs to Frame objects + * translate -- Update all tags to ID3v2.3/4 internally. If you + intend to save, this must be true or you have to + call update_to_v23() / update_to_v24() manually. + * v2_version -- if update_to_v23 or update_to_v24 get called (3 or 4) + + Example of loading a custom frame:: + + my_frames = dict(mutagen.id3.Frames) + class XMYF(Frame): ... + my_frames["XMYF"] = XMYF + mutagen.id3.ID3(filename, known_frames=my_frames) + """ + + if not v2_version in (3, 4): + raise ValueError("Only 3 and 4 possible for v2_version") + + from os.path import getsize + + self.filename = filename + self.__known_frames = known_frames + self.__fileobj = open(filename, 'rb') + self.__filesize = getsize(filename) + try: + try: + self.__load_header() + except EOFError: + self.size = 0 + raise ID3NoHeaderError("%s: too small (%d bytes)" % ( + filename, self.__filesize)) + except (ID3NoHeaderError, ID3UnsupportedVersionError), err: + self.size = 0 + import sys + stack = sys.exc_info()[2] + try: + self.__fileobj.seek(-128, 2) + except EnvironmentError: + raise err, None, stack + else: + frames = ParseID3v1(self.__fileobj.read(128)) + if frames is not None: + self.version = self._V11 + map(self.add, frames.values()) + else: + raise err, None, stack + else: + frames = self.__known_frames + if frames is None: + if self._V23 <= self.version: + frames = Frames + elif self._V22 <= self.version: + frames = Frames_2_2 + data = self.__fullread(self.size - 10) + for frame in self.__read_frames(data, frames=frames): + if isinstance(frame, Frame): + self.add(frame) + else: + self.unknown_frames.append(frame) + self.__unknown_version = self.version + finally: + self.__fileobj.close() + del self.__fileobj + del self.__filesize + if translate: + if v2_version == 3: + self.update_to_v23() + else: + self.update_to_v24() + + def getall(self, key): + """Return all frames with a given name (the list may be empty). + + This is best explained by examples:: + + id3.getall('TIT2') == [id3['TIT2']] + id3.getall('TTTT') == [] + id3.getall('TXXX') == [TXXX(desc='woo', text='bar'), + TXXX(desc='baz', text='quuuux'), ...] + + Since this is based on the frame's HashKey, which is + colon-separated, you can use it to do things like + ``getall('COMM:MusicMatch')`` or ``getall('TXXX:QuodLibet:')``. + """ + if key in self: + return [self[key]] + else: + key = key + ":" + return [v for s, v in self.items() if s.startswith(key)] + + def delall(self, key): + """Delete all tags of a given kind; see getall.""" + if key in self: + del(self[key]) + else: + key = key + ":" + for k in filter(lambda s: s.startswith(key), self.keys()): + del(self[k]) + + def setall(self, key, values): + """Delete frames of the given type and add frames in 'values'.""" + self.delall(key) + for tag in values: + self[tag.HashKey] = tag + + def pprint(self): + """Return tags in a human-readable format. + + "Human-readable" is used loosely here. The format is intended + to mirror that used for Vorbis or APEv2 output, e.g. + + ``TIT2=My Title`` + + However, ID3 frames can have multiple keys: + + ``POPM=user@example.org=3 128/255`` + """ + frames = list(map(Frame.pprint, self.values())) + frames.sort() + return "\n".join(frames) + + def loaded_frame(self, tag): + """Deprecated; use the add method.""" + # turn 2.2 into 2.3/2.4 tags + if len(type(tag).__name__) == 3: + tag = type(tag).__base__(tag) + self[tag.HashKey] = tag + + # add = loaded_frame (and vice versa) break applications that + # expect to be able to override loaded_frame (e.g. Quod Libet), + # as does making loaded_frame call add. + def add(self, frame): + """Add a frame to the tag.""" + return self.loaded_frame(frame) + + def __load_header(self): + fn = self.filename + data = self.__fullread(10) + id3, vmaj, vrev, flags, size = unpack('>3sBBB4s', data) + self.__flags = flags + self.size = BitPaddedInt(size) + 10 + self.version = (2, vmaj, vrev) + + if id3 != 'ID3': + raise ID3NoHeaderError("'%s' doesn't start with an ID3 tag" % fn) + if vmaj not in [2, 3, 4]: + raise ID3UnsupportedVersionError("'%s' ID3v2.%d not supported" + % (fn, vmaj)) + + if self.PEDANTIC: + if not BitPaddedInt.has_valid_padding(size): + raise ValueError("Header size not synchsafe") + + if self._V24 <= self.version and (flags & 0x0f): + raise ValueError("'%s' has invalid flags %#02x" % (fn, flags)) + elif self._V23 <= self.version < self._V24 and (flags & 0x1f): + raise ValueError("'%s' has invalid flags %#02x" % (fn, flags)) + + if self.f_extended: + extsize = self.__fullread(4) + if extsize in Frames: + # Some tagger sets the extended header flag but + # doesn't write an extended header; in this case, the + # ID3 data follows immediately. Since no extended + # header is going to be long enough to actually match + # a frame, and if it's *not* a frame we're going to be + # completely lost anyway, this seems to be the most + # correct check. + # http://code.google.com/p/quodlibet/issues/detail?id=126 + self.__flags ^= 0x40 + self.__extsize = 0 + self.__fileobj.seek(-4, 1) + self.__readbytes -= 4 + elif self.version >= self._V24: + # "Where the 'Extended header size' is the size of the whole + # extended header, stored as a 32 bit synchsafe integer." + self.__extsize = BitPaddedInt(extsize) - 4 + if self.PEDANTIC: + if not BitPaddedInt.has_valid_padding(extsize): + raise ValueError("Extended header size not synchsafe") + else: + # "Where the 'Extended header size', currently 6 or 10 bytes, + # excludes itself." + self.__extsize = unpack('>L', extsize)[0] + if self.__extsize: + self.__extdata = self.__fullread(self.__extsize) + else: + self.__extdata = "" + + def __determine_bpi(self, data, frames, EMPTY="\x00" * 10): + if self.version < self._V24: + return int + # have to special case whether to use bitpaddedints here + # spec says to use them, but iTunes has it wrong + + # count number of tags found as BitPaddedInt and how far past + o = 0 + asbpi = 0 + while o < len(data) - 10: + part = data[o:o + 10] + if part == EMPTY: + bpioff = -((len(data) - o) % 10) + break + name, size, flags = unpack('>4sLH', part) + size = BitPaddedInt(size) + o += 10 + size + if name in frames: + asbpi += 1 + else: + bpioff = o - len(data) + + # count number of tags found as int and how far past + o = 0 + asint = 0 + while o < len(data) - 10: + part = data[o:o + 10] + if part == EMPTY: + intoff = -((len(data) - o) % 10) + break + name, size, flags = unpack('>4sLH', part) + o += 10 + size + if name in frames: + asint += 1 + else: + intoff = o - len(data) + + # if more tags as int, or equal and bpi is past and int is not + if asint > asbpi or (asint == asbpi and (bpioff >= 1 and intoff <= 1)): + return int + return BitPaddedInt + + def __read_frames(self, data, frames): + if self.version < self._V24 and self.f_unsynch: + try: + data = unsynch.decode(data) + except ValueError: + pass + + if self._V23 <= self.version: + bpi = self.__determine_bpi(data, frames) + while data: + header = data[:10] + try: + name, size, flags = unpack('>4sLH', header) + except struct.error: + return # not enough header + if name.strip('\x00') == '': + return + size = bpi(size) + framedata = data[10:10+size] + data = data[10+size:] + if size == 0: + continue # drop empty frames + try: + tag = frames[name] + except KeyError: + if is_valid_frame_id(name): + yield header + framedata + else: + try: + yield self.__load_framedata(tag, flags, framedata) + except NotImplementedError: + yield header + framedata + except ID3JunkFrameError: + pass + + elif self._V22 <= self.version: + while data: + header = data[0:6] + try: + name, size = unpack('>3s3s', header) + except struct.error: + return # not enough header + size, = struct.unpack('>L', '\x00'+size) + if name.strip('\x00') == '': + return + framedata = data[6:6+size] + data = data[6+size:] + if size == 0: + continue # drop empty frames + try: + tag = frames[name] + except KeyError: + if is_valid_frame_id(name): + yield header + framedata + else: + try: + yield self.__load_framedata(tag, 0, framedata) + except NotImplementedError: + yield header + framedata + except ID3JunkFrameError: + pass + + def __load_framedata(self, tag, flags, framedata): + return tag.fromData(self, flags, framedata) + + f_unsynch = property(lambda s: bool(s.__flags & 0x80)) + f_extended = property(lambda s: bool(s.__flags & 0x40)) + f_experimental = property(lambda s: bool(s.__flags & 0x20)) + f_footer = property(lambda s: bool(s.__flags & 0x10)) + + #f_crc = property(lambda s: bool(s.__extflags & 0x8000)) + + def save(self, filename=None, v1=1, v2_version=4, v23_sep='/'): + """Save changes to a file. + + If no filename is given, the one most recently loaded is used. + + Keyword arguments: + v1 -- if 0, ID3v1 tags will be removed + if 1, ID3v1 tags will be updated but not added + if 2, ID3v1 tags will be created and/or updated + v2 -- version of ID3v2 tags (3 or 4). + + By default Mutagen saves ID3v2.4 tags. If you want to save ID3v2.3 + tags, you must call method update_to_v23 before saving the file. + + v23_sep -- the separator used to join multiple text values + if v2_version == 3. Defaults to '/' but if it's None + will be the ID3v2v2.4 null separator. + + The lack of a way to update only an ID3v1 tag is intentional. + """ + + if v2_version == 3: + version = self._V23 + elif v2_version == 4: + version = self._V24 + else: + raise ValueError("Only 3 or 4 allowed for v2_version") + + # Sort frames by 'importance' + order = ["TIT2", "TPE1", "TRCK", "TALB", "TPOS", "TDRC", "TCON"] + order = dict(zip(order, range(len(order)))) + last = len(order) + frames = self.items() + frames.sort(lambda a, b: cmp(order.get(a[0][:4], last), + order.get(b[0][:4], last))) + + framedata = [self.__save_frame(frame, version=version, v23_sep=v23_sep) + for (key, frame) in frames] + + # only write unknown frames if they were loaded from the version + # we are saving with or upgraded to it + if self.__unknown_version == version: + framedata.extend([data for data in self.unknown_frames + if len(data) > 10]) + + if not framedata: + try: + self.delete(filename) + except EnvironmentError, err: + from errno import ENOENT + if err.errno != ENOENT: + raise + return + + framedata = ''.join(framedata) + framesize = len(framedata) + + if filename is None: + filename = self.filename + try: + f = open(filename, 'rb+') + except IOError, err: + from errno import ENOENT + if err.errno != ENOENT: + raise + f = open(filename, 'ab') # create, then reopen + f = open(filename, 'rb+') + try: + idata = f.read(10) + try: + id3, vmaj, vrev, flags, insize = unpack('>3sBBB4s', idata) + except struct.error: + id3, insize = '', 0 + insize = BitPaddedInt(insize) + if id3 != 'ID3': + insize = -10 + + if insize >= framesize: + outsize = insize + else: + outsize = (framesize + 1023) & ~0x3FF + framedata += '\x00' * (outsize - framesize) + + framesize = BitPaddedInt.to_str(outsize, width=4) + flags = 0 + header = pack('>3sBBB4s', 'ID3', v2_version, 0, flags, framesize) + data = header + framedata + + if (insize < outsize): + insert_bytes(f, outsize-insize, insize+10) + f.seek(0) + f.write(data) + + try: + f.seek(-128, 2) + except IOError, err: + # If the file is too small, that's OK - it just means + # we're certain it doesn't have a v1 tag. + from errno import EINVAL + if err.errno != EINVAL: + # If we failed to see for some other reason, bail out. + raise + # Since we're sure this isn't a v1 tag, don't read it. + f.seek(0, 2) + + data = f.read(128) + try: + idx = data.index("TAG") + except ValueError: + offset = 0 + has_v1 = False + else: + offset = idx - len(data) + has_v1 = True + + f.seek(offset, 2) + if v1 == 1 and has_v1 or v1 == 2: + f.write(MakeID3v1(self)) + else: + f.truncate() + + finally: + f.close() + + def delete(self, filename=None, delete_v1=True, delete_v2=True): + """Remove tags from a file. + + If no filename is given, the one most recently loaded is used. + + Keyword arguments: + + * delete_v1 -- delete any ID3v1 tag + * delete_v2 -- delete any ID3v2 tag + """ + if filename is None: + filename = self.filename + delete(filename, delete_v1, delete_v2) + self.clear() + + def __save_frame(self, frame, name=None, version=_V24, v23_sep=None): + flags = 0 + if self.PEDANTIC and isinstance(frame, TextFrame): + if len(str(frame)) == 0: + return '' + + if version == self._V23: + framev23 = frame._get_v23_frame(sep=v23_sep) + framedata = framev23._writeData() + else: + framedata = frame._writeData() + + usize = len(framedata) + if usize > 2048: + # Disabled as this causes iTunes and other programs + # to fail to find these frames, which usually includes + # e.g. APIC. + #framedata = BitPaddedInt.to_str(usize) + framedata.encode('zlib') + #flags |= Frame.FLAG24_COMPRESS | Frame.FLAG24_DATALEN + pass + + if version == self._V24: + bits = 7 + elif version == self._V23: + bits = 8 + else: + raise ValueError + + datasize = BitPaddedInt.to_str(len(framedata), width=4, bits=bits) + header = pack('>4s4sH', name or type(frame).__name__, datasize, flags) + return header + framedata + + def __update_common(self): + """Updates done by both v23 and v24 update""" + + if "TCON" in self: + # Get rid of "(xx)Foobr" format. + self["TCON"].genres = self["TCON"].genres + + if self.version < self._V23: + # ID3v2.2 PIC frames are slightly different. + pics = self.getall("APIC") + mimes = {"PNG": "image/png", "JPG": "image/jpeg"} + self.delall("APIC") + for pic in pics: + newpic = APIC( + encoding=pic.encoding, mime=mimes.get(pic.mime, pic.mime), + type=pic.type, desc=pic.desc, data=pic.data) + self.add(newpic) + + # ID3v2.2 LNK frames are just way too different to upgrade. + self.delall("LINK") + + def update_to_v24(self): + """Convert older tags into an ID3v2.4 tag. + + This updates old ID3v2 frames to ID3v2.4 ones (e.g. TYER to + TDRC). If you intend to save tags, you must call this function + at some point; it is called by default when loading the tag. + """ + + self.__update_common() + + if self.__unknown_version == (2, 3, 0): + # convert unknown 2.3 frames (flags/size) to 2.4 + converted = [] + for frame in self.unknown_frames: + try: + name, size, flags = unpack('>4sLH', frame[:10]) + frame = BinaryFrame.fromData(self, flags, frame[10:]) + except (struct.error, error): + continue + converted.append(self.__save_frame(frame, name=name)) + self.unknown_frames[:] = converted + self.__unknown_version = (2, 4, 0) + + # TDAT, TYER, and TIME have been turned into TDRC. + try: + if str(self.get("TYER", "")).strip("\x00"): + date = str(self.pop("TYER")) + if str(self.get("TDAT", "")).strip("\x00"): + dat = str(self.pop("TDAT")) + date = "%s-%s-%s" % (date, dat[2:], dat[:2]) + if str(self.get("TIME", "")).strip("\x00"): + time = str(self.pop("TIME")) + date += "T%s:%s:00" % (time[:2], time[2:]) + if "TDRC" not in self: + self.add(TDRC(encoding=0, text=date)) + except UnicodeDecodeError: + # Old ID3 tags have *lots* of Unicode problems, so if TYER + # is bad, just chuck the frames. + pass + + # TORY can be the first part of a TDOR. + if "TORY" in self: + f = self.pop("TORY") + if "TDOR" not in self: + try: + self.add(TDOR(encoding=0, text=str(f))) + except UnicodeDecodeError: + pass + + # IPLS is now TIPL. + if "IPLS" in self: + f = self.pop("IPLS") + if "TIPL" not in self: + self.add(TIPL(encoding=f.encoding, people=f.people)) + + # These can't be trivially translated to any ID3v2.4 tags, or + # should have been removed already. + for key in ["RVAD", "EQUA", "TRDA", "TSIZ", "TDAT", "TIME", "CRM"]: + if key in self: + del(self[key]) + + def update_to_v23(self): + """Convert older (and newer) tags into an ID3v2.3 tag. + + This updates incompatible ID3v2 frames to ID3v2.3 ones. If you + intend to save tags as ID3v2.3, you must call this function + at some point. + + If you want to to go off spec and include some v2.4 frames + in v2.3, remove them before calling this and add them back afterwards. + """ + + self.__update_common() + + # we could downgrade unknown v2.4 frames here, but given that + # the main reason to save v2.3 is compatibility and this + # might increase the chance of some parser breaking.. better not + + # TMCL, TIPL -> TIPL + if "TIPL" in self or "TMCL" in self: + people = [] + if "TIPL" in self: + f = self.pop("TIPL") + people.extend(f.people) + if "TMCL" in self: + f = self.pop("TMCL") + people.extend(f.people) + if "IPLS" not in self: + self.add(IPLS(encoding=f.encoding, people=people)) + + # TDOR -> TORY + if "TDOR" in self: + f = self.pop("TDOR") + if f.text: + d = f.text[0] + if d.year and "TORY" not in self: + self.add(TORY(encoding=f.encoding, text="%04d" % d.year)) + + # TDRC -> TYER, TDAT, TIME + if "TDRC" in self: + f = self.pop("TDRC") + if f.text: + d = f.text[0] + if d.year and "TYER" not in self: + self.add(TYER(encoding=f.encoding, text="%04d" % d.year)) + if d.month and d.day and "TDAT" not in self: + self.add(TDAT(encoding=f.encoding, + text="%02d%02d" % (d.day, d.month))) + if d.hour and d.minute and "TIME" not in self: + self.add(TIME(encoding=f.encoding, + text="%02d%02d" % (d.hour, d.minute))) + + # New frames added in v2.4 + v24_frames = [ + 'ASPI', 'EQU2', 'RVA2', 'SEEK', 'SIGN', 'TDEN', 'TDOR', + 'TDRC', 'TDRL', 'TDTG', 'TIPL', 'TMCL', 'TMOO', 'TPRO', + 'TSOA', 'TSOP', 'TSOT', 'TSST', + ] + + for key in v24_frames: + if key in self: + del(self[key]) + + +def delete(filename, delete_v1=True, delete_v2=True): + """Remove tags from a file. + + Keyword arguments: + + * delete_v1 -- delete any ID3v1 tag + * delete_v2 -- delete any ID3v2 tag + """ + + f = open(filename, 'rb+') + + if delete_v1: + try: + f.seek(-128, 2) + except IOError: + pass + else: + if f.read(3) == "TAG": + f.seek(-128, 2) + f.truncate() + + # technically an insize=0 tag is invalid, but we delete it anyway + # (primarily because we used to write it) + if delete_v2: + f.seek(0, 0) + idata = f.read(10) + try: + id3, vmaj, vrev, flags, insize = unpack('>3sBBB4s', idata) + except struct.error: + id3, insize = '', -1 + insize = BitPaddedInt(insize) + if id3 == 'ID3' and insize >= 0: + delete_bytes(f, insize + 10, 0) + + +# support open(filename) as interface +Open = ID3 + + +# ID3v1.1 support. +def ParseID3v1(string): + """Parse an ID3v1 tag, returning a list of ID3v2.4 frames.""" + + try: + string = string[string.index("TAG"):] + except ValueError: + return None + if 128 < len(string) or len(string) < 124: + return None + + # Issue #69 - Previous versions of Mutagen, when encountering + # out-of-spec TDRC and TYER frames of less than four characters, + # wrote only the characters available - e.g. "1" or "" - into the + # year field. To parse those, reduce the size of the year field. + # Amazingly, "0s" works as a struct format string. + unpack_fmt = "3s30s30s30s%ds29sBB" % (len(string) - 124) + + try: + tag, title, artist, album, year, comment, track, genre = unpack( + unpack_fmt, string) + except StructError: + return None + + if tag != "TAG": + return None + + def fix(string): + return string.split("\x00")[0].strip().decode('latin1') + + title, artist, album, year, comment = map( + fix, [title, artist, album, year, comment]) + + frames = {} + if title: + frames["TIT2"] = TIT2(encoding=0, text=title) + if artist: + frames["TPE1"] = TPE1(encoding=0, text=[artist]) + if album: + frames["TALB"] = TALB(encoding=0, text=album) + if year: + frames["TDRC"] = TDRC(encoding=0, text=year) + if comment: + frames["COMM"] = COMM( + encoding=0, lang="eng", desc="ID3v1 Comment", text=comment) + # Don't read a track number if it looks like the comment was + # padded with spaces instead of nulls (thanks, WinAmp). + if track and (track != 32 or string[-3] == '\x00'): + frames["TRCK"] = TRCK(encoding=0, text=str(track)) + if genre != 255: + frames["TCON"] = TCON(encoding=0, text=str(genre)) + return frames + + +def MakeID3v1(id3): + """Return an ID3v1.1 tag string from a dict of ID3v2.4 frames.""" + + v1 = {} + + for v2id, name in {"TIT2": "title", "TPE1": "artist", + "TALB": "album"}.items(): + if v2id in id3: + text = id3[v2id].text[0].encode('latin1', 'replace')[:30] + else: + text = "" + v1[name] = text + ("\x00" * (30 - len(text))) + + if "COMM" in id3: + cmnt = id3["COMM"].text[0].encode('latin1', 'replace')[:28] + else: + cmnt = "" + v1["comment"] = cmnt + ("\x00" * (29 - len(cmnt))) + + if "TRCK" in id3: + try: + v1["track"] = chr(+id3["TRCK"]) + except ValueError: + v1["track"] = "\x00" + else: + v1["track"] = "\x00" + + if "TCON" in id3: + try: + genre = id3["TCON"].genres[0] + except IndexError: + pass + else: + if genre in TCON.GENRES: + v1["genre"] = chr(TCON.GENRES.index(genre)) + if "genre" not in v1: + v1["genre"] = "\xff" + + if "TDRC" in id3: + year = str(id3["TDRC"]) + elif "TYER" in id3: + year = str(id3["TYER"]) + else: + year = "" + v1["year"] = (year + "\x00\x00\x00\x00")[:4] + + return ("TAG%(title)s%(artist)s%(album)s%(year)s%(comment)s" + "%(track)s%(genre)s") % v1 + + +class ID3FileType(mutagen.FileType): + """An unknown type of file with ID3 tags.""" + + ID3 = ID3 + + class _Info(object): + length = 0 + + def __init__(self, fileobj, offset): + pass + + @staticmethod + def pprint(): + return "Unknown format with ID3 tag" + + @staticmethod + def score(filename, fileobj, header): + return header.startswith("ID3") + + def add_tags(self, ID3=None): + """Add an empty ID3 tag to the file. + + A custom tag reader may be used in instead of the default + mutagen.id3.ID3 object, e.g. an EasyID3 reader. + """ + if ID3 is None: + ID3 = self.ID3 + if self.tags is None: + self.ID3 = ID3 + self.tags = ID3() + else: + raise error("an ID3 tag already exists") + + def load(self, filename, ID3=None, **kwargs): + """Load stream and tag information from a file. + + A custom tag reader may be used in instead of the default + mutagen.id3.ID3 object, e.g. an EasyID3 reader. + """ + + if ID3 is None: + ID3 = self.ID3 + else: + # If this was initialized with EasyID3, remember that for + # when tags are auto-instantiated in add_tags. + self.ID3 = ID3 + self.filename = filename + try: + self.tags = ID3(filename, **kwargs) + except error: + self.tags = None + if self.tags is not None: + try: + offset = self.tags.size + except AttributeError: + offset = None + else: + offset = None + try: + fileobj = open(filename, "rb") + self.info = self._Info(fileobj, offset) + finally: + fileobj.close() diff --git a/libs/mutagen/m4a.py b/libs/mutagen/m4a.py new file mode 100644 index 00000000..64b89679 --- /dev/null +++ b/libs/mutagen/m4a.py @@ -0,0 +1,538 @@ +# Copyright 2006 Joe Wreschnig +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +"""Read and write MPEG-4 audio files with iTunes metadata. + +This module will read MPEG-4 audio information and metadata, +as found in Apple's M4A (aka MP4, M4B, M4P) files. + +There is no official specification for this format. The source code +for TagLib, FAAD, and various MPEG specifications at +http://developer.apple.com/documentation/QuickTime/QTFF/, +http://www.geocities.com/xhelmboyx/quicktime/formats/mp4-layout.txt, +and http://wiki.multimedia.cx/index.php?title=Apple_QuickTime were all +consulted. + +This module does not support 64 bit atom sizes, and so will not +work on metadata over 4GB. +""" + +import struct +import sys + +from cStringIO import StringIO + +from mutagen import FileType, Metadata +from mutagen._constants import GENRES +from mutagen._util import cdata, insert_bytes, delete_bytes, DictProxy + + +class error(IOError): + pass + + +class M4AMetadataError(error): + pass + + +class M4AStreamInfoError(error): + pass + + +class M4AMetadataValueError(ValueError, M4AMetadataError): + pass + + +import warnings +warnings.warn( + "mutagen.m4a is deprecated; use mutagen.mp4 instead.", DeprecationWarning) + + +# This is not an exhaustive list of container atoms, but just the +# ones this module needs to peek inside. +_CONTAINERS = ["moov", "udta", "trak", "mdia", "meta", "ilst", + "stbl", "minf", "stsd"] +_SKIP_SIZE = {"meta": 4} + +__all__ = ['M4A', 'Open', 'delete', 'M4ACover'] + + +class M4ACover(str): + """A cover artwork. + + Attributes: + imageformat -- format of the image (either FORMAT_JPEG or FORMAT_PNG) + """ + FORMAT_JPEG = 0x0D + FORMAT_PNG = 0x0E + + def __new__(cls, data, imageformat=None): + self = str.__new__(cls, data) + if imageformat is None: + imageformat = M4ACover.FORMAT_JPEG + self.imageformat = imageformat + try: + self.format + except AttributeError: + self.format = imageformat + return self + + +class Atom(object): + """An individual atom. + + Attributes: + children -- list child atoms (or None for non-container atoms) + length -- length of this atom, including length and name + name -- four byte name of the atom, as a str + offset -- location in the constructor-given fileobj of this atom + + This structure should only be used internally by Mutagen. + """ + + children = None + + def __init__(self, fileobj): + self.offset = fileobj.tell() + self.length, self.name = struct.unpack(">I4s", fileobj.read(8)) + if self.length == 1: + raise error("64 bit atom sizes are not supported") + elif self.length < 8: + return + + if self.name in _CONTAINERS: + self.children = [] + fileobj.seek(_SKIP_SIZE.get(self.name, 0), 1) + while fileobj.tell() < self.offset + self.length: + self.children.append(Atom(fileobj)) + else: + fileobj.seek(self.offset + self.length, 0) + + @staticmethod + def render(name, data): + """Render raw atom data.""" + # this raises OverflowError if Py_ssize_t can't handle the atom data + size = len(data) + 8 + if size <= 0xFFFFFFFF: + return struct.pack(">I4s", size, name) + data + else: + return struct.pack(">I4sQ", 1, name, size + 8) + data + + def __getitem__(self, remaining): + """Look up a child atom, potentially recursively. + + e.g. atom['udta', 'meta'] => + """ + if not remaining: + return self + elif self.children is None: + raise KeyError("%r is not a container" % self.name) + for child in self.children: + if child.name == remaining[0]: + return child[remaining[1:]] + else: + raise KeyError("%r not found" % remaining[0]) + + def __repr__(self): + klass = self.__class__.__name__ + if self.children is None: + return "<%s name=%r length=%r offset=%r>" % ( + klass, self.name, self.length, self.offset) + else: + children = "\n".join([" " + line for child in self.children + for line in repr(child).splitlines()]) + return "<%s name=%r length=%r offset=%r\n%s>" % ( + klass, self.name, self.length, self.offset, children) + + +class Atoms(object): + """Root atoms in a given file. + + Attributes: + atoms -- a list of top-level atoms as Atom objects + + This structure should only be used internally by Mutagen. + """ + def __init__(self, fileobj): + self.atoms = [] + fileobj.seek(0, 2) + end = fileobj.tell() + fileobj.seek(0) + while fileobj.tell() < end: + self.atoms.append(Atom(fileobj)) + + def path(self, *names): + """Look up and return the complete path of an atom. + + For example, atoms.path('moov', 'udta', 'meta') will return a + list of three atoms, corresponding to the moov, udta, and meta + atoms. + """ + path = [self] + for name in names: + path.append(path[-1][name, ]) + return path[1:] + + def __getitem__(self, names): + """Look up a child atom. + + 'names' may be a list of atoms (['moov', 'udta']) or a string + specifying the complete path ('moov.udta'). + """ + if isinstance(names, basestring): + names = names.split(".") + for child in self.atoms: + if child.name == names[0]: + return child[names[1:]] + else: + raise KeyError("%s not found" % names[0]) + + def __repr__(self): + return "\n".join([repr(child) for child in self.atoms]) + + +class M4ATags(DictProxy, Metadata): + """Dictionary containing Apple iTunes metadata list key/values. + + Keys are four byte identifiers, except for freeform ('----') + keys. Values are usually unicode strings, but some atoms have a + special structure: + cpil -- boolean + trkn, disk -- tuple of 16 bit ints (current, total) + tmpo -- 16 bit int + covr -- list of M4ACover objects (which are tagged strs) + gnre -- not supported. Use '\\xa9gen' instead. + + The freeform '----' frames use a key in the format '----:mean:name' + where 'mean' is usually 'com.apple.iTunes' and 'name' is a unique + identifier for this frame. The value is a str, but is probably + text that can be decoded as UTF-8. + + M4A tag data cannot exist outside of the structure of an M4A file, + so this class should not be manually instantiated. + + Unknown non-text tags are removed. + """ + + def load(self, atoms, fileobj): + try: + ilst = atoms["moov.udta.meta.ilst"] + except KeyError, key: + raise M4AMetadataError(key) + for atom in ilst.children: + fileobj.seek(atom.offset + 8) + data = fileobj.read(atom.length - 8) + parse = self.__atoms.get(atom.name, (M4ATags.__parse_text,))[0] + parse(self, atom, data) + + @staticmethod + def __key_sort(item1, item2): + (key1, v1) = item1 + (key2, v2) = item2 + # iTunes always writes the tags in order of "relevance", try + # to copy it as closely as possible. + order = ["\xa9nam", "\xa9ART", "\xa9wrt", "\xa9alb", + "\xa9gen", "gnre", "trkn", "disk", + "\xa9day", "cpil", "tmpo", "\xa9too", + "----", "covr", "\xa9lyr"] + order = dict(zip(order, range(len(order)))) + last = len(order) + # If there's no key-based way to distinguish, order by length. + # If there's still no way, go by string comparison on the + # values, so we at least have something determinstic. + return (cmp(order.get(key1[:4], last), order.get(key2[:4], last)) or + cmp(len(v1), len(v2)) or cmp(v1, v2)) + + def save(self, filename): + """Save the metadata to the given filename.""" + values = [] + items = self.items() + items.sort(self.__key_sort) + for key, value in items: + render = self.__atoms.get( + key[:4], (None, M4ATags.__render_text))[1] + values.append(render(self, key, value)) + data = Atom.render("ilst", "".join(values)) + + # Find the old atoms. + fileobj = open(filename, "rb+") + try: + atoms = Atoms(fileobj) + + moov = atoms["moov"] + + if moov != atoms.atoms[-1]: + # "Free" the old moov block. Something in the mdat + # block is not happy when its offset changes and it + # won't play back. So, rather than try to figure that + # out, just move the moov atom to the end of the file. + offset = self.__move_moov(fileobj, moov) + else: + offset = 0 + + try: + path = atoms.path("moov", "udta", "meta", "ilst") + except KeyError: + self.__save_new(fileobj, atoms, data, offset) + else: + self.__save_existing(fileobj, atoms, path, data, offset) + finally: + fileobj.close() + + def __move_moov(self, fileobj, moov): + fileobj.seek(moov.offset) + data = fileobj.read(moov.length) + fileobj.seek(moov.offset) + free = Atom.render("free", "\x00" * (moov.length - 8)) + fileobj.write(free) + fileobj.seek(0, 2) + # Figure out how far we have to shift all our successive + # seek calls, relative to what the atoms say. + old_end = fileobj.tell() + fileobj.write(data) + return old_end - moov.offset + + def __save_new(self, fileobj, atoms, ilst, offset): + hdlr = Atom.render("hdlr", "\x00" * 8 + "mdirappl" + "\x00" * 9) + meta = Atom.render("meta", "\x00\x00\x00\x00" + hdlr + ilst) + moov, udta = atoms.path("moov", "udta") + insert_bytes(fileobj, len(meta), udta.offset + offset + 8) + fileobj.seek(udta.offset + offset + 8) + fileobj.write(meta) + self.__update_parents(fileobj, [moov, udta], len(meta), offset) + + def __save_existing(self, fileobj, atoms, path, data, offset): + # Replace the old ilst atom. + ilst = path.pop() + delta = len(data) - ilst.length + fileobj.seek(ilst.offset + offset) + if delta > 0: + insert_bytes(fileobj, delta, ilst.offset + offset) + elif delta < 0: + delete_bytes(fileobj, -delta, ilst.offset + offset) + fileobj.seek(ilst.offset + offset) + fileobj.write(data) + self.__update_parents(fileobj, path, delta, offset) + + def __update_parents(self, fileobj, path, delta, offset): + # Update all parent atoms with the new size. + for atom in path: + fileobj.seek(atom.offset + offset) + size = cdata.uint_be(fileobj.read(4)) + delta + fileobj.seek(atom.offset + offset) + fileobj.write(cdata.to_uint_be(size)) + + def __render_data(self, key, flags, data): + data = struct.pack(">2I", flags, 0) + data + return Atom.render(key, Atom.render("data", data)) + + def __parse_freeform(self, atom, data): + try: + fileobj = StringIO(data) + mean_length = cdata.uint_be(fileobj.read(4)) + # skip over 8 bytes of atom name, flags + mean = fileobj.read(mean_length - 4)[8:] + name_length = cdata.uint_be(fileobj.read(4)) + name = fileobj.read(name_length - 4)[8:] + value_length = cdata.uint_be(fileobj.read(4)) + # Name, flags, and reserved bytes + value = fileobj.read(value_length - 4)[12:] + except struct.error: + # Some ---- atoms have no data atom, I have no clue why + # they actually end up in the file. + pass + else: + self["%s:%s:%s" % (atom.name, mean, name)] = value + + def __render_freeform(self, key, value): + dummy, mean, name = key.split(":", 2) + mean = struct.pack(">I4sI", len(mean) + 12, "mean", 0) + mean + name = struct.pack(">I4sI", len(name) + 12, "name", 0) + name + value = struct.pack(">I4s2I", len(value) + 16, "data", 0x1, 0) + value + final = mean + name + value + return Atom.render("----", final) + + def __parse_pair(self, atom, data): + self[atom.name] = struct.unpack(">2H", data[18:22]) + + def __render_pair(self, key, value): + track, total = value + if 0 <= track < 1 << 16 and 0 <= total < 1 << 16: + data = struct.pack(">4H", 0, track, total, 0) + return self.__render_data(key, 0, data) + else: + raise M4AMetadataValueError("invalid numeric pair %r" % (value,)) + + def __render_pair_no_trailing(self, key, value): + track, total = value + if 0 <= track < 1 << 16 and 0 <= total < 1 << 16: + data = struct.pack(">3H", 0, track, total) + return self.__render_data(key, 0, data) + else: + raise M4AMetadataValueError("invalid numeric pair %r" % (value,)) + + def __parse_genre(self, atom, data): + # Translate to a freeform genre. + genre = cdata.short_be(data[16:18]) + if "\xa9gen" not in self: + try: + self["\xa9gen"] = GENRES[genre - 1] + except IndexError: + pass + + def __parse_tempo(self, atom, data): + self[atom.name] = cdata.short_be(data[16:18]) + + def __render_tempo(self, key, value): + if 0 <= value < 1 << 16: + return self.__render_data(key, 0x15, cdata.to_ushort_be(value)) + else: + raise M4AMetadataValueError("invalid short integer %r" % value) + + def __parse_compilation(self, atom, data): + try: + self[atom.name] = bool(ord(data[16:17])) + except TypeError: + self[atom.name] = False + + def __render_compilation(self, key, value): + return self.__render_data(key, 0x15, chr(bool(value))) + + def __parse_cover(self, atom, data): + length, name, imageformat = struct.unpack(">I4sI", data[:12]) + if name != "data": + raise M4AMetadataError( + "unexpected atom %r inside 'covr'" % name) + if imageformat not in (M4ACover.FORMAT_JPEG, M4ACover.FORMAT_PNG): + imageformat = M4ACover.FORMAT_JPEG + self[atom.name] = M4ACover(data[16:length], imageformat) + + def __render_cover(self, key, value): + try: + imageformat = value.imageformat + except AttributeError: + imageformat = M4ACover.FORMAT_JPEG + data = Atom.render("data", struct.pack(">2I", imageformat, 0) + value) + return Atom.render(key, data) + + def __parse_text(self, atom, data): + flags = cdata.uint_be(data[8:12]) + if flags == 1: + self[atom.name] = data[16:].decode('utf-8', 'replace') + + def __render_text(self, key, value): + return self.__render_data(key, 0x1, value.encode('utf-8')) + + def delete(self, filename): + self.clear() + self.save(filename) + + __atoms = { + "----": (__parse_freeform, __render_freeform), + "trkn": (__parse_pair, __render_pair), + "disk": (__parse_pair, __render_pair_no_trailing), + "gnre": (__parse_genre, None), + "tmpo": (__parse_tempo, __render_tempo), + "cpil": (__parse_compilation, __render_compilation), + "covr": (__parse_cover, __render_cover), + } + + def pprint(self): + values = [] + for key, value in self.iteritems(): + key = key.decode('latin1') + try: + values.append("%s=%s" % (key, value)) + except UnicodeDecodeError: + values.append("%s=[%d bytes of data]" % (key, len(value))) + return "\n".join(values) + + +class M4AInfo(object): + """MPEG-4 stream information. + + Attributes: + bitrate -- bitrate in bits per second, as an int + length -- file length in seconds, as a float + """ + + bitrate = 0 + + def __init__(self, atoms, fileobj): + hdlr = atoms["moov.trak.mdia.hdlr"] + fileobj.seek(hdlr.offset) + if "soun" not in fileobj.read(hdlr.length): + raise M4AStreamInfoError("track has no audio data") + + mdhd = atoms["moov.trak.mdia.mdhd"] + fileobj.seek(mdhd.offset) + data = fileobj.read(mdhd.length) + if ord(data[8]) == 0: + offset = 20 + fmt = ">2I" + else: + offset = 28 + fmt = ">IQ" + end = offset + struct.calcsize(fmt) + unit, length = struct.unpack(fmt, data[offset:end]) + self.length = float(length) / unit + + try: + atom = atoms["moov.trak.mdia.minf.stbl.stsd"] + fileobj.seek(atom.offset) + data = fileobj.read(atom.length) + self.bitrate = cdata.uint_be(data[-17:-13]) + except (ValueError, KeyError): + # Bitrate values are optional. + pass + + def pprint(self): + return "MPEG-4 audio, %.2f seconds, %d bps" % ( + self.length, self.bitrate) + + +class M4A(FileType): + """An MPEG-4 audio file, probably containing AAC. + + If more than one track is present in the file, the first is used. + Only audio ('soun') tracks will be read. + """ + + _mimes = ["audio/mp4", "audio/x-m4a", "audio/mpeg4", "audio/aac"] + + def load(self, filename): + self.filename = filename + fileobj = open(filename, "rb") + try: + atoms = Atoms(fileobj) + try: + self.info = M4AInfo(atoms, fileobj) + except StandardError, err: + raise M4AStreamInfoError, err, sys.exc_info()[2] + try: + self.tags = M4ATags(atoms, fileobj) + except M4AMetadataError: + self.tags = None + except StandardError, err: + raise M4AMetadataError, err, sys.exc_info()[2] + finally: + fileobj.close() + + def add_tags(self): + self.tags = M4ATags() + + @staticmethod + def score(filename, fileobj, header): + return ("ftyp" in header) + ("mp4" in header) + + +Open = M4A + + +def delete(filename): + """Remove tags from a file.""" + + M4A(filename).delete() diff --git a/libs/mutagen/monkeysaudio.py b/libs/mutagen/monkeysaudio.py new file mode 100644 index 00000000..355749b9 --- /dev/null +++ b/libs/mutagen/monkeysaudio.py @@ -0,0 +1,84 @@ +# A Monkey's Audio (APE) reader/tagger +# +# Copyright 2006 Lukas Lalinsky +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +"""Monkey's Audio streams with APEv2 tags. + +Monkey's Audio is a very efficient lossless audio compressor developed +by Matt Ashland. + +For more information, see http://www.monkeysaudio.com/. +""" + +__all__ = ["MonkeysAudio", "Open", "delete"] + +import struct + +from mutagen.apev2 import APEv2File, error, delete +from mutagen._util import cdata + + +class MonkeysAudioHeaderError(error): + pass + + +class MonkeysAudioInfo(object): + """Monkey's Audio stream information. + + Attributes: + + * channels -- number of audio channels + * length -- file length in seconds, as a float + * sample_rate -- audio sampling rate in Hz + * bits_per_sample -- bits per sample + * version -- Monkey's Audio stream version, as a float (eg: 3.99) + """ + + def __init__(self, fileobj): + header = fileobj.read(76) + if len(header) != 76 or not header.startswith("MAC "): + raise MonkeysAudioHeaderError("not a Monkey's Audio file") + self.version = cdata.ushort_le(header[4:6]) + if self.version >= 3980: + (blocks_per_frame, final_frame_blocks, total_frames, + self.bits_per_sample, self.channels, + self.sample_rate) = struct.unpack("= 3950: + blocks_per_frame = 73728 * 4 + elif self.version >= 3900 or (self.version >= 3800 and + compression_level == 4): + blocks_per_frame = 73728 + else: + blocks_per_frame = 9216 + self.version /= 1000.0 + self.length = 0.0 + if self.sample_rate != 0 and total_frames > 0: + total_blocks = ((total_frames - 1) * blocks_per_frame + + final_frame_blocks) + self.length = float(total_blocks) / self.sample_rate + + def pprint(self): + return "Monkey's Audio %.2f, %.2f seconds, %d Hz" % ( + self.version, self.length, self.sample_rate) + + +class MonkeysAudio(APEv2File): + _Info = MonkeysAudioInfo + _mimes = ["audio/ape", "audio/x-ape"] + + @staticmethod + def score(filename, fileobj, header): + return header.startswith("MAC ") + filename.lower().endswith(".ape") + + +Open = MonkeysAudio diff --git a/libs/mutagen/mp3.py b/libs/mutagen/mp3.py new file mode 100644 index 00000000..2426610b --- /dev/null +++ b/libs/mutagen/mp3.py @@ -0,0 +1,275 @@ +# MP3 stream header information support for Mutagen. +# Copyright 2006 Joe Wreschnig +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of version 2 of the GNU General Public License as +# published by the Free Software Foundation. + +"""MPEG audio stream information and tags.""" + +import os +import struct + +from mutagen.id3 import ID3FileType, BitPaddedInt, delete + +__all__ = ["MP3", "Open", "delete", "MP3"] + + +class error(RuntimeError): + pass + + +class HeaderNotFoundError(error, IOError): + pass + + +class InvalidMPEGHeader(error, IOError): + pass + + +# Mode values. +STEREO, JOINTSTEREO, DUALCHANNEL, MONO = range(4) + + +class MPEGInfo(object): + """MPEG audio stream information + + Parse information about an MPEG audio file. This also reads the + Xing VBR header format. + + This code was implemented based on the format documentation at + http://mpgedit.org/mpgedit/mpeg_format/mpeghdr.htm. + + Useful attributes: + + * length -- audio length, in seconds + * bitrate -- audio bitrate, in bits per second + * sketchy -- if true, the file may not be valid MPEG audio + + Useless attributes: + + * version -- MPEG version (1, 2, 2.5) + * layer -- 1, 2, or 3 + * mode -- One of STEREO, JOINTSTEREO, DUALCHANNEL, or MONO (0-3) + * protected -- whether or not the file is "protected" + * padding -- whether or not audio frames are padded + * sample_rate -- audio sample rate, in Hz + """ + + # Map (version, layer) tuples to bitrates. + __BITRATE = { + (1, 1): range(0, 480, 32), + (1, 2): [0, 32, 48, 56, 64, 80, 96, 112, 128, + 160, 192, 224, 256, 320, 384], + (1, 3): [0, 32, 40, 48, 56, 64, 80, 96, 112, + 128, 160, 192, 224, 256, 320], + (2, 1): [0, 32, 48, 56, 64, 80, 96, 112, 128, + 144, 160, 176, 192, 224, 256], + (2, 2): [0, 8, 16, 24, 32, 40, 48, 56, 64, + 80, 96, 112, 128, 144, 160], + } + + __BITRATE[(2, 3)] = __BITRATE[(2, 2)] + for i in range(1, 4): + __BITRATE[(2.5, i)] = __BITRATE[(2, i)] + + # Map version to sample rates. + __RATES = { + 1: [44100, 48000, 32000], + 2: [22050, 24000, 16000], + 2.5: [11025, 12000, 8000] + } + + sketchy = False + + def __init__(self, fileobj, offset=None): + """Parse MPEG stream information from a file-like object. + + If an offset argument is given, it is used to start looking + for stream information and Xing headers; otherwise, ID3v2 tags + will be skipped automatically. A correct offset can make + loading files significantly faster. + """ + + try: + size = os.path.getsize(fileobj.name) + except (IOError, OSError, AttributeError): + fileobj.seek(0, 2) + size = fileobj.tell() + + # If we don't get an offset, try to skip an ID3v2 tag. + if offset is None: + fileobj.seek(0, 0) + idata = fileobj.read(10) + try: + id3, insize = struct.unpack('>3sxxx4s', idata) + except struct.error: + id3, insize = '', 0 + insize = BitPaddedInt(insize) + if id3 == 'ID3' and insize > 0: + offset = insize + 10 + else: + offset = 0 + + # Try to find two valid headers (meaning, very likely MPEG data) + # at the given offset, 30% through the file, 60% through the file, + # and 90% through the file. + for i in [offset, 0.3 * size, 0.6 * size, 0.9 * size]: + try: + self.__try(fileobj, int(i), size - offset) + except error: + pass + else: + break + # If we can't find any two consecutive frames, try to find just + # one frame back at the original offset given. + else: + self.__try(fileobj, offset, size - offset, False) + self.sketchy = True + + def __try(self, fileobj, offset, real_size, check_second=True): + # This is going to be one really long function; bear with it, + # because there's not really a sane point to cut it up. + fileobj.seek(offset, 0) + + # We "know" we have an MPEG file if we find two frames that look like + # valid MPEG data. If we can't find them in 32k of reads, something + # is horribly wrong (the longest frame can only be about 4k). This + # is assuming the offset didn't lie. + data = fileobj.read(32768) + + frame_1 = data.find("\xff") + while 0 <= frame_1 <= len(data) - 4: + frame_data = struct.unpack(">I", data[frame_1:frame_1 + 4])[0] + if (frame_data >> 16) & 0xE0 != 0xE0: + frame_1 = data.find("\xff", frame_1 + 2) + else: + version = (frame_data >> 19) & 0x3 + layer = (frame_data >> 17) & 0x3 + protection = (frame_data >> 16) & 0x1 + bitrate = (frame_data >> 12) & 0xF + sample_rate = (frame_data >> 10) & 0x3 + padding = (frame_data >> 9) & 0x1 + #private = (frame_data >> 8) & 0x1 + self.mode = (frame_data >> 6) & 0x3 + #mode_extension = (frame_data >> 4) & 0x3 + #copyright = (frame_data >> 3) & 0x1 + #original = (frame_data >> 2) & 0x1 + #emphasis = (frame_data >> 0) & 0x3 + if (version == 1 or layer == 0 or sample_rate == 0x3 or + bitrate == 0 or bitrate == 0xF): + frame_1 = data.find("\xff", frame_1 + 2) + else: + break + else: + raise HeaderNotFoundError("can't sync to an MPEG frame") + + # There is a serious problem here, which is that many flags + # in an MPEG header are backwards. + self.version = [2.5, None, 2, 1][version] + self.layer = 4 - layer + self.protected = not protection + self.padding = bool(padding) + + self.bitrate = self.__BITRATE[(self.version, self.layer)][bitrate] + self.bitrate *= 1000 + self.sample_rate = self.__RATES[self.version][sample_rate] + + if self.layer == 1: + frame_length = (12 * self.bitrate / self.sample_rate + padding) * 4 + frame_size = 384 + elif self.version >= 2 and self.layer == 3: + frame_length = 72 * self.bitrate / self.sample_rate + padding + frame_size = 576 + else: + frame_length = 144 * self.bitrate / self.sample_rate + padding + frame_size = 1152 + + if check_second: + possible = frame_1 + frame_length + if possible > len(data) + 4: + raise HeaderNotFoundError("can't sync to second MPEG frame") + try: + frame_data = struct.unpack( + ">H", data[possible:possible + 2])[0] + except struct.error: + raise HeaderNotFoundError("can't sync to second MPEG frame") + if frame_data & 0xFFE0 != 0xFFE0: + raise HeaderNotFoundError("can't sync to second MPEG frame") + + self.length = 8 * real_size / float(self.bitrate) + + # Try to find/parse the Xing header, which trumps the above length + # and bitrate calculation. + fileobj.seek(offset, 0) + data = fileobj.read(32768) + try: + xing = data[:-4].index("Xing") + except ValueError: + # Try to find/parse the VBRI header, which trumps the above length + # calculation. + try: + vbri = data[:-24].index("VBRI") + except ValueError: + pass + else: + # If a VBRI header was found, this is definitely MPEG audio. + self.sketchy = False + vbri_version = struct.unpack('>H', data[vbri + 4:vbri + 6])[0] + if vbri_version == 1: + frame_count = struct.unpack( + '>I', data[vbri + 14:vbri + 18])[0] + samples = float(frame_size * frame_count) + self.length = (samples / self.sample_rate) or self.length + else: + # If a Xing header was found, this is definitely MPEG audio. + self.sketchy = False + flags = struct.unpack('>I', data[xing + 4:xing + 8])[0] + if flags & 0x1: + frame_count = struct.unpack('>I', data[xing + 8:xing + 12])[0] + samples = float(frame_size * frame_count) + self.length = (samples / self.sample_rate) or self.length + if flags & 0x2: + bytes = struct.unpack('>I', data[xing + 12:xing + 16])[0] + self.bitrate = int((bytes * 8) // self.length) + + def pprint(self): + s = "MPEG %s layer %d, %d bps, %s Hz, %.2f seconds" % ( + self.version, self.layer, self.bitrate, self.sample_rate, + self.length) + if self.sketchy: + s += " (sketchy)" + return s + + +class MP3(ID3FileType): + """An MPEG audio (usually MPEG-1 Layer 3) file. + + :ivar info: :class:`MPEGInfo` + :ivar tags: :class:`ID3 ` + """ + + _Info = MPEGInfo + _mimes = ["audio/mp3", "audio/x-mp3", "audio/mpeg", "audio/mpg", + "audio/x-mpeg"] + + @staticmethod + def score(filename, fileobj, header): + filename = filename.lower() + return (header.startswith("ID3") * 2 + filename.endswith(".mp3") + + filename.endswith(".mp2") + filename.endswith(".mpg") + + filename.endswith(".mpeg")) + + +Open = MP3 + + +class EasyMP3(MP3): + """Like MP3, but uses EasyID3 for tags. + + :ivar info: :class:`MPEGInfo` + :ivar tags: :class:`EasyID3 ` + """ + + from mutagen.easyid3 import EasyID3 as ID3 + ID3 = ID3 diff --git a/libs/mutagen/mp4.py b/libs/mutagen/mp4.py new file mode 100644 index 00000000..984a38c4 --- /dev/null +++ b/libs/mutagen/mp4.py @@ -0,0 +1,822 @@ +# Copyright 2006 Joe Wreschnig +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +"""Read and write MPEG-4 audio files with iTunes metadata. + +This module will read MPEG-4 audio information and metadata, +as found in Apple's MP4 (aka M4A, M4B, M4P) files. + +There is no official specification for this format. The source code +for TagLib, FAAD, and various MPEG specifications at + +* http://developer.apple.com/documentation/QuickTime/QTFF/ +* http://www.geocities.com/xhelmboyx/quicktime/formats/mp4-layout.txt +* http://standards.iso.org/ittf/PubliclyAvailableStandards/\ +c041828_ISO_IEC_14496-12_2005(E).zip +* http://wiki.multimedia.cx/index.php?title=Apple_QuickTime + +were all consulted. +""" + +import struct +import sys + +from mutagen import FileType, Metadata +from mutagen._constants import GENRES +from mutagen._util import cdata, insert_bytes, DictProxy, utf8 + + +class error(IOError): + pass + + +class MP4MetadataError(error): + pass + + +class MP4StreamInfoError(error): + pass + + +class MP4MetadataValueError(ValueError, MP4MetadataError): + pass + + +# This is not an exhaustive list of container atoms, but just the +# ones this module needs to peek inside. +_CONTAINERS = ["moov", "udta", "trak", "mdia", "meta", "ilst", + "stbl", "minf", "moof", "traf"] +_SKIP_SIZE = {"meta": 4} + +__all__ = ['MP4', 'Open', 'delete', 'MP4Cover', 'MP4FreeForm'] + + +class MP4Cover(str): + """A cover artwork. + + Attributes: + + * imageformat -- format of the image (either FORMAT_JPEG or FORMAT_PNG) + """ + FORMAT_JPEG = 0x0D + FORMAT_PNG = 0x0E + + def __new__(cls, data, *args, **kwargs): + return str.__new__(cls, data) + + def __init__(self, data, imageformat=FORMAT_JPEG): + self.imageformat = imageformat + try: + self.format + except AttributeError: + self.format = imageformat + + +class MP4FreeForm(str): + """A freeform value. + + Attributes: + + * dataformat -- format of the data (either FORMAT_TEXT or FORMAT_DATA) + """ + + FORMAT_DATA = 0x0 + FORMAT_TEXT = 0x1 + + def __new__(cls, data, *args, **kwargs): + return str.__new__(cls, data) + + def __init__(self, data, dataformat=FORMAT_TEXT): + self.dataformat = dataformat + + +class Atom(object): + """An individual atom. + + Attributes: + children -- list child atoms (or None for non-container atoms) + length -- length of this atom, including length and name + name -- four byte name of the atom, as a str + offset -- location in the constructor-given fileobj of this atom + + This structure should only be used internally by Mutagen. + """ + + children = None + + def __init__(self, fileobj, level=0): + self.offset = fileobj.tell() + self.length, self.name = struct.unpack(">I4s", fileobj.read(8)) + if self.length == 1: + self.length, = struct.unpack(">Q", fileobj.read(8)) + if self.length < 16: + raise MP4MetadataError( + "64 bit atom length can only be 16 and higher") + elif self.length == 0: + if level != 0: + raise MP4MetadataError( + "only a top-level atom can have zero length") + # Only the last atom is supposed to have a zero-length, meaning it + # extends to the end of file. + fileobj.seek(0, 2) + self.length = fileobj.tell() - self.offset + fileobj.seek(self.offset + 8, 0) + elif self.length < 8: + raise MP4MetadataError( + "atom length can only be 0, 1 or 8 and higher") + + if self.name in _CONTAINERS: + self.children = [] + fileobj.seek(_SKIP_SIZE.get(self.name, 0), 1) + while fileobj.tell() < self.offset + self.length: + self.children.append(Atom(fileobj, level + 1)) + else: + fileobj.seek(self.offset + self.length, 0) + + @staticmethod + def render(name, data): + """Render raw atom data.""" + # this raises OverflowError if Py_ssize_t can't handle the atom data + size = len(data) + 8 + if size <= 0xFFFFFFFF: + return struct.pack(">I4s", size, name) + data + else: + return struct.pack(">I4sQ", 1, name, size + 8) + data + + def findall(self, name, recursive=False): + """Recursively find all child atoms by specified name.""" + if self.children is not None: + for child in self.children: + if child.name == name: + yield child + if recursive: + for atom in child.findall(name, True): + yield atom + + def __getitem__(self, remaining): + """Look up a child atom, potentially recursively. + + e.g. atom['udta', 'meta'] => + """ + if not remaining: + return self + elif self.children is None: + raise KeyError("%r is not a container" % self.name) + for child in self.children: + if child.name == remaining[0]: + return child[remaining[1:]] + else: + raise KeyError("%r not found" % remaining[0]) + + def __repr__(self): + klass = self.__class__.__name__ + if self.children is None: + return "<%s name=%r length=%r offset=%r>" % ( + klass, self.name, self.length, self.offset) + else: + children = "\n".join([" " + line for child in self.children + for line in repr(child).splitlines()]) + return "<%s name=%r length=%r offset=%r\n%s>" % ( + klass, self.name, self.length, self.offset, children) + + +class Atoms(object): + """Root atoms in a given file. + + Attributes: + atoms -- a list of top-level atoms as Atom objects + + This structure should only be used internally by Mutagen. + """ + + def __init__(self, fileobj): + self.atoms = [] + fileobj.seek(0, 2) + end = fileobj.tell() + fileobj.seek(0) + while fileobj.tell() + 8 <= end: + self.atoms.append(Atom(fileobj)) + + def path(self, *names): + """Look up and return the complete path of an atom. + + For example, atoms.path('moov', 'udta', 'meta') will return a + list of three atoms, corresponding to the moov, udta, and meta + atoms. + """ + + path = [self] + for name in names: + path.append(path[-1][name, ]) + return path[1:] + + def __contains__(self, names): + try: + self[names] + except KeyError: + return False + return True + + def __getitem__(self, names): + """Look up a child atom. + + 'names' may be a list of atoms (['moov', 'udta']) or a string + specifying the complete path ('moov.udta'). + """ + + if isinstance(names, basestring): + names = names.split(".") + for child in self.atoms: + if child.name == names[0]: + return child[names[1:]] + else: + raise KeyError("%s not found" % names[0]) + + def __repr__(self): + return "\n".join([repr(child) for child in self.atoms]) + + +class MP4Tags(DictProxy, Metadata): + r"""Dictionary containing Apple iTunes metadata list key/values. + + Keys are four byte identifiers, except for freeform ('----') + keys. Values are usually unicode strings, but some atoms have a + special structure: + + Text values (multiple values per key are supported): + + * '\\xa9nam' -- track title + * '\\xa9alb' -- album + * '\\xa9ART' -- artist + * 'aART' -- album artist + * '\\xa9wrt' -- composer + * '\\xa9day' -- year + * '\\xa9cmt' -- comment + * 'desc' -- description (usually used in podcasts) + * 'purd' -- purchase date + * '\\xa9grp' -- grouping + * '\\xa9gen' -- genre + * '\\xa9lyr' -- lyrics + * 'purl' -- podcast URL + * 'egid' -- podcast episode GUID + * 'catg' -- podcast category + * 'keyw' -- podcast keywords + * '\\xa9too' -- encoded by + * 'cprt' -- copyright + * 'soal' -- album sort order + * 'soaa' -- album artist sort order + * 'soar' -- artist sort order + * 'sonm' -- title sort order + * 'soco' -- composer sort order + * 'sosn' -- show sort order + * 'tvsh' -- show name + + Boolean values: + + * 'cpil' -- part of a compilation + * 'pgap' -- part of a gapless album + * 'pcst' -- podcast (iTunes reads this only on import) + + Tuples of ints (multiple values per key are supported): + + * 'trkn' -- track number, total tracks + * 'disk' -- disc number, total discs + + Others: + + * 'tmpo' -- tempo/BPM, 16 bit int + * 'covr' -- cover artwork, list of MP4Cover objects (which are + tagged strs) + * 'gnre' -- ID3v1 genre. Not supported, use '\\xa9gen' instead. + + The freeform '----' frames use a key in the format '----:mean:name' + where 'mean' is usually 'com.apple.iTunes' and 'name' is a unique + identifier for this frame. The value is a str, but is probably + text that can be decoded as UTF-8. Multiple values per key are + supported. + + MP4 tag data cannot exist outside of the structure of an MP4 file, + so this class should not be manually instantiated. + + Unknown non-text tags are removed. + """ + + def load(self, atoms, fileobj): + try: + ilst = atoms["moov.udta.meta.ilst"] + except KeyError, key: + raise MP4MetadataError(key) + for atom in ilst.children: + fileobj.seek(atom.offset + 8) + data = fileobj.read(atom.length - 8) + if len(data) != atom.length - 8: + raise MP4MetadataError("Not enough data") + + if atom.name in self.__atoms: + info = self.__atoms[atom.name] + info[0](self, atom, data, *info[2:]) + else: + # unknown atom, try as text and skip if it fails + # FIXME: keep them somehow + try: + self.__parse_text(atom, data) + except MP4MetadataError: + continue + + @classmethod + def _can_load(cls, atoms): + return "moov.udta.meta.ilst" in atoms + + @staticmethod + def __key_sort(item1, item2): + (key1, v1) = item1 + (key2, v2) = item2 + # iTunes always writes the tags in order of "relevance", try + # to copy it as closely as possible. + order = ["\xa9nam", "\xa9ART", "\xa9wrt", "\xa9alb", + "\xa9gen", "gnre", "trkn", "disk", + "\xa9day", "cpil", "pgap", "pcst", "tmpo", + "\xa9too", "----", "covr", "\xa9lyr"] + order = dict(zip(order, range(len(order)))) + last = len(order) + # If there's no key-based way to distinguish, order by length. + # If there's still no way, go by string comparison on the + # values, so we at least have something determinstic. + return (cmp(order.get(key1[:4], last), order.get(key2[:4], last)) or + cmp(len(v1), len(v2)) or cmp(v1, v2)) + + def save(self, filename): + """Save the metadata to the given filename.""" + values = [] + items = self.items() + items.sort(self.__key_sort) + for key, value in items: + info = self.__atoms.get(key[:4], (None, type(self).__render_text)) + try: + values.append(info[1](self, key, value, *info[2:])) + except (TypeError, ValueError), s: + raise MP4MetadataValueError, s, sys.exc_info()[2] + data = Atom.render("ilst", "".join(values)) + + # Find the old atoms. + fileobj = open(filename, "rb+") + try: + atoms = Atoms(fileobj) + try: + path = atoms.path("moov", "udta", "meta", "ilst") + except KeyError: + self.__save_new(fileobj, atoms, data) + else: + self.__save_existing(fileobj, atoms, path, data) + finally: + fileobj.close() + + def __pad_ilst(self, data, length=None): + if length is None: + length = ((len(data) + 1023) & ~1023) - len(data) + return Atom.render("free", "\x00" * length) + + def __save_new(self, fileobj, atoms, ilst): + hdlr = Atom.render("hdlr", "\x00" * 8 + "mdirappl" + "\x00" * 9) + meta = Atom.render( + "meta", "\x00\x00\x00\x00" + hdlr + ilst + self.__pad_ilst(ilst)) + try: + path = atoms.path("moov", "udta") + except KeyError: + # moov.udta not found -- create one + path = atoms.path("moov") + meta = Atom.render("udta", meta) + offset = path[-1].offset + 8 + insert_bytes(fileobj, len(meta), offset) + fileobj.seek(offset) + fileobj.write(meta) + self.__update_parents(fileobj, path, len(meta)) + self.__update_offsets(fileobj, atoms, len(meta), offset) + + def __save_existing(self, fileobj, atoms, path, data): + # Replace the old ilst atom. + ilst = path.pop() + offset = ilst.offset + length = ilst.length + + # Check for padding "free" atoms + meta = path[-1] + index = meta.children.index(ilst) + try: + prev = meta.children[index-1] + if prev.name == "free": + offset = prev.offset + length += prev.length + except IndexError: + pass + try: + next = meta.children[index+1] + if next.name == "free": + length += next.length + except IndexError: + pass + + delta = len(data) - length + if delta > 0 or (delta < 0 and delta > -8): + data += self.__pad_ilst(data) + delta = len(data) - length + insert_bytes(fileobj, delta, offset) + elif delta < 0: + data += self.__pad_ilst(data, -delta - 8) + delta = 0 + + fileobj.seek(offset) + fileobj.write(data) + self.__update_parents(fileobj, path, delta) + self.__update_offsets(fileobj, atoms, delta, offset) + + def __update_parents(self, fileobj, path, delta): + """Update all parent atoms with the new size.""" + for atom in path: + fileobj.seek(atom.offset) + size = cdata.uint_be(fileobj.read(4)) + if size == 1: # 64bit + # skip name (4B) and read size (8B) + size = cdata.ulonglong_be(fileobj.read(12)[4:]) + fileobj.seek(atom.offset + 8) + fileobj.write(cdata.to_ulonglong_be(size + delta)) + else: # 32bit + fileobj.seek(atom.offset) + fileobj.write(cdata.to_uint_be(size + delta)) + + def __update_offset_table(self, fileobj, fmt, atom, delta, offset): + """Update offset table in the specified atom.""" + if atom.offset > offset: + atom.offset += delta + fileobj.seek(atom.offset + 12) + data = fileobj.read(atom.length - 12) + fmt = fmt % cdata.uint_be(data[:4]) + offsets = struct.unpack(fmt, data[4:]) + offsets = [o + (0, delta)[offset < o] for o in offsets] + fileobj.seek(atom.offset + 16) + fileobj.write(struct.pack(fmt, *offsets)) + + def __update_tfhd(self, fileobj, atom, delta, offset): + if atom.offset > offset: + atom.offset += delta + fileobj.seek(atom.offset + 9) + data = fileobj.read(atom.length - 9) + flags = cdata.uint_be("\x00" + data[:3]) + if flags & 1: + o = cdata.ulonglong_be(data[7:15]) + if o > offset: + o += delta + fileobj.seek(atom.offset + 16) + fileobj.write(cdata.to_ulonglong_be(o)) + + def __update_offsets(self, fileobj, atoms, delta, offset): + """Update offset tables in all 'stco' and 'co64' atoms.""" + if delta == 0: + return + moov = atoms["moov"] + for atom in moov.findall('stco', True): + self.__update_offset_table(fileobj, ">%dI", atom, delta, offset) + for atom in moov.findall('co64', True): + self.__update_offset_table(fileobj, ">%dQ", atom, delta, offset) + try: + for atom in atoms["moof"].findall('tfhd', True): + self.__update_tfhd(fileobj, atom, delta, offset) + except KeyError: + pass + + def __parse_data(self, atom, data): + pos = 0 + while pos < atom.length - 8: + length, name, flags = struct.unpack(">I4sI", data[pos:pos+12]) + if name != "data": + raise MP4MetadataError( + "unexpected atom %r inside %r" % (name, atom.name)) + yield flags, data[pos+16:pos+length] + pos += length + + def __render_data(self, key, flags, value): + return Atom.render(key, "".join([ + Atom.render("data", struct.pack(">2I", flags, 0) + data) + for data in value])) + + def __parse_freeform(self, atom, data): + length = cdata.uint_be(data[:4]) + mean = data[12:length] + pos = length + length = cdata.uint_be(data[pos:pos+4]) + name = data[pos+12:pos+length] + pos += length + value = [] + while pos < atom.length - 8: + length, atom_name = struct.unpack(">I4s", data[pos:pos+8]) + if atom_name != "data": + raise MP4MetadataError( + "unexpected atom %r inside %r" % (atom_name, atom.name)) + + version = ord(data[pos+8]) + if version != 0: + raise MP4MetadataError("Unsupported version: %r" % version) + + flags = struct.unpack(">I", "\x00" + data[pos+9:pos+12])[0] + value.append(MP4FreeForm(data[pos+16:pos+length], + dataformat=flags)) + pos += length + if value: + self["%s:%s:%s" % (atom.name, mean, name)] = value + + def __render_freeform(self, key, value): + dummy, mean, name = key.split(":", 2) + mean = struct.pack(">I4sI", len(mean) + 12, "mean", 0) + mean + name = struct.pack(">I4sI", len(name) + 12, "name", 0) + name + if isinstance(value, basestring): + value = [value] + data = "" + for v in value: + flags = MP4FreeForm.FORMAT_TEXT + if isinstance(v, MP4FreeForm): + flags = v.dataformat + data += struct.pack(">I4s2I", len(v) + 16, "data", flags, 0) + data += v + return Atom.render("----", mean + name + data) + + def __parse_pair(self, atom, data): + self[atom.name] = [struct.unpack(">2H", d[2:6]) for + flags, d in self.__parse_data(atom, data)] + + def __render_pair(self, key, value): + data = [] + for (track, total) in value: + if 0 <= track < 1 << 16 and 0 <= total < 1 << 16: + data.append(struct.pack(">4H", 0, track, total, 0)) + else: + raise MP4MetadataValueError( + "invalid numeric pair %r" % ((track, total),)) + return self.__render_data(key, 0, data) + + def __render_pair_no_trailing(self, key, value): + data = [] + for (track, total) in value: + if 0 <= track < 1 << 16 and 0 <= total < 1 << 16: + data.append(struct.pack(">3H", 0, track, total)) + else: + raise MP4MetadataValueError( + "invalid numeric pair %r" % ((track, total),)) + return self.__render_data(key, 0, data) + + def __parse_genre(self, atom, data): + # Translate to a freeform genre. + genre = cdata.short_be(data[16:18]) + if "\xa9gen" not in self: + try: + self["\xa9gen"] = [GENRES[genre - 1]] + except IndexError: + pass + + def __parse_tempo(self, atom, data): + self[atom.name] = [cdata.ushort_be(value[1]) for + value in self.__parse_data(atom, data)] + + def __render_tempo(self, key, value): + try: + if len(value) == 0: + return self.__render_data(key, 0x15, "") + + if min(value) < 0 or max(value) >= 2**16: + raise MP4MetadataValueError( + "invalid 16 bit integers: %r" % value) + except TypeError: + raise MP4MetadataValueError( + "tmpo must be a list of 16 bit integers") + + values = map(cdata.to_ushort_be, value) + return self.__render_data(key, 0x15, values) + + def __parse_bool(self, atom, data): + try: + self[atom.name] = bool(ord(data[16:17])) + except TypeError: + self[atom.name] = False + + def __render_bool(self, key, value): + return self.__render_data(key, 0x15, [chr(bool(value))]) + + def __parse_cover(self, atom, data): + self[atom.name] = [] + pos = 0 + while pos < atom.length - 8: + length, name, imageformat = struct.unpack(">I4sI", + data[pos:pos+12]) + if name != "data": + if name == "name": + pos += length + continue + raise MP4MetadataError( + "unexpected atom %r inside 'covr'" % name) + if imageformat not in (MP4Cover.FORMAT_JPEG, MP4Cover.FORMAT_PNG): + imageformat = MP4Cover.FORMAT_JPEG + cover = MP4Cover(data[pos+16:pos+length], imageformat) + self[atom.name].append(cover) + pos += length + + def __render_cover(self, key, value): + atom_data = [] + for cover in value: + try: + imageformat = cover.imageformat + except AttributeError: + imageformat = MP4Cover.FORMAT_JPEG + atom_data.append(Atom.render( + "data", struct.pack(">2I", imageformat, 0) + cover)) + return Atom.render(key, "".join(atom_data)) + + def __parse_text(self, atom, data, expected_flags=1): + value = [text.decode('utf-8', 'replace') for flags, text + in self.__parse_data(atom, data) + if flags == expected_flags] + if value: + self[atom.name] = value + + def __render_text(self, key, value, flags=1): + if isinstance(value, basestring): + value = [value] + return self.__render_data( + key, flags, map(utf8, value)) + + def delete(self, filename): + """Remove the metadata from the given filename.""" + + self.clear() + self.save(filename) + + __atoms = { + "----": (__parse_freeform, __render_freeform), + "trkn": (__parse_pair, __render_pair), + "disk": (__parse_pair, __render_pair_no_trailing), + "gnre": (__parse_genre, None), + "tmpo": (__parse_tempo, __render_tempo), + "cpil": (__parse_bool, __render_bool), + "pgap": (__parse_bool, __render_bool), + "pcst": (__parse_bool, __render_bool), + "covr": (__parse_cover, __render_cover), + "purl": (__parse_text, __render_text, 0), + "egid": (__parse_text, __render_text, 0), + } + + # the text atoms we know about which should make loading fail if parsing + # any of them fails + for name in ["\xa9nam", "\xa9alb", "\xa9ART", "aART", "\xa9wrt", "\xa9day", + "\xa9cmt", "desc", "purd", "\xa9grp", "\xa9gen", "\xa9lyr", + "catg", "keyw", "\xa9too", "cprt", "soal", "soaa", "soar", + "sonm", "soco", "sosn", "tvsh"]: + __atoms[name] = (__parse_text, __render_text) + + def pprint(self): + values = [] + for key, value in self.iteritems(): + key = key.decode('latin1') + if key == "covr": + values.append("%s=%s" % (key, ", ".join( + ["[%d bytes of data]" % len(data) for data in value]))) + elif isinstance(value, list): + values.append("%s=%s" % (key, " / ".join(map(unicode, value)))) + else: + values.append("%s=%s" % (key, value)) + return "\n".join(values) + + +class MP4Info(object): + """MPEG-4 stream information. + + Attributes: + + * bitrate -- bitrate in bits per second, as an int + * length -- file length in seconds, as a float + * channels -- number of audio channels + * sample_rate -- audio sampling rate in Hz + * bits_per_sample -- bits per sample + """ + + bitrate = 0 + channels = 0 + sample_rate = 0 + bits_per_sample = 0 + + def __init__(self, atoms, fileobj): + for trak in list(atoms["moov"].findall("trak")): + hdlr = trak["mdia", "hdlr"] + fileobj.seek(hdlr.offset) + data = fileobj.read(hdlr.length) + if data[16:20] == "soun": + break + else: + raise MP4StreamInfoError("track has no audio data") + + mdhd = trak["mdia", "mdhd"] + fileobj.seek(mdhd.offset) + data = fileobj.read(mdhd.length) + if ord(data[8]) == 0: + offset = 20 + fmt = ">2I" + else: + offset = 28 + fmt = ">IQ" + end = offset + struct.calcsize(fmt) + unit, length = struct.unpack(fmt, data[offset:end]) + self.length = float(length) / unit + + try: + atom = trak["mdia", "minf", "stbl", "stsd"] + fileobj.seek(atom.offset) + data = fileobj.read(atom.length) + if data[20:24] == "mp4a": + length = cdata.uint_be(data[16:20]) + (self.channels, self.bits_per_sample, _, + self.sample_rate) = struct.unpack(">3HI", data[40:50]) + # ES descriptor type + if data[56:60] == "esds" and ord(data[64:65]) == 0x03: + pos = 65 + # skip extended descriptor type tag, length, ES ID + # and stream priority + if data[pos:pos+3] == "\x80\x80\x80": + pos += 3 + pos += 4 + # decoder config descriptor type + if ord(data[pos]) == 0x04: + pos += 1 + # skip extended descriptor type tag, length, + # object type ID, stream type, buffer size + # and maximum bitrate + if data[pos:pos+3] == "\x80\x80\x80": + pos += 3 + pos += 10 + # average bitrate + self.bitrate = cdata.uint_be(data[pos:pos+4]) + except (ValueError, KeyError): + # stsd atoms are optional + pass + + def pprint(self): + return "MPEG-4 audio, %.2f seconds, %d bps" % ( + self.length, self.bitrate) + + +class MP4(FileType): + """An MPEG-4 audio file, probably containing AAC. + + If more than one track is present in the file, the first is used. + Only audio ('soun') tracks will be read. + + :ivar info: :class:`MP4Info` + :ivar tags: :class:`MP4Tags` + """ + + MP4Tags = MP4Tags + + _mimes = ["audio/mp4", "audio/x-m4a", "audio/mpeg4", "audio/aac"] + + def load(self, filename): + self.filename = filename + fileobj = open(filename, "rb") + try: + atoms = Atoms(fileobj) + + # ftyp is always the first atom in a valid MP4 file + if not atoms.atoms or atoms.atoms[0].name != "ftyp": + raise error("Not a MP4 file") + + try: + self.info = MP4Info(atoms, fileobj) + except StandardError, err: + raise MP4StreamInfoError, err, sys.exc_info()[2] + + if not MP4Tags._can_load(atoms): + self.tags = None + else: + try: + self.tags = self.MP4Tags(atoms, fileobj) + except StandardError, err: + raise MP4MetadataError, err, sys.exc_info()[2] + finally: + fileobj.close() + + def add_tags(self): + if self.tags is None: + self.tags = self.MP4Tags() + else: + raise error("an MP4 tag already exists") + + @staticmethod + def score(filename, fileobj, header): + return ("ftyp" in header) + ("mp4" in header) + + +Open = MP4 + + +def delete(filename): + """Remove tags from a file.""" + + MP4(filename).delete() diff --git a/libs/mutagen/musepack.py b/libs/mutagen/musepack.py new file mode 100644 index 00000000..9804deb3 --- /dev/null +++ b/libs/mutagen/musepack.py @@ -0,0 +1,257 @@ +# A Musepack reader/tagger +# +# Copyright 2006 Lukas Lalinsky +# Copyright 2012 Christoph Reiter +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +"""Musepack audio streams with APEv2 tags. + +Musepack is an audio format originally based on the MPEG-1 Layer-2 +algorithms. Stream versions 4 through 7 are supported. + +For more information, see http://www.musepack.net/. +""" + +__all__ = ["Musepack", "Open", "delete"] + +import struct + +from mutagen.apev2 import APEv2File, error, delete +from mutagen.id3 import BitPaddedInt +from mutagen._util import cdata + + +class MusepackHeaderError(error): + pass + + +RATES = [44100, 48000, 37800, 32000] + + +def _parse_sv8_int(fileobj, limit=9): + """Reads (max limit) bytes from fileobj until the MSB is zero. + All 7 LSB will be merged to a big endian uint. + + Raises ValueError in case not MSB is zero, or EOFError in + case the file ended before limit is reached. + + Returns (parsed number, number of bytes read) + """ + + num = 0 + for i in xrange(limit): + c = fileobj.read(1) + if len(c) != 1: + raise EOFError + num = (num << 7) | (ord(c) & 0x7F) + if not ord(c) & 0x80: + return num, i + 1 + if limit > 0: + raise ValueError + return 0, 0 + + +def _calc_sv8_gain(gain): + # 64.82 taken from mpcdec + return 64.82 - gain / 256.0 + + +def _calc_sv8_peak(peak): + return (10 ** (peak / (256.0 * 20.0)) / 65535.0) + + +class MusepackInfo(object): + """Musepack stream information. + + Attributes: + + * channels -- number of audio channels + * length -- file length in seconds, as a float + * sample_rate -- audio sampling rate in Hz + * bitrate -- audio bitrate, in bits per second + * version -- Musepack stream version + + Optional Attributes: + + * title_gain, title_peak -- Replay Gain and peak data for this song + * album_gain, album_peak -- Replay Gain and peak data for this album + + These attributes are only available in stream version 7/8. The + gains are a float, +/- some dB. The peaks are a percentage [0..1] of + the maximum amplitude. This means to get a number comparable to + VorbisGain, you must multiply the peak by 2. + """ + + def __init__(self, fileobj): + header = fileobj.read(4) + if len(header) != 4: + raise MusepackHeaderError("not a Musepack file") + + # Skip ID3v2 tags + if header[:3] == "ID3": + header = fileobj.read(6) + if len(header) != 6: + raise MusepackHeaderError("not a Musepack file") + size = 10 + BitPaddedInt(header[2:6]) + fileobj.seek(size) + header = fileobj.read(4) + if len(header) != 4: + raise MusepackHeaderError("not a Musepack file") + + if header.startswith("MPCK"): + self.__parse_sv8(fileobj) + else: + self.__parse_sv467(fileobj) + + if not self.bitrate and self.length != 0: + fileobj.seek(0, 2) + self.bitrate = int(round(fileobj.tell() * 8 / self.length)) + + def __parse_sv8(self, fileobj): + #SV8 http://trac.musepack.net/trac/wiki/SV8Specification + + key_size = 2 + mandatory_packets = ["SH", "RG"] + + def check_frame_key(key): + if len(frame_type) != key_size or not 'AA' <= frame_type <= 'ZZ': + raise MusepackHeaderError("Invalid frame key.") + + frame_type = fileobj.read(key_size) + check_frame_key(frame_type) + + while frame_type not in ("AP", "SE") and mandatory_packets: + try: + frame_size, slen = _parse_sv8_int(fileobj) + except (EOFError, ValueError): + raise MusepackHeaderError("Invalid packet size.") + data_size = frame_size - key_size - slen + + if frame_type == "SH": + mandatory_packets.remove(frame_type) + self.__parse_stream_header(fileobj, data_size) + elif frame_type == "RG": + mandatory_packets.remove(frame_type) + self.__parse_replaygain_packet(fileobj, data_size) + else: + fileobj.seek(data_size, 1) + + frame_type = fileobj.read(key_size) + check_frame_key(frame_type) + + if mandatory_packets: + raise MusepackHeaderError("Missing mandatory packets: %s." + % ", ".join(mandatory_packets)) + + self.length = float(self.samples) / self.sample_rate + self.bitrate = 0 + + def __parse_stream_header(self, fileobj, data_size): + fileobj.seek(4, 1) + try: + self.version = ord(fileobj.read(1)) + except TypeError: + raise MusepackHeaderError("SH packet ended unexpectedly.") + try: + samples, l1 = _parse_sv8_int(fileobj) + samples_skip, l2 = _parse_sv8_int(fileobj) + except (EOFError, ValueError): + raise MusepackHeaderError( + "SH packet: Invalid sample counts.") + left_size = data_size - 5 - l1 - l2 + if left_size != 2: + raise MusepackHeaderError("Invalid SH packet size.") + data = fileobj.read(left_size) + if len(data) != left_size: + raise MusepackHeaderError("SH packet ended unexpectedly.") + self.sample_rate = RATES[ord(data[-2]) >> 5] + self.channels = (ord(data[-1]) >> 4) + 1 + self.samples = samples - samples_skip + + def __parse_replaygain_packet(self, fileobj, data_size): + data = fileobj.read(data_size) + if data_size != 9: + raise MusepackHeaderError("Invalid RG packet size.") + if len(data) != data_size: + raise MusepackHeaderError("RG packet ended unexpectedly.") + title_gain = cdata.short_be(data[1:3]) + title_peak = cdata.short_be(data[3:5]) + album_gain = cdata.short_be(data[5:7]) + album_peak = cdata.short_be(data[7:9]) + if title_gain: + self.title_gain = _calc_sv8_gain(title_gain) + if title_peak: + self.title_peak = _calc_sv8_peak(title_peak) + if album_gain: + self.album_gain = _calc_sv8_gain(album_gain) + if album_peak: + self.album_peak = _calc_sv8_peak(album_peak) + + def __parse_sv467(self, fileobj): + fileobj.seek(-4, 1) + header = fileobj.read(32) + if len(header) != 32: + raise MusepackHeaderError("not a Musepack file") + + # SV7 + if header.startswith("MP+"): + self.version = ord(header[3]) & 0xF + if self.version < 7: + raise MusepackHeaderError("not a Musepack file") + frames = cdata.uint_le(header[4:8]) + flags = cdata.uint_le(header[8:12]) + + self.title_peak, self.title_gain = struct.unpack( + "> 16) & 0x0003] + self.bitrate = 0 + # SV4-SV6 + else: + header_dword = cdata.uint_le(header[0:4]) + self.version = (header_dword >> 11) & 0x03FF + if self.version < 4 or self.version > 6: + raise MusepackHeaderError("not a Musepack file") + self.bitrate = (header_dword >> 23) & 0x01FF + self.sample_rate = 44100 + if self.version >= 5: + frames = cdata.uint_le(header[4:8]) + else: + frames = cdata.ushort_le(header[6:8]) + if self.version < 6: + frames -= 1 + self.channels = 2 + self.length = float(frames * 1152 - 576) / self.sample_rate + + def pprint(self): + rg_data = [] + if hasattr(self, "title_gain"): + rg_data.append("%+0.2f (title)" % self.title_gain) + if hasattr(self, "album_gain"): + rg_data.append("%+0.2f (album)" % self.album_gain) + rg_data = (rg_data and ", Gain: " + ", ".join(rg_data)) or "" + + return "Musepack SV%d, %.2f seconds, %d Hz, %d bps%s" % ( + self.version, self.length, self.sample_rate, self.bitrate, rg_data) + + +class Musepack(APEv2File): + _Info = MusepackInfo + _mimes = ["audio/x-musepack", "audio/x-mpc"] + + @staticmethod + def score(filename, fileobj, header): + return (header.startswith("MP+") + header.startswith("MPCK") + + filename.lower().endswith(".mpc")) + + +Open = Musepack diff --git a/libs/mutagen/ogg.py b/libs/mutagen/ogg.py new file mode 100644 index 00000000..657eb7f7 --- /dev/null +++ b/libs/mutagen/ogg.py @@ -0,0 +1,507 @@ +# Copyright 2006 Joe Wreschnig +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +"""Read and write Ogg bitstreams and pages. + +This module reads and writes a subset of the Ogg bitstream format +version 0. It does *not* read or write Ogg Vorbis files! For that, +you should use mutagen.oggvorbis. + +This implementation is based on the RFC 3533 standard found at +http://www.xiph.org/ogg/doc/rfc3533.txt. +""" + +import struct +import sys +import zlib + +from cStringIO import StringIO + +from mutagen import FileType +from mutagen._util import cdata, insert_bytes, delete_bytes + + +class error(IOError): + """Ogg stream parsing errors.""" + + pass + + +class OggPage(object): + """A single Ogg page (not necessarily a single encoded packet). + + A page is a header of 26 bytes, followed by the length of the + data, followed by the data. + + The constructor is givin a file-like object pointing to the start + of an Ogg page. After the constructor is finished it is pointing + to the start of the next page. + + Attributes: + + * version -- stream structure version (currently always 0) + * position -- absolute stream position (default -1) + * serial -- logical stream serial number (default 0) + * sequence -- page sequence number within logical stream (default 0) + * offset -- offset this page was read from (default None) + * complete -- if the last packet on this page is complete (default True) + * packets -- list of raw packet data (default []) + + Note that if 'complete' is false, the next page's 'continued' + property must be true (so set both when constructing pages). + + If a file-like object is supplied to the constructor, the above + attributes will be filled in based on it. + """ + + version = 0 + __type_flags = 0 + position = 0L + serial = 0 + sequence = 0 + offset = None + complete = True + + def __init__(self, fileobj=None): + self.packets = [] + + if fileobj is None: + return + + self.offset = fileobj.tell() + + header = fileobj.read(27) + if len(header) == 0: + raise EOFError + + try: + (oggs, self.version, self.__type_flags, self.position, + self.serial, self.sequence, crc, segments) = struct.unpack( + "<4sBBqIIiB", header) + except struct.error: + raise error("unable to read full header; got %r" % header) + + if oggs != "OggS": + raise error("read %r, expected %r, at 0x%x" % ( + oggs, "OggS", fileobj.tell() - 27)) + + if self.version != 0: + raise error("version %r unsupported" % self.version) + + total = 0 + lacings = [] + lacing_bytes = fileobj.read(segments) + if len(lacing_bytes) != segments: + raise error("unable to read %r lacing bytes" % segments) + for c in map(ord, lacing_bytes): + total += c + if c < 255: + lacings.append(total) + total = 0 + if total: + lacings.append(total) + self.complete = False + + self.packets = map(fileobj.read, lacings) + if map(len, self.packets) != lacings: + raise error("unable to read full data") + + def __eq__(self, other): + """Two Ogg pages are the same if they write the same data.""" + try: + return (self.write() == other.write()) + except AttributeError: + return False + + __hash__ = object.__hash__ + + def __repr__(self): + attrs = ['version', 'position', 'serial', 'sequence', 'offset', + 'complete', 'continued', 'first', 'last'] + values = ["%s=%r" % (attr, getattr(self, attr)) for attr in attrs] + return "<%s %s, %d bytes in %d packets>" % ( + type(self).__name__, " ".join(values), sum(map(len, self.packets)), + len(self.packets)) + + def write(self): + """Return a string encoding of the page header and data. + + A ValueError is raised if the data is too big to fit in a + single page. + """ + + data = [ + struct.pack("<4sBBqIIi", "OggS", self.version, self.__type_flags, + self.position, self.serial, self.sequence, 0) + ] + + lacing_data = [] + for datum in self.packets: + quot, rem = divmod(len(datum), 255) + lacing_data.append("\xff" * quot + chr(rem)) + lacing_data = "".join(lacing_data) + if not self.complete and lacing_data.endswith("\x00"): + lacing_data = lacing_data[:-1] + data.append(chr(len(lacing_data))) + data.append(lacing_data) + data.extend(self.packets) + data = "".join(data) + + # Python's CRC is swapped relative to Ogg's needs. + # crc32 returns uint prior to py2.6 on some platforms, so force uint + crc = (~zlib.crc32(data.translate(cdata.bitswap), -1)) & 0xffffffff + # Although we're using to_uint_be, this actually makes the CRC + # a proper le integer, since Python's CRC is byteswapped. + crc = cdata.to_uint_be(crc).translate(cdata.bitswap) + data = data[:22] + crc + data[26:] + return data + + @property + def size(self): + """Total frame size.""" + + size = 27 # Initial header size + for datum in self.packets: + quot, rem = divmod(len(datum), 255) + size += quot + 1 + if not self.complete and rem == 0: + # Packet contains a multiple of 255 bytes and is not + # terminated, so we don't have a \x00 at the end. + size -= 1 + size += sum(map(len, self.packets)) + return size + + def __set_flag(self, bit, val): + mask = 1 << bit + if val: + self.__type_flags |= mask + else: + self.__type_flags &= ~mask + + continued = property( + lambda self: cdata.test_bit(self.__type_flags, 0), + lambda self, v: self.__set_flag(0, v), + doc="The first packet is continued from the previous page.") + + first = property( + lambda self: cdata.test_bit(self.__type_flags, 1), + lambda self, v: self.__set_flag(1, v), + doc="This is the first page of a logical bitstream.") + + last = property( + lambda self: cdata.test_bit(self.__type_flags, 2), + lambda self, v: self.__set_flag(2, v), + doc="This is the last page of a logical bitstream.") + + @classmethod + def renumber(klass, fileobj, serial, start): + """Renumber pages belonging to a specified logical stream. + + fileobj must be opened with mode r+b or w+b. + + Starting at page number 'start', renumber all pages belonging + to logical stream 'serial'. Other pages will be ignored. + + fileobj must point to the start of a valid Ogg page; any + occuring after it and part of the specified logical stream + will be numbered. No adjustment will be made to the data in + the pages nor the granule position; only the page number, and + so also the CRC. + + If an error occurs (e.g. non-Ogg data is found), fileobj will + be left pointing to the place in the stream the error occured, + but the invalid data will be left intact (since this function + does not change the total file size). + """ + + number = start + while True: + try: + page = OggPage(fileobj) + except EOFError: + break + else: + if page.serial != serial: + # Wrong stream, skip this page. + continue + # Changing the number can't change the page size, + # so seeking back based on the current size is safe. + fileobj.seek(-page.size, 1) + page.sequence = number + fileobj.write(page.write()) + fileobj.seek(page.offset + page.size, 0) + number += 1 + + @classmethod + def to_packets(klass, pages, strict=False): + """Construct a list of packet data from a list of Ogg pages. + + If strict is true, the first page must start a new packet, + and the last page must end the last packet. + """ + + serial = pages[0].serial + sequence = pages[0].sequence + packets = [] + + if strict: + if pages[0].continued: + raise ValueError("first packet is continued") + if not pages[-1].complete: + raise ValueError("last packet does not complete") + elif pages and pages[0].continued: + packets.append([""]) + + for page in pages: + if serial != page.serial: + raise ValueError("invalid serial number in %r" % page) + elif sequence != page.sequence: + raise ValueError("bad sequence number in %r" % page) + else: + sequence += 1 + + if page.continued: + packets[-1].append(page.packets[0]) + else: + packets.append([page.packets[0]]) + packets.extend([[p] for p in page.packets[1:]]) + + return ["".join(p) for p in packets] + + @classmethod + def from_packets(klass, packets, sequence=0, + default_size=4096, wiggle_room=2048): + """Construct a list of Ogg pages from a list of packet data. + + The algorithm will generate pages of approximately + default_size in size (rounded down to the nearest multiple of + 255). However, it will also allow pages to increase to + approximately default_size + wiggle_room if allowing the + wiggle room would finish a packet (only one packet will be + finished in this way per page; if the next packet would fit + into the wiggle room, it still starts on a new page). + + This method reduces packet fragmentation when packet sizes are + slightly larger than the default page size, while still + ensuring most pages are of the average size. + + Pages are numbered started at 'sequence'; other information is + uninitialized. + """ + + chunk_size = (default_size // 255) * 255 + + pages = [] + + page = OggPage() + page.sequence = sequence + + for packet in packets: + page.packets.append("") + while packet: + data, packet = packet[:chunk_size], packet[chunk_size:] + if page.size < default_size and len(page.packets) < 255: + page.packets[-1] += data + else: + # If we've put any packet data into this page yet, + # we need to mark it incomplete. However, we can + # also have just started this packet on an already + # full page, in which case, just start the new + # page with this packet. + if page.packets[-1]: + page.complete = False + if len(page.packets) == 1: + page.position = -1L + else: + page.packets.pop(-1) + pages.append(page) + page = OggPage() + page.continued = not pages[-1].complete + page.sequence = pages[-1].sequence + 1 + page.packets.append(data) + + if len(packet) < wiggle_room: + page.packets[-1] += packet + packet = "" + + if page.packets: + pages.append(page) + + return pages + + @classmethod + def replace(klass, fileobj, old_pages, new_pages): + """Replace old_pages with new_pages within fileobj. + + old_pages must have come from reading fileobj originally. + new_pages are assumed to have the 'same' data as old_pages, + and so the serial and sequence numbers will be copied, as will + the flags for the first and last pages. + + fileobj will be resized and pages renumbered as necessary. As + such, it must be opened r+b or w+b. + """ + + # Number the new pages starting from the first old page. + first = old_pages[0].sequence + for page, seq in zip(new_pages, range(first, first + len(new_pages))): + page.sequence = seq + page.serial = old_pages[0].serial + + new_pages[0].first = old_pages[0].first + new_pages[0].last = old_pages[0].last + new_pages[0].continued = old_pages[0].continued + + new_pages[-1].first = old_pages[-1].first + new_pages[-1].last = old_pages[-1].last + new_pages[-1].complete = old_pages[-1].complete + if not new_pages[-1].complete and len(new_pages[-1].packets) == 1: + new_pages[-1].position = -1L + + new_data = "".join(map(klass.write, new_pages)) + + # Make room in the file for the new data. + delta = len(new_data) + fileobj.seek(old_pages[0].offset, 0) + insert_bytes(fileobj, delta, old_pages[0].offset) + fileobj.seek(old_pages[0].offset, 0) + fileobj.write(new_data) + new_data_end = old_pages[0].offset + delta + + # Go through the old pages and delete them. Since we shifted + # the data down the file, we need to adjust their offsets. We + # also need to go backwards, so we don't adjust the deltas of + # the other pages. + old_pages.reverse() + for old_page in old_pages: + adj_offset = old_page.offset + delta + delete_bytes(fileobj, old_page.size, adj_offset) + + # Finally, if there's any discrepency in length, we need to + # renumber the pages for the logical stream. + if len(old_pages) != len(new_pages): + fileobj.seek(new_data_end, 0) + serial = new_pages[-1].serial + sequence = new_pages[-1].sequence + 1 + klass.renumber(fileobj, serial, sequence) + + @classmethod + def find_last(klass, fileobj, serial): + """Find the last page of the stream 'serial'. + + If the file is not multiplexed this function is fast. If it is, + it must read the whole the stream. + + This finds the last page in the actual file object, or the last + page in the stream (with eos set), whichever comes first. + """ + + # For non-muxed streams, look at the last page. + try: + fileobj.seek(-256*256, 2) + except IOError: + # The file is less than 64k in length. + fileobj.seek(0) + data = fileobj.read() + try: + index = data.rindex("OggS") + except ValueError: + raise error("unable to find final Ogg header") + stringobj = StringIO(data[index:]) + best_page = None + try: + page = OggPage(stringobj) + except error: + pass + else: + if page.serial == serial: + if page.last: + return page + else: + best_page = page + else: + best_page = None + + # The stream is muxed, so use the slow way. + fileobj.seek(0) + try: + page = OggPage(fileobj) + while not page.last: + page = OggPage(fileobj) + while page.serial != serial: + page = OggPage(fileobj) + best_page = page + return page + except error: + return best_page + except EOFError: + return best_page + + +class OggFileType(FileType): + """An generic Ogg file.""" + + _Info = None + _Tags = None + _Error = None + _mimes = ["application/ogg", "application/x-ogg"] + + def load(self, filename): + """Load file information from a filename.""" + + self.filename = filename + fileobj = open(filename, "rb") + try: + try: + self.info = self._Info(fileobj) + self.tags = self._Tags(fileobj, self.info) + self.info._post_tags(fileobj) + except error, e: + raise self._Error, e, sys.exc_info()[2] + except EOFError: + raise self._Error, "no appropriate stream found" + finally: + fileobj.close() + + def delete(self, filename=None): + """Remove tags from a file. + + If no filename is given, the one most recently loaded is used. + """ + + if filename is None: + filename = self.filename + + self.tags.clear() + fileobj = open(filename, "rb+") + try: + try: + self.tags._inject(fileobj) + except error, e: + raise self._Error, e, sys.exc_info()[2] + except EOFError: + raise self._Error, "no appropriate stream found" + finally: + fileobj.close() + + def save(self, filename=None): + """Save a tag to a file. + + If no filename is given, the one most recently loaded is used. + """ + + if filename is None: + filename = self.filename + fileobj = open(filename, "rb+") + try: + try: + self.tags._inject(fileobj) + except error, e: + raise self._Error, e, sys.exc_info()[2] + except EOFError: + raise self._Error, "no appropriate stream found" + finally: + fileobj.close() diff --git a/libs/mutagen/oggflac.py b/libs/mutagen/oggflac.py new file mode 100644 index 00000000..14ecec00 --- /dev/null +++ b/libs/mutagen/oggflac.py @@ -0,0 +1,147 @@ +# Ogg FLAC support. +# +# Copyright 2006 Joe Wreschnig +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +"""Read and write Ogg FLAC comments. + +This module handles FLAC files wrapped in an Ogg bitstream. The first +FLAC stream found is used. For 'naked' FLACs, see mutagen.flac. + +This module is based off the specification at +http://flac.sourceforge.net/ogg_mapping.html. +""" + +__all__ = ["OggFLAC", "Open", "delete"] + +import struct + +from cStringIO import StringIO + +from mutagen.flac import StreamInfo, VCFLACDict, StrictFileObject +from mutagen.ogg import OggPage, OggFileType, error as OggError + + +class error(OggError): + pass + + +class OggFLACHeaderError(error): + pass + + +class OggFLACStreamInfo(StreamInfo): + """Ogg FLAC general header and stream info. + + This encompasses the Ogg wrapper for the FLAC STREAMINFO metadata + block, as well as the Ogg codec setup that precedes it. + + Attributes (in addition to StreamInfo's): + + * packets -- number of metadata packets + * serial -- Ogg logical stream serial number + """ + + packets = 0 + serial = 0 + + def load(self, data): + # Ogg expects file objects that don't raise on read + if isinstance(data, StrictFileObject): + data = data._fileobj + + page = OggPage(data) + while not page.packets[0].startswith("\x7FFLAC"): + page = OggPage(data) + major, minor, self.packets, flac = struct.unpack( + ">BBH4s", page.packets[0][5:13]) + if flac != "fLaC": + raise OggFLACHeaderError("invalid FLAC marker (%r)" % flac) + elif (major, minor) != (1, 0): + raise OggFLACHeaderError( + "unknown mapping version: %d.%d" % (major, minor)) + self.serial = page.serial + + # Skip over the block header. + stringobj = StrictFileObject(StringIO(page.packets[0][17:])) + super(OggFLACStreamInfo, self).load(stringobj) + + def _post_tags(self, fileobj): + if self.length: + return + page = OggPage.find_last(fileobj, self.serial) + self.length = page.position / float(self.sample_rate) + + def pprint(self): + return "Ogg " + super(OggFLACStreamInfo, self).pprint() + + +class OggFLACVComment(VCFLACDict): + def load(self, data, info, errors='replace'): + # data should be pointing at the start of an Ogg page, after + # the first FLAC page. + pages = [] + complete = False + while not complete: + page = OggPage(data) + if page.serial == info.serial: + pages.append(page) + complete = page.complete or (len(page.packets) > 1) + comment = StringIO(OggPage.to_packets(pages)[0][4:]) + super(OggFLACVComment, self).load(comment, errors=errors) + + def _inject(self, fileobj): + """Write tag data into the FLAC Vorbis comment packet/page.""" + + # Ogg FLAC has no convenient data marker like Vorbis, but the + # second packet - and second page - must be the comment data. + fileobj.seek(0) + page = OggPage(fileobj) + while not page.packets[0].startswith("\x7FFLAC"): + page = OggPage(fileobj) + + first_page = page + while not (page.sequence == 1 and page.serial == first_page.serial): + page = OggPage(fileobj) + + old_pages = [page] + while not (old_pages[-1].complete or len(old_pages[-1].packets) > 1): + page = OggPage(fileobj) + if page.serial == first_page.serial: + old_pages.append(page) + + packets = OggPage.to_packets(old_pages, strict=False) + + # Set the new comment block. + data = self.write() + data = packets[0][0] + struct.pack(">I", len(data))[-3:] + data + packets[0] = data + + new_pages = OggPage.from_packets(packets, old_pages[0].sequence) + OggPage.replace(fileobj, old_pages, new_pages) + + +class OggFLAC(OggFileType): + """An Ogg FLAC file.""" + + _Info = OggFLACStreamInfo + _Tags = OggFLACVComment + _Error = OggFLACHeaderError + _mimes = ["audio/x-oggflac"] + + @staticmethod + def score(filename, fileobj, header): + return (header.startswith("OggS") * ( + ("FLAC" in header) + ("fLaC" in header))) + + +Open = OggFLAC + + +def delete(filename): + """Remove tags from a file.""" + + OggFLAC(filename).delete() diff --git a/libs/mutagen/oggopus.py b/libs/mutagen/oggopus.py new file mode 100644 index 00000000..6de44391 --- /dev/null +++ b/libs/mutagen/oggopus.py @@ -0,0 +1,125 @@ +# Copyright 2012 Christoph Reiter +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +"""Read and write Ogg Opus comments. + +This module handles Opus files wrapped in an Ogg bitstream. The +first Opus stream found is used. + +Based on http://tools.ietf.org/html/draft-terriberry-oggopus-01 +""" + +__all__ = ["OggOpus", "Open", "delete"] + +import struct + +from mutagen._vorbis import VCommentDict +from mutagen.ogg import OggPage, OggFileType, error as OggError + + +class error(OggError): + pass + + +class OggOpusHeaderError(error): + pass + + +class OggOpusInfo(object): + """Ogg Opus stream information. + + Attributes: + + * length - file length in seconds, as a float + * channels - number of channels + """ + + length = 0 + + def __init__(self, fileobj): + page = OggPage(fileobj) + while not page.packets[0].startswith("OpusHead"): + page = OggPage(fileobj) + + self.serial = page.serial + + if not page.first: + raise OggOpusHeaderError( + "page has ID header, but doesn't start a stream") + + (version, self.channels, pre_skip, orig_sample_rate, output_gain, + channel_map) = struct.unpack("> 4, version & 0xF + if major != 0: + raise OggOpusHeaderError("version %r unsupported" % major) + + def _post_tags(self, fileobj): + page = OggPage.find_last(fileobj, self.serial) + self.length = (page.position - self.__pre_skip) / float(48000) + + def pprint(self): + return "Ogg Opus, %.2f seconds" % (self.length) + + +class OggOpusVComment(VCommentDict): + """Opus comments embedded in an Ogg bitstream.""" + + def __get_comment_pages(self, fileobj, info): + # find the first tags page with the right serial + page = OggPage(fileobj) + while info.serial != page.serial or \ + not page.packets[0].startswith("OpusTags"): + page = OggPage(fileobj) + + # get all comment pages + pages = [page] + while not (pages[-1].complete or len(pages[-1].packets) > 1): + page = OggPage(fileobj) + if page.serial == pages[0].serial: + pages.append(page) + + return pages + + def __init__(self, fileobj, info): + pages = self.__get_comment_pages(fileobj, info) + data = OggPage.to_packets(pages)[0][8:] # Strip OpusTags + super(OggOpusVComment, self).__init__(data, framing=False) + + def _inject(self, fileobj): + fileobj.seek(0) + info = OggOpusInfo(fileobj) + old_pages = self.__get_comment_pages(fileobj, info) + + packets = OggPage.to_packets(old_pages) + packets[0] = "OpusTags" + self.write(framing=False) + new_pages = OggPage.from_packets(packets, old_pages[0].sequence) + OggPage.replace(fileobj, old_pages, new_pages) + + +class OggOpus(OggFileType): + """An Ogg Opus file.""" + + _Info = OggOpusInfo + _Tags = OggOpusVComment + _Error = OggOpusHeaderError + _mimes = ["audio/ogg", "audio/ogg; codecs=opus"] + + @staticmethod + def score(filename, fileobj, header): + return (header.startswith("OggS") * ("OpusHead" in header)) + + +Open = OggOpus + + +def delete(filename): + """Remove tags from a file.""" + + OggOpus(filename).delete() diff --git a/libs/mutagen/oggspeex.py b/libs/mutagen/oggspeex.py new file mode 100644 index 00000000..4f208521 --- /dev/null +++ b/libs/mutagen/oggspeex.py @@ -0,0 +1,137 @@ +# Ogg Speex support. +# +# Copyright 2006 Joe Wreschnig +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +"""Read and write Ogg Speex comments. + +This module handles Speex files wrapped in an Ogg bitstream. The +first Speex stream found is used. + +Read more about Ogg Speex at http://www.speex.org/. This module is +based on the specification at http://www.speex.org/manual2/node7.html +and clarifications after personal communication with Jean-Marc, +http://lists.xiph.org/pipermail/speex-dev/2006-July/004676.html. +""" + +__all__ = ["OggSpeex", "Open", "delete"] + +from mutagen._vorbis import VCommentDict +from mutagen.ogg import OggPage, OggFileType, error as OggError +from mutagen._util import cdata + + +class error(OggError): + pass + + +class OggSpeexHeaderError(error): + pass + + +class OggSpeexInfo(object): + """Ogg Speex stream information. + + Attributes: + + * bitrate - nominal bitrate in bits per second + * channels - number of channels + * length - file length in seconds, as a float + + The reference encoder does not set the bitrate; in this case, + the bitrate will be 0. + """ + + length = 0 + + def __init__(self, fileobj): + page = OggPage(fileobj) + while not page.packets[0].startswith("Speex "): + page = OggPage(fileobj) + if not page.first: + raise OggSpeexHeaderError( + "page has ID header, but doesn't start a stream") + self.sample_rate = cdata.uint_le(page.packets[0][36:40]) + self.channels = cdata.uint_le(page.packets[0][48:52]) + self.bitrate = max(0, cdata.int_le(page.packets[0][52:56])) + self.serial = page.serial + + def _post_tags(self, fileobj): + page = OggPage.find_last(fileobj, self.serial) + self.length = page.position / float(self.sample_rate) + + def pprint(self): + return "Ogg Speex, %.2f seconds" % self.length + + +class OggSpeexVComment(VCommentDict): + """Speex comments embedded in an Ogg bitstream.""" + + def __init__(self, fileobj, info): + pages = [] + complete = False + while not complete: + page = OggPage(fileobj) + if page.serial == info.serial: + pages.append(page) + complete = page.complete or (len(page.packets) > 1) + data = OggPage.to_packets(pages)[0] + "\x01" + super(OggSpeexVComment, self).__init__(data, framing=False) + + def _inject(self, fileobj): + """Write tag data into the Speex comment packet/page.""" + + fileobj.seek(0) + + # Find the first header page, with the stream info. + # Use it to get the serial number. + page = OggPage(fileobj) + while not page.packets[0].startswith("Speex "): + page = OggPage(fileobj) + + # Look for the next page with that serial number, it'll start + # the comment packet. + serial = page.serial + page = OggPage(fileobj) + while page.serial != serial: + page = OggPage(fileobj) + + # Then find all the pages with the comment packet. + old_pages = [page] + while not (old_pages[-1].complete or len(old_pages[-1].packets) > 1): + page = OggPage(fileobj) + if page.serial == old_pages[0].serial: + old_pages.append(page) + + packets = OggPage.to_packets(old_pages, strict=False) + + # Set the new comment packet. + packets[0] = self.write(framing=False) + + new_pages = OggPage.from_packets(packets, old_pages[0].sequence) + OggPage.replace(fileobj, old_pages, new_pages) + + +class OggSpeex(OggFileType): + """An Ogg Speex file.""" + + _Info = OggSpeexInfo + _Tags = OggSpeexVComment + _Error = OggSpeexHeaderError + _mimes = ["audio/x-speex"] + + @staticmethod + def score(filename, fileobj, header): + return (header.startswith("OggS") * ("Speex " in header)) + + +Open = OggSpeex + + +def delete(filename): + """Remove tags from a file.""" + + OggSpeex(filename).delete() diff --git a/libs/mutagen/oggtheora.py b/libs/mutagen/oggtheora.py new file mode 100644 index 00000000..edf221a7 --- /dev/null +++ b/libs/mutagen/oggtheora.py @@ -0,0 +1,130 @@ +# Ogg Theora support. +# +# Copyright 2006 Joe Wreschnig +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +"""Read and write Ogg Theora comments. + +This module handles Theora files wrapped in an Ogg bitstream. The +first Theora stream found is used. + +Based on the specification at http://theora.org/doc/Theora_I_spec.pdf. +""" + +__all__ = ["OggTheora", "Open", "delete"] + +import struct + +from mutagen._vorbis import VCommentDict +from mutagen._util import cdata +from mutagen.ogg import OggPage, OggFileType, error as OggError + + +class error(OggError): + pass + + +class OggTheoraHeaderError(error): + pass + + +class OggTheoraInfo(object): + """Ogg Theora stream information. + + Attributes: + + * length - file length in seconds, as a float + * fps - video frames per second, as a float + """ + + length = 0 + + def __init__(self, fileobj): + page = OggPage(fileobj) + while not page.packets[0].startswith("\x80theora"): + page = OggPage(fileobj) + if not page.first: + raise OggTheoraHeaderError( + "page has ID header, but doesn't start a stream") + data = page.packets[0] + vmaj, vmin = struct.unpack("2B", data[7:9]) + if (vmaj, vmin) != (3, 2): + raise OggTheoraHeaderError( + "found Theora version %d.%d != 3.2" % (vmaj, vmin)) + fps_num, fps_den = struct.unpack(">2I", data[22:30]) + self.fps = fps_num / float(fps_den) + self.bitrate = cdata.uint_be("\x00" + data[37:40]) + self.granule_shift = (cdata.ushort_be(data[40:42]) >> 5) & 0x1F + self.serial = page.serial + + def _post_tags(self, fileobj): + page = OggPage.find_last(fileobj, self.serial) + position = page.position + mask = (1 << self.granule_shift) - 1 + frames = (position >> self.granule_shift) + (position & mask) + self.length = frames / float(self.fps) + + def pprint(self): + return "Ogg Theora, %.2f seconds, %d bps" % (self.length, self.bitrate) + + +class OggTheoraCommentDict(VCommentDict): + """Theora comments embedded in an Ogg bitstream.""" + + def __init__(self, fileobj, info): + pages = [] + complete = False + while not complete: + page = OggPage(fileobj) + if page.serial == info.serial: + pages.append(page) + complete = page.complete or (len(page.packets) > 1) + data = OggPage.to_packets(pages)[0][7:] + super(OggTheoraCommentDict, self).__init__(data + "\x01") + + def _inject(self, fileobj): + """Write tag data into the Theora comment packet/page.""" + + fileobj.seek(0) + page = OggPage(fileobj) + while not page.packets[0].startswith("\x81theora"): + page = OggPage(fileobj) + + old_pages = [page] + while not (old_pages[-1].complete or len(old_pages[-1].packets) > 1): + page = OggPage(fileobj) + if page.serial == old_pages[0].serial: + old_pages.append(page) + + packets = OggPage.to_packets(old_pages, strict=False) + + packets[0] = "\x81theora" + self.write(framing=False) + + new_pages = OggPage.from_packets(packets, old_pages[0].sequence) + OggPage.replace(fileobj, old_pages, new_pages) + + +class OggTheora(OggFileType): + """An Ogg Theora file.""" + + _Info = OggTheoraInfo + _Tags = OggTheoraCommentDict + _Error = OggTheoraHeaderError + _mimes = ["video/x-theora"] + + @staticmethod + def score(filename, fileobj, header): + return (header.startswith("OggS") * + (("\x80theora" in header) + ("\x81theora" in header))) + + +Open = OggTheora + + +def delete(filename): + """Remove tags from a file.""" + + OggTheora(filename).delete() diff --git a/libs/mutagen/oggvorbis.py b/libs/mutagen/oggvorbis.py new file mode 100644 index 00000000..509fd966 --- /dev/null +++ b/libs/mutagen/oggvorbis.py @@ -0,0 +1,137 @@ +# Ogg Vorbis support. +# +# Copyright 2006 Joe Wreschnig +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +"""Read and write Ogg Vorbis comments. + +This module handles Vorbis files wrapped in an Ogg bitstream. The +first Vorbis stream found is used. + +Read more about Ogg Vorbis at http://vorbis.com/. This module is based +on the specification at http://www.xiph.org/vorbis/doc/Vorbis_I_spec.html. +""" + +__all__ = ["OggVorbis", "Open", "delete"] + +import struct + +from mutagen._vorbis import VCommentDict +from mutagen.ogg import OggPage, OggFileType, error as OggError + + +class error(OggError): + pass + + +class OggVorbisHeaderError(error): + pass + + +class OggVorbisInfo(object): + """Ogg Vorbis stream information. + + Attributes: + + * length - file length in seconds, as a float + * bitrate - nominal ('average') bitrate in bits per second, as an int + """ + + length = 0 + + def __init__(self, fileobj): + page = OggPage(fileobj) + while not page.packets[0].startswith("\x01vorbis"): + page = OggPage(fileobj) + if not page.first: + raise OggVorbisHeaderError( + "page has ID header, but doesn't start a stream") + (self.channels, self.sample_rate, max_bitrate, nominal_bitrate, + min_bitrate) = struct.unpack(" nominal_bitrate: + self.bitrate = min_bitrate + else: + self.bitrate = nominal_bitrate + + def _post_tags(self, fileobj): + page = OggPage.find_last(fileobj, self.serial) + self.length = page.position / float(self.sample_rate) + + def pprint(self): + return "Ogg Vorbis, %.2f seconds, %d bps" % (self.length, self.bitrate) + + +class OggVCommentDict(VCommentDict): + """Vorbis comments embedded in an Ogg bitstream.""" + + def __init__(self, fileobj, info): + pages = [] + complete = False + while not complete: + page = OggPage(fileobj) + if page.serial == info.serial: + pages.append(page) + complete = page.complete or (len(page.packets) > 1) + data = OggPage.to_packets(pages)[0][7:] # Strip off "\x03vorbis". + super(OggVCommentDict, self).__init__(data) + + def _inject(self, fileobj): + """Write tag data into the Vorbis comment packet/page.""" + + # Find the old pages in the file; we'll need to remove them, + # plus grab any stray setup packet data out of them. + fileobj.seek(0) + page = OggPage(fileobj) + while not page.packets[0].startswith("\x03vorbis"): + page = OggPage(fileobj) + + old_pages = [page] + while not (old_pages[-1].complete or len(old_pages[-1].packets) > 1): + page = OggPage(fileobj) + if page.serial == old_pages[0].serial: + old_pages.append(page) + + packets = OggPage.to_packets(old_pages, strict=False) + + # Set the new comment packet. + packets[0] = "\x03vorbis" + self.write() + + new_pages = OggPage.from_packets(packets, old_pages[0].sequence) + OggPage.replace(fileobj, old_pages, new_pages) + + +class OggVorbis(OggFileType): + """An Ogg Vorbis file.""" + + _Info = OggVorbisInfo + _Tags = OggVCommentDict + _Error = OggVorbisHeaderError + _mimes = ["audio/vorbis", "audio/x-vorbis"] + + @staticmethod + def score(filename, fileobj, header): + return (header.startswith("OggS") * ("\x01vorbis" in header)) + + +Open = OggVorbis + + +def delete(filename): + """Remove tags from a file.""" + + OggVorbis(filename).delete() diff --git a/libs/mutagen/optimfrog.py b/libs/mutagen/optimfrog.py new file mode 100644 index 00000000..24a87af8 --- /dev/null +++ b/libs/mutagen/optimfrog.py @@ -0,0 +1,71 @@ +# OptimFROG reader/tagger +# +# Copyright 2006 Lukas Lalinsky +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +"""OptimFROG audio streams with APEv2 tags. + +OptimFROG is a lossless audio compression program. Its main goal is to +reduce at maximum the size of audio files, while permitting bit +identical restoration for all input. It is similar with the ZIP +compression, but it is highly specialized to compress audio data. + +Only versions 4.5 and higher are supported. + +For more information, see http://www.losslessaudio.org/ +""" + +__all__ = ["OptimFROG", "Open", "delete"] + +import struct + +from mutagen.apev2 import APEv2File, error, delete + + +class OptimFROGHeaderError(error): + pass + + +class OptimFROGInfo(object): + """OptimFROG stream information. + + Attributes: + + * channels - number of audio channels + * length - file length in seconds, as a float + * sample_rate - audio sampling rate in Hz + """ + + def __init__(self, fileobj): + header = fileobj.read(76) + if (len(header) != 76 or not header.startswith("OFR ") or + struct.unpack("` + """ + + _Info = TrueAudioInfo + _mimes = ["audio/x-tta"] + + @staticmethod + def score(filename, fileobj, header): + return (header.startswith("ID3") + header.startswith("TTA") + + filename.lower().endswith(".tta") * 2) + + +Open = TrueAudio + + +class EasyTrueAudio(TrueAudio): + """Like MP3, but uses EasyID3 for tags. + + :ivar info: :class:`TrueAudioInfo` + :ivar tags: :class:`EasyID3 ` + """ + + from mutagen.easyid3 import EasyID3 as ID3 + ID3 = ID3 diff --git a/libs/mutagen/wavpack.py b/libs/mutagen/wavpack.py new file mode 100644 index 00000000..1a2db818 --- /dev/null +++ b/libs/mutagen/wavpack.py @@ -0,0 +1,63 @@ +# A WavPack reader/tagger +# +# Copyright 2006 Joe Wreschnig +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. + +"""WavPack reading and writing. + +WavPack is a lossless format that uses APEv2 tags. Read +http://www.wavpack.com/ for more information. +""" + +__all__ = ["WavPack", "Open", "delete"] + +from mutagen.apev2 import APEv2File, error, delete +from mutagen._util import cdata + + +class WavPackHeaderError(error): + pass + +RATES = [6000, 8000, 9600, 11025, 12000, 16000, 22050, 24000, 32000, 44100, + 48000, 64000, 88200, 96000, 192000] + + +class WavPackInfo(object): + """WavPack stream information. + + Attributes: + + * channels - number of audio channels (1 or 2) + * length - file length in seconds, as a float + * sample_rate - audio sampling rate in Hz + * version - WavPack stream version + """ + + def __init__(self, fileobj): + header = fileobj.read(28) + if len(header) != 28 or not header.startswith("wvpk"): + raise WavPackHeaderError("not a WavPack file") + samples = cdata.uint_le(header[12:16]) + flags = cdata.uint_le(header[24:28]) + self.version = cdata.short_le(header[8:10]) + self.channels = bool(flags & 4) or 2 + self.sample_rate = RATES[(flags >> 23) & 0xF] + self.length = float(samples) / self.sample_rate + + def pprint(self): + return "WavPack, %.2f seconds, %d Hz" % (self.length, self.sample_rate) + + +class WavPack(APEv2File): + _Info = WavPackInfo + _mimes = ["audio/x-wavpack"] + + @staticmethod + def score(filename, fileobj, header): + return header.startswith("wvpk") * 2 + + +Open = WavPack diff --git a/libs/unidecode/__init__.py b/libs/unidecode/__init__.py new file mode 100644 index 00000000..82eb5a3f --- /dev/null +++ b/libs/unidecode/__init__.py @@ -0,0 +1,63 @@ +# -*- coding: utf-8 -*- +"""Transliterate Unicode text into plain 7-bit ASCII. + +Example usage: +>>> from unidecode import unidecode: +>>> unidecode(u"\u5317\u4EB0") +"Bei Jing " + +The transliteration uses a straightforward map, and doesn't have alternatives +for the same character based on language, position, or anything else. + +In Python 3, a standard string object will be returned. If you need bytes, use: +>>> unidecode("Κνωσός").encode("ascii") +b'Knosos' +""" +import warnings +from sys import version_info + +Cache = {} + +def unidecode(string): + """Transliterate an Unicode object into an ASCII string + + >>> unidecode(u"\u5317\u4EB0") + "Bei Jing " + """ + + if version_info[0] < 3 and not isinstance(string, unicode): + warnings.warn( "Argument %r is not an unicode object. " + "Passing an encoded string will likely have " + "unexpected results." % (type(string),), + RuntimeWarning, 2) + + retval = [] + + for char in string: + codepoint = ord(char) + + if codepoint < 0x80: # Basic ASCII + retval.append(str(char)) + continue + + if codepoint > 0xeffff: + continue # Characters in Private Use Area and above are ignored + + section = codepoint >> 8 # Chop off the last two hex digits + position = codepoint % 256 # Last two hex digits + + try: + table = Cache[section] + except KeyError: + try: + mod = __import__('unidecode.x%03x'%(section), [], [], ['data']) + except ImportError: + Cache[section] = None + continue # No match: ignore this character and carry on. + + Cache[section] = table = mod.data + + if table and len(table) > position: + retval.append( table[position] ) + + return ''.join(retval) diff --git a/libs/unidecode/x000.py b/libs/unidecode/x000.py new file mode 100644 index 00000000..6821df47 --- /dev/null +++ b/libs/unidecode/x000.py @@ -0,0 +1,258 @@ +data = ( +'\x00', # 0x00 +'\x01', # 0x01 +'\x02', # 0x02 +'\x03', # 0x03 +'\x04', # 0x04 +'\x05', # 0x05 +'\x06', # 0x06 +'\x07', # 0x07 +'\x08', # 0x08 +'\x09', # 0x09 +'\x0a', # 0x0a +'\x0b', # 0x0b +'\x0c', # 0x0c +'\x0d', # 0x0d +'\x0e', # 0x0e +'\x0f', # 0x0f +'\x10', # 0x10 +'\x11', # 0x11 +'\x12', # 0x12 +'\x13', # 0x13 +'\x14', # 0x14 +'\x15', # 0x15 +'\x16', # 0x16 +'\x17', # 0x17 +'\x18', # 0x18 +'\x19', # 0x19 +'\x1a', # 0x1a +'\x1b', # 0x1b +'\x1c', # 0x1c +'\x1d', # 0x1d +'\x1e', # 0x1e +'\x1f', # 0x1f +' ', # 0x20 +'!', # 0x21 +'"', # 0x22 +'#', # 0x23 +'$', # 0x24 +'%', # 0x25 +'&', # 0x26 +'\'', # 0x27 +'(', # 0x28 +')', # 0x29 +'*', # 0x2a +'+', # 0x2b +',', # 0x2c +'-', # 0x2d +'.', # 0x2e +'/', # 0x2f +'0', # 0x30 +'1', # 0x31 +'2', # 0x32 +'3', # 0x33 +'4', # 0x34 +'5', # 0x35 +'6', # 0x36 +'7', # 0x37 +'8', # 0x38 +'9', # 0x39 +':', # 0x3a +';', # 0x3b +'<', # 0x3c +'=', # 0x3d +'>', # 0x3e +'?', # 0x3f +'@', # 0x40 +'A', # 0x41 +'B', # 0x42 +'C', # 0x43 +'D', # 0x44 +'E', # 0x45 +'F', # 0x46 +'G', # 0x47 +'H', # 0x48 +'I', # 0x49 +'J', # 0x4a +'K', # 0x4b +'L', # 0x4c +'M', # 0x4d +'N', # 0x4e +'O', # 0x4f +'P', # 0x50 +'Q', # 0x51 +'R', # 0x52 +'S', # 0x53 +'T', # 0x54 +'U', # 0x55 +'V', # 0x56 +'W', # 0x57 +'X', # 0x58 +'Y', # 0x59 +'Z', # 0x5a +']', # 0x5b +'\\', # 0x5c +']', # 0x5d +'^', # 0x5e +'_', # 0x5f +'`', # 0x60 +'a', # 0x61 +'b', # 0x62 +'c', # 0x63 +'d', # 0x64 +'e', # 0x65 +'f', # 0x66 +'g', # 0x67 +'h', # 0x68 +'i', # 0x69 +'j', # 0x6a +'k', # 0x6b +'l', # 0x6c +'m', # 0x6d +'n', # 0x6e +'o', # 0x6f +'p', # 0x70 +'q', # 0x71 +'r', # 0x72 +'s', # 0x73 +'t', # 0x74 +'u', # 0x75 +'v', # 0x76 +'w', # 0x77 +'x', # 0x78 +'y', # 0x79 +'z', # 0x7a +'{', # 0x7b +'|', # 0x7c +'}', # 0x7d +'~', # 0x7e +'', # 0x7f +'', # 0x80 +'', # 0x81 +'', # 0x82 +'', # 0x83 +'', # 0x84 +'', # 0x85 +'', # 0x86 +'', # 0x87 +'', # 0x88 +'', # 0x89 +'', # 0x8a +'', # 0x8b +'', # 0x8c +'', # 0x8d +'', # 0x8e +'', # 0x8f +'', # 0x90 +'', # 0x91 +'', # 0x92 +'', # 0x93 +'', # 0x94 +'', # 0x95 +'', # 0x96 +'', # 0x97 +'', # 0x98 +'', # 0x99 +'', # 0x9a +'', # 0x9b +'', # 0x9c +'', # 0x9d +'', # 0x9e +'', # 0x9f +' ', # 0xa0 +'!', # 0xa1 +'C/', # 0xa2 +'PS', # 0xa3 +'$?', # 0xa4 +'Y=', # 0xa5 +'|', # 0xa6 +'SS', # 0xa7 +'"', # 0xa8 +'(c)', # 0xa9 +'a', # 0xaa +'<<', # 0xab +'!', # 0xac +'', # 0xad +'(r)', # 0xae +'-', # 0xaf +'deg', # 0xb0 +'+-', # 0xb1 +'2', # 0xb2 +'3', # 0xb3 +'\'', # 0xb4 +'u', # 0xb5 +'P', # 0xb6 +'*', # 0xb7 +',', # 0xb8 +'1', # 0xb9 +'o', # 0xba +'>>', # 0xbb +'1/4', # 0xbc +'1/2', # 0xbd +'3/4', # 0xbe +'?', # 0xbf +'A', # 0xc0 +'A', # 0xc1 +'A', # 0xc2 +'A', # 0xc3 +'A', # 0xc4 +'A', # 0xc5 +'AE', # 0xc6 +'C', # 0xc7 +'E', # 0xc8 +'E', # 0xc9 +'E', # 0xca +'E', # 0xcb +'I', # 0xcc +'I', # 0xcd +'I', # 0xce +'I', # 0xcf +'D', # 0xd0 +'N', # 0xd1 +'O', # 0xd2 +'O', # 0xd3 +'O', # 0xd4 +'O', # 0xd5 +'O', # 0xd6 +'x', # 0xd7 +'O', # 0xd8 +'U', # 0xd9 +'U', # 0xda +'U', # 0xdb +'U', # 0xdc +'Y', # 0xdd +'Th', # 0xde +'ss', # 0xdf +'a', # 0xe0 +'a', # 0xe1 +'a', # 0xe2 +'a', # 0xe3 +'a', # 0xe4 +'a', # 0xe5 +'ae', # 0xe6 +'c', # 0xe7 +'e', # 0xe8 +'e', # 0xe9 +'e', # 0xea +'e', # 0xeb +'i', # 0xec +'i', # 0xed +'i', # 0xee +'i', # 0xef +'d', # 0xf0 +'n', # 0xf1 +'o', # 0xf2 +'o', # 0xf3 +'o', # 0xf4 +'o', # 0xf5 +'o', # 0xf6 +'/', # 0xf7 +'o', # 0xf8 +'u', # 0xf9 +'u', # 0xfa +'u', # 0xfb +'u', # 0xfc +'y', # 0xfd +'th', # 0xfe +'y', # 0xff +) diff --git a/libs/unidecode/x001.py b/libs/unidecode/x001.py new file mode 100644 index 00000000..212c2d1a --- /dev/null +++ b/libs/unidecode/x001.py @@ -0,0 +1,258 @@ +data = ( +'A', # 0x00 +'a', # 0x01 +'A', # 0x02 +'a', # 0x03 +'A', # 0x04 +'a', # 0x05 +'C', # 0x06 +'c', # 0x07 +'C', # 0x08 +'c', # 0x09 +'C', # 0x0a +'c', # 0x0b +'C', # 0x0c +'c', # 0x0d +'D', # 0x0e +'d', # 0x0f +'D', # 0x10 +'d', # 0x11 +'E', # 0x12 +'e', # 0x13 +'E', # 0x14 +'e', # 0x15 +'E', # 0x16 +'e', # 0x17 +'E', # 0x18 +'e', # 0x19 +'E', # 0x1a +'e', # 0x1b +'G', # 0x1c +'g', # 0x1d +'G', # 0x1e +'g', # 0x1f +'G', # 0x20 +'g', # 0x21 +'G', # 0x22 +'g', # 0x23 +'H', # 0x24 +'h', # 0x25 +'H', # 0x26 +'h', # 0x27 +'I', # 0x28 +'i', # 0x29 +'I', # 0x2a +'i', # 0x2b +'I', # 0x2c +'i', # 0x2d +'I', # 0x2e +'i', # 0x2f +'I', # 0x30 +'i', # 0x31 +'IJ', # 0x32 +'ij', # 0x33 +'J', # 0x34 +'j', # 0x35 +'K', # 0x36 +'k', # 0x37 +'k', # 0x38 +'L', # 0x39 +'l', # 0x3a +'L', # 0x3b +'l', # 0x3c +'L', # 0x3d +'l', # 0x3e +'L', # 0x3f +'l', # 0x40 +'L', # 0x41 +'l', # 0x42 +'N', # 0x43 +'n', # 0x44 +'N', # 0x45 +'n', # 0x46 +'N', # 0x47 +'n', # 0x48 +'\'n', # 0x49 +'ng', # 0x4a +'NG', # 0x4b +'O', # 0x4c +'o', # 0x4d +'O', # 0x4e +'o', # 0x4f +'O', # 0x50 +'o', # 0x51 +'OE', # 0x52 +'oe', # 0x53 +'R', # 0x54 +'r', # 0x55 +'R', # 0x56 +'r', # 0x57 +'R', # 0x58 +'r', # 0x59 +'S', # 0x5a +'s', # 0x5b +'S', # 0x5c +'s', # 0x5d +'S', # 0x5e +'s', # 0x5f +'S', # 0x60 +'s', # 0x61 +'T', # 0x62 +'t', # 0x63 +'T', # 0x64 +'t', # 0x65 +'T', # 0x66 +'t', # 0x67 +'U', # 0x68 +'u', # 0x69 +'U', # 0x6a +'u', # 0x6b +'U', # 0x6c +'u', # 0x6d +'U', # 0x6e +'u', # 0x6f +'U', # 0x70 +'u', # 0x71 +'U', # 0x72 +'u', # 0x73 +'W', # 0x74 +'w', # 0x75 +'Y', # 0x76 +'y', # 0x77 +'Y', # 0x78 +'Z', # 0x79 +'z', # 0x7a +'Z', # 0x7b +'z', # 0x7c +'Z', # 0x7d +'z', # 0x7e +'s', # 0x7f +'b', # 0x80 +'B', # 0x81 +'B', # 0x82 +'b', # 0x83 +'6', # 0x84 +'6', # 0x85 +'O', # 0x86 +'C', # 0x87 +'c', # 0x88 +'D', # 0x89 +'D', # 0x8a +'D', # 0x8b +'d', # 0x8c +'d', # 0x8d +'3', # 0x8e +'@', # 0x8f +'E', # 0x90 +'F', # 0x91 +'f', # 0x92 +'G', # 0x93 +'G', # 0x94 +'hv', # 0x95 +'I', # 0x96 +'I', # 0x97 +'K', # 0x98 +'k', # 0x99 +'l', # 0x9a +'l', # 0x9b +'W', # 0x9c +'N', # 0x9d +'n', # 0x9e +'O', # 0x9f +'O', # 0xa0 +'o', # 0xa1 +'OI', # 0xa2 +'oi', # 0xa3 +'P', # 0xa4 +'p', # 0xa5 +'YR', # 0xa6 +'2', # 0xa7 +'2', # 0xa8 +'SH', # 0xa9 +'sh', # 0xaa +'t', # 0xab +'T', # 0xac +'t', # 0xad +'T', # 0xae +'U', # 0xaf +'u', # 0xb0 +'Y', # 0xb1 +'V', # 0xb2 +'Y', # 0xb3 +'y', # 0xb4 +'Z', # 0xb5 +'z', # 0xb6 +'ZH', # 0xb7 +'ZH', # 0xb8 +'zh', # 0xb9 +'zh', # 0xba +'2', # 0xbb +'5', # 0xbc +'5', # 0xbd +'ts', # 0xbe +'w', # 0xbf +'|', # 0xc0 +'||', # 0xc1 +'|=', # 0xc2 +'!', # 0xc3 +'DZ', # 0xc4 +'Dz', # 0xc5 +'dz', # 0xc6 +'LJ', # 0xc7 +'Lj', # 0xc8 +'lj', # 0xc9 +'NJ', # 0xca +'Nj', # 0xcb +'nj', # 0xcc +'A', # 0xcd +'a', # 0xce +'I', # 0xcf +'i', # 0xd0 +'O', # 0xd1 +'o', # 0xd2 +'U', # 0xd3 +'u', # 0xd4 +'U', # 0xd5 +'u', # 0xd6 +'U', # 0xd7 +'u', # 0xd8 +'U', # 0xd9 +'u', # 0xda +'U', # 0xdb +'u', # 0xdc +'@', # 0xdd +'A', # 0xde +'a', # 0xdf +'A', # 0xe0 +'a', # 0xe1 +'AE', # 0xe2 +'ae', # 0xe3 +'G', # 0xe4 +'g', # 0xe5 +'G', # 0xe6 +'g', # 0xe7 +'K', # 0xe8 +'k', # 0xe9 +'O', # 0xea +'o', # 0xeb +'O', # 0xec +'o', # 0xed +'ZH', # 0xee +'zh', # 0xef +'j', # 0xf0 +'DZ', # 0xf1 +'Dz', # 0xf2 +'dz', # 0xf3 +'G', # 0xf4 +'g', # 0xf5 +'HV', # 0xf6 +'W', # 0xf7 +'N', # 0xf8 +'n', # 0xf9 +'A', # 0xfa +'a', # 0xfb +'AE', # 0xfc +'ae', # 0xfd +'O', # 0xfe +'o', # 0xff +) diff --git a/libs/unidecode/x002.py b/libs/unidecode/x002.py new file mode 100644 index 00000000..ea45441e --- /dev/null +++ b/libs/unidecode/x002.py @@ -0,0 +1,257 @@ +data = ( +'A', # 0x00 +'a', # 0x01 +'A', # 0x02 +'a', # 0x03 +'E', # 0x04 +'e', # 0x05 +'E', # 0x06 +'e', # 0x07 +'I', # 0x08 +'i', # 0x09 +'I', # 0x0a +'i', # 0x0b +'O', # 0x0c +'o', # 0x0d +'O', # 0x0e +'o', # 0x0f +'R', # 0x10 +'r', # 0x11 +'R', # 0x12 +'r', # 0x13 +'U', # 0x14 +'u', # 0x15 +'U', # 0x16 +'u', # 0x17 +'S', # 0x18 +'s', # 0x19 +'T', # 0x1a +'t', # 0x1b +'Y', # 0x1c +'y', # 0x1d +'H', # 0x1e +'h', # 0x1f +'N', # 0x20 +'d', # 0x21 +'OU', # 0x22 +'ou', # 0x23 +'Z', # 0x24 +'z', # 0x25 +'A', # 0x26 +'a', # 0x27 +'E', # 0x28 +'e', # 0x29 +'O', # 0x2a +'o', # 0x2b +'O', # 0x2c +'o', # 0x2d +'O', # 0x2e +'o', # 0x2f +'O', # 0x30 +'o', # 0x31 +'Y', # 0x32 +'y', # 0x33 +'l', # 0x34 +'n', # 0x35 +'t', # 0x36 +'j', # 0x37 +'db', # 0x38 +'qp', # 0x39 +'A', # 0x3a +'C', # 0x3b +'c', # 0x3c +'L', # 0x3d +'T', # 0x3e +'s', # 0x3f +'z', # 0x40 +'[?]', # 0x41 +'[?]', # 0x42 +'B', # 0x43 +'U', # 0x44 +'^', # 0x45 +'E', # 0x46 +'e', # 0x47 +'J', # 0x48 +'j', # 0x49 +'q', # 0x4a +'q', # 0x4b +'R', # 0x4c +'r', # 0x4d +'Y', # 0x4e +'y', # 0x4f +'a', # 0x50 +'a', # 0x51 +'a', # 0x52 +'b', # 0x53 +'o', # 0x54 +'c', # 0x55 +'d', # 0x56 +'d', # 0x57 +'e', # 0x58 +'@', # 0x59 +'@', # 0x5a +'e', # 0x5b +'e', # 0x5c +'e', # 0x5d +'e', # 0x5e +'j', # 0x5f +'g', # 0x60 +'g', # 0x61 +'g', # 0x62 +'g', # 0x63 +'u', # 0x64 +'Y', # 0x65 +'h', # 0x66 +'h', # 0x67 +'i', # 0x68 +'i', # 0x69 +'I', # 0x6a +'l', # 0x6b +'l', # 0x6c +'l', # 0x6d +'lZ', # 0x6e +'W', # 0x6f +'W', # 0x70 +'m', # 0x71 +'n', # 0x72 +'n', # 0x73 +'n', # 0x74 +'o', # 0x75 +'OE', # 0x76 +'O', # 0x77 +'F', # 0x78 +'r', # 0x79 +'r', # 0x7a +'r', # 0x7b +'r', # 0x7c +'r', # 0x7d +'r', # 0x7e +'r', # 0x7f +'R', # 0x80 +'R', # 0x81 +'s', # 0x82 +'S', # 0x83 +'j', # 0x84 +'S', # 0x85 +'S', # 0x86 +'t', # 0x87 +'t', # 0x88 +'u', # 0x89 +'U', # 0x8a +'v', # 0x8b +'^', # 0x8c +'w', # 0x8d +'y', # 0x8e +'Y', # 0x8f +'z', # 0x90 +'z', # 0x91 +'Z', # 0x92 +'Z', # 0x93 +'?', # 0x94 +'?', # 0x95 +'?', # 0x96 +'C', # 0x97 +'@', # 0x98 +'B', # 0x99 +'E', # 0x9a +'G', # 0x9b +'H', # 0x9c +'j', # 0x9d +'k', # 0x9e +'L', # 0x9f +'q', # 0xa0 +'?', # 0xa1 +'?', # 0xa2 +'dz', # 0xa3 +'dZ', # 0xa4 +'dz', # 0xa5 +'ts', # 0xa6 +'tS', # 0xa7 +'tC', # 0xa8 +'fN', # 0xa9 +'ls', # 0xaa +'lz', # 0xab +'WW', # 0xac +']]', # 0xad +'h', # 0xae +'h', # 0xaf +'k', # 0xb0 +'h', # 0xb1 +'j', # 0xb2 +'r', # 0xb3 +'r', # 0xb4 +'r', # 0xb5 +'r', # 0xb6 +'w', # 0xb7 +'y', # 0xb8 +'\'', # 0xb9 +'"', # 0xba +'`', # 0xbb +'\'', # 0xbc +'`', # 0xbd +'`', # 0xbe +'\'', # 0xbf +'?', # 0xc0 +'?', # 0xc1 +'<', # 0xc2 +'>', # 0xc3 +'^', # 0xc4 +'V', # 0xc5 +'^', # 0xc6 +'V', # 0xc7 +'\'', # 0xc8 +'-', # 0xc9 +'/', # 0xca +'\\', # 0xcb +',', # 0xcc +'_', # 0xcd +'\\', # 0xce +'/', # 0xcf +':', # 0xd0 +'.', # 0xd1 +'`', # 0xd2 +'\'', # 0xd3 +'^', # 0xd4 +'V', # 0xd5 +'+', # 0xd6 +'-', # 0xd7 +'V', # 0xd8 +'.', # 0xd9 +'@', # 0xda +',', # 0xdb +'~', # 0xdc +'"', # 0xdd +'R', # 0xde +'X', # 0xdf +'G', # 0xe0 +'l', # 0xe1 +'s', # 0xe2 +'x', # 0xe3 +'?', # 0xe4 +'', # 0xe5 +'', # 0xe6 +'', # 0xe7 +'', # 0xe8 +'', # 0xe9 +'', # 0xea +'', # 0xeb +'V', # 0xec +'=', # 0xed +'"', # 0xee +'[?]', # 0xef +'[?]', # 0xf0 +'[?]', # 0xf1 +'[?]', # 0xf2 +'[?]', # 0xf3 +'[?]', # 0xf4 +'[?]', # 0xf5 +'[?]', # 0xf6 +'[?]', # 0xf7 +'[?]', # 0xf8 +'[?]', # 0xf9 +'[?]', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x003.py b/libs/unidecode/x003.py new file mode 100644 index 00000000..4ba8d726 --- /dev/null +++ b/libs/unidecode/x003.py @@ -0,0 +1,257 @@ +data = ( +'', # 0x00 +'', # 0x01 +'', # 0x02 +'', # 0x03 +'', # 0x04 +'', # 0x05 +'', # 0x06 +'', # 0x07 +'', # 0x08 +'', # 0x09 +'', # 0x0a +'', # 0x0b +'', # 0x0c +'', # 0x0d +'', # 0x0e +'', # 0x0f +'', # 0x10 +'', # 0x11 +'', # 0x12 +'', # 0x13 +'', # 0x14 +'', # 0x15 +'', # 0x16 +'', # 0x17 +'', # 0x18 +'', # 0x19 +'', # 0x1a +'', # 0x1b +'', # 0x1c +'', # 0x1d +'', # 0x1e +'', # 0x1f +'', # 0x20 +'', # 0x21 +'', # 0x22 +'', # 0x23 +'', # 0x24 +'', # 0x25 +'', # 0x26 +'', # 0x27 +'', # 0x28 +'', # 0x29 +'', # 0x2a +'', # 0x2b +'', # 0x2c +'', # 0x2d +'', # 0x2e +'', # 0x2f +'', # 0x30 +'', # 0x31 +'', # 0x32 +'', # 0x33 +'', # 0x34 +'', # 0x35 +'', # 0x36 +'', # 0x37 +'', # 0x38 +'', # 0x39 +'', # 0x3a +'', # 0x3b +'', # 0x3c +'', # 0x3d +'', # 0x3e +'', # 0x3f +'', # 0x40 +'', # 0x41 +'', # 0x42 +'', # 0x43 +'', # 0x44 +'', # 0x45 +'', # 0x46 +'', # 0x47 +'', # 0x48 +'', # 0x49 +'', # 0x4a +'', # 0x4b +'', # 0x4c +'', # 0x4d +'', # 0x4e +'[?]', # 0x4f +'[?]', # 0x50 +'[?]', # 0x51 +'[?]', # 0x52 +'[?]', # 0x53 +'[?]', # 0x54 +'[?]', # 0x55 +'[?]', # 0x56 +'[?]', # 0x57 +'[?]', # 0x58 +'[?]', # 0x59 +'[?]', # 0x5a +'[?]', # 0x5b +'[?]', # 0x5c +'[?]', # 0x5d +'[?]', # 0x5e +'[?]', # 0x5f +'', # 0x60 +'', # 0x61 +'', # 0x62 +'a', # 0x63 +'e', # 0x64 +'i', # 0x65 +'o', # 0x66 +'u', # 0x67 +'c', # 0x68 +'d', # 0x69 +'h', # 0x6a +'m', # 0x6b +'r', # 0x6c +'t', # 0x6d +'v', # 0x6e +'x', # 0x6f +'[?]', # 0x70 +'[?]', # 0x71 +'[?]', # 0x72 +'[?]', # 0x73 +'\'', # 0x74 +',', # 0x75 +'[?]', # 0x76 +'[?]', # 0x77 +'[?]', # 0x78 +'[?]', # 0x79 +'', # 0x7a +'[?]', # 0x7b +'[?]', # 0x7c +'[?]', # 0x7d +'?', # 0x7e +'[?]', # 0x7f +'[?]', # 0x80 +'[?]', # 0x81 +'[?]', # 0x82 +'[?]', # 0x83 +'', # 0x84 +'', # 0x85 +'A', # 0x86 +';', # 0x87 +'E', # 0x88 +'E', # 0x89 +'I', # 0x8a +'[?]', # 0x8b +'O', # 0x8c +'[?]', # 0x8d +'U', # 0x8e +'O', # 0x8f +'I', # 0x90 +'A', # 0x91 +'B', # 0x92 +'G', # 0x93 +'D', # 0x94 +'E', # 0x95 +'Z', # 0x96 +'E', # 0x97 +'Th', # 0x98 +'I', # 0x99 +'K', # 0x9a +'L', # 0x9b +'M', # 0x9c +'N', # 0x9d +'Ks', # 0x9e +'O', # 0x9f +'P', # 0xa0 +'R', # 0xa1 +'[?]', # 0xa2 +'S', # 0xa3 +'T', # 0xa4 +'U', # 0xa5 +'Ph', # 0xa6 +'Kh', # 0xa7 +'Ps', # 0xa8 +'O', # 0xa9 +'I', # 0xaa +'U', # 0xab +'a', # 0xac +'e', # 0xad +'e', # 0xae +'i', # 0xaf +'u', # 0xb0 +'a', # 0xb1 +'b', # 0xb2 +'g', # 0xb3 +'d', # 0xb4 +'e', # 0xb5 +'z', # 0xb6 +'e', # 0xb7 +'th', # 0xb8 +'i', # 0xb9 +'k', # 0xba +'l', # 0xbb +'m', # 0xbc +'n', # 0xbd +'x', # 0xbe +'o', # 0xbf +'p', # 0xc0 +'r', # 0xc1 +'s', # 0xc2 +'s', # 0xc3 +'t', # 0xc4 +'u', # 0xc5 +'ph', # 0xc6 +'kh', # 0xc7 +'ps', # 0xc8 +'o', # 0xc9 +'i', # 0xca +'u', # 0xcb +'o', # 0xcc +'u', # 0xcd +'o', # 0xce +'[?]', # 0xcf +'b', # 0xd0 +'th', # 0xd1 +'U', # 0xd2 +'U', # 0xd3 +'U', # 0xd4 +'ph', # 0xd5 +'p', # 0xd6 +'&', # 0xd7 +'[?]', # 0xd8 +'[?]', # 0xd9 +'St', # 0xda +'st', # 0xdb +'W', # 0xdc +'w', # 0xdd +'Q', # 0xde +'q', # 0xdf +'Sp', # 0xe0 +'sp', # 0xe1 +'Sh', # 0xe2 +'sh', # 0xe3 +'F', # 0xe4 +'f', # 0xe5 +'Kh', # 0xe6 +'kh', # 0xe7 +'H', # 0xe8 +'h', # 0xe9 +'G', # 0xea +'g', # 0xeb +'CH', # 0xec +'ch', # 0xed +'Ti', # 0xee +'ti', # 0xef +'k', # 0xf0 +'r', # 0xf1 +'c', # 0xf2 +'j', # 0xf3 +'[?]', # 0xf4 +'[?]', # 0xf5 +'[?]', # 0xf6 +'[?]', # 0xf7 +'[?]', # 0xf8 +'[?]', # 0xf9 +'[?]', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x004.py b/libs/unidecode/x004.py new file mode 100644 index 00000000..1cc3dbc4 --- /dev/null +++ b/libs/unidecode/x004.py @@ -0,0 +1,257 @@ +data = ( +'Ie', # 0x00 +'Io', # 0x01 +'Dj', # 0x02 +'Gj', # 0x03 +'Ie', # 0x04 +'Dz', # 0x05 +'I', # 0x06 +'Yi', # 0x07 +'J', # 0x08 +'Lj', # 0x09 +'Nj', # 0x0a +'Tsh', # 0x0b +'Kj', # 0x0c +'I', # 0x0d +'U', # 0x0e +'Dzh', # 0x0f +'A', # 0x10 +'B', # 0x11 +'V', # 0x12 +'G', # 0x13 +'D', # 0x14 +'E', # 0x15 +'Zh', # 0x16 +'Z', # 0x17 +'I', # 0x18 +'I', # 0x19 +'K', # 0x1a +'L', # 0x1b +'M', # 0x1c +'N', # 0x1d +'O', # 0x1e +'P', # 0x1f +'R', # 0x20 +'S', # 0x21 +'T', # 0x22 +'U', # 0x23 +'F', # 0x24 +'Kh', # 0x25 +'Ts', # 0x26 +'Ch', # 0x27 +'Sh', # 0x28 +'Shch', # 0x29 +'\'', # 0x2a +'Y', # 0x2b +'\'', # 0x2c +'E', # 0x2d +'Iu', # 0x2e +'Ia', # 0x2f +'a', # 0x30 +'b', # 0x31 +'v', # 0x32 +'g', # 0x33 +'d', # 0x34 +'e', # 0x35 +'zh', # 0x36 +'z', # 0x37 +'i', # 0x38 +'i', # 0x39 +'k', # 0x3a +'l', # 0x3b +'m', # 0x3c +'n', # 0x3d +'o', # 0x3e +'p', # 0x3f +'r', # 0x40 +'s', # 0x41 +'t', # 0x42 +'u', # 0x43 +'f', # 0x44 +'kh', # 0x45 +'ts', # 0x46 +'ch', # 0x47 +'sh', # 0x48 +'shch', # 0x49 +'\'', # 0x4a +'y', # 0x4b +'\'', # 0x4c +'e', # 0x4d +'iu', # 0x4e +'ia', # 0x4f +'ie', # 0x50 +'io', # 0x51 +'dj', # 0x52 +'gj', # 0x53 +'ie', # 0x54 +'dz', # 0x55 +'i', # 0x56 +'yi', # 0x57 +'j', # 0x58 +'lj', # 0x59 +'nj', # 0x5a +'tsh', # 0x5b +'kj', # 0x5c +'i', # 0x5d +'u', # 0x5e +'dzh', # 0x5f +'O', # 0x60 +'o', # 0x61 +'E', # 0x62 +'e', # 0x63 +'Ie', # 0x64 +'ie', # 0x65 +'E', # 0x66 +'e', # 0x67 +'Ie', # 0x68 +'ie', # 0x69 +'O', # 0x6a +'o', # 0x6b +'Io', # 0x6c +'io', # 0x6d +'Ks', # 0x6e +'ks', # 0x6f +'Ps', # 0x70 +'ps', # 0x71 +'F', # 0x72 +'f', # 0x73 +'Y', # 0x74 +'y', # 0x75 +'Y', # 0x76 +'y', # 0x77 +'u', # 0x78 +'u', # 0x79 +'O', # 0x7a +'o', # 0x7b +'O', # 0x7c +'o', # 0x7d +'Ot', # 0x7e +'ot', # 0x7f +'Q', # 0x80 +'q', # 0x81 +'*1000*', # 0x82 +'', # 0x83 +'', # 0x84 +'', # 0x85 +'', # 0x86 +'[?]', # 0x87 +'*100.000*', # 0x88 +'*1.000.000*', # 0x89 +'[?]', # 0x8a +'[?]', # 0x8b +'"', # 0x8c +'"', # 0x8d +'R\'', # 0x8e +'r\'', # 0x8f +'G\'', # 0x90 +'g\'', # 0x91 +'G\'', # 0x92 +'g\'', # 0x93 +'G\'', # 0x94 +'g\'', # 0x95 +'Zh\'', # 0x96 +'zh\'', # 0x97 +'Z\'', # 0x98 +'z\'', # 0x99 +'K\'', # 0x9a +'k\'', # 0x9b +'K\'', # 0x9c +'k\'', # 0x9d +'K\'', # 0x9e +'k\'', # 0x9f +'K\'', # 0xa0 +'k\'', # 0xa1 +'N\'', # 0xa2 +'n\'', # 0xa3 +'Ng', # 0xa4 +'ng', # 0xa5 +'P\'', # 0xa6 +'p\'', # 0xa7 +'Kh', # 0xa8 +'kh', # 0xa9 +'S\'', # 0xaa +'s\'', # 0xab +'T\'', # 0xac +'t\'', # 0xad +'U', # 0xae +'u', # 0xaf +'U\'', # 0xb0 +'u\'', # 0xb1 +'Kh\'', # 0xb2 +'kh\'', # 0xb3 +'Tts', # 0xb4 +'tts', # 0xb5 +'Ch\'', # 0xb6 +'ch\'', # 0xb7 +'Ch\'', # 0xb8 +'ch\'', # 0xb9 +'H', # 0xba +'h', # 0xbb +'Ch', # 0xbc +'ch', # 0xbd +'Ch\'', # 0xbe +'ch\'', # 0xbf +'`', # 0xc0 +'Zh', # 0xc1 +'zh', # 0xc2 +'K\'', # 0xc3 +'k\'', # 0xc4 +'[?]', # 0xc5 +'[?]', # 0xc6 +'N\'', # 0xc7 +'n\'', # 0xc8 +'[?]', # 0xc9 +'[?]', # 0xca +'Ch', # 0xcb +'ch', # 0xcc +'[?]', # 0xcd +'[?]', # 0xce +'[?]', # 0xcf +'a', # 0xd0 +'a', # 0xd1 +'A', # 0xd2 +'a', # 0xd3 +'Ae', # 0xd4 +'ae', # 0xd5 +'Ie', # 0xd6 +'ie', # 0xd7 +'@', # 0xd8 +'@', # 0xd9 +'@', # 0xda +'@', # 0xdb +'Zh', # 0xdc +'zh', # 0xdd +'Z', # 0xde +'z', # 0xdf +'Dz', # 0xe0 +'dz', # 0xe1 +'I', # 0xe2 +'i', # 0xe3 +'I', # 0xe4 +'i', # 0xe5 +'O', # 0xe6 +'o', # 0xe7 +'O', # 0xe8 +'o', # 0xe9 +'O', # 0xea +'o', # 0xeb +'E', # 0xec +'e', # 0xed +'U', # 0xee +'u', # 0xef +'U', # 0xf0 +'u', # 0xf1 +'U', # 0xf2 +'u', # 0xf3 +'Ch', # 0xf4 +'ch', # 0xf5 +'[?]', # 0xf6 +'[?]', # 0xf7 +'Y', # 0xf8 +'y', # 0xf9 +'[?]', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x005.py b/libs/unidecode/x005.py new file mode 100644 index 00000000..2913ffff --- /dev/null +++ b/libs/unidecode/x005.py @@ -0,0 +1,257 @@ +data = ( +'[?]', # 0x00 +'[?]', # 0x01 +'[?]', # 0x02 +'[?]', # 0x03 +'[?]', # 0x04 +'[?]', # 0x05 +'[?]', # 0x06 +'[?]', # 0x07 +'[?]', # 0x08 +'[?]', # 0x09 +'[?]', # 0x0a +'[?]', # 0x0b +'[?]', # 0x0c +'[?]', # 0x0d +'[?]', # 0x0e +'[?]', # 0x0f +'[?]', # 0x10 +'[?]', # 0x11 +'[?]', # 0x12 +'[?]', # 0x13 +'[?]', # 0x14 +'[?]', # 0x15 +'[?]', # 0x16 +'[?]', # 0x17 +'[?]', # 0x18 +'[?]', # 0x19 +'[?]', # 0x1a +'[?]', # 0x1b +'[?]', # 0x1c +'[?]', # 0x1d +'[?]', # 0x1e +'[?]', # 0x1f +'[?]', # 0x20 +'[?]', # 0x21 +'[?]', # 0x22 +'[?]', # 0x23 +'[?]', # 0x24 +'[?]', # 0x25 +'[?]', # 0x26 +'[?]', # 0x27 +'[?]', # 0x28 +'[?]', # 0x29 +'[?]', # 0x2a +'[?]', # 0x2b +'[?]', # 0x2c +'[?]', # 0x2d +'[?]', # 0x2e +'[?]', # 0x2f +'[?]', # 0x30 +'A', # 0x31 +'B', # 0x32 +'G', # 0x33 +'D', # 0x34 +'E', # 0x35 +'Z', # 0x36 +'E', # 0x37 +'E', # 0x38 +'T`', # 0x39 +'Zh', # 0x3a +'I', # 0x3b +'L', # 0x3c +'Kh', # 0x3d +'Ts', # 0x3e +'K', # 0x3f +'H', # 0x40 +'Dz', # 0x41 +'Gh', # 0x42 +'Ch', # 0x43 +'M', # 0x44 +'Y', # 0x45 +'N', # 0x46 +'Sh', # 0x47 +'O', # 0x48 +'Ch`', # 0x49 +'P', # 0x4a +'J', # 0x4b +'Rh', # 0x4c +'S', # 0x4d +'V', # 0x4e +'T', # 0x4f +'R', # 0x50 +'Ts`', # 0x51 +'W', # 0x52 +'P`', # 0x53 +'K`', # 0x54 +'O', # 0x55 +'F', # 0x56 +'[?]', # 0x57 +'[?]', # 0x58 +'<', # 0x59 +'\'', # 0x5a +'/', # 0x5b +'!', # 0x5c +',', # 0x5d +'?', # 0x5e +'.', # 0x5f +'[?]', # 0x60 +'a', # 0x61 +'b', # 0x62 +'g', # 0x63 +'d', # 0x64 +'e', # 0x65 +'z', # 0x66 +'e', # 0x67 +'e', # 0x68 +'t`', # 0x69 +'zh', # 0x6a +'i', # 0x6b +'l', # 0x6c +'kh', # 0x6d +'ts', # 0x6e +'k', # 0x6f +'h', # 0x70 +'dz', # 0x71 +'gh', # 0x72 +'ch', # 0x73 +'m', # 0x74 +'y', # 0x75 +'n', # 0x76 +'sh', # 0x77 +'o', # 0x78 +'ch`', # 0x79 +'p', # 0x7a +'j', # 0x7b +'rh', # 0x7c +'s', # 0x7d +'v', # 0x7e +'t', # 0x7f +'r', # 0x80 +'ts`', # 0x81 +'w', # 0x82 +'p`', # 0x83 +'k`', # 0x84 +'o', # 0x85 +'f', # 0x86 +'ew', # 0x87 +'[?]', # 0x88 +':', # 0x89 +'-', # 0x8a +'[?]', # 0x8b +'[?]', # 0x8c +'[?]', # 0x8d +'[?]', # 0x8e +'[?]', # 0x8f +'[?]', # 0x90 +'', # 0x91 +'', # 0x92 +'', # 0x93 +'', # 0x94 +'', # 0x95 +'', # 0x96 +'', # 0x97 +'', # 0x98 +'', # 0x99 +'', # 0x9a +'', # 0x9b +'', # 0x9c +'', # 0x9d +'', # 0x9e +'', # 0x9f +'', # 0xa0 +'', # 0xa1 +'[?]', # 0xa2 +'', # 0xa3 +'', # 0xa4 +'', # 0xa5 +'', # 0xa6 +'', # 0xa7 +'', # 0xa8 +'', # 0xa9 +'', # 0xaa +'', # 0xab +'', # 0xac +'', # 0xad +'', # 0xae +'', # 0xaf +'@', # 0xb0 +'e', # 0xb1 +'a', # 0xb2 +'o', # 0xb3 +'i', # 0xb4 +'e', # 0xb5 +'e', # 0xb6 +'a', # 0xb7 +'a', # 0xb8 +'o', # 0xb9 +'[?]', # 0xba +'u', # 0xbb +'\'', # 0xbc +'', # 0xbd +'', # 0xbe +'', # 0xbf +'|', # 0xc0 +'', # 0xc1 +'', # 0xc2 +':', # 0xc3 +'', # 0xc4 +'[?]', # 0xc5 +'[?]', # 0xc6 +'[?]', # 0xc7 +'[?]', # 0xc8 +'[?]', # 0xc9 +'[?]', # 0xca +'[?]', # 0xcb +'[?]', # 0xcc +'[?]', # 0xcd +'[?]', # 0xce +'[?]', # 0xcf +'', # 0xd0 +'b', # 0xd1 +'g', # 0xd2 +'d', # 0xd3 +'h', # 0xd4 +'v', # 0xd5 +'z', # 0xd6 +'kh', # 0xd7 +'t', # 0xd8 +'y', # 0xd9 +'k', # 0xda +'k', # 0xdb +'l', # 0xdc +'m', # 0xdd +'m', # 0xde +'n', # 0xdf +'n', # 0xe0 +'s', # 0xe1 +'`', # 0xe2 +'p', # 0xe3 +'p', # 0xe4 +'ts', # 0xe5 +'ts', # 0xe6 +'q', # 0xe7 +'r', # 0xe8 +'sh', # 0xe9 +'t', # 0xea +'[?]', # 0xeb +'[?]', # 0xec +'[?]', # 0xed +'[?]', # 0xee +'[?]', # 0xef +'V', # 0xf0 +'oy', # 0xf1 +'i', # 0xf2 +'\'', # 0xf3 +'"', # 0xf4 +'[?]', # 0xf5 +'[?]', # 0xf6 +'[?]', # 0xf7 +'[?]', # 0xf8 +'[?]', # 0xf9 +'[?]', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x006.py b/libs/unidecode/x006.py new file mode 100644 index 00000000..09440b28 --- /dev/null +++ b/libs/unidecode/x006.py @@ -0,0 +1,257 @@ +data = ( +'[?]', # 0x00 +'[?]', # 0x01 +'[?]', # 0x02 +'[?]', # 0x03 +'[?]', # 0x04 +'[?]', # 0x05 +'[?]', # 0x06 +'[?]', # 0x07 +'[?]', # 0x08 +'[?]', # 0x09 +'[?]', # 0x0a +'[?]', # 0x0b +',', # 0x0c +'[?]', # 0x0d +'[?]', # 0x0e +'[?]', # 0x0f +'[?]', # 0x10 +'[?]', # 0x11 +'[?]', # 0x12 +'[?]', # 0x13 +'[?]', # 0x14 +'[?]', # 0x15 +'[?]', # 0x16 +'[?]', # 0x17 +'[?]', # 0x18 +'[?]', # 0x19 +'[?]', # 0x1a +';', # 0x1b +'[?]', # 0x1c +'[?]', # 0x1d +'[?]', # 0x1e +'?', # 0x1f +'[?]', # 0x20 +'', # 0x21 +'a', # 0x22 +'\'', # 0x23 +'w\'', # 0x24 +'', # 0x25 +'y\'', # 0x26 +'', # 0x27 +'b', # 0x28 +'@', # 0x29 +'t', # 0x2a +'th', # 0x2b +'j', # 0x2c +'H', # 0x2d +'kh', # 0x2e +'d', # 0x2f +'dh', # 0x30 +'r', # 0x31 +'z', # 0x32 +'s', # 0x33 +'sh', # 0x34 +'S', # 0x35 +'D', # 0x36 +'T', # 0x37 +'Z', # 0x38 +'`', # 0x39 +'G', # 0x3a +'[?]', # 0x3b +'[?]', # 0x3c +'[?]', # 0x3d +'[?]', # 0x3e +'[?]', # 0x3f +'', # 0x40 +'f', # 0x41 +'q', # 0x42 +'k', # 0x43 +'l', # 0x44 +'m', # 0x45 +'n', # 0x46 +'h', # 0x47 +'w', # 0x48 +'~', # 0x49 +'y', # 0x4a +'an', # 0x4b +'un', # 0x4c +'in', # 0x4d +'a', # 0x4e +'u', # 0x4f +'i', # 0x50 +'W', # 0x51 +'', # 0x52 +'', # 0x53 +'\'', # 0x54 +'\'', # 0x55 +'[?]', # 0x56 +'[?]', # 0x57 +'[?]', # 0x58 +'[?]', # 0x59 +'[?]', # 0x5a +'[?]', # 0x5b +'[?]', # 0x5c +'[?]', # 0x5d +'[?]', # 0x5e +'[?]', # 0x5f +'0', # 0x60 +'1', # 0x61 +'2', # 0x62 +'3', # 0x63 +'4', # 0x64 +'5', # 0x65 +'6', # 0x66 +'7', # 0x67 +'8', # 0x68 +'9', # 0x69 +'%', # 0x6a +'.', # 0x6b +',', # 0x6c +'*', # 0x6d +'[?]', # 0x6e +'[?]', # 0x6f +'', # 0x70 +'\'', # 0x71 +'\'', # 0x72 +'\'', # 0x73 +'', # 0x74 +'\'', # 0x75 +'\'w', # 0x76 +'\'u', # 0x77 +'\'y', # 0x78 +'tt', # 0x79 +'tth', # 0x7a +'b', # 0x7b +'t', # 0x7c +'T', # 0x7d +'p', # 0x7e +'th', # 0x7f +'bh', # 0x80 +'\'h', # 0x81 +'H', # 0x82 +'ny', # 0x83 +'dy', # 0x84 +'H', # 0x85 +'ch', # 0x86 +'cch', # 0x87 +'dd', # 0x88 +'D', # 0x89 +'D', # 0x8a +'Dt', # 0x8b +'dh', # 0x8c +'ddh', # 0x8d +'d', # 0x8e +'D', # 0x8f +'D', # 0x90 +'rr', # 0x91 +'R', # 0x92 +'R', # 0x93 +'R', # 0x94 +'R', # 0x95 +'R', # 0x96 +'R', # 0x97 +'j', # 0x98 +'R', # 0x99 +'S', # 0x9a +'S', # 0x9b +'S', # 0x9c +'S', # 0x9d +'S', # 0x9e +'T', # 0x9f +'GH', # 0xa0 +'F', # 0xa1 +'F', # 0xa2 +'F', # 0xa3 +'v', # 0xa4 +'f', # 0xa5 +'ph', # 0xa6 +'Q', # 0xa7 +'Q', # 0xa8 +'kh', # 0xa9 +'k', # 0xaa +'K', # 0xab +'K', # 0xac +'ng', # 0xad +'K', # 0xae +'g', # 0xaf +'G', # 0xb0 +'N', # 0xb1 +'G', # 0xb2 +'G', # 0xb3 +'G', # 0xb4 +'L', # 0xb5 +'L', # 0xb6 +'L', # 0xb7 +'L', # 0xb8 +'N', # 0xb9 +'N', # 0xba +'N', # 0xbb +'N', # 0xbc +'N', # 0xbd +'h', # 0xbe +'Ch', # 0xbf +'hy', # 0xc0 +'h', # 0xc1 +'H', # 0xc2 +'@', # 0xc3 +'W', # 0xc4 +'oe', # 0xc5 +'oe', # 0xc6 +'u', # 0xc7 +'yu', # 0xc8 +'yu', # 0xc9 +'W', # 0xca +'v', # 0xcb +'y', # 0xcc +'Y', # 0xcd +'Y', # 0xce +'W', # 0xcf +'', # 0xd0 +'', # 0xd1 +'y', # 0xd2 +'y\'', # 0xd3 +'.', # 0xd4 +'ae', # 0xd5 +'', # 0xd6 +'', # 0xd7 +'', # 0xd8 +'', # 0xd9 +'', # 0xda +'', # 0xdb +'', # 0xdc +'@', # 0xdd +'#', # 0xde +'', # 0xdf +'', # 0xe0 +'', # 0xe1 +'', # 0xe2 +'', # 0xe3 +'', # 0xe4 +'', # 0xe5 +'', # 0xe6 +'', # 0xe7 +'', # 0xe8 +'^', # 0xe9 +'', # 0xea +'', # 0xeb +'', # 0xec +'', # 0xed +'[?]', # 0xee +'[?]', # 0xef +'0', # 0xf0 +'1', # 0xf1 +'2', # 0xf2 +'3', # 0xf3 +'4', # 0xf4 +'5', # 0xf5 +'6', # 0xf6 +'7', # 0xf7 +'8', # 0xf8 +'9', # 0xf9 +'Sh', # 0xfa +'D', # 0xfb +'Gh', # 0xfc +'&', # 0xfd +'+m', # 0xfe +) diff --git a/libs/unidecode/x007.py b/libs/unidecode/x007.py new file mode 100644 index 00000000..d2c00213 --- /dev/null +++ b/libs/unidecode/x007.py @@ -0,0 +1,257 @@ +data = ( +'//', # 0x00 +'/', # 0x01 +',', # 0x02 +'!', # 0x03 +'!', # 0x04 +'-', # 0x05 +',', # 0x06 +',', # 0x07 +';', # 0x08 +'?', # 0x09 +'~', # 0x0a +'{', # 0x0b +'}', # 0x0c +'*', # 0x0d +'[?]', # 0x0e +'', # 0x0f +'\'', # 0x10 +'', # 0x11 +'b', # 0x12 +'g', # 0x13 +'g', # 0x14 +'d', # 0x15 +'d', # 0x16 +'h', # 0x17 +'w', # 0x18 +'z', # 0x19 +'H', # 0x1a +'t', # 0x1b +'t', # 0x1c +'y', # 0x1d +'yh', # 0x1e +'k', # 0x1f +'l', # 0x20 +'m', # 0x21 +'n', # 0x22 +'s', # 0x23 +'s', # 0x24 +'`', # 0x25 +'p', # 0x26 +'p', # 0x27 +'S', # 0x28 +'q', # 0x29 +'r', # 0x2a +'sh', # 0x2b +'t', # 0x2c +'[?]', # 0x2d +'[?]', # 0x2e +'[?]', # 0x2f +'a', # 0x30 +'a', # 0x31 +'a', # 0x32 +'A', # 0x33 +'A', # 0x34 +'A', # 0x35 +'e', # 0x36 +'e', # 0x37 +'e', # 0x38 +'E', # 0x39 +'i', # 0x3a +'i', # 0x3b +'u', # 0x3c +'u', # 0x3d +'u', # 0x3e +'o', # 0x3f +'', # 0x40 +'`', # 0x41 +'\'', # 0x42 +'', # 0x43 +'', # 0x44 +'X', # 0x45 +'Q', # 0x46 +'@', # 0x47 +'@', # 0x48 +'|', # 0x49 +'+', # 0x4a +'[?]', # 0x4b +'[?]', # 0x4c +'[?]', # 0x4d +'[?]', # 0x4e +'[?]', # 0x4f +'[?]', # 0x50 +'[?]', # 0x51 +'[?]', # 0x52 +'[?]', # 0x53 +'[?]', # 0x54 +'[?]', # 0x55 +'[?]', # 0x56 +'[?]', # 0x57 +'[?]', # 0x58 +'[?]', # 0x59 +'[?]', # 0x5a +'[?]', # 0x5b +'[?]', # 0x5c +'[?]', # 0x5d +'[?]', # 0x5e +'[?]', # 0x5f +'[?]', # 0x60 +'[?]', # 0x61 +'[?]', # 0x62 +'[?]', # 0x63 +'[?]', # 0x64 +'[?]', # 0x65 +'[?]', # 0x66 +'[?]', # 0x67 +'[?]', # 0x68 +'[?]', # 0x69 +'[?]', # 0x6a +'[?]', # 0x6b +'[?]', # 0x6c +'[?]', # 0x6d +'[?]', # 0x6e +'[?]', # 0x6f +'[?]', # 0x70 +'[?]', # 0x71 +'[?]', # 0x72 +'[?]', # 0x73 +'[?]', # 0x74 +'[?]', # 0x75 +'[?]', # 0x76 +'[?]', # 0x77 +'[?]', # 0x78 +'[?]', # 0x79 +'[?]', # 0x7a +'[?]', # 0x7b +'[?]', # 0x7c +'[?]', # 0x7d +'[?]', # 0x7e +'[?]', # 0x7f +'h', # 0x80 +'sh', # 0x81 +'n', # 0x82 +'r', # 0x83 +'b', # 0x84 +'L', # 0x85 +'k', # 0x86 +'\'', # 0x87 +'v', # 0x88 +'m', # 0x89 +'f', # 0x8a +'dh', # 0x8b +'th', # 0x8c +'l', # 0x8d +'g', # 0x8e +'ny', # 0x8f +'s', # 0x90 +'d', # 0x91 +'z', # 0x92 +'t', # 0x93 +'y', # 0x94 +'p', # 0x95 +'j', # 0x96 +'ch', # 0x97 +'tt', # 0x98 +'hh', # 0x99 +'kh', # 0x9a +'th', # 0x9b +'z', # 0x9c +'sh', # 0x9d +'s', # 0x9e +'d', # 0x9f +'t', # 0xa0 +'z', # 0xa1 +'`', # 0xa2 +'gh', # 0xa3 +'q', # 0xa4 +'w', # 0xa5 +'a', # 0xa6 +'aa', # 0xa7 +'i', # 0xa8 +'ee', # 0xa9 +'u', # 0xaa +'oo', # 0xab +'e', # 0xac +'ey', # 0xad +'o', # 0xae +'oa', # 0xaf +'', # 0xb0 +'[?]', # 0xb1 +'[?]', # 0xb2 +'[?]', # 0xb3 +'[?]', # 0xb4 +'[?]', # 0xb5 +'[?]', # 0xb6 +'[?]', # 0xb7 +'[?]', # 0xb8 +'[?]', # 0xb9 +'[?]', # 0xba +'[?]', # 0xbb +'[?]', # 0xbc +'[?]', # 0xbd +'[?]', # 0xbe +'[?]', # 0xbf +'[?]', # 0xc0 +'[?]', # 0xc1 +'[?]', # 0xc2 +'[?]', # 0xc3 +'[?]', # 0xc4 +'[?]', # 0xc5 +'[?]', # 0xc6 +'[?]', # 0xc7 +'[?]', # 0xc8 +'[?]', # 0xc9 +'[?]', # 0xca +'[?]', # 0xcb +'[?]', # 0xcc +'[?]', # 0xcd +'[?]', # 0xce +'[?]', # 0xcf +'[?]', # 0xd0 +'[?]', # 0xd1 +'[?]', # 0xd2 +'[?]', # 0xd3 +'[?]', # 0xd4 +'[?]', # 0xd5 +'[?]', # 0xd6 +'[?]', # 0xd7 +'[?]', # 0xd8 +'[?]', # 0xd9 +'[?]', # 0xda +'[?]', # 0xdb +'[?]', # 0xdc +'[?]', # 0xdd +'[?]', # 0xde +'[?]', # 0xdf +'[?]', # 0xe0 +'[?]', # 0xe1 +'[?]', # 0xe2 +'[?]', # 0xe3 +'[?]', # 0xe4 +'[?]', # 0xe5 +'[?]', # 0xe6 +'[?]', # 0xe7 +'[?]', # 0xe8 +'[?]', # 0xe9 +'[?]', # 0xea +'[?]', # 0xeb +'[?]', # 0xec +'[?]', # 0xed +'[?]', # 0xee +'[?]', # 0xef +'[?]', # 0xf0 +'[?]', # 0xf1 +'[?]', # 0xf2 +'[?]', # 0xf3 +'[?]', # 0xf4 +'[?]', # 0xf5 +'[?]', # 0xf6 +'[?]', # 0xf7 +'[?]', # 0xf8 +'[?]', # 0xf9 +'[?]', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x009.py b/libs/unidecode/x009.py new file mode 100644 index 00000000..564ec784 --- /dev/null +++ b/libs/unidecode/x009.py @@ -0,0 +1,257 @@ +data = ( +'[?]', # 0x00 +'N', # 0x01 +'N', # 0x02 +'H', # 0x03 +'[?]', # 0x04 +'a', # 0x05 +'aa', # 0x06 +'i', # 0x07 +'ii', # 0x08 +'u', # 0x09 +'uu', # 0x0a +'R', # 0x0b +'L', # 0x0c +'eN', # 0x0d +'e', # 0x0e +'e', # 0x0f +'ai', # 0x10 +'oN', # 0x11 +'o', # 0x12 +'o', # 0x13 +'au', # 0x14 +'k', # 0x15 +'kh', # 0x16 +'g', # 0x17 +'gh', # 0x18 +'ng', # 0x19 +'c', # 0x1a +'ch', # 0x1b +'j', # 0x1c +'jh', # 0x1d +'ny', # 0x1e +'tt', # 0x1f +'tth', # 0x20 +'dd', # 0x21 +'ddh', # 0x22 +'nn', # 0x23 +'t', # 0x24 +'th', # 0x25 +'d', # 0x26 +'dh', # 0x27 +'n', # 0x28 +'nnn', # 0x29 +'p', # 0x2a +'ph', # 0x2b +'b', # 0x2c +'bh', # 0x2d +'m', # 0x2e +'y', # 0x2f +'r', # 0x30 +'rr', # 0x31 +'l', # 0x32 +'l', # 0x33 +'lll', # 0x34 +'v', # 0x35 +'sh', # 0x36 +'ss', # 0x37 +'s', # 0x38 +'h', # 0x39 +'[?]', # 0x3a +'[?]', # 0x3b +'\'', # 0x3c +'\'', # 0x3d +'aa', # 0x3e +'i', # 0x3f +'ii', # 0x40 +'u', # 0x41 +'uu', # 0x42 +'R', # 0x43 +'RR', # 0x44 +'eN', # 0x45 +'e', # 0x46 +'e', # 0x47 +'ai', # 0x48 +'oN', # 0x49 +'o', # 0x4a +'o', # 0x4b +'au', # 0x4c +'', # 0x4d +'[?]', # 0x4e +'[?]', # 0x4f +'AUM', # 0x50 +'\'', # 0x51 +'\'', # 0x52 +'`', # 0x53 +'\'', # 0x54 +'[?]', # 0x55 +'[?]', # 0x56 +'[?]', # 0x57 +'q', # 0x58 +'khh', # 0x59 +'ghh', # 0x5a +'z', # 0x5b +'dddh', # 0x5c +'rh', # 0x5d +'f', # 0x5e +'yy', # 0x5f +'RR', # 0x60 +'LL', # 0x61 +'L', # 0x62 +'LL', # 0x63 +' / ', # 0x64 +' // ', # 0x65 +'0', # 0x66 +'1', # 0x67 +'2', # 0x68 +'3', # 0x69 +'4', # 0x6a +'5', # 0x6b +'6', # 0x6c +'7', # 0x6d +'8', # 0x6e +'9', # 0x6f +'.', # 0x70 +'[?]', # 0x71 +'[?]', # 0x72 +'[?]', # 0x73 +'[?]', # 0x74 +'[?]', # 0x75 +'[?]', # 0x76 +'[?]', # 0x77 +'[?]', # 0x78 +'[?]', # 0x79 +'[?]', # 0x7a +'[?]', # 0x7b +'[?]', # 0x7c +'[?]', # 0x7d +'[?]', # 0x7e +'[?]', # 0x7f +'[?]', # 0x80 +'N', # 0x81 +'N', # 0x82 +'H', # 0x83 +'[?]', # 0x84 +'a', # 0x85 +'aa', # 0x86 +'i', # 0x87 +'ii', # 0x88 +'u', # 0x89 +'uu', # 0x8a +'R', # 0x8b +'RR', # 0x8c +'[?]', # 0x8d +'[?]', # 0x8e +'e', # 0x8f +'ai', # 0x90 +'[?]', # 0x91 +'[?]', # 0x92 +'o', # 0x93 +'au', # 0x94 +'k', # 0x95 +'kh', # 0x96 +'g', # 0x97 +'gh', # 0x98 +'ng', # 0x99 +'c', # 0x9a +'ch', # 0x9b +'j', # 0x9c +'jh', # 0x9d +'ny', # 0x9e +'tt', # 0x9f +'tth', # 0xa0 +'dd', # 0xa1 +'ddh', # 0xa2 +'nn', # 0xa3 +'t', # 0xa4 +'th', # 0xa5 +'d', # 0xa6 +'dh', # 0xa7 +'n', # 0xa8 +'[?]', # 0xa9 +'p', # 0xaa +'ph', # 0xab +'b', # 0xac +'bh', # 0xad +'m', # 0xae +'y', # 0xaf +'r', # 0xb0 +'[?]', # 0xb1 +'l', # 0xb2 +'[?]', # 0xb3 +'[?]', # 0xb4 +'[?]', # 0xb5 +'sh', # 0xb6 +'ss', # 0xb7 +'s', # 0xb8 +'h', # 0xb9 +'[?]', # 0xba +'[?]', # 0xbb +'\'', # 0xbc +'[?]', # 0xbd +'aa', # 0xbe +'i', # 0xbf +'ii', # 0xc0 +'u', # 0xc1 +'uu', # 0xc2 +'R', # 0xc3 +'RR', # 0xc4 +'[?]', # 0xc5 +'[?]', # 0xc6 +'e', # 0xc7 +'ai', # 0xc8 +'[?]', # 0xc9 +'[?]', # 0xca +'o', # 0xcb +'au', # 0xcc +'', # 0xcd +'[?]', # 0xce +'[?]', # 0xcf +'[?]', # 0xd0 +'[?]', # 0xd1 +'[?]', # 0xd2 +'[?]', # 0xd3 +'[?]', # 0xd4 +'[?]', # 0xd5 +'[?]', # 0xd6 +'+', # 0xd7 +'[?]', # 0xd8 +'[?]', # 0xd9 +'[?]', # 0xda +'[?]', # 0xdb +'rr', # 0xdc +'rh', # 0xdd +'[?]', # 0xde +'yy', # 0xdf +'RR', # 0xe0 +'LL', # 0xe1 +'L', # 0xe2 +'LL', # 0xe3 +'[?]', # 0xe4 +'[?]', # 0xe5 +'0', # 0xe6 +'1', # 0xe7 +'2', # 0xe8 +'3', # 0xe9 +'4', # 0xea +'5', # 0xeb +'6', # 0xec +'7', # 0xed +'8', # 0xee +'9', # 0xef +'r\'', # 0xf0 +'r`', # 0xf1 +'Rs', # 0xf2 +'Rs', # 0xf3 +'1/', # 0xf4 +'2/', # 0xf5 +'3/', # 0xf6 +'4/', # 0xf7 +' 1 - 1/', # 0xf8 +'/16', # 0xf9 +'', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x00a.py b/libs/unidecode/x00a.py new file mode 100644 index 00000000..1ccd9df6 --- /dev/null +++ b/libs/unidecode/x00a.py @@ -0,0 +1,257 @@ +data = ( +'[?]', # 0x00 +'[?]', # 0x01 +'N', # 0x02 +'[?]', # 0x03 +'[?]', # 0x04 +'a', # 0x05 +'aa', # 0x06 +'i', # 0x07 +'ii', # 0x08 +'u', # 0x09 +'uu', # 0x0a +'[?]', # 0x0b +'[?]', # 0x0c +'[?]', # 0x0d +'[?]', # 0x0e +'ee', # 0x0f +'ai', # 0x10 +'[?]', # 0x11 +'[?]', # 0x12 +'oo', # 0x13 +'au', # 0x14 +'k', # 0x15 +'kh', # 0x16 +'g', # 0x17 +'gh', # 0x18 +'ng', # 0x19 +'c', # 0x1a +'ch', # 0x1b +'j', # 0x1c +'jh', # 0x1d +'ny', # 0x1e +'tt', # 0x1f +'tth', # 0x20 +'dd', # 0x21 +'ddh', # 0x22 +'nn', # 0x23 +'t', # 0x24 +'th', # 0x25 +'d', # 0x26 +'dh', # 0x27 +'n', # 0x28 +'[?]', # 0x29 +'p', # 0x2a +'ph', # 0x2b +'b', # 0x2c +'bb', # 0x2d +'m', # 0x2e +'y', # 0x2f +'r', # 0x30 +'[?]', # 0x31 +'l', # 0x32 +'ll', # 0x33 +'[?]', # 0x34 +'v', # 0x35 +'sh', # 0x36 +'[?]', # 0x37 +'s', # 0x38 +'h', # 0x39 +'[?]', # 0x3a +'[?]', # 0x3b +'\'', # 0x3c +'[?]', # 0x3d +'aa', # 0x3e +'i', # 0x3f +'ii', # 0x40 +'u', # 0x41 +'uu', # 0x42 +'[?]', # 0x43 +'[?]', # 0x44 +'[?]', # 0x45 +'[?]', # 0x46 +'ee', # 0x47 +'ai', # 0x48 +'[?]', # 0x49 +'[?]', # 0x4a +'oo', # 0x4b +'au', # 0x4c +'', # 0x4d +'[?]', # 0x4e +'[?]', # 0x4f +'[?]', # 0x50 +'[?]', # 0x51 +'[?]', # 0x52 +'[?]', # 0x53 +'[?]', # 0x54 +'[?]', # 0x55 +'[?]', # 0x56 +'[?]', # 0x57 +'[?]', # 0x58 +'khh', # 0x59 +'ghh', # 0x5a +'z', # 0x5b +'rr', # 0x5c +'[?]', # 0x5d +'f', # 0x5e +'[?]', # 0x5f +'[?]', # 0x60 +'[?]', # 0x61 +'[?]', # 0x62 +'[?]', # 0x63 +'[?]', # 0x64 +'[?]', # 0x65 +'0', # 0x66 +'1', # 0x67 +'2', # 0x68 +'3', # 0x69 +'4', # 0x6a +'5', # 0x6b +'6', # 0x6c +'7', # 0x6d +'8', # 0x6e +'9', # 0x6f +'N', # 0x70 +'H', # 0x71 +'', # 0x72 +'', # 0x73 +'G.E.O.', # 0x74 +'[?]', # 0x75 +'[?]', # 0x76 +'[?]', # 0x77 +'[?]', # 0x78 +'[?]', # 0x79 +'[?]', # 0x7a +'[?]', # 0x7b +'[?]', # 0x7c +'[?]', # 0x7d +'[?]', # 0x7e +'[?]', # 0x7f +'[?]', # 0x80 +'N', # 0x81 +'N', # 0x82 +'H', # 0x83 +'[?]', # 0x84 +'a', # 0x85 +'aa', # 0x86 +'i', # 0x87 +'ii', # 0x88 +'u', # 0x89 +'uu', # 0x8a +'R', # 0x8b +'[?]', # 0x8c +'eN', # 0x8d +'[?]', # 0x8e +'e', # 0x8f +'ai', # 0x90 +'oN', # 0x91 +'[?]', # 0x92 +'o', # 0x93 +'au', # 0x94 +'k', # 0x95 +'kh', # 0x96 +'g', # 0x97 +'gh', # 0x98 +'ng', # 0x99 +'c', # 0x9a +'ch', # 0x9b +'j', # 0x9c +'jh', # 0x9d +'ny', # 0x9e +'tt', # 0x9f +'tth', # 0xa0 +'dd', # 0xa1 +'ddh', # 0xa2 +'nn', # 0xa3 +'t', # 0xa4 +'th', # 0xa5 +'d', # 0xa6 +'dh', # 0xa7 +'n', # 0xa8 +'[?]', # 0xa9 +'p', # 0xaa +'ph', # 0xab +'b', # 0xac +'bh', # 0xad +'m', # 0xae +'ya', # 0xaf +'r', # 0xb0 +'[?]', # 0xb1 +'l', # 0xb2 +'ll', # 0xb3 +'[?]', # 0xb4 +'v', # 0xb5 +'sh', # 0xb6 +'ss', # 0xb7 +'s', # 0xb8 +'h', # 0xb9 +'[?]', # 0xba +'[?]', # 0xbb +'\'', # 0xbc +'\'', # 0xbd +'aa', # 0xbe +'i', # 0xbf +'ii', # 0xc0 +'u', # 0xc1 +'uu', # 0xc2 +'R', # 0xc3 +'RR', # 0xc4 +'eN', # 0xc5 +'[?]', # 0xc6 +'e', # 0xc7 +'ai', # 0xc8 +'oN', # 0xc9 +'[?]', # 0xca +'o', # 0xcb +'au', # 0xcc +'', # 0xcd +'[?]', # 0xce +'[?]', # 0xcf +'AUM', # 0xd0 +'[?]', # 0xd1 +'[?]', # 0xd2 +'[?]', # 0xd3 +'[?]', # 0xd4 +'[?]', # 0xd5 +'[?]', # 0xd6 +'[?]', # 0xd7 +'[?]', # 0xd8 +'[?]', # 0xd9 +'[?]', # 0xda +'[?]', # 0xdb +'[?]', # 0xdc +'[?]', # 0xdd +'[?]', # 0xde +'[?]', # 0xdf +'RR', # 0xe0 +'[?]', # 0xe1 +'[?]', # 0xe2 +'[?]', # 0xe3 +'[?]', # 0xe4 +'[?]', # 0xe5 +'0', # 0xe6 +'1', # 0xe7 +'2', # 0xe8 +'3', # 0xe9 +'4', # 0xea +'5', # 0xeb +'6', # 0xec +'7', # 0xed +'8', # 0xee +'9', # 0xef +'[?]', # 0xf0 +'[?]', # 0xf1 +'[?]', # 0xf2 +'[?]', # 0xf3 +'[?]', # 0xf4 +'[?]', # 0xf5 +'[?]', # 0xf6 +'[?]', # 0xf7 +'[?]', # 0xf8 +'[?]', # 0xf9 +'[?]', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x00b.py b/libs/unidecode/x00b.py new file mode 100644 index 00000000..19d18488 --- /dev/null +++ b/libs/unidecode/x00b.py @@ -0,0 +1,257 @@ +data = ( +'[?]', # 0x00 +'N', # 0x01 +'N', # 0x02 +'H', # 0x03 +'[?]', # 0x04 +'a', # 0x05 +'aa', # 0x06 +'i', # 0x07 +'ii', # 0x08 +'u', # 0x09 +'uu', # 0x0a +'R', # 0x0b +'L', # 0x0c +'[?]', # 0x0d +'[?]', # 0x0e +'e', # 0x0f +'ai', # 0x10 +'[?]', # 0x11 +'[?]', # 0x12 +'o', # 0x13 +'au', # 0x14 +'k', # 0x15 +'kh', # 0x16 +'g', # 0x17 +'gh', # 0x18 +'ng', # 0x19 +'c', # 0x1a +'ch', # 0x1b +'j', # 0x1c +'jh', # 0x1d +'ny', # 0x1e +'tt', # 0x1f +'tth', # 0x20 +'dd', # 0x21 +'ddh', # 0x22 +'nn', # 0x23 +'t', # 0x24 +'th', # 0x25 +'d', # 0x26 +'dh', # 0x27 +'n', # 0x28 +'[?]', # 0x29 +'p', # 0x2a +'ph', # 0x2b +'b', # 0x2c +'bh', # 0x2d +'m', # 0x2e +'y', # 0x2f +'r', # 0x30 +'[?]', # 0x31 +'l', # 0x32 +'ll', # 0x33 +'[?]', # 0x34 +'', # 0x35 +'sh', # 0x36 +'ss', # 0x37 +'s', # 0x38 +'h', # 0x39 +'[?]', # 0x3a +'[?]', # 0x3b +'\'', # 0x3c +'\'', # 0x3d +'aa', # 0x3e +'i', # 0x3f +'ii', # 0x40 +'u', # 0x41 +'uu', # 0x42 +'R', # 0x43 +'[?]', # 0x44 +'[?]', # 0x45 +'[?]', # 0x46 +'e', # 0x47 +'ai', # 0x48 +'[?]', # 0x49 +'[?]', # 0x4a +'o', # 0x4b +'au', # 0x4c +'', # 0x4d +'[?]', # 0x4e +'[?]', # 0x4f +'[?]', # 0x50 +'[?]', # 0x51 +'[?]', # 0x52 +'[?]', # 0x53 +'[?]', # 0x54 +'[?]', # 0x55 +'+', # 0x56 +'+', # 0x57 +'[?]', # 0x58 +'[?]', # 0x59 +'[?]', # 0x5a +'[?]', # 0x5b +'rr', # 0x5c +'rh', # 0x5d +'[?]', # 0x5e +'yy', # 0x5f +'RR', # 0x60 +'LL', # 0x61 +'[?]', # 0x62 +'[?]', # 0x63 +'[?]', # 0x64 +'[?]', # 0x65 +'0', # 0x66 +'1', # 0x67 +'2', # 0x68 +'3', # 0x69 +'4', # 0x6a +'5', # 0x6b +'6', # 0x6c +'7', # 0x6d +'8', # 0x6e +'9', # 0x6f +'', # 0x70 +'[?]', # 0x71 +'[?]', # 0x72 +'[?]', # 0x73 +'[?]', # 0x74 +'[?]', # 0x75 +'[?]', # 0x76 +'[?]', # 0x77 +'[?]', # 0x78 +'[?]', # 0x79 +'[?]', # 0x7a +'[?]', # 0x7b +'[?]', # 0x7c +'[?]', # 0x7d +'[?]', # 0x7e +'[?]', # 0x7f +'[?]', # 0x80 +'[?]', # 0x81 +'N', # 0x82 +'H', # 0x83 +'[?]', # 0x84 +'a', # 0x85 +'aa', # 0x86 +'i', # 0x87 +'ii', # 0x88 +'u', # 0x89 +'uu', # 0x8a +'[?]', # 0x8b +'[?]', # 0x8c +'[?]', # 0x8d +'e', # 0x8e +'ee', # 0x8f +'ai', # 0x90 +'[?]', # 0x91 +'o', # 0x92 +'oo', # 0x93 +'au', # 0x94 +'k', # 0x95 +'[?]', # 0x96 +'[?]', # 0x97 +'[?]', # 0x98 +'ng', # 0x99 +'c', # 0x9a +'[?]', # 0x9b +'j', # 0x9c +'[?]', # 0x9d +'ny', # 0x9e +'tt', # 0x9f +'[?]', # 0xa0 +'[?]', # 0xa1 +'[?]', # 0xa2 +'nn', # 0xa3 +'t', # 0xa4 +'[?]', # 0xa5 +'[?]', # 0xa6 +'[?]', # 0xa7 +'n', # 0xa8 +'nnn', # 0xa9 +'p', # 0xaa +'[?]', # 0xab +'[?]', # 0xac +'[?]', # 0xad +'m', # 0xae +'y', # 0xaf +'r', # 0xb0 +'rr', # 0xb1 +'l', # 0xb2 +'ll', # 0xb3 +'lll', # 0xb4 +'v', # 0xb5 +'[?]', # 0xb6 +'ss', # 0xb7 +'s', # 0xb8 +'h', # 0xb9 +'[?]', # 0xba +'[?]', # 0xbb +'[?]', # 0xbc +'[?]', # 0xbd +'aa', # 0xbe +'i', # 0xbf +'ii', # 0xc0 +'u', # 0xc1 +'uu', # 0xc2 +'[?]', # 0xc3 +'[?]', # 0xc4 +'[?]', # 0xc5 +'e', # 0xc6 +'ee', # 0xc7 +'ai', # 0xc8 +'[?]', # 0xc9 +'o', # 0xca +'oo', # 0xcb +'au', # 0xcc +'', # 0xcd +'[?]', # 0xce +'[?]', # 0xcf +'[?]', # 0xd0 +'[?]', # 0xd1 +'[?]', # 0xd2 +'[?]', # 0xd3 +'[?]', # 0xd4 +'[?]', # 0xd5 +'[?]', # 0xd6 +'+', # 0xd7 +'[?]', # 0xd8 +'[?]', # 0xd9 +'[?]', # 0xda +'[?]', # 0xdb +'[?]', # 0xdc +'[?]', # 0xdd +'[?]', # 0xde +'[?]', # 0xdf +'[?]', # 0xe0 +'[?]', # 0xe1 +'[?]', # 0xe2 +'[?]', # 0xe3 +'[?]', # 0xe4 +'[?]', # 0xe5 +'0', # 0xe6 +'1', # 0xe7 +'2', # 0xe8 +'3', # 0xe9 +'4', # 0xea +'5', # 0xeb +'6', # 0xec +'7', # 0xed +'8', # 0xee +'9', # 0xef +'+10+', # 0xf0 +'+100+', # 0xf1 +'+1000+', # 0xf2 +'[?]', # 0xf3 +'[?]', # 0xf4 +'[?]', # 0xf5 +'[?]', # 0xf6 +'[?]', # 0xf7 +'[?]', # 0xf8 +'[?]', # 0xf9 +'[?]', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x00c.py b/libs/unidecode/x00c.py new file mode 100644 index 00000000..56f3654f --- /dev/null +++ b/libs/unidecode/x00c.py @@ -0,0 +1,257 @@ +data = ( +'[?]', # 0x00 +'N', # 0x01 +'N', # 0x02 +'H', # 0x03 +'[?]', # 0x04 +'a', # 0x05 +'aa', # 0x06 +'i', # 0x07 +'ii', # 0x08 +'u', # 0x09 +'uu', # 0x0a +'R', # 0x0b +'L', # 0x0c +'[?]', # 0x0d +'e', # 0x0e +'ee', # 0x0f +'ai', # 0x10 +'[?]', # 0x11 +'o', # 0x12 +'oo', # 0x13 +'au', # 0x14 +'k', # 0x15 +'kh', # 0x16 +'g', # 0x17 +'gh', # 0x18 +'ng', # 0x19 +'c', # 0x1a +'ch', # 0x1b +'j', # 0x1c +'jh', # 0x1d +'ny', # 0x1e +'tt', # 0x1f +'tth', # 0x20 +'dd', # 0x21 +'ddh', # 0x22 +'nn', # 0x23 +'t', # 0x24 +'th', # 0x25 +'d', # 0x26 +'dh', # 0x27 +'n', # 0x28 +'[?]', # 0x29 +'p', # 0x2a +'ph', # 0x2b +'b', # 0x2c +'bh', # 0x2d +'m', # 0x2e +'y', # 0x2f +'r', # 0x30 +'rr', # 0x31 +'l', # 0x32 +'ll', # 0x33 +'[?]', # 0x34 +'v', # 0x35 +'sh', # 0x36 +'ss', # 0x37 +'s', # 0x38 +'h', # 0x39 +'[?]', # 0x3a +'[?]', # 0x3b +'[?]', # 0x3c +'[?]', # 0x3d +'aa', # 0x3e +'i', # 0x3f +'ii', # 0x40 +'u', # 0x41 +'uu', # 0x42 +'R', # 0x43 +'RR', # 0x44 +'[?]', # 0x45 +'e', # 0x46 +'ee', # 0x47 +'ai', # 0x48 +'[?]', # 0x49 +'o', # 0x4a +'oo', # 0x4b +'au', # 0x4c +'', # 0x4d +'[?]', # 0x4e +'[?]', # 0x4f +'[?]', # 0x50 +'[?]', # 0x51 +'[?]', # 0x52 +'[?]', # 0x53 +'[?]', # 0x54 +'+', # 0x55 +'+', # 0x56 +'[?]', # 0x57 +'[?]', # 0x58 +'[?]', # 0x59 +'[?]', # 0x5a +'[?]', # 0x5b +'[?]', # 0x5c +'[?]', # 0x5d +'[?]', # 0x5e +'[?]', # 0x5f +'RR', # 0x60 +'LL', # 0x61 +'[?]', # 0x62 +'[?]', # 0x63 +'[?]', # 0x64 +'[?]', # 0x65 +'0', # 0x66 +'1', # 0x67 +'2', # 0x68 +'3', # 0x69 +'4', # 0x6a +'5', # 0x6b +'6', # 0x6c +'7', # 0x6d +'8', # 0x6e +'9', # 0x6f +'[?]', # 0x70 +'[?]', # 0x71 +'[?]', # 0x72 +'[?]', # 0x73 +'[?]', # 0x74 +'[?]', # 0x75 +'[?]', # 0x76 +'[?]', # 0x77 +'[?]', # 0x78 +'[?]', # 0x79 +'[?]', # 0x7a +'[?]', # 0x7b +'[?]', # 0x7c +'[?]', # 0x7d +'[?]', # 0x7e +'[?]', # 0x7f +'[?]', # 0x80 +'[?]', # 0x81 +'N', # 0x82 +'H', # 0x83 +'[?]', # 0x84 +'a', # 0x85 +'aa', # 0x86 +'i', # 0x87 +'ii', # 0x88 +'u', # 0x89 +'uu', # 0x8a +'R', # 0x8b +'L', # 0x8c +'[?]', # 0x8d +'e', # 0x8e +'ee', # 0x8f +'ai', # 0x90 +'[?]', # 0x91 +'o', # 0x92 +'oo', # 0x93 +'au', # 0x94 +'k', # 0x95 +'kh', # 0x96 +'g', # 0x97 +'gh', # 0x98 +'ng', # 0x99 +'c', # 0x9a +'ch', # 0x9b +'j', # 0x9c +'jh', # 0x9d +'ny', # 0x9e +'tt', # 0x9f +'tth', # 0xa0 +'dd', # 0xa1 +'ddh', # 0xa2 +'nn', # 0xa3 +'t', # 0xa4 +'th', # 0xa5 +'d', # 0xa6 +'dh', # 0xa7 +'n', # 0xa8 +'[?]', # 0xa9 +'p', # 0xaa +'ph', # 0xab +'b', # 0xac +'bh', # 0xad +'m', # 0xae +'y', # 0xaf +'r', # 0xb0 +'rr', # 0xb1 +'l', # 0xb2 +'ll', # 0xb3 +'[?]', # 0xb4 +'v', # 0xb5 +'sh', # 0xb6 +'ss', # 0xb7 +'s', # 0xb8 +'h', # 0xb9 +'[?]', # 0xba +'[?]', # 0xbb +'[?]', # 0xbc +'[?]', # 0xbd +'aa', # 0xbe +'i', # 0xbf +'ii', # 0xc0 +'u', # 0xc1 +'uu', # 0xc2 +'R', # 0xc3 +'RR', # 0xc4 +'[?]', # 0xc5 +'e', # 0xc6 +'ee', # 0xc7 +'ai', # 0xc8 +'[?]', # 0xc9 +'o', # 0xca +'oo', # 0xcb +'au', # 0xcc +'', # 0xcd +'[?]', # 0xce +'[?]', # 0xcf +'[?]', # 0xd0 +'[?]', # 0xd1 +'[?]', # 0xd2 +'[?]', # 0xd3 +'[?]', # 0xd4 +'+', # 0xd5 +'+', # 0xd6 +'[?]', # 0xd7 +'[?]', # 0xd8 +'[?]', # 0xd9 +'[?]', # 0xda +'[?]', # 0xdb +'[?]', # 0xdc +'[?]', # 0xdd +'lll', # 0xde +'[?]', # 0xdf +'RR', # 0xe0 +'LL', # 0xe1 +'[?]', # 0xe2 +'[?]', # 0xe3 +'[?]', # 0xe4 +'[?]', # 0xe5 +'0', # 0xe6 +'1', # 0xe7 +'2', # 0xe8 +'3', # 0xe9 +'4', # 0xea +'5', # 0xeb +'6', # 0xec +'7', # 0xed +'8', # 0xee +'9', # 0xef +'[?]', # 0xf0 +'[?]', # 0xf1 +'[?]', # 0xf2 +'[?]', # 0xf3 +'[?]', # 0xf4 +'[?]', # 0xf5 +'[?]', # 0xf6 +'[?]', # 0xf7 +'[?]', # 0xf8 +'[?]', # 0xf9 +'[?]', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x00d.py b/libs/unidecode/x00d.py new file mode 100644 index 00000000..d105c437 --- /dev/null +++ b/libs/unidecode/x00d.py @@ -0,0 +1,257 @@ +data = ( +'[?]', # 0x00 +'[?]', # 0x01 +'N', # 0x02 +'H', # 0x03 +'[?]', # 0x04 +'a', # 0x05 +'aa', # 0x06 +'i', # 0x07 +'ii', # 0x08 +'u', # 0x09 +'uu', # 0x0a +'R', # 0x0b +'L', # 0x0c +'[?]', # 0x0d +'e', # 0x0e +'ee', # 0x0f +'ai', # 0x10 +'[?]', # 0x11 +'o', # 0x12 +'oo', # 0x13 +'au', # 0x14 +'k', # 0x15 +'kh', # 0x16 +'g', # 0x17 +'gh', # 0x18 +'ng', # 0x19 +'c', # 0x1a +'ch', # 0x1b +'j', # 0x1c +'jh', # 0x1d +'ny', # 0x1e +'tt', # 0x1f +'tth', # 0x20 +'dd', # 0x21 +'ddh', # 0x22 +'nn', # 0x23 +'t', # 0x24 +'th', # 0x25 +'d', # 0x26 +'dh', # 0x27 +'n', # 0x28 +'[?]', # 0x29 +'p', # 0x2a +'ph', # 0x2b +'b', # 0x2c +'bh', # 0x2d +'m', # 0x2e +'y', # 0x2f +'r', # 0x30 +'rr', # 0x31 +'l', # 0x32 +'ll', # 0x33 +'lll', # 0x34 +'v', # 0x35 +'sh', # 0x36 +'ss', # 0x37 +'s', # 0x38 +'h', # 0x39 +'[?]', # 0x3a +'[?]', # 0x3b +'[?]', # 0x3c +'[?]', # 0x3d +'aa', # 0x3e +'i', # 0x3f +'ii', # 0x40 +'u', # 0x41 +'uu', # 0x42 +'R', # 0x43 +'[?]', # 0x44 +'[?]', # 0x45 +'e', # 0x46 +'ee', # 0x47 +'ai', # 0x48 +'', # 0x49 +'o', # 0x4a +'oo', # 0x4b +'au', # 0x4c +'', # 0x4d +'[?]', # 0x4e +'[?]', # 0x4f +'[?]', # 0x50 +'[?]', # 0x51 +'[?]', # 0x52 +'[?]', # 0x53 +'[?]', # 0x54 +'[?]', # 0x55 +'[?]', # 0x56 +'+', # 0x57 +'[?]', # 0x58 +'[?]', # 0x59 +'[?]', # 0x5a +'[?]', # 0x5b +'[?]', # 0x5c +'[?]', # 0x5d +'[?]', # 0x5e +'[?]', # 0x5f +'RR', # 0x60 +'LL', # 0x61 +'[?]', # 0x62 +'[?]', # 0x63 +'[?]', # 0x64 +'[?]', # 0x65 +'0', # 0x66 +'1', # 0x67 +'2', # 0x68 +'3', # 0x69 +'4', # 0x6a +'5', # 0x6b +'6', # 0x6c +'7', # 0x6d +'8', # 0x6e +'9', # 0x6f +'[?]', # 0x70 +'[?]', # 0x71 +'[?]', # 0x72 +'[?]', # 0x73 +'[?]', # 0x74 +'[?]', # 0x75 +'[?]', # 0x76 +'[?]', # 0x77 +'[?]', # 0x78 +'[?]', # 0x79 +'[?]', # 0x7a +'[?]', # 0x7b +'[?]', # 0x7c +'[?]', # 0x7d +'[?]', # 0x7e +'[?]', # 0x7f +'[?]', # 0x80 +'[?]', # 0x81 +'N', # 0x82 +'H', # 0x83 +'[?]', # 0x84 +'a', # 0x85 +'aa', # 0x86 +'ae', # 0x87 +'aae', # 0x88 +'i', # 0x89 +'ii', # 0x8a +'u', # 0x8b +'uu', # 0x8c +'R', # 0x8d +'RR', # 0x8e +'L', # 0x8f +'LL', # 0x90 +'e', # 0x91 +'ee', # 0x92 +'ai', # 0x93 +'o', # 0x94 +'oo', # 0x95 +'au', # 0x96 +'[?]', # 0x97 +'[?]', # 0x98 +'[?]', # 0x99 +'k', # 0x9a +'kh', # 0x9b +'g', # 0x9c +'gh', # 0x9d +'ng', # 0x9e +'nng', # 0x9f +'c', # 0xa0 +'ch', # 0xa1 +'j', # 0xa2 +'jh', # 0xa3 +'ny', # 0xa4 +'jny', # 0xa5 +'nyj', # 0xa6 +'tt', # 0xa7 +'tth', # 0xa8 +'dd', # 0xa9 +'ddh', # 0xaa +'nn', # 0xab +'nndd', # 0xac +'t', # 0xad +'th', # 0xae +'d', # 0xaf +'dh', # 0xb0 +'n', # 0xb1 +'[?]', # 0xb2 +'nd', # 0xb3 +'p', # 0xb4 +'ph', # 0xb5 +'b', # 0xb6 +'bh', # 0xb7 +'m', # 0xb8 +'mb', # 0xb9 +'y', # 0xba +'r', # 0xbb +'[?]', # 0xbc +'l', # 0xbd +'[?]', # 0xbe +'[?]', # 0xbf +'v', # 0xc0 +'sh', # 0xc1 +'ss', # 0xc2 +'s', # 0xc3 +'h', # 0xc4 +'ll', # 0xc5 +'f', # 0xc6 +'[?]', # 0xc7 +'[?]', # 0xc8 +'[?]', # 0xc9 +'', # 0xca +'[?]', # 0xcb +'[?]', # 0xcc +'[?]', # 0xcd +'[?]', # 0xce +'aa', # 0xcf +'ae', # 0xd0 +'aae', # 0xd1 +'i', # 0xd2 +'ii', # 0xd3 +'u', # 0xd4 +'[?]', # 0xd5 +'uu', # 0xd6 +'[?]', # 0xd7 +'R', # 0xd8 +'e', # 0xd9 +'ee', # 0xda +'ai', # 0xdb +'o', # 0xdc +'oo', # 0xdd +'au', # 0xde +'L', # 0xdf +'[?]', # 0xe0 +'[?]', # 0xe1 +'[?]', # 0xe2 +'[?]', # 0xe3 +'[?]', # 0xe4 +'[?]', # 0xe5 +'[?]', # 0xe6 +'[?]', # 0xe7 +'[?]', # 0xe8 +'[?]', # 0xe9 +'[?]', # 0xea +'[?]', # 0xeb +'[?]', # 0xec +'[?]', # 0xed +'[?]', # 0xee +'[?]', # 0xef +'[?]', # 0xf0 +'[?]', # 0xf1 +'RR', # 0xf2 +'LL', # 0xf3 +' . ', # 0xf4 +'[?]', # 0xf5 +'[?]', # 0xf6 +'[?]', # 0xf7 +'[?]', # 0xf8 +'[?]', # 0xf9 +'[?]', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x00e.py b/libs/unidecode/x00e.py new file mode 100644 index 00000000..775b5f4a --- /dev/null +++ b/libs/unidecode/x00e.py @@ -0,0 +1,257 @@ +data = ( +'[?]', # 0x00 +'k', # 0x01 +'kh', # 0x02 +'kh', # 0x03 +'kh', # 0x04 +'kh', # 0x05 +'kh', # 0x06 +'ng', # 0x07 +'cch', # 0x08 +'ch', # 0x09 +'ch', # 0x0a +'ch', # 0x0b +'ch', # 0x0c +'y', # 0x0d +'d', # 0x0e +'t', # 0x0f +'th', # 0x10 +'th', # 0x11 +'th', # 0x12 +'n', # 0x13 +'d', # 0x14 +'t', # 0x15 +'th', # 0x16 +'th', # 0x17 +'th', # 0x18 +'n', # 0x19 +'b', # 0x1a +'p', # 0x1b +'ph', # 0x1c +'f', # 0x1d +'ph', # 0x1e +'f', # 0x1f +'ph', # 0x20 +'m', # 0x21 +'y', # 0x22 +'r', # 0x23 +'R', # 0x24 +'l', # 0x25 +'L', # 0x26 +'w', # 0x27 +'s', # 0x28 +'s', # 0x29 +'s', # 0x2a +'h', # 0x2b +'l', # 0x2c +'`', # 0x2d +'h', # 0x2e +'~', # 0x2f +'a', # 0x30 +'a', # 0x31 +'aa', # 0x32 +'am', # 0x33 +'i', # 0x34 +'ii', # 0x35 +'ue', # 0x36 +'uue', # 0x37 +'u', # 0x38 +'uu', # 0x39 +'\'', # 0x3a +'[?]', # 0x3b +'[?]', # 0x3c +'[?]', # 0x3d +'[?]', # 0x3e +'Bh.', # 0x3f +'e', # 0x40 +'ae', # 0x41 +'o', # 0x42 +'ai', # 0x43 +'ai', # 0x44 +'ao', # 0x45 +'+', # 0x46 +'', # 0x47 +'', # 0x48 +'', # 0x49 +'', # 0x4a +'', # 0x4b +'', # 0x4c +'M', # 0x4d +'', # 0x4e +' * ', # 0x4f +'0', # 0x50 +'1', # 0x51 +'2', # 0x52 +'3', # 0x53 +'4', # 0x54 +'5', # 0x55 +'6', # 0x56 +'7', # 0x57 +'8', # 0x58 +'9', # 0x59 +' // ', # 0x5a +' /// ', # 0x5b +'[?]', # 0x5c +'[?]', # 0x5d +'[?]', # 0x5e +'[?]', # 0x5f +'[?]', # 0x60 +'[?]', # 0x61 +'[?]', # 0x62 +'[?]', # 0x63 +'[?]', # 0x64 +'[?]', # 0x65 +'[?]', # 0x66 +'[?]', # 0x67 +'[?]', # 0x68 +'[?]', # 0x69 +'[?]', # 0x6a +'[?]', # 0x6b +'[?]', # 0x6c +'[?]', # 0x6d +'[?]', # 0x6e +'[?]', # 0x6f +'[?]', # 0x70 +'[?]', # 0x71 +'[?]', # 0x72 +'[?]', # 0x73 +'[?]', # 0x74 +'[?]', # 0x75 +'[?]', # 0x76 +'[?]', # 0x77 +'[?]', # 0x78 +'[?]', # 0x79 +'[?]', # 0x7a +'[?]', # 0x7b +'[?]', # 0x7c +'[?]', # 0x7d +'[?]', # 0x7e +'[?]', # 0x7f +'[?]', # 0x80 +'k', # 0x81 +'kh', # 0x82 +'[?]', # 0x83 +'kh', # 0x84 +'[?]', # 0x85 +'[?]', # 0x86 +'ng', # 0x87 +'ch', # 0x88 +'[?]', # 0x89 +'s', # 0x8a +'[?]', # 0x8b +'[?]', # 0x8c +'ny', # 0x8d +'[?]', # 0x8e +'[?]', # 0x8f +'[?]', # 0x90 +'[?]', # 0x91 +'[?]', # 0x92 +'[?]', # 0x93 +'d', # 0x94 +'h', # 0x95 +'th', # 0x96 +'th', # 0x97 +'[?]', # 0x98 +'n', # 0x99 +'b', # 0x9a +'p', # 0x9b +'ph', # 0x9c +'f', # 0x9d +'ph', # 0x9e +'f', # 0x9f +'[?]', # 0xa0 +'m', # 0xa1 +'y', # 0xa2 +'r', # 0xa3 +'[?]', # 0xa4 +'l', # 0xa5 +'[?]', # 0xa6 +'w', # 0xa7 +'[?]', # 0xa8 +'[?]', # 0xa9 +'s', # 0xaa +'h', # 0xab +'[?]', # 0xac +'`', # 0xad +'', # 0xae +'~', # 0xaf +'a', # 0xb0 +'', # 0xb1 +'aa', # 0xb2 +'am', # 0xb3 +'i', # 0xb4 +'ii', # 0xb5 +'y', # 0xb6 +'yy', # 0xb7 +'u', # 0xb8 +'uu', # 0xb9 +'[?]', # 0xba +'o', # 0xbb +'l', # 0xbc +'ny', # 0xbd +'[?]', # 0xbe +'[?]', # 0xbf +'e', # 0xc0 +'ei', # 0xc1 +'o', # 0xc2 +'ay', # 0xc3 +'ai', # 0xc4 +'[?]', # 0xc5 +'+', # 0xc6 +'[?]', # 0xc7 +'', # 0xc8 +'', # 0xc9 +'', # 0xca +'', # 0xcb +'', # 0xcc +'M', # 0xcd +'[?]', # 0xce +'[?]', # 0xcf +'0', # 0xd0 +'1', # 0xd1 +'2', # 0xd2 +'3', # 0xd3 +'4', # 0xd4 +'5', # 0xd5 +'6', # 0xd6 +'7', # 0xd7 +'8', # 0xd8 +'9', # 0xd9 +'[?]', # 0xda +'[?]', # 0xdb +'hn', # 0xdc +'hm', # 0xdd +'[?]', # 0xde +'[?]', # 0xdf +'[?]', # 0xe0 +'[?]', # 0xe1 +'[?]', # 0xe2 +'[?]', # 0xe3 +'[?]', # 0xe4 +'[?]', # 0xe5 +'[?]', # 0xe6 +'[?]', # 0xe7 +'[?]', # 0xe8 +'[?]', # 0xe9 +'[?]', # 0xea +'[?]', # 0xeb +'[?]', # 0xec +'[?]', # 0xed +'[?]', # 0xee +'[?]', # 0xef +'[?]', # 0xf0 +'[?]', # 0xf1 +'[?]', # 0xf2 +'[?]', # 0xf3 +'[?]', # 0xf4 +'[?]', # 0xf5 +'[?]', # 0xf6 +'[?]', # 0xf7 +'[?]', # 0xf8 +'[?]', # 0xf9 +'[?]', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x00f.py b/libs/unidecode/x00f.py new file mode 100644 index 00000000..4c2410e0 --- /dev/null +++ b/libs/unidecode/x00f.py @@ -0,0 +1,257 @@ +data = ( +'AUM', # 0x00 +'', # 0x01 +'', # 0x02 +'', # 0x03 +'', # 0x04 +'', # 0x05 +'', # 0x06 +'', # 0x07 +' // ', # 0x08 +' * ', # 0x09 +'', # 0x0a +'-', # 0x0b +' / ', # 0x0c +' / ', # 0x0d +' // ', # 0x0e +' -/ ', # 0x0f +' +/ ', # 0x10 +' X/ ', # 0x11 +' /XX/ ', # 0x12 +' /X/ ', # 0x13 +', ', # 0x14 +'', # 0x15 +'', # 0x16 +'', # 0x17 +'', # 0x18 +'', # 0x19 +'', # 0x1a +'', # 0x1b +'', # 0x1c +'', # 0x1d +'', # 0x1e +'', # 0x1f +'0', # 0x20 +'1', # 0x21 +'2', # 0x22 +'3', # 0x23 +'4', # 0x24 +'5', # 0x25 +'6', # 0x26 +'7', # 0x27 +'8', # 0x28 +'9', # 0x29 +'.5', # 0x2a +'1.5', # 0x2b +'2.5', # 0x2c +'3.5', # 0x2d +'4.5', # 0x2e +'5.5', # 0x2f +'6.5', # 0x30 +'7.5', # 0x31 +'8.5', # 0x32 +'-.5', # 0x33 +'+', # 0x34 +'*', # 0x35 +'^', # 0x36 +'_', # 0x37 +'', # 0x38 +'~', # 0x39 +'[?]', # 0x3a +']', # 0x3b +'[[', # 0x3c +']]', # 0x3d +'', # 0x3e +'', # 0x3f +'k', # 0x40 +'kh', # 0x41 +'g', # 0x42 +'gh', # 0x43 +'ng', # 0x44 +'c', # 0x45 +'ch', # 0x46 +'j', # 0x47 +'[?]', # 0x48 +'ny', # 0x49 +'tt', # 0x4a +'tth', # 0x4b +'dd', # 0x4c +'ddh', # 0x4d +'nn', # 0x4e +'t', # 0x4f +'th', # 0x50 +'d', # 0x51 +'dh', # 0x52 +'n', # 0x53 +'p', # 0x54 +'ph', # 0x55 +'b', # 0x56 +'bh', # 0x57 +'m', # 0x58 +'ts', # 0x59 +'tsh', # 0x5a +'dz', # 0x5b +'dzh', # 0x5c +'w', # 0x5d +'zh', # 0x5e +'z', # 0x5f +'\'', # 0x60 +'y', # 0x61 +'r', # 0x62 +'l', # 0x63 +'sh', # 0x64 +'ssh', # 0x65 +'s', # 0x66 +'h', # 0x67 +'a', # 0x68 +'kss', # 0x69 +'r', # 0x6a +'[?]', # 0x6b +'[?]', # 0x6c +'[?]', # 0x6d +'[?]', # 0x6e +'[?]', # 0x6f +'[?]', # 0x70 +'aa', # 0x71 +'i', # 0x72 +'ii', # 0x73 +'u', # 0x74 +'uu', # 0x75 +'R', # 0x76 +'RR', # 0x77 +'L', # 0x78 +'LL', # 0x79 +'e', # 0x7a +'ee', # 0x7b +'o', # 0x7c +'oo', # 0x7d +'M', # 0x7e +'H', # 0x7f +'i', # 0x80 +'ii', # 0x81 +'', # 0x82 +'', # 0x83 +'', # 0x84 +'', # 0x85 +'', # 0x86 +'', # 0x87 +'', # 0x88 +'', # 0x89 +'', # 0x8a +'', # 0x8b +'[?]', # 0x8c +'[?]', # 0x8d +'[?]', # 0x8e +'[?]', # 0x8f +'k', # 0x90 +'kh', # 0x91 +'g', # 0x92 +'gh', # 0x93 +'ng', # 0x94 +'c', # 0x95 +'ch', # 0x96 +'j', # 0x97 +'[?]', # 0x98 +'ny', # 0x99 +'tt', # 0x9a +'tth', # 0x9b +'dd', # 0x9c +'ddh', # 0x9d +'nn', # 0x9e +'t', # 0x9f +'th', # 0xa0 +'d', # 0xa1 +'dh', # 0xa2 +'n', # 0xa3 +'p', # 0xa4 +'ph', # 0xa5 +'b', # 0xa6 +'bh', # 0xa7 +'m', # 0xa8 +'ts', # 0xa9 +'tsh', # 0xaa +'dz', # 0xab +'dzh', # 0xac +'w', # 0xad +'zh', # 0xae +'z', # 0xaf +'\'', # 0xb0 +'y', # 0xb1 +'r', # 0xb2 +'l', # 0xb3 +'sh', # 0xb4 +'ss', # 0xb5 +'s', # 0xb6 +'h', # 0xb7 +'a', # 0xb8 +'kss', # 0xb9 +'w', # 0xba +'y', # 0xbb +'r', # 0xbc +'[?]', # 0xbd +'X', # 0xbe +' :X: ', # 0xbf +' /O/ ', # 0xc0 +' /o/ ', # 0xc1 +' \\o\\ ', # 0xc2 +' (O) ', # 0xc3 +'', # 0xc4 +'', # 0xc5 +'', # 0xc6 +'', # 0xc7 +'', # 0xc8 +'', # 0xc9 +'', # 0xca +'', # 0xcb +'', # 0xcc +'[?]', # 0xcd +'[?]', # 0xce +'', # 0xcf +'[?]', # 0xd0 +'[?]', # 0xd1 +'[?]', # 0xd2 +'[?]', # 0xd3 +'[?]', # 0xd4 +'[?]', # 0xd5 +'[?]', # 0xd6 +'[?]', # 0xd7 +'[?]', # 0xd8 +'[?]', # 0xd9 +'[?]', # 0xda +'[?]', # 0xdb +'[?]', # 0xdc +'[?]', # 0xdd +'[?]', # 0xde +'[?]', # 0xdf +'[?]', # 0xe0 +'[?]', # 0xe1 +'[?]', # 0xe2 +'[?]', # 0xe3 +'[?]', # 0xe4 +'[?]', # 0xe5 +'[?]', # 0xe6 +'[?]', # 0xe7 +'[?]', # 0xe8 +'[?]', # 0xe9 +'[?]', # 0xea +'[?]', # 0xeb +'[?]', # 0xec +'[?]', # 0xed +'[?]', # 0xee +'[?]', # 0xef +'[?]', # 0xf0 +'[?]', # 0xf1 +'[?]', # 0xf2 +'[?]', # 0xf3 +'[?]', # 0xf4 +'[?]', # 0xf5 +'[?]', # 0xf6 +'[?]', # 0xf7 +'[?]', # 0xf8 +'[?]', # 0xf9 +'[?]', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x010.py b/libs/unidecode/x010.py new file mode 100644 index 00000000..aaf820d9 --- /dev/null +++ b/libs/unidecode/x010.py @@ -0,0 +1,257 @@ +data = ( +'k', # 0x00 +'kh', # 0x01 +'g', # 0x02 +'gh', # 0x03 +'ng', # 0x04 +'c', # 0x05 +'ch', # 0x06 +'j', # 0x07 +'jh', # 0x08 +'ny', # 0x09 +'nny', # 0x0a +'tt', # 0x0b +'tth', # 0x0c +'dd', # 0x0d +'ddh', # 0x0e +'nn', # 0x0f +'tt', # 0x10 +'th', # 0x11 +'d', # 0x12 +'dh', # 0x13 +'n', # 0x14 +'p', # 0x15 +'ph', # 0x16 +'b', # 0x17 +'bh', # 0x18 +'m', # 0x19 +'y', # 0x1a +'r', # 0x1b +'l', # 0x1c +'w', # 0x1d +'s', # 0x1e +'h', # 0x1f +'ll', # 0x20 +'a', # 0x21 +'[?]', # 0x22 +'i', # 0x23 +'ii', # 0x24 +'u', # 0x25 +'uu', # 0x26 +'e', # 0x27 +'[?]', # 0x28 +'o', # 0x29 +'au', # 0x2a +'[?]', # 0x2b +'aa', # 0x2c +'i', # 0x2d +'ii', # 0x2e +'u', # 0x2f +'uu', # 0x30 +'e', # 0x31 +'ai', # 0x32 +'[?]', # 0x33 +'[?]', # 0x34 +'[?]', # 0x35 +'N', # 0x36 +'\'', # 0x37 +':', # 0x38 +'', # 0x39 +'[?]', # 0x3a +'[?]', # 0x3b +'[?]', # 0x3c +'[?]', # 0x3d +'[?]', # 0x3e +'[?]', # 0x3f +'0', # 0x40 +'1', # 0x41 +'2', # 0x42 +'3', # 0x43 +'4', # 0x44 +'5', # 0x45 +'6', # 0x46 +'7', # 0x47 +'8', # 0x48 +'9', # 0x49 +' / ', # 0x4a +' // ', # 0x4b +'n*', # 0x4c +'r*', # 0x4d +'l*', # 0x4e +'e*', # 0x4f +'sh', # 0x50 +'ss', # 0x51 +'R', # 0x52 +'RR', # 0x53 +'L', # 0x54 +'LL', # 0x55 +'R', # 0x56 +'RR', # 0x57 +'L', # 0x58 +'LL', # 0x59 +'[?]', # 0x5a +'[?]', # 0x5b +'[?]', # 0x5c +'[?]', # 0x5d +'[?]', # 0x5e +'[?]', # 0x5f +'[?]', # 0x60 +'[?]', # 0x61 +'[?]', # 0x62 +'[?]', # 0x63 +'[?]', # 0x64 +'[?]', # 0x65 +'[?]', # 0x66 +'[?]', # 0x67 +'[?]', # 0x68 +'[?]', # 0x69 +'[?]', # 0x6a +'[?]', # 0x6b +'[?]', # 0x6c +'[?]', # 0x6d +'[?]', # 0x6e +'[?]', # 0x6f +'[?]', # 0x70 +'[?]', # 0x71 +'[?]', # 0x72 +'[?]', # 0x73 +'[?]', # 0x74 +'[?]', # 0x75 +'[?]', # 0x76 +'[?]', # 0x77 +'[?]', # 0x78 +'[?]', # 0x79 +'[?]', # 0x7a +'[?]', # 0x7b +'[?]', # 0x7c +'[?]', # 0x7d +'[?]', # 0x7e +'[?]', # 0x7f +'[?]', # 0x80 +'[?]', # 0x81 +'[?]', # 0x82 +'[?]', # 0x83 +'[?]', # 0x84 +'[?]', # 0x85 +'[?]', # 0x86 +'[?]', # 0x87 +'[?]', # 0x88 +'[?]', # 0x89 +'[?]', # 0x8a +'[?]', # 0x8b +'[?]', # 0x8c +'[?]', # 0x8d +'[?]', # 0x8e +'[?]', # 0x8f +'[?]', # 0x90 +'[?]', # 0x91 +'[?]', # 0x92 +'[?]', # 0x93 +'[?]', # 0x94 +'[?]', # 0x95 +'[?]', # 0x96 +'[?]', # 0x97 +'[?]', # 0x98 +'[?]', # 0x99 +'[?]', # 0x9a +'[?]', # 0x9b +'[?]', # 0x9c +'[?]', # 0x9d +'[?]', # 0x9e +'[?]', # 0x9f +'A', # 0xa0 +'B', # 0xa1 +'G', # 0xa2 +'D', # 0xa3 +'E', # 0xa4 +'V', # 0xa5 +'Z', # 0xa6 +'T`', # 0xa7 +'I', # 0xa8 +'K', # 0xa9 +'L', # 0xaa +'M', # 0xab +'N', # 0xac +'O', # 0xad +'P', # 0xae +'Zh', # 0xaf +'R', # 0xb0 +'S', # 0xb1 +'T', # 0xb2 +'U', # 0xb3 +'P`', # 0xb4 +'K`', # 0xb5 +'G\'', # 0xb6 +'Q', # 0xb7 +'Sh', # 0xb8 +'Ch`', # 0xb9 +'C`', # 0xba +'Z\'', # 0xbb +'C', # 0xbc +'Ch', # 0xbd +'X', # 0xbe +'J', # 0xbf +'H', # 0xc0 +'E', # 0xc1 +'Y', # 0xc2 +'W', # 0xc3 +'Xh', # 0xc4 +'OE', # 0xc5 +'[?]', # 0xc6 +'[?]', # 0xc7 +'[?]', # 0xc8 +'[?]', # 0xc9 +'[?]', # 0xca +'[?]', # 0xcb +'[?]', # 0xcc +'[?]', # 0xcd +'[?]', # 0xce +'[?]', # 0xcf +'a', # 0xd0 +'b', # 0xd1 +'g', # 0xd2 +'d', # 0xd3 +'e', # 0xd4 +'v', # 0xd5 +'z', # 0xd6 +'t`', # 0xd7 +'i', # 0xd8 +'k', # 0xd9 +'l', # 0xda +'m', # 0xdb +'n', # 0xdc +'o', # 0xdd +'p', # 0xde +'zh', # 0xdf +'r', # 0xe0 +'s', # 0xe1 +'t', # 0xe2 +'u', # 0xe3 +'p`', # 0xe4 +'k`', # 0xe5 +'g\'', # 0xe6 +'q', # 0xe7 +'sh', # 0xe8 +'ch`', # 0xe9 +'c`', # 0xea +'z\'', # 0xeb +'c', # 0xec +'ch', # 0xed +'x', # 0xee +'j', # 0xef +'h', # 0xf0 +'e', # 0xf1 +'y', # 0xf2 +'w', # 0xf3 +'xh', # 0xf4 +'oe', # 0xf5 +'f', # 0xf6 +'[?]', # 0xf7 +'[?]', # 0xf8 +'[?]', # 0xf9 +'[?]', # 0xfa +' // ', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x011.py b/libs/unidecode/x011.py new file mode 100644 index 00000000..f0d8f929 --- /dev/null +++ b/libs/unidecode/x011.py @@ -0,0 +1,257 @@ +data = ( +'g', # 0x00 +'gg', # 0x01 +'n', # 0x02 +'d', # 0x03 +'dd', # 0x04 +'r', # 0x05 +'m', # 0x06 +'b', # 0x07 +'bb', # 0x08 +'s', # 0x09 +'ss', # 0x0a +'', # 0x0b +'j', # 0x0c +'jj', # 0x0d +'c', # 0x0e +'k', # 0x0f +'t', # 0x10 +'p', # 0x11 +'h', # 0x12 +'ng', # 0x13 +'nn', # 0x14 +'nd', # 0x15 +'nb', # 0x16 +'dg', # 0x17 +'rn', # 0x18 +'rr', # 0x19 +'rh', # 0x1a +'rN', # 0x1b +'mb', # 0x1c +'mN', # 0x1d +'bg', # 0x1e +'bn', # 0x1f +'', # 0x20 +'bs', # 0x21 +'bsg', # 0x22 +'bst', # 0x23 +'bsb', # 0x24 +'bss', # 0x25 +'bsj', # 0x26 +'bj', # 0x27 +'bc', # 0x28 +'bt', # 0x29 +'bp', # 0x2a +'bN', # 0x2b +'bbN', # 0x2c +'sg', # 0x2d +'sn', # 0x2e +'sd', # 0x2f +'sr', # 0x30 +'sm', # 0x31 +'sb', # 0x32 +'sbg', # 0x33 +'sss', # 0x34 +'s', # 0x35 +'sj', # 0x36 +'sc', # 0x37 +'sk', # 0x38 +'st', # 0x39 +'sp', # 0x3a +'sh', # 0x3b +'', # 0x3c +'', # 0x3d +'', # 0x3e +'', # 0x3f +'Z', # 0x40 +'g', # 0x41 +'d', # 0x42 +'m', # 0x43 +'b', # 0x44 +'s', # 0x45 +'Z', # 0x46 +'', # 0x47 +'j', # 0x48 +'c', # 0x49 +'t', # 0x4a +'p', # 0x4b +'N', # 0x4c +'j', # 0x4d +'', # 0x4e +'', # 0x4f +'', # 0x50 +'', # 0x51 +'ck', # 0x52 +'ch', # 0x53 +'', # 0x54 +'', # 0x55 +'pb', # 0x56 +'pN', # 0x57 +'hh', # 0x58 +'Q', # 0x59 +'[?]', # 0x5a +'[?]', # 0x5b +'[?]', # 0x5c +'[?]', # 0x5d +'[?]', # 0x5e +'', # 0x5f +'', # 0x60 +'a', # 0x61 +'ae', # 0x62 +'ya', # 0x63 +'yae', # 0x64 +'eo', # 0x65 +'e', # 0x66 +'yeo', # 0x67 +'ye', # 0x68 +'o', # 0x69 +'wa', # 0x6a +'wae', # 0x6b +'oe', # 0x6c +'yo', # 0x6d +'u', # 0x6e +'weo', # 0x6f +'we', # 0x70 +'wi', # 0x71 +'yu', # 0x72 +'eu', # 0x73 +'yi', # 0x74 +'i', # 0x75 +'a-o', # 0x76 +'a-u', # 0x77 +'ya-o', # 0x78 +'ya-yo', # 0x79 +'eo-o', # 0x7a +'eo-u', # 0x7b +'eo-eu', # 0x7c +'yeo-o', # 0x7d +'yeo-u', # 0x7e +'o-eo', # 0x7f +'o-e', # 0x80 +'o-ye', # 0x81 +'o-o', # 0x82 +'o-u', # 0x83 +'yo-ya', # 0x84 +'yo-yae', # 0x85 +'yo-yeo', # 0x86 +'yo-o', # 0x87 +'yo-i', # 0x88 +'u-a', # 0x89 +'u-ae', # 0x8a +'u-eo-eu', # 0x8b +'u-ye', # 0x8c +'u-u', # 0x8d +'yu-a', # 0x8e +'yu-eo', # 0x8f +'yu-e', # 0x90 +'yu-yeo', # 0x91 +'yu-ye', # 0x92 +'yu-u', # 0x93 +'yu-i', # 0x94 +'eu-u', # 0x95 +'eu-eu', # 0x96 +'yi-u', # 0x97 +'i-a', # 0x98 +'i-ya', # 0x99 +'i-o', # 0x9a +'i-u', # 0x9b +'i-eu', # 0x9c +'i-U', # 0x9d +'U', # 0x9e +'U-eo', # 0x9f +'U-u', # 0xa0 +'U-i', # 0xa1 +'UU', # 0xa2 +'[?]', # 0xa3 +'[?]', # 0xa4 +'[?]', # 0xa5 +'[?]', # 0xa6 +'[?]', # 0xa7 +'g', # 0xa8 +'gg', # 0xa9 +'gs', # 0xaa +'n', # 0xab +'nj', # 0xac +'nh', # 0xad +'d', # 0xae +'l', # 0xaf +'lg', # 0xb0 +'lm', # 0xb1 +'lb', # 0xb2 +'ls', # 0xb3 +'lt', # 0xb4 +'lp', # 0xb5 +'lh', # 0xb6 +'m', # 0xb7 +'b', # 0xb8 +'bs', # 0xb9 +'s', # 0xba +'ss', # 0xbb +'ng', # 0xbc +'j', # 0xbd +'c', # 0xbe +'k', # 0xbf +'t', # 0xc0 +'p', # 0xc1 +'h', # 0xc2 +'gl', # 0xc3 +'gsg', # 0xc4 +'ng', # 0xc5 +'nd', # 0xc6 +'ns', # 0xc7 +'nZ', # 0xc8 +'nt', # 0xc9 +'dg', # 0xca +'tl', # 0xcb +'lgs', # 0xcc +'ln', # 0xcd +'ld', # 0xce +'lth', # 0xcf +'ll', # 0xd0 +'lmg', # 0xd1 +'lms', # 0xd2 +'lbs', # 0xd3 +'lbh', # 0xd4 +'rNp', # 0xd5 +'lss', # 0xd6 +'lZ', # 0xd7 +'lk', # 0xd8 +'lQ', # 0xd9 +'mg', # 0xda +'ml', # 0xdb +'mb', # 0xdc +'ms', # 0xdd +'mss', # 0xde +'mZ', # 0xdf +'mc', # 0xe0 +'mh', # 0xe1 +'mN', # 0xe2 +'bl', # 0xe3 +'bp', # 0xe4 +'ph', # 0xe5 +'pN', # 0xe6 +'sg', # 0xe7 +'sd', # 0xe8 +'sl', # 0xe9 +'sb', # 0xea +'Z', # 0xeb +'g', # 0xec +'ss', # 0xed +'', # 0xee +'kh', # 0xef +'N', # 0xf0 +'Ns', # 0xf1 +'NZ', # 0xf2 +'pb', # 0xf3 +'pN', # 0xf4 +'hn', # 0xf5 +'hl', # 0xf6 +'hm', # 0xf7 +'hb', # 0xf8 +'Q', # 0xf9 +'[?]', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x012.py b/libs/unidecode/x012.py new file mode 100644 index 00000000..f2670650 --- /dev/null +++ b/libs/unidecode/x012.py @@ -0,0 +1,258 @@ +data = ( +'ha', # 0x00 +'hu', # 0x01 +'hi', # 0x02 +'haa', # 0x03 +'hee', # 0x04 +'he', # 0x05 +'ho', # 0x06 +'[?]', # 0x07 +'la', # 0x08 +'lu', # 0x09 +'li', # 0x0a +'laa', # 0x0b +'lee', # 0x0c +'le', # 0x0d +'lo', # 0x0e +'lwa', # 0x0f +'hha', # 0x10 +'hhu', # 0x11 +'hhi', # 0x12 +'hhaa', # 0x13 +'hhee', # 0x14 +'hhe', # 0x15 +'hho', # 0x16 +'hhwa', # 0x17 +'ma', # 0x18 +'mu', # 0x19 +'mi', # 0x1a +'maa', # 0x1b +'mee', # 0x1c +'me', # 0x1d +'mo', # 0x1e +'mwa', # 0x1f +'sza', # 0x20 +'szu', # 0x21 +'szi', # 0x22 +'szaa', # 0x23 +'szee', # 0x24 +'sze', # 0x25 +'szo', # 0x26 +'szwa', # 0x27 +'ra', # 0x28 +'ru', # 0x29 +'ri', # 0x2a +'raa', # 0x2b +'ree', # 0x2c +'re', # 0x2d +'ro', # 0x2e +'rwa', # 0x2f +'sa', # 0x30 +'su', # 0x31 +'si', # 0x32 +'saa', # 0x33 +'see', # 0x34 +'se', # 0x35 +'so', # 0x36 +'swa', # 0x37 +'sha', # 0x38 +'shu', # 0x39 +'shi', # 0x3a +'shaa', # 0x3b +'shee', # 0x3c +'she', # 0x3d +'sho', # 0x3e +'shwa', # 0x3f +'qa', # 0x40 +'qu', # 0x41 +'qi', # 0x42 +'qaa', # 0x43 +'qee', # 0x44 +'qe', # 0x45 +'qo', # 0x46 +'[?]', # 0x47 +'qwa', # 0x48 +'[?]', # 0x49 +'qwi', # 0x4a +'qwaa', # 0x4b +'qwee', # 0x4c +'qwe', # 0x4d +'[?]', # 0x4e +'[?]', # 0x4f +'qha', # 0x50 +'qhu', # 0x51 +'qhi', # 0x52 +'qhaa', # 0x53 +'qhee', # 0x54 +'qhe', # 0x55 +'qho', # 0x56 +'[?]', # 0x57 +'qhwa', # 0x58 +'[?]', # 0x59 +'qhwi', # 0x5a +'qhwaa', # 0x5b +'qhwee', # 0x5c +'qhwe', # 0x5d +'[?]', # 0x5e +'[?]', # 0x5f +'ba', # 0x60 +'bu', # 0x61 +'bi', # 0x62 +'baa', # 0x63 +'bee', # 0x64 +'be', # 0x65 +'bo', # 0x66 +'bwa', # 0x67 +'va', # 0x68 +'vu', # 0x69 +'vi', # 0x6a +'vaa', # 0x6b +'vee', # 0x6c +'ve', # 0x6d +'vo', # 0x6e +'vwa', # 0x6f +'ta', # 0x70 +'tu', # 0x71 +'ti', # 0x72 +'taa', # 0x73 +'tee', # 0x74 +'te', # 0x75 +'to', # 0x76 +'twa', # 0x77 +'ca', # 0x78 +'cu', # 0x79 +'ci', # 0x7a +'caa', # 0x7b +'cee', # 0x7c +'ce', # 0x7d +'co', # 0x7e +'cwa', # 0x7f +'xa', # 0x80 +'xu', # 0x81 +'xi', # 0x82 +'xaa', # 0x83 +'xee', # 0x84 +'xe', # 0x85 +'xo', # 0x86 +'[?]', # 0x87 +'xwa', # 0x88 +'[?]', # 0x89 +'xwi', # 0x8a +'xwaa', # 0x8b +'xwee', # 0x8c +'xwe', # 0x8d +'[?]', # 0x8e +'[?]', # 0x8f +'na', # 0x90 +'nu', # 0x91 +'ni', # 0x92 +'naa', # 0x93 +'nee', # 0x94 +'ne', # 0x95 +'no', # 0x96 +'nwa', # 0x97 +'nya', # 0x98 +'nyu', # 0x99 +'nyi', # 0x9a +'nyaa', # 0x9b +'nyee', # 0x9c +'nye', # 0x9d +'nyo', # 0x9e +'nywa', # 0x9f +'\'a', # 0xa0 +'\'u', # 0xa1 +'[?]', # 0xa2 +'\'aa', # 0xa3 +'\'ee', # 0xa4 +'\'e', # 0xa5 +'\'o', # 0xa6 +'\'wa', # 0xa7 +'ka', # 0xa8 +'ku', # 0xa9 +'ki', # 0xaa +'kaa', # 0xab +'kee', # 0xac +'ke', # 0xad +'ko', # 0xae +'[?]', # 0xaf +'kwa', # 0xb0 +'[?]', # 0xb1 +'kwi', # 0xb2 +'kwaa', # 0xb3 +'kwee', # 0xb4 +'kwe', # 0xb5 +'[?]', # 0xb6 +'[?]', # 0xb7 +'kxa', # 0xb8 +'kxu', # 0xb9 +'kxi', # 0xba +'kxaa', # 0xbb +'kxee', # 0xbc +'kxe', # 0xbd +'kxo', # 0xbe +'[?]', # 0xbf +'kxwa', # 0xc0 +'[?]', # 0xc1 +'kxwi', # 0xc2 +'kxwaa', # 0xc3 +'kxwee', # 0xc4 +'kxwe', # 0xc5 +'[?]', # 0xc6 +'[?]', # 0xc7 +'wa', # 0xc8 +'wu', # 0xc9 +'wi', # 0xca +'waa', # 0xcb +'wee', # 0xcc +'we', # 0xcd +'wo', # 0xce +'[?]', # 0xcf +'`a', # 0xd0 +'`u', # 0xd1 +'`i', # 0xd2 +'`aa', # 0xd3 +'`ee', # 0xd4 +'`e', # 0xd5 +'`o', # 0xd6 +'[?]', # 0xd7 +'za', # 0xd8 +'zu', # 0xd9 +'zi', # 0xda +'zaa', # 0xdb +'zee', # 0xdc +'ze', # 0xdd +'zo', # 0xde +'zwa', # 0xdf +'zha', # 0xe0 +'zhu', # 0xe1 +'zhi', # 0xe2 +'zhaa', # 0xe3 +'zhee', # 0xe4 +'zhe', # 0xe5 +'zho', # 0xe6 +'zhwa', # 0xe7 +'ya', # 0xe8 +'yu', # 0xe9 +'yi', # 0xea +'yaa', # 0xeb +'yee', # 0xec +'ye', # 0xed +'yo', # 0xee +'[?]', # 0xef +'da', # 0xf0 +'du', # 0xf1 +'di', # 0xf2 +'daa', # 0xf3 +'dee', # 0xf4 +'de', # 0xf5 +'do', # 0xf6 +'dwa', # 0xf7 +'dda', # 0xf8 +'ddu', # 0xf9 +'ddi', # 0xfa +'ddaa', # 0xfb +'ddee', # 0xfc +'dde', # 0xfd +'ddo', # 0xfe +'ddwa', # 0xff +) diff --git a/libs/unidecode/x013.py b/libs/unidecode/x013.py new file mode 100644 index 00000000..8a8c3f9c --- /dev/null +++ b/libs/unidecode/x013.py @@ -0,0 +1,257 @@ +data = ( +'ja', # 0x00 +'ju', # 0x01 +'ji', # 0x02 +'jaa', # 0x03 +'jee', # 0x04 +'je', # 0x05 +'jo', # 0x06 +'jwa', # 0x07 +'ga', # 0x08 +'gu', # 0x09 +'gi', # 0x0a +'gaa', # 0x0b +'gee', # 0x0c +'ge', # 0x0d +'go', # 0x0e +'[?]', # 0x0f +'gwa', # 0x10 +'[?]', # 0x11 +'gwi', # 0x12 +'gwaa', # 0x13 +'gwee', # 0x14 +'gwe', # 0x15 +'[?]', # 0x16 +'[?]', # 0x17 +'gga', # 0x18 +'ggu', # 0x19 +'ggi', # 0x1a +'ggaa', # 0x1b +'ggee', # 0x1c +'gge', # 0x1d +'ggo', # 0x1e +'[?]', # 0x1f +'tha', # 0x20 +'thu', # 0x21 +'thi', # 0x22 +'thaa', # 0x23 +'thee', # 0x24 +'the', # 0x25 +'tho', # 0x26 +'thwa', # 0x27 +'cha', # 0x28 +'chu', # 0x29 +'chi', # 0x2a +'chaa', # 0x2b +'chee', # 0x2c +'che', # 0x2d +'cho', # 0x2e +'chwa', # 0x2f +'pha', # 0x30 +'phu', # 0x31 +'phi', # 0x32 +'phaa', # 0x33 +'phee', # 0x34 +'phe', # 0x35 +'pho', # 0x36 +'phwa', # 0x37 +'tsa', # 0x38 +'tsu', # 0x39 +'tsi', # 0x3a +'tsaa', # 0x3b +'tsee', # 0x3c +'tse', # 0x3d +'tso', # 0x3e +'tswa', # 0x3f +'tza', # 0x40 +'tzu', # 0x41 +'tzi', # 0x42 +'tzaa', # 0x43 +'tzee', # 0x44 +'tze', # 0x45 +'tzo', # 0x46 +'[?]', # 0x47 +'fa', # 0x48 +'fu', # 0x49 +'fi', # 0x4a +'faa', # 0x4b +'fee', # 0x4c +'fe', # 0x4d +'fo', # 0x4e +'fwa', # 0x4f +'pa', # 0x50 +'pu', # 0x51 +'pi', # 0x52 +'paa', # 0x53 +'pee', # 0x54 +'pe', # 0x55 +'po', # 0x56 +'pwa', # 0x57 +'rya', # 0x58 +'mya', # 0x59 +'fya', # 0x5a +'[?]', # 0x5b +'[?]', # 0x5c +'[?]', # 0x5d +'[?]', # 0x5e +'[?]', # 0x5f +'[?]', # 0x60 +' ', # 0x61 +'.', # 0x62 +',', # 0x63 +';', # 0x64 +':', # 0x65 +':: ', # 0x66 +'?', # 0x67 +'//', # 0x68 +'1', # 0x69 +'2', # 0x6a +'3', # 0x6b +'4', # 0x6c +'5', # 0x6d +'6', # 0x6e +'7', # 0x6f +'8', # 0x70 +'9', # 0x71 +'10+', # 0x72 +'20+', # 0x73 +'30+', # 0x74 +'40+', # 0x75 +'50+', # 0x76 +'60+', # 0x77 +'70+', # 0x78 +'80+', # 0x79 +'90+', # 0x7a +'100+', # 0x7b +'10,000+', # 0x7c +'[?]', # 0x7d +'[?]', # 0x7e +'[?]', # 0x7f +'[?]', # 0x80 +'[?]', # 0x81 +'[?]', # 0x82 +'[?]', # 0x83 +'[?]', # 0x84 +'[?]', # 0x85 +'[?]', # 0x86 +'[?]', # 0x87 +'[?]', # 0x88 +'[?]', # 0x89 +'[?]', # 0x8a +'[?]', # 0x8b +'[?]', # 0x8c +'[?]', # 0x8d +'[?]', # 0x8e +'[?]', # 0x8f +'[?]', # 0x90 +'[?]', # 0x91 +'[?]', # 0x92 +'[?]', # 0x93 +'[?]', # 0x94 +'[?]', # 0x95 +'[?]', # 0x96 +'[?]', # 0x97 +'[?]', # 0x98 +'[?]', # 0x99 +'[?]', # 0x9a +'[?]', # 0x9b +'[?]', # 0x9c +'[?]', # 0x9d +'[?]', # 0x9e +'[?]', # 0x9f +'a', # 0xa0 +'e', # 0xa1 +'i', # 0xa2 +'o', # 0xa3 +'u', # 0xa4 +'v', # 0xa5 +'ga', # 0xa6 +'ka', # 0xa7 +'ge', # 0xa8 +'gi', # 0xa9 +'go', # 0xaa +'gu', # 0xab +'gv', # 0xac +'ha', # 0xad +'he', # 0xae +'hi', # 0xaf +'ho', # 0xb0 +'hu', # 0xb1 +'hv', # 0xb2 +'la', # 0xb3 +'le', # 0xb4 +'li', # 0xb5 +'lo', # 0xb6 +'lu', # 0xb7 +'lv', # 0xb8 +'ma', # 0xb9 +'me', # 0xba +'mi', # 0xbb +'mo', # 0xbc +'mu', # 0xbd +'na', # 0xbe +'hna', # 0xbf +'nah', # 0xc0 +'ne', # 0xc1 +'ni', # 0xc2 +'no', # 0xc3 +'nu', # 0xc4 +'nv', # 0xc5 +'qua', # 0xc6 +'que', # 0xc7 +'qui', # 0xc8 +'quo', # 0xc9 +'quu', # 0xca +'quv', # 0xcb +'sa', # 0xcc +'s', # 0xcd +'se', # 0xce +'si', # 0xcf +'so', # 0xd0 +'su', # 0xd1 +'sv', # 0xd2 +'da', # 0xd3 +'ta', # 0xd4 +'de', # 0xd5 +'te', # 0xd6 +'di', # 0xd7 +'ti', # 0xd8 +'do', # 0xd9 +'du', # 0xda +'dv', # 0xdb +'dla', # 0xdc +'tla', # 0xdd +'tle', # 0xde +'tli', # 0xdf +'tlo', # 0xe0 +'tlu', # 0xe1 +'tlv', # 0xe2 +'tsa', # 0xe3 +'tse', # 0xe4 +'tsi', # 0xe5 +'tso', # 0xe6 +'tsu', # 0xe7 +'tsv', # 0xe8 +'wa', # 0xe9 +'we', # 0xea +'wi', # 0xeb +'wo', # 0xec +'wu', # 0xed +'wv', # 0xee +'ya', # 0xef +'ye', # 0xf0 +'yi', # 0xf1 +'yo', # 0xf2 +'yu', # 0xf3 +'yv', # 0xf4 +'[?]', # 0xf5 +'[?]', # 0xf6 +'[?]', # 0xf7 +'[?]', # 0xf8 +'[?]', # 0xf9 +'[?]', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x014.py b/libs/unidecode/x014.py new file mode 100644 index 00000000..e8c01809 --- /dev/null +++ b/libs/unidecode/x014.py @@ -0,0 +1,258 @@ +data = ( +'[?]', # 0x00 +'e', # 0x01 +'aai', # 0x02 +'i', # 0x03 +'ii', # 0x04 +'o', # 0x05 +'oo', # 0x06 +'oo', # 0x07 +'ee', # 0x08 +'i', # 0x09 +'a', # 0x0a +'aa', # 0x0b +'we', # 0x0c +'we', # 0x0d +'wi', # 0x0e +'wi', # 0x0f +'wii', # 0x10 +'wii', # 0x11 +'wo', # 0x12 +'wo', # 0x13 +'woo', # 0x14 +'woo', # 0x15 +'woo', # 0x16 +'wa', # 0x17 +'wa', # 0x18 +'waa', # 0x19 +'waa', # 0x1a +'waa', # 0x1b +'ai', # 0x1c +'w', # 0x1d +'\'', # 0x1e +'t', # 0x1f +'k', # 0x20 +'sh', # 0x21 +'s', # 0x22 +'n', # 0x23 +'w', # 0x24 +'n', # 0x25 +'[?]', # 0x26 +'w', # 0x27 +'c', # 0x28 +'?', # 0x29 +'l', # 0x2a +'en', # 0x2b +'in', # 0x2c +'on', # 0x2d +'an', # 0x2e +'pe', # 0x2f +'paai', # 0x30 +'pi', # 0x31 +'pii', # 0x32 +'po', # 0x33 +'poo', # 0x34 +'poo', # 0x35 +'hee', # 0x36 +'hi', # 0x37 +'pa', # 0x38 +'paa', # 0x39 +'pwe', # 0x3a +'pwe', # 0x3b +'pwi', # 0x3c +'pwi', # 0x3d +'pwii', # 0x3e +'pwii', # 0x3f +'pwo', # 0x40 +'pwo', # 0x41 +'pwoo', # 0x42 +'pwoo', # 0x43 +'pwa', # 0x44 +'pwa', # 0x45 +'pwaa', # 0x46 +'pwaa', # 0x47 +'pwaa', # 0x48 +'p', # 0x49 +'p', # 0x4a +'h', # 0x4b +'te', # 0x4c +'taai', # 0x4d +'ti', # 0x4e +'tii', # 0x4f +'to', # 0x50 +'too', # 0x51 +'too', # 0x52 +'dee', # 0x53 +'di', # 0x54 +'ta', # 0x55 +'taa', # 0x56 +'twe', # 0x57 +'twe', # 0x58 +'twi', # 0x59 +'twi', # 0x5a +'twii', # 0x5b +'twii', # 0x5c +'two', # 0x5d +'two', # 0x5e +'twoo', # 0x5f +'twoo', # 0x60 +'twa', # 0x61 +'twa', # 0x62 +'twaa', # 0x63 +'twaa', # 0x64 +'twaa', # 0x65 +'t', # 0x66 +'tte', # 0x67 +'tti', # 0x68 +'tto', # 0x69 +'tta', # 0x6a +'ke', # 0x6b +'kaai', # 0x6c +'ki', # 0x6d +'kii', # 0x6e +'ko', # 0x6f +'koo', # 0x70 +'koo', # 0x71 +'ka', # 0x72 +'kaa', # 0x73 +'kwe', # 0x74 +'kwe', # 0x75 +'kwi', # 0x76 +'kwi', # 0x77 +'kwii', # 0x78 +'kwii', # 0x79 +'kwo', # 0x7a +'kwo', # 0x7b +'kwoo', # 0x7c +'kwoo', # 0x7d +'kwa', # 0x7e +'kwa', # 0x7f +'kwaa', # 0x80 +'kwaa', # 0x81 +'kwaa', # 0x82 +'k', # 0x83 +'kw', # 0x84 +'keh', # 0x85 +'kih', # 0x86 +'koh', # 0x87 +'kah', # 0x88 +'ce', # 0x89 +'caai', # 0x8a +'ci', # 0x8b +'cii', # 0x8c +'co', # 0x8d +'coo', # 0x8e +'coo', # 0x8f +'ca', # 0x90 +'caa', # 0x91 +'cwe', # 0x92 +'cwe', # 0x93 +'cwi', # 0x94 +'cwi', # 0x95 +'cwii', # 0x96 +'cwii', # 0x97 +'cwo', # 0x98 +'cwo', # 0x99 +'cwoo', # 0x9a +'cwoo', # 0x9b +'cwa', # 0x9c +'cwa', # 0x9d +'cwaa', # 0x9e +'cwaa', # 0x9f +'cwaa', # 0xa0 +'c', # 0xa1 +'th', # 0xa2 +'me', # 0xa3 +'maai', # 0xa4 +'mi', # 0xa5 +'mii', # 0xa6 +'mo', # 0xa7 +'moo', # 0xa8 +'moo', # 0xa9 +'ma', # 0xaa +'maa', # 0xab +'mwe', # 0xac +'mwe', # 0xad +'mwi', # 0xae +'mwi', # 0xaf +'mwii', # 0xb0 +'mwii', # 0xb1 +'mwo', # 0xb2 +'mwo', # 0xb3 +'mwoo', # 0xb4 +'mwoo', # 0xb5 +'mwa', # 0xb6 +'mwa', # 0xb7 +'mwaa', # 0xb8 +'mwaa', # 0xb9 +'mwaa', # 0xba +'m', # 0xbb +'m', # 0xbc +'mh', # 0xbd +'m', # 0xbe +'m', # 0xbf +'ne', # 0xc0 +'naai', # 0xc1 +'ni', # 0xc2 +'nii', # 0xc3 +'no', # 0xc4 +'noo', # 0xc5 +'noo', # 0xc6 +'na', # 0xc7 +'naa', # 0xc8 +'nwe', # 0xc9 +'nwe', # 0xca +'nwa', # 0xcb +'nwa', # 0xcc +'nwaa', # 0xcd +'nwaa', # 0xce +'nwaa', # 0xcf +'n', # 0xd0 +'ng', # 0xd1 +'nh', # 0xd2 +'le', # 0xd3 +'laai', # 0xd4 +'li', # 0xd5 +'lii', # 0xd6 +'lo', # 0xd7 +'loo', # 0xd8 +'loo', # 0xd9 +'la', # 0xda +'laa', # 0xdb +'lwe', # 0xdc +'lwe', # 0xdd +'lwi', # 0xde +'lwi', # 0xdf +'lwii', # 0xe0 +'lwii', # 0xe1 +'lwo', # 0xe2 +'lwo', # 0xe3 +'lwoo', # 0xe4 +'lwoo', # 0xe5 +'lwa', # 0xe6 +'lwa', # 0xe7 +'lwaa', # 0xe8 +'lwaa', # 0xe9 +'l', # 0xea +'l', # 0xeb +'l', # 0xec +'se', # 0xed +'saai', # 0xee +'si', # 0xef +'sii', # 0xf0 +'so', # 0xf1 +'soo', # 0xf2 +'soo', # 0xf3 +'sa', # 0xf4 +'saa', # 0xf5 +'swe', # 0xf6 +'swe', # 0xf7 +'swi', # 0xf8 +'swi', # 0xf9 +'swii', # 0xfa +'swii', # 0xfb +'swo', # 0xfc +'swo', # 0xfd +'swoo', # 0xfe +'swoo', # 0xff +) diff --git a/libs/unidecode/x015.py b/libs/unidecode/x015.py new file mode 100644 index 00000000..5ac22cbe --- /dev/null +++ b/libs/unidecode/x015.py @@ -0,0 +1,258 @@ +data = ( +'swa', # 0x00 +'swa', # 0x01 +'swaa', # 0x02 +'swaa', # 0x03 +'swaa', # 0x04 +'s', # 0x05 +'s', # 0x06 +'sw', # 0x07 +'s', # 0x08 +'sk', # 0x09 +'skw', # 0x0a +'sW', # 0x0b +'spwa', # 0x0c +'stwa', # 0x0d +'skwa', # 0x0e +'scwa', # 0x0f +'she', # 0x10 +'shi', # 0x11 +'shii', # 0x12 +'sho', # 0x13 +'shoo', # 0x14 +'sha', # 0x15 +'shaa', # 0x16 +'shwe', # 0x17 +'shwe', # 0x18 +'shwi', # 0x19 +'shwi', # 0x1a +'shwii', # 0x1b +'shwii', # 0x1c +'shwo', # 0x1d +'shwo', # 0x1e +'shwoo', # 0x1f +'shwoo', # 0x20 +'shwa', # 0x21 +'shwa', # 0x22 +'shwaa', # 0x23 +'shwaa', # 0x24 +'sh', # 0x25 +'ye', # 0x26 +'yaai', # 0x27 +'yi', # 0x28 +'yii', # 0x29 +'yo', # 0x2a +'yoo', # 0x2b +'yoo', # 0x2c +'ya', # 0x2d +'yaa', # 0x2e +'ywe', # 0x2f +'ywe', # 0x30 +'ywi', # 0x31 +'ywi', # 0x32 +'ywii', # 0x33 +'ywii', # 0x34 +'ywo', # 0x35 +'ywo', # 0x36 +'ywoo', # 0x37 +'ywoo', # 0x38 +'ywa', # 0x39 +'ywa', # 0x3a +'ywaa', # 0x3b +'ywaa', # 0x3c +'ywaa', # 0x3d +'y', # 0x3e +'y', # 0x3f +'y', # 0x40 +'yi', # 0x41 +'re', # 0x42 +'re', # 0x43 +'le', # 0x44 +'raai', # 0x45 +'ri', # 0x46 +'rii', # 0x47 +'ro', # 0x48 +'roo', # 0x49 +'lo', # 0x4a +'ra', # 0x4b +'raa', # 0x4c +'la', # 0x4d +'rwaa', # 0x4e +'rwaa', # 0x4f +'r', # 0x50 +'r', # 0x51 +'r', # 0x52 +'fe', # 0x53 +'faai', # 0x54 +'fi', # 0x55 +'fii', # 0x56 +'fo', # 0x57 +'foo', # 0x58 +'fa', # 0x59 +'faa', # 0x5a +'fwaa', # 0x5b +'fwaa', # 0x5c +'f', # 0x5d +'the', # 0x5e +'the', # 0x5f +'thi', # 0x60 +'thi', # 0x61 +'thii', # 0x62 +'thii', # 0x63 +'tho', # 0x64 +'thoo', # 0x65 +'tha', # 0x66 +'thaa', # 0x67 +'thwaa', # 0x68 +'thwaa', # 0x69 +'th', # 0x6a +'tthe', # 0x6b +'tthi', # 0x6c +'ttho', # 0x6d +'ttha', # 0x6e +'tth', # 0x6f +'tye', # 0x70 +'tyi', # 0x71 +'tyo', # 0x72 +'tya', # 0x73 +'he', # 0x74 +'hi', # 0x75 +'hii', # 0x76 +'ho', # 0x77 +'hoo', # 0x78 +'ha', # 0x79 +'haa', # 0x7a +'h', # 0x7b +'h', # 0x7c +'hk', # 0x7d +'qaai', # 0x7e +'qi', # 0x7f +'qii', # 0x80 +'qo', # 0x81 +'qoo', # 0x82 +'qa', # 0x83 +'qaa', # 0x84 +'q', # 0x85 +'tlhe', # 0x86 +'tlhi', # 0x87 +'tlho', # 0x88 +'tlha', # 0x89 +'re', # 0x8a +'ri', # 0x8b +'ro', # 0x8c +'ra', # 0x8d +'ngaai', # 0x8e +'ngi', # 0x8f +'ngii', # 0x90 +'ngo', # 0x91 +'ngoo', # 0x92 +'nga', # 0x93 +'ngaa', # 0x94 +'ng', # 0x95 +'nng', # 0x96 +'she', # 0x97 +'shi', # 0x98 +'sho', # 0x99 +'sha', # 0x9a +'the', # 0x9b +'thi', # 0x9c +'tho', # 0x9d +'tha', # 0x9e +'th', # 0x9f +'lhi', # 0xa0 +'lhii', # 0xa1 +'lho', # 0xa2 +'lhoo', # 0xa3 +'lha', # 0xa4 +'lhaa', # 0xa5 +'lh', # 0xa6 +'the', # 0xa7 +'thi', # 0xa8 +'thii', # 0xa9 +'tho', # 0xaa +'thoo', # 0xab +'tha', # 0xac +'thaa', # 0xad +'th', # 0xae +'b', # 0xaf +'e', # 0xb0 +'i', # 0xb1 +'o', # 0xb2 +'a', # 0xb3 +'we', # 0xb4 +'wi', # 0xb5 +'wo', # 0xb6 +'wa', # 0xb7 +'ne', # 0xb8 +'ni', # 0xb9 +'no', # 0xba +'na', # 0xbb +'ke', # 0xbc +'ki', # 0xbd +'ko', # 0xbe +'ka', # 0xbf +'he', # 0xc0 +'hi', # 0xc1 +'ho', # 0xc2 +'ha', # 0xc3 +'ghu', # 0xc4 +'gho', # 0xc5 +'ghe', # 0xc6 +'ghee', # 0xc7 +'ghi', # 0xc8 +'gha', # 0xc9 +'ru', # 0xca +'ro', # 0xcb +'re', # 0xcc +'ree', # 0xcd +'ri', # 0xce +'ra', # 0xcf +'wu', # 0xd0 +'wo', # 0xd1 +'we', # 0xd2 +'wee', # 0xd3 +'wi', # 0xd4 +'wa', # 0xd5 +'hwu', # 0xd6 +'hwo', # 0xd7 +'hwe', # 0xd8 +'hwee', # 0xd9 +'hwi', # 0xda +'hwa', # 0xdb +'thu', # 0xdc +'tho', # 0xdd +'the', # 0xde +'thee', # 0xdf +'thi', # 0xe0 +'tha', # 0xe1 +'ttu', # 0xe2 +'tto', # 0xe3 +'tte', # 0xe4 +'ttee', # 0xe5 +'tti', # 0xe6 +'tta', # 0xe7 +'pu', # 0xe8 +'po', # 0xe9 +'pe', # 0xea +'pee', # 0xeb +'pi', # 0xec +'pa', # 0xed +'p', # 0xee +'gu', # 0xef +'go', # 0xf0 +'ge', # 0xf1 +'gee', # 0xf2 +'gi', # 0xf3 +'ga', # 0xf4 +'khu', # 0xf5 +'kho', # 0xf6 +'khe', # 0xf7 +'khee', # 0xf8 +'khi', # 0xf9 +'kha', # 0xfa +'kku', # 0xfb +'kko', # 0xfc +'kke', # 0xfd +'kkee', # 0xfe +'kki', # 0xff +) diff --git a/libs/unidecode/x016.py b/libs/unidecode/x016.py new file mode 100644 index 00000000..613d1e90 --- /dev/null +++ b/libs/unidecode/x016.py @@ -0,0 +1,257 @@ +data = ( +'kka', # 0x00 +'kk', # 0x01 +'nu', # 0x02 +'no', # 0x03 +'ne', # 0x04 +'nee', # 0x05 +'ni', # 0x06 +'na', # 0x07 +'mu', # 0x08 +'mo', # 0x09 +'me', # 0x0a +'mee', # 0x0b +'mi', # 0x0c +'ma', # 0x0d +'yu', # 0x0e +'yo', # 0x0f +'ye', # 0x10 +'yee', # 0x11 +'yi', # 0x12 +'ya', # 0x13 +'ju', # 0x14 +'ju', # 0x15 +'jo', # 0x16 +'je', # 0x17 +'jee', # 0x18 +'ji', # 0x19 +'ji', # 0x1a +'ja', # 0x1b +'jju', # 0x1c +'jjo', # 0x1d +'jje', # 0x1e +'jjee', # 0x1f +'jji', # 0x20 +'jja', # 0x21 +'lu', # 0x22 +'lo', # 0x23 +'le', # 0x24 +'lee', # 0x25 +'li', # 0x26 +'la', # 0x27 +'dlu', # 0x28 +'dlo', # 0x29 +'dle', # 0x2a +'dlee', # 0x2b +'dli', # 0x2c +'dla', # 0x2d +'lhu', # 0x2e +'lho', # 0x2f +'lhe', # 0x30 +'lhee', # 0x31 +'lhi', # 0x32 +'lha', # 0x33 +'tlhu', # 0x34 +'tlho', # 0x35 +'tlhe', # 0x36 +'tlhee', # 0x37 +'tlhi', # 0x38 +'tlha', # 0x39 +'tlu', # 0x3a +'tlo', # 0x3b +'tle', # 0x3c +'tlee', # 0x3d +'tli', # 0x3e +'tla', # 0x3f +'zu', # 0x40 +'zo', # 0x41 +'ze', # 0x42 +'zee', # 0x43 +'zi', # 0x44 +'za', # 0x45 +'z', # 0x46 +'z', # 0x47 +'dzu', # 0x48 +'dzo', # 0x49 +'dze', # 0x4a +'dzee', # 0x4b +'dzi', # 0x4c +'dza', # 0x4d +'su', # 0x4e +'so', # 0x4f +'se', # 0x50 +'see', # 0x51 +'si', # 0x52 +'sa', # 0x53 +'shu', # 0x54 +'sho', # 0x55 +'she', # 0x56 +'shee', # 0x57 +'shi', # 0x58 +'sha', # 0x59 +'sh', # 0x5a +'tsu', # 0x5b +'tso', # 0x5c +'tse', # 0x5d +'tsee', # 0x5e +'tsi', # 0x5f +'tsa', # 0x60 +'chu', # 0x61 +'cho', # 0x62 +'che', # 0x63 +'chee', # 0x64 +'chi', # 0x65 +'cha', # 0x66 +'ttsu', # 0x67 +'ttso', # 0x68 +'ttse', # 0x69 +'ttsee', # 0x6a +'ttsi', # 0x6b +'ttsa', # 0x6c +'X', # 0x6d +'.', # 0x6e +'qai', # 0x6f +'ngai', # 0x70 +'nngi', # 0x71 +'nngii', # 0x72 +'nngo', # 0x73 +'nngoo', # 0x74 +'nnga', # 0x75 +'nngaa', # 0x76 +'[?]', # 0x77 +'[?]', # 0x78 +'[?]', # 0x79 +'[?]', # 0x7a +'[?]', # 0x7b +'[?]', # 0x7c +'[?]', # 0x7d +'[?]', # 0x7e +'[?]', # 0x7f +' ', # 0x80 +'b', # 0x81 +'l', # 0x82 +'f', # 0x83 +'s', # 0x84 +'n', # 0x85 +'h', # 0x86 +'d', # 0x87 +'t', # 0x88 +'c', # 0x89 +'q', # 0x8a +'m', # 0x8b +'g', # 0x8c +'ng', # 0x8d +'z', # 0x8e +'r', # 0x8f +'a', # 0x90 +'o', # 0x91 +'u', # 0x92 +'e', # 0x93 +'i', # 0x94 +'ch', # 0x95 +'th', # 0x96 +'ph', # 0x97 +'p', # 0x98 +'x', # 0x99 +'p', # 0x9a +'<', # 0x9b +'>', # 0x9c +'[?]', # 0x9d +'[?]', # 0x9e +'[?]', # 0x9f +'f', # 0xa0 +'v', # 0xa1 +'u', # 0xa2 +'yr', # 0xa3 +'y', # 0xa4 +'w', # 0xa5 +'th', # 0xa6 +'th', # 0xa7 +'a', # 0xa8 +'o', # 0xa9 +'ac', # 0xaa +'ae', # 0xab +'o', # 0xac +'o', # 0xad +'o', # 0xae +'oe', # 0xaf +'on', # 0xb0 +'r', # 0xb1 +'k', # 0xb2 +'c', # 0xb3 +'k', # 0xb4 +'g', # 0xb5 +'ng', # 0xb6 +'g', # 0xb7 +'g', # 0xb8 +'w', # 0xb9 +'h', # 0xba +'h', # 0xbb +'h', # 0xbc +'h', # 0xbd +'n', # 0xbe +'n', # 0xbf +'n', # 0xc0 +'i', # 0xc1 +'e', # 0xc2 +'j', # 0xc3 +'g', # 0xc4 +'ae', # 0xc5 +'a', # 0xc6 +'eo', # 0xc7 +'p', # 0xc8 +'z', # 0xc9 +'s', # 0xca +'s', # 0xcb +'s', # 0xcc +'c', # 0xcd +'z', # 0xce +'t', # 0xcf +'t', # 0xd0 +'d', # 0xd1 +'b', # 0xd2 +'b', # 0xd3 +'p', # 0xd4 +'p', # 0xd5 +'e', # 0xd6 +'m', # 0xd7 +'m', # 0xd8 +'m', # 0xd9 +'l', # 0xda +'l', # 0xdb +'ng', # 0xdc +'ng', # 0xdd +'d', # 0xde +'o', # 0xdf +'ear', # 0xe0 +'ior', # 0xe1 +'qu', # 0xe2 +'qu', # 0xe3 +'qu', # 0xe4 +'s', # 0xe5 +'yr', # 0xe6 +'yr', # 0xe7 +'yr', # 0xe8 +'q', # 0xe9 +'x', # 0xea +'.', # 0xeb +':', # 0xec +'+', # 0xed +'17', # 0xee +'18', # 0xef +'19', # 0xf0 +'[?]', # 0xf1 +'[?]', # 0xf2 +'[?]', # 0xf3 +'[?]', # 0xf4 +'[?]', # 0xf5 +'[?]', # 0xf6 +'[?]', # 0xf7 +'[?]', # 0xf8 +'[?]', # 0xf9 +'[?]', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x017.py b/libs/unidecode/x017.py new file mode 100644 index 00000000..e0a8f447 --- /dev/null +++ b/libs/unidecode/x017.py @@ -0,0 +1,257 @@ +data = ( +'[?]', # 0x00 +'[?]', # 0x01 +'[?]', # 0x02 +'[?]', # 0x03 +'[?]', # 0x04 +'[?]', # 0x05 +'[?]', # 0x06 +'[?]', # 0x07 +'[?]', # 0x08 +'[?]', # 0x09 +'[?]', # 0x0a +'[?]', # 0x0b +'[?]', # 0x0c +'[?]', # 0x0d +'[?]', # 0x0e +'[?]', # 0x0f +'[?]', # 0x10 +'[?]', # 0x11 +'[?]', # 0x12 +'[?]', # 0x13 +'[?]', # 0x14 +'[?]', # 0x15 +'[?]', # 0x16 +'[?]', # 0x17 +'[?]', # 0x18 +'[?]', # 0x19 +'[?]', # 0x1a +'[?]', # 0x1b +'[?]', # 0x1c +'[?]', # 0x1d +'[?]', # 0x1e +'[?]', # 0x1f +'[?]', # 0x20 +'[?]', # 0x21 +'[?]', # 0x22 +'[?]', # 0x23 +'[?]', # 0x24 +'[?]', # 0x25 +'[?]', # 0x26 +'[?]', # 0x27 +'[?]', # 0x28 +'[?]', # 0x29 +'[?]', # 0x2a +'[?]', # 0x2b +'[?]', # 0x2c +'[?]', # 0x2d +'[?]', # 0x2e +'[?]', # 0x2f +'[?]', # 0x30 +'[?]', # 0x31 +'[?]', # 0x32 +'[?]', # 0x33 +'[?]', # 0x34 +'[?]', # 0x35 +'[?]', # 0x36 +'[?]', # 0x37 +'[?]', # 0x38 +'[?]', # 0x39 +'[?]', # 0x3a +'[?]', # 0x3b +'[?]', # 0x3c +'[?]', # 0x3d +'[?]', # 0x3e +'[?]', # 0x3f +'[?]', # 0x40 +'[?]', # 0x41 +'[?]', # 0x42 +'[?]', # 0x43 +'[?]', # 0x44 +'[?]', # 0x45 +'[?]', # 0x46 +'[?]', # 0x47 +'[?]', # 0x48 +'[?]', # 0x49 +'[?]', # 0x4a +'[?]', # 0x4b +'[?]', # 0x4c +'[?]', # 0x4d +'[?]', # 0x4e +'[?]', # 0x4f +'[?]', # 0x50 +'[?]', # 0x51 +'[?]', # 0x52 +'[?]', # 0x53 +'[?]', # 0x54 +'[?]', # 0x55 +'[?]', # 0x56 +'[?]', # 0x57 +'[?]', # 0x58 +'[?]', # 0x59 +'[?]', # 0x5a +'[?]', # 0x5b +'[?]', # 0x5c +'[?]', # 0x5d +'[?]', # 0x5e +'[?]', # 0x5f +'[?]', # 0x60 +'[?]', # 0x61 +'[?]', # 0x62 +'[?]', # 0x63 +'[?]', # 0x64 +'[?]', # 0x65 +'[?]', # 0x66 +'[?]', # 0x67 +'[?]', # 0x68 +'[?]', # 0x69 +'[?]', # 0x6a +'[?]', # 0x6b +'[?]', # 0x6c +'[?]', # 0x6d +'[?]', # 0x6e +'[?]', # 0x6f +'[?]', # 0x70 +'[?]', # 0x71 +'[?]', # 0x72 +'[?]', # 0x73 +'[?]', # 0x74 +'[?]', # 0x75 +'[?]', # 0x76 +'[?]', # 0x77 +'[?]', # 0x78 +'[?]', # 0x79 +'[?]', # 0x7a +'[?]', # 0x7b +'[?]', # 0x7c +'[?]', # 0x7d +'[?]', # 0x7e +'[?]', # 0x7f +'k', # 0x80 +'kh', # 0x81 +'g', # 0x82 +'gh', # 0x83 +'ng', # 0x84 +'c', # 0x85 +'ch', # 0x86 +'j', # 0x87 +'jh', # 0x88 +'ny', # 0x89 +'t', # 0x8a +'tth', # 0x8b +'d', # 0x8c +'ddh', # 0x8d +'nn', # 0x8e +'t', # 0x8f +'th', # 0x90 +'d', # 0x91 +'dh', # 0x92 +'n', # 0x93 +'p', # 0x94 +'ph', # 0x95 +'b', # 0x96 +'bh', # 0x97 +'m', # 0x98 +'y', # 0x99 +'r', # 0x9a +'l', # 0x9b +'v', # 0x9c +'sh', # 0x9d +'ss', # 0x9e +'s', # 0x9f +'h', # 0xa0 +'l', # 0xa1 +'q', # 0xa2 +'a', # 0xa3 +'aa', # 0xa4 +'i', # 0xa5 +'ii', # 0xa6 +'u', # 0xa7 +'uk', # 0xa8 +'uu', # 0xa9 +'uuv', # 0xaa +'ry', # 0xab +'ryy', # 0xac +'ly', # 0xad +'lyy', # 0xae +'e', # 0xaf +'ai', # 0xb0 +'oo', # 0xb1 +'oo', # 0xb2 +'au', # 0xb3 +'a', # 0xb4 +'aa', # 0xb5 +'aa', # 0xb6 +'i', # 0xb7 +'ii', # 0xb8 +'y', # 0xb9 +'yy', # 0xba +'u', # 0xbb +'uu', # 0xbc +'ua', # 0xbd +'oe', # 0xbe +'ya', # 0xbf +'ie', # 0xc0 +'e', # 0xc1 +'ae', # 0xc2 +'ai', # 0xc3 +'oo', # 0xc4 +'au', # 0xc5 +'M', # 0xc6 +'H', # 0xc7 +'a`', # 0xc8 +'', # 0xc9 +'', # 0xca +'', # 0xcb +'r', # 0xcc +'', # 0xcd +'!', # 0xce +'', # 0xcf +'', # 0xd0 +'', # 0xd1 +'', # 0xd2 +'', # 0xd3 +'.', # 0xd4 +' // ', # 0xd5 +':', # 0xd6 +'+', # 0xd7 +'++', # 0xd8 +' * ', # 0xd9 +' /// ', # 0xda +'KR', # 0xdb +'\'', # 0xdc +'[?]', # 0xdd +'[?]', # 0xde +'[?]', # 0xdf +'0', # 0xe0 +'1', # 0xe1 +'2', # 0xe2 +'3', # 0xe3 +'4', # 0xe4 +'5', # 0xe5 +'6', # 0xe6 +'7', # 0xe7 +'8', # 0xe8 +'9', # 0xe9 +'[?]', # 0xea +'[?]', # 0xeb +'[?]', # 0xec +'[?]', # 0xed +'[?]', # 0xee +'[?]', # 0xef +'[?]', # 0xf0 +'[?]', # 0xf1 +'[?]', # 0xf2 +'[?]', # 0xf3 +'[?]', # 0xf4 +'[?]', # 0xf5 +'[?]', # 0xf6 +'[?]', # 0xf7 +'[?]', # 0xf8 +'[?]', # 0xf9 +'[?]', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x018.py b/libs/unidecode/x018.py new file mode 100644 index 00000000..3162a010 --- /dev/null +++ b/libs/unidecode/x018.py @@ -0,0 +1,257 @@ +data = ( +' @ ', # 0x00 +' ... ', # 0x01 +', ', # 0x02 +'. ', # 0x03 +': ', # 0x04 +' // ', # 0x05 +'', # 0x06 +'-', # 0x07 +', ', # 0x08 +'. ', # 0x09 +'', # 0x0a +'', # 0x0b +'', # 0x0c +'', # 0x0d +'', # 0x0e +'[?]', # 0x0f +'0', # 0x10 +'1', # 0x11 +'2', # 0x12 +'3', # 0x13 +'4', # 0x14 +'5', # 0x15 +'6', # 0x16 +'7', # 0x17 +'8', # 0x18 +'9', # 0x19 +'[?]', # 0x1a +'[?]', # 0x1b +'[?]', # 0x1c +'[?]', # 0x1d +'[?]', # 0x1e +'[?]', # 0x1f +'a', # 0x20 +'e', # 0x21 +'i', # 0x22 +'o', # 0x23 +'u', # 0x24 +'O', # 0x25 +'U', # 0x26 +'ee', # 0x27 +'n', # 0x28 +'ng', # 0x29 +'b', # 0x2a +'p', # 0x2b +'q', # 0x2c +'g', # 0x2d +'m', # 0x2e +'l', # 0x2f +'s', # 0x30 +'sh', # 0x31 +'t', # 0x32 +'d', # 0x33 +'ch', # 0x34 +'j', # 0x35 +'y', # 0x36 +'r', # 0x37 +'w', # 0x38 +'f', # 0x39 +'k', # 0x3a +'kha', # 0x3b +'ts', # 0x3c +'z', # 0x3d +'h', # 0x3e +'zr', # 0x3f +'lh', # 0x40 +'zh', # 0x41 +'ch', # 0x42 +'-', # 0x43 +'e', # 0x44 +'i', # 0x45 +'o', # 0x46 +'u', # 0x47 +'O', # 0x48 +'U', # 0x49 +'ng', # 0x4a +'b', # 0x4b +'p', # 0x4c +'q', # 0x4d +'g', # 0x4e +'m', # 0x4f +'t', # 0x50 +'d', # 0x51 +'ch', # 0x52 +'j', # 0x53 +'ts', # 0x54 +'y', # 0x55 +'w', # 0x56 +'k', # 0x57 +'g', # 0x58 +'h', # 0x59 +'jy', # 0x5a +'ny', # 0x5b +'dz', # 0x5c +'e', # 0x5d +'i', # 0x5e +'iy', # 0x5f +'U', # 0x60 +'u', # 0x61 +'ng', # 0x62 +'k', # 0x63 +'g', # 0x64 +'h', # 0x65 +'p', # 0x66 +'sh', # 0x67 +'t', # 0x68 +'d', # 0x69 +'j', # 0x6a +'f', # 0x6b +'g', # 0x6c +'h', # 0x6d +'ts', # 0x6e +'z', # 0x6f +'r', # 0x70 +'ch', # 0x71 +'zh', # 0x72 +'i', # 0x73 +'k', # 0x74 +'r', # 0x75 +'f', # 0x76 +'zh', # 0x77 +'[?]', # 0x78 +'[?]', # 0x79 +'[?]', # 0x7a +'[?]', # 0x7b +'[?]', # 0x7c +'[?]', # 0x7d +'[?]', # 0x7e +'[?]', # 0x7f +'[?]', # 0x80 +'H', # 0x81 +'X', # 0x82 +'W', # 0x83 +'M', # 0x84 +' 3 ', # 0x85 +' 333 ', # 0x86 +'a', # 0x87 +'i', # 0x88 +'k', # 0x89 +'ng', # 0x8a +'c', # 0x8b +'tt', # 0x8c +'tth', # 0x8d +'dd', # 0x8e +'nn', # 0x8f +'t', # 0x90 +'d', # 0x91 +'p', # 0x92 +'ph', # 0x93 +'ss', # 0x94 +'zh', # 0x95 +'z', # 0x96 +'a', # 0x97 +'t', # 0x98 +'zh', # 0x99 +'gh', # 0x9a +'ng', # 0x9b +'c', # 0x9c +'jh', # 0x9d +'tta', # 0x9e +'ddh', # 0x9f +'t', # 0xa0 +'dh', # 0xa1 +'ss', # 0xa2 +'cy', # 0xa3 +'zh', # 0xa4 +'z', # 0xa5 +'u', # 0xa6 +'y', # 0xa7 +'bh', # 0xa8 +'\'', # 0xa9 +'[?]', # 0xaa +'[?]', # 0xab +'[?]', # 0xac +'[?]', # 0xad +'[?]', # 0xae +'[?]', # 0xaf +'[?]', # 0xb0 +'[?]', # 0xb1 +'[?]', # 0xb2 +'[?]', # 0xb3 +'[?]', # 0xb4 +'[?]', # 0xb5 +'[?]', # 0xb6 +'[?]', # 0xb7 +'[?]', # 0xb8 +'[?]', # 0xb9 +'[?]', # 0xba +'[?]', # 0xbb +'[?]', # 0xbc +'[?]', # 0xbd +'[?]', # 0xbe +'[?]', # 0xbf +'[?]', # 0xc0 +'[?]', # 0xc1 +'[?]', # 0xc2 +'[?]', # 0xc3 +'[?]', # 0xc4 +'[?]', # 0xc5 +'[?]', # 0xc6 +'[?]', # 0xc7 +'[?]', # 0xc8 +'[?]', # 0xc9 +'[?]', # 0xca +'[?]', # 0xcb +'[?]', # 0xcc +'[?]', # 0xcd +'[?]', # 0xce +'[?]', # 0xcf +'[?]', # 0xd0 +'[?]', # 0xd1 +'[?]', # 0xd2 +'[?]', # 0xd3 +'[?]', # 0xd4 +'[?]', # 0xd5 +'[?]', # 0xd6 +'[?]', # 0xd7 +'[?]', # 0xd8 +'[?]', # 0xd9 +'[?]', # 0xda +'[?]', # 0xdb +'[?]', # 0xdc +'[?]', # 0xdd +'[?]', # 0xde +'[?]', # 0xdf +'[?]', # 0xe0 +'[?]', # 0xe1 +'[?]', # 0xe2 +'[?]', # 0xe3 +'[?]', # 0xe4 +'[?]', # 0xe5 +'[?]', # 0xe6 +'[?]', # 0xe7 +'[?]', # 0xe8 +'[?]', # 0xe9 +'[?]', # 0xea +'[?]', # 0xeb +'[?]', # 0xec +'[?]', # 0xed +'[?]', # 0xee +'[?]', # 0xef +'[?]', # 0xf0 +'[?]', # 0xf1 +'[?]', # 0xf2 +'[?]', # 0xf3 +'[?]', # 0xf4 +'[?]', # 0xf5 +'[?]', # 0xf6 +'[?]', # 0xf7 +'[?]', # 0xf8 +'[?]', # 0xf9 +'[?]', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x01d.py b/libs/unidecode/x01d.py new file mode 100644 index 00000000..5b659060 --- /dev/null +++ b/libs/unidecode/x01d.py @@ -0,0 +1,257 @@ +data = ( +'', # 0x00 +'', # 0x01 +'', # 0x02 +'', # 0x03 +'', # 0x04 +'', # 0x05 +'', # 0x06 +'', # 0x07 +'', # 0x08 +'', # 0x09 +'', # 0x0a +'', # 0x0b +'', # 0x0c +'', # 0x0d +'', # 0x0e +'', # 0x0f +'', # 0x10 +'', # 0x11 +'', # 0x12 +'', # 0x13 +'', # 0x14 +'', # 0x15 +'', # 0x16 +'', # 0x17 +'', # 0x18 +'', # 0x19 +'', # 0x1a +'', # 0x1b +'', # 0x1c +'', # 0x1d +'', # 0x1e +'', # 0x1f +'', # 0x20 +'', # 0x21 +'', # 0x22 +'', # 0x23 +'', # 0x24 +'', # 0x25 +'', # 0x26 +'', # 0x27 +'', # 0x28 +'', # 0x29 +'', # 0x2a +'', # 0x2b +'', # 0x2c +'', # 0x2d +'', # 0x2e +'', # 0x2f +'', # 0x30 +'', # 0x31 +'', # 0x32 +'', # 0x33 +'', # 0x34 +'', # 0x35 +'', # 0x36 +'', # 0x37 +'', # 0x38 +'', # 0x39 +'', # 0x3a +'', # 0x3b +'', # 0x3c +'', # 0x3d +'', # 0x3e +'', # 0x3f +'', # 0x40 +'', # 0x41 +'', # 0x42 +'', # 0x43 +'', # 0x44 +'', # 0x45 +'', # 0x46 +'', # 0x47 +'', # 0x48 +'', # 0x49 +'', # 0x4a +'', # 0x4b +'', # 0x4c +'', # 0x4d +'', # 0x4e +'', # 0x4f +'', # 0x50 +'', # 0x51 +'', # 0x52 +'', # 0x53 +'', # 0x54 +'', # 0x55 +'', # 0x56 +'', # 0x57 +'', # 0x58 +'', # 0x59 +'', # 0x5a +'', # 0x5b +'', # 0x5c +'', # 0x5d +'', # 0x5e +'', # 0x5f +'', # 0x60 +'', # 0x61 +'', # 0x62 +'', # 0x63 +'', # 0x64 +'', # 0x65 +'', # 0x66 +'', # 0x67 +'', # 0x68 +'', # 0x69 +'', # 0x6a +'', # 0x6b +'b', # 0x6c +'d', # 0x6d +'f', # 0x6e +'m', # 0x6f +'n', # 0x70 +'p', # 0x71 +'r', # 0x72 +'r', # 0x73 +'s', # 0x74 +'t', # 0x75 +'z', # 0x76 +'g', # 0x77 +'', # 0x78 +'', # 0x79 +'', # 0x7a +'', # 0x7b +'', # 0x7c +'p', # 0x7d +'', # 0x7e +'', # 0x7f +'b', # 0x80 +'d', # 0x81 +'f', # 0x82 +'g', # 0x83 +'k', # 0x84 +'l', # 0x85 +'m', # 0x86 +'n', # 0x87 +'p', # 0x88 +'r', # 0x89 +'s', # 0x8a +'', # 0x8b +'v', # 0x8c +'x', # 0x8d +'z', # 0x8e +'', # 0x8f +'', # 0x90 +'', # 0x91 +'', # 0x92 +'', # 0x93 +'', # 0x94 +'', # 0x95 +'', # 0x96 +'', # 0x97 +'', # 0x98 +'', # 0x99 +'', # 0x9a +'', # 0x9b +'', # 0x9c +'', # 0x9d +'', # 0x9e +'', # 0x9f +'', # 0xa0 +'', # 0xa1 +'', # 0xa2 +'', # 0xa3 +'', # 0xa4 +'', # 0xa5 +'', # 0xa6 +'', # 0xa7 +'', # 0xa8 +'', # 0xa9 +'', # 0xaa +'', # 0xab +'', # 0xac +'', # 0xad +'', # 0xae +'', # 0xaf +'', # 0xb0 +'', # 0xb1 +'', # 0xb2 +'', # 0xb3 +'', # 0xb4 +'', # 0xb5 +'', # 0xb6 +'', # 0xb7 +'', # 0xb8 +'', # 0xb9 +'', # 0xba +'', # 0xbb +'', # 0xbc +'', # 0xbd +'', # 0xbe +'', # 0xbf +'', # 0xc0 +'', # 0xc1 +'', # 0xc2 +'', # 0xc3 +'', # 0xc4 +'', # 0xc5 +'', # 0xc6 +'', # 0xc7 +'', # 0xc8 +'', # 0xc9 +'', # 0xca +'', # 0xcb +'', # 0xcc +'', # 0xcd +'', # 0xce +'', # 0xcf +'', # 0xd0 +'', # 0xd1 +'', # 0xd2 +'', # 0xd3 +'', # 0xd4 +'', # 0xd5 +'', # 0xd6 +'', # 0xd7 +'', # 0xd8 +'', # 0xd9 +'', # 0xda +'', # 0xdb +'', # 0xdc +'', # 0xdd +'', # 0xde +'', # 0xdf +'', # 0xe0 +'', # 0xe1 +'', # 0xe2 +'', # 0xe3 +'', # 0xe4 +'', # 0xe5 +'', # 0xe6 +'', # 0xe7 +'', # 0xe8 +'', # 0xe9 +'', # 0xea +'', # 0xeb +'', # 0xec +'', # 0xed +'', # 0xee +'', # 0xef +'', # 0xf0 +'', # 0xf1 +'', # 0xf2 +'', # 0xf3 +'', # 0xf4 +'', # 0xf5 +'', # 0xf6 +'', # 0xf7 +'', # 0xf8 +'', # 0xf9 +'', # 0xfa +'', # 0xfb +'', # 0xfc +'', # 0xfd +'', # 0xfe +) diff --git a/libs/unidecode/x01e.py b/libs/unidecode/x01e.py new file mode 100644 index 00000000..606576b6 --- /dev/null +++ b/libs/unidecode/x01e.py @@ -0,0 +1,257 @@ +data = ( +'A', # 0x00 +'a', # 0x01 +'B', # 0x02 +'b', # 0x03 +'B', # 0x04 +'b', # 0x05 +'B', # 0x06 +'b', # 0x07 +'C', # 0x08 +'c', # 0x09 +'D', # 0x0a +'d', # 0x0b +'D', # 0x0c +'d', # 0x0d +'D', # 0x0e +'d', # 0x0f +'D', # 0x10 +'d', # 0x11 +'D', # 0x12 +'d', # 0x13 +'E', # 0x14 +'e', # 0x15 +'E', # 0x16 +'e', # 0x17 +'E', # 0x18 +'e', # 0x19 +'E', # 0x1a +'e', # 0x1b +'E', # 0x1c +'e', # 0x1d +'F', # 0x1e +'f', # 0x1f +'G', # 0x20 +'g', # 0x21 +'H', # 0x22 +'h', # 0x23 +'H', # 0x24 +'h', # 0x25 +'H', # 0x26 +'h', # 0x27 +'H', # 0x28 +'h', # 0x29 +'H', # 0x2a +'h', # 0x2b +'I', # 0x2c +'i', # 0x2d +'I', # 0x2e +'i', # 0x2f +'K', # 0x30 +'k', # 0x31 +'K', # 0x32 +'k', # 0x33 +'K', # 0x34 +'k', # 0x35 +'L', # 0x36 +'l', # 0x37 +'L', # 0x38 +'l', # 0x39 +'L', # 0x3a +'l', # 0x3b +'L', # 0x3c +'l', # 0x3d +'M', # 0x3e +'m', # 0x3f +'M', # 0x40 +'m', # 0x41 +'M', # 0x42 +'m', # 0x43 +'N', # 0x44 +'n', # 0x45 +'N', # 0x46 +'n', # 0x47 +'N', # 0x48 +'n', # 0x49 +'N', # 0x4a +'n', # 0x4b +'O', # 0x4c +'o', # 0x4d +'O', # 0x4e +'o', # 0x4f +'O', # 0x50 +'o', # 0x51 +'O', # 0x52 +'o', # 0x53 +'P', # 0x54 +'p', # 0x55 +'P', # 0x56 +'p', # 0x57 +'R', # 0x58 +'r', # 0x59 +'R', # 0x5a +'r', # 0x5b +'R', # 0x5c +'r', # 0x5d +'R', # 0x5e +'r', # 0x5f +'S', # 0x60 +'s', # 0x61 +'S', # 0x62 +'s', # 0x63 +'S', # 0x64 +'s', # 0x65 +'S', # 0x66 +'s', # 0x67 +'S', # 0x68 +'s', # 0x69 +'T', # 0x6a +'t', # 0x6b +'T', # 0x6c +'t', # 0x6d +'T', # 0x6e +'t', # 0x6f +'T', # 0x70 +'t', # 0x71 +'U', # 0x72 +'u', # 0x73 +'U', # 0x74 +'u', # 0x75 +'U', # 0x76 +'u', # 0x77 +'U', # 0x78 +'u', # 0x79 +'U', # 0x7a +'u', # 0x7b +'V', # 0x7c +'v', # 0x7d +'V', # 0x7e +'v', # 0x7f +'W', # 0x80 +'w', # 0x81 +'W', # 0x82 +'w', # 0x83 +'W', # 0x84 +'w', # 0x85 +'W', # 0x86 +'w', # 0x87 +'W', # 0x88 +'w', # 0x89 +'X', # 0x8a +'x', # 0x8b +'X', # 0x8c +'x', # 0x8d +'Y', # 0x8e +'y', # 0x8f +'Z', # 0x90 +'z', # 0x91 +'Z', # 0x92 +'z', # 0x93 +'Z', # 0x94 +'z', # 0x95 +'h', # 0x96 +'t', # 0x97 +'w', # 0x98 +'y', # 0x99 +'a', # 0x9a +'S', # 0x9b +'[?]', # 0x9c +'[?]', # 0x9d +'Ss', # 0x9e +'[?]', # 0x9f +'A', # 0xa0 +'a', # 0xa1 +'A', # 0xa2 +'a', # 0xa3 +'A', # 0xa4 +'a', # 0xa5 +'A', # 0xa6 +'a', # 0xa7 +'A', # 0xa8 +'a', # 0xa9 +'A', # 0xaa +'a', # 0xab +'A', # 0xac +'a', # 0xad +'A', # 0xae +'a', # 0xaf +'A', # 0xb0 +'a', # 0xb1 +'A', # 0xb2 +'a', # 0xb3 +'A', # 0xb4 +'a', # 0xb5 +'A', # 0xb6 +'a', # 0xb7 +'E', # 0xb8 +'e', # 0xb9 +'E', # 0xba +'e', # 0xbb +'E', # 0xbc +'e', # 0xbd +'E', # 0xbe +'e', # 0xbf +'E', # 0xc0 +'e', # 0xc1 +'E', # 0xc2 +'e', # 0xc3 +'E', # 0xc4 +'e', # 0xc5 +'E', # 0xc6 +'e', # 0xc7 +'I', # 0xc8 +'i', # 0xc9 +'I', # 0xca +'i', # 0xcb +'O', # 0xcc +'o', # 0xcd +'O', # 0xce +'o', # 0xcf +'O', # 0xd0 +'o', # 0xd1 +'O', # 0xd2 +'o', # 0xd3 +'O', # 0xd4 +'o', # 0xd5 +'O', # 0xd6 +'o', # 0xd7 +'O', # 0xd8 +'o', # 0xd9 +'O', # 0xda +'o', # 0xdb +'O', # 0xdc +'o', # 0xdd +'O', # 0xde +'o', # 0xdf +'O', # 0xe0 +'o', # 0xe1 +'O', # 0xe2 +'o', # 0xe3 +'U', # 0xe4 +'u', # 0xe5 +'U', # 0xe6 +'u', # 0xe7 +'U', # 0xe8 +'u', # 0xe9 +'U', # 0xea +'u', # 0xeb +'U', # 0xec +'u', # 0xed +'U', # 0xee +'u', # 0xef +'U', # 0xf0 +'u', # 0xf1 +'Y', # 0xf2 +'y', # 0xf3 +'Y', # 0xf4 +'y', # 0xf5 +'Y', # 0xf6 +'y', # 0xf7 +'Y', # 0xf8 +'y', # 0xf9 +'[?]', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x01f.py b/libs/unidecode/x01f.py new file mode 100644 index 00000000..bcd2dec5 --- /dev/null +++ b/libs/unidecode/x01f.py @@ -0,0 +1,257 @@ +data = ( +'a', # 0x00 +'a', # 0x01 +'a', # 0x02 +'a', # 0x03 +'a', # 0x04 +'a', # 0x05 +'a', # 0x06 +'a', # 0x07 +'A', # 0x08 +'A', # 0x09 +'A', # 0x0a +'A', # 0x0b +'A', # 0x0c +'A', # 0x0d +'A', # 0x0e +'A', # 0x0f +'e', # 0x10 +'e', # 0x11 +'e', # 0x12 +'e', # 0x13 +'e', # 0x14 +'e', # 0x15 +'[?]', # 0x16 +'[?]', # 0x17 +'E', # 0x18 +'E', # 0x19 +'E', # 0x1a +'E', # 0x1b +'E', # 0x1c +'E', # 0x1d +'[?]', # 0x1e +'[?]', # 0x1f +'e', # 0x20 +'e', # 0x21 +'e', # 0x22 +'e', # 0x23 +'e', # 0x24 +'e', # 0x25 +'e', # 0x26 +'e', # 0x27 +'E', # 0x28 +'E', # 0x29 +'E', # 0x2a +'E', # 0x2b +'E', # 0x2c +'E', # 0x2d +'E', # 0x2e +'E', # 0x2f +'i', # 0x30 +'i', # 0x31 +'i', # 0x32 +'i', # 0x33 +'i', # 0x34 +'i', # 0x35 +'i', # 0x36 +'i', # 0x37 +'I', # 0x38 +'I', # 0x39 +'I', # 0x3a +'I', # 0x3b +'I', # 0x3c +'I', # 0x3d +'I', # 0x3e +'I', # 0x3f +'o', # 0x40 +'o', # 0x41 +'o', # 0x42 +'o', # 0x43 +'o', # 0x44 +'o', # 0x45 +'[?]', # 0x46 +'[?]', # 0x47 +'O', # 0x48 +'O', # 0x49 +'O', # 0x4a +'O', # 0x4b +'O', # 0x4c +'O', # 0x4d +'[?]', # 0x4e +'[?]', # 0x4f +'u', # 0x50 +'u', # 0x51 +'u', # 0x52 +'u', # 0x53 +'u', # 0x54 +'u', # 0x55 +'u', # 0x56 +'u', # 0x57 +'[?]', # 0x58 +'U', # 0x59 +'[?]', # 0x5a +'U', # 0x5b +'[?]', # 0x5c +'U', # 0x5d +'[?]', # 0x5e +'U', # 0x5f +'o', # 0x60 +'o', # 0x61 +'o', # 0x62 +'o', # 0x63 +'o', # 0x64 +'o', # 0x65 +'o', # 0x66 +'o', # 0x67 +'O', # 0x68 +'O', # 0x69 +'O', # 0x6a +'O', # 0x6b +'O', # 0x6c +'O', # 0x6d +'O', # 0x6e +'O', # 0x6f +'a', # 0x70 +'a', # 0x71 +'e', # 0x72 +'e', # 0x73 +'e', # 0x74 +'e', # 0x75 +'i', # 0x76 +'i', # 0x77 +'o', # 0x78 +'o', # 0x79 +'u', # 0x7a +'u', # 0x7b +'o', # 0x7c +'o', # 0x7d +'[?]', # 0x7e +'[?]', # 0x7f +'a', # 0x80 +'a', # 0x81 +'a', # 0x82 +'a', # 0x83 +'a', # 0x84 +'a', # 0x85 +'a', # 0x86 +'a', # 0x87 +'A', # 0x88 +'A', # 0x89 +'A', # 0x8a +'A', # 0x8b +'A', # 0x8c +'A', # 0x8d +'A', # 0x8e +'A', # 0x8f +'e', # 0x90 +'e', # 0x91 +'e', # 0x92 +'e', # 0x93 +'e', # 0x94 +'e', # 0x95 +'e', # 0x96 +'e', # 0x97 +'E', # 0x98 +'E', # 0x99 +'E', # 0x9a +'E', # 0x9b +'E', # 0x9c +'E', # 0x9d +'E', # 0x9e +'E', # 0x9f +'o', # 0xa0 +'o', # 0xa1 +'o', # 0xa2 +'o', # 0xa3 +'o', # 0xa4 +'o', # 0xa5 +'o', # 0xa6 +'o', # 0xa7 +'O', # 0xa8 +'O', # 0xa9 +'O', # 0xaa +'O', # 0xab +'O', # 0xac +'O', # 0xad +'O', # 0xae +'O', # 0xaf +'a', # 0xb0 +'a', # 0xb1 +'a', # 0xb2 +'a', # 0xb3 +'a', # 0xb4 +'[?]', # 0xb5 +'a', # 0xb6 +'a', # 0xb7 +'A', # 0xb8 +'A', # 0xb9 +'A', # 0xba +'A', # 0xbb +'A', # 0xbc +'\'', # 0xbd +'i', # 0xbe +'\'', # 0xbf +'~', # 0xc0 +'"~', # 0xc1 +'e', # 0xc2 +'e', # 0xc3 +'e', # 0xc4 +'[?]', # 0xc5 +'e', # 0xc6 +'e', # 0xc7 +'E', # 0xc8 +'E', # 0xc9 +'E', # 0xca +'E', # 0xcb +'E', # 0xcc +'\'`', # 0xcd +'\'\'', # 0xce +'\'~', # 0xcf +'i', # 0xd0 +'i', # 0xd1 +'i', # 0xd2 +'i', # 0xd3 +'[?]', # 0xd4 +'[?]', # 0xd5 +'i', # 0xd6 +'i', # 0xd7 +'I', # 0xd8 +'I', # 0xd9 +'I', # 0xda +'I', # 0xdb +'[?]', # 0xdc +'`\'', # 0xdd +'`\'', # 0xde +'`~', # 0xdf +'u', # 0xe0 +'u', # 0xe1 +'u', # 0xe2 +'u', # 0xe3 +'R', # 0xe4 +'R', # 0xe5 +'u', # 0xe6 +'u', # 0xe7 +'U', # 0xe8 +'U', # 0xe9 +'U', # 0xea +'U', # 0xeb +'R', # 0xec +'"`', # 0xed +'"\'', # 0xee +'`', # 0xef +'[?]', # 0xf0 +'[?]', # 0xf1 +'o', # 0xf2 +'o', # 0xf3 +'o', # 0xf4 +'[?]', # 0xf5 +'o', # 0xf6 +'o', # 0xf7 +'O', # 0xf8 +'O', # 0xf9 +'O', # 0xfa +'O', # 0xfb +'O', # 0xfc +'\'', # 0xfd +'`', # 0xfe +) diff --git a/libs/unidecode/x020.py b/libs/unidecode/x020.py new file mode 100644 index 00000000..f67264c8 --- /dev/null +++ b/libs/unidecode/x020.py @@ -0,0 +1,257 @@ +data = ( +' ', # 0x00 +' ', # 0x01 +' ', # 0x02 +' ', # 0x03 +' ', # 0x04 +' ', # 0x05 +' ', # 0x06 +' ', # 0x07 +' ', # 0x08 +' ', # 0x09 +' ', # 0x0a +' ', # 0x0b +'', # 0x0c +'', # 0x0d +'', # 0x0e +'', # 0x0f +'-', # 0x10 +'-', # 0x11 +'-', # 0x12 +'-', # 0x13 +'--', # 0x14 +'--', # 0x15 +'||', # 0x16 +'_', # 0x17 +'\'', # 0x18 +'\'', # 0x19 +',', # 0x1a +'\'', # 0x1b +'"', # 0x1c +'"', # 0x1d +',,', # 0x1e +'"', # 0x1f +'+', # 0x20 +'++', # 0x21 +'*', # 0x22 +'*>', # 0x23 +'.', # 0x24 +'..', # 0x25 +'...', # 0x26 +'.', # 0x27 +'\x0a', # 0x28 +'\x0a\x0a', # 0x29 +'', # 0x2a +'', # 0x2b +'', # 0x2c +'', # 0x2d +'', # 0x2e +' ', # 0x2f +'%0', # 0x30 +'%00', # 0x31 +'\'', # 0x32 +'\'\'', # 0x33 +'\'\'\'', # 0x34 +'`', # 0x35 +'``', # 0x36 +'```', # 0x37 +'^', # 0x38 +'<', # 0x39 +'>', # 0x3a +'*', # 0x3b +'!!', # 0x3c +'!?', # 0x3d +'-', # 0x3e +'_', # 0x3f +'-', # 0x40 +'^', # 0x41 +'***', # 0x42 +'--', # 0x43 +'/', # 0x44 +'-[', # 0x45 +']-', # 0x46 +'??', # 0x47 +'?!', # 0x48 +'!?', # 0x49 +'7', # 0x4a +'PP', # 0x4b +'(]', # 0x4c +'[)', # 0x4d +'*', # 0x4e +'[?]', # 0x4f +'[?]', # 0x50 +'[?]', # 0x51 +'%', # 0x52 +'~', # 0x53 +'[?]', # 0x54 +'[?]', # 0x55 +'[?]', # 0x56 +"''''", # 0x57 +'[?]', # 0x58 +'[?]', # 0x59 +'[?]', # 0x5a +'[?]', # 0x5b +'[?]', # 0x5c +'[?]', # 0x5d +'[?]', # 0x5e +'[?]', # 0x5f +'', # 0x60 +'[?]', # 0x61 +'[?]', # 0x62 +'[?]', # 0x63 +'[?]', # 0x64 +'[?]', # 0x65 +'[?]', # 0x66 +'[?]', # 0x67 +'[?]', # 0x68 +'[?]', # 0x69 +'', # 0x6a +'', # 0x6b +'', # 0x6c +'', # 0x6d +'', # 0x6e +'', # 0x6f +'0', # 0x70 +'', # 0x71 +'', # 0x72 +'', # 0x73 +'4', # 0x74 +'5', # 0x75 +'6', # 0x76 +'7', # 0x77 +'8', # 0x78 +'9', # 0x79 +'+', # 0x7a +'-', # 0x7b +'=', # 0x7c +'(', # 0x7d +')', # 0x7e +'n', # 0x7f +'0', # 0x80 +'1', # 0x81 +'2', # 0x82 +'3', # 0x83 +'4', # 0x84 +'5', # 0x85 +'6', # 0x86 +'7', # 0x87 +'8', # 0x88 +'9', # 0x89 +'+', # 0x8a +'-', # 0x8b +'=', # 0x8c +'(', # 0x8d +')', # 0x8e +'[?]', # 0x8f +'[?]', # 0x90 +'[?]', # 0x91 +'[?]', # 0x92 +'[?]', # 0x93 +'[?]', # 0x94 +'[?]', # 0x95 +'[?]', # 0x96 +'[?]', # 0x97 +'[?]', # 0x98 +'[?]', # 0x99 +'[?]', # 0x9a +'[?]', # 0x9b +'[?]', # 0x9c +'[?]', # 0x9d +'[?]', # 0x9e +'[?]', # 0x9f +'ECU', # 0xa0 +'CL', # 0xa1 +'Cr', # 0xa2 +'FF', # 0xa3 +'L', # 0xa4 +'mil', # 0xa5 +'N', # 0xa6 +'Pts', # 0xa7 +'Rs', # 0xa8 +'W', # 0xa9 +'NS', # 0xaa +'D', # 0xab +'EU', # 0xac +'K', # 0xad +'T', # 0xae +'Dr', # 0xaf +'[?]', # 0xb0 +'[?]', # 0xb1 +'[?]', # 0xb2 +'[?]', # 0xb3 +'[?]', # 0xb4 +'[?]', # 0xb5 +'[?]', # 0xb6 +'[?]', # 0xb7 +'[?]', # 0xb8 +'[?]', # 0xb9 +'[?]', # 0xba +'[?]', # 0xbb +'[?]', # 0xbc +'[?]', # 0xbd +'[?]', # 0xbe +'[?]', # 0xbf +'[?]', # 0xc0 +'[?]', # 0xc1 +'[?]', # 0xc2 +'[?]', # 0xc3 +'[?]', # 0xc4 +'[?]', # 0xc5 +'[?]', # 0xc6 +'[?]', # 0xc7 +'[?]', # 0xc8 +'[?]', # 0xc9 +'[?]', # 0xca +'[?]', # 0xcb +'[?]', # 0xcc +'[?]', # 0xcd +'[?]', # 0xce +'[?]', # 0xcf +'', # 0xd0 +'', # 0xd1 +'', # 0xd2 +'', # 0xd3 +'', # 0xd4 +'', # 0xd5 +'', # 0xd6 +'', # 0xd7 +'', # 0xd8 +'', # 0xd9 +'', # 0xda +'', # 0xdb +'', # 0xdc +'', # 0xdd +'', # 0xde +'', # 0xdf +'', # 0xe0 +'', # 0xe1 +'', # 0xe2 +'', # 0xe3 +'[?]', # 0xe4 +'', # 0xe5 +'[?]', # 0xe6 +'[?]', # 0xe7 +'[?]', # 0xe8 +'[?]', # 0xe9 +'[?]', # 0xea +'[?]', # 0xeb +'[?]', # 0xec +'[?]', # 0xed +'[?]', # 0xee +'[?]', # 0xef +'[?]', # 0xf0 +'[?]', # 0xf1 +'[?]', # 0xf2 +'[?]', # 0xf3 +'[?]', # 0xf4 +'[?]', # 0xf5 +'[?]', # 0xf6 +'[?]', # 0xf7 +'[?]', # 0xf8 +'[?]', # 0xf9 +'[?]', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x021.py b/libs/unidecode/x021.py new file mode 100644 index 00000000..fcb651ba --- /dev/null +++ b/libs/unidecode/x021.py @@ -0,0 +1,257 @@ +data = ( +'', # 0x00 +'', # 0x01 +'', # 0x02 +'', # 0x03 +'', # 0x04 +'', # 0x05 +'', # 0x06 +'', # 0x07 +'', # 0x08 +'', # 0x09 +'', # 0x0a +'', # 0x0b +'', # 0x0c +'', # 0x0d +'', # 0x0e +'', # 0x0f +'', # 0x10 +'', # 0x11 +'', # 0x12 +'', # 0x13 +'', # 0x14 +'', # 0x15 +'', # 0x16 +'', # 0x17 +'', # 0x18 +'', # 0x19 +'', # 0x1a +'', # 0x1b +'', # 0x1c +'', # 0x1d +'', # 0x1e +'', # 0x1f +'(sm)', # 0x20 +'TEL', # 0x21 +'(tm)', # 0x22 +'', # 0x23 +'', # 0x24 +'', # 0x25 +'', # 0x26 +'', # 0x27 +'', # 0x28 +'', # 0x29 +'K', # 0x2a +'A', # 0x2b +'', # 0x2c +'', # 0x2d +'', # 0x2e +'', # 0x2f +'', # 0x30 +'', # 0x31 +'F', # 0x32 +'', # 0x33 +'', # 0x34 +'', # 0x35 +'', # 0x36 +'', # 0x37 +'', # 0x38 +'', # 0x39 +'', # 0x3a +'FAX', # 0x3b +'[?]', # 0x3c +'[?]', # 0x3d +'[?]', # 0x3e +'[?]', # 0x3f +'[?]', # 0x40 +'[?]', # 0x41 +'[?]', # 0x42 +'[?]', # 0x43 +'[?]', # 0x44 +'[?]', # 0x45 +'[?]', # 0x46 +'[?]', # 0x47 +'[?]', # 0x48 +'[?]', # 0x49 +'[?]', # 0x4a +'[?]', # 0x4b +'[?]', # 0x4c +'[?]', # 0x4d +'F', # 0x4e +'[?]', # 0x4f +'[?]', # 0x50 +'[?]', # 0x51 +'[?]', # 0x52 +' 1/3 ', # 0x53 +' 2/3 ', # 0x54 +' 1/5 ', # 0x55 +' 2/5 ', # 0x56 +' 3/5 ', # 0x57 +' 4/5 ', # 0x58 +' 1/6 ', # 0x59 +' 5/6 ', # 0x5a +' 1/8 ', # 0x5b +' 3/8 ', # 0x5c +' 5/8 ', # 0x5d +' 7/8 ', # 0x5e +' 1/', # 0x5f +'I', # 0x60 +'II', # 0x61 +'III', # 0x62 +'IV', # 0x63 +'V', # 0x64 +'VI', # 0x65 +'VII', # 0x66 +'VIII', # 0x67 +'IX', # 0x68 +'X', # 0x69 +'XI', # 0x6a +'XII', # 0x6b +'L', # 0x6c +'C', # 0x6d +'D', # 0x6e +'M', # 0x6f +'i', # 0x70 +'ii', # 0x71 +'iii', # 0x72 +'iv', # 0x73 +'v', # 0x74 +'vi', # 0x75 +'vii', # 0x76 +'viii', # 0x77 +'ix', # 0x78 +'x', # 0x79 +'xi', # 0x7a +'xii', # 0x7b +'l', # 0x7c +'c', # 0x7d +'d', # 0x7e +'m', # 0x7f +'(D', # 0x80 +'D)', # 0x81 +'((|))', # 0x82 +')', # 0x83 +'[?]', # 0x84 +'[?]', # 0x85 +'[?]', # 0x86 +'[?]', # 0x87 +'[?]', # 0x88 +'[?]', # 0x89 +'[?]', # 0x8a +'[?]', # 0x8b +'[?]', # 0x8c +'[?]', # 0x8d +'[?]', # 0x8e +'[?]', # 0x8f +'-', # 0x90 +'|', # 0x91 +'-', # 0x92 +'|', # 0x93 +'-', # 0x94 +'|', # 0x95 +'\\', # 0x96 +'/', # 0x97 +'\\', # 0x98 +'/', # 0x99 +'-', # 0x9a +'-', # 0x9b +'~', # 0x9c +'~', # 0x9d +'-', # 0x9e +'|', # 0x9f +'-', # 0xa0 +'|', # 0xa1 +'-', # 0xa2 +'-', # 0xa3 +'-', # 0xa4 +'|', # 0xa5 +'-', # 0xa6 +'|', # 0xa7 +'|', # 0xa8 +'-', # 0xa9 +'-', # 0xaa +'-', # 0xab +'-', # 0xac +'-', # 0xad +'-', # 0xae +'|', # 0xaf +'|', # 0xb0 +'|', # 0xb1 +'|', # 0xb2 +'|', # 0xb3 +'|', # 0xb4 +'|', # 0xb5 +'^', # 0xb6 +'V', # 0xb7 +'\\', # 0xb8 +'=', # 0xb9 +'V', # 0xba +'^', # 0xbb +'-', # 0xbc +'-', # 0xbd +'|', # 0xbe +'|', # 0xbf +'-', # 0xc0 +'-', # 0xc1 +'|', # 0xc2 +'|', # 0xc3 +'=', # 0xc4 +'|', # 0xc5 +'=', # 0xc6 +'=', # 0xc7 +'|', # 0xc8 +'=', # 0xc9 +'|', # 0xca +'=', # 0xcb +'=', # 0xcc +'=', # 0xcd +'=', # 0xce +'=', # 0xcf +'=', # 0xd0 +'|', # 0xd1 +'=', # 0xd2 +'|', # 0xd3 +'=', # 0xd4 +'|', # 0xd5 +'\\', # 0xd6 +'/', # 0xd7 +'\\', # 0xd8 +'/', # 0xd9 +'=', # 0xda +'=', # 0xdb +'~', # 0xdc +'~', # 0xdd +'|', # 0xde +'|', # 0xdf +'-', # 0xe0 +'|', # 0xe1 +'-', # 0xe2 +'|', # 0xe3 +'-', # 0xe4 +'-', # 0xe5 +'-', # 0xe6 +'|', # 0xe7 +'-', # 0xe8 +'|', # 0xe9 +'|', # 0xea +'|', # 0xeb +'|', # 0xec +'|', # 0xed +'|', # 0xee +'|', # 0xef +'-', # 0xf0 +'\\', # 0xf1 +'\\', # 0xf2 +'|', # 0xf3 +'[?]', # 0xf4 +'[?]', # 0xf5 +'[?]', # 0xf6 +'[?]', # 0xf7 +'[?]', # 0xf8 +'[?]', # 0xf9 +'[?]', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x022.py b/libs/unidecode/x022.py new file mode 100644 index 00000000..e38fb5cc --- /dev/null +++ b/libs/unidecode/x022.py @@ -0,0 +1,257 @@ +data = ( +'[?]', # 0x00 +'[?]', # 0x01 +'[?]', # 0x02 +'[?]', # 0x03 +'[?]', # 0x04 +'[?]', # 0x05 +'[?]', # 0x06 +'[?]', # 0x07 +'[?]', # 0x08 +'[?]', # 0x09 +'[?]', # 0x0a +'[?]', # 0x0b +'[?]', # 0x0c +'[?]', # 0x0d +'[?]', # 0x0e +'[?]', # 0x0f +'[?]', # 0x10 +'[?]', # 0x11 +'-', # 0x12 +'[?]', # 0x13 +'[?]', # 0x14 +'/', # 0x15 +'\\', # 0x16 +'*', # 0x17 +'[?]', # 0x18 +'[?]', # 0x19 +'[?]', # 0x1a +'[?]', # 0x1b +'[?]', # 0x1c +'[?]', # 0x1d +'[?]', # 0x1e +'[?]', # 0x1f +'[?]', # 0x20 +'[?]', # 0x21 +'[?]', # 0x22 +'|', # 0x23 +'[?]', # 0x24 +'[?]', # 0x25 +'[?]', # 0x26 +'[?]', # 0x27 +'[?]', # 0x28 +'[?]', # 0x29 +'[?]', # 0x2a +'[?]', # 0x2b +'[?]', # 0x2c +'[?]', # 0x2d +'[?]', # 0x2e +'[?]', # 0x2f +'[?]', # 0x30 +'[?]', # 0x31 +'[?]', # 0x32 +'[?]', # 0x33 +'[?]', # 0x34 +'[?]', # 0x35 +':', # 0x36 +'[?]', # 0x37 +'[?]', # 0x38 +'[?]', # 0x39 +'[?]', # 0x3a +'[?]', # 0x3b +'~', # 0x3c +'[?]', # 0x3d +'[?]', # 0x3e +'[?]', # 0x3f +'[?]', # 0x40 +'[?]', # 0x41 +'[?]', # 0x42 +'[?]', # 0x43 +'[?]', # 0x44 +'[?]', # 0x45 +'[?]', # 0x46 +'[?]', # 0x47 +'[?]', # 0x48 +'[?]', # 0x49 +'[?]', # 0x4a +'[?]', # 0x4b +'[?]', # 0x4c +'[?]', # 0x4d +'[?]', # 0x4e +'[?]', # 0x4f +'[?]', # 0x50 +'[?]', # 0x51 +'[?]', # 0x52 +'[?]', # 0x53 +'[?]', # 0x54 +'[?]', # 0x55 +'[?]', # 0x56 +'[?]', # 0x57 +'[?]', # 0x58 +'[?]', # 0x59 +'[?]', # 0x5a +'[?]', # 0x5b +'[?]', # 0x5c +'[?]', # 0x5d +'[?]', # 0x5e +'[?]', # 0x5f +'[?]', # 0x60 +'[?]', # 0x61 +'[?]', # 0x62 +'[?]', # 0x63 +'<=', # 0x64 +'>=', # 0x65 +'<=', # 0x66 +'>=', # 0x67 +'[?]', # 0x68 +'[?]', # 0x69 +'[?]', # 0x6a +'[?]', # 0x6b +'[?]', # 0x6c +'[?]', # 0x6d +'[?]', # 0x6e +'[?]', # 0x6f +'[?]', # 0x70 +'[?]', # 0x71 +'[?]', # 0x72 +'[?]', # 0x73 +'[?]', # 0x74 +'[?]', # 0x75 +'[?]', # 0x76 +'[?]', # 0x77 +'[?]', # 0x78 +'[?]', # 0x79 +'[?]', # 0x7a +'[?]', # 0x7b +'[?]', # 0x7c +'[?]', # 0x7d +'[?]', # 0x7e +'[?]', # 0x7f +'[?]', # 0x80 +'[?]', # 0x81 +'[?]', # 0x82 +'[?]', # 0x83 +'[?]', # 0x84 +'[?]', # 0x85 +'[?]', # 0x86 +'[?]', # 0x87 +'[?]', # 0x88 +'[?]', # 0x89 +'[?]', # 0x8a +'[?]', # 0x8b +'[?]', # 0x8c +'[?]', # 0x8d +'[?]', # 0x8e +'[?]', # 0x8f +'[?]', # 0x90 +'[?]', # 0x91 +'[?]', # 0x92 +'[?]', # 0x93 +'[?]', # 0x94 +'[?]', # 0x95 +'[?]', # 0x96 +'[?]', # 0x97 +'[?]', # 0x98 +'[?]', # 0x99 +'[?]', # 0x9a +'[?]', # 0x9b +'[?]', # 0x9c +'[?]', # 0x9d +'[?]', # 0x9e +'[?]', # 0x9f +'[?]', # 0xa0 +'[?]', # 0xa1 +'[?]', # 0xa2 +'[?]', # 0xa3 +'[?]', # 0xa4 +'[?]', # 0xa5 +'[?]', # 0xa6 +'[?]', # 0xa7 +'[?]', # 0xa8 +'[?]', # 0xa9 +'[?]', # 0xaa +'[?]', # 0xab +'[?]', # 0xac +'[?]', # 0xad +'[?]', # 0xae +'[?]', # 0xaf +'[?]', # 0xb0 +'[?]', # 0xb1 +'[?]', # 0xb2 +'[?]', # 0xb3 +'[?]', # 0xb4 +'[?]', # 0xb5 +'[?]', # 0xb6 +'[?]', # 0xb7 +'[?]', # 0xb8 +'[?]', # 0xb9 +'[?]', # 0xba +'[?]', # 0xbb +'[?]', # 0xbc +'[?]', # 0xbd +'[?]', # 0xbe +'[?]', # 0xbf +'[?]', # 0xc0 +'[?]', # 0xc1 +'[?]', # 0xc2 +'[?]', # 0xc3 +'[?]', # 0xc4 +'[?]', # 0xc5 +'[?]', # 0xc6 +'[?]', # 0xc7 +'[?]', # 0xc8 +'[?]', # 0xc9 +'[?]', # 0xca +'[?]', # 0xcb +'[?]', # 0xcc +'[?]', # 0xcd +'[?]', # 0xce +'[?]', # 0xcf +'[?]', # 0xd0 +'[?]', # 0xd1 +'[?]', # 0xd2 +'[?]', # 0xd3 +'[?]', # 0xd4 +'[?]', # 0xd5 +'[?]', # 0xd6 +'[?]', # 0xd7 +'[?]', # 0xd8 +'[?]', # 0xd9 +'[?]', # 0xda +'[?]', # 0xdb +'[?]', # 0xdc +'[?]', # 0xdd +'[?]', # 0xde +'[?]', # 0xdf +'[?]', # 0xe0 +'[?]', # 0xe1 +'[?]', # 0xe2 +'[?]', # 0xe3 +'[?]', # 0xe4 +'[?]', # 0xe5 +'[?]', # 0xe6 +'[?]', # 0xe7 +'[?]', # 0xe8 +'[?]', # 0xe9 +'[?]', # 0xea +'[?]', # 0xeb +'[?]', # 0xec +'[?]', # 0xed +'[?]', # 0xee +'[?]', # 0xef +'[?]', # 0xf0 +'[?]', # 0xf1 +'[?]', # 0xf2 +'[?]', # 0xf3 +'[?]', # 0xf4 +'[?]', # 0xf5 +'[?]', # 0xf6 +'[?]', # 0xf7 +'[?]', # 0xf8 +'[?]', # 0xf9 +'[?]', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x023.py b/libs/unidecode/x023.py new file mode 100644 index 00000000..3c4462e2 --- /dev/null +++ b/libs/unidecode/x023.py @@ -0,0 +1,257 @@ +data = ( +'[?]', # 0x00 +'[?]', # 0x01 +'[?]', # 0x02 +'^', # 0x03 +'[?]', # 0x04 +'[?]', # 0x05 +'[?]', # 0x06 +'[?]', # 0x07 +'[?]', # 0x08 +'[?]', # 0x09 +'[?]', # 0x0a +'[?]', # 0x0b +'[?]', # 0x0c +'[?]', # 0x0d +'[?]', # 0x0e +'[?]', # 0x0f +'[?]', # 0x10 +'[?]', # 0x11 +'[?]', # 0x12 +'[?]', # 0x13 +'[?]', # 0x14 +'[?]', # 0x15 +'[?]', # 0x16 +'[?]', # 0x17 +'[?]', # 0x18 +'[?]', # 0x19 +'[?]', # 0x1a +'[?]', # 0x1b +'[?]', # 0x1c +'[?]', # 0x1d +'[?]', # 0x1e +'[?]', # 0x1f +'[?]', # 0x20 +'[?]', # 0x21 +'[?]', # 0x22 +'[?]', # 0x23 +'[?]', # 0x24 +'[?]', # 0x25 +'[?]', # 0x26 +'[?]', # 0x27 +'[?]', # 0x28 +'<', # 0x29 +'> ', # 0x2a +'[?]', # 0x2b +'[?]', # 0x2c +'[?]', # 0x2d +'[?]', # 0x2e +'[?]', # 0x2f +'[?]', # 0x30 +'[?]', # 0x31 +'[?]', # 0x32 +'[?]', # 0x33 +'[?]', # 0x34 +'[?]', # 0x35 +'[?]', # 0x36 +'[?]', # 0x37 +'[?]', # 0x38 +'[?]', # 0x39 +'[?]', # 0x3a +'[?]', # 0x3b +'[?]', # 0x3c +'[?]', # 0x3d +'[?]', # 0x3e +'[?]', # 0x3f +'[?]', # 0x40 +'[?]', # 0x41 +'[?]', # 0x42 +'[?]', # 0x43 +'[?]', # 0x44 +'[?]', # 0x45 +'[?]', # 0x46 +'[?]', # 0x47 +'[?]', # 0x48 +'[?]', # 0x49 +'[?]', # 0x4a +'[?]', # 0x4b +'[?]', # 0x4c +'[?]', # 0x4d +'[?]', # 0x4e +'[?]', # 0x4f +'[?]', # 0x50 +'[?]', # 0x51 +'[?]', # 0x52 +'[?]', # 0x53 +'[?]', # 0x54 +'[?]', # 0x55 +'[?]', # 0x56 +'[?]', # 0x57 +'[?]', # 0x58 +'[?]', # 0x59 +'[?]', # 0x5a +'[?]', # 0x5b +'[?]', # 0x5c +'[?]', # 0x5d +'[?]', # 0x5e +'[?]', # 0x5f +'[?]', # 0x60 +'[?]', # 0x61 +'[?]', # 0x62 +'[?]', # 0x63 +'[?]', # 0x64 +'[?]', # 0x65 +'[?]', # 0x66 +'[?]', # 0x67 +'[?]', # 0x68 +'[?]', # 0x69 +'[?]', # 0x6a +'[?]', # 0x6b +'[?]', # 0x6c +'[?]', # 0x6d +'[?]', # 0x6e +'[?]', # 0x6f +'[?]', # 0x70 +'[?]', # 0x71 +'[?]', # 0x72 +'[?]', # 0x73 +'[?]', # 0x74 +'[?]', # 0x75 +'[?]', # 0x76 +'[?]', # 0x77 +'[?]', # 0x78 +'[?]', # 0x79 +'[?]', # 0x7a +'[?]', # 0x7b +'[?]', # 0x7c +'[?]', # 0x7d +'[?]', # 0x7e +'[?]', # 0x7f +'[?]', # 0x80 +'[?]', # 0x81 +'[?]', # 0x82 +'[?]', # 0x83 +'[?]', # 0x84 +'[?]', # 0x85 +'[?]', # 0x86 +'[?]', # 0x87 +'[?]', # 0x88 +'[?]', # 0x89 +'[?]', # 0x8a +'[?]', # 0x8b +'[?]', # 0x8c +'[?]', # 0x8d +'[?]', # 0x8e +'[?]', # 0x8f +'[?]', # 0x90 +'[?]', # 0x91 +'[?]', # 0x92 +'[?]', # 0x93 +'[?]', # 0x94 +'[?]', # 0x95 +'[?]', # 0x96 +'[?]', # 0x97 +'[?]', # 0x98 +'[?]', # 0x99 +'[?]', # 0x9a +'[?]', # 0x9b +'[?]', # 0x9c +'[?]', # 0x9d +'[?]', # 0x9e +'[?]', # 0x9f +'[?]', # 0xa0 +'[?]', # 0xa1 +'[?]', # 0xa2 +'[?]', # 0xa3 +'[?]', # 0xa4 +'[?]', # 0xa5 +'[?]', # 0xa6 +'[?]', # 0xa7 +'[?]', # 0xa8 +'[?]', # 0xa9 +'[?]', # 0xaa +'[?]', # 0xab +'[?]', # 0xac +'[?]', # 0xad +'[?]', # 0xae +'[?]', # 0xaf +'[?]', # 0xb0 +'[?]', # 0xb1 +'[?]', # 0xb2 +'[?]', # 0xb3 +'[?]', # 0xb4 +'[?]', # 0xb5 +'[?]', # 0xb6 +'[?]', # 0xb7 +'[?]', # 0xb8 +'[?]', # 0xb9 +'[?]', # 0xba +'[?]', # 0xbb +'[?]', # 0xbc +'[?]', # 0xbd +'[?]', # 0xbe +'[?]', # 0xbf +'[?]', # 0xc0 +'[?]', # 0xc1 +'[?]', # 0xc2 +'[?]', # 0xc3 +'[?]', # 0xc4 +'[?]', # 0xc5 +'[?]', # 0xc6 +'[?]', # 0xc7 +'[?]', # 0xc8 +'[?]', # 0xc9 +'[?]', # 0xca +'[?]', # 0xcb +'[?]', # 0xcc +'[?]', # 0xcd +'[?]', # 0xce +'[?]', # 0xcf +'[?]', # 0xd0 +'[?]', # 0xd1 +'[?]', # 0xd2 +'[?]', # 0xd3 +'[?]', # 0xd4 +'[?]', # 0xd5 +'[?]', # 0xd6 +'[?]', # 0xd7 +'[?]', # 0xd8 +'[?]', # 0xd9 +'[?]', # 0xda +'[?]', # 0xdb +'[?]', # 0xdc +'[?]', # 0xdd +'[?]', # 0xde +'[?]', # 0xdf +'[?]', # 0xe0 +'[?]', # 0xe1 +'[?]', # 0xe2 +'[?]', # 0xe3 +'[?]', # 0xe4 +'[?]', # 0xe5 +'[?]', # 0xe6 +'[?]', # 0xe7 +'[?]', # 0xe8 +'[?]', # 0xe9 +'[?]', # 0xea +'[?]', # 0xeb +'[?]', # 0xec +'[?]', # 0xed +'[?]', # 0xee +'[?]', # 0xef +'[?]', # 0xf0 +'[?]', # 0xf1 +'[?]', # 0xf2 +'[?]', # 0xf3 +'[?]', # 0xf4 +'[?]', # 0xf5 +'[?]', # 0xf6 +'[?]', # 0xf7 +'[?]', # 0xf8 +'[?]', # 0xf9 +'[?]', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x024.py b/libs/unidecode/x024.py new file mode 100644 index 00000000..20b3c8f1 --- /dev/null +++ b/libs/unidecode/x024.py @@ -0,0 +1,257 @@ +data = ( +'', # 0x00 +'', # 0x01 +'', # 0x02 +'', # 0x03 +'', # 0x04 +'', # 0x05 +'', # 0x06 +'', # 0x07 +'', # 0x08 +'', # 0x09 +'', # 0x0a +'', # 0x0b +'', # 0x0c +'', # 0x0d +'', # 0x0e +'', # 0x0f +'', # 0x10 +'', # 0x11 +'', # 0x12 +'', # 0x13 +'', # 0x14 +'', # 0x15 +'', # 0x16 +'', # 0x17 +'', # 0x18 +'', # 0x19 +'', # 0x1a +'', # 0x1b +'', # 0x1c +'', # 0x1d +'', # 0x1e +'', # 0x1f +'', # 0x20 +'', # 0x21 +'', # 0x22 +'', # 0x23 +'', # 0x24 +'', # 0x25 +'', # 0x26 +'[?]', # 0x27 +'[?]', # 0x28 +'[?]', # 0x29 +'[?]', # 0x2a +'[?]', # 0x2b +'[?]', # 0x2c +'[?]', # 0x2d +'[?]', # 0x2e +'[?]', # 0x2f +'[?]', # 0x30 +'[?]', # 0x31 +'[?]', # 0x32 +'[?]', # 0x33 +'[?]', # 0x34 +'[?]', # 0x35 +'[?]', # 0x36 +'[?]', # 0x37 +'[?]', # 0x38 +'[?]', # 0x39 +'[?]', # 0x3a +'[?]', # 0x3b +'[?]', # 0x3c +'[?]', # 0x3d +'[?]', # 0x3e +'[?]', # 0x3f +'', # 0x40 +'', # 0x41 +'', # 0x42 +'', # 0x43 +'', # 0x44 +'', # 0x45 +'', # 0x46 +'', # 0x47 +'', # 0x48 +'', # 0x49 +'', # 0x4a +'[?]', # 0x4b +'[?]', # 0x4c +'[?]', # 0x4d +'[?]', # 0x4e +'[?]', # 0x4f +'[?]', # 0x50 +'[?]', # 0x51 +'[?]', # 0x52 +'[?]', # 0x53 +'[?]', # 0x54 +'[?]', # 0x55 +'[?]', # 0x56 +'[?]', # 0x57 +'[?]', # 0x58 +'[?]', # 0x59 +'[?]', # 0x5a +'[?]', # 0x5b +'[?]', # 0x5c +'[?]', # 0x5d +'[?]', # 0x5e +'[?]', # 0x5f +'1', # 0x60 +'2', # 0x61 +'3', # 0x62 +'4', # 0x63 +'5', # 0x64 +'6', # 0x65 +'7', # 0x66 +'8', # 0x67 +'9', # 0x68 +'10', # 0x69 +'11', # 0x6a +'12', # 0x6b +'13', # 0x6c +'14', # 0x6d +'15', # 0x6e +'16', # 0x6f +'17', # 0x70 +'18', # 0x71 +'19', # 0x72 +'20', # 0x73 +'(1)', # 0x74 +'(2)', # 0x75 +'(3)', # 0x76 +'(4)', # 0x77 +'(5)', # 0x78 +'(6)', # 0x79 +'(7)', # 0x7a +'(8)', # 0x7b +'(9)', # 0x7c +'(10)', # 0x7d +'(11)', # 0x7e +'(12)', # 0x7f +'(13)', # 0x80 +'(14)', # 0x81 +'(15)', # 0x82 +'(16)', # 0x83 +'(17)', # 0x84 +'(18)', # 0x85 +'(19)', # 0x86 +'(20)', # 0x87 +'1.', # 0x88 +'2.', # 0x89 +'3.', # 0x8a +'4.', # 0x8b +'5.', # 0x8c +'6.', # 0x8d +'7.', # 0x8e +'8.', # 0x8f +'9.', # 0x90 +'10.', # 0x91 +'11.', # 0x92 +'12.', # 0x93 +'13.', # 0x94 +'14.', # 0x95 +'15.', # 0x96 +'16.', # 0x97 +'17.', # 0x98 +'18.', # 0x99 +'19.', # 0x9a +'20.', # 0x9b +'(a)', # 0x9c +'(b)', # 0x9d +'(c)', # 0x9e +'(d)', # 0x9f +'(e)', # 0xa0 +'(f)', # 0xa1 +'(g)', # 0xa2 +'(h)', # 0xa3 +'(i)', # 0xa4 +'(j)', # 0xa5 +'(k)', # 0xa6 +'(l)', # 0xa7 +'(m)', # 0xa8 +'(n)', # 0xa9 +'(o)', # 0xaa +'(p)', # 0xab +'(q)', # 0xac +'(r)', # 0xad +'(s)', # 0xae +'(t)', # 0xaf +'(u)', # 0xb0 +'(v)', # 0xb1 +'(w)', # 0xb2 +'(x)', # 0xb3 +'(y)', # 0xb4 +'(z)', # 0xb5 +'a', # 0xb6 +'b', # 0xb7 +'c', # 0xb8 +'d', # 0xb9 +'e', # 0xba +'f', # 0xbb +'g', # 0xbc +'h', # 0xbd +'i', # 0xbe +'j', # 0xbf +'k', # 0xc0 +'l', # 0xc1 +'m', # 0xc2 +'n', # 0xc3 +'o', # 0xc4 +'p', # 0xc5 +'q', # 0xc6 +'r', # 0xc7 +'s', # 0xc8 +'t', # 0xc9 +'u', # 0xca +'v', # 0xcb +'w', # 0xcc +'x', # 0xcd +'y', # 0xce +'z', # 0xcf +'a', # 0xd0 +'b', # 0xd1 +'c', # 0xd2 +'d', # 0xd3 +'e', # 0xd4 +'f', # 0xd5 +'g', # 0xd6 +'h', # 0xd7 +'i', # 0xd8 +'j', # 0xd9 +'k', # 0xda +'l', # 0xdb +'m', # 0xdc +'n', # 0xdd +'o', # 0xde +'p', # 0xdf +'q', # 0xe0 +'r', # 0xe1 +'s', # 0xe2 +'t', # 0xe3 +'u', # 0xe4 +'v', # 0xe5 +'w', # 0xe6 +'x', # 0xe7 +'y', # 0xe8 +'z', # 0xe9 +'0', # 0xea +'[?]', # 0xeb +'[?]', # 0xec +'[?]', # 0xed +'[?]', # 0xee +'[?]', # 0xef +'[?]', # 0xf0 +'[?]', # 0xf1 +'[?]', # 0xf2 +'[?]', # 0xf3 +'[?]', # 0xf4 +'[?]', # 0xf5 +'[?]', # 0xf6 +'[?]', # 0xf7 +'[?]', # 0xf8 +'[?]', # 0xf9 +'[?]', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x025.py b/libs/unidecode/x025.py new file mode 100644 index 00000000..5a62b10d --- /dev/null +++ b/libs/unidecode/x025.py @@ -0,0 +1,257 @@ +data = ( +'-', # 0x00 +'-', # 0x01 +'|', # 0x02 +'|', # 0x03 +'-', # 0x04 +'-', # 0x05 +'|', # 0x06 +'|', # 0x07 +'-', # 0x08 +'-', # 0x09 +'|', # 0x0a +'|', # 0x0b +'+', # 0x0c +'+', # 0x0d +'+', # 0x0e +'+', # 0x0f +'+', # 0x10 +'+', # 0x11 +'+', # 0x12 +'+', # 0x13 +'+', # 0x14 +'+', # 0x15 +'+', # 0x16 +'+', # 0x17 +'+', # 0x18 +'+', # 0x19 +'+', # 0x1a +'+', # 0x1b +'+', # 0x1c +'+', # 0x1d +'+', # 0x1e +'+', # 0x1f +'+', # 0x20 +'+', # 0x21 +'+', # 0x22 +'+', # 0x23 +'+', # 0x24 +'+', # 0x25 +'+', # 0x26 +'+', # 0x27 +'+', # 0x28 +'+', # 0x29 +'+', # 0x2a +'+', # 0x2b +'+', # 0x2c +'+', # 0x2d +'+', # 0x2e +'+', # 0x2f +'+', # 0x30 +'+', # 0x31 +'+', # 0x32 +'+', # 0x33 +'+', # 0x34 +'+', # 0x35 +'+', # 0x36 +'+', # 0x37 +'+', # 0x38 +'+', # 0x39 +'+', # 0x3a +'+', # 0x3b +'+', # 0x3c +'+', # 0x3d +'+', # 0x3e +'+', # 0x3f +'+', # 0x40 +'+', # 0x41 +'+', # 0x42 +'+', # 0x43 +'+', # 0x44 +'+', # 0x45 +'+', # 0x46 +'+', # 0x47 +'+', # 0x48 +'+', # 0x49 +'+', # 0x4a +'+', # 0x4b +'-', # 0x4c +'-', # 0x4d +'|', # 0x4e +'|', # 0x4f +'-', # 0x50 +'|', # 0x51 +'+', # 0x52 +'+', # 0x53 +'+', # 0x54 +'+', # 0x55 +'+', # 0x56 +'+', # 0x57 +'+', # 0x58 +'+', # 0x59 +'+', # 0x5a +'+', # 0x5b +'+', # 0x5c +'+', # 0x5d +'+', # 0x5e +'+', # 0x5f +'+', # 0x60 +'+', # 0x61 +'+', # 0x62 +'+', # 0x63 +'+', # 0x64 +'+', # 0x65 +'+', # 0x66 +'+', # 0x67 +'+', # 0x68 +'+', # 0x69 +'+', # 0x6a +'+', # 0x6b +'+', # 0x6c +'+', # 0x6d +'+', # 0x6e +'+', # 0x6f +'+', # 0x70 +'/', # 0x71 +'\\', # 0x72 +'X', # 0x73 +'-', # 0x74 +'|', # 0x75 +'-', # 0x76 +'|', # 0x77 +'-', # 0x78 +'|', # 0x79 +'-', # 0x7a +'|', # 0x7b +'-', # 0x7c +'|', # 0x7d +'-', # 0x7e +'|', # 0x7f +'#', # 0x80 +'#', # 0x81 +'#', # 0x82 +'#', # 0x83 +'#', # 0x84 +'#', # 0x85 +'#', # 0x86 +'#', # 0x87 +'#', # 0x88 +'#', # 0x89 +'#', # 0x8a +'#', # 0x8b +'#', # 0x8c +'#', # 0x8d +'#', # 0x8e +'#', # 0x8f +'#', # 0x90 +'#', # 0x91 +'#', # 0x92 +'#', # 0x93 +'-', # 0x94 +'|', # 0x95 +'[?]', # 0x96 +'[?]', # 0x97 +'[?]', # 0x98 +'[?]', # 0x99 +'[?]', # 0x9a +'[?]', # 0x9b +'[?]', # 0x9c +'[?]', # 0x9d +'[?]', # 0x9e +'[?]', # 0x9f +'#', # 0xa0 +'#', # 0xa1 +'#', # 0xa2 +'#', # 0xa3 +'#', # 0xa4 +'#', # 0xa5 +'#', # 0xa6 +'#', # 0xa7 +'#', # 0xa8 +'#', # 0xa9 +'#', # 0xaa +'#', # 0xab +'#', # 0xac +'#', # 0xad +'#', # 0xae +'#', # 0xaf +'#', # 0xb0 +'#', # 0xb1 +'^', # 0xb2 +'^', # 0xb3 +'^', # 0xb4 +'^', # 0xb5 +'>', # 0xb6 +'>', # 0xb7 +'>', # 0xb8 +'>', # 0xb9 +'>', # 0xba +'>', # 0xbb +'V', # 0xbc +'V', # 0xbd +'V', # 0xbe +'V', # 0xbf +'<', # 0xc0 +'<', # 0xc1 +'<', # 0xc2 +'<', # 0xc3 +'<', # 0xc4 +'<', # 0xc5 +'*', # 0xc6 +'*', # 0xc7 +'*', # 0xc8 +'*', # 0xc9 +'*', # 0xca +'*', # 0xcb +'*', # 0xcc +'*', # 0xcd +'*', # 0xce +'*', # 0xcf +'*', # 0xd0 +'*', # 0xd1 +'*', # 0xd2 +'*', # 0xd3 +'*', # 0xd4 +'*', # 0xd5 +'*', # 0xd6 +'*', # 0xd7 +'*', # 0xd8 +'*', # 0xd9 +'*', # 0xda +'*', # 0xdb +'*', # 0xdc +'*', # 0xdd +'*', # 0xde +'*', # 0xdf +'*', # 0xe0 +'*', # 0xe1 +'*', # 0xe2 +'*', # 0xe3 +'*', # 0xe4 +'*', # 0xe5 +'*', # 0xe6 +'#', # 0xe7 +'#', # 0xe8 +'#', # 0xe9 +'#', # 0xea +'#', # 0xeb +'^', # 0xec +'^', # 0xed +'^', # 0xee +'O', # 0xef +'#', # 0xf0 +'#', # 0xf1 +'#', # 0xf2 +'#', # 0xf3 +'#', # 0xf4 +'#', # 0xf5 +'#', # 0xf6 +'#', # 0xf7 +'[?]', # 0xf8 +'[?]', # 0xf9 +'[?]', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x026.py b/libs/unidecode/x026.py new file mode 100644 index 00000000..c575472c --- /dev/null +++ b/libs/unidecode/x026.py @@ -0,0 +1,257 @@ +data = ( +'', # 0x00 +'', # 0x01 +'', # 0x02 +'', # 0x03 +'', # 0x04 +'', # 0x05 +'', # 0x06 +'', # 0x07 +'', # 0x08 +'', # 0x09 +'', # 0x0a +'', # 0x0b +'', # 0x0c +'', # 0x0d +'', # 0x0e +'', # 0x0f +'', # 0x10 +'', # 0x11 +'', # 0x12 +'', # 0x13 +'[?]', # 0x14 +'[?]', # 0x15 +'[?]', # 0x16 +'[?]', # 0x17 +'[?]', # 0x18 +'', # 0x19 +'', # 0x1a +'', # 0x1b +'', # 0x1c +'', # 0x1d +'', # 0x1e +'', # 0x1f +'', # 0x20 +'', # 0x21 +'', # 0x22 +'', # 0x23 +'', # 0x24 +'', # 0x25 +'', # 0x26 +'', # 0x27 +'', # 0x28 +'', # 0x29 +'', # 0x2a +'', # 0x2b +'', # 0x2c +'', # 0x2d +'', # 0x2e +'', # 0x2f +'', # 0x30 +'', # 0x31 +'', # 0x32 +'', # 0x33 +'', # 0x34 +'', # 0x35 +'', # 0x36 +'', # 0x37 +'', # 0x38 +'', # 0x39 +'', # 0x3a +'', # 0x3b +'', # 0x3c +'', # 0x3d +'', # 0x3e +'', # 0x3f +'', # 0x40 +'', # 0x41 +'', # 0x42 +'', # 0x43 +'', # 0x44 +'', # 0x45 +'', # 0x46 +'', # 0x47 +'', # 0x48 +'', # 0x49 +'', # 0x4a +'', # 0x4b +'', # 0x4c +'', # 0x4d +'', # 0x4e +'', # 0x4f +'', # 0x50 +'', # 0x51 +'', # 0x52 +'', # 0x53 +'', # 0x54 +'', # 0x55 +'', # 0x56 +'', # 0x57 +'', # 0x58 +'', # 0x59 +'', # 0x5a +'', # 0x5b +'', # 0x5c +'', # 0x5d +'', # 0x5e +'', # 0x5f +'', # 0x60 +'', # 0x61 +'', # 0x62 +'', # 0x63 +'', # 0x64 +'', # 0x65 +'', # 0x66 +'', # 0x67 +'', # 0x68 +'', # 0x69 +'', # 0x6a +'', # 0x6b +'', # 0x6c +'', # 0x6d +'', # 0x6e +'#', # 0x6f +'', # 0x70 +'', # 0x71 +'[?]', # 0x72 +'[?]', # 0x73 +'[?]', # 0x74 +'[?]', # 0x75 +'[?]', # 0x76 +'[?]', # 0x77 +'[?]', # 0x78 +'[?]', # 0x79 +'[?]', # 0x7a +'[?]', # 0x7b +'[?]', # 0x7c +'[?]', # 0x7d +'[?]', # 0x7e +'[?]', # 0x7f +'[?]', # 0x80 +'[?]', # 0x81 +'[?]', # 0x82 +'[?]', # 0x83 +'[?]', # 0x84 +'[?]', # 0x85 +'[?]', # 0x86 +'[?]', # 0x87 +'[?]', # 0x88 +'[?]', # 0x89 +'[?]', # 0x8a +'[?]', # 0x8b +'[?]', # 0x8c +'[?]', # 0x8d +'[?]', # 0x8e +'[?]', # 0x8f +'[?]', # 0x90 +'[?]', # 0x91 +'[?]', # 0x92 +'[?]', # 0x93 +'[?]', # 0x94 +'[?]', # 0x95 +'[?]', # 0x96 +'[?]', # 0x97 +'[?]', # 0x98 +'[?]', # 0x99 +'[?]', # 0x9a +'[?]', # 0x9b +'[?]', # 0x9c +'[?]', # 0x9d +'[?]', # 0x9e +'[?]', # 0x9f +'[?]', # 0xa0 +'[?]', # 0xa1 +'[?]', # 0xa2 +'[?]', # 0xa3 +'[?]', # 0xa4 +'[?]', # 0xa5 +'[?]', # 0xa6 +'[?]', # 0xa7 +'[?]', # 0xa8 +'[?]', # 0xa9 +'[?]', # 0xaa +'[?]', # 0xab +'[?]', # 0xac +'[?]', # 0xad +'[?]', # 0xae +'[?]', # 0xaf +'[?]', # 0xb0 +'[?]', # 0xb1 +'[?]', # 0xb2 +'[?]', # 0xb3 +'[?]', # 0xb4 +'[?]', # 0xb5 +'[?]', # 0xb6 +'[?]', # 0xb7 +'[?]', # 0xb8 +'[?]', # 0xb9 +'[?]', # 0xba +'[?]', # 0xbb +'[?]', # 0xbc +'[?]', # 0xbd +'[?]', # 0xbe +'[?]', # 0xbf +'[?]', # 0xc0 +'[?]', # 0xc1 +'[?]', # 0xc2 +'[?]', # 0xc3 +'[?]', # 0xc4 +'[?]', # 0xc5 +'[?]', # 0xc6 +'[?]', # 0xc7 +'[?]', # 0xc8 +'[?]', # 0xc9 +'[?]', # 0xca +'[?]', # 0xcb +'[?]', # 0xcc +'[?]', # 0xcd +'[?]', # 0xce +'[?]', # 0xcf +'[?]', # 0xd0 +'[?]', # 0xd1 +'[?]', # 0xd2 +'[?]', # 0xd3 +'[?]', # 0xd4 +'[?]', # 0xd5 +'[?]', # 0xd6 +'[?]', # 0xd7 +'[?]', # 0xd8 +'[?]', # 0xd9 +'[?]', # 0xda +'[?]', # 0xdb +'[?]', # 0xdc +'[?]', # 0xdd +'[?]', # 0xde +'[?]', # 0xdf +'[?]', # 0xe0 +'[?]', # 0xe1 +'[?]', # 0xe2 +'[?]', # 0xe3 +'[?]', # 0xe4 +'[?]', # 0xe5 +'[?]', # 0xe6 +'[?]', # 0xe7 +'[?]', # 0xe8 +'[?]', # 0xe9 +'[?]', # 0xea +'[?]', # 0xeb +'[?]', # 0xec +'[?]', # 0xed +'[?]', # 0xee +'[?]', # 0xef +'[?]', # 0xf0 +'[?]', # 0xf1 +'[?]', # 0xf2 +'[?]', # 0xf3 +'[?]', # 0xf4 +'[?]', # 0xf5 +'[?]', # 0xf6 +'[?]', # 0xf7 +'[?]', # 0xf8 +'[?]', # 0xf9 +'[?]', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x027.py b/libs/unidecode/x027.py new file mode 100644 index 00000000..3c74c073 --- /dev/null +++ b/libs/unidecode/x027.py @@ -0,0 +1,257 @@ +data = ( +'[?]', # 0x00 +'', # 0x01 +'', # 0x02 +'', # 0x03 +'', # 0x04 +'', # 0x05 +'', # 0x06 +'', # 0x07 +'', # 0x08 +'', # 0x09 +'', # 0x0a +'', # 0x0b +'', # 0x0c +'', # 0x0d +'', # 0x0e +'', # 0x0f +'', # 0x10 +'', # 0x11 +'', # 0x12 +'', # 0x13 +'', # 0x14 +'', # 0x15 +'', # 0x16 +'', # 0x17 +'', # 0x18 +'', # 0x19 +'', # 0x1a +'', # 0x1b +'', # 0x1c +'', # 0x1d +'', # 0x1e +'', # 0x1f +'', # 0x20 +'', # 0x21 +'', # 0x22 +'', # 0x23 +'', # 0x24 +'', # 0x25 +'', # 0x26 +'', # 0x27 +'', # 0x28 +'', # 0x29 +'', # 0x2a +'', # 0x2b +'', # 0x2c +'', # 0x2d +'', # 0x2e +'', # 0x2f +'', # 0x30 +'*', # 0x31 +'', # 0x32 +'', # 0x33 +'', # 0x34 +'', # 0x35 +'', # 0x36 +'', # 0x37 +'', # 0x38 +'', # 0x39 +'', # 0x3a +'', # 0x3b +'', # 0x3c +'', # 0x3d +'', # 0x3e +'', # 0x3f +'', # 0x40 +'', # 0x41 +'', # 0x42 +'', # 0x43 +'', # 0x44 +'', # 0x45 +'', # 0x46 +'', # 0x47 +'', # 0x48 +'', # 0x49 +'', # 0x4a +'', # 0x4b +'', # 0x4c +'', # 0x4d +'', # 0x4e +'', # 0x4f +'', # 0x50 +'', # 0x51 +'', # 0x52 +'', # 0x53 +'', # 0x54 +'', # 0x55 +'', # 0x56 +'', # 0x57 +'|', # 0x58 +'', # 0x59 +'', # 0x5a +'', # 0x5b +'', # 0x5c +'', # 0x5d +'', # 0x5e +'[?]', # 0x5f +'[?]', # 0x60 +'', # 0x61 +'!', # 0x62 +'', # 0x63 +'', # 0x64 +'', # 0x65 +'', # 0x66 +'', # 0x67 +'', # 0x68 +'', # 0x69 +'', # 0x6a +'', # 0x6b +'', # 0x6c +'', # 0x6d +'', # 0x6e +'', # 0x6f +'', # 0x70 +'', # 0x71 +'', # 0x72 +'', # 0x73 +'', # 0x74 +'', # 0x75 +'', # 0x76 +'', # 0x77 +'', # 0x78 +'', # 0x79 +'', # 0x7a +'', # 0x7b +'', # 0x7c +'', # 0x7d +'', # 0x7e +'', # 0x7f +'', # 0x80 +'', # 0x81 +'', # 0x82 +'', # 0x83 +'', # 0x84 +'', # 0x85 +'', # 0x86 +'', # 0x87 +'', # 0x88 +'', # 0x89 +'', # 0x8a +'', # 0x8b +'', # 0x8c +'', # 0x8d +'', # 0x8e +'', # 0x8f +'', # 0x90 +'', # 0x91 +'', # 0x92 +'', # 0x93 +'', # 0x94 +'', # 0x95 +'', # 0x96 +'', # 0x97 +'', # 0x98 +'', # 0x99 +'', # 0x9a +'', # 0x9b +'', # 0x9c +'', # 0x9d +'', # 0x9e +'', # 0x9f +'', # 0xa0 +'', # 0xa1 +'', # 0xa2 +'', # 0xa3 +'', # 0xa4 +'', # 0xa5 +'', # 0xa6 +'', # 0xa7 +'', # 0xa8 +'', # 0xa9 +'', # 0xaa +'', # 0xab +'', # 0xac +'', # 0xad +'', # 0xae +'', # 0xaf +'[?]', # 0xb0 +'', # 0xb1 +'', # 0xb2 +'', # 0xb3 +'', # 0xb4 +'', # 0xb5 +'', # 0xb6 +'', # 0xb7 +'', # 0xb8 +'', # 0xb9 +'', # 0xba +'', # 0xbb +'', # 0xbc +'', # 0xbd +'', # 0xbe +'[?]', # 0xbf +'[?]', # 0xc0 +'[?]', # 0xc1 +'[?]', # 0xc2 +'[?]', # 0xc3 +'[?]', # 0xc4 +'[?]', # 0xc5 +'[?]', # 0xc6 +'[?]', # 0xc7 +'[?]', # 0xc8 +'[?]', # 0xc9 +'[?]', # 0xca +'[?]', # 0xcb +'[?]', # 0xcc +'[?]', # 0xcd +'[?]', # 0xce +'[?]', # 0xcf +'[?]', # 0xd0 +'[?]', # 0xd1 +'[?]', # 0xd2 +'[?]', # 0xd3 +'[?]', # 0xd4 +'[?]', # 0xd5 +'[?]', # 0xd6 +'[?]', # 0xd7 +'[?]', # 0xd8 +'[?]', # 0xd9 +'[?]', # 0xda +'[?]', # 0xdb +'[?]', # 0xdc +'[?]', # 0xdd +'[?]', # 0xde +'[?]', # 0xdf +'[?]', # 0xe0 +'[?]', # 0xe1 +'[?]', # 0xe2 +'[?]', # 0xe3 +'[?]', # 0xe4 +'[?]', # 0xe5 +'[', # 0xe6 +'[?]', # 0xe7 +'<', # 0xe8 +'> ', # 0xe9 +'[?]', # 0xea +'[?]', # 0xeb +'[?]', # 0xec +'[?]', # 0xed +'[?]', # 0xee +'[?]', # 0xef +'[?]', # 0xf0 +'[?]', # 0xf1 +'[?]', # 0xf2 +'[?]', # 0xf3 +'[?]', # 0xf4 +'[?]', # 0xf5 +'[?]', # 0xf6 +'[?]', # 0xf7 +'[?]', # 0xf8 +'[?]', # 0xf9 +'[?]', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x028.py b/libs/unidecode/x028.py new file mode 100644 index 00000000..dc2f3f05 --- /dev/null +++ b/libs/unidecode/x028.py @@ -0,0 +1,258 @@ +data = ( +' ', # 0x00 +'a', # 0x01 +'1', # 0x02 +'b', # 0x03 +'\'', # 0x04 +'k', # 0x05 +'2', # 0x06 +'l', # 0x07 +'@', # 0x08 +'c', # 0x09 +'i', # 0x0a +'f', # 0x0b +'/', # 0x0c +'m', # 0x0d +'s', # 0x0e +'p', # 0x0f +'"', # 0x10 +'e', # 0x11 +'3', # 0x12 +'h', # 0x13 +'9', # 0x14 +'o', # 0x15 +'6', # 0x16 +'r', # 0x17 +'^', # 0x18 +'d', # 0x19 +'j', # 0x1a +'g', # 0x1b +'>', # 0x1c +'n', # 0x1d +'t', # 0x1e +'q', # 0x1f +',', # 0x20 +'*', # 0x21 +'5', # 0x22 +'<', # 0x23 +'-', # 0x24 +'u', # 0x25 +'8', # 0x26 +'v', # 0x27 +'.', # 0x28 +'%', # 0x29 +'[', # 0x2a +'$', # 0x2b +'+', # 0x2c +'x', # 0x2d +'!', # 0x2e +'&', # 0x2f +';', # 0x30 +':', # 0x31 +'4', # 0x32 +'\\', # 0x33 +'0', # 0x34 +'z', # 0x35 +'7', # 0x36 +'(', # 0x37 +'_', # 0x38 +'?', # 0x39 +'w', # 0x3a +']', # 0x3b +'#', # 0x3c +'y', # 0x3d +')', # 0x3e +'=', # 0x3f +'[d7]', # 0x40 +'[d17]', # 0x41 +'[d27]', # 0x42 +'[d127]', # 0x43 +'[d37]', # 0x44 +'[d137]', # 0x45 +'[d237]', # 0x46 +'[d1237]', # 0x47 +'[d47]', # 0x48 +'[d147]', # 0x49 +'[d247]', # 0x4a +'[d1247]', # 0x4b +'[d347]', # 0x4c +'[d1347]', # 0x4d +'[d2347]', # 0x4e +'[d12347]', # 0x4f +'[d57]', # 0x50 +'[d157]', # 0x51 +'[d257]', # 0x52 +'[d1257]', # 0x53 +'[d357]', # 0x54 +'[d1357]', # 0x55 +'[d2357]', # 0x56 +'[d12357]', # 0x57 +'[d457]', # 0x58 +'[d1457]', # 0x59 +'[d2457]', # 0x5a +'[d12457]', # 0x5b +'[d3457]', # 0x5c +'[d13457]', # 0x5d +'[d23457]', # 0x5e +'[d123457]', # 0x5f +'[d67]', # 0x60 +'[d167]', # 0x61 +'[d267]', # 0x62 +'[d1267]', # 0x63 +'[d367]', # 0x64 +'[d1367]', # 0x65 +'[d2367]', # 0x66 +'[d12367]', # 0x67 +'[d467]', # 0x68 +'[d1467]', # 0x69 +'[d2467]', # 0x6a +'[d12467]', # 0x6b +'[d3467]', # 0x6c +'[d13467]', # 0x6d +'[d23467]', # 0x6e +'[d123467]', # 0x6f +'[d567]', # 0x70 +'[d1567]', # 0x71 +'[d2567]', # 0x72 +'[d12567]', # 0x73 +'[d3567]', # 0x74 +'[d13567]', # 0x75 +'[d23567]', # 0x76 +'[d123567]', # 0x77 +'[d4567]', # 0x78 +'[d14567]', # 0x79 +'[d24567]', # 0x7a +'[d124567]', # 0x7b +'[d34567]', # 0x7c +'[d134567]', # 0x7d +'[d234567]', # 0x7e +'[d1234567]', # 0x7f +'[d8]', # 0x80 +'[d18]', # 0x81 +'[d28]', # 0x82 +'[d128]', # 0x83 +'[d38]', # 0x84 +'[d138]', # 0x85 +'[d238]', # 0x86 +'[d1238]', # 0x87 +'[d48]', # 0x88 +'[d148]', # 0x89 +'[d248]', # 0x8a +'[d1248]', # 0x8b +'[d348]', # 0x8c +'[d1348]', # 0x8d +'[d2348]', # 0x8e +'[d12348]', # 0x8f +'[d58]', # 0x90 +'[d158]', # 0x91 +'[d258]', # 0x92 +'[d1258]', # 0x93 +'[d358]', # 0x94 +'[d1358]', # 0x95 +'[d2358]', # 0x96 +'[d12358]', # 0x97 +'[d458]', # 0x98 +'[d1458]', # 0x99 +'[d2458]', # 0x9a +'[d12458]', # 0x9b +'[d3458]', # 0x9c +'[d13458]', # 0x9d +'[d23458]', # 0x9e +'[d123458]', # 0x9f +'[d68]', # 0xa0 +'[d168]', # 0xa1 +'[d268]', # 0xa2 +'[d1268]', # 0xa3 +'[d368]', # 0xa4 +'[d1368]', # 0xa5 +'[d2368]', # 0xa6 +'[d12368]', # 0xa7 +'[d468]', # 0xa8 +'[d1468]', # 0xa9 +'[d2468]', # 0xaa +'[d12468]', # 0xab +'[d3468]', # 0xac +'[d13468]', # 0xad +'[d23468]', # 0xae +'[d123468]', # 0xaf +'[d568]', # 0xb0 +'[d1568]', # 0xb1 +'[d2568]', # 0xb2 +'[d12568]', # 0xb3 +'[d3568]', # 0xb4 +'[d13568]', # 0xb5 +'[d23568]', # 0xb6 +'[d123568]', # 0xb7 +'[d4568]', # 0xb8 +'[d14568]', # 0xb9 +'[d24568]', # 0xba +'[d124568]', # 0xbb +'[d34568]', # 0xbc +'[d134568]', # 0xbd +'[d234568]', # 0xbe +'[d1234568]', # 0xbf +'[d78]', # 0xc0 +'[d178]', # 0xc1 +'[d278]', # 0xc2 +'[d1278]', # 0xc3 +'[d378]', # 0xc4 +'[d1378]', # 0xc5 +'[d2378]', # 0xc6 +'[d12378]', # 0xc7 +'[d478]', # 0xc8 +'[d1478]', # 0xc9 +'[d2478]', # 0xca +'[d12478]', # 0xcb +'[d3478]', # 0xcc +'[d13478]', # 0xcd +'[d23478]', # 0xce +'[d123478]', # 0xcf +'[d578]', # 0xd0 +'[d1578]', # 0xd1 +'[d2578]', # 0xd2 +'[d12578]', # 0xd3 +'[d3578]', # 0xd4 +'[d13578]', # 0xd5 +'[d23578]', # 0xd6 +'[d123578]', # 0xd7 +'[d4578]', # 0xd8 +'[d14578]', # 0xd9 +'[d24578]', # 0xda +'[d124578]', # 0xdb +'[d34578]', # 0xdc +'[d134578]', # 0xdd +'[d234578]', # 0xde +'[d1234578]', # 0xdf +'[d678]', # 0xe0 +'[d1678]', # 0xe1 +'[d2678]', # 0xe2 +'[d12678]', # 0xe3 +'[d3678]', # 0xe4 +'[d13678]', # 0xe5 +'[d23678]', # 0xe6 +'[d123678]', # 0xe7 +'[d4678]', # 0xe8 +'[d14678]', # 0xe9 +'[d24678]', # 0xea +'[d124678]', # 0xeb +'[d34678]', # 0xec +'[d134678]', # 0xed +'[d234678]', # 0xee +'[d1234678]', # 0xef +'[d5678]', # 0xf0 +'[d15678]', # 0xf1 +'[d25678]', # 0xf2 +'[d125678]', # 0xf3 +'[d35678]', # 0xf4 +'[d135678]', # 0xf5 +'[d235678]', # 0xf6 +'[d1235678]', # 0xf7 +'[d45678]', # 0xf8 +'[d145678]', # 0xf9 +'[d245678]', # 0xfa +'[d1245678]', # 0xfb +'[d345678]', # 0xfc +'[d1345678]', # 0xfd +'[d2345678]', # 0xfe +'[d12345678]', # 0xff +) diff --git a/libs/unidecode/x029.py b/libs/unidecode/x029.py new file mode 100644 index 00000000..c2df2548 --- /dev/null +++ b/libs/unidecode/x029.py @@ -0,0 +1,257 @@ +data = ( +'', # 0x00 +'', # 0x01 +'', # 0x02 +'', # 0x03 +'', # 0x04 +'', # 0x05 +'', # 0x06 +'', # 0x07 +'', # 0x08 +'', # 0x09 +'', # 0x0a +'', # 0x0b +'', # 0x0c +'', # 0x0d +'', # 0x0e +'', # 0x0f +'', # 0x10 +'', # 0x11 +'', # 0x12 +'', # 0x13 +'', # 0x14 +'', # 0x15 +'', # 0x16 +'', # 0x17 +'', # 0x18 +'', # 0x19 +'', # 0x1a +'', # 0x1b +'', # 0x1c +'', # 0x1d +'', # 0x1e +'', # 0x1f +'', # 0x20 +'', # 0x21 +'', # 0x22 +'', # 0x23 +'', # 0x24 +'', # 0x25 +'', # 0x26 +'', # 0x27 +'', # 0x28 +'', # 0x29 +'', # 0x2a +'', # 0x2b +'', # 0x2c +'', # 0x2d +'', # 0x2e +'', # 0x2f +'', # 0x30 +'', # 0x31 +'', # 0x32 +'', # 0x33 +'', # 0x34 +'', # 0x35 +'', # 0x36 +'', # 0x37 +'', # 0x38 +'', # 0x39 +'', # 0x3a +'', # 0x3b +'', # 0x3c +'', # 0x3d +'', # 0x3e +'', # 0x3f +'', # 0x40 +'', # 0x41 +'', # 0x42 +'', # 0x43 +'', # 0x44 +'', # 0x45 +'', # 0x46 +'', # 0x47 +'', # 0x48 +'', # 0x49 +'', # 0x4a +'', # 0x4b +'', # 0x4c +'', # 0x4d +'', # 0x4e +'', # 0x4f +'', # 0x50 +'', # 0x51 +'', # 0x52 +'', # 0x53 +'', # 0x54 +'', # 0x55 +'', # 0x56 +'', # 0x57 +'', # 0x58 +'', # 0x59 +'', # 0x5a +'', # 0x5b +'', # 0x5c +'', # 0x5d +'', # 0x5e +'', # 0x5f +'', # 0x60 +'', # 0x61 +'', # 0x62 +'', # 0x63 +'', # 0x64 +'', # 0x65 +'', # 0x66 +'', # 0x67 +'', # 0x68 +'', # 0x69 +'', # 0x6a +'', # 0x6b +'', # 0x6c +'', # 0x6d +'', # 0x6e +'', # 0x6f +'', # 0x70 +'', # 0x71 +'', # 0x72 +'', # 0x73 +'', # 0x74 +'', # 0x75 +'', # 0x76 +'', # 0x77 +'', # 0x78 +'', # 0x79 +'', # 0x7a +'', # 0x7b +'', # 0x7c +'', # 0x7d +'', # 0x7e +'', # 0x7f +'', # 0x80 +'', # 0x81 +'', # 0x82 +'{', # 0x83 +'} ', # 0x84 +'', # 0x85 +'', # 0x86 +'', # 0x87 +'', # 0x88 +'', # 0x89 +'', # 0x8a +'', # 0x8b +'', # 0x8c +'', # 0x8d +'', # 0x8e +'', # 0x8f +'', # 0x90 +'', # 0x91 +'', # 0x92 +'', # 0x93 +'', # 0x94 +'', # 0x95 +'', # 0x96 +'', # 0x97 +'', # 0x98 +'', # 0x99 +'', # 0x9a +'', # 0x9b +'', # 0x9c +'', # 0x9d +'', # 0x9e +'', # 0x9f +'', # 0xa0 +'', # 0xa1 +'', # 0xa2 +'', # 0xa3 +'', # 0xa4 +'', # 0xa5 +'', # 0xa6 +'', # 0xa7 +'', # 0xa8 +'', # 0xa9 +'', # 0xaa +'', # 0xab +'', # 0xac +'', # 0xad +'', # 0xae +'', # 0xaf +'', # 0xb0 +'', # 0xb1 +'', # 0xb2 +'', # 0xb3 +'', # 0xb4 +'', # 0xb5 +'', # 0xb6 +'', # 0xb7 +'', # 0xb8 +'', # 0xb9 +'', # 0xba +'', # 0xbb +'', # 0xbc +'', # 0xbd +'', # 0xbe +'', # 0xbf +'', # 0xc0 +'', # 0xc1 +'', # 0xc2 +'', # 0xc3 +'', # 0xc4 +'', # 0xc5 +'', # 0xc6 +'', # 0xc7 +'', # 0xc8 +'', # 0xc9 +'', # 0xca +'', # 0xcb +'', # 0xcc +'', # 0xcd +'', # 0xce +'', # 0xcf +'', # 0xd0 +'', # 0xd1 +'', # 0xd2 +'', # 0xd3 +'', # 0xd4 +'', # 0xd5 +'', # 0xd6 +'', # 0xd7 +'', # 0xd8 +'', # 0xd9 +'', # 0xda +'', # 0xdb +'', # 0xdc +'', # 0xdd +'', # 0xde +'', # 0xdf +'', # 0xe0 +'', # 0xe1 +'', # 0xe2 +'', # 0xe3 +'', # 0xe4 +'', # 0xe5 +'', # 0xe6 +'', # 0xe7 +'', # 0xe8 +'', # 0xe9 +'', # 0xea +'', # 0xeb +'', # 0xec +'', # 0xed +'', # 0xee +'', # 0xef +'', # 0xf0 +'', # 0xf1 +'', # 0xf2 +'', # 0xf3 +'', # 0xf4 +'', # 0xf5 +'', # 0xf6 +'', # 0xf7 +'', # 0xf8 +'', # 0xf9 +'', # 0xfa +'', # 0xfb +'', # 0xfc +'', # 0xfd +'', # 0xfe +) diff --git a/libs/unidecode/x02a.py b/libs/unidecode/x02a.py new file mode 100644 index 00000000..b832ef35 --- /dev/null +++ b/libs/unidecode/x02a.py @@ -0,0 +1,257 @@ +data = ( +'', # 0x00 +'', # 0x01 +'', # 0x02 +'', # 0x03 +'', # 0x04 +'', # 0x05 +'', # 0x06 +'', # 0x07 +'', # 0x08 +'', # 0x09 +'', # 0x0a +'', # 0x0b +'', # 0x0c +'', # 0x0d +'', # 0x0e +'', # 0x0f +'', # 0x10 +'', # 0x11 +'', # 0x12 +'', # 0x13 +'', # 0x14 +'', # 0x15 +'', # 0x16 +'', # 0x17 +'', # 0x18 +'', # 0x19 +'', # 0x1a +'', # 0x1b +'', # 0x1c +'', # 0x1d +'', # 0x1e +'', # 0x1f +'', # 0x20 +'', # 0x21 +'', # 0x22 +'', # 0x23 +'', # 0x24 +'', # 0x25 +'', # 0x26 +'', # 0x27 +'', # 0x28 +'', # 0x29 +'', # 0x2a +'', # 0x2b +'', # 0x2c +'', # 0x2d +'', # 0x2e +'', # 0x2f +'', # 0x30 +'', # 0x31 +'', # 0x32 +'', # 0x33 +'', # 0x34 +'', # 0x35 +'', # 0x36 +'', # 0x37 +'', # 0x38 +'', # 0x39 +'', # 0x3a +'', # 0x3b +'', # 0x3c +'', # 0x3d +'', # 0x3e +'', # 0x3f +'', # 0x40 +'', # 0x41 +'', # 0x42 +'', # 0x43 +'', # 0x44 +'', # 0x45 +'', # 0x46 +'', # 0x47 +'', # 0x48 +'', # 0x49 +'', # 0x4a +'', # 0x4b +'', # 0x4c +'', # 0x4d +'', # 0x4e +'', # 0x4f +'', # 0x50 +'', # 0x51 +'', # 0x52 +'', # 0x53 +'', # 0x54 +'', # 0x55 +'', # 0x56 +'', # 0x57 +'', # 0x58 +'', # 0x59 +'', # 0x5a +'', # 0x5b +'', # 0x5c +'', # 0x5d +'', # 0x5e +'', # 0x5f +'', # 0x60 +'', # 0x61 +'', # 0x62 +'', # 0x63 +'', # 0x64 +'', # 0x65 +'', # 0x66 +'', # 0x67 +'', # 0x68 +'', # 0x69 +'', # 0x6a +'', # 0x6b +'', # 0x6c +'', # 0x6d +'', # 0x6e +'', # 0x6f +'', # 0x70 +'', # 0x71 +'', # 0x72 +'', # 0x73 +'::=', # 0x74 +'==', # 0x75 +'===', # 0x76 +'', # 0x77 +'', # 0x78 +'', # 0x79 +'', # 0x7a +'', # 0x7b +'', # 0x7c +'', # 0x7d +'', # 0x7e +'', # 0x7f +'', # 0x80 +'', # 0x81 +'', # 0x82 +'', # 0x83 +'', # 0x84 +'', # 0x85 +'', # 0x86 +'', # 0x87 +'', # 0x88 +'', # 0x89 +'', # 0x8a +'', # 0x8b +'', # 0x8c +'', # 0x8d +'', # 0x8e +'', # 0x8f +'', # 0x90 +'', # 0x91 +'', # 0x92 +'', # 0x93 +'', # 0x94 +'', # 0x95 +'', # 0x96 +'', # 0x97 +'', # 0x98 +'', # 0x99 +'', # 0x9a +'', # 0x9b +'', # 0x9c +'', # 0x9d +'', # 0x9e +'', # 0x9f +'', # 0xa0 +'', # 0xa1 +'', # 0xa2 +'', # 0xa3 +'', # 0xa4 +'', # 0xa5 +'', # 0xa6 +'', # 0xa7 +'', # 0xa8 +'', # 0xa9 +'', # 0xaa +'', # 0xab +'', # 0xac +'', # 0xad +'', # 0xae +'', # 0xaf +'', # 0xb0 +'', # 0xb1 +'', # 0xb2 +'', # 0xb3 +'', # 0xb4 +'', # 0xb5 +'', # 0xb6 +'', # 0xb7 +'', # 0xb8 +'', # 0xb9 +'', # 0xba +'', # 0xbb +'', # 0xbc +'', # 0xbd +'', # 0xbe +'', # 0xbf +'', # 0xc0 +'', # 0xc1 +'', # 0xc2 +'', # 0xc3 +'', # 0xc4 +'', # 0xc5 +'', # 0xc6 +'', # 0xc7 +'', # 0xc8 +'', # 0xc9 +'', # 0xca +'', # 0xcb +'', # 0xcc +'', # 0xcd +'', # 0xce +'', # 0xcf +'', # 0xd0 +'', # 0xd1 +'', # 0xd2 +'', # 0xd3 +'', # 0xd4 +'', # 0xd5 +'', # 0xd6 +'', # 0xd7 +'', # 0xd8 +'', # 0xd9 +'', # 0xda +'', # 0xdb +'', # 0xdc +'', # 0xdd +'', # 0xde +'', # 0xdf +'', # 0xe0 +'', # 0xe1 +'', # 0xe2 +'', # 0xe3 +'', # 0xe4 +'', # 0xe5 +'', # 0xe6 +'', # 0xe7 +'', # 0xe8 +'', # 0xe9 +'', # 0xea +'', # 0xeb +'', # 0xec +'', # 0xed +'', # 0xee +'', # 0xef +'', # 0xf0 +'', # 0xf1 +'', # 0xf2 +'', # 0xf3 +'', # 0xf4 +'', # 0xf5 +'', # 0xf6 +'', # 0xf7 +'', # 0xf8 +'', # 0xf9 +'', # 0xfa +'', # 0xfb +'', # 0xfc +'', # 0xfd +'', # 0xfe +) diff --git a/libs/unidecode/x02c.py b/libs/unidecode/x02c.py new file mode 100644 index 00000000..0d05d069 --- /dev/null +++ b/libs/unidecode/x02c.py @@ -0,0 +1,257 @@ +data = ( +'', # 0x00 +'', # 0x01 +'', # 0x02 +'', # 0x03 +'', # 0x04 +'', # 0x05 +'', # 0x06 +'', # 0x07 +'', # 0x08 +'', # 0x09 +'', # 0x0a +'', # 0x0b +'', # 0x0c +'', # 0x0d +'', # 0x0e +'', # 0x0f +'', # 0x10 +'', # 0x11 +'', # 0x12 +'', # 0x13 +'', # 0x14 +'', # 0x15 +'', # 0x16 +'', # 0x17 +'', # 0x18 +'', # 0x19 +'', # 0x1a +'', # 0x1b +'', # 0x1c +'', # 0x1d +'', # 0x1e +'', # 0x1f +'', # 0x20 +'', # 0x21 +'', # 0x22 +'', # 0x23 +'', # 0x24 +'', # 0x25 +'', # 0x26 +'', # 0x27 +'', # 0x28 +'', # 0x29 +'', # 0x2a +'', # 0x2b +'', # 0x2c +'', # 0x2d +'', # 0x2e +'', # 0x2f +'', # 0x30 +'', # 0x31 +'', # 0x32 +'', # 0x33 +'', # 0x34 +'', # 0x35 +'', # 0x36 +'', # 0x37 +'', # 0x38 +'', # 0x39 +'', # 0x3a +'', # 0x3b +'', # 0x3c +'', # 0x3d +'', # 0x3e +'', # 0x3f +'', # 0x40 +'', # 0x41 +'', # 0x42 +'', # 0x43 +'', # 0x44 +'', # 0x45 +'', # 0x46 +'', # 0x47 +'', # 0x48 +'', # 0x49 +'', # 0x4a +'', # 0x4b +'', # 0x4c +'', # 0x4d +'', # 0x4e +'', # 0x4f +'', # 0x50 +'', # 0x51 +'', # 0x52 +'', # 0x53 +'', # 0x54 +'', # 0x55 +'', # 0x56 +'', # 0x57 +'', # 0x58 +'', # 0x59 +'', # 0x5a +'', # 0x5b +'', # 0x5c +'', # 0x5d +'', # 0x5e +'', # 0x5f +'L', # 0x60 +'l', # 0x61 +'L', # 0x62 +'P', # 0x63 +'R', # 0x64 +'a', # 0x65 +'t', # 0x66 +'H', # 0x67 +'h', # 0x68 +'K', # 0x69 +'k', # 0x6a +'Z', # 0x6b +'z', # 0x6c +'', # 0x6d +'M', # 0x6e +'A', # 0x6f +'', # 0x70 +'', # 0x71 +'', # 0x72 +'', # 0x73 +'', # 0x74 +'', # 0x75 +'', # 0x76 +'', # 0x77 +'', # 0x78 +'', # 0x79 +'', # 0x7a +'', # 0x7b +'', # 0x7c +'', # 0x7d +'', # 0x7e +'', # 0x7f +'', # 0x80 +'', # 0x81 +'', # 0x82 +'', # 0x83 +'', # 0x84 +'', # 0x85 +'', # 0x86 +'', # 0x87 +'', # 0x88 +'', # 0x89 +'', # 0x8a +'', # 0x8b +'', # 0x8c +'', # 0x8d +'', # 0x8e +'', # 0x8f +'', # 0x90 +'', # 0x91 +'', # 0x92 +'', # 0x93 +'', # 0x94 +'', # 0x95 +'', # 0x96 +'', # 0x97 +'', # 0x98 +'', # 0x99 +'', # 0x9a +'', # 0x9b +'', # 0x9c +'', # 0x9d +'', # 0x9e +'', # 0x9f +'', # 0xa0 +'', # 0xa1 +'', # 0xa2 +'', # 0xa3 +'', # 0xa4 +'', # 0xa5 +'', # 0xa6 +'', # 0xa7 +'', # 0xa8 +'', # 0xa9 +'', # 0xaa +'', # 0xab +'', # 0xac +'', # 0xad +'', # 0xae +'', # 0xaf +'', # 0xb0 +'', # 0xb1 +'', # 0xb2 +'', # 0xb3 +'', # 0xb4 +'', # 0xb5 +'', # 0xb6 +'', # 0xb7 +'', # 0xb8 +'', # 0xb9 +'', # 0xba +'', # 0xbb +'', # 0xbc +'', # 0xbd +'', # 0xbe +'', # 0xbf +'', # 0xc0 +'', # 0xc1 +'', # 0xc2 +'', # 0xc3 +'', # 0xc4 +'', # 0xc5 +'', # 0xc6 +'', # 0xc7 +'', # 0xc8 +'', # 0xc9 +'', # 0xca +'', # 0xcb +'', # 0xcc +'', # 0xcd +'', # 0xce +'', # 0xcf +'', # 0xd0 +'', # 0xd1 +'', # 0xd2 +'', # 0xd3 +'', # 0xd4 +'', # 0xd5 +'', # 0xd6 +'', # 0xd7 +'', # 0xd8 +'', # 0xd9 +'', # 0xda +'', # 0xdb +'', # 0xdc +'', # 0xdd +'', # 0xde +'', # 0xdf +'', # 0xe0 +'', # 0xe1 +'', # 0xe2 +'', # 0xe3 +'', # 0xe4 +'', # 0xe5 +'', # 0xe6 +'', # 0xe7 +'', # 0xe8 +'', # 0xe9 +'', # 0xea +'', # 0xeb +'', # 0xec +'', # 0xed +'', # 0xee +'', # 0xef +'', # 0xf0 +'', # 0xf1 +'', # 0xf2 +'', # 0xf3 +'', # 0xf4 +'', # 0xf5 +'', # 0xf6 +'', # 0xf7 +'', # 0xf8 +'', # 0xf9 +'', # 0xfa +'', # 0xfb +'', # 0xfc +'', # 0xfd +'', # 0xfe +) diff --git a/libs/unidecode/x02e.py b/libs/unidecode/x02e.py new file mode 100644 index 00000000..feaad8d3 --- /dev/null +++ b/libs/unidecode/x02e.py @@ -0,0 +1,257 @@ +data = ( +'[?]', # 0x00 +'[?]', # 0x01 +'[?]', # 0x02 +'[?]', # 0x03 +'[?]', # 0x04 +'[?]', # 0x05 +'[?]', # 0x06 +'[?]', # 0x07 +'[?]', # 0x08 +'[?]', # 0x09 +'[?]', # 0x0a +'[?]', # 0x0b +'[?]', # 0x0c +'[?]', # 0x0d +'[?]', # 0x0e +'[?]', # 0x0f +'[?]', # 0x10 +'[?]', # 0x11 +'[?]', # 0x12 +'[?]', # 0x13 +'[?]', # 0x14 +'[?]', # 0x15 +'[?]', # 0x16 +'[?]', # 0x17 +'[?]', # 0x18 +'[?]', # 0x19 +'[?]', # 0x1a +'[?]', # 0x1b +'[?]', # 0x1c +'[?]', # 0x1d +'[?]', # 0x1e +'[?]', # 0x1f +'[?]', # 0x20 +'[?]', # 0x21 +'[?]', # 0x22 +'[?]', # 0x23 +'[?]', # 0x24 +'[?]', # 0x25 +'[?]', # 0x26 +'[?]', # 0x27 +'[?]', # 0x28 +'[?]', # 0x29 +'[?]', # 0x2a +'[?]', # 0x2b +'[?]', # 0x2c +'[?]', # 0x2d +'[?]', # 0x2e +'[?]', # 0x2f +'[?]', # 0x30 +'[?]', # 0x31 +'[?]', # 0x32 +'[?]', # 0x33 +'[?]', # 0x34 +'[?]', # 0x35 +'[?]', # 0x36 +'[?]', # 0x37 +'[?]', # 0x38 +'[?]', # 0x39 +'[?]', # 0x3a +'[?]', # 0x3b +'[?]', # 0x3c +'[?]', # 0x3d +'[?]', # 0x3e +'[?]', # 0x3f +'[?]', # 0x40 +'[?]', # 0x41 +'[?]', # 0x42 +'[?]', # 0x43 +'[?]', # 0x44 +'[?]', # 0x45 +'[?]', # 0x46 +'[?]', # 0x47 +'[?]', # 0x48 +'[?]', # 0x49 +'[?]', # 0x4a +'[?]', # 0x4b +'[?]', # 0x4c +'[?]', # 0x4d +'[?]', # 0x4e +'[?]', # 0x4f +'[?]', # 0x50 +'[?]', # 0x51 +'[?]', # 0x52 +'[?]', # 0x53 +'[?]', # 0x54 +'[?]', # 0x55 +'[?]', # 0x56 +'[?]', # 0x57 +'[?]', # 0x58 +'[?]', # 0x59 +'[?]', # 0x5a +'[?]', # 0x5b +'[?]', # 0x5c +'[?]', # 0x5d +'[?]', # 0x5e +'[?]', # 0x5f +'[?]', # 0x60 +'[?]', # 0x61 +'[?]', # 0x62 +'[?]', # 0x63 +'[?]', # 0x64 +'[?]', # 0x65 +'[?]', # 0x66 +'[?]', # 0x67 +'[?]', # 0x68 +'[?]', # 0x69 +'[?]', # 0x6a +'[?]', # 0x6b +'[?]', # 0x6c +'[?]', # 0x6d +'[?]', # 0x6e +'[?]', # 0x6f +'[?]', # 0x70 +'[?]', # 0x71 +'[?]', # 0x72 +'[?]', # 0x73 +'[?]', # 0x74 +'[?]', # 0x75 +'[?]', # 0x76 +'[?]', # 0x77 +'[?]', # 0x78 +'[?]', # 0x79 +'[?]', # 0x7a +'[?]', # 0x7b +'[?]', # 0x7c +'[?]', # 0x7d +'[?]', # 0x7e +'[?]', # 0x7f +'[?] ', # 0x80 +'[?] ', # 0x81 +'[?] ', # 0x82 +'[?] ', # 0x83 +'[?] ', # 0x84 +'[?] ', # 0x85 +'[?] ', # 0x86 +'[?] ', # 0x87 +'[?] ', # 0x88 +'[?] ', # 0x89 +'[?] ', # 0x8a +'[?] ', # 0x8b +'[?] ', # 0x8c +'[?] ', # 0x8d +'[?] ', # 0x8e +'[?] ', # 0x8f +'[?] ', # 0x90 +'[?] ', # 0x91 +'[?] ', # 0x92 +'[?] ', # 0x93 +'[?] ', # 0x94 +'[?] ', # 0x95 +'[?] ', # 0x96 +'[?] ', # 0x97 +'[?] ', # 0x98 +'[?] ', # 0x99 +'[?]', # 0x9a +'[?] ', # 0x9b +'[?] ', # 0x9c +'[?] ', # 0x9d +'[?] ', # 0x9e +'[?] ', # 0x9f +'[?] ', # 0xa0 +'[?] ', # 0xa1 +'[?] ', # 0xa2 +'[?] ', # 0xa3 +'[?] ', # 0xa4 +'[?] ', # 0xa5 +'[?] ', # 0xa6 +'[?] ', # 0xa7 +'[?] ', # 0xa8 +'[?] ', # 0xa9 +'[?] ', # 0xaa +'[?] ', # 0xab +'[?] ', # 0xac +'[?] ', # 0xad +'[?] ', # 0xae +'[?] ', # 0xaf +'[?] ', # 0xb0 +'[?] ', # 0xb1 +'[?] ', # 0xb2 +'[?] ', # 0xb3 +'[?] ', # 0xb4 +'[?] ', # 0xb5 +'[?] ', # 0xb6 +'[?] ', # 0xb7 +'[?] ', # 0xb8 +'[?] ', # 0xb9 +'[?] ', # 0xba +'[?] ', # 0xbb +'[?] ', # 0xbc +'[?] ', # 0xbd +'[?] ', # 0xbe +'[?] ', # 0xbf +'[?] ', # 0xc0 +'[?] ', # 0xc1 +'[?] ', # 0xc2 +'[?] ', # 0xc3 +'[?] ', # 0xc4 +'[?] ', # 0xc5 +'[?] ', # 0xc6 +'[?] ', # 0xc7 +'[?] ', # 0xc8 +'[?] ', # 0xc9 +'[?] ', # 0xca +'[?] ', # 0xcb +'[?] ', # 0xcc +'[?] ', # 0xcd +'[?] ', # 0xce +'[?] ', # 0xcf +'[?] ', # 0xd0 +'[?] ', # 0xd1 +'[?] ', # 0xd2 +'[?] ', # 0xd3 +'[?] ', # 0xd4 +'[?] ', # 0xd5 +'[?] ', # 0xd6 +'[?] ', # 0xd7 +'[?] ', # 0xd8 +'[?] ', # 0xd9 +'[?] ', # 0xda +'[?] ', # 0xdb +'[?] ', # 0xdc +'[?] ', # 0xdd +'[?] ', # 0xde +'[?] ', # 0xdf +'[?] ', # 0xe0 +'[?] ', # 0xe1 +'[?] ', # 0xe2 +'[?] ', # 0xe3 +'[?] ', # 0xe4 +'[?] ', # 0xe5 +'[?] ', # 0xe6 +'[?] ', # 0xe7 +'[?] ', # 0xe8 +'[?] ', # 0xe9 +'[?] ', # 0xea +'[?] ', # 0xeb +'[?] ', # 0xec +'[?] ', # 0xed +'[?] ', # 0xee +'[?] ', # 0xef +'[?] ', # 0xf0 +'[?] ', # 0xf1 +'[?] ', # 0xf2 +'[?] ', # 0xf3 +'[?]', # 0xf4 +'[?]', # 0xf5 +'[?]', # 0xf6 +'[?]', # 0xf7 +'[?]', # 0xf8 +'[?]', # 0xf9 +'[?]', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x02f.py b/libs/unidecode/x02f.py new file mode 100644 index 00000000..01f8b15b --- /dev/null +++ b/libs/unidecode/x02f.py @@ -0,0 +1,257 @@ +data = ( +'[?] ', # 0x00 +'[?] ', # 0x01 +'[?] ', # 0x02 +'[?] ', # 0x03 +'[?] ', # 0x04 +'[?] ', # 0x05 +'[?] ', # 0x06 +'[?] ', # 0x07 +'[?] ', # 0x08 +'[?] ', # 0x09 +'[?] ', # 0x0a +'[?] ', # 0x0b +'[?] ', # 0x0c +'[?] ', # 0x0d +'[?] ', # 0x0e +'[?] ', # 0x0f +'[?] ', # 0x10 +'[?] ', # 0x11 +'[?] ', # 0x12 +'[?] ', # 0x13 +'[?] ', # 0x14 +'[?] ', # 0x15 +'[?] ', # 0x16 +'[?] ', # 0x17 +'[?] ', # 0x18 +'[?] ', # 0x19 +'[?] ', # 0x1a +'[?] ', # 0x1b +'[?] ', # 0x1c +'[?] ', # 0x1d +'[?] ', # 0x1e +'[?] ', # 0x1f +'[?] ', # 0x20 +'[?] ', # 0x21 +'[?] ', # 0x22 +'[?] ', # 0x23 +'[?] ', # 0x24 +'[?] ', # 0x25 +'[?] ', # 0x26 +'[?] ', # 0x27 +'[?] ', # 0x28 +'[?] ', # 0x29 +'[?] ', # 0x2a +'[?] ', # 0x2b +'[?] ', # 0x2c +'[?] ', # 0x2d +'[?] ', # 0x2e +'[?] ', # 0x2f +'[?] ', # 0x30 +'[?] ', # 0x31 +'[?] ', # 0x32 +'[?] ', # 0x33 +'[?] ', # 0x34 +'[?] ', # 0x35 +'[?] ', # 0x36 +'[?] ', # 0x37 +'[?] ', # 0x38 +'[?] ', # 0x39 +'[?] ', # 0x3a +'[?] ', # 0x3b +'[?] ', # 0x3c +'[?] ', # 0x3d +'[?] ', # 0x3e +'[?] ', # 0x3f +'[?] ', # 0x40 +'[?] ', # 0x41 +'[?] ', # 0x42 +'[?] ', # 0x43 +'[?] ', # 0x44 +'[?] ', # 0x45 +'[?] ', # 0x46 +'[?] ', # 0x47 +'[?] ', # 0x48 +'[?] ', # 0x49 +'[?] ', # 0x4a +'[?] ', # 0x4b +'[?] ', # 0x4c +'[?] ', # 0x4d +'[?] ', # 0x4e +'[?] ', # 0x4f +'[?] ', # 0x50 +'[?] ', # 0x51 +'[?] ', # 0x52 +'[?] ', # 0x53 +'[?] ', # 0x54 +'[?] ', # 0x55 +'[?] ', # 0x56 +'[?] ', # 0x57 +'[?] ', # 0x58 +'[?] ', # 0x59 +'[?] ', # 0x5a +'[?] ', # 0x5b +'[?] ', # 0x5c +'[?] ', # 0x5d +'[?] ', # 0x5e +'[?] ', # 0x5f +'[?] ', # 0x60 +'[?] ', # 0x61 +'[?] ', # 0x62 +'[?] ', # 0x63 +'[?] ', # 0x64 +'[?] ', # 0x65 +'[?] ', # 0x66 +'[?] ', # 0x67 +'[?] ', # 0x68 +'[?] ', # 0x69 +'[?] ', # 0x6a +'[?] ', # 0x6b +'[?] ', # 0x6c +'[?] ', # 0x6d +'[?] ', # 0x6e +'[?] ', # 0x6f +'[?] ', # 0x70 +'[?] ', # 0x71 +'[?] ', # 0x72 +'[?] ', # 0x73 +'[?] ', # 0x74 +'[?] ', # 0x75 +'[?] ', # 0x76 +'[?] ', # 0x77 +'[?] ', # 0x78 +'[?] ', # 0x79 +'[?] ', # 0x7a +'[?] ', # 0x7b +'[?] ', # 0x7c +'[?] ', # 0x7d +'[?] ', # 0x7e +'[?] ', # 0x7f +'[?] ', # 0x80 +'[?] ', # 0x81 +'[?] ', # 0x82 +'[?] ', # 0x83 +'[?] ', # 0x84 +'[?] ', # 0x85 +'[?] ', # 0x86 +'[?] ', # 0x87 +'[?] ', # 0x88 +'[?] ', # 0x89 +'[?] ', # 0x8a +'[?] ', # 0x8b +'[?] ', # 0x8c +'[?] ', # 0x8d +'[?] ', # 0x8e +'[?] ', # 0x8f +'[?] ', # 0x90 +'[?] ', # 0x91 +'[?] ', # 0x92 +'[?] ', # 0x93 +'[?] ', # 0x94 +'[?] ', # 0x95 +'[?] ', # 0x96 +'[?] ', # 0x97 +'[?] ', # 0x98 +'[?] ', # 0x99 +'[?] ', # 0x9a +'[?] ', # 0x9b +'[?] ', # 0x9c +'[?] ', # 0x9d +'[?] ', # 0x9e +'[?] ', # 0x9f +'[?] ', # 0xa0 +'[?] ', # 0xa1 +'[?] ', # 0xa2 +'[?] ', # 0xa3 +'[?] ', # 0xa4 +'[?] ', # 0xa5 +'[?] ', # 0xa6 +'[?] ', # 0xa7 +'[?] ', # 0xa8 +'[?] ', # 0xa9 +'[?] ', # 0xaa +'[?] ', # 0xab +'[?] ', # 0xac +'[?] ', # 0xad +'[?] ', # 0xae +'[?] ', # 0xaf +'[?] ', # 0xb0 +'[?] ', # 0xb1 +'[?] ', # 0xb2 +'[?] ', # 0xb3 +'[?] ', # 0xb4 +'[?] ', # 0xb5 +'[?] ', # 0xb6 +'[?] ', # 0xb7 +'[?] ', # 0xb8 +'[?] ', # 0xb9 +'[?] ', # 0xba +'[?] ', # 0xbb +'[?] ', # 0xbc +'[?] ', # 0xbd +'[?] ', # 0xbe +'[?] ', # 0xbf +'[?] ', # 0xc0 +'[?] ', # 0xc1 +'[?] ', # 0xc2 +'[?] ', # 0xc3 +'[?] ', # 0xc4 +'[?] ', # 0xc5 +'[?] ', # 0xc6 +'[?] ', # 0xc7 +'[?] ', # 0xc8 +'[?] ', # 0xc9 +'[?] ', # 0xca +'[?] ', # 0xcb +'[?] ', # 0xcc +'[?] ', # 0xcd +'[?] ', # 0xce +'[?] ', # 0xcf +'[?] ', # 0xd0 +'[?] ', # 0xd1 +'[?] ', # 0xd2 +'[?] ', # 0xd3 +'[?] ', # 0xd4 +'[?] ', # 0xd5 +'[?]', # 0xd6 +'[?]', # 0xd7 +'[?]', # 0xd8 +'[?]', # 0xd9 +'[?]', # 0xda +'[?]', # 0xdb +'[?]', # 0xdc +'[?]', # 0xdd +'[?]', # 0xde +'[?]', # 0xdf +'[?]', # 0xe0 +'[?]', # 0xe1 +'[?]', # 0xe2 +'[?]', # 0xe3 +'[?]', # 0xe4 +'[?]', # 0xe5 +'[?]', # 0xe6 +'[?]', # 0xe7 +'[?]', # 0xe8 +'[?]', # 0xe9 +'[?]', # 0xea +'[?]', # 0xeb +'[?]', # 0xec +'[?]', # 0xed +'[?]', # 0xee +'[?]', # 0xef +'[?] ', # 0xf0 +'[?] ', # 0xf1 +'[?] ', # 0xf2 +'[?] ', # 0xf3 +'[?] ', # 0xf4 +'[?] ', # 0xf5 +'[?] ', # 0xf6 +'[?] ', # 0xf7 +'[?] ', # 0xf8 +'[?] ', # 0xf9 +'[?] ', # 0xfa +'[?] ', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x030.py b/libs/unidecode/x030.py new file mode 100644 index 00000000..d65ed4c5 --- /dev/null +++ b/libs/unidecode/x030.py @@ -0,0 +1,257 @@ +data = ( +' ', # 0x00 +', ', # 0x01 +'. ', # 0x02 +'"', # 0x03 +'[JIS]', # 0x04 +'"', # 0x05 +'/', # 0x06 +'0', # 0x07 +'<', # 0x08 +'> ', # 0x09 +'<<', # 0x0a +'>> ', # 0x0b +'[', # 0x0c +'] ', # 0x0d +'{', # 0x0e +'} ', # 0x0f +'[(', # 0x10 +')] ', # 0x11 +'@', # 0x12 +'X ', # 0x13 +'[', # 0x14 +'] ', # 0x15 +'[[', # 0x16 +']] ', # 0x17 +'((', # 0x18 +')) ', # 0x19 +'[[', # 0x1a +']] ', # 0x1b +'~ ', # 0x1c +'``', # 0x1d +'\'\'', # 0x1e +',,', # 0x1f +'@', # 0x20 +'1', # 0x21 +'2', # 0x22 +'3', # 0x23 +'4', # 0x24 +'5', # 0x25 +'6', # 0x26 +'7', # 0x27 +'8', # 0x28 +'9', # 0x29 +'', # 0x2a +'', # 0x2b +'', # 0x2c +'', # 0x2d +'', # 0x2e +'', # 0x2f +'~', # 0x30 +'+', # 0x31 +'+', # 0x32 +'+', # 0x33 +'+', # 0x34 +'', # 0x35 +'@', # 0x36 +' // ', # 0x37 +'+10+', # 0x38 +'+20+', # 0x39 +'+30+', # 0x3a +'[?]', # 0x3b +'[?]', # 0x3c +'[?]', # 0x3d +'', # 0x3e +'', # 0x3f +'[?]', # 0x40 +'a', # 0x41 +'a', # 0x42 +'i', # 0x43 +'i', # 0x44 +'u', # 0x45 +'u', # 0x46 +'e', # 0x47 +'e', # 0x48 +'o', # 0x49 +'o', # 0x4a +'ka', # 0x4b +'ga', # 0x4c +'ki', # 0x4d +'gi', # 0x4e +'ku', # 0x4f +'gu', # 0x50 +'ke', # 0x51 +'ge', # 0x52 +'ko', # 0x53 +'go', # 0x54 +'sa', # 0x55 +'za', # 0x56 +'shi', # 0x57 +'zi', # 0x58 +'su', # 0x59 +'zu', # 0x5a +'se', # 0x5b +'ze', # 0x5c +'so', # 0x5d +'zo', # 0x5e +'ta', # 0x5f +'da', # 0x60 +'chi', # 0x61 +'di', # 0x62 +'tsu', # 0x63 +'tsu', # 0x64 +'du', # 0x65 +'te', # 0x66 +'de', # 0x67 +'to', # 0x68 +'do', # 0x69 +'na', # 0x6a +'ni', # 0x6b +'nu', # 0x6c +'ne', # 0x6d +'no', # 0x6e +'ha', # 0x6f +'ba', # 0x70 +'pa', # 0x71 +'hi', # 0x72 +'bi', # 0x73 +'pi', # 0x74 +'hu', # 0x75 +'bu', # 0x76 +'pu', # 0x77 +'he', # 0x78 +'be', # 0x79 +'pe', # 0x7a +'ho', # 0x7b +'bo', # 0x7c +'po', # 0x7d +'ma', # 0x7e +'mi', # 0x7f +'mu', # 0x80 +'me', # 0x81 +'mo', # 0x82 +'ya', # 0x83 +'ya', # 0x84 +'yu', # 0x85 +'yu', # 0x86 +'yo', # 0x87 +'yo', # 0x88 +'ra', # 0x89 +'ri', # 0x8a +'ru', # 0x8b +'re', # 0x8c +'ro', # 0x8d +'wa', # 0x8e +'wa', # 0x8f +'wi', # 0x90 +'we', # 0x91 +'wo', # 0x92 +'n', # 0x93 +'vu', # 0x94 +'[?]', # 0x95 +'[?]', # 0x96 +'[?]', # 0x97 +'[?]', # 0x98 +'', # 0x99 +'', # 0x9a +'', # 0x9b +'', # 0x9c +'"', # 0x9d +'"', # 0x9e +'[?]', # 0x9f +'[?]', # 0xa0 +'a', # 0xa1 +'a', # 0xa2 +'i', # 0xa3 +'i', # 0xa4 +'u', # 0xa5 +'u', # 0xa6 +'e', # 0xa7 +'e', # 0xa8 +'o', # 0xa9 +'o', # 0xaa +'ka', # 0xab +'ga', # 0xac +'ki', # 0xad +'gi', # 0xae +'ku', # 0xaf +'gu', # 0xb0 +'ke', # 0xb1 +'ge', # 0xb2 +'ko', # 0xb3 +'go', # 0xb4 +'sa', # 0xb5 +'za', # 0xb6 +'shi', # 0xb7 +'zi', # 0xb8 +'su', # 0xb9 +'zu', # 0xba +'se', # 0xbb +'ze', # 0xbc +'so', # 0xbd +'zo', # 0xbe +'ta', # 0xbf +'da', # 0xc0 +'chi', # 0xc1 +'di', # 0xc2 +'tsu', # 0xc3 +'tsu', # 0xc4 +'du', # 0xc5 +'te', # 0xc6 +'de', # 0xc7 +'to', # 0xc8 +'do', # 0xc9 +'na', # 0xca +'ni', # 0xcb +'nu', # 0xcc +'ne', # 0xcd +'no', # 0xce +'ha', # 0xcf +'ba', # 0xd0 +'pa', # 0xd1 +'hi', # 0xd2 +'bi', # 0xd3 +'pi', # 0xd4 +'hu', # 0xd5 +'bu', # 0xd6 +'pu', # 0xd7 +'he', # 0xd8 +'be', # 0xd9 +'pe', # 0xda +'ho', # 0xdb +'bo', # 0xdc +'po', # 0xdd +'ma', # 0xde +'mi', # 0xdf +'mu', # 0xe0 +'me', # 0xe1 +'mo', # 0xe2 +'ya', # 0xe3 +'ya', # 0xe4 +'yu', # 0xe5 +'yu', # 0xe6 +'yo', # 0xe7 +'yo', # 0xe8 +'ra', # 0xe9 +'ri', # 0xea +'ru', # 0xeb +'re', # 0xec +'ro', # 0xed +'wa', # 0xee +'wa', # 0xef +'wi', # 0xf0 +'we', # 0xf1 +'wo', # 0xf2 +'n', # 0xf3 +'vu', # 0xf4 +'ka', # 0xf5 +'ke', # 0xf6 +'va', # 0xf7 +'vi', # 0xf8 +'ve', # 0xf9 +'vo', # 0xfa +'', # 0xfb +'', # 0xfc +'"', # 0xfd +'"', # 0xfe +) diff --git a/libs/unidecode/x031.py b/libs/unidecode/x031.py new file mode 100644 index 00000000..f5576080 --- /dev/null +++ b/libs/unidecode/x031.py @@ -0,0 +1,257 @@ +data = ( +'[?]', # 0x00 +'[?]', # 0x01 +'[?]', # 0x02 +'[?]', # 0x03 +'[?]', # 0x04 +'B', # 0x05 +'P', # 0x06 +'M', # 0x07 +'F', # 0x08 +'D', # 0x09 +'T', # 0x0a +'N', # 0x0b +'L', # 0x0c +'G', # 0x0d +'K', # 0x0e +'H', # 0x0f +'J', # 0x10 +'Q', # 0x11 +'X', # 0x12 +'ZH', # 0x13 +'CH', # 0x14 +'SH', # 0x15 +'R', # 0x16 +'Z', # 0x17 +'C', # 0x18 +'S', # 0x19 +'A', # 0x1a +'O', # 0x1b +'E', # 0x1c +'EH', # 0x1d +'AI', # 0x1e +'EI', # 0x1f +'AU', # 0x20 +'OU', # 0x21 +'AN', # 0x22 +'EN', # 0x23 +'ANG', # 0x24 +'ENG', # 0x25 +'ER', # 0x26 +'I', # 0x27 +'U', # 0x28 +'IU', # 0x29 +'V', # 0x2a +'NG', # 0x2b +'GN', # 0x2c +'[?]', # 0x2d +'[?]', # 0x2e +'[?]', # 0x2f +'[?]', # 0x30 +'g', # 0x31 +'gg', # 0x32 +'gs', # 0x33 +'n', # 0x34 +'nj', # 0x35 +'nh', # 0x36 +'d', # 0x37 +'dd', # 0x38 +'r', # 0x39 +'lg', # 0x3a +'lm', # 0x3b +'lb', # 0x3c +'ls', # 0x3d +'lt', # 0x3e +'lp', # 0x3f +'rh', # 0x40 +'m', # 0x41 +'b', # 0x42 +'bb', # 0x43 +'bs', # 0x44 +'s', # 0x45 +'ss', # 0x46 +'', # 0x47 +'j', # 0x48 +'jj', # 0x49 +'c', # 0x4a +'k', # 0x4b +'t', # 0x4c +'p', # 0x4d +'h', # 0x4e +'a', # 0x4f +'ae', # 0x50 +'ya', # 0x51 +'yae', # 0x52 +'eo', # 0x53 +'e', # 0x54 +'yeo', # 0x55 +'ye', # 0x56 +'o', # 0x57 +'wa', # 0x58 +'wae', # 0x59 +'oe', # 0x5a +'yo', # 0x5b +'u', # 0x5c +'weo', # 0x5d +'we', # 0x5e +'wi', # 0x5f +'yu', # 0x60 +'eu', # 0x61 +'yi', # 0x62 +'i', # 0x63 +'', # 0x64 +'nn', # 0x65 +'nd', # 0x66 +'ns', # 0x67 +'nZ', # 0x68 +'lgs', # 0x69 +'ld', # 0x6a +'lbs', # 0x6b +'lZ', # 0x6c +'lQ', # 0x6d +'mb', # 0x6e +'ms', # 0x6f +'mZ', # 0x70 +'mN', # 0x71 +'bg', # 0x72 +'', # 0x73 +'bsg', # 0x74 +'bst', # 0x75 +'bj', # 0x76 +'bt', # 0x77 +'bN', # 0x78 +'bbN', # 0x79 +'sg', # 0x7a +'sn', # 0x7b +'sd', # 0x7c +'sb', # 0x7d +'sj', # 0x7e +'Z', # 0x7f +'', # 0x80 +'N', # 0x81 +'Ns', # 0x82 +'NZ', # 0x83 +'pN', # 0x84 +'hh', # 0x85 +'Q', # 0x86 +'yo-ya', # 0x87 +'yo-yae', # 0x88 +'yo-i', # 0x89 +'yu-yeo', # 0x8a +'yu-ye', # 0x8b +'yu-i', # 0x8c +'U', # 0x8d +'U-i', # 0x8e +'[?]', # 0x8f +'', # 0x90 +'', # 0x91 +'', # 0x92 +'', # 0x93 +'', # 0x94 +'', # 0x95 +'', # 0x96 +'', # 0x97 +'', # 0x98 +'', # 0x99 +'', # 0x9a +'', # 0x9b +'', # 0x9c +'', # 0x9d +'', # 0x9e +'', # 0x9f +'BU', # 0xa0 +'ZI', # 0xa1 +'JI', # 0xa2 +'GU', # 0xa3 +'EE', # 0xa4 +'ENN', # 0xa5 +'OO', # 0xa6 +'ONN', # 0xa7 +'IR', # 0xa8 +'ANN', # 0xa9 +'INN', # 0xaa +'UNN', # 0xab +'IM', # 0xac +'NGG', # 0xad +'AINN', # 0xae +'AUNN', # 0xaf +'AM', # 0xb0 +'OM', # 0xb1 +'ONG', # 0xb2 +'INNN', # 0xb3 +'P', # 0xb4 +'T', # 0xb5 +'K', # 0xb6 +'H', # 0xb7 +'[?]', # 0xb8 +'[?]', # 0xb9 +'[?]', # 0xba +'[?]', # 0xbb +'[?]', # 0xbc +'[?]', # 0xbd +'[?]', # 0xbe +'[?]', # 0xbf +'[?]', # 0xc0 +'[?]', # 0xc1 +'[?]', # 0xc2 +'[?]', # 0xc3 +'[?]', # 0xc4 +'[?]', # 0xc5 +'[?]', # 0xc6 +'[?]', # 0xc7 +'[?]', # 0xc8 +'[?]', # 0xc9 +'[?]', # 0xca +'[?]', # 0xcb +'[?]', # 0xcc +'[?]', # 0xcd +'[?]', # 0xce +'[?]', # 0xcf +'[?]', # 0xd0 +'[?]', # 0xd1 +'[?]', # 0xd2 +'[?]', # 0xd3 +'[?]', # 0xd4 +'[?]', # 0xd5 +'[?]', # 0xd6 +'[?]', # 0xd7 +'[?]', # 0xd8 +'[?]', # 0xd9 +'[?]', # 0xda +'[?]', # 0xdb +'[?]', # 0xdc +'[?]', # 0xdd +'[?]', # 0xde +'[?]', # 0xdf +'[?]', # 0xe0 +'[?]', # 0xe1 +'[?]', # 0xe2 +'[?]', # 0xe3 +'[?]', # 0xe4 +'[?]', # 0xe5 +'[?]', # 0xe6 +'[?]', # 0xe7 +'[?]', # 0xe8 +'[?]', # 0xe9 +'[?]', # 0xea +'[?]', # 0xeb +'[?]', # 0xec +'[?]', # 0xed +'[?]', # 0xee +'[?]', # 0xef +'[?]', # 0xf0 +'[?]', # 0xf1 +'[?]', # 0xf2 +'[?]', # 0xf3 +'[?]', # 0xf4 +'[?]', # 0xf5 +'[?]', # 0xf6 +'[?]', # 0xf7 +'[?]', # 0xf8 +'[?]', # 0xf9 +'[?]', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x032.py b/libs/unidecode/x032.py new file mode 100644 index 00000000..30282d4a --- /dev/null +++ b/libs/unidecode/x032.py @@ -0,0 +1,257 @@ +data = ( +'(g)', # 0x00 +'(n)', # 0x01 +'(d)', # 0x02 +'(r)', # 0x03 +'(m)', # 0x04 +'(b)', # 0x05 +'(s)', # 0x06 +'()', # 0x07 +'(j)', # 0x08 +'(c)', # 0x09 +'(k)', # 0x0a +'(t)', # 0x0b +'(p)', # 0x0c +'(h)', # 0x0d +'(ga)', # 0x0e +'(na)', # 0x0f +'(da)', # 0x10 +'(ra)', # 0x11 +'(ma)', # 0x12 +'(ba)', # 0x13 +'(sa)', # 0x14 +'(a)', # 0x15 +'(ja)', # 0x16 +'(ca)', # 0x17 +'(ka)', # 0x18 +'(ta)', # 0x19 +'(pa)', # 0x1a +'(ha)', # 0x1b +'(ju)', # 0x1c +'[?]', # 0x1d +'[?]', # 0x1e +'[?]', # 0x1f +'(1) ', # 0x20 +'(2) ', # 0x21 +'(3) ', # 0x22 +'(4) ', # 0x23 +'(5) ', # 0x24 +'(6) ', # 0x25 +'(7) ', # 0x26 +'(8) ', # 0x27 +'(9) ', # 0x28 +'(10) ', # 0x29 +'(Yue) ', # 0x2a +'(Huo) ', # 0x2b +'(Shui) ', # 0x2c +'(Mu) ', # 0x2d +'(Jin) ', # 0x2e +'(Tu) ', # 0x2f +'(Ri) ', # 0x30 +'(Zhu) ', # 0x31 +'(You) ', # 0x32 +'(She) ', # 0x33 +'(Ming) ', # 0x34 +'(Te) ', # 0x35 +'(Cai) ', # 0x36 +'(Zhu) ', # 0x37 +'(Lao) ', # 0x38 +'(Dai) ', # 0x39 +'(Hu) ', # 0x3a +'(Xue) ', # 0x3b +'(Jian) ', # 0x3c +'(Qi) ', # 0x3d +'(Zi) ', # 0x3e +'(Xie) ', # 0x3f +'(Ji) ', # 0x40 +'(Xiu) ', # 0x41 +'<<', # 0x42 +'>>', # 0x43 +'[?]', # 0x44 +'[?]', # 0x45 +'[?]', # 0x46 +'[?]', # 0x47 +'[?]', # 0x48 +'[?]', # 0x49 +'[?]', # 0x4a +'[?]', # 0x4b +'[?]', # 0x4c +'[?]', # 0x4d +'[?]', # 0x4e +'[?]', # 0x4f +'[?]', # 0x50 +'21', # 0x51 +'22', # 0x52 +'23', # 0x53 +'24', # 0x54 +'25', # 0x55 +'26', # 0x56 +'27', # 0x57 +'28', # 0x58 +'29', # 0x59 +'30', # 0x5a +'31', # 0x5b +'32', # 0x5c +'33', # 0x5d +'34', # 0x5e +'35', # 0x5f +'(g)', # 0x60 +'(n)', # 0x61 +'(d)', # 0x62 +'(r)', # 0x63 +'(m)', # 0x64 +'(b)', # 0x65 +'(s)', # 0x66 +'()', # 0x67 +'(j)', # 0x68 +'(c)', # 0x69 +'(k)', # 0x6a +'(t)', # 0x6b +'(p)', # 0x6c +'(h)', # 0x6d +'(ga)', # 0x6e +'(na)', # 0x6f +'(da)', # 0x70 +'(ra)', # 0x71 +'(ma)', # 0x72 +'(ba)', # 0x73 +'(sa)', # 0x74 +'(a)', # 0x75 +'(ja)', # 0x76 +'(ca)', # 0x77 +'(ka)', # 0x78 +'(ta)', # 0x79 +'(pa)', # 0x7a +'(ha)', # 0x7b +'[?]', # 0x7c +'[?]', # 0x7d +'[?]', # 0x7e +'KIS ', # 0x7f +'(1) ', # 0x80 +'(2) ', # 0x81 +'(3) ', # 0x82 +'(4) ', # 0x83 +'(5) ', # 0x84 +'(6) ', # 0x85 +'(7) ', # 0x86 +'(8) ', # 0x87 +'(9) ', # 0x88 +'(10) ', # 0x89 +'(Yue) ', # 0x8a +'(Huo) ', # 0x8b +'(Shui) ', # 0x8c +'(Mu) ', # 0x8d +'(Jin) ', # 0x8e +'(Tu) ', # 0x8f +'(Ri) ', # 0x90 +'(Zhu) ', # 0x91 +'(You) ', # 0x92 +'(She) ', # 0x93 +'(Ming) ', # 0x94 +'(Te) ', # 0x95 +'(Cai) ', # 0x96 +'(Zhu) ', # 0x97 +'(Lao) ', # 0x98 +'(Mi) ', # 0x99 +'(Nan) ', # 0x9a +'(Nu) ', # 0x9b +'(Shi) ', # 0x9c +'(You) ', # 0x9d +'(Yin) ', # 0x9e +'(Zhu) ', # 0x9f +'(Xiang) ', # 0xa0 +'(Xiu) ', # 0xa1 +'(Xie) ', # 0xa2 +'(Zheng) ', # 0xa3 +'(Shang) ', # 0xa4 +'(Zhong) ', # 0xa5 +'(Xia) ', # 0xa6 +'(Zuo) ', # 0xa7 +'(You) ', # 0xa8 +'(Yi) ', # 0xa9 +'(Zong) ', # 0xaa +'(Xue) ', # 0xab +'(Jian) ', # 0xac +'(Qi) ', # 0xad +'(Zi) ', # 0xae +'(Xie) ', # 0xaf +'(Ye) ', # 0xb0 +'36', # 0xb1 +'37', # 0xb2 +'38', # 0xb3 +'39', # 0xb4 +'40', # 0xb5 +'41', # 0xb6 +'42', # 0xb7 +'43', # 0xb8 +'44', # 0xb9 +'45', # 0xba +'46', # 0xbb +'47', # 0xbc +'48', # 0xbd +'49', # 0xbe +'50', # 0xbf +'1M', # 0xc0 +'2M', # 0xc1 +'3M', # 0xc2 +'4M', # 0xc3 +'5M', # 0xc4 +'6M', # 0xc5 +'7M', # 0xc6 +'8M', # 0xc7 +'9M', # 0xc8 +'10M', # 0xc9 +'11M', # 0xca +'12M', # 0xcb +'[?]', # 0xcc +'[?]', # 0xcd +'[?]', # 0xce +'[?]', # 0xcf +'a', # 0xd0 +'i', # 0xd1 +'u', # 0xd2 +'u', # 0xd3 +'o', # 0xd4 +'ka', # 0xd5 +'ki', # 0xd6 +'ku', # 0xd7 +'ke', # 0xd8 +'ko', # 0xd9 +'sa', # 0xda +'si', # 0xdb +'su', # 0xdc +'se', # 0xdd +'so', # 0xde +'ta', # 0xdf +'ti', # 0xe0 +'tu', # 0xe1 +'te', # 0xe2 +'to', # 0xe3 +'na', # 0xe4 +'ni', # 0xe5 +'nu', # 0xe6 +'ne', # 0xe7 +'no', # 0xe8 +'ha', # 0xe9 +'hi', # 0xea +'hu', # 0xeb +'he', # 0xec +'ho', # 0xed +'ma', # 0xee +'mi', # 0xef +'mu', # 0xf0 +'me', # 0xf1 +'mo', # 0xf2 +'ya', # 0xf3 +'yu', # 0xf4 +'yo', # 0xf5 +'ra', # 0xf6 +'ri', # 0xf7 +'ru', # 0xf8 +'re', # 0xf9 +'ro', # 0xfa +'wa', # 0xfb +'wi', # 0xfc +'we', # 0xfd +'wo', # 0xfe +) diff --git a/libs/unidecode/x033.py b/libs/unidecode/x033.py new file mode 100644 index 00000000..64eb651a --- /dev/null +++ b/libs/unidecode/x033.py @@ -0,0 +1,257 @@ +data = ( +'apartment', # 0x00 +'alpha', # 0x01 +'ampere', # 0x02 +'are', # 0x03 +'inning', # 0x04 +'inch', # 0x05 +'won', # 0x06 +'escudo', # 0x07 +'acre', # 0x08 +'ounce', # 0x09 +'ohm', # 0x0a +'kai-ri', # 0x0b +'carat', # 0x0c +'calorie', # 0x0d +'gallon', # 0x0e +'gamma', # 0x0f +'giga', # 0x10 +'guinea', # 0x11 +'curie', # 0x12 +'guilder', # 0x13 +'kilo', # 0x14 +'kilogram', # 0x15 +'kilometer', # 0x16 +'kilowatt', # 0x17 +'gram', # 0x18 +'gram ton', # 0x19 +'cruzeiro', # 0x1a +'krone', # 0x1b +'case', # 0x1c +'koruna', # 0x1d +'co-op', # 0x1e +'cycle', # 0x1f +'centime', # 0x20 +'shilling', # 0x21 +'centi', # 0x22 +'cent', # 0x23 +'dozen', # 0x24 +'desi', # 0x25 +'dollar', # 0x26 +'ton', # 0x27 +'nano', # 0x28 +'knot', # 0x29 +'heights', # 0x2a +'percent', # 0x2b +'parts', # 0x2c +'barrel', # 0x2d +'piaster', # 0x2e +'picul', # 0x2f +'pico', # 0x30 +'building', # 0x31 +'farad', # 0x32 +'feet', # 0x33 +'bushel', # 0x34 +'franc', # 0x35 +'hectare', # 0x36 +'peso', # 0x37 +'pfennig', # 0x38 +'hertz', # 0x39 +'pence', # 0x3a +'page', # 0x3b +'beta', # 0x3c +'point', # 0x3d +'volt', # 0x3e +'hon', # 0x3f +'pound', # 0x40 +'hall', # 0x41 +'horn', # 0x42 +'micro', # 0x43 +'mile', # 0x44 +'mach', # 0x45 +'mark', # 0x46 +'mansion', # 0x47 +'micron', # 0x48 +'milli', # 0x49 +'millibar', # 0x4a +'mega', # 0x4b +'megaton', # 0x4c +'meter', # 0x4d +'yard', # 0x4e +'yard', # 0x4f +'yuan', # 0x50 +'liter', # 0x51 +'lira', # 0x52 +'rupee', # 0x53 +'ruble', # 0x54 +'rem', # 0x55 +'roentgen', # 0x56 +'watt', # 0x57 +'0h', # 0x58 +'1h', # 0x59 +'2h', # 0x5a +'3h', # 0x5b +'4h', # 0x5c +'5h', # 0x5d +'6h', # 0x5e +'7h', # 0x5f +'8h', # 0x60 +'9h', # 0x61 +'10h', # 0x62 +'11h', # 0x63 +'12h', # 0x64 +'13h', # 0x65 +'14h', # 0x66 +'15h', # 0x67 +'16h', # 0x68 +'17h', # 0x69 +'18h', # 0x6a +'19h', # 0x6b +'20h', # 0x6c +'21h', # 0x6d +'22h', # 0x6e +'23h', # 0x6f +'24h', # 0x70 +'HPA', # 0x71 +'da', # 0x72 +'AU', # 0x73 +'bar', # 0x74 +'oV', # 0x75 +'pc', # 0x76 +'[?]', # 0x77 +'[?]', # 0x78 +'[?]', # 0x79 +'[?]', # 0x7a +'Heisei', # 0x7b +'Syouwa', # 0x7c +'Taisyou', # 0x7d +'Meiji', # 0x7e +'Inc.', # 0x7f +'pA', # 0x80 +'nA', # 0x81 +'microamp', # 0x82 +'mA', # 0x83 +'kA', # 0x84 +'kB', # 0x85 +'MB', # 0x86 +'GB', # 0x87 +'cal', # 0x88 +'kcal', # 0x89 +'pF', # 0x8a +'nF', # 0x8b +'microFarad', # 0x8c +'microgram', # 0x8d +'mg', # 0x8e +'kg', # 0x8f +'Hz', # 0x90 +'kHz', # 0x91 +'MHz', # 0x92 +'GHz', # 0x93 +'THz', # 0x94 +'microliter', # 0x95 +'ml', # 0x96 +'dl', # 0x97 +'kl', # 0x98 +'fm', # 0x99 +'nm', # 0x9a +'micrometer', # 0x9b +'mm', # 0x9c +'cm', # 0x9d +'km', # 0x9e +'mm^2', # 0x9f +'cm^2', # 0xa0 +'m^2', # 0xa1 +'km^2', # 0xa2 +'mm^4', # 0xa3 +'cm^3', # 0xa4 +'m^3', # 0xa5 +'km^3', # 0xa6 +'m/s', # 0xa7 +'m/s^2', # 0xa8 +'Pa', # 0xa9 +'kPa', # 0xaa +'MPa', # 0xab +'GPa', # 0xac +'rad', # 0xad +'rad/s', # 0xae +'rad/s^2', # 0xaf +'ps', # 0xb0 +'ns', # 0xb1 +'microsecond', # 0xb2 +'ms', # 0xb3 +'pV', # 0xb4 +'nV', # 0xb5 +'microvolt', # 0xb6 +'mV', # 0xb7 +'kV', # 0xb8 +'MV', # 0xb9 +'pW', # 0xba +'nW', # 0xbb +'microwatt', # 0xbc +'mW', # 0xbd +'kW', # 0xbe +'MW', # 0xbf +'kOhm', # 0xc0 +'MOhm', # 0xc1 +'a.m.', # 0xc2 +'Bq', # 0xc3 +'cc', # 0xc4 +'cd', # 0xc5 +'C/kg', # 0xc6 +'Co.', # 0xc7 +'dB', # 0xc8 +'Gy', # 0xc9 +'ha', # 0xca +'HP', # 0xcb +'in', # 0xcc +'K.K.', # 0xcd +'KM', # 0xce +'kt', # 0xcf +'lm', # 0xd0 +'ln', # 0xd1 +'log', # 0xd2 +'lx', # 0xd3 +'mb', # 0xd4 +'mil', # 0xd5 +'mol', # 0xd6 +'pH', # 0xd7 +'p.m.', # 0xd8 +'PPM', # 0xd9 +'PR', # 0xda +'sr', # 0xdb +'Sv', # 0xdc +'Wb', # 0xdd +'[?]', # 0xde +'[?]', # 0xdf +'1d', # 0xe0 +'2d', # 0xe1 +'3d', # 0xe2 +'4d', # 0xe3 +'5d', # 0xe4 +'6d', # 0xe5 +'7d', # 0xe6 +'8d', # 0xe7 +'9d', # 0xe8 +'10d', # 0xe9 +'11d', # 0xea +'12d', # 0xeb +'13d', # 0xec +'14d', # 0xed +'15d', # 0xee +'16d', # 0xef +'17d', # 0xf0 +'18d', # 0xf1 +'19d', # 0xf2 +'20d', # 0xf3 +'21d', # 0xf4 +'22d', # 0xf5 +'23d', # 0xf6 +'24d', # 0xf7 +'25d', # 0xf8 +'26d', # 0xf9 +'27d', # 0xfa +'28d', # 0xfb +'29d', # 0xfc +'30d', # 0xfd +'31d', # 0xfe +) diff --git a/libs/unidecode/x04d.py b/libs/unidecode/x04d.py new file mode 100644 index 00000000..b025461a --- /dev/null +++ b/libs/unidecode/x04d.py @@ -0,0 +1,257 @@ +data = ( +'[?] ', # 0x00 +'[?] ', # 0x01 +'[?] ', # 0x02 +'[?] ', # 0x03 +'[?] ', # 0x04 +'[?] ', # 0x05 +'[?] ', # 0x06 +'[?] ', # 0x07 +'[?] ', # 0x08 +'[?] ', # 0x09 +'[?] ', # 0x0a +'[?] ', # 0x0b +'[?] ', # 0x0c +'[?] ', # 0x0d +'[?] ', # 0x0e +'[?] ', # 0x0f +'[?] ', # 0x10 +'[?] ', # 0x11 +'[?] ', # 0x12 +'[?] ', # 0x13 +'[?] ', # 0x14 +'[?] ', # 0x15 +'[?] ', # 0x16 +'[?] ', # 0x17 +'[?] ', # 0x18 +'[?] ', # 0x19 +'[?] ', # 0x1a +'[?] ', # 0x1b +'[?] ', # 0x1c +'[?] ', # 0x1d +'[?] ', # 0x1e +'[?] ', # 0x1f +'[?] ', # 0x20 +'[?] ', # 0x21 +'[?] ', # 0x22 +'[?] ', # 0x23 +'[?] ', # 0x24 +'[?] ', # 0x25 +'[?] ', # 0x26 +'[?] ', # 0x27 +'[?] ', # 0x28 +'[?] ', # 0x29 +'[?] ', # 0x2a +'[?] ', # 0x2b +'[?] ', # 0x2c +'[?] ', # 0x2d +'[?] ', # 0x2e +'[?] ', # 0x2f +'[?] ', # 0x30 +'[?] ', # 0x31 +'[?] ', # 0x32 +'[?] ', # 0x33 +'[?] ', # 0x34 +'[?] ', # 0x35 +'[?] ', # 0x36 +'[?] ', # 0x37 +'[?] ', # 0x38 +'[?] ', # 0x39 +'[?] ', # 0x3a +'[?] ', # 0x3b +'[?] ', # 0x3c +'[?] ', # 0x3d +'[?] ', # 0x3e +'[?] ', # 0x3f +'[?] ', # 0x40 +'[?] ', # 0x41 +'[?] ', # 0x42 +'[?] ', # 0x43 +'[?] ', # 0x44 +'[?] ', # 0x45 +'[?] ', # 0x46 +'[?] ', # 0x47 +'[?] ', # 0x48 +'[?] ', # 0x49 +'[?] ', # 0x4a +'[?] ', # 0x4b +'[?] ', # 0x4c +'[?] ', # 0x4d +'[?] ', # 0x4e +'[?] ', # 0x4f +'[?] ', # 0x50 +'[?] ', # 0x51 +'[?] ', # 0x52 +'[?] ', # 0x53 +'[?] ', # 0x54 +'[?] ', # 0x55 +'[?] ', # 0x56 +'[?] ', # 0x57 +'[?] ', # 0x58 +'[?] ', # 0x59 +'[?] ', # 0x5a +'[?] ', # 0x5b +'[?] ', # 0x5c +'[?] ', # 0x5d +'[?] ', # 0x5e +'[?] ', # 0x5f +'[?] ', # 0x60 +'[?] ', # 0x61 +'[?] ', # 0x62 +'[?] ', # 0x63 +'[?] ', # 0x64 +'[?] ', # 0x65 +'[?] ', # 0x66 +'[?] ', # 0x67 +'[?] ', # 0x68 +'[?] ', # 0x69 +'[?] ', # 0x6a +'[?] ', # 0x6b +'[?] ', # 0x6c +'[?] ', # 0x6d +'[?] ', # 0x6e +'[?] ', # 0x6f +'[?] ', # 0x70 +'[?] ', # 0x71 +'[?] ', # 0x72 +'[?] ', # 0x73 +'[?] ', # 0x74 +'[?] ', # 0x75 +'[?] ', # 0x76 +'[?] ', # 0x77 +'[?] ', # 0x78 +'[?] ', # 0x79 +'[?] ', # 0x7a +'[?] ', # 0x7b +'[?] ', # 0x7c +'[?] ', # 0x7d +'[?] ', # 0x7e +'[?] ', # 0x7f +'[?] ', # 0x80 +'[?] ', # 0x81 +'[?] ', # 0x82 +'[?] ', # 0x83 +'[?] ', # 0x84 +'[?] ', # 0x85 +'[?] ', # 0x86 +'[?] ', # 0x87 +'[?] ', # 0x88 +'[?] ', # 0x89 +'[?] ', # 0x8a +'[?] ', # 0x8b +'[?] ', # 0x8c +'[?] ', # 0x8d +'[?] ', # 0x8e +'[?] ', # 0x8f +'[?] ', # 0x90 +'[?] ', # 0x91 +'[?] ', # 0x92 +'[?] ', # 0x93 +'[?] ', # 0x94 +'[?] ', # 0x95 +'[?] ', # 0x96 +'[?] ', # 0x97 +'[?] ', # 0x98 +'[?] ', # 0x99 +'[?] ', # 0x9a +'[?] ', # 0x9b +'[?] ', # 0x9c +'[?] ', # 0x9d +'[?] ', # 0x9e +'[?] ', # 0x9f +'[?] ', # 0xa0 +'[?] ', # 0xa1 +'[?] ', # 0xa2 +'[?] ', # 0xa3 +'[?] ', # 0xa4 +'[?] ', # 0xa5 +'[?] ', # 0xa6 +'[?] ', # 0xa7 +'[?] ', # 0xa8 +'[?] ', # 0xa9 +'[?] ', # 0xaa +'[?] ', # 0xab +'[?] ', # 0xac +'[?] ', # 0xad +'[?] ', # 0xae +'[?] ', # 0xaf +'[?] ', # 0xb0 +'[?] ', # 0xb1 +'[?] ', # 0xb2 +'[?] ', # 0xb3 +'[?] ', # 0xb4 +'[?] ', # 0xb5 +'[?]', # 0xb6 +'[?]', # 0xb7 +'[?]', # 0xb8 +'[?]', # 0xb9 +'[?]', # 0xba +'[?]', # 0xbb +'[?]', # 0xbc +'[?]', # 0xbd +'[?]', # 0xbe +'[?]', # 0xbf +'[?]', # 0xc0 +'[?]', # 0xc1 +'[?]', # 0xc2 +'[?]', # 0xc3 +'[?]', # 0xc4 +'[?]', # 0xc5 +'[?]', # 0xc6 +'[?]', # 0xc7 +'[?]', # 0xc8 +'[?]', # 0xc9 +'[?]', # 0xca +'[?]', # 0xcb +'[?]', # 0xcc +'[?]', # 0xcd +'[?]', # 0xce +'[?]', # 0xcf +'[?]', # 0xd0 +'[?]', # 0xd1 +'[?]', # 0xd2 +'[?]', # 0xd3 +'[?]', # 0xd4 +'[?]', # 0xd5 +'[?]', # 0xd6 +'[?]', # 0xd7 +'[?]', # 0xd8 +'[?]', # 0xd9 +'[?]', # 0xda +'[?]', # 0xdb +'[?]', # 0xdc +'[?]', # 0xdd +'[?]', # 0xde +'[?]', # 0xdf +'[?]', # 0xe0 +'[?]', # 0xe1 +'[?]', # 0xe2 +'[?]', # 0xe3 +'[?]', # 0xe4 +'[?]', # 0xe5 +'[?]', # 0xe6 +'[?]', # 0xe7 +'[?]', # 0xe8 +'[?]', # 0xe9 +'[?]', # 0xea +'[?]', # 0xeb +'[?]', # 0xec +'[?]', # 0xed +'[?]', # 0xee +'[?]', # 0xef +'[?]', # 0xf0 +'[?]', # 0xf1 +'[?]', # 0xf2 +'[?]', # 0xf3 +'[?]', # 0xf4 +'[?]', # 0xf5 +'[?]', # 0xf6 +'[?]', # 0xf7 +'[?]', # 0xf8 +'[?]', # 0xf9 +'[?]', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x04e.py b/libs/unidecode/x04e.py new file mode 100644 index 00000000..e346f67b --- /dev/null +++ b/libs/unidecode/x04e.py @@ -0,0 +1,258 @@ +data = ( +'[?] ', # 0x00 +'Ding ', # 0x01 +'Kao ', # 0x02 +'Qi ', # 0x03 +'Shang ', # 0x04 +'Xia ', # 0x05 +'[?] ', # 0x06 +'Mo ', # 0x07 +'Zhang ', # 0x08 +'San ', # 0x09 +'Shang ', # 0x0a +'Xia ', # 0x0b +'Ji ', # 0x0c +'Bu ', # 0x0d +'Yu ', # 0x0e +'Mian ', # 0x0f +'Gai ', # 0x10 +'Chou ', # 0x11 +'Chou ', # 0x12 +'Zhuan ', # 0x13 +'Qie ', # 0x14 +'Pi ', # 0x15 +'Shi ', # 0x16 +'Shi ', # 0x17 +'Qiu ', # 0x18 +'Bing ', # 0x19 +'Ye ', # 0x1a +'Cong ', # 0x1b +'Dong ', # 0x1c +'Si ', # 0x1d +'Cheng ', # 0x1e +'Diu ', # 0x1f +'Qiu ', # 0x20 +'Liang ', # 0x21 +'Diu ', # 0x22 +'You ', # 0x23 +'Liang ', # 0x24 +'Yan ', # 0x25 +'Bing ', # 0x26 +'Sang ', # 0x27 +'Gun ', # 0x28 +'Jiu ', # 0x29 +'Ge ', # 0x2a +'Ya ', # 0x2b +'Qiang ', # 0x2c +'Zhong ', # 0x2d +'Ji ', # 0x2e +'Jie ', # 0x2f +'Feng ', # 0x30 +'Guan ', # 0x31 +'Chuan ', # 0x32 +'Chan ', # 0x33 +'Lin ', # 0x34 +'Zhuo ', # 0x35 +'Zhu ', # 0x36 +'Ha ', # 0x37 +'Wan ', # 0x38 +'Dan ', # 0x39 +'Wei ', # 0x3a +'Zhu ', # 0x3b +'Jing ', # 0x3c +'Li ', # 0x3d +'Ju ', # 0x3e +'Pie ', # 0x3f +'Fu ', # 0x40 +'Yi ', # 0x41 +'Yi ', # 0x42 +'Nai ', # 0x43 +'Shime ', # 0x44 +'Jiu ', # 0x45 +'Jiu ', # 0x46 +'Zhe ', # 0x47 +'Yao ', # 0x48 +'Yi ', # 0x49 +'[?] ', # 0x4a +'Zhi ', # 0x4b +'Wu ', # 0x4c +'Zha ', # 0x4d +'Hu ', # 0x4e +'Fa ', # 0x4f +'Le ', # 0x50 +'Zhong ', # 0x51 +'Ping ', # 0x52 +'Pang ', # 0x53 +'Qiao ', # 0x54 +'Hu ', # 0x55 +'Guai ', # 0x56 +'Cheng ', # 0x57 +'Cheng ', # 0x58 +'Yi ', # 0x59 +'Yin ', # 0x5a +'[?] ', # 0x5b +'Mie ', # 0x5c +'Jiu ', # 0x5d +'Qi ', # 0x5e +'Ye ', # 0x5f +'Xi ', # 0x60 +'Xiang ', # 0x61 +'Gai ', # 0x62 +'Diu ', # 0x63 +'Hal ', # 0x64 +'[?] ', # 0x65 +'Shu ', # 0x66 +'Twul ', # 0x67 +'Shi ', # 0x68 +'Ji ', # 0x69 +'Nang ', # 0x6a +'Jia ', # 0x6b +'Kel ', # 0x6c +'Shi ', # 0x6d +'[?] ', # 0x6e +'Ol ', # 0x6f +'Mai ', # 0x70 +'Luan ', # 0x71 +'Cal ', # 0x72 +'Ru ', # 0x73 +'Xue ', # 0x74 +'Yan ', # 0x75 +'Fu ', # 0x76 +'Sha ', # 0x77 +'Na ', # 0x78 +'Gan ', # 0x79 +'Sol ', # 0x7a +'El ', # 0x7b +'Cwul ', # 0x7c +'[?] ', # 0x7d +'Gan ', # 0x7e +'Chi ', # 0x7f +'Gui ', # 0x80 +'Gan ', # 0x81 +'Luan ', # 0x82 +'Lin ', # 0x83 +'Yi ', # 0x84 +'Jue ', # 0x85 +'Liao ', # 0x86 +'Ma ', # 0x87 +'Yu ', # 0x88 +'Zheng ', # 0x89 +'Shi ', # 0x8a +'Shi ', # 0x8b +'Er ', # 0x8c +'Chu ', # 0x8d +'Yu ', # 0x8e +'Yu ', # 0x8f +'Yu ', # 0x90 +'Yun ', # 0x91 +'Hu ', # 0x92 +'Qi ', # 0x93 +'Wu ', # 0x94 +'Jing ', # 0x95 +'Si ', # 0x96 +'Sui ', # 0x97 +'Gen ', # 0x98 +'Gen ', # 0x99 +'Ya ', # 0x9a +'Xie ', # 0x9b +'Ya ', # 0x9c +'Qi ', # 0x9d +'Ya ', # 0x9e +'Ji ', # 0x9f +'Tou ', # 0xa0 +'Wang ', # 0xa1 +'Kang ', # 0xa2 +'Ta ', # 0xa3 +'Jiao ', # 0xa4 +'Hai ', # 0xa5 +'Yi ', # 0xa6 +'Chan ', # 0xa7 +'Heng ', # 0xa8 +'Mu ', # 0xa9 +'[?] ', # 0xaa +'Xiang ', # 0xab +'Jing ', # 0xac +'Ting ', # 0xad +'Liang ', # 0xae +'Xiang ', # 0xaf +'Jing ', # 0xb0 +'Ye ', # 0xb1 +'Qin ', # 0xb2 +'Bo ', # 0xb3 +'You ', # 0xb4 +'Xie ', # 0xb5 +'Dan ', # 0xb6 +'Lian ', # 0xb7 +'Duo ', # 0xb8 +'Wei ', # 0xb9 +'Ren ', # 0xba +'Ren ', # 0xbb +'Ji ', # 0xbc +'La ', # 0xbd +'Wang ', # 0xbe +'Yi ', # 0xbf +'Shi ', # 0xc0 +'Ren ', # 0xc1 +'Le ', # 0xc2 +'Ding ', # 0xc3 +'Ze ', # 0xc4 +'Jin ', # 0xc5 +'Pu ', # 0xc6 +'Chou ', # 0xc7 +'Ba ', # 0xc8 +'Zhang ', # 0xc9 +'Jin ', # 0xca +'Jie ', # 0xcb +'Bing ', # 0xcc +'Reng ', # 0xcd +'Cong ', # 0xce +'Fo ', # 0xcf +'San ', # 0xd0 +'Lun ', # 0xd1 +'Sya ', # 0xd2 +'Cang ', # 0xd3 +'Zi ', # 0xd4 +'Shi ', # 0xd5 +'Ta ', # 0xd6 +'Zhang ', # 0xd7 +'Fu ', # 0xd8 +'Xian ', # 0xd9 +'Xian ', # 0xda +'Tuo ', # 0xdb +'Hong ', # 0xdc +'Tong ', # 0xdd +'Ren ', # 0xde +'Qian ', # 0xdf +'Gan ', # 0xe0 +'Yi ', # 0xe1 +'Di ', # 0xe2 +'Dai ', # 0xe3 +'Ling ', # 0xe4 +'Yi ', # 0xe5 +'Chao ', # 0xe6 +'Chang ', # 0xe7 +'Sa ', # 0xe8 +'[?] ', # 0xe9 +'Yi ', # 0xea +'Mu ', # 0xeb +'Men ', # 0xec +'Ren ', # 0xed +'Jia ', # 0xee +'Chao ', # 0xef +'Yang ', # 0xf0 +'Qian ', # 0xf1 +'Zhong ', # 0xf2 +'Pi ', # 0xf3 +'Wan ', # 0xf4 +'Wu ', # 0xf5 +'Jian ', # 0xf6 +'Jie ', # 0xf7 +'Yao ', # 0xf8 +'Feng ', # 0xf9 +'Cang ', # 0xfa +'Ren ', # 0xfb +'Wang ', # 0xfc +'Fen ', # 0xfd +'Di ', # 0xfe +'Fang ', # 0xff +) diff --git a/libs/unidecode/x04f.py b/libs/unidecode/x04f.py new file mode 100644 index 00000000..98c22910 --- /dev/null +++ b/libs/unidecode/x04f.py @@ -0,0 +1,258 @@ +data = ( +'Zhong ', # 0x00 +'Qi ', # 0x01 +'Pei ', # 0x02 +'Yu ', # 0x03 +'Diao ', # 0x04 +'Dun ', # 0x05 +'Wen ', # 0x06 +'Yi ', # 0x07 +'Xin ', # 0x08 +'Kang ', # 0x09 +'Yi ', # 0x0a +'Ji ', # 0x0b +'Ai ', # 0x0c +'Wu ', # 0x0d +'Ji ', # 0x0e +'Fu ', # 0x0f +'Fa ', # 0x10 +'Xiu ', # 0x11 +'Jin ', # 0x12 +'Bei ', # 0x13 +'Dan ', # 0x14 +'Fu ', # 0x15 +'Tang ', # 0x16 +'Zhong ', # 0x17 +'You ', # 0x18 +'Huo ', # 0x19 +'Hui ', # 0x1a +'Yu ', # 0x1b +'Cui ', # 0x1c +'Chuan ', # 0x1d +'San ', # 0x1e +'Wei ', # 0x1f +'Chuan ', # 0x20 +'Che ', # 0x21 +'Ya ', # 0x22 +'Xian ', # 0x23 +'Shang ', # 0x24 +'Chang ', # 0x25 +'Lun ', # 0x26 +'Cang ', # 0x27 +'Xun ', # 0x28 +'Xin ', # 0x29 +'Wei ', # 0x2a +'Zhu ', # 0x2b +'[?] ', # 0x2c +'Xuan ', # 0x2d +'Nu ', # 0x2e +'Bo ', # 0x2f +'Gu ', # 0x30 +'Ni ', # 0x31 +'Ni ', # 0x32 +'Xie ', # 0x33 +'Ban ', # 0x34 +'Xu ', # 0x35 +'Ling ', # 0x36 +'Zhou ', # 0x37 +'Shen ', # 0x38 +'Qu ', # 0x39 +'Si ', # 0x3a +'Beng ', # 0x3b +'Si ', # 0x3c +'Jia ', # 0x3d +'Pi ', # 0x3e +'Yi ', # 0x3f +'Si ', # 0x40 +'Ai ', # 0x41 +'Zheng ', # 0x42 +'Dian ', # 0x43 +'Han ', # 0x44 +'Mai ', # 0x45 +'Dan ', # 0x46 +'Zhu ', # 0x47 +'Bu ', # 0x48 +'Qu ', # 0x49 +'Bi ', # 0x4a +'Shao ', # 0x4b +'Ci ', # 0x4c +'Wei ', # 0x4d +'Di ', # 0x4e +'Zhu ', # 0x4f +'Zuo ', # 0x50 +'You ', # 0x51 +'Yang ', # 0x52 +'Ti ', # 0x53 +'Zhan ', # 0x54 +'He ', # 0x55 +'Bi ', # 0x56 +'Tuo ', # 0x57 +'She ', # 0x58 +'Yu ', # 0x59 +'Yi ', # 0x5a +'Fo ', # 0x5b +'Zuo ', # 0x5c +'Kou ', # 0x5d +'Ning ', # 0x5e +'Tong ', # 0x5f +'Ni ', # 0x60 +'Xuan ', # 0x61 +'Qu ', # 0x62 +'Yong ', # 0x63 +'Wa ', # 0x64 +'Qian ', # 0x65 +'[?] ', # 0x66 +'Ka ', # 0x67 +'[?] ', # 0x68 +'Pei ', # 0x69 +'Huai ', # 0x6a +'He ', # 0x6b +'Lao ', # 0x6c +'Xiang ', # 0x6d +'Ge ', # 0x6e +'Yang ', # 0x6f +'Bai ', # 0x70 +'Fa ', # 0x71 +'Ming ', # 0x72 +'Jia ', # 0x73 +'Er ', # 0x74 +'Bing ', # 0x75 +'Ji ', # 0x76 +'Hen ', # 0x77 +'Huo ', # 0x78 +'Gui ', # 0x79 +'Quan ', # 0x7a +'Tiao ', # 0x7b +'Jiao ', # 0x7c +'Ci ', # 0x7d +'Yi ', # 0x7e +'Shi ', # 0x7f +'Xing ', # 0x80 +'Shen ', # 0x81 +'Tuo ', # 0x82 +'Kan ', # 0x83 +'Zhi ', # 0x84 +'Gai ', # 0x85 +'Lai ', # 0x86 +'Yi ', # 0x87 +'Chi ', # 0x88 +'Kua ', # 0x89 +'Guang ', # 0x8a +'Li ', # 0x8b +'Yin ', # 0x8c +'Shi ', # 0x8d +'Mi ', # 0x8e +'Zhu ', # 0x8f +'Xu ', # 0x90 +'You ', # 0x91 +'An ', # 0x92 +'Lu ', # 0x93 +'Mou ', # 0x94 +'Er ', # 0x95 +'Lun ', # 0x96 +'Tong ', # 0x97 +'Cha ', # 0x98 +'Chi ', # 0x99 +'Xun ', # 0x9a +'Gong ', # 0x9b +'Zhou ', # 0x9c +'Yi ', # 0x9d +'Ru ', # 0x9e +'Jian ', # 0x9f +'Xia ', # 0xa0 +'Jia ', # 0xa1 +'Zai ', # 0xa2 +'Lu ', # 0xa3 +'Ko ', # 0xa4 +'Jiao ', # 0xa5 +'Zhen ', # 0xa6 +'Ce ', # 0xa7 +'Qiao ', # 0xa8 +'Kuai ', # 0xa9 +'Chai ', # 0xaa +'Ning ', # 0xab +'Nong ', # 0xac +'Jin ', # 0xad +'Wu ', # 0xae +'Hou ', # 0xaf +'Jiong ', # 0xb0 +'Cheng ', # 0xb1 +'Zhen ', # 0xb2 +'Zuo ', # 0xb3 +'Chou ', # 0xb4 +'Qin ', # 0xb5 +'Lu ', # 0xb6 +'Ju ', # 0xb7 +'Shu ', # 0xb8 +'Ting ', # 0xb9 +'Shen ', # 0xba +'Tuo ', # 0xbb +'Bo ', # 0xbc +'Nan ', # 0xbd +'Hao ', # 0xbe +'Bian ', # 0xbf +'Tui ', # 0xc0 +'Yu ', # 0xc1 +'Xi ', # 0xc2 +'Cu ', # 0xc3 +'E ', # 0xc4 +'Qiu ', # 0xc5 +'Xu ', # 0xc6 +'Kuang ', # 0xc7 +'Ku ', # 0xc8 +'Wu ', # 0xc9 +'Jun ', # 0xca +'Yi ', # 0xcb +'Fu ', # 0xcc +'Lang ', # 0xcd +'Zu ', # 0xce +'Qiao ', # 0xcf +'Li ', # 0xd0 +'Yong ', # 0xd1 +'Hun ', # 0xd2 +'Jing ', # 0xd3 +'Xian ', # 0xd4 +'San ', # 0xd5 +'Pai ', # 0xd6 +'Su ', # 0xd7 +'Fu ', # 0xd8 +'Xi ', # 0xd9 +'Li ', # 0xda +'Fu ', # 0xdb +'Ping ', # 0xdc +'Bao ', # 0xdd +'Yu ', # 0xde +'Si ', # 0xdf +'Xia ', # 0xe0 +'Xin ', # 0xe1 +'Xiu ', # 0xe2 +'Yu ', # 0xe3 +'Ti ', # 0xe4 +'Che ', # 0xe5 +'Chou ', # 0xe6 +'[?] ', # 0xe7 +'Yan ', # 0xe8 +'Lia ', # 0xe9 +'Li ', # 0xea +'Lai ', # 0xeb +'[?] ', # 0xec +'Jian ', # 0xed +'Xiu ', # 0xee +'Fu ', # 0xef +'He ', # 0xf0 +'Ju ', # 0xf1 +'Xiao ', # 0xf2 +'Pai ', # 0xf3 +'Jian ', # 0xf4 +'Biao ', # 0xf5 +'Chu ', # 0xf6 +'Fei ', # 0xf7 +'Feng ', # 0xf8 +'Ya ', # 0xf9 +'An ', # 0xfa +'Bei ', # 0xfb +'Yu ', # 0xfc +'Xin ', # 0xfd +'Bi ', # 0xfe +'Jian ', # 0xff +) diff --git a/libs/unidecode/x050.py b/libs/unidecode/x050.py new file mode 100644 index 00000000..184b87fd --- /dev/null +++ b/libs/unidecode/x050.py @@ -0,0 +1,258 @@ +data = ( +'Chang ', # 0x00 +'Chi ', # 0x01 +'Bing ', # 0x02 +'Zan ', # 0x03 +'Yao ', # 0x04 +'Cui ', # 0x05 +'Lia ', # 0x06 +'Wan ', # 0x07 +'Lai ', # 0x08 +'Cang ', # 0x09 +'Zong ', # 0x0a +'Ge ', # 0x0b +'Guan ', # 0x0c +'Bei ', # 0x0d +'Tian ', # 0x0e +'Shu ', # 0x0f +'Shu ', # 0x10 +'Men ', # 0x11 +'Dao ', # 0x12 +'Tan ', # 0x13 +'Jue ', # 0x14 +'Chui ', # 0x15 +'Xing ', # 0x16 +'Peng ', # 0x17 +'Tang ', # 0x18 +'Hou ', # 0x19 +'Yi ', # 0x1a +'Qi ', # 0x1b +'Ti ', # 0x1c +'Gan ', # 0x1d +'Jing ', # 0x1e +'Jie ', # 0x1f +'Sui ', # 0x20 +'Chang ', # 0x21 +'Jie ', # 0x22 +'Fang ', # 0x23 +'Zhi ', # 0x24 +'Kong ', # 0x25 +'Juan ', # 0x26 +'Zong ', # 0x27 +'Ju ', # 0x28 +'Qian ', # 0x29 +'Ni ', # 0x2a +'Lun ', # 0x2b +'Zhuo ', # 0x2c +'Wei ', # 0x2d +'Luo ', # 0x2e +'Song ', # 0x2f +'Leng ', # 0x30 +'Hun ', # 0x31 +'Dong ', # 0x32 +'Zi ', # 0x33 +'Ben ', # 0x34 +'Wu ', # 0x35 +'Ju ', # 0x36 +'Nai ', # 0x37 +'Cai ', # 0x38 +'Jian ', # 0x39 +'Zhai ', # 0x3a +'Ye ', # 0x3b +'Zhi ', # 0x3c +'Sha ', # 0x3d +'Qing ', # 0x3e +'[?] ', # 0x3f +'Ying ', # 0x40 +'Cheng ', # 0x41 +'Jian ', # 0x42 +'Yan ', # 0x43 +'Nuan ', # 0x44 +'Zhong ', # 0x45 +'Chun ', # 0x46 +'Jia ', # 0x47 +'Jie ', # 0x48 +'Wei ', # 0x49 +'Yu ', # 0x4a +'Bing ', # 0x4b +'Ruo ', # 0x4c +'Ti ', # 0x4d +'Wei ', # 0x4e +'Pian ', # 0x4f +'Yan ', # 0x50 +'Feng ', # 0x51 +'Tang ', # 0x52 +'Wo ', # 0x53 +'E ', # 0x54 +'Xie ', # 0x55 +'Che ', # 0x56 +'Sheng ', # 0x57 +'Kan ', # 0x58 +'Di ', # 0x59 +'Zuo ', # 0x5a +'Cha ', # 0x5b +'Ting ', # 0x5c +'Bei ', # 0x5d +'Ye ', # 0x5e +'Huang ', # 0x5f +'Yao ', # 0x60 +'Zhan ', # 0x61 +'Chou ', # 0x62 +'Yan ', # 0x63 +'You ', # 0x64 +'Jian ', # 0x65 +'Xu ', # 0x66 +'Zha ', # 0x67 +'Ci ', # 0x68 +'Fu ', # 0x69 +'Bi ', # 0x6a +'Zhi ', # 0x6b +'Zong ', # 0x6c +'Mian ', # 0x6d +'Ji ', # 0x6e +'Yi ', # 0x6f +'Xie ', # 0x70 +'Xun ', # 0x71 +'Si ', # 0x72 +'Duan ', # 0x73 +'Ce ', # 0x74 +'Zhen ', # 0x75 +'Ou ', # 0x76 +'Tou ', # 0x77 +'Tou ', # 0x78 +'Bei ', # 0x79 +'Za ', # 0x7a +'Lu ', # 0x7b +'Jie ', # 0x7c +'Wei ', # 0x7d +'Fen ', # 0x7e +'Chang ', # 0x7f +'Gui ', # 0x80 +'Sou ', # 0x81 +'Zhi ', # 0x82 +'Su ', # 0x83 +'Xia ', # 0x84 +'Fu ', # 0x85 +'Yuan ', # 0x86 +'Rong ', # 0x87 +'Li ', # 0x88 +'Ru ', # 0x89 +'Yun ', # 0x8a +'Gou ', # 0x8b +'Ma ', # 0x8c +'Bang ', # 0x8d +'Dian ', # 0x8e +'Tang ', # 0x8f +'Hao ', # 0x90 +'Jie ', # 0x91 +'Xi ', # 0x92 +'Shan ', # 0x93 +'Qian ', # 0x94 +'Jue ', # 0x95 +'Cang ', # 0x96 +'Chu ', # 0x97 +'San ', # 0x98 +'Bei ', # 0x99 +'Xiao ', # 0x9a +'Yong ', # 0x9b +'Yao ', # 0x9c +'Tan ', # 0x9d +'Suo ', # 0x9e +'Yang ', # 0x9f +'Fa ', # 0xa0 +'Bing ', # 0xa1 +'Jia ', # 0xa2 +'Dai ', # 0xa3 +'Zai ', # 0xa4 +'Tang ', # 0xa5 +'[?] ', # 0xa6 +'Bin ', # 0xa7 +'Chu ', # 0xa8 +'Nuo ', # 0xa9 +'Can ', # 0xaa +'Lei ', # 0xab +'Cui ', # 0xac +'Yong ', # 0xad +'Zao ', # 0xae +'Zong ', # 0xaf +'Peng ', # 0xb0 +'Song ', # 0xb1 +'Ao ', # 0xb2 +'Chuan ', # 0xb3 +'Yu ', # 0xb4 +'Zhai ', # 0xb5 +'Cou ', # 0xb6 +'Shang ', # 0xb7 +'Qiang ', # 0xb8 +'Jing ', # 0xb9 +'Chi ', # 0xba +'Sha ', # 0xbb +'Han ', # 0xbc +'Zhang ', # 0xbd +'Qing ', # 0xbe +'Yan ', # 0xbf +'Di ', # 0xc0 +'Xi ', # 0xc1 +'Lu ', # 0xc2 +'Bei ', # 0xc3 +'Piao ', # 0xc4 +'Jin ', # 0xc5 +'Lian ', # 0xc6 +'Lu ', # 0xc7 +'Man ', # 0xc8 +'Qian ', # 0xc9 +'Xian ', # 0xca +'Tan ', # 0xcb +'Ying ', # 0xcc +'Dong ', # 0xcd +'Zhuan ', # 0xce +'Xiang ', # 0xcf +'Shan ', # 0xd0 +'Qiao ', # 0xd1 +'Jiong ', # 0xd2 +'Tui ', # 0xd3 +'Zun ', # 0xd4 +'Pu ', # 0xd5 +'Xi ', # 0xd6 +'Lao ', # 0xd7 +'Chang ', # 0xd8 +'Guang ', # 0xd9 +'Liao ', # 0xda +'Qi ', # 0xdb +'Deng ', # 0xdc +'Chan ', # 0xdd +'Wei ', # 0xde +'Ji ', # 0xdf +'Fan ', # 0xe0 +'Hui ', # 0xe1 +'Chuan ', # 0xe2 +'Jian ', # 0xe3 +'Dan ', # 0xe4 +'Jiao ', # 0xe5 +'Jiu ', # 0xe6 +'Seng ', # 0xe7 +'Fen ', # 0xe8 +'Xian ', # 0xe9 +'Jue ', # 0xea +'E ', # 0xeb +'Jiao ', # 0xec +'Jian ', # 0xed +'Tong ', # 0xee +'Lin ', # 0xef +'Bo ', # 0xf0 +'Gu ', # 0xf1 +'[?] ', # 0xf2 +'Su ', # 0xf3 +'Xian ', # 0xf4 +'Jiang ', # 0xf5 +'Min ', # 0xf6 +'Ye ', # 0xf7 +'Jin ', # 0xf8 +'Jia ', # 0xf9 +'Qiao ', # 0xfa +'Pi ', # 0xfb +'Feng ', # 0xfc +'Zhou ', # 0xfd +'Ai ', # 0xfe +'Sai ', # 0xff +) diff --git a/libs/unidecode/x051.py b/libs/unidecode/x051.py new file mode 100644 index 00000000..c1928354 --- /dev/null +++ b/libs/unidecode/x051.py @@ -0,0 +1,258 @@ +data = ( +'Yi ', # 0x00 +'Jun ', # 0x01 +'Nong ', # 0x02 +'Chan ', # 0x03 +'Yi ', # 0x04 +'Dang ', # 0x05 +'Jing ', # 0x06 +'Xuan ', # 0x07 +'Kuai ', # 0x08 +'Jian ', # 0x09 +'Chu ', # 0x0a +'Dan ', # 0x0b +'Jiao ', # 0x0c +'Sha ', # 0x0d +'Zai ', # 0x0e +'[?] ', # 0x0f +'Bin ', # 0x10 +'An ', # 0x11 +'Ru ', # 0x12 +'Tai ', # 0x13 +'Chou ', # 0x14 +'Chai ', # 0x15 +'Lan ', # 0x16 +'Ni ', # 0x17 +'Jin ', # 0x18 +'Qian ', # 0x19 +'Meng ', # 0x1a +'Wu ', # 0x1b +'Ning ', # 0x1c +'Qiong ', # 0x1d +'Ni ', # 0x1e +'Chang ', # 0x1f +'Lie ', # 0x20 +'Lei ', # 0x21 +'Lu ', # 0x22 +'Kuang ', # 0x23 +'Bao ', # 0x24 +'Du ', # 0x25 +'Biao ', # 0x26 +'Zan ', # 0x27 +'Zhi ', # 0x28 +'Si ', # 0x29 +'You ', # 0x2a +'Hao ', # 0x2b +'Chen ', # 0x2c +'Chen ', # 0x2d +'Li ', # 0x2e +'Teng ', # 0x2f +'Wei ', # 0x30 +'Long ', # 0x31 +'Chu ', # 0x32 +'Chan ', # 0x33 +'Rang ', # 0x34 +'Shu ', # 0x35 +'Hui ', # 0x36 +'Li ', # 0x37 +'Luo ', # 0x38 +'Zan ', # 0x39 +'Nuo ', # 0x3a +'Tang ', # 0x3b +'Yan ', # 0x3c +'Lei ', # 0x3d +'Nang ', # 0x3e +'Er ', # 0x3f +'Wu ', # 0x40 +'Yun ', # 0x41 +'Zan ', # 0x42 +'Yuan ', # 0x43 +'Xiong ', # 0x44 +'Chong ', # 0x45 +'Zhao ', # 0x46 +'Xiong ', # 0x47 +'Xian ', # 0x48 +'Guang ', # 0x49 +'Dui ', # 0x4a +'Ke ', # 0x4b +'Dui ', # 0x4c +'Mian ', # 0x4d +'Tu ', # 0x4e +'Chang ', # 0x4f +'Er ', # 0x50 +'Dui ', # 0x51 +'Er ', # 0x52 +'Xin ', # 0x53 +'Tu ', # 0x54 +'Si ', # 0x55 +'Yan ', # 0x56 +'Yan ', # 0x57 +'Shi ', # 0x58 +'Shi ', # 0x59 +'Dang ', # 0x5a +'Qian ', # 0x5b +'Dou ', # 0x5c +'Fen ', # 0x5d +'Mao ', # 0x5e +'Shen ', # 0x5f +'Dou ', # 0x60 +'Bai ', # 0x61 +'Jing ', # 0x62 +'Li ', # 0x63 +'Huang ', # 0x64 +'Ru ', # 0x65 +'Wang ', # 0x66 +'Nei ', # 0x67 +'Quan ', # 0x68 +'Liang ', # 0x69 +'Yu ', # 0x6a +'Ba ', # 0x6b +'Gong ', # 0x6c +'Liu ', # 0x6d +'Xi ', # 0x6e +'[?] ', # 0x6f +'Lan ', # 0x70 +'Gong ', # 0x71 +'Tian ', # 0x72 +'Guan ', # 0x73 +'Xing ', # 0x74 +'Bing ', # 0x75 +'Qi ', # 0x76 +'Ju ', # 0x77 +'Dian ', # 0x78 +'Zi ', # 0x79 +'Ppwun ', # 0x7a +'Yang ', # 0x7b +'Jian ', # 0x7c +'Shou ', # 0x7d +'Ji ', # 0x7e +'Yi ', # 0x7f +'Ji ', # 0x80 +'Chan ', # 0x81 +'Jiong ', # 0x82 +'Mao ', # 0x83 +'Ran ', # 0x84 +'Nei ', # 0x85 +'Yuan ', # 0x86 +'Mao ', # 0x87 +'Gang ', # 0x88 +'Ran ', # 0x89 +'Ce ', # 0x8a +'Jiong ', # 0x8b +'Ce ', # 0x8c +'Zai ', # 0x8d +'Gua ', # 0x8e +'Jiong ', # 0x8f +'Mao ', # 0x90 +'Zhou ', # 0x91 +'Mou ', # 0x92 +'Gou ', # 0x93 +'Xu ', # 0x94 +'Mian ', # 0x95 +'Mi ', # 0x96 +'Rong ', # 0x97 +'Yin ', # 0x98 +'Xie ', # 0x99 +'Kan ', # 0x9a +'Jun ', # 0x9b +'Nong ', # 0x9c +'Yi ', # 0x9d +'Mi ', # 0x9e +'Shi ', # 0x9f +'Guan ', # 0xa0 +'Meng ', # 0xa1 +'Zhong ', # 0xa2 +'Ju ', # 0xa3 +'Yuan ', # 0xa4 +'Ming ', # 0xa5 +'Kou ', # 0xa6 +'Lam ', # 0xa7 +'Fu ', # 0xa8 +'Xie ', # 0xa9 +'Mi ', # 0xaa +'Bing ', # 0xab +'Dong ', # 0xac +'Tai ', # 0xad +'Gang ', # 0xae +'Feng ', # 0xaf +'Bing ', # 0xb0 +'Hu ', # 0xb1 +'Chong ', # 0xb2 +'Jue ', # 0xb3 +'Hu ', # 0xb4 +'Kuang ', # 0xb5 +'Ye ', # 0xb6 +'Leng ', # 0xb7 +'Pan ', # 0xb8 +'Fu ', # 0xb9 +'Min ', # 0xba +'Dong ', # 0xbb +'Xian ', # 0xbc +'Lie ', # 0xbd +'Xia ', # 0xbe +'Jian ', # 0xbf +'Jing ', # 0xc0 +'Shu ', # 0xc1 +'Mei ', # 0xc2 +'Tu ', # 0xc3 +'Qi ', # 0xc4 +'Gu ', # 0xc5 +'Zhun ', # 0xc6 +'Song ', # 0xc7 +'Jing ', # 0xc8 +'Liang ', # 0xc9 +'Qing ', # 0xca +'Diao ', # 0xcb +'Ling ', # 0xcc +'Dong ', # 0xcd +'Gan ', # 0xce +'Jian ', # 0xcf +'Yin ', # 0xd0 +'Cou ', # 0xd1 +'Yi ', # 0xd2 +'Li ', # 0xd3 +'Cang ', # 0xd4 +'Ming ', # 0xd5 +'Zhuen ', # 0xd6 +'Cui ', # 0xd7 +'Si ', # 0xd8 +'Duo ', # 0xd9 +'Jin ', # 0xda +'Lin ', # 0xdb +'Lin ', # 0xdc +'Ning ', # 0xdd +'Xi ', # 0xde +'Du ', # 0xdf +'Ji ', # 0xe0 +'Fan ', # 0xe1 +'Fan ', # 0xe2 +'Fan ', # 0xe3 +'Feng ', # 0xe4 +'Ju ', # 0xe5 +'Chu ', # 0xe6 +'Tako ', # 0xe7 +'Feng ', # 0xe8 +'Mok ', # 0xe9 +'Ci ', # 0xea +'Fu ', # 0xeb +'Feng ', # 0xec +'Ping ', # 0xed +'Feng ', # 0xee +'Kai ', # 0xef +'Huang ', # 0xf0 +'Kai ', # 0xf1 +'Gan ', # 0xf2 +'Deng ', # 0xf3 +'Ping ', # 0xf4 +'Qu ', # 0xf5 +'Xiong ', # 0xf6 +'Kuai ', # 0xf7 +'Tu ', # 0xf8 +'Ao ', # 0xf9 +'Chu ', # 0xfa +'Ji ', # 0xfb +'Dang ', # 0xfc +'Han ', # 0xfd +'Han ', # 0xfe +'Zao ', # 0xff +) diff --git a/libs/unidecode/x052.py b/libs/unidecode/x052.py new file mode 100644 index 00000000..088f221f --- /dev/null +++ b/libs/unidecode/x052.py @@ -0,0 +1,258 @@ +data = ( +'Dao ', # 0x00 +'Diao ', # 0x01 +'Dao ', # 0x02 +'Ren ', # 0x03 +'Ren ', # 0x04 +'Chuang ', # 0x05 +'Fen ', # 0x06 +'Qie ', # 0x07 +'Yi ', # 0x08 +'Ji ', # 0x09 +'Kan ', # 0x0a +'Qian ', # 0x0b +'Cun ', # 0x0c +'Chu ', # 0x0d +'Wen ', # 0x0e +'Ji ', # 0x0f +'Dan ', # 0x10 +'Xing ', # 0x11 +'Hua ', # 0x12 +'Wan ', # 0x13 +'Jue ', # 0x14 +'Li ', # 0x15 +'Yue ', # 0x16 +'Lie ', # 0x17 +'Liu ', # 0x18 +'Ze ', # 0x19 +'Gang ', # 0x1a +'Chuang ', # 0x1b +'Fu ', # 0x1c +'Chu ', # 0x1d +'Qu ', # 0x1e +'Ju ', # 0x1f +'Shan ', # 0x20 +'Min ', # 0x21 +'Ling ', # 0x22 +'Zhong ', # 0x23 +'Pan ', # 0x24 +'Bie ', # 0x25 +'Jie ', # 0x26 +'Jie ', # 0x27 +'Bao ', # 0x28 +'Li ', # 0x29 +'Shan ', # 0x2a +'Bie ', # 0x2b +'Chan ', # 0x2c +'Jing ', # 0x2d +'Gua ', # 0x2e +'Gen ', # 0x2f +'Dao ', # 0x30 +'Chuang ', # 0x31 +'Kui ', # 0x32 +'Ku ', # 0x33 +'Duo ', # 0x34 +'Er ', # 0x35 +'Zhi ', # 0x36 +'Shua ', # 0x37 +'Quan ', # 0x38 +'Cha ', # 0x39 +'Ci ', # 0x3a +'Ke ', # 0x3b +'Jie ', # 0x3c +'Gui ', # 0x3d +'Ci ', # 0x3e +'Gui ', # 0x3f +'Kai ', # 0x40 +'Duo ', # 0x41 +'Ji ', # 0x42 +'Ti ', # 0x43 +'Jing ', # 0x44 +'Lou ', # 0x45 +'Gen ', # 0x46 +'Ze ', # 0x47 +'Yuan ', # 0x48 +'Cuo ', # 0x49 +'Xue ', # 0x4a +'Ke ', # 0x4b +'La ', # 0x4c +'Qian ', # 0x4d +'Cha ', # 0x4e +'Chuang ', # 0x4f +'Gua ', # 0x50 +'Jian ', # 0x51 +'Cuo ', # 0x52 +'Li ', # 0x53 +'Ti ', # 0x54 +'Fei ', # 0x55 +'Pou ', # 0x56 +'Chan ', # 0x57 +'Qi ', # 0x58 +'Chuang ', # 0x59 +'Zi ', # 0x5a +'Gang ', # 0x5b +'Wan ', # 0x5c +'Bo ', # 0x5d +'Ji ', # 0x5e +'Duo ', # 0x5f +'Qing ', # 0x60 +'Yan ', # 0x61 +'Zhuo ', # 0x62 +'Jian ', # 0x63 +'Ji ', # 0x64 +'Bo ', # 0x65 +'Yan ', # 0x66 +'Ju ', # 0x67 +'Huo ', # 0x68 +'Sheng ', # 0x69 +'Jian ', # 0x6a +'Duo ', # 0x6b +'Duan ', # 0x6c +'Wu ', # 0x6d +'Gua ', # 0x6e +'Fu ', # 0x6f +'Sheng ', # 0x70 +'Jian ', # 0x71 +'Ge ', # 0x72 +'Zha ', # 0x73 +'Kai ', # 0x74 +'Chuang ', # 0x75 +'Juan ', # 0x76 +'Chan ', # 0x77 +'Tuan ', # 0x78 +'Lu ', # 0x79 +'Li ', # 0x7a +'Fou ', # 0x7b +'Shan ', # 0x7c +'Piao ', # 0x7d +'Kou ', # 0x7e +'Jiao ', # 0x7f +'Gua ', # 0x80 +'Qiao ', # 0x81 +'Jue ', # 0x82 +'Hua ', # 0x83 +'Zha ', # 0x84 +'Zhuo ', # 0x85 +'Lian ', # 0x86 +'Ju ', # 0x87 +'Pi ', # 0x88 +'Liu ', # 0x89 +'Gui ', # 0x8a +'Jiao ', # 0x8b +'Gui ', # 0x8c +'Jian ', # 0x8d +'Jian ', # 0x8e +'Tang ', # 0x8f +'Huo ', # 0x90 +'Ji ', # 0x91 +'Jian ', # 0x92 +'Yi ', # 0x93 +'Jian ', # 0x94 +'Zhi ', # 0x95 +'Chan ', # 0x96 +'Cuan ', # 0x97 +'Mo ', # 0x98 +'Li ', # 0x99 +'Zhu ', # 0x9a +'Li ', # 0x9b +'Ya ', # 0x9c +'Quan ', # 0x9d +'Ban ', # 0x9e +'Gong ', # 0x9f +'Jia ', # 0xa0 +'Wu ', # 0xa1 +'Mai ', # 0xa2 +'Lie ', # 0xa3 +'Jin ', # 0xa4 +'Keng ', # 0xa5 +'Xie ', # 0xa6 +'Zhi ', # 0xa7 +'Dong ', # 0xa8 +'Zhu ', # 0xa9 +'Nu ', # 0xaa +'Jie ', # 0xab +'Qu ', # 0xac +'Shao ', # 0xad +'Yi ', # 0xae +'Zhu ', # 0xaf +'Miao ', # 0xb0 +'Li ', # 0xb1 +'Jing ', # 0xb2 +'Lao ', # 0xb3 +'Lao ', # 0xb4 +'Juan ', # 0xb5 +'Kou ', # 0xb6 +'Yang ', # 0xb7 +'Wa ', # 0xb8 +'Xiao ', # 0xb9 +'Mou ', # 0xba +'Kuang ', # 0xbb +'Jie ', # 0xbc +'Lie ', # 0xbd +'He ', # 0xbe +'Shi ', # 0xbf +'Ke ', # 0xc0 +'Jing ', # 0xc1 +'Hao ', # 0xc2 +'Bo ', # 0xc3 +'Min ', # 0xc4 +'Chi ', # 0xc5 +'Lang ', # 0xc6 +'Yong ', # 0xc7 +'Yong ', # 0xc8 +'Mian ', # 0xc9 +'Ke ', # 0xca +'Xun ', # 0xcb +'Juan ', # 0xcc +'Qing ', # 0xcd +'Lu ', # 0xce +'Pou ', # 0xcf +'Meng ', # 0xd0 +'Lai ', # 0xd1 +'Le ', # 0xd2 +'Kai ', # 0xd3 +'Mian ', # 0xd4 +'Dong ', # 0xd5 +'Xu ', # 0xd6 +'Xu ', # 0xd7 +'Kan ', # 0xd8 +'Wu ', # 0xd9 +'Yi ', # 0xda +'Xun ', # 0xdb +'Weng ', # 0xdc +'Sheng ', # 0xdd +'Lao ', # 0xde +'Mu ', # 0xdf +'Lu ', # 0xe0 +'Piao ', # 0xe1 +'Shi ', # 0xe2 +'Ji ', # 0xe3 +'Qin ', # 0xe4 +'Qiang ', # 0xe5 +'Jiao ', # 0xe6 +'Quan ', # 0xe7 +'Yang ', # 0xe8 +'Yi ', # 0xe9 +'Jue ', # 0xea +'Fan ', # 0xeb +'Juan ', # 0xec +'Tong ', # 0xed +'Ju ', # 0xee +'Dan ', # 0xef +'Xie ', # 0xf0 +'Mai ', # 0xf1 +'Xun ', # 0xf2 +'Xun ', # 0xf3 +'Lu ', # 0xf4 +'Li ', # 0xf5 +'Che ', # 0xf6 +'Rang ', # 0xf7 +'Quan ', # 0xf8 +'Bao ', # 0xf9 +'Shao ', # 0xfa +'Yun ', # 0xfb +'Jiu ', # 0xfc +'Bao ', # 0xfd +'Gou ', # 0xfe +'Wu ', # 0xff +) diff --git a/libs/unidecode/x053.py b/libs/unidecode/x053.py new file mode 100644 index 00000000..fa08b6ef --- /dev/null +++ b/libs/unidecode/x053.py @@ -0,0 +1,258 @@ +data = ( +'Yun ', # 0x00 +'Mwun ', # 0x01 +'Nay ', # 0x02 +'Gai ', # 0x03 +'Gai ', # 0x04 +'Bao ', # 0x05 +'Cong ', # 0x06 +'[?] ', # 0x07 +'Xiong ', # 0x08 +'Peng ', # 0x09 +'Ju ', # 0x0a +'Tao ', # 0x0b +'Ge ', # 0x0c +'Pu ', # 0x0d +'An ', # 0x0e +'Pao ', # 0x0f +'Fu ', # 0x10 +'Gong ', # 0x11 +'Da ', # 0x12 +'Jiu ', # 0x13 +'Qiong ', # 0x14 +'Bi ', # 0x15 +'Hua ', # 0x16 +'Bei ', # 0x17 +'Nao ', # 0x18 +'Chi ', # 0x19 +'Fang ', # 0x1a +'Jiu ', # 0x1b +'Yi ', # 0x1c +'Za ', # 0x1d +'Jiang ', # 0x1e +'Kang ', # 0x1f +'Jiang ', # 0x20 +'Kuang ', # 0x21 +'Hu ', # 0x22 +'Xia ', # 0x23 +'Qu ', # 0x24 +'Bian ', # 0x25 +'Gui ', # 0x26 +'Qie ', # 0x27 +'Zang ', # 0x28 +'Kuang ', # 0x29 +'Fei ', # 0x2a +'Hu ', # 0x2b +'Tou ', # 0x2c +'Gui ', # 0x2d +'Gui ', # 0x2e +'Hui ', # 0x2f +'Dan ', # 0x30 +'Gui ', # 0x31 +'Lian ', # 0x32 +'Lian ', # 0x33 +'Suan ', # 0x34 +'Du ', # 0x35 +'Jiu ', # 0x36 +'Qu ', # 0x37 +'Xi ', # 0x38 +'Pi ', # 0x39 +'Qu ', # 0x3a +'Yi ', # 0x3b +'Qia ', # 0x3c +'Yan ', # 0x3d +'Bian ', # 0x3e +'Ni ', # 0x3f +'Qu ', # 0x40 +'Shi ', # 0x41 +'Xin ', # 0x42 +'Qian ', # 0x43 +'Nian ', # 0x44 +'Sa ', # 0x45 +'Zu ', # 0x46 +'Sheng ', # 0x47 +'Wu ', # 0x48 +'Hui ', # 0x49 +'Ban ', # 0x4a +'Shi ', # 0x4b +'Xi ', # 0x4c +'Wan ', # 0x4d +'Hua ', # 0x4e +'Xie ', # 0x4f +'Wan ', # 0x50 +'Bei ', # 0x51 +'Zu ', # 0x52 +'Zhuo ', # 0x53 +'Xie ', # 0x54 +'Dan ', # 0x55 +'Mai ', # 0x56 +'Nan ', # 0x57 +'Dan ', # 0x58 +'Ji ', # 0x59 +'Bo ', # 0x5a +'Shuai ', # 0x5b +'Bu ', # 0x5c +'Kuang ', # 0x5d +'Bian ', # 0x5e +'Bu ', # 0x5f +'Zhan ', # 0x60 +'Qia ', # 0x61 +'Lu ', # 0x62 +'You ', # 0x63 +'Lu ', # 0x64 +'Xi ', # 0x65 +'Gua ', # 0x66 +'Wo ', # 0x67 +'Xie ', # 0x68 +'Jie ', # 0x69 +'Jie ', # 0x6a +'Wei ', # 0x6b +'Ang ', # 0x6c +'Qiong ', # 0x6d +'Zhi ', # 0x6e +'Mao ', # 0x6f +'Yin ', # 0x70 +'Wei ', # 0x71 +'Shao ', # 0x72 +'Ji ', # 0x73 +'Que ', # 0x74 +'Luan ', # 0x75 +'Shi ', # 0x76 +'Juan ', # 0x77 +'Xie ', # 0x78 +'Xu ', # 0x79 +'Jin ', # 0x7a +'Que ', # 0x7b +'Wu ', # 0x7c +'Ji ', # 0x7d +'E ', # 0x7e +'Qing ', # 0x7f +'Xi ', # 0x80 +'[?] ', # 0x81 +'Han ', # 0x82 +'Zhan ', # 0x83 +'E ', # 0x84 +'Ting ', # 0x85 +'Li ', # 0x86 +'Zhe ', # 0x87 +'Han ', # 0x88 +'Li ', # 0x89 +'Ya ', # 0x8a +'Ya ', # 0x8b +'Yan ', # 0x8c +'She ', # 0x8d +'Zhi ', # 0x8e +'Zha ', # 0x8f +'Pang ', # 0x90 +'[?] ', # 0x91 +'He ', # 0x92 +'Ya ', # 0x93 +'Zhi ', # 0x94 +'Ce ', # 0x95 +'Pang ', # 0x96 +'Ti ', # 0x97 +'Li ', # 0x98 +'She ', # 0x99 +'Hou ', # 0x9a +'Ting ', # 0x9b +'Zui ', # 0x9c +'Cuo ', # 0x9d +'Fei ', # 0x9e +'Yuan ', # 0x9f +'Ce ', # 0xa0 +'Yuan ', # 0xa1 +'Xiang ', # 0xa2 +'Yan ', # 0xa3 +'Li ', # 0xa4 +'Jue ', # 0xa5 +'Sha ', # 0xa6 +'Dian ', # 0xa7 +'Chu ', # 0xa8 +'Jiu ', # 0xa9 +'Qin ', # 0xaa +'Ao ', # 0xab +'Gui ', # 0xac +'Yan ', # 0xad +'Si ', # 0xae +'Li ', # 0xaf +'Chang ', # 0xb0 +'Lan ', # 0xb1 +'Li ', # 0xb2 +'Yan ', # 0xb3 +'Yan ', # 0xb4 +'Yuan ', # 0xb5 +'Si ', # 0xb6 +'Gong ', # 0xb7 +'Lin ', # 0xb8 +'Qiu ', # 0xb9 +'Qu ', # 0xba +'Qu ', # 0xbb +'Uk ', # 0xbc +'Lei ', # 0xbd +'Du ', # 0xbe +'Xian ', # 0xbf +'Zhuan ', # 0xc0 +'San ', # 0xc1 +'Can ', # 0xc2 +'Can ', # 0xc3 +'Can ', # 0xc4 +'Can ', # 0xc5 +'Ai ', # 0xc6 +'Dai ', # 0xc7 +'You ', # 0xc8 +'Cha ', # 0xc9 +'Ji ', # 0xca +'You ', # 0xcb +'Shuang ', # 0xcc +'Fan ', # 0xcd +'Shou ', # 0xce +'Guai ', # 0xcf +'Ba ', # 0xd0 +'Fa ', # 0xd1 +'Ruo ', # 0xd2 +'Shi ', # 0xd3 +'Shu ', # 0xd4 +'Zhuo ', # 0xd5 +'Qu ', # 0xd6 +'Shou ', # 0xd7 +'Bian ', # 0xd8 +'Xu ', # 0xd9 +'Jia ', # 0xda +'Pan ', # 0xdb +'Sou ', # 0xdc +'Gao ', # 0xdd +'Wei ', # 0xde +'Sou ', # 0xdf +'Die ', # 0xe0 +'Rui ', # 0xe1 +'Cong ', # 0xe2 +'Kou ', # 0xe3 +'Gu ', # 0xe4 +'Ju ', # 0xe5 +'Ling ', # 0xe6 +'Gua ', # 0xe7 +'Tao ', # 0xe8 +'Kou ', # 0xe9 +'Zhi ', # 0xea +'Jiao ', # 0xeb +'Zhao ', # 0xec +'Ba ', # 0xed +'Ding ', # 0xee +'Ke ', # 0xef +'Tai ', # 0xf0 +'Chi ', # 0xf1 +'Shi ', # 0xf2 +'You ', # 0xf3 +'Qiu ', # 0xf4 +'Po ', # 0xf5 +'Xie ', # 0xf6 +'Hao ', # 0xf7 +'Si ', # 0xf8 +'Tan ', # 0xf9 +'Chi ', # 0xfa +'Le ', # 0xfb +'Diao ', # 0xfc +'Ji ', # 0xfd +'[?] ', # 0xfe +'Hong ', # 0xff +) diff --git a/libs/unidecode/x054.py b/libs/unidecode/x054.py new file mode 100644 index 00000000..c014e0fe --- /dev/null +++ b/libs/unidecode/x054.py @@ -0,0 +1,258 @@ +data = ( +'Mie ', # 0x00 +'Xu ', # 0x01 +'Mang ', # 0x02 +'Chi ', # 0x03 +'Ge ', # 0x04 +'Xuan ', # 0x05 +'Yao ', # 0x06 +'Zi ', # 0x07 +'He ', # 0x08 +'Ji ', # 0x09 +'Diao ', # 0x0a +'Cun ', # 0x0b +'Tong ', # 0x0c +'Ming ', # 0x0d +'Hou ', # 0x0e +'Li ', # 0x0f +'Tu ', # 0x10 +'Xiang ', # 0x11 +'Zha ', # 0x12 +'Xia ', # 0x13 +'Ye ', # 0x14 +'Lu ', # 0x15 +'A ', # 0x16 +'Ma ', # 0x17 +'Ou ', # 0x18 +'Xue ', # 0x19 +'Yi ', # 0x1a +'Jun ', # 0x1b +'Chou ', # 0x1c +'Lin ', # 0x1d +'Tun ', # 0x1e +'Yin ', # 0x1f +'Fei ', # 0x20 +'Bi ', # 0x21 +'Qin ', # 0x22 +'Qin ', # 0x23 +'Jie ', # 0x24 +'Bu ', # 0x25 +'Fou ', # 0x26 +'Ba ', # 0x27 +'Dun ', # 0x28 +'Fen ', # 0x29 +'E ', # 0x2a +'Han ', # 0x2b +'Ting ', # 0x2c +'Hang ', # 0x2d +'Shun ', # 0x2e +'Qi ', # 0x2f +'Hong ', # 0x30 +'Zhi ', # 0x31 +'Shen ', # 0x32 +'Wu ', # 0x33 +'Wu ', # 0x34 +'Chao ', # 0x35 +'Ne ', # 0x36 +'Xue ', # 0x37 +'Xi ', # 0x38 +'Chui ', # 0x39 +'Dou ', # 0x3a +'Wen ', # 0x3b +'Hou ', # 0x3c +'Ou ', # 0x3d +'Wu ', # 0x3e +'Gao ', # 0x3f +'Ya ', # 0x40 +'Jun ', # 0x41 +'Lu ', # 0x42 +'E ', # 0x43 +'Ge ', # 0x44 +'Mei ', # 0x45 +'Ai ', # 0x46 +'Qi ', # 0x47 +'Cheng ', # 0x48 +'Wu ', # 0x49 +'Gao ', # 0x4a +'Fu ', # 0x4b +'Jiao ', # 0x4c +'Hong ', # 0x4d +'Chi ', # 0x4e +'Sheng ', # 0x4f +'Ne ', # 0x50 +'Tun ', # 0x51 +'Fu ', # 0x52 +'Yi ', # 0x53 +'Dai ', # 0x54 +'Ou ', # 0x55 +'Li ', # 0x56 +'Bai ', # 0x57 +'Yuan ', # 0x58 +'Kuai ', # 0x59 +'[?] ', # 0x5a +'Qiang ', # 0x5b +'Wu ', # 0x5c +'E ', # 0x5d +'Shi ', # 0x5e +'Quan ', # 0x5f +'Pen ', # 0x60 +'Wen ', # 0x61 +'Ni ', # 0x62 +'M ', # 0x63 +'Ling ', # 0x64 +'Ran ', # 0x65 +'You ', # 0x66 +'Di ', # 0x67 +'Zhou ', # 0x68 +'Shi ', # 0x69 +'Zhou ', # 0x6a +'Tie ', # 0x6b +'Xi ', # 0x6c +'Yi ', # 0x6d +'Qi ', # 0x6e +'Ping ', # 0x6f +'Zi ', # 0x70 +'Gu ', # 0x71 +'Zi ', # 0x72 +'Wei ', # 0x73 +'Xu ', # 0x74 +'He ', # 0x75 +'Nao ', # 0x76 +'Xia ', # 0x77 +'Pei ', # 0x78 +'Yi ', # 0x79 +'Xiao ', # 0x7a +'Shen ', # 0x7b +'Hu ', # 0x7c +'Ming ', # 0x7d +'Da ', # 0x7e +'Qu ', # 0x7f +'Ju ', # 0x80 +'Gem ', # 0x81 +'Za ', # 0x82 +'Tuo ', # 0x83 +'Duo ', # 0x84 +'Pou ', # 0x85 +'Pao ', # 0x86 +'Bi ', # 0x87 +'Fu ', # 0x88 +'Yang ', # 0x89 +'He ', # 0x8a +'Zha ', # 0x8b +'He ', # 0x8c +'Hai ', # 0x8d +'Jiu ', # 0x8e +'Yong ', # 0x8f +'Fu ', # 0x90 +'Que ', # 0x91 +'Zhou ', # 0x92 +'Wa ', # 0x93 +'Ka ', # 0x94 +'Gu ', # 0x95 +'Ka ', # 0x96 +'Zuo ', # 0x97 +'Bu ', # 0x98 +'Long ', # 0x99 +'Dong ', # 0x9a +'Ning ', # 0x9b +'Tha ', # 0x9c +'Si ', # 0x9d +'Xian ', # 0x9e +'Huo ', # 0x9f +'Qi ', # 0xa0 +'Er ', # 0xa1 +'E ', # 0xa2 +'Guang ', # 0xa3 +'Zha ', # 0xa4 +'Xi ', # 0xa5 +'Yi ', # 0xa6 +'Lie ', # 0xa7 +'Zi ', # 0xa8 +'Mie ', # 0xa9 +'Mi ', # 0xaa +'Zhi ', # 0xab +'Yao ', # 0xac +'Ji ', # 0xad +'Zhou ', # 0xae +'Ge ', # 0xaf +'Shuai ', # 0xb0 +'Zan ', # 0xb1 +'Xiao ', # 0xb2 +'Ke ', # 0xb3 +'Hui ', # 0xb4 +'Kua ', # 0xb5 +'Huai ', # 0xb6 +'Tao ', # 0xb7 +'Xian ', # 0xb8 +'E ', # 0xb9 +'Xuan ', # 0xba +'Xiu ', # 0xbb +'Wai ', # 0xbc +'Yan ', # 0xbd +'Lao ', # 0xbe +'Yi ', # 0xbf +'Ai ', # 0xc0 +'Pin ', # 0xc1 +'Shen ', # 0xc2 +'Tong ', # 0xc3 +'Hong ', # 0xc4 +'Xiong ', # 0xc5 +'Chi ', # 0xc6 +'Wa ', # 0xc7 +'Ha ', # 0xc8 +'Zai ', # 0xc9 +'Yu ', # 0xca +'Di ', # 0xcb +'Pai ', # 0xcc +'Xiang ', # 0xcd +'Ai ', # 0xce +'Hen ', # 0xcf +'Kuang ', # 0xd0 +'Ya ', # 0xd1 +'Da ', # 0xd2 +'Xiao ', # 0xd3 +'Bi ', # 0xd4 +'Yue ', # 0xd5 +'[?] ', # 0xd6 +'Hua ', # 0xd7 +'Sasou ', # 0xd8 +'Kuai ', # 0xd9 +'Duo ', # 0xda +'[?] ', # 0xdb +'Ji ', # 0xdc +'Nong ', # 0xdd +'Mou ', # 0xde +'Yo ', # 0xdf +'Hao ', # 0xe0 +'Yuan ', # 0xe1 +'Long ', # 0xe2 +'Pou ', # 0xe3 +'Mang ', # 0xe4 +'Ge ', # 0xe5 +'E ', # 0xe6 +'Chi ', # 0xe7 +'Shao ', # 0xe8 +'Li ', # 0xe9 +'Na ', # 0xea +'Zu ', # 0xeb +'He ', # 0xec +'Ku ', # 0xed +'Xiao ', # 0xee +'Xian ', # 0xef +'Lao ', # 0xf0 +'Bo ', # 0xf1 +'Zhe ', # 0xf2 +'Zha ', # 0xf3 +'Liang ', # 0xf4 +'Ba ', # 0xf5 +'Mie ', # 0xf6 +'Le ', # 0xf7 +'Sui ', # 0xf8 +'Fou ', # 0xf9 +'Bu ', # 0xfa +'Han ', # 0xfb +'Heng ', # 0xfc +'Geng ', # 0xfd +'Shuo ', # 0xfe +'Ge ', # 0xff +) diff --git a/libs/unidecode/x055.py b/libs/unidecode/x055.py new file mode 100644 index 00000000..26aea747 --- /dev/null +++ b/libs/unidecode/x055.py @@ -0,0 +1,258 @@ +data = ( +'You ', # 0x00 +'Yan ', # 0x01 +'Gu ', # 0x02 +'Gu ', # 0x03 +'Bai ', # 0x04 +'Han ', # 0x05 +'Suo ', # 0x06 +'Chun ', # 0x07 +'Yi ', # 0x08 +'Ai ', # 0x09 +'Jia ', # 0x0a +'Tu ', # 0x0b +'Xian ', # 0x0c +'Huan ', # 0x0d +'Li ', # 0x0e +'Xi ', # 0x0f +'Tang ', # 0x10 +'Zuo ', # 0x11 +'Qiu ', # 0x12 +'Che ', # 0x13 +'Wu ', # 0x14 +'Zao ', # 0x15 +'Ya ', # 0x16 +'Dou ', # 0x17 +'Qi ', # 0x18 +'Di ', # 0x19 +'Qin ', # 0x1a +'Ma ', # 0x1b +'Mal ', # 0x1c +'Hong ', # 0x1d +'Dou ', # 0x1e +'Kes ', # 0x1f +'Lao ', # 0x20 +'Liang ', # 0x21 +'Suo ', # 0x22 +'Zao ', # 0x23 +'Huan ', # 0x24 +'Lang ', # 0x25 +'Sha ', # 0x26 +'Ji ', # 0x27 +'Zuo ', # 0x28 +'Wo ', # 0x29 +'Feng ', # 0x2a +'Yin ', # 0x2b +'Hu ', # 0x2c +'Qi ', # 0x2d +'Shou ', # 0x2e +'Wei ', # 0x2f +'Shua ', # 0x30 +'Chang ', # 0x31 +'Er ', # 0x32 +'Li ', # 0x33 +'Qiang ', # 0x34 +'An ', # 0x35 +'Jie ', # 0x36 +'Yo ', # 0x37 +'Nian ', # 0x38 +'Yu ', # 0x39 +'Tian ', # 0x3a +'Lai ', # 0x3b +'Sha ', # 0x3c +'Xi ', # 0x3d +'Tuo ', # 0x3e +'Hu ', # 0x3f +'Ai ', # 0x40 +'Zhou ', # 0x41 +'Nou ', # 0x42 +'Ken ', # 0x43 +'Zhuo ', # 0x44 +'Zhuo ', # 0x45 +'Shang ', # 0x46 +'Di ', # 0x47 +'Heng ', # 0x48 +'Lan ', # 0x49 +'A ', # 0x4a +'Xiao ', # 0x4b +'Xiang ', # 0x4c +'Tun ', # 0x4d +'Wu ', # 0x4e +'Wen ', # 0x4f +'Cui ', # 0x50 +'Sha ', # 0x51 +'Hu ', # 0x52 +'Qi ', # 0x53 +'Qi ', # 0x54 +'Tao ', # 0x55 +'Dan ', # 0x56 +'Dan ', # 0x57 +'Ye ', # 0x58 +'Zi ', # 0x59 +'Bi ', # 0x5a +'Cui ', # 0x5b +'Chuo ', # 0x5c +'He ', # 0x5d +'Ya ', # 0x5e +'Qi ', # 0x5f +'Zhe ', # 0x60 +'Pei ', # 0x61 +'Liang ', # 0x62 +'Xian ', # 0x63 +'Pi ', # 0x64 +'Sha ', # 0x65 +'La ', # 0x66 +'Ze ', # 0x67 +'Qing ', # 0x68 +'Gua ', # 0x69 +'Pa ', # 0x6a +'Zhe ', # 0x6b +'Se ', # 0x6c +'Zhuan ', # 0x6d +'Nie ', # 0x6e +'Guo ', # 0x6f +'Luo ', # 0x70 +'Yan ', # 0x71 +'Di ', # 0x72 +'Quan ', # 0x73 +'Tan ', # 0x74 +'Bo ', # 0x75 +'Ding ', # 0x76 +'Lang ', # 0x77 +'Xiao ', # 0x78 +'[?] ', # 0x79 +'Tang ', # 0x7a +'Chi ', # 0x7b +'Ti ', # 0x7c +'An ', # 0x7d +'Jiu ', # 0x7e +'Dan ', # 0x7f +'Ke ', # 0x80 +'Yong ', # 0x81 +'Wei ', # 0x82 +'Nan ', # 0x83 +'Shan ', # 0x84 +'Yu ', # 0x85 +'Zhe ', # 0x86 +'La ', # 0x87 +'Jie ', # 0x88 +'Hou ', # 0x89 +'Han ', # 0x8a +'Die ', # 0x8b +'Zhou ', # 0x8c +'Chai ', # 0x8d +'Wai ', # 0x8e +'Re ', # 0x8f +'Yu ', # 0x90 +'Yin ', # 0x91 +'Zan ', # 0x92 +'Yao ', # 0x93 +'Wo ', # 0x94 +'Mian ', # 0x95 +'Hu ', # 0x96 +'Yun ', # 0x97 +'Chuan ', # 0x98 +'Hui ', # 0x99 +'Huan ', # 0x9a +'Huan ', # 0x9b +'Xi ', # 0x9c +'He ', # 0x9d +'Ji ', # 0x9e +'Kui ', # 0x9f +'Zhong ', # 0xa0 +'Wei ', # 0xa1 +'Sha ', # 0xa2 +'Xu ', # 0xa3 +'Huang ', # 0xa4 +'Du ', # 0xa5 +'Nie ', # 0xa6 +'Xuan ', # 0xa7 +'Liang ', # 0xa8 +'Yu ', # 0xa9 +'Sang ', # 0xaa +'Chi ', # 0xab +'Qiao ', # 0xac +'Yan ', # 0xad +'Dan ', # 0xae +'Pen ', # 0xaf +'Can ', # 0xb0 +'Li ', # 0xb1 +'Yo ', # 0xb2 +'Zha ', # 0xb3 +'Wei ', # 0xb4 +'Miao ', # 0xb5 +'Ying ', # 0xb6 +'Pen ', # 0xb7 +'Phos ', # 0xb8 +'Kui ', # 0xb9 +'Xi ', # 0xba +'Yu ', # 0xbb +'Jie ', # 0xbc +'Lou ', # 0xbd +'Ku ', # 0xbe +'Sao ', # 0xbf +'Huo ', # 0xc0 +'Ti ', # 0xc1 +'Yao ', # 0xc2 +'He ', # 0xc3 +'A ', # 0xc4 +'Xiu ', # 0xc5 +'Qiang ', # 0xc6 +'Se ', # 0xc7 +'Yong ', # 0xc8 +'Su ', # 0xc9 +'Hong ', # 0xca +'Xie ', # 0xcb +'Yi ', # 0xcc +'Suo ', # 0xcd +'Ma ', # 0xce +'Cha ', # 0xcf +'Hai ', # 0xd0 +'Ke ', # 0xd1 +'Ta ', # 0xd2 +'Sang ', # 0xd3 +'Tian ', # 0xd4 +'Ru ', # 0xd5 +'Sou ', # 0xd6 +'Wa ', # 0xd7 +'Ji ', # 0xd8 +'Pang ', # 0xd9 +'Wu ', # 0xda +'Xian ', # 0xdb +'Shi ', # 0xdc +'Ge ', # 0xdd +'Zi ', # 0xde +'Jie ', # 0xdf +'Luo ', # 0xe0 +'Weng ', # 0xe1 +'Wa ', # 0xe2 +'Si ', # 0xe3 +'Chi ', # 0xe4 +'Hao ', # 0xe5 +'Suo ', # 0xe6 +'Jia ', # 0xe7 +'Hai ', # 0xe8 +'Suo ', # 0xe9 +'Qin ', # 0xea +'Nie ', # 0xeb +'He ', # 0xec +'Cis ', # 0xed +'Sai ', # 0xee +'Ng ', # 0xef +'Ge ', # 0xf0 +'Na ', # 0xf1 +'Dia ', # 0xf2 +'Ai ', # 0xf3 +'[?] ', # 0xf4 +'Tong ', # 0xf5 +'Bi ', # 0xf6 +'Ao ', # 0xf7 +'Ao ', # 0xf8 +'Lian ', # 0xf9 +'Cui ', # 0xfa +'Zhe ', # 0xfb +'Mo ', # 0xfc +'Sou ', # 0xfd +'Sou ', # 0xfe +'Tan ', # 0xff +) diff --git a/libs/unidecode/x056.py b/libs/unidecode/x056.py new file mode 100644 index 00000000..30b7fa54 --- /dev/null +++ b/libs/unidecode/x056.py @@ -0,0 +1,258 @@ +data = ( +'Di ', # 0x00 +'Qi ', # 0x01 +'Jiao ', # 0x02 +'Chong ', # 0x03 +'Jiao ', # 0x04 +'Kai ', # 0x05 +'Tan ', # 0x06 +'San ', # 0x07 +'Cao ', # 0x08 +'Jia ', # 0x09 +'Ai ', # 0x0a +'Xiao ', # 0x0b +'Piao ', # 0x0c +'Lou ', # 0x0d +'Ga ', # 0x0e +'Gu ', # 0x0f +'Xiao ', # 0x10 +'Hu ', # 0x11 +'Hui ', # 0x12 +'Guo ', # 0x13 +'Ou ', # 0x14 +'Xian ', # 0x15 +'Ze ', # 0x16 +'Chang ', # 0x17 +'Xu ', # 0x18 +'Po ', # 0x19 +'De ', # 0x1a +'Ma ', # 0x1b +'Ma ', # 0x1c +'Hu ', # 0x1d +'Lei ', # 0x1e +'Du ', # 0x1f +'Ga ', # 0x20 +'Tang ', # 0x21 +'Ye ', # 0x22 +'Beng ', # 0x23 +'Ying ', # 0x24 +'Saai ', # 0x25 +'Jiao ', # 0x26 +'Mi ', # 0x27 +'Xiao ', # 0x28 +'Hua ', # 0x29 +'Mai ', # 0x2a +'Ran ', # 0x2b +'Zuo ', # 0x2c +'Peng ', # 0x2d +'Lao ', # 0x2e +'Xiao ', # 0x2f +'Ji ', # 0x30 +'Zhu ', # 0x31 +'Chao ', # 0x32 +'Kui ', # 0x33 +'Zui ', # 0x34 +'Xiao ', # 0x35 +'Si ', # 0x36 +'Hao ', # 0x37 +'Fu ', # 0x38 +'Liao ', # 0x39 +'Qiao ', # 0x3a +'Xi ', # 0x3b +'Xiu ', # 0x3c +'Tan ', # 0x3d +'Tan ', # 0x3e +'Mo ', # 0x3f +'Xun ', # 0x40 +'E ', # 0x41 +'Zun ', # 0x42 +'Fan ', # 0x43 +'Chi ', # 0x44 +'Hui ', # 0x45 +'Zan ', # 0x46 +'Chuang ', # 0x47 +'Cu ', # 0x48 +'Dan ', # 0x49 +'Yu ', # 0x4a +'Tun ', # 0x4b +'Cheng ', # 0x4c +'Jiao ', # 0x4d +'Ye ', # 0x4e +'Xi ', # 0x4f +'Qi ', # 0x50 +'Hao ', # 0x51 +'Lian ', # 0x52 +'Xu ', # 0x53 +'Deng ', # 0x54 +'Hui ', # 0x55 +'Yin ', # 0x56 +'Pu ', # 0x57 +'Jue ', # 0x58 +'Qin ', # 0x59 +'Xun ', # 0x5a +'Nie ', # 0x5b +'Lu ', # 0x5c +'Si ', # 0x5d +'Yan ', # 0x5e +'Ying ', # 0x5f +'Da ', # 0x60 +'Dan ', # 0x61 +'Yu ', # 0x62 +'Zhou ', # 0x63 +'Jin ', # 0x64 +'Nong ', # 0x65 +'Yue ', # 0x66 +'Hui ', # 0x67 +'Qi ', # 0x68 +'E ', # 0x69 +'Zao ', # 0x6a +'Yi ', # 0x6b +'Shi ', # 0x6c +'Jiao ', # 0x6d +'Yuan ', # 0x6e +'Ai ', # 0x6f +'Yong ', # 0x70 +'Jue ', # 0x71 +'Kuai ', # 0x72 +'Yu ', # 0x73 +'Pen ', # 0x74 +'Dao ', # 0x75 +'Ge ', # 0x76 +'Xin ', # 0x77 +'Dun ', # 0x78 +'Dang ', # 0x79 +'Sin ', # 0x7a +'Sai ', # 0x7b +'Pi ', # 0x7c +'Pi ', # 0x7d +'Yin ', # 0x7e +'Zui ', # 0x7f +'Ning ', # 0x80 +'Di ', # 0x81 +'Lan ', # 0x82 +'Ta ', # 0x83 +'Huo ', # 0x84 +'Ru ', # 0x85 +'Hao ', # 0x86 +'Xia ', # 0x87 +'Ya ', # 0x88 +'Duo ', # 0x89 +'Xi ', # 0x8a +'Chou ', # 0x8b +'Ji ', # 0x8c +'Jin ', # 0x8d +'Hao ', # 0x8e +'Ti ', # 0x8f +'Chang ', # 0x90 +'[?] ', # 0x91 +'[?] ', # 0x92 +'Ca ', # 0x93 +'Ti ', # 0x94 +'Lu ', # 0x95 +'Hui ', # 0x96 +'Bo ', # 0x97 +'You ', # 0x98 +'Nie ', # 0x99 +'Yin ', # 0x9a +'Hu ', # 0x9b +'Mo ', # 0x9c +'Huang ', # 0x9d +'Zhe ', # 0x9e +'Li ', # 0x9f +'Liu ', # 0xa0 +'Haai ', # 0xa1 +'Nang ', # 0xa2 +'Xiao ', # 0xa3 +'Mo ', # 0xa4 +'Yan ', # 0xa5 +'Li ', # 0xa6 +'Lu ', # 0xa7 +'Long ', # 0xa8 +'Fu ', # 0xa9 +'Dan ', # 0xaa +'Chen ', # 0xab +'Pin ', # 0xac +'Pi ', # 0xad +'Xiang ', # 0xae +'Huo ', # 0xaf +'Mo ', # 0xb0 +'Xi ', # 0xb1 +'Duo ', # 0xb2 +'Ku ', # 0xb3 +'Yan ', # 0xb4 +'Chan ', # 0xb5 +'Ying ', # 0xb6 +'Rang ', # 0xb7 +'Dian ', # 0xb8 +'La ', # 0xb9 +'Ta ', # 0xba +'Xiao ', # 0xbb +'Jiao ', # 0xbc +'Chuo ', # 0xbd +'Huan ', # 0xbe +'Huo ', # 0xbf +'Zhuan ', # 0xc0 +'Nie ', # 0xc1 +'Xiao ', # 0xc2 +'Ca ', # 0xc3 +'Li ', # 0xc4 +'Chan ', # 0xc5 +'Chai ', # 0xc6 +'Li ', # 0xc7 +'Yi ', # 0xc8 +'Luo ', # 0xc9 +'Nang ', # 0xca +'Zan ', # 0xcb +'Su ', # 0xcc +'Xi ', # 0xcd +'So ', # 0xce +'Jian ', # 0xcf +'Za ', # 0xd0 +'Zhu ', # 0xd1 +'Lan ', # 0xd2 +'Nie ', # 0xd3 +'Nang ', # 0xd4 +'[?] ', # 0xd5 +'[?] ', # 0xd6 +'Wei ', # 0xd7 +'Hui ', # 0xd8 +'Yin ', # 0xd9 +'Qiu ', # 0xda +'Si ', # 0xdb +'Nin ', # 0xdc +'Jian ', # 0xdd +'Hui ', # 0xde +'Xin ', # 0xdf +'Yin ', # 0xe0 +'Nan ', # 0xe1 +'Tuan ', # 0xe2 +'Tuan ', # 0xe3 +'Dun ', # 0xe4 +'Kang ', # 0xe5 +'Yuan ', # 0xe6 +'Jiong ', # 0xe7 +'Pian ', # 0xe8 +'Yun ', # 0xe9 +'Cong ', # 0xea +'Hu ', # 0xeb +'Hui ', # 0xec +'Yuan ', # 0xed +'You ', # 0xee +'Guo ', # 0xef +'Kun ', # 0xf0 +'Cong ', # 0xf1 +'Wei ', # 0xf2 +'Tu ', # 0xf3 +'Wei ', # 0xf4 +'Lun ', # 0xf5 +'Guo ', # 0xf6 +'Qun ', # 0xf7 +'Ri ', # 0xf8 +'Ling ', # 0xf9 +'Gu ', # 0xfa +'Guo ', # 0xfb +'Tai ', # 0xfc +'Guo ', # 0xfd +'Tu ', # 0xfe +'You ', # 0xff +) diff --git a/libs/unidecode/x057.py b/libs/unidecode/x057.py new file mode 100644 index 00000000..9392fb86 --- /dev/null +++ b/libs/unidecode/x057.py @@ -0,0 +1,258 @@ +data = ( +'Guo ', # 0x00 +'Yin ', # 0x01 +'Hun ', # 0x02 +'Pu ', # 0x03 +'Yu ', # 0x04 +'Han ', # 0x05 +'Yuan ', # 0x06 +'Lun ', # 0x07 +'Quan ', # 0x08 +'Yu ', # 0x09 +'Qing ', # 0x0a +'Guo ', # 0x0b +'Chuan ', # 0x0c +'Wei ', # 0x0d +'Yuan ', # 0x0e +'Quan ', # 0x0f +'Ku ', # 0x10 +'Fu ', # 0x11 +'Yuan ', # 0x12 +'Yuan ', # 0x13 +'E ', # 0x14 +'Tu ', # 0x15 +'Tu ', # 0x16 +'Tu ', # 0x17 +'Tuan ', # 0x18 +'Lue ', # 0x19 +'Hui ', # 0x1a +'Yi ', # 0x1b +'Yuan ', # 0x1c +'Luan ', # 0x1d +'Luan ', # 0x1e +'Tu ', # 0x1f +'Ya ', # 0x20 +'Tu ', # 0x21 +'Ting ', # 0x22 +'Sheng ', # 0x23 +'Pu ', # 0x24 +'Lu ', # 0x25 +'Iri ', # 0x26 +'Ya ', # 0x27 +'Zai ', # 0x28 +'Wei ', # 0x29 +'Ge ', # 0x2a +'Yu ', # 0x2b +'Wu ', # 0x2c +'Gui ', # 0x2d +'Pi ', # 0x2e +'Yi ', # 0x2f +'Di ', # 0x30 +'Qian ', # 0x31 +'Qian ', # 0x32 +'Zhen ', # 0x33 +'Zhuo ', # 0x34 +'Dang ', # 0x35 +'Qia ', # 0x36 +'Akutsu ', # 0x37 +'Yama ', # 0x38 +'Kuang ', # 0x39 +'Chang ', # 0x3a +'Qi ', # 0x3b +'Nie ', # 0x3c +'Mo ', # 0x3d +'Ji ', # 0x3e +'Jia ', # 0x3f +'Zhi ', # 0x40 +'Zhi ', # 0x41 +'Ban ', # 0x42 +'Xun ', # 0x43 +'Tou ', # 0x44 +'Qin ', # 0x45 +'Fen ', # 0x46 +'Jun ', # 0x47 +'Keng ', # 0x48 +'Tun ', # 0x49 +'Fang ', # 0x4a +'Fen ', # 0x4b +'Ben ', # 0x4c +'Tan ', # 0x4d +'Kan ', # 0x4e +'Pi ', # 0x4f +'Zuo ', # 0x50 +'Keng ', # 0x51 +'Bi ', # 0x52 +'Xing ', # 0x53 +'Di ', # 0x54 +'Jing ', # 0x55 +'Ji ', # 0x56 +'Kuai ', # 0x57 +'Di ', # 0x58 +'Jing ', # 0x59 +'Jian ', # 0x5a +'Tan ', # 0x5b +'Li ', # 0x5c +'Ba ', # 0x5d +'Wu ', # 0x5e +'Fen ', # 0x5f +'Zhui ', # 0x60 +'Po ', # 0x61 +'Pan ', # 0x62 +'Tang ', # 0x63 +'Kun ', # 0x64 +'Qu ', # 0x65 +'Tan ', # 0x66 +'Zhi ', # 0x67 +'Tuo ', # 0x68 +'Gan ', # 0x69 +'Ping ', # 0x6a +'Dian ', # 0x6b +'Gua ', # 0x6c +'Ni ', # 0x6d +'Tai ', # 0x6e +'Pi ', # 0x6f +'Jiong ', # 0x70 +'Yang ', # 0x71 +'Fo ', # 0x72 +'Ao ', # 0x73 +'Liu ', # 0x74 +'Qiu ', # 0x75 +'Mu ', # 0x76 +'Ke ', # 0x77 +'Gou ', # 0x78 +'Xue ', # 0x79 +'Ba ', # 0x7a +'Chi ', # 0x7b +'Che ', # 0x7c +'Ling ', # 0x7d +'Zhu ', # 0x7e +'Fu ', # 0x7f +'Hu ', # 0x80 +'Zhi ', # 0x81 +'Chui ', # 0x82 +'La ', # 0x83 +'Long ', # 0x84 +'Long ', # 0x85 +'Lu ', # 0x86 +'Ao ', # 0x87 +'Tay ', # 0x88 +'Pao ', # 0x89 +'[?] ', # 0x8a +'Xing ', # 0x8b +'Dong ', # 0x8c +'Ji ', # 0x8d +'Ke ', # 0x8e +'Lu ', # 0x8f +'Ci ', # 0x90 +'Chi ', # 0x91 +'Lei ', # 0x92 +'Gai ', # 0x93 +'Yin ', # 0x94 +'Hou ', # 0x95 +'Dui ', # 0x96 +'Zhao ', # 0x97 +'Fu ', # 0x98 +'Guang ', # 0x99 +'Yao ', # 0x9a +'Duo ', # 0x9b +'Duo ', # 0x9c +'Gui ', # 0x9d +'Cha ', # 0x9e +'Yang ', # 0x9f +'Yin ', # 0xa0 +'Fa ', # 0xa1 +'Gou ', # 0xa2 +'Yuan ', # 0xa3 +'Die ', # 0xa4 +'Xie ', # 0xa5 +'Ken ', # 0xa6 +'Jiong ', # 0xa7 +'Shou ', # 0xa8 +'E ', # 0xa9 +'Ha ', # 0xaa +'Dian ', # 0xab +'Hong ', # 0xac +'Wu ', # 0xad +'Kua ', # 0xae +'[?] ', # 0xaf +'Tao ', # 0xb0 +'Dang ', # 0xb1 +'Kai ', # 0xb2 +'Gake ', # 0xb3 +'Nao ', # 0xb4 +'An ', # 0xb5 +'Xing ', # 0xb6 +'Xian ', # 0xb7 +'Huan ', # 0xb8 +'Bang ', # 0xb9 +'Pei ', # 0xba +'Ba ', # 0xbb +'Yi ', # 0xbc +'Yin ', # 0xbd +'Han ', # 0xbe +'Xu ', # 0xbf +'Chui ', # 0xc0 +'Cen ', # 0xc1 +'Geng ', # 0xc2 +'Ai ', # 0xc3 +'Peng ', # 0xc4 +'Fang ', # 0xc5 +'Que ', # 0xc6 +'Yong ', # 0xc7 +'Xun ', # 0xc8 +'Jia ', # 0xc9 +'Di ', # 0xca +'Mai ', # 0xcb +'Lang ', # 0xcc +'Xuan ', # 0xcd +'Cheng ', # 0xce +'Yan ', # 0xcf +'Jin ', # 0xd0 +'Zhe ', # 0xd1 +'Lei ', # 0xd2 +'Lie ', # 0xd3 +'Bu ', # 0xd4 +'Cheng ', # 0xd5 +'Gomi ', # 0xd6 +'Bu ', # 0xd7 +'Shi ', # 0xd8 +'Xun ', # 0xd9 +'Guo ', # 0xda +'Jiong ', # 0xdb +'Ye ', # 0xdc +'Nian ', # 0xdd +'Di ', # 0xde +'Yu ', # 0xdf +'Bu ', # 0xe0 +'Ya ', # 0xe1 +'Juan ', # 0xe2 +'Sui ', # 0xe3 +'Pi ', # 0xe4 +'Cheng ', # 0xe5 +'Wan ', # 0xe6 +'Ju ', # 0xe7 +'Lun ', # 0xe8 +'Zheng ', # 0xe9 +'Kong ', # 0xea +'Chong ', # 0xeb +'Dong ', # 0xec +'Dai ', # 0xed +'Tan ', # 0xee +'An ', # 0xef +'Cai ', # 0xf0 +'Shu ', # 0xf1 +'Beng ', # 0xf2 +'Kan ', # 0xf3 +'Zhi ', # 0xf4 +'Duo ', # 0xf5 +'Yi ', # 0xf6 +'Zhi ', # 0xf7 +'Yi ', # 0xf8 +'Pei ', # 0xf9 +'Ji ', # 0xfa +'Zhun ', # 0xfb +'Qi ', # 0xfc +'Sao ', # 0xfd +'Ju ', # 0xfe +'Ni ', # 0xff +) diff --git a/libs/unidecode/x058.py b/libs/unidecode/x058.py new file mode 100644 index 00000000..88057182 --- /dev/null +++ b/libs/unidecode/x058.py @@ -0,0 +1,258 @@ +data = ( +'Ku ', # 0x00 +'Ke ', # 0x01 +'Tang ', # 0x02 +'Kun ', # 0x03 +'Ni ', # 0x04 +'Jian ', # 0x05 +'Dui ', # 0x06 +'Jin ', # 0x07 +'Gang ', # 0x08 +'Yu ', # 0x09 +'E ', # 0x0a +'Peng ', # 0x0b +'Gu ', # 0x0c +'Tu ', # 0x0d +'Leng ', # 0x0e +'[?] ', # 0x0f +'Ya ', # 0x10 +'Qian ', # 0x11 +'[?] ', # 0x12 +'An ', # 0x13 +'[?] ', # 0x14 +'Duo ', # 0x15 +'Nao ', # 0x16 +'Tu ', # 0x17 +'Cheng ', # 0x18 +'Yin ', # 0x19 +'Hun ', # 0x1a +'Bi ', # 0x1b +'Lian ', # 0x1c +'Guo ', # 0x1d +'Die ', # 0x1e +'Zhuan ', # 0x1f +'Hou ', # 0x20 +'Bao ', # 0x21 +'Bao ', # 0x22 +'Yu ', # 0x23 +'Di ', # 0x24 +'Mao ', # 0x25 +'Jie ', # 0x26 +'Ruan ', # 0x27 +'E ', # 0x28 +'Geng ', # 0x29 +'Kan ', # 0x2a +'Zong ', # 0x2b +'Yu ', # 0x2c +'Huang ', # 0x2d +'E ', # 0x2e +'Yao ', # 0x2f +'Yan ', # 0x30 +'Bao ', # 0x31 +'Ji ', # 0x32 +'Mei ', # 0x33 +'Chang ', # 0x34 +'Du ', # 0x35 +'Tuo ', # 0x36 +'Yin ', # 0x37 +'Feng ', # 0x38 +'Zhong ', # 0x39 +'Jie ', # 0x3a +'Zhen ', # 0x3b +'Feng ', # 0x3c +'Gang ', # 0x3d +'Chuan ', # 0x3e +'Jian ', # 0x3f +'Pyeng ', # 0x40 +'Toride ', # 0x41 +'Xiang ', # 0x42 +'Huang ', # 0x43 +'Leng ', # 0x44 +'Duan ', # 0x45 +'[?] ', # 0x46 +'Xuan ', # 0x47 +'Ji ', # 0x48 +'Ji ', # 0x49 +'Kuai ', # 0x4a +'Ying ', # 0x4b +'Ta ', # 0x4c +'Cheng ', # 0x4d +'Yong ', # 0x4e +'Kai ', # 0x4f +'Su ', # 0x50 +'Su ', # 0x51 +'Shi ', # 0x52 +'Mi ', # 0x53 +'Ta ', # 0x54 +'Weng ', # 0x55 +'Cheng ', # 0x56 +'Tu ', # 0x57 +'Tang ', # 0x58 +'Que ', # 0x59 +'Zhong ', # 0x5a +'Li ', # 0x5b +'Peng ', # 0x5c +'Bang ', # 0x5d +'Sai ', # 0x5e +'Zang ', # 0x5f +'Dui ', # 0x60 +'Tian ', # 0x61 +'Wu ', # 0x62 +'Cheng ', # 0x63 +'Xun ', # 0x64 +'Ge ', # 0x65 +'Zhen ', # 0x66 +'Ai ', # 0x67 +'Gong ', # 0x68 +'Yan ', # 0x69 +'Kan ', # 0x6a +'Tian ', # 0x6b +'Yuan ', # 0x6c +'Wen ', # 0x6d +'Xie ', # 0x6e +'Liu ', # 0x6f +'Ama ', # 0x70 +'Lang ', # 0x71 +'Chang ', # 0x72 +'Peng ', # 0x73 +'Beng ', # 0x74 +'Chen ', # 0x75 +'Cu ', # 0x76 +'Lu ', # 0x77 +'Ou ', # 0x78 +'Qian ', # 0x79 +'Mei ', # 0x7a +'Mo ', # 0x7b +'Zhuan ', # 0x7c +'Shuang ', # 0x7d +'Shu ', # 0x7e +'Lou ', # 0x7f +'Chi ', # 0x80 +'Man ', # 0x81 +'Biao ', # 0x82 +'Jing ', # 0x83 +'Qi ', # 0x84 +'Shu ', # 0x85 +'Di ', # 0x86 +'Zhang ', # 0x87 +'Kan ', # 0x88 +'Yong ', # 0x89 +'Dian ', # 0x8a +'Chen ', # 0x8b +'Zhi ', # 0x8c +'Xi ', # 0x8d +'Guo ', # 0x8e +'Qiang ', # 0x8f +'Jin ', # 0x90 +'Di ', # 0x91 +'Shang ', # 0x92 +'Mu ', # 0x93 +'Cui ', # 0x94 +'Yan ', # 0x95 +'Ta ', # 0x96 +'Zeng ', # 0x97 +'Qi ', # 0x98 +'Qiang ', # 0x99 +'Liang ', # 0x9a +'[?] ', # 0x9b +'Zhui ', # 0x9c +'Qiao ', # 0x9d +'Zeng ', # 0x9e +'Xu ', # 0x9f +'Shan ', # 0xa0 +'Shan ', # 0xa1 +'Ba ', # 0xa2 +'Pu ', # 0xa3 +'Kuai ', # 0xa4 +'Dong ', # 0xa5 +'Fan ', # 0xa6 +'Que ', # 0xa7 +'Mo ', # 0xa8 +'Dun ', # 0xa9 +'Dun ', # 0xaa +'Dun ', # 0xab +'Di ', # 0xac +'Sheng ', # 0xad +'Duo ', # 0xae +'Duo ', # 0xaf +'Tan ', # 0xb0 +'Deng ', # 0xb1 +'Wu ', # 0xb2 +'Fen ', # 0xb3 +'Huang ', # 0xb4 +'Tan ', # 0xb5 +'Da ', # 0xb6 +'Ye ', # 0xb7 +'Sho ', # 0xb8 +'Mama ', # 0xb9 +'Yu ', # 0xba +'Qiang ', # 0xbb +'Ji ', # 0xbc +'Qiao ', # 0xbd +'Ken ', # 0xbe +'Yi ', # 0xbf +'Pi ', # 0xc0 +'Bi ', # 0xc1 +'Dian ', # 0xc2 +'Jiang ', # 0xc3 +'Ye ', # 0xc4 +'Yong ', # 0xc5 +'Bo ', # 0xc6 +'Tan ', # 0xc7 +'Lan ', # 0xc8 +'Ju ', # 0xc9 +'Huai ', # 0xca +'Dang ', # 0xcb +'Rang ', # 0xcc +'Qian ', # 0xcd +'Xun ', # 0xce +'Lan ', # 0xcf +'Xi ', # 0xd0 +'He ', # 0xd1 +'Ai ', # 0xd2 +'Ya ', # 0xd3 +'Dao ', # 0xd4 +'Hao ', # 0xd5 +'Ruan ', # 0xd6 +'Mama ', # 0xd7 +'Lei ', # 0xd8 +'Kuang ', # 0xd9 +'Lu ', # 0xda +'Yan ', # 0xdb +'Tan ', # 0xdc +'Wei ', # 0xdd +'Huai ', # 0xde +'Long ', # 0xdf +'Long ', # 0xe0 +'Rui ', # 0xe1 +'Li ', # 0xe2 +'Lin ', # 0xe3 +'Rang ', # 0xe4 +'Ten ', # 0xe5 +'Xun ', # 0xe6 +'Yan ', # 0xe7 +'Lei ', # 0xe8 +'Ba ', # 0xe9 +'[?] ', # 0xea +'Shi ', # 0xeb +'Ren ', # 0xec +'[?] ', # 0xed +'Zhuang ', # 0xee +'Zhuang ', # 0xef +'Sheng ', # 0xf0 +'Yi ', # 0xf1 +'Mai ', # 0xf2 +'Ke ', # 0xf3 +'Zhu ', # 0xf4 +'Zhuang ', # 0xf5 +'Hu ', # 0xf6 +'Hu ', # 0xf7 +'Kun ', # 0xf8 +'Yi ', # 0xf9 +'Hu ', # 0xfa +'Xu ', # 0xfb +'Kun ', # 0xfc +'Shou ', # 0xfd +'Mang ', # 0xfe +'Zun ', # 0xff +) diff --git a/libs/unidecode/x059.py b/libs/unidecode/x059.py new file mode 100644 index 00000000..45966661 --- /dev/null +++ b/libs/unidecode/x059.py @@ -0,0 +1,258 @@ +data = ( +'Shou ', # 0x00 +'Yi ', # 0x01 +'Zhi ', # 0x02 +'Gu ', # 0x03 +'Chu ', # 0x04 +'Jiang ', # 0x05 +'Feng ', # 0x06 +'Bei ', # 0x07 +'Cay ', # 0x08 +'Bian ', # 0x09 +'Sui ', # 0x0a +'Qun ', # 0x0b +'Ling ', # 0x0c +'Fu ', # 0x0d +'Zuo ', # 0x0e +'Xia ', # 0x0f +'Xiong ', # 0x10 +'[?] ', # 0x11 +'Nao ', # 0x12 +'Xia ', # 0x13 +'Kui ', # 0x14 +'Xi ', # 0x15 +'Wai ', # 0x16 +'Yuan ', # 0x17 +'Mao ', # 0x18 +'Su ', # 0x19 +'Duo ', # 0x1a +'Duo ', # 0x1b +'Ye ', # 0x1c +'Qing ', # 0x1d +'Uys ', # 0x1e +'Gou ', # 0x1f +'Gou ', # 0x20 +'Qi ', # 0x21 +'Meng ', # 0x22 +'Meng ', # 0x23 +'Yin ', # 0x24 +'Huo ', # 0x25 +'Chen ', # 0x26 +'Da ', # 0x27 +'Ze ', # 0x28 +'Tian ', # 0x29 +'Tai ', # 0x2a +'Fu ', # 0x2b +'Guai ', # 0x2c +'Yao ', # 0x2d +'Yang ', # 0x2e +'Hang ', # 0x2f +'Gao ', # 0x30 +'Shi ', # 0x31 +'Ben ', # 0x32 +'Tai ', # 0x33 +'Tou ', # 0x34 +'Yan ', # 0x35 +'Bi ', # 0x36 +'Yi ', # 0x37 +'Kua ', # 0x38 +'Jia ', # 0x39 +'Duo ', # 0x3a +'Kwu ', # 0x3b +'Kuang ', # 0x3c +'Yun ', # 0x3d +'Jia ', # 0x3e +'Pa ', # 0x3f +'En ', # 0x40 +'Lian ', # 0x41 +'Huan ', # 0x42 +'Di ', # 0x43 +'Yan ', # 0x44 +'Pao ', # 0x45 +'Quan ', # 0x46 +'Qi ', # 0x47 +'Nai ', # 0x48 +'Feng ', # 0x49 +'Xie ', # 0x4a +'Fen ', # 0x4b +'Dian ', # 0x4c +'[?] ', # 0x4d +'Kui ', # 0x4e +'Zou ', # 0x4f +'Huan ', # 0x50 +'Qi ', # 0x51 +'Kai ', # 0x52 +'Zha ', # 0x53 +'Ben ', # 0x54 +'Yi ', # 0x55 +'Jiang ', # 0x56 +'Tao ', # 0x57 +'Zang ', # 0x58 +'Ben ', # 0x59 +'Xi ', # 0x5a +'Xiang ', # 0x5b +'Fei ', # 0x5c +'Diao ', # 0x5d +'Xun ', # 0x5e +'Keng ', # 0x5f +'Dian ', # 0x60 +'Ao ', # 0x61 +'She ', # 0x62 +'Weng ', # 0x63 +'Pan ', # 0x64 +'Ao ', # 0x65 +'Wu ', # 0x66 +'Ao ', # 0x67 +'Jiang ', # 0x68 +'Lian ', # 0x69 +'Duo ', # 0x6a +'Yun ', # 0x6b +'Jiang ', # 0x6c +'Shi ', # 0x6d +'Fen ', # 0x6e +'Huo ', # 0x6f +'Bi ', # 0x70 +'Lian ', # 0x71 +'Duo ', # 0x72 +'Nu ', # 0x73 +'Nu ', # 0x74 +'Ding ', # 0x75 +'Nai ', # 0x76 +'Qian ', # 0x77 +'Jian ', # 0x78 +'Ta ', # 0x79 +'Jiu ', # 0x7a +'Nan ', # 0x7b +'Cha ', # 0x7c +'Hao ', # 0x7d +'Xian ', # 0x7e +'Fan ', # 0x7f +'Ji ', # 0x80 +'Shuo ', # 0x81 +'Ru ', # 0x82 +'Fei ', # 0x83 +'Wang ', # 0x84 +'Hong ', # 0x85 +'Zhuang ', # 0x86 +'Fu ', # 0x87 +'Ma ', # 0x88 +'Dan ', # 0x89 +'Ren ', # 0x8a +'Fu ', # 0x8b +'Jing ', # 0x8c +'Yan ', # 0x8d +'Xie ', # 0x8e +'Wen ', # 0x8f +'Zhong ', # 0x90 +'Pa ', # 0x91 +'Du ', # 0x92 +'Ji ', # 0x93 +'Keng ', # 0x94 +'Zhong ', # 0x95 +'Yao ', # 0x96 +'Jin ', # 0x97 +'Yun ', # 0x98 +'Miao ', # 0x99 +'Pei ', # 0x9a +'Shi ', # 0x9b +'Yue ', # 0x9c +'Zhuang ', # 0x9d +'Niu ', # 0x9e +'Yan ', # 0x9f +'Na ', # 0xa0 +'Xin ', # 0xa1 +'Fen ', # 0xa2 +'Bi ', # 0xa3 +'Yu ', # 0xa4 +'Tuo ', # 0xa5 +'Feng ', # 0xa6 +'Yuan ', # 0xa7 +'Fang ', # 0xa8 +'Wu ', # 0xa9 +'Yu ', # 0xaa +'Gui ', # 0xab +'Du ', # 0xac +'Ba ', # 0xad +'Ni ', # 0xae +'Zhou ', # 0xaf +'Zhuo ', # 0xb0 +'Zhao ', # 0xb1 +'Da ', # 0xb2 +'Nai ', # 0xb3 +'Yuan ', # 0xb4 +'Tou ', # 0xb5 +'Xuan ', # 0xb6 +'Zhi ', # 0xb7 +'E ', # 0xb8 +'Mei ', # 0xb9 +'Mo ', # 0xba +'Qi ', # 0xbb +'Bi ', # 0xbc +'Shen ', # 0xbd +'Qie ', # 0xbe +'E ', # 0xbf +'He ', # 0xc0 +'Xu ', # 0xc1 +'Fa ', # 0xc2 +'Zheng ', # 0xc3 +'Min ', # 0xc4 +'Ban ', # 0xc5 +'Mu ', # 0xc6 +'Fu ', # 0xc7 +'Ling ', # 0xc8 +'Zi ', # 0xc9 +'Zi ', # 0xca +'Shi ', # 0xcb +'Ran ', # 0xcc +'Shan ', # 0xcd +'Yang ', # 0xce +'Man ', # 0xcf +'Jie ', # 0xd0 +'Gu ', # 0xd1 +'Si ', # 0xd2 +'Xing ', # 0xd3 +'Wei ', # 0xd4 +'Zi ', # 0xd5 +'Ju ', # 0xd6 +'Shan ', # 0xd7 +'Pin ', # 0xd8 +'Ren ', # 0xd9 +'Yao ', # 0xda +'Tong ', # 0xdb +'Jiang ', # 0xdc +'Shu ', # 0xdd +'Ji ', # 0xde +'Gai ', # 0xdf +'Shang ', # 0xe0 +'Kuo ', # 0xe1 +'Juan ', # 0xe2 +'Jiao ', # 0xe3 +'Gou ', # 0xe4 +'Mu ', # 0xe5 +'Jian ', # 0xe6 +'Jian ', # 0xe7 +'Yi ', # 0xe8 +'Nian ', # 0xe9 +'Zhi ', # 0xea +'Ji ', # 0xeb +'Ji ', # 0xec +'Xian ', # 0xed +'Heng ', # 0xee +'Guang ', # 0xef +'Jun ', # 0xf0 +'Kua ', # 0xf1 +'Yan ', # 0xf2 +'Ming ', # 0xf3 +'Lie ', # 0xf4 +'Pei ', # 0xf5 +'Yan ', # 0xf6 +'You ', # 0xf7 +'Yan ', # 0xf8 +'Cha ', # 0xf9 +'Shen ', # 0xfa +'Yin ', # 0xfb +'Chi ', # 0xfc +'Gui ', # 0xfd +'Quan ', # 0xfe +'Zi ', # 0xff +) diff --git a/libs/unidecode/x05a.py b/libs/unidecode/x05a.py new file mode 100644 index 00000000..be56e652 --- /dev/null +++ b/libs/unidecode/x05a.py @@ -0,0 +1,258 @@ +data = ( +'Song ', # 0x00 +'Wei ', # 0x01 +'Hong ', # 0x02 +'Wa ', # 0x03 +'Lou ', # 0x04 +'Ya ', # 0x05 +'Rao ', # 0x06 +'Jiao ', # 0x07 +'Luan ', # 0x08 +'Ping ', # 0x09 +'Xian ', # 0x0a +'Shao ', # 0x0b +'Li ', # 0x0c +'Cheng ', # 0x0d +'Xiao ', # 0x0e +'Mang ', # 0x0f +'Fu ', # 0x10 +'Suo ', # 0x11 +'Wu ', # 0x12 +'Wei ', # 0x13 +'Ke ', # 0x14 +'Lai ', # 0x15 +'Chuo ', # 0x16 +'Ding ', # 0x17 +'Niang ', # 0x18 +'Xing ', # 0x19 +'Nan ', # 0x1a +'Yu ', # 0x1b +'Nuo ', # 0x1c +'Pei ', # 0x1d +'Nei ', # 0x1e +'Juan ', # 0x1f +'Shen ', # 0x20 +'Zhi ', # 0x21 +'Han ', # 0x22 +'Di ', # 0x23 +'Zhuang ', # 0x24 +'E ', # 0x25 +'Pin ', # 0x26 +'Tui ', # 0x27 +'Han ', # 0x28 +'Mian ', # 0x29 +'Wu ', # 0x2a +'Yan ', # 0x2b +'Wu ', # 0x2c +'Xi ', # 0x2d +'Yan ', # 0x2e +'Yu ', # 0x2f +'Si ', # 0x30 +'Yu ', # 0x31 +'Wa ', # 0x32 +'[?] ', # 0x33 +'Xian ', # 0x34 +'Ju ', # 0x35 +'Qu ', # 0x36 +'Shui ', # 0x37 +'Qi ', # 0x38 +'Xian ', # 0x39 +'Zhui ', # 0x3a +'Dong ', # 0x3b +'Chang ', # 0x3c +'Lu ', # 0x3d +'Ai ', # 0x3e +'E ', # 0x3f +'E ', # 0x40 +'Lou ', # 0x41 +'Mian ', # 0x42 +'Cong ', # 0x43 +'Pou ', # 0x44 +'Ju ', # 0x45 +'Po ', # 0x46 +'Cai ', # 0x47 +'Ding ', # 0x48 +'Wan ', # 0x49 +'Biao ', # 0x4a +'Xiao ', # 0x4b +'Shu ', # 0x4c +'Qi ', # 0x4d +'Hui ', # 0x4e +'Fu ', # 0x4f +'E ', # 0x50 +'Wo ', # 0x51 +'Tan ', # 0x52 +'Fei ', # 0x53 +'Wei ', # 0x54 +'Jie ', # 0x55 +'Tian ', # 0x56 +'Ni ', # 0x57 +'Quan ', # 0x58 +'Jing ', # 0x59 +'Hun ', # 0x5a +'Jing ', # 0x5b +'Qian ', # 0x5c +'Dian ', # 0x5d +'Xing ', # 0x5e +'Hu ', # 0x5f +'Wa ', # 0x60 +'Lai ', # 0x61 +'Bi ', # 0x62 +'Yin ', # 0x63 +'Chou ', # 0x64 +'Chuo ', # 0x65 +'Fu ', # 0x66 +'Jing ', # 0x67 +'Lun ', # 0x68 +'Yan ', # 0x69 +'Lan ', # 0x6a +'Kun ', # 0x6b +'Yin ', # 0x6c +'Ya ', # 0x6d +'Ju ', # 0x6e +'Li ', # 0x6f +'Dian ', # 0x70 +'Xian ', # 0x71 +'Hwa ', # 0x72 +'Hua ', # 0x73 +'Ying ', # 0x74 +'Chan ', # 0x75 +'Shen ', # 0x76 +'Ting ', # 0x77 +'Dang ', # 0x78 +'Yao ', # 0x79 +'Wu ', # 0x7a +'Nan ', # 0x7b +'Ruo ', # 0x7c +'Jia ', # 0x7d +'Tou ', # 0x7e +'Xu ', # 0x7f +'Yu ', # 0x80 +'Wei ', # 0x81 +'Ti ', # 0x82 +'Rou ', # 0x83 +'Mei ', # 0x84 +'Dan ', # 0x85 +'Ruan ', # 0x86 +'Qin ', # 0x87 +'Hui ', # 0x88 +'Wu ', # 0x89 +'Qian ', # 0x8a +'Chun ', # 0x8b +'Mao ', # 0x8c +'Fu ', # 0x8d +'Jie ', # 0x8e +'Duan ', # 0x8f +'Xi ', # 0x90 +'Zhong ', # 0x91 +'Mei ', # 0x92 +'Huang ', # 0x93 +'Mian ', # 0x94 +'An ', # 0x95 +'Ying ', # 0x96 +'Xuan ', # 0x97 +'Jie ', # 0x98 +'Wei ', # 0x99 +'Mei ', # 0x9a +'Yuan ', # 0x9b +'Zhen ', # 0x9c +'Qiu ', # 0x9d +'Ti ', # 0x9e +'Xie ', # 0x9f +'Tuo ', # 0xa0 +'Lian ', # 0xa1 +'Mao ', # 0xa2 +'Ran ', # 0xa3 +'Si ', # 0xa4 +'Pian ', # 0xa5 +'Wei ', # 0xa6 +'Wa ', # 0xa7 +'Jiu ', # 0xa8 +'Hu ', # 0xa9 +'Ao ', # 0xaa +'[?] ', # 0xab +'Bou ', # 0xac +'Xu ', # 0xad +'Tou ', # 0xae +'Gui ', # 0xaf +'Zou ', # 0xb0 +'Yao ', # 0xb1 +'Pi ', # 0xb2 +'Xi ', # 0xb3 +'Yuan ', # 0xb4 +'Ying ', # 0xb5 +'Rong ', # 0xb6 +'Ru ', # 0xb7 +'Chi ', # 0xb8 +'Liu ', # 0xb9 +'Mei ', # 0xba +'Pan ', # 0xbb +'Ao ', # 0xbc +'Ma ', # 0xbd +'Gou ', # 0xbe +'Kui ', # 0xbf +'Qin ', # 0xc0 +'Jia ', # 0xc1 +'Sao ', # 0xc2 +'Zhen ', # 0xc3 +'Yuan ', # 0xc4 +'Cha ', # 0xc5 +'Yong ', # 0xc6 +'Ming ', # 0xc7 +'Ying ', # 0xc8 +'Ji ', # 0xc9 +'Su ', # 0xca +'Niao ', # 0xcb +'Xian ', # 0xcc +'Tao ', # 0xcd +'Pang ', # 0xce +'Lang ', # 0xcf +'Nao ', # 0xd0 +'Bao ', # 0xd1 +'Ai ', # 0xd2 +'Pi ', # 0xd3 +'Pin ', # 0xd4 +'Yi ', # 0xd5 +'Piao ', # 0xd6 +'Yu ', # 0xd7 +'Lei ', # 0xd8 +'Xuan ', # 0xd9 +'Man ', # 0xda +'Yi ', # 0xdb +'Zhang ', # 0xdc +'Kang ', # 0xdd +'Yong ', # 0xde +'Ni ', # 0xdf +'Li ', # 0xe0 +'Di ', # 0xe1 +'Gui ', # 0xe2 +'Yan ', # 0xe3 +'Jin ', # 0xe4 +'Zhuan ', # 0xe5 +'Chang ', # 0xe6 +'Ce ', # 0xe7 +'Han ', # 0xe8 +'Nen ', # 0xe9 +'Lao ', # 0xea +'Mo ', # 0xeb +'Zhe ', # 0xec +'Hu ', # 0xed +'Hu ', # 0xee +'Ao ', # 0xef +'Nen ', # 0xf0 +'Qiang ', # 0xf1 +'Ma ', # 0xf2 +'Pie ', # 0xf3 +'Gu ', # 0xf4 +'Wu ', # 0xf5 +'Jiao ', # 0xf6 +'Tuo ', # 0xf7 +'Zhan ', # 0xf8 +'Mao ', # 0xf9 +'Xian ', # 0xfa +'Xian ', # 0xfb +'Mo ', # 0xfc +'Liao ', # 0xfd +'Lian ', # 0xfe +'Hua ', # 0xff +) diff --git a/libs/unidecode/x05b.py b/libs/unidecode/x05b.py new file mode 100644 index 00000000..1b167b3e --- /dev/null +++ b/libs/unidecode/x05b.py @@ -0,0 +1,258 @@ +data = ( +'Gui ', # 0x00 +'Deng ', # 0x01 +'Zhi ', # 0x02 +'Xu ', # 0x03 +'Yi ', # 0x04 +'Hua ', # 0x05 +'Xi ', # 0x06 +'Hui ', # 0x07 +'Rao ', # 0x08 +'Xi ', # 0x09 +'Yan ', # 0x0a +'Chan ', # 0x0b +'Jiao ', # 0x0c +'Mei ', # 0x0d +'Fan ', # 0x0e +'Fan ', # 0x0f +'Xian ', # 0x10 +'Yi ', # 0x11 +'Wei ', # 0x12 +'Jiao ', # 0x13 +'Fu ', # 0x14 +'Shi ', # 0x15 +'Bi ', # 0x16 +'Shan ', # 0x17 +'Sui ', # 0x18 +'Qiang ', # 0x19 +'Lian ', # 0x1a +'Huan ', # 0x1b +'Xin ', # 0x1c +'Niao ', # 0x1d +'Dong ', # 0x1e +'Yi ', # 0x1f +'Can ', # 0x20 +'Ai ', # 0x21 +'Niang ', # 0x22 +'Neng ', # 0x23 +'Ma ', # 0x24 +'Tiao ', # 0x25 +'Chou ', # 0x26 +'Jin ', # 0x27 +'Ci ', # 0x28 +'Yu ', # 0x29 +'Pin ', # 0x2a +'Yong ', # 0x2b +'Xu ', # 0x2c +'Nai ', # 0x2d +'Yan ', # 0x2e +'Tai ', # 0x2f +'Ying ', # 0x30 +'Can ', # 0x31 +'Niao ', # 0x32 +'Wo ', # 0x33 +'Ying ', # 0x34 +'Mian ', # 0x35 +'Kaka ', # 0x36 +'Ma ', # 0x37 +'Shen ', # 0x38 +'Xing ', # 0x39 +'Ni ', # 0x3a +'Du ', # 0x3b +'Liu ', # 0x3c +'Yuan ', # 0x3d +'Lan ', # 0x3e +'Yan ', # 0x3f +'Shuang ', # 0x40 +'Ling ', # 0x41 +'Jiao ', # 0x42 +'Niang ', # 0x43 +'Lan ', # 0x44 +'Xian ', # 0x45 +'Ying ', # 0x46 +'Shuang ', # 0x47 +'Shuai ', # 0x48 +'Quan ', # 0x49 +'Mi ', # 0x4a +'Li ', # 0x4b +'Luan ', # 0x4c +'Yan ', # 0x4d +'Zhu ', # 0x4e +'Lan ', # 0x4f +'Zi ', # 0x50 +'Jie ', # 0x51 +'Jue ', # 0x52 +'Jue ', # 0x53 +'Kong ', # 0x54 +'Yun ', # 0x55 +'Zi ', # 0x56 +'Zi ', # 0x57 +'Cun ', # 0x58 +'Sun ', # 0x59 +'Fu ', # 0x5a +'Bei ', # 0x5b +'Zi ', # 0x5c +'Xiao ', # 0x5d +'Xin ', # 0x5e +'Meng ', # 0x5f +'Si ', # 0x60 +'Tai ', # 0x61 +'Bao ', # 0x62 +'Ji ', # 0x63 +'Gu ', # 0x64 +'Nu ', # 0x65 +'Xue ', # 0x66 +'[?] ', # 0x67 +'Zhuan ', # 0x68 +'Hai ', # 0x69 +'Luan ', # 0x6a +'Sun ', # 0x6b +'Huai ', # 0x6c +'Mie ', # 0x6d +'Cong ', # 0x6e +'Qian ', # 0x6f +'Shu ', # 0x70 +'Chan ', # 0x71 +'Ya ', # 0x72 +'Zi ', # 0x73 +'Ni ', # 0x74 +'Fu ', # 0x75 +'Zi ', # 0x76 +'Li ', # 0x77 +'Xue ', # 0x78 +'Bo ', # 0x79 +'Ru ', # 0x7a +'Lai ', # 0x7b +'Nie ', # 0x7c +'Nie ', # 0x7d +'Ying ', # 0x7e +'Luan ', # 0x7f +'Mian ', # 0x80 +'Zhu ', # 0x81 +'Rong ', # 0x82 +'Ta ', # 0x83 +'Gui ', # 0x84 +'Zhai ', # 0x85 +'Qiong ', # 0x86 +'Yu ', # 0x87 +'Shou ', # 0x88 +'An ', # 0x89 +'Tu ', # 0x8a +'Song ', # 0x8b +'Wan ', # 0x8c +'Rou ', # 0x8d +'Yao ', # 0x8e +'Hong ', # 0x8f +'Yi ', # 0x90 +'Jing ', # 0x91 +'Zhun ', # 0x92 +'Mi ', # 0x93 +'Zhu ', # 0x94 +'Dang ', # 0x95 +'Hong ', # 0x96 +'Zong ', # 0x97 +'Guan ', # 0x98 +'Zhou ', # 0x99 +'Ding ', # 0x9a +'Wan ', # 0x9b +'Yi ', # 0x9c +'Bao ', # 0x9d +'Shi ', # 0x9e +'Shi ', # 0x9f +'Chong ', # 0xa0 +'Shen ', # 0xa1 +'Ke ', # 0xa2 +'Xuan ', # 0xa3 +'Shi ', # 0xa4 +'You ', # 0xa5 +'Huan ', # 0xa6 +'Yi ', # 0xa7 +'Tiao ', # 0xa8 +'Shi ', # 0xa9 +'Xian ', # 0xaa +'Gong ', # 0xab +'Cheng ', # 0xac +'Qun ', # 0xad +'Gong ', # 0xae +'Xiao ', # 0xaf +'Zai ', # 0xb0 +'Zha ', # 0xb1 +'Bao ', # 0xb2 +'Hai ', # 0xb3 +'Yan ', # 0xb4 +'Xiao ', # 0xb5 +'Jia ', # 0xb6 +'Shen ', # 0xb7 +'Chen ', # 0xb8 +'Rong ', # 0xb9 +'Huang ', # 0xba +'Mi ', # 0xbb +'Kou ', # 0xbc +'Kuan ', # 0xbd +'Bin ', # 0xbe +'Su ', # 0xbf +'Cai ', # 0xc0 +'Zan ', # 0xc1 +'Ji ', # 0xc2 +'Yuan ', # 0xc3 +'Ji ', # 0xc4 +'Yin ', # 0xc5 +'Mi ', # 0xc6 +'Kou ', # 0xc7 +'Qing ', # 0xc8 +'Que ', # 0xc9 +'Zhen ', # 0xca +'Jian ', # 0xcb +'Fu ', # 0xcc +'Ning ', # 0xcd +'Bing ', # 0xce +'Huan ', # 0xcf +'Mei ', # 0xd0 +'Qin ', # 0xd1 +'Han ', # 0xd2 +'Yu ', # 0xd3 +'Shi ', # 0xd4 +'Ning ', # 0xd5 +'Qin ', # 0xd6 +'Ning ', # 0xd7 +'Zhi ', # 0xd8 +'Yu ', # 0xd9 +'Bao ', # 0xda +'Kuan ', # 0xdb +'Ning ', # 0xdc +'Qin ', # 0xdd +'Mo ', # 0xde +'Cha ', # 0xdf +'Ju ', # 0xe0 +'Gua ', # 0xe1 +'Qin ', # 0xe2 +'Hu ', # 0xe3 +'Wu ', # 0xe4 +'Liao ', # 0xe5 +'Shi ', # 0xe6 +'Zhu ', # 0xe7 +'Zhai ', # 0xe8 +'Shen ', # 0xe9 +'Wei ', # 0xea +'Xie ', # 0xeb +'Kuan ', # 0xec +'Hui ', # 0xed +'Liao ', # 0xee +'Jun ', # 0xef +'Huan ', # 0xf0 +'Yi ', # 0xf1 +'Yi ', # 0xf2 +'Bao ', # 0xf3 +'Qin ', # 0xf4 +'Chong ', # 0xf5 +'Bao ', # 0xf6 +'Feng ', # 0xf7 +'Cun ', # 0xf8 +'Dui ', # 0xf9 +'Si ', # 0xfa +'Xun ', # 0xfb +'Dao ', # 0xfc +'Lu ', # 0xfd +'Dui ', # 0xfe +'Shou ', # 0xff +) diff --git a/libs/unidecode/x05c.py b/libs/unidecode/x05c.py new file mode 100644 index 00000000..62957e87 --- /dev/null +++ b/libs/unidecode/x05c.py @@ -0,0 +1,258 @@ +data = ( +'Po ', # 0x00 +'Feng ', # 0x01 +'Zhuan ', # 0x02 +'Fu ', # 0x03 +'She ', # 0x04 +'Ke ', # 0x05 +'Jiang ', # 0x06 +'Jiang ', # 0x07 +'Zhuan ', # 0x08 +'Wei ', # 0x09 +'Zun ', # 0x0a +'Xun ', # 0x0b +'Shu ', # 0x0c +'Dui ', # 0x0d +'Dao ', # 0x0e +'Xiao ', # 0x0f +'Ji ', # 0x10 +'Shao ', # 0x11 +'Er ', # 0x12 +'Er ', # 0x13 +'Er ', # 0x14 +'Ga ', # 0x15 +'Jian ', # 0x16 +'Shu ', # 0x17 +'Chen ', # 0x18 +'Shang ', # 0x19 +'Shang ', # 0x1a +'Mo ', # 0x1b +'Ga ', # 0x1c +'Chang ', # 0x1d +'Liao ', # 0x1e +'Xian ', # 0x1f +'Xian ', # 0x20 +'[?] ', # 0x21 +'Wang ', # 0x22 +'Wang ', # 0x23 +'You ', # 0x24 +'Liao ', # 0x25 +'Liao ', # 0x26 +'Yao ', # 0x27 +'Mang ', # 0x28 +'Wang ', # 0x29 +'Wang ', # 0x2a +'Wang ', # 0x2b +'Ga ', # 0x2c +'Yao ', # 0x2d +'Duo ', # 0x2e +'Kui ', # 0x2f +'Zhong ', # 0x30 +'Jiu ', # 0x31 +'Gan ', # 0x32 +'Gu ', # 0x33 +'Gan ', # 0x34 +'Tui ', # 0x35 +'Gan ', # 0x36 +'Gan ', # 0x37 +'Shi ', # 0x38 +'Yin ', # 0x39 +'Chi ', # 0x3a +'Kao ', # 0x3b +'Ni ', # 0x3c +'Jin ', # 0x3d +'Wei ', # 0x3e +'Niao ', # 0x3f +'Ju ', # 0x40 +'Pi ', # 0x41 +'Ceng ', # 0x42 +'Xi ', # 0x43 +'Bi ', # 0x44 +'Ju ', # 0x45 +'Jie ', # 0x46 +'Tian ', # 0x47 +'Qu ', # 0x48 +'Ti ', # 0x49 +'Jie ', # 0x4a +'Wu ', # 0x4b +'Diao ', # 0x4c +'Shi ', # 0x4d +'Shi ', # 0x4e +'Ping ', # 0x4f +'Ji ', # 0x50 +'Xie ', # 0x51 +'Chen ', # 0x52 +'Xi ', # 0x53 +'Ni ', # 0x54 +'Zhan ', # 0x55 +'Xi ', # 0x56 +'[?] ', # 0x57 +'Man ', # 0x58 +'E ', # 0x59 +'Lou ', # 0x5a +'Ping ', # 0x5b +'Ti ', # 0x5c +'Fei ', # 0x5d +'Shu ', # 0x5e +'Xie ', # 0x5f +'Tu ', # 0x60 +'Lu ', # 0x61 +'Lu ', # 0x62 +'Xi ', # 0x63 +'Ceng ', # 0x64 +'Lu ', # 0x65 +'Ju ', # 0x66 +'Xie ', # 0x67 +'Ju ', # 0x68 +'Jue ', # 0x69 +'Liao ', # 0x6a +'Jue ', # 0x6b +'Shu ', # 0x6c +'Xi ', # 0x6d +'Che ', # 0x6e +'Tun ', # 0x6f +'Ni ', # 0x70 +'Shan ', # 0x71 +'[?] ', # 0x72 +'Xian ', # 0x73 +'Li ', # 0x74 +'Xue ', # 0x75 +'Nata ', # 0x76 +'[?] ', # 0x77 +'Long ', # 0x78 +'Yi ', # 0x79 +'Qi ', # 0x7a +'Ren ', # 0x7b +'Wu ', # 0x7c +'Han ', # 0x7d +'Shen ', # 0x7e +'Yu ', # 0x7f +'Chu ', # 0x80 +'Sui ', # 0x81 +'Qi ', # 0x82 +'[?] ', # 0x83 +'Yue ', # 0x84 +'Ban ', # 0x85 +'Yao ', # 0x86 +'Ang ', # 0x87 +'Ya ', # 0x88 +'Wu ', # 0x89 +'Jie ', # 0x8a +'E ', # 0x8b +'Ji ', # 0x8c +'Qian ', # 0x8d +'Fen ', # 0x8e +'Yuan ', # 0x8f +'Qi ', # 0x90 +'Cen ', # 0x91 +'Qian ', # 0x92 +'Qi ', # 0x93 +'Cha ', # 0x94 +'Jie ', # 0x95 +'Qu ', # 0x96 +'Gang ', # 0x97 +'Xian ', # 0x98 +'Ao ', # 0x99 +'Lan ', # 0x9a +'Dao ', # 0x9b +'Ba ', # 0x9c +'Zuo ', # 0x9d +'Zuo ', # 0x9e +'Yang ', # 0x9f +'Ju ', # 0xa0 +'Gang ', # 0xa1 +'Ke ', # 0xa2 +'Gou ', # 0xa3 +'Xue ', # 0xa4 +'Bei ', # 0xa5 +'Li ', # 0xa6 +'Tiao ', # 0xa7 +'Ju ', # 0xa8 +'Yan ', # 0xa9 +'Fu ', # 0xaa +'Xiu ', # 0xab +'Jia ', # 0xac +'Ling ', # 0xad +'Tuo ', # 0xae +'Pei ', # 0xaf +'You ', # 0xb0 +'Dai ', # 0xb1 +'Kuang ', # 0xb2 +'Yue ', # 0xb3 +'Qu ', # 0xb4 +'Hu ', # 0xb5 +'Po ', # 0xb6 +'Min ', # 0xb7 +'An ', # 0xb8 +'Tiao ', # 0xb9 +'Ling ', # 0xba +'Chi ', # 0xbb +'Yuri ', # 0xbc +'Dong ', # 0xbd +'Cem ', # 0xbe +'Kui ', # 0xbf +'Xiu ', # 0xc0 +'Mao ', # 0xc1 +'Tong ', # 0xc2 +'Xue ', # 0xc3 +'Yi ', # 0xc4 +'Kura ', # 0xc5 +'He ', # 0xc6 +'Ke ', # 0xc7 +'Luo ', # 0xc8 +'E ', # 0xc9 +'Fu ', # 0xca +'Xun ', # 0xcb +'Die ', # 0xcc +'Lu ', # 0xcd +'An ', # 0xce +'Er ', # 0xcf +'Gai ', # 0xd0 +'Quan ', # 0xd1 +'Tong ', # 0xd2 +'Yi ', # 0xd3 +'Mu ', # 0xd4 +'Shi ', # 0xd5 +'An ', # 0xd6 +'Wei ', # 0xd7 +'Hu ', # 0xd8 +'Zhi ', # 0xd9 +'Mi ', # 0xda +'Li ', # 0xdb +'Ji ', # 0xdc +'Tong ', # 0xdd +'Wei ', # 0xde +'You ', # 0xdf +'Sang ', # 0xe0 +'Xia ', # 0xe1 +'Li ', # 0xe2 +'Yao ', # 0xe3 +'Jiao ', # 0xe4 +'Zheng ', # 0xe5 +'Luan ', # 0xe6 +'Jiao ', # 0xe7 +'E ', # 0xe8 +'E ', # 0xe9 +'Yu ', # 0xea +'Ye ', # 0xeb +'Bu ', # 0xec +'Qiao ', # 0xed +'Qun ', # 0xee +'Feng ', # 0xef +'Feng ', # 0xf0 +'Nao ', # 0xf1 +'Li ', # 0xf2 +'You ', # 0xf3 +'Xian ', # 0xf4 +'Hong ', # 0xf5 +'Dao ', # 0xf6 +'Shen ', # 0xf7 +'Cheng ', # 0xf8 +'Tu ', # 0xf9 +'Geng ', # 0xfa +'Jun ', # 0xfb +'Hao ', # 0xfc +'Xia ', # 0xfd +'Yin ', # 0xfe +'Yu ', # 0xff +) diff --git a/libs/unidecode/x05d.py b/libs/unidecode/x05d.py new file mode 100644 index 00000000..c85032aa --- /dev/null +++ b/libs/unidecode/x05d.py @@ -0,0 +1,258 @@ +data = ( +'Lang ', # 0x00 +'Kan ', # 0x01 +'Lao ', # 0x02 +'Lai ', # 0x03 +'Xian ', # 0x04 +'Que ', # 0x05 +'Kong ', # 0x06 +'Chong ', # 0x07 +'Chong ', # 0x08 +'Ta ', # 0x09 +'Lin ', # 0x0a +'Hua ', # 0x0b +'Ju ', # 0x0c +'Lai ', # 0x0d +'Qi ', # 0x0e +'Min ', # 0x0f +'Kun ', # 0x10 +'Kun ', # 0x11 +'Zu ', # 0x12 +'Gu ', # 0x13 +'Cui ', # 0x14 +'Ya ', # 0x15 +'Ya ', # 0x16 +'Gang ', # 0x17 +'Lun ', # 0x18 +'Lun ', # 0x19 +'Leng ', # 0x1a +'Jue ', # 0x1b +'Duo ', # 0x1c +'Zheng ', # 0x1d +'Guo ', # 0x1e +'Yin ', # 0x1f +'Dong ', # 0x20 +'Han ', # 0x21 +'Zheng ', # 0x22 +'Wei ', # 0x23 +'Yao ', # 0x24 +'Pi ', # 0x25 +'Yan ', # 0x26 +'Song ', # 0x27 +'Jie ', # 0x28 +'Beng ', # 0x29 +'Zu ', # 0x2a +'Jue ', # 0x2b +'Dong ', # 0x2c +'Zhan ', # 0x2d +'Gu ', # 0x2e +'Yin ', # 0x2f +'[?] ', # 0x30 +'Ze ', # 0x31 +'Huang ', # 0x32 +'Yu ', # 0x33 +'Wei ', # 0x34 +'Yang ', # 0x35 +'Feng ', # 0x36 +'Qiu ', # 0x37 +'Dun ', # 0x38 +'Ti ', # 0x39 +'Yi ', # 0x3a +'Zhi ', # 0x3b +'Shi ', # 0x3c +'Zai ', # 0x3d +'Yao ', # 0x3e +'E ', # 0x3f +'Zhu ', # 0x40 +'Kan ', # 0x41 +'Lu ', # 0x42 +'Yan ', # 0x43 +'Mei ', # 0x44 +'Gan ', # 0x45 +'Ji ', # 0x46 +'Ji ', # 0x47 +'Huan ', # 0x48 +'Ting ', # 0x49 +'Sheng ', # 0x4a +'Mei ', # 0x4b +'Qian ', # 0x4c +'Wu ', # 0x4d +'Yu ', # 0x4e +'Zong ', # 0x4f +'Lan ', # 0x50 +'Jue ', # 0x51 +'Yan ', # 0x52 +'Yan ', # 0x53 +'Wei ', # 0x54 +'Zong ', # 0x55 +'Cha ', # 0x56 +'Sui ', # 0x57 +'Rong ', # 0x58 +'Yamashina ', # 0x59 +'Qin ', # 0x5a +'Yu ', # 0x5b +'Kewashii ', # 0x5c +'Lou ', # 0x5d +'Tu ', # 0x5e +'Dui ', # 0x5f +'Xi ', # 0x60 +'Weng ', # 0x61 +'Cang ', # 0x62 +'Dang ', # 0x63 +'Hong ', # 0x64 +'Jie ', # 0x65 +'Ai ', # 0x66 +'Liu ', # 0x67 +'Wu ', # 0x68 +'Song ', # 0x69 +'Qiao ', # 0x6a +'Zi ', # 0x6b +'Wei ', # 0x6c +'Beng ', # 0x6d +'Dian ', # 0x6e +'Cuo ', # 0x6f +'Qian ', # 0x70 +'Yong ', # 0x71 +'Nie ', # 0x72 +'Cuo ', # 0x73 +'Ji ', # 0x74 +'[?] ', # 0x75 +'Tao ', # 0x76 +'Song ', # 0x77 +'Zong ', # 0x78 +'Jiang ', # 0x79 +'Liao ', # 0x7a +'Kang ', # 0x7b +'Chan ', # 0x7c +'Die ', # 0x7d +'Cen ', # 0x7e +'Ding ', # 0x7f +'Tu ', # 0x80 +'Lou ', # 0x81 +'Zhang ', # 0x82 +'Zhan ', # 0x83 +'Zhan ', # 0x84 +'Ao ', # 0x85 +'Cao ', # 0x86 +'Qu ', # 0x87 +'Qiang ', # 0x88 +'Zui ', # 0x89 +'Zui ', # 0x8a +'Dao ', # 0x8b +'Dao ', # 0x8c +'Xi ', # 0x8d +'Yu ', # 0x8e +'Bo ', # 0x8f +'Long ', # 0x90 +'Xiang ', # 0x91 +'Ceng ', # 0x92 +'Bo ', # 0x93 +'Qin ', # 0x94 +'Jiao ', # 0x95 +'Yan ', # 0x96 +'Lao ', # 0x97 +'Zhan ', # 0x98 +'Lin ', # 0x99 +'Liao ', # 0x9a +'Liao ', # 0x9b +'Jin ', # 0x9c +'Deng ', # 0x9d +'Duo ', # 0x9e +'Zun ', # 0x9f +'Jiao ', # 0xa0 +'Gui ', # 0xa1 +'Yao ', # 0xa2 +'Qiao ', # 0xa3 +'Yao ', # 0xa4 +'Jue ', # 0xa5 +'Zhan ', # 0xa6 +'Yi ', # 0xa7 +'Xue ', # 0xa8 +'Nao ', # 0xa9 +'Ye ', # 0xaa +'Ye ', # 0xab +'Yi ', # 0xac +'E ', # 0xad +'Xian ', # 0xae +'Ji ', # 0xaf +'Xie ', # 0xb0 +'Ke ', # 0xb1 +'Xi ', # 0xb2 +'Di ', # 0xb3 +'Ao ', # 0xb4 +'Zui ', # 0xb5 +'[?] ', # 0xb6 +'Ni ', # 0xb7 +'Rong ', # 0xb8 +'Dao ', # 0xb9 +'Ling ', # 0xba +'Za ', # 0xbb +'Yu ', # 0xbc +'Yue ', # 0xbd +'Yin ', # 0xbe +'[?] ', # 0xbf +'Jie ', # 0xc0 +'Li ', # 0xc1 +'Sui ', # 0xc2 +'Long ', # 0xc3 +'Long ', # 0xc4 +'Dian ', # 0xc5 +'Ying ', # 0xc6 +'Xi ', # 0xc7 +'Ju ', # 0xc8 +'Chan ', # 0xc9 +'Ying ', # 0xca +'Kui ', # 0xcb +'Yan ', # 0xcc +'Wei ', # 0xcd +'Nao ', # 0xce +'Quan ', # 0xcf +'Chao ', # 0xd0 +'Cuan ', # 0xd1 +'Luan ', # 0xd2 +'Dian ', # 0xd3 +'Dian ', # 0xd4 +'[?] ', # 0xd5 +'Yan ', # 0xd6 +'Yan ', # 0xd7 +'Yan ', # 0xd8 +'Nao ', # 0xd9 +'Yan ', # 0xda +'Chuan ', # 0xdb +'Gui ', # 0xdc +'Chuan ', # 0xdd +'Zhou ', # 0xde +'Huang ', # 0xdf +'Jing ', # 0xe0 +'Xun ', # 0xe1 +'Chao ', # 0xe2 +'Chao ', # 0xe3 +'Lie ', # 0xe4 +'Gong ', # 0xe5 +'Zuo ', # 0xe6 +'Qiao ', # 0xe7 +'Ju ', # 0xe8 +'Gong ', # 0xe9 +'Kek ', # 0xea +'Wu ', # 0xeb +'Pwu ', # 0xec +'Pwu ', # 0xed +'Chai ', # 0xee +'Qiu ', # 0xef +'Qiu ', # 0xf0 +'Ji ', # 0xf1 +'Yi ', # 0xf2 +'Si ', # 0xf3 +'Ba ', # 0xf4 +'Zhi ', # 0xf5 +'Zhao ', # 0xf6 +'Xiang ', # 0xf7 +'Yi ', # 0xf8 +'Jin ', # 0xf9 +'Xun ', # 0xfa +'Juan ', # 0xfb +'Phas ', # 0xfc +'Xun ', # 0xfd +'Jin ', # 0xfe +'Fu ', # 0xff +) diff --git a/libs/unidecode/x05e.py b/libs/unidecode/x05e.py new file mode 100644 index 00000000..af879280 --- /dev/null +++ b/libs/unidecode/x05e.py @@ -0,0 +1,258 @@ +data = ( +'Za ', # 0x00 +'Bi ', # 0x01 +'Shi ', # 0x02 +'Bu ', # 0x03 +'Ding ', # 0x04 +'Shuai ', # 0x05 +'Fan ', # 0x06 +'Nie ', # 0x07 +'Shi ', # 0x08 +'Fen ', # 0x09 +'Pa ', # 0x0a +'Zhi ', # 0x0b +'Xi ', # 0x0c +'Hu ', # 0x0d +'Dan ', # 0x0e +'Wei ', # 0x0f +'Zhang ', # 0x10 +'Tang ', # 0x11 +'Dai ', # 0x12 +'Ma ', # 0x13 +'Pei ', # 0x14 +'Pa ', # 0x15 +'Tie ', # 0x16 +'Fu ', # 0x17 +'Lian ', # 0x18 +'Zhi ', # 0x19 +'Zhou ', # 0x1a +'Bo ', # 0x1b +'Zhi ', # 0x1c +'Di ', # 0x1d +'Mo ', # 0x1e +'Yi ', # 0x1f +'Yi ', # 0x20 +'Ping ', # 0x21 +'Qia ', # 0x22 +'Juan ', # 0x23 +'Ru ', # 0x24 +'Shuai ', # 0x25 +'Dai ', # 0x26 +'Zheng ', # 0x27 +'Shui ', # 0x28 +'Qiao ', # 0x29 +'Zhen ', # 0x2a +'Shi ', # 0x2b +'Qun ', # 0x2c +'Xi ', # 0x2d +'Bang ', # 0x2e +'Dai ', # 0x2f +'Gui ', # 0x30 +'Chou ', # 0x31 +'Ping ', # 0x32 +'Zhang ', # 0x33 +'Sha ', # 0x34 +'Wan ', # 0x35 +'Dai ', # 0x36 +'Wei ', # 0x37 +'Chang ', # 0x38 +'Sha ', # 0x39 +'Qi ', # 0x3a +'Ze ', # 0x3b +'Guo ', # 0x3c +'Mao ', # 0x3d +'Du ', # 0x3e +'Hou ', # 0x3f +'Zheng ', # 0x40 +'Xu ', # 0x41 +'Mi ', # 0x42 +'Wei ', # 0x43 +'Wo ', # 0x44 +'Fu ', # 0x45 +'Yi ', # 0x46 +'Bang ', # 0x47 +'Ping ', # 0x48 +'Tazuna ', # 0x49 +'Gong ', # 0x4a +'Pan ', # 0x4b +'Huang ', # 0x4c +'Dao ', # 0x4d +'Mi ', # 0x4e +'Jia ', # 0x4f +'Teng ', # 0x50 +'Hui ', # 0x51 +'Zhong ', # 0x52 +'Shan ', # 0x53 +'Man ', # 0x54 +'Mu ', # 0x55 +'Biao ', # 0x56 +'Guo ', # 0x57 +'Ze ', # 0x58 +'Mu ', # 0x59 +'Bang ', # 0x5a +'Zhang ', # 0x5b +'Jiong ', # 0x5c +'Chan ', # 0x5d +'Fu ', # 0x5e +'Zhi ', # 0x5f +'Hu ', # 0x60 +'Fan ', # 0x61 +'Chuang ', # 0x62 +'Bi ', # 0x63 +'Hei ', # 0x64 +'[?] ', # 0x65 +'Mi ', # 0x66 +'Qiao ', # 0x67 +'Chan ', # 0x68 +'Fen ', # 0x69 +'Meng ', # 0x6a +'Bang ', # 0x6b +'Chou ', # 0x6c +'Mie ', # 0x6d +'Chu ', # 0x6e +'Jie ', # 0x6f +'Xian ', # 0x70 +'Lan ', # 0x71 +'Gan ', # 0x72 +'Ping ', # 0x73 +'Nian ', # 0x74 +'Qian ', # 0x75 +'Bing ', # 0x76 +'Bing ', # 0x77 +'Xing ', # 0x78 +'Gan ', # 0x79 +'Yao ', # 0x7a +'Huan ', # 0x7b +'You ', # 0x7c +'You ', # 0x7d +'Ji ', # 0x7e +'Yan ', # 0x7f +'Pi ', # 0x80 +'Ting ', # 0x81 +'Ze ', # 0x82 +'Guang ', # 0x83 +'Zhuang ', # 0x84 +'Mo ', # 0x85 +'Qing ', # 0x86 +'Bi ', # 0x87 +'Qin ', # 0x88 +'Dun ', # 0x89 +'Chuang ', # 0x8a +'Gui ', # 0x8b +'Ya ', # 0x8c +'Bai ', # 0x8d +'Jie ', # 0x8e +'Xu ', # 0x8f +'Lu ', # 0x90 +'Wu ', # 0x91 +'[?] ', # 0x92 +'Ku ', # 0x93 +'Ying ', # 0x94 +'Di ', # 0x95 +'Pao ', # 0x96 +'Dian ', # 0x97 +'Ya ', # 0x98 +'Miao ', # 0x99 +'Geng ', # 0x9a +'Ci ', # 0x9b +'Fu ', # 0x9c +'Tong ', # 0x9d +'Pang ', # 0x9e +'Fei ', # 0x9f +'Xiang ', # 0xa0 +'Yi ', # 0xa1 +'Zhi ', # 0xa2 +'Tiao ', # 0xa3 +'Zhi ', # 0xa4 +'Xiu ', # 0xa5 +'Du ', # 0xa6 +'Zuo ', # 0xa7 +'Xiao ', # 0xa8 +'Tu ', # 0xa9 +'Gui ', # 0xaa +'Ku ', # 0xab +'Pang ', # 0xac +'Ting ', # 0xad +'You ', # 0xae +'Bu ', # 0xaf +'Ding ', # 0xb0 +'Cheng ', # 0xb1 +'Lai ', # 0xb2 +'Bei ', # 0xb3 +'Ji ', # 0xb4 +'An ', # 0xb5 +'Shu ', # 0xb6 +'Kang ', # 0xb7 +'Yong ', # 0xb8 +'Tuo ', # 0xb9 +'Song ', # 0xba +'Shu ', # 0xbb +'Qing ', # 0xbc +'Yu ', # 0xbd +'Yu ', # 0xbe +'Miao ', # 0xbf +'Sou ', # 0xc0 +'Ce ', # 0xc1 +'Xiang ', # 0xc2 +'Fei ', # 0xc3 +'Jiu ', # 0xc4 +'He ', # 0xc5 +'Hui ', # 0xc6 +'Liu ', # 0xc7 +'Sha ', # 0xc8 +'Lian ', # 0xc9 +'Lang ', # 0xca +'Sou ', # 0xcb +'Jian ', # 0xcc +'Pou ', # 0xcd +'Qing ', # 0xce +'Jiu ', # 0xcf +'Jiu ', # 0xd0 +'Qin ', # 0xd1 +'Ao ', # 0xd2 +'Kuo ', # 0xd3 +'Lou ', # 0xd4 +'Yin ', # 0xd5 +'Liao ', # 0xd6 +'Dai ', # 0xd7 +'Lu ', # 0xd8 +'Yi ', # 0xd9 +'Chu ', # 0xda +'Chan ', # 0xdb +'Tu ', # 0xdc +'Si ', # 0xdd +'Xin ', # 0xde +'Miao ', # 0xdf +'Chang ', # 0xe0 +'Wu ', # 0xe1 +'Fei ', # 0xe2 +'Guang ', # 0xe3 +'Koc ', # 0xe4 +'Kuai ', # 0xe5 +'Bi ', # 0xe6 +'Qiang ', # 0xe7 +'Xie ', # 0xe8 +'Lin ', # 0xe9 +'Lin ', # 0xea +'Liao ', # 0xeb +'Lu ', # 0xec +'[?] ', # 0xed +'Ying ', # 0xee +'Xian ', # 0xef +'Ting ', # 0xf0 +'Yong ', # 0xf1 +'Li ', # 0xf2 +'Ting ', # 0xf3 +'Yin ', # 0xf4 +'Xun ', # 0xf5 +'Yan ', # 0xf6 +'Ting ', # 0xf7 +'Di ', # 0xf8 +'Po ', # 0xf9 +'Jian ', # 0xfa +'Hui ', # 0xfb +'Nai ', # 0xfc +'Hui ', # 0xfd +'Gong ', # 0xfe +'Nian ', # 0xff +) diff --git a/libs/unidecode/x05f.py b/libs/unidecode/x05f.py new file mode 100644 index 00000000..032eab89 --- /dev/null +++ b/libs/unidecode/x05f.py @@ -0,0 +1,258 @@ +data = ( +'Kai ', # 0x00 +'Bian ', # 0x01 +'Yi ', # 0x02 +'Qi ', # 0x03 +'Nong ', # 0x04 +'Fen ', # 0x05 +'Ju ', # 0x06 +'Yan ', # 0x07 +'Yi ', # 0x08 +'Zang ', # 0x09 +'Bi ', # 0x0a +'Yi ', # 0x0b +'Yi ', # 0x0c +'Er ', # 0x0d +'San ', # 0x0e +'Shi ', # 0x0f +'Er ', # 0x10 +'Shi ', # 0x11 +'Shi ', # 0x12 +'Gong ', # 0x13 +'Diao ', # 0x14 +'Yin ', # 0x15 +'Hu ', # 0x16 +'Fu ', # 0x17 +'Hong ', # 0x18 +'Wu ', # 0x19 +'Tui ', # 0x1a +'Chi ', # 0x1b +'Jiang ', # 0x1c +'Ba ', # 0x1d +'Shen ', # 0x1e +'Di ', # 0x1f +'Zhang ', # 0x20 +'Jue ', # 0x21 +'Tao ', # 0x22 +'Fu ', # 0x23 +'Di ', # 0x24 +'Mi ', # 0x25 +'Xian ', # 0x26 +'Hu ', # 0x27 +'Chao ', # 0x28 +'Nu ', # 0x29 +'Jing ', # 0x2a +'Zhen ', # 0x2b +'Yi ', # 0x2c +'Mi ', # 0x2d +'Quan ', # 0x2e +'Wan ', # 0x2f +'Shao ', # 0x30 +'Ruo ', # 0x31 +'Xuan ', # 0x32 +'Jing ', # 0x33 +'Dun ', # 0x34 +'Zhang ', # 0x35 +'Jiang ', # 0x36 +'Qiang ', # 0x37 +'Peng ', # 0x38 +'Dan ', # 0x39 +'Qiang ', # 0x3a +'Bi ', # 0x3b +'Bi ', # 0x3c +'She ', # 0x3d +'Dan ', # 0x3e +'Jian ', # 0x3f +'Gou ', # 0x40 +'Sei ', # 0x41 +'Fa ', # 0x42 +'Bi ', # 0x43 +'Kou ', # 0x44 +'Nagi ', # 0x45 +'Bie ', # 0x46 +'Xiao ', # 0x47 +'Dan ', # 0x48 +'Kuo ', # 0x49 +'Qiang ', # 0x4a +'Hong ', # 0x4b +'Mi ', # 0x4c +'Kuo ', # 0x4d +'Wan ', # 0x4e +'Jue ', # 0x4f +'Ji ', # 0x50 +'Ji ', # 0x51 +'Gui ', # 0x52 +'Dang ', # 0x53 +'Lu ', # 0x54 +'Lu ', # 0x55 +'Tuan ', # 0x56 +'Hui ', # 0x57 +'Zhi ', # 0x58 +'Hui ', # 0x59 +'Hui ', # 0x5a +'Yi ', # 0x5b +'Yi ', # 0x5c +'Yi ', # 0x5d +'Yi ', # 0x5e +'Huo ', # 0x5f +'Huo ', # 0x60 +'Shan ', # 0x61 +'Xing ', # 0x62 +'Wen ', # 0x63 +'Tong ', # 0x64 +'Yan ', # 0x65 +'Yan ', # 0x66 +'Yu ', # 0x67 +'Chi ', # 0x68 +'Cai ', # 0x69 +'Biao ', # 0x6a +'Diao ', # 0x6b +'Bin ', # 0x6c +'Peng ', # 0x6d +'Yong ', # 0x6e +'Piao ', # 0x6f +'Zhang ', # 0x70 +'Ying ', # 0x71 +'Chi ', # 0x72 +'Chi ', # 0x73 +'Zhuo ', # 0x74 +'Tuo ', # 0x75 +'Ji ', # 0x76 +'Pang ', # 0x77 +'Zhong ', # 0x78 +'Yi ', # 0x79 +'Wang ', # 0x7a +'Che ', # 0x7b +'Bi ', # 0x7c +'Chi ', # 0x7d +'Ling ', # 0x7e +'Fu ', # 0x7f +'Wang ', # 0x80 +'Zheng ', # 0x81 +'Cu ', # 0x82 +'Wang ', # 0x83 +'Jing ', # 0x84 +'Dai ', # 0x85 +'Xi ', # 0x86 +'Xun ', # 0x87 +'Hen ', # 0x88 +'Yang ', # 0x89 +'Huai ', # 0x8a +'Lu ', # 0x8b +'Hou ', # 0x8c +'Wa ', # 0x8d +'Cheng ', # 0x8e +'Zhi ', # 0x8f +'Xu ', # 0x90 +'Jing ', # 0x91 +'Tu ', # 0x92 +'Cong ', # 0x93 +'[?] ', # 0x94 +'Lai ', # 0x95 +'Cong ', # 0x96 +'De ', # 0x97 +'Pai ', # 0x98 +'Xi ', # 0x99 +'[?] ', # 0x9a +'Qi ', # 0x9b +'Chang ', # 0x9c +'Zhi ', # 0x9d +'Cong ', # 0x9e +'Zhou ', # 0x9f +'Lai ', # 0xa0 +'Yu ', # 0xa1 +'Xie ', # 0xa2 +'Jie ', # 0xa3 +'Jian ', # 0xa4 +'Chi ', # 0xa5 +'Jia ', # 0xa6 +'Bian ', # 0xa7 +'Huang ', # 0xa8 +'Fu ', # 0xa9 +'Xun ', # 0xaa +'Wei ', # 0xab +'Pang ', # 0xac +'Yao ', # 0xad +'Wei ', # 0xae +'Xi ', # 0xaf +'Zheng ', # 0xb0 +'Piao ', # 0xb1 +'Chi ', # 0xb2 +'De ', # 0xb3 +'Zheng ', # 0xb4 +'Zheng ', # 0xb5 +'Bie ', # 0xb6 +'De ', # 0xb7 +'Chong ', # 0xb8 +'Che ', # 0xb9 +'Jiao ', # 0xba +'Wei ', # 0xbb +'Jiao ', # 0xbc +'Hui ', # 0xbd +'Mei ', # 0xbe +'Long ', # 0xbf +'Xiang ', # 0xc0 +'Bao ', # 0xc1 +'Qu ', # 0xc2 +'Xin ', # 0xc3 +'Shu ', # 0xc4 +'Bi ', # 0xc5 +'Yi ', # 0xc6 +'Le ', # 0xc7 +'Ren ', # 0xc8 +'Dao ', # 0xc9 +'Ding ', # 0xca +'Gai ', # 0xcb +'Ji ', # 0xcc +'Ren ', # 0xcd +'Ren ', # 0xce +'Chan ', # 0xcf +'Tan ', # 0xd0 +'Te ', # 0xd1 +'Te ', # 0xd2 +'Gan ', # 0xd3 +'Qi ', # 0xd4 +'Shi ', # 0xd5 +'Cun ', # 0xd6 +'Zhi ', # 0xd7 +'Wang ', # 0xd8 +'Mang ', # 0xd9 +'Xi ', # 0xda +'Fan ', # 0xdb +'Ying ', # 0xdc +'Tian ', # 0xdd +'Min ', # 0xde +'Min ', # 0xdf +'Zhong ', # 0xe0 +'Chong ', # 0xe1 +'Wu ', # 0xe2 +'Ji ', # 0xe3 +'Wu ', # 0xe4 +'Xi ', # 0xe5 +'Ye ', # 0xe6 +'You ', # 0xe7 +'Wan ', # 0xe8 +'Cong ', # 0xe9 +'Zhong ', # 0xea +'Kuai ', # 0xeb +'Yu ', # 0xec +'Bian ', # 0xed +'Zhi ', # 0xee +'Qi ', # 0xef +'Cui ', # 0xf0 +'Chen ', # 0xf1 +'Tai ', # 0xf2 +'Tun ', # 0xf3 +'Qian ', # 0xf4 +'Nian ', # 0xf5 +'Hun ', # 0xf6 +'Xiong ', # 0xf7 +'Niu ', # 0xf8 +'Wang ', # 0xf9 +'Xian ', # 0xfa +'Xin ', # 0xfb +'Kang ', # 0xfc +'Hu ', # 0xfd +'Kai ', # 0xfe +'Fen ', # 0xff +) diff --git a/libs/unidecode/x060.py b/libs/unidecode/x060.py new file mode 100644 index 00000000..ad3728f8 --- /dev/null +++ b/libs/unidecode/x060.py @@ -0,0 +1,258 @@ +data = ( +'Huai ', # 0x00 +'Tai ', # 0x01 +'Song ', # 0x02 +'Wu ', # 0x03 +'Ou ', # 0x04 +'Chang ', # 0x05 +'Chuang ', # 0x06 +'Ju ', # 0x07 +'Yi ', # 0x08 +'Bao ', # 0x09 +'Chao ', # 0x0a +'Min ', # 0x0b +'Pei ', # 0x0c +'Zuo ', # 0x0d +'Zen ', # 0x0e +'Yang ', # 0x0f +'Kou ', # 0x10 +'Ban ', # 0x11 +'Nu ', # 0x12 +'Nao ', # 0x13 +'Zheng ', # 0x14 +'Pa ', # 0x15 +'Bu ', # 0x16 +'Tie ', # 0x17 +'Gu ', # 0x18 +'Hu ', # 0x19 +'Ju ', # 0x1a +'Da ', # 0x1b +'Lian ', # 0x1c +'Si ', # 0x1d +'Chou ', # 0x1e +'Di ', # 0x1f +'Dai ', # 0x20 +'Yi ', # 0x21 +'Tu ', # 0x22 +'You ', # 0x23 +'Fu ', # 0x24 +'Ji ', # 0x25 +'Peng ', # 0x26 +'Xing ', # 0x27 +'Yuan ', # 0x28 +'Ni ', # 0x29 +'Guai ', # 0x2a +'Fu ', # 0x2b +'Xi ', # 0x2c +'Bi ', # 0x2d +'You ', # 0x2e +'Qie ', # 0x2f +'Xuan ', # 0x30 +'Cong ', # 0x31 +'Bing ', # 0x32 +'Huang ', # 0x33 +'Xu ', # 0x34 +'Chu ', # 0x35 +'Pi ', # 0x36 +'Xi ', # 0x37 +'Xi ', # 0x38 +'Tan ', # 0x39 +'Koraeru ', # 0x3a +'Zong ', # 0x3b +'Dui ', # 0x3c +'[?] ', # 0x3d +'Ki ', # 0x3e +'Yi ', # 0x3f +'Chi ', # 0x40 +'Ren ', # 0x41 +'Xun ', # 0x42 +'Shi ', # 0x43 +'Xi ', # 0x44 +'Lao ', # 0x45 +'Heng ', # 0x46 +'Kuang ', # 0x47 +'Mu ', # 0x48 +'Zhi ', # 0x49 +'Xie ', # 0x4a +'Lian ', # 0x4b +'Tiao ', # 0x4c +'Huang ', # 0x4d +'Die ', # 0x4e +'Hao ', # 0x4f +'Kong ', # 0x50 +'Gui ', # 0x51 +'Heng ', # 0x52 +'Xi ', # 0x53 +'Xiao ', # 0x54 +'Shu ', # 0x55 +'S ', # 0x56 +'Kua ', # 0x57 +'Qiu ', # 0x58 +'Yang ', # 0x59 +'Hui ', # 0x5a +'Hui ', # 0x5b +'Chi ', # 0x5c +'Jia ', # 0x5d +'Yi ', # 0x5e +'Xiong ', # 0x5f +'Guai ', # 0x60 +'Lin ', # 0x61 +'Hui ', # 0x62 +'Zi ', # 0x63 +'Xu ', # 0x64 +'Chi ', # 0x65 +'Xiang ', # 0x66 +'Nu ', # 0x67 +'Hen ', # 0x68 +'En ', # 0x69 +'Ke ', # 0x6a +'Tong ', # 0x6b +'Tian ', # 0x6c +'Gong ', # 0x6d +'Quan ', # 0x6e +'Xi ', # 0x6f +'Qia ', # 0x70 +'Yue ', # 0x71 +'Peng ', # 0x72 +'Ken ', # 0x73 +'De ', # 0x74 +'Hui ', # 0x75 +'E ', # 0x76 +'Kyuu ', # 0x77 +'Tong ', # 0x78 +'Yan ', # 0x79 +'Kai ', # 0x7a +'Ce ', # 0x7b +'Nao ', # 0x7c +'Yun ', # 0x7d +'Mang ', # 0x7e +'Yong ', # 0x7f +'Yong ', # 0x80 +'Yuan ', # 0x81 +'Pi ', # 0x82 +'Kun ', # 0x83 +'Qiao ', # 0x84 +'Yue ', # 0x85 +'Yu ', # 0x86 +'Yu ', # 0x87 +'Jie ', # 0x88 +'Xi ', # 0x89 +'Zhe ', # 0x8a +'Lin ', # 0x8b +'Ti ', # 0x8c +'Han ', # 0x8d +'Hao ', # 0x8e +'Qie ', # 0x8f +'Ti ', # 0x90 +'Bu ', # 0x91 +'Yi ', # 0x92 +'Qian ', # 0x93 +'Hui ', # 0x94 +'Xi ', # 0x95 +'Bei ', # 0x96 +'Man ', # 0x97 +'Yi ', # 0x98 +'Heng ', # 0x99 +'Song ', # 0x9a +'Quan ', # 0x9b +'Cheng ', # 0x9c +'Hui ', # 0x9d +'Wu ', # 0x9e +'Wu ', # 0x9f +'You ', # 0xa0 +'Li ', # 0xa1 +'Liang ', # 0xa2 +'Huan ', # 0xa3 +'Cong ', # 0xa4 +'Yi ', # 0xa5 +'Yue ', # 0xa6 +'Li ', # 0xa7 +'Nin ', # 0xa8 +'Nao ', # 0xa9 +'E ', # 0xaa +'Que ', # 0xab +'Xuan ', # 0xac +'Qian ', # 0xad +'Wu ', # 0xae +'Min ', # 0xaf +'Cong ', # 0xb0 +'Fei ', # 0xb1 +'Bei ', # 0xb2 +'Duo ', # 0xb3 +'Cui ', # 0xb4 +'Chang ', # 0xb5 +'Men ', # 0xb6 +'Li ', # 0xb7 +'Ji ', # 0xb8 +'Guan ', # 0xb9 +'Guan ', # 0xba +'Xing ', # 0xbb +'Dao ', # 0xbc +'Qi ', # 0xbd +'Kong ', # 0xbe +'Tian ', # 0xbf +'Lun ', # 0xc0 +'Xi ', # 0xc1 +'Kan ', # 0xc2 +'Kun ', # 0xc3 +'Ni ', # 0xc4 +'Qing ', # 0xc5 +'Chou ', # 0xc6 +'Dun ', # 0xc7 +'Guo ', # 0xc8 +'Chan ', # 0xc9 +'Liang ', # 0xca +'Wan ', # 0xcb +'Yuan ', # 0xcc +'Jin ', # 0xcd +'Ji ', # 0xce +'Lin ', # 0xcf +'Yu ', # 0xd0 +'Huo ', # 0xd1 +'He ', # 0xd2 +'Quan ', # 0xd3 +'Tan ', # 0xd4 +'Ti ', # 0xd5 +'Ti ', # 0xd6 +'Nie ', # 0xd7 +'Wang ', # 0xd8 +'Chuo ', # 0xd9 +'Bu ', # 0xda +'Hun ', # 0xdb +'Xi ', # 0xdc +'Tang ', # 0xdd +'Xin ', # 0xde +'Wei ', # 0xdf +'Hui ', # 0xe0 +'E ', # 0xe1 +'Rui ', # 0xe2 +'Zong ', # 0xe3 +'Jian ', # 0xe4 +'Yong ', # 0xe5 +'Dian ', # 0xe6 +'Ju ', # 0xe7 +'Can ', # 0xe8 +'Cheng ', # 0xe9 +'De ', # 0xea +'Bei ', # 0xeb +'Qie ', # 0xec +'Can ', # 0xed +'Dan ', # 0xee +'Guan ', # 0xef +'Duo ', # 0xf0 +'Nao ', # 0xf1 +'Yun ', # 0xf2 +'Xiang ', # 0xf3 +'Zhui ', # 0xf4 +'Die ', # 0xf5 +'Huang ', # 0xf6 +'Chun ', # 0xf7 +'Qiong ', # 0xf8 +'Re ', # 0xf9 +'Xing ', # 0xfa +'Ce ', # 0xfb +'Bian ', # 0xfc +'Hun ', # 0xfd +'Zong ', # 0xfe +'Ti ', # 0xff +) diff --git a/libs/unidecode/x061.py b/libs/unidecode/x061.py new file mode 100644 index 00000000..6e8ab80d --- /dev/null +++ b/libs/unidecode/x061.py @@ -0,0 +1,258 @@ +data = ( +'Qiao ', # 0x00 +'Chou ', # 0x01 +'Bei ', # 0x02 +'Xuan ', # 0x03 +'Wei ', # 0x04 +'Ge ', # 0x05 +'Qian ', # 0x06 +'Wei ', # 0x07 +'Yu ', # 0x08 +'Yu ', # 0x09 +'Bi ', # 0x0a +'Xuan ', # 0x0b +'Huan ', # 0x0c +'Min ', # 0x0d +'Bi ', # 0x0e +'Yi ', # 0x0f +'Mian ', # 0x10 +'Yong ', # 0x11 +'Kai ', # 0x12 +'Dang ', # 0x13 +'Yin ', # 0x14 +'E ', # 0x15 +'Chen ', # 0x16 +'Mou ', # 0x17 +'Ke ', # 0x18 +'Ke ', # 0x19 +'Yu ', # 0x1a +'Ai ', # 0x1b +'Qie ', # 0x1c +'Yan ', # 0x1d +'Nuo ', # 0x1e +'Gan ', # 0x1f +'Yun ', # 0x20 +'Zong ', # 0x21 +'Sai ', # 0x22 +'Leng ', # 0x23 +'Fen ', # 0x24 +'[?] ', # 0x25 +'Kui ', # 0x26 +'Kui ', # 0x27 +'Que ', # 0x28 +'Gong ', # 0x29 +'Yun ', # 0x2a +'Su ', # 0x2b +'Su ', # 0x2c +'Qi ', # 0x2d +'Yao ', # 0x2e +'Song ', # 0x2f +'Huang ', # 0x30 +'Ji ', # 0x31 +'Gu ', # 0x32 +'Ju ', # 0x33 +'Chuang ', # 0x34 +'Ni ', # 0x35 +'Xie ', # 0x36 +'Kai ', # 0x37 +'Zheng ', # 0x38 +'Yong ', # 0x39 +'Cao ', # 0x3a +'Sun ', # 0x3b +'Shen ', # 0x3c +'Bo ', # 0x3d +'Kai ', # 0x3e +'Yuan ', # 0x3f +'Xie ', # 0x40 +'Hun ', # 0x41 +'Yong ', # 0x42 +'Yang ', # 0x43 +'Li ', # 0x44 +'Sao ', # 0x45 +'Tao ', # 0x46 +'Yin ', # 0x47 +'Ci ', # 0x48 +'Xu ', # 0x49 +'Qian ', # 0x4a +'Tai ', # 0x4b +'Huang ', # 0x4c +'Yun ', # 0x4d +'Shen ', # 0x4e +'Ming ', # 0x4f +'[?] ', # 0x50 +'She ', # 0x51 +'Cong ', # 0x52 +'Piao ', # 0x53 +'Mo ', # 0x54 +'Mu ', # 0x55 +'Guo ', # 0x56 +'Chi ', # 0x57 +'Can ', # 0x58 +'Can ', # 0x59 +'Can ', # 0x5a +'Cui ', # 0x5b +'Min ', # 0x5c +'Te ', # 0x5d +'Zhang ', # 0x5e +'Tong ', # 0x5f +'Ao ', # 0x60 +'Shuang ', # 0x61 +'Man ', # 0x62 +'Guan ', # 0x63 +'Que ', # 0x64 +'Zao ', # 0x65 +'Jiu ', # 0x66 +'Hui ', # 0x67 +'Kai ', # 0x68 +'Lian ', # 0x69 +'Ou ', # 0x6a +'Song ', # 0x6b +'Jin ', # 0x6c +'Yin ', # 0x6d +'Lu ', # 0x6e +'Shang ', # 0x6f +'Wei ', # 0x70 +'Tuan ', # 0x71 +'Man ', # 0x72 +'Qian ', # 0x73 +'She ', # 0x74 +'Yong ', # 0x75 +'Qing ', # 0x76 +'Kang ', # 0x77 +'Di ', # 0x78 +'Zhi ', # 0x79 +'Lou ', # 0x7a +'Juan ', # 0x7b +'Qi ', # 0x7c +'Qi ', # 0x7d +'Yu ', # 0x7e +'Ping ', # 0x7f +'Liao ', # 0x80 +'Cong ', # 0x81 +'You ', # 0x82 +'Chong ', # 0x83 +'Zhi ', # 0x84 +'Tong ', # 0x85 +'Cheng ', # 0x86 +'Qi ', # 0x87 +'Qu ', # 0x88 +'Peng ', # 0x89 +'Bei ', # 0x8a +'Bie ', # 0x8b +'Chun ', # 0x8c +'Jiao ', # 0x8d +'Zeng ', # 0x8e +'Chi ', # 0x8f +'Lian ', # 0x90 +'Ping ', # 0x91 +'Kui ', # 0x92 +'Hui ', # 0x93 +'Qiao ', # 0x94 +'Cheng ', # 0x95 +'Yin ', # 0x96 +'Yin ', # 0x97 +'Xi ', # 0x98 +'Xi ', # 0x99 +'Dan ', # 0x9a +'Tan ', # 0x9b +'Duo ', # 0x9c +'Dui ', # 0x9d +'Dui ', # 0x9e +'Su ', # 0x9f +'Jue ', # 0xa0 +'Ce ', # 0xa1 +'Xiao ', # 0xa2 +'Fan ', # 0xa3 +'Fen ', # 0xa4 +'Lao ', # 0xa5 +'Lao ', # 0xa6 +'Chong ', # 0xa7 +'Han ', # 0xa8 +'Qi ', # 0xa9 +'Xian ', # 0xaa +'Min ', # 0xab +'Jing ', # 0xac +'Liao ', # 0xad +'Wu ', # 0xae +'Can ', # 0xaf +'Jue ', # 0xb0 +'Cu ', # 0xb1 +'Xian ', # 0xb2 +'Tan ', # 0xb3 +'Sheng ', # 0xb4 +'Pi ', # 0xb5 +'Yi ', # 0xb6 +'Chu ', # 0xb7 +'Xian ', # 0xb8 +'Nao ', # 0xb9 +'Dan ', # 0xba +'Tan ', # 0xbb +'Jing ', # 0xbc +'Song ', # 0xbd +'Han ', # 0xbe +'Jiao ', # 0xbf +'Wai ', # 0xc0 +'Huan ', # 0xc1 +'Dong ', # 0xc2 +'Qin ', # 0xc3 +'Qin ', # 0xc4 +'Qu ', # 0xc5 +'Cao ', # 0xc6 +'Ken ', # 0xc7 +'Xie ', # 0xc8 +'Ying ', # 0xc9 +'Ao ', # 0xca +'Mao ', # 0xcb +'Yi ', # 0xcc +'Lin ', # 0xcd +'Se ', # 0xce +'Jun ', # 0xcf +'Huai ', # 0xd0 +'Men ', # 0xd1 +'Lan ', # 0xd2 +'Ai ', # 0xd3 +'Lin ', # 0xd4 +'Yan ', # 0xd5 +'Gua ', # 0xd6 +'Xia ', # 0xd7 +'Chi ', # 0xd8 +'Yu ', # 0xd9 +'Yin ', # 0xda +'Dai ', # 0xdb +'Meng ', # 0xdc +'Ai ', # 0xdd +'Meng ', # 0xde +'Dui ', # 0xdf +'Qi ', # 0xe0 +'Mo ', # 0xe1 +'Lan ', # 0xe2 +'Men ', # 0xe3 +'Chou ', # 0xe4 +'Zhi ', # 0xe5 +'Nuo ', # 0xe6 +'Nuo ', # 0xe7 +'Yan ', # 0xe8 +'Yang ', # 0xe9 +'Bo ', # 0xea +'Zhi ', # 0xeb +'Kuang ', # 0xec +'Kuang ', # 0xed +'You ', # 0xee +'Fu ', # 0xef +'Liu ', # 0xf0 +'Mie ', # 0xf1 +'Cheng ', # 0xf2 +'[?] ', # 0xf3 +'Chan ', # 0xf4 +'Meng ', # 0xf5 +'Lan ', # 0xf6 +'Huai ', # 0xf7 +'Xuan ', # 0xf8 +'Rang ', # 0xf9 +'Chan ', # 0xfa +'Ji ', # 0xfb +'Ju ', # 0xfc +'Huan ', # 0xfd +'She ', # 0xfe +'Yi ', # 0xff +) diff --git a/libs/unidecode/x062.py b/libs/unidecode/x062.py new file mode 100644 index 00000000..97979203 --- /dev/null +++ b/libs/unidecode/x062.py @@ -0,0 +1,258 @@ +data = ( +'Lian ', # 0x00 +'Nan ', # 0x01 +'Mi ', # 0x02 +'Tang ', # 0x03 +'Jue ', # 0x04 +'Gang ', # 0x05 +'Gang ', # 0x06 +'Gang ', # 0x07 +'Ge ', # 0x08 +'Yue ', # 0x09 +'Wu ', # 0x0a +'Jian ', # 0x0b +'Xu ', # 0x0c +'Shu ', # 0x0d +'Rong ', # 0x0e +'Xi ', # 0x0f +'Cheng ', # 0x10 +'Wo ', # 0x11 +'Jie ', # 0x12 +'Ge ', # 0x13 +'Jian ', # 0x14 +'Qiang ', # 0x15 +'Huo ', # 0x16 +'Qiang ', # 0x17 +'Zhan ', # 0x18 +'Dong ', # 0x19 +'Qi ', # 0x1a +'Jia ', # 0x1b +'Die ', # 0x1c +'Zei ', # 0x1d +'Jia ', # 0x1e +'Ji ', # 0x1f +'Shi ', # 0x20 +'Kan ', # 0x21 +'Ji ', # 0x22 +'Kui ', # 0x23 +'Gai ', # 0x24 +'Deng ', # 0x25 +'Zhan ', # 0x26 +'Chuang ', # 0x27 +'Ge ', # 0x28 +'Jian ', # 0x29 +'Jie ', # 0x2a +'Yu ', # 0x2b +'Jian ', # 0x2c +'Yan ', # 0x2d +'Lu ', # 0x2e +'Xi ', # 0x2f +'Zhan ', # 0x30 +'Xi ', # 0x31 +'Xi ', # 0x32 +'Chuo ', # 0x33 +'Dai ', # 0x34 +'Qu ', # 0x35 +'Hu ', # 0x36 +'Hu ', # 0x37 +'Hu ', # 0x38 +'E ', # 0x39 +'Shi ', # 0x3a +'Li ', # 0x3b +'Mao ', # 0x3c +'Hu ', # 0x3d +'Li ', # 0x3e +'Fang ', # 0x3f +'Suo ', # 0x40 +'Bian ', # 0x41 +'Dian ', # 0x42 +'Jiong ', # 0x43 +'Shang ', # 0x44 +'Yi ', # 0x45 +'Yi ', # 0x46 +'Shan ', # 0x47 +'Hu ', # 0x48 +'Fei ', # 0x49 +'Yan ', # 0x4a +'Shou ', # 0x4b +'T ', # 0x4c +'Cai ', # 0x4d +'Zha ', # 0x4e +'Qiu ', # 0x4f +'Le ', # 0x50 +'Bu ', # 0x51 +'Ba ', # 0x52 +'Da ', # 0x53 +'Reng ', # 0x54 +'Fu ', # 0x55 +'Hameru ', # 0x56 +'Zai ', # 0x57 +'Tuo ', # 0x58 +'Zhang ', # 0x59 +'Diao ', # 0x5a +'Kang ', # 0x5b +'Yu ', # 0x5c +'Ku ', # 0x5d +'Han ', # 0x5e +'Shen ', # 0x5f +'Cha ', # 0x60 +'Yi ', # 0x61 +'Gu ', # 0x62 +'Kou ', # 0x63 +'Wu ', # 0x64 +'Tuo ', # 0x65 +'Qian ', # 0x66 +'Zhi ', # 0x67 +'Ren ', # 0x68 +'Kuo ', # 0x69 +'Men ', # 0x6a +'Sao ', # 0x6b +'Yang ', # 0x6c +'Niu ', # 0x6d +'Ban ', # 0x6e +'Che ', # 0x6f +'Rao ', # 0x70 +'Xi ', # 0x71 +'Qian ', # 0x72 +'Ban ', # 0x73 +'Jia ', # 0x74 +'Yu ', # 0x75 +'Fu ', # 0x76 +'Ao ', # 0x77 +'Xi ', # 0x78 +'Pi ', # 0x79 +'Zhi ', # 0x7a +'Zi ', # 0x7b +'E ', # 0x7c +'Dun ', # 0x7d +'Zhao ', # 0x7e +'Cheng ', # 0x7f +'Ji ', # 0x80 +'Yan ', # 0x81 +'Kuang ', # 0x82 +'Bian ', # 0x83 +'Chao ', # 0x84 +'Ju ', # 0x85 +'Wen ', # 0x86 +'Hu ', # 0x87 +'Yue ', # 0x88 +'Jue ', # 0x89 +'Ba ', # 0x8a +'Qin ', # 0x8b +'Zhen ', # 0x8c +'Zheng ', # 0x8d +'Yun ', # 0x8e +'Wan ', # 0x8f +'Nu ', # 0x90 +'Yi ', # 0x91 +'Shu ', # 0x92 +'Zhua ', # 0x93 +'Pou ', # 0x94 +'Tou ', # 0x95 +'Dou ', # 0x96 +'Kang ', # 0x97 +'Zhe ', # 0x98 +'Pou ', # 0x99 +'Fu ', # 0x9a +'Pao ', # 0x9b +'Ba ', # 0x9c +'Ao ', # 0x9d +'Ze ', # 0x9e +'Tuan ', # 0x9f +'Kou ', # 0xa0 +'Lun ', # 0xa1 +'Qiang ', # 0xa2 +'[?] ', # 0xa3 +'Hu ', # 0xa4 +'Bao ', # 0xa5 +'Bing ', # 0xa6 +'Zhi ', # 0xa7 +'Peng ', # 0xa8 +'Tan ', # 0xa9 +'Pu ', # 0xaa +'Pi ', # 0xab +'Tai ', # 0xac +'Yao ', # 0xad +'Zhen ', # 0xae +'Zha ', # 0xaf +'Yang ', # 0xb0 +'Bao ', # 0xb1 +'He ', # 0xb2 +'Ni ', # 0xb3 +'Yi ', # 0xb4 +'Di ', # 0xb5 +'Chi ', # 0xb6 +'Pi ', # 0xb7 +'Za ', # 0xb8 +'Mo ', # 0xb9 +'Mo ', # 0xba +'Shen ', # 0xbb +'Ya ', # 0xbc +'Chou ', # 0xbd +'Qu ', # 0xbe +'Min ', # 0xbf +'Chu ', # 0xc0 +'Jia ', # 0xc1 +'Fu ', # 0xc2 +'Zhan ', # 0xc3 +'Zhu ', # 0xc4 +'Dan ', # 0xc5 +'Chai ', # 0xc6 +'Mu ', # 0xc7 +'Nian ', # 0xc8 +'La ', # 0xc9 +'Fu ', # 0xca +'Pao ', # 0xcb +'Ban ', # 0xcc +'Pai ', # 0xcd +'Ling ', # 0xce +'Na ', # 0xcf +'Guai ', # 0xd0 +'Qian ', # 0xd1 +'Ju ', # 0xd2 +'Tuo ', # 0xd3 +'Ba ', # 0xd4 +'Tuo ', # 0xd5 +'Tuo ', # 0xd6 +'Ao ', # 0xd7 +'Ju ', # 0xd8 +'Zhuo ', # 0xd9 +'Pan ', # 0xda +'Zhao ', # 0xdb +'Bai ', # 0xdc +'Bai ', # 0xdd +'Di ', # 0xde +'Ni ', # 0xdf +'Ju ', # 0xe0 +'Kuo ', # 0xe1 +'Long ', # 0xe2 +'Jian ', # 0xe3 +'[?] ', # 0xe4 +'Yong ', # 0xe5 +'Lan ', # 0xe6 +'Ning ', # 0xe7 +'Bo ', # 0xe8 +'Ze ', # 0xe9 +'Qian ', # 0xea +'Hen ', # 0xeb +'Gua ', # 0xec +'Shi ', # 0xed +'Jie ', # 0xee +'Zheng ', # 0xef +'Nin ', # 0xf0 +'Gong ', # 0xf1 +'Gong ', # 0xf2 +'Quan ', # 0xf3 +'Shuan ', # 0xf4 +'Cun ', # 0xf5 +'Zan ', # 0xf6 +'Kao ', # 0xf7 +'Chi ', # 0xf8 +'Xie ', # 0xf9 +'Ce ', # 0xfa +'Hui ', # 0xfb +'Pin ', # 0xfc +'Zhuai ', # 0xfd +'Shi ', # 0xfe +'Na ', # 0xff +) diff --git a/libs/unidecode/x063.py b/libs/unidecode/x063.py new file mode 100644 index 00000000..896cea25 --- /dev/null +++ b/libs/unidecode/x063.py @@ -0,0 +1,258 @@ +data = ( +'Bo ', # 0x00 +'Chi ', # 0x01 +'Gua ', # 0x02 +'Zhi ', # 0x03 +'Kuo ', # 0x04 +'Duo ', # 0x05 +'Duo ', # 0x06 +'Zhi ', # 0x07 +'Qie ', # 0x08 +'An ', # 0x09 +'Nong ', # 0x0a +'Zhen ', # 0x0b +'Ge ', # 0x0c +'Jiao ', # 0x0d +'Ku ', # 0x0e +'Dong ', # 0x0f +'Ru ', # 0x10 +'Tiao ', # 0x11 +'Lie ', # 0x12 +'Zha ', # 0x13 +'Lu ', # 0x14 +'Die ', # 0x15 +'Wa ', # 0x16 +'Jue ', # 0x17 +'Mushiru ', # 0x18 +'Ju ', # 0x19 +'Zhi ', # 0x1a +'Luan ', # 0x1b +'Ya ', # 0x1c +'Zhua ', # 0x1d +'Ta ', # 0x1e +'Xie ', # 0x1f +'Nao ', # 0x20 +'Dang ', # 0x21 +'Jiao ', # 0x22 +'Zheng ', # 0x23 +'Ji ', # 0x24 +'Hui ', # 0x25 +'Xun ', # 0x26 +'Ku ', # 0x27 +'Ai ', # 0x28 +'Tuo ', # 0x29 +'Nuo ', # 0x2a +'Cuo ', # 0x2b +'Bo ', # 0x2c +'Geng ', # 0x2d +'Ti ', # 0x2e +'Zhen ', # 0x2f +'Cheng ', # 0x30 +'Suo ', # 0x31 +'Suo ', # 0x32 +'Keng ', # 0x33 +'Mei ', # 0x34 +'Long ', # 0x35 +'Ju ', # 0x36 +'Peng ', # 0x37 +'Jian ', # 0x38 +'Yi ', # 0x39 +'Ting ', # 0x3a +'Shan ', # 0x3b +'Nuo ', # 0x3c +'Wan ', # 0x3d +'Xie ', # 0x3e +'Cha ', # 0x3f +'Feng ', # 0x40 +'Jiao ', # 0x41 +'Wu ', # 0x42 +'Jun ', # 0x43 +'Jiu ', # 0x44 +'Tong ', # 0x45 +'Kun ', # 0x46 +'Huo ', # 0x47 +'Tu ', # 0x48 +'Zhuo ', # 0x49 +'Pou ', # 0x4a +'Le ', # 0x4b +'Ba ', # 0x4c +'Han ', # 0x4d +'Shao ', # 0x4e +'Nie ', # 0x4f +'Juan ', # 0x50 +'Ze ', # 0x51 +'Song ', # 0x52 +'Ye ', # 0x53 +'Jue ', # 0x54 +'Bu ', # 0x55 +'Huan ', # 0x56 +'Bu ', # 0x57 +'Zun ', # 0x58 +'Yi ', # 0x59 +'Zhai ', # 0x5a +'Lu ', # 0x5b +'Sou ', # 0x5c +'Tuo ', # 0x5d +'Lao ', # 0x5e +'Sun ', # 0x5f +'Bang ', # 0x60 +'Jian ', # 0x61 +'Huan ', # 0x62 +'Dao ', # 0x63 +'[?] ', # 0x64 +'Wan ', # 0x65 +'Qin ', # 0x66 +'Peng ', # 0x67 +'She ', # 0x68 +'Lie ', # 0x69 +'Min ', # 0x6a +'Men ', # 0x6b +'Fu ', # 0x6c +'Bai ', # 0x6d +'Ju ', # 0x6e +'Dao ', # 0x6f +'Wo ', # 0x70 +'Ai ', # 0x71 +'Juan ', # 0x72 +'Yue ', # 0x73 +'Zong ', # 0x74 +'Chen ', # 0x75 +'Chui ', # 0x76 +'Jie ', # 0x77 +'Tu ', # 0x78 +'Ben ', # 0x79 +'Na ', # 0x7a +'Nian ', # 0x7b +'Nuo ', # 0x7c +'Zu ', # 0x7d +'Wo ', # 0x7e +'Xi ', # 0x7f +'Xian ', # 0x80 +'Cheng ', # 0x81 +'Dian ', # 0x82 +'Sao ', # 0x83 +'Lun ', # 0x84 +'Qing ', # 0x85 +'Gang ', # 0x86 +'Duo ', # 0x87 +'Shou ', # 0x88 +'Diao ', # 0x89 +'Pou ', # 0x8a +'Di ', # 0x8b +'Zhang ', # 0x8c +'Gun ', # 0x8d +'Ji ', # 0x8e +'Tao ', # 0x8f +'Qia ', # 0x90 +'Qi ', # 0x91 +'Pai ', # 0x92 +'Shu ', # 0x93 +'Qian ', # 0x94 +'Ling ', # 0x95 +'Yi ', # 0x96 +'Ya ', # 0x97 +'Jue ', # 0x98 +'Zheng ', # 0x99 +'Liang ', # 0x9a +'Gua ', # 0x9b +'Yi ', # 0x9c +'Huo ', # 0x9d +'Shan ', # 0x9e +'Zheng ', # 0x9f +'Lue ', # 0xa0 +'Cai ', # 0xa1 +'Tan ', # 0xa2 +'Che ', # 0xa3 +'Bing ', # 0xa4 +'Jie ', # 0xa5 +'Ti ', # 0xa6 +'Kong ', # 0xa7 +'Tui ', # 0xa8 +'Yan ', # 0xa9 +'Cuo ', # 0xaa +'Zou ', # 0xab +'Ju ', # 0xac +'Tian ', # 0xad +'Qian ', # 0xae +'Ken ', # 0xaf +'Bai ', # 0xb0 +'Shou ', # 0xb1 +'Jie ', # 0xb2 +'Lu ', # 0xb3 +'Guo ', # 0xb4 +'Haba ', # 0xb5 +'[?] ', # 0xb6 +'Zhi ', # 0xb7 +'Dan ', # 0xb8 +'Mang ', # 0xb9 +'Xian ', # 0xba +'Sao ', # 0xbb +'Guan ', # 0xbc +'Peng ', # 0xbd +'Yuan ', # 0xbe +'Nuo ', # 0xbf +'Jian ', # 0xc0 +'Zhen ', # 0xc1 +'Jiu ', # 0xc2 +'Jian ', # 0xc3 +'Yu ', # 0xc4 +'Yan ', # 0xc5 +'Kui ', # 0xc6 +'Nan ', # 0xc7 +'Hong ', # 0xc8 +'Rou ', # 0xc9 +'Pi ', # 0xca +'Wei ', # 0xcb +'Sai ', # 0xcc +'Zou ', # 0xcd +'Xuan ', # 0xce +'Miao ', # 0xcf +'Ti ', # 0xd0 +'Nie ', # 0xd1 +'Cha ', # 0xd2 +'Shi ', # 0xd3 +'Zong ', # 0xd4 +'Zhen ', # 0xd5 +'Yi ', # 0xd6 +'Shun ', # 0xd7 +'Heng ', # 0xd8 +'Bian ', # 0xd9 +'Yang ', # 0xda +'Huan ', # 0xdb +'Yan ', # 0xdc +'Zuan ', # 0xdd +'An ', # 0xde +'Xu ', # 0xdf +'Ya ', # 0xe0 +'Wo ', # 0xe1 +'Ke ', # 0xe2 +'Chuai ', # 0xe3 +'Ji ', # 0xe4 +'Ti ', # 0xe5 +'La ', # 0xe6 +'La ', # 0xe7 +'Cheng ', # 0xe8 +'Kai ', # 0xe9 +'Jiu ', # 0xea +'Jiu ', # 0xeb +'Tu ', # 0xec +'Jie ', # 0xed +'Hui ', # 0xee +'Geng ', # 0xef +'Chong ', # 0xf0 +'Shuo ', # 0xf1 +'She ', # 0xf2 +'Xie ', # 0xf3 +'Yuan ', # 0xf4 +'Qian ', # 0xf5 +'Ye ', # 0xf6 +'Cha ', # 0xf7 +'Zha ', # 0xf8 +'Bei ', # 0xf9 +'Yao ', # 0xfa +'[?] ', # 0xfb +'[?] ', # 0xfc +'Lan ', # 0xfd +'Wen ', # 0xfe +'Qin ', # 0xff +) diff --git a/libs/unidecode/x064.py b/libs/unidecode/x064.py new file mode 100644 index 00000000..dc1514b6 --- /dev/null +++ b/libs/unidecode/x064.py @@ -0,0 +1,258 @@ +data = ( +'Chan ', # 0x00 +'Ge ', # 0x01 +'Lou ', # 0x02 +'Zong ', # 0x03 +'Geng ', # 0x04 +'Jiao ', # 0x05 +'Gou ', # 0x06 +'Qin ', # 0x07 +'Yong ', # 0x08 +'Que ', # 0x09 +'Chou ', # 0x0a +'Chi ', # 0x0b +'Zhan ', # 0x0c +'Sun ', # 0x0d +'Sun ', # 0x0e +'Bo ', # 0x0f +'Chu ', # 0x10 +'Rong ', # 0x11 +'Beng ', # 0x12 +'Cuo ', # 0x13 +'Sao ', # 0x14 +'Ke ', # 0x15 +'Yao ', # 0x16 +'Dao ', # 0x17 +'Zhi ', # 0x18 +'Nu ', # 0x19 +'Xie ', # 0x1a +'Jian ', # 0x1b +'Sou ', # 0x1c +'Qiu ', # 0x1d +'Gao ', # 0x1e +'Xian ', # 0x1f +'Shuo ', # 0x20 +'Sang ', # 0x21 +'Jin ', # 0x22 +'Mie ', # 0x23 +'E ', # 0x24 +'Chui ', # 0x25 +'Nuo ', # 0x26 +'Shan ', # 0x27 +'Ta ', # 0x28 +'Jie ', # 0x29 +'Tang ', # 0x2a +'Pan ', # 0x2b +'Ban ', # 0x2c +'Da ', # 0x2d +'Li ', # 0x2e +'Tao ', # 0x2f +'Hu ', # 0x30 +'Zhi ', # 0x31 +'Wa ', # 0x32 +'Xia ', # 0x33 +'Qian ', # 0x34 +'Wen ', # 0x35 +'Qiang ', # 0x36 +'Tian ', # 0x37 +'Zhen ', # 0x38 +'E ', # 0x39 +'Xi ', # 0x3a +'Nuo ', # 0x3b +'Quan ', # 0x3c +'Cha ', # 0x3d +'Zha ', # 0x3e +'Ge ', # 0x3f +'Wu ', # 0x40 +'En ', # 0x41 +'She ', # 0x42 +'Kang ', # 0x43 +'She ', # 0x44 +'Shu ', # 0x45 +'Bai ', # 0x46 +'Yao ', # 0x47 +'Bin ', # 0x48 +'Sou ', # 0x49 +'Tan ', # 0x4a +'Sa ', # 0x4b +'Chan ', # 0x4c +'Suo ', # 0x4d +'Liao ', # 0x4e +'Chong ', # 0x4f +'Chuang ', # 0x50 +'Guo ', # 0x51 +'Bing ', # 0x52 +'Feng ', # 0x53 +'Shuai ', # 0x54 +'Di ', # 0x55 +'Qi ', # 0x56 +'Sou ', # 0x57 +'Zhai ', # 0x58 +'Lian ', # 0x59 +'Tang ', # 0x5a +'Chi ', # 0x5b +'Guan ', # 0x5c +'Lu ', # 0x5d +'Luo ', # 0x5e +'Lou ', # 0x5f +'Zong ', # 0x60 +'Gai ', # 0x61 +'Hu ', # 0x62 +'Zha ', # 0x63 +'Chuang ', # 0x64 +'Tang ', # 0x65 +'Hua ', # 0x66 +'Cui ', # 0x67 +'Nai ', # 0x68 +'Mo ', # 0x69 +'Jiang ', # 0x6a +'Gui ', # 0x6b +'Ying ', # 0x6c +'Zhi ', # 0x6d +'Ao ', # 0x6e +'Zhi ', # 0x6f +'Nie ', # 0x70 +'Man ', # 0x71 +'Shan ', # 0x72 +'Kou ', # 0x73 +'Shu ', # 0x74 +'Suo ', # 0x75 +'Tuan ', # 0x76 +'Jiao ', # 0x77 +'Mo ', # 0x78 +'Mo ', # 0x79 +'Zhe ', # 0x7a +'Xian ', # 0x7b +'Keng ', # 0x7c +'Piao ', # 0x7d +'Jiang ', # 0x7e +'Yin ', # 0x7f +'Gou ', # 0x80 +'Qian ', # 0x81 +'Lue ', # 0x82 +'Ji ', # 0x83 +'Ying ', # 0x84 +'Jue ', # 0x85 +'Pie ', # 0x86 +'Pie ', # 0x87 +'Lao ', # 0x88 +'Dun ', # 0x89 +'Xian ', # 0x8a +'Ruan ', # 0x8b +'Kui ', # 0x8c +'Zan ', # 0x8d +'Yi ', # 0x8e +'Xun ', # 0x8f +'Cheng ', # 0x90 +'Cheng ', # 0x91 +'Sa ', # 0x92 +'Nao ', # 0x93 +'Heng ', # 0x94 +'Si ', # 0x95 +'Qian ', # 0x96 +'Huang ', # 0x97 +'Da ', # 0x98 +'Zun ', # 0x99 +'Nian ', # 0x9a +'Lin ', # 0x9b +'Zheng ', # 0x9c +'Hui ', # 0x9d +'Zhuang ', # 0x9e +'Jiao ', # 0x9f +'Ji ', # 0xa0 +'Cao ', # 0xa1 +'Dan ', # 0xa2 +'Dan ', # 0xa3 +'Che ', # 0xa4 +'Bo ', # 0xa5 +'Che ', # 0xa6 +'Jue ', # 0xa7 +'Xiao ', # 0xa8 +'Liao ', # 0xa9 +'Ben ', # 0xaa +'Fu ', # 0xab +'Qiao ', # 0xac +'Bo ', # 0xad +'Cuo ', # 0xae +'Zhuo ', # 0xaf +'Zhuan ', # 0xb0 +'Tuo ', # 0xb1 +'Pu ', # 0xb2 +'Qin ', # 0xb3 +'Dun ', # 0xb4 +'Nian ', # 0xb5 +'[?] ', # 0xb6 +'Xie ', # 0xb7 +'Lu ', # 0xb8 +'Jiao ', # 0xb9 +'Cuan ', # 0xba +'Ta ', # 0xbb +'Han ', # 0xbc +'Qiao ', # 0xbd +'Zhua ', # 0xbe +'Jian ', # 0xbf +'Gan ', # 0xc0 +'Yong ', # 0xc1 +'Lei ', # 0xc2 +'Kuo ', # 0xc3 +'Lu ', # 0xc4 +'Shan ', # 0xc5 +'Zhuo ', # 0xc6 +'Ze ', # 0xc7 +'Pu ', # 0xc8 +'Chuo ', # 0xc9 +'Ji ', # 0xca +'Dang ', # 0xcb +'Suo ', # 0xcc +'Cao ', # 0xcd +'Qing ', # 0xce +'Jing ', # 0xcf +'Huan ', # 0xd0 +'Jie ', # 0xd1 +'Qin ', # 0xd2 +'Kuai ', # 0xd3 +'Dan ', # 0xd4 +'Xi ', # 0xd5 +'Ge ', # 0xd6 +'Pi ', # 0xd7 +'Bo ', # 0xd8 +'Ao ', # 0xd9 +'Ju ', # 0xda +'Ye ', # 0xdb +'[?] ', # 0xdc +'Mang ', # 0xdd +'Sou ', # 0xde +'Mi ', # 0xdf +'Ji ', # 0xe0 +'Tai ', # 0xe1 +'Zhuo ', # 0xe2 +'Dao ', # 0xe3 +'Xing ', # 0xe4 +'Lan ', # 0xe5 +'Ca ', # 0xe6 +'Ju ', # 0xe7 +'Ye ', # 0xe8 +'Ru ', # 0xe9 +'Ye ', # 0xea +'Ye ', # 0xeb +'Ni ', # 0xec +'Hu ', # 0xed +'Ji ', # 0xee +'Bin ', # 0xef +'Ning ', # 0xf0 +'Ge ', # 0xf1 +'Zhi ', # 0xf2 +'Jie ', # 0xf3 +'Kuo ', # 0xf4 +'Mo ', # 0xf5 +'Jian ', # 0xf6 +'Xie ', # 0xf7 +'Lie ', # 0xf8 +'Tan ', # 0xf9 +'Bai ', # 0xfa +'Sou ', # 0xfb +'Lu ', # 0xfc +'Lue ', # 0xfd +'Rao ', # 0xfe +'Zhi ', # 0xff +) diff --git a/libs/unidecode/x065.py b/libs/unidecode/x065.py new file mode 100644 index 00000000..ede51764 --- /dev/null +++ b/libs/unidecode/x065.py @@ -0,0 +1,258 @@ +data = ( +'Pan ', # 0x00 +'Yang ', # 0x01 +'Lei ', # 0x02 +'Sa ', # 0x03 +'Shu ', # 0x04 +'Zan ', # 0x05 +'Nian ', # 0x06 +'Xian ', # 0x07 +'Jun ', # 0x08 +'Huo ', # 0x09 +'Li ', # 0x0a +'La ', # 0x0b +'Han ', # 0x0c +'Ying ', # 0x0d +'Lu ', # 0x0e +'Long ', # 0x0f +'Qian ', # 0x10 +'Qian ', # 0x11 +'Zan ', # 0x12 +'Qian ', # 0x13 +'Lan ', # 0x14 +'San ', # 0x15 +'Ying ', # 0x16 +'Mei ', # 0x17 +'Rang ', # 0x18 +'Chan ', # 0x19 +'[?] ', # 0x1a +'Cuan ', # 0x1b +'Xi ', # 0x1c +'She ', # 0x1d +'Luo ', # 0x1e +'Jun ', # 0x1f +'Mi ', # 0x20 +'Li ', # 0x21 +'Zan ', # 0x22 +'Luan ', # 0x23 +'Tan ', # 0x24 +'Zuan ', # 0x25 +'Li ', # 0x26 +'Dian ', # 0x27 +'Wa ', # 0x28 +'Dang ', # 0x29 +'Jiao ', # 0x2a +'Jue ', # 0x2b +'Lan ', # 0x2c +'Li ', # 0x2d +'Nang ', # 0x2e +'Zhi ', # 0x2f +'Gui ', # 0x30 +'Gui ', # 0x31 +'Qi ', # 0x32 +'Xin ', # 0x33 +'Pu ', # 0x34 +'Sui ', # 0x35 +'Shou ', # 0x36 +'Kao ', # 0x37 +'You ', # 0x38 +'Gai ', # 0x39 +'Yi ', # 0x3a +'Gong ', # 0x3b +'Gan ', # 0x3c +'Ban ', # 0x3d +'Fang ', # 0x3e +'Zheng ', # 0x3f +'Bo ', # 0x40 +'Dian ', # 0x41 +'Kou ', # 0x42 +'Min ', # 0x43 +'Wu ', # 0x44 +'Gu ', # 0x45 +'He ', # 0x46 +'Ce ', # 0x47 +'Xiao ', # 0x48 +'Mi ', # 0x49 +'Chu ', # 0x4a +'Ge ', # 0x4b +'Di ', # 0x4c +'Xu ', # 0x4d +'Jiao ', # 0x4e +'Min ', # 0x4f +'Chen ', # 0x50 +'Jiu ', # 0x51 +'Zhen ', # 0x52 +'Duo ', # 0x53 +'Yu ', # 0x54 +'Chi ', # 0x55 +'Ao ', # 0x56 +'Bai ', # 0x57 +'Xu ', # 0x58 +'Jiao ', # 0x59 +'Duo ', # 0x5a +'Lian ', # 0x5b +'Nie ', # 0x5c +'Bi ', # 0x5d +'Chang ', # 0x5e +'Dian ', # 0x5f +'Duo ', # 0x60 +'Yi ', # 0x61 +'Gan ', # 0x62 +'San ', # 0x63 +'Ke ', # 0x64 +'Yan ', # 0x65 +'Dun ', # 0x66 +'Qi ', # 0x67 +'Dou ', # 0x68 +'Xiao ', # 0x69 +'Duo ', # 0x6a +'Jiao ', # 0x6b +'Jing ', # 0x6c +'Yang ', # 0x6d +'Xia ', # 0x6e +'Min ', # 0x6f +'Shu ', # 0x70 +'Ai ', # 0x71 +'Qiao ', # 0x72 +'Ai ', # 0x73 +'Zheng ', # 0x74 +'Di ', # 0x75 +'Zhen ', # 0x76 +'Fu ', # 0x77 +'Shu ', # 0x78 +'Liao ', # 0x79 +'Qu ', # 0x7a +'Xiong ', # 0x7b +'Xi ', # 0x7c +'Jiao ', # 0x7d +'Sen ', # 0x7e +'Jiao ', # 0x7f +'Zhuo ', # 0x80 +'Yi ', # 0x81 +'Lian ', # 0x82 +'Bi ', # 0x83 +'Li ', # 0x84 +'Xiao ', # 0x85 +'Xiao ', # 0x86 +'Wen ', # 0x87 +'Xue ', # 0x88 +'Qi ', # 0x89 +'Qi ', # 0x8a +'Zhai ', # 0x8b +'Bin ', # 0x8c +'Jue ', # 0x8d +'Zhai ', # 0x8e +'[?] ', # 0x8f +'Fei ', # 0x90 +'Ban ', # 0x91 +'Ban ', # 0x92 +'Lan ', # 0x93 +'Yu ', # 0x94 +'Lan ', # 0x95 +'Wei ', # 0x96 +'Dou ', # 0x97 +'Sheng ', # 0x98 +'Liao ', # 0x99 +'Jia ', # 0x9a +'Hu ', # 0x9b +'Xie ', # 0x9c +'Jia ', # 0x9d +'Yu ', # 0x9e +'Zhen ', # 0x9f +'Jiao ', # 0xa0 +'Wo ', # 0xa1 +'Tou ', # 0xa2 +'Chu ', # 0xa3 +'Jin ', # 0xa4 +'Chi ', # 0xa5 +'Yin ', # 0xa6 +'Fu ', # 0xa7 +'Qiang ', # 0xa8 +'Zhan ', # 0xa9 +'Qu ', # 0xaa +'Zhuo ', # 0xab +'Zhan ', # 0xac +'Duan ', # 0xad +'Zhuo ', # 0xae +'Si ', # 0xaf +'Xin ', # 0xb0 +'Zhuo ', # 0xb1 +'Zhuo ', # 0xb2 +'Qin ', # 0xb3 +'Lin ', # 0xb4 +'Zhuo ', # 0xb5 +'Chu ', # 0xb6 +'Duan ', # 0xb7 +'Zhu ', # 0xb8 +'Fang ', # 0xb9 +'Xie ', # 0xba +'Hang ', # 0xbb +'Yu ', # 0xbc +'Shi ', # 0xbd +'Pei ', # 0xbe +'You ', # 0xbf +'Mye ', # 0xc0 +'Pang ', # 0xc1 +'Qi ', # 0xc2 +'Zhan ', # 0xc3 +'Mao ', # 0xc4 +'Lu ', # 0xc5 +'Pei ', # 0xc6 +'Pi ', # 0xc7 +'Liu ', # 0xc8 +'Fu ', # 0xc9 +'Fang ', # 0xca +'Xuan ', # 0xcb +'Jing ', # 0xcc +'Jing ', # 0xcd +'Ni ', # 0xce +'Zu ', # 0xcf +'Zhao ', # 0xd0 +'Yi ', # 0xd1 +'Liu ', # 0xd2 +'Shao ', # 0xd3 +'Jian ', # 0xd4 +'Es ', # 0xd5 +'Yi ', # 0xd6 +'Qi ', # 0xd7 +'Zhi ', # 0xd8 +'Fan ', # 0xd9 +'Piao ', # 0xda +'Fan ', # 0xdb +'Zhan ', # 0xdc +'Guai ', # 0xdd +'Sui ', # 0xde +'Yu ', # 0xdf +'Wu ', # 0xe0 +'Ji ', # 0xe1 +'Ji ', # 0xe2 +'Ji ', # 0xe3 +'Huo ', # 0xe4 +'Ri ', # 0xe5 +'Dan ', # 0xe6 +'Jiu ', # 0xe7 +'Zhi ', # 0xe8 +'Zao ', # 0xe9 +'Xie ', # 0xea +'Tiao ', # 0xeb +'Xun ', # 0xec +'Xu ', # 0xed +'Xu ', # 0xee +'Xu ', # 0xef +'Gan ', # 0xf0 +'Han ', # 0xf1 +'Tai ', # 0xf2 +'Di ', # 0xf3 +'Xu ', # 0xf4 +'Chan ', # 0xf5 +'Shi ', # 0xf6 +'Kuang ', # 0xf7 +'Yang ', # 0xf8 +'Shi ', # 0xf9 +'Wang ', # 0xfa +'Min ', # 0xfb +'Min ', # 0xfc +'Tun ', # 0xfd +'Chun ', # 0xfe +'Wu ', # 0xff +) diff --git a/libs/unidecode/x066.py b/libs/unidecode/x066.py new file mode 100644 index 00000000..01898d55 --- /dev/null +++ b/libs/unidecode/x066.py @@ -0,0 +1,258 @@ +data = ( +'Yun ', # 0x00 +'Bei ', # 0x01 +'Ang ', # 0x02 +'Ze ', # 0x03 +'Ban ', # 0x04 +'Jie ', # 0x05 +'Kun ', # 0x06 +'Sheng ', # 0x07 +'Hu ', # 0x08 +'Fang ', # 0x09 +'Hao ', # 0x0a +'Gui ', # 0x0b +'Chang ', # 0x0c +'Xuan ', # 0x0d +'Ming ', # 0x0e +'Hun ', # 0x0f +'Fen ', # 0x10 +'Qin ', # 0x11 +'Hu ', # 0x12 +'Yi ', # 0x13 +'Xi ', # 0x14 +'Xin ', # 0x15 +'Yan ', # 0x16 +'Ze ', # 0x17 +'Fang ', # 0x18 +'Tan ', # 0x19 +'Shen ', # 0x1a +'Ju ', # 0x1b +'Yang ', # 0x1c +'Zan ', # 0x1d +'Bing ', # 0x1e +'Xing ', # 0x1f +'Ying ', # 0x20 +'Xuan ', # 0x21 +'Pei ', # 0x22 +'Zhen ', # 0x23 +'Ling ', # 0x24 +'Chun ', # 0x25 +'Hao ', # 0x26 +'Mei ', # 0x27 +'Zuo ', # 0x28 +'Mo ', # 0x29 +'Bian ', # 0x2a +'Xu ', # 0x2b +'Hun ', # 0x2c +'Zhao ', # 0x2d +'Zong ', # 0x2e +'Shi ', # 0x2f +'Shi ', # 0x30 +'Yu ', # 0x31 +'Fei ', # 0x32 +'Die ', # 0x33 +'Mao ', # 0x34 +'Ni ', # 0x35 +'Chang ', # 0x36 +'Wen ', # 0x37 +'Dong ', # 0x38 +'Ai ', # 0x39 +'Bing ', # 0x3a +'Ang ', # 0x3b +'Zhou ', # 0x3c +'Long ', # 0x3d +'Xian ', # 0x3e +'Kuang ', # 0x3f +'Tiao ', # 0x40 +'Chao ', # 0x41 +'Shi ', # 0x42 +'Huang ', # 0x43 +'Huang ', # 0x44 +'Xuan ', # 0x45 +'Kui ', # 0x46 +'Xu ', # 0x47 +'Jiao ', # 0x48 +'Jin ', # 0x49 +'Zhi ', # 0x4a +'Jin ', # 0x4b +'Shang ', # 0x4c +'Tong ', # 0x4d +'Hong ', # 0x4e +'Yan ', # 0x4f +'Gai ', # 0x50 +'Xiang ', # 0x51 +'Shai ', # 0x52 +'Xiao ', # 0x53 +'Ye ', # 0x54 +'Yun ', # 0x55 +'Hui ', # 0x56 +'Han ', # 0x57 +'Han ', # 0x58 +'Jun ', # 0x59 +'Wan ', # 0x5a +'Xian ', # 0x5b +'Kun ', # 0x5c +'Zhou ', # 0x5d +'Xi ', # 0x5e +'Cheng ', # 0x5f +'Sheng ', # 0x60 +'Bu ', # 0x61 +'Zhe ', # 0x62 +'Zhe ', # 0x63 +'Wu ', # 0x64 +'Han ', # 0x65 +'Hui ', # 0x66 +'Hao ', # 0x67 +'Chen ', # 0x68 +'Wan ', # 0x69 +'Tian ', # 0x6a +'Zhuo ', # 0x6b +'Zui ', # 0x6c +'Zhou ', # 0x6d +'Pu ', # 0x6e +'Jing ', # 0x6f +'Xi ', # 0x70 +'Shan ', # 0x71 +'Yi ', # 0x72 +'Xi ', # 0x73 +'Qing ', # 0x74 +'Qi ', # 0x75 +'Jing ', # 0x76 +'Gui ', # 0x77 +'Zhen ', # 0x78 +'Yi ', # 0x79 +'Zhi ', # 0x7a +'An ', # 0x7b +'Wan ', # 0x7c +'Lin ', # 0x7d +'Liang ', # 0x7e +'Chang ', # 0x7f +'Wang ', # 0x80 +'Xiao ', # 0x81 +'Zan ', # 0x82 +'Hi ', # 0x83 +'Xuan ', # 0x84 +'Xuan ', # 0x85 +'Yi ', # 0x86 +'Xia ', # 0x87 +'Yun ', # 0x88 +'Hui ', # 0x89 +'Fu ', # 0x8a +'Min ', # 0x8b +'Kui ', # 0x8c +'He ', # 0x8d +'Ying ', # 0x8e +'Du ', # 0x8f +'Wei ', # 0x90 +'Shu ', # 0x91 +'Qing ', # 0x92 +'Mao ', # 0x93 +'Nan ', # 0x94 +'Jian ', # 0x95 +'Nuan ', # 0x96 +'An ', # 0x97 +'Yang ', # 0x98 +'Chun ', # 0x99 +'Yao ', # 0x9a +'Suo ', # 0x9b +'Jin ', # 0x9c +'Ming ', # 0x9d +'Jiao ', # 0x9e +'Kai ', # 0x9f +'Gao ', # 0xa0 +'Weng ', # 0xa1 +'Chang ', # 0xa2 +'Qi ', # 0xa3 +'Hao ', # 0xa4 +'Yan ', # 0xa5 +'Li ', # 0xa6 +'Ai ', # 0xa7 +'Ji ', # 0xa8 +'Gui ', # 0xa9 +'Men ', # 0xaa +'Zan ', # 0xab +'Xie ', # 0xac +'Hao ', # 0xad +'Mu ', # 0xae +'Mo ', # 0xaf +'Cong ', # 0xb0 +'Ni ', # 0xb1 +'Zhang ', # 0xb2 +'Hui ', # 0xb3 +'Bao ', # 0xb4 +'Han ', # 0xb5 +'Xuan ', # 0xb6 +'Chuan ', # 0xb7 +'Liao ', # 0xb8 +'Xian ', # 0xb9 +'Dan ', # 0xba +'Jing ', # 0xbb +'Pie ', # 0xbc +'Lin ', # 0xbd +'Tun ', # 0xbe +'Xi ', # 0xbf +'Yi ', # 0xc0 +'Ji ', # 0xc1 +'Huang ', # 0xc2 +'Tai ', # 0xc3 +'Ye ', # 0xc4 +'Ye ', # 0xc5 +'Li ', # 0xc6 +'Tan ', # 0xc7 +'Tong ', # 0xc8 +'Xiao ', # 0xc9 +'Fei ', # 0xca +'Qin ', # 0xcb +'Zhao ', # 0xcc +'Hao ', # 0xcd +'Yi ', # 0xce +'Xiang ', # 0xcf +'Xing ', # 0xd0 +'Sen ', # 0xd1 +'Jiao ', # 0xd2 +'Bao ', # 0xd3 +'Jing ', # 0xd4 +'Yian ', # 0xd5 +'Ai ', # 0xd6 +'Ye ', # 0xd7 +'Ru ', # 0xd8 +'Shu ', # 0xd9 +'Meng ', # 0xda +'Xun ', # 0xdb +'Yao ', # 0xdc +'Pu ', # 0xdd +'Li ', # 0xde +'Chen ', # 0xdf +'Kuang ', # 0xe0 +'Die ', # 0xe1 +'[?] ', # 0xe2 +'Yan ', # 0xe3 +'Huo ', # 0xe4 +'Lu ', # 0xe5 +'Xi ', # 0xe6 +'Rong ', # 0xe7 +'Long ', # 0xe8 +'Nang ', # 0xe9 +'Luo ', # 0xea +'Luan ', # 0xeb +'Shai ', # 0xec +'Tang ', # 0xed +'Yan ', # 0xee +'Chu ', # 0xef +'Yue ', # 0xf0 +'Yue ', # 0xf1 +'Qu ', # 0xf2 +'Yi ', # 0xf3 +'Geng ', # 0xf4 +'Ye ', # 0xf5 +'Hu ', # 0xf6 +'He ', # 0xf7 +'Shu ', # 0xf8 +'Cao ', # 0xf9 +'Cao ', # 0xfa +'Noboru ', # 0xfb +'Man ', # 0xfc +'Ceng ', # 0xfd +'Ceng ', # 0xfe +'Ti ', # 0xff +) diff --git a/libs/unidecode/x067.py b/libs/unidecode/x067.py new file mode 100644 index 00000000..2e863ae0 --- /dev/null +++ b/libs/unidecode/x067.py @@ -0,0 +1,258 @@ +data = ( +'Zui ', # 0x00 +'Can ', # 0x01 +'Xu ', # 0x02 +'Hui ', # 0x03 +'Yin ', # 0x04 +'Qie ', # 0x05 +'Fen ', # 0x06 +'Pi ', # 0x07 +'Yue ', # 0x08 +'You ', # 0x09 +'Ruan ', # 0x0a +'Peng ', # 0x0b +'Ban ', # 0x0c +'Fu ', # 0x0d +'Ling ', # 0x0e +'Fei ', # 0x0f +'Qu ', # 0x10 +'[?] ', # 0x11 +'Nu ', # 0x12 +'Tiao ', # 0x13 +'Shuo ', # 0x14 +'Zhen ', # 0x15 +'Lang ', # 0x16 +'Lang ', # 0x17 +'Juan ', # 0x18 +'Ming ', # 0x19 +'Huang ', # 0x1a +'Wang ', # 0x1b +'Tun ', # 0x1c +'Zhao ', # 0x1d +'Ji ', # 0x1e +'Qi ', # 0x1f +'Ying ', # 0x20 +'Zong ', # 0x21 +'Wang ', # 0x22 +'Tong ', # 0x23 +'Lang ', # 0x24 +'[?] ', # 0x25 +'Meng ', # 0x26 +'Long ', # 0x27 +'Mu ', # 0x28 +'Deng ', # 0x29 +'Wei ', # 0x2a +'Mo ', # 0x2b +'Ben ', # 0x2c +'Zha ', # 0x2d +'Zhu ', # 0x2e +'Zhu ', # 0x2f +'[?] ', # 0x30 +'Zhu ', # 0x31 +'Ren ', # 0x32 +'Ba ', # 0x33 +'Po ', # 0x34 +'Duo ', # 0x35 +'Duo ', # 0x36 +'Dao ', # 0x37 +'Li ', # 0x38 +'Qiu ', # 0x39 +'Ji ', # 0x3a +'Jiu ', # 0x3b +'Bi ', # 0x3c +'Xiu ', # 0x3d +'Ting ', # 0x3e +'Ci ', # 0x3f +'Sha ', # 0x40 +'Eburi ', # 0x41 +'Za ', # 0x42 +'Quan ', # 0x43 +'Qian ', # 0x44 +'Yu ', # 0x45 +'Gan ', # 0x46 +'Wu ', # 0x47 +'Cha ', # 0x48 +'Shan ', # 0x49 +'Xun ', # 0x4a +'Fan ', # 0x4b +'Wu ', # 0x4c +'Zi ', # 0x4d +'Li ', # 0x4e +'Xing ', # 0x4f +'Cai ', # 0x50 +'Cun ', # 0x51 +'Ren ', # 0x52 +'Shao ', # 0x53 +'Tuo ', # 0x54 +'Di ', # 0x55 +'Zhang ', # 0x56 +'Mang ', # 0x57 +'Chi ', # 0x58 +'Yi ', # 0x59 +'Gu ', # 0x5a +'Gong ', # 0x5b +'Du ', # 0x5c +'Yi ', # 0x5d +'Qi ', # 0x5e +'Shu ', # 0x5f +'Gang ', # 0x60 +'Tiao ', # 0x61 +'Moku ', # 0x62 +'Soma ', # 0x63 +'Tochi ', # 0x64 +'Lai ', # 0x65 +'Sugi ', # 0x66 +'Mang ', # 0x67 +'Yang ', # 0x68 +'Ma ', # 0x69 +'Miao ', # 0x6a +'Si ', # 0x6b +'Yuan ', # 0x6c +'Hang ', # 0x6d +'Fei ', # 0x6e +'Bei ', # 0x6f +'Jie ', # 0x70 +'Dong ', # 0x71 +'Gao ', # 0x72 +'Yao ', # 0x73 +'Xian ', # 0x74 +'Chu ', # 0x75 +'Qun ', # 0x76 +'Pa ', # 0x77 +'Shu ', # 0x78 +'Hua ', # 0x79 +'Xin ', # 0x7a +'Chou ', # 0x7b +'Zhu ', # 0x7c +'Chou ', # 0x7d +'Song ', # 0x7e +'Ban ', # 0x7f +'Song ', # 0x80 +'Ji ', # 0x81 +'Yue ', # 0x82 +'Jin ', # 0x83 +'Gou ', # 0x84 +'Ji ', # 0x85 +'Mao ', # 0x86 +'Pi ', # 0x87 +'Bi ', # 0x88 +'Wang ', # 0x89 +'Ang ', # 0x8a +'Fang ', # 0x8b +'Fen ', # 0x8c +'Yi ', # 0x8d +'Fu ', # 0x8e +'Nan ', # 0x8f +'Xi ', # 0x90 +'Hu ', # 0x91 +'Ya ', # 0x92 +'Dou ', # 0x93 +'Xun ', # 0x94 +'Zhen ', # 0x95 +'Yao ', # 0x96 +'Lin ', # 0x97 +'Rui ', # 0x98 +'E ', # 0x99 +'Mei ', # 0x9a +'Zhao ', # 0x9b +'Guo ', # 0x9c +'Zhi ', # 0x9d +'Cong ', # 0x9e +'Yun ', # 0x9f +'Waku ', # 0xa0 +'Dou ', # 0xa1 +'Shu ', # 0xa2 +'Zao ', # 0xa3 +'[?] ', # 0xa4 +'Li ', # 0xa5 +'Haze ', # 0xa6 +'Jian ', # 0xa7 +'Cheng ', # 0xa8 +'Matsu ', # 0xa9 +'Qiang ', # 0xaa +'Feng ', # 0xab +'Nan ', # 0xac +'Xiao ', # 0xad +'Xian ', # 0xae +'Ku ', # 0xaf +'Ping ', # 0xb0 +'Yi ', # 0xb1 +'Xi ', # 0xb2 +'Zhi ', # 0xb3 +'Guai ', # 0xb4 +'Xiao ', # 0xb5 +'Jia ', # 0xb6 +'Jia ', # 0xb7 +'Gou ', # 0xb8 +'Fu ', # 0xb9 +'Mo ', # 0xba +'Yi ', # 0xbb +'Ye ', # 0xbc +'Ye ', # 0xbd +'Shi ', # 0xbe +'Nie ', # 0xbf +'Bi ', # 0xc0 +'Duo ', # 0xc1 +'Yi ', # 0xc2 +'Ling ', # 0xc3 +'Bing ', # 0xc4 +'Ni ', # 0xc5 +'La ', # 0xc6 +'He ', # 0xc7 +'Pan ', # 0xc8 +'Fan ', # 0xc9 +'Zhong ', # 0xca +'Dai ', # 0xcb +'Ci ', # 0xcc +'Yang ', # 0xcd +'Fu ', # 0xce +'Bo ', # 0xcf +'Mou ', # 0xd0 +'Gan ', # 0xd1 +'Qi ', # 0xd2 +'Ran ', # 0xd3 +'Rou ', # 0xd4 +'Mao ', # 0xd5 +'Zhao ', # 0xd6 +'Song ', # 0xd7 +'Zhe ', # 0xd8 +'Xia ', # 0xd9 +'You ', # 0xda +'Shen ', # 0xdb +'Ju ', # 0xdc +'Tuo ', # 0xdd +'Zuo ', # 0xde +'Nan ', # 0xdf +'Ning ', # 0xe0 +'Yong ', # 0xe1 +'Di ', # 0xe2 +'Zhi ', # 0xe3 +'Zha ', # 0xe4 +'Cha ', # 0xe5 +'Dan ', # 0xe6 +'Gu ', # 0xe7 +'Pu ', # 0xe8 +'Jiu ', # 0xe9 +'Ao ', # 0xea +'Fu ', # 0xeb +'Jian ', # 0xec +'Bo ', # 0xed +'Duo ', # 0xee +'Ke ', # 0xef +'Nai ', # 0xf0 +'Zhu ', # 0xf1 +'Bi ', # 0xf2 +'Liu ', # 0xf3 +'Chai ', # 0xf4 +'Zha ', # 0xf5 +'Si ', # 0xf6 +'Zhu ', # 0xf7 +'Pei ', # 0xf8 +'Shi ', # 0xf9 +'Guai ', # 0xfa +'Cha ', # 0xfb +'Yao ', # 0xfc +'Jue ', # 0xfd +'Jiu ', # 0xfe +'Shi ', # 0xff +) diff --git a/libs/unidecode/x068.py b/libs/unidecode/x068.py new file mode 100644 index 00000000..c562311c --- /dev/null +++ b/libs/unidecode/x068.py @@ -0,0 +1,258 @@ +data = ( +'Zhi ', # 0x00 +'Liu ', # 0x01 +'Mei ', # 0x02 +'Hoy ', # 0x03 +'Rong ', # 0x04 +'Zha ', # 0x05 +'[?] ', # 0x06 +'Biao ', # 0x07 +'Zhan ', # 0x08 +'Jie ', # 0x09 +'Long ', # 0x0a +'Dong ', # 0x0b +'Lu ', # 0x0c +'Sayng ', # 0x0d +'Li ', # 0x0e +'Lan ', # 0x0f +'Yong ', # 0x10 +'Shu ', # 0x11 +'Xun ', # 0x12 +'Shuan ', # 0x13 +'Qi ', # 0x14 +'Zhen ', # 0x15 +'Qi ', # 0x16 +'Li ', # 0x17 +'Yi ', # 0x18 +'Xiang ', # 0x19 +'Zhen ', # 0x1a +'Li ', # 0x1b +'Su ', # 0x1c +'Gua ', # 0x1d +'Kan ', # 0x1e +'Bing ', # 0x1f +'Ren ', # 0x20 +'Xiao ', # 0x21 +'Bo ', # 0x22 +'Ren ', # 0x23 +'Bing ', # 0x24 +'Zi ', # 0x25 +'Chou ', # 0x26 +'Yi ', # 0x27 +'Jie ', # 0x28 +'Xu ', # 0x29 +'Zhu ', # 0x2a +'Jian ', # 0x2b +'Zui ', # 0x2c +'Er ', # 0x2d +'Er ', # 0x2e +'You ', # 0x2f +'Fa ', # 0x30 +'Gong ', # 0x31 +'Kao ', # 0x32 +'Lao ', # 0x33 +'Zhan ', # 0x34 +'Li ', # 0x35 +'Yin ', # 0x36 +'Yang ', # 0x37 +'He ', # 0x38 +'Gen ', # 0x39 +'Zhi ', # 0x3a +'Chi ', # 0x3b +'Ge ', # 0x3c +'Zai ', # 0x3d +'Luan ', # 0x3e +'Fu ', # 0x3f +'Jie ', # 0x40 +'Hang ', # 0x41 +'Gui ', # 0x42 +'Tao ', # 0x43 +'Guang ', # 0x44 +'Wei ', # 0x45 +'Kuang ', # 0x46 +'Ru ', # 0x47 +'An ', # 0x48 +'An ', # 0x49 +'Juan ', # 0x4a +'Yi ', # 0x4b +'Zhuo ', # 0x4c +'Ku ', # 0x4d +'Zhi ', # 0x4e +'Qiong ', # 0x4f +'Tong ', # 0x50 +'Sang ', # 0x51 +'Sang ', # 0x52 +'Huan ', # 0x53 +'Jie ', # 0x54 +'Jiu ', # 0x55 +'Xue ', # 0x56 +'Duo ', # 0x57 +'Zhui ', # 0x58 +'Yu ', # 0x59 +'Zan ', # 0x5a +'Kasei ', # 0x5b +'Ying ', # 0x5c +'Masu ', # 0x5d +'[?] ', # 0x5e +'Zhan ', # 0x5f +'Ya ', # 0x60 +'Nao ', # 0x61 +'Zhen ', # 0x62 +'Dang ', # 0x63 +'Qi ', # 0x64 +'Qiao ', # 0x65 +'Hua ', # 0x66 +'Kuai ', # 0x67 +'Jiang ', # 0x68 +'Zhuang ', # 0x69 +'Xun ', # 0x6a +'Suo ', # 0x6b +'Sha ', # 0x6c +'Zhen ', # 0x6d +'Bei ', # 0x6e +'Ting ', # 0x6f +'Gua ', # 0x70 +'Jing ', # 0x71 +'Bo ', # 0x72 +'Ben ', # 0x73 +'Fu ', # 0x74 +'Rui ', # 0x75 +'Tong ', # 0x76 +'Jue ', # 0x77 +'Xi ', # 0x78 +'Lang ', # 0x79 +'Liu ', # 0x7a +'Feng ', # 0x7b +'Qi ', # 0x7c +'Wen ', # 0x7d +'Jun ', # 0x7e +'Gan ', # 0x7f +'Cu ', # 0x80 +'Liang ', # 0x81 +'Qiu ', # 0x82 +'Ting ', # 0x83 +'You ', # 0x84 +'Mei ', # 0x85 +'Bang ', # 0x86 +'Long ', # 0x87 +'Peng ', # 0x88 +'Zhuang ', # 0x89 +'Di ', # 0x8a +'Xuan ', # 0x8b +'Tu ', # 0x8c +'Zao ', # 0x8d +'Ao ', # 0x8e +'Gu ', # 0x8f +'Bi ', # 0x90 +'Di ', # 0x91 +'Han ', # 0x92 +'Zi ', # 0x93 +'Zhi ', # 0x94 +'Ren ', # 0x95 +'Bei ', # 0x96 +'Geng ', # 0x97 +'Jian ', # 0x98 +'Huan ', # 0x99 +'Wan ', # 0x9a +'Nuo ', # 0x9b +'Jia ', # 0x9c +'Tiao ', # 0x9d +'Ji ', # 0x9e +'Xiao ', # 0x9f +'Lu ', # 0xa0 +'Huan ', # 0xa1 +'Shao ', # 0xa2 +'Cen ', # 0xa3 +'Fen ', # 0xa4 +'Song ', # 0xa5 +'Meng ', # 0xa6 +'Wu ', # 0xa7 +'Li ', # 0xa8 +'Li ', # 0xa9 +'Dou ', # 0xaa +'Cen ', # 0xab +'Ying ', # 0xac +'Suo ', # 0xad +'Ju ', # 0xae +'Ti ', # 0xaf +'Jie ', # 0xb0 +'Kun ', # 0xb1 +'Zhuo ', # 0xb2 +'Shu ', # 0xb3 +'Chan ', # 0xb4 +'Fan ', # 0xb5 +'Wei ', # 0xb6 +'Jing ', # 0xb7 +'Li ', # 0xb8 +'Bing ', # 0xb9 +'Fumoto ', # 0xba +'Shikimi ', # 0xbb +'Tao ', # 0xbc +'Zhi ', # 0xbd +'Lai ', # 0xbe +'Lian ', # 0xbf +'Jian ', # 0xc0 +'Zhuo ', # 0xc1 +'Ling ', # 0xc2 +'Li ', # 0xc3 +'Qi ', # 0xc4 +'Bing ', # 0xc5 +'Zhun ', # 0xc6 +'Cong ', # 0xc7 +'Qian ', # 0xc8 +'Mian ', # 0xc9 +'Qi ', # 0xca +'Qi ', # 0xcb +'Cai ', # 0xcc +'Gun ', # 0xcd +'Chan ', # 0xce +'Te ', # 0xcf +'Fei ', # 0xd0 +'Pai ', # 0xd1 +'Bang ', # 0xd2 +'Pou ', # 0xd3 +'Hun ', # 0xd4 +'Zong ', # 0xd5 +'Cheng ', # 0xd6 +'Zao ', # 0xd7 +'Ji ', # 0xd8 +'Li ', # 0xd9 +'Peng ', # 0xda +'Yu ', # 0xdb +'Yu ', # 0xdc +'Gu ', # 0xdd +'Hun ', # 0xde +'Dong ', # 0xdf +'Tang ', # 0xe0 +'Gang ', # 0xe1 +'Wang ', # 0xe2 +'Di ', # 0xe3 +'Xi ', # 0xe4 +'Fan ', # 0xe5 +'Cheng ', # 0xe6 +'Zhan ', # 0xe7 +'Qi ', # 0xe8 +'Yuan ', # 0xe9 +'Yan ', # 0xea +'Yu ', # 0xeb +'Quan ', # 0xec +'Yi ', # 0xed +'Sen ', # 0xee +'Ren ', # 0xef +'Chui ', # 0xf0 +'Leng ', # 0xf1 +'Qi ', # 0xf2 +'Zhuo ', # 0xf3 +'Fu ', # 0xf4 +'Ke ', # 0xf5 +'Lai ', # 0xf6 +'Zou ', # 0xf7 +'Zou ', # 0xf8 +'Zhuo ', # 0xf9 +'Guan ', # 0xfa +'Fen ', # 0xfb +'Fen ', # 0xfc +'Chen ', # 0xfd +'Qiong ', # 0xfe +'Nie ', # 0xff +) diff --git a/libs/unidecode/x069.py b/libs/unidecode/x069.py new file mode 100644 index 00000000..7fa8c7de --- /dev/null +++ b/libs/unidecode/x069.py @@ -0,0 +1,258 @@ +data = ( +'Wan ', # 0x00 +'Guo ', # 0x01 +'Lu ', # 0x02 +'Hao ', # 0x03 +'Jie ', # 0x04 +'Yi ', # 0x05 +'Chou ', # 0x06 +'Ju ', # 0x07 +'Ju ', # 0x08 +'Cheng ', # 0x09 +'Zuo ', # 0x0a +'Liang ', # 0x0b +'Qiang ', # 0x0c +'Zhi ', # 0x0d +'Zhui ', # 0x0e +'Ya ', # 0x0f +'Ju ', # 0x10 +'Bei ', # 0x11 +'Jiao ', # 0x12 +'Zhuo ', # 0x13 +'Zi ', # 0x14 +'Bin ', # 0x15 +'Peng ', # 0x16 +'Ding ', # 0x17 +'Chu ', # 0x18 +'Chang ', # 0x19 +'Kunugi ', # 0x1a +'Momiji ', # 0x1b +'Jian ', # 0x1c +'Gui ', # 0x1d +'Xi ', # 0x1e +'Du ', # 0x1f +'Qian ', # 0x20 +'Kunugi ', # 0x21 +'Soko ', # 0x22 +'Shide ', # 0x23 +'Luo ', # 0x24 +'Zhi ', # 0x25 +'Ken ', # 0x26 +'Myeng ', # 0x27 +'Tafu ', # 0x28 +'[?] ', # 0x29 +'Peng ', # 0x2a +'Zhan ', # 0x2b +'[?] ', # 0x2c +'Tuo ', # 0x2d +'Sen ', # 0x2e +'Duo ', # 0x2f +'Ye ', # 0x30 +'Fou ', # 0x31 +'Wei ', # 0x32 +'Wei ', # 0x33 +'Duan ', # 0x34 +'Jia ', # 0x35 +'Zong ', # 0x36 +'Jian ', # 0x37 +'Yi ', # 0x38 +'Shen ', # 0x39 +'Xi ', # 0x3a +'Yan ', # 0x3b +'Yan ', # 0x3c +'Chuan ', # 0x3d +'Zhan ', # 0x3e +'Chun ', # 0x3f +'Yu ', # 0x40 +'He ', # 0x41 +'Zha ', # 0x42 +'Wo ', # 0x43 +'Pian ', # 0x44 +'Bi ', # 0x45 +'Yao ', # 0x46 +'Huo ', # 0x47 +'Xu ', # 0x48 +'Ruo ', # 0x49 +'Yang ', # 0x4a +'La ', # 0x4b +'Yan ', # 0x4c +'Ben ', # 0x4d +'Hun ', # 0x4e +'Kui ', # 0x4f +'Jie ', # 0x50 +'Kui ', # 0x51 +'Si ', # 0x52 +'Feng ', # 0x53 +'Xie ', # 0x54 +'Tuo ', # 0x55 +'Zhi ', # 0x56 +'Jian ', # 0x57 +'Mu ', # 0x58 +'Mao ', # 0x59 +'Chu ', # 0x5a +'Hu ', # 0x5b +'Hu ', # 0x5c +'Lian ', # 0x5d +'Leng ', # 0x5e +'Ting ', # 0x5f +'Nan ', # 0x60 +'Yu ', # 0x61 +'You ', # 0x62 +'Mei ', # 0x63 +'Song ', # 0x64 +'Xuan ', # 0x65 +'Xuan ', # 0x66 +'Ying ', # 0x67 +'Zhen ', # 0x68 +'Pian ', # 0x69 +'Ye ', # 0x6a +'Ji ', # 0x6b +'Jie ', # 0x6c +'Ye ', # 0x6d +'Chu ', # 0x6e +'Shun ', # 0x6f +'Yu ', # 0x70 +'Cou ', # 0x71 +'Wei ', # 0x72 +'Mei ', # 0x73 +'Di ', # 0x74 +'Ji ', # 0x75 +'Jie ', # 0x76 +'Kai ', # 0x77 +'Qiu ', # 0x78 +'Ying ', # 0x79 +'Rou ', # 0x7a +'Heng ', # 0x7b +'Lou ', # 0x7c +'Le ', # 0x7d +'Hazou ', # 0x7e +'Katsura ', # 0x7f +'Pin ', # 0x80 +'Muro ', # 0x81 +'Gai ', # 0x82 +'Tan ', # 0x83 +'Lan ', # 0x84 +'Yun ', # 0x85 +'Yu ', # 0x86 +'Chen ', # 0x87 +'Lu ', # 0x88 +'Ju ', # 0x89 +'Sakaki ', # 0x8a +'[?] ', # 0x8b +'Pi ', # 0x8c +'Xie ', # 0x8d +'Jia ', # 0x8e +'Yi ', # 0x8f +'Zhan ', # 0x90 +'Fu ', # 0x91 +'Nai ', # 0x92 +'Mi ', # 0x93 +'Lang ', # 0x94 +'Rong ', # 0x95 +'Gu ', # 0x96 +'Jian ', # 0x97 +'Ju ', # 0x98 +'Ta ', # 0x99 +'Yao ', # 0x9a +'Zhen ', # 0x9b +'Bang ', # 0x9c +'Sha ', # 0x9d +'Yuan ', # 0x9e +'Zi ', # 0x9f +'Ming ', # 0xa0 +'Su ', # 0xa1 +'Jia ', # 0xa2 +'Yao ', # 0xa3 +'Jie ', # 0xa4 +'Huang ', # 0xa5 +'Gan ', # 0xa6 +'Fei ', # 0xa7 +'Zha ', # 0xa8 +'Qian ', # 0xa9 +'Ma ', # 0xaa +'Sun ', # 0xab +'Yuan ', # 0xac +'Xie ', # 0xad +'Rong ', # 0xae +'Shi ', # 0xaf +'Zhi ', # 0xb0 +'Cui ', # 0xb1 +'Yun ', # 0xb2 +'Ting ', # 0xb3 +'Liu ', # 0xb4 +'Rong ', # 0xb5 +'Tang ', # 0xb6 +'Que ', # 0xb7 +'Zhai ', # 0xb8 +'Si ', # 0xb9 +'Sheng ', # 0xba +'Ta ', # 0xbb +'Ke ', # 0xbc +'Xi ', # 0xbd +'Gu ', # 0xbe +'Qi ', # 0xbf +'Kao ', # 0xc0 +'Gao ', # 0xc1 +'Sun ', # 0xc2 +'Pan ', # 0xc3 +'Tao ', # 0xc4 +'Ge ', # 0xc5 +'Xun ', # 0xc6 +'Dian ', # 0xc7 +'Nou ', # 0xc8 +'Ji ', # 0xc9 +'Shuo ', # 0xca +'Gou ', # 0xcb +'Chui ', # 0xcc +'Qiang ', # 0xcd +'Cha ', # 0xce +'Qian ', # 0xcf +'Huai ', # 0xd0 +'Mei ', # 0xd1 +'Xu ', # 0xd2 +'Gang ', # 0xd3 +'Gao ', # 0xd4 +'Zhuo ', # 0xd5 +'Tuo ', # 0xd6 +'Hashi ', # 0xd7 +'Yang ', # 0xd8 +'Dian ', # 0xd9 +'Jia ', # 0xda +'Jian ', # 0xdb +'Zui ', # 0xdc +'Kashi ', # 0xdd +'Ori ', # 0xde +'Bin ', # 0xdf +'Zhu ', # 0xe0 +'[?] ', # 0xe1 +'Xi ', # 0xe2 +'Qi ', # 0xe3 +'Lian ', # 0xe4 +'Hui ', # 0xe5 +'Yong ', # 0xe6 +'Qian ', # 0xe7 +'Guo ', # 0xe8 +'Gai ', # 0xe9 +'Gai ', # 0xea +'Tuan ', # 0xeb +'Hua ', # 0xec +'Cu ', # 0xed +'Sen ', # 0xee +'Cui ', # 0xef +'Beng ', # 0xf0 +'You ', # 0xf1 +'Hu ', # 0xf2 +'Jiang ', # 0xf3 +'Hu ', # 0xf4 +'Huan ', # 0xf5 +'Kui ', # 0xf6 +'Yi ', # 0xf7 +'Nie ', # 0xf8 +'Gao ', # 0xf9 +'Kang ', # 0xfa +'Gui ', # 0xfb +'Gui ', # 0xfc +'Cao ', # 0xfd +'Man ', # 0xfe +'Jin ', # 0xff +) diff --git a/libs/unidecode/x06a.py b/libs/unidecode/x06a.py new file mode 100644 index 00000000..12fcabd5 --- /dev/null +++ b/libs/unidecode/x06a.py @@ -0,0 +1,258 @@ +data = ( +'Di ', # 0x00 +'Zhuang ', # 0x01 +'Le ', # 0x02 +'Lang ', # 0x03 +'Chen ', # 0x04 +'Cong ', # 0x05 +'Li ', # 0x06 +'Xiu ', # 0x07 +'Qing ', # 0x08 +'Shuang ', # 0x09 +'Fan ', # 0x0a +'Tong ', # 0x0b +'Guan ', # 0x0c +'Ji ', # 0x0d +'Suo ', # 0x0e +'Lei ', # 0x0f +'Lu ', # 0x10 +'Liang ', # 0x11 +'Mi ', # 0x12 +'Lou ', # 0x13 +'Chao ', # 0x14 +'Su ', # 0x15 +'Ke ', # 0x16 +'Shu ', # 0x17 +'Tang ', # 0x18 +'Biao ', # 0x19 +'Lu ', # 0x1a +'Jiu ', # 0x1b +'Shu ', # 0x1c +'Zha ', # 0x1d +'Shu ', # 0x1e +'Zhang ', # 0x1f +'Men ', # 0x20 +'Mo ', # 0x21 +'Niao ', # 0x22 +'Yang ', # 0x23 +'Tiao ', # 0x24 +'Peng ', # 0x25 +'Zhu ', # 0x26 +'Sha ', # 0x27 +'Xi ', # 0x28 +'Quan ', # 0x29 +'Heng ', # 0x2a +'Jian ', # 0x2b +'Cong ', # 0x2c +'[?] ', # 0x2d +'Hokuso ', # 0x2e +'Qiang ', # 0x2f +'Tara ', # 0x30 +'Ying ', # 0x31 +'Er ', # 0x32 +'Xin ', # 0x33 +'Zhi ', # 0x34 +'Qiao ', # 0x35 +'Zui ', # 0x36 +'Cong ', # 0x37 +'Pu ', # 0x38 +'Shu ', # 0x39 +'Hua ', # 0x3a +'Kui ', # 0x3b +'Zhen ', # 0x3c +'Zun ', # 0x3d +'Yue ', # 0x3e +'Zhan ', # 0x3f +'Xi ', # 0x40 +'Xun ', # 0x41 +'Dian ', # 0x42 +'Fa ', # 0x43 +'Gan ', # 0x44 +'Mo ', # 0x45 +'Wu ', # 0x46 +'Qiao ', # 0x47 +'Nao ', # 0x48 +'Lin ', # 0x49 +'Liu ', # 0x4a +'Qiao ', # 0x4b +'Xian ', # 0x4c +'Run ', # 0x4d +'Fan ', # 0x4e +'Zhan ', # 0x4f +'Tuo ', # 0x50 +'Lao ', # 0x51 +'Yun ', # 0x52 +'Shun ', # 0x53 +'Tui ', # 0x54 +'Cheng ', # 0x55 +'Tang ', # 0x56 +'Meng ', # 0x57 +'Ju ', # 0x58 +'Cheng ', # 0x59 +'Su ', # 0x5a +'Jue ', # 0x5b +'Jue ', # 0x5c +'Tan ', # 0x5d +'Hui ', # 0x5e +'Ji ', # 0x5f +'Nuo ', # 0x60 +'Xiang ', # 0x61 +'Tuo ', # 0x62 +'Ning ', # 0x63 +'Rui ', # 0x64 +'Zhu ', # 0x65 +'Chuang ', # 0x66 +'Zeng ', # 0x67 +'Fen ', # 0x68 +'Qiong ', # 0x69 +'Ran ', # 0x6a +'Heng ', # 0x6b +'Cen ', # 0x6c +'Gu ', # 0x6d +'Liu ', # 0x6e +'Lao ', # 0x6f +'Gao ', # 0x70 +'Chu ', # 0x71 +'Zusa ', # 0x72 +'Nude ', # 0x73 +'Ca ', # 0x74 +'San ', # 0x75 +'Ji ', # 0x76 +'Dou ', # 0x77 +'Shou ', # 0x78 +'Lu ', # 0x79 +'[?] ', # 0x7a +'[?] ', # 0x7b +'Yuan ', # 0x7c +'Ta ', # 0x7d +'Shu ', # 0x7e +'Jiang ', # 0x7f +'Tan ', # 0x80 +'Lin ', # 0x81 +'Nong ', # 0x82 +'Yin ', # 0x83 +'Xi ', # 0x84 +'Sui ', # 0x85 +'Shan ', # 0x86 +'Zui ', # 0x87 +'Xuan ', # 0x88 +'Cheng ', # 0x89 +'Gan ', # 0x8a +'Ju ', # 0x8b +'Zui ', # 0x8c +'Yi ', # 0x8d +'Qin ', # 0x8e +'Pu ', # 0x8f +'Yan ', # 0x90 +'Lei ', # 0x91 +'Feng ', # 0x92 +'Hui ', # 0x93 +'Dang ', # 0x94 +'Ji ', # 0x95 +'Sui ', # 0x96 +'Bo ', # 0x97 +'Bi ', # 0x98 +'Ding ', # 0x99 +'Chu ', # 0x9a +'Zhua ', # 0x9b +'Kuai ', # 0x9c +'Ji ', # 0x9d +'Jie ', # 0x9e +'Jia ', # 0x9f +'Qing ', # 0xa0 +'Zhe ', # 0xa1 +'Jian ', # 0xa2 +'Qiang ', # 0xa3 +'Dao ', # 0xa4 +'Yi ', # 0xa5 +'Biao ', # 0xa6 +'Song ', # 0xa7 +'She ', # 0xa8 +'Lin ', # 0xa9 +'Kunugi ', # 0xaa +'Cha ', # 0xab +'Meng ', # 0xac +'Yin ', # 0xad +'Tao ', # 0xae +'Tai ', # 0xaf +'Mian ', # 0xb0 +'Qi ', # 0xb1 +'Toan ', # 0xb2 +'Bin ', # 0xb3 +'Huo ', # 0xb4 +'Ji ', # 0xb5 +'Qian ', # 0xb6 +'Mi ', # 0xb7 +'Ning ', # 0xb8 +'Yi ', # 0xb9 +'Gao ', # 0xba +'Jian ', # 0xbb +'Yin ', # 0xbc +'Er ', # 0xbd +'Qing ', # 0xbe +'Yan ', # 0xbf +'Qi ', # 0xc0 +'Mi ', # 0xc1 +'Zhao ', # 0xc2 +'Gui ', # 0xc3 +'Chun ', # 0xc4 +'Ji ', # 0xc5 +'Kui ', # 0xc6 +'Po ', # 0xc7 +'Deng ', # 0xc8 +'Chu ', # 0xc9 +'[?] ', # 0xca +'Mian ', # 0xcb +'You ', # 0xcc +'Zhi ', # 0xcd +'Guang ', # 0xce +'Qian ', # 0xcf +'Lei ', # 0xd0 +'Lei ', # 0xd1 +'Sa ', # 0xd2 +'Lu ', # 0xd3 +'Li ', # 0xd4 +'Cuan ', # 0xd5 +'Lu ', # 0xd6 +'Mie ', # 0xd7 +'Hui ', # 0xd8 +'Ou ', # 0xd9 +'Lu ', # 0xda +'Jie ', # 0xdb +'Gao ', # 0xdc +'Du ', # 0xdd +'Yuan ', # 0xde +'Li ', # 0xdf +'Fei ', # 0xe0 +'Zhuo ', # 0xe1 +'Sou ', # 0xe2 +'Lian ', # 0xe3 +'Tamo ', # 0xe4 +'Chu ', # 0xe5 +'[?] ', # 0xe6 +'Zhu ', # 0xe7 +'Lu ', # 0xe8 +'Yan ', # 0xe9 +'Li ', # 0xea +'Zhu ', # 0xeb +'Chen ', # 0xec +'Jie ', # 0xed +'E ', # 0xee +'Su ', # 0xef +'Huai ', # 0xf0 +'Nie ', # 0xf1 +'Yu ', # 0xf2 +'Long ', # 0xf3 +'Lai ', # 0xf4 +'[?] ', # 0xf5 +'Xian ', # 0xf6 +'Kwi ', # 0xf7 +'Ju ', # 0xf8 +'Xiao ', # 0xf9 +'Ling ', # 0xfa +'Ying ', # 0xfb +'Jian ', # 0xfc +'Yin ', # 0xfd +'You ', # 0xfe +'Ying ', # 0xff +) diff --git a/libs/unidecode/x06b.py b/libs/unidecode/x06b.py new file mode 100644 index 00000000..56aa7c65 --- /dev/null +++ b/libs/unidecode/x06b.py @@ -0,0 +1,258 @@ +data = ( +'Xiang ', # 0x00 +'Nong ', # 0x01 +'Bo ', # 0x02 +'Chan ', # 0x03 +'Lan ', # 0x04 +'Ju ', # 0x05 +'Shuang ', # 0x06 +'She ', # 0x07 +'Wei ', # 0x08 +'Cong ', # 0x09 +'Quan ', # 0x0a +'Qu ', # 0x0b +'Cang ', # 0x0c +'[?] ', # 0x0d +'Yu ', # 0x0e +'Luo ', # 0x0f +'Li ', # 0x10 +'Zan ', # 0x11 +'Luan ', # 0x12 +'Dang ', # 0x13 +'Jue ', # 0x14 +'Em ', # 0x15 +'Lan ', # 0x16 +'Lan ', # 0x17 +'Zhu ', # 0x18 +'Lei ', # 0x19 +'Li ', # 0x1a +'Ba ', # 0x1b +'Nang ', # 0x1c +'Yu ', # 0x1d +'Ling ', # 0x1e +'Tsuki ', # 0x1f +'Qian ', # 0x20 +'Ci ', # 0x21 +'Huan ', # 0x22 +'Xin ', # 0x23 +'Yu ', # 0x24 +'Yu ', # 0x25 +'Qian ', # 0x26 +'Ou ', # 0x27 +'Xu ', # 0x28 +'Chao ', # 0x29 +'Chu ', # 0x2a +'Chi ', # 0x2b +'Kai ', # 0x2c +'Yi ', # 0x2d +'Jue ', # 0x2e +'Xi ', # 0x2f +'Xu ', # 0x30 +'Xia ', # 0x31 +'Yu ', # 0x32 +'Kuai ', # 0x33 +'Lang ', # 0x34 +'Kuan ', # 0x35 +'Shuo ', # 0x36 +'Xi ', # 0x37 +'Ai ', # 0x38 +'Yi ', # 0x39 +'Qi ', # 0x3a +'Hu ', # 0x3b +'Chi ', # 0x3c +'Qin ', # 0x3d +'Kuan ', # 0x3e +'Kan ', # 0x3f +'Kuan ', # 0x40 +'Kan ', # 0x41 +'Chuan ', # 0x42 +'Sha ', # 0x43 +'Gua ', # 0x44 +'Yin ', # 0x45 +'Xin ', # 0x46 +'Xie ', # 0x47 +'Yu ', # 0x48 +'Qian ', # 0x49 +'Xiao ', # 0x4a +'Yi ', # 0x4b +'Ge ', # 0x4c +'Wu ', # 0x4d +'Tan ', # 0x4e +'Jin ', # 0x4f +'Ou ', # 0x50 +'Hu ', # 0x51 +'Ti ', # 0x52 +'Huan ', # 0x53 +'Xu ', # 0x54 +'Pen ', # 0x55 +'Xi ', # 0x56 +'Xiao ', # 0x57 +'Xu ', # 0x58 +'Xi ', # 0x59 +'Sen ', # 0x5a +'Lian ', # 0x5b +'Chu ', # 0x5c +'Yi ', # 0x5d +'Kan ', # 0x5e +'Yu ', # 0x5f +'Chuo ', # 0x60 +'Huan ', # 0x61 +'Zhi ', # 0x62 +'Zheng ', # 0x63 +'Ci ', # 0x64 +'Bu ', # 0x65 +'Wu ', # 0x66 +'Qi ', # 0x67 +'Bu ', # 0x68 +'Bu ', # 0x69 +'Wai ', # 0x6a +'Ju ', # 0x6b +'Qian ', # 0x6c +'Chi ', # 0x6d +'Se ', # 0x6e +'Chi ', # 0x6f +'Se ', # 0x70 +'Zhong ', # 0x71 +'Sui ', # 0x72 +'Sui ', # 0x73 +'Li ', # 0x74 +'Cuo ', # 0x75 +'Yu ', # 0x76 +'Li ', # 0x77 +'Gui ', # 0x78 +'Dai ', # 0x79 +'Dai ', # 0x7a +'Si ', # 0x7b +'Jian ', # 0x7c +'Zhe ', # 0x7d +'Mo ', # 0x7e +'Mo ', # 0x7f +'Yao ', # 0x80 +'Mo ', # 0x81 +'Cu ', # 0x82 +'Yang ', # 0x83 +'Tian ', # 0x84 +'Sheng ', # 0x85 +'Dai ', # 0x86 +'Shang ', # 0x87 +'Xu ', # 0x88 +'Xun ', # 0x89 +'Shu ', # 0x8a +'Can ', # 0x8b +'Jue ', # 0x8c +'Piao ', # 0x8d +'Qia ', # 0x8e +'Qiu ', # 0x8f +'Su ', # 0x90 +'Qing ', # 0x91 +'Yun ', # 0x92 +'Lian ', # 0x93 +'Yi ', # 0x94 +'Fou ', # 0x95 +'Zhi ', # 0x96 +'Ye ', # 0x97 +'Can ', # 0x98 +'Hun ', # 0x99 +'Dan ', # 0x9a +'Ji ', # 0x9b +'Ye ', # 0x9c +'Zhen ', # 0x9d +'Yun ', # 0x9e +'Wen ', # 0x9f +'Chou ', # 0xa0 +'Bin ', # 0xa1 +'Ti ', # 0xa2 +'Jin ', # 0xa3 +'Shang ', # 0xa4 +'Yin ', # 0xa5 +'Diao ', # 0xa6 +'Cu ', # 0xa7 +'Hui ', # 0xa8 +'Cuan ', # 0xa9 +'Yi ', # 0xaa +'Dan ', # 0xab +'Du ', # 0xac +'Jiang ', # 0xad +'Lian ', # 0xae +'Bin ', # 0xaf +'Du ', # 0xb0 +'Tsukusu ', # 0xb1 +'Jian ', # 0xb2 +'Shu ', # 0xb3 +'Ou ', # 0xb4 +'Duan ', # 0xb5 +'Zhu ', # 0xb6 +'Yin ', # 0xb7 +'Qing ', # 0xb8 +'Yi ', # 0xb9 +'Sha ', # 0xba +'Que ', # 0xbb +'Ke ', # 0xbc +'Yao ', # 0xbd +'Jun ', # 0xbe +'Dian ', # 0xbf +'Hui ', # 0xc0 +'Hui ', # 0xc1 +'Gu ', # 0xc2 +'Que ', # 0xc3 +'Ji ', # 0xc4 +'Yi ', # 0xc5 +'Ou ', # 0xc6 +'Hui ', # 0xc7 +'Duan ', # 0xc8 +'Yi ', # 0xc9 +'Xiao ', # 0xca +'Wu ', # 0xcb +'Guan ', # 0xcc +'Mu ', # 0xcd +'Mei ', # 0xce +'Mei ', # 0xcf +'Ai ', # 0xd0 +'Zuo ', # 0xd1 +'Du ', # 0xd2 +'Yu ', # 0xd3 +'Bi ', # 0xd4 +'Bi ', # 0xd5 +'Bi ', # 0xd6 +'Pi ', # 0xd7 +'Pi ', # 0xd8 +'Bi ', # 0xd9 +'Chan ', # 0xda +'Mao ', # 0xdb +'[?] ', # 0xdc +'[?] ', # 0xdd +'Pu ', # 0xde +'Mushiru ', # 0xdf +'Jia ', # 0xe0 +'Zhan ', # 0xe1 +'Sai ', # 0xe2 +'Mu ', # 0xe3 +'Tuo ', # 0xe4 +'Xun ', # 0xe5 +'Er ', # 0xe6 +'Rong ', # 0xe7 +'Xian ', # 0xe8 +'Ju ', # 0xe9 +'Mu ', # 0xea +'Hao ', # 0xeb +'Qiu ', # 0xec +'Dou ', # 0xed +'Mushiru ', # 0xee +'Tan ', # 0xef +'Pei ', # 0xf0 +'Ju ', # 0xf1 +'Duo ', # 0xf2 +'Cui ', # 0xf3 +'Bi ', # 0xf4 +'San ', # 0xf5 +'[?] ', # 0xf6 +'Mao ', # 0xf7 +'Sui ', # 0xf8 +'Yu ', # 0xf9 +'Yu ', # 0xfa +'Tuo ', # 0xfb +'He ', # 0xfc +'Jian ', # 0xfd +'Ta ', # 0xfe +'San ', # 0xff +) diff --git a/libs/unidecode/x06c.py b/libs/unidecode/x06c.py new file mode 100644 index 00000000..a1534e74 --- /dev/null +++ b/libs/unidecode/x06c.py @@ -0,0 +1,258 @@ +data = ( +'Lu ', # 0x00 +'Mu ', # 0x01 +'Li ', # 0x02 +'Tong ', # 0x03 +'Rong ', # 0x04 +'Chang ', # 0x05 +'Pu ', # 0x06 +'Luo ', # 0x07 +'Zhan ', # 0x08 +'Sao ', # 0x09 +'Zhan ', # 0x0a +'Meng ', # 0x0b +'Luo ', # 0x0c +'Qu ', # 0x0d +'Die ', # 0x0e +'Shi ', # 0x0f +'Di ', # 0x10 +'Min ', # 0x11 +'Jue ', # 0x12 +'Mang ', # 0x13 +'Qi ', # 0x14 +'Pie ', # 0x15 +'Nai ', # 0x16 +'Qi ', # 0x17 +'Dao ', # 0x18 +'Xian ', # 0x19 +'Chuan ', # 0x1a +'Fen ', # 0x1b +'Ri ', # 0x1c +'Nei ', # 0x1d +'[?] ', # 0x1e +'Fu ', # 0x1f +'Shen ', # 0x20 +'Dong ', # 0x21 +'Qing ', # 0x22 +'Qi ', # 0x23 +'Yin ', # 0x24 +'Xi ', # 0x25 +'Hai ', # 0x26 +'Yang ', # 0x27 +'An ', # 0x28 +'Ya ', # 0x29 +'Ke ', # 0x2a +'Qing ', # 0x2b +'Ya ', # 0x2c +'Dong ', # 0x2d +'Dan ', # 0x2e +'Lu ', # 0x2f +'Qing ', # 0x30 +'Yang ', # 0x31 +'Yun ', # 0x32 +'Yun ', # 0x33 +'Shui ', # 0x34 +'San ', # 0x35 +'Zheng ', # 0x36 +'Bing ', # 0x37 +'Yong ', # 0x38 +'Dang ', # 0x39 +'Shitamizu ', # 0x3a +'Le ', # 0x3b +'Ni ', # 0x3c +'Tun ', # 0x3d +'Fan ', # 0x3e +'Gui ', # 0x3f +'Ting ', # 0x40 +'Zhi ', # 0x41 +'Qiu ', # 0x42 +'Bin ', # 0x43 +'Ze ', # 0x44 +'Mian ', # 0x45 +'Cuan ', # 0x46 +'Hui ', # 0x47 +'Diao ', # 0x48 +'Yi ', # 0x49 +'Cha ', # 0x4a +'Zhuo ', # 0x4b +'Chuan ', # 0x4c +'Wan ', # 0x4d +'Fan ', # 0x4e +'Dai ', # 0x4f +'Xi ', # 0x50 +'Tuo ', # 0x51 +'Mang ', # 0x52 +'Qiu ', # 0x53 +'Qi ', # 0x54 +'Shan ', # 0x55 +'Pai ', # 0x56 +'Han ', # 0x57 +'Qian ', # 0x58 +'Wu ', # 0x59 +'Wu ', # 0x5a +'Xun ', # 0x5b +'Si ', # 0x5c +'Ru ', # 0x5d +'Gong ', # 0x5e +'Jiang ', # 0x5f +'Chi ', # 0x60 +'Wu ', # 0x61 +'Tsuchi ', # 0x62 +'[?] ', # 0x63 +'Tang ', # 0x64 +'Zhi ', # 0x65 +'Chi ', # 0x66 +'Qian ', # 0x67 +'Mi ', # 0x68 +'Yu ', # 0x69 +'Wang ', # 0x6a +'Qing ', # 0x6b +'Jing ', # 0x6c +'Rui ', # 0x6d +'Jun ', # 0x6e +'Hong ', # 0x6f +'Tai ', # 0x70 +'Quan ', # 0x71 +'Ji ', # 0x72 +'Bian ', # 0x73 +'Bian ', # 0x74 +'Gan ', # 0x75 +'Wen ', # 0x76 +'Zhong ', # 0x77 +'Fang ', # 0x78 +'Xiong ', # 0x79 +'Jue ', # 0x7a +'Hang ', # 0x7b +'Niou ', # 0x7c +'Qi ', # 0x7d +'Fen ', # 0x7e +'Xu ', # 0x7f +'Xu ', # 0x80 +'Qin ', # 0x81 +'Yi ', # 0x82 +'Wo ', # 0x83 +'Yun ', # 0x84 +'Yuan ', # 0x85 +'Hang ', # 0x86 +'Yan ', # 0x87 +'Chen ', # 0x88 +'Chen ', # 0x89 +'Dan ', # 0x8a +'You ', # 0x8b +'Dun ', # 0x8c +'Hu ', # 0x8d +'Huo ', # 0x8e +'Qie ', # 0x8f +'Mu ', # 0x90 +'Rou ', # 0x91 +'Mei ', # 0x92 +'Ta ', # 0x93 +'Mian ', # 0x94 +'Wu ', # 0x95 +'Chong ', # 0x96 +'Tian ', # 0x97 +'Bi ', # 0x98 +'Sha ', # 0x99 +'Zhi ', # 0x9a +'Pei ', # 0x9b +'Pan ', # 0x9c +'Zhui ', # 0x9d +'Za ', # 0x9e +'Gou ', # 0x9f +'Liu ', # 0xa0 +'Mei ', # 0xa1 +'Ze ', # 0xa2 +'Feng ', # 0xa3 +'Ou ', # 0xa4 +'Li ', # 0xa5 +'Lun ', # 0xa6 +'Cang ', # 0xa7 +'Feng ', # 0xa8 +'Wei ', # 0xa9 +'Hu ', # 0xaa +'Mo ', # 0xab +'Mei ', # 0xac +'Shu ', # 0xad +'Ju ', # 0xae +'Zan ', # 0xaf +'Tuo ', # 0xb0 +'Tuo ', # 0xb1 +'Tuo ', # 0xb2 +'He ', # 0xb3 +'Li ', # 0xb4 +'Mi ', # 0xb5 +'Yi ', # 0xb6 +'Fa ', # 0xb7 +'Fei ', # 0xb8 +'You ', # 0xb9 +'Tian ', # 0xba +'Zhi ', # 0xbb +'Zhao ', # 0xbc +'Gu ', # 0xbd +'Zhan ', # 0xbe +'Yan ', # 0xbf +'Si ', # 0xc0 +'Kuang ', # 0xc1 +'Jiong ', # 0xc2 +'Ju ', # 0xc3 +'Xie ', # 0xc4 +'Qiu ', # 0xc5 +'Yi ', # 0xc6 +'Jia ', # 0xc7 +'Zhong ', # 0xc8 +'Quan ', # 0xc9 +'Bo ', # 0xca +'Hui ', # 0xcb +'Mi ', # 0xcc +'Ben ', # 0xcd +'Zhuo ', # 0xce +'Chu ', # 0xcf +'Le ', # 0xd0 +'You ', # 0xd1 +'Gu ', # 0xd2 +'Hong ', # 0xd3 +'Gan ', # 0xd4 +'Fa ', # 0xd5 +'Mao ', # 0xd6 +'Si ', # 0xd7 +'Hu ', # 0xd8 +'Ping ', # 0xd9 +'Ci ', # 0xda +'Fan ', # 0xdb +'Chi ', # 0xdc +'Su ', # 0xdd +'Ning ', # 0xde +'Cheng ', # 0xdf +'Ling ', # 0xe0 +'Pao ', # 0xe1 +'Bo ', # 0xe2 +'Qi ', # 0xe3 +'Si ', # 0xe4 +'Ni ', # 0xe5 +'Ju ', # 0xe6 +'Yue ', # 0xe7 +'Zhu ', # 0xe8 +'Sheng ', # 0xe9 +'Lei ', # 0xea +'Xuan ', # 0xeb +'Xue ', # 0xec +'Fu ', # 0xed +'Pan ', # 0xee +'Min ', # 0xef +'Tai ', # 0xf0 +'Yang ', # 0xf1 +'Ji ', # 0xf2 +'Yong ', # 0xf3 +'Guan ', # 0xf4 +'Beng ', # 0xf5 +'Xue ', # 0xf6 +'Long ', # 0xf7 +'Lu ', # 0xf8 +'[?] ', # 0xf9 +'Bo ', # 0xfa +'Xie ', # 0xfb +'Po ', # 0xfc +'Ze ', # 0xfd +'Jing ', # 0xfe +'Yin ', # 0xff +) diff --git a/libs/unidecode/x06d.py b/libs/unidecode/x06d.py new file mode 100644 index 00000000..a9113465 --- /dev/null +++ b/libs/unidecode/x06d.py @@ -0,0 +1,258 @@ +data = ( +'Zhou ', # 0x00 +'Ji ', # 0x01 +'Yi ', # 0x02 +'Hui ', # 0x03 +'Hui ', # 0x04 +'Zui ', # 0x05 +'Cheng ', # 0x06 +'Yin ', # 0x07 +'Wei ', # 0x08 +'Hou ', # 0x09 +'Jian ', # 0x0a +'Yang ', # 0x0b +'Lie ', # 0x0c +'Si ', # 0x0d +'Ji ', # 0x0e +'Er ', # 0x0f +'Xing ', # 0x10 +'Fu ', # 0x11 +'Sa ', # 0x12 +'Suo ', # 0x13 +'Zhi ', # 0x14 +'Yin ', # 0x15 +'Wu ', # 0x16 +'Xi ', # 0x17 +'Kao ', # 0x18 +'Zhu ', # 0x19 +'Jiang ', # 0x1a +'Luo ', # 0x1b +'[?] ', # 0x1c +'An ', # 0x1d +'Dong ', # 0x1e +'Yi ', # 0x1f +'Mou ', # 0x20 +'Lei ', # 0x21 +'Yi ', # 0x22 +'Mi ', # 0x23 +'Quan ', # 0x24 +'Jin ', # 0x25 +'Mo ', # 0x26 +'Wei ', # 0x27 +'Xiao ', # 0x28 +'Xie ', # 0x29 +'Hong ', # 0x2a +'Xu ', # 0x2b +'Shuo ', # 0x2c +'Kuang ', # 0x2d +'Tao ', # 0x2e +'Qie ', # 0x2f +'Ju ', # 0x30 +'Er ', # 0x31 +'Zhou ', # 0x32 +'Ru ', # 0x33 +'Ping ', # 0x34 +'Xun ', # 0x35 +'Xiong ', # 0x36 +'Zhi ', # 0x37 +'Guang ', # 0x38 +'Huan ', # 0x39 +'Ming ', # 0x3a +'Huo ', # 0x3b +'Wa ', # 0x3c +'Qia ', # 0x3d +'Pai ', # 0x3e +'Wu ', # 0x3f +'Qu ', # 0x40 +'Liu ', # 0x41 +'Yi ', # 0x42 +'Jia ', # 0x43 +'Jing ', # 0x44 +'Qian ', # 0x45 +'Jiang ', # 0x46 +'Jiao ', # 0x47 +'Cheng ', # 0x48 +'Shi ', # 0x49 +'Zhuo ', # 0x4a +'Ce ', # 0x4b +'Pal ', # 0x4c +'Kuai ', # 0x4d +'Ji ', # 0x4e +'Liu ', # 0x4f +'Chan ', # 0x50 +'Hun ', # 0x51 +'Hu ', # 0x52 +'Nong ', # 0x53 +'Xun ', # 0x54 +'Jin ', # 0x55 +'Lie ', # 0x56 +'Qiu ', # 0x57 +'Wei ', # 0x58 +'Zhe ', # 0x59 +'Jun ', # 0x5a +'Han ', # 0x5b +'Bang ', # 0x5c +'Mang ', # 0x5d +'Zhuo ', # 0x5e +'You ', # 0x5f +'Xi ', # 0x60 +'Bo ', # 0x61 +'Dou ', # 0x62 +'Wan ', # 0x63 +'Hong ', # 0x64 +'Yi ', # 0x65 +'Pu ', # 0x66 +'Ying ', # 0x67 +'Lan ', # 0x68 +'Hao ', # 0x69 +'Lang ', # 0x6a +'Han ', # 0x6b +'Li ', # 0x6c +'Geng ', # 0x6d +'Fu ', # 0x6e +'Wu ', # 0x6f +'Lian ', # 0x70 +'Chun ', # 0x71 +'Feng ', # 0x72 +'Yi ', # 0x73 +'Yu ', # 0x74 +'Tong ', # 0x75 +'Lao ', # 0x76 +'Hai ', # 0x77 +'Jin ', # 0x78 +'Jia ', # 0x79 +'Chong ', # 0x7a +'Weng ', # 0x7b +'Mei ', # 0x7c +'Sui ', # 0x7d +'Cheng ', # 0x7e +'Pei ', # 0x7f +'Xian ', # 0x80 +'Shen ', # 0x81 +'Tu ', # 0x82 +'Kun ', # 0x83 +'Pin ', # 0x84 +'Nie ', # 0x85 +'Han ', # 0x86 +'Jing ', # 0x87 +'Xiao ', # 0x88 +'She ', # 0x89 +'Nian ', # 0x8a +'Tu ', # 0x8b +'Yong ', # 0x8c +'Xiao ', # 0x8d +'Xian ', # 0x8e +'Ting ', # 0x8f +'E ', # 0x90 +'Su ', # 0x91 +'Tun ', # 0x92 +'Juan ', # 0x93 +'Cen ', # 0x94 +'Ti ', # 0x95 +'Li ', # 0x96 +'Shui ', # 0x97 +'Si ', # 0x98 +'Lei ', # 0x99 +'Shui ', # 0x9a +'Tao ', # 0x9b +'Du ', # 0x9c +'Lao ', # 0x9d +'Lai ', # 0x9e +'Lian ', # 0x9f +'Wei ', # 0xa0 +'Wo ', # 0xa1 +'Yun ', # 0xa2 +'Huan ', # 0xa3 +'Di ', # 0xa4 +'[?] ', # 0xa5 +'Run ', # 0xa6 +'Jian ', # 0xa7 +'Zhang ', # 0xa8 +'Se ', # 0xa9 +'Fu ', # 0xaa +'Guan ', # 0xab +'Xing ', # 0xac +'Shou ', # 0xad +'Shuan ', # 0xae +'Ya ', # 0xaf +'Chuo ', # 0xb0 +'Zhang ', # 0xb1 +'Ye ', # 0xb2 +'Kong ', # 0xb3 +'Wo ', # 0xb4 +'Han ', # 0xb5 +'Tuo ', # 0xb6 +'Dong ', # 0xb7 +'He ', # 0xb8 +'Wo ', # 0xb9 +'Ju ', # 0xba +'Gan ', # 0xbb +'Liang ', # 0xbc +'Hun ', # 0xbd +'Ta ', # 0xbe +'Zhuo ', # 0xbf +'Dian ', # 0xc0 +'Qie ', # 0xc1 +'De ', # 0xc2 +'Juan ', # 0xc3 +'Zi ', # 0xc4 +'Xi ', # 0xc5 +'Yao ', # 0xc6 +'Qi ', # 0xc7 +'Gu ', # 0xc8 +'Guo ', # 0xc9 +'Han ', # 0xca +'Lin ', # 0xcb +'Tang ', # 0xcc +'Zhou ', # 0xcd +'Peng ', # 0xce +'Hao ', # 0xcf +'Chang ', # 0xd0 +'Shu ', # 0xd1 +'Qi ', # 0xd2 +'Fang ', # 0xd3 +'Chi ', # 0xd4 +'Lu ', # 0xd5 +'Nao ', # 0xd6 +'Ju ', # 0xd7 +'Tao ', # 0xd8 +'Cong ', # 0xd9 +'Lei ', # 0xda +'Zhi ', # 0xdb +'Peng ', # 0xdc +'Fei ', # 0xdd +'Song ', # 0xde +'Tian ', # 0xdf +'Pi ', # 0xe0 +'Dan ', # 0xe1 +'Yu ', # 0xe2 +'Ni ', # 0xe3 +'Yu ', # 0xe4 +'Lu ', # 0xe5 +'Gan ', # 0xe6 +'Mi ', # 0xe7 +'Jing ', # 0xe8 +'Ling ', # 0xe9 +'Lun ', # 0xea +'Yin ', # 0xeb +'Cui ', # 0xec +'Qu ', # 0xed +'Huai ', # 0xee +'Yu ', # 0xef +'Nian ', # 0xf0 +'Shen ', # 0xf1 +'Piao ', # 0xf2 +'Chun ', # 0xf3 +'Wa ', # 0xf4 +'Yuan ', # 0xf5 +'Lai ', # 0xf6 +'Hun ', # 0xf7 +'Qing ', # 0xf8 +'Yan ', # 0xf9 +'Qian ', # 0xfa +'Tian ', # 0xfb +'Miao ', # 0xfc +'Zhi ', # 0xfd +'Yin ', # 0xfe +'Mi ', # 0xff +) diff --git a/libs/unidecode/x06e.py b/libs/unidecode/x06e.py new file mode 100644 index 00000000..d4698fd4 --- /dev/null +++ b/libs/unidecode/x06e.py @@ -0,0 +1,258 @@ +data = ( +'Ben ', # 0x00 +'Yuan ', # 0x01 +'Wen ', # 0x02 +'Re ', # 0x03 +'Fei ', # 0x04 +'Qing ', # 0x05 +'Yuan ', # 0x06 +'Ke ', # 0x07 +'Ji ', # 0x08 +'She ', # 0x09 +'Yuan ', # 0x0a +'Shibui ', # 0x0b +'Lu ', # 0x0c +'Zi ', # 0x0d +'Du ', # 0x0e +'[?] ', # 0x0f +'Jian ', # 0x10 +'Min ', # 0x11 +'Pi ', # 0x12 +'Tani ', # 0x13 +'Yu ', # 0x14 +'Yuan ', # 0x15 +'Shen ', # 0x16 +'Shen ', # 0x17 +'Rou ', # 0x18 +'Huan ', # 0x19 +'Zhu ', # 0x1a +'Jian ', # 0x1b +'Nuan ', # 0x1c +'Yu ', # 0x1d +'Qiu ', # 0x1e +'Ting ', # 0x1f +'Qu ', # 0x20 +'Du ', # 0x21 +'Feng ', # 0x22 +'Zha ', # 0x23 +'Bo ', # 0x24 +'Wo ', # 0x25 +'Wo ', # 0x26 +'Di ', # 0x27 +'Wei ', # 0x28 +'Wen ', # 0x29 +'Ru ', # 0x2a +'Xie ', # 0x2b +'Ce ', # 0x2c +'Wei ', # 0x2d +'Ge ', # 0x2e +'Gang ', # 0x2f +'Yan ', # 0x30 +'Hong ', # 0x31 +'Xuan ', # 0x32 +'Mi ', # 0x33 +'Ke ', # 0x34 +'Mao ', # 0x35 +'Ying ', # 0x36 +'Yan ', # 0x37 +'You ', # 0x38 +'Hong ', # 0x39 +'Miao ', # 0x3a +'Xing ', # 0x3b +'Mei ', # 0x3c +'Zai ', # 0x3d +'Hun ', # 0x3e +'Nai ', # 0x3f +'Kui ', # 0x40 +'Shi ', # 0x41 +'E ', # 0x42 +'Pai ', # 0x43 +'Mei ', # 0x44 +'Lian ', # 0x45 +'Qi ', # 0x46 +'Qi ', # 0x47 +'Mei ', # 0x48 +'Tian ', # 0x49 +'Cou ', # 0x4a +'Wei ', # 0x4b +'Can ', # 0x4c +'Tuan ', # 0x4d +'Mian ', # 0x4e +'Hui ', # 0x4f +'Mo ', # 0x50 +'Xu ', # 0x51 +'Ji ', # 0x52 +'Pen ', # 0x53 +'Jian ', # 0x54 +'Jian ', # 0x55 +'Hu ', # 0x56 +'Feng ', # 0x57 +'Xiang ', # 0x58 +'Yi ', # 0x59 +'Yin ', # 0x5a +'Zhan ', # 0x5b +'Shi ', # 0x5c +'Jie ', # 0x5d +'Cheng ', # 0x5e +'Huang ', # 0x5f +'Tan ', # 0x60 +'Yu ', # 0x61 +'Bi ', # 0x62 +'Min ', # 0x63 +'Shi ', # 0x64 +'Tu ', # 0x65 +'Sheng ', # 0x66 +'Yong ', # 0x67 +'Qu ', # 0x68 +'Zhong ', # 0x69 +'Suei ', # 0x6a +'Jiu ', # 0x6b +'Jiao ', # 0x6c +'Qiou ', # 0x6d +'Yin ', # 0x6e +'Tang ', # 0x6f +'Long ', # 0x70 +'Huo ', # 0x71 +'Yuan ', # 0x72 +'Nan ', # 0x73 +'Ban ', # 0x74 +'You ', # 0x75 +'Quan ', # 0x76 +'Chui ', # 0x77 +'Liang ', # 0x78 +'Chan ', # 0x79 +'Yan ', # 0x7a +'Chun ', # 0x7b +'Nie ', # 0x7c +'Zi ', # 0x7d +'Wan ', # 0x7e +'Shi ', # 0x7f +'Man ', # 0x80 +'Ying ', # 0x81 +'Ratsu ', # 0x82 +'Kui ', # 0x83 +'[?] ', # 0x84 +'Jian ', # 0x85 +'Xu ', # 0x86 +'Lu ', # 0x87 +'Gui ', # 0x88 +'Gai ', # 0x89 +'[?] ', # 0x8a +'[?] ', # 0x8b +'Po ', # 0x8c +'Jin ', # 0x8d +'Gui ', # 0x8e +'Tang ', # 0x8f +'Yuan ', # 0x90 +'Suo ', # 0x91 +'Yuan ', # 0x92 +'Lian ', # 0x93 +'Yao ', # 0x94 +'Meng ', # 0x95 +'Zhun ', # 0x96 +'Sheng ', # 0x97 +'Ke ', # 0x98 +'Tai ', # 0x99 +'Da ', # 0x9a +'Wa ', # 0x9b +'Liu ', # 0x9c +'Gou ', # 0x9d +'Sao ', # 0x9e +'Ming ', # 0x9f +'Zha ', # 0xa0 +'Shi ', # 0xa1 +'Yi ', # 0xa2 +'Lun ', # 0xa3 +'Ma ', # 0xa4 +'Pu ', # 0xa5 +'Wei ', # 0xa6 +'Li ', # 0xa7 +'Cai ', # 0xa8 +'Wu ', # 0xa9 +'Xi ', # 0xaa +'Wen ', # 0xab +'Qiang ', # 0xac +'Ze ', # 0xad +'Shi ', # 0xae +'Su ', # 0xaf +'Yi ', # 0xb0 +'Zhen ', # 0xb1 +'Sou ', # 0xb2 +'Yun ', # 0xb3 +'Xiu ', # 0xb4 +'Yin ', # 0xb5 +'Rong ', # 0xb6 +'Hun ', # 0xb7 +'Su ', # 0xb8 +'Su ', # 0xb9 +'Ni ', # 0xba +'Ta ', # 0xbb +'Shi ', # 0xbc +'Ru ', # 0xbd +'Wei ', # 0xbe +'Pan ', # 0xbf +'Chu ', # 0xc0 +'Chu ', # 0xc1 +'Pang ', # 0xc2 +'Weng ', # 0xc3 +'Cang ', # 0xc4 +'Mie ', # 0xc5 +'He ', # 0xc6 +'Dian ', # 0xc7 +'Hao ', # 0xc8 +'Huang ', # 0xc9 +'Xi ', # 0xca +'Zi ', # 0xcb +'Di ', # 0xcc +'Zhi ', # 0xcd +'Ying ', # 0xce +'Fu ', # 0xcf +'Jie ', # 0xd0 +'Hua ', # 0xd1 +'Ge ', # 0xd2 +'Zi ', # 0xd3 +'Tao ', # 0xd4 +'Teng ', # 0xd5 +'Sui ', # 0xd6 +'Bi ', # 0xd7 +'Jiao ', # 0xd8 +'Hui ', # 0xd9 +'Gun ', # 0xda +'Yin ', # 0xdb +'Gao ', # 0xdc +'Long ', # 0xdd +'Zhi ', # 0xde +'Yan ', # 0xdf +'She ', # 0xe0 +'Man ', # 0xe1 +'Ying ', # 0xe2 +'Chun ', # 0xe3 +'Lu ', # 0xe4 +'Lan ', # 0xe5 +'Luan ', # 0xe6 +'[?] ', # 0xe7 +'Bin ', # 0xe8 +'Tan ', # 0xe9 +'Yu ', # 0xea +'Sou ', # 0xeb +'Hu ', # 0xec +'Bi ', # 0xed +'Biao ', # 0xee +'Zhi ', # 0xef +'Jiang ', # 0xf0 +'Kou ', # 0xf1 +'Shen ', # 0xf2 +'Shang ', # 0xf3 +'Di ', # 0xf4 +'Mi ', # 0xf5 +'Ao ', # 0xf6 +'Lu ', # 0xf7 +'Hu ', # 0xf8 +'Hu ', # 0xf9 +'You ', # 0xfa +'Chan ', # 0xfb +'Fan ', # 0xfc +'Yong ', # 0xfd +'Gun ', # 0xfe +'Man ', # 0xff +) diff --git a/libs/unidecode/x06f.py b/libs/unidecode/x06f.py new file mode 100644 index 00000000..36bf2a26 --- /dev/null +++ b/libs/unidecode/x06f.py @@ -0,0 +1,258 @@ +data = ( +'Qing ', # 0x00 +'Yu ', # 0x01 +'Piao ', # 0x02 +'Ji ', # 0x03 +'Ya ', # 0x04 +'Jiao ', # 0x05 +'Qi ', # 0x06 +'Xi ', # 0x07 +'Ji ', # 0x08 +'Lu ', # 0x09 +'Lu ', # 0x0a +'Long ', # 0x0b +'Jin ', # 0x0c +'Guo ', # 0x0d +'Cong ', # 0x0e +'Lou ', # 0x0f +'Zhi ', # 0x10 +'Gai ', # 0x11 +'Qiang ', # 0x12 +'Li ', # 0x13 +'Yan ', # 0x14 +'Cao ', # 0x15 +'Jiao ', # 0x16 +'Cong ', # 0x17 +'Qun ', # 0x18 +'Tuan ', # 0x19 +'Ou ', # 0x1a +'Teng ', # 0x1b +'Ye ', # 0x1c +'Xi ', # 0x1d +'Mi ', # 0x1e +'Tang ', # 0x1f +'Mo ', # 0x20 +'Shang ', # 0x21 +'Han ', # 0x22 +'Lian ', # 0x23 +'Lan ', # 0x24 +'Wa ', # 0x25 +'Li ', # 0x26 +'Qian ', # 0x27 +'Feng ', # 0x28 +'Xuan ', # 0x29 +'Yi ', # 0x2a +'Man ', # 0x2b +'Zi ', # 0x2c +'Mang ', # 0x2d +'Kang ', # 0x2e +'Lei ', # 0x2f +'Peng ', # 0x30 +'Shu ', # 0x31 +'Zhang ', # 0x32 +'Zhang ', # 0x33 +'Chong ', # 0x34 +'Xu ', # 0x35 +'Huan ', # 0x36 +'Kuo ', # 0x37 +'Jian ', # 0x38 +'Yan ', # 0x39 +'Chuang ', # 0x3a +'Liao ', # 0x3b +'Cui ', # 0x3c +'Ti ', # 0x3d +'Yang ', # 0x3e +'Jiang ', # 0x3f +'Cong ', # 0x40 +'Ying ', # 0x41 +'Hong ', # 0x42 +'Xun ', # 0x43 +'Shu ', # 0x44 +'Guan ', # 0x45 +'Ying ', # 0x46 +'Xiao ', # 0x47 +'[?] ', # 0x48 +'[?] ', # 0x49 +'Xu ', # 0x4a +'Lian ', # 0x4b +'Zhi ', # 0x4c +'Wei ', # 0x4d +'Pi ', # 0x4e +'Jue ', # 0x4f +'Jiao ', # 0x50 +'Po ', # 0x51 +'Dang ', # 0x52 +'Hui ', # 0x53 +'Jie ', # 0x54 +'Wu ', # 0x55 +'Pa ', # 0x56 +'Ji ', # 0x57 +'Pan ', # 0x58 +'Gui ', # 0x59 +'Xiao ', # 0x5a +'Qian ', # 0x5b +'Qian ', # 0x5c +'Xi ', # 0x5d +'Lu ', # 0x5e +'Xi ', # 0x5f +'Xuan ', # 0x60 +'Dun ', # 0x61 +'Huang ', # 0x62 +'Min ', # 0x63 +'Run ', # 0x64 +'Su ', # 0x65 +'Liao ', # 0x66 +'Zhen ', # 0x67 +'Zhong ', # 0x68 +'Yi ', # 0x69 +'Di ', # 0x6a +'Wan ', # 0x6b +'Dan ', # 0x6c +'Tan ', # 0x6d +'Chao ', # 0x6e +'Xun ', # 0x6f +'Kui ', # 0x70 +'Yie ', # 0x71 +'Shao ', # 0x72 +'Tu ', # 0x73 +'Zhu ', # 0x74 +'San ', # 0x75 +'Hei ', # 0x76 +'Bi ', # 0x77 +'Shan ', # 0x78 +'Chan ', # 0x79 +'Chan ', # 0x7a +'Shu ', # 0x7b +'Tong ', # 0x7c +'Pu ', # 0x7d +'Lin ', # 0x7e +'Wei ', # 0x7f +'Se ', # 0x80 +'Se ', # 0x81 +'Cheng ', # 0x82 +'Jiong ', # 0x83 +'Cheng ', # 0x84 +'Hua ', # 0x85 +'Jiao ', # 0x86 +'Lao ', # 0x87 +'Che ', # 0x88 +'Gan ', # 0x89 +'Cun ', # 0x8a +'Heng ', # 0x8b +'Si ', # 0x8c +'Shu ', # 0x8d +'Peng ', # 0x8e +'Han ', # 0x8f +'Yun ', # 0x90 +'Liu ', # 0x91 +'Hong ', # 0x92 +'Fu ', # 0x93 +'Hao ', # 0x94 +'He ', # 0x95 +'Xian ', # 0x96 +'Jian ', # 0x97 +'Shan ', # 0x98 +'Xi ', # 0x99 +'Oki ', # 0x9a +'[?] ', # 0x9b +'Lan ', # 0x9c +'[?] ', # 0x9d +'Yu ', # 0x9e +'Lin ', # 0x9f +'Min ', # 0xa0 +'Zao ', # 0xa1 +'Dang ', # 0xa2 +'Wan ', # 0xa3 +'Ze ', # 0xa4 +'Xie ', # 0xa5 +'Yu ', # 0xa6 +'Li ', # 0xa7 +'Shi ', # 0xa8 +'Xue ', # 0xa9 +'Ling ', # 0xaa +'Man ', # 0xab +'Zi ', # 0xac +'Yong ', # 0xad +'Kuai ', # 0xae +'Can ', # 0xaf +'Lian ', # 0xb0 +'Dian ', # 0xb1 +'Ye ', # 0xb2 +'Ao ', # 0xb3 +'Huan ', # 0xb4 +'Zhen ', # 0xb5 +'Chan ', # 0xb6 +'Man ', # 0xb7 +'Dan ', # 0xb8 +'Dan ', # 0xb9 +'Yi ', # 0xba +'Sui ', # 0xbb +'Pi ', # 0xbc +'Ju ', # 0xbd +'Ta ', # 0xbe +'Qin ', # 0xbf +'Ji ', # 0xc0 +'Zhuo ', # 0xc1 +'Lian ', # 0xc2 +'Nong ', # 0xc3 +'Guo ', # 0xc4 +'Jin ', # 0xc5 +'Fen ', # 0xc6 +'Se ', # 0xc7 +'Ji ', # 0xc8 +'Sui ', # 0xc9 +'Hui ', # 0xca +'Chu ', # 0xcb +'Ta ', # 0xcc +'Song ', # 0xcd +'Ding ', # 0xce +'[?] ', # 0xcf +'Zhu ', # 0xd0 +'Lai ', # 0xd1 +'Bin ', # 0xd2 +'Lian ', # 0xd3 +'Mi ', # 0xd4 +'Shi ', # 0xd5 +'Shu ', # 0xd6 +'Mi ', # 0xd7 +'Ning ', # 0xd8 +'Ying ', # 0xd9 +'Ying ', # 0xda +'Meng ', # 0xdb +'Jin ', # 0xdc +'Qi ', # 0xdd +'Pi ', # 0xde +'Ji ', # 0xdf +'Hao ', # 0xe0 +'Ru ', # 0xe1 +'Zui ', # 0xe2 +'Wo ', # 0xe3 +'Tao ', # 0xe4 +'Yin ', # 0xe5 +'Yin ', # 0xe6 +'Dui ', # 0xe7 +'Ci ', # 0xe8 +'Huo ', # 0xe9 +'Jing ', # 0xea +'Lan ', # 0xeb +'Jun ', # 0xec +'Ai ', # 0xed +'Pu ', # 0xee +'Zhuo ', # 0xef +'Wei ', # 0xf0 +'Bin ', # 0xf1 +'Gu ', # 0xf2 +'Qian ', # 0xf3 +'Xing ', # 0xf4 +'Hama ', # 0xf5 +'Kuo ', # 0xf6 +'Fei ', # 0xf7 +'[?] ', # 0xf8 +'Boku ', # 0xf9 +'Jian ', # 0xfa +'Wei ', # 0xfb +'Luo ', # 0xfc +'Zan ', # 0xfd +'Lu ', # 0xfe +'Li ', # 0xff +) diff --git a/libs/unidecode/x070.py b/libs/unidecode/x070.py new file mode 100644 index 00000000..b12567ff --- /dev/null +++ b/libs/unidecode/x070.py @@ -0,0 +1,258 @@ +data = ( +'You ', # 0x00 +'Yang ', # 0x01 +'Lu ', # 0x02 +'Si ', # 0x03 +'Jie ', # 0x04 +'Ying ', # 0x05 +'Du ', # 0x06 +'Wang ', # 0x07 +'Hui ', # 0x08 +'Xie ', # 0x09 +'Pan ', # 0x0a +'Shen ', # 0x0b +'Biao ', # 0x0c +'Chan ', # 0x0d +'Mo ', # 0x0e +'Liu ', # 0x0f +'Jian ', # 0x10 +'Pu ', # 0x11 +'Se ', # 0x12 +'Cheng ', # 0x13 +'Gu ', # 0x14 +'Bin ', # 0x15 +'Huo ', # 0x16 +'Xian ', # 0x17 +'Lu ', # 0x18 +'Qin ', # 0x19 +'Han ', # 0x1a +'Ying ', # 0x1b +'Yong ', # 0x1c +'Li ', # 0x1d +'Jing ', # 0x1e +'Xiao ', # 0x1f +'Ying ', # 0x20 +'Sui ', # 0x21 +'Wei ', # 0x22 +'Xie ', # 0x23 +'Huai ', # 0x24 +'Hao ', # 0x25 +'Zhu ', # 0x26 +'Long ', # 0x27 +'Lai ', # 0x28 +'Dui ', # 0x29 +'Fan ', # 0x2a +'Hu ', # 0x2b +'Lai ', # 0x2c +'[?] ', # 0x2d +'[?] ', # 0x2e +'Ying ', # 0x2f +'Mi ', # 0x30 +'Ji ', # 0x31 +'Lian ', # 0x32 +'Jian ', # 0x33 +'Ying ', # 0x34 +'Fen ', # 0x35 +'Lin ', # 0x36 +'Yi ', # 0x37 +'Jian ', # 0x38 +'Yue ', # 0x39 +'Chan ', # 0x3a +'Dai ', # 0x3b +'Rang ', # 0x3c +'Jian ', # 0x3d +'Lan ', # 0x3e +'Fan ', # 0x3f +'Shuang ', # 0x40 +'Yuan ', # 0x41 +'Zhuo ', # 0x42 +'Feng ', # 0x43 +'She ', # 0x44 +'Lei ', # 0x45 +'Lan ', # 0x46 +'Cong ', # 0x47 +'Qu ', # 0x48 +'Yong ', # 0x49 +'Qian ', # 0x4a +'Fa ', # 0x4b +'Guan ', # 0x4c +'Que ', # 0x4d +'Yan ', # 0x4e +'Hao ', # 0x4f +'Hyeng ', # 0x50 +'Sa ', # 0x51 +'Zan ', # 0x52 +'Luan ', # 0x53 +'Yan ', # 0x54 +'Li ', # 0x55 +'Mi ', # 0x56 +'Shan ', # 0x57 +'Tan ', # 0x58 +'Dang ', # 0x59 +'Jiao ', # 0x5a +'Chan ', # 0x5b +'[?] ', # 0x5c +'Hao ', # 0x5d +'Ba ', # 0x5e +'Zhu ', # 0x5f +'Lan ', # 0x60 +'Lan ', # 0x61 +'Nang ', # 0x62 +'Wan ', # 0x63 +'Luan ', # 0x64 +'Xun ', # 0x65 +'Xian ', # 0x66 +'Yan ', # 0x67 +'Gan ', # 0x68 +'Yan ', # 0x69 +'Yu ', # 0x6a +'Huo ', # 0x6b +'Si ', # 0x6c +'Mie ', # 0x6d +'Guang ', # 0x6e +'Deng ', # 0x6f +'Hui ', # 0x70 +'Xiao ', # 0x71 +'Xiao ', # 0x72 +'Hu ', # 0x73 +'Hong ', # 0x74 +'Ling ', # 0x75 +'Zao ', # 0x76 +'Zhuan ', # 0x77 +'Jiu ', # 0x78 +'Zha ', # 0x79 +'Xie ', # 0x7a +'Chi ', # 0x7b +'Zhuo ', # 0x7c +'Zai ', # 0x7d +'Zai ', # 0x7e +'Can ', # 0x7f +'Yang ', # 0x80 +'Qi ', # 0x81 +'Zhong ', # 0x82 +'Fen ', # 0x83 +'Niu ', # 0x84 +'Jiong ', # 0x85 +'Wen ', # 0x86 +'Po ', # 0x87 +'Yi ', # 0x88 +'Lu ', # 0x89 +'Chui ', # 0x8a +'Pi ', # 0x8b +'Kai ', # 0x8c +'Pan ', # 0x8d +'Yan ', # 0x8e +'Kai ', # 0x8f +'Pang ', # 0x90 +'Mu ', # 0x91 +'Chao ', # 0x92 +'Liao ', # 0x93 +'Gui ', # 0x94 +'Kang ', # 0x95 +'Tun ', # 0x96 +'Guang ', # 0x97 +'Xin ', # 0x98 +'Zhi ', # 0x99 +'Guang ', # 0x9a +'Guang ', # 0x9b +'Wei ', # 0x9c +'Qiang ', # 0x9d +'[?] ', # 0x9e +'Da ', # 0x9f +'Xia ', # 0xa0 +'Zheng ', # 0xa1 +'Zhu ', # 0xa2 +'Ke ', # 0xa3 +'Zhao ', # 0xa4 +'Fu ', # 0xa5 +'Ba ', # 0xa6 +'Duo ', # 0xa7 +'Duo ', # 0xa8 +'Ling ', # 0xa9 +'Zhuo ', # 0xaa +'Xuan ', # 0xab +'Ju ', # 0xac +'Tan ', # 0xad +'Pao ', # 0xae +'Jiong ', # 0xaf +'Pao ', # 0xb0 +'Tai ', # 0xb1 +'Tai ', # 0xb2 +'Bing ', # 0xb3 +'Yang ', # 0xb4 +'Tong ', # 0xb5 +'Han ', # 0xb6 +'Zhu ', # 0xb7 +'Zha ', # 0xb8 +'Dian ', # 0xb9 +'Wei ', # 0xba +'Shi ', # 0xbb +'Lian ', # 0xbc +'Chi ', # 0xbd +'Huang ', # 0xbe +'[?] ', # 0xbf +'Hu ', # 0xc0 +'Shuo ', # 0xc1 +'Lan ', # 0xc2 +'Jing ', # 0xc3 +'Jiao ', # 0xc4 +'Xu ', # 0xc5 +'Xing ', # 0xc6 +'Quan ', # 0xc7 +'Lie ', # 0xc8 +'Huan ', # 0xc9 +'Yang ', # 0xca +'Xiao ', # 0xcb +'Xiu ', # 0xcc +'Xian ', # 0xcd +'Yin ', # 0xce +'Wu ', # 0xcf +'Zhou ', # 0xd0 +'Yao ', # 0xd1 +'Shi ', # 0xd2 +'Wei ', # 0xd3 +'Tong ', # 0xd4 +'Xue ', # 0xd5 +'Zai ', # 0xd6 +'Kai ', # 0xd7 +'Hong ', # 0xd8 +'Luo ', # 0xd9 +'Xia ', # 0xda +'Zhu ', # 0xdb +'Xuan ', # 0xdc +'Zheng ', # 0xdd +'Po ', # 0xde +'Yan ', # 0xdf +'Hui ', # 0xe0 +'Guang ', # 0xe1 +'Zhe ', # 0xe2 +'Hui ', # 0xe3 +'Kao ', # 0xe4 +'[?] ', # 0xe5 +'Fan ', # 0xe6 +'Shao ', # 0xe7 +'Ye ', # 0xe8 +'Hui ', # 0xe9 +'[?] ', # 0xea +'Tang ', # 0xeb +'Jin ', # 0xec +'Re ', # 0xed +'[?] ', # 0xee +'Xi ', # 0xef +'Fu ', # 0xf0 +'Jiong ', # 0xf1 +'Che ', # 0xf2 +'Pu ', # 0xf3 +'Jing ', # 0xf4 +'Zhuo ', # 0xf5 +'Ting ', # 0xf6 +'Wan ', # 0xf7 +'Hai ', # 0xf8 +'Peng ', # 0xf9 +'Lang ', # 0xfa +'Shan ', # 0xfb +'Hu ', # 0xfc +'Feng ', # 0xfd +'Chi ', # 0xfe +'Rong ', # 0xff +) diff --git a/libs/unidecode/x071.py b/libs/unidecode/x071.py new file mode 100644 index 00000000..bad8f7ea --- /dev/null +++ b/libs/unidecode/x071.py @@ -0,0 +1,258 @@ +data = ( +'Hu ', # 0x00 +'Xi ', # 0x01 +'Shu ', # 0x02 +'He ', # 0x03 +'Xun ', # 0x04 +'Ku ', # 0x05 +'Jue ', # 0x06 +'Xiao ', # 0x07 +'Xi ', # 0x08 +'Yan ', # 0x09 +'Han ', # 0x0a +'Zhuang ', # 0x0b +'Jun ', # 0x0c +'Di ', # 0x0d +'Xie ', # 0x0e +'Ji ', # 0x0f +'Wu ', # 0x10 +'[?] ', # 0x11 +'[?] ', # 0x12 +'Han ', # 0x13 +'Yan ', # 0x14 +'Huan ', # 0x15 +'Men ', # 0x16 +'Ju ', # 0x17 +'Chou ', # 0x18 +'Bei ', # 0x19 +'Fen ', # 0x1a +'Lin ', # 0x1b +'Kun ', # 0x1c +'Hun ', # 0x1d +'Tun ', # 0x1e +'Xi ', # 0x1f +'Cui ', # 0x20 +'Wu ', # 0x21 +'Hong ', # 0x22 +'Ju ', # 0x23 +'Fu ', # 0x24 +'Wo ', # 0x25 +'Jiao ', # 0x26 +'Cong ', # 0x27 +'Feng ', # 0x28 +'Ping ', # 0x29 +'Qiong ', # 0x2a +'Ruo ', # 0x2b +'Xi ', # 0x2c +'Qiong ', # 0x2d +'Xin ', # 0x2e +'Zhuo ', # 0x2f +'Yan ', # 0x30 +'Yan ', # 0x31 +'Yi ', # 0x32 +'Jue ', # 0x33 +'Yu ', # 0x34 +'Gang ', # 0x35 +'Ran ', # 0x36 +'Pi ', # 0x37 +'Gu ', # 0x38 +'[?] ', # 0x39 +'Sheng ', # 0x3a +'Chang ', # 0x3b +'Shao ', # 0x3c +'[?] ', # 0x3d +'[?] ', # 0x3e +'[?] ', # 0x3f +'[?] ', # 0x40 +'Chen ', # 0x41 +'He ', # 0x42 +'Kui ', # 0x43 +'Zhong ', # 0x44 +'Duan ', # 0x45 +'Xia ', # 0x46 +'Hui ', # 0x47 +'Feng ', # 0x48 +'Lian ', # 0x49 +'Xuan ', # 0x4a +'Xing ', # 0x4b +'Huang ', # 0x4c +'Jiao ', # 0x4d +'Jian ', # 0x4e +'Bi ', # 0x4f +'Ying ', # 0x50 +'Zhu ', # 0x51 +'Wei ', # 0x52 +'Tuan ', # 0x53 +'Tian ', # 0x54 +'Xi ', # 0x55 +'Nuan ', # 0x56 +'Nuan ', # 0x57 +'Chan ', # 0x58 +'Yan ', # 0x59 +'Jiong ', # 0x5a +'Jiong ', # 0x5b +'Yu ', # 0x5c +'Mei ', # 0x5d +'Sha ', # 0x5e +'Wei ', # 0x5f +'Ye ', # 0x60 +'Xin ', # 0x61 +'Qiong ', # 0x62 +'Rou ', # 0x63 +'Mei ', # 0x64 +'Huan ', # 0x65 +'Xu ', # 0x66 +'Zhao ', # 0x67 +'Wei ', # 0x68 +'Fan ', # 0x69 +'Qiu ', # 0x6a +'Sui ', # 0x6b +'Yang ', # 0x6c +'Lie ', # 0x6d +'Zhu ', # 0x6e +'Jie ', # 0x6f +'Gao ', # 0x70 +'Gua ', # 0x71 +'Bao ', # 0x72 +'Hu ', # 0x73 +'Yun ', # 0x74 +'Xia ', # 0x75 +'[?] ', # 0x76 +'[?] ', # 0x77 +'Bian ', # 0x78 +'Gou ', # 0x79 +'Tui ', # 0x7a +'Tang ', # 0x7b +'Chao ', # 0x7c +'Shan ', # 0x7d +'N ', # 0x7e +'Bo ', # 0x7f +'Huang ', # 0x80 +'Xie ', # 0x81 +'Xi ', # 0x82 +'Wu ', # 0x83 +'Xi ', # 0x84 +'Yun ', # 0x85 +'He ', # 0x86 +'He ', # 0x87 +'Xi ', # 0x88 +'Yun ', # 0x89 +'Xiong ', # 0x8a +'Nai ', # 0x8b +'Shan ', # 0x8c +'Qiong ', # 0x8d +'Yao ', # 0x8e +'Xun ', # 0x8f +'Mi ', # 0x90 +'Lian ', # 0x91 +'Ying ', # 0x92 +'Wen ', # 0x93 +'Rong ', # 0x94 +'Oozutsu ', # 0x95 +'[?] ', # 0x96 +'Qiang ', # 0x97 +'Liu ', # 0x98 +'Xi ', # 0x99 +'Bi ', # 0x9a +'Biao ', # 0x9b +'Zong ', # 0x9c +'Lu ', # 0x9d +'Jian ', # 0x9e +'Shou ', # 0x9f +'Yi ', # 0xa0 +'Lou ', # 0xa1 +'Feng ', # 0xa2 +'Sui ', # 0xa3 +'Yi ', # 0xa4 +'Tong ', # 0xa5 +'Jue ', # 0xa6 +'Zong ', # 0xa7 +'Yun ', # 0xa8 +'Hu ', # 0xa9 +'Yi ', # 0xaa +'Zhi ', # 0xab +'Ao ', # 0xac +'Wei ', # 0xad +'Liao ', # 0xae +'Han ', # 0xaf +'Ou ', # 0xb0 +'Re ', # 0xb1 +'Jiong ', # 0xb2 +'Man ', # 0xb3 +'[?] ', # 0xb4 +'Shang ', # 0xb5 +'Cuan ', # 0xb6 +'Zeng ', # 0xb7 +'Jian ', # 0xb8 +'Xi ', # 0xb9 +'Xi ', # 0xba +'Xi ', # 0xbb +'Yi ', # 0xbc +'Xiao ', # 0xbd +'Chi ', # 0xbe +'Huang ', # 0xbf +'Chan ', # 0xc0 +'Ye ', # 0xc1 +'Qian ', # 0xc2 +'Ran ', # 0xc3 +'Yan ', # 0xc4 +'Xian ', # 0xc5 +'Qiao ', # 0xc6 +'Zun ', # 0xc7 +'Deng ', # 0xc8 +'Dun ', # 0xc9 +'Shen ', # 0xca +'Jiao ', # 0xcb +'Fen ', # 0xcc +'Si ', # 0xcd +'Liao ', # 0xce +'Yu ', # 0xcf +'Lin ', # 0xd0 +'Tong ', # 0xd1 +'Shao ', # 0xd2 +'Fen ', # 0xd3 +'Fan ', # 0xd4 +'Yan ', # 0xd5 +'Xun ', # 0xd6 +'Lan ', # 0xd7 +'Mei ', # 0xd8 +'Tang ', # 0xd9 +'Yi ', # 0xda +'Jing ', # 0xdb +'Men ', # 0xdc +'[?] ', # 0xdd +'[?] ', # 0xde +'Ying ', # 0xdf +'Yu ', # 0xe0 +'Yi ', # 0xe1 +'Xue ', # 0xe2 +'Lan ', # 0xe3 +'Tai ', # 0xe4 +'Zao ', # 0xe5 +'Can ', # 0xe6 +'Sui ', # 0xe7 +'Xi ', # 0xe8 +'Que ', # 0xe9 +'Cong ', # 0xea +'Lian ', # 0xeb +'Hui ', # 0xec +'Zhu ', # 0xed +'Xie ', # 0xee +'Ling ', # 0xef +'Wei ', # 0xf0 +'Yi ', # 0xf1 +'Xie ', # 0xf2 +'Zhao ', # 0xf3 +'Hui ', # 0xf4 +'Tatsu ', # 0xf5 +'Nung ', # 0xf6 +'Lan ', # 0xf7 +'Ru ', # 0xf8 +'Xian ', # 0xf9 +'Kao ', # 0xfa +'Xun ', # 0xfb +'Jin ', # 0xfc +'Chou ', # 0xfd +'Chou ', # 0xfe +'Yao ', # 0xff +) diff --git a/libs/unidecode/x072.py b/libs/unidecode/x072.py new file mode 100644 index 00000000..c91c93cb --- /dev/null +++ b/libs/unidecode/x072.py @@ -0,0 +1,258 @@ +data = ( +'He ', # 0x00 +'Lan ', # 0x01 +'Biao ', # 0x02 +'Rong ', # 0x03 +'Li ', # 0x04 +'Mo ', # 0x05 +'Bao ', # 0x06 +'Ruo ', # 0x07 +'Lu ', # 0x08 +'La ', # 0x09 +'Ao ', # 0x0a +'Xun ', # 0x0b +'Kuang ', # 0x0c +'Shuo ', # 0x0d +'[?] ', # 0x0e +'Li ', # 0x0f +'Lu ', # 0x10 +'Jue ', # 0x11 +'Liao ', # 0x12 +'Yan ', # 0x13 +'Xi ', # 0x14 +'Xie ', # 0x15 +'Long ', # 0x16 +'Ye ', # 0x17 +'[?] ', # 0x18 +'Rang ', # 0x19 +'Yue ', # 0x1a +'Lan ', # 0x1b +'Cong ', # 0x1c +'Jue ', # 0x1d +'Tong ', # 0x1e +'Guan ', # 0x1f +'[?] ', # 0x20 +'Che ', # 0x21 +'Mi ', # 0x22 +'Tang ', # 0x23 +'Lan ', # 0x24 +'Zhu ', # 0x25 +'[?] ', # 0x26 +'Ling ', # 0x27 +'Cuan ', # 0x28 +'Yu ', # 0x29 +'Zhua ', # 0x2a +'Tsumekanmuri ', # 0x2b +'Pa ', # 0x2c +'Zheng ', # 0x2d +'Pao ', # 0x2e +'Cheng ', # 0x2f +'Yuan ', # 0x30 +'Ai ', # 0x31 +'Wei ', # 0x32 +'[?] ', # 0x33 +'Jue ', # 0x34 +'Jue ', # 0x35 +'Fu ', # 0x36 +'Ye ', # 0x37 +'Ba ', # 0x38 +'Die ', # 0x39 +'Ye ', # 0x3a +'Yao ', # 0x3b +'Zu ', # 0x3c +'Shuang ', # 0x3d +'Er ', # 0x3e +'Qiang ', # 0x3f +'Chuang ', # 0x40 +'Ge ', # 0x41 +'Zang ', # 0x42 +'Die ', # 0x43 +'Qiang ', # 0x44 +'Yong ', # 0x45 +'Qiang ', # 0x46 +'Pian ', # 0x47 +'Ban ', # 0x48 +'Pan ', # 0x49 +'Shao ', # 0x4a +'Jian ', # 0x4b +'Pai ', # 0x4c +'Du ', # 0x4d +'Chuang ', # 0x4e +'Tou ', # 0x4f +'Zha ', # 0x50 +'Bian ', # 0x51 +'Die ', # 0x52 +'Bang ', # 0x53 +'Bo ', # 0x54 +'Chuang ', # 0x55 +'You ', # 0x56 +'[?] ', # 0x57 +'Du ', # 0x58 +'Ya ', # 0x59 +'Cheng ', # 0x5a +'Niu ', # 0x5b +'Ushihen ', # 0x5c +'Pin ', # 0x5d +'Jiu ', # 0x5e +'Mou ', # 0x5f +'Tuo ', # 0x60 +'Mu ', # 0x61 +'Lao ', # 0x62 +'Ren ', # 0x63 +'Mang ', # 0x64 +'Fang ', # 0x65 +'Mao ', # 0x66 +'Mu ', # 0x67 +'Gang ', # 0x68 +'Wu ', # 0x69 +'Yan ', # 0x6a +'Ge ', # 0x6b +'Bei ', # 0x6c +'Si ', # 0x6d +'Jian ', # 0x6e +'Gu ', # 0x6f +'You ', # 0x70 +'Ge ', # 0x71 +'Sheng ', # 0x72 +'Mu ', # 0x73 +'Di ', # 0x74 +'Qian ', # 0x75 +'Quan ', # 0x76 +'Quan ', # 0x77 +'Zi ', # 0x78 +'Te ', # 0x79 +'Xi ', # 0x7a +'Mang ', # 0x7b +'Keng ', # 0x7c +'Qian ', # 0x7d +'Wu ', # 0x7e +'Gu ', # 0x7f +'Xi ', # 0x80 +'Li ', # 0x81 +'Li ', # 0x82 +'Pou ', # 0x83 +'Ji ', # 0x84 +'Gang ', # 0x85 +'Zhi ', # 0x86 +'Ben ', # 0x87 +'Quan ', # 0x88 +'Run ', # 0x89 +'Du ', # 0x8a +'Ju ', # 0x8b +'Jia ', # 0x8c +'Jian ', # 0x8d +'Feng ', # 0x8e +'Pian ', # 0x8f +'Ke ', # 0x90 +'Ju ', # 0x91 +'Kao ', # 0x92 +'Chu ', # 0x93 +'Xi ', # 0x94 +'Bei ', # 0x95 +'Luo ', # 0x96 +'Jie ', # 0x97 +'Ma ', # 0x98 +'San ', # 0x99 +'Wei ', # 0x9a +'Li ', # 0x9b +'Dun ', # 0x9c +'Tong ', # 0x9d +'[?] ', # 0x9e +'Jiang ', # 0x9f +'Ikenie ', # 0xa0 +'Li ', # 0xa1 +'Du ', # 0xa2 +'Lie ', # 0xa3 +'Pi ', # 0xa4 +'Piao ', # 0xa5 +'Bao ', # 0xa6 +'Xi ', # 0xa7 +'Chou ', # 0xa8 +'Wei ', # 0xa9 +'Kui ', # 0xaa +'Chou ', # 0xab +'Quan ', # 0xac +'Fan ', # 0xad +'Ba ', # 0xae +'Fan ', # 0xaf +'Qiu ', # 0xb0 +'Ji ', # 0xb1 +'Cai ', # 0xb2 +'Chuo ', # 0xb3 +'An ', # 0xb4 +'Jie ', # 0xb5 +'Zhuang ', # 0xb6 +'Guang ', # 0xb7 +'Ma ', # 0xb8 +'You ', # 0xb9 +'Kang ', # 0xba +'Bo ', # 0xbb +'Hou ', # 0xbc +'Ya ', # 0xbd +'Yin ', # 0xbe +'Huan ', # 0xbf +'Zhuang ', # 0xc0 +'Yun ', # 0xc1 +'Kuang ', # 0xc2 +'Niu ', # 0xc3 +'Di ', # 0xc4 +'Qing ', # 0xc5 +'Zhong ', # 0xc6 +'Mu ', # 0xc7 +'Bei ', # 0xc8 +'Pi ', # 0xc9 +'Ju ', # 0xca +'Ni ', # 0xcb +'Sheng ', # 0xcc +'Pao ', # 0xcd +'Xia ', # 0xce +'Tuo ', # 0xcf +'Hu ', # 0xd0 +'Ling ', # 0xd1 +'Fei ', # 0xd2 +'Pi ', # 0xd3 +'Ni ', # 0xd4 +'Ao ', # 0xd5 +'You ', # 0xd6 +'Gou ', # 0xd7 +'Yue ', # 0xd8 +'Ju ', # 0xd9 +'Dan ', # 0xda +'Po ', # 0xdb +'Gu ', # 0xdc +'Xian ', # 0xdd +'Ning ', # 0xde +'Huan ', # 0xdf +'Hen ', # 0xe0 +'Jiao ', # 0xe1 +'He ', # 0xe2 +'Zhao ', # 0xe3 +'Ji ', # 0xe4 +'Xun ', # 0xe5 +'Shan ', # 0xe6 +'Ta ', # 0xe7 +'Rong ', # 0xe8 +'Shou ', # 0xe9 +'Tong ', # 0xea +'Lao ', # 0xeb +'Du ', # 0xec +'Xia ', # 0xed +'Shi ', # 0xee +'Hua ', # 0xef +'Zheng ', # 0xf0 +'Yu ', # 0xf1 +'Sun ', # 0xf2 +'Yu ', # 0xf3 +'Bi ', # 0xf4 +'Mang ', # 0xf5 +'Xi ', # 0xf6 +'Juan ', # 0xf7 +'Li ', # 0xf8 +'Xia ', # 0xf9 +'Yin ', # 0xfa +'Suan ', # 0xfb +'Lang ', # 0xfc +'Bei ', # 0xfd +'Zhi ', # 0xfe +'Yan ', # 0xff +) diff --git a/libs/unidecode/x073.py b/libs/unidecode/x073.py new file mode 100644 index 00000000..4cf0176d --- /dev/null +++ b/libs/unidecode/x073.py @@ -0,0 +1,258 @@ +data = ( +'Sha ', # 0x00 +'Li ', # 0x01 +'Han ', # 0x02 +'Xian ', # 0x03 +'Jing ', # 0x04 +'Pai ', # 0x05 +'Fei ', # 0x06 +'Yao ', # 0x07 +'Ba ', # 0x08 +'Qi ', # 0x09 +'Ni ', # 0x0a +'Biao ', # 0x0b +'Yin ', # 0x0c +'Lai ', # 0x0d +'Xi ', # 0x0e +'Jian ', # 0x0f +'Qiang ', # 0x10 +'Kun ', # 0x11 +'Yan ', # 0x12 +'Guo ', # 0x13 +'Zong ', # 0x14 +'Mi ', # 0x15 +'Chang ', # 0x16 +'Yi ', # 0x17 +'Zhi ', # 0x18 +'Zheng ', # 0x19 +'Ya ', # 0x1a +'Meng ', # 0x1b +'Cai ', # 0x1c +'Cu ', # 0x1d +'She ', # 0x1e +'Kari ', # 0x1f +'Cen ', # 0x20 +'Luo ', # 0x21 +'Hu ', # 0x22 +'Zong ', # 0x23 +'Ji ', # 0x24 +'Wei ', # 0x25 +'Feng ', # 0x26 +'Wo ', # 0x27 +'Yuan ', # 0x28 +'Xing ', # 0x29 +'Zhu ', # 0x2a +'Mao ', # 0x2b +'Wei ', # 0x2c +'Yuan ', # 0x2d +'Xian ', # 0x2e +'Tuan ', # 0x2f +'Ya ', # 0x30 +'Nao ', # 0x31 +'Xie ', # 0x32 +'Jia ', # 0x33 +'Hou ', # 0x34 +'Bian ', # 0x35 +'You ', # 0x36 +'You ', # 0x37 +'Mei ', # 0x38 +'Zha ', # 0x39 +'Yao ', # 0x3a +'Sun ', # 0x3b +'Bo ', # 0x3c +'Ming ', # 0x3d +'Hua ', # 0x3e +'Yuan ', # 0x3f +'Sou ', # 0x40 +'Ma ', # 0x41 +'Yuan ', # 0x42 +'Dai ', # 0x43 +'Yu ', # 0x44 +'Shi ', # 0x45 +'Hao ', # 0x46 +'[?] ', # 0x47 +'Yi ', # 0x48 +'Zhen ', # 0x49 +'Chuang ', # 0x4a +'Hao ', # 0x4b +'Man ', # 0x4c +'Jing ', # 0x4d +'Jiang ', # 0x4e +'Mu ', # 0x4f +'Zhang ', # 0x50 +'Chan ', # 0x51 +'Ao ', # 0x52 +'Ao ', # 0x53 +'Hao ', # 0x54 +'Cui ', # 0x55 +'Fen ', # 0x56 +'Jue ', # 0x57 +'Bi ', # 0x58 +'Bi ', # 0x59 +'Huang ', # 0x5a +'Pu ', # 0x5b +'Lin ', # 0x5c +'Yu ', # 0x5d +'Tong ', # 0x5e +'Yao ', # 0x5f +'Liao ', # 0x60 +'Shuo ', # 0x61 +'Xiao ', # 0x62 +'Swu ', # 0x63 +'Ton ', # 0x64 +'Xi ', # 0x65 +'Ge ', # 0x66 +'Juan ', # 0x67 +'Du ', # 0x68 +'Hui ', # 0x69 +'Kuai ', # 0x6a +'Xian ', # 0x6b +'Xie ', # 0x6c +'Ta ', # 0x6d +'Xian ', # 0x6e +'Xun ', # 0x6f +'Ning ', # 0x70 +'Pin ', # 0x71 +'Huo ', # 0x72 +'Nou ', # 0x73 +'Meng ', # 0x74 +'Lie ', # 0x75 +'Nao ', # 0x76 +'Guang ', # 0x77 +'Shou ', # 0x78 +'Lu ', # 0x79 +'Ta ', # 0x7a +'Xian ', # 0x7b +'Mi ', # 0x7c +'Rang ', # 0x7d +'Huan ', # 0x7e +'Nao ', # 0x7f +'Luo ', # 0x80 +'Xian ', # 0x81 +'Qi ', # 0x82 +'Jue ', # 0x83 +'Xuan ', # 0x84 +'Miao ', # 0x85 +'Zi ', # 0x86 +'Lu ', # 0x87 +'Lu ', # 0x88 +'Yu ', # 0x89 +'Su ', # 0x8a +'Wang ', # 0x8b +'Qiu ', # 0x8c +'Ga ', # 0x8d +'Ding ', # 0x8e +'Le ', # 0x8f +'Ba ', # 0x90 +'Ji ', # 0x91 +'Hong ', # 0x92 +'Di ', # 0x93 +'Quan ', # 0x94 +'Gan ', # 0x95 +'Jiu ', # 0x96 +'Yu ', # 0x97 +'Ji ', # 0x98 +'Yu ', # 0x99 +'Yang ', # 0x9a +'Ma ', # 0x9b +'Gong ', # 0x9c +'Wu ', # 0x9d +'Fu ', # 0x9e +'Wen ', # 0x9f +'Jie ', # 0xa0 +'Ya ', # 0xa1 +'Fen ', # 0xa2 +'Bian ', # 0xa3 +'Beng ', # 0xa4 +'Yue ', # 0xa5 +'Jue ', # 0xa6 +'Yun ', # 0xa7 +'Jue ', # 0xa8 +'Wan ', # 0xa9 +'Jian ', # 0xaa +'Mei ', # 0xab +'Dan ', # 0xac +'Pi ', # 0xad +'Wei ', # 0xae +'Huan ', # 0xaf +'Xian ', # 0xb0 +'Qiang ', # 0xb1 +'Ling ', # 0xb2 +'Dai ', # 0xb3 +'Yi ', # 0xb4 +'An ', # 0xb5 +'Ping ', # 0xb6 +'Dian ', # 0xb7 +'Fu ', # 0xb8 +'Xuan ', # 0xb9 +'Xi ', # 0xba +'Bo ', # 0xbb +'Ci ', # 0xbc +'Gou ', # 0xbd +'Jia ', # 0xbe +'Shao ', # 0xbf +'Po ', # 0xc0 +'Ci ', # 0xc1 +'Ke ', # 0xc2 +'Ran ', # 0xc3 +'Sheng ', # 0xc4 +'Shen ', # 0xc5 +'Yi ', # 0xc6 +'Zu ', # 0xc7 +'Jia ', # 0xc8 +'Min ', # 0xc9 +'Shan ', # 0xca +'Liu ', # 0xcb +'Bi ', # 0xcc +'Zhen ', # 0xcd +'Zhen ', # 0xce +'Jue ', # 0xcf +'Fa ', # 0xd0 +'Long ', # 0xd1 +'Jin ', # 0xd2 +'Jiao ', # 0xd3 +'Jian ', # 0xd4 +'Li ', # 0xd5 +'Guang ', # 0xd6 +'Xian ', # 0xd7 +'Zhou ', # 0xd8 +'Gong ', # 0xd9 +'Yan ', # 0xda +'Xiu ', # 0xdb +'Yang ', # 0xdc +'Xu ', # 0xdd +'Luo ', # 0xde +'Su ', # 0xdf +'Zhu ', # 0xe0 +'Qin ', # 0xe1 +'Ken ', # 0xe2 +'Xun ', # 0xe3 +'Bao ', # 0xe4 +'Er ', # 0xe5 +'Xiang ', # 0xe6 +'Yao ', # 0xe7 +'Xia ', # 0xe8 +'Heng ', # 0xe9 +'Gui ', # 0xea +'Chong ', # 0xeb +'Xu ', # 0xec +'Ban ', # 0xed +'Pei ', # 0xee +'[?] ', # 0xef +'Dang ', # 0xf0 +'Ei ', # 0xf1 +'Hun ', # 0xf2 +'Wen ', # 0xf3 +'E ', # 0xf4 +'Cheng ', # 0xf5 +'Ti ', # 0xf6 +'Wu ', # 0xf7 +'Wu ', # 0xf8 +'Cheng ', # 0xf9 +'Jun ', # 0xfa +'Mei ', # 0xfb +'Bei ', # 0xfc +'Ting ', # 0xfd +'Xian ', # 0xfe +'Chuo ', # 0xff +) diff --git a/libs/unidecode/x074.py b/libs/unidecode/x074.py new file mode 100644 index 00000000..312fc646 --- /dev/null +++ b/libs/unidecode/x074.py @@ -0,0 +1,258 @@ +data = ( +'Han ', # 0x00 +'Xuan ', # 0x01 +'Yan ', # 0x02 +'Qiu ', # 0x03 +'Quan ', # 0x04 +'Lang ', # 0x05 +'Li ', # 0x06 +'Xiu ', # 0x07 +'Fu ', # 0x08 +'Liu ', # 0x09 +'Ye ', # 0x0a +'Xi ', # 0x0b +'Ling ', # 0x0c +'Li ', # 0x0d +'Jin ', # 0x0e +'Lian ', # 0x0f +'Suo ', # 0x10 +'Chiisai ', # 0x11 +'[?] ', # 0x12 +'Wan ', # 0x13 +'Dian ', # 0x14 +'Pin ', # 0x15 +'Zhan ', # 0x16 +'Cui ', # 0x17 +'Min ', # 0x18 +'Yu ', # 0x19 +'Ju ', # 0x1a +'Chen ', # 0x1b +'Lai ', # 0x1c +'Wen ', # 0x1d +'Sheng ', # 0x1e +'Wei ', # 0x1f +'Dian ', # 0x20 +'Chu ', # 0x21 +'Zhuo ', # 0x22 +'Pei ', # 0x23 +'Cheng ', # 0x24 +'Hu ', # 0x25 +'Qi ', # 0x26 +'E ', # 0x27 +'Kun ', # 0x28 +'Chang ', # 0x29 +'Qi ', # 0x2a +'Beng ', # 0x2b +'Wan ', # 0x2c +'Lu ', # 0x2d +'Cong ', # 0x2e +'Guan ', # 0x2f +'Yan ', # 0x30 +'Diao ', # 0x31 +'Bei ', # 0x32 +'Lin ', # 0x33 +'Qin ', # 0x34 +'Pi ', # 0x35 +'Pa ', # 0x36 +'Que ', # 0x37 +'Zhuo ', # 0x38 +'Qin ', # 0x39 +'Fa ', # 0x3a +'[?] ', # 0x3b +'Qiong ', # 0x3c +'Du ', # 0x3d +'Jie ', # 0x3e +'Hun ', # 0x3f +'Yu ', # 0x40 +'Mao ', # 0x41 +'Mei ', # 0x42 +'Chun ', # 0x43 +'Xuan ', # 0x44 +'Ti ', # 0x45 +'Xing ', # 0x46 +'Dai ', # 0x47 +'Rou ', # 0x48 +'Min ', # 0x49 +'Zhen ', # 0x4a +'Wei ', # 0x4b +'Ruan ', # 0x4c +'Huan ', # 0x4d +'Jie ', # 0x4e +'Chuan ', # 0x4f +'Jian ', # 0x50 +'Zhuan ', # 0x51 +'Yang ', # 0x52 +'Lian ', # 0x53 +'Quan ', # 0x54 +'Xia ', # 0x55 +'Duan ', # 0x56 +'Yuan ', # 0x57 +'Ye ', # 0x58 +'Nao ', # 0x59 +'Hu ', # 0x5a +'Ying ', # 0x5b +'Yu ', # 0x5c +'Huang ', # 0x5d +'Rui ', # 0x5e +'Se ', # 0x5f +'Liu ', # 0x60 +'Shi ', # 0x61 +'Rong ', # 0x62 +'Suo ', # 0x63 +'Yao ', # 0x64 +'Wen ', # 0x65 +'Wu ', # 0x66 +'Jin ', # 0x67 +'Jin ', # 0x68 +'Ying ', # 0x69 +'Ma ', # 0x6a +'Tao ', # 0x6b +'Liu ', # 0x6c +'Tang ', # 0x6d +'Li ', # 0x6e +'Lang ', # 0x6f +'Gui ', # 0x70 +'Zhen ', # 0x71 +'Qiang ', # 0x72 +'Cuo ', # 0x73 +'Jue ', # 0x74 +'Zhao ', # 0x75 +'Yao ', # 0x76 +'Ai ', # 0x77 +'Bin ', # 0x78 +'Tu ', # 0x79 +'Chang ', # 0x7a +'Kun ', # 0x7b +'Zhuan ', # 0x7c +'Cong ', # 0x7d +'Jin ', # 0x7e +'Yi ', # 0x7f +'Cui ', # 0x80 +'Cong ', # 0x81 +'Qi ', # 0x82 +'Li ', # 0x83 +'Ying ', # 0x84 +'Suo ', # 0x85 +'Qiu ', # 0x86 +'Xuan ', # 0x87 +'Ao ', # 0x88 +'Lian ', # 0x89 +'Man ', # 0x8a +'Zhang ', # 0x8b +'Yin ', # 0x8c +'[?] ', # 0x8d +'Ying ', # 0x8e +'Zhi ', # 0x8f +'Lu ', # 0x90 +'Wu ', # 0x91 +'Deng ', # 0x92 +'Xiou ', # 0x93 +'Zeng ', # 0x94 +'Xun ', # 0x95 +'Qu ', # 0x96 +'Dang ', # 0x97 +'Lin ', # 0x98 +'Liao ', # 0x99 +'Qiong ', # 0x9a +'Su ', # 0x9b +'Huang ', # 0x9c +'Gui ', # 0x9d +'Pu ', # 0x9e +'Jing ', # 0x9f +'Fan ', # 0xa0 +'Jin ', # 0xa1 +'Liu ', # 0xa2 +'Ji ', # 0xa3 +'[?] ', # 0xa4 +'Jing ', # 0xa5 +'Ai ', # 0xa6 +'Bi ', # 0xa7 +'Can ', # 0xa8 +'Qu ', # 0xa9 +'Zao ', # 0xaa +'Dang ', # 0xab +'Jiao ', # 0xac +'Gun ', # 0xad +'Tan ', # 0xae +'Hui ', # 0xaf +'Huan ', # 0xb0 +'Se ', # 0xb1 +'Sui ', # 0xb2 +'Tian ', # 0xb3 +'[?] ', # 0xb4 +'Yu ', # 0xb5 +'Jin ', # 0xb6 +'Lu ', # 0xb7 +'Bin ', # 0xb8 +'Shou ', # 0xb9 +'Wen ', # 0xba +'Zui ', # 0xbb +'Lan ', # 0xbc +'Xi ', # 0xbd +'Ji ', # 0xbe +'Xuan ', # 0xbf +'Ruan ', # 0xc0 +'Huo ', # 0xc1 +'Gai ', # 0xc2 +'Lei ', # 0xc3 +'Du ', # 0xc4 +'Li ', # 0xc5 +'Zhi ', # 0xc6 +'Rou ', # 0xc7 +'Li ', # 0xc8 +'Zan ', # 0xc9 +'Qiong ', # 0xca +'Zhe ', # 0xcb +'Gui ', # 0xcc +'Sui ', # 0xcd +'La ', # 0xce +'Long ', # 0xcf +'Lu ', # 0xd0 +'Li ', # 0xd1 +'Zan ', # 0xd2 +'Lan ', # 0xd3 +'Ying ', # 0xd4 +'Mi ', # 0xd5 +'Xiang ', # 0xd6 +'Xi ', # 0xd7 +'Guan ', # 0xd8 +'Dao ', # 0xd9 +'Zan ', # 0xda +'Huan ', # 0xdb +'Gua ', # 0xdc +'Bo ', # 0xdd +'Die ', # 0xde +'Bao ', # 0xdf +'Hu ', # 0xe0 +'Zhi ', # 0xe1 +'Piao ', # 0xe2 +'Ban ', # 0xe3 +'Rang ', # 0xe4 +'Li ', # 0xe5 +'Wa ', # 0xe6 +'Dekaguramu ', # 0xe7 +'Jiang ', # 0xe8 +'Qian ', # 0xe9 +'Fan ', # 0xea +'Pen ', # 0xeb +'Fang ', # 0xec +'Dan ', # 0xed +'Weng ', # 0xee +'Ou ', # 0xef +'Deshiguramu ', # 0xf0 +'Miriguramu ', # 0xf1 +'Thon ', # 0xf2 +'Hu ', # 0xf3 +'Ling ', # 0xf4 +'Yi ', # 0xf5 +'Ping ', # 0xf6 +'Ci ', # 0xf7 +'Hekutogura ', # 0xf8 +'Juan ', # 0xf9 +'Chang ', # 0xfa +'Chi ', # 0xfb +'Sarake ', # 0xfc +'Dang ', # 0xfd +'Meng ', # 0xfe +'Pou ', # 0xff +) diff --git a/libs/unidecode/x075.py b/libs/unidecode/x075.py new file mode 100644 index 00000000..a356ac41 --- /dev/null +++ b/libs/unidecode/x075.py @@ -0,0 +1,258 @@ +data = ( +'Zhui ', # 0x00 +'Ping ', # 0x01 +'Bian ', # 0x02 +'Zhou ', # 0x03 +'Zhen ', # 0x04 +'Senchigura ', # 0x05 +'Ci ', # 0x06 +'Ying ', # 0x07 +'Qi ', # 0x08 +'Xian ', # 0x09 +'Lou ', # 0x0a +'Di ', # 0x0b +'Ou ', # 0x0c +'Meng ', # 0x0d +'Zhuan ', # 0x0e +'Peng ', # 0x0f +'Lin ', # 0x10 +'Zeng ', # 0x11 +'Wu ', # 0x12 +'Pi ', # 0x13 +'Dan ', # 0x14 +'Weng ', # 0x15 +'Ying ', # 0x16 +'Yan ', # 0x17 +'Gan ', # 0x18 +'Dai ', # 0x19 +'Shen ', # 0x1a +'Tian ', # 0x1b +'Tian ', # 0x1c +'Han ', # 0x1d +'Chang ', # 0x1e +'Sheng ', # 0x1f +'Qing ', # 0x20 +'Sheng ', # 0x21 +'Chan ', # 0x22 +'Chan ', # 0x23 +'Rui ', # 0x24 +'Sheng ', # 0x25 +'Su ', # 0x26 +'Sen ', # 0x27 +'Yong ', # 0x28 +'Shuai ', # 0x29 +'Lu ', # 0x2a +'Fu ', # 0x2b +'Yong ', # 0x2c +'Beng ', # 0x2d +'Feng ', # 0x2e +'Ning ', # 0x2f +'Tian ', # 0x30 +'You ', # 0x31 +'Jia ', # 0x32 +'Shen ', # 0x33 +'Zha ', # 0x34 +'Dian ', # 0x35 +'Fu ', # 0x36 +'Nan ', # 0x37 +'Dian ', # 0x38 +'Ping ', # 0x39 +'Ting ', # 0x3a +'Hua ', # 0x3b +'Ting ', # 0x3c +'Quan ', # 0x3d +'Zi ', # 0x3e +'Meng ', # 0x3f +'Bi ', # 0x40 +'Qi ', # 0x41 +'Liu ', # 0x42 +'Xun ', # 0x43 +'Liu ', # 0x44 +'Chang ', # 0x45 +'Mu ', # 0x46 +'Yun ', # 0x47 +'Fan ', # 0x48 +'Fu ', # 0x49 +'Geng ', # 0x4a +'Tian ', # 0x4b +'Jie ', # 0x4c +'Jie ', # 0x4d +'Quan ', # 0x4e +'Wei ', # 0x4f +'Fu ', # 0x50 +'Tian ', # 0x51 +'Mu ', # 0x52 +'Tap ', # 0x53 +'Pan ', # 0x54 +'Jiang ', # 0x55 +'Wa ', # 0x56 +'Da ', # 0x57 +'Nan ', # 0x58 +'Liu ', # 0x59 +'Ben ', # 0x5a +'Zhen ', # 0x5b +'Chu ', # 0x5c +'Mu ', # 0x5d +'Mu ', # 0x5e +'Ce ', # 0x5f +'Cen ', # 0x60 +'Gai ', # 0x61 +'Bi ', # 0x62 +'Da ', # 0x63 +'Zhi ', # 0x64 +'Lue ', # 0x65 +'Qi ', # 0x66 +'Lue ', # 0x67 +'Pan ', # 0x68 +'Kesa ', # 0x69 +'Fan ', # 0x6a +'Hua ', # 0x6b +'Yu ', # 0x6c +'Yu ', # 0x6d +'Mu ', # 0x6e +'Jun ', # 0x6f +'Yi ', # 0x70 +'Liu ', # 0x71 +'Yu ', # 0x72 +'Die ', # 0x73 +'Chou ', # 0x74 +'Hua ', # 0x75 +'Dang ', # 0x76 +'Chuo ', # 0x77 +'Ji ', # 0x78 +'Wan ', # 0x79 +'Jiang ', # 0x7a +'Sheng ', # 0x7b +'Chang ', # 0x7c +'Tuan ', # 0x7d +'Lei ', # 0x7e +'Ji ', # 0x7f +'Cha ', # 0x80 +'Liu ', # 0x81 +'Tatamu ', # 0x82 +'Tuan ', # 0x83 +'Lin ', # 0x84 +'Jiang ', # 0x85 +'Jiang ', # 0x86 +'Chou ', # 0x87 +'Bo ', # 0x88 +'Die ', # 0x89 +'Die ', # 0x8a +'Pi ', # 0x8b +'Nie ', # 0x8c +'Dan ', # 0x8d +'Shu ', # 0x8e +'Shu ', # 0x8f +'Zhi ', # 0x90 +'Yi ', # 0x91 +'Chuang ', # 0x92 +'Nai ', # 0x93 +'Ding ', # 0x94 +'Bi ', # 0x95 +'Jie ', # 0x96 +'Liao ', # 0x97 +'Gong ', # 0x98 +'Ge ', # 0x99 +'Jiu ', # 0x9a +'Zhou ', # 0x9b +'Xia ', # 0x9c +'Shan ', # 0x9d +'Xu ', # 0x9e +'Nue ', # 0x9f +'Li ', # 0xa0 +'Yang ', # 0xa1 +'Chen ', # 0xa2 +'You ', # 0xa3 +'Ba ', # 0xa4 +'Jie ', # 0xa5 +'Jue ', # 0xa6 +'Zhi ', # 0xa7 +'Xia ', # 0xa8 +'Cui ', # 0xa9 +'Bi ', # 0xaa +'Yi ', # 0xab +'Li ', # 0xac +'Zong ', # 0xad +'Chuang ', # 0xae +'Feng ', # 0xaf +'Zhu ', # 0xb0 +'Pao ', # 0xb1 +'Pi ', # 0xb2 +'Gan ', # 0xb3 +'Ke ', # 0xb4 +'Ci ', # 0xb5 +'Xie ', # 0xb6 +'Qi ', # 0xb7 +'Dan ', # 0xb8 +'Zhen ', # 0xb9 +'Fa ', # 0xba +'Zhi ', # 0xbb +'Teng ', # 0xbc +'Ju ', # 0xbd +'Ji ', # 0xbe +'Fei ', # 0xbf +'Qu ', # 0xc0 +'Dian ', # 0xc1 +'Jia ', # 0xc2 +'Xian ', # 0xc3 +'Cha ', # 0xc4 +'Bing ', # 0xc5 +'Ni ', # 0xc6 +'Zheng ', # 0xc7 +'Yong ', # 0xc8 +'Jing ', # 0xc9 +'Quan ', # 0xca +'Chong ', # 0xcb +'Tong ', # 0xcc +'Yi ', # 0xcd +'Kai ', # 0xce +'Wei ', # 0xcf +'Hui ', # 0xd0 +'Duo ', # 0xd1 +'Yang ', # 0xd2 +'Chi ', # 0xd3 +'Zhi ', # 0xd4 +'Hen ', # 0xd5 +'Ya ', # 0xd6 +'Mei ', # 0xd7 +'Dou ', # 0xd8 +'Jing ', # 0xd9 +'Xiao ', # 0xda +'Tong ', # 0xdb +'Tu ', # 0xdc +'Mang ', # 0xdd +'Pi ', # 0xde +'Xiao ', # 0xdf +'Suan ', # 0xe0 +'Pu ', # 0xe1 +'Li ', # 0xe2 +'Zhi ', # 0xe3 +'Cuo ', # 0xe4 +'Duo ', # 0xe5 +'Wu ', # 0xe6 +'Sha ', # 0xe7 +'Lao ', # 0xe8 +'Shou ', # 0xe9 +'Huan ', # 0xea +'Xian ', # 0xeb +'Yi ', # 0xec +'Peng ', # 0xed +'Zhang ', # 0xee +'Guan ', # 0xef +'Tan ', # 0xf0 +'Fei ', # 0xf1 +'Ma ', # 0xf2 +'Lin ', # 0xf3 +'Chi ', # 0xf4 +'Ji ', # 0xf5 +'Dian ', # 0xf6 +'An ', # 0xf7 +'Chi ', # 0xf8 +'Bi ', # 0xf9 +'Bei ', # 0xfa +'Min ', # 0xfb +'Gu ', # 0xfc +'Dui ', # 0xfd +'E ', # 0xfe +'Wei ', # 0xff +) diff --git a/libs/unidecode/x076.py b/libs/unidecode/x076.py new file mode 100644 index 00000000..fc8b1672 --- /dev/null +++ b/libs/unidecode/x076.py @@ -0,0 +1,258 @@ +data = ( +'Yu ', # 0x00 +'Cui ', # 0x01 +'Ya ', # 0x02 +'Zhu ', # 0x03 +'Cu ', # 0x04 +'Dan ', # 0x05 +'Shen ', # 0x06 +'Zhung ', # 0x07 +'Ji ', # 0x08 +'Yu ', # 0x09 +'Hou ', # 0x0a +'Feng ', # 0x0b +'La ', # 0x0c +'Yang ', # 0x0d +'Shen ', # 0x0e +'Tu ', # 0x0f +'Yu ', # 0x10 +'Gua ', # 0x11 +'Wen ', # 0x12 +'Huan ', # 0x13 +'Ku ', # 0x14 +'Jia ', # 0x15 +'Yin ', # 0x16 +'Yi ', # 0x17 +'Lu ', # 0x18 +'Sao ', # 0x19 +'Jue ', # 0x1a +'Chi ', # 0x1b +'Xi ', # 0x1c +'Guan ', # 0x1d +'Yi ', # 0x1e +'Wen ', # 0x1f +'Ji ', # 0x20 +'Chuang ', # 0x21 +'Ban ', # 0x22 +'Lei ', # 0x23 +'Liu ', # 0x24 +'Chai ', # 0x25 +'Shou ', # 0x26 +'Nue ', # 0x27 +'Dian ', # 0x28 +'Da ', # 0x29 +'Pie ', # 0x2a +'Tan ', # 0x2b +'Zhang ', # 0x2c +'Biao ', # 0x2d +'Shen ', # 0x2e +'Cu ', # 0x2f +'Luo ', # 0x30 +'Yi ', # 0x31 +'Zong ', # 0x32 +'Chou ', # 0x33 +'Zhang ', # 0x34 +'Zhai ', # 0x35 +'Sou ', # 0x36 +'Suo ', # 0x37 +'Que ', # 0x38 +'Diao ', # 0x39 +'Lou ', # 0x3a +'Lu ', # 0x3b +'Mo ', # 0x3c +'Jin ', # 0x3d +'Yin ', # 0x3e +'Ying ', # 0x3f +'Huang ', # 0x40 +'Fu ', # 0x41 +'Liao ', # 0x42 +'Long ', # 0x43 +'Qiao ', # 0x44 +'Liu ', # 0x45 +'Lao ', # 0x46 +'Xian ', # 0x47 +'Fei ', # 0x48 +'Dan ', # 0x49 +'Yin ', # 0x4a +'He ', # 0x4b +'Yan ', # 0x4c +'Ban ', # 0x4d +'Xian ', # 0x4e +'Guan ', # 0x4f +'Guai ', # 0x50 +'Nong ', # 0x51 +'Yu ', # 0x52 +'Wei ', # 0x53 +'Yi ', # 0x54 +'Yong ', # 0x55 +'Pi ', # 0x56 +'Lei ', # 0x57 +'Li ', # 0x58 +'Shu ', # 0x59 +'Dan ', # 0x5a +'Lin ', # 0x5b +'Dian ', # 0x5c +'Lin ', # 0x5d +'Lai ', # 0x5e +'Pie ', # 0x5f +'Ji ', # 0x60 +'Chi ', # 0x61 +'Yang ', # 0x62 +'Xian ', # 0x63 +'Jie ', # 0x64 +'Zheng ', # 0x65 +'[?] ', # 0x66 +'Li ', # 0x67 +'Huo ', # 0x68 +'Lai ', # 0x69 +'Shaku ', # 0x6a +'Dian ', # 0x6b +'Xian ', # 0x6c +'Ying ', # 0x6d +'Yin ', # 0x6e +'Qu ', # 0x6f +'Yong ', # 0x70 +'Tan ', # 0x71 +'Dian ', # 0x72 +'Luo ', # 0x73 +'Luan ', # 0x74 +'Luan ', # 0x75 +'Bo ', # 0x76 +'[?] ', # 0x77 +'Gui ', # 0x78 +'Po ', # 0x79 +'Fa ', # 0x7a +'Deng ', # 0x7b +'Fa ', # 0x7c +'Bai ', # 0x7d +'Bai ', # 0x7e +'Qie ', # 0x7f +'Bi ', # 0x80 +'Zao ', # 0x81 +'Zao ', # 0x82 +'Mao ', # 0x83 +'De ', # 0x84 +'Pa ', # 0x85 +'Jie ', # 0x86 +'Huang ', # 0x87 +'Gui ', # 0x88 +'Ci ', # 0x89 +'Ling ', # 0x8a +'Gao ', # 0x8b +'Mo ', # 0x8c +'Ji ', # 0x8d +'Jiao ', # 0x8e +'Peng ', # 0x8f +'Gao ', # 0x90 +'Ai ', # 0x91 +'E ', # 0x92 +'Hao ', # 0x93 +'Han ', # 0x94 +'Bi ', # 0x95 +'Wan ', # 0x96 +'Chou ', # 0x97 +'Qian ', # 0x98 +'Xi ', # 0x99 +'Ai ', # 0x9a +'Jiong ', # 0x9b +'Hao ', # 0x9c +'Huang ', # 0x9d +'Hao ', # 0x9e +'Ze ', # 0x9f +'Cui ', # 0xa0 +'Hao ', # 0xa1 +'Xiao ', # 0xa2 +'Ye ', # 0xa3 +'Po ', # 0xa4 +'Hao ', # 0xa5 +'Jiao ', # 0xa6 +'Ai ', # 0xa7 +'Xing ', # 0xa8 +'Huang ', # 0xa9 +'Li ', # 0xaa +'Piao ', # 0xab +'He ', # 0xac +'Jiao ', # 0xad +'Pi ', # 0xae +'Gan ', # 0xaf +'Pao ', # 0xb0 +'Zhou ', # 0xb1 +'Jun ', # 0xb2 +'Qiu ', # 0xb3 +'Cun ', # 0xb4 +'Que ', # 0xb5 +'Zha ', # 0xb6 +'Gu ', # 0xb7 +'Jun ', # 0xb8 +'Jun ', # 0xb9 +'Zhou ', # 0xba +'Zha ', # 0xbb +'Gu ', # 0xbc +'Zhan ', # 0xbd +'Du ', # 0xbe +'Min ', # 0xbf +'Qi ', # 0xc0 +'Ying ', # 0xc1 +'Yu ', # 0xc2 +'Bei ', # 0xc3 +'Zhao ', # 0xc4 +'Zhong ', # 0xc5 +'Pen ', # 0xc6 +'He ', # 0xc7 +'Ying ', # 0xc8 +'He ', # 0xc9 +'Yi ', # 0xca +'Bo ', # 0xcb +'Wan ', # 0xcc +'He ', # 0xcd +'Ang ', # 0xce +'Zhan ', # 0xcf +'Yan ', # 0xd0 +'Jian ', # 0xd1 +'He ', # 0xd2 +'Yu ', # 0xd3 +'Kui ', # 0xd4 +'Fan ', # 0xd5 +'Gai ', # 0xd6 +'Dao ', # 0xd7 +'Pan ', # 0xd8 +'Fu ', # 0xd9 +'Qiu ', # 0xda +'Sheng ', # 0xdb +'Dao ', # 0xdc +'Lu ', # 0xdd +'Zhan ', # 0xde +'Meng ', # 0xdf +'Li ', # 0xe0 +'Jin ', # 0xe1 +'Xu ', # 0xe2 +'Jian ', # 0xe3 +'Pan ', # 0xe4 +'Guan ', # 0xe5 +'An ', # 0xe6 +'Lu ', # 0xe7 +'Shu ', # 0xe8 +'Zhou ', # 0xe9 +'Dang ', # 0xea +'An ', # 0xeb +'Gu ', # 0xec +'Li ', # 0xed +'Mu ', # 0xee +'Cheng ', # 0xef +'Gan ', # 0xf0 +'Xu ', # 0xf1 +'Mang ', # 0xf2 +'Mang ', # 0xf3 +'Zhi ', # 0xf4 +'Qi ', # 0xf5 +'Ruan ', # 0xf6 +'Tian ', # 0xf7 +'Xiang ', # 0xf8 +'Dun ', # 0xf9 +'Xin ', # 0xfa +'Xi ', # 0xfb +'Pan ', # 0xfc +'Feng ', # 0xfd +'Dun ', # 0xfe +'Min ', # 0xff +) diff --git a/libs/unidecode/x077.py b/libs/unidecode/x077.py new file mode 100644 index 00000000..3ed6a36b --- /dev/null +++ b/libs/unidecode/x077.py @@ -0,0 +1,258 @@ +data = ( +'Ming ', # 0x00 +'Sheng ', # 0x01 +'Shi ', # 0x02 +'Yun ', # 0x03 +'Mian ', # 0x04 +'Pan ', # 0x05 +'Fang ', # 0x06 +'Miao ', # 0x07 +'Dan ', # 0x08 +'Mei ', # 0x09 +'Mao ', # 0x0a +'Kan ', # 0x0b +'Xian ', # 0x0c +'Ou ', # 0x0d +'Shi ', # 0x0e +'Yang ', # 0x0f +'Zheng ', # 0x10 +'Yao ', # 0x11 +'Shen ', # 0x12 +'Huo ', # 0x13 +'Da ', # 0x14 +'Zhen ', # 0x15 +'Kuang ', # 0x16 +'Ju ', # 0x17 +'Shen ', # 0x18 +'Chi ', # 0x19 +'Sheng ', # 0x1a +'Mei ', # 0x1b +'Mo ', # 0x1c +'Zhu ', # 0x1d +'Zhen ', # 0x1e +'Zhen ', # 0x1f +'Mian ', # 0x20 +'Di ', # 0x21 +'Yuan ', # 0x22 +'Die ', # 0x23 +'Yi ', # 0x24 +'Zi ', # 0x25 +'Zi ', # 0x26 +'Chao ', # 0x27 +'Zha ', # 0x28 +'Xuan ', # 0x29 +'Bing ', # 0x2a +'Mi ', # 0x2b +'Long ', # 0x2c +'Sui ', # 0x2d +'Dong ', # 0x2e +'Mi ', # 0x2f +'Die ', # 0x30 +'Yi ', # 0x31 +'Er ', # 0x32 +'Ming ', # 0x33 +'Xuan ', # 0x34 +'Chi ', # 0x35 +'Kuang ', # 0x36 +'Juan ', # 0x37 +'Mou ', # 0x38 +'Zhen ', # 0x39 +'Tiao ', # 0x3a +'Yang ', # 0x3b +'Yan ', # 0x3c +'Mo ', # 0x3d +'Zhong ', # 0x3e +'Mai ', # 0x3f +'Zhao ', # 0x40 +'Zheng ', # 0x41 +'Mei ', # 0x42 +'Jun ', # 0x43 +'Shao ', # 0x44 +'Han ', # 0x45 +'Huan ', # 0x46 +'Di ', # 0x47 +'Cheng ', # 0x48 +'Cuo ', # 0x49 +'Juan ', # 0x4a +'E ', # 0x4b +'Wan ', # 0x4c +'Xian ', # 0x4d +'Xi ', # 0x4e +'Kun ', # 0x4f +'Lai ', # 0x50 +'Jian ', # 0x51 +'Shan ', # 0x52 +'Tian ', # 0x53 +'Hun ', # 0x54 +'Wan ', # 0x55 +'Ling ', # 0x56 +'Shi ', # 0x57 +'Qiong ', # 0x58 +'Lie ', # 0x59 +'Yai ', # 0x5a +'Jing ', # 0x5b +'Zheng ', # 0x5c +'Li ', # 0x5d +'Lai ', # 0x5e +'Sui ', # 0x5f +'Juan ', # 0x60 +'Shui ', # 0x61 +'Sui ', # 0x62 +'Du ', # 0x63 +'Bi ', # 0x64 +'Bi ', # 0x65 +'Mu ', # 0x66 +'Hun ', # 0x67 +'Ni ', # 0x68 +'Lu ', # 0x69 +'Yi ', # 0x6a +'Jie ', # 0x6b +'Cai ', # 0x6c +'Zhou ', # 0x6d +'Yu ', # 0x6e +'Hun ', # 0x6f +'Ma ', # 0x70 +'Xia ', # 0x71 +'Xing ', # 0x72 +'Xi ', # 0x73 +'Gun ', # 0x74 +'Cai ', # 0x75 +'Chun ', # 0x76 +'Jian ', # 0x77 +'Mei ', # 0x78 +'Du ', # 0x79 +'Hou ', # 0x7a +'Xuan ', # 0x7b +'Ti ', # 0x7c +'Kui ', # 0x7d +'Gao ', # 0x7e +'Rui ', # 0x7f +'Mou ', # 0x80 +'Xu ', # 0x81 +'Fa ', # 0x82 +'Wen ', # 0x83 +'Miao ', # 0x84 +'Chou ', # 0x85 +'Kui ', # 0x86 +'Mi ', # 0x87 +'Weng ', # 0x88 +'Kou ', # 0x89 +'Dang ', # 0x8a +'Chen ', # 0x8b +'Ke ', # 0x8c +'Sou ', # 0x8d +'Xia ', # 0x8e +'Qiong ', # 0x8f +'Mao ', # 0x90 +'Ming ', # 0x91 +'Man ', # 0x92 +'Shui ', # 0x93 +'Ze ', # 0x94 +'Zhang ', # 0x95 +'Yi ', # 0x96 +'Diao ', # 0x97 +'Ou ', # 0x98 +'Mo ', # 0x99 +'Shun ', # 0x9a +'Cong ', # 0x9b +'Lou ', # 0x9c +'Chi ', # 0x9d +'Man ', # 0x9e +'Piao ', # 0x9f +'Cheng ', # 0xa0 +'Ji ', # 0xa1 +'Meng ', # 0xa2 +'[?] ', # 0xa3 +'Run ', # 0xa4 +'Pie ', # 0xa5 +'Xi ', # 0xa6 +'Qiao ', # 0xa7 +'Pu ', # 0xa8 +'Zhu ', # 0xa9 +'Deng ', # 0xaa +'Shen ', # 0xab +'Shun ', # 0xac +'Liao ', # 0xad +'Che ', # 0xae +'Xian ', # 0xaf +'Kan ', # 0xb0 +'Ye ', # 0xb1 +'Xu ', # 0xb2 +'Tong ', # 0xb3 +'Mou ', # 0xb4 +'Lin ', # 0xb5 +'Kui ', # 0xb6 +'Xian ', # 0xb7 +'Ye ', # 0xb8 +'Ai ', # 0xb9 +'Hui ', # 0xba +'Zhan ', # 0xbb +'Jian ', # 0xbc +'Gu ', # 0xbd +'Zhao ', # 0xbe +'Qu ', # 0xbf +'Wei ', # 0xc0 +'Chou ', # 0xc1 +'Sao ', # 0xc2 +'Ning ', # 0xc3 +'Xun ', # 0xc4 +'Yao ', # 0xc5 +'Huo ', # 0xc6 +'Meng ', # 0xc7 +'Mian ', # 0xc8 +'Bin ', # 0xc9 +'Mian ', # 0xca +'Li ', # 0xcb +'Kuang ', # 0xcc +'Jue ', # 0xcd +'Xuan ', # 0xce +'Mian ', # 0xcf +'Huo ', # 0xd0 +'Lu ', # 0xd1 +'Meng ', # 0xd2 +'Long ', # 0xd3 +'Guan ', # 0xd4 +'Man ', # 0xd5 +'Xi ', # 0xd6 +'Chu ', # 0xd7 +'Tang ', # 0xd8 +'Kan ', # 0xd9 +'Zhu ', # 0xda +'Mao ', # 0xdb +'Jin ', # 0xdc +'Lin ', # 0xdd +'Yu ', # 0xde +'Shuo ', # 0xdf +'Ce ', # 0xe0 +'Jue ', # 0xe1 +'Shi ', # 0xe2 +'Yi ', # 0xe3 +'Shen ', # 0xe4 +'Zhi ', # 0xe5 +'Hou ', # 0xe6 +'Shen ', # 0xe7 +'Ying ', # 0xe8 +'Ju ', # 0xe9 +'Zhou ', # 0xea +'Jiao ', # 0xeb +'Cuo ', # 0xec +'Duan ', # 0xed +'Ai ', # 0xee +'Jiao ', # 0xef +'Zeng ', # 0xf0 +'Huo ', # 0xf1 +'Bai ', # 0xf2 +'Shi ', # 0xf3 +'Ding ', # 0xf4 +'Qi ', # 0xf5 +'Ji ', # 0xf6 +'Zi ', # 0xf7 +'Gan ', # 0xf8 +'Wu ', # 0xf9 +'Tuo ', # 0xfa +'Ku ', # 0xfb +'Qiang ', # 0xfc +'Xi ', # 0xfd +'Fan ', # 0xfe +'Kuang ', # 0xff +) diff --git a/libs/unidecode/x078.py b/libs/unidecode/x078.py new file mode 100644 index 00000000..23d677de --- /dev/null +++ b/libs/unidecode/x078.py @@ -0,0 +1,258 @@ +data = ( +'Dang ', # 0x00 +'Ma ', # 0x01 +'Sha ', # 0x02 +'Dan ', # 0x03 +'Jue ', # 0x04 +'Li ', # 0x05 +'Fu ', # 0x06 +'Min ', # 0x07 +'Nuo ', # 0x08 +'Huo ', # 0x09 +'Kang ', # 0x0a +'Zhi ', # 0x0b +'Qi ', # 0x0c +'Kan ', # 0x0d +'Jie ', # 0x0e +'Fen ', # 0x0f +'E ', # 0x10 +'Ya ', # 0x11 +'Pi ', # 0x12 +'Zhe ', # 0x13 +'Yan ', # 0x14 +'Sui ', # 0x15 +'Zhuan ', # 0x16 +'Che ', # 0x17 +'Dun ', # 0x18 +'Pan ', # 0x19 +'Yan ', # 0x1a +'[?] ', # 0x1b +'Feng ', # 0x1c +'Fa ', # 0x1d +'Mo ', # 0x1e +'Zha ', # 0x1f +'Qu ', # 0x20 +'Yu ', # 0x21 +'Luo ', # 0x22 +'Tuo ', # 0x23 +'Tuo ', # 0x24 +'Di ', # 0x25 +'Zhai ', # 0x26 +'Zhen ', # 0x27 +'Ai ', # 0x28 +'Fei ', # 0x29 +'Mu ', # 0x2a +'Zhu ', # 0x2b +'Li ', # 0x2c +'Bian ', # 0x2d +'Nu ', # 0x2e +'Ping ', # 0x2f +'Peng ', # 0x30 +'Ling ', # 0x31 +'Pao ', # 0x32 +'Le ', # 0x33 +'Po ', # 0x34 +'Bo ', # 0x35 +'Po ', # 0x36 +'Shen ', # 0x37 +'Za ', # 0x38 +'Nuo ', # 0x39 +'Li ', # 0x3a +'Long ', # 0x3b +'Tong ', # 0x3c +'[?] ', # 0x3d +'Li ', # 0x3e +'Aragane ', # 0x3f +'Chu ', # 0x40 +'Keng ', # 0x41 +'Quan ', # 0x42 +'Zhu ', # 0x43 +'Kuang ', # 0x44 +'Huo ', # 0x45 +'E ', # 0x46 +'Nao ', # 0x47 +'Jia ', # 0x48 +'Lu ', # 0x49 +'Wei ', # 0x4a +'Ai ', # 0x4b +'Luo ', # 0x4c +'Ken ', # 0x4d +'Xing ', # 0x4e +'Yan ', # 0x4f +'Tong ', # 0x50 +'Peng ', # 0x51 +'Xi ', # 0x52 +'[?] ', # 0x53 +'Hong ', # 0x54 +'Shuo ', # 0x55 +'Xia ', # 0x56 +'Qiao ', # 0x57 +'[?] ', # 0x58 +'Wei ', # 0x59 +'Qiao ', # 0x5a +'[?] ', # 0x5b +'Keng ', # 0x5c +'Xiao ', # 0x5d +'Que ', # 0x5e +'Chan ', # 0x5f +'Lang ', # 0x60 +'Hong ', # 0x61 +'Yu ', # 0x62 +'Xiao ', # 0x63 +'Xia ', # 0x64 +'Mang ', # 0x65 +'Long ', # 0x66 +'Iong ', # 0x67 +'Che ', # 0x68 +'Che ', # 0x69 +'E ', # 0x6a +'Liu ', # 0x6b +'Ying ', # 0x6c +'Mang ', # 0x6d +'Que ', # 0x6e +'Yan ', # 0x6f +'Sha ', # 0x70 +'Kun ', # 0x71 +'Yu ', # 0x72 +'[?] ', # 0x73 +'Kaki ', # 0x74 +'Lu ', # 0x75 +'Chen ', # 0x76 +'Jian ', # 0x77 +'Nue ', # 0x78 +'Song ', # 0x79 +'Zhuo ', # 0x7a +'Keng ', # 0x7b +'Peng ', # 0x7c +'Yan ', # 0x7d +'Zhui ', # 0x7e +'Kong ', # 0x7f +'Ceng ', # 0x80 +'Qi ', # 0x81 +'Zong ', # 0x82 +'Qing ', # 0x83 +'Lin ', # 0x84 +'Jun ', # 0x85 +'Bo ', # 0x86 +'Ding ', # 0x87 +'Min ', # 0x88 +'Diao ', # 0x89 +'Jian ', # 0x8a +'He ', # 0x8b +'Lu ', # 0x8c +'Ai ', # 0x8d +'Sui ', # 0x8e +'Que ', # 0x8f +'Ling ', # 0x90 +'Bei ', # 0x91 +'Yin ', # 0x92 +'Dui ', # 0x93 +'Wu ', # 0x94 +'Qi ', # 0x95 +'Lun ', # 0x96 +'Wan ', # 0x97 +'Dian ', # 0x98 +'Gang ', # 0x99 +'Pei ', # 0x9a +'Qi ', # 0x9b +'Chen ', # 0x9c +'Ruan ', # 0x9d +'Yan ', # 0x9e +'Die ', # 0x9f +'Ding ', # 0xa0 +'Du ', # 0xa1 +'Tuo ', # 0xa2 +'Jie ', # 0xa3 +'Ying ', # 0xa4 +'Bian ', # 0xa5 +'Ke ', # 0xa6 +'Bi ', # 0xa7 +'Wei ', # 0xa8 +'Shuo ', # 0xa9 +'Zhen ', # 0xaa +'Duan ', # 0xab +'Xia ', # 0xac +'Dang ', # 0xad +'Ti ', # 0xae +'Nao ', # 0xaf +'Peng ', # 0xb0 +'Jian ', # 0xb1 +'Di ', # 0xb2 +'Tan ', # 0xb3 +'Cha ', # 0xb4 +'Seki ', # 0xb5 +'Qi ', # 0xb6 +'[?] ', # 0xb7 +'Feng ', # 0xb8 +'Xuan ', # 0xb9 +'Que ', # 0xba +'Que ', # 0xbb +'Ma ', # 0xbc +'Gong ', # 0xbd +'Nian ', # 0xbe +'Su ', # 0xbf +'E ', # 0xc0 +'Ci ', # 0xc1 +'Liu ', # 0xc2 +'Si ', # 0xc3 +'Tang ', # 0xc4 +'Bang ', # 0xc5 +'Hua ', # 0xc6 +'Pi ', # 0xc7 +'Wei ', # 0xc8 +'Sang ', # 0xc9 +'Lei ', # 0xca +'Cuo ', # 0xcb +'Zhen ', # 0xcc +'Xia ', # 0xcd +'Qi ', # 0xce +'Lian ', # 0xcf +'Pan ', # 0xd0 +'Wei ', # 0xd1 +'Yun ', # 0xd2 +'Dui ', # 0xd3 +'Zhe ', # 0xd4 +'Ke ', # 0xd5 +'La ', # 0xd6 +'[?] ', # 0xd7 +'Qing ', # 0xd8 +'Gun ', # 0xd9 +'Zhuan ', # 0xda +'Chan ', # 0xdb +'Qi ', # 0xdc +'Ao ', # 0xdd +'Peng ', # 0xde +'Lu ', # 0xdf +'Lu ', # 0xe0 +'Kan ', # 0xe1 +'Qiang ', # 0xe2 +'Chen ', # 0xe3 +'Yin ', # 0xe4 +'Lei ', # 0xe5 +'Biao ', # 0xe6 +'Qi ', # 0xe7 +'Mo ', # 0xe8 +'Qi ', # 0xe9 +'Cui ', # 0xea +'Zong ', # 0xeb +'Qing ', # 0xec +'Chuo ', # 0xed +'[?] ', # 0xee +'Ji ', # 0xef +'Shan ', # 0xf0 +'Lao ', # 0xf1 +'Qu ', # 0xf2 +'Zeng ', # 0xf3 +'Deng ', # 0xf4 +'Jian ', # 0xf5 +'Xi ', # 0xf6 +'Lin ', # 0xf7 +'Ding ', # 0xf8 +'Dian ', # 0xf9 +'Huang ', # 0xfa +'Pan ', # 0xfb +'Za ', # 0xfc +'Qiao ', # 0xfd +'Di ', # 0xfe +'Li ', # 0xff +) diff --git a/libs/unidecode/x079.py b/libs/unidecode/x079.py new file mode 100644 index 00000000..ed1c5143 --- /dev/null +++ b/libs/unidecode/x079.py @@ -0,0 +1,258 @@ +data = ( +'Tani ', # 0x00 +'Jiao ', # 0x01 +'[?] ', # 0x02 +'Zhang ', # 0x03 +'Qiao ', # 0x04 +'Dun ', # 0x05 +'Xian ', # 0x06 +'Yu ', # 0x07 +'Zhui ', # 0x08 +'He ', # 0x09 +'Huo ', # 0x0a +'Zhai ', # 0x0b +'Lei ', # 0x0c +'Ke ', # 0x0d +'Chu ', # 0x0e +'Ji ', # 0x0f +'Que ', # 0x10 +'Dang ', # 0x11 +'Yi ', # 0x12 +'Jiang ', # 0x13 +'Pi ', # 0x14 +'Pi ', # 0x15 +'Yu ', # 0x16 +'Pin ', # 0x17 +'Qi ', # 0x18 +'Ai ', # 0x19 +'Kai ', # 0x1a +'Jian ', # 0x1b +'Yu ', # 0x1c +'Ruan ', # 0x1d +'Meng ', # 0x1e +'Pao ', # 0x1f +'Ci ', # 0x20 +'[?] ', # 0x21 +'[?] ', # 0x22 +'Mie ', # 0x23 +'Ca ', # 0x24 +'Xian ', # 0x25 +'Kuang ', # 0x26 +'Lei ', # 0x27 +'Lei ', # 0x28 +'Zhi ', # 0x29 +'Li ', # 0x2a +'Li ', # 0x2b +'Fan ', # 0x2c +'Que ', # 0x2d +'Pao ', # 0x2e +'Ying ', # 0x2f +'Li ', # 0x30 +'Long ', # 0x31 +'Long ', # 0x32 +'Mo ', # 0x33 +'Bo ', # 0x34 +'Shuang ', # 0x35 +'Guan ', # 0x36 +'Lan ', # 0x37 +'Zan ', # 0x38 +'Yan ', # 0x39 +'Shi ', # 0x3a +'Shi ', # 0x3b +'Li ', # 0x3c +'Reng ', # 0x3d +'She ', # 0x3e +'Yue ', # 0x3f +'Si ', # 0x40 +'Qi ', # 0x41 +'Ta ', # 0x42 +'Ma ', # 0x43 +'Xie ', # 0x44 +'Xian ', # 0x45 +'Xian ', # 0x46 +'Zhi ', # 0x47 +'Qi ', # 0x48 +'Zhi ', # 0x49 +'Beng ', # 0x4a +'Dui ', # 0x4b +'Zhong ', # 0x4c +'[?] ', # 0x4d +'Yi ', # 0x4e +'Shi ', # 0x4f +'You ', # 0x50 +'Zhi ', # 0x51 +'Tiao ', # 0x52 +'Fu ', # 0x53 +'Fu ', # 0x54 +'Mi ', # 0x55 +'Zu ', # 0x56 +'Zhi ', # 0x57 +'Suan ', # 0x58 +'Mei ', # 0x59 +'Zuo ', # 0x5a +'Qu ', # 0x5b +'Hu ', # 0x5c +'Zhu ', # 0x5d +'Shen ', # 0x5e +'Sui ', # 0x5f +'Ci ', # 0x60 +'Chai ', # 0x61 +'Mi ', # 0x62 +'Lu ', # 0x63 +'Yu ', # 0x64 +'Xiang ', # 0x65 +'Wu ', # 0x66 +'Tiao ', # 0x67 +'Piao ', # 0x68 +'Zhu ', # 0x69 +'Gui ', # 0x6a +'Xia ', # 0x6b +'Zhi ', # 0x6c +'Ji ', # 0x6d +'Gao ', # 0x6e +'Zhen ', # 0x6f +'Gao ', # 0x70 +'Shui ', # 0x71 +'Jin ', # 0x72 +'Chen ', # 0x73 +'Gai ', # 0x74 +'Kun ', # 0x75 +'Di ', # 0x76 +'Dao ', # 0x77 +'Huo ', # 0x78 +'Tao ', # 0x79 +'Qi ', # 0x7a +'Gu ', # 0x7b +'Guan ', # 0x7c +'Zui ', # 0x7d +'Ling ', # 0x7e +'Lu ', # 0x7f +'Bing ', # 0x80 +'Jin ', # 0x81 +'Dao ', # 0x82 +'Zhi ', # 0x83 +'Lu ', # 0x84 +'Shan ', # 0x85 +'Bei ', # 0x86 +'Zhe ', # 0x87 +'Hui ', # 0x88 +'You ', # 0x89 +'Xi ', # 0x8a +'Yin ', # 0x8b +'Zi ', # 0x8c +'Huo ', # 0x8d +'Zhen ', # 0x8e +'Fu ', # 0x8f +'Yuan ', # 0x90 +'Wu ', # 0x91 +'Xian ', # 0x92 +'Yang ', # 0x93 +'Ti ', # 0x94 +'Yi ', # 0x95 +'Mei ', # 0x96 +'Si ', # 0x97 +'Di ', # 0x98 +'[?] ', # 0x99 +'Zhuo ', # 0x9a +'Zhen ', # 0x9b +'Yong ', # 0x9c +'Ji ', # 0x9d +'Gao ', # 0x9e +'Tang ', # 0x9f +'Si ', # 0xa0 +'Ma ', # 0xa1 +'Ta ', # 0xa2 +'[?] ', # 0xa3 +'Xuan ', # 0xa4 +'Qi ', # 0xa5 +'Yu ', # 0xa6 +'Xi ', # 0xa7 +'Ji ', # 0xa8 +'Si ', # 0xa9 +'Chan ', # 0xaa +'Tan ', # 0xab +'Kuai ', # 0xac +'Sui ', # 0xad +'Li ', # 0xae +'Nong ', # 0xaf +'Ni ', # 0xb0 +'Dao ', # 0xb1 +'Li ', # 0xb2 +'Rang ', # 0xb3 +'Yue ', # 0xb4 +'Ti ', # 0xb5 +'Zan ', # 0xb6 +'Lei ', # 0xb7 +'Rou ', # 0xb8 +'Yu ', # 0xb9 +'Yu ', # 0xba +'Chi ', # 0xbb +'Xie ', # 0xbc +'Qin ', # 0xbd +'He ', # 0xbe +'Tu ', # 0xbf +'Xiu ', # 0xc0 +'Si ', # 0xc1 +'Ren ', # 0xc2 +'Tu ', # 0xc3 +'Zi ', # 0xc4 +'Cha ', # 0xc5 +'Gan ', # 0xc6 +'Yi ', # 0xc7 +'Xian ', # 0xc8 +'Bing ', # 0xc9 +'Nian ', # 0xca +'Qiu ', # 0xcb +'Qiu ', # 0xcc +'Chong ', # 0xcd +'Fen ', # 0xce +'Hao ', # 0xcf +'Yun ', # 0xd0 +'Ke ', # 0xd1 +'Miao ', # 0xd2 +'Zhi ', # 0xd3 +'Geng ', # 0xd4 +'Bi ', # 0xd5 +'Zhi ', # 0xd6 +'Yu ', # 0xd7 +'Mi ', # 0xd8 +'Ku ', # 0xd9 +'Ban ', # 0xda +'Pi ', # 0xdb +'Ni ', # 0xdc +'Li ', # 0xdd +'You ', # 0xde +'Zu ', # 0xdf +'Pi ', # 0xe0 +'Ba ', # 0xe1 +'Ling ', # 0xe2 +'Mo ', # 0xe3 +'Cheng ', # 0xe4 +'Nian ', # 0xe5 +'Qin ', # 0xe6 +'Yang ', # 0xe7 +'Zuo ', # 0xe8 +'Zhi ', # 0xe9 +'Zhi ', # 0xea +'Shu ', # 0xeb +'Ju ', # 0xec +'Zi ', # 0xed +'Huo ', # 0xee +'Ji ', # 0xef +'Cheng ', # 0xf0 +'Tong ', # 0xf1 +'Zhi ', # 0xf2 +'Huo ', # 0xf3 +'He ', # 0xf4 +'Yin ', # 0xf5 +'Zi ', # 0xf6 +'Zhi ', # 0xf7 +'Jie ', # 0xf8 +'Ren ', # 0xf9 +'Du ', # 0xfa +'Yi ', # 0xfb +'Zhu ', # 0xfc +'Hui ', # 0xfd +'Nong ', # 0xfe +'Fu ', # 0xff +) diff --git a/libs/unidecode/x07a.py b/libs/unidecode/x07a.py new file mode 100644 index 00000000..b6d512cd --- /dev/null +++ b/libs/unidecode/x07a.py @@ -0,0 +1,258 @@ +data = ( +'Xi ', # 0x00 +'Kao ', # 0x01 +'Lang ', # 0x02 +'Fu ', # 0x03 +'Ze ', # 0x04 +'Shui ', # 0x05 +'Lu ', # 0x06 +'Kun ', # 0x07 +'Gan ', # 0x08 +'Geng ', # 0x09 +'Ti ', # 0x0a +'Cheng ', # 0x0b +'Tu ', # 0x0c +'Shao ', # 0x0d +'Shui ', # 0x0e +'Ya ', # 0x0f +'Lun ', # 0x10 +'Lu ', # 0x11 +'Gu ', # 0x12 +'Zuo ', # 0x13 +'Ren ', # 0x14 +'Zhun ', # 0x15 +'Bang ', # 0x16 +'Bai ', # 0x17 +'Ji ', # 0x18 +'Zhi ', # 0x19 +'Zhi ', # 0x1a +'Kun ', # 0x1b +'Leng ', # 0x1c +'Peng ', # 0x1d +'Ke ', # 0x1e +'Bing ', # 0x1f +'Chou ', # 0x20 +'Zu ', # 0x21 +'Yu ', # 0x22 +'Su ', # 0x23 +'Lue ', # 0x24 +'[?] ', # 0x25 +'Yi ', # 0x26 +'Xi ', # 0x27 +'Bian ', # 0x28 +'Ji ', # 0x29 +'Fu ', # 0x2a +'Bi ', # 0x2b +'Nuo ', # 0x2c +'Jie ', # 0x2d +'Zhong ', # 0x2e +'Zong ', # 0x2f +'Xu ', # 0x30 +'Cheng ', # 0x31 +'Dao ', # 0x32 +'Wen ', # 0x33 +'Lian ', # 0x34 +'Zi ', # 0x35 +'Yu ', # 0x36 +'Ji ', # 0x37 +'Xu ', # 0x38 +'Zhen ', # 0x39 +'Zhi ', # 0x3a +'Dao ', # 0x3b +'Jia ', # 0x3c +'Ji ', # 0x3d +'Gao ', # 0x3e +'Gao ', # 0x3f +'Gu ', # 0x40 +'Rong ', # 0x41 +'Sui ', # 0x42 +'You ', # 0x43 +'Ji ', # 0x44 +'Kang ', # 0x45 +'Mu ', # 0x46 +'Shan ', # 0x47 +'Men ', # 0x48 +'Zhi ', # 0x49 +'Ji ', # 0x4a +'Lu ', # 0x4b +'Su ', # 0x4c +'Ji ', # 0x4d +'Ying ', # 0x4e +'Wen ', # 0x4f +'Qiu ', # 0x50 +'Se ', # 0x51 +'[?] ', # 0x52 +'Yi ', # 0x53 +'Huang ', # 0x54 +'Qie ', # 0x55 +'Ji ', # 0x56 +'Sui ', # 0x57 +'Xiao ', # 0x58 +'Pu ', # 0x59 +'Jiao ', # 0x5a +'Zhuo ', # 0x5b +'Tong ', # 0x5c +'Sai ', # 0x5d +'Lu ', # 0x5e +'Sui ', # 0x5f +'Nong ', # 0x60 +'Se ', # 0x61 +'Hui ', # 0x62 +'Rang ', # 0x63 +'Nuo ', # 0x64 +'Yu ', # 0x65 +'Bin ', # 0x66 +'Ji ', # 0x67 +'Tui ', # 0x68 +'Wen ', # 0x69 +'Cheng ', # 0x6a +'Huo ', # 0x6b +'Gong ', # 0x6c +'Lu ', # 0x6d +'Biao ', # 0x6e +'[?] ', # 0x6f +'Rang ', # 0x70 +'Zhuo ', # 0x71 +'Li ', # 0x72 +'Zan ', # 0x73 +'Xue ', # 0x74 +'Wa ', # 0x75 +'Jiu ', # 0x76 +'Qiong ', # 0x77 +'Xi ', # 0x78 +'Qiong ', # 0x79 +'Kong ', # 0x7a +'Yu ', # 0x7b +'Sen ', # 0x7c +'Jing ', # 0x7d +'Yao ', # 0x7e +'Chuan ', # 0x7f +'Zhun ', # 0x80 +'Tu ', # 0x81 +'Lao ', # 0x82 +'Qie ', # 0x83 +'Zhai ', # 0x84 +'Yao ', # 0x85 +'Bian ', # 0x86 +'Bao ', # 0x87 +'Yao ', # 0x88 +'Bing ', # 0x89 +'Wa ', # 0x8a +'Zhu ', # 0x8b +'Jiao ', # 0x8c +'Qiao ', # 0x8d +'Diao ', # 0x8e +'Wu ', # 0x8f +'Gui ', # 0x90 +'Yao ', # 0x91 +'Zhi ', # 0x92 +'Chuang ', # 0x93 +'Yao ', # 0x94 +'Tiao ', # 0x95 +'Jiao ', # 0x96 +'Chuang ', # 0x97 +'Jiong ', # 0x98 +'Xiao ', # 0x99 +'Cheng ', # 0x9a +'Kou ', # 0x9b +'Cuan ', # 0x9c +'Wo ', # 0x9d +'Dan ', # 0x9e +'Ku ', # 0x9f +'Ke ', # 0xa0 +'Zhui ', # 0xa1 +'Xu ', # 0xa2 +'Su ', # 0xa3 +'Guan ', # 0xa4 +'Kui ', # 0xa5 +'Dou ', # 0xa6 +'[?] ', # 0xa7 +'Yin ', # 0xa8 +'Wo ', # 0xa9 +'Wa ', # 0xaa +'Ya ', # 0xab +'Yu ', # 0xac +'Ju ', # 0xad +'Qiong ', # 0xae +'Yao ', # 0xaf +'Yao ', # 0xb0 +'Tiao ', # 0xb1 +'Chao ', # 0xb2 +'Yu ', # 0xb3 +'Tian ', # 0xb4 +'Diao ', # 0xb5 +'Ju ', # 0xb6 +'Liao ', # 0xb7 +'Xi ', # 0xb8 +'Wu ', # 0xb9 +'Kui ', # 0xba +'Chuang ', # 0xbb +'Zhao ', # 0xbc +'[?] ', # 0xbd +'Kuan ', # 0xbe +'Long ', # 0xbf +'Cheng ', # 0xc0 +'Cui ', # 0xc1 +'Piao ', # 0xc2 +'Zao ', # 0xc3 +'Cuan ', # 0xc4 +'Qiao ', # 0xc5 +'Qiong ', # 0xc6 +'Dou ', # 0xc7 +'Zao ', # 0xc8 +'Long ', # 0xc9 +'Qie ', # 0xca +'Li ', # 0xcb +'Chu ', # 0xcc +'Shi ', # 0xcd +'Fou ', # 0xce +'Qian ', # 0xcf +'Chu ', # 0xd0 +'Hong ', # 0xd1 +'Qi ', # 0xd2 +'Qian ', # 0xd3 +'Gong ', # 0xd4 +'Shi ', # 0xd5 +'Shu ', # 0xd6 +'Miao ', # 0xd7 +'Ju ', # 0xd8 +'Zhan ', # 0xd9 +'Zhu ', # 0xda +'Ling ', # 0xdb +'Long ', # 0xdc +'Bing ', # 0xdd +'Jing ', # 0xde +'Jing ', # 0xdf +'Zhang ', # 0xe0 +'Yi ', # 0xe1 +'Si ', # 0xe2 +'Jun ', # 0xe3 +'Hong ', # 0xe4 +'Tong ', # 0xe5 +'Song ', # 0xe6 +'Jing ', # 0xe7 +'Diao ', # 0xe8 +'Yi ', # 0xe9 +'Shu ', # 0xea +'Jing ', # 0xeb +'Qu ', # 0xec +'Jie ', # 0xed +'Ping ', # 0xee +'Duan ', # 0xef +'Shao ', # 0xf0 +'Zhuan ', # 0xf1 +'Ceng ', # 0xf2 +'Deng ', # 0xf3 +'Cui ', # 0xf4 +'Huai ', # 0xf5 +'Jing ', # 0xf6 +'Kan ', # 0xf7 +'Jing ', # 0xf8 +'Zhu ', # 0xf9 +'Zhu ', # 0xfa +'Le ', # 0xfb +'Peng ', # 0xfc +'Yu ', # 0xfd +'Chi ', # 0xfe +'Gan ', # 0xff +) diff --git a/libs/unidecode/x07b.py b/libs/unidecode/x07b.py new file mode 100644 index 00000000..c904395c --- /dev/null +++ b/libs/unidecode/x07b.py @@ -0,0 +1,258 @@ +data = ( +'Mang ', # 0x00 +'Zhu ', # 0x01 +'Utsubo ', # 0x02 +'Du ', # 0x03 +'Ji ', # 0x04 +'Xiao ', # 0x05 +'Ba ', # 0x06 +'Suan ', # 0x07 +'Ji ', # 0x08 +'Zhen ', # 0x09 +'Zhao ', # 0x0a +'Sun ', # 0x0b +'Ya ', # 0x0c +'Zhui ', # 0x0d +'Yuan ', # 0x0e +'Hu ', # 0x0f +'Gang ', # 0x10 +'Xiao ', # 0x11 +'Cen ', # 0x12 +'Pi ', # 0x13 +'Bi ', # 0x14 +'Jian ', # 0x15 +'Yi ', # 0x16 +'Dong ', # 0x17 +'Shan ', # 0x18 +'Sheng ', # 0x19 +'Xia ', # 0x1a +'Di ', # 0x1b +'Zhu ', # 0x1c +'Na ', # 0x1d +'Chi ', # 0x1e +'Gu ', # 0x1f +'Li ', # 0x20 +'Qie ', # 0x21 +'Min ', # 0x22 +'Bao ', # 0x23 +'Tiao ', # 0x24 +'Si ', # 0x25 +'Fu ', # 0x26 +'Ce ', # 0x27 +'Ben ', # 0x28 +'Pei ', # 0x29 +'Da ', # 0x2a +'Zi ', # 0x2b +'Di ', # 0x2c +'Ling ', # 0x2d +'Ze ', # 0x2e +'Nu ', # 0x2f +'Fu ', # 0x30 +'Gou ', # 0x31 +'Fan ', # 0x32 +'Jia ', # 0x33 +'Ge ', # 0x34 +'Fan ', # 0x35 +'Shi ', # 0x36 +'Mao ', # 0x37 +'Po ', # 0x38 +'Sey ', # 0x39 +'Jian ', # 0x3a +'Qiong ', # 0x3b +'Long ', # 0x3c +'Souke ', # 0x3d +'Bian ', # 0x3e +'Luo ', # 0x3f +'Gui ', # 0x40 +'Qu ', # 0x41 +'Chi ', # 0x42 +'Yin ', # 0x43 +'Yao ', # 0x44 +'Xian ', # 0x45 +'Bi ', # 0x46 +'Qiong ', # 0x47 +'Gua ', # 0x48 +'Deng ', # 0x49 +'Jiao ', # 0x4a +'Jin ', # 0x4b +'Quan ', # 0x4c +'Sun ', # 0x4d +'Ru ', # 0x4e +'Fa ', # 0x4f +'Kuang ', # 0x50 +'Zhu ', # 0x51 +'Tong ', # 0x52 +'Ji ', # 0x53 +'Da ', # 0x54 +'Xing ', # 0x55 +'Ce ', # 0x56 +'Zhong ', # 0x57 +'Kou ', # 0x58 +'Lai ', # 0x59 +'Bi ', # 0x5a +'Shai ', # 0x5b +'Dang ', # 0x5c +'Zheng ', # 0x5d +'Ce ', # 0x5e +'Fu ', # 0x5f +'Yun ', # 0x60 +'Tu ', # 0x61 +'Pa ', # 0x62 +'Li ', # 0x63 +'Lang ', # 0x64 +'Ju ', # 0x65 +'Guan ', # 0x66 +'Jian ', # 0x67 +'Han ', # 0x68 +'Tong ', # 0x69 +'Xia ', # 0x6a +'Zhi ', # 0x6b +'Cheng ', # 0x6c +'Suan ', # 0x6d +'Shi ', # 0x6e +'Zhu ', # 0x6f +'Zuo ', # 0x70 +'Xiao ', # 0x71 +'Shao ', # 0x72 +'Ting ', # 0x73 +'Ce ', # 0x74 +'Yan ', # 0x75 +'Gao ', # 0x76 +'Kuai ', # 0x77 +'Gan ', # 0x78 +'Chou ', # 0x79 +'Kago ', # 0x7a +'Gang ', # 0x7b +'Yun ', # 0x7c +'O ', # 0x7d +'Qian ', # 0x7e +'Xiao ', # 0x7f +'Jian ', # 0x80 +'Pu ', # 0x81 +'Lai ', # 0x82 +'Zou ', # 0x83 +'Bi ', # 0x84 +'Bi ', # 0x85 +'Bi ', # 0x86 +'Ge ', # 0x87 +'Chi ', # 0x88 +'Guai ', # 0x89 +'Yu ', # 0x8a +'Jian ', # 0x8b +'Zhao ', # 0x8c +'Gu ', # 0x8d +'Chi ', # 0x8e +'Zheng ', # 0x8f +'Jing ', # 0x90 +'Sha ', # 0x91 +'Zhou ', # 0x92 +'Lu ', # 0x93 +'Bo ', # 0x94 +'Ji ', # 0x95 +'Lin ', # 0x96 +'Suan ', # 0x97 +'Jun ', # 0x98 +'Fu ', # 0x99 +'Zha ', # 0x9a +'Gu ', # 0x9b +'Kong ', # 0x9c +'Qian ', # 0x9d +'Quan ', # 0x9e +'Jun ', # 0x9f +'Chui ', # 0xa0 +'Guan ', # 0xa1 +'Yuan ', # 0xa2 +'Ce ', # 0xa3 +'Ju ', # 0xa4 +'Bo ', # 0xa5 +'Ze ', # 0xa6 +'Qie ', # 0xa7 +'Tuo ', # 0xa8 +'Luo ', # 0xa9 +'Dan ', # 0xaa +'Xiao ', # 0xab +'Ruo ', # 0xac +'Jian ', # 0xad +'Xuan ', # 0xae +'Bian ', # 0xaf +'Sun ', # 0xb0 +'Xiang ', # 0xb1 +'Xian ', # 0xb2 +'Ping ', # 0xb3 +'Zhen ', # 0xb4 +'Sheng ', # 0xb5 +'Hu ', # 0xb6 +'Shi ', # 0xb7 +'Zhu ', # 0xb8 +'Yue ', # 0xb9 +'Chun ', # 0xba +'Lu ', # 0xbb +'Wu ', # 0xbc +'Dong ', # 0xbd +'Xiao ', # 0xbe +'Ji ', # 0xbf +'Jie ', # 0xc0 +'Huang ', # 0xc1 +'Xing ', # 0xc2 +'Mei ', # 0xc3 +'Fan ', # 0xc4 +'Chui ', # 0xc5 +'Zhuan ', # 0xc6 +'Pian ', # 0xc7 +'Feng ', # 0xc8 +'Zhu ', # 0xc9 +'Hong ', # 0xca +'Qie ', # 0xcb +'Hou ', # 0xcc +'Qiu ', # 0xcd +'Miao ', # 0xce +'Qian ', # 0xcf +'[?] ', # 0xd0 +'Kui ', # 0xd1 +'Sik ', # 0xd2 +'Lou ', # 0xd3 +'Yun ', # 0xd4 +'He ', # 0xd5 +'Tang ', # 0xd6 +'Yue ', # 0xd7 +'Chou ', # 0xd8 +'Gao ', # 0xd9 +'Fei ', # 0xda +'Ruo ', # 0xdb +'Zheng ', # 0xdc +'Gou ', # 0xdd +'Nie ', # 0xde +'Qian ', # 0xdf +'Xiao ', # 0xe0 +'Cuan ', # 0xe1 +'Gong ', # 0xe2 +'Pang ', # 0xe3 +'Du ', # 0xe4 +'Li ', # 0xe5 +'Bi ', # 0xe6 +'Zhuo ', # 0xe7 +'Chu ', # 0xe8 +'Shai ', # 0xe9 +'Chi ', # 0xea +'Zhu ', # 0xeb +'Qiang ', # 0xec +'Long ', # 0xed +'Lan ', # 0xee +'Jian ', # 0xef +'Bu ', # 0xf0 +'Li ', # 0xf1 +'Hui ', # 0xf2 +'Bi ', # 0xf3 +'Di ', # 0xf4 +'Cong ', # 0xf5 +'Yan ', # 0xf6 +'Peng ', # 0xf7 +'Sen ', # 0xf8 +'Zhuan ', # 0xf9 +'Pai ', # 0xfa +'Piao ', # 0xfb +'Dou ', # 0xfc +'Yu ', # 0xfd +'Mie ', # 0xfe +'Zhuan ', # 0xff +) diff --git a/libs/unidecode/x07c.py b/libs/unidecode/x07c.py new file mode 100644 index 00000000..3379947a --- /dev/null +++ b/libs/unidecode/x07c.py @@ -0,0 +1,258 @@ +data = ( +'Ze ', # 0x00 +'Xi ', # 0x01 +'Guo ', # 0x02 +'Yi ', # 0x03 +'Hu ', # 0x04 +'Chan ', # 0x05 +'Kou ', # 0x06 +'Cu ', # 0x07 +'Ping ', # 0x08 +'Chou ', # 0x09 +'Ji ', # 0x0a +'Gui ', # 0x0b +'Su ', # 0x0c +'Lou ', # 0x0d +'Zha ', # 0x0e +'Lu ', # 0x0f +'Nian ', # 0x10 +'Suo ', # 0x11 +'Cuan ', # 0x12 +'Sasara ', # 0x13 +'Suo ', # 0x14 +'Le ', # 0x15 +'Duan ', # 0x16 +'Yana ', # 0x17 +'Xiao ', # 0x18 +'Bo ', # 0x19 +'Mi ', # 0x1a +'Si ', # 0x1b +'Dang ', # 0x1c +'Liao ', # 0x1d +'Dan ', # 0x1e +'Dian ', # 0x1f +'Fu ', # 0x20 +'Jian ', # 0x21 +'Min ', # 0x22 +'Kui ', # 0x23 +'Dai ', # 0x24 +'Qiao ', # 0x25 +'Deng ', # 0x26 +'Huang ', # 0x27 +'Sun ', # 0x28 +'Lao ', # 0x29 +'Zan ', # 0x2a +'Xiao ', # 0x2b +'Du ', # 0x2c +'Shi ', # 0x2d +'Zan ', # 0x2e +'[?] ', # 0x2f +'Pai ', # 0x30 +'Hata ', # 0x31 +'Pai ', # 0x32 +'Gan ', # 0x33 +'Ju ', # 0x34 +'Du ', # 0x35 +'Lu ', # 0x36 +'Yan ', # 0x37 +'Bo ', # 0x38 +'Dang ', # 0x39 +'Sai ', # 0x3a +'Ke ', # 0x3b +'Long ', # 0x3c +'Qian ', # 0x3d +'Lian ', # 0x3e +'Bo ', # 0x3f +'Zhou ', # 0x40 +'Lai ', # 0x41 +'[?] ', # 0x42 +'Lan ', # 0x43 +'Kui ', # 0x44 +'Yu ', # 0x45 +'Yue ', # 0x46 +'Hao ', # 0x47 +'Zhen ', # 0x48 +'Tai ', # 0x49 +'Ti ', # 0x4a +'Mi ', # 0x4b +'Chou ', # 0x4c +'Ji ', # 0x4d +'[?] ', # 0x4e +'Hata ', # 0x4f +'Teng ', # 0x50 +'Zhuan ', # 0x51 +'Zhou ', # 0x52 +'Fan ', # 0x53 +'Sou ', # 0x54 +'Zhou ', # 0x55 +'Kuji ', # 0x56 +'Zhuo ', # 0x57 +'Teng ', # 0x58 +'Lu ', # 0x59 +'Lu ', # 0x5a +'Jian ', # 0x5b +'Tuo ', # 0x5c +'Ying ', # 0x5d +'Yu ', # 0x5e +'Lai ', # 0x5f +'Long ', # 0x60 +'Shinshi ', # 0x61 +'Lian ', # 0x62 +'Lan ', # 0x63 +'Qian ', # 0x64 +'Yue ', # 0x65 +'Zhong ', # 0x66 +'Qu ', # 0x67 +'Lian ', # 0x68 +'Bian ', # 0x69 +'Duan ', # 0x6a +'Zuan ', # 0x6b +'Li ', # 0x6c +'Si ', # 0x6d +'Luo ', # 0x6e +'Ying ', # 0x6f +'Yue ', # 0x70 +'Zhuo ', # 0x71 +'Xu ', # 0x72 +'Mi ', # 0x73 +'Di ', # 0x74 +'Fan ', # 0x75 +'Shen ', # 0x76 +'Zhe ', # 0x77 +'Shen ', # 0x78 +'Nu ', # 0x79 +'Xie ', # 0x7a +'Lei ', # 0x7b +'Xian ', # 0x7c +'Zi ', # 0x7d +'Ni ', # 0x7e +'Cun ', # 0x7f +'[?] ', # 0x80 +'Qian ', # 0x81 +'Kume ', # 0x82 +'Bi ', # 0x83 +'Ban ', # 0x84 +'Wu ', # 0x85 +'Sha ', # 0x86 +'Kang ', # 0x87 +'Rou ', # 0x88 +'Fen ', # 0x89 +'Bi ', # 0x8a +'Cui ', # 0x8b +'[?] ', # 0x8c +'Li ', # 0x8d +'Chi ', # 0x8e +'Nukamiso ', # 0x8f +'Ro ', # 0x90 +'Ba ', # 0x91 +'Li ', # 0x92 +'Gan ', # 0x93 +'Ju ', # 0x94 +'Po ', # 0x95 +'Mo ', # 0x96 +'Cu ', # 0x97 +'Nian ', # 0x98 +'Zhou ', # 0x99 +'Li ', # 0x9a +'Su ', # 0x9b +'Tiao ', # 0x9c +'Li ', # 0x9d +'Qi ', # 0x9e +'Su ', # 0x9f +'Hong ', # 0xa0 +'Tong ', # 0xa1 +'Zi ', # 0xa2 +'Ce ', # 0xa3 +'Yue ', # 0xa4 +'Zhou ', # 0xa5 +'Lin ', # 0xa6 +'Zhuang ', # 0xa7 +'Bai ', # 0xa8 +'[?] ', # 0xa9 +'Fen ', # 0xaa +'Ji ', # 0xab +'[?] ', # 0xac +'Sukumo ', # 0xad +'Liang ', # 0xae +'Xian ', # 0xaf +'Fu ', # 0xb0 +'Liang ', # 0xb1 +'Can ', # 0xb2 +'Geng ', # 0xb3 +'Li ', # 0xb4 +'Yue ', # 0xb5 +'Lu ', # 0xb6 +'Ju ', # 0xb7 +'Qi ', # 0xb8 +'Cui ', # 0xb9 +'Bai ', # 0xba +'Zhang ', # 0xbb +'Lin ', # 0xbc +'Zong ', # 0xbd +'Jing ', # 0xbe +'Guo ', # 0xbf +'Kouji ', # 0xc0 +'San ', # 0xc1 +'San ', # 0xc2 +'Tang ', # 0xc3 +'Bian ', # 0xc4 +'Rou ', # 0xc5 +'Mian ', # 0xc6 +'Hou ', # 0xc7 +'Xu ', # 0xc8 +'Zong ', # 0xc9 +'Hu ', # 0xca +'Jian ', # 0xcb +'Zan ', # 0xcc +'Ci ', # 0xcd +'Li ', # 0xce +'Xie ', # 0xcf +'Fu ', # 0xd0 +'Ni ', # 0xd1 +'Bei ', # 0xd2 +'Gu ', # 0xd3 +'Xiu ', # 0xd4 +'Gao ', # 0xd5 +'Tang ', # 0xd6 +'Qiu ', # 0xd7 +'Sukumo ', # 0xd8 +'Cao ', # 0xd9 +'Zhuang ', # 0xda +'Tang ', # 0xdb +'Mi ', # 0xdc +'San ', # 0xdd +'Fen ', # 0xde +'Zao ', # 0xdf +'Kang ', # 0xe0 +'Jiang ', # 0xe1 +'Mo ', # 0xe2 +'San ', # 0xe3 +'San ', # 0xe4 +'Nuo ', # 0xe5 +'Xi ', # 0xe6 +'Liang ', # 0xe7 +'Jiang ', # 0xe8 +'Kuai ', # 0xe9 +'Bo ', # 0xea +'Huan ', # 0xeb +'[?] ', # 0xec +'Zong ', # 0xed +'Xian ', # 0xee +'Nuo ', # 0xef +'Tuan ', # 0xf0 +'Nie ', # 0xf1 +'Li ', # 0xf2 +'Zuo ', # 0xf3 +'Di ', # 0xf4 +'Nie ', # 0xf5 +'Tiao ', # 0xf6 +'Lan ', # 0xf7 +'Mi ', # 0xf8 +'Jiao ', # 0xf9 +'Jiu ', # 0xfa +'Xi ', # 0xfb +'Gong ', # 0xfc +'Zheng ', # 0xfd +'Jiu ', # 0xfe +'You ', # 0xff +) diff --git a/libs/unidecode/x07d.py b/libs/unidecode/x07d.py new file mode 100644 index 00000000..241db29c --- /dev/null +++ b/libs/unidecode/x07d.py @@ -0,0 +1,258 @@ +data = ( +'Ji ', # 0x00 +'Cha ', # 0x01 +'Zhou ', # 0x02 +'Xun ', # 0x03 +'Yue ', # 0x04 +'Hong ', # 0x05 +'Yu ', # 0x06 +'He ', # 0x07 +'Wan ', # 0x08 +'Ren ', # 0x09 +'Wen ', # 0x0a +'Wen ', # 0x0b +'Qiu ', # 0x0c +'Na ', # 0x0d +'Zi ', # 0x0e +'Tou ', # 0x0f +'Niu ', # 0x10 +'Fou ', # 0x11 +'Jie ', # 0x12 +'Shu ', # 0x13 +'Chun ', # 0x14 +'Pi ', # 0x15 +'Yin ', # 0x16 +'Sha ', # 0x17 +'Hong ', # 0x18 +'Zhi ', # 0x19 +'Ji ', # 0x1a +'Fen ', # 0x1b +'Yun ', # 0x1c +'Ren ', # 0x1d +'Dan ', # 0x1e +'Jin ', # 0x1f +'Su ', # 0x20 +'Fang ', # 0x21 +'Suo ', # 0x22 +'Cui ', # 0x23 +'Jiu ', # 0x24 +'Zha ', # 0x25 +'Kinu ', # 0x26 +'Jin ', # 0x27 +'Fu ', # 0x28 +'Zhi ', # 0x29 +'Ci ', # 0x2a +'Zi ', # 0x2b +'Chou ', # 0x2c +'Hong ', # 0x2d +'Zha ', # 0x2e +'Lei ', # 0x2f +'Xi ', # 0x30 +'Fu ', # 0x31 +'Xie ', # 0x32 +'Shen ', # 0x33 +'Bei ', # 0x34 +'Zhu ', # 0x35 +'Qu ', # 0x36 +'Ling ', # 0x37 +'Zhu ', # 0x38 +'Shao ', # 0x39 +'Gan ', # 0x3a +'Yang ', # 0x3b +'Fu ', # 0x3c +'Tuo ', # 0x3d +'Zhen ', # 0x3e +'Dai ', # 0x3f +'Zhuo ', # 0x40 +'Shi ', # 0x41 +'Zhong ', # 0x42 +'Xian ', # 0x43 +'Zu ', # 0x44 +'Jiong ', # 0x45 +'Ban ', # 0x46 +'Ju ', # 0x47 +'Mo ', # 0x48 +'Shu ', # 0x49 +'Zui ', # 0x4a +'Wata ', # 0x4b +'Jing ', # 0x4c +'Ren ', # 0x4d +'Heng ', # 0x4e +'Xie ', # 0x4f +'Jie ', # 0x50 +'Zhu ', # 0x51 +'Chou ', # 0x52 +'Gua ', # 0x53 +'Bai ', # 0x54 +'Jue ', # 0x55 +'Kuang ', # 0x56 +'Hu ', # 0x57 +'Ci ', # 0x58 +'Geng ', # 0x59 +'Geng ', # 0x5a +'Tao ', # 0x5b +'Xie ', # 0x5c +'Ku ', # 0x5d +'Jiao ', # 0x5e +'Quan ', # 0x5f +'Gai ', # 0x60 +'Luo ', # 0x61 +'Xuan ', # 0x62 +'Bing ', # 0x63 +'Xian ', # 0x64 +'Fu ', # 0x65 +'Gei ', # 0x66 +'Tong ', # 0x67 +'Rong ', # 0x68 +'Tiao ', # 0x69 +'Yin ', # 0x6a +'Lei ', # 0x6b +'Xie ', # 0x6c +'Quan ', # 0x6d +'Xu ', # 0x6e +'Lun ', # 0x6f +'Die ', # 0x70 +'Tong ', # 0x71 +'Si ', # 0x72 +'Jiang ', # 0x73 +'Xiang ', # 0x74 +'Hui ', # 0x75 +'Jue ', # 0x76 +'Zhi ', # 0x77 +'Jian ', # 0x78 +'Juan ', # 0x79 +'Chi ', # 0x7a +'Mian ', # 0x7b +'Zhen ', # 0x7c +'Lu ', # 0x7d +'Cheng ', # 0x7e +'Qiu ', # 0x7f +'Shu ', # 0x80 +'Bang ', # 0x81 +'Tong ', # 0x82 +'Xiao ', # 0x83 +'Wan ', # 0x84 +'Qin ', # 0x85 +'Geng ', # 0x86 +'Xiu ', # 0x87 +'Ti ', # 0x88 +'Xiu ', # 0x89 +'Xie ', # 0x8a +'Hong ', # 0x8b +'Xi ', # 0x8c +'Fu ', # 0x8d +'Ting ', # 0x8e +'Sui ', # 0x8f +'Dui ', # 0x90 +'Kun ', # 0x91 +'Fu ', # 0x92 +'Jing ', # 0x93 +'Hu ', # 0x94 +'Zhi ', # 0x95 +'Yan ', # 0x96 +'Jiong ', # 0x97 +'Feng ', # 0x98 +'Ji ', # 0x99 +'Sok ', # 0x9a +'Kase ', # 0x9b +'Zong ', # 0x9c +'Lin ', # 0x9d +'Duo ', # 0x9e +'Li ', # 0x9f +'Lu ', # 0xa0 +'Liang ', # 0xa1 +'Chou ', # 0xa2 +'Quan ', # 0xa3 +'Shao ', # 0xa4 +'Qi ', # 0xa5 +'Qi ', # 0xa6 +'Zhun ', # 0xa7 +'Qi ', # 0xa8 +'Wan ', # 0xa9 +'Qian ', # 0xaa +'Xian ', # 0xab +'Shou ', # 0xac +'Wei ', # 0xad +'Qi ', # 0xae +'Tao ', # 0xaf +'Wan ', # 0xb0 +'Gang ', # 0xb1 +'Wang ', # 0xb2 +'Beng ', # 0xb3 +'Zhui ', # 0xb4 +'Cai ', # 0xb5 +'Guo ', # 0xb6 +'Cui ', # 0xb7 +'Lun ', # 0xb8 +'Liu ', # 0xb9 +'Qi ', # 0xba +'Zhan ', # 0xbb +'Bei ', # 0xbc +'Chuo ', # 0xbd +'Ling ', # 0xbe +'Mian ', # 0xbf +'Qi ', # 0xc0 +'Qie ', # 0xc1 +'Tan ', # 0xc2 +'Zong ', # 0xc3 +'Gun ', # 0xc4 +'Zou ', # 0xc5 +'Yi ', # 0xc6 +'Zi ', # 0xc7 +'Xing ', # 0xc8 +'Liang ', # 0xc9 +'Jin ', # 0xca +'Fei ', # 0xcb +'Rui ', # 0xcc +'Min ', # 0xcd +'Yu ', # 0xce +'Zong ', # 0xcf +'Fan ', # 0xd0 +'Lu ', # 0xd1 +'Xu ', # 0xd2 +'Yingl ', # 0xd3 +'Zhang ', # 0xd4 +'Kasuri ', # 0xd5 +'Xu ', # 0xd6 +'Xiang ', # 0xd7 +'Jian ', # 0xd8 +'Ke ', # 0xd9 +'Xian ', # 0xda +'Ruan ', # 0xdb +'Mian ', # 0xdc +'Qi ', # 0xdd +'Duan ', # 0xde +'Zhong ', # 0xdf +'Di ', # 0xe0 +'Min ', # 0xe1 +'Miao ', # 0xe2 +'Yuan ', # 0xe3 +'Xie ', # 0xe4 +'Bao ', # 0xe5 +'Si ', # 0xe6 +'Qiu ', # 0xe7 +'Bian ', # 0xe8 +'Huan ', # 0xe9 +'Geng ', # 0xea +'Cong ', # 0xeb +'Mian ', # 0xec +'Wei ', # 0xed +'Fu ', # 0xee +'Wei ', # 0xef +'Yu ', # 0xf0 +'Gou ', # 0xf1 +'Miao ', # 0xf2 +'Xie ', # 0xf3 +'Lian ', # 0xf4 +'Zong ', # 0xf5 +'Bian ', # 0xf6 +'Yun ', # 0xf7 +'Yin ', # 0xf8 +'Ti ', # 0xf9 +'Gua ', # 0xfa +'Zhi ', # 0xfb +'Yun ', # 0xfc +'Cheng ', # 0xfd +'Chan ', # 0xfe +'Dai ', # 0xff +) diff --git a/libs/unidecode/x07e.py b/libs/unidecode/x07e.py new file mode 100644 index 00000000..131ef35c --- /dev/null +++ b/libs/unidecode/x07e.py @@ -0,0 +1,258 @@ +data = ( +'Xia ', # 0x00 +'Yuan ', # 0x01 +'Zong ', # 0x02 +'Xu ', # 0x03 +'Nawa ', # 0x04 +'Odoshi ', # 0x05 +'Geng ', # 0x06 +'Sen ', # 0x07 +'Ying ', # 0x08 +'Jin ', # 0x09 +'Yi ', # 0x0a +'Zhui ', # 0x0b +'Ni ', # 0x0c +'Bang ', # 0x0d +'Gu ', # 0x0e +'Pan ', # 0x0f +'Zhou ', # 0x10 +'Jian ', # 0x11 +'Cuo ', # 0x12 +'Quan ', # 0x13 +'Shuang ', # 0x14 +'Yun ', # 0x15 +'Xia ', # 0x16 +'Shuai ', # 0x17 +'Xi ', # 0x18 +'Rong ', # 0x19 +'Tao ', # 0x1a +'Fu ', # 0x1b +'Yun ', # 0x1c +'Zhen ', # 0x1d +'Gao ', # 0x1e +'Ru ', # 0x1f +'Hu ', # 0x20 +'Zai ', # 0x21 +'Teng ', # 0x22 +'Xian ', # 0x23 +'Su ', # 0x24 +'Zhen ', # 0x25 +'Zong ', # 0x26 +'Tao ', # 0x27 +'Horo ', # 0x28 +'Cai ', # 0x29 +'Bi ', # 0x2a +'Feng ', # 0x2b +'Cu ', # 0x2c +'Li ', # 0x2d +'Suo ', # 0x2e +'Yin ', # 0x2f +'Xi ', # 0x30 +'Zong ', # 0x31 +'Lei ', # 0x32 +'Zhuan ', # 0x33 +'Qian ', # 0x34 +'Man ', # 0x35 +'Zhi ', # 0x36 +'Lu ', # 0x37 +'Mo ', # 0x38 +'Piao ', # 0x39 +'Lian ', # 0x3a +'Mi ', # 0x3b +'Xuan ', # 0x3c +'Zong ', # 0x3d +'Ji ', # 0x3e +'Shan ', # 0x3f +'Sui ', # 0x40 +'Fan ', # 0x41 +'Shuai ', # 0x42 +'Beng ', # 0x43 +'Yi ', # 0x44 +'Sao ', # 0x45 +'Mou ', # 0x46 +'Zhou ', # 0x47 +'Qiang ', # 0x48 +'Hun ', # 0x49 +'Sem ', # 0x4a +'Xi ', # 0x4b +'Jung ', # 0x4c +'Xiu ', # 0x4d +'Ran ', # 0x4e +'Xuan ', # 0x4f +'Hui ', # 0x50 +'Qiao ', # 0x51 +'Zeng ', # 0x52 +'Zuo ', # 0x53 +'Zhi ', # 0x54 +'Shan ', # 0x55 +'San ', # 0x56 +'Lin ', # 0x57 +'Yu ', # 0x58 +'Fan ', # 0x59 +'Liao ', # 0x5a +'Chuo ', # 0x5b +'Zun ', # 0x5c +'Jian ', # 0x5d +'Rao ', # 0x5e +'Chan ', # 0x5f +'Rui ', # 0x60 +'Xiu ', # 0x61 +'Hui ', # 0x62 +'Hua ', # 0x63 +'Zuan ', # 0x64 +'Xi ', # 0x65 +'Qiang ', # 0x66 +'Un ', # 0x67 +'Da ', # 0x68 +'Sheng ', # 0x69 +'Hui ', # 0x6a +'Xi ', # 0x6b +'Se ', # 0x6c +'Jian ', # 0x6d +'Jiang ', # 0x6e +'Huan ', # 0x6f +'Zao ', # 0x70 +'Cong ', # 0x71 +'Jie ', # 0x72 +'Jiao ', # 0x73 +'Bo ', # 0x74 +'Chan ', # 0x75 +'Yi ', # 0x76 +'Nao ', # 0x77 +'Sui ', # 0x78 +'Yi ', # 0x79 +'Shai ', # 0x7a +'Xu ', # 0x7b +'Ji ', # 0x7c +'Bin ', # 0x7d +'Qian ', # 0x7e +'Lan ', # 0x7f +'Pu ', # 0x80 +'Xun ', # 0x81 +'Zuan ', # 0x82 +'Qi ', # 0x83 +'Peng ', # 0x84 +'Li ', # 0x85 +'Mo ', # 0x86 +'Lei ', # 0x87 +'Xie ', # 0x88 +'Zuan ', # 0x89 +'Kuang ', # 0x8a +'You ', # 0x8b +'Xu ', # 0x8c +'Lei ', # 0x8d +'Xian ', # 0x8e +'Chan ', # 0x8f +'Kou ', # 0x90 +'Lu ', # 0x91 +'Chan ', # 0x92 +'Ying ', # 0x93 +'Cai ', # 0x94 +'Xiang ', # 0x95 +'Xian ', # 0x96 +'Zui ', # 0x97 +'Zuan ', # 0x98 +'Luo ', # 0x99 +'Xi ', # 0x9a +'Dao ', # 0x9b +'Lan ', # 0x9c +'Lei ', # 0x9d +'Lian ', # 0x9e +'Si ', # 0x9f +'Jiu ', # 0xa0 +'Yu ', # 0xa1 +'Hong ', # 0xa2 +'Zhou ', # 0xa3 +'Xian ', # 0xa4 +'He ', # 0xa5 +'Yue ', # 0xa6 +'Ji ', # 0xa7 +'Wan ', # 0xa8 +'Kuang ', # 0xa9 +'Ji ', # 0xaa +'Ren ', # 0xab +'Wei ', # 0xac +'Yun ', # 0xad +'Hong ', # 0xae +'Chun ', # 0xaf +'Pi ', # 0xb0 +'Sha ', # 0xb1 +'Gang ', # 0xb2 +'Na ', # 0xb3 +'Ren ', # 0xb4 +'Zong ', # 0xb5 +'Lun ', # 0xb6 +'Fen ', # 0xb7 +'Zhi ', # 0xb8 +'Wen ', # 0xb9 +'Fang ', # 0xba +'Zhu ', # 0xbb +'Yin ', # 0xbc +'Niu ', # 0xbd +'Shu ', # 0xbe +'Xian ', # 0xbf +'Gan ', # 0xc0 +'Xie ', # 0xc1 +'Fu ', # 0xc2 +'Lian ', # 0xc3 +'Zu ', # 0xc4 +'Shen ', # 0xc5 +'Xi ', # 0xc6 +'Zhi ', # 0xc7 +'Zhong ', # 0xc8 +'Zhou ', # 0xc9 +'Ban ', # 0xca +'Fu ', # 0xcb +'Zhuo ', # 0xcc +'Shao ', # 0xcd +'Yi ', # 0xce +'Jing ', # 0xcf +'Dai ', # 0xd0 +'Bang ', # 0xd1 +'Rong ', # 0xd2 +'Jie ', # 0xd3 +'Ku ', # 0xd4 +'Rao ', # 0xd5 +'Die ', # 0xd6 +'Heng ', # 0xd7 +'Hui ', # 0xd8 +'Gei ', # 0xd9 +'Xuan ', # 0xda +'Jiang ', # 0xdb +'Luo ', # 0xdc +'Jue ', # 0xdd +'Jiao ', # 0xde +'Tong ', # 0xdf +'Geng ', # 0xe0 +'Xiao ', # 0xe1 +'Juan ', # 0xe2 +'Xiu ', # 0xe3 +'Xi ', # 0xe4 +'Sui ', # 0xe5 +'Tao ', # 0xe6 +'Ji ', # 0xe7 +'Ti ', # 0xe8 +'Ji ', # 0xe9 +'Xu ', # 0xea +'Ling ', # 0xeb +'[?] ', # 0xec +'Xu ', # 0xed +'Qi ', # 0xee +'Fei ', # 0xef +'Chuo ', # 0xf0 +'Zhang ', # 0xf1 +'Gun ', # 0xf2 +'Sheng ', # 0xf3 +'Wei ', # 0xf4 +'Mian ', # 0xf5 +'Shou ', # 0xf6 +'Beng ', # 0xf7 +'Chou ', # 0xf8 +'Tao ', # 0xf9 +'Liu ', # 0xfa +'Quan ', # 0xfb +'Zong ', # 0xfc +'Zhan ', # 0xfd +'Wan ', # 0xfe +'Lu ', # 0xff +) diff --git a/libs/unidecode/x07f.py b/libs/unidecode/x07f.py new file mode 100644 index 00000000..0a708d6d --- /dev/null +++ b/libs/unidecode/x07f.py @@ -0,0 +1,258 @@ +data = ( +'Zhui ', # 0x00 +'Zi ', # 0x01 +'Ke ', # 0x02 +'Xiang ', # 0x03 +'Jian ', # 0x04 +'Mian ', # 0x05 +'Lan ', # 0x06 +'Ti ', # 0x07 +'Miao ', # 0x08 +'Qi ', # 0x09 +'Yun ', # 0x0a +'Hui ', # 0x0b +'Si ', # 0x0c +'Duo ', # 0x0d +'Duan ', # 0x0e +'Bian ', # 0x0f +'Xian ', # 0x10 +'Gou ', # 0x11 +'Zhui ', # 0x12 +'Huan ', # 0x13 +'Di ', # 0x14 +'Lu ', # 0x15 +'Bian ', # 0x16 +'Min ', # 0x17 +'Yuan ', # 0x18 +'Jin ', # 0x19 +'Fu ', # 0x1a +'Ru ', # 0x1b +'Zhen ', # 0x1c +'Feng ', # 0x1d +'Shuai ', # 0x1e +'Gao ', # 0x1f +'Chan ', # 0x20 +'Li ', # 0x21 +'Yi ', # 0x22 +'Jian ', # 0x23 +'Bin ', # 0x24 +'Piao ', # 0x25 +'Man ', # 0x26 +'Lei ', # 0x27 +'Ying ', # 0x28 +'Suo ', # 0x29 +'Mou ', # 0x2a +'Sao ', # 0x2b +'Xie ', # 0x2c +'Liao ', # 0x2d +'Shan ', # 0x2e +'Zeng ', # 0x2f +'Jiang ', # 0x30 +'Qian ', # 0x31 +'Zao ', # 0x32 +'Huan ', # 0x33 +'Jiao ', # 0x34 +'Zuan ', # 0x35 +'Fou ', # 0x36 +'Xie ', # 0x37 +'Gang ', # 0x38 +'Fou ', # 0x39 +'Que ', # 0x3a +'Fou ', # 0x3b +'Kaakeru ', # 0x3c +'Bo ', # 0x3d +'Ping ', # 0x3e +'Hou ', # 0x3f +'[?] ', # 0x40 +'Gang ', # 0x41 +'Ying ', # 0x42 +'Ying ', # 0x43 +'Qing ', # 0x44 +'Xia ', # 0x45 +'Guan ', # 0x46 +'Zun ', # 0x47 +'Tan ', # 0x48 +'Chang ', # 0x49 +'Qi ', # 0x4a +'Weng ', # 0x4b +'Ying ', # 0x4c +'Lei ', # 0x4d +'Tan ', # 0x4e +'Lu ', # 0x4f +'Guan ', # 0x50 +'Wang ', # 0x51 +'Wang ', # 0x52 +'Gang ', # 0x53 +'Wang ', # 0x54 +'Han ', # 0x55 +'[?] ', # 0x56 +'Luo ', # 0x57 +'Fu ', # 0x58 +'Mi ', # 0x59 +'Fa ', # 0x5a +'Gu ', # 0x5b +'Zhu ', # 0x5c +'Ju ', # 0x5d +'Mao ', # 0x5e +'Gu ', # 0x5f +'Min ', # 0x60 +'Gang ', # 0x61 +'Ba ', # 0x62 +'Gua ', # 0x63 +'Ti ', # 0x64 +'Juan ', # 0x65 +'Fu ', # 0x66 +'Lin ', # 0x67 +'Yan ', # 0x68 +'Zhao ', # 0x69 +'Zui ', # 0x6a +'Gua ', # 0x6b +'Zhuo ', # 0x6c +'Yu ', # 0x6d +'Zhi ', # 0x6e +'An ', # 0x6f +'Fa ', # 0x70 +'Nan ', # 0x71 +'Shu ', # 0x72 +'Si ', # 0x73 +'Pi ', # 0x74 +'Ma ', # 0x75 +'Liu ', # 0x76 +'Ba ', # 0x77 +'Fa ', # 0x78 +'Li ', # 0x79 +'Chao ', # 0x7a +'Wei ', # 0x7b +'Bi ', # 0x7c +'Ji ', # 0x7d +'Zeng ', # 0x7e +'Tong ', # 0x7f +'Liu ', # 0x80 +'Ji ', # 0x81 +'Juan ', # 0x82 +'Mi ', # 0x83 +'Zhao ', # 0x84 +'Luo ', # 0x85 +'Pi ', # 0x86 +'Ji ', # 0x87 +'Ji ', # 0x88 +'Luan ', # 0x89 +'Yang ', # 0x8a +'Mie ', # 0x8b +'Qiang ', # 0x8c +'Ta ', # 0x8d +'Mei ', # 0x8e +'Yang ', # 0x8f +'You ', # 0x90 +'You ', # 0x91 +'Fen ', # 0x92 +'Ba ', # 0x93 +'Gao ', # 0x94 +'Yang ', # 0x95 +'Gu ', # 0x96 +'Qiang ', # 0x97 +'Zang ', # 0x98 +'Gao ', # 0x99 +'Ling ', # 0x9a +'Yi ', # 0x9b +'Zhu ', # 0x9c +'Di ', # 0x9d +'Xiu ', # 0x9e +'Qian ', # 0x9f +'Yi ', # 0xa0 +'Xian ', # 0xa1 +'Rong ', # 0xa2 +'Qun ', # 0xa3 +'Qun ', # 0xa4 +'Qian ', # 0xa5 +'Huan ', # 0xa6 +'Zui ', # 0xa7 +'Xian ', # 0xa8 +'Yi ', # 0xa9 +'Yashinau ', # 0xaa +'Qiang ', # 0xab +'Xian ', # 0xac +'Yu ', # 0xad +'Geng ', # 0xae +'Jie ', # 0xaf +'Tang ', # 0xb0 +'Yuan ', # 0xb1 +'Xi ', # 0xb2 +'Fan ', # 0xb3 +'Shan ', # 0xb4 +'Fen ', # 0xb5 +'Shan ', # 0xb6 +'Lian ', # 0xb7 +'Lei ', # 0xb8 +'Geng ', # 0xb9 +'Nou ', # 0xba +'Qiang ', # 0xbb +'Chan ', # 0xbc +'Yu ', # 0xbd +'Gong ', # 0xbe +'Yi ', # 0xbf +'Chong ', # 0xc0 +'Weng ', # 0xc1 +'Fen ', # 0xc2 +'Hong ', # 0xc3 +'Chi ', # 0xc4 +'Chi ', # 0xc5 +'Cui ', # 0xc6 +'Fu ', # 0xc7 +'Xia ', # 0xc8 +'Pen ', # 0xc9 +'Yi ', # 0xca +'La ', # 0xcb +'Yi ', # 0xcc +'Pi ', # 0xcd +'Ling ', # 0xce +'Liu ', # 0xcf +'Zhi ', # 0xd0 +'Qu ', # 0xd1 +'Xi ', # 0xd2 +'Xie ', # 0xd3 +'Xiang ', # 0xd4 +'Xi ', # 0xd5 +'Xi ', # 0xd6 +'Qi ', # 0xd7 +'Qiao ', # 0xd8 +'Hui ', # 0xd9 +'Hui ', # 0xda +'Xiao ', # 0xdb +'Se ', # 0xdc +'Hong ', # 0xdd +'Jiang ', # 0xde +'Di ', # 0xdf +'Cui ', # 0xe0 +'Fei ', # 0xe1 +'Tao ', # 0xe2 +'Sha ', # 0xe3 +'Chi ', # 0xe4 +'Zhu ', # 0xe5 +'Jian ', # 0xe6 +'Xuan ', # 0xe7 +'Shi ', # 0xe8 +'Pian ', # 0xe9 +'Zong ', # 0xea +'Wan ', # 0xeb +'Hui ', # 0xec +'Hou ', # 0xed +'He ', # 0xee +'He ', # 0xef +'Han ', # 0xf0 +'Ao ', # 0xf1 +'Piao ', # 0xf2 +'Yi ', # 0xf3 +'Lian ', # 0xf4 +'Qu ', # 0xf5 +'[?] ', # 0xf6 +'Lin ', # 0xf7 +'Pen ', # 0xf8 +'Qiao ', # 0xf9 +'Ao ', # 0xfa +'Fan ', # 0xfb +'Yi ', # 0xfc +'Hui ', # 0xfd +'Xuan ', # 0xfe +'Dao ', # 0xff +) diff --git a/libs/unidecode/x080.py b/libs/unidecode/x080.py new file mode 100644 index 00000000..11f324b4 --- /dev/null +++ b/libs/unidecode/x080.py @@ -0,0 +1,258 @@ +data = ( +'Yao ', # 0x00 +'Lao ', # 0x01 +'[?] ', # 0x02 +'Kao ', # 0x03 +'Mao ', # 0x04 +'Zhe ', # 0x05 +'Qi ', # 0x06 +'Gou ', # 0x07 +'Gou ', # 0x08 +'Gou ', # 0x09 +'Die ', # 0x0a +'Die ', # 0x0b +'Er ', # 0x0c +'Shua ', # 0x0d +'Ruan ', # 0x0e +'Er ', # 0x0f +'Nai ', # 0x10 +'Zhuan ', # 0x11 +'Lei ', # 0x12 +'Ting ', # 0x13 +'Zi ', # 0x14 +'Geng ', # 0x15 +'Chao ', # 0x16 +'Hao ', # 0x17 +'Yun ', # 0x18 +'Pa ', # 0x19 +'Pi ', # 0x1a +'Chi ', # 0x1b +'Si ', # 0x1c +'Chu ', # 0x1d +'Jia ', # 0x1e +'Ju ', # 0x1f +'He ', # 0x20 +'Chu ', # 0x21 +'Lao ', # 0x22 +'Lun ', # 0x23 +'Ji ', # 0x24 +'Tang ', # 0x25 +'Ou ', # 0x26 +'Lou ', # 0x27 +'Nou ', # 0x28 +'Gou ', # 0x29 +'Pang ', # 0x2a +'Ze ', # 0x2b +'Lou ', # 0x2c +'Ji ', # 0x2d +'Lao ', # 0x2e +'Huo ', # 0x2f +'You ', # 0x30 +'Mo ', # 0x31 +'Huai ', # 0x32 +'Er ', # 0x33 +'Zhe ', # 0x34 +'Ting ', # 0x35 +'Ye ', # 0x36 +'Da ', # 0x37 +'Song ', # 0x38 +'Qin ', # 0x39 +'Yun ', # 0x3a +'Chi ', # 0x3b +'Dan ', # 0x3c +'Dan ', # 0x3d +'Hong ', # 0x3e +'Geng ', # 0x3f +'Zhi ', # 0x40 +'[?] ', # 0x41 +'Nie ', # 0x42 +'Dan ', # 0x43 +'Zhen ', # 0x44 +'Che ', # 0x45 +'Ling ', # 0x46 +'Zheng ', # 0x47 +'You ', # 0x48 +'Wa ', # 0x49 +'Liao ', # 0x4a +'Long ', # 0x4b +'Zhi ', # 0x4c +'Ning ', # 0x4d +'Tiao ', # 0x4e +'Er ', # 0x4f +'Ya ', # 0x50 +'Die ', # 0x51 +'Gua ', # 0x52 +'[?] ', # 0x53 +'Lian ', # 0x54 +'Hao ', # 0x55 +'Sheng ', # 0x56 +'Lie ', # 0x57 +'Pin ', # 0x58 +'Jing ', # 0x59 +'Ju ', # 0x5a +'Bi ', # 0x5b +'Di ', # 0x5c +'Guo ', # 0x5d +'Wen ', # 0x5e +'Xu ', # 0x5f +'Ping ', # 0x60 +'Cong ', # 0x61 +'Shikato ', # 0x62 +'[?] ', # 0x63 +'Ting ', # 0x64 +'Yu ', # 0x65 +'Cong ', # 0x66 +'Kui ', # 0x67 +'Tsuraneru ', # 0x68 +'Kui ', # 0x69 +'Cong ', # 0x6a +'Lian ', # 0x6b +'Weng ', # 0x6c +'Kui ', # 0x6d +'Lian ', # 0x6e +'Lian ', # 0x6f +'Cong ', # 0x70 +'Ao ', # 0x71 +'Sheng ', # 0x72 +'Song ', # 0x73 +'Ting ', # 0x74 +'Kui ', # 0x75 +'Nie ', # 0x76 +'Zhi ', # 0x77 +'Dan ', # 0x78 +'Ning ', # 0x79 +'Qie ', # 0x7a +'Ji ', # 0x7b +'Ting ', # 0x7c +'Ting ', # 0x7d +'Long ', # 0x7e +'Yu ', # 0x7f +'Yu ', # 0x80 +'Zhao ', # 0x81 +'Si ', # 0x82 +'Su ', # 0x83 +'Yi ', # 0x84 +'Su ', # 0x85 +'Si ', # 0x86 +'Zhao ', # 0x87 +'Zhao ', # 0x88 +'Rou ', # 0x89 +'Yi ', # 0x8a +'Le ', # 0x8b +'Ji ', # 0x8c +'Qiu ', # 0x8d +'Ken ', # 0x8e +'Cao ', # 0x8f +'Ge ', # 0x90 +'Di ', # 0x91 +'Huan ', # 0x92 +'Huang ', # 0x93 +'Yi ', # 0x94 +'Ren ', # 0x95 +'Xiao ', # 0x96 +'Ru ', # 0x97 +'Zhou ', # 0x98 +'Yuan ', # 0x99 +'Du ', # 0x9a +'Gang ', # 0x9b +'Rong ', # 0x9c +'Gan ', # 0x9d +'Cha ', # 0x9e +'Wo ', # 0x9f +'Chang ', # 0xa0 +'Gu ', # 0xa1 +'Zhi ', # 0xa2 +'Han ', # 0xa3 +'Fu ', # 0xa4 +'Fei ', # 0xa5 +'Fen ', # 0xa6 +'Pei ', # 0xa7 +'Pang ', # 0xa8 +'Jian ', # 0xa9 +'Fang ', # 0xaa +'Zhun ', # 0xab +'You ', # 0xac +'Na ', # 0xad +'Hang ', # 0xae +'Ken ', # 0xaf +'Ran ', # 0xb0 +'Gong ', # 0xb1 +'Yu ', # 0xb2 +'Wen ', # 0xb3 +'Yao ', # 0xb4 +'Jin ', # 0xb5 +'Pi ', # 0xb6 +'Qian ', # 0xb7 +'Xi ', # 0xb8 +'Xi ', # 0xb9 +'Fei ', # 0xba +'Ken ', # 0xbb +'Jing ', # 0xbc +'Tai ', # 0xbd +'Shen ', # 0xbe +'Zhong ', # 0xbf +'Zhang ', # 0xc0 +'Xie ', # 0xc1 +'Shen ', # 0xc2 +'Wei ', # 0xc3 +'Zhou ', # 0xc4 +'Die ', # 0xc5 +'Dan ', # 0xc6 +'Fei ', # 0xc7 +'Ba ', # 0xc8 +'Bo ', # 0xc9 +'Qu ', # 0xca +'Tian ', # 0xcb +'Bei ', # 0xcc +'Gua ', # 0xcd +'Tai ', # 0xce +'Zi ', # 0xcf +'Ku ', # 0xd0 +'Zhi ', # 0xd1 +'Ni ', # 0xd2 +'Ping ', # 0xd3 +'Zi ', # 0xd4 +'Fu ', # 0xd5 +'Pang ', # 0xd6 +'Zhen ', # 0xd7 +'Xian ', # 0xd8 +'Zuo ', # 0xd9 +'Pei ', # 0xda +'Jia ', # 0xdb +'Sheng ', # 0xdc +'Zhi ', # 0xdd +'Bao ', # 0xde +'Mu ', # 0xdf +'Qu ', # 0xe0 +'Hu ', # 0xe1 +'Ke ', # 0xe2 +'Yi ', # 0xe3 +'Yin ', # 0xe4 +'Xu ', # 0xe5 +'Yang ', # 0xe6 +'Long ', # 0xe7 +'Dong ', # 0xe8 +'Ka ', # 0xe9 +'Lu ', # 0xea +'Jing ', # 0xeb +'Nu ', # 0xec +'Yan ', # 0xed +'Pang ', # 0xee +'Kua ', # 0xef +'Yi ', # 0xf0 +'Guang ', # 0xf1 +'Gai ', # 0xf2 +'Ge ', # 0xf3 +'Dong ', # 0xf4 +'Zhi ', # 0xf5 +'Xiao ', # 0xf6 +'Xiong ', # 0xf7 +'Xiong ', # 0xf8 +'Er ', # 0xf9 +'E ', # 0xfa +'Xing ', # 0xfb +'Pian ', # 0xfc +'Neng ', # 0xfd +'Zi ', # 0xfe +'Gui ', # 0xff +) diff --git a/libs/unidecode/x081.py b/libs/unidecode/x081.py new file mode 100644 index 00000000..01ca95d3 --- /dev/null +++ b/libs/unidecode/x081.py @@ -0,0 +1,258 @@ +data = ( +'Cheng ', # 0x00 +'Tiao ', # 0x01 +'Zhi ', # 0x02 +'Cui ', # 0x03 +'Mei ', # 0x04 +'Xie ', # 0x05 +'Cui ', # 0x06 +'Xie ', # 0x07 +'Mo ', # 0x08 +'Mai ', # 0x09 +'Ji ', # 0x0a +'Obiyaakasu ', # 0x0b +'[?] ', # 0x0c +'Kuai ', # 0x0d +'Sa ', # 0x0e +'Zang ', # 0x0f +'Qi ', # 0x10 +'Nao ', # 0x11 +'Mi ', # 0x12 +'Nong ', # 0x13 +'Luan ', # 0x14 +'Wan ', # 0x15 +'Bo ', # 0x16 +'Wen ', # 0x17 +'Guan ', # 0x18 +'Qiu ', # 0x19 +'Jiao ', # 0x1a +'Jing ', # 0x1b +'Rou ', # 0x1c +'Heng ', # 0x1d +'Cuo ', # 0x1e +'Lie ', # 0x1f +'Shan ', # 0x20 +'Ting ', # 0x21 +'Mei ', # 0x22 +'Chun ', # 0x23 +'Shen ', # 0x24 +'Xie ', # 0x25 +'De ', # 0x26 +'Zui ', # 0x27 +'Cu ', # 0x28 +'Xiu ', # 0x29 +'Xin ', # 0x2a +'Tuo ', # 0x2b +'Pao ', # 0x2c +'Cheng ', # 0x2d +'Nei ', # 0x2e +'Fu ', # 0x2f +'Dou ', # 0x30 +'Tuo ', # 0x31 +'Niao ', # 0x32 +'Noy ', # 0x33 +'Pi ', # 0x34 +'Gu ', # 0x35 +'Gua ', # 0x36 +'Li ', # 0x37 +'Lian ', # 0x38 +'Zhang ', # 0x39 +'Cui ', # 0x3a +'Jie ', # 0x3b +'Liang ', # 0x3c +'Zhou ', # 0x3d +'Pi ', # 0x3e +'Biao ', # 0x3f +'Lun ', # 0x40 +'Pian ', # 0x41 +'Guo ', # 0x42 +'Kui ', # 0x43 +'Chui ', # 0x44 +'Dan ', # 0x45 +'Tian ', # 0x46 +'Nei ', # 0x47 +'Jing ', # 0x48 +'Jie ', # 0x49 +'La ', # 0x4a +'Yi ', # 0x4b +'An ', # 0x4c +'Ren ', # 0x4d +'Shen ', # 0x4e +'Chuo ', # 0x4f +'Fu ', # 0x50 +'Fu ', # 0x51 +'Ju ', # 0x52 +'Fei ', # 0x53 +'Qiang ', # 0x54 +'Wan ', # 0x55 +'Dong ', # 0x56 +'Pi ', # 0x57 +'Guo ', # 0x58 +'Zong ', # 0x59 +'Ding ', # 0x5a +'Wu ', # 0x5b +'Mei ', # 0x5c +'Ruan ', # 0x5d +'Zhuan ', # 0x5e +'Zhi ', # 0x5f +'Cou ', # 0x60 +'Gua ', # 0x61 +'Ou ', # 0x62 +'Di ', # 0x63 +'An ', # 0x64 +'Xing ', # 0x65 +'Nao ', # 0x66 +'Yu ', # 0x67 +'Chuan ', # 0x68 +'Nan ', # 0x69 +'Yun ', # 0x6a +'Zhong ', # 0x6b +'Rou ', # 0x6c +'E ', # 0x6d +'Sai ', # 0x6e +'Tu ', # 0x6f +'Yao ', # 0x70 +'Jian ', # 0x71 +'Wei ', # 0x72 +'Jiao ', # 0x73 +'Yu ', # 0x74 +'Jia ', # 0x75 +'Duan ', # 0x76 +'Bi ', # 0x77 +'Chang ', # 0x78 +'Fu ', # 0x79 +'Xian ', # 0x7a +'Ni ', # 0x7b +'Mian ', # 0x7c +'Wa ', # 0x7d +'Teng ', # 0x7e +'Tui ', # 0x7f +'Bang ', # 0x80 +'Qian ', # 0x81 +'Lu ', # 0x82 +'Wa ', # 0x83 +'Sou ', # 0x84 +'Tang ', # 0x85 +'Su ', # 0x86 +'Zhui ', # 0x87 +'Ge ', # 0x88 +'Yi ', # 0x89 +'Bo ', # 0x8a +'Liao ', # 0x8b +'Ji ', # 0x8c +'Pi ', # 0x8d +'Xie ', # 0x8e +'Gao ', # 0x8f +'Lu ', # 0x90 +'Bin ', # 0x91 +'Ou ', # 0x92 +'Chang ', # 0x93 +'Lu ', # 0x94 +'Guo ', # 0x95 +'Pang ', # 0x96 +'Chuai ', # 0x97 +'Piao ', # 0x98 +'Jiang ', # 0x99 +'Fu ', # 0x9a +'Tang ', # 0x9b +'Mo ', # 0x9c +'Xi ', # 0x9d +'Zhuan ', # 0x9e +'Lu ', # 0x9f +'Jiao ', # 0xa0 +'Ying ', # 0xa1 +'Lu ', # 0xa2 +'Zhi ', # 0xa3 +'Tara ', # 0xa4 +'Chun ', # 0xa5 +'Lian ', # 0xa6 +'Tong ', # 0xa7 +'Peng ', # 0xa8 +'Ni ', # 0xa9 +'Zha ', # 0xaa +'Liao ', # 0xab +'Cui ', # 0xac +'Gui ', # 0xad +'Xiao ', # 0xae +'Teng ', # 0xaf +'Fan ', # 0xb0 +'Zhi ', # 0xb1 +'Jiao ', # 0xb2 +'Shan ', # 0xb3 +'Wu ', # 0xb4 +'Cui ', # 0xb5 +'Run ', # 0xb6 +'Xiang ', # 0xb7 +'Sui ', # 0xb8 +'Fen ', # 0xb9 +'Ying ', # 0xba +'Tan ', # 0xbb +'Zhua ', # 0xbc +'Dan ', # 0xbd +'Kuai ', # 0xbe +'Nong ', # 0xbf +'Tun ', # 0xc0 +'Lian ', # 0xc1 +'Bi ', # 0xc2 +'Yong ', # 0xc3 +'Jue ', # 0xc4 +'Chu ', # 0xc5 +'Yi ', # 0xc6 +'Juan ', # 0xc7 +'La ', # 0xc8 +'Lian ', # 0xc9 +'Sao ', # 0xca +'Tun ', # 0xcb +'Gu ', # 0xcc +'Qi ', # 0xcd +'Cui ', # 0xce +'Bin ', # 0xcf +'Xun ', # 0xd0 +'Ru ', # 0xd1 +'Huo ', # 0xd2 +'Zang ', # 0xd3 +'Xian ', # 0xd4 +'Biao ', # 0xd5 +'Xing ', # 0xd6 +'Kuan ', # 0xd7 +'La ', # 0xd8 +'Yan ', # 0xd9 +'Lu ', # 0xda +'Huo ', # 0xdb +'Zang ', # 0xdc +'Luo ', # 0xdd +'Qu ', # 0xde +'Zang ', # 0xdf +'Luan ', # 0xe0 +'Ni ', # 0xe1 +'Zang ', # 0xe2 +'Chen ', # 0xe3 +'Qian ', # 0xe4 +'Wo ', # 0xe5 +'Guang ', # 0xe6 +'Zang ', # 0xe7 +'Lin ', # 0xe8 +'Guang ', # 0xe9 +'Zi ', # 0xea +'Jiao ', # 0xeb +'Nie ', # 0xec +'Chou ', # 0xed +'Ji ', # 0xee +'Gao ', # 0xef +'Chou ', # 0xf0 +'Mian ', # 0xf1 +'Nie ', # 0xf2 +'Zhi ', # 0xf3 +'Zhi ', # 0xf4 +'Ge ', # 0xf5 +'Jian ', # 0xf6 +'Die ', # 0xf7 +'Zhi ', # 0xf8 +'Xiu ', # 0xf9 +'Tai ', # 0xfa +'Zhen ', # 0xfb +'Jiu ', # 0xfc +'Xian ', # 0xfd +'Yu ', # 0xfe +'Cha ', # 0xff +) diff --git a/libs/unidecode/x082.py b/libs/unidecode/x082.py new file mode 100644 index 00000000..daea2e23 --- /dev/null +++ b/libs/unidecode/x082.py @@ -0,0 +1,258 @@ +data = ( +'Yao ', # 0x00 +'Yu ', # 0x01 +'Chong ', # 0x02 +'Xi ', # 0x03 +'Xi ', # 0x04 +'Jiu ', # 0x05 +'Yu ', # 0x06 +'Yu ', # 0x07 +'Xing ', # 0x08 +'Ju ', # 0x09 +'Jiu ', # 0x0a +'Xin ', # 0x0b +'She ', # 0x0c +'She ', # 0x0d +'Yadoru ', # 0x0e +'Jiu ', # 0x0f +'Shi ', # 0x10 +'Tan ', # 0x11 +'Shu ', # 0x12 +'Shi ', # 0x13 +'Tian ', # 0x14 +'Dan ', # 0x15 +'Pu ', # 0x16 +'Pu ', # 0x17 +'Guan ', # 0x18 +'Hua ', # 0x19 +'Tan ', # 0x1a +'Chuan ', # 0x1b +'Shun ', # 0x1c +'Xia ', # 0x1d +'Wu ', # 0x1e +'Zhou ', # 0x1f +'Dao ', # 0x20 +'Gang ', # 0x21 +'Shan ', # 0x22 +'Yi ', # 0x23 +'[?] ', # 0x24 +'Pa ', # 0x25 +'Tai ', # 0x26 +'Fan ', # 0x27 +'Ban ', # 0x28 +'Chuan ', # 0x29 +'Hang ', # 0x2a +'Fang ', # 0x2b +'Ban ', # 0x2c +'Que ', # 0x2d +'Hesaki ', # 0x2e +'Zhong ', # 0x2f +'Jian ', # 0x30 +'Cang ', # 0x31 +'Ling ', # 0x32 +'Zhu ', # 0x33 +'Ze ', # 0x34 +'Duo ', # 0x35 +'Bo ', # 0x36 +'Xian ', # 0x37 +'Ge ', # 0x38 +'Chuan ', # 0x39 +'Jia ', # 0x3a +'Lu ', # 0x3b +'Hong ', # 0x3c +'Pang ', # 0x3d +'Xi ', # 0x3e +'[?] ', # 0x3f +'Fu ', # 0x40 +'Zao ', # 0x41 +'Feng ', # 0x42 +'Li ', # 0x43 +'Shao ', # 0x44 +'Yu ', # 0x45 +'Lang ', # 0x46 +'Ting ', # 0x47 +'[?] ', # 0x48 +'Wei ', # 0x49 +'Bo ', # 0x4a +'Meng ', # 0x4b +'Nian ', # 0x4c +'Ju ', # 0x4d +'Huang ', # 0x4e +'Shou ', # 0x4f +'Zong ', # 0x50 +'Bian ', # 0x51 +'Mao ', # 0x52 +'Die ', # 0x53 +'[?] ', # 0x54 +'Bang ', # 0x55 +'Cha ', # 0x56 +'Yi ', # 0x57 +'Sao ', # 0x58 +'Cang ', # 0x59 +'Cao ', # 0x5a +'Lou ', # 0x5b +'Dai ', # 0x5c +'Sori ', # 0x5d +'Yao ', # 0x5e +'Tong ', # 0x5f +'Yofune ', # 0x60 +'Dang ', # 0x61 +'Tan ', # 0x62 +'Lu ', # 0x63 +'Yi ', # 0x64 +'Jie ', # 0x65 +'Jian ', # 0x66 +'Huo ', # 0x67 +'Meng ', # 0x68 +'Qi ', # 0x69 +'Lu ', # 0x6a +'Lu ', # 0x6b +'Chan ', # 0x6c +'Shuang ', # 0x6d +'Gen ', # 0x6e +'Liang ', # 0x6f +'Jian ', # 0x70 +'Jian ', # 0x71 +'Se ', # 0x72 +'Yan ', # 0x73 +'Fu ', # 0x74 +'Ping ', # 0x75 +'Yan ', # 0x76 +'Yan ', # 0x77 +'Cao ', # 0x78 +'Cao ', # 0x79 +'Yi ', # 0x7a +'Le ', # 0x7b +'Ting ', # 0x7c +'Qiu ', # 0x7d +'Ai ', # 0x7e +'Nai ', # 0x7f +'Tiao ', # 0x80 +'Jiao ', # 0x81 +'Jie ', # 0x82 +'Peng ', # 0x83 +'Wan ', # 0x84 +'Yi ', # 0x85 +'Chai ', # 0x86 +'Mian ', # 0x87 +'Mie ', # 0x88 +'Gan ', # 0x89 +'Qian ', # 0x8a +'Yu ', # 0x8b +'Yu ', # 0x8c +'Shuo ', # 0x8d +'Qiong ', # 0x8e +'Tu ', # 0x8f +'Xia ', # 0x90 +'Qi ', # 0x91 +'Mang ', # 0x92 +'Zi ', # 0x93 +'Hui ', # 0x94 +'Sui ', # 0x95 +'Zhi ', # 0x96 +'Xiang ', # 0x97 +'Bi ', # 0x98 +'Fu ', # 0x99 +'Tun ', # 0x9a +'Wei ', # 0x9b +'Wu ', # 0x9c +'Zhi ', # 0x9d +'Qi ', # 0x9e +'Shan ', # 0x9f +'Wen ', # 0xa0 +'Qian ', # 0xa1 +'Ren ', # 0xa2 +'Fou ', # 0xa3 +'Kou ', # 0xa4 +'Jie ', # 0xa5 +'Lu ', # 0xa6 +'Xu ', # 0xa7 +'Ji ', # 0xa8 +'Qin ', # 0xa9 +'Qi ', # 0xaa +'Yuan ', # 0xab +'Fen ', # 0xac +'Ba ', # 0xad +'Rui ', # 0xae +'Xin ', # 0xaf +'Ji ', # 0xb0 +'Hua ', # 0xb1 +'Hua ', # 0xb2 +'Fang ', # 0xb3 +'Wu ', # 0xb4 +'Jue ', # 0xb5 +'Gou ', # 0xb6 +'Zhi ', # 0xb7 +'Yun ', # 0xb8 +'Qin ', # 0xb9 +'Ao ', # 0xba +'Chu ', # 0xbb +'Mao ', # 0xbc +'Ya ', # 0xbd +'Fei ', # 0xbe +'Reng ', # 0xbf +'Hang ', # 0xc0 +'Cong ', # 0xc1 +'Yin ', # 0xc2 +'You ', # 0xc3 +'Bian ', # 0xc4 +'Yi ', # 0xc5 +'Susa ', # 0xc6 +'Wei ', # 0xc7 +'Li ', # 0xc8 +'Pi ', # 0xc9 +'E ', # 0xca +'Xian ', # 0xcb +'Chang ', # 0xcc +'Cang ', # 0xcd +'Meng ', # 0xce +'Su ', # 0xcf +'Yi ', # 0xd0 +'Yuan ', # 0xd1 +'Ran ', # 0xd2 +'Ling ', # 0xd3 +'Tai ', # 0xd4 +'Tiao ', # 0xd5 +'Di ', # 0xd6 +'Miao ', # 0xd7 +'Qiong ', # 0xd8 +'Li ', # 0xd9 +'Yong ', # 0xda +'Ke ', # 0xdb +'Mu ', # 0xdc +'Pei ', # 0xdd +'Bao ', # 0xde +'Gou ', # 0xdf +'Min ', # 0xe0 +'Yi ', # 0xe1 +'Yi ', # 0xe2 +'Ju ', # 0xe3 +'Pi ', # 0xe4 +'Ruo ', # 0xe5 +'Ku ', # 0xe6 +'Zhu ', # 0xe7 +'Ni ', # 0xe8 +'Bo ', # 0xe9 +'Bing ', # 0xea +'Shan ', # 0xeb +'Qiu ', # 0xec +'Yao ', # 0xed +'Xian ', # 0xee +'Ben ', # 0xef +'Hong ', # 0xf0 +'Ying ', # 0xf1 +'Zha ', # 0xf2 +'Dong ', # 0xf3 +'Ju ', # 0xf4 +'Die ', # 0xf5 +'Nie ', # 0xf6 +'Gan ', # 0xf7 +'Hu ', # 0xf8 +'Ping ', # 0xf9 +'Mei ', # 0xfa +'Fu ', # 0xfb +'Sheng ', # 0xfc +'Gu ', # 0xfd +'Bi ', # 0xfe +'Wei ', # 0xff +) diff --git a/libs/unidecode/x083.py b/libs/unidecode/x083.py new file mode 100644 index 00000000..672cd5d8 --- /dev/null +++ b/libs/unidecode/x083.py @@ -0,0 +1,258 @@ +data = ( +'Fu ', # 0x00 +'Zhuo ', # 0x01 +'Mao ', # 0x02 +'Fan ', # 0x03 +'Qie ', # 0x04 +'Mao ', # 0x05 +'Mao ', # 0x06 +'Ba ', # 0x07 +'Zi ', # 0x08 +'Mo ', # 0x09 +'Zi ', # 0x0a +'Di ', # 0x0b +'Chi ', # 0x0c +'Ji ', # 0x0d +'Jing ', # 0x0e +'Long ', # 0x0f +'[?] ', # 0x10 +'Niao ', # 0x11 +'[?] ', # 0x12 +'Xue ', # 0x13 +'Ying ', # 0x14 +'Qiong ', # 0x15 +'Ge ', # 0x16 +'Ming ', # 0x17 +'Li ', # 0x18 +'Rong ', # 0x19 +'Yin ', # 0x1a +'Gen ', # 0x1b +'Qian ', # 0x1c +'Chai ', # 0x1d +'Chen ', # 0x1e +'Yu ', # 0x1f +'Xiu ', # 0x20 +'Zi ', # 0x21 +'Lie ', # 0x22 +'Wu ', # 0x23 +'Ji ', # 0x24 +'Kui ', # 0x25 +'Ce ', # 0x26 +'Chong ', # 0x27 +'Ci ', # 0x28 +'Gou ', # 0x29 +'Guang ', # 0x2a +'Mang ', # 0x2b +'Chi ', # 0x2c +'Jiao ', # 0x2d +'Jiao ', # 0x2e +'Fu ', # 0x2f +'Yu ', # 0x30 +'Zhu ', # 0x31 +'Zi ', # 0x32 +'Jiang ', # 0x33 +'Hui ', # 0x34 +'Yin ', # 0x35 +'Cha ', # 0x36 +'Fa ', # 0x37 +'Rong ', # 0x38 +'Ru ', # 0x39 +'Chong ', # 0x3a +'Mang ', # 0x3b +'Tong ', # 0x3c +'Zhong ', # 0x3d +'[?] ', # 0x3e +'Zhu ', # 0x3f +'Xun ', # 0x40 +'Huan ', # 0x41 +'Kua ', # 0x42 +'Quan ', # 0x43 +'Gai ', # 0x44 +'Da ', # 0x45 +'Jing ', # 0x46 +'Xing ', # 0x47 +'Quan ', # 0x48 +'Cao ', # 0x49 +'Jing ', # 0x4a +'Er ', # 0x4b +'An ', # 0x4c +'Shou ', # 0x4d +'Chi ', # 0x4e +'Ren ', # 0x4f +'Jian ', # 0x50 +'Ti ', # 0x51 +'Huang ', # 0x52 +'Ping ', # 0x53 +'Li ', # 0x54 +'Jin ', # 0x55 +'Lao ', # 0x56 +'Shu ', # 0x57 +'Zhuang ', # 0x58 +'Da ', # 0x59 +'Jia ', # 0x5a +'Rao ', # 0x5b +'Bi ', # 0x5c +'Ze ', # 0x5d +'Qiao ', # 0x5e +'Hui ', # 0x5f +'Qi ', # 0x60 +'Dang ', # 0x61 +'[?] ', # 0x62 +'Rong ', # 0x63 +'Hun ', # 0x64 +'Ying ', # 0x65 +'Luo ', # 0x66 +'Ying ', # 0x67 +'Xun ', # 0x68 +'Jin ', # 0x69 +'Sun ', # 0x6a +'Yin ', # 0x6b +'Mai ', # 0x6c +'Hong ', # 0x6d +'Zhou ', # 0x6e +'Yao ', # 0x6f +'Du ', # 0x70 +'Wei ', # 0x71 +'Chu ', # 0x72 +'Dou ', # 0x73 +'Fu ', # 0x74 +'Ren ', # 0x75 +'Yin ', # 0x76 +'He ', # 0x77 +'Bi ', # 0x78 +'Bu ', # 0x79 +'Yun ', # 0x7a +'Di ', # 0x7b +'Tu ', # 0x7c +'Sui ', # 0x7d +'Sui ', # 0x7e +'Cheng ', # 0x7f +'Chen ', # 0x80 +'Wu ', # 0x81 +'Bie ', # 0x82 +'Xi ', # 0x83 +'Geng ', # 0x84 +'Li ', # 0x85 +'Fu ', # 0x86 +'Zhu ', # 0x87 +'Mo ', # 0x88 +'Li ', # 0x89 +'Zhuang ', # 0x8a +'Ji ', # 0x8b +'Duo ', # 0x8c +'Qiu ', # 0x8d +'Sha ', # 0x8e +'Suo ', # 0x8f +'Chen ', # 0x90 +'Feng ', # 0x91 +'Ju ', # 0x92 +'Mei ', # 0x93 +'Meng ', # 0x94 +'Xing ', # 0x95 +'Jing ', # 0x96 +'Che ', # 0x97 +'Xin ', # 0x98 +'Jun ', # 0x99 +'Yan ', # 0x9a +'Ting ', # 0x9b +'Diao ', # 0x9c +'Cuo ', # 0x9d +'Wan ', # 0x9e +'Han ', # 0x9f +'You ', # 0xa0 +'Cuo ', # 0xa1 +'Jia ', # 0xa2 +'Wang ', # 0xa3 +'You ', # 0xa4 +'Niu ', # 0xa5 +'Shao ', # 0xa6 +'Xian ', # 0xa7 +'Lang ', # 0xa8 +'Fu ', # 0xa9 +'E ', # 0xaa +'Mo ', # 0xab +'Wen ', # 0xac +'Jie ', # 0xad +'Nan ', # 0xae +'Mu ', # 0xaf +'Kan ', # 0xb0 +'Lai ', # 0xb1 +'Lian ', # 0xb2 +'Shi ', # 0xb3 +'Wo ', # 0xb4 +'Usagi ', # 0xb5 +'Lian ', # 0xb6 +'Huo ', # 0xb7 +'You ', # 0xb8 +'Ying ', # 0xb9 +'Ying ', # 0xba +'Nuc ', # 0xbb +'Chun ', # 0xbc +'Mang ', # 0xbd +'Mang ', # 0xbe +'Ci ', # 0xbf +'Wan ', # 0xc0 +'Jing ', # 0xc1 +'Di ', # 0xc2 +'Qu ', # 0xc3 +'Dong ', # 0xc4 +'Jian ', # 0xc5 +'Zou ', # 0xc6 +'Gu ', # 0xc7 +'La ', # 0xc8 +'Lu ', # 0xc9 +'Ju ', # 0xca +'Wei ', # 0xcb +'Jun ', # 0xcc +'Nie ', # 0xcd +'Kun ', # 0xce +'He ', # 0xcf +'Pu ', # 0xd0 +'Zi ', # 0xd1 +'Gao ', # 0xd2 +'Guo ', # 0xd3 +'Fu ', # 0xd4 +'Lun ', # 0xd5 +'Chang ', # 0xd6 +'Chou ', # 0xd7 +'Song ', # 0xd8 +'Chui ', # 0xd9 +'Zhan ', # 0xda +'Men ', # 0xdb +'Cai ', # 0xdc +'Ba ', # 0xdd +'Li ', # 0xde +'Tu ', # 0xdf +'Bo ', # 0xe0 +'Han ', # 0xe1 +'Bao ', # 0xe2 +'Qin ', # 0xe3 +'Juan ', # 0xe4 +'Xi ', # 0xe5 +'Qin ', # 0xe6 +'Di ', # 0xe7 +'Jie ', # 0xe8 +'Pu ', # 0xe9 +'Dang ', # 0xea +'Jin ', # 0xeb +'Zhao ', # 0xec +'Tai ', # 0xed +'Geng ', # 0xee +'Hua ', # 0xef +'Gu ', # 0xf0 +'Ling ', # 0xf1 +'Fei ', # 0xf2 +'Jin ', # 0xf3 +'An ', # 0xf4 +'Wang ', # 0xf5 +'Beng ', # 0xf6 +'Zhou ', # 0xf7 +'Yan ', # 0xf8 +'Ju ', # 0xf9 +'Jian ', # 0xfa +'Lin ', # 0xfb +'Tan ', # 0xfc +'Shu ', # 0xfd +'Tian ', # 0xfe +'Dao ', # 0xff +) diff --git a/libs/unidecode/x084.py b/libs/unidecode/x084.py new file mode 100644 index 00000000..571a3607 --- /dev/null +++ b/libs/unidecode/x084.py @@ -0,0 +1,258 @@ +data = ( +'Hu ', # 0x00 +'Qi ', # 0x01 +'He ', # 0x02 +'Cui ', # 0x03 +'Tao ', # 0x04 +'Chun ', # 0x05 +'Bei ', # 0x06 +'Chang ', # 0x07 +'Huan ', # 0x08 +'Fei ', # 0x09 +'Lai ', # 0x0a +'Qi ', # 0x0b +'Meng ', # 0x0c +'Ping ', # 0x0d +'Wei ', # 0x0e +'Dan ', # 0x0f +'Sha ', # 0x10 +'Huan ', # 0x11 +'Yan ', # 0x12 +'Yi ', # 0x13 +'Tiao ', # 0x14 +'Qi ', # 0x15 +'Wan ', # 0x16 +'Ce ', # 0x17 +'Nai ', # 0x18 +'Kutabireru ', # 0x19 +'Tuo ', # 0x1a +'Jiu ', # 0x1b +'Tie ', # 0x1c +'Luo ', # 0x1d +'[?] ', # 0x1e +'[?] ', # 0x1f +'Meng ', # 0x20 +'[?] ', # 0x21 +'Yaji ', # 0x22 +'[?] ', # 0x23 +'Ying ', # 0x24 +'Ying ', # 0x25 +'Ying ', # 0x26 +'Xiao ', # 0x27 +'Sa ', # 0x28 +'Qiu ', # 0x29 +'Ke ', # 0x2a +'Xiang ', # 0x2b +'Wan ', # 0x2c +'Yu ', # 0x2d +'Yu ', # 0x2e +'Fu ', # 0x2f +'Lian ', # 0x30 +'Xuan ', # 0x31 +'Yuan ', # 0x32 +'Nan ', # 0x33 +'Ze ', # 0x34 +'Wo ', # 0x35 +'Chun ', # 0x36 +'Xiao ', # 0x37 +'Yu ', # 0x38 +'Pian ', # 0x39 +'Mao ', # 0x3a +'An ', # 0x3b +'E ', # 0x3c +'Luo ', # 0x3d +'Ying ', # 0x3e +'Huo ', # 0x3f +'Gua ', # 0x40 +'Jiang ', # 0x41 +'Mian ', # 0x42 +'Zuo ', # 0x43 +'Zuo ', # 0x44 +'Ju ', # 0x45 +'Bao ', # 0x46 +'Rou ', # 0x47 +'Xi ', # 0x48 +'Xie ', # 0x49 +'An ', # 0x4a +'Qu ', # 0x4b +'Jian ', # 0x4c +'Fu ', # 0x4d +'Lu ', # 0x4e +'Jing ', # 0x4f +'Pen ', # 0x50 +'Feng ', # 0x51 +'Hong ', # 0x52 +'Hong ', # 0x53 +'Hou ', # 0x54 +'Yan ', # 0x55 +'Tu ', # 0x56 +'Zhu ', # 0x57 +'Zi ', # 0x58 +'Xiang ', # 0x59 +'Shen ', # 0x5a +'Ge ', # 0x5b +'Jie ', # 0x5c +'Jing ', # 0x5d +'Mi ', # 0x5e +'Huang ', # 0x5f +'Shen ', # 0x60 +'Pu ', # 0x61 +'Gai ', # 0x62 +'Dong ', # 0x63 +'Zhou ', # 0x64 +'Qian ', # 0x65 +'Wei ', # 0x66 +'Bo ', # 0x67 +'Wei ', # 0x68 +'Pa ', # 0x69 +'Ji ', # 0x6a +'Hu ', # 0x6b +'Zang ', # 0x6c +'Jia ', # 0x6d +'Duan ', # 0x6e +'Yao ', # 0x6f +'Jun ', # 0x70 +'Cong ', # 0x71 +'Quan ', # 0x72 +'Wei ', # 0x73 +'Xian ', # 0x74 +'Kui ', # 0x75 +'Ting ', # 0x76 +'Hun ', # 0x77 +'Xi ', # 0x78 +'Shi ', # 0x79 +'Qi ', # 0x7a +'Lan ', # 0x7b +'Zong ', # 0x7c +'Yao ', # 0x7d +'Yuan ', # 0x7e +'Mei ', # 0x7f +'Yun ', # 0x80 +'Shu ', # 0x81 +'Di ', # 0x82 +'Zhuan ', # 0x83 +'Guan ', # 0x84 +'Sukumo ', # 0x85 +'Xue ', # 0x86 +'Chan ', # 0x87 +'Kai ', # 0x88 +'Kui ', # 0x89 +'[?] ', # 0x8a +'Jiang ', # 0x8b +'Lou ', # 0x8c +'Wei ', # 0x8d +'Pai ', # 0x8e +'[?] ', # 0x8f +'Sou ', # 0x90 +'Yin ', # 0x91 +'Shi ', # 0x92 +'Chun ', # 0x93 +'Shi ', # 0x94 +'Yun ', # 0x95 +'Zhen ', # 0x96 +'Lang ', # 0x97 +'Nu ', # 0x98 +'Meng ', # 0x99 +'He ', # 0x9a +'Que ', # 0x9b +'Suan ', # 0x9c +'Yuan ', # 0x9d +'Li ', # 0x9e +'Ju ', # 0x9f +'Xi ', # 0xa0 +'Pang ', # 0xa1 +'Chu ', # 0xa2 +'Xu ', # 0xa3 +'Tu ', # 0xa4 +'Liu ', # 0xa5 +'Wo ', # 0xa6 +'Zhen ', # 0xa7 +'Qian ', # 0xa8 +'Zu ', # 0xa9 +'Po ', # 0xaa +'Cuo ', # 0xab +'Yuan ', # 0xac +'Chu ', # 0xad +'Yu ', # 0xae +'Kuai ', # 0xaf +'Pan ', # 0xb0 +'Pu ', # 0xb1 +'Pu ', # 0xb2 +'Na ', # 0xb3 +'Shuo ', # 0xb4 +'Xi ', # 0xb5 +'Fen ', # 0xb6 +'Yun ', # 0xb7 +'Zheng ', # 0xb8 +'Jian ', # 0xb9 +'Ji ', # 0xba +'Ruo ', # 0xbb +'Cang ', # 0xbc +'En ', # 0xbd +'Mi ', # 0xbe +'Hao ', # 0xbf +'Sun ', # 0xc0 +'Zhen ', # 0xc1 +'Ming ', # 0xc2 +'Sou ', # 0xc3 +'Xu ', # 0xc4 +'Liu ', # 0xc5 +'Xi ', # 0xc6 +'Gu ', # 0xc7 +'Lang ', # 0xc8 +'Rong ', # 0xc9 +'Weng ', # 0xca +'Gai ', # 0xcb +'Cuo ', # 0xcc +'Shi ', # 0xcd +'Tang ', # 0xce +'Luo ', # 0xcf +'Ru ', # 0xd0 +'Suo ', # 0xd1 +'Xian ', # 0xd2 +'Bei ', # 0xd3 +'Yao ', # 0xd4 +'Gui ', # 0xd5 +'Bi ', # 0xd6 +'Zong ', # 0xd7 +'Gun ', # 0xd8 +'Za ', # 0xd9 +'Xiu ', # 0xda +'Ce ', # 0xdb +'Hai ', # 0xdc +'Lan ', # 0xdd +'[?] ', # 0xde +'Ji ', # 0xdf +'Li ', # 0xe0 +'Can ', # 0xe1 +'Lang ', # 0xe2 +'Yu ', # 0xe3 +'[?] ', # 0xe4 +'Ying ', # 0xe5 +'Mo ', # 0xe6 +'Diao ', # 0xe7 +'Tiao ', # 0xe8 +'Mao ', # 0xe9 +'Tong ', # 0xea +'Zhu ', # 0xeb +'Peng ', # 0xec +'An ', # 0xed +'Lian ', # 0xee +'Cong ', # 0xef +'Xi ', # 0xf0 +'Ping ', # 0xf1 +'Qiu ', # 0xf2 +'Jin ', # 0xf3 +'Chun ', # 0xf4 +'Jie ', # 0xf5 +'Wei ', # 0xf6 +'Tui ', # 0xf7 +'Cao ', # 0xf8 +'Yu ', # 0xf9 +'Yi ', # 0xfa +'Ji ', # 0xfb +'Liao ', # 0xfc +'Bi ', # 0xfd +'Lu ', # 0xfe +'Su ', # 0xff +) diff --git a/libs/unidecode/x085.py b/libs/unidecode/x085.py new file mode 100644 index 00000000..c11c513b --- /dev/null +++ b/libs/unidecode/x085.py @@ -0,0 +1,258 @@ +data = ( +'Bu ', # 0x00 +'Zhang ', # 0x01 +'Luo ', # 0x02 +'Jiang ', # 0x03 +'Man ', # 0x04 +'Yan ', # 0x05 +'Ling ', # 0x06 +'Ji ', # 0x07 +'Piao ', # 0x08 +'Gun ', # 0x09 +'Han ', # 0x0a +'Di ', # 0x0b +'Su ', # 0x0c +'Lu ', # 0x0d +'She ', # 0x0e +'Shang ', # 0x0f +'Di ', # 0x10 +'Mie ', # 0x11 +'Xun ', # 0x12 +'Man ', # 0x13 +'Bo ', # 0x14 +'Di ', # 0x15 +'Cuo ', # 0x16 +'Zhe ', # 0x17 +'Sen ', # 0x18 +'Xuan ', # 0x19 +'Wei ', # 0x1a +'Hu ', # 0x1b +'Ao ', # 0x1c +'Mi ', # 0x1d +'Lou ', # 0x1e +'Cu ', # 0x1f +'Zhong ', # 0x20 +'Cai ', # 0x21 +'Po ', # 0x22 +'Jiang ', # 0x23 +'Mi ', # 0x24 +'Cong ', # 0x25 +'Niao ', # 0x26 +'Hui ', # 0x27 +'Jun ', # 0x28 +'Yin ', # 0x29 +'Jian ', # 0x2a +'Yan ', # 0x2b +'Shu ', # 0x2c +'Yin ', # 0x2d +'Kui ', # 0x2e +'Chen ', # 0x2f +'Hu ', # 0x30 +'Sha ', # 0x31 +'Kou ', # 0x32 +'Qian ', # 0x33 +'Ma ', # 0x34 +'Zang ', # 0x35 +'Sonoko ', # 0x36 +'Qiang ', # 0x37 +'Dou ', # 0x38 +'Lian ', # 0x39 +'Lin ', # 0x3a +'Kou ', # 0x3b +'Ai ', # 0x3c +'Bi ', # 0x3d +'Li ', # 0x3e +'Wei ', # 0x3f +'Ji ', # 0x40 +'Xun ', # 0x41 +'Sheng ', # 0x42 +'Fan ', # 0x43 +'Meng ', # 0x44 +'Ou ', # 0x45 +'Chan ', # 0x46 +'Dian ', # 0x47 +'Xun ', # 0x48 +'Jiao ', # 0x49 +'Rui ', # 0x4a +'Rui ', # 0x4b +'Lei ', # 0x4c +'Yu ', # 0x4d +'Qiao ', # 0x4e +'Chu ', # 0x4f +'Hua ', # 0x50 +'Jian ', # 0x51 +'Mai ', # 0x52 +'Yun ', # 0x53 +'Bao ', # 0x54 +'You ', # 0x55 +'Qu ', # 0x56 +'Lu ', # 0x57 +'Rao ', # 0x58 +'Hui ', # 0x59 +'E ', # 0x5a +'Teng ', # 0x5b +'Fei ', # 0x5c +'Jue ', # 0x5d +'Zui ', # 0x5e +'Fa ', # 0x5f +'Ru ', # 0x60 +'Fen ', # 0x61 +'Kui ', # 0x62 +'Shun ', # 0x63 +'Rui ', # 0x64 +'Ya ', # 0x65 +'Xu ', # 0x66 +'Fu ', # 0x67 +'Jue ', # 0x68 +'Dang ', # 0x69 +'Wu ', # 0x6a +'Tong ', # 0x6b +'Si ', # 0x6c +'Xiao ', # 0x6d +'Xi ', # 0x6e +'Long ', # 0x6f +'Yun ', # 0x70 +'[?] ', # 0x71 +'Qi ', # 0x72 +'Jian ', # 0x73 +'Yun ', # 0x74 +'Sun ', # 0x75 +'Ling ', # 0x76 +'Yu ', # 0x77 +'Xia ', # 0x78 +'Yong ', # 0x79 +'Ji ', # 0x7a +'Hong ', # 0x7b +'Si ', # 0x7c +'Nong ', # 0x7d +'Lei ', # 0x7e +'Xuan ', # 0x7f +'Yun ', # 0x80 +'Yu ', # 0x81 +'Xi ', # 0x82 +'Hao ', # 0x83 +'Bo ', # 0x84 +'Hao ', # 0x85 +'Ai ', # 0x86 +'Wei ', # 0x87 +'Hui ', # 0x88 +'Wei ', # 0x89 +'Ji ', # 0x8a +'Ci ', # 0x8b +'Xiang ', # 0x8c +'Luan ', # 0x8d +'Mie ', # 0x8e +'Yi ', # 0x8f +'Leng ', # 0x90 +'Jiang ', # 0x91 +'Can ', # 0x92 +'Shen ', # 0x93 +'Qiang ', # 0x94 +'Lian ', # 0x95 +'Ke ', # 0x96 +'Yuan ', # 0x97 +'Da ', # 0x98 +'Ti ', # 0x99 +'Tang ', # 0x9a +'Xie ', # 0x9b +'Bi ', # 0x9c +'Zhan ', # 0x9d +'Sun ', # 0x9e +'Lian ', # 0x9f +'Fan ', # 0xa0 +'Ding ', # 0xa1 +'Jie ', # 0xa2 +'Gu ', # 0xa3 +'Xie ', # 0xa4 +'Shu ', # 0xa5 +'Jian ', # 0xa6 +'Kao ', # 0xa7 +'Hong ', # 0xa8 +'Sa ', # 0xa9 +'Xin ', # 0xaa +'Xun ', # 0xab +'Yao ', # 0xac +'Hie ', # 0xad +'Sou ', # 0xae +'Shu ', # 0xaf +'Xun ', # 0xb0 +'Dui ', # 0xb1 +'Pin ', # 0xb2 +'Wei ', # 0xb3 +'Neng ', # 0xb4 +'Chou ', # 0xb5 +'Mai ', # 0xb6 +'Ru ', # 0xb7 +'Piao ', # 0xb8 +'Tai ', # 0xb9 +'Qi ', # 0xba +'Zao ', # 0xbb +'Chen ', # 0xbc +'Zhen ', # 0xbd +'Er ', # 0xbe +'Ni ', # 0xbf +'Ying ', # 0xc0 +'Gao ', # 0xc1 +'Cong ', # 0xc2 +'Xiao ', # 0xc3 +'Qi ', # 0xc4 +'Fa ', # 0xc5 +'Jian ', # 0xc6 +'Xu ', # 0xc7 +'Kui ', # 0xc8 +'Jie ', # 0xc9 +'Bian ', # 0xca +'Diao ', # 0xcb +'Mi ', # 0xcc +'Lan ', # 0xcd +'Jin ', # 0xce +'Cang ', # 0xcf +'Miao ', # 0xd0 +'Qiong ', # 0xd1 +'Qie ', # 0xd2 +'Xian ', # 0xd3 +'[?] ', # 0xd4 +'Ou ', # 0xd5 +'Xian ', # 0xd6 +'Su ', # 0xd7 +'Lu ', # 0xd8 +'Yi ', # 0xd9 +'Xu ', # 0xda +'Xie ', # 0xdb +'Li ', # 0xdc +'Yi ', # 0xdd +'La ', # 0xde +'Lei ', # 0xdf +'Xiao ', # 0xe0 +'Di ', # 0xe1 +'Zhi ', # 0xe2 +'Bei ', # 0xe3 +'Teng ', # 0xe4 +'Yao ', # 0xe5 +'Mo ', # 0xe6 +'Huan ', # 0xe7 +'Piao ', # 0xe8 +'Fan ', # 0xe9 +'Sou ', # 0xea +'Tan ', # 0xeb +'Tui ', # 0xec +'Qiong ', # 0xed +'Qiao ', # 0xee +'Wei ', # 0xef +'Liu ', # 0xf0 +'Hui ', # 0xf1 +'[?] ', # 0xf2 +'Gao ', # 0xf3 +'Yun ', # 0xf4 +'[?] ', # 0xf5 +'Li ', # 0xf6 +'Shu ', # 0xf7 +'Chu ', # 0xf8 +'Ai ', # 0xf9 +'Lin ', # 0xfa +'Zao ', # 0xfb +'Xuan ', # 0xfc +'Chen ', # 0xfd +'Lai ', # 0xfe +'Huo ', # 0xff +) diff --git a/libs/unidecode/x086.py b/libs/unidecode/x086.py new file mode 100644 index 00000000..38784a61 --- /dev/null +++ b/libs/unidecode/x086.py @@ -0,0 +1,258 @@ +data = ( +'Tuo ', # 0x00 +'Wu ', # 0x01 +'Rui ', # 0x02 +'Rui ', # 0x03 +'Qi ', # 0x04 +'Heng ', # 0x05 +'Lu ', # 0x06 +'Su ', # 0x07 +'Tui ', # 0x08 +'Mang ', # 0x09 +'Yun ', # 0x0a +'Pin ', # 0x0b +'Yu ', # 0x0c +'Xun ', # 0x0d +'Ji ', # 0x0e +'Jiong ', # 0x0f +'Xian ', # 0x10 +'Mo ', # 0x11 +'Hagi ', # 0x12 +'Su ', # 0x13 +'Jiong ', # 0x14 +'[?] ', # 0x15 +'Nie ', # 0x16 +'Bo ', # 0x17 +'Rang ', # 0x18 +'Yi ', # 0x19 +'Xian ', # 0x1a +'Yu ', # 0x1b +'Ju ', # 0x1c +'Lian ', # 0x1d +'Lian ', # 0x1e +'Yin ', # 0x1f +'Qiang ', # 0x20 +'Ying ', # 0x21 +'Long ', # 0x22 +'Tong ', # 0x23 +'Wei ', # 0x24 +'Yue ', # 0x25 +'Ling ', # 0x26 +'Qu ', # 0x27 +'Yao ', # 0x28 +'Fan ', # 0x29 +'Mi ', # 0x2a +'Lan ', # 0x2b +'Kui ', # 0x2c +'Lan ', # 0x2d +'Ji ', # 0x2e +'Dang ', # 0x2f +'Katsura ', # 0x30 +'Lei ', # 0x31 +'Lei ', # 0x32 +'Hua ', # 0x33 +'Feng ', # 0x34 +'Zhi ', # 0x35 +'Wei ', # 0x36 +'Kui ', # 0x37 +'Zhan ', # 0x38 +'Huai ', # 0x39 +'Li ', # 0x3a +'Ji ', # 0x3b +'Mi ', # 0x3c +'Lei ', # 0x3d +'Huai ', # 0x3e +'Luo ', # 0x3f +'Ji ', # 0x40 +'Kui ', # 0x41 +'Lu ', # 0x42 +'Jian ', # 0x43 +'San ', # 0x44 +'[?] ', # 0x45 +'Lei ', # 0x46 +'Quan ', # 0x47 +'Xiao ', # 0x48 +'Yi ', # 0x49 +'Luan ', # 0x4a +'Men ', # 0x4b +'Bie ', # 0x4c +'Hu ', # 0x4d +'Hu ', # 0x4e +'Lu ', # 0x4f +'Nue ', # 0x50 +'Lu ', # 0x51 +'Si ', # 0x52 +'Xiao ', # 0x53 +'Qian ', # 0x54 +'Chu ', # 0x55 +'Hu ', # 0x56 +'Xu ', # 0x57 +'Cuo ', # 0x58 +'Fu ', # 0x59 +'Xu ', # 0x5a +'Xu ', # 0x5b +'Lu ', # 0x5c +'Hu ', # 0x5d +'Yu ', # 0x5e +'Hao ', # 0x5f +'Jiao ', # 0x60 +'Ju ', # 0x61 +'Guo ', # 0x62 +'Bao ', # 0x63 +'Yan ', # 0x64 +'Zhan ', # 0x65 +'Zhan ', # 0x66 +'Kui ', # 0x67 +'Ban ', # 0x68 +'Xi ', # 0x69 +'Shu ', # 0x6a +'Chong ', # 0x6b +'Qiu ', # 0x6c +'Diao ', # 0x6d +'Ji ', # 0x6e +'Qiu ', # 0x6f +'Cheng ', # 0x70 +'Shi ', # 0x71 +'[?] ', # 0x72 +'Di ', # 0x73 +'Zhe ', # 0x74 +'She ', # 0x75 +'Yu ', # 0x76 +'Gan ', # 0x77 +'Zi ', # 0x78 +'Hong ', # 0x79 +'Hui ', # 0x7a +'Meng ', # 0x7b +'Ge ', # 0x7c +'Sui ', # 0x7d +'Xia ', # 0x7e +'Chai ', # 0x7f +'Shi ', # 0x80 +'Yi ', # 0x81 +'Ma ', # 0x82 +'Xiang ', # 0x83 +'Fang ', # 0x84 +'E ', # 0x85 +'Pa ', # 0x86 +'Chi ', # 0x87 +'Qian ', # 0x88 +'Wen ', # 0x89 +'Wen ', # 0x8a +'Rui ', # 0x8b +'Bang ', # 0x8c +'Bi ', # 0x8d +'Yue ', # 0x8e +'Yue ', # 0x8f +'Jun ', # 0x90 +'Qi ', # 0x91 +'Ran ', # 0x92 +'Yin ', # 0x93 +'Qi ', # 0x94 +'Tian ', # 0x95 +'Yuan ', # 0x96 +'Jue ', # 0x97 +'Hui ', # 0x98 +'Qin ', # 0x99 +'Qi ', # 0x9a +'Zhong ', # 0x9b +'Ya ', # 0x9c +'Ci ', # 0x9d +'Mu ', # 0x9e +'Wang ', # 0x9f +'Fen ', # 0xa0 +'Fen ', # 0xa1 +'Hang ', # 0xa2 +'Gong ', # 0xa3 +'Zao ', # 0xa4 +'Fu ', # 0xa5 +'Ran ', # 0xa6 +'Jie ', # 0xa7 +'Fu ', # 0xa8 +'Chi ', # 0xa9 +'Dou ', # 0xaa +'Piao ', # 0xab +'Xian ', # 0xac +'Ni ', # 0xad +'Te ', # 0xae +'Qiu ', # 0xaf +'You ', # 0xb0 +'Zha ', # 0xb1 +'Ping ', # 0xb2 +'Chi ', # 0xb3 +'You ', # 0xb4 +'He ', # 0xb5 +'Han ', # 0xb6 +'Ju ', # 0xb7 +'Li ', # 0xb8 +'Fu ', # 0xb9 +'Ran ', # 0xba +'Zha ', # 0xbb +'Gou ', # 0xbc +'Pi ', # 0xbd +'Bo ', # 0xbe +'Xian ', # 0xbf +'Zhu ', # 0xc0 +'Diao ', # 0xc1 +'Bie ', # 0xc2 +'Bing ', # 0xc3 +'Gu ', # 0xc4 +'Ran ', # 0xc5 +'Qu ', # 0xc6 +'She ', # 0xc7 +'Tie ', # 0xc8 +'Ling ', # 0xc9 +'Gu ', # 0xca +'Dan ', # 0xcb +'Gu ', # 0xcc +'Ying ', # 0xcd +'Li ', # 0xce +'Cheng ', # 0xcf +'Qu ', # 0xd0 +'Mou ', # 0xd1 +'Ge ', # 0xd2 +'Ci ', # 0xd3 +'Hui ', # 0xd4 +'Hui ', # 0xd5 +'Mang ', # 0xd6 +'Fu ', # 0xd7 +'Yang ', # 0xd8 +'Wa ', # 0xd9 +'Lie ', # 0xda +'Zhu ', # 0xdb +'Yi ', # 0xdc +'Xian ', # 0xdd +'Kuo ', # 0xde +'Jiao ', # 0xdf +'Li ', # 0xe0 +'Yi ', # 0xe1 +'Ping ', # 0xe2 +'Ji ', # 0xe3 +'Ha ', # 0xe4 +'She ', # 0xe5 +'Yi ', # 0xe6 +'Wang ', # 0xe7 +'Mo ', # 0xe8 +'Qiong ', # 0xe9 +'Qie ', # 0xea +'Gui ', # 0xeb +'Gong ', # 0xec +'Zhi ', # 0xed +'Man ', # 0xee +'Ebi ', # 0xef +'Zhi ', # 0xf0 +'Jia ', # 0xf1 +'Rao ', # 0xf2 +'Si ', # 0xf3 +'Qi ', # 0xf4 +'Xing ', # 0xf5 +'Lie ', # 0xf6 +'Qiu ', # 0xf7 +'Shao ', # 0xf8 +'Yong ', # 0xf9 +'Jia ', # 0xfa +'Shui ', # 0xfb +'Che ', # 0xfc +'Bai ', # 0xfd +'E ', # 0xfe +'Han ', # 0xff +) diff --git a/libs/unidecode/x087.py b/libs/unidecode/x087.py new file mode 100644 index 00000000..2a2b79aa --- /dev/null +++ b/libs/unidecode/x087.py @@ -0,0 +1,258 @@ +data = ( +'Shu ', # 0x00 +'Xuan ', # 0x01 +'Feng ', # 0x02 +'Shen ', # 0x03 +'Zhen ', # 0x04 +'Fu ', # 0x05 +'Xian ', # 0x06 +'Zhe ', # 0x07 +'Wu ', # 0x08 +'Fu ', # 0x09 +'Li ', # 0x0a +'Lang ', # 0x0b +'Bi ', # 0x0c +'Chu ', # 0x0d +'Yuan ', # 0x0e +'You ', # 0x0f +'Jie ', # 0x10 +'Dan ', # 0x11 +'Yan ', # 0x12 +'Ting ', # 0x13 +'Dian ', # 0x14 +'Shui ', # 0x15 +'Hui ', # 0x16 +'Gua ', # 0x17 +'Zhi ', # 0x18 +'Song ', # 0x19 +'Fei ', # 0x1a +'Ju ', # 0x1b +'Mi ', # 0x1c +'Qi ', # 0x1d +'Qi ', # 0x1e +'Yu ', # 0x1f +'Jun ', # 0x20 +'Zha ', # 0x21 +'Meng ', # 0x22 +'Qiang ', # 0x23 +'Si ', # 0x24 +'Xi ', # 0x25 +'Lun ', # 0x26 +'Li ', # 0x27 +'Die ', # 0x28 +'Tiao ', # 0x29 +'Tao ', # 0x2a +'Kun ', # 0x2b +'Gan ', # 0x2c +'Han ', # 0x2d +'Yu ', # 0x2e +'Bang ', # 0x2f +'Fei ', # 0x30 +'Pi ', # 0x31 +'Wei ', # 0x32 +'Dun ', # 0x33 +'Yi ', # 0x34 +'Yuan ', # 0x35 +'Su ', # 0x36 +'Quan ', # 0x37 +'Qian ', # 0x38 +'Rui ', # 0x39 +'Ni ', # 0x3a +'Qing ', # 0x3b +'Wei ', # 0x3c +'Liang ', # 0x3d +'Guo ', # 0x3e +'Wan ', # 0x3f +'Dong ', # 0x40 +'E ', # 0x41 +'Ban ', # 0x42 +'Di ', # 0x43 +'Wang ', # 0x44 +'Can ', # 0x45 +'Yang ', # 0x46 +'Ying ', # 0x47 +'Guo ', # 0x48 +'Chan ', # 0x49 +'[?] ', # 0x4a +'La ', # 0x4b +'Ke ', # 0x4c +'Ji ', # 0x4d +'He ', # 0x4e +'Ting ', # 0x4f +'Mai ', # 0x50 +'Xu ', # 0x51 +'Mian ', # 0x52 +'Yu ', # 0x53 +'Jie ', # 0x54 +'Shi ', # 0x55 +'Xuan ', # 0x56 +'Huang ', # 0x57 +'Yan ', # 0x58 +'Bian ', # 0x59 +'Rou ', # 0x5a +'Wei ', # 0x5b +'Fu ', # 0x5c +'Yuan ', # 0x5d +'Mei ', # 0x5e +'Wei ', # 0x5f +'Fu ', # 0x60 +'Ruan ', # 0x61 +'Xie ', # 0x62 +'You ', # 0x63 +'Qiu ', # 0x64 +'Mao ', # 0x65 +'Xia ', # 0x66 +'Ying ', # 0x67 +'Shi ', # 0x68 +'Chong ', # 0x69 +'Tang ', # 0x6a +'Zhu ', # 0x6b +'Zong ', # 0x6c +'Ti ', # 0x6d +'Fu ', # 0x6e +'Yuan ', # 0x6f +'Hui ', # 0x70 +'Meng ', # 0x71 +'La ', # 0x72 +'Du ', # 0x73 +'Hu ', # 0x74 +'Qiu ', # 0x75 +'Die ', # 0x76 +'Li ', # 0x77 +'Gua ', # 0x78 +'Yun ', # 0x79 +'Ju ', # 0x7a +'Nan ', # 0x7b +'Lou ', # 0x7c +'Qun ', # 0x7d +'Rong ', # 0x7e +'Ying ', # 0x7f +'Jiang ', # 0x80 +'[?] ', # 0x81 +'Lang ', # 0x82 +'Pang ', # 0x83 +'Si ', # 0x84 +'Xi ', # 0x85 +'Ci ', # 0x86 +'Xi ', # 0x87 +'Yuan ', # 0x88 +'Weng ', # 0x89 +'Lian ', # 0x8a +'Sou ', # 0x8b +'Ban ', # 0x8c +'Rong ', # 0x8d +'Rong ', # 0x8e +'Ji ', # 0x8f +'Wu ', # 0x90 +'Qiu ', # 0x91 +'Han ', # 0x92 +'Qin ', # 0x93 +'Yi ', # 0x94 +'Bi ', # 0x95 +'Hua ', # 0x96 +'Tang ', # 0x97 +'Yi ', # 0x98 +'Du ', # 0x99 +'Nai ', # 0x9a +'He ', # 0x9b +'Hu ', # 0x9c +'Hui ', # 0x9d +'Ma ', # 0x9e +'Ming ', # 0x9f +'Yi ', # 0xa0 +'Wen ', # 0xa1 +'Ying ', # 0xa2 +'Teng ', # 0xa3 +'Yu ', # 0xa4 +'Cang ', # 0xa5 +'So ', # 0xa6 +'Ebi ', # 0xa7 +'Man ', # 0xa8 +'[?] ', # 0xa9 +'Shang ', # 0xaa +'Zhe ', # 0xab +'Cao ', # 0xac +'Chi ', # 0xad +'Di ', # 0xae +'Ao ', # 0xaf +'Lu ', # 0xb0 +'Wei ', # 0xb1 +'Zhi ', # 0xb2 +'Tang ', # 0xb3 +'Chen ', # 0xb4 +'Piao ', # 0xb5 +'Qu ', # 0xb6 +'Pi ', # 0xb7 +'Yu ', # 0xb8 +'Jian ', # 0xb9 +'Luo ', # 0xba +'Lou ', # 0xbb +'Qin ', # 0xbc +'Zhong ', # 0xbd +'Yin ', # 0xbe +'Jiang ', # 0xbf +'Shuai ', # 0xc0 +'Wen ', # 0xc1 +'Jiao ', # 0xc2 +'Wan ', # 0xc3 +'Zhi ', # 0xc4 +'Zhe ', # 0xc5 +'Ma ', # 0xc6 +'Ma ', # 0xc7 +'Guo ', # 0xc8 +'Liu ', # 0xc9 +'Mao ', # 0xca +'Xi ', # 0xcb +'Cong ', # 0xcc +'Li ', # 0xcd +'Man ', # 0xce +'Xiao ', # 0xcf +'Kamakiri ', # 0xd0 +'Zhang ', # 0xd1 +'Mang ', # 0xd2 +'Xiang ', # 0xd3 +'Mo ', # 0xd4 +'Zui ', # 0xd5 +'Si ', # 0xd6 +'Qiu ', # 0xd7 +'Te ', # 0xd8 +'Zhi ', # 0xd9 +'Peng ', # 0xda +'Peng ', # 0xdb +'Jiao ', # 0xdc +'Qu ', # 0xdd +'Bie ', # 0xde +'Liao ', # 0xdf +'Pan ', # 0xe0 +'Gui ', # 0xe1 +'Xi ', # 0xe2 +'Ji ', # 0xe3 +'Zhuan ', # 0xe4 +'Huang ', # 0xe5 +'Fei ', # 0xe6 +'Lao ', # 0xe7 +'Jue ', # 0xe8 +'Jue ', # 0xe9 +'Hui ', # 0xea +'Yin ', # 0xeb +'Chan ', # 0xec +'Jiao ', # 0xed +'Shan ', # 0xee +'Rao ', # 0xef +'Xiao ', # 0xf0 +'Mou ', # 0xf1 +'Chong ', # 0xf2 +'Xun ', # 0xf3 +'Si ', # 0xf4 +'[?] ', # 0xf5 +'Cheng ', # 0xf6 +'Dang ', # 0xf7 +'Li ', # 0xf8 +'Xie ', # 0xf9 +'Shan ', # 0xfa +'Yi ', # 0xfb +'Jing ', # 0xfc +'Da ', # 0xfd +'Chan ', # 0xfe +'Qi ', # 0xff +) diff --git a/libs/unidecode/x088.py b/libs/unidecode/x088.py new file mode 100644 index 00000000..f907ce92 --- /dev/null +++ b/libs/unidecode/x088.py @@ -0,0 +1,258 @@ +data = ( +'Ci ', # 0x00 +'Xiang ', # 0x01 +'She ', # 0x02 +'Luo ', # 0x03 +'Qin ', # 0x04 +'Ying ', # 0x05 +'Chai ', # 0x06 +'Li ', # 0x07 +'Ze ', # 0x08 +'Xuan ', # 0x09 +'Lian ', # 0x0a +'Zhu ', # 0x0b +'Ze ', # 0x0c +'Xie ', # 0x0d +'Mang ', # 0x0e +'Xie ', # 0x0f +'Qi ', # 0x10 +'Rong ', # 0x11 +'Jian ', # 0x12 +'Meng ', # 0x13 +'Hao ', # 0x14 +'Ruan ', # 0x15 +'Huo ', # 0x16 +'Zhuo ', # 0x17 +'Jie ', # 0x18 +'Bin ', # 0x19 +'He ', # 0x1a +'Mie ', # 0x1b +'Fan ', # 0x1c +'Lei ', # 0x1d +'Jie ', # 0x1e +'La ', # 0x1f +'Mi ', # 0x20 +'Li ', # 0x21 +'Chun ', # 0x22 +'Li ', # 0x23 +'Qiu ', # 0x24 +'Nie ', # 0x25 +'Lu ', # 0x26 +'Du ', # 0x27 +'Xiao ', # 0x28 +'Zhu ', # 0x29 +'Long ', # 0x2a +'Li ', # 0x2b +'Long ', # 0x2c +'Feng ', # 0x2d +'Ye ', # 0x2e +'Beng ', # 0x2f +'Shang ', # 0x30 +'Gu ', # 0x31 +'Juan ', # 0x32 +'Ying ', # 0x33 +'[?] ', # 0x34 +'Xi ', # 0x35 +'Can ', # 0x36 +'Qu ', # 0x37 +'Quan ', # 0x38 +'Du ', # 0x39 +'Can ', # 0x3a +'Man ', # 0x3b +'Jue ', # 0x3c +'Jie ', # 0x3d +'Zhu ', # 0x3e +'Zha ', # 0x3f +'Xie ', # 0x40 +'Huang ', # 0x41 +'Niu ', # 0x42 +'Pei ', # 0x43 +'Nu ', # 0x44 +'Xin ', # 0x45 +'Zhong ', # 0x46 +'Mo ', # 0x47 +'Er ', # 0x48 +'Ke ', # 0x49 +'Mie ', # 0x4a +'Xi ', # 0x4b +'Xing ', # 0x4c +'Yan ', # 0x4d +'Kan ', # 0x4e +'Yuan ', # 0x4f +'[?] ', # 0x50 +'Ling ', # 0x51 +'Xuan ', # 0x52 +'Shu ', # 0x53 +'Xian ', # 0x54 +'Tong ', # 0x55 +'Long ', # 0x56 +'Jie ', # 0x57 +'Xian ', # 0x58 +'Ya ', # 0x59 +'Hu ', # 0x5a +'Wei ', # 0x5b +'Dao ', # 0x5c +'Chong ', # 0x5d +'Wei ', # 0x5e +'Dao ', # 0x5f +'Zhun ', # 0x60 +'Heng ', # 0x61 +'Qu ', # 0x62 +'Yi ', # 0x63 +'Yi ', # 0x64 +'Bu ', # 0x65 +'Gan ', # 0x66 +'Yu ', # 0x67 +'Biao ', # 0x68 +'Cha ', # 0x69 +'Yi ', # 0x6a +'Shan ', # 0x6b +'Chen ', # 0x6c +'Fu ', # 0x6d +'Gun ', # 0x6e +'Fen ', # 0x6f +'Shuai ', # 0x70 +'Jie ', # 0x71 +'Na ', # 0x72 +'Zhong ', # 0x73 +'Dan ', # 0x74 +'Ri ', # 0x75 +'Zhong ', # 0x76 +'Zhong ', # 0x77 +'Xie ', # 0x78 +'Qi ', # 0x79 +'Xie ', # 0x7a +'Ran ', # 0x7b +'Zhi ', # 0x7c +'Ren ', # 0x7d +'Qin ', # 0x7e +'Jin ', # 0x7f +'Jun ', # 0x80 +'Yuan ', # 0x81 +'Mei ', # 0x82 +'Chai ', # 0x83 +'Ao ', # 0x84 +'Niao ', # 0x85 +'Hui ', # 0x86 +'Ran ', # 0x87 +'Jia ', # 0x88 +'Tuo ', # 0x89 +'Ling ', # 0x8a +'Dai ', # 0x8b +'Bao ', # 0x8c +'Pao ', # 0x8d +'Yao ', # 0x8e +'Zuo ', # 0x8f +'Bi ', # 0x90 +'Shao ', # 0x91 +'Tan ', # 0x92 +'Ju ', # 0x93 +'He ', # 0x94 +'Shu ', # 0x95 +'Xiu ', # 0x96 +'Zhen ', # 0x97 +'Yi ', # 0x98 +'Pa ', # 0x99 +'Bo ', # 0x9a +'Di ', # 0x9b +'Wa ', # 0x9c +'Fu ', # 0x9d +'Gun ', # 0x9e +'Zhi ', # 0x9f +'Zhi ', # 0xa0 +'Ran ', # 0xa1 +'Pan ', # 0xa2 +'Yi ', # 0xa3 +'Mao ', # 0xa4 +'Tuo ', # 0xa5 +'Na ', # 0xa6 +'Kou ', # 0xa7 +'Xian ', # 0xa8 +'Chan ', # 0xa9 +'Qu ', # 0xaa +'Bei ', # 0xab +'Gun ', # 0xac +'Xi ', # 0xad +'Ne ', # 0xae +'Bo ', # 0xaf +'Horo ', # 0xb0 +'Fu ', # 0xb1 +'Yi ', # 0xb2 +'Chi ', # 0xb3 +'Ku ', # 0xb4 +'Ren ', # 0xb5 +'Jiang ', # 0xb6 +'Jia ', # 0xb7 +'Cun ', # 0xb8 +'Mo ', # 0xb9 +'Jie ', # 0xba +'Er ', # 0xbb +'Luo ', # 0xbc +'Ru ', # 0xbd +'Zhu ', # 0xbe +'Gui ', # 0xbf +'Yin ', # 0xc0 +'Cai ', # 0xc1 +'Lie ', # 0xc2 +'Kamishimo ', # 0xc3 +'Yuki ', # 0xc4 +'Zhuang ', # 0xc5 +'Dang ', # 0xc6 +'[?] ', # 0xc7 +'Kun ', # 0xc8 +'Ken ', # 0xc9 +'Niao ', # 0xca +'Shu ', # 0xcb +'Jia ', # 0xcc +'Kun ', # 0xcd +'Cheng ', # 0xce +'Li ', # 0xcf +'Juan ', # 0xd0 +'Shen ', # 0xd1 +'Pou ', # 0xd2 +'Ge ', # 0xd3 +'Yi ', # 0xd4 +'Yu ', # 0xd5 +'Zhen ', # 0xd6 +'Liu ', # 0xd7 +'Qiu ', # 0xd8 +'Qun ', # 0xd9 +'Ji ', # 0xda +'Yi ', # 0xdb +'Bu ', # 0xdc +'Zhuang ', # 0xdd +'Shui ', # 0xde +'Sha ', # 0xdf +'Qun ', # 0xe0 +'Li ', # 0xe1 +'Lian ', # 0xe2 +'Lian ', # 0xe3 +'Ku ', # 0xe4 +'Jian ', # 0xe5 +'Fou ', # 0xe6 +'Chan ', # 0xe7 +'Bi ', # 0xe8 +'Gun ', # 0xe9 +'Tao ', # 0xea +'Yuan ', # 0xeb +'Ling ', # 0xec +'Chi ', # 0xed +'Chang ', # 0xee +'Chou ', # 0xef +'Duo ', # 0xf0 +'Biao ', # 0xf1 +'Liang ', # 0xf2 +'Chang ', # 0xf3 +'Pei ', # 0xf4 +'Pei ', # 0xf5 +'Fei ', # 0xf6 +'Yuan ', # 0xf7 +'Luo ', # 0xf8 +'Guo ', # 0xf9 +'Yan ', # 0xfa +'Du ', # 0xfb +'Xi ', # 0xfc +'Zhi ', # 0xfd +'Ju ', # 0xfe +'Qi ', # 0xff +) diff --git a/libs/unidecode/x089.py b/libs/unidecode/x089.py new file mode 100644 index 00000000..d23abc3c --- /dev/null +++ b/libs/unidecode/x089.py @@ -0,0 +1,258 @@ +data = ( +'Ji ', # 0x00 +'Zhi ', # 0x01 +'Gua ', # 0x02 +'Ken ', # 0x03 +'Che ', # 0x04 +'Ti ', # 0x05 +'Ti ', # 0x06 +'Fu ', # 0x07 +'Chong ', # 0x08 +'Xie ', # 0x09 +'Bian ', # 0x0a +'Die ', # 0x0b +'Kun ', # 0x0c +'Duan ', # 0x0d +'Xiu ', # 0x0e +'Xiu ', # 0x0f +'He ', # 0x10 +'Yuan ', # 0x11 +'Bao ', # 0x12 +'Bao ', # 0x13 +'Fu ', # 0x14 +'Yu ', # 0x15 +'Tuan ', # 0x16 +'Yan ', # 0x17 +'Hui ', # 0x18 +'Bei ', # 0x19 +'Chu ', # 0x1a +'Lu ', # 0x1b +'Ena ', # 0x1c +'Hitoe ', # 0x1d +'Yun ', # 0x1e +'Da ', # 0x1f +'Gou ', # 0x20 +'Da ', # 0x21 +'Huai ', # 0x22 +'Rong ', # 0x23 +'Yuan ', # 0x24 +'Ru ', # 0x25 +'Nai ', # 0x26 +'Jiong ', # 0x27 +'Suo ', # 0x28 +'Ban ', # 0x29 +'Tun ', # 0x2a +'Chi ', # 0x2b +'Sang ', # 0x2c +'Niao ', # 0x2d +'Ying ', # 0x2e +'Jie ', # 0x2f +'Qian ', # 0x30 +'Huai ', # 0x31 +'Ku ', # 0x32 +'Lian ', # 0x33 +'Bao ', # 0x34 +'Li ', # 0x35 +'Zhe ', # 0x36 +'Shi ', # 0x37 +'Lu ', # 0x38 +'Yi ', # 0x39 +'Die ', # 0x3a +'Xie ', # 0x3b +'Xian ', # 0x3c +'Wei ', # 0x3d +'Biao ', # 0x3e +'Cao ', # 0x3f +'Ji ', # 0x40 +'Jiang ', # 0x41 +'Sen ', # 0x42 +'Bao ', # 0x43 +'Xiang ', # 0x44 +'Chihaya ', # 0x45 +'Pu ', # 0x46 +'Jian ', # 0x47 +'Zhuan ', # 0x48 +'Jian ', # 0x49 +'Zui ', # 0x4a +'Ji ', # 0x4b +'Dan ', # 0x4c +'Za ', # 0x4d +'Fan ', # 0x4e +'Bo ', # 0x4f +'Xiang ', # 0x50 +'Xin ', # 0x51 +'Bie ', # 0x52 +'Rao ', # 0x53 +'Man ', # 0x54 +'Lan ', # 0x55 +'Ao ', # 0x56 +'Duo ', # 0x57 +'Gui ', # 0x58 +'Cao ', # 0x59 +'Sui ', # 0x5a +'Nong ', # 0x5b +'Chan ', # 0x5c +'Lian ', # 0x5d +'Bi ', # 0x5e +'Jin ', # 0x5f +'Dang ', # 0x60 +'Shu ', # 0x61 +'Tan ', # 0x62 +'Bi ', # 0x63 +'Lan ', # 0x64 +'Pu ', # 0x65 +'Ru ', # 0x66 +'Zhi ', # 0x67 +'[?] ', # 0x68 +'Shu ', # 0x69 +'Wa ', # 0x6a +'Shi ', # 0x6b +'Bai ', # 0x6c +'Xie ', # 0x6d +'Bo ', # 0x6e +'Chen ', # 0x6f +'Lai ', # 0x70 +'Long ', # 0x71 +'Xi ', # 0x72 +'Xian ', # 0x73 +'Lan ', # 0x74 +'Zhe ', # 0x75 +'Dai ', # 0x76 +'Tasuki ', # 0x77 +'Zan ', # 0x78 +'Shi ', # 0x79 +'Jian ', # 0x7a +'Pan ', # 0x7b +'Yi ', # 0x7c +'Ran ', # 0x7d +'Ya ', # 0x7e +'Xi ', # 0x7f +'Xi ', # 0x80 +'Yao ', # 0x81 +'Feng ', # 0x82 +'Tan ', # 0x83 +'[?] ', # 0x84 +'Biao ', # 0x85 +'Fu ', # 0x86 +'Ba ', # 0x87 +'He ', # 0x88 +'Ji ', # 0x89 +'Ji ', # 0x8a +'Jian ', # 0x8b +'Guan ', # 0x8c +'Bian ', # 0x8d +'Yan ', # 0x8e +'Gui ', # 0x8f +'Jue ', # 0x90 +'Pian ', # 0x91 +'Mao ', # 0x92 +'Mi ', # 0x93 +'Mi ', # 0x94 +'Mie ', # 0x95 +'Shi ', # 0x96 +'Si ', # 0x97 +'Zhan ', # 0x98 +'Luo ', # 0x99 +'Jue ', # 0x9a +'Mi ', # 0x9b +'Tiao ', # 0x9c +'Lian ', # 0x9d +'Yao ', # 0x9e +'Zhi ', # 0x9f +'Jun ', # 0xa0 +'Xi ', # 0xa1 +'Shan ', # 0xa2 +'Wei ', # 0xa3 +'Xi ', # 0xa4 +'Tian ', # 0xa5 +'Yu ', # 0xa6 +'Lan ', # 0xa7 +'E ', # 0xa8 +'Du ', # 0xa9 +'Qin ', # 0xaa +'Pang ', # 0xab +'Ji ', # 0xac +'Ming ', # 0xad +'Ying ', # 0xae +'Gou ', # 0xaf +'Qu ', # 0xb0 +'Zhan ', # 0xb1 +'Jin ', # 0xb2 +'Guan ', # 0xb3 +'Deng ', # 0xb4 +'Jian ', # 0xb5 +'Luo ', # 0xb6 +'Qu ', # 0xb7 +'Jian ', # 0xb8 +'Wei ', # 0xb9 +'Jue ', # 0xba +'Qu ', # 0xbb +'Luo ', # 0xbc +'Lan ', # 0xbd +'Shen ', # 0xbe +'Di ', # 0xbf +'Guan ', # 0xc0 +'Jian ', # 0xc1 +'Guan ', # 0xc2 +'Yan ', # 0xc3 +'Gui ', # 0xc4 +'Mi ', # 0xc5 +'Shi ', # 0xc6 +'Zhan ', # 0xc7 +'Lan ', # 0xc8 +'Jue ', # 0xc9 +'Ji ', # 0xca +'Xi ', # 0xcb +'Di ', # 0xcc +'Tian ', # 0xcd +'Yu ', # 0xce +'Gou ', # 0xcf +'Jin ', # 0xd0 +'Qu ', # 0xd1 +'Jiao ', # 0xd2 +'Jiu ', # 0xd3 +'Jin ', # 0xd4 +'Cu ', # 0xd5 +'Jue ', # 0xd6 +'Zhi ', # 0xd7 +'Chao ', # 0xd8 +'Ji ', # 0xd9 +'Gu ', # 0xda +'Dan ', # 0xdb +'Zui ', # 0xdc +'Di ', # 0xdd +'Shang ', # 0xde +'Hua ', # 0xdf +'Quan ', # 0xe0 +'Ge ', # 0xe1 +'Chi ', # 0xe2 +'Jie ', # 0xe3 +'Gui ', # 0xe4 +'Gong ', # 0xe5 +'Hong ', # 0xe6 +'Jie ', # 0xe7 +'Hun ', # 0xe8 +'Qiu ', # 0xe9 +'Xing ', # 0xea +'Su ', # 0xeb +'Ni ', # 0xec +'Ji ', # 0xed +'Lu ', # 0xee +'Zhi ', # 0xef +'Zha ', # 0xf0 +'Bi ', # 0xf1 +'Xing ', # 0xf2 +'Hu ', # 0xf3 +'Shang ', # 0xf4 +'Gong ', # 0xf5 +'Zhi ', # 0xf6 +'Xue ', # 0xf7 +'Chu ', # 0xf8 +'Xi ', # 0xf9 +'Yi ', # 0xfa +'Lu ', # 0xfb +'Jue ', # 0xfc +'Xi ', # 0xfd +'Yan ', # 0xfe +'Xi ', # 0xff +) diff --git a/libs/unidecode/x08a.py b/libs/unidecode/x08a.py new file mode 100644 index 00000000..0b0fa0a6 --- /dev/null +++ b/libs/unidecode/x08a.py @@ -0,0 +1,258 @@ +data = ( +'Yan ', # 0x00 +'Yan ', # 0x01 +'Ding ', # 0x02 +'Fu ', # 0x03 +'Qiu ', # 0x04 +'Qiu ', # 0x05 +'Jiao ', # 0x06 +'Hong ', # 0x07 +'Ji ', # 0x08 +'Fan ', # 0x09 +'Xun ', # 0x0a +'Diao ', # 0x0b +'Hong ', # 0x0c +'Cha ', # 0x0d +'Tao ', # 0x0e +'Xu ', # 0x0f +'Jie ', # 0x10 +'Yi ', # 0x11 +'Ren ', # 0x12 +'Xun ', # 0x13 +'Yin ', # 0x14 +'Shan ', # 0x15 +'Qi ', # 0x16 +'Tuo ', # 0x17 +'Ji ', # 0x18 +'Xun ', # 0x19 +'Yin ', # 0x1a +'E ', # 0x1b +'Fen ', # 0x1c +'Ya ', # 0x1d +'Yao ', # 0x1e +'Song ', # 0x1f +'Shen ', # 0x20 +'Yin ', # 0x21 +'Xin ', # 0x22 +'Jue ', # 0x23 +'Xiao ', # 0x24 +'Ne ', # 0x25 +'Chen ', # 0x26 +'You ', # 0x27 +'Zhi ', # 0x28 +'Xiong ', # 0x29 +'Fang ', # 0x2a +'Xin ', # 0x2b +'Chao ', # 0x2c +'She ', # 0x2d +'Xian ', # 0x2e +'Sha ', # 0x2f +'Tun ', # 0x30 +'Xu ', # 0x31 +'Yi ', # 0x32 +'Yi ', # 0x33 +'Su ', # 0x34 +'Chi ', # 0x35 +'He ', # 0x36 +'Shen ', # 0x37 +'He ', # 0x38 +'Xu ', # 0x39 +'Zhen ', # 0x3a +'Zhu ', # 0x3b +'Zheng ', # 0x3c +'Gou ', # 0x3d +'Zi ', # 0x3e +'Zi ', # 0x3f +'Zhan ', # 0x40 +'Gu ', # 0x41 +'Fu ', # 0x42 +'Quan ', # 0x43 +'Die ', # 0x44 +'Ling ', # 0x45 +'Di ', # 0x46 +'Yang ', # 0x47 +'Li ', # 0x48 +'Nao ', # 0x49 +'Pan ', # 0x4a +'Zhou ', # 0x4b +'Gan ', # 0x4c +'Yi ', # 0x4d +'Ju ', # 0x4e +'Ao ', # 0x4f +'Zha ', # 0x50 +'Tuo ', # 0x51 +'Yi ', # 0x52 +'Qu ', # 0x53 +'Zhao ', # 0x54 +'Ping ', # 0x55 +'Bi ', # 0x56 +'Xiong ', # 0x57 +'Qu ', # 0x58 +'Ba ', # 0x59 +'Da ', # 0x5a +'Zu ', # 0x5b +'Tao ', # 0x5c +'Zhu ', # 0x5d +'Ci ', # 0x5e +'Zhe ', # 0x5f +'Yong ', # 0x60 +'Xu ', # 0x61 +'Xun ', # 0x62 +'Yi ', # 0x63 +'Huang ', # 0x64 +'He ', # 0x65 +'Shi ', # 0x66 +'Cha ', # 0x67 +'Jiao ', # 0x68 +'Shi ', # 0x69 +'Hen ', # 0x6a +'Cha ', # 0x6b +'Gou ', # 0x6c +'Gui ', # 0x6d +'Quan ', # 0x6e +'Hui ', # 0x6f +'Jie ', # 0x70 +'Hua ', # 0x71 +'Gai ', # 0x72 +'Xiang ', # 0x73 +'Wei ', # 0x74 +'Shen ', # 0x75 +'Chou ', # 0x76 +'Tong ', # 0x77 +'Mi ', # 0x78 +'Zhan ', # 0x79 +'Ming ', # 0x7a +'E ', # 0x7b +'Hui ', # 0x7c +'Yan ', # 0x7d +'Xiong ', # 0x7e +'Gua ', # 0x7f +'Er ', # 0x80 +'Beng ', # 0x81 +'Tiao ', # 0x82 +'Chi ', # 0x83 +'Lei ', # 0x84 +'Zhu ', # 0x85 +'Kuang ', # 0x86 +'Kua ', # 0x87 +'Wu ', # 0x88 +'Yu ', # 0x89 +'Teng ', # 0x8a +'Ji ', # 0x8b +'Zhi ', # 0x8c +'Ren ', # 0x8d +'Su ', # 0x8e +'Lang ', # 0x8f +'E ', # 0x90 +'Kuang ', # 0x91 +'E ', # 0x92 +'Shi ', # 0x93 +'Ting ', # 0x94 +'Dan ', # 0x95 +'Bo ', # 0x96 +'Chan ', # 0x97 +'You ', # 0x98 +'Heng ', # 0x99 +'Qiao ', # 0x9a +'Qin ', # 0x9b +'Shua ', # 0x9c +'An ', # 0x9d +'Yu ', # 0x9e +'Xiao ', # 0x9f +'Cheng ', # 0xa0 +'Jie ', # 0xa1 +'Xian ', # 0xa2 +'Wu ', # 0xa3 +'Wu ', # 0xa4 +'Gao ', # 0xa5 +'Song ', # 0xa6 +'Pu ', # 0xa7 +'Hui ', # 0xa8 +'Jing ', # 0xa9 +'Shuo ', # 0xaa +'Zhen ', # 0xab +'Shuo ', # 0xac +'Du ', # 0xad +'Yasashi ', # 0xae +'Chang ', # 0xaf +'Shui ', # 0xb0 +'Jie ', # 0xb1 +'Ke ', # 0xb2 +'Qu ', # 0xb3 +'Cong ', # 0xb4 +'Xiao ', # 0xb5 +'Sui ', # 0xb6 +'Wang ', # 0xb7 +'Xuan ', # 0xb8 +'Fei ', # 0xb9 +'Chi ', # 0xba +'Ta ', # 0xbb +'Yi ', # 0xbc +'Na ', # 0xbd +'Yin ', # 0xbe +'Diao ', # 0xbf +'Pi ', # 0xc0 +'Chuo ', # 0xc1 +'Chan ', # 0xc2 +'Chen ', # 0xc3 +'Zhun ', # 0xc4 +'Ji ', # 0xc5 +'Qi ', # 0xc6 +'Tan ', # 0xc7 +'Zhui ', # 0xc8 +'Wei ', # 0xc9 +'Ju ', # 0xca +'Qing ', # 0xcb +'Jian ', # 0xcc +'Zheng ', # 0xcd +'Ze ', # 0xce +'Zou ', # 0xcf +'Qian ', # 0xd0 +'Zhuo ', # 0xd1 +'Liang ', # 0xd2 +'Jian ', # 0xd3 +'Zhu ', # 0xd4 +'Hao ', # 0xd5 +'Lun ', # 0xd6 +'Shen ', # 0xd7 +'Biao ', # 0xd8 +'Huai ', # 0xd9 +'Pian ', # 0xda +'Yu ', # 0xdb +'Die ', # 0xdc +'Xu ', # 0xdd +'Pian ', # 0xde +'Shi ', # 0xdf +'Xuan ', # 0xe0 +'Shi ', # 0xe1 +'Hun ', # 0xe2 +'Hua ', # 0xe3 +'E ', # 0xe4 +'Zhong ', # 0xe5 +'Di ', # 0xe6 +'Xie ', # 0xe7 +'Fu ', # 0xe8 +'Pu ', # 0xe9 +'Ting ', # 0xea +'Jian ', # 0xeb +'Qi ', # 0xec +'Yu ', # 0xed +'Zi ', # 0xee +'Chuan ', # 0xef +'Xi ', # 0xf0 +'Hui ', # 0xf1 +'Yin ', # 0xf2 +'An ', # 0xf3 +'Xian ', # 0xf4 +'Nan ', # 0xf5 +'Chen ', # 0xf6 +'Feng ', # 0xf7 +'Zhu ', # 0xf8 +'Yang ', # 0xf9 +'Yan ', # 0xfa +'Heng ', # 0xfb +'Xuan ', # 0xfc +'Ge ', # 0xfd +'Nuo ', # 0xfe +'Qi ', # 0xff +) diff --git a/libs/unidecode/x08b.py b/libs/unidecode/x08b.py new file mode 100644 index 00000000..b89c37a2 --- /dev/null +++ b/libs/unidecode/x08b.py @@ -0,0 +1,258 @@ +data = ( +'Mou ', # 0x00 +'Ye ', # 0x01 +'Wei ', # 0x02 +'[?] ', # 0x03 +'Teng ', # 0x04 +'Zou ', # 0x05 +'Shan ', # 0x06 +'Jian ', # 0x07 +'Bo ', # 0x08 +'Ku ', # 0x09 +'Huang ', # 0x0a +'Huo ', # 0x0b +'Ge ', # 0x0c +'Ying ', # 0x0d +'Mi ', # 0x0e +'Xiao ', # 0x0f +'Mi ', # 0x10 +'Xi ', # 0x11 +'Qiang ', # 0x12 +'Chen ', # 0x13 +'Nue ', # 0x14 +'Ti ', # 0x15 +'Su ', # 0x16 +'Bang ', # 0x17 +'Chi ', # 0x18 +'Qian ', # 0x19 +'Shi ', # 0x1a +'Jiang ', # 0x1b +'Yuan ', # 0x1c +'Xie ', # 0x1d +'Xue ', # 0x1e +'Tao ', # 0x1f +'Yao ', # 0x20 +'Yao ', # 0x21 +'[?] ', # 0x22 +'Yu ', # 0x23 +'Biao ', # 0x24 +'Cong ', # 0x25 +'Qing ', # 0x26 +'Li ', # 0x27 +'Mo ', # 0x28 +'Mo ', # 0x29 +'Shang ', # 0x2a +'Zhe ', # 0x2b +'Miu ', # 0x2c +'Jian ', # 0x2d +'Ze ', # 0x2e +'Jie ', # 0x2f +'Lian ', # 0x30 +'Lou ', # 0x31 +'Can ', # 0x32 +'Ou ', # 0x33 +'Guan ', # 0x34 +'Xi ', # 0x35 +'Zhuo ', # 0x36 +'Ao ', # 0x37 +'Ao ', # 0x38 +'Jin ', # 0x39 +'Zhe ', # 0x3a +'Yi ', # 0x3b +'Hu ', # 0x3c +'Jiang ', # 0x3d +'Man ', # 0x3e +'Chao ', # 0x3f +'Han ', # 0x40 +'Hua ', # 0x41 +'Chan ', # 0x42 +'Xu ', # 0x43 +'Zeng ', # 0x44 +'Se ', # 0x45 +'Xi ', # 0x46 +'She ', # 0x47 +'Dui ', # 0x48 +'Zheng ', # 0x49 +'Nao ', # 0x4a +'Lan ', # 0x4b +'E ', # 0x4c +'Ying ', # 0x4d +'Jue ', # 0x4e +'Ji ', # 0x4f +'Zun ', # 0x50 +'Jiao ', # 0x51 +'Bo ', # 0x52 +'Hui ', # 0x53 +'Zhuan ', # 0x54 +'Mu ', # 0x55 +'Zen ', # 0x56 +'Zha ', # 0x57 +'Shi ', # 0x58 +'Qiao ', # 0x59 +'Tan ', # 0x5a +'Zen ', # 0x5b +'Pu ', # 0x5c +'Sheng ', # 0x5d +'Xuan ', # 0x5e +'Zao ', # 0x5f +'Tan ', # 0x60 +'Dang ', # 0x61 +'Sui ', # 0x62 +'Qian ', # 0x63 +'Ji ', # 0x64 +'Jiao ', # 0x65 +'Jing ', # 0x66 +'Lian ', # 0x67 +'Nou ', # 0x68 +'Yi ', # 0x69 +'Ai ', # 0x6a +'Zhan ', # 0x6b +'Pi ', # 0x6c +'Hui ', # 0x6d +'Hua ', # 0x6e +'Yi ', # 0x6f +'Yi ', # 0x70 +'Shan ', # 0x71 +'Rang ', # 0x72 +'Nou ', # 0x73 +'Qian ', # 0x74 +'Zhui ', # 0x75 +'Ta ', # 0x76 +'Hu ', # 0x77 +'Zhou ', # 0x78 +'Hao ', # 0x79 +'Ye ', # 0x7a +'Ying ', # 0x7b +'Jian ', # 0x7c +'Yu ', # 0x7d +'Jian ', # 0x7e +'Hui ', # 0x7f +'Du ', # 0x80 +'Zhe ', # 0x81 +'Xuan ', # 0x82 +'Zan ', # 0x83 +'Lei ', # 0x84 +'Shen ', # 0x85 +'Wei ', # 0x86 +'Chan ', # 0x87 +'Li ', # 0x88 +'Yi ', # 0x89 +'Bian ', # 0x8a +'Zhe ', # 0x8b +'Yan ', # 0x8c +'E ', # 0x8d +'Chou ', # 0x8e +'Wei ', # 0x8f +'Chou ', # 0x90 +'Yao ', # 0x91 +'Chan ', # 0x92 +'Rang ', # 0x93 +'Yin ', # 0x94 +'Lan ', # 0x95 +'Chen ', # 0x96 +'Huo ', # 0x97 +'Zhe ', # 0x98 +'Huan ', # 0x99 +'Zan ', # 0x9a +'Yi ', # 0x9b +'Dang ', # 0x9c +'Zhan ', # 0x9d +'Yan ', # 0x9e +'Du ', # 0x9f +'Yan ', # 0xa0 +'Ji ', # 0xa1 +'Ding ', # 0xa2 +'Fu ', # 0xa3 +'Ren ', # 0xa4 +'Ji ', # 0xa5 +'Jie ', # 0xa6 +'Hong ', # 0xa7 +'Tao ', # 0xa8 +'Rang ', # 0xa9 +'Shan ', # 0xaa +'Qi ', # 0xab +'Tuo ', # 0xac +'Xun ', # 0xad +'Yi ', # 0xae +'Xun ', # 0xaf +'Ji ', # 0xb0 +'Ren ', # 0xb1 +'Jiang ', # 0xb2 +'Hui ', # 0xb3 +'Ou ', # 0xb4 +'Ju ', # 0xb5 +'Ya ', # 0xb6 +'Ne ', # 0xb7 +'Xu ', # 0xb8 +'E ', # 0xb9 +'Lun ', # 0xba +'Xiong ', # 0xbb +'Song ', # 0xbc +'Feng ', # 0xbd +'She ', # 0xbe +'Fang ', # 0xbf +'Jue ', # 0xc0 +'Zheng ', # 0xc1 +'Gu ', # 0xc2 +'He ', # 0xc3 +'Ping ', # 0xc4 +'Zu ', # 0xc5 +'Shi ', # 0xc6 +'Xiong ', # 0xc7 +'Zha ', # 0xc8 +'Su ', # 0xc9 +'Zhen ', # 0xca +'Di ', # 0xcb +'Zou ', # 0xcc +'Ci ', # 0xcd +'Qu ', # 0xce +'Zhao ', # 0xcf +'Bi ', # 0xd0 +'Yi ', # 0xd1 +'Yi ', # 0xd2 +'Kuang ', # 0xd3 +'Lei ', # 0xd4 +'Shi ', # 0xd5 +'Gua ', # 0xd6 +'Shi ', # 0xd7 +'Jie ', # 0xd8 +'Hui ', # 0xd9 +'Cheng ', # 0xda +'Zhu ', # 0xdb +'Shen ', # 0xdc +'Hua ', # 0xdd +'Dan ', # 0xde +'Gou ', # 0xdf +'Quan ', # 0xe0 +'Gui ', # 0xe1 +'Xun ', # 0xe2 +'Yi ', # 0xe3 +'Zheng ', # 0xe4 +'Gai ', # 0xe5 +'Xiang ', # 0xe6 +'Cha ', # 0xe7 +'Hun ', # 0xe8 +'Xu ', # 0xe9 +'Zhou ', # 0xea +'Jie ', # 0xeb +'Wu ', # 0xec +'Yu ', # 0xed +'Qiao ', # 0xee +'Wu ', # 0xef +'Gao ', # 0xf0 +'You ', # 0xf1 +'Hui ', # 0xf2 +'Kuang ', # 0xf3 +'Shuo ', # 0xf4 +'Song ', # 0xf5 +'Ai ', # 0xf6 +'Qing ', # 0xf7 +'Zhu ', # 0xf8 +'Zou ', # 0xf9 +'Nuo ', # 0xfa +'Du ', # 0xfb +'Zhuo ', # 0xfc +'Fei ', # 0xfd +'Ke ', # 0xfe +'Wei ', # 0xff +) diff --git a/libs/unidecode/x08c.py b/libs/unidecode/x08c.py new file mode 100644 index 00000000..514c446b --- /dev/null +++ b/libs/unidecode/x08c.py @@ -0,0 +1,258 @@ +data = ( +'Yu ', # 0x00 +'Shui ', # 0x01 +'Shen ', # 0x02 +'Diao ', # 0x03 +'Chan ', # 0x04 +'Liang ', # 0x05 +'Zhun ', # 0x06 +'Sui ', # 0x07 +'Tan ', # 0x08 +'Shen ', # 0x09 +'Yi ', # 0x0a +'Mou ', # 0x0b +'Chen ', # 0x0c +'Die ', # 0x0d +'Huang ', # 0x0e +'Jian ', # 0x0f +'Xie ', # 0x10 +'Nue ', # 0x11 +'Ye ', # 0x12 +'Wei ', # 0x13 +'E ', # 0x14 +'Yu ', # 0x15 +'Xuan ', # 0x16 +'Chan ', # 0x17 +'Zi ', # 0x18 +'An ', # 0x19 +'Yan ', # 0x1a +'Di ', # 0x1b +'Mi ', # 0x1c +'Pian ', # 0x1d +'Xu ', # 0x1e +'Mo ', # 0x1f +'Dang ', # 0x20 +'Su ', # 0x21 +'Xie ', # 0x22 +'Yao ', # 0x23 +'Bang ', # 0x24 +'Shi ', # 0x25 +'Qian ', # 0x26 +'Mi ', # 0x27 +'Jin ', # 0x28 +'Man ', # 0x29 +'Zhe ', # 0x2a +'Jian ', # 0x2b +'Miu ', # 0x2c +'Tan ', # 0x2d +'Zen ', # 0x2e +'Qiao ', # 0x2f +'Lan ', # 0x30 +'Pu ', # 0x31 +'Jue ', # 0x32 +'Yan ', # 0x33 +'Qian ', # 0x34 +'Zhan ', # 0x35 +'Chen ', # 0x36 +'Gu ', # 0x37 +'Qian ', # 0x38 +'Hong ', # 0x39 +'Xia ', # 0x3a +'Jue ', # 0x3b +'Hong ', # 0x3c +'Han ', # 0x3d +'Hong ', # 0x3e +'Xi ', # 0x3f +'Xi ', # 0x40 +'Huo ', # 0x41 +'Liao ', # 0x42 +'Han ', # 0x43 +'Du ', # 0x44 +'Long ', # 0x45 +'Dou ', # 0x46 +'Jiang ', # 0x47 +'Qi ', # 0x48 +'Shi ', # 0x49 +'Li ', # 0x4a +'Deng ', # 0x4b +'Wan ', # 0x4c +'Bi ', # 0x4d +'Shu ', # 0x4e +'Xian ', # 0x4f +'Feng ', # 0x50 +'Zhi ', # 0x51 +'Zhi ', # 0x52 +'Yan ', # 0x53 +'Yan ', # 0x54 +'Shi ', # 0x55 +'Chu ', # 0x56 +'Hui ', # 0x57 +'Tun ', # 0x58 +'Yi ', # 0x59 +'Tun ', # 0x5a +'Yi ', # 0x5b +'Jian ', # 0x5c +'Ba ', # 0x5d +'Hou ', # 0x5e +'E ', # 0x5f +'Cu ', # 0x60 +'Xiang ', # 0x61 +'Huan ', # 0x62 +'Jian ', # 0x63 +'Ken ', # 0x64 +'Gai ', # 0x65 +'Qu ', # 0x66 +'Fu ', # 0x67 +'Xi ', # 0x68 +'Bin ', # 0x69 +'Hao ', # 0x6a +'Yu ', # 0x6b +'Zhu ', # 0x6c +'Jia ', # 0x6d +'[?] ', # 0x6e +'Xi ', # 0x6f +'Bo ', # 0x70 +'Wen ', # 0x71 +'Huan ', # 0x72 +'Bin ', # 0x73 +'Di ', # 0x74 +'Zong ', # 0x75 +'Fen ', # 0x76 +'Yi ', # 0x77 +'Zhi ', # 0x78 +'Bao ', # 0x79 +'Chai ', # 0x7a +'Han ', # 0x7b +'Pi ', # 0x7c +'Na ', # 0x7d +'Pi ', # 0x7e +'Gou ', # 0x7f +'Na ', # 0x80 +'You ', # 0x81 +'Diao ', # 0x82 +'Mo ', # 0x83 +'Si ', # 0x84 +'Xiu ', # 0x85 +'Huan ', # 0x86 +'Kun ', # 0x87 +'He ', # 0x88 +'He ', # 0x89 +'Mo ', # 0x8a +'Han ', # 0x8b +'Mao ', # 0x8c +'Li ', # 0x8d +'Ni ', # 0x8e +'Bi ', # 0x8f +'Yu ', # 0x90 +'Jia ', # 0x91 +'Tuan ', # 0x92 +'Mao ', # 0x93 +'Pi ', # 0x94 +'Xi ', # 0x95 +'E ', # 0x96 +'Ju ', # 0x97 +'Mo ', # 0x98 +'Chu ', # 0x99 +'Tan ', # 0x9a +'Huan ', # 0x9b +'Jue ', # 0x9c +'Bei ', # 0x9d +'Zhen ', # 0x9e +'Yuan ', # 0x9f +'Fu ', # 0xa0 +'Cai ', # 0xa1 +'Gong ', # 0xa2 +'Te ', # 0xa3 +'Yi ', # 0xa4 +'Hang ', # 0xa5 +'Wan ', # 0xa6 +'Pin ', # 0xa7 +'Huo ', # 0xa8 +'Fan ', # 0xa9 +'Tan ', # 0xaa +'Guan ', # 0xab +'Ze ', # 0xac +'Zhi ', # 0xad +'Er ', # 0xae +'Zhu ', # 0xaf +'Shi ', # 0xb0 +'Bi ', # 0xb1 +'Zi ', # 0xb2 +'Er ', # 0xb3 +'Gui ', # 0xb4 +'Pian ', # 0xb5 +'Bian ', # 0xb6 +'Mai ', # 0xb7 +'Dai ', # 0xb8 +'Sheng ', # 0xb9 +'Kuang ', # 0xba +'Fei ', # 0xbb +'Tie ', # 0xbc +'Yi ', # 0xbd +'Chi ', # 0xbe +'Mao ', # 0xbf +'He ', # 0xc0 +'Bi ', # 0xc1 +'Lu ', # 0xc2 +'Ren ', # 0xc3 +'Hui ', # 0xc4 +'Gai ', # 0xc5 +'Pian ', # 0xc6 +'Zi ', # 0xc7 +'Jia ', # 0xc8 +'Xu ', # 0xc9 +'Zei ', # 0xca +'Jiao ', # 0xcb +'Gai ', # 0xcc +'Zang ', # 0xcd +'Jian ', # 0xce +'Ying ', # 0xcf +'Xun ', # 0xd0 +'Zhen ', # 0xd1 +'She ', # 0xd2 +'Bin ', # 0xd3 +'Bin ', # 0xd4 +'Qiu ', # 0xd5 +'She ', # 0xd6 +'Chuan ', # 0xd7 +'Zang ', # 0xd8 +'Zhou ', # 0xd9 +'Lai ', # 0xda +'Zan ', # 0xdb +'Si ', # 0xdc +'Chen ', # 0xdd +'Shang ', # 0xde +'Tian ', # 0xdf +'Pei ', # 0xe0 +'Geng ', # 0xe1 +'Xian ', # 0xe2 +'Mai ', # 0xe3 +'Jian ', # 0xe4 +'Sui ', # 0xe5 +'Fu ', # 0xe6 +'Tan ', # 0xe7 +'Cong ', # 0xe8 +'Cong ', # 0xe9 +'Zhi ', # 0xea +'Ji ', # 0xeb +'Zhang ', # 0xec +'Du ', # 0xed +'Jin ', # 0xee +'Xiong ', # 0xef +'Shun ', # 0xf0 +'Yun ', # 0xf1 +'Bao ', # 0xf2 +'Zai ', # 0xf3 +'Lai ', # 0xf4 +'Feng ', # 0xf5 +'Cang ', # 0xf6 +'Ji ', # 0xf7 +'Sheng ', # 0xf8 +'Ai ', # 0xf9 +'Zhuan ', # 0xfa +'Fu ', # 0xfb +'Gou ', # 0xfc +'Sai ', # 0xfd +'Ze ', # 0xfe +'Liao ', # 0xff +) diff --git a/libs/unidecode/x08d.py b/libs/unidecode/x08d.py new file mode 100644 index 00000000..ae63f226 --- /dev/null +++ b/libs/unidecode/x08d.py @@ -0,0 +1,258 @@ +data = ( +'Wei ', # 0x00 +'Bai ', # 0x01 +'Chen ', # 0x02 +'Zhuan ', # 0x03 +'Zhi ', # 0x04 +'Zhui ', # 0x05 +'Biao ', # 0x06 +'Yun ', # 0x07 +'Zeng ', # 0x08 +'Tan ', # 0x09 +'Zan ', # 0x0a +'Yan ', # 0x0b +'[?] ', # 0x0c +'Shan ', # 0x0d +'Wan ', # 0x0e +'Ying ', # 0x0f +'Jin ', # 0x10 +'Gan ', # 0x11 +'Xian ', # 0x12 +'Zang ', # 0x13 +'Bi ', # 0x14 +'Du ', # 0x15 +'Shu ', # 0x16 +'Yan ', # 0x17 +'[?] ', # 0x18 +'Xuan ', # 0x19 +'Long ', # 0x1a +'Gan ', # 0x1b +'Zang ', # 0x1c +'Bei ', # 0x1d +'Zhen ', # 0x1e +'Fu ', # 0x1f +'Yuan ', # 0x20 +'Gong ', # 0x21 +'Cai ', # 0x22 +'Ze ', # 0x23 +'Xian ', # 0x24 +'Bai ', # 0x25 +'Zhang ', # 0x26 +'Huo ', # 0x27 +'Zhi ', # 0x28 +'Fan ', # 0x29 +'Tan ', # 0x2a +'Pin ', # 0x2b +'Bian ', # 0x2c +'Gou ', # 0x2d +'Zhu ', # 0x2e +'Guan ', # 0x2f +'Er ', # 0x30 +'Jian ', # 0x31 +'Bi ', # 0x32 +'Shi ', # 0x33 +'Tie ', # 0x34 +'Gui ', # 0x35 +'Kuang ', # 0x36 +'Dai ', # 0x37 +'Mao ', # 0x38 +'Fei ', # 0x39 +'He ', # 0x3a +'Yi ', # 0x3b +'Zei ', # 0x3c +'Zhi ', # 0x3d +'Jia ', # 0x3e +'Hui ', # 0x3f +'Zi ', # 0x40 +'Ren ', # 0x41 +'Lu ', # 0x42 +'Zang ', # 0x43 +'Zi ', # 0x44 +'Gai ', # 0x45 +'Jin ', # 0x46 +'Qiu ', # 0x47 +'Zhen ', # 0x48 +'Lai ', # 0x49 +'She ', # 0x4a +'Fu ', # 0x4b +'Du ', # 0x4c +'Ji ', # 0x4d +'Shu ', # 0x4e +'Shang ', # 0x4f +'Si ', # 0x50 +'Bi ', # 0x51 +'Zhou ', # 0x52 +'Geng ', # 0x53 +'Pei ', # 0x54 +'Tan ', # 0x55 +'Lai ', # 0x56 +'Feng ', # 0x57 +'Zhui ', # 0x58 +'Fu ', # 0x59 +'Zhuan ', # 0x5a +'Sai ', # 0x5b +'Ze ', # 0x5c +'Yan ', # 0x5d +'Zan ', # 0x5e +'Yun ', # 0x5f +'Zeng ', # 0x60 +'Shan ', # 0x61 +'Ying ', # 0x62 +'Gan ', # 0x63 +'Chi ', # 0x64 +'Xi ', # 0x65 +'She ', # 0x66 +'Nan ', # 0x67 +'Xiong ', # 0x68 +'Xi ', # 0x69 +'Cheng ', # 0x6a +'He ', # 0x6b +'Cheng ', # 0x6c +'Zhe ', # 0x6d +'Xia ', # 0x6e +'Tang ', # 0x6f +'Zou ', # 0x70 +'Zou ', # 0x71 +'Li ', # 0x72 +'Jiu ', # 0x73 +'Fu ', # 0x74 +'Zhao ', # 0x75 +'Gan ', # 0x76 +'Qi ', # 0x77 +'Shan ', # 0x78 +'Qiong ', # 0x79 +'Qin ', # 0x7a +'Xian ', # 0x7b +'Ci ', # 0x7c +'Jue ', # 0x7d +'Qin ', # 0x7e +'Chi ', # 0x7f +'Ci ', # 0x80 +'Chen ', # 0x81 +'Chen ', # 0x82 +'Die ', # 0x83 +'Ju ', # 0x84 +'Chao ', # 0x85 +'Di ', # 0x86 +'Se ', # 0x87 +'Zhan ', # 0x88 +'Zhu ', # 0x89 +'Yue ', # 0x8a +'Qu ', # 0x8b +'Jie ', # 0x8c +'Chi ', # 0x8d +'Chu ', # 0x8e +'Gua ', # 0x8f +'Xue ', # 0x90 +'Ci ', # 0x91 +'Tiao ', # 0x92 +'Duo ', # 0x93 +'Lie ', # 0x94 +'Gan ', # 0x95 +'Suo ', # 0x96 +'Cu ', # 0x97 +'Xi ', # 0x98 +'Zhao ', # 0x99 +'Su ', # 0x9a +'Yin ', # 0x9b +'Ju ', # 0x9c +'Jian ', # 0x9d +'Que ', # 0x9e +'Tang ', # 0x9f +'Chuo ', # 0xa0 +'Cui ', # 0xa1 +'Lu ', # 0xa2 +'Qu ', # 0xa3 +'Dang ', # 0xa4 +'Qiu ', # 0xa5 +'Zi ', # 0xa6 +'Ti ', # 0xa7 +'Qu ', # 0xa8 +'Chi ', # 0xa9 +'Huang ', # 0xaa +'Qiao ', # 0xab +'Qiao ', # 0xac +'Yao ', # 0xad +'Zao ', # 0xae +'Ti ', # 0xaf +'[?] ', # 0xb0 +'Zan ', # 0xb1 +'Zan ', # 0xb2 +'Zu ', # 0xb3 +'Pa ', # 0xb4 +'Bao ', # 0xb5 +'Ku ', # 0xb6 +'Ke ', # 0xb7 +'Dun ', # 0xb8 +'Jue ', # 0xb9 +'Fu ', # 0xba +'Chen ', # 0xbb +'Jian ', # 0xbc +'Fang ', # 0xbd +'Zhi ', # 0xbe +'Sa ', # 0xbf +'Yue ', # 0xc0 +'Pa ', # 0xc1 +'Qi ', # 0xc2 +'Yue ', # 0xc3 +'Qiang ', # 0xc4 +'Tuo ', # 0xc5 +'Tai ', # 0xc6 +'Yi ', # 0xc7 +'Nian ', # 0xc8 +'Ling ', # 0xc9 +'Mei ', # 0xca +'Ba ', # 0xcb +'Die ', # 0xcc +'Ku ', # 0xcd +'Tuo ', # 0xce +'Jia ', # 0xcf +'Ci ', # 0xd0 +'Pao ', # 0xd1 +'Qia ', # 0xd2 +'Zhu ', # 0xd3 +'Ju ', # 0xd4 +'Die ', # 0xd5 +'Zhi ', # 0xd6 +'Fu ', # 0xd7 +'Pan ', # 0xd8 +'Ju ', # 0xd9 +'Shan ', # 0xda +'Bo ', # 0xdb +'Ni ', # 0xdc +'Ju ', # 0xdd +'Li ', # 0xde +'Gen ', # 0xdf +'Yi ', # 0xe0 +'Ji ', # 0xe1 +'Dai ', # 0xe2 +'Xian ', # 0xe3 +'Jiao ', # 0xe4 +'Duo ', # 0xe5 +'Zhu ', # 0xe6 +'Zhuan ', # 0xe7 +'Kua ', # 0xe8 +'Zhuai ', # 0xe9 +'Gui ', # 0xea +'Qiong ', # 0xeb +'Kui ', # 0xec +'Xiang ', # 0xed +'Chi ', # 0xee +'Lu ', # 0xef +'Beng ', # 0xf0 +'Zhi ', # 0xf1 +'Jia ', # 0xf2 +'Tiao ', # 0xf3 +'Cai ', # 0xf4 +'Jian ', # 0xf5 +'Ta ', # 0xf6 +'Qiao ', # 0xf7 +'Bi ', # 0xf8 +'Xian ', # 0xf9 +'Duo ', # 0xfa +'Ji ', # 0xfb +'Ju ', # 0xfc +'Ji ', # 0xfd +'Shu ', # 0xfe +'Tu ', # 0xff +) diff --git a/libs/unidecode/x08e.py b/libs/unidecode/x08e.py new file mode 100644 index 00000000..015ed1ea --- /dev/null +++ b/libs/unidecode/x08e.py @@ -0,0 +1,258 @@ +data = ( +'Chu ', # 0x00 +'Jing ', # 0x01 +'Nie ', # 0x02 +'Xiao ', # 0x03 +'Bo ', # 0x04 +'Chi ', # 0x05 +'Qun ', # 0x06 +'Mou ', # 0x07 +'Shu ', # 0x08 +'Lang ', # 0x09 +'Yong ', # 0x0a +'Jiao ', # 0x0b +'Chou ', # 0x0c +'Qiao ', # 0x0d +'[?] ', # 0x0e +'Ta ', # 0x0f +'Jian ', # 0x10 +'Qi ', # 0x11 +'Wo ', # 0x12 +'Wei ', # 0x13 +'Zhuo ', # 0x14 +'Jie ', # 0x15 +'Ji ', # 0x16 +'Nie ', # 0x17 +'Ju ', # 0x18 +'Ju ', # 0x19 +'Lun ', # 0x1a +'Lu ', # 0x1b +'Leng ', # 0x1c +'Huai ', # 0x1d +'Ju ', # 0x1e +'Chi ', # 0x1f +'Wan ', # 0x20 +'Quan ', # 0x21 +'Ti ', # 0x22 +'Bo ', # 0x23 +'Zu ', # 0x24 +'Qie ', # 0x25 +'Ji ', # 0x26 +'Cu ', # 0x27 +'Zong ', # 0x28 +'Cai ', # 0x29 +'Zong ', # 0x2a +'Peng ', # 0x2b +'Zhi ', # 0x2c +'Zheng ', # 0x2d +'Dian ', # 0x2e +'Zhi ', # 0x2f +'Yu ', # 0x30 +'Duo ', # 0x31 +'Dun ', # 0x32 +'Chun ', # 0x33 +'Yong ', # 0x34 +'Zhong ', # 0x35 +'Di ', # 0x36 +'Zhe ', # 0x37 +'Chen ', # 0x38 +'Chuai ', # 0x39 +'Jian ', # 0x3a +'Gua ', # 0x3b +'Tang ', # 0x3c +'Ju ', # 0x3d +'Fu ', # 0x3e +'Zu ', # 0x3f +'Die ', # 0x40 +'Pian ', # 0x41 +'Rou ', # 0x42 +'Nuo ', # 0x43 +'Ti ', # 0x44 +'Cha ', # 0x45 +'Tui ', # 0x46 +'Jian ', # 0x47 +'Dao ', # 0x48 +'Cuo ', # 0x49 +'Xi ', # 0x4a +'Ta ', # 0x4b +'Qiang ', # 0x4c +'Zhan ', # 0x4d +'Dian ', # 0x4e +'Ti ', # 0x4f +'Ji ', # 0x50 +'Nie ', # 0x51 +'Man ', # 0x52 +'Liu ', # 0x53 +'Zhan ', # 0x54 +'Bi ', # 0x55 +'Chong ', # 0x56 +'Lu ', # 0x57 +'Liao ', # 0x58 +'Cu ', # 0x59 +'Tang ', # 0x5a +'Dai ', # 0x5b +'Suo ', # 0x5c +'Xi ', # 0x5d +'Kui ', # 0x5e +'Ji ', # 0x5f +'Zhi ', # 0x60 +'Qiang ', # 0x61 +'Di ', # 0x62 +'Man ', # 0x63 +'Zong ', # 0x64 +'Lian ', # 0x65 +'Beng ', # 0x66 +'Zao ', # 0x67 +'Nian ', # 0x68 +'Bie ', # 0x69 +'Tui ', # 0x6a +'Ju ', # 0x6b +'Deng ', # 0x6c +'Ceng ', # 0x6d +'Xian ', # 0x6e +'Fan ', # 0x6f +'Chu ', # 0x70 +'Zhong ', # 0x71 +'Dun ', # 0x72 +'Bo ', # 0x73 +'Cu ', # 0x74 +'Zu ', # 0x75 +'Jue ', # 0x76 +'Jue ', # 0x77 +'Lin ', # 0x78 +'Ta ', # 0x79 +'Qiao ', # 0x7a +'Qiao ', # 0x7b +'Pu ', # 0x7c +'Liao ', # 0x7d +'Dun ', # 0x7e +'Cuan ', # 0x7f +'Kuang ', # 0x80 +'Zao ', # 0x81 +'Ta ', # 0x82 +'Bi ', # 0x83 +'Bi ', # 0x84 +'Zhu ', # 0x85 +'Ju ', # 0x86 +'Chu ', # 0x87 +'Qiao ', # 0x88 +'Dun ', # 0x89 +'Chou ', # 0x8a +'Ji ', # 0x8b +'Wu ', # 0x8c +'Yue ', # 0x8d +'Nian ', # 0x8e +'Lin ', # 0x8f +'Lie ', # 0x90 +'Zhi ', # 0x91 +'Li ', # 0x92 +'Zhi ', # 0x93 +'Chan ', # 0x94 +'Chu ', # 0x95 +'Duan ', # 0x96 +'Wei ', # 0x97 +'Long ', # 0x98 +'Lin ', # 0x99 +'Xian ', # 0x9a +'Wei ', # 0x9b +'Zuan ', # 0x9c +'Lan ', # 0x9d +'Xie ', # 0x9e +'Rang ', # 0x9f +'Xie ', # 0xa0 +'Nie ', # 0xa1 +'Ta ', # 0xa2 +'Qu ', # 0xa3 +'Jie ', # 0xa4 +'Cuan ', # 0xa5 +'Zuan ', # 0xa6 +'Xi ', # 0xa7 +'Kui ', # 0xa8 +'Jue ', # 0xa9 +'Lin ', # 0xaa +'Shen ', # 0xab +'Gong ', # 0xac +'Dan ', # 0xad +'Segare ', # 0xae +'Qu ', # 0xaf +'Ti ', # 0xb0 +'Duo ', # 0xb1 +'Duo ', # 0xb2 +'Gong ', # 0xb3 +'Lang ', # 0xb4 +'Nerau ', # 0xb5 +'Luo ', # 0xb6 +'Ai ', # 0xb7 +'Ji ', # 0xb8 +'Ju ', # 0xb9 +'Tang ', # 0xba +'Utsuke ', # 0xbb +'[?] ', # 0xbc +'Yan ', # 0xbd +'Shitsuke ', # 0xbe +'Kang ', # 0xbf +'Qu ', # 0xc0 +'Lou ', # 0xc1 +'Lao ', # 0xc2 +'Tuo ', # 0xc3 +'Zhi ', # 0xc4 +'Yagate ', # 0xc5 +'Ti ', # 0xc6 +'Dao ', # 0xc7 +'Yagate ', # 0xc8 +'Yu ', # 0xc9 +'Che ', # 0xca +'Ya ', # 0xcb +'Gui ', # 0xcc +'Jun ', # 0xcd +'Wei ', # 0xce +'Yue ', # 0xcf +'Xin ', # 0xd0 +'Di ', # 0xd1 +'Xuan ', # 0xd2 +'Fan ', # 0xd3 +'Ren ', # 0xd4 +'Shan ', # 0xd5 +'Qiang ', # 0xd6 +'Shu ', # 0xd7 +'Tun ', # 0xd8 +'Chen ', # 0xd9 +'Dai ', # 0xda +'E ', # 0xdb +'Na ', # 0xdc +'Qi ', # 0xdd +'Mao ', # 0xde +'Ruan ', # 0xdf +'Ren ', # 0xe0 +'Fan ', # 0xe1 +'Zhuan ', # 0xe2 +'Hong ', # 0xe3 +'Hu ', # 0xe4 +'Qu ', # 0xe5 +'Huang ', # 0xe6 +'Di ', # 0xe7 +'Ling ', # 0xe8 +'Dai ', # 0xe9 +'Ao ', # 0xea +'Zhen ', # 0xeb +'Fan ', # 0xec +'Kuang ', # 0xed +'Ang ', # 0xee +'Peng ', # 0xef +'Bei ', # 0xf0 +'Gu ', # 0xf1 +'Ku ', # 0xf2 +'Pao ', # 0xf3 +'Zhu ', # 0xf4 +'Rong ', # 0xf5 +'E ', # 0xf6 +'Ba ', # 0xf7 +'Zhou ', # 0xf8 +'Zhi ', # 0xf9 +'Yao ', # 0xfa +'Ke ', # 0xfb +'Yi ', # 0xfc +'Qing ', # 0xfd +'Shi ', # 0xfe +'Ping ', # 0xff +) diff --git a/libs/unidecode/x08f.py b/libs/unidecode/x08f.py new file mode 100644 index 00000000..39d04a9c --- /dev/null +++ b/libs/unidecode/x08f.py @@ -0,0 +1,258 @@ +data = ( +'Er ', # 0x00 +'Qiong ', # 0x01 +'Ju ', # 0x02 +'Jiao ', # 0x03 +'Guang ', # 0x04 +'Lu ', # 0x05 +'Kai ', # 0x06 +'Quan ', # 0x07 +'Zhou ', # 0x08 +'Zai ', # 0x09 +'Zhi ', # 0x0a +'She ', # 0x0b +'Liang ', # 0x0c +'Yu ', # 0x0d +'Shao ', # 0x0e +'You ', # 0x0f +'Huan ', # 0x10 +'Yun ', # 0x11 +'Zhe ', # 0x12 +'Wan ', # 0x13 +'Fu ', # 0x14 +'Qing ', # 0x15 +'Zhou ', # 0x16 +'Ni ', # 0x17 +'Ling ', # 0x18 +'Zhe ', # 0x19 +'Zhan ', # 0x1a +'Liang ', # 0x1b +'Zi ', # 0x1c +'Hui ', # 0x1d +'Wang ', # 0x1e +'Chuo ', # 0x1f +'Guo ', # 0x20 +'Kan ', # 0x21 +'Yi ', # 0x22 +'Peng ', # 0x23 +'Qian ', # 0x24 +'Gun ', # 0x25 +'Nian ', # 0x26 +'Pian ', # 0x27 +'Guan ', # 0x28 +'Bei ', # 0x29 +'Lun ', # 0x2a +'Pai ', # 0x2b +'Liang ', # 0x2c +'Ruan ', # 0x2d +'Rou ', # 0x2e +'Ji ', # 0x2f +'Yang ', # 0x30 +'Xian ', # 0x31 +'Chuan ', # 0x32 +'Cou ', # 0x33 +'Qun ', # 0x34 +'Ge ', # 0x35 +'You ', # 0x36 +'Hong ', # 0x37 +'Shu ', # 0x38 +'Fu ', # 0x39 +'Zi ', # 0x3a +'Fu ', # 0x3b +'Wen ', # 0x3c +'Ben ', # 0x3d +'Zhan ', # 0x3e +'Yu ', # 0x3f +'Wen ', # 0x40 +'Tao ', # 0x41 +'Gu ', # 0x42 +'Zhen ', # 0x43 +'Xia ', # 0x44 +'Yuan ', # 0x45 +'Lu ', # 0x46 +'Jiu ', # 0x47 +'Chao ', # 0x48 +'Zhuan ', # 0x49 +'Wei ', # 0x4a +'Hun ', # 0x4b +'Sori ', # 0x4c +'Che ', # 0x4d +'Jiao ', # 0x4e +'Zhan ', # 0x4f +'Pu ', # 0x50 +'Lao ', # 0x51 +'Fen ', # 0x52 +'Fan ', # 0x53 +'Lin ', # 0x54 +'Ge ', # 0x55 +'Se ', # 0x56 +'Kan ', # 0x57 +'Huan ', # 0x58 +'Yi ', # 0x59 +'Ji ', # 0x5a +'Dui ', # 0x5b +'Er ', # 0x5c +'Yu ', # 0x5d +'Xian ', # 0x5e +'Hong ', # 0x5f +'Lei ', # 0x60 +'Pei ', # 0x61 +'Li ', # 0x62 +'Li ', # 0x63 +'Lu ', # 0x64 +'Lin ', # 0x65 +'Che ', # 0x66 +'Ya ', # 0x67 +'Gui ', # 0x68 +'Xuan ', # 0x69 +'Di ', # 0x6a +'Ren ', # 0x6b +'Zhuan ', # 0x6c +'E ', # 0x6d +'Lun ', # 0x6e +'Ruan ', # 0x6f +'Hong ', # 0x70 +'Ku ', # 0x71 +'Ke ', # 0x72 +'Lu ', # 0x73 +'Zhou ', # 0x74 +'Zhi ', # 0x75 +'Yi ', # 0x76 +'Hu ', # 0x77 +'Zhen ', # 0x78 +'Li ', # 0x79 +'Yao ', # 0x7a +'Qing ', # 0x7b +'Shi ', # 0x7c +'Zai ', # 0x7d +'Zhi ', # 0x7e +'Jiao ', # 0x7f +'Zhou ', # 0x80 +'Quan ', # 0x81 +'Lu ', # 0x82 +'Jiao ', # 0x83 +'Zhe ', # 0x84 +'Fu ', # 0x85 +'Liang ', # 0x86 +'Nian ', # 0x87 +'Bei ', # 0x88 +'Hui ', # 0x89 +'Gun ', # 0x8a +'Wang ', # 0x8b +'Liang ', # 0x8c +'Chuo ', # 0x8d +'Zi ', # 0x8e +'Cou ', # 0x8f +'Fu ', # 0x90 +'Ji ', # 0x91 +'Wen ', # 0x92 +'Shu ', # 0x93 +'Pei ', # 0x94 +'Yuan ', # 0x95 +'Xia ', # 0x96 +'Zhan ', # 0x97 +'Lu ', # 0x98 +'Che ', # 0x99 +'Lin ', # 0x9a +'Xin ', # 0x9b +'Gu ', # 0x9c +'Ci ', # 0x9d +'Ci ', # 0x9e +'Pi ', # 0x9f +'Zui ', # 0xa0 +'Bian ', # 0xa1 +'La ', # 0xa2 +'La ', # 0xa3 +'Ci ', # 0xa4 +'Xue ', # 0xa5 +'Ban ', # 0xa6 +'Bian ', # 0xa7 +'Bian ', # 0xa8 +'Bian ', # 0xa9 +'[?] ', # 0xaa +'Bian ', # 0xab +'Ban ', # 0xac +'Ci ', # 0xad +'Bian ', # 0xae +'Bian ', # 0xaf +'Chen ', # 0xb0 +'Ru ', # 0xb1 +'Nong ', # 0xb2 +'Nong ', # 0xb3 +'Zhen ', # 0xb4 +'Chuo ', # 0xb5 +'Chuo ', # 0xb6 +'Suberu ', # 0xb7 +'Reng ', # 0xb8 +'Bian ', # 0xb9 +'Bian ', # 0xba +'Sip ', # 0xbb +'Ip ', # 0xbc +'Liao ', # 0xbd +'Da ', # 0xbe +'Chan ', # 0xbf +'Gan ', # 0xc0 +'Qian ', # 0xc1 +'Yu ', # 0xc2 +'Yu ', # 0xc3 +'Qi ', # 0xc4 +'Xun ', # 0xc5 +'Yi ', # 0xc6 +'Guo ', # 0xc7 +'Mai ', # 0xc8 +'Qi ', # 0xc9 +'Za ', # 0xca +'Wang ', # 0xcb +'Jia ', # 0xcc +'Zhun ', # 0xcd +'Ying ', # 0xce +'Ti ', # 0xcf +'Yun ', # 0xd0 +'Jin ', # 0xd1 +'Hang ', # 0xd2 +'Ya ', # 0xd3 +'Fan ', # 0xd4 +'Wu ', # 0xd5 +'Da ', # 0xd6 +'E ', # 0xd7 +'Huan ', # 0xd8 +'Zhe ', # 0xd9 +'Totemo ', # 0xda +'Jin ', # 0xdb +'Yuan ', # 0xdc +'Wei ', # 0xdd +'Lian ', # 0xde +'Chi ', # 0xdf +'Che ', # 0xe0 +'Ni ', # 0xe1 +'Tiao ', # 0xe2 +'Zhi ', # 0xe3 +'Yi ', # 0xe4 +'Jiong ', # 0xe5 +'Jia ', # 0xe6 +'Chen ', # 0xe7 +'Dai ', # 0xe8 +'Er ', # 0xe9 +'Di ', # 0xea +'Po ', # 0xeb +'Wang ', # 0xec +'Die ', # 0xed +'Ze ', # 0xee +'Tao ', # 0xef +'Shu ', # 0xf0 +'Tuo ', # 0xf1 +'Kep ', # 0xf2 +'Jing ', # 0xf3 +'Hui ', # 0xf4 +'Tong ', # 0xf5 +'You ', # 0xf6 +'Mi ', # 0xf7 +'Beng ', # 0xf8 +'Ji ', # 0xf9 +'Nai ', # 0xfa +'Yi ', # 0xfb +'Jie ', # 0xfc +'Zhui ', # 0xfd +'Lie ', # 0xfe +'Xun ', # 0xff +) diff --git a/libs/unidecode/x090.py b/libs/unidecode/x090.py new file mode 100644 index 00000000..ade65069 --- /dev/null +++ b/libs/unidecode/x090.py @@ -0,0 +1,258 @@ +data = ( +'Tui ', # 0x00 +'Song ', # 0x01 +'Gua ', # 0x02 +'Tao ', # 0x03 +'Pang ', # 0x04 +'Hou ', # 0x05 +'Ni ', # 0x06 +'Dun ', # 0x07 +'Jiong ', # 0x08 +'Xuan ', # 0x09 +'Xun ', # 0x0a +'Bu ', # 0x0b +'You ', # 0x0c +'Xiao ', # 0x0d +'Qiu ', # 0x0e +'Tou ', # 0x0f +'Zhu ', # 0x10 +'Qiu ', # 0x11 +'Di ', # 0x12 +'Di ', # 0x13 +'Tu ', # 0x14 +'Jing ', # 0x15 +'Ti ', # 0x16 +'Dou ', # 0x17 +'Yi ', # 0x18 +'Zhe ', # 0x19 +'Tong ', # 0x1a +'Guang ', # 0x1b +'Wu ', # 0x1c +'Shi ', # 0x1d +'Cheng ', # 0x1e +'Su ', # 0x1f +'Zao ', # 0x20 +'Qun ', # 0x21 +'Feng ', # 0x22 +'Lian ', # 0x23 +'Suo ', # 0x24 +'Hui ', # 0x25 +'Li ', # 0x26 +'Sako ', # 0x27 +'Lai ', # 0x28 +'Ben ', # 0x29 +'Cuo ', # 0x2a +'Jue ', # 0x2b +'Beng ', # 0x2c +'Huan ', # 0x2d +'Dai ', # 0x2e +'Lu ', # 0x2f +'You ', # 0x30 +'Zhou ', # 0x31 +'Jin ', # 0x32 +'Yu ', # 0x33 +'Chuo ', # 0x34 +'Kui ', # 0x35 +'Wei ', # 0x36 +'Ti ', # 0x37 +'Yi ', # 0x38 +'Da ', # 0x39 +'Yuan ', # 0x3a +'Luo ', # 0x3b +'Bi ', # 0x3c +'Nuo ', # 0x3d +'Yu ', # 0x3e +'Dang ', # 0x3f +'Sui ', # 0x40 +'Dun ', # 0x41 +'Sui ', # 0x42 +'Yan ', # 0x43 +'Chuan ', # 0x44 +'Chi ', # 0x45 +'Ti ', # 0x46 +'Yu ', # 0x47 +'Shi ', # 0x48 +'Zhen ', # 0x49 +'You ', # 0x4a +'Yun ', # 0x4b +'E ', # 0x4c +'Bian ', # 0x4d +'Guo ', # 0x4e +'E ', # 0x4f +'Xia ', # 0x50 +'Huang ', # 0x51 +'Qiu ', # 0x52 +'Dao ', # 0x53 +'Da ', # 0x54 +'Wei ', # 0x55 +'Appare ', # 0x56 +'Yi ', # 0x57 +'Gou ', # 0x58 +'Yao ', # 0x59 +'Chu ', # 0x5a +'Liu ', # 0x5b +'Xun ', # 0x5c +'Ta ', # 0x5d +'Di ', # 0x5e +'Chi ', # 0x5f +'Yuan ', # 0x60 +'Su ', # 0x61 +'Ta ', # 0x62 +'Qian ', # 0x63 +'[?] ', # 0x64 +'Yao ', # 0x65 +'Guan ', # 0x66 +'Zhang ', # 0x67 +'Ao ', # 0x68 +'Shi ', # 0x69 +'Ce ', # 0x6a +'Chi ', # 0x6b +'Su ', # 0x6c +'Zao ', # 0x6d +'Zhe ', # 0x6e +'Dun ', # 0x6f +'Di ', # 0x70 +'Lou ', # 0x71 +'Chi ', # 0x72 +'Cuo ', # 0x73 +'Lin ', # 0x74 +'Zun ', # 0x75 +'Rao ', # 0x76 +'Qian ', # 0x77 +'Xuan ', # 0x78 +'Yu ', # 0x79 +'Yi ', # 0x7a +'Wu ', # 0x7b +'Liao ', # 0x7c +'Ju ', # 0x7d +'Shi ', # 0x7e +'Bi ', # 0x7f +'Yao ', # 0x80 +'Mai ', # 0x81 +'Xie ', # 0x82 +'Sui ', # 0x83 +'Huan ', # 0x84 +'Zhan ', # 0x85 +'Teng ', # 0x86 +'Er ', # 0x87 +'Miao ', # 0x88 +'Bian ', # 0x89 +'Bian ', # 0x8a +'La ', # 0x8b +'Li ', # 0x8c +'Yuan ', # 0x8d +'Yao ', # 0x8e +'Luo ', # 0x8f +'Li ', # 0x90 +'Yi ', # 0x91 +'Ting ', # 0x92 +'Deng ', # 0x93 +'Qi ', # 0x94 +'Yong ', # 0x95 +'Shan ', # 0x96 +'Han ', # 0x97 +'Yu ', # 0x98 +'Mang ', # 0x99 +'Ru ', # 0x9a +'Qiong ', # 0x9b +'[?] ', # 0x9c +'Kuang ', # 0x9d +'Fu ', # 0x9e +'Kang ', # 0x9f +'Bin ', # 0xa0 +'Fang ', # 0xa1 +'Xing ', # 0xa2 +'Na ', # 0xa3 +'Xin ', # 0xa4 +'Shen ', # 0xa5 +'Bang ', # 0xa6 +'Yuan ', # 0xa7 +'Cun ', # 0xa8 +'Huo ', # 0xa9 +'Xie ', # 0xaa +'Bang ', # 0xab +'Wu ', # 0xac +'Ju ', # 0xad +'You ', # 0xae +'Han ', # 0xaf +'Tai ', # 0xb0 +'Qiu ', # 0xb1 +'Bi ', # 0xb2 +'Pei ', # 0xb3 +'Bing ', # 0xb4 +'Shao ', # 0xb5 +'Bei ', # 0xb6 +'Wa ', # 0xb7 +'Di ', # 0xb8 +'Zou ', # 0xb9 +'Ye ', # 0xba +'Lin ', # 0xbb +'Kuang ', # 0xbc +'Gui ', # 0xbd +'Zhu ', # 0xbe +'Shi ', # 0xbf +'Ku ', # 0xc0 +'Yu ', # 0xc1 +'Gai ', # 0xc2 +'Ge ', # 0xc3 +'Xi ', # 0xc4 +'Zhi ', # 0xc5 +'Ji ', # 0xc6 +'Xun ', # 0xc7 +'Hou ', # 0xc8 +'Xing ', # 0xc9 +'Jiao ', # 0xca +'Xi ', # 0xcb +'Gui ', # 0xcc +'Nuo ', # 0xcd +'Lang ', # 0xce +'Jia ', # 0xcf +'Kuai ', # 0xd0 +'Zheng ', # 0xd1 +'Otoko ', # 0xd2 +'Yun ', # 0xd3 +'Yan ', # 0xd4 +'Cheng ', # 0xd5 +'Dou ', # 0xd6 +'Chi ', # 0xd7 +'Lu ', # 0xd8 +'Fu ', # 0xd9 +'Wu ', # 0xda +'Fu ', # 0xdb +'Gao ', # 0xdc +'Hao ', # 0xdd +'Lang ', # 0xde +'Jia ', # 0xdf +'Geng ', # 0xe0 +'Jun ', # 0xe1 +'Ying ', # 0xe2 +'Bo ', # 0xe3 +'Xi ', # 0xe4 +'Bei ', # 0xe5 +'Li ', # 0xe6 +'Yun ', # 0xe7 +'Bu ', # 0xe8 +'Xiao ', # 0xe9 +'Qi ', # 0xea +'Pi ', # 0xeb +'Qing ', # 0xec +'Guo ', # 0xed +'Zhou ', # 0xee +'Tan ', # 0xef +'Zou ', # 0xf0 +'Ping ', # 0xf1 +'Lai ', # 0xf2 +'Ni ', # 0xf3 +'Chen ', # 0xf4 +'You ', # 0xf5 +'Bu ', # 0xf6 +'Xiang ', # 0xf7 +'Dan ', # 0xf8 +'Ju ', # 0xf9 +'Yong ', # 0xfa +'Qiao ', # 0xfb +'Yi ', # 0xfc +'Du ', # 0xfd +'Yan ', # 0xfe +'Mei ', # 0xff +) diff --git a/libs/unidecode/x091.py b/libs/unidecode/x091.py new file mode 100644 index 00000000..fa3dd766 --- /dev/null +++ b/libs/unidecode/x091.py @@ -0,0 +1,258 @@ +data = ( +'Ruo ', # 0x00 +'Bei ', # 0x01 +'E ', # 0x02 +'Yu ', # 0x03 +'Juan ', # 0x04 +'Yu ', # 0x05 +'Yun ', # 0x06 +'Hou ', # 0x07 +'Kui ', # 0x08 +'Xiang ', # 0x09 +'Xiang ', # 0x0a +'Sou ', # 0x0b +'Tang ', # 0x0c +'Ming ', # 0x0d +'Xi ', # 0x0e +'Ru ', # 0x0f +'Chu ', # 0x10 +'Zi ', # 0x11 +'Zou ', # 0x12 +'Ju ', # 0x13 +'Wu ', # 0x14 +'Xiang ', # 0x15 +'Yun ', # 0x16 +'Hao ', # 0x17 +'Yong ', # 0x18 +'Bi ', # 0x19 +'Mo ', # 0x1a +'Chao ', # 0x1b +'Fu ', # 0x1c +'Liao ', # 0x1d +'Yin ', # 0x1e +'Zhuan ', # 0x1f +'Hu ', # 0x20 +'Qiao ', # 0x21 +'Yan ', # 0x22 +'Zhang ', # 0x23 +'Fan ', # 0x24 +'Qiao ', # 0x25 +'Xu ', # 0x26 +'Deng ', # 0x27 +'Bi ', # 0x28 +'Xin ', # 0x29 +'Bi ', # 0x2a +'Ceng ', # 0x2b +'Wei ', # 0x2c +'Zheng ', # 0x2d +'Mao ', # 0x2e +'Shan ', # 0x2f +'Lin ', # 0x30 +'Po ', # 0x31 +'Dan ', # 0x32 +'Meng ', # 0x33 +'Ye ', # 0x34 +'Cao ', # 0x35 +'Kuai ', # 0x36 +'Feng ', # 0x37 +'Meng ', # 0x38 +'Zou ', # 0x39 +'Kuang ', # 0x3a +'Lian ', # 0x3b +'Zan ', # 0x3c +'Chan ', # 0x3d +'You ', # 0x3e +'Qi ', # 0x3f +'Yan ', # 0x40 +'Chan ', # 0x41 +'Zan ', # 0x42 +'Ling ', # 0x43 +'Huan ', # 0x44 +'Xi ', # 0x45 +'Feng ', # 0x46 +'Zan ', # 0x47 +'Li ', # 0x48 +'You ', # 0x49 +'Ding ', # 0x4a +'Qiu ', # 0x4b +'Zhuo ', # 0x4c +'Pei ', # 0x4d +'Zhou ', # 0x4e +'Yi ', # 0x4f +'Hang ', # 0x50 +'Yu ', # 0x51 +'Jiu ', # 0x52 +'Yan ', # 0x53 +'Zui ', # 0x54 +'Mao ', # 0x55 +'Dan ', # 0x56 +'Xu ', # 0x57 +'Tou ', # 0x58 +'Zhen ', # 0x59 +'Fen ', # 0x5a +'Sakenomoto ', # 0x5b +'[?] ', # 0x5c +'Yun ', # 0x5d +'Tai ', # 0x5e +'Tian ', # 0x5f +'Qia ', # 0x60 +'Tuo ', # 0x61 +'Zuo ', # 0x62 +'Han ', # 0x63 +'Gu ', # 0x64 +'Su ', # 0x65 +'Po ', # 0x66 +'Chou ', # 0x67 +'Zai ', # 0x68 +'Ming ', # 0x69 +'Luo ', # 0x6a +'Chuo ', # 0x6b +'Chou ', # 0x6c +'You ', # 0x6d +'Tong ', # 0x6e +'Zhi ', # 0x6f +'Xian ', # 0x70 +'Jiang ', # 0x71 +'Cheng ', # 0x72 +'Yin ', # 0x73 +'Tu ', # 0x74 +'Xiao ', # 0x75 +'Mei ', # 0x76 +'Ku ', # 0x77 +'Suan ', # 0x78 +'Lei ', # 0x79 +'Pu ', # 0x7a +'Zui ', # 0x7b +'Hai ', # 0x7c +'Yan ', # 0x7d +'Xi ', # 0x7e +'Niang ', # 0x7f +'Wei ', # 0x80 +'Lu ', # 0x81 +'Lan ', # 0x82 +'Yan ', # 0x83 +'Tao ', # 0x84 +'Pei ', # 0x85 +'Zhan ', # 0x86 +'Chun ', # 0x87 +'Tan ', # 0x88 +'Zui ', # 0x89 +'Chuo ', # 0x8a +'Cu ', # 0x8b +'Kun ', # 0x8c +'Ti ', # 0x8d +'Mian ', # 0x8e +'Du ', # 0x8f +'Hu ', # 0x90 +'Xu ', # 0x91 +'Xing ', # 0x92 +'Tan ', # 0x93 +'Jiu ', # 0x94 +'Chun ', # 0x95 +'Yun ', # 0x96 +'Po ', # 0x97 +'Ke ', # 0x98 +'Sou ', # 0x99 +'Mi ', # 0x9a +'Quan ', # 0x9b +'Chou ', # 0x9c +'Cuo ', # 0x9d +'Yun ', # 0x9e +'Yong ', # 0x9f +'Ang ', # 0xa0 +'Zha ', # 0xa1 +'Hai ', # 0xa2 +'Tang ', # 0xa3 +'Jiang ', # 0xa4 +'Piao ', # 0xa5 +'Shan ', # 0xa6 +'Yu ', # 0xa7 +'Li ', # 0xa8 +'Zao ', # 0xa9 +'Lao ', # 0xaa +'Yi ', # 0xab +'Jiang ', # 0xac +'Pu ', # 0xad +'Jiao ', # 0xae +'Xi ', # 0xaf +'Tan ', # 0xb0 +'Po ', # 0xb1 +'Nong ', # 0xb2 +'Yi ', # 0xb3 +'Li ', # 0xb4 +'Ju ', # 0xb5 +'Jiao ', # 0xb6 +'Yi ', # 0xb7 +'Niang ', # 0xb8 +'Ru ', # 0xb9 +'Xun ', # 0xba +'Chou ', # 0xbb +'Yan ', # 0xbc +'Ling ', # 0xbd +'Mi ', # 0xbe +'Mi ', # 0xbf +'Niang ', # 0xc0 +'Xin ', # 0xc1 +'Jiao ', # 0xc2 +'Xi ', # 0xc3 +'Mi ', # 0xc4 +'Yan ', # 0xc5 +'Bian ', # 0xc6 +'Cai ', # 0xc7 +'Shi ', # 0xc8 +'You ', # 0xc9 +'Shi ', # 0xca +'Shi ', # 0xcb +'Li ', # 0xcc +'Zhong ', # 0xcd +'Ye ', # 0xce +'Liang ', # 0xcf +'Li ', # 0xd0 +'Jin ', # 0xd1 +'Jin ', # 0xd2 +'Qiu ', # 0xd3 +'Yi ', # 0xd4 +'Diao ', # 0xd5 +'Dao ', # 0xd6 +'Zhao ', # 0xd7 +'Ding ', # 0xd8 +'Po ', # 0xd9 +'Qiu ', # 0xda +'He ', # 0xdb +'Fu ', # 0xdc +'Zhen ', # 0xdd +'Zhi ', # 0xde +'Ba ', # 0xdf +'Luan ', # 0xe0 +'Fu ', # 0xe1 +'Nai ', # 0xe2 +'Diao ', # 0xe3 +'Shan ', # 0xe4 +'Qiao ', # 0xe5 +'Kou ', # 0xe6 +'Chuan ', # 0xe7 +'Zi ', # 0xe8 +'Fan ', # 0xe9 +'Yu ', # 0xea +'Hua ', # 0xeb +'Han ', # 0xec +'Gong ', # 0xed +'Qi ', # 0xee +'Mang ', # 0xef +'Ri ', # 0xf0 +'Di ', # 0xf1 +'Si ', # 0xf2 +'Xi ', # 0xf3 +'Yi ', # 0xf4 +'Chai ', # 0xf5 +'Shi ', # 0xf6 +'Tu ', # 0xf7 +'Xi ', # 0xf8 +'Nu ', # 0xf9 +'Qian ', # 0xfa +'Ishiyumi ', # 0xfb +'Jian ', # 0xfc +'Pi ', # 0xfd +'Ye ', # 0xfe +'Yin ', # 0xff +) diff --git a/libs/unidecode/x092.py b/libs/unidecode/x092.py new file mode 100644 index 00000000..e752f4fe --- /dev/null +++ b/libs/unidecode/x092.py @@ -0,0 +1,258 @@ +data = ( +'Ba ', # 0x00 +'Fang ', # 0x01 +'Chen ', # 0x02 +'Xing ', # 0x03 +'Tou ', # 0x04 +'Yue ', # 0x05 +'Yan ', # 0x06 +'Fu ', # 0x07 +'Pi ', # 0x08 +'Na ', # 0x09 +'Xin ', # 0x0a +'E ', # 0x0b +'Jue ', # 0x0c +'Dun ', # 0x0d +'Gou ', # 0x0e +'Yin ', # 0x0f +'Qian ', # 0x10 +'Ban ', # 0x11 +'Ji ', # 0x12 +'Ren ', # 0x13 +'Chao ', # 0x14 +'Niu ', # 0x15 +'Fen ', # 0x16 +'Yun ', # 0x17 +'Ji ', # 0x18 +'Qin ', # 0x19 +'Pi ', # 0x1a +'Guo ', # 0x1b +'Hong ', # 0x1c +'Yin ', # 0x1d +'Jun ', # 0x1e +'Shi ', # 0x1f +'Yi ', # 0x20 +'Zhong ', # 0x21 +'Nie ', # 0x22 +'Gai ', # 0x23 +'Ri ', # 0x24 +'Huo ', # 0x25 +'Tai ', # 0x26 +'Kang ', # 0x27 +'Habaki ', # 0x28 +'Irori ', # 0x29 +'Ngaak ', # 0x2a +'[?] ', # 0x2b +'Duo ', # 0x2c +'Zi ', # 0x2d +'Ni ', # 0x2e +'Tu ', # 0x2f +'Shi ', # 0x30 +'Min ', # 0x31 +'Gu ', # 0x32 +'E ', # 0x33 +'Ling ', # 0x34 +'Bing ', # 0x35 +'Yi ', # 0x36 +'Gu ', # 0x37 +'Ba ', # 0x38 +'Pi ', # 0x39 +'Yu ', # 0x3a +'Si ', # 0x3b +'Zuo ', # 0x3c +'Bu ', # 0x3d +'You ', # 0x3e +'Dian ', # 0x3f +'Jia ', # 0x40 +'Zhen ', # 0x41 +'Shi ', # 0x42 +'Shi ', # 0x43 +'Tie ', # 0x44 +'Ju ', # 0x45 +'Zhan ', # 0x46 +'Shi ', # 0x47 +'She ', # 0x48 +'Xuan ', # 0x49 +'Zhao ', # 0x4a +'Bao ', # 0x4b +'He ', # 0x4c +'Bi ', # 0x4d +'Sheng ', # 0x4e +'Chu ', # 0x4f +'Shi ', # 0x50 +'Bo ', # 0x51 +'Zhu ', # 0x52 +'Chi ', # 0x53 +'Za ', # 0x54 +'Po ', # 0x55 +'Tong ', # 0x56 +'Qian ', # 0x57 +'Fu ', # 0x58 +'Zhai ', # 0x59 +'Liu ', # 0x5a +'Qian ', # 0x5b +'Fu ', # 0x5c +'Li ', # 0x5d +'Yue ', # 0x5e +'Pi ', # 0x5f +'Yang ', # 0x60 +'Ban ', # 0x61 +'Bo ', # 0x62 +'Jie ', # 0x63 +'Gou ', # 0x64 +'Shu ', # 0x65 +'Zheng ', # 0x66 +'Mu ', # 0x67 +'Ni ', # 0x68 +'Nie ', # 0x69 +'Di ', # 0x6a +'Jia ', # 0x6b +'Mu ', # 0x6c +'Dan ', # 0x6d +'Shen ', # 0x6e +'Yi ', # 0x6f +'Si ', # 0x70 +'Kuang ', # 0x71 +'Ka ', # 0x72 +'Bei ', # 0x73 +'Jian ', # 0x74 +'Tong ', # 0x75 +'Xing ', # 0x76 +'Hong ', # 0x77 +'Jiao ', # 0x78 +'Chi ', # 0x79 +'Er ', # 0x7a +'Ge ', # 0x7b +'Bing ', # 0x7c +'Shi ', # 0x7d +'Mou ', # 0x7e +'Jia ', # 0x7f +'Yin ', # 0x80 +'Jun ', # 0x81 +'Zhou ', # 0x82 +'Chong ', # 0x83 +'Shang ', # 0x84 +'Tong ', # 0x85 +'Mo ', # 0x86 +'Lei ', # 0x87 +'Ji ', # 0x88 +'Yu ', # 0x89 +'Xu ', # 0x8a +'Ren ', # 0x8b +'Zun ', # 0x8c +'Zhi ', # 0x8d +'Qiong ', # 0x8e +'Shan ', # 0x8f +'Chi ', # 0x90 +'Xian ', # 0x91 +'Xing ', # 0x92 +'Quan ', # 0x93 +'Pi ', # 0x94 +'Tie ', # 0x95 +'Zhu ', # 0x96 +'Hou ', # 0x97 +'Ming ', # 0x98 +'Kua ', # 0x99 +'Yao ', # 0x9a +'Xian ', # 0x9b +'Xian ', # 0x9c +'Xiu ', # 0x9d +'Jun ', # 0x9e +'Cha ', # 0x9f +'Lao ', # 0xa0 +'Ji ', # 0xa1 +'Pi ', # 0xa2 +'Ru ', # 0xa3 +'Mi ', # 0xa4 +'Yi ', # 0xa5 +'Yin ', # 0xa6 +'Guang ', # 0xa7 +'An ', # 0xa8 +'Diou ', # 0xa9 +'You ', # 0xaa +'Se ', # 0xab +'Kao ', # 0xac +'Qian ', # 0xad +'Luan ', # 0xae +'Kasugai ', # 0xaf +'Ai ', # 0xb0 +'Diao ', # 0xb1 +'Han ', # 0xb2 +'Rui ', # 0xb3 +'Shi ', # 0xb4 +'Keng ', # 0xb5 +'Qiu ', # 0xb6 +'Xiao ', # 0xb7 +'Zhe ', # 0xb8 +'Xiu ', # 0xb9 +'Zang ', # 0xba +'Ti ', # 0xbb +'Cuo ', # 0xbc +'Gua ', # 0xbd +'Gong ', # 0xbe +'Zhong ', # 0xbf +'Dou ', # 0xc0 +'Lu ', # 0xc1 +'Mei ', # 0xc2 +'Lang ', # 0xc3 +'Wan ', # 0xc4 +'Xin ', # 0xc5 +'Yun ', # 0xc6 +'Bei ', # 0xc7 +'Wu ', # 0xc8 +'Su ', # 0xc9 +'Yu ', # 0xca +'Chan ', # 0xcb +'Ting ', # 0xcc +'Bo ', # 0xcd +'Han ', # 0xce +'Jia ', # 0xcf +'Hong ', # 0xd0 +'Cuan ', # 0xd1 +'Feng ', # 0xd2 +'Chan ', # 0xd3 +'Wan ', # 0xd4 +'Zhi ', # 0xd5 +'Si ', # 0xd6 +'Xuan ', # 0xd7 +'Wu ', # 0xd8 +'Wu ', # 0xd9 +'Tiao ', # 0xda +'Gong ', # 0xdb +'Zhuo ', # 0xdc +'Lue ', # 0xdd +'Xing ', # 0xde +'Qian ', # 0xdf +'Shen ', # 0xe0 +'Han ', # 0xe1 +'Lue ', # 0xe2 +'Xie ', # 0xe3 +'Chu ', # 0xe4 +'Zheng ', # 0xe5 +'Ju ', # 0xe6 +'Xian ', # 0xe7 +'Tie ', # 0xe8 +'Mang ', # 0xe9 +'Pu ', # 0xea +'Li ', # 0xeb +'Pan ', # 0xec +'Rui ', # 0xed +'Cheng ', # 0xee +'Gao ', # 0xef +'Li ', # 0xf0 +'Te ', # 0xf1 +'Pyeng ', # 0xf2 +'Zhu ', # 0xf3 +'[?] ', # 0xf4 +'Tu ', # 0xf5 +'Liu ', # 0xf6 +'Zui ', # 0xf7 +'Ju ', # 0xf8 +'Chang ', # 0xf9 +'Yuan ', # 0xfa +'Jian ', # 0xfb +'Gang ', # 0xfc +'Diao ', # 0xfd +'Tao ', # 0xfe +'Chang ', # 0xff +) diff --git a/libs/unidecode/x093.py b/libs/unidecode/x093.py new file mode 100644 index 00000000..82857e9a --- /dev/null +++ b/libs/unidecode/x093.py @@ -0,0 +1,258 @@ +data = ( +'Lun ', # 0x00 +'Kua ', # 0x01 +'Ling ', # 0x02 +'Bei ', # 0x03 +'Lu ', # 0x04 +'Li ', # 0x05 +'Qiang ', # 0x06 +'Pou ', # 0x07 +'Juan ', # 0x08 +'Min ', # 0x09 +'Zui ', # 0x0a +'Peng ', # 0x0b +'An ', # 0x0c +'Pi ', # 0x0d +'Xian ', # 0x0e +'Ya ', # 0x0f +'Zhui ', # 0x10 +'Lei ', # 0x11 +'A ', # 0x12 +'Kong ', # 0x13 +'Ta ', # 0x14 +'Kun ', # 0x15 +'Du ', # 0x16 +'Wei ', # 0x17 +'Chui ', # 0x18 +'Zi ', # 0x19 +'Zheng ', # 0x1a +'Ben ', # 0x1b +'Nie ', # 0x1c +'Cong ', # 0x1d +'Qun ', # 0x1e +'Tan ', # 0x1f +'Ding ', # 0x20 +'Qi ', # 0x21 +'Qian ', # 0x22 +'Zhuo ', # 0x23 +'Qi ', # 0x24 +'Yu ', # 0x25 +'Jin ', # 0x26 +'Guan ', # 0x27 +'Mao ', # 0x28 +'Chang ', # 0x29 +'Tian ', # 0x2a +'Xi ', # 0x2b +'Lian ', # 0x2c +'Tao ', # 0x2d +'Gu ', # 0x2e +'Cuo ', # 0x2f +'Shu ', # 0x30 +'Zhen ', # 0x31 +'Lu ', # 0x32 +'Meng ', # 0x33 +'Lu ', # 0x34 +'Hua ', # 0x35 +'Biao ', # 0x36 +'Ga ', # 0x37 +'Lai ', # 0x38 +'Ken ', # 0x39 +'Kazari ', # 0x3a +'Bu ', # 0x3b +'Nai ', # 0x3c +'Wan ', # 0x3d +'Zan ', # 0x3e +'[?] ', # 0x3f +'De ', # 0x40 +'Xian ', # 0x41 +'[?] ', # 0x42 +'Huo ', # 0x43 +'Liang ', # 0x44 +'[?] ', # 0x45 +'Men ', # 0x46 +'Kai ', # 0x47 +'Ying ', # 0x48 +'Di ', # 0x49 +'Lian ', # 0x4a +'Guo ', # 0x4b +'Xian ', # 0x4c +'Du ', # 0x4d +'Tu ', # 0x4e +'Wei ', # 0x4f +'Cong ', # 0x50 +'Fu ', # 0x51 +'Rou ', # 0x52 +'Ji ', # 0x53 +'E ', # 0x54 +'Rou ', # 0x55 +'Chen ', # 0x56 +'Ti ', # 0x57 +'Zha ', # 0x58 +'Hong ', # 0x59 +'Yang ', # 0x5a +'Duan ', # 0x5b +'Xia ', # 0x5c +'Yu ', # 0x5d +'Keng ', # 0x5e +'Xing ', # 0x5f +'Huang ', # 0x60 +'Wei ', # 0x61 +'Fu ', # 0x62 +'Zhao ', # 0x63 +'Cha ', # 0x64 +'Qie ', # 0x65 +'She ', # 0x66 +'Hong ', # 0x67 +'Kui ', # 0x68 +'Tian ', # 0x69 +'Mou ', # 0x6a +'Qiao ', # 0x6b +'Qiao ', # 0x6c +'Hou ', # 0x6d +'Tou ', # 0x6e +'Cong ', # 0x6f +'Huan ', # 0x70 +'Ye ', # 0x71 +'Min ', # 0x72 +'Jian ', # 0x73 +'Duan ', # 0x74 +'Jian ', # 0x75 +'Song ', # 0x76 +'Kui ', # 0x77 +'Hu ', # 0x78 +'Xuan ', # 0x79 +'Duo ', # 0x7a +'Jie ', # 0x7b +'Zhen ', # 0x7c +'Bian ', # 0x7d +'Zhong ', # 0x7e +'Zi ', # 0x7f +'Xiu ', # 0x80 +'Ye ', # 0x81 +'Mei ', # 0x82 +'Pai ', # 0x83 +'Ai ', # 0x84 +'Jie ', # 0x85 +'[?] ', # 0x86 +'Mei ', # 0x87 +'Chuo ', # 0x88 +'Ta ', # 0x89 +'Bang ', # 0x8a +'Xia ', # 0x8b +'Lian ', # 0x8c +'Suo ', # 0x8d +'Xi ', # 0x8e +'Liu ', # 0x8f +'Zu ', # 0x90 +'Ye ', # 0x91 +'Nou ', # 0x92 +'Weng ', # 0x93 +'Rong ', # 0x94 +'Tang ', # 0x95 +'Suo ', # 0x96 +'Qiang ', # 0x97 +'Ge ', # 0x98 +'Shuo ', # 0x99 +'Chui ', # 0x9a +'Bo ', # 0x9b +'Pan ', # 0x9c +'Sa ', # 0x9d +'Bi ', # 0x9e +'Sang ', # 0x9f +'Gang ', # 0xa0 +'Zi ', # 0xa1 +'Wu ', # 0xa2 +'Ying ', # 0xa3 +'Huang ', # 0xa4 +'Tiao ', # 0xa5 +'Liu ', # 0xa6 +'Kai ', # 0xa7 +'Sun ', # 0xa8 +'Sha ', # 0xa9 +'Sou ', # 0xaa +'Wan ', # 0xab +'Hao ', # 0xac +'Zhen ', # 0xad +'Zhen ', # 0xae +'Luo ', # 0xaf +'Yi ', # 0xb0 +'Yuan ', # 0xb1 +'Tang ', # 0xb2 +'Nie ', # 0xb3 +'Xi ', # 0xb4 +'Jia ', # 0xb5 +'Ge ', # 0xb6 +'Ma ', # 0xb7 +'Juan ', # 0xb8 +'Kasugai ', # 0xb9 +'Habaki ', # 0xba +'Suo ', # 0xbb +'[?] ', # 0xbc +'[?] ', # 0xbd +'[?] ', # 0xbe +'Na ', # 0xbf +'Lu ', # 0xc0 +'Suo ', # 0xc1 +'Ou ', # 0xc2 +'Zu ', # 0xc3 +'Tuan ', # 0xc4 +'Xiu ', # 0xc5 +'Guan ', # 0xc6 +'Xuan ', # 0xc7 +'Lian ', # 0xc8 +'Shou ', # 0xc9 +'Ao ', # 0xca +'Man ', # 0xcb +'Mo ', # 0xcc +'Luo ', # 0xcd +'Bi ', # 0xce +'Wei ', # 0xcf +'Liu ', # 0xd0 +'Di ', # 0xd1 +'Qiao ', # 0xd2 +'Cong ', # 0xd3 +'Yi ', # 0xd4 +'Lu ', # 0xd5 +'Ao ', # 0xd6 +'Keng ', # 0xd7 +'Qiang ', # 0xd8 +'Cui ', # 0xd9 +'Qi ', # 0xda +'Chang ', # 0xdb +'Tang ', # 0xdc +'Man ', # 0xdd +'Yong ', # 0xde +'Chan ', # 0xdf +'Feng ', # 0xe0 +'Jing ', # 0xe1 +'Biao ', # 0xe2 +'Shu ', # 0xe3 +'Lou ', # 0xe4 +'Xiu ', # 0xe5 +'Cong ', # 0xe6 +'Long ', # 0xe7 +'Zan ', # 0xe8 +'Jian ', # 0xe9 +'Cao ', # 0xea +'Li ', # 0xeb +'Xia ', # 0xec +'Xi ', # 0xed +'Kang ', # 0xee +'[?] ', # 0xef +'Beng ', # 0xf0 +'[?] ', # 0xf1 +'[?] ', # 0xf2 +'Zheng ', # 0xf3 +'Lu ', # 0xf4 +'Hua ', # 0xf5 +'Ji ', # 0xf6 +'Pu ', # 0xf7 +'Hui ', # 0xf8 +'Qiang ', # 0xf9 +'Po ', # 0xfa +'Lin ', # 0xfb +'Suo ', # 0xfc +'Xiu ', # 0xfd +'San ', # 0xfe +'Cheng ', # 0xff +) diff --git a/libs/unidecode/x094.py b/libs/unidecode/x094.py new file mode 100644 index 00000000..17eb9ddb --- /dev/null +++ b/libs/unidecode/x094.py @@ -0,0 +1,258 @@ +data = ( +'Kui ', # 0x00 +'Si ', # 0x01 +'Liu ', # 0x02 +'Nao ', # 0x03 +'Heng ', # 0x04 +'Pie ', # 0x05 +'Sui ', # 0x06 +'Fan ', # 0x07 +'Qiao ', # 0x08 +'Quan ', # 0x09 +'Yang ', # 0x0a +'Tang ', # 0x0b +'Xiang ', # 0x0c +'Jue ', # 0x0d +'Jiao ', # 0x0e +'Zun ', # 0x0f +'Liao ', # 0x10 +'Jie ', # 0x11 +'Lao ', # 0x12 +'Dui ', # 0x13 +'Tan ', # 0x14 +'Zan ', # 0x15 +'Ji ', # 0x16 +'Jian ', # 0x17 +'Zhong ', # 0x18 +'Deng ', # 0x19 +'Ya ', # 0x1a +'Ying ', # 0x1b +'Dui ', # 0x1c +'Jue ', # 0x1d +'Nou ', # 0x1e +'Ti ', # 0x1f +'Pu ', # 0x20 +'Tie ', # 0x21 +'[?] ', # 0x22 +'[?] ', # 0x23 +'Ding ', # 0x24 +'Shan ', # 0x25 +'Kai ', # 0x26 +'Jian ', # 0x27 +'Fei ', # 0x28 +'Sui ', # 0x29 +'Lu ', # 0x2a +'Juan ', # 0x2b +'Hui ', # 0x2c +'Yu ', # 0x2d +'Lian ', # 0x2e +'Zhuo ', # 0x2f +'Qiao ', # 0x30 +'Qian ', # 0x31 +'Zhuo ', # 0x32 +'Lei ', # 0x33 +'Bi ', # 0x34 +'Tie ', # 0x35 +'Huan ', # 0x36 +'Ye ', # 0x37 +'Duo ', # 0x38 +'Guo ', # 0x39 +'Dang ', # 0x3a +'Ju ', # 0x3b +'Fen ', # 0x3c +'Da ', # 0x3d +'Bei ', # 0x3e +'Yi ', # 0x3f +'Ai ', # 0x40 +'Zong ', # 0x41 +'Xun ', # 0x42 +'Diao ', # 0x43 +'Zhu ', # 0x44 +'Heng ', # 0x45 +'Zhui ', # 0x46 +'Ji ', # 0x47 +'Nie ', # 0x48 +'Ta ', # 0x49 +'Huo ', # 0x4a +'Qing ', # 0x4b +'Bin ', # 0x4c +'Ying ', # 0x4d +'Kui ', # 0x4e +'Ning ', # 0x4f +'Xu ', # 0x50 +'Jian ', # 0x51 +'Jian ', # 0x52 +'Yari ', # 0x53 +'Cha ', # 0x54 +'Zhi ', # 0x55 +'Mie ', # 0x56 +'Li ', # 0x57 +'Lei ', # 0x58 +'Ji ', # 0x59 +'Zuan ', # 0x5a +'Kuang ', # 0x5b +'Shang ', # 0x5c +'Peng ', # 0x5d +'La ', # 0x5e +'Du ', # 0x5f +'Shuo ', # 0x60 +'Chuo ', # 0x61 +'Lu ', # 0x62 +'Biao ', # 0x63 +'Bao ', # 0x64 +'Lu ', # 0x65 +'[?] ', # 0x66 +'[?] ', # 0x67 +'Long ', # 0x68 +'E ', # 0x69 +'Lu ', # 0x6a +'Xin ', # 0x6b +'Jian ', # 0x6c +'Lan ', # 0x6d +'Bo ', # 0x6e +'Jian ', # 0x6f +'Yao ', # 0x70 +'Chan ', # 0x71 +'Xiang ', # 0x72 +'Jian ', # 0x73 +'Xi ', # 0x74 +'Guan ', # 0x75 +'Cang ', # 0x76 +'Nie ', # 0x77 +'Lei ', # 0x78 +'Cuan ', # 0x79 +'Qu ', # 0x7a +'Pan ', # 0x7b +'Luo ', # 0x7c +'Zuan ', # 0x7d +'Luan ', # 0x7e +'Zao ', # 0x7f +'Nie ', # 0x80 +'Jue ', # 0x81 +'Tang ', # 0x82 +'Shu ', # 0x83 +'Lan ', # 0x84 +'Jin ', # 0x85 +'Qiu ', # 0x86 +'Yi ', # 0x87 +'Zhen ', # 0x88 +'Ding ', # 0x89 +'Zhao ', # 0x8a +'Po ', # 0x8b +'Diao ', # 0x8c +'Tu ', # 0x8d +'Qian ', # 0x8e +'Chuan ', # 0x8f +'Shan ', # 0x90 +'Ji ', # 0x91 +'Fan ', # 0x92 +'Diao ', # 0x93 +'Men ', # 0x94 +'Nu ', # 0x95 +'Xi ', # 0x96 +'Chai ', # 0x97 +'Xing ', # 0x98 +'Gai ', # 0x99 +'Bu ', # 0x9a +'Tai ', # 0x9b +'Ju ', # 0x9c +'Dun ', # 0x9d +'Chao ', # 0x9e +'Zhong ', # 0x9f +'Na ', # 0xa0 +'Bei ', # 0xa1 +'Gang ', # 0xa2 +'Ban ', # 0xa3 +'Qian ', # 0xa4 +'Yao ', # 0xa5 +'Qin ', # 0xa6 +'Jun ', # 0xa7 +'Wu ', # 0xa8 +'Gou ', # 0xa9 +'Kang ', # 0xaa +'Fang ', # 0xab +'Huo ', # 0xac +'Tou ', # 0xad +'Niu ', # 0xae +'Ba ', # 0xaf +'Yu ', # 0xb0 +'Qian ', # 0xb1 +'Zheng ', # 0xb2 +'Qian ', # 0xb3 +'Gu ', # 0xb4 +'Bo ', # 0xb5 +'E ', # 0xb6 +'Po ', # 0xb7 +'Bu ', # 0xb8 +'Ba ', # 0xb9 +'Yue ', # 0xba +'Zuan ', # 0xbb +'Mu ', # 0xbc +'Dan ', # 0xbd +'Jia ', # 0xbe +'Dian ', # 0xbf +'You ', # 0xc0 +'Tie ', # 0xc1 +'Bo ', # 0xc2 +'Ling ', # 0xc3 +'Shuo ', # 0xc4 +'Qian ', # 0xc5 +'Liu ', # 0xc6 +'Bao ', # 0xc7 +'Shi ', # 0xc8 +'Xuan ', # 0xc9 +'She ', # 0xca +'Bi ', # 0xcb +'Ni ', # 0xcc +'Pi ', # 0xcd +'Duo ', # 0xce +'Xing ', # 0xcf +'Kao ', # 0xd0 +'Lao ', # 0xd1 +'Er ', # 0xd2 +'Mang ', # 0xd3 +'Ya ', # 0xd4 +'You ', # 0xd5 +'Cheng ', # 0xd6 +'Jia ', # 0xd7 +'Ye ', # 0xd8 +'Nao ', # 0xd9 +'Zhi ', # 0xda +'Dang ', # 0xdb +'Tong ', # 0xdc +'Lu ', # 0xdd +'Diao ', # 0xde +'Yin ', # 0xdf +'Kai ', # 0xe0 +'Zha ', # 0xe1 +'Zhu ', # 0xe2 +'Xian ', # 0xe3 +'Ting ', # 0xe4 +'Diu ', # 0xe5 +'Xian ', # 0xe6 +'Hua ', # 0xe7 +'Quan ', # 0xe8 +'Sha ', # 0xe9 +'Jia ', # 0xea +'Yao ', # 0xeb +'Ge ', # 0xec +'Ming ', # 0xed +'Zheng ', # 0xee +'Se ', # 0xef +'Jiao ', # 0xf0 +'Yi ', # 0xf1 +'Chan ', # 0xf2 +'Chong ', # 0xf3 +'Tang ', # 0xf4 +'An ', # 0xf5 +'Yin ', # 0xf6 +'Ru ', # 0xf7 +'Zhu ', # 0xf8 +'Lao ', # 0xf9 +'Pu ', # 0xfa +'Wu ', # 0xfb +'Lai ', # 0xfc +'Te ', # 0xfd +'Lian ', # 0xfe +'Keng ', # 0xff +) diff --git a/libs/unidecode/x095.py b/libs/unidecode/x095.py new file mode 100644 index 00000000..4b363942 --- /dev/null +++ b/libs/unidecode/x095.py @@ -0,0 +1,258 @@ +data = ( +'Xiao ', # 0x00 +'Suo ', # 0x01 +'Li ', # 0x02 +'Zheng ', # 0x03 +'Chu ', # 0x04 +'Guo ', # 0x05 +'Gao ', # 0x06 +'Tie ', # 0x07 +'Xiu ', # 0x08 +'Cuo ', # 0x09 +'Lue ', # 0x0a +'Feng ', # 0x0b +'Xin ', # 0x0c +'Liu ', # 0x0d +'Kai ', # 0x0e +'Jian ', # 0x0f +'Rui ', # 0x10 +'Ti ', # 0x11 +'Lang ', # 0x12 +'Qian ', # 0x13 +'Ju ', # 0x14 +'A ', # 0x15 +'Qiang ', # 0x16 +'Duo ', # 0x17 +'Tian ', # 0x18 +'Cuo ', # 0x19 +'Mao ', # 0x1a +'Ben ', # 0x1b +'Qi ', # 0x1c +'De ', # 0x1d +'Kua ', # 0x1e +'Kun ', # 0x1f +'Chang ', # 0x20 +'Xi ', # 0x21 +'Gu ', # 0x22 +'Luo ', # 0x23 +'Chui ', # 0x24 +'Zhui ', # 0x25 +'Jin ', # 0x26 +'Zhi ', # 0x27 +'Xian ', # 0x28 +'Juan ', # 0x29 +'Huo ', # 0x2a +'Pou ', # 0x2b +'Tan ', # 0x2c +'Ding ', # 0x2d +'Jian ', # 0x2e +'Ju ', # 0x2f +'Meng ', # 0x30 +'Zi ', # 0x31 +'Qie ', # 0x32 +'Ying ', # 0x33 +'Kai ', # 0x34 +'Qiang ', # 0x35 +'Song ', # 0x36 +'E ', # 0x37 +'Cha ', # 0x38 +'Qiao ', # 0x39 +'Zhong ', # 0x3a +'Duan ', # 0x3b +'Sou ', # 0x3c +'Huang ', # 0x3d +'Huan ', # 0x3e +'Ai ', # 0x3f +'Du ', # 0x40 +'Mei ', # 0x41 +'Lou ', # 0x42 +'Zi ', # 0x43 +'Fei ', # 0x44 +'Mei ', # 0x45 +'Mo ', # 0x46 +'Zhen ', # 0x47 +'Bo ', # 0x48 +'Ge ', # 0x49 +'Nie ', # 0x4a +'Tang ', # 0x4b +'Juan ', # 0x4c +'Nie ', # 0x4d +'Na ', # 0x4e +'Liu ', # 0x4f +'Hao ', # 0x50 +'Bang ', # 0x51 +'Yi ', # 0x52 +'Jia ', # 0x53 +'Bin ', # 0x54 +'Rong ', # 0x55 +'Biao ', # 0x56 +'Tang ', # 0x57 +'Man ', # 0x58 +'Luo ', # 0x59 +'Beng ', # 0x5a +'Yong ', # 0x5b +'Jing ', # 0x5c +'Di ', # 0x5d +'Zu ', # 0x5e +'Xuan ', # 0x5f +'Liu ', # 0x60 +'Tan ', # 0x61 +'Jue ', # 0x62 +'Liao ', # 0x63 +'Pu ', # 0x64 +'Lu ', # 0x65 +'Dui ', # 0x66 +'Lan ', # 0x67 +'Pu ', # 0x68 +'Cuan ', # 0x69 +'Qiang ', # 0x6a +'Deng ', # 0x6b +'Huo ', # 0x6c +'Lei ', # 0x6d +'Huan ', # 0x6e +'Zhuo ', # 0x6f +'Lian ', # 0x70 +'Yi ', # 0x71 +'Cha ', # 0x72 +'Biao ', # 0x73 +'La ', # 0x74 +'Chan ', # 0x75 +'Xiang ', # 0x76 +'Chang ', # 0x77 +'Chang ', # 0x78 +'Jiu ', # 0x79 +'Ao ', # 0x7a +'Die ', # 0x7b +'Qu ', # 0x7c +'Liao ', # 0x7d +'Mi ', # 0x7e +'Chang ', # 0x7f +'Men ', # 0x80 +'Ma ', # 0x81 +'Shuan ', # 0x82 +'Shan ', # 0x83 +'Huo ', # 0x84 +'Men ', # 0x85 +'Yan ', # 0x86 +'Bi ', # 0x87 +'Han ', # 0x88 +'Bi ', # 0x89 +'San ', # 0x8a +'Kai ', # 0x8b +'Kang ', # 0x8c +'Beng ', # 0x8d +'Hong ', # 0x8e +'Run ', # 0x8f +'San ', # 0x90 +'Xian ', # 0x91 +'Xian ', # 0x92 +'Jian ', # 0x93 +'Min ', # 0x94 +'Xia ', # 0x95 +'Yuru ', # 0x96 +'Dou ', # 0x97 +'Zha ', # 0x98 +'Nao ', # 0x99 +'Jian ', # 0x9a +'Peng ', # 0x9b +'Xia ', # 0x9c +'Ling ', # 0x9d +'Bian ', # 0x9e +'Bi ', # 0x9f +'Run ', # 0xa0 +'He ', # 0xa1 +'Guan ', # 0xa2 +'Ge ', # 0xa3 +'Ge ', # 0xa4 +'Fa ', # 0xa5 +'Chu ', # 0xa6 +'Hong ', # 0xa7 +'Gui ', # 0xa8 +'Min ', # 0xa9 +'Se ', # 0xaa +'Kun ', # 0xab +'Lang ', # 0xac +'Lu ', # 0xad +'Ting ', # 0xae +'Sha ', # 0xaf +'Ju ', # 0xb0 +'Yue ', # 0xb1 +'Yue ', # 0xb2 +'Chan ', # 0xb3 +'Qu ', # 0xb4 +'Lin ', # 0xb5 +'Chang ', # 0xb6 +'Shai ', # 0xb7 +'Kun ', # 0xb8 +'Yan ', # 0xb9 +'Min ', # 0xba +'Yan ', # 0xbb +'E ', # 0xbc +'Hun ', # 0xbd +'Yu ', # 0xbe +'Wen ', # 0xbf +'Xiang ', # 0xc0 +'Bao ', # 0xc1 +'Xiang ', # 0xc2 +'Qu ', # 0xc3 +'Yao ', # 0xc4 +'Wen ', # 0xc5 +'Ban ', # 0xc6 +'An ', # 0xc7 +'Wei ', # 0xc8 +'Yin ', # 0xc9 +'Kuo ', # 0xca +'Que ', # 0xcb +'Lan ', # 0xcc +'Du ', # 0xcd +'[?] ', # 0xce +'Phwung ', # 0xcf +'Tian ', # 0xd0 +'Nie ', # 0xd1 +'Ta ', # 0xd2 +'Kai ', # 0xd3 +'He ', # 0xd4 +'Que ', # 0xd5 +'Chuang ', # 0xd6 +'Guan ', # 0xd7 +'Dou ', # 0xd8 +'Qi ', # 0xd9 +'Kui ', # 0xda +'Tang ', # 0xdb +'Guan ', # 0xdc +'Piao ', # 0xdd +'Kan ', # 0xde +'Xi ', # 0xdf +'Hui ', # 0xe0 +'Chan ', # 0xe1 +'Pi ', # 0xe2 +'Dang ', # 0xe3 +'Huan ', # 0xe4 +'Ta ', # 0xe5 +'Wen ', # 0xe6 +'[?] ', # 0xe7 +'Men ', # 0xe8 +'Shuan ', # 0xe9 +'Shan ', # 0xea +'Yan ', # 0xeb +'Han ', # 0xec +'Bi ', # 0xed +'Wen ', # 0xee +'Chuang ', # 0xef +'Run ', # 0xf0 +'Wei ', # 0xf1 +'Xian ', # 0xf2 +'Hong ', # 0xf3 +'Jian ', # 0xf4 +'Min ', # 0xf5 +'Kang ', # 0xf6 +'Men ', # 0xf7 +'Zha ', # 0xf8 +'Nao ', # 0xf9 +'Gui ', # 0xfa +'Wen ', # 0xfb +'Ta ', # 0xfc +'Min ', # 0xfd +'Lu ', # 0xfe +'Kai ', # 0xff +) diff --git a/libs/unidecode/x096.py b/libs/unidecode/x096.py new file mode 100644 index 00000000..738a4ea3 --- /dev/null +++ b/libs/unidecode/x096.py @@ -0,0 +1,258 @@ +data = ( +'Fa ', # 0x00 +'Ge ', # 0x01 +'He ', # 0x02 +'Kun ', # 0x03 +'Jiu ', # 0x04 +'Yue ', # 0x05 +'Lang ', # 0x06 +'Du ', # 0x07 +'Yu ', # 0x08 +'Yan ', # 0x09 +'Chang ', # 0x0a +'Xi ', # 0x0b +'Wen ', # 0x0c +'Hun ', # 0x0d +'Yan ', # 0x0e +'E ', # 0x0f +'Chan ', # 0x10 +'Lan ', # 0x11 +'Qu ', # 0x12 +'Hui ', # 0x13 +'Kuo ', # 0x14 +'Que ', # 0x15 +'Ge ', # 0x16 +'Tian ', # 0x17 +'Ta ', # 0x18 +'Que ', # 0x19 +'Kan ', # 0x1a +'Huan ', # 0x1b +'Fu ', # 0x1c +'Fu ', # 0x1d +'Le ', # 0x1e +'Dui ', # 0x1f +'Xin ', # 0x20 +'Qian ', # 0x21 +'Wu ', # 0x22 +'Yi ', # 0x23 +'Tuo ', # 0x24 +'Yin ', # 0x25 +'Yang ', # 0x26 +'Dou ', # 0x27 +'E ', # 0x28 +'Sheng ', # 0x29 +'Ban ', # 0x2a +'Pei ', # 0x2b +'Keng ', # 0x2c +'Yun ', # 0x2d +'Ruan ', # 0x2e +'Zhi ', # 0x2f +'Pi ', # 0x30 +'Jing ', # 0x31 +'Fang ', # 0x32 +'Yang ', # 0x33 +'Yin ', # 0x34 +'Zhen ', # 0x35 +'Jie ', # 0x36 +'Cheng ', # 0x37 +'E ', # 0x38 +'Qu ', # 0x39 +'Di ', # 0x3a +'Zu ', # 0x3b +'Zuo ', # 0x3c +'Dian ', # 0x3d +'Ling ', # 0x3e +'A ', # 0x3f +'Tuo ', # 0x40 +'Tuo ', # 0x41 +'Po ', # 0x42 +'Bing ', # 0x43 +'Fu ', # 0x44 +'Ji ', # 0x45 +'Lu ', # 0x46 +'Long ', # 0x47 +'Chen ', # 0x48 +'Xing ', # 0x49 +'Duo ', # 0x4a +'Lou ', # 0x4b +'Mo ', # 0x4c +'Jiang ', # 0x4d +'Shu ', # 0x4e +'Duo ', # 0x4f +'Xian ', # 0x50 +'Er ', # 0x51 +'Gui ', # 0x52 +'Yu ', # 0x53 +'Gai ', # 0x54 +'Shan ', # 0x55 +'Xun ', # 0x56 +'Qiao ', # 0x57 +'Xing ', # 0x58 +'Chun ', # 0x59 +'Fu ', # 0x5a +'Bi ', # 0x5b +'Xia ', # 0x5c +'Shan ', # 0x5d +'Sheng ', # 0x5e +'Zhi ', # 0x5f +'Pu ', # 0x60 +'Dou ', # 0x61 +'Yuan ', # 0x62 +'Zhen ', # 0x63 +'Chu ', # 0x64 +'Xian ', # 0x65 +'Tou ', # 0x66 +'Nie ', # 0x67 +'Yun ', # 0x68 +'Xian ', # 0x69 +'Pei ', # 0x6a +'Pei ', # 0x6b +'Zou ', # 0x6c +'Yi ', # 0x6d +'Dui ', # 0x6e +'Lun ', # 0x6f +'Yin ', # 0x70 +'Ju ', # 0x71 +'Chui ', # 0x72 +'Chen ', # 0x73 +'Pi ', # 0x74 +'Ling ', # 0x75 +'Tao ', # 0x76 +'Xian ', # 0x77 +'Lu ', # 0x78 +'Sheng ', # 0x79 +'Xian ', # 0x7a +'Yin ', # 0x7b +'Zhu ', # 0x7c +'Yang ', # 0x7d +'Reng ', # 0x7e +'Shan ', # 0x7f +'Chong ', # 0x80 +'Yan ', # 0x81 +'Yin ', # 0x82 +'Yu ', # 0x83 +'Ti ', # 0x84 +'Yu ', # 0x85 +'Long ', # 0x86 +'Wei ', # 0x87 +'Wei ', # 0x88 +'Nie ', # 0x89 +'Dui ', # 0x8a +'Sui ', # 0x8b +'An ', # 0x8c +'Huang ', # 0x8d +'Jie ', # 0x8e +'Sui ', # 0x8f +'Yin ', # 0x90 +'Gai ', # 0x91 +'Yan ', # 0x92 +'Hui ', # 0x93 +'Ge ', # 0x94 +'Yun ', # 0x95 +'Wu ', # 0x96 +'Wei ', # 0x97 +'Ai ', # 0x98 +'Xi ', # 0x99 +'Tang ', # 0x9a +'Ji ', # 0x9b +'Zhang ', # 0x9c +'Dao ', # 0x9d +'Ao ', # 0x9e +'Xi ', # 0x9f +'Yin ', # 0xa0 +'[?] ', # 0xa1 +'Rao ', # 0xa2 +'Lin ', # 0xa3 +'Tui ', # 0xa4 +'Deng ', # 0xa5 +'Pi ', # 0xa6 +'Sui ', # 0xa7 +'Sui ', # 0xa8 +'Yu ', # 0xa9 +'Xian ', # 0xaa +'Fen ', # 0xab +'Ni ', # 0xac +'Er ', # 0xad +'Ji ', # 0xae +'Dao ', # 0xaf +'Xi ', # 0xb0 +'Yin ', # 0xb1 +'E ', # 0xb2 +'Hui ', # 0xb3 +'Long ', # 0xb4 +'Xi ', # 0xb5 +'Li ', # 0xb6 +'Li ', # 0xb7 +'Li ', # 0xb8 +'Zhui ', # 0xb9 +'He ', # 0xba +'Zhi ', # 0xbb +'Zhun ', # 0xbc +'Jun ', # 0xbd +'Nan ', # 0xbe +'Yi ', # 0xbf +'Que ', # 0xc0 +'Yan ', # 0xc1 +'Qian ', # 0xc2 +'Ya ', # 0xc3 +'Xiong ', # 0xc4 +'Ya ', # 0xc5 +'Ji ', # 0xc6 +'Gu ', # 0xc7 +'Huan ', # 0xc8 +'Zhi ', # 0xc9 +'Gou ', # 0xca +'Jun ', # 0xcb +'Ci ', # 0xcc +'Yong ', # 0xcd +'Ju ', # 0xce +'Chu ', # 0xcf +'Hu ', # 0xd0 +'Za ', # 0xd1 +'Luo ', # 0xd2 +'Yu ', # 0xd3 +'Chou ', # 0xd4 +'Diao ', # 0xd5 +'Sui ', # 0xd6 +'Han ', # 0xd7 +'Huo ', # 0xd8 +'Shuang ', # 0xd9 +'Guan ', # 0xda +'Chu ', # 0xdb +'Za ', # 0xdc +'Yong ', # 0xdd +'Ji ', # 0xde +'Xi ', # 0xdf +'Chou ', # 0xe0 +'Liu ', # 0xe1 +'Li ', # 0xe2 +'Nan ', # 0xe3 +'Xue ', # 0xe4 +'Za ', # 0xe5 +'Ji ', # 0xe6 +'Ji ', # 0xe7 +'Yu ', # 0xe8 +'Yu ', # 0xe9 +'Xue ', # 0xea +'Na ', # 0xeb +'Fou ', # 0xec +'Se ', # 0xed +'Mu ', # 0xee +'Wen ', # 0xef +'Fen ', # 0xf0 +'Pang ', # 0xf1 +'Yun ', # 0xf2 +'Li ', # 0xf3 +'Li ', # 0xf4 +'Ang ', # 0xf5 +'Ling ', # 0xf6 +'Lei ', # 0xf7 +'An ', # 0xf8 +'Bao ', # 0xf9 +'Meng ', # 0xfa +'Dian ', # 0xfb +'Dang ', # 0xfc +'Xing ', # 0xfd +'Wu ', # 0xfe +'Zhao ', # 0xff +) diff --git a/libs/unidecode/x097.py b/libs/unidecode/x097.py new file mode 100644 index 00000000..7255f0f8 --- /dev/null +++ b/libs/unidecode/x097.py @@ -0,0 +1,258 @@ +data = ( +'Xu ', # 0x00 +'Ji ', # 0x01 +'Mu ', # 0x02 +'Chen ', # 0x03 +'Xiao ', # 0x04 +'Zha ', # 0x05 +'Ting ', # 0x06 +'Zhen ', # 0x07 +'Pei ', # 0x08 +'Mei ', # 0x09 +'Ling ', # 0x0a +'Qi ', # 0x0b +'Chou ', # 0x0c +'Huo ', # 0x0d +'Sha ', # 0x0e +'Fei ', # 0x0f +'Weng ', # 0x10 +'Zhan ', # 0x11 +'Yin ', # 0x12 +'Ni ', # 0x13 +'Chou ', # 0x14 +'Tun ', # 0x15 +'Lin ', # 0x16 +'[?] ', # 0x17 +'Dong ', # 0x18 +'Ying ', # 0x19 +'Wu ', # 0x1a +'Ling ', # 0x1b +'Shuang ', # 0x1c +'Ling ', # 0x1d +'Xia ', # 0x1e +'Hong ', # 0x1f +'Yin ', # 0x20 +'Mo ', # 0x21 +'Mai ', # 0x22 +'Yun ', # 0x23 +'Liu ', # 0x24 +'Meng ', # 0x25 +'Bin ', # 0x26 +'Wu ', # 0x27 +'Wei ', # 0x28 +'Huo ', # 0x29 +'Yin ', # 0x2a +'Xi ', # 0x2b +'Yi ', # 0x2c +'Ai ', # 0x2d +'Dan ', # 0x2e +'Deng ', # 0x2f +'Xian ', # 0x30 +'Yu ', # 0x31 +'Lu ', # 0x32 +'Long ', # 0x33 +'Dai ', # 0x34 +'Ji ', # 0x35 +'Pang ', # 0x36 +'Yang ', # 0x37 +'Ba ', # 0x38 +'Pi ', # 0x39 +'Wei ', # 0x3a +'[?] ', # 0x3b +'Xi ', # 0x3c +'Ji ', # 0x3d +'Mai ', # 0x3e +'Meng ', # 0x3f +'Meng ', # 0x40 +'Lei ', # 0x41 +'Li ', # 0x42 +'Huo ', # 0x43 +'Ai ', # 0x44 +'Fei ', # 0x45 +'Dai ', # 0x46 +'Long ', # 0x47 +'Ling ', # 0x48 +'Ai ', # 0x49 +'Feng ', # 0x4a +'Li ', # 0x4b +'Bao ', # 0x4c +'[?] ', # 0x4d +'He ', # 0x4e +'He ', # 0x4f +'Bing ', # 0x50 +'Qing ', # 0x51 +'Qing ', # 0x52 +'Jing ', # 0x53 +'Tian ', # 0x54 +'Zhen ', # 0x55 +'Jing ', # 0x56 +'Cheng ', # 0x57 +'Qing ', # 0x58 +'Jing ', # 0x59 +'Jing ', # 0x5a +'Dian ', # 0x5b +'Jing ', # 0x5c +'Tian ', # 0x5d +'Fei ', # 0x5e +'Fei ', # 0x5f +'Kao ', # 0x60 +'Mi ', # 0x61 +'Mian ', # 0x62 +'Mian ', # 0x63 +'Pao ', # 0x64 +'Ye ', # 0x65 +'Tian ', # 0x66 +'Hui ', # 0x67 +'Ye ', # 0x68 +'Ge ', # 0x69 +'Ding ', # 0x6a +'Cha ', # 0x6b +'Jian ', # 0x6c +'Ren ', # 0x6d +'Di ', # 0x6e +'Du ', # 0x6f +'Wu ', # 0x70 +'Ren ', # 0x71 +'Qin ', # 0x72 +'Jin ', # 0x73 +'Xue ', # 0x74 +'Niu ', # 0x75 +'Ba ', # 0x76 +'Yin ', # 0x77 +'Sa ', # 0x78 +'Na ', # 0x79 +'Mo ', # 0x7a +'Zu ', # 0x7b +'Da ', # 0x7c +'Ban ', # 0x7d +'Yi ', # 0x7e +'Yao ', # 0x7f +'Tao ', # 0x80 +'Tuo ', # 0x81 +'Jia ', # 0x82 +'Hong ', # 0x83 +'Pao ', # 0x84 +'Yang ', # 0x85 +'Tomo ', # 0x86 +'Yin ', # 0x87 +'Jia ', # 0x88 +'Tao ', # 0x89 +'Ji ', # 0x8a +'Xie ', # 0x8b +'An ', # 0x8c +'An ', # 0x8d +'Hen ', # 0x8e +'Gong ', # 0x8f +'Kohaze ', # 0x90 +'Da ', # 0x91 +'Qiao ', # 0x92 +'Ting ', # 0x93 +'Wan ', # 0x94 +'Ying ', # 0x95 +'Sui ', # 0x96 +'Tiao ', # 0x97 +'Qiao ', # 0x98 +'Xuan ', # 0x99 +'Kong ', # 0x9a +'Beng ', # 0x9b +'Ta ', # 0x9c +'Zhang ', # 0x9d +'Bing ', # 0x9e +'Kuo ', # 0x9f +'Ju ', # 0xa0 +'La ', # 0xa1 +'Xie ', # 0xa2 +'Rou ', # 0xa3 +'Bang ', # 0xa4 +'Yi ', # 0xa5 +'Qiu ', # 0xa6 +'Qiu ', # 0xa7 +'He ', # 0xa8 +'Xiao ', # 0xa9 +'Mu ', # 0xaa +'Ju ', # 0xab +'Jian ', # 0xac +'Bian ', # 0xad +'Di ', # 0xae +'Jian ', # 0xaf +'On ', # 0xb0 +'Tao ', # 0xb1 +'Gou ', # 0xb2 +'Ta ', # 0xb3 +'Bei ', # 0xb4 +'Xie ', # 0xb5 +'Pan ', # 0xb6 +'Ge ', # 0xb7 +'Bi ', # 0xb8 +'Kuo ', # 0xb9 +'Tang ', # 0xba +'Lou ', # 0xbb +'Gui ', # 0xbc +'Qiao ', # 0xbd +'Xue ', # 0xbe +'Ji ', # 0xbf +'Jian ', # 0xc0 +'Jiang ', # 0xc1 +'Chan ', # 0xc2 +'Da ', # 0xc3 +'Huo ', # 0xc4 +'Xian ', # 0xc5 +'Qian ', # 0xc6 +'Du ', # 0xc7 +'Wa ', # 0xc8 +'Jian ', # 0xc9 +'Lan ', # 0xca +'Wei ', # 0xcb +'Ren ', # 0xcc +'Fu ', # 0xcd +'Mei ', # 0xce +'Juan ', # 0xcf +'Ge ', # 0xd0 +'Wei ', # 0xd1 +'Qiao ', # 0xd2 +'Han ', # 0xd3 +'Chang ', # 0xd4 +'[?] ', # 0xd5 +'Rou ', # 0xd6 +'Xun ', # 0xd7 +'She ', # 0xd8 +'Wei ', # 0xd9 +'Ge ', # 0xda +'Bei ', # 0xdb +'Tao ', # 0xdc +'Gou ', # 0xdd +'Yun ', # 0xde +'[?] ', # 0xdf +'Bi ', # 0xe0 +'Wei ', # 0xe1 +'Hui ', # 0xe2 +'Du ', # 0xe3 +'Wa ', # 0xe4 +'Du ', # 0xe5 +'Wei ', # 0xe6 +'Ren ', # 0xe7 +'Fu ', # 0xe8 +'Han ', # 0xe9 +'Wei ', # 0xea +'Yun ', # 0xeb +'Tao ', # 0xec +'Jiu ', # 0xed +'Jiu ', # 0xee +'Xian ', # 0xef +'Xie ', # 0xf0 +'Xian ', # 0xf1 +'Ji ', # 0xf2 +'Yin ', # 0xf3 +'Za ', # 0xf4 +'Yun ', # 0xf5 +'Shao ', # 0xf6 +'Le ', # 0xf7 +'Peng ', # 0xf8 +'Heng ', # 0xf9 +'Ying ', # 0xfa +'Yun ', # 0xfb +'Peng ', # 0xfc +'Yin ', # 0xfd +'Yin ', # 0xfe +'Xiang ', # 0xff +) diff --git a/libs/unidecode/x098.py b/libs/unidecode/x098.py new file mode 100644 index 00000000..98160e77 --- /dev/null +++ b/libs/unidecode/x098.py @@ -0,0 +1,258 @@ +data = ( +'Hu ', # 0x00 +'Ye ', # 0x01 +'Ding ', # 0x02 +'Qing ', # 0x03 +'Pan ', # 0x04 +'Xiang ', # 0x05 +'Shun ', # 0x06 +'Han ', # 0x07 +'Xu ', # 0x08 +'Yi ', # 0x09 +'Xu ', # 0x0a +'Gu ', # 0x0b +'Song ', # 0x0c +'Kui ', # 0x0d +'Qi ', # 0x0e +'Hang ', # 0x0f +'Yu ', # 0x10 +'Wan ', # 0x11 +'Ban ', # 0x12 +'Dun ', # 0x13 +'Di ', # 0x14 +'Dan ', # 0x15 +'Pan ', # 0x16 +'Po ', # 0x17 +'Ling ', # 0x18 +'Ce ', # 0x19 +'Jing ', # 0x1a +'Lei ', # 0x1b +'He ', # 0x1c +'Qiao ', # 0x1d +'E ', # 0x1e +'E ', # 0x1f +'Wei ', # 0x20 +'Jie ', # 0x21 +'Gua ', # 0x22 +'Shen ', # 0x23 +'Yi ', # 0x24 +'Shen ', # 0x25 +'Hai ', # 0x26 +'Dui ', # 0x27 +'Pian ', # 0x28 +'Ping ', # 0x29 +'Lei ', # 0x2a +'Fu ', # 0x2b +'Jia ', # 0x2c +'Tou ', # 0x2d +'Hui ', # 0x2e +'Kui ', # 0x2f +'Jia ', # 0x30 +'Le ', # 0x31 +'Tian ', # 0x32 +'Cheng ', # 0x33 +'Ying ', # 0x34 +'Jun ', # 0x35 +'Hu ', # 0x36 +'Han ', # 0x37 +'Jing ', # 0x38 +'Tui ', # 0x39 +'Tui ', # 0x3a +'Pin ', # 0x3b +'Lai ', # 0x3c +'Tui ', # 0x3d +'Zi ', # 0x3e +'Zi ', # 0x3f +'Chui ', # 0x40 +'Ding ', # 0x41 +'Lai ', # 0x42 +'Yan ', # 0x43 +'Han ', # 0x44 +'Jian ', # 0x45 +'Ke ', # 0x46 +'Cui ', # 0x47 +'Jiong ', # 0x48 +'Qin ', # 0x49 +'Yi ', # 0x4a +'Sai ', # 0x4b +'Ti ', # 0x4c +'E ', # 0x4d +'E ', # 0x4e +'Yan ', # 0x4f +'Hun ', # 0x50 +'Kan ', # 0x51 +'Yong ', # 0x52 +'Zhuan ', # 0x53 +'Yan ', # 0x54 +'Xian ', # 0x55 +'Xin ', # 0x56 +'Yi ', # 0x57 +'Yuan ', # 0x58 +'Sang ', # 0x59 +'Dian ', # 0x5a +'Dian ', # 0x5b +'Jiang ', # 0x5c +'Ku ', # 0x5d +'Lei ', # 0x5e +'Liao ', # 0x5f +'Piao ', # 0x60 +'Yi ', # 0x61 +'Man ', # 0x62 +'Qi ', # 0x63 +'Rao ', # 0x64 +'Hao ', # 0x65 +'Qiao ', # 0x66 +'Gu ', # 0x67 +'Xun ', # 0x68 +'Qian ', # 0x69 +'Hui ', # 0x6a +'Zhan ', # 0x6b +'Ru ', # 0x6c +'Hong ', # 0x6d +'Bin ', # 0x6e +'Xian ', # 0x6f +'Pin ', # 0x70 +'Lu ', # 0x71 +'Lan ', # 0x72 +'Nie ', # 0x73 +'Quan ', # 0x74 +'Ye ', # 0x75 +'Ding ', # 0x76 +'Qing ', # 0x77 +'Han ', # 0x78 +'Xiang ', # 0x79 +'Shun ', # 0x7a +'Xu ', # 0x7b +'Xu ', # 0x7c +'Wan ', # 0x7d +'Gu ', # 0x7e +'Dun ', # 0x7f +'Qi ', # 0x80 +'Ban ', # 0x81 +'Song ', # 0x82 +'Hang ', # 0x83 +'Yu ', # 0x84 +'Lu ', # 0x85 +'Ling ', # 0x86 +'Po ', # 0x87 +'Jing ', # 0x88 +'Jie ', # 0x89 +'Jia ', # 0x8a +'Tian ', # 0x8b +'Han ', # 0x8c +'Ying ', # 0x8d +'Jiong ', # 0x8e +'Hai ', # 0x8f +'Yi ', # 0x90 +'Pin ', # 0x91 +'Hui ', # 0x92 +'Tui ', # 0x93 +'Han ', # 0x94 +'Ying ', # 0x95 +'Ying ', # 0x96 +'Ke ', # 0x97 +'Ti ', # 0x98 +'Yong ', # 0x99 +'E ', # 0x9a +'Zhuan ', # 0x9b +'Yan ', # 0x9c +'E ', # 0x9d +'Nie ', # 0x9e +'Man ', # 0x9f +'Dian ', # 0xa0 +'Sang ', # 0xa1 +'Hao ', # 0xa2 +'Lei ', # 0xa3 +'Zhan ', # 0xa4 +'Ru ', # 0xa5 +'Pin ', # 0xa6 +'Quan ', # 0xa7 +'Feng ', # 0xa8 +'Biao ', # 0xa9 +'Oroshi ', # 0xaa +'Fu ', # 0xab +'Xia ', # 0xac +'Zhan ', # 0xad +'Biao ', # 0xae +'Sa ', # 0xaf +'Ba ', # 0xb0 +'Tai ', # 0xb1 +'Lie ', # 0xb2 +'Gua ', # 0xb3 +'Xuan ', # 0xb4 +'Shao ', # 0xb5 +'Ju ', # 0xb6 +'Bi ', # 0xb7 +'Si ', # 0xb8 +'Wei ', # 0xb9 +'Yang ', # 0xba +'Yao ', # 0xbb +'Sou ', # 0xbc +'Kai ', # 0xbd +'Sao ', # 0xbe +'Fan ', # 0xbf +'Liu ', # 0xc0 +'Xi ', # 0xc1 +'Liao ', # 0xc2 +'Piao ', # 0xc3 +'Piao ', # 0xc4 +'Liu ', # 0xc5 +'Biao ', # 0xc6 +'Biao ', # 0xc7 +'Biao ', # 0xc8 +'Liao ', # 0xc9 +'[?] ', # 0xca +'Se ', # 0xcb +'Feng ', # 0xcc +'Biao ', # 0xcd +'Feng ', # 0xce +'Yang ', # 0xcf +'Zhan ', # 0xd0 +'Biao ', # 0xd1 +'Sa ', # 0xd2 +'Ju ', # 0xd3 +'Si ', # 0xd4 +'Sou ', # 0xd5 +'Yao ', # 0xd6 +'Liu ', # 0xd7 +'Piao ', # 0xd8 +'Biao ', # 0xd9 +'Biao ', # 0xda +'Fei ', # 0xdb +'Fan ', # 0xdc +'Fei ', # 0xdd +'Fei ', # 0xde +'Shi ', # 0xdf +'Shi ', # 0xe0 +'Can ', # 0xe1 +'Ji ', # 0xe2 +'Ding ', # 0xe3 +'Si ', # 0xe4 +'Tuo ', # 0xe5 +'Zhan ', # 0xe6 +'Sun ', # 0xe7 +'Xiang ', # 0xe8 +'Tun ', # 0xe9 +'Ren ', # 0xea +'Yu ', # 0xeb +'Juan ', # 0xec +'Chi ', # 0xed +'Yin ', # 0xee +'Fan ', # 0xef +'Fan ', # 0xf0 +'Sun ', # 0xf1 +'Yin ', # 0xf2 +'Zhu ', # 0xf3 +'Yi ', # 0xf4 +'Zhai ', # 0xf5 +'Bi ', # 0xf6 +'Jie ', # 0xf7 +'Tao ', # 0xf8 +'Liu ', # 0xf9 +'Ci ', # 0xfa +'Tie ', # 0xfb +'Si ', # 0xfc +'Bao ', # 0xfd +'Shi ', # 0xfe +'Duo ', # 0xff +) diff --git a/libs/unidecode/x099.py b/libs/unidecode/x099.py new file mode 100644 index 00000000..2adf3de8 --- /dev/null +++ b/libs/unidecode/x099.py @@ -0,0 +1,258 @@ +data = ( +'Hai ', # 0x00 +'Ren ', # 0x01 +'Tian ', # 0x02 +'Jiao ', # 0x03 +'Jia ', # 0x04 +'Bing ', # 0x05 +'Yao ', # 0x06 +'Tong ', # 0x07 +'Ci ', # 0x08 +'Xiang ', # 0x09 +'Yang ', # 0x0a +'Yang ', # 0x0b +'Er ', # 0x0c +'Yan ', # 0x0d +'Le ', # 0x0e +'Yi ', # 0x0f +'Can ', # 0x10 +'Bo ', # 0x11 +'Nei ', # 0x12 +'E ', # 0x13 +'Bu ', # 0x14 +'Jun ', # 0x15 +'Dou ', # 0x16 +'Su ', # 0x17 +'Yu ', # 0x18 +'Shi ', # 0x19 +'Yao ', # 0x1a +'Hun ', # 0x1b +'Guo ', # 0x1c +'Shi ', # 0x1d +'Jian ', # 0x1e +'Zhui ', # 0x1f +'Bing ', # 0x20 +'Xian ', # 0x21 +'Bu ', # 0x22 +'Ye ', # 0x23 +'Tan ', # 0x24 +'Fei ', # 0x25 +'Zhang ', # 0x26 +'Wei ', # 0x27 +'Guan ', # 0x28 +'E ', # 0x29 +'Nuan ', # 0x2a +'Hun ', # 0x2b +'Hu ', # 0x2c +'Huang ', # 0x2d +'Tie ', # 0x2e +'Hui ', # 0x2f +'Jian ', # 0x30 +'Hou ', # 0x31 +'He ', # 0x32 +'Xing ', # 0x33 +'Fen ', # 0x34 +'Wei ', # 0x35 +'Gu ', # 0x36 +'Cha ', # 0x37 +'Song ', # 0x38 +'Tang ', # 0x39 +'Bo ', # 0x3a +'Gao ', # 0x3b +'Xi ', # 0x3c +'Kui ', # 0x3d +'Liu ', # 0x3e +'Sou ', # 0x3f +'Tao ', # 0x40 +'Ye ', # 0x41 +'Yun ', # 0x42 +'Mo ', # 0x43 +'Tang ', # 0x44 +'Man ', # 0x45 +'Bi ', # 0x46 +'Yu ', # 0x47 +'Xiu ', # 0x48 +'Jin ', # 0x49 +'San ', # 0x4a +'Kui ', # 0x4b +'Zhuan ', # 0x4c +'Shan ', # 0x4d +'Chi ', # 0x4e +'Dan ', # 0x4f +'Yi ', # 0x50 +'Ji ', # 0x51 +'Rao ', # 0x52 +'Cheng ', # 0x53 +'Yong ', # 0x54 +'Tao ', # 0x55 +'Hui ', # 0x56 +'Xiang ', # 0x57 +'Zhan ', # 0x58 +'Fen ', # 0x59 +'Hai ', # 0x5a +'Meng ', # 0x5b +'Yan ', # 0x5c +'Mo ', # 0x5d +'Chan ', # 0x5e +'Xiang ', # 0x5f +'Luo ', # 0x60 +'Zuan ', # 0x61 +'Nang ', # 0x62 +'Shi ', # 0x63 +'Ding ', # 0x64 +'Ji ', # 0x65 +'Tuo ', # 0x66 +'Xing ', # 0x67 +'Tun ', # 0x68 +'Xi ', # 0x69 +'Ren ', # 0x6a +'Yu ', # 0x6b +'Chi ', # 0x6c +'Fan ', # 0x6d +'Yin ', # 0x6e +'Jian ', # 0x6f +'Shi ', # 0x70 +'Bao ', # 0x71 +'Si ', # 0x72 +'Duo ', # 0x73 +'Yi ', # 0x74 +'Er ', # 0x75 +'Rao ', # 0x76 +'Xiang ', # 0x77 +'Jia ', # 0x78 +'Le ', # 0x79 +'Jiao ', # 0x7a +'Yi ', # 0x7b +'Bing ', # 0x7c +'Bo ', # 0x7d +'Dou ', # 0x7e +'E ', # 0x7f +'Yu ', # 0x80 +'Nei ', # 0x81 +'Jun ', # 0x82 +'Guo ', # 0x83 +'Hun ', # 0x84 +'Xian ', # 0x85 +'Guan ', # 0x86 +'Cha ', # 0x87 +'Kui ', # 0x88 +'Gu ', # 0x89 +'Sou ', # 0x8a +'Chan ', # 0x8b +'Ye ', # 0x8c +'Mo ', # 0x8d +'Bo ', # 0x8e +'Liu ', # 0x8f +'Xiu ', # 0x90 +'Jin ', # 0x91 +'Man ', # 0x92 +'San ', # 0x93 +'Zhuan ', # 0x94 +'Nang ', # 0x95 +'Shou ', # 0x96 +'Kui ', # 0x97 +'Guo ', # 0x98 +'Xiang ', # 0x99 +'Fen ', # 0x9a +'Ba ', # 0x9b +'Ni ', # 0x9c +'Bi ', # 0x9d +'Bo ', # 0x9e +'Tu ', # 0x9f +'Han ', # 0xa0 +'Fei ', # 0xa1 +'Jian ', # 0xa2 +'An ', # 0xa3 +'Ai ', # 0xa4 +'Fu ', # 0xa5 +'Xian ', # 0xa6 +'Wen ', # 0xa7 +'Xin ', # 0xa8 +'Fen ', # 0xa9 +'Bin ', # 0xaa +'Xing ', # 0xab +'Ma ', # 0xac +'Yu ', # 0xad +'Feng ', # 0xae +'Han ', # 0xaf +'Di ', # 0xb0 +'Tuo ', # 0xb1 +'Tuo ', # 0xb2 +'Chi ', # 0xb3 +'Xun ', # 0xb4 +'Zhu ', # 0xb5 +'Zhi ', # 0xb6 +'Pei ', # 0xb7 +'Xin ', # 0xb8 +'Ri ', # 0xb9 +'Sa ', # 0xba +'Yin ', # 0xbb +'Wen ', # 0xbc +'Zhi ', # 0xbd +'Dan ', # 0xbe +'Lu ', # 0xbf +'You ', # 0xc0 +'Bo ', # 0xc1 +'Bao ', # 0xc2 +'Kuai ', # 0xc3 +'Tuo ', # 0xc4 +'Yi ', # 0xc5 +'Qu ', # 0xc6 +'[?] ', # 0xc7 +'Qu ', # 0xc8 +'Jiong ', # 0xc9 +'Bo ', # 0xca +'Zhao ', # 0xcb +'Yuan ', # 0xcc +'Peng ', # 0xcd +'Zhou ', # 0xce +'Ju ', # 0xcf +'Zhu ', # 0xd0 +'Nu ', # 0xd1 +'Ju ', # 0xd2 +'Pi ', # 0xd3 +'Zang ', # 0xd4 +'Jia ', # 0xd5 +'Ling ', # 0xd6 +'Zhen ', # 0xd7 +'Tai ', # 0xd8 +'Fu ', # 0xd9 +'Yang ', # 0xda +'Shi ', # 0xdb +'Bi ', # 0xdc +'Tuo ', # 0xdd +'Tuo ', # 0xde +'Si ', # 0xdf +'Liu ', # 0xe0 +'Ma ', # 0xe1 +'Pian ', # 0xe2 +'Tao ', # 0xe3 +'Zhi ', # 0xe4 +'Rong ', # 0xe5 +'Teng ', # 0xe6 +'Dong ', # 0xe7 +'Xun ', # 0xe8 +'Quan ', # 0xe9 +'Shen ', # 0xea +'Jiong ', # 0xeb +'Er ', # 0xec +'Hai ', # 0xed +'Bo ', # 0xee +'Zhu ', # 0xef +'Yin ', # 0xf0 +'Luo ', # 0xf1 +'Shuu ', # 0xf2 +'Dan ', # 0xf3 +'Xie ', # 0xf4 +'Liu ', # 0xf5 +'Ju ', # 0xf6 +'Song ', # 0xf7 +'Qin ', # 0xf8 +'Mang ', # 0xf9 +'Liang ', # 0xfa +'Han ', # 0xfb +'Tu ', # 0xfc +'Xuan ', # 0xfd +'Tui ', # 0xfe +'Jun ', # 0xff +) diff --git a/libs/unidecode/x09a.py b/libs/unidecode/x09a.py new file mode 100644 index 00000000..ed9cd937 --- /dev/null +++ b/libs/unidecode/x09a.py @@ -0,0 +1,258 @@ +data = ( +'E ', # 0x00 +'Cheng ', # 0x01 +'Xin ', # 0x02 +'Ai ', # 0x03 +'Lu ', # 0x04 +'Zhui ', # 0x05 +'Zhou ', # 0x06 +'She ', # 0x07 +'Pian ', # 0x08 +'Kun ', # 0x09 +'Tao ', # 0x0a +'Lai ', # 0x0b +'Zong ', # 0x0c +'Ke ', # 0x0d +'Qi ', # 0x0e +'Qi ', # 0x0f +'Yan ', # 0x10 +'Fei ', # 0x11 +'Sao ', # 0x12 +'Yan ', # 0x13 +'Jie ', # 0x14 +'Yao ', # 0x15 +'Wu ', # 0x16 +'Pian ', # 0x17 +'Cong ', # 0x18 +'Pian ', # 0x19 +'Qian ', # 0x1a +'Fei ', # 0x1b +'Huang ', # 0x1c +'Jian ', # 0x1d +'Huo ', # 0x1e +'Yu ', # 0x1f +'Ti ', # 0x20 +'Quan ', # 0x21 +'Xia ', # 0x22 +'Zong ', # 0x23 +'Kui ', # 0x24 +'Rou ', # 0x25 +'Si ', # 0x26 +'Gua ', # 0x27 +'Tuo ', # 0x28 +'Kui ', # 0x29 +'Sou ', # 0x2a +'Qian ', # 0x2b +'Cheng ', # 0x2c +'Zhi ', # 0x2d +'Liu ', # 0x2e +'Pang ', # 0x2f +'Teng ', # 0x30 +'Xi ', # 0x31 +'Cao ', # 0x32 +'Du ', # 0x33 +'Yan ', # 0x34 +'Yuan ', # 0x35 +'Zou ', # 0x36 +'Sao ', # 0x37 +'Shan ', # 0x38 +'Li ', # 0x39 +'Zhi ', # 0x3a +'Shuang ', # 0x3b +'Lu ', # 0x3c +'Xi ', # 0x3d +'Luo ', # 0x3e +'Zhang ', # 0x3f +'Mo ', # 0x40 +'Ao ', # 0x41 +'Can ', # 0x42 +'Piao ', # 0x43 +'Cong ', # 0x44 +'Qu ', # 0x45 +'Bi ', # 0x46 +'Zhi ', # 0x47 +'Yu ', # 0x48 +'Xu ', # 0x49 +'Hua ', # 0x4a +'Bo ', # 0x4b +'Su ', # 0x4c +'Xiao ', # 0x4d +'Lin ', # 0x4e +'Chan ', # 0x4f +'Dun ', # 0x50 +'Liu ', # 0x51 +'Tuo ', # 0x52 +'Zeng ', # 0x53 +'Tan ', # 0x54 +'Jiao ', # 0x55 +'Tie ', # 0x56 +'Yan ', # 0x57 +'Luo ', # 0x58 +'Zhan ', # 0x59 +'Jing ', # 0x5a +'Yi ', # 0x5b +'Ye ', # 0x5c +'Tuo ', # 0x5d +'Bin ', # 0x5e +'Zou ', # 0x5f +'Yan ', # 0x60 +'Peng ', # 0x61 +'Lu ', # 0x62 +'Teng ', # 0x63 +'Xiang ', # 0x64 +'Ji ', # 0x65 +'Shuang ', # 0x66 +'Ju ', # 0x67 +'Xi ', # 0x68 +'Huan ', # 0x69 +'Li ', # 0x6a +'Biao ', # 0x6b +'Ma ', # 0x6c +'Yu ', # 0x6d +'Tuo ', # 0x6e +'Xun ', # 0x6f +'Chi ', # 0x70 +'Qu ', # 0x71 +'Ri ', # 0x72 +'Bo ', # 0x73 +'Lu ', # 0x74 +'Zang ', # 0x75 +'Shi ', # 0x76 +'Si ', # 0x77 +'Fu ', # 0x78 +'Ju ', # 0x79 +'Zou ', # 0x7a +'Zhu ', # 0x7b +'Tuo ', # 0x7c +'Nu ', # 0x7d +'Jia ', # 0x7e +'Yi ', # 0x7f +'Tai ', # 0x80 +'Xiao ', # 0x81 +'Ma ', # 0x82 +'Yin ', # 0x83 +'Jiao ', # 0x84 +'Hua ', # 0x85 +'Luo ', # 0x86 +'Hai ', # 0x87 +'Pian ', # 0x88 +'Biao ', # 0x89 +'Li ', # 0x8a +'Cheng ', # 0x8b +'Yan ', # 0x8c +'Xin ', # 0x8d +'Qin ', # 0x8e +'Jun ', # 0x8f +'Qi ', # 0x90 +'Qi ', # 0x91 +'Ke ', # 0x92 +'Zhui ', # 0x93 +'Zong ', # 0x94 +'Su ', # 0x95 +'Can ', # 0x96 +'Pian ', # 0x97 +'Zhi ', # 0x98 +'Kui ', # 0x99 +'Sao ', # 0x9a +'Wu ', # 0x9b +'Ao ', # 0x9c +'Liu ', # 0x9d +'Qian ', # 0x9e +'Shan ', # 0x9f +'Piao ', # 0xa0 +'Luo ', # 0xa1 +'Cong ', # 0xa2 +'Chan ', # 0xa3 +'Zou ', # 0xa4 +'Ji ', # 0xa5 +'Shuang ', # 0xa6 +'Xiang ', # 0xa7 +'Gu ', # 0xa8 +'Wei ', # 0xa9 +'Wei ', # 0xaa +'Wei ', # 0xab +'Yu ', # 0xac +'Gan ', # 0xad +'Yi ', # 0xae +'Ang ', # 0xaf +'Tou ', # 0xb0 +'Xie ', # 0xb1 +'Bao ', # 0xb2 +'Bi ', # 0xb3 +'Chi ', # 0xb4 +'Ti ', # 0xb5 +'Di ', # 0xb6 +'Ku ', # 0xb7 +'Hai ', # 0xb8 +'Qiao ', # 0xb9 +'Gou ', # 0xba +'Kua ', # 0xbb +'Ge ', # 0xbc +'Tui ', # 0xbd +'Geng ', # 0xbe +'Pian ', # 0xbf +'Bi ', # 0xc0 +'Ke ', # 0xc1 +'Ka ', # 0xc2 +'Yu ', # 0xc3 +'Sui ', # 0xc4 +'Lou ', # 0xc5 +'Bo ', # 0xc6 +'Xiao ', # 0xc7 +'Pang ', # 0xc8 +'Bo ', # 0xc9 +'Ci ', # 0xca +'Kuan ', # 0xcb +'Bin ', # 0xcc +'Mo ', # 0xcd +'Liao ', # 0xce +'Lou ', # 0xcf +'Nao ', # 0xd0 +'Du ', # 0xd1 +'Zang ', # 0xd2 +'Sui ', # 0xd3 +'Ti ', # 0xd4 +'Bin ', # 0xd5 +'Kuan ', # 0xd6 +'Lu ', # 0xd7 +'Gao ', # 0xd8 +'Gao ', # 0xd9 +'Qiao ', # 0xda +'Kao ', # 0xdb +'Qiao ', # 0xdc +'Lao ', # 0xdd +'Zao ', # 0xde +'Biao ', # 0xdf +'Kun ', # 0xe0 +'Kun ', # 0xe1 +'Ti ', # 0xe2 +'Fang ', # 0xe3 +'Xiu ', # 0xe4 +'Ran ', # 0xe5 +'Mao ', # 0xe6 +'Dan ', # 0xe7 +'Kun ', # 0xe8 +'Bin ', # 0xe9 +'Fa ', # 0xea +'Tiao ', # 0xeb +'Peng ', # 0xec +'Zi ', # 0xed +'Fa ', # 0xee +'Ran ', # 0xef +'Ti ', # 0xf0 +'Pao ', # 0xf1 +'Pi ', # 0xf2 +'Mao ', # 0xf3 +'Fu ', # 0xf4 +'Er ', # 0xf5 +'Rong ', # 0xf6 +'Qu ', # 0xf7 +'Gong ', # 0xf8 +'Xiu ', # 0xf9 +'Gua ', # 0xfa +'Ji ', # 0xfb +'Peng ', # 0xfc +'Zhua ', # 0xfd +'Shao ', # 0xfe +'Sha ', # 0xff +) diff --git a/libs/unidecode/x09b.py b/libs/unidecode/x09b.py new file mode 100644 index 00000000..7fd0a2db --- /dev/null +++ b/libs/unidecode/x09b.py @@ -0,0 +1,258 @@ +data = ( +'Ti ', # 0x00 +'Li ', # 0x01 +'Bin ', # 0x02 +'Zong ', # 0x03 +'Ti ', # 0x04 +'Peng ', # 0x05 +'Song ', # 0x06 +'Zheng ', # 0x07 +'Quan ', # 0x08 +'Zong ', # 0x09 +'Shun ', # 0x0a +'Jian ', # 0x0b +'Duo ', # 0x0c +'Hu ', # 0x0d +'La ', # 0x0e +'Jiu ', # 0x0f +'Qi ', # 0x10 +'Lian ', # 0x11 +'Zhen ', # 0x12 +'Bin ', # 0x13 +'Peng ', # 0x14 +'Mo ', # 0x15 +'San ', # 0x16 +'Man ', # 0x17 +'Man ', # 0x18 +'Seng ', # 0x19 +'Xu ', # 0x1a +'Lie ', # 0x1b +'Qian ', # 0x1c +'Qian ', # 0x1d +'Nong ', # 0x1e +'Huan ', # 0x1f +'Kuai ', # 0x20 +'Ning ', # 0x21 +'Bin ', # 0x22 +'Lie ', # 0x23 +'Rang ', # 0x24 +'Dou ', # 0x25 +'Dou ', # 0x26 +'Nao ', # 0x27 +'Hong ', # 0x28 +'Xi ', # 0x29 +'Dou ', # 0x2a +'Han ', # 0x2b +'Dou ', # 0x2c +'Dou ', # 0x2d +'Jiu ', # 0x2e +'Chang ', # 0x2f +'Yu ', # 0x30 +'Yu ', # 0x31 +'Li ', # 0x32 +'Juan ', # 0x33 +'Fu ', # 0x34 +'Qian ', # 0x35 +'Gui ', # 0x36 +'Zong ', # 0x37 +'Liu ', # 0x38 +'Gui ', # 0x39 +'Shang ', # 0x3a +'Yu ', # 0x3b +'Gui ', # 0x3c +'Mei ', # 0x3d +'Ji ', # 0x3e +'Qi ', # 0x3f +'Jie ', # 0x40 +'Kui ', # 0x41 +'Hun ', # 0x42 +'Ba ', # 0x43 +'Po ', # 0x44 +'Mei ', # 0x45 +'Xu ', # 0x46 +'Yan ', # 0x47 +'Xiao ', # 0x48 +'Liang ', # 0x49 +'Yu ', # 0x4a +'Tui ', # 0x4b +'Qi ', # 0x4c +'Wang ', # 0x4d +'Liang ', # 0x4e +'Wei ', # 0x4f +'Jian ', # 0x50 +'Chi ', # 0x51 +'Piao ', # 0x52 +'Bi ', # 0x53 +'Mo ', # 0x54 +'Ji ', # 0x55 +'Xu ', # 0x56 +'Chou ', # 0x57 +'Yan ', # 0x58 +'Zhan ', # 0x59 +'Yu ', # 0x5a +'Dao ', # 0x5b +'Ren ', # 0x5c +'Ji ', # 0x5d +'Eri ', # 0x5e +'Gong ', # 0x5f +'Tuo ', # 0x60 +'Diao ', # 0x61 +'Ji ', # 0x62 +'Xu ', # 0x63 +'E ', # 0x64 +'E ', # 0x65 +'Sha ', # 0x66 +'Hang ', # 0x67 +'Tun ', # 0x68 +'Mo ', # 0x69 +'Jie ', # 0x6a +'Shen ', # 0x6b +'Fan ', # 0x6c +'Yuan ', # 0x6d +'Bi ', # 0x6e +'Lu ', # 0x6f +'Wen ', # 0x70 +'Hu ', # 0x71 +'Lu ', # 0x72 +'Za ', # 0x73 +'Fang ', # 0x74 +'Fen ', # 0x75 +'Na ', # 0x76 +'You ', # 0x77 +'Namazu ', # 0x78 +'Todo ', # 0x79 +'He ', # 0x7a +'Xia ', # 0x7b +'Qu ', # 0x7c +'Han ', # 0x7d +'Pi ', # 0x7e +'Ling ', # 0x7f +'Tuo ', # 0x80 +'Bo ', # 0x81 +'Qiu ', # 0x82 +'Ping ', # 0x83 +'Fu ', # 0x84 +'Bi ', # 0x85 +'Ji ', # 0x86 +'Wei ', # 0x87 +'Ju ', # 0x88 +'Diao ', # 0x89 +'Bo ', # 0x8a +'You ', # 0x8b +'Gun ', # 0x8c +'Pi ', # 0x8d +'Nian ', # 0x8e +'Xing ', # 0x8f +'Tai ', # 0x90 +'Bao ', # 0x91 +'Fu ', # 0x92 +'Zha ', # 0x93 +'Ju ', # 0x94 +'Gu ', # 0x95 +'Kajika ', # 0x96 +'Tong ', # 0x97 +'[?] ', # 0x98 +'Ta ', # 0x99 +'Jie ', # 0x9a +'Shu ', # 0x9b +'Hou ', # 0x9c +'Xiang ', # 0x9d +'Er ', # 0x9e +'An ', # 0x9f +'Wei ', # 0xa0 +'Tiao ', # 0xa1 +'Zhu ', # 0xa2 +'Yin ', # 0xa3 +'Lie ', # 0xa4 +'Luo ', # 0xa5 +'Tong ', # 0xa6 +'Yi ', # 0xa7 +'Qi ', # 0xa8 +'Bing ', # 0xa9 +'Wei ', # 0xaa +'Jiao ', # 0xab +'Bu ', # 0xac +'Gui ', # 0xad +'Xian ', # 0xae +'Ge ', # 0xaf +'Hui ', # 0xb0 +'Bora ', # 0xb1 +'Mate ', # 0xb2 +'Kao ', # 0xb3 +'Gori ', # 0xb4 +'Duo ', # 0xb5 +'Jun ', # 0xb6 +'Ti ', # 0xb7 +'Man ', # 0xb8 +'Xiao ', # 0xb9 +'Za ', # 0xba +'Sha ', # 0xbb +'Qin ', # 0xbc +'Yu ', # 0xbd +'Nei ', # 0xbe +'Zhe ', # 0xbf +'Gun ', # 0xc0 +'Geng ', # 0xc1 +'Su ', # 0xc2 +'Wu ', # 0xc3 +'Qiu ', # 0xc4 +'Ting ', # 0xc5 +'Fu ', # 0xc6 +'Wan ', # 0xc7 +'You ', # 0xc8 +'Li ', # 0xc9 +'Sha ', # 0xca +'Sha ', # 0xcb +'Gao ', # 0xcc +'Meng ', # 0xcd +'Ugui ', # 0xce +'Asari ', # 0xcf +'Subashiri ', # 0xd0 +'Kazunoko ', # 0xd1 +'Yong ', # 0xd2 +'Ni ', # 0xd3 +'Zi ', # 0xd4 +'Qi ', # 0xd5 +'Qing ', # 0xd6 +'Xiang ', # 0xd7 +'Nei ', # 0xd8 +'Chun ', # 0xd9 +'Ji ', # 0xda +'Diao ', # 0xdb +'Qie ', # 0xdc +'Gu ', # 0xdd +'Zhou ', # 0xde +'Dong ', # 0xdf +'Lai ', # 0xe0 +'Fei ', # 0xe1 +'Ni ', # 0xe2 +'Yi ', # 0xe3 +'Kun ', # 0xe4 +'Lu ', # 0xe5 +'Jiu ', # 0xe6 +'Chang ', # 0xe7 +'Jing ', # 0xe8 +'Lun ', # 0xe9 +'Ling ', # 0xea +'Zou ', # 0xeb +'Li ', # 0xec +'Meng ', # 0xed +'Zong ', # 0xee +'Zhi ', # 0xef +'Nian ', # 0xf0 +'Shachi ', # 0xf1 +'Dojou ', # 0xf2 +'Sukesou ', # 0xf3 +'Shi ', # 0xf4 +'Shen ', # 0xf5 +'Hun ', # 0xf6 +'Shi ', # 0xf7 +'Hou ', # 0xf8 +'Xing ', # 0xf9 +'Zhu ', # 0xfa +'La ', # 0xfb +'Zong ', # 0xfc +'Ji ', # 0xfd +'Bian ', # 0xfe +'Bian ', # 0xff +) diff --git a/libs/unidecode/x09c.py b/libs/unidecode/x09c.py new file mode 100644 index 00000000..e7f7937f --- /dev/null +++ b/libs/unidecode/x09c.py @@ -0,0 +1,258 @@ +data = ( +'Huan ', # 0x00 +'Quan ', # 0x01 +'Ze ', # 0x02 +'Wei ', # 0x03 +'Wei ', # 0x04 +'Yu ', # 0x05 +'Qun ', # 0x06 +'Rou ', # 0x07 +'Die ', # 0x08 +'Huang ', # 0x09 +'Lian ', # 0x0a +'Yan ', # 0x0b +'Qiu ', # 0x0c +'Qiu ', # 0x0d +'Jian ', # 0x0e +'Bi ', # 0x0f +'E ', # 0x10 +'Yang ', # 0x11 +'Fu ', # 0x12 +'Sai ', # 0x13 +'Jian ', # 0x14 +'Xia ', # 0x15 +'Tuo ', # 0x16 +'Hu ', # 0x17 +'Muroaji ', # 0x18 +'Ruo ', # 0x19 +'Haraka ', # 0x1a +'Wen ', # 0x1b +'Jian ', # 0x1c +'Hao ', # 0x1d +'Wu ', # 0x1e +'Fang ', # 0x1f +'Sao ', # 0x20 +'Liu ', # 0x21 +'Ma ', # 0x22 +'Shi ', # 0x23 +'Shi ', # 0x24 +'Yin ', # 0x25 +'Z ', # 0x26 +'Teng ', # 0x27 +'Ta ', # 0x28 +'Yao ', # 0x29 +'Ge ', # 0x2a +'Rong ', # 0x2b +'Qian ', # 0x2c +'Qi ', # 0x2d +'Wen ', # 0x2e +'Ruo ', # 0x2f +'Hatahata ', # 0x30 +'Lian ', # 0x31 +'Ao ', # 0x32 +'Le ', # 0x33 +'Hui ', # 0x34 +'Min ', # 0x35 +'Ji ', # 0x36 +'Tiao ', # 0x37 +'Qu ', # 0x38 +'Jian ', # 0x39 +'Sao ', # 0x3a +'Man ', # 0x3b +'Xi ', # 0x3c +'Qiu ', # 0x3d +'Biao ', # 0x3e +'Ji ', # 0x3f +'Ji ', # 0x40 +'Zhu ', # 0x41 +'Jiang ', # 0x42 +'Qiu ', # 0x43 +'Zhuan ', # 0x44 +'Yong ', # 0x45 +'Zhang ', # 0x46 +'Kang ', # 0x47 +'Xue ', # 0x48 +'Bie ', # 0x49 +'Jue ', # 0x4a +'Qu ', # 0x4b +'Xiang ', # 0x4c +'Bo ', # 0x4d +'Jiao ', # 0x4e +'Xun ', # 0x4f +'Su ', # 0x50 +'Huang ', # 0x51 +'Zun ', # 0x52 +'Shan ', # 0x53 +'Shan ', # 0x54 +'Fan ', # 0x55 +'Jue ', # 0x56 +'Lin ', # 0x57 +'Xun ', # 0x58 +'Miao ', # 0x59 +'Xi ', # 0x5a +'Eso ', # 0x5b +'Kyou ', # 0x5c +'Fen ', # 0x5d +'Guan ', # 0x5e +'Hou ', # 0x5f +'Kuai ', # 0x60 +'Zei ', # 0x61 +'Sao ', # 0x62 +'Zhan ', # 0x63 +'Gan ', # 0x64 +'Gui ', # 0x65 +'Sheng ', # 0x66 +'Li ', # 0x67 +'Chang ', # 0x68 +'Hatahata ', # 0x69 +'Shiira ', # 0x6a +'Mutsu ', # 0x6b +'Ru ', # 0x6c +'Ji ', # 0x6d +'Xu ', # 0x6e +'Huo ', # 0x6f +'Shiira ', # 0x70 +'Li ', # 0x71 +'Lie ', # 0x72 +'Li ', # 0x73 +'Mie ', # 0x74 +'Zhen ', # 0x75 +'Xiang ', # 0x76 +'E ', # 0x77 +'Lu ', # 0x78 +'Guan ', # 0x79 +'Li ', # 0x7a +'Xian ', # 0x7b +'Yu ', # 0x7c +'Dao ', # 0x7d +'Ji ', # 0x7e +'You ', # 0x7f +'Tun ', # 0x80 +'Lu ', # 0x81 +'Fang ', # 0x82 +'Ba ', # 0x83 +'He ', # 0x84 +'Bo ', # 0x85 +'Ping ', # 0x86 +'Nian ', # 0x87 +'Lu ', # 0x88 +'You ', # 0x89 +'Zha ', # 0x8a +'Fu ', # 0x8b +'Bo ', # 0x8c +'Bao ', # 0x8d +'Hou ', # 0x8e +'Pi ', # 0x8f +'Tai ', # 0x90 +'Gui ', # 0x91 +'Jie ', # 0x92 +'Kao ', # 0x93 +'Wei ', # 0x94 +'Er ', # 0x95 +'Tong ', # 0x96 +'Ze ', # 0x97 +'Hou ', # 0x98 +'Kuai ', # 0x99 +'Ji ', # 0x9a +'Jiao ', # 0x9b +'Xian ', # 0x9c +'Za ', # 0x9d +'Xiang ', # 0x9e +'Xun ', # 0x9f +'Geng ', # 0xa0 +'Li ', # 0xa1 +'Lian ', # 0xa2 +'Jian ', # 0xa3 +'Li ', # 0xa4 +'Shi ', # 0xa5 +'Tiao ', # 0xa6 +'Gun ', # 0xa7 +'Sha ', # 0xa8 +'Wan ', # 0xa9 +'Jun ', # 0xaa +'Ji ', # 0xab +'Yong ', # 0xac +'Qing ', # 0xad +'Ling ', # 0xae +'Qi ', # 0xaf +'Zou ', # 0xb0 +'Fei ', # 0xb1 +'Kun ', # 0xb2 +'Chang ', # 0xb3 +'Gu ', # 0xb4 +'Ni ', # 0xb5 +'Nian ', # 0xb6 +'Diao ', # 0xb7 +'Jing ', # 0xb8 +'Shen ', # 0xb9 +'Shi ', # 0xba +'Zi ', # 0xbb +'Fen ', # 0xbc +'Die ', # 0xbd +'Bi ', # 0xbe +'Chang ', # 0xbf +'Shi ', # 0xc0 +'Wen ', # 0xc1 +'Wei ', # 0xc2 +'Sai ', # 0xc3 +'E ', # 0xc4 +'Qiu ', # 0xc5 +'Fu ', # 0xc6 +'Huang ', # 0xc7 +'Quan ', # 0xc8 +'Jiang ', # 0xc9 +'Bian ', # 0xca +'Sao ', # 0xcb +'Ao ', # 0xcc +'Qi ', # 0xcd +'Ta ', # 0xce +'Yin ', # 0xcf +'Yao ', # 0xd0 +'Fang ', # 0xd1 +'Jian ', # 0xd2 +'Le ', # 0xd3 +'Biao ', # 0xd4 +'Xue ', # 0xd5 +'Bie ', # 0xd6 +'Man ', # 0xd7 +'Min ', # 0xd8 +'Yong ', # 0xd9 +'Wei ', # 0xda +'Xi ', # 0xdb +'Jue ', # 0xdc +'Shan ', # 0xdd +'Lin ', # 0xde +'Zun ', # 0xdf +'Huo ', # 0xe0 +'Gan ', # 0xe1 +'Li ', # 0xe2 +'Zhan ', # 0xe3 +'Guan ', # 0xe4 +'Niao ', # 0xe5 +'Yi ', # 0xe6 +'Fu ', # 0xe7 +'Li ', # 0xe8 +'Jiu ', # 0xe9 +'Bu ', # 0xea +'Yan ', # 0xeb +'Fu ', # 0xec +'Diao ', # 0xed +'Ji ', # 0xee +'Feng ', # 0xef +'Nio ', # 0xf0 +'Gan ', # 0xf1 +'Shi ', # 0xf2 +'Feng ', # 0xf3 +'Ming ', # 0xf4 +'Bao ', # 0xf5 +'Yuan ', # 0xf6 +'Zhi ', # 0xf7 +'Hu ', # 0xf8 +'Qin ', # 0xf9 +'Fu ', # 0xfa +'Fen ', # 0xfb +'Wen ', # 0xfc +'Jian ', # 0xfd +'Shi ', # 0xfe +'Yu ', # 0xff +) diff --git a/libs/unidecode/x09d.py b/libs/unidecode/x09d.py new file mode 100644 index 00000000..99d5859c --- /dev/null +++ b/libs/unidecode/x09d.py @@ -0,0 +1,258 @@ +data = ( +'Fou ', # 0x00 +'Yiao ', # 0x01 +'Jue ', # 0x02 +'Jue ', # 0x03 +'Pi ', # 0x04 +'Huan ', # 0x05 +'Zhen ', # 0x06 +'Bao ', # 0x07 +'Yan ', # 0x08 +'Ya ', # 0x09 +'Zheng ', # 0x0a +'Fang ', # 0x0b +'Feng ', # 0x0c +'Wen ', # 0x0d +'Ou ', # 0x0e +'Te ', # 0x0f +'Jia ', # 0x10 +'Nu ', # 0x11 +'Ling ', # 0x12 +'Mie ', # 0x13 +'Fu ', # 0x14 +'Tuo ', # 0x15 +'Wen ', # 0x16 +'Li ', # 0x17 +'Bian ', # 0x18 +'Zhi ', # 0x19 +'Ge ', # 0x1a +'Yuan ', # 0x1b +'Zi ', # 0x1c +'Qu ', # 0x1d +'Xiao ', # 0x1e +'Zhi ', # 0x1f +'Dan ', # 0x20 +'Ju ', # 0x21 +'You ', # 0x22 +'Gu ', # 0x23 +'Zhong ', # 0x24 +'Yu ', # 0x25 +'Yang ', # 0x26 +'Rong ', # 0x27 +'Ya ', # 0x28 +'Tie ', # 0x29 +'Yu ', # 0x2a +'Shigi ', # 0x2b +'Ying ', # 0x2c +'Zhui ', # 0x2d +'Wu ', # 0x2e +'Er ', # 0x2f +'Gua ', # 0x30 +'Ai ', # 0x31 +'Zhi ', # 0x32 +'Yan ', # 0x33 +'Heng ', # 0x34 +'Jiao ', # 0x35 +'Ji ', # 0x36 +'Lie ', # 0x37 +'Zhu ', # 0x38 +'Ren ', # 0x39 +'Yi ', # 0x3a +'Hong ', # 0x3b +'Luo ', # 0x3c +'Ru ', # 0x3d +'Mou ', # 0x3e +'Ge ', # 0x3f +'Ren ', # 0x40 +'Jiao ', # 0x41 +'Xiu ', # 0x42 +'Zhou ', # 0x43 +'Zhi ', # 0x44 +'Luo ', # 0x45 +'Chidori ', # 0x46 +'Toki ', # 0x47 +'Ten ', # 0x48 +'Luan ', # 0x49 +'Jia ', # 0x4a +'Ji ', # 0x4b +'Yu ', # 0x4c +'Huan ', # 0x4d +'Tuo ', # 0x4e +'Bu ', # 0x4f +'Wu ', # 0x50 +'Juan ', # 0x51 +'Yu ', # 0x52 +'Bo ', # 0x53 +'Xun ', # 0x54 +'Xun ', # 0x55 +'Bi ', # 0x56 +'Xi ', # 0x57 +'Jun ', # 0x58 +'Ju ', # 0x59 +'Tu ', # 0x5a +'Jing ', # 0x5b +'Ti ', # 0x5c +'E ', # 0x5d +'E ', # 0x5e +'Kuang ', # 0x5f +'Hu ', # 0x60 +'Wu ', # 0x61 +'Shen ', # 0x62 +'Lai ', # 0x63 +'Ikaruga ', # 0x64 +'Kakesu ', # 0x65 +'Lu ', # 0x66 +'Ping ', # 0x67 +'Shu ', # 0x68 +'Fu ', # 0x69 +'An ', # 0x6a +'Zhao ', # 0x6b +'Peng ', # 0x6c +'Qin ', # 0x6d +'Qian ', # 0x6e +'Bei ', # 0x6f +'Diao ', # 0x70 +'Lu ', # 0x71 +'Que ', # 0x72 +'Jian ', # 0x73 +'Ju ', # 0x74 +'Tu ', # 0x75 +'Ya ', # 0x76 +'Yuan ', # 0x77 +'Qi ', # 0x78 +'Li ', # 0x79 +'Ye ', # 0x7a +'Zhui ', # 0x7b +'Kong ', # 0x7c +'Zhui ', # 0x7d +'Kun ', # 0x7e +'Sheng ', # 0x7f +'Qi ', # 0x80 +'Jing ', # 0x81 +'Yi ', # 0x82 +'Yi ', # 0x83 +'Jing ', # 0x84 +'Zi ', # 0x85 +'Lai ', # 0x86 +'Dong ', # 0x87 +'Qi ', # 0x88 +'Chun ', # 0x89 +'Geng ', # 0x8a +'Ju ', # 0x8b +'Qu ', # 0x8c +'Isuka ', # 0x8d +'Kikuitadaki ', # 0x8e +'Ji ', # 0x8f +'Shu ', # 0x90 +'[?] ', # 0x91 +'Chi ', # 0x92 +'Miao ', # 0x93 +'Rou ', # 0x94 +'An ', # 0x95 +'Qiu ', # 0x96 +'Ti ', # 0x97 +'Hu ', # 0x98 +'Ti ', # 0x99 +'E ', # 0x9a +'Jie ', # 0x9b +'Mao ', # 0x9c +'Fu ', # 0x9d +'Chun ', # 0x9e +'Tu ', # 0x9f +'Yan ', # 0xa0 +'He ', # 0xa1 +'Yuan ', # 0xa2 +'Pian ', # 0xa3 +'Yun ', # 0xa4 +'Mei ', # 0xa5 +'Hu ', # 0xa6 +'Ying ', # 0xa7 +'Dun ', # 0xa8 +'Mu ', # 0xa9 +'Ju ', # 0xaa +'Tsugumi ', # 0xab +'Cang ', # 0xac +'Fang ', # 0xad +'Gu ', # 0xae +'Ying ', # 0xaf +'Yuan ', # 0xb0 +'Xuan ', # 0xb1 +'Weng ', # 0xb2 +'Shi ', # 0xb3 +'He ', # 0xb4 +'Chu ', # 0xb5 +'Tang ', # 0xb6 +'Xia ', # 0xb7 +'Ruo ', # 0xb8 +'Liu ', # 0xb9 +'Ji ', # 0xba +'Gu ', # 0xbb +'Jian ', # 0xbc +'Zhun ', # 0xbd +'Han ', # 0xbe +'Zi ', # 0xbf +'Zi ', # 0xc0 +'Ni ', # 0xc1 +'Yao ', # 0xc2 +'Yan ', # 0xc3 +'Ji ', # 0xc4 +'Li ', # 0xc5 +'Tian ', # 0xc6 +'Kou ', # 0xc7 +'Ti ', # 0xc8 +'Ti ', # 0xc9 +'Ni ', # 0xca +'Tu ', # 0xcb +'Ma ', # 0xcc +'Jiao ', # 0xcd +'Gao ', # 0xce +'Tian ', # 0xcf +'Chen ', # 0xd0 +'Li ', # 0xd1 +'Zhuan ', # 0xd2 +'Zhe ', # 0xd3 +'Ao ', # 0xd4 +'Yao ', # 0xd5 +'Yi ', # 0xd6 +'Ou ', # 0xd7 +'Chi ', # 0xd8 +'Zhi ', # 0xd9 +'Liao ', # 0xda +'Rong ', # 0xdb +'Lou ', # 0xdc +'Bi ', # 0xdd +'Shuang ', # 0xde +'Zhuo ', # 0xdf +'Yu ', # 0xe0 +'Wu ', # 0xe1 +'Jue ', # 0xe2 +'Yin ', # 0xe3 +'Quan ', # 0xe4 +'Si ', # 0xe5 +'Jiao ', # 0xe6 +'Yi ', # 0xe7 +'Hua ', # 0xe8 +'Bi ', # 0xe9 +'Ying ', # 0xea +'Su ', # 0xeb +'Huang ', # 0xec +'Fan ', # 0xed +'Jiao ', # 0xee +'Liao ', # 0xef +'Yan ', # 0xf0 +'Kao ', # 0xf1 +'Jiu ', # 0xf2 +'Xian ', # 0xf3 +'Xian ', # 0xf4 +'Tu ', # 0xf5 +'Mai ', # 0xf6 +'Zun ', # 0xf7 +'Yu ', # 0xf8 +'Ying ', # 0xf9 +'Lu ', # 0xfa +'Tuan ', # 0xfb +'Xian ', # 0xfc +'Xue ', # 0xfd +'Yi ', # 0xfe +'Pi ', # 0xff +) diff --git a/libs/unidecode/x09e.py b/libs/unidecode/x09e.py new file mode 100644 index 00000000..8a392a23 --- /dev/null +++ b/libs/unidecode/x09e.py @@ -0,0 +1,258 @@ +data = ( +'Shu ', # 0x00 +'Luo ', # 0x01 +'Qi ', # 0x02 +'Yi ', # 0x03 +'Ji ', # 0x04 +'Zhe ', # 0x05 +'Yu ', # 0x06 +'Zhan ', # 0x07 +'Ye ', # 0x08 +'Yang ', # 0x09 +'Pi ', # 0x0a +'Ning ', # 0x0b +'Huo ', # 0x0c +'Mi ', # 0x0d +'Ying ', # 0x0e +'Meng ', # 0x0f +'Di ', # 0x10 +'Yue ', # 0x11 +'Yu ', # 0x12 +'Lei ', # 0x13 +'Bao ', # 0x14 +'Lu ', # 0x15 +'He ', # 0x16 +'Long ', # 0x17 +'Shuang ', # 0x18 +'Yue ', # 0x19 +'Ying ', # 0x1a +'Guan ', # 0x1b +'Qu ', # 0x1c +'Li ', # 0x1d +'Luan ', # 0x1e +'Niao ', # 0x1f +'Jiu ', # 0x20 +'Ji ', # 0x21 +'Yuan ', # 0x22 +'Ming ', # 0x23 +'Shi ', # 0x24 +'Ou ', # 0x25 +'Ya ', # 0x26 +'Cang ', # 0x27 +'Bao ', # 0x28 +'Zhen ', # 0x29 +'Gu ', # 0x2a +'Dong ', # 0x2b +'Lu ', # 0x2c +'Ya ', # 0x2d +'Xiao ', # 0x2e +'Yang ', # 0x2f +'Ling ', # 0x30 +'Zhi ', # 0x31 +'Qu ', # 0x32 +'Yuan ', # 0x33 +'Xue ', # 0x34 +'Tuo ', # 0x35 +'Si ', # 0x36 +'Zhi ', # 0x37 +'Er ', # 0x38 +'Gua ', # 0x39 +'Xiu ', # 0x3a +'Heng ', # 0x3b +'Zhou ', # 0x3c +'Ge ', # 0x3d +'Luan ', # 0x3e +'Hong ', # 0x3f +'Wu ', # 0x40 +'Bo ', # 0x41 +'Li ', # 0x42 +'Juan ', # 0x43 +'Hu ', # 0x44 +'E ', # 0x45 +'Yu ', # 0x46 +'Xian ', # 0x47 +'Ti ', # 0x48 +'Wu ', # 0x49 +'Que ', # 0x4a +'Miao ', # 0x4b +'An ', # 0x4c +'Kun ', # 0x4d +'Bei ', # 0x4e +'Peng ', # 0x4f +'Qian ', # 0x50 +'Chun ', # 0x51 +'Geng ', # 0x52 +'Yuan ', # 0x53 +'Su ', # 0x54 +'Hu ', # 0x55 +'He ', # 0x56 +'E ', # 0x57 +'Gu ', # 0x58 +'Qiu ', # 0x59 +'Zi ', # 0x5a +'Mei ', # 0x5b +'Mu ', # 0x5c +'Ni ', # 0x5d +'Yao ', # 0x5e +'Weng ', # 0x5f +'Liu ', # 0x60 +'Ji ', # 0x61 +'Ni ', # 0x62 +'Jian ', # 0x63 +'He ', # 0x64 +'Yi ', # 0x65 +'Ying ', # 0x66 +'Zhe ', # 0x67 +'Liao ', # 0x68 +'Liao ', # 0x69 +'Jiao ', # 0x6a +'Jiu ', # 0x6b +'Yu ', # 0x6c +'Lu ', # 0x6d +'Xuan ', # 0x6e +'Zhan ', # 0x6f +'Ying ', # 0x70 +'Huo ', # 0x71 +'Meng ', # 0x72 +'Guan ', # 0x73 +'Shuang ', # 0x74 +'Lu ', # 0x75 +'Jin ', # 0x76 +'Ling ', # 0x77 +'Jian ', # 0x78 +'Xian ', # 0x79 +'Cuo ', # 0x7a +'Jian ', # 0x7b +'Jian ', # 0x7c +'Yan ', # 0x7d +'Cuo ', # 0x7e +'Lu ', # 0x7f +'You ', # 0x80 +'Cu ', # 0x81 +'Ji ', # 0x82 +'Biao ', # 0x83 +'Cu ', # 0x84 +'Biao ', # 0x85 +'Zhu ', # 0x86 +'Jun ', # 0x87 +'Zhu ', # 0x88 +'Jian ', # 0x89 +'Mi ', # 0x8a +'Mi ', # 0x8b +'Wu ', # 0x8c +'Liu ', # 0x8d +'Chen ', # 0x8e +'Jun ', # 0x8f +'Lin ', # 0x90 +'Ni ', # 0x91 +'Qi ', # 0x92 +'Lu ', # 0x93 +'Jiu ', # 0x94 +'Jun ', # 0x95 +'Jing ', # 0x96 +'Li ', # 0x97 +'Xiang ', # 0x98 +'Yan ', # 0x99 +'Jia ', # 0x9a +'Mi ', # 0x9b +'Li ', # 0x9c +'She ', # 0x9d +'Zhang ', # 0x9e +'Lin ', # 0x9f +'Jing ', # 0xa0 +'Ji ', # 0xa1 +'Ling ', # 0xa2 +'Yan ', # 0xa3 +'Cu ', # 0xa4 +'Mai ', # 0xa5 +'Mai ', # 0xa6 +'Ge ', # 0xa7 +'Chao ', # 0xa8 +'Fu ', # 0xa9 +'Mian ', # 0xaa +'Mian ', # 0xab +'Fu ', # 0xac +'Pao ', # 0xad +'Qu ', # 0xae +'Qu ', # 0xaf +'Mou ', # 0xb0 +'Fu ', # 0xb1 +'Xian ', # 0xb2 +'Lai ', # 0xb3 +'Qu ', # 0xb4 +'Mian ', # 0xb5 +'[?] ', # 0xb6 +'Feng ', # 0xb7 +'Fu ', # 0xb8 +'Qu ', # 0xb9 +'Mian ', # 0xba +'Ma ', # 0xbb +'Mo ', # 0xbc +'Mo ', # 0xbd +'Hui ', # 0xbe +'Ma ', # 0xbf +'Zou ', # 0xc0 +'Nen ', # 0xc1 +'Fen ', # 0xc2 +'Huang ', # 0xc3 +'Huang ', # 0xc4 +'Jin ', # 0xc5 +'Guang ', # 0xc6 +'Tian ', # 0xc7 +'Tou ', # 0xc8 +'Heng ', # 0xc9 +'Xi ', # 0xca +'Kuang ', # 0xcb +'Heng ', # 0xcc +'Shu ', # 0xcd +'Li ', # 0xce +'Nian ', # 0xcf +'Chi ', # 0xd0 +'Hei ', # 0xd1 +'Hei ', # 0xd2 +'Yi ', # 0xd3 +'Qian ', # 0xd4 +'Dan ', # 0xd5 +'Xi ', # 0xd6 +'Tuan ', # 0xd7 +'Mo ', # 0xd8 +'Mo ', # 0xd9 +'Qian ', # 0xda +'Dai ', # 0xdb +'Chu ', # 0xdc +'You ', # 0xdd +'Dian ', # 0xde +'Yi ', # 0xdf +'Xia ', # 0xe0 +'Yan ', # 0xe1 +'Qu ', # 0xe2 +'Mei ', # 0xe3 +'Yan ', # 0xe4 +'Jing ', # 0xe5 +'Yu ', # 0xe6 +'Li ', # 0xe7 +'Dang ', # 0xe8 +'Du ', # 0xe9 +'Can ', # 0xea +'Yin ', # 0xeb +'An ', # 0xec +'Yan ', # 0xed +'Tan ', # 0xee +'An ', # 0xef +'Zhen ', # 0xf0 +'Dai ', # 0xf1 +'Can ', # 0xf2 +'Yi ', # 0xf3 +'Mei ', # 0xf4 +'Dan ', # 0xf5 +'Yan ', # 0xf6 +'Du ', # 0xf7 +'Lu ', # 0xf8 +'Zhi ', # 0xf9 +'Fen ', # 0xfa +'Fu ', # 0xfb +'Fu ', # 0xfc +'Min ', # 0xfd +'Min ', # 0xfe +'Yuan ', # 0xff +) diff --git a/libs/unidecode/x09f.py b/libs/unidecode/x09f.py new file mode 100644 index 00000000..acd59a69 --- /dev/null +++ b/libs/unidecode/x09f.py @@ -0,0 +1,257 @@ +data = ( +'Cu ', # 0x00 +'Qu ', # 0x01 +'Chao ', # 0x02 +'Wa ', # 0x03 +'Zhu ', # 0x04 +'Zhi ', # 0x05 +'Mang ', # 0x06 +'Ao ', # 0x07 +'Bie ', # 0x08 +'Tuo ', # 0x09 +'Bi ', # 0x0a +'Yuan ', # 0x0b +'Chao ', # 0x0c +'Tuo ', # 0x0d +'Ding ', # 0x0e +'Mi ', # 0x0f +'Nai ', # 0x10 +'Ding ', # 0x11 +'Zi ', # 0x12 +'Gu ', # 0x13 +'Gu ', # 0x14 +'Dong ', # 0x15 +'Fen ', # 0x16 +'Tao ', # 0x17 +'Yuan ', # 0x18 +'Pi ', # 0x19 +'Chang ', # 0x1a +'Gao ', # 0x1b +'Qi ', # 0x1c +'Yuan ', # 0x1d +'Tang ', # 0x1e +'Teng ', # 0x1f +'Shu ', # 0x20 +'Shu ', # 0x21 +'Fen ', # 0x22 +'Fei ', # 0x23 +'Wen ', # 0x24 +'Ba ', # 0x25 +'Diao ', # 0x26 +'Tuo ', # 0x27 +'Tong ', # 0x28 +'Qu ', # 0x29 +'Sheng ', # 0x2a +'Shi ', # 0x2b +'You ', # 0x2c +'Shi ', # 0x2d +'Ting ', # 0x2e +'Wu ', # 0x2f +'Nian ', # 0x30 +'Jing ', # 0x31 +'Hun ', # 0x32 +'Ju ', # 0x33 +'Yan ', # 0x34 +'Tu ', # 0x35 +'Ti ', # 0x36 +'Xi ', # 0x37 +'Xian ', # 0x38 +'Yan ', # 0x39 +'Lei ', # 0x3a +'Bi ', # 0x3b +'Yao ', # 0x3c +'Qiu ', # 0x3d +'Han ', # 0x3e +'Wu ', # 0x3f +'Wu ', # 0x40 +'Hou ', # 0x41 +'Xi ', # 0x42 +'Ge ', # 0x43 +'Zha ', # 0x44 +'Xiu ', # 0x45 +'Weng ', # 0x46 +'Zha ', # 0x47 +'Nong ', # 0x48 +'Nang ', # 0x49 +'Qi ', # 0x4a +'Zhai ', # 0x4b +'Ji ', # 0x4c +'Zi ', # 0x4d +'Ji ', # 0x4e +'Ji ', # 0x4f +'Qi ', # 0x50 +'Ji ', # 0x51 +'Chi ', # 0x52 +'Chen ', # 0x53 +'Chen ', # 0x54 +'He ', # 0x55 +'Ya ', # 0x56 +'Ken ', # 0x57 +'Xie ', # 0x58 +'Pao ', # 0x59 +'Cuo ', # 0x5a +'Shi ', # 0x5b +'Zi ', # 0x5c +'Chi ', # 0x5d +'Nian ', # 0x5e +'Ju ', # 0x5f +'Tiao ', # 0x60 +'Ling ', # 0x61 +'Ling ', # 0x62 +'Chu ', # 0x63 +'Quan ', # 0x64 +'Xie ', # 0x65 +'Ken ', # 0x66 +'Nie ', # 0x67 +'Jiu ', # 0x68 +'Yao ', # 0x69 +'Chuo ', # 0x6a +'Kun ', # 0x6b +'Yu ', # 0x6c +'Chu ', # 0x6d +'Yi ', # 0x6e +'Ni ', # 0x6f +'Cuo ', # 0x70 +'Zou ', # 0x71 +'Qu ', # 0x72 +'Nen ', # 0x73 +'Xian ', # 0x74 +'Ou ', # 0x75 +'E ', # 0x76 +'Wo ', # 0x77 +'Yi ', # 0x78 +'Chuo ', # 0x79 +'Zou ', # 0x7a +'Dian ', # 0x7b +'Chu ', # 0x7c +'Jin ', # 0x7d +'Ya ', # 0x7e +'Chi ', # 0x7f +'Chen ', # 0x80 +'He ', # 0x81 +'Ken ', # 0x82 +'Ju ', # 0x83 +'Ling ', # 0x84 +'Pao ', # 0x85 +'Tiao ', # 0x86 +'Zi ', # 0x87 +'Ken ', # 0x88 +'Yu ', # 0x89 +'Chuo ', # 0x8a +'Qu ', # 0x8b +'Wo ', # 0x8c +'Long ', # 0x8d +'Pang ', # 0x8e +'Gong ', # 0x8f +'Pang ', # 0x90 +'Yan ', # 0x91 +'Long ', # 0x92 +'Long ', # 0x93 +'Gong ', # 0x94 +'Kan ', # 0x95 +'Ta ', # 0x96 +'Ling ', # 0x97 +'Ta ', # 0x98 +'Long ', # 0x99 +'Gong ', # 0x9a +'Kan ', # 0x9b +'Gui ', # 0x9c +'Qiu ', # 0x9d +'Bie ', # 0x9e +'Gui ', # 0x9f +'Yue ', # 0xa0 +'Chui ', # 0xa1 +'He ', # 0xa2 +'Jue ', # 0xa3 +'Xie ', # 0xa4 +'Yu ', # 0xa5 +'[?]', # 0xa6 +'[?]', # 0xa7 +'[?]', # 0xa8 +'[?]', # 0xa9 +'[?]', # 0xaa +'[?]', # 0xab +'[?]', # 0xac +'[?]', # 0xad +'[?]', # 0xae +'[?]', # 0xaf +'[?]', # 0xb0 +'[?]', # 0xb1 +'[?]', # 0xb2 +'[?]', # 0xb3 +'[?]', # 0xb4 +'[?]', # 0xb5 +'[?]', # 0xb6 +'[?]', # 0xb7 +'[?]', # 0xb8 +'[?]', # 0xb9 +'[?]', # 0xba +'[?]', # 0xbb +'[?]', # 0xbc +'[?]', # 0xbd +'[?]', # 0xbe +'[?]', # 0xbf +'[?]', # 0xc0 +'[?]', # 0xc1 +'[?]', # 0xc2 +'[?]', # 0xc3 +'[?]', # 0xc4 +'[?]', # 0xc5 +'[?]', # 0xc6 +'[?]', # 0xc7 +'[?]', # 0xc8 +'[?]', # 0xc9 +'[?]', # 0xca +'[?]', # 0xcb +'[?]', # 0xcc +'[?]', # 0xcd +'[?]', # 0xce +'[?]', # 0xcf +'[?]', # 0xd0 +'[?]', # 0xd1 +'[?]', # 0xd2 +'[?]', # 0xd3 +'[?]', # 0xd4 +'[?]', # 0xd5 +'[?]', # 0xd6 +'[?]', # 0xd7 +'[?]', # 0xd8 +'[?]', # 0xd9 +'[?]', # 0xda +'[?]', # 0xdb +'[?]', # 0xdc +'[?]', # 0xdd +'[?]', # 0xde +'[?]', # 0xdf +'[?]', # 0xe0 +'[?]', # 0xe1 +'[?]', # 0xe2 +'[?]', # 0xe3 +'[?]', # 0xe4 +'[?]', # 0xe5 +'[?]', # 0xe6 +'[?]', # 0xe7 +'[?]', # 0xe8 +'[?]', # 0xe9 +'[?]', # 0xea +'[?]', # 0xeb +'[?]', # 0xec +'[?]', # 0xed +'[?]', # 0xee +'[?]', # 0xef +'[?]', # 0xf0 +'[?]', # 0xf1 +'[?]', # 0xf2 +'[?]', # 0xf3 +'[?]', # 0xf4 +'[?]', # 0xf5 +'[?]', # 0xf6 +'[?]', # 0xf7 +'[?]', # 0xf8 +'[?]', # 0xf9 +'[?]', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x0a0.py b/libs/unidecode/x0a0.py new file mode 100644 index 00000000..c25f17bc --- /dev/null +++ b/libs/unidecode/x0a0.py @@ -0,0 +1,258 @@ +data = ( +'it', # 0x00 +'ix', # 0x01 +'i', # 0x02 +'ip', # 0x03 +'iet', # 0x04 +'iex', # 0x05 +'ie', # 0x06 +'iep', # 0x07 +'at', # 0x08 +'ax', # 0x09 +'a', # 0x0a +'ap', # 0x0b +'uox', # 0x0c +'uo', # 0x0d +'uop', # 0x0e +'ot', # 0x0f +'ox', # 0x10 +'o', # 0x11 +'op', # 0x12 +'ex', # 0x13 +'e', # 0x14 +'wu', # 0x15 +'bit', # 0x16 +'bix', # 0x17 +'bi', # 0x18 +'bip', # 0x19 +'biet', # 0x1a +'biex', # 0x1b +'bie', # 0x1c +'biep', # 0x1d +'bat', # 0x1e +'bax', # 0x1f +'ba', # 0x20 +'bap', # 0x21 +'buox', # 0x22 +'buo', # 0x23 +'buop', # 0x24 +'bot', # 0x25 +'box', # 0x26 +'bo', # 0x27 +'bop', # 0x28 +'bex', # 0x29 +'be', # 0x2a +'bep', # 0x2b +'but', # 0x2c +'bux', # 0x2d +'bu', # 0x2e +'bup', # 0x2f +'burx', # 0x30 +'bur', # 0x31 +'byt', # 0x32 +'byx', # 0x33 +'by', # 0x34 +'byp', # 0x35 +'byrx', # 0x36 +'byr', # 0x37 +'pit', # 0x38 +'pix', # 0x39 +'pi', # 0x3a +'pip', # 0x3b +'piex', # 0x3c +'pie', # 0x3d +'piep', # 0x3e +'pat', # 0x3f +'pax', # 0x40 +'pa', # 0x41 +'pap', # 0x42 +'puox', # 0x43 +'puo', # 0x44 +'puop', # 0x45 +'pot', # 0x46 +'pox', # 0x47 +'po', # 0x48 +'pop', # 0x49 +'put', # 0x4a +'pux', # 0x4b +'pu', # 0x4c +'pup', # 0x4d +'purx', # 0x4e +'pur', # 0x4f +'pyt', # 0x50 +'pyx', # 0x51 +'py', # 0x52 +'pyp', # 0x53 +'pyrx', # 0x54 +'pyr', # 0x55 +'bbit', # 0x56 +'bbix', # 0x57 +'bbi', # 0x58 +'bbip', # 0x59 +'bbiet', # 0x5a +'bbiex', # 0x5b +'bbie', # 0x5c +'bbiep', # 0x5d +'bbat', # 0x5e +'bbax', # 0x5f +'bba', # 0x60 +'bbap', # 0x61 +'bbuox', # 0x62 +'bbuo', # 0x63 +'bbuop', # 0x64 +'bbot', # 0x65 +'bbox', # 0x66 +'bbo', # 0x67 +'bbop', # 0x68 +'bbex', # 0x69 +'bbe', # 0x6a +'bbep', # 0x6b +'bbut', # 0x6c +'bbux', # 0x6d +'bbu', # 0x6e +'bbup', # 0x6f +'bburx', # 0x70 +'bbur', # 0x71 +'bbyt', # 0x72 +'bbyx', # 0x73 +'bby', # 0x74 +'bbyp', # 0x75 +'nbit', # 0x76 +'nbix', # 0x77 +'nbi', # 0x78 +'nbip', # 0x79 +'nbiex', # 0x7a +'nbie', # 0x7b +'nbiep', # 0x7c +'nbat', # 0x7d +'nbax', # 0x7e +'nba', # 0x7f +'nbap', # 0x80 +'nbot', # 0x81 +'nbox', # 0x82 +'nbo', # 0x83 +'nbop', # 0x84 +'nbut', # 0x85 +'nbux', # 0x86 +'nbu', # 0x87 +'nbup', # 0x88 +'nburx', # 0x89 +'nbur', # 0x8a +'nbyt', # 0x8b +'nbyx', # 0x8c +'nby', # 0x8d +'nbyp', # 0x8e +'nbyrx', # 0x8f +'nbyr', # 0x90 +'hmit', # 0x91 +'hmix', # 0x92 +'hmi', # 0x93 +'hmip', # 0x94 +'hmiex', # 0x95 +'hmie', # 0x96 +'hmiep', # 0x97 +'hmat', # 0x98 +'hmax', # 0x99 +'hma', # 0x9a +'hmap', # 0x9b +'hmuox', # 0x9c +'hmuo', # 0x9d +'hmuop', # 0x9e +'hmot', # 0x9f +'hmox', # 0xa0 +'hmo', # 0xa1 +'hmop', # 0xa2 +'hmut', # 0xa3 +'hmux', # 0xa4 +'hmu', # 0xa5 +'hmup', # 0xa6 +'hmurx', # 0xa7 +'hmur', # 0xa8 +'hmyx', # 0xa9 +'hmy', # 0xaa +'hmyp', # 0xab +'hmyrx', # 0xac +'hmyr', # 0xad +'mit', # 0xae +'mix', # 0xaf +'mi', # 0xb0 +'mip', # 0xb1 +'miex', # 0xb2 +'mie', # 0xb3 +'miep', # 0xb4 +'mat', # 0xb5 +'max', # 0xb6 +'ma', # 0xb7 +'map', # 0xb8 +'muot', # 0xb9 +'muox', # 0xba +'muo', # 0xbb +'muop', # 0xbc +'mot', # 0xbd +'mox', # 0xbe +'mo', # 0xbf +'mop', # 0xc0 +'mex', # 0xc1 +'me', # 0xc2 +'mut', # 0xc3 +'mux', # 0xc4 +'mu', # 0xc5 +'mup', # 0xc6 +'murx', # 0xc7 +'mur', # 0xc8 +'myt', # 0xc9 +'myx', # 0xca +'my', # 0xcb +'myp', # 0xcc +'fit', # 0xcd +'fix', # 0xce +'fi', # 0xcf +'fip', # 0xd0 +'fat', # 0xd1 +'fax', # 0xd2 +'fa', # 0xd3 +'fap', # 0xd4 +'fox', # 0xd5 +'fo', # 0xd6 +'fop', # 0xd7 +'fut', # 0xd8 +'fux', # 0xd9 +'fu', # 0xda +'fup', # 0xdb +'furx', # 0xdc +'fur', # 0xdd +'fyt', # 0xde +'fyx', # 0xdf +'fy', # 0xe0 +'fyp', # 0xe1 +'vit', # 0xe2 +'vix', # 0xe3 +'vi', # 0xe4 +'vip', # 0xe5 +'viet', # 0xe6 +'viex', # 0xe7 +'vie', # 0xe8 +'viep', # 0xe9 +'vat', # 0xea +'vax', # 0xeb +'va', # 0xec +'vap', # 0xed +'vot', # 0xee +'vox', # 0xef +'vo', # 0xf0 +'vop', # 0xf1 +'vex', # 0xf2 +'vep', # 0xf3 +'vut', # 0xf4 +'vux', # 0xf5 +'vu', # 0xf6 +'vup', # 0xf7 +'vurx', # 0xf8 +'vur', # 0xf9 +'vyt', # 0xfa +'vyx', # 0xfb +'vy', # 0xfc +'vyp', # 0xfd +'vyrx', # 0xfe +'vyr', # 0xff +) diff --git a/libs/unidecode/x0a1.py b/libs/unidecode/x0a1.py new file mode 100644 index 00000000..185dc8ba --- /dev/null +++ b/libs/unidecode/x0a1.py @@ -0,0 +1,258 @@ +data = ( +'dit', # 0x00 +'dix', # 0x01 +'di', # 0x02 +'dip', # 0x03 +'diex', # 0x04 +'die', # 0x05 +'diep', # 0x06 +'dat', # 0x07 +'dax', # 0x08 +'da', # 0x09 +'dap', # 0x0a +'duox', # 0x0b +'duo', # 0x0c +'dot', # 0x0d +'dox', # 0x0e +'do', # 0x0f +'dop', # 0x10 +'dex', # 0x11 +'de', # 0x12 +'dep', # 0x13 +'dut', # 0x14 +'dux', # 0x15 +'du', # 0x16 +'dup', # 0x17 +'durx', # 0x18 +'dur', # 0x19 +'tit', # 0x1a +'tix', # 0x1b +'ti', # 0x1c +'tip', # 0x1d +'tiex', # 0x1e +'tie', # 0x1f +'tiep', # 0x20 +'tat', # 0x21 +'tax', # 0x22 +'ta', # 0x23 +'tap', # 0x24 +'tuot', # 0x25 +'tuox', # 0x26 +'tuo', # 0x27 +'tuop', # 0x28 +'tot', # 0x29 +'tox', # 0x2a +'to', # 0x2b +'top', # 0x2c +'tex', # 0x2d +'te', # 0x2e +'tep', # 0x2f +'tut', # 0x30 +'tux', # 0x31 +'tu', # 0x32 +'tup', # 0x33 +'turx', # 0x34 +'tur', # 0x35 +'ddit', # 0x36 +'ddix', # 0x37 +'ddi', # 0x38 +'ddip', # 0x39 +'ddiex', # 0x3a +'ddie', # 0x3b +'ddiep', # 0x3c +'ddat', # 0x3d +'ddax', # 0x3e +'dda', # 0x3f +'ddap', # 0x40 +'dduox', # 0x41 +'dduo', # 0x42 +'dduop', # 0x43 +'ddot', # 0x44 +'ddox', # 0x45 +'ddo', # 0x46 +'ddop', # 0x47 +'ddex', # 0x48 +'dde', # 0x49 +'ddep', # 0x4a +'ddut', # 0x4b +'ddux', # 0x4c +'ddu', # 0x4d +'ddup', # 0x4e +'ddurx', # 0x4f +'ddur', # 0x50 +'ndit', # 0x51 +'ndix', # 0x52 +'ndi', # 0x53 +'ndip', # 0x54 +'ndiex', # 0x55 +'ndie', # 0x56 +'ndat', # 0x57 +'ndax', # 0x58 +'nda', # 0x59 +'ndap', # 0x5a +'ndot', # 0x5b +'ndox', # 0x5c +'ndo', # 0x5d +'ndop', # 0x5e +'ndex', # 0x5f +'nde', # 0x60 +'ndep', # 0x61 +'ndut', # 0x62 +'ndux', # 0x63 +'ndu', # 0x64 +'ndup', # 0x65 +'ndurx', # 0x66 +'ndur', # 0x67 +'hnit', # 0x68 +'hnix', # 0x69 +'hni', # 0x6a +'hnip', # 0x6b +'hniet', # 0x6c +'hniex', # 0x6d +'hnie', # 0x6e +'hniep', # 0x6f +'hnat', # 0x70 +'hnax', # 0x71 +'hna', # 0x72 +'hnap', # 0x73 +'hnuox', # 0x74 +'hnuo', # 0x75 +'hnot', # 0x76 +'hnox', # 0x77 +'hnop', # 0x78 +'hnex', # 0x79 +'hne', # 0x7a +'hnep', # 0x7b +'hnut', # 0x7c +'nit', # 0x7d +'nix', # 0x7e +'ni', # 0x7f +'nip', # 0x80 +'niex', # 0x81 +'nie', # 0x82 +'niep', # 0x83 +'nax', # 0x84 +'na', # 0x85 +'nap', # 0x86 +'nuox', # 0x87 +'nuo', # 0x88 +'nuop', # 0x89 +'not', # 0x8a +'nox', # 0x8b +'no', # 0x8c +'nop', # 0x8d +'nex', # 0x8e +'ne', # 0x8f +'nep', # 0x90 +'nut', # 0x91 +'nux', # 0x92 +'nu', # 0x93 +'nup', # 0x94 +'nurx', # 0x95 +'nur', # 0x96 +'hlit', # 0x97 +'hlix', # 0x98 +'hli', # 0x99 +'hlip', # 0x9a +'hliex', # 0x9b +'hlie', # 0x9c +'hliep', # 0x9d +'hlat', # 0x9e +'hlax', # 0x9f +'hla', # 0xa0 +'hlap', # 0xa1 +'hluox', # 0xa2 +'hluo', # 0xa3 +'hluop', # 0xa4 +'hlox', # 0xa5 +'hlo', # 0xa6 +'hlop', # 0xa7 +'hlex', # 0xa8 +'hle', # 0xa9 +'hlep', # 0xaa +'hlut', # 0xab +'hlux', # 0xac +'hlu', # 0xad +'hlup', # 0xae +'hlurx', # 0xaf +'hlur', # 0xb0 +'hlyt', # 0xb1 +'hlyx', # 0xb2 +'hly', # 0xb3 +'hlyp', # 0xb4 +'hlyrx', # 0xb5 +'hlyr', # 0xb6 +'lit', # 0xb7 +'lix', # 0xb8 +'li', # 0xb9 +'lip', # 0xba +'liet', # 0xbb +'liex', # 0xbc +'lie', # 0xbd +'liep', # 0xbe +'lat', # 0xbf +'lax', # 0xc0 +'la', # 0xc1 +'lap', # 0xc2 +'luot', # 0xc3 +'luox', # 0xc4 +'luo', # 0xc5 +'luop', # 0xc6 +'lot', # 0xc7 +'lox', # 0xc8 +'lo', # 0xc9 +'lop', # 0xca +'lex', # 0xcb +'le', # 0xcc +'lep', # 0xcd +'lut', # 0xce +'lux', # 0xcf +'lu', # 0xd0 +'lup', # 0xd1 +'lurx', # 0xd2 +'lur', # 0xd3 +'lyt', # 0xd4 +'lyx', # 0xd5 +'ly', # 0xd6 +'lyp', # 0xd7 +'lyrx', # 0xd8 +'lyr', # 0xd9 +'git', # 0xda +'gix', # 0xdb +'gi', # 0xdc +'gip', # 0xdd +'giet', # 0xde +'giex', # 0xdf +'gie', # 0xe0 +'giep', # 0xe1 +'gat', # 0xe2 +'gax', # 0xe3 +'ga', # 0xe4 +'gap', # 0xe5 +'guot', # 0xe6 +'guox', # 0xe7 +'guo', # 0xe8 +'guop', # 0xe9 +'got', # 0xea +'gox', # 0xeb +'go', # 0xec +'gop', # 0xed +'get', # 0xee +'gex', # 0xef +'ge', # 0xf0 +'gep', # 0xf1 +'gut', # 0xf2 +'gux', # 0xf3 +'gu', # 0xf4 +'gup', # 0xf5 +'gurx', # 0xf6 +'gur', # 0xf7 +'kit', # 0xf8 +'kix', # 0xf9 +'ki', # 0xfa +'kip', # 0xfb +'kiex', # 0xfc +'kie', # 0xfd +'kiep', # 0xfe +'kat', # 0xff +) diff --git a/libs/unidecode/x0a2.py b/libs/unidecode/x0a2.py new file mode 100644 index 00000000..8ea89913 --- /dev/null +++ b/libs/unidecode/x0a2.py @@ -0,0 +1,258 @@ +data = ( +'kax', # 0x00 +'ka', # 0x01 +'kap', # 0x02 +'kuox', # 0x03 +'kuo', # 0x04 +'kuop', # 0x05 +'kot', # 0x06 +'kox', # 0x07 +'ko', # 0x08 +'kop', # 0x09 +'ket', # 0x0a +'kex', # 0x0b +'ke', # 0x0c +'kep', # 0x0d +'kut', # 0x0e +'kux', # 0x0f +'ku', # 0x10 +'kup', # 0x11 +'kurx', # 0x12 +'kur', # 0x13 +'ggit', # 0x14 +'ggix', # 0x15 +'ggi', # 0x16 +'ggiex', # 0x17 +'ggie', # 0x18 +'ggiep', # 0x19 +'ggat', # 0x1a +'ggax', # 0x1b +'gga', # 0x1c +'ggap', # 0x1d +'gguot', # 0x1e +'gguox', # 0x1f +'gguo', # 0x20 +'gguop', # 0x21 +'ggot', # 0x22 +'ggox', # 0x23 +'ggo', # 0x24 +'ggop', # 0x25 +'gget', # 0x26 +'ggex', # 0x27 +'gge', # 0x28 +'ggep', # 0x29 +'ggut', # 0x2a +'ggux', # 0x2b +'ggu', # 0x2c +'ggup', # 0x2d +'ggurx', # 0x2e +'ggur', # 0x2f +'mgiex', # 0x30 +'mgie', # 0x31 +'mgat', # 0x32 +'mgax', # 0x33 +'mga', # 0x34 +'mgap', # 0x35 +'mguox', # 0x36 +'mguo', # 0x37 +'mguop', # 0x38 +'mgot', # 0x39 +'mgox', # 0x3a +'mgo', # 0x3b +'mgop', # 0x3c +'mgex', # 0x3d +'mge', # 0x3e +'mgep', # 0x3f +'mgut', # 0x40 +'mgux', # 0x41 +'mgu', # 0x42 +'mgup', # 0x43 +'mgurx', # 0x44 +'mgur', # 0x45 +'hxit', # 0x46 +'hxix', # 0x47 +'hxi', # 0x48 +'hxip', # 0x49 +'hxiet', # 0x4a +'hxiex', # 0x4b +'hxie', # 0x4c +'hxiep', # 0x4d +'hxat', # 0x4e +'hxax', # 0x4f +'hxa', # 0x50 +'hxap', # 0x51 +'hxuot', # 0x52 +'hxuox', # 0x53 +'hxuo', # 0x54 +'hxuop', # 0x55 +'hxot', # 0x56 +'hxox', # 0x57 +'hxo', # 0x58 +'hxop', # 0x59 +'hxex', # 0x5a +'hxe', # 0x5b +'hxep', # 0x5c +'ngiex', # 0x5d +'ngie', # 0x5e +'ngiep', # 0x5f +'ngat', # 0x60 +'ngax', # 0x61 +'nga', # 0x62 +'ngap', # 0x63 +'nguot', # 0x64 +'nguox', # 0x65 +'nguo', # 0x66 +'ngot', # 0x67 +'ngox', # 0x68 +'ngo', # 0x69 +'ngop', # 0x6a +'ngex', # 0x6b +'nge', # 0x6c +'ngep', # 0x6d +'hit', # 0x6e +'hiex', # 0x6f +'hie', # 0x70 +'hat', # 0x71 +'hax', # 0x72 +'ha', # 0x73 +'hap', # 0x74 +'huot', # 0x75 +'huox', # 0x76 +'huo', # 0x77 +'huop', # 0x78 +'hot', # 0x79 +'hox', # 0x7a +'ho', # 0x7b +'hop', # 0x7c +'hex', # 0x7d +'he', # 0x7e +'hep', # 0x7f +'wat', # 0x80 +'wax', # 0x81 +'wa', # 0x82 +'wap', # 0x83 +'wuox', # 0x84 +'wuo', # 0x85 +'wuop', # 0x86 +'wox', # 0x87 +'wo', # 0x88 +'wop', # 0x89 +'wex', # 0x8a +'we', # 0x8b +'wep', # 0x8c +'zit', # 0x8d +'zix', # 0x8e +'zi', # 0x8f +'zip', # 0x90 +'ziex', # 0x91 +'zie', # 0x92 +'ziep', # 0x93 +'zat', # 0x94 +'zax', # 0x95 +'za', # 0x96 +'zap', # 0x97 +'zuox', # 0x98 +'zuo', # 0x99 +'zuop', # 0x9a +'zot', # 0x9b +'zox', # 0x9c +'zo', # 0x9d +'zop', # 0x9e +'zex', # 0x9f +'ze', # 0xa0 +'zep', # 0xa1 +'zut', # 0xa2 +'zux', # 0xa3 +'zu', # 0xa4 +'zup', # 0xa5 +'zurx', # 0xa6 +'zur', # 0xa7 +'zyt', # 0xa8 +'zyx', # 0xa9 +'zy', # 0xaa +'zyp', # 0xab +'zyrx', # 0xac +'zyr', # 0xad +'cit', # 0xae +'cix', # 0xaf +'ci', # 0xb0 +'cip', # 0xb1 +'ciet', # 0xb2 +'ciex', # 0xb3 +'cie', # 0xb4 +'ciep', # 0xb5 +'cat', # 0xb6 +'cax', # 0xb7 +'ca', # 0xb8 +'cap', # 0xb9 +'cuox', # 0xba +'cuo', # 0xbb +'cuop', # 0xbc +'cot', # 0xbd +'cox', # 0xbe +'co', # 0xbf +'cop', # 0xc0 +'cex', # 0xc1 +'ce', # 0xc2 +'cep', # 0xc3 +'cut', # 0xc4 +'cux', # 0xc5 +'cu', # 0xc6 +'cup', # 0xc7 +'curx', # 0xc8 +'cur', # 0xc9 +'cyt', # 0xca +'cyx', # 0xcb +'cy', # 0xcc +'cyp', # 0xcd +'cyrx', # 0xce +'cyr', # 0xcf +'zzit', # 0xd0 +'zzix', # 0xd1 +'zzi', # 0xd2 +'zzip', # 0xd3 +'zziet', # 0xd4 +'zziex', # 0xd5 +'zzie', # 0xd6 +'zziep', # 0xd7 +'zzat', # 0xd8 +'zzax', # 0xd9 +'zza', # 0xda +'zzap', # 0xdb +'zzox', # 0xdc +'zzo', # 0xdd +'zzop', # 0xde +'zzex', # 0xdf +'zze', # 0xe0 +'zzep', # 0xe1 +'zzux', # 0xe2 +'zzu', # 0xe3 +'zzup', # 0xe4 +'zzurx', # 0xe5 +'zzur', # 0xe6 +'zzyt', # 0xe7 +'zzyx', # 0xe8 +'zzy', # 0xe9 +'zzyp', # 0xea +'zzyrx', # 0xeb +'zzyr', # 0xec +'nzit', # 0xed +'nzix', # 0xee +'nzi', # 0xef +'nzip', # 0xf0 +'nziex', # 0xf1 +'nzie', # 0xf2 +'nziep', # 0xf3 +'nzat', # 0xf4 +'nzax', # 0xf5 +'nza', # 0xf6 +'nzap', # 0xf7 +'nzuox', # 0xf8 +'nzuo', # 0xf9 +'nzox', # 0xfa +'nzop', # 0xfb +'nzex', # 0xfc +'nze', # 0xfd +'nzux', # 0xfe +'nzu', # 0xff +) diff --git a/libs/unidecode/x0a3.py b/libs/unidecode/x0a3.py new file mode 100644 index 00000000..5e77aec0 --- /dev/null +++ b/libs/unidecode/x0a3.py @@ -0,0 +1,258 @@ +data = ( +'nzup', # 0x00 +'nzurx', # 0x01 +'nzur', # 0x02 +'nzyt', # 0x03 +'nzyx', # 0x04 +'nzy', # 0x05 +'nzyp', # 0x06 +'nzyrx', # 0x07 +'nzyr', # 0x08 +'sit', # 0x09 +'six', # 0x0a +'si', # 0x0b +'sip', # 0x0c +'siex', # 0x0d +'sie', # 0x0e +'siep', # 0x0f +'sat', # 0x10 +'sax', # 0x11 +'sa', # 0x12 +'sap', # 0x13 +'suox', # 0x14 +'suo', # 0x15 +'suop', # 0x16 +'sot', # 0x17 +'sox', # 0x18 +'so', # 0x19 +'sop', # 0x1a +'sex', # 0x1b +'se', # 0x1c +'sep', # 0x1d +'sut', # 0x1e +'sux', # 0x1f +'su', # 0x20 +'sup', # 0x21 +'surx', # 0x22 +'sur', # 0x23 +'syt', # 0x24 +'syx', # 0x25 +'sy', # 0x26 +'syp', # 0x27 +'syrx', # 0x28 +'syr', # 0x29 +'ssit', # 0x2a +'ssix', # 0x2b +'ssi', # 0x2c +'ssip', # 0x2d +'ssiex', # 0x2e +'ssie', # 0x2f +'ssiep', # 0x30 +'ssat', # 0x31 +'ssax', # 0x32 +'ssa', # 0x33 +'ssap', # 0x34 +'ssot', # 0x35 +'ssox', # 0x36 +'sso', # 0x37 +'ssop', # 0x38 +'ssex', # 0x39 +'sse', # 0x3a +'ssep', # 0x3b +'ssut', # 0x3c +'ssux', # 0x3d +'ssu', # 0x3e +'ssup', # 0x3f +'ssyt', # 0x40 +'ssyx', # 0x41 +'ssy', # 0x42 +'ssyp', # 0x43 +'ssyrx', # 0x44 +'ssyr', # 0x45 +'zhat', # 0x46 +'zhax', # 0x47 +'zha', # 0x48 +'zhap', # 0x49 +'zhuox', # 0x4a +'zhuo', # 0x4b +'zhuop', # 0x4c +'zhot', # 0x4d +'zhox', # 0x4e +'zho', # 0x4f +'zhop', # 0x50 +'zhet', # 0x51 +'zhex', # 0x52 +'zhe', # 0x53 +'zhep', # 0x54 +'zhut', # 0x55 +'zhux', # 0x56 +'zhu', # 0x57 +'zhup', # 0x58 +'zhurx', # 0x59 +'zhur', # 0x5a +'zhyt', # 0x5b +'zhyx', # 0x5c +'zhy', # 0x5d +'zhyp', # 0x5e +'zhyrx', # 0x5f +'zhyr', # 0x60 +'chat', # 0x61 +'chax', # 0x62 +'cha', # 0x63 +'chap', # 0x64 +'chuot', # 0x65 +'chuox', # 0x66 +'chuo', # 0x67 +'chuop', # 0x68 +'chot', # 0x69 +'chox', # 0x6a +'cho', # 0x6b +'chop', # 0x6c +'chet', # 0x6d +'chex', # 0x6e +'che', # 0x6f +'chep', # 0x70 +'chux', # 0x71 +'chu', # 0x72 +'chup', # 0x73 +'churx', # 0x74 +'chur', # 0x75 +'chyt', # 0x76 +'chyx', # 0x77 +'chy', # 0x78 +'chyp', # 0x79 +'chyrx', # 0x7a +'chyr', # 0x7b +'rrax', # 0x7c +'rra', # 0x7d +'rruox', # 0x7e +'rruo', # 0x7f +'rrot', # 0x80 +'rrox', # 0x81 +'rro', # 0x82 +'rrop', # 0x83 +'rret', # 0x84 +'rrex', # 0x85 +'rre', # 0x86 +'rrep', # 0x87 +'rrut', # 0x88 +'rrux', # 0x89 +'rru', # 0x8a +'rrup', # 0x8b +'rrurx', # 0x8c +'rrur', # 0x8d +'rryt', # 0x8e +'rryx', # 0x8f +'rry', # 0x90 +'rryp', # 0x91 +'rryrx', # 0x92 +'rryr', # 0x93 +'nrat', # 0x94 +'nrax', # 0x95 +'nra', # 0x96 +'nrap', # 0x97 +'nrox', # 0x98 +'nro', # 0x99 +'nrop', # 0x9a +'nret', # 0x9b +'nrex', # 0x9c +'nre', # 0x9d +'nrep', # 0x9e +'nrut', # 0x9f +'nrux', # 0xa0 +'nru', # 0xa1 +'nrup', # 0xa2 +'nrurx', # 0xa3 +'nrur', # 0xa4 +'nryt', # 0xa5 +'nryx', # 0xa6 +'nry', # 0xa7 +'nryp', # 0xa8 +'nryrx', # 0xa9 +'nryr', # 0xaa +'shat', # 0xab +'shax', # 0xac +'sha', # 0xad +'shap', # 0xae +'shuox', # 0xaf +'shuo', # 0xb0 +'shuop', # 0xb1 +'shot', # 0xb2 +'shox', # 0xb3 +'sho', # 0xb4 +'shop', # 0xb5 +'shet', # 0xb6 +'shex', # 0xb7 +'she', # 0xb8 +'shep', # 0xb9 +'shut', # 0xba +'shux', # 0xbb +'shu', # 0xbc +'shup', # 0xbd +'shurx', # 0xbe +'shur', # 0xbf +'shyt', # 0xc0 +'shyx', # 0xc1 +'shy', # 0xc2 +'shyp', # 0xc3 +'shyrx', # 0xc4 +'shyr', # 0xc5 +'rat', # 0xc6 +'rax', # 0xc7 +'ra', # 0xc8 +'rap', # 0xc9 +'ruox', # 0xca +'ruo', # 0xcb +'ruop', # 0xcc +'rot', # 0xcd +'rox', # 0xce +'ro', # 0xcf +'rop', # 0xd0 +'rex', # 0xd1 +'re', # 0xd2 +'rep', # 0xd3 +'rut', # 0xd4 +'rux', # 0xd5 +'ru', # 0xd6 +'rup', # 0xd7 +'rurx', # 0xd8 +'rur', # 0xd9 +'ryt', # 0xda +'ryx', # 0xdb +'ry', # 0xdc +'ryp', # 0xdd +'ryrx', # 0xde +'ryr', # 0xdf +'jit', # 0xe0 +'jix', # 0xe1 +'ji', # 0xe2 +'jip', # 0xe3 +'jiet', # 0xe4 +'jiex', # 0xe5 +'jie', # 0xe6 +'jiep', # 0xe7 +'juot', # 0xe8 +'juox', # 0xe9 +'juo', # 0xea +'juop', # 0xeb +'jot', # 0xec +'jox', # 0xed +'jo', # 0xee +'jop', # 0xef +'jut', # 0xf0 +'jux', # 0xf1 +'ju', # 0xf2 +'jup', # 0xf3 +'jurx', # 0xf4 +'jur', # 0xf5 +'jyt', # 0xf6 +'jyx', # 0xf7 +'jy', # 0xf8 +'jyp', # 0xf9 +'jyrx', # 0xfa +'jyr', # 0xfb +'qit', # 0xfc +'qix', # 0xfd +'qi', # 0xfe +'qip', # 0xff +) diff --git a/libs/unidecode/x0a4.py b/libs/unidecode/x0a4.py new file mode 100644 index 00000000..4fb6b264 --- /dev/null +++ b/libs/unidecode/x0a4.py @@ -0,0 +1,257 @@ +data = ( +'qiet', # 0x00 +'qiex', # 0x01 +'qie', # 0x02 +'qiep', # 0x03 +'quot', # 0x04 +'quox', # 0x05 +'quo', # 0x06 +'quop', # 0x07 +'qot', # 0x08 +'qox', # 0x09 +'qo', # 0x0a +'qop', # 0x0b +'qut', # 0x0c +'qux', # 0x0d +'qu', # 0x0e +'qup', # 0x0f +'qurx', # 0x10 +'qur', # 0x11 +'qyt', # 0x12 +'qyx', # 0x13 +'qy', # 0x14 +'qyp', # 0x15 +'qyrx', # 0x16 +'qyr', # 0x17 +'jjit', # 0x18 +'jjix', # 0x19 +'jji', # 0x1a +'jjip', # 0x1b +'jjiet', # 0x1c +'jjiex', # 0x1d +'jjie', # 0x1e +'jjiep', # 0x1f +'jjuox', # 0x20 +'jjuo', # 0x21 +'jjuop', # 0x22 +'jjot', # 0x23 +'jjox', # 0x24 +'jjo', # 0x25 +'jjop', # 0x26 +'jjut', # 0x27 +'jjux', # 0x28 +'jju', # 0x29 +'jjup', # 0x2a +'jjurx', # 0x2b +'jjur', # 0x2c +'jjyt', # 0x2d +'jjyx', # 0x2e +'jjy', # 0x2f +'jjyp', # 0x30 +'njit', # 0x31 +'njix', # 0x32 +'nji', # 0x33 +'njip', # 0x34 +'njiet', # 0x35 +'njiex', # 0x36 +'njie', # 0x37 +'njiep', # 0x38 +'njuox', # 0x39 +'njuo', # 0x3a +'njot', # 0x3b +'njox', # 0x3c +'njo', # 0x3d +'njop', # 0x3e +'njux', # 0x3f +'nju', # 0x40 +'njup', # 0x41 +'njurx', # 0x42 +'njur', # 0x43 +'njyt', # 0x44 +'njyx', # 0x45 +'njy', # 0x46 +'njyp', # 0x47 +'njyrx', # 0x48 +'njyr', # 0x49 +'nyit', # 0x4a +'nyix', # 0x4b +'nyi', # 0x4c +'nyip', # 0x4d +'nyiet', # 0x4e +'nyiex', # 0x4f +'nyie', # 0x50 +'nyiep', # 0x51 +'nyuox', # 0x52 +'nyuo', # 0x53 +'nyuop', # 0x54 +'nyot', # 0x55 +'nyox', # 0x56 +'nyo', # 0x57 +'nyop', # 0x58 +'nyut', # 0x59 +'nyux', # 0x5a +'nyu', # 0x5b +'nyup', # 0x5c +'xit', # 0x5d +'xix', # 0x5e +'xi', # 0x5f +'xip', # 0x60 +'xiet', # 0x61 +'xiex', # 0x62 +'xie', # 0x63 +'xiep', # 0x64 +'xuox', # 0x65 +'xuo', # 0x66 +'xot', # 0x67 +'xox', # 0x68 +'xo', # 0x69 +'xop', # 0x6a +'xyt', # 0x6b +'xyx', # 0x6c +'xy', # 0x6d +'xyp', # 0x6e +'xyrx', # 0x6f +'xyr', # 0x70 +'yit', # 0x71 +'yix', # 0x72 +'yi', # 0x73 +'yip', # 0x74 +'yiet', # 0x75 +'yiex', # 0x76 +'yie', # 0x77 +'yiep', # 0x78 +'yuot', # 0x79 +'yuox', # 0x7a +'yuo', # 0x7b +'yuop', # 0x7c +'yot', # 0x7d +'yox', # 0x7e +'yo', # 0x7f +'yop', # 0x80 +'yut', # 0x81 +'yux', # 0x82 +'yu', # 0x83 +'yup', # 0x84 +'yurx', # 0x85 +'yur', # 0x86 +'yyt', # 0x87 +'yyx', # 0x88 +'yy', # 0x89 +'yyp', # 0x8a +'yyrx', # 0x8b +'yyr', # 0x8c +'[?]', # 0x8d +'[?]', # 0x8e +'[?]', # 0x8f +'Qot', # 0x90 +'Li', # 0x91 +'Kit', # 0x92 +'Nyip', # 0x93 +'Cyp', # 0x94 +'Ssi', # 0x95 +'Ggop', # 0x96 +'Gep', # 0x97 +'Mi', # 0x98 +'Hxit', # 0x99 +'Lyr', # 0x9a +'Bbut', # 0x9b +'Mop', # 0x9c +'Yo', # 0x9d +'Put', # 0x9e +'Hxuo', # 0x9f +'Tat', # 0xa0 +'Ga', # 0xa1 +'[?]', # 0xa2 +'[?]', # 0xa3 +'Ddur', # 0xa4 +'Bur', # 0xa5 +'Gguo', # 0xa6 +'Nyop', # 0xa7 +'Tu', # 0xa8 +'Op', # 0xa9 +'Jjut', # 0xaa +'Zot', # 0xab +'Pyt', # 0xac +'Hmo', # 0xad +'Yit', # 0xae +'Vur', # 0xaf +'Shy', # 0xb0 +'Vep', # 0xb1 +'Za', # 0xb2 +'Jo', # 0xb3 +'[?]', # 0xb4 +'Jjy', # 0xb5 +'Got', # 0xb6 +'Jjie', # 0xb7 +'Wo', # 0xb8 +'Du', # 0xb9 +'Shur', # 0xba +'Lie', # 0xbb +'Cy', # 0xbc +'Cuop', # 0xbd +'Cip', # 0xbe +'Hxop', # 0xbf +'Shat', # 0xc0 +'[?]', # 0xc1 +'Shop', # 0xc2 +'Che', # 0xc3 +'Zziet', # 0xc4 +'[?]', # 0xc5 +'Ke', # 0xc6 +'[?]', # 0xc7 +'[?]', # 0xc8 +'[?]', # 0xc9 +'[?]', # 0xca +'[?]', # 0xcb +'[?]', # 0xcc +'[?]', # 0xcd +'[?]', # 0xce +'[?]', # 0xcf +'[?]', # 0xd0 +'[?]', # 0xd1 +'[?]', # 0xd2 +'[?]', # 0xd3 +'[?]', # 0xd4 +'[?]', # 0xd5 +'[?]', # 0xd6 +'[?]', # 0xd7 +'[?]', # 0xd8 +'[?]', # 0xd9 +'[?]', # 0xda +'[?]', # 0xdb +'[?]', # 0xdc +'[?]', # 0xdd +'[?]', # 0xde +'[?]', # 0xdf +'[?]', # 0xe0 +'[?]', # 0xe1 +'[?]', # 0xe2 +'[?]', # 0xe3 +'[?]', # 0xe4 +'[?]', # 0xe5 +'[?]', # 0xe6 +'[?]', # 0xe7 +'[?]', # 0xe8 +'[?]', # 0xe9 +'[?]', # 0xea +'[?]', # 0xeb +'[?]', # 0xec +'[?]', # 0xed +'[?]', # 0xee +'[?]', # 0xef +'[?]', # 0xf0 +'[?]', # 0xf1 +'[?]', # 0xf2 +'[?]', # 0xf3 +'[?]', # 0xf4 +'[?]', # 0xf5 +'[?]', # 0xf6 +'[?]', # 0xf7 +'[?]', # 0xf8 +'[?]', # 0xf9 +'[?]', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x0ac.py b/libs/unidecode/x0ac.py new file mode 100644 index 00000000..e627fab7 --- /dev/null +++ b/libs/unidecode/x0ac.py @@ -0,0 +1,258 @@ +data = ( +'ga', # 0x00 +'gag', # 0x01 +'gagg', # 0x02 +'gags', # 0x03 +'gan', # 0x04 +'ganj', # 0x05 +'ganh', # 0x06 +'gad', # 0x07 +'gal', # 0x08 +'galg', # 0x09 +'galm', # 0x0a +'galb', # 0x0b +'gals', # 0x0c +'galt', # 0x0d +'galp', # 0x0e +'galh', # 0x0f +'gam', # 0x10 +'gab', # 0x11 +'gabs', # 0x12 +'gas', # 0x13 +'gass', # 0x14 +'gang', # 0x15 +'gaj', # 0x16 +'gac', # 0x17 +'gak', # 0x18 +'gat', # 0x19 +'gap', # 0x1a +'gah', # 0x1b +'gae', # 0x1c +'gaeg', # 0x1d +'gaegg', # 0x1e +'gaegs', # 0x1f +'gaen', # 0x20 +'gaenj', # 0x21 +'gaenh', # 0x22 +'gaed', # 0x23 +'gael', # 0x24 +'gaelg', # 0x25 +'gaelm', # 0x26 +'gaelb', # 0x27 +'gaels', # 0x28 +'gaelt', # 0x29 +'gaelp', # 0x2a +'gaelh', # 0x2b +'gaem', # 0x2c +'gaeb', # 0x2d +'gaebs', # 0x2e +'gaes', # 0x2f +'gaess', # 0x30 +'gaeng', # 0x31 +'gaej', # 0x32 +'gaec', # 0x33 +'gaek', # 0x34 +'gaet', # 0x35 +'gaep', # 0x36 +'gaeh', # 0x37 +'gya', # 0x38 +'gyag', # 0x39 +'gyagg', # 0x3a +'gyags', # 0x3b +'gyan', # 0x3c +'gyanj', # 0x3d +'gyanh', # 0x3e +'gyad', # 0x3f +'gyal', # 0x40 +'gyalg', # 0x41 +'gyalm', # 0x42 +'gyalb', # 0x43 +'gyals', # 0x44 +'gyalt', # 0x45 +'gyalp', # 0x46 +'gyalh', # 0x47 +'gyam', # 0x48 +'gyab', # 0x49 +'gyabs', # 0x4a +'gyas', # 0x4b +'gyass', # 0x4c +'gyang', # 0x4d +'gyaj', # 0x4e +'gyac', # 0x4f +'gyak', # 0x50 +'gyat', # 0x51 +'gyap', # 0x52 +'gyah', # 0x53 +'gyae', # 0x54 +'gyaeg', # 0x55 +'gyaegg', # 0x56 +'gyaegs', # 0x57 +'gyaen', # 0x58 +'gyaenj', # 0x59 +'gyaenh', # 0x5a +'gyaed', # 0x5b +'gyael', # 0x5c +'gyaelg', # 0x5d +'gyaelm', # 0x5e +'gyaelb', # 0x5f +'gyaels', # 0x60 +'gyaelt', # 0x61 +'gyaelp', # 0x62 +'gyaelh', # 0x63 +'gyaem', # 0x64 +'gyaeb', # 0x65 +'gyaebs', # 0x66 +'gyaes', # 0x67 +'gyaess', # 0x68 +'gyaeng', # 0x69 +'gyaej', # 0x6a +'gyaec', # 0x6b +'gyaek', # 0x6c +'gyaet', # 0x6d +'gyaep', # 0x6e +'gyaeh', # 0x6f +'geo', # 0x70 +'geog', # 0x71 +'geogg', # 0x72 +'geogs', # 0x73 +'geon', # 0x74 +'geonj', # 0x75 +'geonh', # 0x76 +'geod', # 0x77 +'geol', # 0x78 +'geolg', # 0x79 +'geolm', # 0x7a +'geolb', # 0x7b +'geols', # 0x7c +'geolt', # 0x7d +'geolp', # 0x7e +'geolh', # 0x7f +'geom', # 0x80 +'geob', # 0x81 +'geobs', # 0x82 +'geos', # 0x83 +'geoss', # 0x84 +'geong', # 0x85 +'geoj', # 0x86 +'geoc', # 0x87 +'geok', # 0x88 +'geot', # 0x89 +'geop', # 0x8a +'geoh', # 0x8b +'ge', # 0x8c +'geg', # 0x8d +'gegg', # 0x8e +'gegs', # 0x8f +'gen', # 0x90 +'genj', # 0x91 +'genh', # 0x92 +'ged', # 0x93 +'gel', # 0x94 +'gelg', # 0x95 +'gelm', # 0x96 +'gelb', # 0x97 +'gels', # 0x98 +'gelt', # 0x99 +'gelp', # 0x9a +'gelh', # 0x9b +'gem', # 0x9c +'geb', # 0x9d +'gebs', # 0x9e +'ges', # 0x9f +'gess', # 0xa0 +'geng', # 0xa1 +'gej', # 0xa2 +'gec', # 0xa3 +'gek', # 0xa4 +'get', # 0xa5 +'gep', # 0xa6 +'geh', # 0xa7 +'gyeo', # 0xa8 +'gyeog', # 0xa9 +'gyeogg', # 0xaa +'gyeogs', # 0xab +'gyeon', # 0xac +'gyeonj', # 0xad +'gyeonh', # 0xae +'gyeod', # 0xaf +'gyeol', # 0xb0 +'gyeolg', # 0xb1 +'gyeolm', # 0xb2 +'gyeolb', # 0xb3 +'gyeols', # 0xb4 +'gyeolt', # 0xb5 +'gyeolp', # 0xb6 +'gyeolh', # 0xb7 +'gyeom', # 0xb8 +'gyeob', # 0xb9 +'gyeobs', # 0xba +'gyeos', # 0xbb +'gyeoss', # 0xbc +'gyeong', # 0xbd +'gyeoj', # 0xbe +'gyeoc', # 0xbf +'gyeok', # 0xc0 +'gyeot', # 0xc1 +'gyeop', # 0xc2 +'gyeoh', # 0xc3 +'gye', # 0xc4 +'gyeg', # 0xc5 +'gyegg', # 0xc6 +'gyegs', # 0xc7 +'gyen', # 0xc8 +'gyenj', # 0xc9 +'gyenh', # 0xca +'gyed', # 0xcb +'gyel', # 0xcc +'gyelg', # 0xcd +'gyelm', # 0xce +'gyelb', # 0xcf +'gyels', # 0xd0 +'gyelt', # 0xd1 +'gyelp', # 0xd2 +'gyelh', # 0xd3 +'gyem', # 0xd4 +'gyeb', # 0xd5 +'gyebs', # 0xd6 +'gyes', # 0xd7 +'gyess', # 0xd8 +'gyeng', # 0xd9 +'gyej', # 0xda +'gyec', # 0xdb +'gyek', # 0xdc +'gyet', # 0xdd +'gyep', # 0xde +'gyeh', # 0xdf +'go', # 0xe0 +'gog', # 0xe1 +'gogg', # 0xe2 +'gogs', # 0xe3 +'gon', # 0xe4 +'gonj', # 0xe5 +'gonh', # 0xe6 +'god', # 0xe7 +'gol', # 0xe8 +'golg', # 0xe9 +'golm', # 0xea +'golb', # 0xeb +'gols', # 0xec +'golt', # 0xed +'golp', # 0xee +'golh', # 0xef +'gom', # 0xf0 +'gob', # 0xf1 +'gobs', # 0xf2 +'gos', # 0xf3 +'goss', # 0xf4 +'gong', # 0xf5 +'goj', # 0xf6 +'goc', # 0xf7 +'gok', # 0xf8 +'got', # 0xf9 +'gop', # 0xfa +'goh', # 0xfb +'gwa', # 0xfc +'gwag', # 0xfd +'gwagg', # 0xfe +'gwags', # 0xff +) diff --git a/libs/unidecode/x0ad.py b/libs/unidecode/x0ad.py new file mode 100644 index 00000000..ac2cf2a5 --- /dev/null +++ b/libs/unidecode/x0ad.py @@ -0,0 +1,258 @@ +data = ( +'gwan', # 0x00 +'gwanj', # 0x01 +'gwanh', # 0x02 +'gwad', # 0x03 +'gwal', # 0x04 +'gwalg', # 0x05 +'gwalm', # 0x06 +'gwalb', # 0x07 +'gwals', # 0x08 +'gwalt', # 0x09 +'gwalp', # 0x0a +'gwalh', # 0x0b +'gwam', # 0x0c +'gwab', # 0x0d +'gwabs', # 0x0e +'gwas', # 0x0f +'gwass', # 0x10 +'gwang', # 0x11 +'gwaj', # 0x12 +'gwac', # 0x13 +'gwak', # 0x14 +'gwat', # 0x15 +'gwap', # 0x16 +'gwah', # 0x17 +'gwae', # 0x18 +'gwaeg', # 0x19 +'gwaegg', # 0x1a +'gwaegs', # 0x1b +'gwaen', # 0x1c +'gwaenj', # 0x1d +'gwaenh', # 0x1e +'gwaed', # 0x1f +'gwael', # 0x20 +'gwaelg', # 0x21 +'gwaelm', # 0x22 +'gwaelb', # 0x23 +'gwaels', # 0x24 +'gwaelt', # 0x25 +'gwaelp', # 0x26 +'gwaelh', # 0x27 +'gwaem', # 0x28 +'gwaeb', # 0x29 +'gwaebs', # 0x2a +'gwaes', # 0x2b +'gwaess', # 0x2c +'gwaeng', # 0x2d +'gwaej', # 0x2e +'gwaec', # 0x2f +'gwaek', # 0x30 +'gwaet', # 0x31 +'gwaep', # 0x32 +'gwaeh', # 0x33 +'goe', # 0x34 +'goeg', # 0x35 +'goegg', # 0x36 +'goegs', # 0x37 +'goen', # 0x38 +'goenj', # 0x39 +'goenh', # 0x3a +'goed', # 0x3b +'goel', # 0x3c +'goelg', # 0x3d +'goelm', # 0x3e +'goelb', # 0x3f +'goels', # 0x40 +'goelt', # 0x41 +'goelp', # 0x42 +'goelh', # 0x43 +'goem', # 0x44 +'goeb', # 0x45 +'goebs', # 0x46 +'goes', # 0x47 +'goess', # 0x48 +'goeng', # 0x49 +'goej', # 0x4a +'goec', # 0x4b +'goek', # 0x4c +'goet', # 0x4d +'goep', # 0x4e +'goeh', # 0x4f +'gyo', # 0x50 +'gyog', # 0x51 +'gyogg', # 0x52 +'gyogs', # 0x53 +'gyon', # 0x54 +'gyonj', # 0x55 +'gyonh', # 0x56 +'gyod', # 0x57 +'gyol', # 0x58 +'gyolg', # 0x59 +'gyolm', # 0x5a +'gyolb', # 0x5b +'gyols', # 0x5c +'gyolt', # 0x5d +'gyolp', # 0x5e +'gyolh', # 0x5f +'gyom', # 0x60 +'gyob', # 0x61 +'gyobs', # 0x62 +'gyos', # 0x63 +'gyoss', # 0x64 +'gyong', # 0x65 +'gyoj', # 0x66 +'gyoc', # 0x67 +'gyok', # 0x68 +'gyot', # 0x69 +'gyop', # 0x6a +'gyoh', # 0x6b +'gu', # 0x6c +'gug', # 0x6d +'gugg', # 0x6e +'gugs', # 0x6f +'gun', # 0x70 +'gunj', # 0x71 +'gunh', # 0x72 +'gud', # 0x73 +'gul', # 0x74 +'gulg', # 0x75 +'gulm', # 0x76 +'gulb', # 0x77 +'guls', # 0x78 +'gult', # 0x79 +'gulp', # 0x7a +'gulh', # 0x7b +'gum', # 0x7c +'gub', # 0x7d +'gubs', # 0x7e +'gus', # 0x7f +'guss', # 0x80 +'gung', # 0x81 +'guj', # 0x82 +'guc', # 0x83 +'guk', # 0x84 +'gut', # 0x85 +'gup', # 0x86 +'guh', # 0x87 +'gweo', # 0x88 +'gweog', # 0x89 +'gweogg', # 0x8a +'gweogs', # 0x8b +'gweon', # 0x8c +'gweonj', # 0x8d +'gweonh', # 0x8e +'gweod', # 0x8f +'gweol', # 0x90 +'gweolg', # 0x91 +'gweolm', # 0x92 +'gweolb', # 0x93 +'gweols', # 0x94 +'gweolt', # 0x95 +'gweolp', # 0x96 +'gweolh', # 0x97 +'gweom', # 0x98 +'gweob', # 0x99 +'gweobs', # 0x9a +'gweos', # 0x9b +'gweoss', # 0x9c +'gweong', # 0x9d +'gweoj', # 0x9e +'gweoc', # 0x9f +'gweok', # 0xa0 +'gweot', # 0xa1 +'gweop', # 0xa2 +'gweoh', # 0xa3 +'gwe', # 0xa4 +'gweg', # 0xa5 +'gwegg', # 0xa6 +'gwegs', # 0xa7 +'gwen', # 0xa8 +'gwenj', # 0xa9 +'gwenh', # 0xaa +'gwed', # 0xab +'gwel', # 0xac +'gwelg', # 0xad +'gwelm', # 0xae +'gwelb', # 0xaf +'gwels', # 0xb0 +'gwelt', # 0xb1 +'gwelp', # 0xb2 +'gwelh', # 0xb3 +'gwem', # 0xb4 +'gweb', # 0xb5 +'gwebs', # 0xb6 +'gwes', # 0xb7 +'gwess', # 0xb8 +'gweng', # 0xb9 +'gwej', # 0xba +'gwec', # 0xbb +'gwek', # 0xbc +'gwet', # 0xbd +'gwep', # 0xbe +'gweh', # 0xbf +'gwi', # 0xc0 +'gwig', # 0xc1 +'gwigg', # 0xc2 +'gwigs', # 0xc3 +'gwin', # 0xc4 +'gwinj', # 0xc5 +'gwinh', # 0xc6 +'gwid', # 0xc7 +'gwil', # 0xc8 +'gwilg', # 0xc9 +'gwilm', # 0xca +'gwilb', # 0xcb +'gwils', # 0xcc +'gwilt', # 0xcd +'gwilp', # 0xce +'gwilh', # 0xcf +'gwim', # 0xd0 +'gwib', # 0xd1 +'gwibs', # 0xd2 +'gwis', # 0xd3 +'gwiss', # 0xd4 +'gwing', # 0xd5 +'gwij', # 0xd6 +'gwic', # 0xd7 +'gwik', # 0xd8 +'gwit', # 0xd9 +'gwip', # 0xda +'gwih', # 0xdb +'gyu', # 0xdc +'gyug', # 0xdd +'gyugg', # 0xde +'gyugs', # 0xdf +'gyun', # 0xe0 +'gyunj', # 0xe1 +'gyunh', # 0xe2 +'gyud', # 0xe3 +'gyul', # 0xe4 +'gyulg', # 0xe5 +'gyulm', # 0xe6 +'gyulb', # 0xe7 +'gyuls', # 0xe8 +'gyult', # 0xe9 +'gyulp', # 0xea +'gyulh', # 0xeb +'gyum', # 0xec +'gyub', # 0xed +'gyubs', # 0xee +'gyus', # 0xef +'gyuss', # 0xf0 +'gyung', # 0xf1 +'gyuj', # 0xf2 +'gyuc', # 0xf3 +'gyuk', # 0xf4 +'gyut', # 0xf5 +'gyup', # 0xf6 +'gyuh', # 0xf7 +'geu', # 0xf8 +'geug', # 0xf9 +'geugg', # 0xfa +'geugs', # 0xfb +'geun', # 0xfc +'geunj', # 0xfd +'geunh', # 0xfe +'geud', # 0xff +) diff --git a/libs/unidecode/x0ae.py b/libs/unidecode/x0ae.py new file mode 100644 index 00000000..37a7abca --- /dev/null +++ b/libs/unidecode/x0ae.py @@ -0,0 +1,258 @@ +data = ( +'geul', # 0x00 +'geulg', # 0x01 +'geulm', # 0x02 +'geulb', # 0x03 +'geuls', # 0x04 +'geult', # 0x05 +'geulp', # 0x06 +'geulh', # 0x07 +'geum', # 0x08 +'geub', # 0x09 +'geubs', # 0x0a +'geus', # 0x0b +'geuss', # 0x0c +'geung', # 0x0d +'geuj', # 0x0e +'geuc', # 0x0f +'geuk', # 0x10 +'geut', # 0x11 +'geup', # 0x12 +'geuh', # 0x13 +'gyi', # 0x14 +'gyig', # 0x15 +'gyigg', # 0x16 +'gyigs', # 0x17 +'gyin', # 0x18 +'gyinj', # 0x19 +'gyinh', # 0x1a +'gyid', # 0x1b +'gyil', # 0x1c +'gyilg', # 0x1d +'gyilm', # 0x1e +'gyilb', # 0x1f +'gyils', # 0x20 +'gyilt', # 0x21 +'gyilp', # 0x22 +'gyilh', # 0x23 +'gyim', # 0x24 +'gyib', # 0x25 +'gyibs', # 0x26 +'gyis', # 0x27 +'gyiss', # 0x28 +'gying', # 0x29 +'gyij', # 0x2a +'gyic', # 0x2b +'gyik', # 0x2c +'gyit', # 0x2d +'gyip', # 0x2e +'gyih', # 0x2f +'gi', # 0x30 +'gig', # 0x31 +'gigg', # 0x32 +'gigs', # 0x33 +'gin', # 0x34 +'ginj', # 0x35 +'ginh', # 0x36 +'gid', # 0x37 +'gil', # 0x38 +'gilg', # 0x39 +'gilm', # 0x3a +'gilb', # 0x3b +'gils', # 0x3c +'gilt', # 0x3d +'gilp', # 0x3e +'gilh', # 0x3f +'gim', # 0x40 +'gib', # 0x41 +'gibs', # 0x42 +'gis', # 0x43 +'giss', # 0x44 +'ging', # 0x45 +'gij', # 0x46 +'gic', # 0x47 +'gik', # 0x48 +'git', # 0x49 +'gip', # 0x4a +'gih', # 0x4b +'gga', # 0x4c +'ggag', # 0x4d +'ggagg', # 0x4e +'ggags', # 0x4f +'ggan', # 0x50 +'gganj', # 0x51 +'gganh', # 0x52 +'ggad', # 0x53 +'ggal', # 0x54 +'ggalg', # 0x55 +'ggalm', # 0x56 +'ggalb', # 0x57 +'ggals', # 0x58 +'ggalt', # 0x59 +'ggalp', # 0x5a +'ggalh', # 0x5b +'ggam', # 0x5c +'ggab', # 0x5d +'ggabs', # 0x5e +'ggas', # 0x5f +'ggass', # 0x60 +'ggang', # 0x61 +'ggaj', # 0x62 +'ggac', # 0x63 +'ggak', # 0x64 +'ggat', # 0x65 +'ggap', # 0x66 +'ggah', # 0x67 +'ggae', # 0x68 +'ggaeg', # 0x69 +'ggaegg', # 0x6a +'ggaegs', # 0x6b +'ggaen', # 0x6c +'ggaenj', # 0x6d +'ggaenh', # 0x6e +'ggaed', # 0x6f +'ggael', # 0x70 +'ggaelg', # 0x71 +'ggaelm', # 0x72 +'ggaelb', # 0x73 +'ggaels', # 0x74 +'ggaelt', # 0x75 +'ggaelp', # 0x76 +'ggaelh', # 0x77 +'ggaem', # 0x78 +'ggaeb', # 0x79 +'ggaebs', # 0x7a +'ggaes', # 0x7b +'ggaess', # 0x7c +'ggaeng', # 0x7d +'ggaej', # 0x7e +'ggaec', # 0x7f +'ggaek', # 0x80 +'ggaet', # 0x81 +'ggaep', # 0x82 +'ggaeh', # 0x83 +'ggya', # 0x84 +'ggyag', # 0x85 +'ggyagg', # 0x86 +'ggyags', # 0x87 +'ggyan', # 0x88 +'ggyanj', # 0x89 +'ggyanh', # 0x8a +'ggyad', # 0x8b +'ggyal', # 0x8c +'ggyalg', # 0x8d +'ggyalm', # 0x8e +'ggyalb', # 0x8f +'ggyals', # 0x90 +'ggyalt', # 0x91 +'ggyalp', # 0x92 +'ggyalh', # 0x93 +'ggyam', # 0x94 +'ggyab', # 0x95 +'ggyabs', # 0x96 +'ggyas', # 0x97 +'ggyass', # 0x98 +'ggyang', # 0x99 +'ggyaj', # 0x9a +'ggyac', # 0x9b +'ggyak', # 0x9c +'ggyat', # 0x9d +'ggyap', # 0x9e +'ggyah', # 0x9f +'ggyae', # 0xa0 +'ggyaeg', # 0xa1 +'ggyaegg', # 0xa2 +'ggyaegs', # 0xa3 +'ggyaen', # 0xa4 +'ggyaenj', # 0xa5 +'ggyaenh', # 0xa6 +'ggyaed', # 0xa7 +'ggyael', # 0xa8 +'ggyaelg', # 0xa9 +'ggyaelm', # 0xaa +'ggyaelb', # 0xab +'ggyaels', # 0xac +'ggyaelt', # 0xad +'ggyaelp', # 0xae +'ggyaelh', # 0xaf +'ggyaem', # 0xb0 +'ggyaeb', # 0xb1 +'ggyaebs', # 0xb2 +'ggyaes', # 0xb3 +'ggyaess', # 0xb4 +'ggyaeng', # 0xb5 +'ggyaej', # 0xb6 +'ggyaec', # 0xb7 +'ggyaek', # 0xb8 +'ggyaet', # 0xb9 +'ggyaep', # 0xba +'ggyaeh', # 0xbb +'ggeo', # 0xbc +'ggeog', # 0xbd +'ggeogg', # 0xbe +'ggeogs', # 0xbf +'ggeon', # 0xc0 +'ggeonj', # 0xc1 +'ggeonh', # 0xc2 +'ggeod', # 0xc3 +'ggeol', # 0xc4 +'ggeolg', # 0xc5 +'ggeolm', # 0xc6 +'ggeolb', # 0xc7 +'ggeols', # 0xc8 +'ggeolt', # 0xc9 +'ggeolp', # 0xca +'ggeolh', # 0xcb +'ggeom', # 0xcc +'ggeob', # 0xcd +'ggeobs', # 0xce +'ggeos', # 0xcf +'ggeoss', # 0xd0 +'ggeong', # 0xd1 +'ggeoj', # 0xd2 +'ggeoc', # 0xd3 +'ggeok', # 0xd4 +'ggeot', # 0xd5 +'ggeop', # 0xd6 +'ggeoh', # 0xd7 +'gge', # 0xd8 +'ggeg', # 0xd9 +'ggegg', # 0xda +'ggegs', # 0xdb +'ggen', # 0xdc +'ggenj', # 0xdd +'ggenh', # 0xde +'gged', # 0xdf +'ggel', # 0xe0 +'ggelg', # 0xe1 +'ggelm', # 0xe2 +'ggelb', # 0xe3 +'ggels', # 0xe4 +'ggelt', # 0xe5 +'ggelp', # 0xe6 +'ggelh', # 0xe7 +'ggem', # 0xe8 +'ggeb', # 0xe9 +'ggebs', # 0xea +'gges', # 0xeb +'ggess', # 0xec +'ggeng', # 0xed +'ggej', # 0xee +'ggec', # 0xef +'ggek', # 0xf0 +'gget', # 0xf1 +'ggep', # 0xf2 +'ggeh', # 0xf3 +'ggyeo', # 0xf4 +'ggyeog', # 0xf5 +'ggyeogg', # 0xf6 +'ggyeogs', # 0xf7 +'ggyeon', # 0xf8 +'ggyeonj', # 0xf9 +'ggyeonh', # 0xfa +'ggyeod', # 0xfb +'ggyeol', # 0xfc +'ggyeolg', # 0xfd +'ggyeolm', # 0xfe +'ggyeolb', # 0xff +) diff --git a/libs/unidecode/x0af.py b/libs/unidecode/x0af.py new file mode 100644 index 00000000..448d26bf --- /dev/null +++ b/libs/unidecode/x0af.py @@ -0,0 +1,258 @@ +data = ( +'ggyeols', # 0x00 +'ggyeolt', # 0x01 +'ggyeolp', # 0x02 +'ggyeolh', # 0x03 +'ggyeom', # 0x04 +'ggyeob', # 0x05 +'ggyeobs', # 0x06 +'ggyeos', # 0x07 +'ggyeoss', # 0x08 +'ggyeong', # 0x09 +'ggyeoj', # 0x0a +'ggyeoc', # 0x0b +'ggyeok', # 0x0c +'ggyeot', # 0x0d +'ggyeop', # 0x0e +'ggyeoh', # 0x0f +'ggye', # 0x10 +'ggyeg', # 0x11 +'ggyegg', # 0x12 +'ggyegs', # 0x13 +'ggyen', # 0x14 +'ggyenj', # 0x15 +'ggyenh', # 0x16 +'ggyed', # 0x17 +'ggyel', # 0x18 +'ggyelg', # 0x19 +'ggyelm', # 0x1a +'ggyelb', # 0x1b +'ggyels', # 0x1c +'ggyelt', # 0x1d +'ggyelp', # 0x1e +'ggyelh', # 0x1f +'ggyem', # 0x20 +'ggyeb', # 0x21 +'ggyebs', # 0x22 +'ggyes', # 0x23 +'ggyess', # 0x24 +'ggyeng', # 0x25 +'ggyej', # 0x26 +'ggyec', # 0x27 +'ggyek', # 0x28 +'ggyet', # 0x29 +'ggyep', # 0x2a +'ggyeh', # 0x2b +'ggo', # 0x2c +'ggog', # 0x2d +'ggogg', # 0x2e +'ggogs', # 0x2f +'ggon', # 0x30 +'ggonj', # 0x31 +'ggonh', # 0x32 +'ggod', # 0x33 +'ggol', # 0x34 +'ggolg', # 0x35 +'ggolm', # 0x36 +'ggolb', # 0x37 +'ggols', # 0x38 +'ggolt', # 0x39 +'ggolp', # 0x3a +'ggolh', # 0x3b +'ggom', # 0x3c +'ggob', # 0x3d +'ggobs', # 0x3e +'ggos', # 0x3f +'ggoss', # 0x40 +'ggong', # 0x41 +'ggoj', # 0x42 +'ggoc', # 0x43 +'ggok', # 0x44 +'ggot', # 0x45 +'ggop', # 0x46 +'ggoh', # 0x47 +'ggwa', # 0x48 +'ggwag', # 0x49 +'ggwagg', # 0x4a +'ggwags', # 0x4b +'ggwan', # 0x4c +'ggwanj', # 0x4d +'ggwanh', # 0x4e +'ggwad', # 0x4f +'ggwal', # 0x50 +'ggwalg', # 0x51 +'ggwalm', # 0x52 +'ggwalb', # 0x53 +'ggwals', # 0x54 +'ggwalt', # 0x55 +'ggwalp', # 0x56 +'ggwalh', # 0x57 +'ggwam', # 0x58 +'ggwab', # 0x59 +'ggwabs', # 0x5a +'ggwas', # 0x5b +'ggwass', # 0x5c +'ggwang', # 0x5d +'ggwaj', # 0x5e +'ggwac', # 0x5f +'ggwak', # 0x60 +'ggwat', # 0x61 +'ggwap', # 0x62 +'ggwah', # 0x63 +'ggwae', # 0x64 +'ggwaeg', # 0x65 +'ggwaegg', # 0x66 +'ggwaegs', # 0x67 +'ggwaen', # 0x68 +'ggwaenj', # 0x69 +'ggwaenh', # 0x6a +'ggwaed', # 0x6b +'ggwael', # 0x6c +'ggwaelg', # 0x6d +'ggwaelm', # 0x6e +'ggwaelb', # 0x6f +'ggwaels', # 0x70 +'ggwaelt', # 0x71 +'ggwaelp', # 0x72 +'ggwaelh', # 0x73 +'ggwaem', # 0x74 +'ggwaeb', # 0x75 +'ggwaebs', # 0x76 +'ggwaes', # 0x77 +'ggwaess', # 0x78 +'ggwaeng', # 0x79 +'ggwaej', # 0x7a +'ggwaec', # 0x7b +'ggwaek', # 0x7c +'ggwaet', # 0x7d +'ggwaep', # 0x7e +'ggwaeh', # 0x7f +'ggoe', # 0x80 +'ggoeg', # 0x81 +'ggoegg', # 0x82 +'ggoegs', # 0x83 +'ggoen', # 0x84 +'ggoenj', # 0x85 +'ggoenh', # 0x86 +'ggoed', # 0x87 +'ggoel', # 0x88 +'ggoelg', # 0x89 +'ggoelm', # 0x8a +'ggoelb', # 0x8b +'ggoels', # 0x8c +'ggoelt', # 0x8d +'ggoelp', # 0x8e +'ggoelh', # 0x8f +'ggoem', # 0x90 +'ggoeb', # 0x91 +'ggoebs', # 0x92 +'ggoes', # 0x93 +'ggoess', # 0x94 +'ggoeng', # 0x95 +'ggoej', # 0x96 +'ggoec', # 0x97 +'ggoek', # 0x98 +'ggoet', # 0x99 +'ggoep', # 0x9a +'ggoeh', # 0x9b +'ggyo', # 0x9c +'ggyog', # 0x9d +'ggyogg', # 0x9e +'ggyogs', # 0x9f +'ggyon', # 0xa0 +'ggyonj', # 0xa1 +'ggyonh', # 0xa2 +'ggyod', # 0xa3 +'ggyol', # 0xa4 +'ggyolg', # 0xa5 +'ggyolm', # 0xa6 +'ggyolb', # 0xa7 +'ggyols', # 0xa8 +'ggyolt', # 0xa9 +'ggyolp', # 0xaa +'ggyolh', # 0xab +'ggyom', # 0xac +'ggyob', # 0xad +'ggyobs', # 0xae +'ggyos', # 0xaf +'ggyoss', # 0xb0 +'ggyong', # 0xb1 +'ggyoj', # 0xb2 +'ggyoc', # 0xb3 +'ggyok', # 0xb4 +'ggyot', # 0xb5 +'ggyop', # 0xb6 +'ggyoh', # 0xb7 +'ggu', # 0xb8 +'ggug', # 0xb9 +'ggugg', # 0xba +'ggugs', # 0xbb +'ggun', # 0xbc +'ggunj', # 0xbd +'ggunh', # 0xbe +'ggud', # 0xbf +'ggul', # 0xc0 +'ggulg', # 0xc1 +'ggulm', # 0xc2 +'ggulb', # 0xc3 +'gguls', # 0xc4 +'ggult', # 0xc5 +'ggulp', # 0xc6 +'ggulh', # 0xc7 +'ggum', # 0xc8 +'ggub', # 0xc9 +'ggubs', # 0xca +'ggus', # 0xcb +'gguss', # 0xcc +'ggung', # 0xcd +'gguj', # 0xce +'gguc', # 0xcf +'gguk', # 0xd0 +'ggut', # 0xd1 +'ggup', # 0xd2 +'gguh', # 0xd3 +'ggweo', # 0xd4 +'ggweog', # 0xd5 +'ggweogg', # 0xd6 +'ggweogs', # 0xd7 +'ggweon', # 0xd8 +'ggweonj', # 0xd9 +'ggweonh', # 0xda +'ggweod', # 0xdb +'ggweol', # 0xdc +'ggweolg', # 0xdd +'ggweolm', # 0xde +'ggweolb', # 0xdf +'ggweols', # 0xe0 +'ggweolt', # 0xe1 +'ggweolp', # 0xe2 +'ggweolh', # 0xe3 +'ggweom', # 0xe4 +'ggweob', # 0xe5 +'ggweobs', # 0xe6 +'ggweos', # 0xe7 +'ggweoss', # 0xe8 +'ggweong', # 0xe9 +'ggweoj', # 0xea +'ggweoc', # 0xeb +'ggweok', # 0xec +'ggweot', # 0xed +'ggweop', # 0xee +'ggweoh', # 0xef +'ggwe', # 0xf0 +'ggweg', # 0xf1 +'ggwegg', # 0xf2 +'ggwegs', # 0xf3 +'ggwen', # 0xf4 +'ggwenj', # 0xf5 +'ggwenh', # 0xf6 +'ggwed', # 0xf7 +'ggwel', # 0xf8 +'ggwelg', # 0xf9 +'ggwelm', # 0xfa +'ggwelb', # 0xfb +'ggwels', # 0xfc +'ggwelt', # 0xfd +'ggwelp', # 0xfe +'ggwelh', # 0xff +) diff --git a/libs/unidecode/x0b0.py b/libs/unidecode/x0b0.py new file mode 100644 index 00000000..20f41b3e --- /dev/null +++ b/libs/unidecode/x0b0.py @@ -0,0 +1,258 @@ +data = ( +'ggwem', # 0x00 +'ggweb', # 0x01 +'ggwebs', # 0x02 +'ggwes', # 0x03 +'ggwess', # 0x04 +'ggweng', # 0x05 +'ggwej', # 0x06 +'ggwec', # 0x07 +'ggwek', # 0x08 +'ggwet', # 0x09 +'ggwep', # 0x0a +'ggweh', # 0x0b +'ggwi', # 0x0c +'ggwig', # 0x0d +'ggwigg', # 0x0e +'ggwigs', # 0x0f +'ggwin', # 0x10 +'ggwinj', # 0x11 +'ggwinh', # 0x12 +'ggwid', # 0x13 +'ggwil', # 0x14 +'ggwilg', # 0x15 +'ggwilm', # 0x16 +'ggwilb', # 0x17 +'ggwils', # 0x18 +'ggwilt', # 0x19 +'ggwilp', # 0x1a +'ggwilh', # 0x1b +'ggwim', # 0x1c +'ggwib', # 0x1d +'ggwibs', # 0x1e +'ggwis', # 0x1f +'ggwiss', # 0x20 +'ggwing', # 0x21 +'ggwij', # 0x22 +'ggwic', # 0x23 +'ggwik', # 0x24 +'ggwit', # 0x25 +'ggwip', # 0x26 +'ggwih', # 0x27 +'ggyu', # 0x28 +'ggyug', # 0x29 +'ggyugg', # 0x2a +'ggyugs', # 0x2b +'ggyun', # 0x2c +'ggyunj', # 0x2d +'ggyunh', # 0x2e +'ggyud', # 0x2f +'ggyul', # 0x30 +'ggyulg', # 0x31 +'ggyulm', # 0x32 +'ggyulb', # 0x33 +'ggyuls', # 0x34 +'ggyult', # 0x35 +'ggyulp', # 0x36 +'ggyulh', # 0x37 +'ggyum', # 0x38 +'ggyub', # 0x39 +'ggyubs', # 0x3a +'ggyus', # 0x3b +'ggyuss', # 0x3c +'ggyung', # 0x3d +'ggyuj', # 0x3e +'ggyuc', # 0x3f +'ggyuk', # 0x40 +'ggyut', # 0x41 +'ggyup', # 0x42 +'ggyuh', # 0x43 +'ggeu', # 0x44 +'ggeug', # 0x45 +'ggeugg', # 0x46 +'ggeugs', # 0x47 +'ggeun', # 0x48 +'ggeunj', # 0x49 +'ggeunh', # 0x4a +'ggeud', # 0x4b +'ggeul', # 0x4c +'ggeulg', # 0x4d +'ggeulm', # 0x4e +'ggeulb', # 0x4f +'ggeuls', # 0x50 +'ggeult', # 0x51 +'ggeulp', # 0x52 +'ggeulh', # 0x53 +'ggeum', # 0x54 +'ggeub', # 0x55 +'ggeubs', # 0x56 +'ggeus', # 0x57 +'ggeuss', # 0x58 +'ggeung', # 0x59 +'ggeuj', # 0x5a +'ggeuc', # 0x5b +'ggeuk', # 0x5c +'ggeut', # 0x5d +'ggeup', # 0x5e +'ggeuh', # 0x5f +'ggyi', # 0x60 +'ggyig', # 0x61 +'ggyigg', # 0x62 +'ggyigs', # 0x63 +'ggyin', # 0x64 +'ggyinj', # 0x65 +'ggyinh', # 0x66 +'ggyid', # 0x67 +'ggyil', # 0x68 +'ggyilg', # 0x69 +'ggyilm', # 0x6a +'ggyilb', # 0x6b +'ggyils', # 0x6c +'ggyilt', # 0x6d +'ggyilp', # 0x6e +'ggyilh', # 0x6f +'ggyim', # 0x70 +'ggyib', # 0x71 +'ggyibs', # 0x72 +'ggyis', # 0x73 +'ggyiss', # 0x74 +'ggying', # 0x75 +'ggyij', # 0x76 +'ggyic', # 0x77 +'ggyik', # 0x78 +'ggyit', # 0x79 +'ggyip', # 0x7a +'ggyih', # 0x7b +'ggi', # 0x7c +'ggig', # 0x7d +'ggigg', # 0x7e +'ggigs', # 0x7f +'ggin', # 0x80 +'gginj', # 0x81 +'gginh', # 0x82 +'ggid', # 0x83 +'ggil', # 0x84 +'ggilg', # 0x85 +'ggilm', # 0x86 +'ggilb', # 0x87 +'ggils', # 0x88 +'ggilt', # 0x89 +'ggilp', # 0x8a +'ggilh', # 0x8b +'ggim', # 0x8c +'ggib', # 0x8d +'ggibs', # 0x8e +'ggis', # 0x8f +'ggiss', # 0x90 +'gging', # 0x91 +'ggij', # 0x92 +'ggic', # 0x93 +'ggik', # 0x94 +'ggit', # 0x95 +'ggip', # 0x96 +'ggih', # 0x97 +'na', # 0x98 +'nag', # 0x99 +'nagg', # 0x9a +'nags', # 0x9b +'nan', # 0x9c +'nanj', # 0x9d +'nanh', # 0x9e +'nad', # 0x9f +'nal', # 0xa0 +'nalg', # 0xa1 +'nalm', # 0xa2 +'nalb', # 0xa3 +'nals', # 0xa4 +'nalt', # 0xa5 +'nalp', # 0xa6 +'nalh', # 0xa7 +'nam', # 0xa8 +'nab', # 0xa9 +'nabs', # 0xaa +'nas', # 0xab +'nass', # 0xac +'nang', # 0xad +'naj', # 0xae +'nac', # 0xaf +'nak', # 0xb0 +'nat', # 0xb1 +'nap', # 0xb2 +'nah', # 0xb3 +'nae', # 0xb4 +'naeg', # 0xb5 +'naegg', # 0xb6 +'naegs', # 0xb7 +'naen', # 0xb8 +'naenj', # 0xb9 +'naenh', # 0xba +'naed', # 0xbb +'nael', # 0xbc +'naelg', # 0xbd +'naelm', # 0xbe +'naelb', # 0xbf +'naels', # 0xc0 +'naelt', # 0xc1 +'naelp', # 0xc2 +'naelh', # 0xc3 +'naem', # 0xc4 +'naeb', # 0xc5 +'naebs', # 0xc6 +'naes', # 0xc7 +'naess', # 0xc8 +'naeng', # 0xc9 +'naej', # 0xca +'naec', # 0xcb +'naek', # 0xcc +'naet', # 0xcd +'naep', # 0xce +'naeh', # 0xcf +'nya', # 0xd0 +'nyag', # 0xd1 +'nyagg', # 0xd2 +'nyags', # 0xd3 +'nyan', # 0xd4 +'nyanj', # 0xd5 +'nyanh', # 0xd6 +'nyad', # 0xd7 +'nyal', # 0xd8 +'nyalg', # 0xd9 +'nyalm', # 0xda +'nyalb', # 0xdb +'nyals', # 0xdc +'nyalt', # 0xdd +'nyalp', # 0xde +'nyalh', # 0xdf +'nyam', # 0xe0 +'nyab', # 0xe1 +'nyabs', # 0xe2 +'nyas', # 0xe3 +'nyass', # 0xe4 +'nyang', # 0xe5 +'nyaj', # 0xe6 +'nyac', # 0xe7 +'nyak', # 0xe8 +'nyat', # 0xe9 +'nyap', # 0xea +'nyah', # 0xeb +'nyae', # 0xec +'nyaeg', # 0xed +'nyaegg', # 0xee +'nyaegs', # 0xef +'nyaen', # 0xf0 +'nyaenj', # 0xf1 +'nyaenh', # 0xf2 +'nyaed', # 0xf3 +'nyael', # 0xf4 +'nyaelg', # 0xf5 +'nyaelm', # 0xf6 +'nyaelb', # 0xf7 +'nyaels', # 0xf8 +'nyaelt', # 0xf9 +'nyaelp', # 0xfa +'nyaelh', # 0xfb +'nyaem', # 0xfc +'nyaeb', # 0xfd +'nyaebs', # 0xfe +'nyaes', # 0xff +) diff --git a/libs/unidecode/x0b1.py b/libs/unidecode/x0b1.py new file mode 100644 index 00000000..5aabeae2 --- /dev/null +++ b/libs/unidecode/x0b1.py @@ -0,0 +1,258 @@ +data = ( +'nyaess', # 0x00 +'nyaeng', # 0x01 +'nyaej', # 0x02 +'nyaec', # 0x03 +'nyaek', # 0x04 +'nyaet', # 0x05 +'nyaep', # 0x06 +'nyaeh', # 0x07 +'neo', # 0x08 +'neog', # 0x09 +'neogg', # 0x0a +'neogs', # 0x0b +'neon', # 0x0c +'neonj', # 0x0d +'neonh', # 0x0e +'neod', # 0x0f +'neol', # 0x10 +'neolg', # 0x11 +'neolm', # 0x12 +'neolb', # 0x13 +'neols', # 0x14 +'neolt', # 0x15 +'neolp', # 0x16 +'neolh', # 0x17 +'neom', # 0x18 +'neob', # 0x19 +'neobs', # 0x1a +'neos', # 0x1b +'neoss', # 0x1c +'neong', # 0x1d +'neoj', # 0x1e +'neoc', # 0x1f +'neok', # 0x20 +'neot', # 0x21 +'neop', # 0x22 +'neoh', # 0x23 +'ne', # 0x24 +'neg', # 0x25 +'negg', # 0x26 +'negs', # 0x27 +'nen', # 0x28 +'nenj', # 0x29 +'nenh', # 0x2a +'ned', # 0x2b +'nel', # 0x2c +'nelg', # 0x2d +'nelm', # 0x2e +'nelb', # 0x2f +'nels', # 0x30 +'nelt', # 0x31 +'nelp', # 0x32 +'nelh', # 0x33 +'nem', # 0x34 +'neb', # 0x35 +'nebs', # 0x36 +'nes', # 0x37 +'ness', # 0x38 +'neng', # 0x39 +'nej', # 0x3a +'nec', # 0x3b +'nek', # 0x3c +'net', # 0x3d +'nep', # 0x3e +'neh', # 0x3f +'nyeo', # 0x40 +'nyeog', # 0x41 +'nyeogg', # 0x42 +'nyeogs', # 0x43 +'nyeon', # 0x44 +'nyeonj', # 0x45 +'nyeonh', # 0x46 +'nyeod', # 0x47 +'nyeol', # 0x48 +'nyeolg', # 0x49 +'nyeolm', # 0x4a +'nyeolb', # 0x4b +'nyeols', # 0x4c +'nyeolt', # 0x4d +'nyeolp', # 0x4e +'nyeolh', # 0x4f +'nyeom', # 0x50 +'nyeob', # 0x51 +'nyeobs', # 0x52 +'nyeos', # 0x53 +'nyeoss', # 0x54 +'nyeong', # 0x55 +'nyeoj', # 0x56 +'nyeoc', # 0x57 +'nyeok', # 0x58 +'nyeot', # 0x59 +'nyeop', # 0x5a +'nyeoh', # 0x5b +'nye', # 0x5c +'nyeg', # 0x5d +'nyegg', # 0x5e +'nyegs', # 0x5f +'nyen', # 0x60 +'nyenj', # 0x61 +'nyenh', # 0x62 +'nyed', # 0x63 +'nyel', # 0x64 +'nyelg', # 0x65 +'nyelm', # 0x66 +'nyelb', # 0x67 +'nyels', # 0x68 +'nyelt', # 0x69 +'nyelp', # 0x6a +'nyelh', # 0x6b +'nyem', # 0x6c +'nyeb', # 0x6d +'nyebs', # 0x6e +'nyes', # 0x6f +'nyess', # 0x70 +'nyeng', # 0x71 +'nyej', # 0x72 +'nyec', # 0x73 +'nyek', # 0x74 +'nyet', # 0x75 +'nyep', # 0x76 +'nyeh', # 0x77 +'no', # 0x78 +'nog', # 0x79 +'nogg', # 0x7a +'nogs', # 0x7b +'non', # 0x7c +'nonj', # 0x7d +'nonh', # 0x7e +'nod', # 0x7f +'nol', # 0x80 +'nolg', # 0x81 +'nolm', # 0x82 +'nolb', # 0x83 +'nols', # 0x84 +'nolt', # 0x85 +'nolp', # 0x86 +'nolh', # 0x87 +'nom', # 0x88 +'nob', # 0x89 +'nobs', # 0x8a +'nos', # 0x8b +'noss', # 0x8c +'nong', # 0x8d +'noj', # 0x8e +'noc', # 0x8f +'nok', # 0x90 +'not', # 0x91 +'nop', # 0x92 +'noh', # 0x93 +'nwa', # 0x94 +'nwag', # 0x95 +'nwagg', # 0x96 +'nwags', # 0x97 +'nwan', # 0x98 +'nwanj', # 0x99 +'nwanh', # 0x9a +'nwad', # 0x9b +'nwal', # 0x9c +'nwalg', # 0x9d +'nwalm', # 0x9e +'nwalb', # 0x9f +'nwals', # 0xa0 +'nwalt', # 0xa1 +'nwalp', # 0xa2 +'nwalh', # 0xa3 +'nwam', # 0xa4 +'nwab', # 0xa5 +'nwabs', # 0xa6 +'nwas', # 0xa7 +'nwass', # 0xa8 +'nwang', # 0xa9 +'nwaj', # 0xaa +'nwac', # 0xab +'nwak', # 0xac +'nwat', # 0xad +'nwap', # 0xae +'nwah', # 0xaf +'nwae', # 0xb0 +'nwaeg', # 0xb1 +'nwaegg', # 0xb2 +'nwaegs', # 0xb3 +'nwaen', # 0xb4 +'nwaenj', # 0xb5 +'nwaenh', # 0xb6 +'nwaed', # 0xb7 +'nwael', # 0xb8 +'nwaelg', # 0xb9 +'nwaelm', # 0xba +'nwaelb', # 0xbb +'nwaels', # 0xbc +'nwaelt', # 0xbd +'nwaelp', # 0xbe +'nwaelh', # 0xbf +'nwaem', # 0xc0 +'nwaeb', # 0xc1 +'nwaebs', # 0xc2 +'nwaes', # 0xc3 +'nwaess', # 0xc4 +'nwaeng', # 0xc5 +'nwaej', # 0xc6 +'nwaec', # 0xc7 +'nwaek', # 0xc8 +'nwaet', # 0xc9 +'nwaep', # 0xca +'nwaeh', # 0xcb +'noe', # 0xcc +'noeg', # 0xcd +'noegg', # 0xce +'noegs', # 0xcf +'noen', # 0xd0 +'noenj', # 0xd1 +'noenh', # 0xd2 +'noed', # 0xd3 +'noel', # 0xd4 +'noelg', # 0xd5 +'noelm', # 0xd6 +'noelb', # 0xd7 +'noels', # 0xd8 +'noelt', # 0xd9 +'noelp', # 0xda +'noelh', # 0xdb +'noem', # 0xdc +'noeb', # 0xdd +'noebs', # 0xde +'noes', # 0xdf +'noess', # 0xe0 +'noeng', # 0xe1 +'noej', # 0xe2 +'noec', # 0xe3 +'noek', # 0xe4 +'noet', # 0xe5 +'noep', # 0xe6 +'noeh', # 0xe7 +'nyo', # 0xe8 +'nyog', # 0xe9 +'nyogg', # 0xea +'nyogs', # 0xeb +'nyon', # 0xec +'nyonj', # 0xed +'nyonh', # 0xee +'nyod', # 0xef +'nyol', # 0xf0 +'nyolg', # 0xf1 +'nyolm', # 0xf2 +'nyolb', # 0xf3 +'nyols', # 0xf4 +'nyolt', # 0xf5 +'nyolp', # 0xf6 +'nyolh', # 0xf7 +'nyom', # 0xf8 +'nyob', # 0xf9 +'nyobs', # 0xfa +'nyos', # 0xfb +'nyoss', # 0xfc +'nyong', # 0xfd +'nyoj', # 0xfe +'nyoc', # 0xff +) diff --git a/libs/unidecode/x0b2.py b/libs/unidecode/x0b2.py new file mode 100644 index 00000000..8b8aee41 --- /dev/null +++ b/libs/unidecode/x0b2.py @@ -0,0 +1,258 @@ +data = ( +'nyok', # 0x00 +'nyot', # 0x01 +'nyop', # 0x02 +'nyoh', # 0x03 +'nu', # 0x04 +'nug', # 0x05 +'nugg', # 0x06 +'nugs', # 0x07 +'nun', # 0x08 +'nunj', # 0x09 +'nunh', # 0x0a +'nud', # 0x0b +'nul', # 0x0c +'nulg', # 0x0d +'nulm', # 0x0e +'nulb', # 0x0f +'nuls', # 0x10 +'nult', # 0x11 +'nulp', # 0x12 +'nulh', # 0x13 +'num', # 0x14 +'nub', # 0x15 +'nubs', # 0x16 +'nus', # 0x17 +'nuss', # 0x18 +'nung', # 0x19 +'nuj', # 0x1a +'nuc', # 0x1b +'nuk', # 0x1c +'nut', # 0x1d +'nup', # 0x1e +'nuh', # 0x1f +'nweo', # 0x20 +'nweog', # 0x21 +'nweogg', # 0x22 +'nweogs', # 0x23 +'nweon', # 0x24 +'nweonj', # 0x25 +'nweonh', # 0x26 +'nweod', # 0x27 +'nweol', # 0x28 +'nweolg', # 0x29 +'nweolm', # 0x2a +'nweolb', # 0x2b +'nweols', # 0x2c +'nweolt', # 0x2d +'nweolp', # 0x2e +'nweolh', # 0x2f +'nweom', # 0x30 +'nweob', # 0x31 +'nweobs', # 0x32 +'nweos', # 0x33 +'nweoss', # 0x34 +'nweong', # 0x35 +'nweoj', # 0x36 +'nweoc', # 0x37 +'nweok', # 0x38 +'nweot', # 0x39 +'nweop', # 0x3a +'nweoh', # 0x3b +'nwe', # 0x3c +'nweg', # 0x3d +'nwegg', # 0x3e +'nwegs', # 0x3f +'nwen', # 0x40 +'nwenj', # 0x41 +'nwenh', # 0x42 +'nwed', # 0x43 +'nwel', # 0x44 +'nwelg', # 0x45 +'nwelm', # 0x46 +'nwelb', # 0x47 +'nwels', # 0x48 +'nwelt', # 0x49 +'nwelp', # 0x4a +'nwelh', # 0x4b +'nwem', # 0x4c +'nweb', # 0x4d +'nwebs', # 0x4e +'nwes', # 0x4f +'nwess', # 0x50 +'nweng', # 0x51 +'nwej', # 0x52 +'nwec', # 0x53 +'nwek', # 0x54 +'nwet', # 0x55 +'nwep', # 0x56 +'nweh', # 0x57 +'nwi', # 0x58 +'nwig', # 0x59 +'nwigg', # 0x5a +'nwigs', # 0x5b +'nwin', # 0x5c +'nwinj', # 0x5d +'nwinh', # 0x5e +'nwid', # 0x5f +'nwil', # 0x60 +'nwilg', # 0x61 +'nwilm', # 0x62 +'nwilb', # 0x63 +'nwils', # 0x64 +'nwilt', # 0x65 +'nwilp', # 0x66 +'nwilh', # 0x67 +'nwim', # 0x68 +'nwib', # 0x69 +'nwibs', # 0x6a +'nwis', # 0x6b +'nwiss', # 0x6c +'nwing', # 0x6d +'nwij', # 0x6e +'nwic', # 0x6f +'nwik', # 0x70 +'nwit', # 0x71 +'nwip', # 0x72 +'nwih', # 0x73 +'nyu', # 0x74 +'nyug', # 0x75 +'nyugg', # 0x76 +'nyugs', # 0x77 +'nyun', # 0x78 +'nyunj', # 0x79 +'nyunh', # 0x7a +'nyud', # 0x7b +'nyul', # 0x7c +'nyulg', # 0x7d +'nyulm', # 0x7e +'nyulb', # 0x7f +'nyuls', # 0x80 +'nyult', # 0x81 +'nyulp', # 0x82 +'nyulh', # 0x83 +'nyum', # 0x84 +'nyub', # 0x85 +'nyubs', # 0x86 +'nyus', # 0x87 +'nyuss', # 0x88 +'nyung', # 0x89 +'nyuj', # 0x8a +'nyuc', # 0x8b +'nyuk', # 0x8c +'nyut', # 0x8d +'nyup', # 0x8e +'nyuh', # 0x8f +'neu', # 0x90 +'neug', # 0x91 +'neugg', # 0x92 +'neugs', # 0x93 +'neun', # 0x94 +'neunj', # 0x95 +'neunh', # 0x96 +'neud', # 0x97 +'neul', # 0x98 +'neulg', # 0x99 +'neulm', # 0x9a +'neulb', # 0x9b +'neuls', # 0x9c +'neult', # 0x9d +'neulp', # 0x9e +'neulh', # 0x9f +'neum', # 0xa0 +'neub', # 0xa1 +'neubs', # 0xa2 +'neus', # 0xa3 +'neuss', # 0xa4 +'neung', # 0xa5 +'neuj', # 0xa6 +'neuc', # 0xa7 +'neuk', # 0xa8 +'neut', # 0xa9 +'neup', # 0xaa +'neuh', # 0xab +'nyi', # 0xac +'nyig', # 0xad +'nyigg', # 0xae +'nyigs', # 0xaf +'nyin', # 0xb0 +'nyinj', # 0xb1 +'nyinh', # 0xb2 +'nyid', # 0xb3 +'nyil', # 0xb4 +'nyilg', # 0xb5 +'nyilm', # 0xb6 +'nyilb', # 0xb7 +'nyils', # 0xb8 +'nyilt', # 0xb9 +'nyilp', # 0xba +'nyilh', # 0xbb +'nyim', # 0xbc +'nyib', # 0xbd +'nyibs', # 0xbe +'nyis', # 0xbf +'nyiss', # 0xc0 +'nying', # 0xc1 +'nyij', # 0xc2 +'nyic', # 0xc3 +'nyik', # 0xc4 +'nyit', # 0xc5 +'nyip', # 0xc6 +'nyih', # 0xc7 +'ni', # 0xc8 +'nig', # 0xc9 +'nigg', # 0xca +'nigs', # 0xcb +'nin', # 0xcc +'ninj', # 0xcd +'ninh', # 0xce +'nid', # 0xcf +'nil', # 0xd0 +'nilg', # 0xd1 +'nilm', # 0xd2 +'nilb', # 0xd3 +'nils', # 0xd4 +'nilt', # 0xd5 +'nilp', # 0xd6 +'nilh', # 0xd7 +'nim', # 0xd8 +'nib', # 0xd9 +'nibs', # 0xda +'nis', # 0xdb +'niss', # 0xdc +'ning', # 0xdd +'nij', # 0xde +'nic', # 0xdf +'nik', # 0xe0 +'nit', # 0xe1 +'nip', # 0xe2 +'nih', # 0xe3 +'da', # 0xe4 +'dag', # 0xe5 +'dagg', # 0xe6 +'dags', # 0xe7 +'dan', # 0xe8 +'danj', # 0xe9 +'danh', # 0xea +'dad', # 0xeb +'dal', # 0xec +'dalg', # 0xed +'dalm', # 0xee +'dalb', # 0xef +'dals', # 0xf0 +'dalt', # 0xf1 +'dalp', # 0xf2 +'dalh', # 0xf3 +'dam', # 0xf4 +'dab', # 0xf5 +'dabs', # 0xf6 +'das', # 0xf7 +'dass', # 0xf8 +'dang', # 0xf9 +'daj', # 0xfa +'dac', # 0xfb +'dak', # 0xfc +'dat', # 0xfd +'dap', # 0xfe +'dah', # 0xff +) diff --git a/libs/unidecode/x0b3.py b/libs/unidecode/x0b3.py new file mode 100644 index 00000000..830915aa --- /dev/null +++ b/libs/unidecode/x0b3.py @@ -0,0 +1,258 @@ +data = ( +'dae', # 0x00 +'daeg', # 0x01 +'daegg', # 0x02 +'daegs', # 0x03 +'daen', # 0x04 +'daenj', # 0x05 +'daenh', # 0x06 +'daed', # 0x07 +'dael', # 0x08 +'daelg', # 0x09 +'daelm', # 0x0a +'daelb', # 0x0b +'daels', # 0x0c +'daelt', # 0x0d +'daelp', # 0x0e +'daelh', # 0x0f +'daem', # 0x10 +'daeb', # 0x11 +'daebs', # 0x12 +'daes', # 0x13 +'daess', # 0x14 +'daeng', # 0x15 +'daej', # 0x16 +'daec', # 0x17 +'daek', # 0x18 +'daet', # 0x19 +'daep', # 0x1a +'daeh', # 0x1b +'dya', # 0x1c +'dyag', # 0x1d +'dyagg', # 0x1e +'dyags', # 0x1f +'dyan', # 0x20 +'dyanj', # 0x21 +'dyanh', # 0x22 +'dyad', # 0x23 +'dyal', # 0x24 +'dyalg', # 0x25 +'dyalm', # 0x26 +'dyalb', # 0x27 +'dyals', # 0x28 +'dyalt', # 0x29 +'dyalp', # 0x2a +'dyalh', # 0x2b +'dyam', # 0x2c +'dyab', # 0x2d +'dyabs', # 0x2e +'dyas', # 0x2f +'dyass', # 0x30 +'dyang', # 0x31 +'dyaj', # 0x32 +'dyac', # 0x33 +'dyak', # 0x34 +'dyat', # 0x35 +'dyap', # 0x36 +'dyah', # 0x37 +'dyae', # 0x38 +'dyaeg', # 0x39 +'dyaegg', # 0x3a +'dyaegs', # 0x3b +'dyaen', # 0x3c +'dyaenj', # 0x3d +'dyaenh', # 0x3e +'dyaed', # 0x3f +'dyael', # 0x40 +'dyaelg', # 0x41 +'dyaelm', # 0x42 +'dyaelb', # 0x43 +'dyaels', # 0x44 +'dyaelt', # 0x45 +'dyaelp', # 0x46 +'dyaelh', # 0x47 +'dyaem', # 0x48 +'dyaeb', # 0x49 +'dyaebs', # 0x4a +'dyaes', # 0x4b +'dyaess', # 0x4c +'dyaeng', # 0x4d +'dyaej', # 0x4e +'dyaec', # 0x4f +'dyaek', # 0x50 +'dyaet', # 0x51 +'dyaep', # 0x52 +'dyaeh', # 0x53 +'deo', # 0x54 +'deog', # 0x55 +'deogg', # 0x56 +'deogs', # 0x57 +'deon', # 0x58 +'deonj', # 0x59 +'deonh', # 0x5a +'deod', # 0x5b +'deol', # 0x5c +'deolg', # 0x5d +'deolm', # 0x5e +'deolb', # 0x5f +'deols', # 0x60 +'deolt', # 0x61 +'deolp', # 0x62 +'deolh', # 0x63 +'deom', # 0x64 +'deob', # 0x65 +'deobs', # 0x66 +'deos', # 0x67 +'deoss', # 0x68 +'deong', # 0x69 +'deoj', # 0x6a +'deoc', # 0x6b +'deok', # 0x6c +'deot', # 0x6d +'deop', # 0x6e +'deoh', # 0x6f +'de', # 0x70 +'deg', # 0x71 +'degg', # 0x72 +'degs', # 0x73 +'den', # 0x74 +'denj', # 0x75 +'denh', # 0x76 +'ded', # 0x77 +'del', # 0x78 +'delg', # 0x79 +'delm', # 0x7a +'delb', # 0x7b +'dels', # 0x7c +'delt', # 0x7d +'delp', # 0x7e +'delh', # 0x7f +'dem', # 0x80 +'deb', # 0x81 +'debs', # 0x82 +'des', # 0x83 +'dess', # 0x84 +'deng', # 0x85 +'dej', # 0x86 +'dec', # 0x87 +'dek', # 0x88 +'det', # 0x89 +'dep', # 0x8a +'deh', # 0x8b +'dyeo', # 0x8c +'dyeog', # 0x8d +'dyeogg', # 0x8e +'dyeogs', # 0x8f +'dyeon', # 0x90 +'dyeonj', # 0x91 +'dyeonh', # 0x92 +'dyeod', # 0x93 +'dyeol', # 0x94 +'dyeolg', # 0x95 +'dyeolm', # 0x96 +'dyeolb', # 0x97 +'dyeols', # 0x98 +'dyeolt', # 0x99 +'dyeolp', # 0x9a +'dyeolh', # 0x9b +'dyeom', # 0x9c +'dyeob', # 0x9d +'dyeobs', # 0x9e +'dyeos', # 0x9f +'dyeoss', # 0xa0 +'dyeong', # 0xa1 +'dyeoj', # 0xa2 +'dyeoc', # 0xa3 +'dyeok', # 0xa4 +'dyeot', # 0xa5 +'dyeop', # 0xa6 +'dyeoh', # 0xa7 +'dye', # 0xa8 +'dyeg', # 0xa9 +'dyegg', # 0xaa +'dyegs', # 0xab +'dyen', # 0xac +'dyenj', # 0xad +'dyenh', # 0xae +'dyed', # 0xaf +'dyel', # 0xb0 +'dyelg', # 0xb1 +'dyelm', # 0xb2 +'dyelb', # 0xb3 +'dyels', # 0xb4 +'dyelt', # 0xb5 +'dyelp', # 0xb6 +'dyelh', # 0xb7 +'dyem', # 0xb8 +'dyeb', # 0xb9 +'dyebs', # 0xba +'dyes', # 0xbb +'dyess', # 0xbc +'dyeng', # 0xbd +'dyej', # 0xbe +'dyec', # 0xbf +'dyek', # 0xc0 +'dyet', # 0xc1 +'dyep', # 0xc2 +'dyeh', # 0xc3 +'do', # 0xc4 +'dog', # 0xc5 +'dogg', # 0xc6 +'dogs', # 0xc7 +'don', # 0xc8 +'donj', # 0xc9 +'donh', # 0xca +'dod', # 0xcb +'dol', # 0xcc +'dolg', # 0xcd +'dolm', # 0xce +'dolb', # 0xcf +'dols', # 0xd0 +'dolt', # 0xd1 +'dolp', # 0xd2 +'dolh', # 0xd3 +'dom', # 0xd4 +'dob', # 0xd5 +'dobs', # 0xd6 +'dos', # 0xd7 +'doss', # 0xd8 +'dong', # 0xd9 +'doj', # 0xda +'doc', # 0xdb +'dok', # 0xdc +'dot', # 0xdd +'dop', # 0xde +'doh', # 0xdf +'dwa', # 0xe0 +'dwag', # 0xe1 +'dwagg', # 0xe2 +'dwags', # 0xe3 +'dwan', # 0xe4 +'dwanj', # 0xe5 +'dwanh', # 0xe6 +'dwad', # 0xe7 +'dwal', # 0xe8 +'dwalg', # 0xe9 +'dwalm', # 0xea +'dwalb', # 0xeb +'dwals', # 0xec +'dwalt', # 0xed +'dwalp', # 0xee +'dwalh', # 0xef +'dwam', # 0xf0 +'dwab', # 0xf1 +'dwabs', # 0xf2 +'dwas', # 0xf3 +'dwass', # 0xf4 +'dwang', # 0xf5 +'dwaj', # 0xf6 +'dwac', # 0xf7 +'dwak', # 0xf8 +'dwat', # 0xf9 +'dwap', # 0xfa +'dwah', # 0xfb +'dwae', # 0xfc +'dwaeg', # 0xfd +'dwaegg', # 0xfe +'dwaegs', # 0xff +) diff --git a/libs/unidecode/x0b4.py b/libs/unidecode/x0b4.py new file mode 100644 index 00000000..7a6a5aaa --- /dev/null +++ b/libs/unidecode/x0b4.py @@ -0,0 +1,258 @@ +data = ( +'dwaen', # 0x00 +'dwaenj', # 0x01 +'dwaenh', # 0x02 +'dwaed', # 0x03 +'dwael', # 0x04 +'dwaelg', # 0x05 +'dwaelm', # 0x06 +'dwaelb', # 0x07 +'dwaels', # 0x08 +'dwaelt', # 0x09 +'dwaelp', # 0x0a +'dwaelh', # 0x0b +'dwaem', # 0x0c +'dwaeb', # 0x0d +'dwaebs', # 0x0e +'dwaes', # 0x0f +'dwaess', # 0x10 +'dwaeng', # 0x11 +'dwaej', # 0x12 +'dwaec', # 0x13 +'dwaek', # 0x14 +'dwaet', # 0x15 +'dwaep', # 0x16 +'dwaeh', # 0x17 +'doe', # 0x18 +'doeg', # 0x19 +'doegg', # 0x1a +'doegs', # 0x1b +'doen', # 0x1c +'doenj', # 0x1d +'doenh', # 0x1e +'doed', # 0x1f +'doel', # 0x20 +'doelg', # 0x21 +'doelm', # 0x22 +'doelb', # 0x23 +'doels', # 0x24 +'doelt', # 0x25 +'doelp', # 0x26 +'doelh', # 0x27 +'doem', # 0x28 +'doeb', # 0x29 +'doebs', # 0x2a +'does', # 0x2b +'doess', # 0x2c +'doeng', # 0x2d +'doej', # 0x2e +'doec', # 0x2f +'doek', # 0x30 +'doet', # 0x31 +'doep', # 0x32 +'doeh', # 0x33 +'dyo', # 0x34 +'dyog', # 0x35 +'dyogg', # 0x36 +'dyogs', # 0x37 +'dyon', # 0x38 +'dyonj', # 0x39 +'dyonh', # 0x3a +'dyod', # 0x3b +'dyol', # 0x3c +'dyolg', # 0x3d +'dyolm', # 0x3e +'dyolb', # 0x3f +'dyols', # 0x40 +'dyolt', # 0x41 +'dyolp', # 0x42 +'dyolh', # 0x43 +'dyom', # 0x44 +'dyob', # 0x45 +'dyobs', # 0x46 +'dyos', # 0x47 +'dyoss', # 0x48 +'dyong', # 0x49 +'dyoj', # 0x4a +'dyoc', # 0x4b +'dyok', # 0x4c +'dyot', # 0x4d +'dyop', # 0x4e +'dyoh', # 0x4f +'du', # 0x50 +'dug', # 0x51 +'dugg', # 0x52 +'dugs', # 0x53 +'dun', # 0x54 +'dunj', # 0x55 +'dunh', # 0x56 +'dud', # 0x57 +'dul', # 0x58 +'dulg', # 0x59 +'dulm', # 0x5a +'dulb', # 0x5b +'duls', # 0x5c +'dult', # 0x5d +'dulp', # 0x5e +'dulh', # 0x5f +'dum', # 0x60 +'dub', # 0x61 +'dubs', # 0x62 +'dus', # 0x63 +'duss', # 0x64 +'dung', # 0x65 +'duj', # 0x66 +'duc', # 0x67 +'duk', # 0x68 +'dut', # 0x69 +'dup', # 0x6a +'duh', # 0x6b +'dweo', # 0x6c +'dweog', # 0x6d +'dweogg', # 0x6e +'dweogs', # 0x6f +'dweon', # 0x70 +'dweonj', # 0x71 +'dweonh', # 0x72 +'dweod', # 0x73 +'dweol', # 0x74 +'dweolg', # 0x75 +'dweolm', # 0x76 +'dweolb', # 0x77 +'dweols', # 0x78 +'dweolt', # 0x79 +'dweolp', # 0x7a +'dweolh', # 0x7b +'dweom', # 0x7c +'dweob', # 0x7d +'dweobs', # 0x7e +'dweos', # 0x7f +'dweoss', # 0x80 +'dweong', # 0x81 +'dweoj', # 0x82 +'dweoc', # 0x83 +'dweok', # 0x84 +'dweot', # 0x85 +'dweop', # 0x86 +'dweoh', # 0x87 +'dwe', # 0x88 +'dweg', # 0x89 +'dwegg', # 0x8a +'dwegs', # 0x8b +'dwen', # 0x8c +'dwenj', # 0x8d +'dwenh', # 0x8e +'dwed', # 0x8f +'dwel', # 0x90 +'dwelg', # 0x91 +'dwelm', # 0x92 +'dwelb', # 0x93 +'dwels', # 0x94 +'dwelt', # 0x95 +'dwelp', # 0x96 +'dwelh', # 0x97 +'dwem', # 0x98 +'dweb', # 0x99 +'dwebs', # 0x9a +'dwes', # 0x9b +'dwess', # 0x9c +'dweng', # 0x9d +'dwej', # 0x9e +'dwec', # 0x9f +'dwek', # 0xa0 +'dwet', # 0xa1 +'dwep', # 0xa2 +'dweh', # 0xa3 +'dwi', # 0xa4 +'dwig', # 0xa5 +'dwigg', # 0xa6 +'dwigs', # 0xa7 +'dwin', # 0xa8 +'dwinj', # 0xa9 +'dwinh', # 0xaa +'dwid', # 0xab +'dwil', # 0xac +'dwilg', # 0xad +'dwilm', # 0xae +'dwilb', # 0xaf +'dwils', # 0xb0 +'dwilt', # 0xb1 +'dwilp', # 0xb2 +'dwilh', # 0xb3 +'dwim', # 0xb4 +'dwib', # 0xb5 +'dwibs', # 0xb6 +'dwis', # 0xb7 +'dwiss', # 0xb8 +'dwing', # 0xb9 +'dwij', # 0xba +'dwic', # 0xbb +'dwik', # 0xbc +'dwit', # 0xbd +'dwip', # 0xbe +'dwih', # 0xbf +'dyu', # 0xc0 +'dyug', # 0xc1 +'dyugg', # 0xc2 +'dyugs', # 0xc3 +'dyun', # 0xc4 +'dyunj', # 0xc5 +'dyunh', # 0xc6 +'dyud', # 0xc7 +'dyul', # 0xc8 +'dyulg', # 0xc9 +'dyulm', # 0xca +'dyulb', # 0xcb +'dyuls', # 0xcc +'dyult', # 0xcd +'dyulp', # 0xce +'dyulh', # 0xcf +'dyum', # 0xd0 +'dyub', # 0xd1 +'dyubs', # 0xd2 +'dyus', # 0xd3 +'dyuss', # 0xd4 +'dyung', # 0xd5 +'dyuj', # 0xd6 +'dyuc', # 0xd7 +'dyuk', # 0xd8 +'dyut', # 0xd9 +'dyup', # 0xda +'dyuh', # 0xdb +'deu', # 0xdc +'deug', # 0xdd +'deugg', # 0xde +'deugs', # 0xdf +'deun', # 0xe0 +'deunj', # 0xe1 +'deunh', # 0xe2 +'deud', # 0xe3 +'deul', # 0xe4 +'deulg', # 0xe5 +'deulm', # 0xe6 +'deulb', # 0xe7 +'deuls', # 0xe8 +'deult', # 0xe9 +'deulp', # 0xea +'deulh', # 0xeb +'deum', # 0xec +'deub', # 0xed +'deubs', # 0xee +'deus', # 0xef +'deuss', # 0xf0 +'deung', # 0xf1 +'deuj', # 0xf2 +'deuc', # 0xf3 +'deuk', # 0xf4 +'deut', # 0xf5 +'deup', # 0xf6 +'deuh', # 0xf7 +'dyi', # 0xf8 +'dyig', # 0xf9 +'dyigg', # 0xfa +'dyigs', # 0xfb +'dyin', # 0xfc +'dyinj', # 0xfd +'dyinh', # 0xfe +'dyid', # 0xff +) diff --git a/libs/unidecode/x0b5.py b/libs/unidecode/x0b5.py new file mode 100644 index 00000000..9d4de3df --- /dev/null +++ b/libs/unidecode/x0b5.py @@ -0,0 +1,258 @@ +data = ( +'dyil', # 0x00 +'dyilg', # 0x01 +'dyilm', # 0x02 +'dyilb', # 0x03 +'dyils', # 0x04 +'dyilt', # 0x05 +'dyilp', # 0x06 +'dyilh', # 0x07 +'dyim', # 0x08 +'dyib', # 0x09 +'dyibs', # 0x0a +'dyis', # 0x0b +'dyiss', # 0x0c +'dying', # 0x0d +'dyij', # 0x0e +'dyic', # 0x0f +'dyik', # 0x10 +'dyit', # 0x11 +'dyip', # 0x12 +'dyih', # 0x13 +'di', # 0x14 +'dig', # 0x15 +'digg', # 0x16 +'digs', # 0x17 +'din', # 0x18 +'dinj', # 0x19 +'dinh', # 0x1a +'did', # 0x1b +'dil', # 0x1c +'dilg', # 0x1d +'dilm', # 0x1e +'dilb', # 0x1f +'dils', # 0x20 +'dilt', # 0x21 +'dilp', # 0x22 +'dilh', # 0x23 +'dim', # 0x24 +'dib', # 0x25 +'dibs', # 0x26 +'dis', # 0x27 +'diss', # 0x28 +'ding', # 0x29 +'dij', # 0x2a +'dic', # 0x2b +'dik', # 0x2c +'dit', # 0x2d +'dip', # 0x2e +'dih', # 0x2f +'dda', # 0x30 +'ddag', # 0x31 +'ddagg', # 0x32 +'ddags', # 0x33 +'ddan', # 0x34 +'ddanj', # 0x35 +'ddanh', # 0x36 +'ddad', # 0x37 +'ddal', # 0x38 +'ddalg', # 0x39 +'ddalm', # 0x3a +'ddalb', # 0x3b +'ddals', # 0x3c +'ddalt', # 0x3d +'ddalp', # 0x3e +'ddalh', # 0x3f +'ddam', # 0x40 +'ddab', # 0x41 +'ddabs', # 0x42 +'ddas', # 0x43 +'ddass', # 0x44 +'ddang', # 0x45 +'ddaj', # 0x46 +'ddac', # 0x47 +'ddak', # 0x48 +'ddat', # 0x49 +'ddap', # 0x4a +'ddah', # 0x4b +'ddae', # 0x4c +'ddaeg', # 0x4d +'ddaegg', # 0x4e +'ddaegs', # 0x4f +'ddaen', # 0x50 +'ddaenj', # 0x51 +'ddaenh', # 0x52 +'ddaed', # 0x53 +'ddael', # 0x54 +'ddaelg', # 0x55 +'ddaelm', # 0x56 +'ddaelb', # 0x57 +'ddaels', # 0x58 +'ddaelt', # 0x59 +'ddaelp', # 0x5a +'ddaelh', # 0x5b +'ddaem', # 0x5c +'ddaeb', # 0x5d +'ddaebs', # 0x5e +'ddaes', # 0x5f +'ddaess', # 0x60 +'ddaeng', # 0x61 +'ddaej', # 0x62 +'ddaec', # 0x63 +'ddaek', # 0x64 +'ddaet', # 0x65 +'ddaep', # 0x66 +'ddaeh', # 0x67 +'ddya', # 0x68 +'ddyag', # 0x69 +'ddyagg', # 0x6a +'ddyags', # 0x6b +'ddyan', # 0x6c +'ddyanj', # 0x6d +'ddyanh', # 0x6e +'ddyad', # 0x6f +'ddyal', # 0x70 +'ddyalg', # 0x71 +'ddyalm', # 0x72 +'ddyalb', # 0x73 +'ddyals', # 0x74 +'ddyalt', # 0x75 +'ddyalp', # 0x76 +'ddyalh', # 0x77 +'ddyam', # 0x78 +'ddyab', # 0x79 +'ddyabs', # 0x7a +'ddyas', # 0x7b +'ddyass', # 0x7c +'ddyang', # 0x7d +'ddyaj', # 0x7e +'ddyac', # 0x7f +'ddyak', # 0x80 +'ddyat', # 0x81 +'ddyap', # 0x82 +'ddyah', # 0x83 +'ddyae', # 0x84 +'ddyaeg', # 0x85 +'ddyaegg', # 0x86 +'ddyaegs', # 0x87 +'ddyaen', # 0x88 +'ddyaenj', # 0x89 +'ddyaenh', # 0x8a +'ddyaed', # 0x8b +'ddyael', # 0x8c +'ddyaelg', # 0x8d +'ddyaelm', # 0x8e +'ddyaelb', # 0x8f +'ddyaels', # 0x90 +'ddyaelt', # 0x91 +'ddyaelp', # 0x92 +'ddyaelh', # 0x93 +'ddyaem', # 0x94 +'ddyaeb', # 0x95 +'ddyaebs', # 0x96 +'ddyaes', # 0x97 +'ddyaess', # 0x98 +'ddyaeng', # 0x99 +'ddyaej', # 0x9a +'ddyaec', # 0x9b +'ddyaek', # 0x9c +'ddyaet', # 0x9d +'ddyaep', # 0x9e +'ddyaeh', # 0x9f +'ddeo', # 0xa0 +'ddeog', # 0xa1 +'ddeogg', # 0xa2 +'ddeogs', # 0xa3 +'ddeon', # 0xa4 +'ddeonj', # 0xa5 +'ddeonh', # 0xa6 +'ddeod', # 0xa7 +'ddeol', # 0xa8 +'ddeolg', # 0xa9 +'ddeolm', # 0xaa +'ddeolb', # 0xab +'ddeols', # 0xac +'ddeolt', # 0xad +'ddeolp', # 0xae +'ddeolh', # 0xaf +'ddeom', # 0xb0 +'ddeob', # 0xb1 +'ddeobs', # 0xb2 +'ddeos', # 0xb3 +'ddeoss', # 0xb4 +'ddeong', # 0xb5 +'ddeoj', # 0xb6 +'ddeoc', # 0xb7 +'ddeok', # 0xb8 +'ddeot', # 0xb9 +'ddeop', # 0xba +'ddeoh', # 0xbb +'dde', # 0xbc +'ddeg', # 0xbd +'ddegg', # 0xbe +'ddegs', # 0xbf +'dden', # 0xc0 +'ddenj', # 0xc1 +'ddenh', # 0xc2 +'dded', # 0xc3 +'ddel', # 0xc4 +'ddelg', # 0xc5 +'ddelm', # 0xc6 +'ddelb', # 0xc7 +'ddels', # 0xc8 +'ddelt', # 0xc9 +'ddelp', # 0xca +'ddelh', # 0xcb +'ddem', # 0xcc +'ddeb', # 0xcd +'ddebs', # 0xce +'ddes', # 0xcf +'ddess', # 0xd0 +'ddeng', # 0xd1 +'ddej', # 0xd2 +'ddec', # 0xd3 +'ddek', # 0xd4 +'ddet', # 0xd5 +'ddep', # 0xd6 +'ddeh', # 0xd7 +'ddyeo', # 0xd8 +'ddyeog', # 0xd9 +'ddyeogg', # 0xda +'ddyeogs', # 0xdb +'ddyeon', # 0xdc +'ddyeonj', # 0xdd +'ddyeonh', # 0xde +'ddyeod', # 0xdf +'ddyeol', # 0xe0 +'ddyeolg', # 0xe1 +'ddyeolm', # 0xe2 +'ddyeolb', # 0xe3 +'ddyeols', # 0xe4 +'ddyeolt', # 0xe5 +'ddyeolp', # 0xe6 +'ddyeolh', # 0xe7 +'ddyeom', # 0xe8 +'ddyeob', # 0xe9 +'ddyeobs', # 0xea +'ddyeos', # 0xeb +'ddyeoss', # 0xec +'ddyeong', # 0xed +'ddyeoj', # 0xee +'ddyeoc', # 0xef +'ddyeok', # 0xf0 +'ddyeot', # 0xf1 +'ddyeop', # 0xf2 +'ddyeoh', # 0xf3 +'ddye', # 0xf4 +'ddyeg', # 0xf5 +'ddyegg', # 0xf6 +'ddyegs', # 0xf7 +'ddyen', # 0xf8 +'ddyenj', # 0xf9 +'ddyenh', # 0xfa +'ddyed', # 0xfb +'ddyel', # 0xfc +'ddyelg', # 0xfd +'ddyelm', # 0xfe +'ddyelb', # 0xff +) diff --git a/libs/unidecode/x0b6.py b/libs/unidecode/x0b6.py new file mode 100644 index 00000000..2800e3bc --- /dev/null +++ b/libs/unidecode/x0b6.py @@ -0,0 +1,258 @@ +data = ( +'ddyels', # 0x00 +'ddyelt', # 0x01 +'ddyelp', # 0x02 +'ddyelh', # 0x03 +'ddyem', # 0x04 +'ddyeb', # 0x05 +'ddyebs', # 0x06 +'ddyes', # 0x07 +'ddyess', # 0x08 +'ddyeng', # 0x09 +'ddyej', # 0x0a +'ddyec', # 0x0b +'ddyek', # 0x0c +'ddyet', # 0x0d +'ddyep', # 0x0e +'ddyeh', # 0x0f +'ddo', # 0x10 +'ddog', # 0x11 +'ddogg', # 0x12 +'ddogs', # 0x13 +'ddon', # 0x14 +'ddonj', # 0x15 +'ddonh', # 0x16 +'ddod', # 0x17 +'ddol', # 0x18 +'ddolg', # 0x19 +'ddolm', # 0x1a +'ddolb', # 0x1b +'ddols', # 0x1c +'ddolt', # 0x1d +'ddolp', # 0x1e +'ddolh', # 0x1f +'ddom', # 0x20 +'ddob', # 0x21 +'ddobs', # 0x22 +'ddos', # 0x23 +'ddoss', # 0x24 +'ddong', # 0x25 +'ddoj', # 0x26 +'ddoc', # 0x27 +'ddok', # 0x28 +'ddot', # 0x29 +'ddop', # 0x2a +'ddoh', # 0x2b +'ddwa', # 0x2c +'ddwag', # 0x2d +'ddwagg', # 0x2e +'ddwags', # 0x2f +'ddwan', # 0x30 +'ddwanj', # 0x31 +'ddwanh', # 0x32 +'ddwad', # 0x33 +'ddwal', # 0x34 +'ddwalg', # 0x35 +'ddwalm', # 0x36 +'ddwalb', # 0x37 +'ddwals', # 0x38 +'ddwalt', # 0x39 +'ddwalp', # 0x3a +'ddwalh', # 0x3b +'ddwam', # 0x3c +'ddwab', # 0x3d +'ddwabs', # 0x3e +'ddwas', # 0x3f +'ddwass', # 0x40 +'ddwang', # 0x41 +'ddwaj', # 0x42 +'ddwac', # 0x43 +'ddwak', # 0x44 +'ddwat', # 0x45 +'ddwap', # 0x46 +'ddwah', # 0x47 +'ddwae', # 0x48 +'ddwaeg', # 0x49 +'ddwaegg', # 0x4a +'ddwaegs', # 0x4b +'ddwaen', # 0x4c +'ddwaenj', # 0x4d +'ddwaenh', # 0x4e +'ddwaed', # 0x4f +'ddwael', # 0x50 +'ddwaelg', # 0x51 +'ddwaelm', # 0x52 +'ddwaelb', # 0x53 +'ddwaels', # 0x54 +'ddwaelt', # 0x55 +'ddwaelp', # 0x56 +'ddwaelh', # 0x57 +'ddwaem', # 0x58 +'ddwaeb', # 0x59 +'ddwaebs', # 0x5a +'ddwaes', # 0x5b +'ddwaess', # 0x5c +'ddwaeng', # 0x5d +'ddwaej', # 0x5e +'ddwaec', # 0x5f +'ddwaek', # 0x60 +'ddwaet', # 0x61 +'ddwaep', # 0x62 +'ddwaeh', # 0x63 +'ddoe', # 0x64 +'ddoeg', # 0x65 +'ddoegg', # 0x66 +'ddoegs', # 0x67 +'ddoen', # 0x68 +'ddoenj', # 0x69 +'ddoenh', # 0x6a +'ddoed', # 0x6b +'ddoel', # 0x6c +'ddoelg', # 0x6d +'ddoelm', # 0x6e +'ddoelb', # 0x6f +'ddoels', # 0x70 +'ddoelt', # 0x71 +'ddoelp', # 0x72 +'ddoelh', # 0x73 +'ddoem', # 0x74 +'ddoeb', # 0x75 +'ddoebs', # 0x76 +'ddoes', # 0x77 +'ddoess', # 0x78 +'ddoeng', # 0x79 +'ddoej', # 0x7a +'ddoec', # 0x7b +'ddoek', # 0x7c +'ddoet', # 0x7d +'ddoep', # 0x7e +'ddoeh', # 0x7f +'ddyo', # 0x80 +'ddyog', # 0x81 +'ddyogg', # 0x82 +'ddyogs', # 0x83 +'ddyon', # 0x84 +'ddyonj', # 0x85 +'ddyonh', # 0x86 +'ddyod', # 0x87 +'ddyol', # 0x88 +'ddyolg', # 0x89 +'ddyolm', # 0x8a +'ddyolb', # 0x8b +'ddyols', # 0x8c +'ddyolt', # 0x8d +'ddyolp', # 0x8e +'ddyolh', # 0x8f +'ddyom', # 0x90 +'ddyob', # 0x91 +'ddyobs', # 0x92 +'ddyos', # 0x93 +'ddyoss', # 0x94 +'ddyong', # 0x95 +'ddyoj', # 0x96 +'ddyoc', # 0x97 +'ddyok', # 0x98 +'ddyot', # 0x99 +'ddyop', # 0x9a +'ddyoh', # 0x9b +'ddu', # 0x9c +'ddug', # 0x9d +'ddugg', # 0x9e +'ddugs', # 0x9f +'ddun', # 0xa0 +'ddunj', # 0xa1 +'ddunh', # 0xa2 +'ddud', # 0xa3 +'ddul', # 0xa4 +'ddulg', # 0xa5 +'ddulm', # 0xa6 +'ddulb', # 0xa7 +'dduls', # 0xa8 +'ddult', # 0xa9 +'ddulp', # 0xaa +'ddulh', # 0xab +'ddum', # 0xac +'ddub', # 0xad +'ddubs', # 0xae +'ddus', # 0xaf +'dduss', # 0xb0 +'ddung', # 0xb1 +'dduj', # 0xb2 +'dduc', # 0xb3 +'dduk', # 0xb4 +'ddut', # 0xb5 +'ddup', # 0xb6 +'dduh', # 0xb7 +'ddweo', # 0xb8 +'ddweog', # 0xb9 +'ddweogg', # 0xba +'ddweogs', # 0xbb +'ddweon', # 0xbc +'ddweonj', # 0xbd +'ddweonh', # 0xbe +'ddweod', # 0xbf +'ddweol', # 0xc0 +'ddweolg', # 0xc1 +'ddweolm', # 0xc2 +'ddweolb', # 0xc3 +'ddweols', # 0xc4 +'ddweolt', # 0xc5 +'ddweolp', # 0xc6 +'ddweolh', # 0xc7 +'ddweom', # 0xc8 +'ddweob', # 0xc9 +'ddweobs', # 0xca +'ddweos', # 0xcb +'ddweoss', # 0xcc +'ddweong', # 0xcd +'ddweoj', # 0xce +'ddweoc', # 0xcf +'ddweok', # 0xd0 +'ddweot', # 0xd1 +'ddweop', # 0xd2 +'ddweoh', # 0xd3 +'ddwe', # 0xd4 +'ddweg', # 0xd5 +'ddwegg', # 0xd6 +'ddwegs', # 0xd7 +'ddwen', # 0xd8 +'ddwenj', # 0xd9 +'ddwenh', # 0xda +'ddwed', # 0xdb +'ddwel', # 0xdc +'ddwelg', # 0xdd +'ddwelm', # 0xde +'ddwelb', # 0xdf +'ddwels', # 0xe0 +'ddwelt', # 0xe1 +'ddwelp', # 0xe2 +'ddwelh', # 0xe3 +'ddwem', # 0xe4 +'ddweb', # 0xe5 +'ddwebs', # 0xe6 +'ddwes', # 0xe7 +'ddwess', # 0xe8 +'ddweng', # 0xe9 +'ddwej', # 0xea +'ddwec', # 0xeb +'ddwek', # 0xec +'ddwet', # 0xed +'ddwep', # 0xee +'ddweh', # 0xef +'ddwi', # 0xf0 +'ddwig', # 0xf1 +'ddwigg', # 0xf2 +'ddwigs', # 0xf3 +'ddwin', # 0xf4 +'ddwinj', # 0xf5 +'ddwinh', # 0xf6 +'ddwid', # 0xf7 +'ddwil', # 0xf8 +'ddwilg', # 0xf9 +'ddwilm', # 0xfa +'ddwilb', # 0xfb +'ddwils', # 0xfc +'ddwilt', # 0xfd +'ddwilp', # 0xfe +'ddwilh', # 0xff +) diff --git a/libs/unidecode/x0b7.py b/libs/unidecode/x0b7.py new file mode 100644 index 00000000..483dddeb --- /dev/null +++ b/libs/unidecode/x0b7.py @@ -0,0 +1,258 @@ +data = ( +'ddwim', # 0x00 +'ddwib', # 0x01 +'ddwibs', # 0x02 +'ddwis', # 0x03 +'ddwiss', # 0x04 +'ddwing', # 0x05 +'ddwij', # 0x06 +'ddwic', # 0x07 +'ddwik', # 0x08 +'ddwit', # 0x09 +'ddwip', # 0x0a +'ddwih', # 0x0b +'ddyu', # 0x0c +'ddyug', # 0x0d +'ddyugg', # 0x0e +'ddyugs', # 0x0f +'ddyun', # 0x10 +'ddyunj', # 0x11 +'ddyunh', # 0x12 +'ddyud', # 0x13 +'ddyul', # 0x14 +'ddyulg', # 0x15 +'ddyulm', # 0x16 +'ddyulb', # 0x17 +'ddyuls', # 0x18 +'ddyult', # 0x19 +'ddyulp', # 0x1a +'ddyulh', # 0x1b +'ddyum', # 0x1c +'ddyub', # 0x1d +'ddyubs', # 0x1e +'ddyus', # 0x1f +'ddyuss', # 0x20 +'ddyung', # 0x21 +'ddyuj', # 0x22 +'ddyuc', # 0x23 +'ddyuk', # 0x24 +'ddyut', # 0x25 +'ddyup', # 0x26 +'ddyuh', # 0x27 +'ddeu', # 0x28 +'ddeug', # 0x29 +'ddeugg', # 0x2a +'ddeugs', # 0x2b +'ddeun', # 0x2c +'ddeunj', # 0x2d +'ddeunh', # 0x2e +'ddeud', # 0x2f +'ddeul', # 0x30 +'ddeulg', # 0x31 +'ddeulm', # 0x32 +'ddeulb', # 0x33 +'ddeuls', # 0x34 +'ddeult', # 0x35 +'ddeulp', # 0x36 +'ddeulh', # 0x37 +'ddeum', # 0x38 +'ddeub', # 0x39 +'ddeubs', # 0x3a +'ddeus', # 0x3b +'ddeuss', # 0x3c +'ddeung', # 0x3d +'ddeuj', # 0x3e +'ddeuc', # 0x3f +'ddeuk', # 0x40 +'ddeut', # 0x41 +'ddeup', # 0x42 +'ddeuh', # 0x43 +'ddyi', # 0x44 +'ddyig', # 0x45 +'ddyigg', # 0x46 +'ddyigs', # 0x47 +'ddyin', # 0x48 +'ddyinj', # 0x49 +'ddyinh', # 0x4a +'ddyid', # 0x4b +'ddyil', # 0x4c +'ddyilg', # 0x4d +'ddyilm', # 0x4e +'ddyilb', # 0x4f +'ddyils', # 0x50 +'ddyilt', # 0x51 +'ddyilp', # 0x52 +'ddyilh', # 0x53 +'ddyim', # 0x54 +'ddyib', # 0x55 +'ddyibs', # 0x56 +'ddyis', # 0x57 +'ddyiss', # 0x58 +'ddying', # 0x59 +'ddyij', # 0x5a +'ddyic', # 0x5b +'ddyik', # 0x5c +'ddyit', # 0x5d +'ddyip', # 0x5e +'ddyih', # 0x5f +'ddi', # 0x60 +'ddig', # 0x61 +'ddigg', # 0x62 +'ddigs', # 0x63 +'ddin', # 0x64 +'ddinj', # 0x65 +'ddinh', # 0x66 +'ddid', # 0x67 +'ddil', # 0x68 +'ddilg', # 0x69 +'ddilm', # 0x6a +'ddilb', # 0x6b +'ddils', # 0x6c +'ddilt', # 0x6d +'ddilp', # 0x6e +'ddilh', # 0x6f +'ddim', # 0x70 +'ddib', # 0x71 +'ddibs', # 0x72 +'ddis', # 0x73 +'ddiss', # 0x74 +'dding', # 0x75 +'ddij', # 0x76 +'ddic', # 0x77 +'ddik', # 0x78 +'ddit', # 0x79 +'ddip', # 0x7a +'ddih', # 0x7b +'ra', # 0x7c +'rag', # 0x7d +'ragg', # 0x7e +'rags', # 0x7f +'ran', # 0x80 +'ranj', # 0x81 +'ranh', # 0x82 +'rad', # 0x83 +'ral', # 0x84 +'ralg', # 0x85 +'ralm', # 0x86 +'ralb', # 0x87 +'rals', # 0x88 +'ralt', # 0x89 +'ralp', # 0x8a +'ralh', # 0x8b +'ram', # 0x8c +'rab', # 0x8d +'rabs', # 0x8e +'ras', # 0x8f +'rass', # 0x90 +'rang', # 0x91 +'raj', # 0x92 +'rac', # 0x93 +'rak', # 0x94 +'rat', # 0x95 +'rap', # 0x96 +'rah', # 0x97 +'rae', # 0x98 +'raeg', # 0x99 +'raegg', # 0x9a +'raegs', # 0x9b +'raen', # 0x9c +'raenj', # 0x9d +'raenh', # 0x9e +'raed', # 0x9f +'rael', # 0xa0 +'raelg', # 0xa1 +'raelm', # 0xa2 +'raelb', # 0xa3 +'raels', # 0xa4 +'raelt', # 0xa5 +'raelp', # 0xa6 +'raelh', # 0xa7 +'raem', # 0xa8 +'raeb', # 0xa9 +'raebs', # 0xaa +'raes', # 0xab +'raess', # 0xac +'raeng', # 0xad +'raej', # 0xae +'raec', # 0xaf +'raek', # 0xb0 +'raet', # 0xb1 +'raep', # 0xb2 +'raeh', # 0xb3 +'rya', # 0xb4 +'ryag', # 0xb5 +'ryagg', # 0xb6 +'ryags', # 0xb7 +'ryan', # 0xb8 +'ryanj', # 0xb9 +'ryanh', # 0xba +'ryad', # 0xbb +'ryal', # 0xbc +'ryalg', # 0xbd +'ryalm', # 0xbe +'ryalb', # 0xbf +'ryals', # 0xc0 +'ryalt', # 0xc1 +'ryalp', # 0xc2 +'ryalh', # 0xc3 +'ryam', # 0xc4 +'ryab', # 0xc5 +'ryabs', # 0xc6 +'ryas', # 0xc7 +'ryass', # 0xc8 +'ryang', # 0xc9 +'ryaj', # 0xca +'ryac', # 0xcb +'ryak', # 0xcc +'ryat', # 0xcd +'ryap', # 0xce +'ryah', # 0xcf +'ryae', # 0xd0 +'ryaeg', # 0xd1 +'ryaegg', # 0xd2 +'ryaegs', # 0xd3 +'ryaen', # 0xd4 +'ryaenj', # 0xd5 +'ryaenh', # 0xd6 +'ryaed', # 0xd7 +'ryael', # 0xd8 +'ryaelg', # 0xd9 +'ryaelm', # 0xda +'ryaelb', # 0xdb +'ryaels', # 0xdc +'ryaelt', # 0xdd +'ryaelp', # 0xde +'ryaelh', # 0xdf +'ryaem', # 0xe0 +'ryaeb', # 0xe1 +'ryaebs', # 0xe2 +'ryaes', # 0xe3 +'ryaess', # 0xe4 +'ryaeng', # 0xe5 +'ryaej', # 0xe6 +'ryaec', # 0xe7 +'ryaek', # 0xe8 +'ryaet', # 0xe9 +'ryaep', # 0xea +'ryaeh', # 0xeb +'reo', # 0xec +'reog', # 0xed +'reogg', # 0xee +'reogs', # 0xef +'reon', # 0xf0 +'reonj', # 0xf1 +'reonh', # 0xf2 +'reod', # 0xf3 +'reol', # 0xf4 +'reolg', # 0xf5 +'reolm', # 0xf6 +'reolb', # 0xf7 +'reols', # 0xf8 +'reolt', # 0xf9 +'reolp', # 0xfa +'reolh', # 0xfb +'reom', # 0xfc +'reob', # 0xfd +'reobs', # 0xfe +'reos', # 0xff +) diff --git a/libs/unidecode/x0b8.py b/libs/unidecode/x0b8.py new file mode 100644 index 00000000..5c845ebc --- /dev/null +++ b/libs/unidecode/x0b8.py @@ -0,0 +1,258 @@ +data = ( +'reoss', # 0x00 +'reong', # 0x01 +'reoj', # 0x02 +'reoc', # 0x03 +'reok', # 0x04 +'reot', # 0x05 +'reop', # 0x06 +'reoh', # 0x07 +'re', # 0x08 +'reg', # 0x09 +'regg', # 0x0a +'regs', # 0x0b +'ren', # 0x0c +'renj', # 0x0d +'renh', # 0x0e +'red', # 0x0f +'rel', # 0x10 +'relg', # 0x11 +'relm', # 0x12 +'relb', # 0x13 +'rels', # 0x14 +'relt', # 0x15 +'relp', # 0x16 +'relh', # 0x17 +'rem', # 0x18 +'reb', # 0x19 +'rebs', # 0x1a +'res', # 0x1b +'ress', # 0x1c +'reng', # 0x1d +'rej', # 0x1e +'rec', # 0x1f +'rek', # 0x20 +'ret', # 0x21 +'rep', # 0x22 +'reh', # 0x23 +'ryeo', # 0x24 +'ryeog', # 0x25 +'ryeogg', # 0x26 +'ryeogs', # 0x27 +'ryeon', # 0x28 +'ryeonj', # 0x29 +'ryeonh', # 0x2a +'ryeod', # 0x2b +'ryeol', # 0x2c +'ryeolg', # 0x2d +'ryeolm', # 0x2e +'ryeolb', # 0x2f +'ryeols', # 0x30 +'ryeolt', # 0x31 +'ryeolp', # 0x32 +'ryeolh', # 0x33 +'ryeom', # 0x34 +'ryeob', # 0x35 +'ryeobs', # 0x36 +'ryeos', # 0x37 +'ryeoss', # 0x38 +'ryeong', # 0x39 +'ryeoj', # 0x3a +'ryeoc', # 0x3b +'ryeok', # 0x3c +'ryeot', # 0x3d +'ryeop', # 0x3e +'ryeoh', # 0x3f +'rye', # 0x40 +'ryeg', # 0x41 +'ryegg', # 0x42 +'ryegs', # 0x43 +'ryen', # 0x44 +'ryenj', # 0x45 +'ryenh', # 0x46 +'ryed', # 0x47 +'ryel', # 0x48 +'ryelg', # 0x49 +'ryelm', # 0x4a +'ryelb', # 0x4b +'ryels', # 0x4c +'ryelt', # 0x4d +'ryelp', # 0x4e +'ryelh', # 0x4f +'ryem', # 0x50 +'ryeb', # 0x51 +'ryebs', # 0x52 +'ryes', # 0x53 +'ryess', # 0x54 +'ryeng', # 0x55 +'ryej', # 0x56 +'ryec', # 0x57 +'ryek', # 0x58 +'ryet', # 0x59 +'ryep', # 0x5a +'ryeh', # 0x5b +'ro', # 0x5c +'rog', # 0x5d +'rogg', # 0x5e +'rogs', # 0x5f +'ron', # 0x60 +'ronj', # 0x61 +'ronh', # 0x62 +'rod', # 0x63 +'rol', # 0x64 +'rolg', # 0x65 +'rolm', # 0x66 +'rolb', # 0x67 +'rols', # 0x68 +'rolt', # 0x69 +'rolp', # 0x6a +'rolh', # 0x6b +'rom', # 0x6c +'rob', # 0x6d +'robs', # 0x6e +'ros', # 0x6f +'ross', # 0x70 +'rong', # 0x71 +'roj', # 0x72 +'roc', # 0x73 +'rok', # 0x74 +'rot', # 0x75 +'rop', # 0x76 +'roh', # 0x77 +'rwa', # 0x78 +'rwag', # 0x79 +'rwagg', # 0x7a +'rwags', # 0x7b +'rwan', # 0x7c +'rwanj', # 0x7d +'rwanh', # 0x7e +'rwad', # 0x7f +'rwal', # 0x80 +'rwalg', # 0x81 +'rwalm', # 0x82 +'rwalb', # 0x83 +'rwals', # 0x84 +'rwalt', # 0x85 +'rwalp', # 0x86 +'rwalh', # 0x87 +'rwam', # 0x88 +'rwab', # 0x89 +'rwabs', # 0x8a +'rwas', # 0x8b +'rwass', # 0x8c +'rwang', # 0x8d +'rwaj', # 0x8e +'rwac', # 0x8f +'rwak', # 0x90 +'rwat', # 0x91 +'rwap', # 0x92 +'rwah', # 0x93 +'rwae', # 0x94 +'rwaeg', # 0x95 +'rwaegg', # 0x96 +'rwaegs', # 0x97 +'rwaen', # 0x98 +'rwaenj', # 0x99 +'rwaenh', # 0x9a +'rwaed', # 0x9b +'rwael', # 0x9c +'rwaelg', # 0x9d +'rwaelm', # 0x9e +'rwaelb', # 0x9f +'rwaels', # 0xa0 +'rwaelt', # 0xa1 +'rwaelp', # 0xa2 +'rwaelh', # 0xa3 +'rwaem', # 0xa4 +'rwaeb', # 0xa5 +'rwaebs', # 0xa6 +'rwaes', # 0xa7 +'rwaess', # 0xa8 +'rwaeng', # 0xa9 +'rwaej', # 0xaa +'rwaec', # 0xab +'rwaek', # 0xac +'rwaet', # 0xad +'rwaep', # 0xae +'rwaeh', # 0xaf +'roe', # 0xb0 +'roeg', # 0xb1 +'roegg', # 0xb2 +'roegs', # 0xb3 +'roen', # 0xb4 +'roenj', # 0xb5 +'roenh', # 0xb6 +'roed', # 0xb7 +'roel', # 0xb8 +'roelg', # 0xb9 +'roelm', # 0xba +'roelb', # 0xbb +'roels', # 0xbc +'roelt', # 0xbd +'roelp', # 0xbe +'roelh', # 0xbf +'roem', # 0xc0 +'roeb', # 0xc1 +'roebs', # 0xc2 +'roes', # 0xc3 +'roess', # 0xc4 +'roeng', # 0xc5 +'roej', # 0xc6 +'roec', # 0xc7 +'roek', # 0xc8 +'roet', # 0xc9 +'roep', # 0xca +'roeh', # 0xcb +'ryo', # 0xcc +'ryog', # 0xcd +'ryogg', # 0xce +'ryogs', # 0xcf +'ryon', # 0xd0 +'ryonj', # 0xd1 +'ryonh', # 0xd2 +'ryod', # 0xd3 +'ryol', # 0xd4 +'ryolg', # 0xd5 +'ryolm', # 0xd6 +'ryolb', # 0xd7 +'ryols', # 0xd8 +'ryolt', # 0xd9 +'ryolp', # 0xda +'ryolh', # 0xdb +'ryom', # 0xdc +'ryob', # 0xdd +'ryobs', # 0xde +'ryos', # 0xdf +'ryoss', # 0xe0 +'ryong', # 0xe1 +'ryoj', # 0xe2 +'ryoc', # 0xe3 +'ryok', # 0xe4 +'ryot', # 0xe5 +'ryop', # 0xe6 +'ryoh', # 0xe7 +'ru', # 0xe8 +'rug', # 0xe9 +'rugg', # 0xea +'rugs', # 0xeb +'run', # 0xec +'runj', # 0xed +'runh', # 0xee +'rud', # 0xef +'rul', # 0xf0 +'rulg', # 0xf1 +'rulm', # 0xf2 +'rulb', # 0xf3 +'ruls', # 0xf4 +'rult', # 0xf5 +'rulp', # 0xf6 +'rulh', # 0xf7 +'rum', # 0xf8 +'rub', # 0xf9 +'rubs', # 0xfa +'rus', # 0xfb +'russ', # 0xfc +'rung', # 0xfd +'ruj', # 0xfe +'ruc', # 0xff +) diff --git a/libs/unidecode/x0b9.py b/libs/unidecode/x0b9.py new file mode 100644 index 00000000..35340dc7 --- /dev/null +++ b/libs/unidecode/x0b9.py @@ -0,0 +1,258 @@ +data = ( +'ruk', # 0x00 +'rut', # 0x01 +'rup', # 0x02 +'ruh', # 0x03 +'rweo', # 0x04 +'rweog', # 0x05 +'rweogg', # 0x06 +'rweogs', # 0x07 +'rweon', # 0x08 +'rweonj', # 0x09 +'rweonh', # 0x0a +'rweod', # 0x0b +'rweol', # 0x0c +'rweolg', # 0x0d +'rweolm', # 0x0e +'rweolb', # 0x0f +'rweols', # 0x10 +'rweolt', # 0x11 +'rweolp', # 0x12 +'rweolh', # 0x13 +'rweom', # 0x14 +'rweob', # 0x15 +'rweobs', # 0x16 +'rweos', # 0x17 +'rweoss', # 0x18 +'rweong', # 0x19 +'rweoj', # 0x1a +'rweoc', # 0x1b +'rweok', # 0x1c +'rweot', # 0x1d +'rweop', # 0x1e +'rweoh', # 0x1f +'rwe', # 0x20 +'rweg', # 0x21 +'rwegg', # 0x22 +'rwegs', # 0x23 +'rwen', # 0x24 +'rwenj', # 0x25 +'rwenh', # 0x26 +'rwed', # 0x27 +'rwel', # 0x28 +'rwelg', # 0x29 +'rwelm', # 0x2a +'rwelb', # 0x2b +'rwels', # 0x2c +'rwelt', # 0x2d +'rwelp', # 0x2e +'rwelh', # 0x2f +'rwem', # 0x30 +'rweb', # 0x31 +'rwebs', # 0x32 +'rwes', # 0x33 +'rwess', # 0x34 +'rweng', # 0x35 +'rwej', # 0x36 +'rwec', # 0x37 +'rwek', # 0x38 +'rwet', # 0x39 +'rwep', # 0x3a +'rweh', # 0x3b +'rwi', # 0x3c +'rwig', # 0x3d +'rwigg', # 0x3e +'rwigs', # 0x3f +'rwin', # 0x40 +'rwinj', # 0x41 +'rwinh', # 0x42 +'rwid', # 0x43 +'rwil', # 0x44 +'rwilg', # 0x45 +'rwilm', # 0x46 +'rwilb', # 0x47 +'rwils', # 0x48 +'rwilt', # 0x49 +'rwilp', # 0x4a +'rwilh', # 0x4b +'rwim', # 0x4c +'rwib', # 0x4d +'rwibs', # 0x4e +'rwis', # 0x4f +'rwiss', # 0x50 +'rwing', # 0x51 +'rwij', # 0x52 +'rwic', # 0x53 +'rwik', # 0x54 +'rwit', # 0x55 +'rwip', # 0x56 +'rwih', # 0x57 +'ryu', # 0x58 +'ryug', # 0x59 +'ryugg', # 0x5a +'ryugs', # 0x5b +'ryun', # 0x5c +'ryunj', # 0x5d +'ryunh', # 0x5e +'ryud', # 0x5f +'ryul', # 0x60 +'ryulg', # 0x61 +'ryulm', # 0x62 +'ryulb', # 0x63 +'ryuls', # 0x64 +'ryult', # 0x65 +'ryulp', # 0x66 +'ryulh', # 0x67 +'ryum', # 0x68 +'ryub', # 0x69 +'ryubs', # 0x6a +'ryus', # 0x6b +'ryuss', # 0x6c +'ryung', # 0x6d +'ryuj', # 0x6e +'ryuc', # 0x6f +'ryuk', # 0x70 +'ryut', # 0x71 +'ryup', # 0x72 +'ryuh', # 0x73 +'reu', # 0x74 +'reug', # 0x75 +'reugg', # 0x76 +'reugs', # 0x77 +'reun', # 0x78 +'reunj', # 0x79 +'reunh', # 0x7a +'reud', # 0x7b +'reul', # 0x7c +'reulg', # 0x7d +'reulm', # 0x7e +'reulb', # 0x7f +'reuls', # 0x80 +'reult', # 0x81 +'reulp', # 0x82 +'reulh', # 0x83 +'reum', # 0x84 +'reub', # 0x85 +'reubs', # 0x86 +'reus', # 0x87 +'reuss', # 0x88 +'reung', # 0x89 +'reuj', # 0x8a +'reuc', # 0x8b +'reuk', # 0x8c +'reut', # 0x8d +'reup', # 0x8e +'reuh', # 0x8f +'ryi', # 0x90 +'ryig', # 0x91 +'ryigg', # 0x92 +'ryigs', # 0x93 +'ryin', # 0x94 +'ryinj', # 0x95 +'ryinh', # 0x96 +'ryid', # 0x97 +'ryil', # 0x98 +'ryilg', # 0x99 +'ryilm', # 0x9a +'ryilb', # 0x9b +'ryils', # 0x9c +'ryilt', # 0x9d +'ryilp', # 0x9e +'ryilh', # 0x9f +'ryim', # 0xa0 +'ryib', # 0xa1 +'ryibs', # 0xa2 +'ryis', # 0xa3 +'ryiss', # 0xa4 +'rying', # 0xa5 +'ryij', # 0xa6 +'ryic', # 0xa7 +'ryik', # 0xa8 +'ryit', # 0xa9 +'ryip', # 0xaa +'ryih', # 0xab +'ri', # 0xac +'rig', # 0xad +'rigg', # 0xae +'rigs', # 0xaf +'rin', # 0xb0 +'rinj', # 0xb1 +'rinh', # 0xb2 +'rid', # 0xb3 +'ril', # 0xb4 +'rilg', # 0xb5 +'rilm', # 0xb6 +'rilb', # 0xb7 +'rils', # 0xb8 +'rilt', # 0xb9 +'rilp', # 0xba +'rilh', # 0xbb +'rim', # 0xbc +'rib', # 0xbd +'ribs', # 0xbe +'ris', # 0xbf +'riss', # 0xc0 +'ring', # 0xc1 +'rij', # 0xc2 +'ric', # 0xc3 +'rik', # 0xc4 +'rit', # 0xc5 +'rip', # 0xc6 +'rih', # 0xc7 +'ma', # 0xc8 +'mag', # 0xc9 +'magg', # 0xca +'mags', # 0xcb +'man', # 0xcc +'manj', # 0xcd +'manh', # 0xce +'mad', # 0xcf +'mal', # 0xd0 +'malg', # 0xd1 +'malm', # 0xd2 +'malb', # 0xd3 +'mals', # 0xd4 +'malt', # 0xd5 +'malp', # 0xd6 +'malh', # 0xd7 +'mam', # 0xd8 +'mab', # 0xd9 +'mabs', # 0xda +'mas', # 0xdb +'mass', # 0xdc +'mang', # 0xdd +'maj', # 0xde +'mac', # 0xdf +'mak', # 0xe0 +'mat', # 0xe1 +'map', # 0xe2 +'mah', # 0xe3 +'mae', # 0xe4 +'maeg', # 0xe5 +'maegg', # 0xe6 +'maegs', # 0xe7 +'maen', # 0xe8 +'maenj', # 0xe9 +'maenh', # 0xea +'maed', # 0xeb +'mael', # 0xec +'maelg', # 0xed +'maelm', # 0xee +'maelb', # 0xef +'maels', # 0xf0 +'maelt', # 0xf1 +'maelp', # 0xf2 +'maelh', # 0xf3 +'maem', # 0xf4 +'maeb', # 0xf5 +'maebs', # 0xf6 +'maes', # 0xf7 +'maess', # 0xf8 +'maeng', # 0xf9 +'maej', # 0xfa +'maec', # 0xfb +'maek', # 0xfc +'maet', # 0xfd +'maep', # 0xfe +'maeh', # 0xff +) diff --git a/libs/unidecode/x0ba.py b/libs/unidecode/x0ba.py new file mode 100644 index 00000000..9ef82940 --- /dev/null +++ b/libs/unidecode/x0ba.py @@ -0,0 +1,258 @@ +data = ( +'mya', # 0x00 +'myag', # 0x01 +'myagg', # 0x02 +'myags', # 0x03 +'myan', # 0x04 +'myanj', # 0x05 +'myanh', # 0x06 +'myad', # 0x07 +'myal', # 0x08 +'myalg', # 0x09 +'myalm', # 0x0a +'myalb', # 0x0b +'myals', # 0x0c +'myalt', # 0x0d +'myalp', # 0x0e +'myalh', # 0x0f +'myam', # 0x10 +'myab', # 0x11 +'myabs', # 0x12 +'myas', # 0x13 +'myass', # 0x14 +'myang', # 0x15 +'myaj', # 0x16 +'myac', # 0x17 +'myak', # 0x18 +'myat', # 0x19 +'myap', # 0x1a +'myah', # 0x1b +'myae', # 0x1c +'myaeg', # 0x1d +'myaegg', # 0x1e +'myaegs', # 0x1f +'myaen', # 0x20 +'myaenj', # 0x21 +'myaenh', # 0x22 +'myaed', # 0x23 +'myael', # 0x24 +'myaelg', # 0x25 +'myaelm', # 0x26 +'myaelb', # 0x27 +'myaels', # 0x28 +'myaelt', # 0x29 +'myaelp', # 0x2a +'myaelh', # 0x2b +'myaem', # 0x2c +'myaeb', # 0x2d +'myaebs', # 0x2e +'myaes', # 0x2f +'myaess', # 0x30 +'myaeng', # 0x31 +'myaej', # 0x32 +'myaec', # 0x33 +'myaek', # 0x34 +'myaet', # 0x35 +'myaep', # 0x36 +'myaeh', # 0x37 +'meo', # 0x38 +'meog', # 0x39 +'meogg', # 0x3a +'meogs', # 0x3b +'meon', # 0x3c +'meonj', # 0x3d +'meonh', # 0x3e +'meod', # 0x3f +'meol', # 0x40 +'meolg', # 0x41 +'meolm', # 0x42 +'meolb', # 0x43 +'meols', # 0x44 +'meolt', # 0x45 +'meolp', # 0x46 +'meolh', # 0x47 +'meom', # 0x48 +'meob', # 0x49 +'meobs', # 0x4a +'meos', # 0x4b +'meoss', # 0x4c +'meong', # 0x4d +'meoj', # 0x4e +'meoc', # 0x4f +'meok', # 0x50 +'meot', # 0x51 +'meop', # 0x52 +'meoh', # 0x53 +'me', # 0x54 +'meg', # 0x55 +'megg', # 0x56 +'megs', # 0x57 +'men', # 0x58 +'menj', # 0x59 +'menh', # 0x5a +'med', # 0x5b +'mel', # 0x5c +'melg', # 0x5d +'melm', # 0x5e +'melb', # 0x5f +'mels', # 0x60 +'melt', # 0x61 +'melp', # 0x62 +'melh', # 0x63 +'mem', # 0x64 +'meb', # 0x65 +'mebs', # 0x66 +'mes', # 0x67 +'mess', # 0x68 +'meng', # 0x69 +'mej', # 0x6a +'mec', # 0x6b +'mek', # 0x6c +'met', # 0x6d +'mep', # 0x6e +'meh', # 0x6f +'myeo', # 0x70 +'myeog', # 0x71 +'myeogg', # 0x72 +'myeogs', # 0x73 +'myeon', # 0x74 +'myeonj', # 0x75 +'myeonh', # 0x76 +'myeod', # 0x77 +'myeol', # 0x78 +'myeolg', # 0x79 +'myeolm', # 0x7a +'myeolb', # 0x7b +'myeols', # 0x7c +'myeolt', # 0x7d +'myeolp', # 0x7e +'myeolh', # 0x7f +'myeom', # 0x80 +'myeob', # 0x81 +'myeobs', # 0x82 +'myeos', # 0x83 +'myeoss', # 0x84 +'myeong', # 0x85 +'myeoj', # 0x86 +'myeoc', # 0x87 +'myeok', # 0x88 +'myeot', # 0x89 +'myeop', # 0x8a +'myeoh', # 0x8b +'mye', # 0x8c +'myeg', # 0x8d +'myegg', # 0x8e +'myegs', # 0x8f +'myen', # 0x90 +'myenj', # 0x91 +'myenh', # 0x92 +'myed', # 0x93 +'myel', # 0x94 +'myelg', # 0x95 +'myelm', # 0x96 +'myelb', # 0x97 +'myels', # 0x98 +'myelt', # 0x99 +'myelp', # 0x9a +'myelh', # 0x9b +'myem', # 0x9c +'myeb', # 0x9d +'myebs', # 0x9e +'myes', # 0x9f +'myess', # 0xa0 +'myeng', # 0xa1 +'myej', # 0xa2 +'myec', # 0xa3 +'myek', # 0xa4 +'myet', # 0xa5 +'myep', # 0xa6 +'myeh', # 0xa7 +'mo', # 0xa8 +'mog', # 0xa9 +'mogg', # 0xaa +'mogs', # 0xab +'mon', # 0xac +'monj', # 0xad +'monh', # 0xae +'mod', # 0xaf +'mol', # 0xb0 +'molg', # 0xb1 +'molm', # 0xb2 +'molb', # 0xb3 +'mols', # 0xb4 +'molt', # 0xb5 +'molp', # 0xb6 +'molh', # 0xb7 +'mom', # 0xb8 +'mob', # 0xb9 +'mobs', # 0xba +'mos', # 0xbb +'moss', # 0xbc +'mong', # 0xbd +'moj', # 0xbe +'moc', # 0xbf +'mok', # 0xc0 +'mot', # 0xc1 +'mop', # 0xc2 +'moh', # 0xc3 +'mwa', # 0xc4 +'mwag', # 0xc5 +'mwagg', # 0xc6 +'mwags', # 0xc7 +'mwan', # 0xc8 +'mwanj', # 0xc9 +'mwanh', # 0xca +'mwad', # 0xcb +'mwal', # 0xcc +'mwalg', # 0xcd +'mwalm', # 0xce +'mwalb', # 0xcf +'mwals', # 0xd0 +'mwalt', # 0xd1 +'mwalp', # 0xd2 +'mwalh', # 0xd3 +'mwam', # 0xd4 +'mwab', # 0xd5 +'mwabs', # 0xd6 +'mwas', # 0xd7 +'mwass', # 0xd8 +'mwang', # 0xd9 +'mwaj', # 0xda +'mwac', # 0xdb +'mwak', # 0xdc +'mwat', # 0xdd +'mwap', # 0xde +'mwah', # 0xdf +'mwae', # 0xe0 +'mwaeg', # 0xe1 +'mwaegg', # 0xe2 +'mwaegs', # 0xe3 +'mwaen', # 0xe4 +'mwaenj', # 0xe5 +'mwaenh', # 0xe6 +'mwaed', # 0xe7 +'mwael', # 0xe8 +'mwaelg', # 0xe9 +'mwaelm', # 0xea +'mwaelb', # 0xeb +'mwaels', # 0xec +'mwaelt', # 0xed +'mwaelp', # 0xee +'mwaelh', # 0xef +'mwaem', # 0xf0 +'mwaeb', # 0xf1 +'mwaebs', # 0xf2 +'mwaes', # 0xf3 +'mwaess', # 0xf4 +'mwaeng', # 0xf5 +'mwaej', # 0xf6 +'mwaec', # 0xf7 +'mwaek', # 0xf8 +'mwaet', # 0xf9 +'mwaep', # 0xfa +'mwaeh', # 0xfb +'moe', # 0xfc +'moeg', # 0xfd +'moegg', # 0xfe +'moegs', # 0xff +) diff --git a/libs/unidecode/x0bb.py b/libs/unidecode/x0bb.py new file mode 100644 index 00000000..b92031be --- /dev/null +++ b/libs/unidecode/x0bb.py @@ -0,0 +1,258 @@ +data = ( +'moen', # 0x00 +'moenj', # 0x01 +'moenh', # 0x02 +'moed', # 0x03 +'moel', # 0x04 +'moelg', # 0x05 +'moelm', # 0x06 +'moelb', # 0x07 +'moels', # 0x08 +'moelt', # 0x09 +'moelp', # 0x0a +'moelh', # 0x0b +'moem', # 0x0c +'moeb', # 0x0d +'moebs', # 0x0e +'moes', # 0x0f +'moess', # 0x10 +'moeng', # 0x11 +'moej', # 0x12 +'moec', # 0x13 +'moek', # 0x14 +'moet', # 0x15 +'moep', # 0x16 +'moeh', # 0x17 +'myo', # 0x18 +'myog', # 0x19 +'myogg', # 0x1a +'myogs', # 0x1b +'myon', # 0x1c +'myonj', # 0x1d +'myonh', # 0x1e +'myod', # 0x1f +'myol', # 0x20 +'myolg', # 0x21 +'myolm', # 0x22 +'myolb', # 0x23 +'myols', # 0x24 +'myolt', # 0x25 +'myolp', # 0x26 +'myolh', # 0x27 +'myom', # 0x28 +'myob', # 0x29 +'myobs', # 0x2a +'myos', # 0x2b +'myoss', # 0x2c +'myong', # 0x2d +'myoj', # 0x2e +'myoc', # 0x2f +'myok', # 0x30 +'myot', # 0x31 +'myop', # 0x32 +'myoh', # 0x33 +'mu', # 0x34 +'mug', # 0x35 +'mugg', # 0x36 +'mugs', # 0x37 +'mun', # 0x38 +'munj', # 0x39 +'munh', # 0x3a +'mud', # 0x3b +'mul', # 0x3c +'mulg', # 0x3d +'mulm', # 0x3e +'mulb', # 0x3f +'muls', # 0x40 +'mult', # 0x41 +'mulp', # 0x42 +'mulh', # 0x43 +'mum', # 0x44 +'mub', # 0x45 +'mubs', # 0x46 +'mus', # 0x47 +'muss', # 0x48 +'mung', # 0x49 +'muj', # 0x4a +'muc', # 0x4b +'muk', # 0x4c +'mut', # 0x4d +'mup', # 0x4e +'muh', # 0x4f +'mweo', # 0x50 +'mweog', # 0x51 +'mweogg', # 0x52 +'mweogs', # 0x53 +'mweon', # 0x54 +'mweonj', # 0x55 +'mweonh', # 0x56 +'mweod', # 0x57 +'mweol', # 0x58 +'mweolg', # 0x59 +'mweolm', # 0x5a +'mweolb', # 0x5b +'mweols', # 0x5c +'mweolt', # 0x5d +'mweolp', # 0x5e +'mweolh', # 0x5f +'mweom', # 0x60 +'mweob', # 0x61 +'mweobs', # 0x62 +'mweos', # 0x63 +'mweoss', # 0x64 +'mweong', # 0x65 +'mweoj', # 0x66 +'mweoc', # 0x67 +'mweok', # 0x68 +'mweot', # 0x69 +'mweop', # 0x6a +'mweoh', # 0x6b +'mwe', # 0x6c +'mweg', # 0x6d +'mwegg', # 0x6e +'mwegs', # 0x6f +'mwen', # 0x70 +'mwenj', # 0x71 +'mwenh', # 0x72 +'mwed', # 0x73 +'mwel', # 0x74 +'mwelg', # 0x75 +'mwelm', # 0x76 +'mwelb', # 0x77 +'mwels', # 0x78 +'mwelt', # 0x79 +'mwelp', # 0x7a +'mwelh', # 0x7b +'mwem', # 0x7c +'mweb', # 0x7d +'mwebs', # 0x7e +'mwes', # 0x7f +'mwess', # 0x80 +'mweng', # 0x81 +'mwej', # 0x82 +'mwec', # 0x83 +'mwek', # 0x84 +'mwet', # 0x85 +'mwep', # 0x86 +'mweh', # 0x87 +'mwi', # 0x88 +'mwig', # 0x89 +'mwigg', # 0x8a +'mwigs', # 0x8b +'mwin', # 0x8c +'mwinj', # 0x8d +'mwinh', # 0x8e +'mwid', # 0x8f +'mwil', # 0x90 +'mwilg', # 0x91 +'mwilm', # 0x92 +'mwilb', # 0x93 +'mwils', # 0x94 +'mwilt', # 0x95 +'mwilp', # 0x96 +'mwilh', # 0x97 +'mwim', # 0x98 +'mwib', # 0x99 +'mwibs', # 0x9a +'mwis', # 0x9b +'mwiss', # 0x9c +'mwing', # 0x9d +'mwij', # 0x9e +'mwic', # 0x9f +'mwik', # 0xa0 +'mwit', # 0xa1 +'mwip', # 0xa2 +'mwih', # 0xa3 +'myu', # 0xa4 +'myug', # 0xa5 +'myugg', # 0xa6 +'myugs', # 0xa7 +'myun', # 0xa8 +'myunj', # 0xa9 +'myunh', # 0xaa +'myud', # 0xab +'myul', # 0xac +'myulg', # 0xad +'myulm', # 0xae +'myulb', # 0xaf +'myuls', # 0xb0 +'myult', # 0xb1 +'myulp', # 0xb2 +'myulh', # 0xb3 +'myum', # 0xb4 +'myub', # 0xb5 +'myubs', # 0xb6 +'myus', # 0xb7 +'myuss', # 0xb8 +'myung', # 0xb9 +'myuj', # 0xba +'myuc', # 0xbb +'myuk', # 0xbc +'myut', # 0xbd +'myup', # 0xbe +'myuh', # 0xbf +'meu', # 0xc0 +'meug', # 0xc1 +'meugg', # 0xc2 +'meugs', # 0xc3 +'meun', # 0xc4 +'meunj', # 0xc5 +'meunh', # 0xc6 +'meud', # 0xc7 +'meul', # 0xc8 +'meulg', # 0xc9 +'meulm', # 0xca +'meulb', # 0xcb +'meuls', # 0xcc +'meult', # 0xcd +'meulp', # 0xce +'meulh', # 0xcf +'meum', # 0xd0 +'meub', # 0xd1 +'meubs', # 0xd2 +'meus', # 0xd3 +'meuss', # 0xd4 +'meung', # 0xd5 +'meuj', # 0xd6 +'meuc', # 0xd7 +'meuk', # 0xd8 +'meut', # 0xd9 +'meup', # 0xda +'meuh', # 0xdb +'myi', # 0xdc +'myig', # 0xdd +'myigg', # 0xde +'myigs', # 0xdf +'myin', # 0xe0 +'myinj', # 0xe1 +'myinh', # 0xe2 +'myid', # 0xe3 +'myil', # 0xe4 +'myilg', # 0xe5 +'myilm', # 0xe6 +'myilb', # 0xe7 +'myils', # 0xe8 +'myilt', # 0xe9 +'myilp', # 0xea +'myilh', # 0xeb +'myim', # 0xec +'myib', # 0xed +'myibs', # 0xee +'myis', # 0xef +'myiss', # 0xf0 +'mying', # 0xf1 +'myij', # 0xf2 +'myic', # 0xf3 +'myik', # 0xf4 +'myit', # 0xf5 +'myip', # 0xf6 +'myih', # 0xf7 +'mi', # 0xf8 +'mig', # 0xf9 +'migg', # 0xfa +'migs', # 0xfb +'min', # 0xfc +'minj', # 0xfd +'minh', # 0xfe +'mid', # 0xff +) diff --git a/libs/unidecode/x0bc.py b/libs/unidecode/x0bc.py new file mode 100644 index 00000000..c0b3f320 --- /dev/null +++ b/libs/unidecode/x0bc.py @@ -0,0 +1,258 @@ +data = ( +'mil', # 0x00 +'milg', # 0x01 +'milm', # 0x02 +'milb', # 0x03 +'mils', # 0x04 +'milt', # 0x05 +'milp', # 0x06 +'milh', # 0x07 +'mim', # 0x08 +'mib', # 0x09 +'mibs', # 0x0a +'mis', # 0x0b +'miss', # 0x0c +'ming', # 0x0d +'mij', # 0x0e +'mic', # 0x0f +'mik', # 0x10 +'mit', # 0x11 +'mip', # 0x12 +'mih', # 0x13 +'ba', # 0x14 +'bag', # 0x15 +'bagg', # 0x16 +'bags', # 0x17 +'ban', # 0x18 +'banj', # 0x19 +'banh', # 0x1a +'bad', # 0x1b +'bal', # 0x1c +'balg', # 0x1d +'balm', # 0x1e +'balb', # 0x1f +'bals', # 0x20 +'balt', # 0x21 +'balp', # 0x22 +'balh', # 0x23 +'bam', # 0x24 +'bab', # 0x25 +'babs', # 0x26 +'bas', # 0x27 +'bass', # 0x28 +'bang', # 0x29 +'baj', # 0x2a +'bac', # 0x2b +'bak', # 0x2c +'bat', # 0x2d +'bap', # 0x2e +'bah', # 0x2f +'bae', # 0x30 +'baeg', # 0x31 +'baegg', # 0x32 +'baegs', # 0x33 +'baen', # 0x34 +'baenj', # 0x35 +'baenh', # 0x36 +'baed', # 0x37 +'bael', # 0x38 +'baelg', # 0x39 +'baelm', # 0x3a +'baelb', # 0x3b +'baels', # 0x3c +'baelt', # 0x3d +'baelp', # 0x3e +'baelh', # 0x3f +'baem', # 0x40 +'baeb', # 0x41 +'baebs', # 0x42 +'baes', # 0x43 +'baess', # 0x44 +'baeng', # 0x45 +'baej', # 0x46 +'baec', # 0x47 +'baek', # 0x48 +'baet', # 0x49 +'baep', # 0x4a +'baeh', # 0x4b +'bya', # 0x4c +'byag', # 0x4d +'byagg', # 0x4e +'byags', # 0x4f +'byan', # 0x50 +'byanj', # 0x51 +'byanh', # 0x52 +'byad', # 0x53 +'byal', # 0x54 +'byalg', # 0x55 +'byalm', # 0x56 +'byalb', # 0x57 +'byals', # 0x58 +'byalt', # 0x59 +'byalp', # 0x5a +'byalh', # 0x5b +'byam', # 0x5c +'byab', # 0x5d +'byabs', # 0x5e +'byas', # 0x5f +'byass', # 0x60 +'byang', # 0x61 +'byaj', # 0x62 +'byac', # 0x63 +'byak', # 0x64 +'byat', # 0x65 +'byap', # 0x66 +'byah', # 0x67 +'byae', # 0x68 +'byaeg', # 0x69 +'byaegg', # 0x6a +'byaegs', # 0x6b +'byaen', # 0x6c +'byaenj', # 0x6d +'byaenh', # 0x6e +'byaed', # 0x6f +'byael', # 0x70 +'byaelg', # 0x71 +'byaelm', # 0x72 +'byaelb', # 0x73 +'byaels', # 0x74 +'byaelt', # 0x75 +'byaelp', # 0x76 +'byaelh', # 0x77 +'byaem', # 0x78 +'byaeb', # 0x79 +'byaebs', # 0x7a +'byaes', # 0x7b +'byaess', # 0x7c +'byaeng', # 0x7d +'byaej', # 0x7e +'byaec', # 0x7f +'byaek', # 0x80 +'byaet', # 0x81 +'byaep', # 0x82 +'byaeh', # 0x83 +'beo', # 0x84 +'beog', # 0x85 +'beogg', # 0x86 +'beogs', # 0x87 +'beon', # 0x88 +'beonj', # 0x89 +'beonh', # 0x8a +'beod', # 0x8b +'beol', # 0x8c +'beolg', # 0x8d +'beolm', # 0x8e +'beolb', # 0x8f +'beols', # 0x90 +'beolt', # 0x91 +'beolp', # 0x92 +'beolh', # 0x93 +'beom', # 0x94 +'beob', # 0x95 +'beobs', # 0x96 +'beos', # 0x97 +'beoss', # 0x98 +'beong', # 0x99 +'beoj', # 0x9a +'beoc', # 0x9b +'beok', # 0x9c +'beot', # 0x9d +'beop', # 0x9e +'beoh', # 0x9f +'be', # 0xa0 +'beg', # 0xa1 +'begg', # 0xa2 +'begs', # 0xa3 +'ben', # 0xa4 +'benj', # 0xa5 +'benh', # 0xa6 +'bed', # 0xa7 +'bel', # 0xa8 +'belg', # 0xa9 +'belm', # 0xaa +'belb', # 0xab +'bels', # 0xac +'belt', # 0xad +'belp', # 0xae +'belh', # 0xaf +'bem', # 0xb0 +'beb', # 0xb1 +'bebs', # 0xb2 +'bes', # 0xb3 +'bess', # 0xb4 +'beng', # 0xb5 +'bej', # 0xb6 +'bec', # 0xb7 +'bek', # 0xb8 +'bet', # 0xb9 +'bep', # 0xba +'beh', # 0xbb +'byeo', # 0xbc +'byeog', # 0xbd +'byeogg', # 0xbe +'byeogs', # 0xbf +'byeon', # 0xc0 +'byeonj', # 0xc1 +'byeonh', # 0xc2 +'byeod', # 0xc3 +'byeol', # 0xc4 +'byeolg', # 0xc5 +'byeolm', # 0xc6 +'byeolb', # 0xc7 +'byeols', # 0xc8 +'byeolt', # 0xc9 +'byeolp', # 0xca +'byeolh', # 0xcb +'byeom', # 0xcc +'byeob', # 0xcd +'byeobs', # 0xce +'byeos', # 0xcf +'byeoss', # 0xd0 +'byeong', # 0xd1 +'byeoj', # 0xd2 +'byeoc', # 0xd3 +'byeok', # 0xd4 +'byeot', # 0xd5 +'byeop', # 0xd6 +'byeoh', # 0xd7 +'bye', # 0xd8 +'byeg', # 0xd9 +'byegg', # 0xda +'byegs', # 0xdb +'byen', # 0xdc +'byenj', # 0xdd +'byenh', # 0xde +'byed', # 0xdf +'byel', # 0xe0 +'byelg', # 0xe1 +'byelm', # 0xe2 +'byelb', # 0xe3 +'byels', # 0xe4 +'byelt', # 0xe5 +'byelp', # 0xe6 +'byelh', # 0xe7 +'byem', # 0xe8 +'byeb', # 0xe9 +'byebs', # 0xea +'byes', # 0xeb +'byess', # 0xec +'byeng', # 0xed +'byej', # 0xee +'byec', # 0xef +'byek', # 0xf0 +'byet', # 0xf1 +'byep', # 0xf2 +'byeh', # 0xf3 +'bo', # 0xf4 +'bog', # 0xf5 +'bogg', # 0xf6 +'bogs', # 0xf7 +'bon', # 0xf8 +'bonj', # 0xf9 +'bonh', # 0xfa +'bod', # 0xfb +'bol', # 0xfc +'bolg', # 0xfd +'bolm', # 0xfe +'bolb', # 0xff +) diff --git a/libs/unidecode/x0bd.py b/libs/unidecode/x0bd.py new file mode 100644 index 00000000..6473883f --- /dev/null +++ b/libs/unidecode/x0bd.py @@ -0,0 +1,258 @@ +data = ( +'bols', # 0x00 +'bolt', # 0x01 +'bolp', # 0x02 +'bolh', # 0x03 +'bom', # 0x04 +'bob', # 0x05 +'bobs', # 0x06 +'bos', # 0x07 +'boss', # 0x08 +'bong', # 0x09 +'boj', # 0x0a +'boc', # 0x0b +'bok', # 0x0c +'bot', # 0x0d +'bop', # 0x0e +'boh', # 0x0f +'bwa', # 0x10 +'bwag', # 0x11 +'bwagg', # 0x12 +'bwags', # 0x13 +'bwan', # 0x14 +'bwanj', # 0x15 +'bwanh', # 0x16 +'bwad', # 0x17 +'bwal', # 0x18 +'bwalg', # 0x19 +'bwalm', # 0x1a +'bwalb', # 0x1b +'bwals', # 0x1c +'bwalt', # 0x1d +'bwalp', # 0x1e +'bwalh', # 0x1f +'bwam', # 0x20 +'bwab', # 0x21 +'bwabs', # 0x22 +'bwas', # 0x23 +'bwass', # 0x24 +'bwang', # 0x25 +'bwaj', # 0x26 +'bwac', # 0x27 +'bwak', # 0x28 +'bwat', # 0x29 +'bwap', # 0x2a +'bwah', # 0x2b +'bwae', # 0x2c +'bwaeg', # 0x2d +'bwaegg', # 0x2e +'bwaegs', # 0x2f +'bwaen', # 0x30 +'bwaenj', # 0x31 +'bwaenh', # 0x32 +'bwaed', # 0x33 +'bwael', # 0x34 +'bwaelg', # 0x35 +'bwaelm', # 0x36 +'bwaelb', # 0x37 +'bwaels', # 0x38 +'bwaelt', # 0x39 +'bwaelp', # 0x3a +'bwaelh', # 0x3b +'bwaem', # 0x3c +'bwaeb', # 0x3d +'bwaebs', # 0x3e +'bwaes', # 0x3f +'bwaess', # 0x40 +'bwaeng', # 0x41 +'bwaej', # 0x42 +'bwaec', # 0x43 +'bwaek', # 0x44 +'bwaet', # 0x45 +'bwaep', # 0x46 +'bwaeh', # 0x47 +'boe', # 0x48 +'boeg', # 0x49 +'boegg', # 0x4a +'boegs', # 0x4b +'boen', # 0x4c +'boenj', # 0x4d +'boenh', # 0x4e +'boed', # 0x4f +'boel', # 0x50 +'boelg', # 0x51 +'boelm', # 0x52 +'boelb', # 0x53 +'boels', # 0x54 +'boelt', # 0x55 +'boelp', # 0x56 +'boelh', # 0x57 +'boem', # 0x58 +'boeb', # 0x59 +'boebs', # 0x5a +'boes', # 0x5b +'boess', # 0x5c +'boeng', # 0x5d +'boej', # 0x5e +'boec', # 0x5f +'boek', # 0x60 +'boet', # 0x61 +'boep', # 0x62 +'boeh', # 0x63 +'byo', # 0x64 +'byog', # 0x65 +'byogg', # 0x66 +'byogs', # 0x67 +'byon', # 0x68 +'byonj', # 0x69 +'byonh', # 0x6a +'byod', # 0x6b +'byol', # 0x6c +'byolg', # 0x6d +'byolm', # 0x6e +'byolb', # 0x6f +'byols', # 0x70 +'byolt', # 0x71 +'byolp', # 0x72 +'byolh', # 0x73 +'byom', # 0x74 +'byob', # 0x75 +'byobs', # 0x76 +'byos', # 0x77 +'byoss', # 0x78 +'byong', # 0x79 +'byoj', # 0x7a +'byoc', # 0x7b +'byok', # 0x7c +'byot', # 0x7d +'byop', # 0x7e +'byoh', # 0x7f +'bu', # 0x80 +'bug', # 0x81 +'bugg', # 0x82 +'bugs', # 0x83 +'bun', # 0x84 +'bunj', # 0x85 +'bunh', # 0x86 +'bud', # 0x87 +'bul', # 0x88 +'bulg', # 0x89 +'bulm', # 0x8a +'bulb', # 0x8b +'buls', # 0x8c +'bult', # 0x8d +'bulp', # 0x8e +'bulh', # 0x8f +'bum', # 0x90 +'bub', # 0x91 +'bubs', # 0x92 +'bus', # 0x93 +'buss', # 0x94 +'bung', # 0x95 +'buj', # 0x96 +'buc', # 0x97 +'buk', # 0x98 +'but', # 0x99 +'bup', # 0x9a +'buh', # 0x9b +'bweo', # 0x9c +'bweog', # 0x9d +'bweogg', # 0x9e +'bweogs', # 0x9f +'bweon', # 0xa0 +'bweonj', # 0xa1 +'bweonh', # 0xa2 +'bweod', # 0xa3 +'bweol', # 0xa4 +'bweolg', # 0xa5 +'bweolm', # 0xa6 +'bweolb', # 0xa7 +'bweols', # 0xa8 +'bweolt', # 0xa9 +'bweolp', # 0xaa +'bweolh', # 0xab +'bweom', # 0xac +'bweob', # 0xad +'bweobs', # 0xae +'bweos', # 0xaf +'bweoss', # 0xb0 +'bweong', # 0xb1 +'bweoj', # 0xb2 +'bweoc', # 0xb3 +'bweok', # 0xb4 +'bweot', # 0xb5 +'bweop', # 0xb6 +'bweoh', # 0xb7 +'bwe', # 0xb8 +'bweg', # 0xb9 +'bwegg', # 0xba +'bwegs', # 0xbb +'bwen', # 0xbc +'bwenj', # 0xbd +'bwenh', # 0xbe +'bwed', # 0xbf +'bwel', # 0xc0 +'bwelg', # 0xc1 +'bwelm', # 0xc2 +'bwelb', # 0xc3 +'bwels', # 0xc4 +'bwelt', # 0xc5 +'bwelp', # 0xc6 +'bwelh', # 0xc7 +'bwem', # 0xc8 +'bweb', # 0xc9 +'bwebs', # 0xca +'bwes', # 0xcb +'bwess', # 0xcc +'bweng', # 0xcd +'bwej', # 0xce +'bwec', # 0xcf +'bwek', # 0xd0 +'bwet', # 0xd1 +'bwep', # 0xd2 +'bweh', # 0xd3 +'bwi', # 0xd4 +'bwig', # 0xd5 +'bwigg', # 0xd6 +'bwigs', # 0xd7 +'bwin', # 0xd8 +'bwinj', # 0xd9 +'bwinh', # 0xda +'bwid', # 0xdb +'bwil', # 0xdc +'bwilg', # 0xdd +'bwilm', # 0xde +'bwilb', # 0xdf +'bwils', # 0xe0 +'bwilt', # 0xe1 +'bwilp', # 0xe2 +'bwilh', # 0xe3 +'bwim', # 0xe4 +'bwib', # 0xe5 +'bwibs', # 0xe6 +'bwis', # 0xe7 +'bwiss', # 0xe8 +'bwing', # 0xe9 +'bwij', # 0xea +'bwic', # 0xeb +'bwik', # 0xec +'bwit', # 0xed +'bwip', # 0xee +'bwih', # 0xef +'byu', # 0xf0 +'byug', # 0xf1 +'byugg', # 0xf2 +'byugs', # 0xf3 +'byun', # 0xf4 +'byunj', # 0xf5 +'byunh', # 0xf6 +'byud', # 0xf7 +'byul', # 0xf8 +'byulg', # 0xf9 +'byulm', # 0xfa +'byulb', # 0xfb +'byuls', # 0xfc +'byult', # 0xfd +'byulp', # 0xfe +'byulh', # 0xff +) diff --git a/libs/unidecode/x0be.py b/libs/unidecode/x0be.py new file mode 100644 index 00000000..85c184e7 --- /dev/null +++ b/libs/unidecode/x0be.py @@ -0,0 +1,258 @@ +data = ( +'byum', # 0x00 +'byub', # 0x01 +'byubs', # 0x02 +'byus', # 0x03 +'byuss', # 0x04 +'byung', # 0x05 +'byuj', # 0x06 +'byuc', # 0x07 +'byuk', # 0x08 +'byut', # 0x09 +'byup', # 0x0a +'byuh', # 0x0b +'beu', # 0x0c +'beug', # 0x0d +'beugg', # 0x0e +'beugs', # 0x0f +'beun', # 0x10 +'beunj', # 0x11 +'beunh', # 0x12 +'beud', # 0x13 +'beul', # 0x14 +'beulg', # 0x15 +'beulm', # 0x16 +'beulb', # 0x17 +'beuls', # 0x18 +'beult', # 0x19 +'beulp', # 0x1a +'beulh', # 0x1b +'beum', # 0x1c +'beub', # 0x1d +'beubs', # 0x1e +'beus', # 0x1f +'beuss', # 0x20 +'beung', # 0x21 +'beuj', # 0x22 +'beuc', # 0x23 +'beuk', # 0x24 +'beut', # 0x25 +'beup', # 0x26 +'beuh', # 0x27 +'byi', # 0x28 +'byig', # 0x29 +'byigg', # 0x2a +'byigs', # 0x2b +'byin', # 0x2c +'byinj', # 0x2d +'byinh', # 0x2e +'byid', # 0x2f +'byil', # 0x30 +'byilg', # 0x31 +'byilm', # 0x32 +'byilb', # 0x33 +'byils', # 0x34 +'byilt', # 0x35 +'byilp', # 0x36 +'byilh', # 0x37 +'byim', # 0x38 +'byib', # 0x39 +'byibs', # 0x3a +'byis', # 0x3b +'byiss', # 0x3c +'bying', # 0x3d +'byij', # 0x3e +'byic', # 0x3f +'byik', # 0x40 +'byit', # 0x41 +'byip', # 0x42 +'byih', # 0x43 +'bi', # 0x44 +'big', # 0x45 +'bigg', # 0x46 +'bigs', # 0x47 +'bin', # 0x48 +'binj', # 0x49 +'binh', # 0x4a +'bid', # 0x4b +'bil', # 0x4c +'bilg', # 0x4d +'bilm', # 0x4e +'bilb', # 0x4f +'bils', # 0x50 +'bilt', # 0x51 +'bilp', # 0x52 +'bilh', # 0x53 +'bim', # 0x54 +'bib', # 0x55 +'bibs', # 0x56 +'bis', # 0x57 +'biss', # 0x58 +'bing', # 0x59 +'bij', # 0x5a +'bic', # 0x5b +'bik', # 0x5c +'bit', # 0x5d +'bip', # 0x5e +'bih', # 0x5f +'bba', # 0x60 +'bbag', # 0x61 +'bbagg', # 0x62 +'bbags', # 0x63 +'bban', # 0x64 +'bbanj', # 0x65 +'bbanh', # 0x66 +'bbad', # 0x67 +'bbal', # 0x68 +'bbalg', # 0x69 +'bbalm', # 0x6a +'bbalb', # 0x6b +'bbals', # 0x6c +'bbalt', # 0x6d +'bbalp', # 0x6e +'bbalh', # 0x6f +'bbam', # 0x70 +'bbab', # 0x71 +'bbabs', # 0x72 +'bbas', # 0x73 +'bbass', # 0x74 +'bbang', # 0x75 +'bbaj', # 0x76 +'bbac', # 0x77 +'bbak', # 0x78 +'bbat', # 0x79 +'bbap', # 0x7a +'bbah', # 0x7b +'bbae', # 0x7c +'bbaeg', # 0x7d +'bbaegg', # 0x7e +'bbaegs', # 0x7f +'bbaen', # 0x80 +'bbaenj', # 0x81 +'bbaenh', # 0x82 +'bbaed', # 0x83 +'bbael', # 0x84 +'bbaelg', # 0x85 +'bbaelm', # 0x86 +'bbaelb', # 0x87 +'bbaels', # 0x88 +'bbaelt', # 0x89 +'bbaelp', # 0x8a +'bbaelh', # 0x8b +'bbaem', # 0x8c +'bbaeb', # 0x8d +'bbaebs', # 0x8e +'bbaes', # 0x8f +'bbaess', # 0x90 +'bbaeng', # 0x91 +'bbaej', # 0x92 +'bbaec', # 0x93 +'bbaek', # 0x94 +'bbaet', # 0x95 +'bbaep', # 0x96 +'bbaeh', # 0x97 +'bbya', # 0x98 +'bbyag', # 0x99 +'bbyagg', # 0x9a +'bbyags', # 0x9b +'bbyan', # 0x9c +'bbyanj', # 0x9d +'bbyanh', # 0x9e +'bbyad', # 0x9f +'bbyal', # 0xa0 +'bbyalg', # 0xa1 +'bbyalm', # 0xa2 +'bbyalb', # 0xa3 +'bbyals', # 0xa4 +'bbyalt', # 0xa5 +'bbyalp', # 0xa6 +'bbyalh', # 0xa7 +'bbyam', # 0xa8 +'bbyab', # 0xa9 +'bbyabs', # 0xaa +'bbyas', # 0xab +'bbyass', # 0xac +'bbyang', # 0xad +'bbyaj', # 0xae +'bbyac', # 0xaf +'bbyak', # 0xb0 +'bbyat', # 0xb1 +'bbyap', # 0xb2 +'bbyah', # 0xb3 +'bbyae', # 0xb4 +'bbyaeg', # 0xb5 +'bbyaegg', # 0xb6 +'bbyaegs', # 0xb7 +'bbyaen', # 0xb8 +'bbyaenj', # 0xb9 +'bbyaenh', # 0xba +'bbyaed', # 0xbb +'bbyael', # 0xbc +'bbyaelg', # 0xbd +'bbyaelm', # 0xbe +'bbyaelb', # 0xbf +'bbyaels', # 0xc0 +'bbyaelt', # 0xc1 +'bbyaelp', # 0xc2 +'bbyaelh', # 0xc3 +'bbyaem', # 0xc4 +'bbyaeb', # 0xc5 +'bbyaebs', # 0xc6 +'bbyaes', # 0xc7 +'bbyaess', # 0xc8 +'bbyaeng', # 0xc9 +'bbyaej', # 0xca +'bbyaec', # 0xcb +'bbyaek', # 0xcc +'bbyaet', # 0xcd +'bbyaep', # 0xce +'bbyaeh', # 0xcf +'bbeo', # 0xd0 +'bbeog', # 0xd1 +'bbeogg', # 0xd2 +'bbeogs', # 0xd3 +'bbeon', # 0xd4 +'bbeonj', # 0xd5 +'bbeonh', # 0xd6 +'bbeod', # 0xd7 +'bbeol', # 0xd8 +'bbeolg', # 0xd9 +'bbeolm', # 0xda +'bbeolb', # 0xdb +'bbeols', # 0xdc +'bbeolt', # 0xdd +'bbeolp', # 0xde +'bbeolh', # 0xdf +'bbeom', # 0xe0 +'bbeob', # 0xe1 +'bbeobs', # 0xe2 +'bbeos', # 0xe3 +'bbeoss', # 0xe4 +'bbeong', # 0xe5 +'bbeoj', # 0xe6 +'bbeoc', # 0xe7 +'bbeok', # 0xe8 +'bbeot', # 0xe9 +'bbeop', # 0xea +'bbeoh', # 0xeb +'bbe', # 0xec +'bbeg', # 0xed +'bbegg', # 0xee +'bbegs', # 0xef +'bben', # 0xf0 +'bbenj', # 0xf1 +'bbenh', # 0xf2 +'bbed', # 0xf3 +'bbel', # 0xf4 +'bbelg', # 0xf5 +'bbelm', # 0xf6 +'bbelb', # 0xf7 +'bbels', # 0xf8 +'bbelt', # 0xf9 +'bbelp', # 0xfa +'bbelh', # 0xfb +'bbem', # 0xfc +'bbeb', # 0xfd +'bbebs', # 0xfe +'bbes', # 0xff +) diff --git a/libs/unidecode/x0bf.py b/libs/unidecode/x0bf.py new file mode 100644 index 00000000..a7b3a718 --- /dev/null +++ b/libs/unidecode/x0bf.py @@ -0,0 +1,258 @@ +data = ( +'bbess', # 0x00 +'bbeng', # 0x01 +'bbej', # 0x02 +'bbec', # 0x03 +'bbek', # 0x04 +'bbet', # 0x05 +'bbep', # 0x06 +'bbeh', # 0x07 +'bbyeo', # 0x08 +'bbyeog', # 0x09 +'bbyeogg', # 0x0a +'bbyeogs', # 0x0b +'bbyeon', # 0x0c +'bbyeonj', # 0x0d +'bbyeonh', # 0x0e +'bbyeod', # 0x0f +'bbyeol', # 0x10 +'bbyeolg', # 0x11 +'bbyeolm', # 0x12 +'bbyeolb', # 0x13 +'bbyeols', # 0x14 +'bbyeolt', # 0x15 +'bbyeolp', # 0x16 +'bbyeolh', # 0x17 +'bbyeom', # 0x18 +'bbyeob', # 0x19 +'bbyeobs', # 0x1a +'bbyeos', # 0x1b +'bbyeoss', # 0x1c +'bbyeong', # 0x1d +'bbyeoj', # 0x1e +'bbyeoc', # 0x1f +'bbyeok', # 0x20 +'bbyeot', # 0x21 +'bbyeop', # 0x22 +'bbyeoh', # 0x23 +'bbye', # 0x24 +'bbyeg', # 0x25 +'bbyegg', # 0x26 +'bbyegs', # 0x27 +'bbyen', # 0x28 +'bbyenj', # 0x29 +'bbyenh', # 0x2a +'bbyed', # 0x2b +'bbyel', # 0x2c +'bbyelg', # 0x2d +'bbyelm', # 0x2e +'bbyelb', # 0x2f +'bbyels', # 0x30 +'bbyelt', # 0x31 +'bbyelp', # 0x32 +'bbyelh', # 0x33 +'bbyem', # 0x34 +'bbyeb', # 0x35 +'bbyebs', # 0x36 +'bbyes', # 0x37 +'bbyess', # 0x38 +'bbyeng', # 0x39 +'bbyej', # 0x3a +'bbyec', # 0x3b +'bbyek', # 0x3c +'bbyet', # 0x3d +'bbyep', # 0x3e +'bbyeh', # 0x3f +'bbo', # 0x40 +'bbog', # 0x41 +'bbogg', # 0x42 +'bbogs', # 0x43 +'bbon', # 0x44 +'bbonj', # 0x45 +'bbonh', # 0x46 +'bbod', # 0x47 +'bbol', # 0x48 +'bbolg', # 0x49 +'bbolm', # 0x4a +'bbolb', # 0x4b +'bbols', # 0x4c +'bbolt', # 0x4d +'bbolp', # 0x4e +'bbolh', # 0x4f +'bbom', # 0x50 +'bbob', # 0x51 +'bbobs', # 0x52 +'bbos', # 0x53 +'bboss', # 0x54 +'bbong', # 0x55 +'bboj', # 0x56 +'bboc', # 0x57 +'bbok', # 0x58 +'bbot', # 0x59 +'bbop', # 0x5a +'bboh', # 0x5b +'bbwa', # 0x5c +'bbwag', # 0x5d +'bbwagg', # 0x5e +'bbwags', # 0x5f +'bbwan', # 0x60 +'bbwanj', # 0x61 +'bbwanh', # 0x62 +'bbwad', # 0x63 +'bbwal', # 0x64 +'bbwalg', # 0x65 +'bbwalm', # 0x66 +'bbwalb', # 0x67 +'bbwals', # 0x68 +'bbwalt', # 0x69 +'bbwalp', # 0x6a +'bbwalh', # 0x6b +'bbwam', # 0x6c +'bbwab', # 0x6d +'bbwabs', # 0x6e +'bbwas', # 0x6f +'bbwass', # 0x70 +'bbwang', # 0x71 +'bbwaj', # 0x72 +'bbwac', # 0x73 +'bbwak', # 0x74 +'bbwat', # 0x75 +'bbwap', # 0x76 +'bbwah', # 0x77 +'bbwae', # 0x78 +'bbwaeg', # 0x79 +'bbwaegg', # 0x7a +'bbwaegs', # 0x7b +'bbwaen', # 0x7c +'bbwaenj', # 0x7d +'bbwaenh', # 0x7e +'bbwaed', # 0x7f +'bbwael', # 0x80 +'bbwaelg', # 0x81 +'bbwaelm', # 0x82 +'bbwaelb', # 0x83 +'bbwaels', # 0x84 +'bbwaelt', # 0x85 +'bbwaelp', # 0x86 +'bbwaelh', # 0x87 +'bbwaem', # 0x88 +'bbwaeb', # 0x89 +'bbwaebs', # 0x8a +'bbwaes', # 0x8b +'bbwaess', # 0x8c +'bbwaeng', # 0x8d +'bbwaej', # 0x8e +'bbwaec', # 0x8f +'bbwaek', # 0x90 +'bbwaet', # 0x91 +'bbwaep', # 0x92 +'bbwaeh', # 0x93 +'bboe', # 0x94 +'bboeg', # 0x95 +'bboegg', # 0x96 +'bboegs', # 0x97 +'bboen', # 0x98 +'bboenj', # 0x99 +'bboenh', # 0x9a +'bboed', # 0x9b +'bboel', # 0x9c +'bboelg', # 0x9d +'bboelm', # 0x9e +'bboelb', # 0x9f +'bboels', # 0xa0 +'bboelt', # 0xa1 +'bboelp', # 0xa2 +'bboelh', # 0xa3 +'bboem', # 0xa4 +'bboeb', # 0xa5 +'bboebs', # 0xa6 +'bboes', # 0xa7 +'bboess', # 0xa8 +'bboeng', # 0xa9 +'bboej', # 0xaa +'bboec', # 0xab +'bboek', # 0xac +'bboet', # 0xad +'bboep', # 0xae +'bboeh', # 0xaf +'bbyo', # 0xb0 +'bbyog', # 0xb1 +'bbyogg', # 0xb2 +'bbyogs', # 0xb3 +'bbyon', # 0xb4 +'bbyonj', # 0xb5 +'bbyonh', # 0xb6 +'bbyod', # 0xb7 +'bbyol', # 0xb8 +'bbyolg', # 0xb9 +'bbyolm', # 0xba +'bbyolb', # 0xbb +'bbyols', # 0xbc +'bbyolt', # 0xbd +'bbyolp', # 0xbe +'bbyolh', # 0xbf +'bbyom', # 0xc0 +'bbyob', # 0xc1 +'bbyobs', # 0xc2 +'bbyos', # 0xc3 +'bbyoss', # 0xc4 +'bbyong', # 0xc5 +'bbyoj', # 0xc6 +'bbyoc', # 0xc7 +'bbyok', # 0xc8 +'bbyot', # 0xc9 +'bbyop', # 0xca +'bbyoh', # 0xcb +'bbu', # 0xcc +'bbug', # 0xcd +'bbugg', # 0xce +'bbugs', # 0xcf +'bbun', # 0xd0 +'bbunj', # 0xd1 +'bbunh', # 0xd2 +'bbud', # 0xd3 +'bbul', # 0xd4 +'bbulg', # 0xd5 +'bbulm', # 0xd6 +'bbulb', # 0xd7 +'bbuls', # 0xd8 +'bbult', # 0xd9 +'bbulp', # 0xda +'bbulh', # 0xdb +'bbum', # 0xdc +'bbub', # 0xdd +'bbubs', # 0xde +'bbus', # 0xdf +'bbuss', # 0xe0 +'bbung', # 0xe1 +'bbuj', # 0xe2 +'bbuc', # 0xe3 +'bbuk', # 0xe4 +'bbut', # 0xe5 +'bbup', # 0xe6 +'bbuh', # 0xe7 +'bbweo', # 0xe8 +'bbweog', # 0xe9 +'bbweogg', # 0xea +'bbweogs', # 0xeb +'bbweon', # 0xec +'bbweonj', # 0xed +'bbweonh', # 0xee +'bbweod', # 0xef +'bbweol', # 0xf0 +'bbweolg', # 0xf1 +'bbweolm', # 0xf2 +'bbweolb', # 0xf3 +'bbweols', # 0xf4 +'bbweolt', # 0xf5 +'bbweolp', # 0xf6 +'bbweolh', # 0xf7 +'bbweom', # 0xf8 +'bbweob', # 0xf9 +'bbweobs', # 0xfa +'bbweos', # 0xfb +'bbweoss', # 0xfc +'bbweong', # 0xfd +'bbweoj', # 0xfe +'bbweoc', # 0xff +) diff --git a/libs/unidecode/x0c0.py b/libs/unidecode/x0c0.py new file mode 100644 index 00000000..35e50391 --- /dev/null +++ b/libs/unidecode/x0c0.py @@ -0,0 +1,258 @@ +data = ( +'bbweok', # 0x00 +'bbweot', # 0x01 +'bbweop', # 0x02 +'bbweoh', # 0x03 +'bbwe', # 0x04 +'bbweg', # 0x05 +'bbwegg', # 0x06 +'bbwegs', # 0x07 +'bbwen', # 0x08 +'bbwenj', # 0x09 +'bbwenh', # 0x0a +'bbwed', # 0x0b +'bbwel', # 0x0c +'bbwelg', # 0x0d +'bbwelm', # 0x0e +'bbwelb', # 0x0f +'bbwels', # 0x10 +'bbwelt', # 0x11 +'bbwelp', # 0x12 +'bbwelh', # 0x13 +'bbwem', # 0x14 +'bbweb', # 0x15 +'bbwebs', # 0x16 +'bbwes', # 0x17 +'bbwess', # 0x18 +'bbweng', # 0x19 +'bbwej', # 0x1a +'bbwec', # 0x1b +'bbwek', # 0x1c +'bbwet', # 0x1d +'bbwep', # 0x1e +'bbweh', # 0x1f +'bbwi', # 0x20 +'bbwig', # 0x21 +'bbwigg', # 0x22 +'bbwigs', # 0x23 +'bbwin', # 0x24 +'bbwinj', # 0x25 +'bbwinh', # 0x26 +'bbwid', # 0x27 +'bbwil', # 0x28 +'bbwilg', # 0x29 +'bbwilm', # 0x2a +'bbwilb', # 0x2b +'bbwils', # 0x2c +'bbwilt', # 0x2d +'bbwilp', # 0x2e +'bbwilh', # 0x2f +'bbwim', # 0x30 +'bbwib', # 0x31 +'bbwibs', # 0x32 +'bbwis', # 0x33 +'bbwiss', # 0x34 +'bbwing', # 0x35 +'bbwij', # 0x36 +'bbwic', # 0x37 +'bbwik', # 0x38 +'bbwit', # 0x39 +'bbwip', # 0x3a +'bbwih', # 0x3b +'bbyu', # 0x3c +'bbyug', # 0x3d +'bbyugg', # 0x3e +'bbyugs', # 0x3f +'bbyun', # 0x40 +'bbyunj', # 0x41 +'bbyunh', # 0x42 +'bbyud', # 0x43 +'bbyul', # 0x44 +'bbyulg', # 0x45 +'bbyulm', # 0x46 +'bbyulb', # 0x47 +'bbyuls', # 0x48 +'bbyult', # 0x49 +'bbyulp', # 0x4a +'bbyulh', # 0x4b +'bbyum', # 0x4c +'bbyub', # 0x4d +'bbyubs', # 0x4e +'bbyus', # 0x4f +'bbyuss', # 0x50 +'bbyung', # 0x51 +'bbyuj', # 0x52 +'bbyuc', # 0x53 +'bbyuk', # 0x54 +'bbyut', # 0x55 +'bbyup', # 0x56 +'bbyuh', # 0x57 +'bbeu', # 0x58 +'bbeug', # 0x59 +'bbeugg', # 0x5a +'bbeugs', # 0x5b +'bbeun', # 0x5c +'bbeunj', # 0x5d +'bbeunh', # 0x5e +'bbeud', # 0x5f +'bbeul', # 0x60 +'bbeulg', # 0x61 +'bbeulm', # 0x62 +'bbeulb', # 0x63 +'bbeuls', # 0x64 +'bbeult', # 0x65 +'bbeulp', # 0x66 +'bbeulh', # 0x67 +'bbeum', # 0x68 +'bbeub', # 0x69 +'bbeubs', # 0x6a +'bbeus', # 0x6b +'bbeuss', # 0x6c +'bbeung', # 0x6d +'bbeuj', # 0x6e +'bbeuc', # 0x6f +'bbeuk', # 0x70 +'bbeut', # 0x71 +'bbeup', # 0x72 +'bbeuh', # 0x73 +'bbyi', # 0x74 +'bbyig', # 0x75 +'bbyigg', # 0x76 +'bbyigs', # 0x77 +'bbyin', # 0x78 +'bbyinj', # 0x79 +'bbyinh', # 0x7a +'bbyid', # 0x7b +'bbyil', # 0x7c +'bbyilg', # 0x7d +'bbyilm', # 0x7e +'bbyilb', # 0x7f +'bbyils', # 0x80 +'bbyilt', # 0x81 +'bbyilp', # 0x82 +'bbyilh', # 0x83 +'bbyim', # 0x84 +'bbyib', # 0x85 +'bbyibs', # 0x86 +'bbyis', # 0x87 +'bbyiss', # 0x88 +'bbying', # 0x89 +'bbyij', # 0x8a +'bbyic', # 0x8b +'bbyik', # 0x8c +'bbyit', # 0x8d +'bbyip', # 0x8e +'bbyih', # 0x8f +'bbi', # 0x90 +'bbig', # 0x91 +'bbigg', # 0x92 +'bbigs', # 0x93 +'bbin', # 0x94 +'bbinj', # 0x95 +'bbinh', # 0x96 +'bbid', # 0x97 +'bbil', # 0x98 +'bbilg', # 0x99 +'bbilm', # 0x9a +'bbilb', # 0x9b +'bbils', # 0x9c +'bbilt', # 0x9d +'bbilp', # 0x9e +'bbilh', # 0x9f +'bbim', # 0xa0 +'bbib', # 0xa1 +'bbibs', # 0xa2 +'bbis', # 0xa3 +'bbiss', # 0xa4 +'bbing', # 0xa5 +'bbij', # 0xa6 +'bbic', # 0xa7 +'bbik', # 0xa8 +'bbit', # 0xa9 +'bbip', # 0xaa +'bbih', # 0xab +'sa', # 0xac +'sag', # 0xad +'sagg', # 0xae +'sags', # 0xaf +'san', # 0xb0 +'sanj', # 0xb1 +'sanh', # 0xb2 +'sad', # 0xb3 +'sal', # 0xb4 +'salg', # 0xb5 +'salm', # 0xb6 +'salb', # 0xb7 +'sals', # 0xb8 +'salt', # 0xb9 +'salp', # 0xba +'salh', # 0xbb +'sam', # 0xbc +'sab', # 0xbd +'sabs', # 0xbe +'sas', # 0xbf +'sass', # 0xc0 +'sang', # 0xc1 +'saj', # 0xc2 +'sac', # 0xc3 +'sak', # 0xc4 +'sat', # 0xc5 +'sap', # 0xc6 +'sah', # 0xc7 +'sae', # 0xc8 +'saeg', # 0xc9 +'saegg', # 0xca +'saegs', # 0xcb +'saen', # 0xcc +'saenj', # 0xcd +'saenh', # 0xce +'saed', # 0xcf +'sael', # 0xd0 +'saelg', # 0xd1 +'saelm', # 0xd2 +'saelb', # 0xd3 +'saels', # 0xd4 +'saelt', # 0xd5 +'saelp', # 0xd6 +'saelh', # 0xd7 +'saem', # 0xd8 +'saeb', # 0xd9 +'saebs', # 0xda +'saes', # 0xdb +'saess', # 0xdc +'saeng', # 0xdd +'saej', # 0xde +'saec', # 0xdf +'saek', # 0xe0 +'saet', # 0xe1 +'saep', # 0xe2 +'saeh', # 0xe3 +'sya', # 0xe4 +'syag', # 0xe5 +'syagg', # 0xe6 +'syags', # 0xe7 +'syan', # 0xe8 +'syanj', # 0xe9 +'syanh', # 0xea +'syad', # 0xeb +'syal', # 0xec +'syalg', # 0xed +'syalm', # 0xee +'syalb', # 0xef +'syals', # 0xf0 +'syalt', # 0xf1 +'syalp', # 0xf2 +'syalh', # 0xf3 +'syam', # 0xf4 +'syab', # 0xf5 +'syabs', # 0xf6 +'syas', # 0xf7 +'syass', # 0xf8 +'syang', # 0xf9 +'syaj', # 0xfa +'syac', # 0xfb +'syak', # 0xfc +'syat', # 0xfd +'syap', # 0xfe +'syah', # 0xff +) diff --git a/libs/unidecode/x0c1.py b/libs/unidecode/x0c1.py new file mode 100644 index 00000000..776847f4 --- /dev/null +++ b/libs/unidecode/x0c1.py @@ -0,0 +1,258 @@ +data = ( +'syae', # 0x00 +'syaeg', # 0x01 +'syaegg', # 0x02 +'syaegs', # 0x03 +'syaen', # 0x04 +'syaenj', # 0x05 +'syaenh', # 0x06 +'syaed', # 0x07 +'syael', # 0x08 +'syaelg', # 0x09 +'syaelm', # 0x0a +'syaelb', # 0x0b +'syaels', # 0x0c +'syaelt', # 0x0d +'syaelp', # 0x0e +'syaelh', # 0x0f +'syaem', # 0x10 +'syaeb', # 0x11 +'syaebs', # 0x12 +'syaes', # 0x13 +'syaess', # 0x14 +'syaeng', # 0x15 +'syaej', # 0x16 +'syaec', # 0x17 +'syaek', # 0x18 +'syaet', # 0x19 +'syaep', # 0x1a +'syaeh', # 0x1b +'seo', # 0x1c +'seog', # 0x1d +'seogg', # 0x1e +'seogs', # 0x1f +'seon', # 0x20 +'seonj', # 0x21 +'seonh', # 0x22 +'seod', # 0x23 +'seol', # 0x24 +'seolg', # 0x25 +'seolm', # 0x26 +'seolb', # 0x27 +'seols', # 0x28 +'seolt', # 0x29 +'seolp', # 0x2a +'seolh', # 0x2b +'seom', # 0x2c +'seob', # 0x2d +'seobs', # 0x2e +'seos', # 0x2f +'seoss', # 0x30 +'seong', # 0x31 +'seoj', # 0x32 +'seoc', # 0x33 +'seok', # 0x34 +'seot', # 0x35 +'seop', # 0x36 +'seoh', # 0x37 +'se', # 0x38 +'seg', # 0x39 +'segg', # 0x3a +'segs', # 0x3b +'sen', # 0x3c +'senj', # 0x3d +'senh', # 0x3e +'sed', # 0x3f +'sel', # 0x40 +'selg', # 0x41 +'selm', # 0x42 +'selb', # 0x43 +'sels', # 0x44 +'selt', # 0x45 +'selp', # 0x46 +'selh', # 0x47 +'sem', # 0x48 +'seb', # 0x49 +'sebs', # 0x4a +'ses', # 0x4b +'sess', # 0x4c +'seng', # 0x4d +'sej', # 0x4e +'sec', # 0x4f +'sek', # 0x50 +'set', # 0x51 +'sep', # 0x52 +'seh', # 0x53 +'syeo', # 0x54 +'syeog', # 0x55 +'syeogg', # 0x56 +'syeogs', # 0x57 +'syeon', # 0x58 +'syeonj', # 0x59 +'syeonh', # 0x5a +'syeod', # 0x5b +'syeol', # 0x5c +'syeolg', # 0x5d +'syeolm', # 0x5e +'syeolb', # 0x5f +'syeols', # 0x60 +'syeolt', # 0x61 +'syeolp', # 0x62 +'syeolh', # 0x63 +'syeom', # 0x64 +'syeob', # 0x65 +'syeobs', # 0x66 +'syeos', # 0x67 +'syeoss', # 0x68 +'syeong', # 0x69 +'syeoj', # 0x6a +'syeoc', # 0x6b +'syeok', # 0x6c +'syeot', # 0x6d +'syeop', # 0x6e +'syeoh', # 0x6f +'sye', # 0x70 +'syeg', # 0x71 +'syegg', # 0x72 +'syegs', # 0x73 +'syen', # 0x74 +'syenj', # 0x75 +'syenh', # 0x76 +'syed', # 0x77 +'syel', # 0x78 +'syelg', # 0x79 +'syelm', # 0x7a +'syelb', # 0x7b +'syels', # 0x7c +'syelt', # 0x7d +'syelp', # 0x7e +'syelh', # 0x7f +'syem', # 0x80 +'syeb', # 0x81 +'syebs', # 0x82 +'syes', # 0x83 +'syess', # 0x84 +'syeng', # 0x85 +'syej', # 0x86 +'syec', # 0x87 +'syek', # 0x88 +'syet', # 0x89 +'syep', # 0x8a +'syeh', # 0x8b +'so', # 0x8c +'sog', # 0x8d +'sogg', # 0x8e +'sogs', # 0x8f +'son', # 0x90 +'sonj', # 0x91 +'sonh', # 0x92 +'sod', # 0x93 +'sol', # 0x94 +'solg', # 0x95 +'solm', # 0x96 +'solb', # 0x97 +'sols', # 0x98 +'solt', # 0x99 +'solp', # 0x9a +'solh', # 0x9b +'som', # 0x9c +'sob', # 0x9d +'sobs', # 0x9e +'sos', # 0x9f +'soss', # 0xa0 +'song', # 0xa1 +'soj', # 0xa2 +'soc', # 0xa3 +'sok', # 0xa4 +'sot', # 0xa5 +'sop', # 0xa6 +'soh', # 0xa7 +'swa', # 0xa8 +'swag', # 0xa9 +'swagg', # 0xaa +'swags', # 0xab +'swan', # 0xac +'swanj', # 0xad +'swanh', # 0xae +'swad', # 0xaf +'swal', # 0xb0 +'swalg', # 0xb1 +'swalm', # 0xb2 +'swalb', # 0xb3 +'swals', # 0xb4 +'swalt', # 0xb5 +'swalp', # 0xb6 +'swalh', # 0xb7 +'swam', # 0xb8 +'swab', # 0xb9 +'swabs', # 0xba +'swas', # 0xbb +'swass', # 0xbc +'swang', # 0xbd +'swaj', # 0xbe +'swac', # 0xbf +'swak', # 0xc0 +'swat', # 0xc1 +'swap', # 0xc2 +'swah', # 0xc3 +'swae', # 0xc4 +'swaeg', # 0xc5 +'swaegg', # 0xc6 +'swaegs', # 0xc7 +'swaen', # 0xc8 +'swaenj', # 0xc9 +'swaenh', # 0xca +'swaed', # 0xcb +'swael', # 0xcc +'swaelg', # 0xcd +'swaelm', # 0xce +'swaelb', # 0xcf +'swaels', # 0xd0 +'swaelt', # 0xd1 +'swaelp', # 0xd2 +'swaelh', # 0xd3 +'swaem', # 0xd4 +'swaeb', # 0xd5 +'swaebs', # 0xd6 +'swaes', # 0xd7 +'swaess', # 0xd8 +'swaeng', # 0xd9 +'swaej', # 0xda +'swaec', # 0xdb +'swaek', # 0xdc +'swaet', # 0xdd +'swaep', # 0xde +'swaeh', # 0xdf +'soe', # 0xe0 +'soeg', # 0xe1 +'soegg', # 0xe2 +'soegs', # 0xe3 +'soen', # 0xe4 +'soenj', # 0xe5 +'soenh', # 0xe6 +'soed', # 0xe7 +'soel', # 0xe8 +'soelg', # 0xe9 +'soelm', # 0xea +'soelb', # 0xeb +'soels', # 0xec +'soelt', # 0xed +'soelp', # 0xee +'soelh', # 0xef +'soem', # 0xf0 +'soeb', # 0xf1 +'soebs', # 0xf2 +'soes', # 0xf3 +'soess', # 0xf4 +'soeng', # 0xf5 +'soej', # 0xf6 +'soec', # 0xf7 +'soek', # 0xf8 +'soet', # 0xf9 +'soep', # 0xfa +'soeh', # 0xfb +'syo', # 0xfc +'syog', # 0xfd +'syogg', # 0xfe +'syogs', # 0xff +) diff --git a/libs/unidecode/x0c2.py b/libs/unidecode/x0c2.py new file mode 100644 index 00000000..5b799cb6 --- /dev/null +++ b/libs/unidecode/x0c2.py @@ -0,0 +1,258 @@ +data = ( +'syon', # 0x00 +'syonj', # 0x01 +'syonh', # 0x02 +'syod', # 0x03 +'syol', # 0x04 +'syolg', # 0x05 +'syolm', # 0x06 +'syolb', # 0x07 +'syols', # 0x08 +'syolt', # 0x09 +'syolp', # 0x0a +'syolh', # 0x0b +'syom', # 0x0c +'syob', # 0x0d +'syobs', # 0x0e +'syos', # 0x0f +'syoss', # 0x10 +'syong', # 0x11 +'syoj', # 0x12 +'syoc', # 0x13 +'syok', # 0x14 +'syot', # 0x15 +'syop', # 0x16 +'syoh', # 0x17 +'su', # 0x18 +'sug', # 0x19 +'sugg', # 0x1a +'sugs', # 0x1b +'sun', # 0x1c +'sunj', # 0x1d +'sunh', # 0x1e +'sud', # 0x1f +'sul', # 0x20 +'sulg', # 0x21 +'sulm', # 0x22 +'sulb', # 0x23 +'suls', # 0x24 +'sult', # 0x25 +'sulp', # 0x26 +'sulh', # 0x27 +'sum', # 0x28 +'sub', # 0x29 +'subs', # 0x2a +'sus', # 0x2b +'suss', # 0x2c +'sung', # 0x2d +'suj', # 0x2e +'suc', # 0x2f +'suk', # 0x30 +'sut', # 0x31 +'sup', # 0x32 +'suh', # 0x33 +'sweo', # 0x34 +'sweog', # 0x35 +'sweogg', # 0x36 +'sweogs', # 0x37 +'sweon', # 0x38 +'sweonj', # 0x39 +'sweonh', # 0x3a +'sweod', # 0x3b +'sweol', # 0x3c +'sweolg', # 0x3d +'sweolm', # 0x3e +'sweolb', # 0x3f +'sweols', # 0x40 +'sweolt', # 0x41 +'sweolp', # 0x42 +'sweolh', # 0x43 +'sweom', # 0x44 +'sweob', # 0x45 +'sweobs', # 0x46 +'sweos', # 0x47 +'sweoss', # 0x48 +'sweong', # 0x49 +'sweoj', # 0x4a +'sweoc', # 0x4b +'sweok', # 0x4c +'sweot', # 0x4d +'sweop', # 0x4e +'sweoh', # 0x4f +'swe', # 0x50 +'sweg', # 0x51 +'swegg', # 0x52 +'swegs', # 0x53 +'swen', # 0x54 +'swenj', # 0x55 +'swenh', # 0x56 +'swed', # 0x57 +'swel', # 0x58 +'swelg', # 0x59 +'swelm', # 0x5a +'swelb', # 0x5b +'swels', # 0x5c +'swelt', # 0x5d +'swelp', # 0x5e +'swelh', # 0x5f +'swem', # 0x60 +'sweb', # 0x61 +'swebs', # 0x62 +'swes', # 0x63 +'swess', # 0x64 +'sweng', # 0x65 +'swej', # 0x66 +'swec', # 0x67 +'swek', # 0x68 +'swet', # 0x69 +'swep', # 0x6a +'sweh', # 0x6b +'swi', # 0x6c +'swig', # 0x6d +'swigg', # 0x6e +'swigs', # 0x6f +'swin', # 0x70 +'swinj', # 0x71 +'swinh', # 0x72 +'swid', # 0x73 +'swil', # 0x74 +'swilg', # 0x75 +'swilm', # 0x76 +'swilb', # 0x77 +'swils', # 0x78 +'swilt', # 0x79 +'swilp', # 0x7a +'swilh', # 0x7b +'swim', # 0x7c +'swib', # 0x7d +'swibs', # 0x7e +'swis', # 0x7f +'swiss', # 0x80 +'swing', # 0x81 +'swij', # 0x82 +'swic', # 0x83 +'swik', # 0x84 +'swit', # 0x85 +'swip', # 0x86 +'swih', # 0x87 +'syu', # 0x88 +'syug', # 0x89 +'syugg', # 0x8a +'syugs', # 0x8b +'syun', # 0x8c +'syunj', # 0x8d +'syunh', # 0x8e +'syud', # 0x8f +'syul', # 0x90 +'syulg', # 0x91 +'syulm', # 0x92 +'syulb', # 0x93 +'syuls', # 0x94 +'syult', # 0x95 +'syulp', # 0x96 +'syulh', # 0x97 +'syum', # 0x98 +'syub', # 0x99 +'syubs', # 0x9a +'syus', # 0x9b +'syuss', # 0x9c +'syung', # 0x9d +'syuj', # 0x9e +'syuc', # 0x9f +'syuk', # 0xa0 +'syut', # 0xa1 +'syup', # 0xa2 +'syuh', # 0xa3 +'seu', # 0xa4 +'seug', # 0xa5 +'seugg', # 0xa6 +'seugs', # 0xa7 +'seun', # 0xa8 +'seunj', # 0xa9 +'seunh', # 0xaa +'seud', # 0xab +'seul', # 0xac +'seulg', # 0xad +'seulm', # 0xae +'seulb', # 0xaf +'seuls', # 0xb0 +'seult', # 0xb1 +'seulp', # 0xb2 +'seulh', # 0xb3 +'seum', # 0xb4 +'seub', # 0xb5 +'seubs', # 0xb6 +'seus', # 0xb7 +'seuss', # 0xb8 +'seung', # 0xb9 +'seuj', # 0xba +'seuc', # 0xbb +'seuk', # 0xbc +'seut', # 0xbd +'seup', # 0xbe +'seuh', # 0xbf +'syi', # 0xc0 +'syig', # 0xc1 +'syigg', # 0xc2 +'syigs', # 0xc3 +'syin', # 0xc4 +'syinj', # 0xc5 +'syinh', # 0xc6 +'syid', # 0xc7 +'syil', # 0xc8 +'syilg', # 0xc9 +'syilm', # 0xca +'syilb', # 0xcb +'syils', # 0xcc +'syilt', # 0xcd +'syilp', # 0xce +'syilh', # 0xcf +'syim', # 0xd0 +'syib', # 0xd1 +'syibs', # 0xd2 +'syis', # 0xd3 +'syiss', # 0xd4 +'sying', # 0xd5 +'syij', # 0xd6 +'syic', # 0xd7 +'syik', # 0xd8 +'syit', # 0xd9 +'syip', # 0xda +'syih', # 0xdb +'si', # 0xdc +'sig', # 0xdd +'sigg', # 0xde +'sigs', # 0xdf +'sin', # 0xe0 +'sinj', # 0xe1 +'sinh', # 0xe2 +'sid', # 0xe3 +'sil', # 0xe4 +'silg', # 0xe5 +'silm', # 0xe6 +'silb', # 0xe7 +'sils', # 0xe8 +'silt', # 0xe9 +'silp', # 0xea +'silh', # 0xeb +'sim', # 0xec +'sib', # 0xed +'sibs', # 0xee +'sis', # 0xef +'siss', # 0xf0 +'sing', # 0xf1 +'sij', # 0xf2 +'sic', # 0xf3 +'sik', # 0xf4 +'sit', # 0xf5 +'sip', # 0xf6 +'sih', # 0xf7 +'ssa', # 0xf8 +'ssag', # 0xf9 +'ssagg', # 0xfa +'ssags', # 0xfb +'ssan', # 0xfc +'ssanj', # 0xfd +'ssanh', # 0xfe +'ssad', # 0xff +) diff --git a/libs/unidecode/x0c3.py b/libs/unidecode/x0c3.py new file mode 100644 index 00000000..bc81d642 --- /dev/null +++ b/libs/unidecode/x0c3.py @@ -0,0 +1,258 @@ +data = ( +'ssal', # 0x00 +'ssalg', # 0x01 +'ssalm', # 0x02 +'ssalb', # 0x03 +'ssals', # 0x04 +'ssalt', # 0x05 +'ssalp', # 0x06 +'ssalh', # 0x07 +'ssam', # 0x08 +'ssab', # 0x09 +'ssabs', # 0x0a +'ssas', # 0x0b +'ssass', # 0x0c +'ssang', # 0x0d +'ssaj', # 0x0e +'ssac', # 0x0f +'ssak', # 0x10 +'ssat', # 0x11 +'ssap', # 0x12 +'ssah', # 0x13 +'ssae', # 0x14 +'ssaeg', # 0x15 +'ssaegg', # 0x16 +'ssaegs', # 0x17 +'ssaen', # 0x18 +'ssaenj', # 0x19 +'ssaenh', # 0x1a +'ssaed', # 0x1b +'ssael', # 0x1c +'ssaelg', # 0x1d +'ssaelm', # 0x1e +'ssaelb', # 0x1f +'ssaels', # 0x20 +'ssaelt', # 0x21 +'ssaelp', # 0x22 +'ssaelh', # 0x23 +'ssaem', # 0x24 +'ssaeb', # 0x25 +'ssaebs', # 0x26 +'ssaes', # 0x27 +'ssaess', # 0x28 +'ssaeng', # 0x29 +'ssaej', # 0x2a +'ssaec', # 0x2b +'ssaek', # 0x2c +'ssaet', # 0x2d +'ssaep', # 0x2e +'ssaeh', # 0x2f +'ssya', # 0x30 +'ssyag', # 0x31 +'ssyagg', # 0x32 +'ssyags', # 0x33 +'ssyan', # 0x34 +'ssyanj', # 0x35 +'ssyanh', # 0x36 +'ssyad', # 0x37 +'ssyal', # 0x38 +'ssyalg', # 0x39 +'ssyalm', # 0x3a +'ssyalb', # 0x3b +'ssyals', # 0x3c +'ssyalt', # 0x3d +'ssyalp', # 0x3e +'ssyalh', # 0x3f +'ssyam', # 0x40 +'ssyab', # 0x41 +'ssyabs', # 0x42 +'ssyas', # 0x43 +'ssyass', # 0x44 +'ssyang', # 0x45 +'ssyaj', # 0x46 +'ssyac', # 0x47 +'ssyak', # 0x48 +'ssyat', # 0x49 +'ssyap', # 0x4a +'ssyah', # 0x4b +'ssyae', # 0x4c +'ssyaeg', # 0x4d +'ssyaegg', # 0x4e +'ssyaegs', # 0x4f +'ssyaen', # 0x50 +'ssyaenj', # 0x51 +'ssyaenh', # 0x52 +'ssyaed', # 0x53 +'ssyael', # 0x54 +'ssyaelg', # 0x55 +'ssyaelm', # 0x56 +'ssyaelb', # 0x57 +'ssyaels', # 0x58 +'ssyaelt', # 0x59 +'ssyaelp', # 0x5a +'ssyaelh', # 0x5b +'ssyaem', # 0x5c +'ssyaeb', # 0x5d +'ssyaebs', # 0x5e +'ssyaes', # 0x5f +'ssyaess', # 0x60 +'ssyaeng', # 0x61 +'ssyaej', # 0x62 +'ssyaec', # 0x63 +'ssyaek', # 0x64 +'ssyaet', # 0x65 +'ssyaep', # 0x66 +'ssyaeh', # 0x67 +'sseo', # 0x68 +'sseog', # 0x69 +'sseogg', # 0x6a +'sseogs', # 0x6b +'sseon', # 0x6c +'sseonj', # 0x6d +'sseonh', # 0x6e +'sseod', # 0x6f +'sseol', # 0x70 +'sseolg', # 0x71 +'sseolm', # 0x72 +'sseolb', # 0x73 +'sseols', # 0x74 +'sseolt', # 0x75 +'sseolp', # 0x76 +'sseolh', # 0x77 +'sseom', # 0x78 +'sseob', # 0x79 +'sseobs', # 0x7a +'sseos', # 0x7b +'sseoss', # 0x7c +'sseong', # 0x7d +'sseoj', # 0x7e +'sseoc', # 0x7f +'sseok', # 0x80 +'sseot', # 0x81 +'sseop', # 0x82 +'sseoh', # 0x83 +'sse', # 0x84 +'sseg', # 0x85 +'ssegg', # 0x86 +'ssegs', # 0x87 +'ssen', # 0x88 +'ssenj', # 0x89 +'ssenh', # 0x8a +'ssed', # 0x8b +'ssel', # 0x8c +'sselg', # 0x8d +'sselm', # 0x8e +'sselb', # 0x8f +'ssels', # 0x90 +'sselt', # 0x91 +'sselp', # 0x92 +'sselh', # 0x93 +'ssem', # 0x94 +'sseb', # 0x95 +'ssebs', # 0x96 +'sses', # 0x97 +'ssess', # 0x98 +'sseng', # 0x99 +'ssej', # 0x9a +'ssec', # 0x9b +'ssek', # 0x9c +'sset', # 0x9d +'ssep', # 0x9e +'sseh', # 0x9f +'ssyeo', # 0xa0 +'ssyeog', # 0xa1 +'ssyeogg', # 0xa2 +'ssyeogs', # 0xa3 +'ssyeon', # 0xa4 +'ssyeonj', # 0xa5 +'ssyeonh', # 0xa6 +'ssyeod', # 0xa7 +'ssyeol', # 0xa8 +'ssyeolg', # 0xa9 +'ssyeolm', # 0xaa +'ssyeolb', # 0xab +'ssyeols', # 0xac +'ssyeolt', # 0xad +'ssyeolp', # 0xae +'ssyeolh', # 0xaf +'ssyeom', # 0xb0 +'ssyeob', # 0xb1 +'ssyeobs', # 0xb2 +'ssyeos', # 0xb3 +'ssyeoss', # 0xb4 +'ssyeong', # 0xb5 +'ssyeoj', # 0xb6 +'ssyeoc', # 0xb7 +'ssyeok', # 0xb8 +'ssyeot', # 0xb9 +'ssyeop', # 0xba +'ssyeoh', # 0xbb +'ssye', # 0xbc +'ssyeg', # 0xbd +'ssyegg', # 0xbe +'ssyegs', # 0xbf +'ssyen', # 0xc0 +'ssyenj', # 0xc1 +'ssyenh', # 0xc2 +'ssyed', # 0xc3 +'ssyel', # 0xc4 +'ssyelg', # 0xc5 +'ssyelm', # 0xc6 +'ssyelb', # 0xc7 +'ssyels', # 0xc8 +'ssyelt', # 0xc9 +'ssyelp', # 0xca +'ssyelh', # 0xcb +'ssyem', # 0xcc +'ssyeb', # 0xcd +'ssyebs', # 0xce +'ssyes', # 0xcf +'ssyess', # 0xd0 +'ssyeng', # 0xd1 +'ssyej', # 0xd2 +'ssyec', # 0xd3 +'ssyek', # 0xd4 +'ssyet', # 0xd5 +'ssyep', # 0xd6 +'ssyeh', # 0xd7 +'sso', # 0xd8 +'ssog', # 0xd9 +'ssogg', # 0xda +'ssogs', # 0xdb +'sson', # 0xdc +'ssonj', # 0xdd +'ssonh', # 0xde +'ssod', # 0xdf +'ssol', # 0xe0 +'ssolg', # 0xe1 +'ssolm', # 0xe2 +'ssolb', # 0xe3 +'ssols', # 0xe4 +'ssolt', # 0xe5 +'ssolp', # 0xe6 +'ssolh', # 0xe7 +'ssom', # 0xe8 +'ssob', # 0xe9 +'ssobs', # 0xea +'ssos', # 0xeb +'ssoss', # 0xec +'ssong', # 0xed +'ssoj', # 0xee +'ssoc', # 0xef +'ssok', # 0xf0 +'ssot', # 0xf1 +'ssop', # 0xf2 +'ssoh', # 0xf3 +'sswa', # 0xf4 +'sswag', # 0xf5 +'sswagg', # 0xf6 +'sswags', # 0xf7 +'sswan', # 0xf8 +'sswanj', # 0xf9 +'sswanh', # 0xfa +'sswad', # 0xfb +'sswal', # 0xfc +'sswalg', # 0xfd +'sswalm', # 0xfe +'sswalb', # 0xff +) diff --git a/libs/unidecode/x0c4.py b/libs/unidecode/x0c4.py new file mode 100644 index 00000000..6288ca63 --- /dev/null +++ b/libs/unidecode/x0c4.py @@ -0,0 +1,258 @@ +data = ( +'sswals', # 0x00 +'sswalt', # 0x01 +'sswalp', # 0x02 +'sswalh', # 0x03 +'sswam', # 0x04 +'sswab', # 0x05 +'sswabs', # 0x06 +'sswas', # 0x07 +'sswass', # 0x08 +'sswang', # 0x09 +'sswaj', # 0x0a +'sswac', # 0x0b +'sswak', # 0x0c +'sswat', # 0x0d +'sswap', # 0x0e +'sswah', # 0x0f +'sswae', # 0x10 +'sswaeg', # 0x11 +'sswaegg', # 0x12 +'sswaegs', # 0x13 +'sswaen', # 0x14 +'sswaenj', # 0x15 +'sswaenh', # 0x16 +'sswaed', # 0x17 +'sswael', # 0x18 +'sswaelg', # 0x19 +'sswaelm', # 0x1a +'sswaelb', # 0x1b +'sswaels', # 0x1c +'sswaelt', # 0x1d +'sswaelp', # 0x1e +'sswaelh', # 0x1f +'sswaem', # 0x20 +'sswaeb', # 0x21 +'sswaebs', # 0x22 +'sswaes', # 0x23 +'sswaess', # 0x24 +'sswaeng', # 0x25 +'sswaej', # 0x26 +'sswaec', # 0x27 +'sswaek', # 0x28 +'sswaet', # 0x29 +'sswaep', # 0x2a +'sswaeh', # 0x2b +'ssoe', # 0x2c +'ssoeg', # 0x2d +'ssoegg', # 0x2e +'ssoegs', # 0x2f +'ssoen', # 0x30 +'ssoenj', # 0x31 +'ssoenh', # 0x32 +'ssoed', # 0x33 +'ssoel', # 0x34 +'ssoelg', # 0x35 +'ssoelm', # 0x36 +'ssoelb', # 0x37 +'ssoels', # 0x38 +'ssoelt', # 0x39 +'ssoelp', # 0x3a +'ssoelh', # 0x3b +'ssoem', # 0x3c +'ssoeb', # 0x3d +'ssoebs', # 0x3e +'ssoes', # 0x3f +'ssoess', # 0x40 +'ssoeng', # 0x41 +'ssoej', # 0x42 +'ssoec', # 0x43 +'ssoek', # 0x44 +'ssoet', # 0x45 +'ssoep', # 0x46 +'ssoeh', # 0x47 +'ssyo', # 0x48 +'ssyog', # 0x49 +'ssyogg', # 0x4a +'ssyogs', # 0x4b +'ssyon', # 0x4c +'ssyonj', # 0x4d +'ssyonh', # 0x4e +'ssyod', # 0x4f +'ssyol', # 0x50 +'ssyolg', # 0x51 +'ssyolm', # 0x52 +'ssyolb', # 0x53 +'ssyols', # 0x54 +'ssyolt', # 0x55 +'ssyolp', # 0x56 +'ssyolh', # 0x57 +'ssyom', # 0x58 +'ssyob', # 0x59 +'ssyobs', # 0x5a +'ssyos', # 0x5b +'ssyoss', # 0x5c +'ssyong', # 0x5d +'ssyoj', # 0x5e +'ssyoc', # 0x5f +'ssyok', # 0x60 +'ssyot', # 0x61 +'ssyop', # 0x62 +'ssyoh', # 0x63 +'ssu', # 0x64 +'ssug', # 0x65 +'ssugg', # 0x66 +'ssugs', # 0x67 +'ssun', # 0x68 +'ssunj', # 0x69 +'ssunh', # 0x6a +'ssud', # 0x6b +'ssul', # 0x6c +'ssulg', # 0x6d +'ssulm', # 0x6e +'ssulb', # 0x6f +'ssuls', # 0x70 +'ssult', # 0x71 +'ssulp', # 0x72 +'ssulh', # 0x73 +'ssum', # 0x74 +'ssub', # 0x75 +'ssubs', # 0x76 +'ssus', # 0x77 +'ssuss', # 0x78 +'ssung', # 0x79 +'ssuj', # 0x7a +'ssuc', # 0x7b +'ssuk', # 0x7c +'ssut', # 0x7d +'ssup', # 0x7e +'ssuh', # 0x7f +'ssweo', # 0x80 +'ssweog', # 0x81 +'ssweogg', # 0x82 +'ssweogs', # 0x83 +'ssweon', # 0x84 +'ssweonj', # 0x85 +'ssweonh', # 0x86 +'ssweod', # 0x87 +'ssweol', # 0x88 +'ssweolg', # 0x89 +'ssweolm', # 0x8a +'ssweolb', # 0x8b +'ssweols', # 0x8c +'ssweolt', # 0x8d +'ssweolp', # 0x8e +'ssweolh', # 0x8f +'ssweom', # 0x90 +'ssweob', # 0x91 +'ssweobs', # 0x92 +'ssweos', # 0x93 +'ssweoss', # 0x94 +'ssweong', # 0x95 +'ssweoj', # 0x96 +'ssweoc', # 0x97 +'ssweok', # 0x98 +'ssweot', # 0x99 +'ssweop', # 0x9a +'ssweoh', # 0x9b +'sswe', # 0x9c +'ssweg', # 0x9d +'sswegg', # 0x9e +'sswegs', # 0x9f +'sswen', # 0xa0 +'sswenj', # 0xa1 +'sswenh', # 0xa2 +'sswed', # 0xa3 +'sswel', # 0xa4 +'sswelg', # 0xa5 +'sswelm', # 0xa6 +'sswelb', # 0xa7 +'sswels', # 0xa8 +'sswelt', # 0xa9 +'sswelp', # 0xaa +'sswelh', # 0xab +'sswem', # 0xac +'ssweb', # 0xad +'sswebs', # 0xae +'sswes', # 0xaf +'sswess', # 0xb0 +'ssweng', # 0xb1 +'sswej', # 0xb2 +'sswec', # 0xb3 +'sswek', # 0xb4 +'sswet', # 0xb5 +'sswep', # 0xb6 +'ssweh', # 0xb7 +'sswi', # 0xb8 +'sswig', # 0xb9 +'sswigg', # 0xba +'sswigs', # 0xbb +'sswin', # 0xbc +'sswinj', # 0xbd +'sswinh', # 0xbe +'sswid', # 0xbf +'sswil', # 0xc0 +'sswilg', # 0xc1 +'sswilm', # 0xc2 +'sswilb', # 0xc3 +'sswils', # 0xc4 +'sswilt', # 0xc5 +'sswilp', # 0xc6 +'sswilh', # 0xc7 +'sswim', # 0xc8 +'sswib', # 0xc9 +'sswibs', # 0xca +'sswis', # 0xcb +'sswiss', # 0xcc +'sswing', # 0xcd +'sswij', # 0xce +'sswic', # 0xcf +'sswik', # 0xd0 +'sswit', # 0xd1 +'sswip', # 0xd2 +'sswih', # 0xd3 +'ssyu', # 0xd4 +'ssyug', # 0xd5 +'ssyugg', # 0xd6 +'ssyugs', # 0xd7 +'ssyun', # 0xd8 +'ssyunj', # 0xd9 +'ssyunh', # 0xda +'ssyud', # 0xdb +'ssyul', # 0xdc +'ssyulg', # 0xdd +'ssyulm', # 0xde +'ssyulb', # 0xdf +'ssyuls', # 0xe0 +'ssyult', # 0xe1 +'ssyulp', # 0xe2 +'ssyulh', # 0xe3 +'ssyum', # 0xe4 +'ssyub', # 0xe5 +'ssyubs', # 0xe6 +'ssyus', # 0xe7 +'ssyuss', # 0xe8 +'ssyung', # 0xe9 +'ssyuj', # 0xea +'ssyuc', # 0xeb +'ssyuk', # 0xec +'ssyut', # 0xed +'ssyup', # 0xee +'ssyuh', # 0xef +'sseu', # 0xf0 +'sseug', # 0xf1 +'sseugg', # 0xf2 +'sseugs', # 0xf3 +'sseun', # 0xf4 +'sseunj', # 0xf5 +'sseunh', # 0xf6 +'sseud', # 0xf7 +'sseul', # 0xf8 +'sseulg', # 0xf9 +'sseulm', # 0xfa +'sseulb', # 0xfb +'sseuls', # 0xfc +'sseult', # 0xfd +'sseulp', # 0xfe +'sseulh', # 0xff +) diff --git a/libs/unidecode/x0c5.py b/libs/unidecode/x0c5.py new file mode 100644 index 00000000..3f4778e7 --- /dev/null +++ b/libs/unidecode/x0c5.py @@ -0,0 +1,258 @@ +data = ( +'sseum', # 0x00 +'sseub', # 0x01 +'sseubs', # 0x02 +'sseus', # 0x03 +'sseuss', # 0x04 +'sseung', # 0x05 +'sseuj', # 0x06 +'sseuc', # 0x07 +'sseuk', # 0x08 +'sseut', # 0x09 +'sseup', # 0x0a +'sseuh', # 0x0b +'ssyi', # 0x0c +'ssyig', # 0x0d +'ssyigg', # 0x0e +'ssyigs', # 0x0f +'ssyin', # 0x10 +'ssyinj', # 0x11 +'ssyinh', # 0x12 +'ssyid', # 0x13 +'ssyil', # 0x14 +'ssyilg', # 0x15 +'ssyilm', # 0x16 +'ssyilb', # 0x17 +'ssyils', # 0x18 +'ssyilt', # 0x19 +'ssyilp', # 0x1a +'ssyilh', # 0x1b +'ssyim', # 0x1c +'ssyib', # 0x1d +'ssyibs', # 0x1e +'ssyis', # 0x1f +'ssyiss', # 0x20 +'ssying', # 0x21 +'ssyij', # 0x22 +'ssyic', # 0x23 +'ssyik', # 0x24 +'ssyit', # 0x25 +'ssyip', # 0x26 +'ssyih', # 0x27 +'ssi', # 0x28 +'ssig', # 0x29 +'ssigg', # 0x2a +'ssigs', # 0x2b +'ssin', # 0x2c +'ssinj', # 0x2d +'ssinh', # 0x2e +'ssid', # 0x2f +'ssil', # 0x30 +'ssilg', # 0x31 +'ssilm', # 0x32 +'ssilb', # 0x33 +'ssils', # 0x34 +'ssilt', # 0x35 +'ssilp', # 0x36 +'ssilh', # 0x37 +'ssim', # 0x38 +'ssib', # 0x39 +'ssibs', # 0x3a +'ssis', # 0x3b +'ssiss', # 0x3c +'ssing', # 0x3d +'ssij', # 0x3e +'ssic', # 0x3f +'ssik', # 0x40 +'ssit', # 0x41 +'ssip', # 0x42 +'ssih', # 0x43 +'a', # 0x44 +'ag', # 0x45 +'agg', # 0x46 +'ags', # 0x47 +'an', # 0x48 +'anj', # 0x49 +'anh', # 0x4a +'ad', # 0x4b +'al', # 0x4c +'alg', # 0x4d +'alm', # 0x4e +'alb', # 0x4f +'als', # 0x50 +'alt', # 0x51 +'alp', # 0x52 +'alh', # 0x53 +'am', # 0x54 +'ab', # 0x55 +'abs', # 0x56 +'as', # 0x57 +'ass', # 0x58 +'ang', # 0x59 +'aj', # 0x5a +'ac', # 0x5b +'ak', # 0x5c +'at', # 0x5d +'ap', # 0x5e +'ah', # 0x5f +'ae', # 0x60 +'aeg', # 0x61 +'aegg', # 0x62 +'aegs', # 0x63 +'aen', # 0x64 +'aenj', # 0x65 +'aenh', # 0x66 +'aed', # 0x67 +'ael', # 0x68 +'aelg', # 0x69 +'aelm', # 0x6a +'aelb', # 0x6b +'aels', # 0x6c +'aelt', # 0x6d +'aelp', # 0x6e +'aelh', # 0x6f +'aem', # 0x70 +'aeb', # 0x71 +'aebs', # 0x72 +'aes', # 0x73 +'aess', # 0x74 +'aeng', # 0x75 +'aej', # 0x76 +'aec', # 0x77 +'aek', # 0x78 +'aet', # 0x79 +'aep', # 0x7a +'aeh', # 0x7b +'ya', # 0x7c +'yag', # 0x7d +'yagg', # 0x7e +'yags', # 0x7f +'yan', # 0x80 +'yanj', # 0x81 +'yanh', # 0x82 +'yad', # 0x83 +'yal', # 0x84 +'yalg', # 0x85 +'yalm', # 0x86 +'yalb', # 0x87 +'yals', # 0x88 +'yalt', # 0x89 +'yalp', # 0x8a +'yalh', # 0x8b +'yam', # 0x8c +'yab', # 0x8d +'yabs', # 0x8e +'yas', # 0x8f +'yass', # 0x90 +'yang', # 0x91 +'yaj', # 0x92 +'yac', # 0x93 +'yak', # 0x94 +'yat', # 0x95 +'yap', # 0x96 +'yah', # 0x97 +'yae', # 0x98 +'yaeg', # 0x99 +'yaegg', # 0x9a +'yaegs', # 0x9b +'yaen', # 0x9c +'yaenj', # 0x9d +'yaenh', # 0x9e +'yaed', # 0x9f +'yael', # 0xa0 +'yaelg', # 0xa1 +'yaelm', # 0xa2 +'yaelb', # 0xa3 +'yaels', # 0xa4 +'yaelt', # 0xa5 +'yaelp', # 0xa6 +'yaelh', # 0xa7 +'yaem', # 0xa8 +'yaeb', # 0xa9 +'yaebs', # 0xaa +'yaes', # 0xab +'yaess', # 0xac +'yaeng', # 0xad +'yaej', # 0xae +'yaec', # 0xaf +'yaek', # 0xb0 +'yaet', # 0xb1 +'yaep', # 0xb2 +'yaeh', # 0xb3 +'eo', # 0xb4 +'eog', # 0xb5 +'eogg', # 0xb6 +'eogs', # 0xb7 +'eon', # 0xb8 +'eonj', # 0xb9 +'eonh', # 0xba +'eod', # 0xbb +'eol', # 0xbc +'eolg', # 0xbd +'eolm', # 0xbe +'eolb', # 0xbf +'eols', # 0xc0 +'eolt', # 0xc1 +'eolp', # 0xc2 +'eolh', # 0xc3 +'eom', # 0xc4 +'eob', # 0xc5 +'eobs', # 0xc6 +'eos', # 0xc7 +'eoss', # 0xc8 +'eong', # 0xc9 +'eoj', # 0xca +'eoc', # 0xcb +'eok', # 0xcc +'eot', # 0xcd +'eop', # 0xce +'eoh', # 0xcf +'e', # 0xd0 +'eg', # 0xd1 +'egg', # 0xd2 +'egs', # 0xd3 +'en', # 0xd4 +'enj', # 0xd5 +'enh', # 0xd6 +'ed', # 0xd7 +'el', # 0xd8 +'elg', # 0xd9 +'elm', # 0xda +'elb', # 0xdb +'els', # 0xdc +'elt', # 0xdd +'elp', # 0xde +'elh', # 0xdf +'em', # 0xe0 +'eb', # 0xe1 +'ebs', # 0xe2 +'es', # 0xe3 +'ess', # 0xe4 +'eng', # 0xe5 +'ej', # 0xe6 +'ec', # 0xe7 +'ek', # 0xe8 +'et', # 0xe9 +'ep', # 0xea +'eh', # 0xeb +'yeo', # 0xec +'yeog', # 0xed +'yeogg', # 0xee +'yeogs', # 0xef +'yeon', # 0xf0 +'yeonj', # 0xf1 +'yeonh', # 0xf2 +'yeod', # 0xf3 +'yeol', # 0xf4 +'yeolg', # 0xf5 +'yeolm', # 0xf6 +'yeolb', # 0xf7 +'yeols', # 0xf8 +'yeolt', # 0xf9 +'yeolp', # 0xfa +'yeolh', # 0xfb +'yeom', # 0xfc +'yeob', # 0xfd +'yeobs', # 0xfe +'yeos', # 0xff +) diff --git a/libs/unidecode/x0c6.py b/libs/unidecode/x0c6.py new file mode 100644 index 00000000..c6eeaeba --- /dev/null +++ b/libs/unidecode/x0c6.py @@ -0,0 +1,258 @@ +data = ( +'yeoss', # 0x00 +'yeong', # 0x01 +'yeoj', # 0x02 +'yeoc', # 0x03 +'yeok', # 0x04 +'yeot', # 0x05 +'yeop', # 0x06 +'yeoh', # 0x07 +'ye', # 0x08 +'yeg', # 0x09 +'yegg', # 0x0a +'yegs', # 0x0b +'yen', # 0x0c +'yenj', # 0x0d +'yenh', # 0x0e +'yed', # 0x0f +'yel', # 0x10 +'yelg', # 0x11 +'yelm', # 0x12 +'yelb', # 0x13 +'yels', # 0x14 +'yelt', # 0x15 +'yelp', # 0x16 +'yelh', # 0x17 +'yem', # 0x18 +'yeb', # 0x19 +'yebs', # 0x1a +'yes', # 0x1b +'yess', # 0x1c +'yeng', # 0x1d +'yej', # 0x1e +'yec', # 0x1f +'yek', # 0x20 +'yet', # 0x21 +'yep', # 0x22 +'yeh', # 0x23 +'o', # 0x24 +'og', # 0x25 +'ogg', # 0x26 +'ogs', # 0x27 +'on', # 0x28 +'onj', # 0x29 +'onh', # 0x2a +'od', # 0x2b +'ol', # 0x2c +'olg', # 0x2d +'olm', # 0x2e +'olb', # 0x2f +'ols', # 0x30 +'olt', # 0x31 +'olp', # 0x32 +'olh', # 0x33 +'om', # 0x34 +'ob', # 0x35 +'obs', # 0x36 +'os', # 0x37 +'oss', # 0x38 +'ong', # 0x39 +'oj', # 0x3a +'oc', # 0x3b +'ok', # 0x3c +'ot', # 0x3d +'op', # 0x3e +'oh', # 0x3f +'wa', # 0x40 +'wag', # 0x41 +'wagg', # 0x42 +'wags', # 0x43 +'wan', # 0x44 +'wanj', # 0x45 +'wanh', # 0x46 +'wad', # 0x47 +'wal', # 0x48 +'walg', # 0x49 +'walm', # 0x4a +'walb', # 0x4b +'wals', # 0x4c +'walt', # 0x4d +'walp', # 0x4e +'walh', # 0x4f +'wam', # 0x50 +'wab', # 0x51 +'wabs', # 0x52 +'was', # 0x53 +'wass', # 0x54 +'wang', # 0x55 +'waj', # 0x56 +'wac', # 0x57 +'wak', # 0x58 +'wat', # 0x59 +'wap', # 0x5a +'wah', # 0x5b +'wae', # 0x5c +'waeg', # 0x5d +'waegg', # 0x5e +'waegs', # 0x5f +'waen', # 0x60 +'waenj', # 0x61 +'waenh', # 0x62 +'waed', # 0x63 +'wael', # 0x64 +'waelg', # 0x65 +'waelm', # 0x66 +'waelb', # 0x67 +'waels', # 0x68 +'waelt', # 0x69 +'waelp', # 0x6a +'waelh', # 0x6b +'waem', # 0x6c +'waeb', # 0x6d +'waebs', # 0x6e +'waes', # 0x6f +'waess', # 0x70 +'waeng', # 0x71 +'waej', # 0x72 +'waec', # 0x73 +'waek', # 0x74 +'waet', # 0x75 +'waep', # 0x76 +'waeh', # 0x77 +'oe', # 0x78 +'oeg', # 0x79 +'oegg', # 0x7a +'oegs', # 0x7b +'oen', # 0x7c +'oenj', # 0x7d +'oenh', # 0x7e +'oed', # 0x7f +'oel', # 0x80 +'oelg', # 0x81 +'oelm', # 0x82 +'oelb', # 0x83 +'oels', # 0x84 +'oelt', # 0x85 +'oelp', # 0x86 +'oelh', # 0x87 +'oem', # 0x88 +'oeb', # 0x89 +'oebs', # 0x8a +'oes', # 0x8b +'oess', # 0x8c +'oeng', # 0x8d +'oej', # 0x8e +'oec', # 0x8f +'oek', # 0x90 +'oet', # 0x91 +'oep', # 0x92 +'oeh', # 0x93 +'yo', # 0x94 +'yog', # 0x95 +'yogg', # 0x96 +'yogs', # 0x97 +'yon', # 0x98 +'yonj', # 0x99 +'yonh', # 0x9a +'yod', # 0x9b +'yol', # 0x9c +'yolg', # 0x9d +'yolm', # 0x9e +'yolb', # 0x9f +'yols', # 0xa0 +'yolt', # 0xa1 +'yolp', # 0xa2 +'yolh', # 0xa3 +'yom', # 0xa4 +'yob', # 0xa5 +'yobs', # 0xa6 +'yos', # 0xa7 +'yoss', # 0xa8 +'yong', # 0xa9 +'yoj', # 0xaa +'yoc', # 0xab +'yok', # 0xac +'yot', # 0xad +'yop', # 0xae +'yoh', # 0xaf +'u', # 0xb0 +'ug', # 0xb1 +'ugg', # 0xb2 +'ugs', # 0xb3 +'un', # 0xb4 +'unj', # 0xb5 +'unh', # 0xb6 +'ud', # 0xb7 +'ul', # 0xb8 +'ulg', # 0xb9 +'ulm', # 0xba +'ulb', # 0xbb +'uls', # 0xbc +'ult', # 0xbd +'ulp', # 0xbe +'ulh', # 0xbf +'um', # 0xc0 +'ub', # 0xc1 +'ubs', # 0xc2 +'us', # 0xc3 +'uss', # 0xc4 +'ung', # 0xc5 +'uj', # 0xc6 +'uc', # 0xc7 +'uk', # 0xc8 +'ut', # 0xc9 +'up', # 0xca +'uh', # 0xcb +'weo', # 0xcc +'weog', # 0xcd +'weogg', # 0xce +'weogs', # 0xcf +'weon', # 0xd0 +'weonj', # 0xd1 +'weonh', # 0xd2 +'weod', # 0xd3 +'weol', # 0xd4 +'weolg', # 0xd5 +'weolm', # 0xd6 +'weolb', # 0xd7 +'weols', # 0xd8 +'weolt', # 0xd9 +'weolp', # 0xda +'weolh', # 0xdb +'weom', # 0xdc +'weob', # 0xdd +'weobs', # 0xde +'weos', # 0xdf +'weoss', # 0xe0 +'weong', # 0xe1 +'weoj', # 0xe2 +'weoc', # 0xe3 +'weok', # 0xe4 +'weot', # 0xe5 +'weop', # 0xe6 +'weoh', # 0xe7 +'we', # 0xe8 +'weg', # 0xe9 +'wegg', # 0xea +'wegs', # 0xeb +'wen', # 0xec +'wenj', # 0xed +'wenh', # 0xee +'wed', # 0xef +'wel', # 0xf0 +'welg', # 0xf1 +'welm', # 0xf2 +'welb', # 0xf3 +'wels', # 0xf4 +'welt', # 0xf5 +'welp', # 0xf6 +'welh', # 0xf7 +'wem', # 0xf8 +'web', # 0xf9 +'webs', # 0xfa +'wes', # 0xfb +'wess', # 0xfc +'weng', # 0xfd +'wej', # 0xfe +'wec', # 0xff +) diff --git a/libs/unidecode/x0c7.py b/libs/unidecode/x0c7.py new file mode 100644 index 00000000..4c1a9e13 --- /dev/null +++ b/libs/unidecode/x0c7.py @@ -0,0 +1,258 @@ +data = ( +'wek', # 0x00 +'wet', # 0x01 +'wep', # 0x02 +'weh', # 0x03 +'wi', # 0x04 +'wig', # 0x05 +'wigg', # 0x06 +'wigs', # 0x07 +'win', # 0x08 +'winj', # 0x09 +'winh', # 0x0a +'wid', # 0x0b +'wil', # 0x0c +'wilg', # 0x0d +'wilm', # 0x0e +'wilb', # 0x0f +'wils', # 0x10 +'wilt', # 0x11 +'wilp', # 0x12 +'wilh', # 0x13 +'wim', # 0x14 +'wib', # 0x15 +'wibs', # 0x16 +'wis', # 0x17 +'wiss', # 0x18 +'wing', # 0x19 +'wij', # 0x1a +'wic', # 0x1b +'wik', # 0x1c +'wit', # 0x1d +'wip', # 0x1e +'wih', # 0x1f +'yu', # 0x20 +'yug', # 0x21 +'yugg', # 0x22 +'yugs', # 0x23 +'yun', # 0x24 +'yunj', # 0x25 +'yunh', # 0x26 +'yud', # 0x27 +'yul', # 0x28 +'yulg', # 0x29 +'yulm', # 0x2a +'yulb', # 0x2b +'yuls', # 0x2c +'yult', # 0x2d +'yulp', # 0x2e +'yulh', # 0x2f +'yum', # 0x30 +'yub', # 0x31 +'yubs', # 0x32 +'yus', # 0x33 +'yuss', # 0x34 +'yung', # 0x35 +'yuj', # 0x36 +'yuc', # 0x37 +'yuk', # 0x38 +'yut', # 0x39 +'yup', # 0x3a +'yuh', # 0x3b +'eu', # 0x3c +'eug', # 0x3d +'eugg', # 0x3e +'eugs', # 0x3f +'eun', # 0x40 +'eunj', # 0x41 +'eunh', # 0x42 +'eud', # 0x43 +'eul', # 0x44 +'eulg', # 0x45 +'eulm', # 0x46 +'eulb', # 0x47 +'euls', # 0x48 +'eult', # 0x49 +'eulp', # 0x4a +'eulh', # 0x4b +'eum', # 0x4c +'eub', # 0x4d +'eubs', # 0x4e +'eus', # 0x4f +'euss', # 0x50 +'eung', # 0x51 +'euj', # 0x52 +'euc', # 0x53 +'euk', # 0x54 +'eut', # 0x55 +'eup', # 0x56 +'euh', # 0x57 +'yi', # 0x58 +'yig', # 0x59 +'yigg', # 0x5a +'yigs', # 0x5b +'yin', # 0x5c +'yinj', # 0x5d +'yinh', # 0x5e +'yid', # 0x5f +'yil', # 0x60 +'yilg', # 0x61 +'yilm', # 0x62 +'yilb', # 0x63 +'yils', # 0x64 +'yilt', # 0x65 +'yilp', # 0x66 +'yilh', # 0x67 +'yim', # 0x68 +'yib', # 0x69 +'yibs', # 0x6a +'yis', # 0x6b +'yiss', # 0x6c +'ying', # 0x6d +'yij', # 0x6e +'yic', # 0x6f +'yik', # 0x70 +'yit', # 0x71 +'yip', # 0x72 +'yih', # 0x73 +'i', # 0x74 +'ig', # 0x75 +'igg', # 0x76 +'igs', # 0x77 +'in', # 0x78 +'inj', # 0x79 +'inh', # 0x7a +'id', # 0x7b +'il', # 0x7c +'ilg', # 0x7d +'ilm', # 0x7e +'ilb', # 0x7f +'ils', # 0x80 +'ilt', # 0x81 +'ilp', # 0x82 +'ilh', # 0x83 +'im', # 0x84 +'ib', # 0x85 +'ibs', # 0x86 +'is', # 0x87 +'iss', # 0x88 +'ing', # 0x89 +'ij', # 0x8a +'ic', # 0x8b +'ik', # 0x8c +'it', # 0x8d +'ip', # 0x8e +'ih', # 0x8f +'ja', # 0x90 +'jag', # 0x91 +'jagg', # 0x92 +'jags', # 0x93 +'jan', # 0x94 +'janj', # 0x95 +'janh', # 0x96 +'jad', # 0x97 +'jal', # 0x98 +'jalg', # 0x99 +'jalm', # 0x9a +'jalb', # 0x9b +'jals', # 0x9c +'jalt', # 0x9d +'jalp', # 0x9e +'jalh', # 0x9f +'jam', # 0xa0 +'jab', # 0xa1 +'jabs', # 0xa2 +'jas', # 0xa3 +'jass', # 0xa4 +'jang', # 0xa5 +'jaj', # 0xa6 +'jac', # 0xa7 +'jak', # 0xa8 +'jat', # 0xa9 +'jap', # 0xaa +'jah', # 0xab +'jae', # 0xac +'jaeg', # 0xad +'jaegg', # 0xae +'jaegs', # 0xaf +'jaen', # 0xb0 +'jaenj', # 0xb1 +'jaenh', # 0xb2 +'jaed', # 0xb3 +'jael', # 0xb4 +'jaelg', # 0xb5 +'jaelm', # 0xb6 +'jaelb', # 0xb7 +'jaels', # 0xb8 +'jaelt', # 0xb9 +'jaelp', # 0xba +'jaelh', # 0xbb +'jaem', # 0xbc +'jaeb', # 0xbd +'jaebs', # 0xbe +'jaes', # 0xbf +'jaess', # 0xc0 +'jaeng', # 0xc1 +'jaej', # 0xc2 +'jaec', # 0xc3 +'jaek', # 0xc4 +'jaet', # 0xc5 +'jaep', # 0xc6 +'jaeh', # 0xc7 +'jya', # 0xc8 +'jyag', # 0xc9 +'jyagg', # 0xca +'jyags', # 0xcb +'jyan', # 0xcc +'jyanj', # 0xcd +'jyanh', # 0xce +'jyad', # 0xcf +'jyal', # 0xd0 +'jyalg', # 0xd1 +'jyalm', # 0xd2 +'jyalb', # 0xd3 +'jyals', # 0xd4 +'jyalt', # 0xd5 +'jyalp', # 0xd6 +'jyalh', # 0xd7 +'jyam', # 0xd8 +'jyab', # 0xd9 +'jyabs', # 0xda +'jyas', # 0xdb +'jyass', # 0xdc +'jyang', # 0xdd +'jyaj', # 0xde +'jyac', # 0xdf +'jyak', # 0xe0 +'jyat', # 0xe1 +'jyap', # 0xe2 +'jyah', # 0xe3 +'jyae', # 0xe4 +'jyaeg', # 0xe5 +'jyaegg', # 0xe6 +'jyaegs', # 0xe7 +'jyaen', # 0xe8 +'jyaenj', # 0xe9 +'jyaenh', # 0xea +'jyaed', # 0xeb +'jyael', # 0xec +'jyaelg', # 0xed +'jyaelm', # 0xee +'jyaelb', # 0xef +'jyaels', # 0xf0 +'jyaelt', # 0xf1 +'jyaelp', # 0xf2 +'jyaelh', # 0xf3 +'jyaem', # 0xf4 +'jyaeb', # 0xf5 +'jyaebs', # 0xf6 +'jyaes', # 0xf7 +'jyaess', # 0xf8 +'jyaeng', # 0xf9 +'jyaej', # 0xfa +'jyaec', # 0xfb +'jyaek', # 0xfc +'jyaet', # 0xfd +'jyaep', # 0xfe +'jyaeh', # 0xff +) diff --git a/libs/unidecode/x0c8.py b/libs/unidecode/x0c8.py new file mode 100644 index 00000000..2dc75649 --- /dev/null +++ b/libs/unidecode/x0c8.py @@ -0,0 +1,258 @@ +data = ( +'jeo', # 0x00 +'jeog', # 0x01 +'jeogg', # 0x02 +'jeogs', # 0x03 +'jeon', # 0x04 +'jeonj', # 0x05 +'jeonh', # 0x06 +'jeod', # 0x07 +'jeol', # 0x08 +'jeolg', # 0x09 +'jeolm', # 0x0a +'jeolb', # 0x0b +'jeols', # 0x0c +'jeolt', # 0x0d +'jeolp', # 0x0e +'jeolh', # 0x0f +'jeom', # 0x10 +'jeob', # 0x11 +'jeobs', # 0x12 +'jeos', # 0x13 +'jeoss', # 0x14 +'jeong', # 0x15 +'jeoj', # 0x16 +'jeoc', # 0x17 +'jeok', # 0x18 +'jeot', # 0x19 +'jeop', # 0x1a +'jeoh', # 0x1b +'je', # 0x1c +'jeg', # 0x1d +'jegg', # 0x1e +'jegs', # 0x1f +'jen', # 0x20 +'jenj', # 0x21 +'jenh', # 0x22 +'jed', # 0x23 +'jel', # 0x24 +'jelg', # 0x25 +'jelm', # 0x26 +'jelb', # 0x27 +'jels', # 0x28 +'jelt', # 0x29 +'jelp', # 0x2a +'jelh', # 0x2b +'jem', # 0x2c +'jeb', # 0x2d +'jebs', # 0x2e +'jes', # 0x2f +'jess', # 0x30 +'jeng', # 0x31 +'jej', # 0x32 +'jec', # 0x33 +'jek', # 0x34 +'jet', # 0x35 +'jep', # 0x36 +'jeh', # 0x37 +'jyeo', # 0x38 +'jyeog', # 0x39 +'jyeogg', # 0x3a +'jyeogs', # 0x3b +'jyeon', # 0x3c +'jyeonj', # 0x3d +'jyeonh', # 0x3e +'jyeod', # 0x3f +'jyeol', # 0x40 +'jyeolg', # 0x41 +'jyeolm', # 0x42 +'jyeolb', # 0x43 +'jyeols', # 0x44 +'jyeolt', # 0x45 +'jyeolp', # 0x46 +'jyeolh', # 0x47 +'jyeom', # 0x48 +'jyeob', # 0x49 +'jyeobs', # 0x4a +'jyeos', # 0x4b +'jyeoss', # 0x4c +'jyeong', # 0x4d +'jyeoj', # 0x4e +'jyeoc', # 0x4f +'jyeok', # 0x50 +'jyeot', # 0x51 +'jyeop', # 0x52 +'jyeoh', # 0x53 +'jye', # 0x54 +'jyeg', # 0x55 +'jyegg', # 0x56 +'jyegs', # 0x57 +'jyen', # 0x58 +'jyenj', # 0x59 +'jyenh', # 0x5a +'jyed', # 0x5b +'jyel', # 0x5c +'jyelg', # 0x5d +'jyelm', # 0x5e +'jyelb', # 0x5f +'jyels', # 0x60 +'jyelt', # 0x61 +'jyelp', # 0x62 +'jyelh', # 0x63 +'jyem', # 0x64 +'jyeb', # 0x65 +'jyebs', # 0x66 +'jyes', # 0x67 +'jyess', # 0x68 +'jyeng', # 0x69 +'jyej', # 0x6a +'jyec', # 0x6b +'jyek', # 0x6c +'jyet', # 0x6d +'jyep', # 0x6e +'jyeh', # 0x6f +'jo', # 0x70 +'jog', # 0x71 +'jogg', # 0x72 +'jogs', # 0x73 +'jon', # 0x74 +'jonj', # 0x75 +'jonh', # 0x76 +'jod', # 0x77 +'jol', # 0x78 +'jolg', # 0x79 +'jolm', # 0x7a +'jolb', # 0x7b +'jols', # 0x7c +'jolt', # 0x7d +'jolp', # 0x7e +'jolh', # 0x7f +'jom', # 0x80 +'job', # 0x81 +'jobs', # 0x82 +'jos', # 0x83 +'joss', # 0x84 +'jong', # 0x85 +'joj', # 0x86 +'joc', # 0x87 +'jok', # 0x88 +'jot', # 0x89 +'jop', # 0x8a +'joh', # 0x8b +'jwa', # 0x8c +'jwag', # 0x8d +'jwagg', # 0x8e +'jwags', # 0x8f +'jwan', # 0x90 +'jwanj', # 0x91 +'jwanh', # 0x92 +'jwad', # 0x93 +'jwal', # 0x94 +'jwalg', # 0x95 +'jwalm', # 0x96 +'jwalb', # 0x97 +'jwals', # 0x98 +'jwalt', # 0x99 +'jwalp', # 0x9a +'jwalh', # 0x9b +'jwam', # 0x9c +'jwab', # 0x9d +'jwabs', # 0x9e +'jwas', # 0x9f +'jwass', # 0xa0 +'jwang', # 0xa1 +'jwaj', # 0xa2 +'jwac', # 0xa3 +'jwak', # 0xa4 +'jwat', # 0xa5 +'jwap', # 0xa6 +'jwah', # 0xa7 +'jwae', # 0xa8 +'jwaeg', # 0xa9 +'jwaegg', # 0xaa +'jwaegs', # 0xab +'jwaen', # 0xac +'jwaenj', # 0xad +'jwaenh', # 0xae +'jwaed', # 0xaf +'jwael', # 0xb0 +'jwaelg', # 0xb1 +'jwaelm', # 0xb2 +'jwaelb', # 0xb3 +'jwaels', # 0xb4 +'jwaelt', # 0xb5 +'jwaelp', # 0xb6 +'jwaelh', # 0xb7 +'jwaem', # 0xb8 +'jwaeb', # 0xb9 +'jwaebs', # 0xba +'jwaes', # 0xbb +'jwaess', # 0xbc +'jwaeng', # 0xbd +'jwaej', # 0xbe +'jwaec', # 0xbf +'jwaek', # 0xc0 +'jwaet', # 0xc1 +'jwaep', # 0xc2 +'jwaeh', # 0xc3 +'joe', # 0xc4 +'joeg', # 0xc5 +'joegg', # 0xc6 +'joegs', # 0xc7 +'joen', # 0xc8 +'joenj', # 0xc9 +'joenh', # 0xca +'joed', # 0xcb +'joel', # 0xcc +'joelg', # 0xcd +'joelm', # 0xce +'joelb', # 0xcf +'joels', # 0xd0 +'joelt', # 0xd1 +'joelp', # 0xd2 +'joelh', # 0xd3 +'joem', # 0xd4 +'joeb', # 0xd5 +'joebs', # 0xd6 +'joes', # 0xd7 +'joess', # 0xd8 +'joeng', # 0xd9 +'joej', # 0xda +'joec', # 0xdb +'joek', # 0xdc +'joet', # 0xdd +'joep', # 0xde +'joeh', # 0xdf +'jyo', # 0xe0 +'jyog', # 0xe1 +'jyogg', # 0xe2 +'jyogs', # 0xe3 +'jyon', # 0xe4 +'jyonj', # 0xe5 +'jyonh', # 0xe6 +'jyod', # 0xe7 +'jyol', # 0xe8 +'jyolg', # 0xe9 +'jyolm', # 0xea +'jyolb', # 0xeb +'jyols', # 0xec +'jyolt', # 0xed +'jyolp', # 0xee +'jyolh', # 0xef +'jyom', # 0xf0 +'jyob', # 0xf1 +'jyobs', # 0xf2 +'jyos', # 0xf3 +'jyoss', # 0xf4 +'jyong', # 0xf5 +'jyoj', # 0xf6 +'jyoc', # 0xf7 +'jyok', # 0xf8 +'jyot', # 0xf9 +'jyop', # 0xfa +'jyoh', # 0xfb +'ju', # 0xfc +'jug', # 0xfd +'jugg', # 0xfe +'jugs', # 0xff +) diff --git a/libs/unidecode/x0c9.py b/libs/unidecode/x0c9.py new file mode 100644 index 00000000..7e098327 --- /dev/null +++ b/libs/unidecode/x0c9.py @@ -0,0 +1,258 @@ +data = ( +'jun', # 0x00 +'junj', # 0x01 +'junh', # 0x02 +'jud', # 0x03 +'jul', # 0x04 +'julg', # 0x05 +'julm', # 0x06 +'julb', # 0x07 +'juls', # 0x08 +'jult', # 0x09 +'julp', # 0x0a +'julh', # 0x0b +'jum', # 0x0c +'jub', # 0x0d +'jubs', # 0x0e +'jus', # 0x0f +'juss', # 0x10 +'jung', # 0x11 +'juj', # 0x12 +'juc', # 0x13 +'juk', # 0x14 +'jut', # 0x15 +'jup', # 0x16 +'juh', # 0x17 +'jweo', # 0x18 +'jweog', # 0x19 +'jweogg', # 0x1a +'jweogs', # 0x1b +'jweon', # 0x1c +'jweonj', # 0x1d +'jweonh', # 0x1e +'jweod', # 0x1f +'jweol', # 0x20 +'jweolg', # 0x21 +'jweolm', # 0x22 +'jweolb', # 0x23 +'jweols', # 0x24 +'jweolt', # 0x25 +'jweolp', # 0x26 +'jweolh', # 0x27 +'jweom', # 0x28 +'jweob', # 0x29 +'jweobs', # 0x2a +'jweos', # 0x2b +'jweoss', # 0x2c +'jweong', # 0x2d +'jweoj', # 0x2e +'jweoc', # 0x2f +'jweok', # 0x30 +'jweot', # 0x31 +'jweop', # 0x32 +'jweoh', # 0x33 +'jwe', # 0x34 +'jweg', # 0x35 +'jwegg', # 0x36 +'jwegs', # 0x37 +'jwen', # 0x38 +'jwenj', # 0x39 +'jwenh', # 0x3a +'jwed', # 0x3b +'jwel', # 0x3c +'jwelg', # 0x3d +'jwelm', # 0x3e +'jwelb', # 0x3f +'jwels', # 0x40 +'jwelt', # 0x41 +'jwelp', # 0x42 +'jwelh', # 0x43 +'jwem', # 0x44 +'jweb', # 0x45 +'jwebs', # 0x46 +'jwes', # 0x47 +'jwess', # 0x48 +'jweng', # 0x49 +'jwej', # 0x4a +'jwec', # 0x4b +'jwek', # 0x4c +'jwet', # 0x4d +'jwep', # 0x4e +'jweh', # 0x4f +'jwi', # 0x50 +'jwig', # 0x51 +'jwigg', # 0x52 +'jwigs', # 0x53 +'jwin', # 0x54 +'jwinj', # 0x55 +'jwinh', # 0x56 +'jwid', # 0x57 +'jwil', # 0x58 +'jwilg', # 0x59 +'jwilm', # 0x5a +'jwilb', # 0x5b +'jwils', # 0x5c +'jwilt', # 0x5d +'jwilp', # 0x5e +'jwilh', # 0x5f +'jwim', # 0x60 +'jwib', # 0x61 +'jwibs', # 0x62 +'jwis', # 0x63 +'jwiss', # 0x64 +'jwing', # 0x65 +'jwij', # 0x66 +'jwic', # 0x67 +'jwik', # 0x68 +'jwit', # 0x69 +'jwip', # 0x6a +'jwih', # 0x6b +'jyu', # 0x6c +'jyug', # 0x6d +'jyugg', # 0x6e +'jyugs', # 0x6f +'jyun', # 0x70 +'jyunj', # 0x71 +'jyunh', # 0x72 +'jyud', # 0x73 +'jyul', # 0x74 +'jyulg', # 0x75 +'jyulm', # 0x76 +'jyulb', # 0x77 +'jyuls', # 0x78 +'jyult', # 0x79 +'jyulp', # 0x7a +'jyulh', # 0x7b +'jyum', # 0x7c +'jyub', # 0x7d +'jyubs', # 0x7e +'jyus', # 0x7f +'jyuss', # 0x80 +'jyung', # 0x81 +'jyuj', # 0x82 +'jyuc', # 0x83 +'jyuk', # 0x84 +'jyut', # 0x85 +'jyup', # 0x86 +'jyuh', # 0x87 +'jeu', # 0x88 +'jeug', # 0x89 +'jeugg', # 0x8a +'jeugs', # 0x8b +'jeun', # 0x8c +'jeunj', # 0x8d +'jeunh', # 0x8e +'jeud', # 0x8f +'jeul', # 0x90 +'jeulg', # 0x91 +'jeulm', # 0x92 +'jeulb', # 0x93 +'jeuls', # 0x94 +'jeult', # 0x95 +'jeulp', # 0x96 +'jeulh', # 0x97 +'jeum', # 0x98 +'jeub', # 0x99 +'jeubs', # 0x9a +'jeus', # 0x9b +'jeuss', # 0x9c +'jeung', # 0x9d +'jeuj', # 0x9e +'jeuc', # 0x9f +'jeuk', # 0xa0 +'jeut', # 0xa1 +'jeup', # 0xa2 +'jeuh', # 0xa3 +'jyi', # 0xa4 +'jyig', # 0xa5 +'jyigg', # 0xa6 +'jyigs', # 0xa7 +'jyin', # 0xa8 +'jyinj', # 0xa9 +'jyinh', # 0xaa +'jyid', # 0xab +'jyil', # 0xac +'jyilg', # 0xad +'jyilm', # 0xae +'jyilb', # 0xaf +'jyils', # 0xb0 +'jyilt', # 0xb1 +'jyilp', # 0xb2 +'jyilh', # 0xb3 +'jyim', # 0xb4 +'jyib', # 0xb5 +'jyibs', # 0xb6 +'jyis', # 0xb7 +'jyiss', # 0xb8 +'jying', # 0xb9 +'jyij', # 0xba +'jyic', # 0xbb +'jyik', # 0xbc +'jyit', # 0xbd +'jyip', # 0xbe +'jyih', # 0xbf +'ji', # 0xc0 +'jig', # 0xc1 +'jigg', # 0xc2 +'jigs', # 0xc3 +'jin', # 0xc4 +'jinj', # 0xc5 +'jinh', # 0xc6 +'jid', # 0xc7 +'jil', # 0xc8 +'jilg', # 0xc9 +'jilm', # 0xca +'jilb', # 0xcb +'jils', # 0xcc +'jilt', # 0xcd +'jilp', # 0xce +'jilh', # 0xcf +'jim', # 0xd0 +'jib', # 0xd1 +'jibs', # 0xd2 +'jis', # 0xd3 +'jiss', # 0xd4 +'jing', # 0xd5 +'jij', # 0xd6 +'jic', # 0xd7 +'jik', # 0xd8 +'jit', # 0xd9 +'jip', # 0xda +'jih', # 0xdb +'jja', # 0xdc +'jjag', # 0xdd +'jjagg', # 0xde +'jjags', # 0xdf +'jjan', # 0xe0 +'jjanj', # 0xe1 +'jjanh', # 0xe2 +'jjad', # 0xe3 +'jjal', # 0xe4 +'jjalg', # 0xe5 +'jjalm', # 0xe6 +'jjalb', # 0xe7 +'jjals', # 0xe8 +'jjalt', # 0xe9 +'jjalp', # 0xea +'jjalh', # 0xeb +'jjam', # 0xec +'jjab', # 0xed +'jjabs', # 0xee +'jjas', # 0xef +'jjass', # 0xf0 +'jjang', # 0xf1 +'jjaj', # 0xf2 +'jjac', # 0xf3 +'jjak', # 0xf4 +'jjat', # 0xf5 +'jjap', # 0xf6 +'jjah', # 0xf7 +'jjae', # 0xf8 +'jjaeg', # 0xf9 +'jjaegg', # 0xfa +'jjaegs', # 0xfb +'jjaen', # 0xfc +'jjaenj', # 0xfd +'jjaenh', # 0xfe +'jjaed', # 0xff +) diff --git a/libs/unidecode/x0ca.py b/libs/unidecode/x0ca.py new file mode 100644 index 00000000..20239b71 --- /dev/null +++ b/libs/unidecode/x0ca.py @@ -0,0 +1,258 @@ +data = ( +'jjael', # 0x00 +'jjaelg', # 0x01 +'jjaelm', # 0x02 +'jjaelb', # 0x03 +'jjaels', # 0x04 +'jjaelt', # 0x05 +'jjaelp', # 0x06 +'jjaelh', # 0x07 +'jjaem', # 0x08 +'jjaeb', # 0x09 +'jjaebs', # 0x0a +'jjaes', # 0x0b +'jjaess', # 0x0c +'jjaeng', # 0x0d +'jjaej', # 0x0e +'jjaec', # 0x0f +'jjaek', # 0x10 +'jjaet', # 0x11 +'jjaep', # 0x12 +'jjaeh', # 0x13 +'jjya', # 0x14 +'jjyag', # 0x15 +'jjyagg', # 0x16 +'jjyags', # 0x17 +'jjyan', # 0x18 +'jjyanj', # 0x19 +'jjyanh', # 0x1a +'jjyad', # 0x1b +'jjyal', # 0x1c +'jjyalg', # 0x1d +'jjyalm', # 0x1e +'jjyalb', # 0x1f +'jjyals', # 0x20 +'jjyalt', # 0x21 +'jjyalp', # 0x22 +'jjyalh', # 0x23 +'jjyam', # 0x24 +'jjyab', # 0x25 +'jjyabs', # 0x26 +'jjyas', # 0x27 +'jjyass', # 0x28 +'jjyang', # 0x29 +'jjyaj', # 0x2a +'jjyac', # 0x2b +'jjyak', # 0x2c +'jjyat', # 0x2d +'jjyap', # 0x2e +'jjyah', # 0x2f +'jjyae', # 0x30 +'jjyaeg', # 0x31 +'jjyaegg', # 0x32 +'jjyaegs', # 0x33 +'jjyaen', # 0x34 +'jjyaenj', # 0x35 +'jjyaenh', # 0x36 +'jjyaed', # 0x37 +'jjyael', # 0x38 +'jjyaelg', # 0x39 +'jjyaelm', # 0x3a +'jjyaelb', # 0x3b +'jjyaels', # 0x3c +'jjyaelt', # 0x3d +'jjyaelp', # 0x3e +'jjyaelh', # 0x3f +'jjyaem', # 0x40 +'jjyaeb', # 0x41 +'jjyaebs', # 0x42 +'jjyaes', # 0x43 +'jjyaess', # 0x44 +'jjyaeng', # 0x45 +'jjyaej', # 0x46 +'jjyaec', # 0x47 +'jjyaek', # 0x48 +'jjyaet', # 0x49 +'jjyaep', # 0x4a +'jjyaeh', # 0x4b +'jjeo', # 0x4c +'jjeog', # 0x4d +'jjeogg', # 0x4e +'jjeogs', # 0x4f +'jjeon', # 0x50 +'jjeonj', # 0x51 +'jjeonh', # 0x52 +'jjeod', # 0x53 +'jjeol', # 0x54 +'jjeolg', # 0x55 +'jjeolm', # 0x56 +'jjeolb', # 0x57 +'jjeols', # 0x58 +'jjeolt', # 0x59 +'jjeolp', # 0x5a +'jjeolh', # 0x5b +'jjeom', # 0x5c +'jjeob', # 0x5d +'jjeobs', # 0x5e +'jjeos', # 0x5f +'jjeoss', # 0x60 +'jjeong', # 0x61 +'jjeoj', # 0x62 +'jjeoc', # 0x63 +'jjeok', # 0x64 +'jjeot', # 0x65 +'jjeop', # 0x66 +'jjeoh', # 0x67 +'jje', # 0x68 +'jjeg', # 0x69 +'jjegg', # 0x6a +'jjegs', # 0x6b +'jjen', # 0x6c +'jjenj', # 0x6d +'jjenh', # 0x6e +'jjed', # 0x6f +'jjel', # 0x70 +'jjelg', # 0x71 +'jjelm', # 0x72 +'jjelb', # 0x73 +'jjels', # 0x74 +'jjelt', # 0x75 +'jjelp', # 0x76 +'jjelh', # 0x77 +'jjem', # 0x78 +'jjeb', # 0x79 +'jjebs', # 0x7a +'jjes', # 0x7b +'jjess', # 0x7c +'jjeng', # 0x7d +'jjej', # 0x7e +'jjec', # 0x7f +'jjek', # 0x80 +'jjet', # 0x81 +'jjep', # 0x82 +'jjeh', # 0x83 +'jjyeo', # 0x84 +'jjyeog', # 0x85 +'jjyeogg', # 0x86 +'jjyeogs', # 0x87 +'jjyeon', # 0x88 +'jjyeonj', # 0x89 +'jjyeonh', # 0x8a +'jjyeod', # 0x8b +'jjyeol', # 0x8c +'jjyeolg', # 0x8d +'jjyeolm', # 0x8e +'jjyeolb', # 0x8f +'jjyeols', # 0x90 +'jjyeolt', # 0x91 +'jjyeolp', # 0x92 +'jjyeolh', # 0x93 +'jjyeom', # 0x94 +'jjyeob', # 0x95 +'jjyeobs', # 0x96 +'jjyeos', # 0x97 +'jjyeoss', # 0x98 +'jjyeong', # 0x99 +'jjyeoj', # 0x9a +'jjyeoc', # 0x9b +'jjyeok', # 0x9c +'jjyeot', # 0x9d +'jjyeop', # 0x9e +'jjyeoh', # 0x9f +'jjye', # 0xa0 +'jjyeg', # 0xa1 +'jjyegg', # 0xa2 +'jjyegs', # 0xa3 +'jjyen', # 0xa4 +'jjyenj', # 0xa5 +'jjyenh', # 0xa6 +'jjyed', # 0xa7 +'jjyel', # 0xa8 +'jjyelg', # 0xa9 +'jjyelm', # 0xaa +'jjyelb', # 0xab +'jjyels', # 0xac +'jjyelt', # 0xad +'jjyelp', # 0xae +'jjyelh', # 0xaf +'jjyem', # 0xb0 +'jjyeb', # 0xb1 +'jjyebs', # 0xb2 +'jjyes', # 0xb3 +'jjyess', # 0xb4 +'jjyeng', # 0xb5 +'jjyej', # 0xb6 +'jjyec', # 0xb7 +'jjyek', # 0xb8 +'jjyet', # 0xb9 +'jjyep', # 0xba +'jjyeh', # 0xbb +'jjo', # 0xbc +'jjog', # 0xbd +'jjogg', # 0xbe +'jjogs', # 0xbf +'jjon', # 0xc0 +'jjonj', # 0xc1 +'jjonh', # 0xc2 +'jjod', # 0xc3 +'jjol', # 0xc4 +'jjolg', # 0xc5 +'jjolm', # 0xc6 +'jjolb', # 0xc7 +'jjols', # 0xc8 +'jjolt', # 0xc9 +'jjolp', # 0xca +'jjolh', # 0xcb +'jjom', # 0xcc +'jjob', # 0xcd +'jjobs', # 0xce +'jjos', # 0xcf +'jjoss', # 0xd0 +'jjong', # 0xd1 +'jjoj', # 0xd2 +'jjoc', # 0xd3 +'jjok', # 0xd4 +'jjot', # 0xd5 +'jjop', # 0xd6 +'jjoh', # 0xd7 +'jjwa', # 0xd8 +'jjwag', # 0xd9 +'jjwagg', # 0xda +'jjwags', # 0xdb +'jjwan', # 0xdc +'jjwanj', # 0xdd +'jjwanh', # 0xde +'jjwad', # 0xdf +'jjwal', # 0xe0 +'jjwalg', # 0xe1 +'jjwalm', # 0xe2 +'jjwalb', # 0xe3 +'jjwals', # 0xe4 +'jjwalt', # 0xe5 +'jjwalp', # 0xe6 +'jjwalh', # 0xe7 +'jjwam', # 0xe8 +'jjwab', # 0xe9 +'jjwabs', # 0xea +'jjwas', # 0xeb +'jjwass', # 0xec +'jjwang', # 0xed +'jjwaj', # 0xee +'jjwac', # 0xef +'jjwak', # 0xf0 +'jjwat', # 0xf1 +'jjwap', # 0xf2 +'jjwah', # 0xf3 +'jjwae', # 0xf4 +'jjwaeg', # 0xf5 +'jjwaegg', # 0xf6 +'jjwaegs', # 0xf7 +'jjwaen', # 0xf8 +'jjwaenj', # 0xf9 +'jjwaenh', # 0xfa +'jjwaed', # 0xfb +'jjwael', # 0xfc +'jjwaelg', # 0xfd +'jjwaelm', # 0xfe +'jjwaelb', # 0xff +) diff --git a/libs/unidecode/x0cb.py b/libs/unidecode/x0cb.py new file mode 100644 index 00000000..96d9c18b --- /dev/null +++ b/libs/unidecode/x0cb.py @@ -0,0 +1,258 @@ +data = ( +'jjwaels', # 0x00 +'jjwaelt', # 0x01 +'jjwaelp', # 0x02 +'jjwaelh', # 0x03 +'jjwaem', # 0x04 +'jjwaeb', # 0x05 +'jjwaebs', # 0x06 +'jjwaes', # 0x07 +'jjwaess', # 0x08 +'jjwaeng', # 0x09 +'jjwaej', # 0x0a +'jjwaec', # 0x0b +'jjwaek', # 0x0c +'jjwaet', # 0x0d +'jjwaep', # 0x0e +'jjwaeh', # 0x0f +'jjoe', # 0x10 +'jjoeg', # 0x11 +'jjoegg', # 0x12 +'jjoegs', # 0x13 +'jjoen', # 0x14 +'jjoenj', # 0x15 +'jjoenh', # 0x16 +'jjoed', # 0x17 +'jjoel', # 0x18 +'jjoelg', # 0x19 +'jjoelm', # 0x1a +'jjoelb', # 0x1b +'jjoels', # 0x1c +'jjoelt', # 0x1d +'jjoelp', # 0x1e +'jjoelh', # 0x1f +'jjoem', # 0x20 +'jjoeb', # 0x21 +'jjoebs', # 0x22 +'jjoes', # 0x23 +'jjoess', # 0x24 +'jjoeng', # 0x25 +'jjoej', # 0x26 +'jjoec', # 0x27 +'jjoek', # 0x28 +'jjoet', # 0x29 +'jjoep', # 0x2a +'jjoeh', # 0x2b +'jjyo', # 0x2c +'jjyog', # 0x2d +'jjyogg', # 0x2e +'jjyogs', # 0x2f +'jjyon', # 0x30 +'jjyonj', # 0x31 +'jjyonh', # 0x32 +'jjyod', # 0x33 +'jjyol', # 0x34 +'jjyolg', # 0x35 +'jjyolm', # 0x36 +'jjyolb', # 0x37 +'jjyols', # 0x38 +'jjyolt', # 0x39 +'jjyolp', # 0x3a +'jjyolh', # 0x3b +'jjyom', # 0x3c +'jjyob', # 0x3d +'jjyobs', # 0x3e +'jjyos', # 0x3f +'jjyoss', # 0x40 +'jjyong', # 0x41 +'jjyoj', # 0x42 +'jjyoc', # 0x43 +'jjyok', # 0x44 +'jjyot', # 0x45 +'jjyop', # 0x46 +'jjyoh', # 0x47 +'jju', # 0x48 +'jjug', # 0x49 +'jjugg', # 0x4a +'jjugs', # 0x4b +'jjun', # 0x4c +'jjunj', # 0x4d +'jjunh', # 0x4e +'jjud', # 0x4f +'jjul', # 0x50 +'jjulg', # 0x51 +'jjulm', # 0x52 +'jjulb', # 0x53 +'jjuls', # 0x54 +'jjult', # 0x55 +'jjulp', # 0x56 +'jjulh', # 0x57 +'jjum', # 0x58 +'jjub', # 0x59 +'jjubs', # 0x5a +'jjus', # 0x5b +'jjuss', # 0x5c +'jjung', # 0x5d +'jjuj', # 0x5e +'jjuc', # 0x5f +'jjuk', # 0x60 +'jjut', # 0x61 +'jjup', # 0x62 +'jjuh', # 0x63 +'jjweo', # 0x64 +'jjweog', # 0x65 +'jjweogg', # 0x66 +'jjweogs', # 0x67 +'jjweon', # 0x68 +'jjweonj', # 0x69 +'jjweonh', # 0x6a +'jjweod', # 0x6b +'jjweol', # 0x6c +'jjweolg', # 0x6d +'jjweolm', # 0x6e +'jjweolb', # 0x6f +'jjweols', # 0x70 +'jjweolt', # 0x71 +'jjweolp', # 0x72 +'jjweolh', # 0x73 +'jjweom', # 0x74 +'jjweob', # 0x75 +'jjweobs', # 0x76 +'jjweos', # 0x77 +'jjweoss', # 0x78 +'jjweong', # 0x79 +'jjweoj', # 0x7a +'jjweoc', # 0x7b +'jjweok', # 0x7c +'jjweot', # 0x7d +'jjweop', # 0x7e +'jjweoh', # 0x7f +'jjwe', # 0x80 +'jjweg', # 0x81 +'jjwegg', # 0x82 +'jjwegs', # 0x83 +'jjwen', # 0x84 +'jjwenj', # 0x85 +'jjwenh', # 0x86 +'jjwed', # 0x87 +'jjwel', # 0x88 +'jjwelg', # 0x89 +'jjwelm', # 0x8a +'jjwelb', # 0x8b +'jjwels', # 0x8c +'jjwelt', # 0x8d +'jjwelp', # 0x8e +'jjwelh', # 0x8f +'jjwem', # 0x90 +'jjweb', # 0x91 +'jjwebs', # 0x92 +'jjwes', # 0x93 +'jjwess', # 0x94 +'jjweng', # 0x95 +'jjwej', # 0x96 +'jjwec', # 0x97 +'jjwek', # 0x98 +'jjwet', # 0x99 +'jjwep', # 0x9a +'jjweh', # 0x9b +'jjwi', # 0x9c +'jjwig', # 0x9d +'jjwigg', # 0x9e +'jjwigs', # 0x9f +'jjwin', # 0xa0 +'jjwinj', # 0xa1 +'jjwinh', # 0xa2 +'jjwid', # 0xa3 +'jjwil', # 0xa4 +'jjwilg', # 0xa5 +'jjwilm', # 0xa6 +'jjwilb', # 0xa7 +'jjwils', # 0xa8 +'jjwilt', # 0xa9 +'jjwilp', # 0xaa +'jjwilh', # 0xab +'jjwim', # 0xac +'jjwib', # 0xad +'jjwibs', # 0xae +'jjwis', # 0xaf +'jjwiss', # 0xb0 +'jjwing', # 0xb1 +'jjwij', # 0xb2 +'jjwic', # 0xb3 +'jjwik', # 0xb4 +'jjwit', # 0xb5 +'jjwip', # 0xb6 +'jjwih', # 0xb7 +'jjyu', # 0xb8 +'jjyug', # 0xb9 +'jjyugg', # 0xba +'jjyugs', # 0xbb +'jjyun', # 0xbc +'jjyunj', # 0xbd +'jjyunh', # 0xbe +'jjyud', # 0xbf +'jjyul', # 0xc0 +'jjyulg', # 0xc1 +'jjyulm', # 0xc2 +'jjyulb', # 0xc3 +'jjyuls', # 0xc4 +'jjyult', # 0xc5 +'jjyulp', # 0xc6 +'jjyulh', # 0xc7 +'jjyum', # 0xc8 +'jjyub', # 0xc9 +'jjyubs', # 0xca +'jjyus', # 0xcb +'jjyuss', # 0xcc +'jjyung', # 0xcd +'jjyuj', # 0xce +'jjyuc', # 0xcf +'jjyuk', # 0xd0 +'jjyut', # 0xd1 +'jjyup', # 0xd2 +'jjyuh', # 0xd3 +'jjeu', # 0xd4 +'jjeug', # 0xd5 +'jjeugg', # 0xd6 +'jjeugs', # 0xd7 +'jjeun', # 0xd8 +'jjeunj', # 0xd9 +'jjeunh', # 0xda +'jjeud', # 0xdb +'jjeul', # 0xdc +'jjeulg', # 0xdd +'jjeulm', # 0xde +'jjeulb', # 0xdf +'jjeuls', # 0xe0 +'jjeult', # 0xe1 +'jjeulp', # 0xe2 +'jjeulh', # 0xe3 +'jjeum', # 0xe4 +'jjeub', # 0xe5 +'jjeubs', # 0xe6 +'jjeus', # 0xe7 +'jjeuss', # 0xe8 +'jjeung', # 0xe9 +'jjeuj', # 0xea +'jjeuc', # 0xeb +'jjeuk', # 0xec +'jjeut', # 0xed +'jjeup', # 0xee +'jjeuh', # 0xef +'jjyi', # 0xf0 +'jjyig', # 0xf1 +'jjyigg', # 0xf2 +'jjyigs', # 0xf3 +'jjyin', # 0xf4 +'jjyinj', # 0xf5 +'jjyinh', # 0xf6 +'jjyid', # 0xf7 +'jjyil', # 0xf8 +'jjyilg', # 0xf9 +'jjyilm', # 0xfa +'jjyilb', # 0xfb +'jjyils', # 0xfc +'jjyilt', # 0xfd +'jjyilp', # 0xfe +'jjyilh', # 0xff +) diff --git a/libs/unidecode/x0cc.py b/libs/unidecode/x0cc.py new file mode 100644 index 00000000..58f819a0 --- /dev/null +++ b/libs/unidecode/x0cc.py @@ -0,0 +1,258 @@ +data = ( +'jjyim', # 0x00 +'jjyib', # 0x01 +'jjyibs', # 0x02 +'jjyis', # 0x03 +'jjyiss', # 0x04 +'jjying', # 0x05 +'jjyij', # 0x06 +'jjyic', # 0x07 +'jjyik', # 0x08 +'jjyit', # 0x09 +'jjyip', # 0x0a +'jjyih', # 0x0b +'jji', # 0x0c +'jjig', # 0x0d +'jjigg', # 0x0e +'jjigs', # 0x0f +'jjin', # 0x10 +'jjinj', # 0x11 +'jjinh', # 0x12 +'jjid', # 0x13 +'jjil', # 0x14 +'jjilg', # 0x15 +'jjilm', # 0x16 +'jjilb', # 0x17 +'jjils', # 0x18 +'jjilt', # 0x19 +'jjilp', # 0x1a +'jjilh', # 0x1b +'jjim', # 0x1c +'jjib', # 0x1d +'jjibs', # 0x1e +'jjis', # 0x1f +'jjiss', # 0x20 +'jjing', # 0x21 +'jjij', # 0x22 +'jjic', # 0x23 +'jjik', # 0x24 +'jjit', # 0x25 +'jjip', # 0x26 +'jjih', # 0x27 +'ca', # 0x28 +'cag', # 0x29 +'cagg', # 0x2a +'cags', # 0x2b +'can', # 0x2c +'canj', # 0x2d +'canh', # 0x2e +'cad', # 0x2f +'cal', # 0x30 +'calg', # 0x31 +'calm', # 0x32 +'calb', # 0x33 +'cals', # 0x34 +'calt', # 0x35 +'calp', # 0x36 +'calh', # 0x37 +'cam', # 0x38 +'cab', # 0x39 +'cabs', # 0x3a +'cas', # 0x3b +'cass', # 0x3c +'cang', # 0x3d +'caj', # 0x3e +'cac', # 0x3f +'cak', # 0x40 +'cat', # 0x41 +'cap', # 0x42 +'cah', # 0x43 +'cae', # 0x44 +'caeg', # 0x45 +'caegg', # 0x46 +'caegs', # 0x47 +'caen', # 0x48 +'caenj', # 0x49 +'caenh', # 0x4a +'caed', # 0x4b +'cael', # 0x4c +'caelg', # 0x4d +'caelm', # 0x4e +'caelb', # 0x4f +'caels', # 0x50 +'caelt', # 0x51 +'caelp', # 0x52 +'caelh', # 0x53 +'caem', # 0x54 +'caeb', # 0x55 +'caebs', # 0x56 +'caes', # 0x57 +'caess', # 0x58 +'caeng', # 0x59 +'caej', # 0x5a +'caec', # 0x5b +'caek', # 0x5c +'caet', # 0x5d +'caep', # 0x5e +'caeh', # 0x5f +'cya', # 0x60 +'cyag', # 0x61 +'cyagg', # 0x62 +'cyags', # 0x63 +'cyan', # 0x64 +'cyanj', # 0x65 +'cyanh', # 0x66 +'cyad', # 0x67 +'cyal', # 0x68 +'cyalg', # 0x69 +'cyalm', # 0x6a +'cyalb', # 0x6b +'cyals', # 0x6c +'cyalt', # 0x6d +'cyalp', # 0x6e +'cyalh', # 0x6f +'cyam', # 0x70 +'cyab', # 0x71 +'cyabs', # 0x72 +'cyas', # 0x73 +'cyass', # 0x74 +'cyang', # 0x75 +'cyaj', # 0x76 +'cyac', # 0x77 +'cyak', # 0x78 +'cyat', # 0x79 +'cyap', # 0x7a +'cyah', # 0x7b +'cyae', # 0x7c +'cyaeg', # 0x7d +'cyaegg', # 0x7e +'cyaegs', # 0x7f +'cyaen', # 0x80 +'cyaenj', # 0x81 +'cyaenh', # 0x82 +'cyaed', # 0x83 +'cyael', # 0x84 +'cyaelg', # 0x85 +'cyaelm', # 0x86 +'cyaelb', # 0x87 +'cyaels', # 0x88 +'cyaelt', # 0x89 +'cyaelp', # 0x8a +'cyaelh', # 0x8b +'cyaem', # 0x8c +'cyaeb', # 0x8d +'cyaebs', # 0x8e +'cyaes', # 0x8f +'cyaess', # 0x90 +'cyaeng', # 0x91 +'cyaej', # 0x92 +'cyaec', # 0x93 +'cyaek', # 0x94 +'cyaet', # 0x95 +'cyaep', # 0x96 +'cyaeh', # 0x97 +'ceo', # 0x98 +'ceog', # 0x99 +'ceogg', # 0x9a +'ceogs', # 0x9b +'ceon', # 0x9c +'ceonj', # 0x9d +'ceonh', # 0x9e +'ceod', # 0x9f +'ceol', # 0xa0 +'ceolg', # 0xa1 +'ceolm', # 0xa2 +'ceolb', # 0xa3 +'ceols', # 0xa4 +'ceolt', # 0xa5 +'ceolp', # 0xa6 +'ceolh', # 0xa7 +'ceom', # 0xa8 +'ceob', # 0xa9 +'ceobs', # 0xaa +'ceos', # 0xab +'ceoss', # 0xac +'ceong', # 0xad +'ceoj', # 0xae +'ceoc', # 0xaf +'ceok', # 0xb0 +'ceot', # 0xb1 +'ceop', # 0xb2 +'ceoh', # 0xb3 +'ce', # 0xb4 +'ceg', # 0xb5 +'cegg', # 0xb6 +'cegs', # 0xb7 +'cen', # 0xb8 +'cenj', # 0xb9 +'cenh', # 0xba +'ced', # 0xbb +'cel', # 0xbc +'celg', # 0xbd +'celm', # 0xbe +'celb', # 0xbf +'cels', # 0xc0 +'celt', # 0xc1 +'celp', # 0xc2 +'celh', # 0xc3 +'cem', # 0xc4 +'ceb', # 0xc5 +'cebs', # 0xc6 +'ces', # 0xc7 +'cess', # 0xc8 +'ceng', # 0xc9 +'cej', # 0xca +'cec', # 0xcb +'cek', # 0xcc +'cet', # 0xcd +'cep', # 0xce +'ceh', # 0xcf +'cyeo', # 0xd0 +'cyeog', # 0xd1 +'cyeogg', # 0xd2 +'cyeogs', # 0xd3 +'cyeon', # 0xd4 +'cyeonj', # 0xd5 +'cyeonh', # 0xd6 +'cyeod', # 0xd7 +'cyeol', # 0xd8 +'cyeolg', # 0xd9 +'cyeolm', # 0xda +'cyeolb', # 0xdb +'cyeols', # 0xdc +'cyeolt', # 0xdd +'cyeolp', # 0xde +'cyeolh', # 0xdf +'cyeom', # 0xe0 +'cyeob', # 0xe1 +'cyeobs', # 0xe2 +'cyeos', # 0xe3 +'cyeoss', # 0xe4 +'cyeong', # 0xe5 +'cyeoj', # 0xe6 +'cyeoc', # 0xe7 +'cyeok', # 0xe8 +'cyeot', # 0xe9 +'cyeop', # 0xea +'cyeoh', # 0xeb +'cye', # 0xec +'cyeg', # 0xed +'cyegg', # 0xee +'cyegs', # 0xef +'cyen', # 0xf0 +'cyenj', # 0xf1 +'cyenh', # 0xf2 +'cyed', # 0xf3 +'cyel', # 0xf4 +'cyelg', # 0xf5 +'cyelm', # 0xf6 +'cyelb', # 0xf7 +'cyels', # 0xf8 +'cyelt', # 0xf9 +'cyelp', # 0xfa +'cyelh', # 0xfb +'cyem', # 0xfc +'cyeb', # 0xfd +'cyebs', # 0xfe +'cyes', # 0xff +) diff --git a/libs/unidecode/x0cd.py b/libs/unidecode/x0cd.py new file mode 100644 index 00000000..dd6909a1 --- /dev/null +++ b/libs/unidecode/x0cd.py @@ -0,0 +1,258 @@ +data = ( +'cyess', # 0x00 +'cyeng', # 0x01 +'cyej', # 0x02 +'cyec', # 0x03 +'cyek', # 0x04 +'cyet', # 0x05 +'cyep', # 0x06 +'cyeh', # 0x07 +'co', # 0x08 +'cog', # 0x09 +'cogg', # 0x0a +'cogs', # 0x0b +'con', # 0x0c +'conj', # 0x0d +'conh', # 0x0e +'cod', # 0x0f +'col', # 0x10 +'colg', # 0x11 +'colm', # 0x12 +'colb', # 0x13 +'cols', # 0x14 +'colt', # 0x15 +'colp', # 0x16 +'colh', # 0x17 +'com', # 0x18 +'cob', # 0x19 +'cobs', # 0x1a +'cos', # 0x1b +'coss', # 0x1c +'cong', # 0x1d +'coj', # 0x1e +'coc', # 0x1f +'cok', # 0x20 +'cot', # 0x21 +'cop', # 0x22 +'coh', # 0x23 +'cwa', # 0x24 +'cwag', # 0x25 +'cwagg', # 0x26 +'cwags', # 0x27 +'cwan', # 0x28 +'cwanj', # 0x29 +'cwanh', # 0x2a +'cwad', # 0x2b +'cwal', # 0x2c +'cwalg', # 0x2d +'cwalm', # 0x2e +'cwalb', # 0x2f +'cwals', # 0x30 +'cwalt', # 0x31 +'cwalp', # 0x32 +'cwalh', # 0x33 +'cwam', # 0x34 +'cwab', # 0x35 +'cwabs', # 0x36 +'cwas', # 0x37 +'cwass', # 0x38 +'cwang', # 0x39 +'cwaj', # 0x3a +'cwac', # 0x3b +'cwak', # 0x3c +'cwat', # 0x3d +'cwap', # 0x3e +'cwah', # 0x3f +'cwae', # 0x40 +'cwaeg', # 0x41 +'cwaegg', # 0x42 +'cwaegs', # 0x43 +'cwaen', # 0x44 +'cwaenj', # 0x45 +'cwaenh', # 0x46 +'cwaed', # 0x47 +'cwael', # 0x48 +'cwaelg', # 0x49 +'cwaelm', # 0x4a +'cwaelb', # 0x4b +'cwaels', # 0x4c +'cwaelt', # 0x4d +'cwaelp', # 0x4e +'cwaelh', # 0x4f +'cwaem', # 0x50 +'cwaeb', # 0x51 +'cwaebs', # 0x52 +'cwaes', # 0x53 +'cwaess', # 0x54 +'cwaeng', # 0x55 +'cwaej', # 0x56 +'cwaec', # 0x57 +'cwaek', # 0x58 +'cwaet', # 0x59 +'cwaep', # 0x5a +'cwaeh', # 0x5b +'coe', # 0x5c +'coeg', # 0x5d +'coegg', # 0x5e +'coegs', # 0x5f +'coen', # 0x60 +'coenj', # 0x61 +'coenh', # 0x62 +'coed', # 0x63 +'coel', # 0x64 +'coelg', # 0x65 +'coelm', # 0x66 +'coelb', # 0x67 +'coels', # 0x68 +'coelt', # 0x69 +'coelp', # 0x6a +'coelh', # 0x6b +'coem', # 0x6c +'coeb', # 0x6d +'coebs', # 0x6e +'coes', # 0x6f +'coess', # 0x70 +'coeng', # 0x71 +'coej', # 0x72 +'coec', # 0x73 +'coek', # 0x74 +'coet', # 0x75 +'coep', # 0x76 +'coeh', # 0x77 +'cyo', # 0x78 +'cyog', # 0x79 +'cyogg', # 0x7a +'cyogs', # 0x7b +'cyon', # 0x7c +'cyonj', # 0x7d +'cyonh', # 0x7e +'cyod', # 0x7f +'cyol', # 0x80 +'cyolg', # 0x81 +'cyolm', # 0x82 +'cyolb', # 0x83 +'cyols', # 0x84 +'cyolt', # 0x85 +'cyolp', # 0x86 +'cyolh', # 0x87 +'cyom', # 0x88 +'cyob', # 0x89 +'cyobs', # 0x8a +'cyos', # 0x8b +'cyoss', # 0x8c +'cyong', # 0x8d +'cyoj', # 0x8e +'cyoc', # 0x8f +'cyok', # 0x90 +'cyot', # 0x91 +'cyop', # 0x92 +'cyoh', # 0x93 +'cu', # 0x94 +'cug', # 0x95 +'cugg', # 0x96 +'cugs', # 0x97 +'cun', # 0x98 +'cunj', # 0x99 +'cunh', # 0x9a +'cud', # 0x9b +'cul', # 0x9c +'culg', # 0x9d +'culm', # 0x9e +'culb', # 0x9f +'culs', # 0xa0 +'cult', # 0xa1 +'culp', # 0xa2 +'culh', # 0xa3 +'cum', # 0xa4 +'cub', # 0xa5 +'cubs', # 0xa6 +'cus', # 0xa7 +'cuss', # 0xa8 +'cung', # 0xa9 +'cuj', # 0xaa +'cuc', # 0xab +'cuk', # 0xac +'cut', # 0xad +'cup', # 0xae +'cuh', # 0xaf +'cweo', # 0xb0 +'cweog', # 0xb1 +'cweogg', # 0xb2 +'cweogs', # 0xb3 +'cweon', # 0xb4 +'cweonj', # 0xb5 +'cweonh', # 0xb6 +'cweod', # 0xb7 +'cweol', # 0xb8 +'cweolg', # 0xb9 +'cweolm', # 0xba +'cweolb', # 0xbb +'cweols', # 0xbc +'cweolt', # 0xbd +'cweolp', # 0xbe +'cweolh', # 0xbf +'cweom', # 0xc0 +'cweob', # 0xc1 +'cweobs', # 0xc2 +'cweos', # 0xc3 +'cweoss', # 0xc4 +'cweong', # 0xc5 +'cweoj', # 0xc6 +'cweoc', # 0xc7 +'cweok', # 0xc8 +'cweot', # 0xc9 +'cweop', # 0xca +'cweoh', # 0xcb +'cwe', # 0xcc +'cweg', # 0xcd +'cwegg', # 0xce +'cwegs', # 0xcf +'cwen', # 0xd0 +'cwenj', # 0xd1 +'cwenh', # 0xd2 +'cwed', # 0xd3 +'cwel', # 0xd4 +'cwelg', # 0xd5 +'cwelm', # 0xd6 +'cwelb', # 0xd7 +'cwels', # 0xd8 +'cwelt', # 0xd9 +'cwelp', # 0xda +'cwelh', # 0xdb +'cwem', # 0xdc +'cweb', # 0xdd +'cwebs', # 0xde +'cwes', # 0xdf +'cwess', # 0xe0 +'cweng', # 0xe1 +'cwej', # 0xe2 +'cwec', # 0xe3 +'cwek', # 0xe4 +'cwet', # 0xe5 +'cwep', # 0xe6 +'cweh', # 0xe7 +'cwi', # 0xe8 +'cwig', # 0xe9 +'cwigg', # 0xea +'cwigs', # 0xeb +'cwin', # 0xec +'cwinj', # 0xed +'cwinh', # 0xee +'cwid', # 0xef +'cwil', # 0xf0 +'cwilg', # 0xf1 +'cwilm', # 0xf2 +'cwilb', # 0xf3 +'cwils', # 0xf4 +'cwilt', # 0xf5 +'cwilp', # 0xf6 +'cwilh', # 0xf7 +'cwim', # 0xf8 +'cwib', # 0xf9 +'cwibs', # 0xfa +'cwis', # 0xfb +'cwiss', # 0xfc +'cwing', # 0xfd +'cwij', # 0xfe +'cwic', # 0xff +) diff --git a/libs/unidecode/x0ce.py b/libs/unidecode/x0ce.py new file mode 100644 index 00000000..4b993e89 --- /dev/null +++ b/libs/unidecode/x0ce.py @@ -0,0 +1,258 @@ +data = ( +'cwik', # 0x00 +'cwit', # 0x01 +'cwip', # 0x02 +'cwih', # 0x03 +'cyu', # 0x04 +'cyug', # 0x05 +'cyugg', # 0x06 +'cyugs', # 0x07 +'cyun', # 0x08 +'cyunj', # 0x09 +'cyunh', # 0x0a +'cyud', # 0x0b +'cyul', # 0x0c +'cyulg', # 0x0d +'cyulm', # 0x0e +'cyulb', # 0x0f +'cyuls', # 0x10 +'cyult', # 0x11 +'cyulp', # 0x12 +'cyulh', # 0x13 +'cyum', # 0x14 +'cyub', # 0x15 +'cyubs', # 0x16 +'cyus', # 0x17 +'cyuss', # 0x18 +'cyung', # 0x19 +'cyuj', # 0x1a +'cyuc', # 0x1b +'cyuk', # 0x1c +'cyut', # 0x1d +'cyup', # 0x1e +'cyuh', # 0x1f +'ceu', # 0x20 +'ceug', # 0x21 +'ceugg', # 0x22 +'ceugs', # 0x23 +'ceun', # 0x24 +'ceunj', # 0x25 +'ceunh', # 0x26 +'ceud', # 0x27 +'ceul', # 0x28 +'ceulg', # 0x29 +'ceulm', # 0x2a +'ceulb', # 0x2b +'ceuls', # 0x2c +'ceult', # 0x2d +'ceulp', # 0x2e +'ceulh', # 0x2f +'ceum', # 0x30 +'ceub', # 0x31 +'ceubs', # 0x32 +'ceus', # 0x33 +'ceuss', # 0x34 +'ceung', # 0x35 +'ceuj', # 0x36 +'ceuc', # 0x37 +'ceuk', # 0x38 +'ceut', # 0x39 +'ceup', # 0x3a +'ceuh', # 0x3b +'cyi', # 0x3c +'cyig', # 0x3d +'cyigg', # 0x3e +'cyigs', # 0x3f +'cyin', # 0x40 +'cyinj', # 0x41 +'cyinh', # 0x42 +'cyid', # 0x43 +'cyil', # 0x44 +'cyilg', # 0x45 +'cyilm', # 0x46 +'cyilb', # 0x47 +'cyils', # 0x48 +'cyilt', # 0x49 +'cyilp', # 0x4a +'cyilh', # 0x4b +'cyim', # 0x4c +'cyib', # 0x4d +'cyibs', # 0x4e +'cyis', # 0x4f +'cyiss', # 0x50 +'cying', # 0x51 +'cyij', # 0x52 +'cyic', # 0x53 +'cyik', # 0x54 +'cyit', # 0x55 +'cyip', # 0x56 +'cyih', # 0x57 +'ci', # 0x58 +'cig', # 0x59 +'cigg', # 0x5a +'cigs', # 0x5b +'cin', # 0x5c +'cinj', # 0x5d +'cinh', # 0x5e +'cid', # 0x5f +'cil', # 0x60 +'cilg', # 0x61 +'cilm', # 0x62 +'cilb', # 0x63 +'cils', # 0x64 +'cilt', # 0x65 +'cilp', # 0x66 +'cilh', # 0x67 +'cim', # 0x68 +'cib', # 0x69 +'cibs', # 0x6a +'cis', # 0x6b +'ciss', # 0x6c +'cing', # 0x6d +'cij', # 0x6e +'cic', # 0x6f +'cik', # 0x70 +'cit', # 0x71 +'cip', # 0x72 +'cih', # 0x73 +'ka', # 0x74 +'kag', # 0x75 +'kagg', # 0x76 +'kags', # 0x77 +'kan', # 0x78 +'kanj', # 0x79 +'kanh', # 0x7a +'kad', # 0x7b +'kal', # 0x7c +'kalg', # 0x7d +'kalm', # 0x7e +'kalb', # 0x7f +'kals', # 0x80 +'kalt', # 0x81 +'kalp', # 0x82 +'kalh', # 0x83 +'kam', # 0x84 +'kab', # 0x85 +'kabs', # 0x86 +'kas', # 0x87 +'kass', # 0x88 +'kang', # 0x89 +'kaj', # 0x8a +'kac', # 0x8b +'kak', # 0x8c +'kat', # 0x8d +'kap', # 0x8e +'kah', # 0x8f +'kae', # 0x90 +'kaeg', # 0x91 +'kaegg', # 0x92 +'kaegs', # 0x93 +'kaen', # 0x94 +'kaenj', # 0x95 +'kaenh', # 0x96 +'kaed', # 0x97 +'kael', # 0x98 +'kaelg', # 0x99 +'kaelm', # 0x9a +'kaelb', # 0x9b +'kaels', # 0x9c +'kaelt', # 0x9d +'kaelp', # 0x9e +'kaelh', # 0x9f +'kaem', # 0xa0 +'kaeb', # 0xa1 +'kaebs', # 0xa2 +'kaes', # 0xa3 +'kaess', # 0xa4 +'kaeng', # 0xa5 +'kaej', # 0xa6 +'kaec', # 0xa7 +'kaek', # 0xa8 +'kaet', # 0xa9 +'kaep', # 0xaa +'kaeh', # 0xab +'kya', # 0xac +'kyag', # 0xad +'kyagg', # 0xae +'kyags', # 0xaf +'kyan', # 0xb0 +'kyanj', # 0xb1 +'kyanh', # 0xb2 +'kyad', # 0xb3 +'kyal', # 0xb4 +'kyalg', # 0xb5 +'kyalm', # 0xb6 +'kyalb', # 0xb7 +'kyals', # 0xb8 +'kyalt', # 0xb9 +'kyalp', # 0xba +'kyalh', # 0xbb +'kyam', # 0xbc +'kyab', # 0xbd +'kyabs', # 0xbe +'kyas', # 0xbf +'kyass', # 0xc0 +'kyang', # 0xc1 +'kyaj', # 0xc2 +'kyac', # 0xc3 +'kyak', # 0xc4 +'kyat', # 0xc5 +'kyap', # 0xc6 +'kyah', # 0xc7 +'kyae', # 0xc8 +'kyaeg', # 0xc9 +'kyaegg', # 0xca +'kyaegs', # 0xcb +'kyaen', # 0xcc +'kyaenj', # 0xcd +'kyaenh', # 0xce +'kyaed', # 0xcf +'kyael', # 0xd0 +'kyaelg', # 0xd1 +'kyaelm', # 0xd2 +'kyaelb', # 0xd3 +'kyaels', # 0xd4 +'kyaelt', # 0xd5 +'kyaelp', # 0xd6 +'kyaelh', # 0xd7 +'kyaem', # 0xd8 +'kyaeb', # 0xd9 +'kyaebs', # 0xda +'kyaes', # 0xdb +'kyaess', # 0xdc +'kyaeng', # 0xdd +'kyaej', # 0xde +'kyaec', # 0xdf +'kyaek', # 0xe0 +'kyaet', # 0xe1 +'kyaep', # 0xe2 +'kyaeh', # 0xe3 +'keo', # 0xe4 +'keog', # 0xe5 +'keogg', # 0xe6 +'keogs', # 0xe7 +'keon', # 0xe8 +'keonj', # 0xe9 +'keonh', # 0xea +'keod', # 0xeb +'keol', # 0xec +'keolg', # 0xed +'keolm', # 0xee +'keolb', # 0xef +'keols', # 0xf0 +'keolt', # 0xf1 +'keolp', # 0xf2 +'keolh', # 0xf3 +'keom', # 0xf4 +'keob', # 0xf5 +'keobs', # 0xf6 +'keos', # 0xf7 +'keoss', # 0xf8 +'keong', # 0xf9 +'keoj', # 0xfa +'keoc', # 0xfb +'keok', # 0xfc +'keot', # 0xfd +'keop', # 0xfe +'keoh', # 0xff +) diff --git a/libs/unidecode/x0cf.py b/libs/unidecode/x0cf.py new file mode 100644 index 00000000..e825983e --- /dev/null +++ b/libs/unidecode/x0cf.py @@ -0,0 +1,258 @@ +data = ( +'ke', # 0x00 +'keg', # 0x01 +'kegg', # 0x02 +'kegs', # 0x03 +'ken', # 0x04 +'kenj', # 0x05 +'kenh', # 0x06 +'ked', # 0x07 +'kel', # 0x08 +'kelg', # 0x09 +'kelm', # 0x0a +'kelb', # 0x0b +'kels', # 0x0c +'kelt', # 0x0d +'kelp', # 0x0e +'kelh', # 0x0f +'kem', # 0x10 +'keb', # 0x11 +'kebs', # 0x12 +'kes', # 0x13 +'kess', # 0x14 +'keng', # 0x15 +'kej', # 0x16 +'kec', # 0x17 +'kek', # 0x18 +'ket', # 0x19 +'kep', # 0x1a +'keh', # 0x1b +'kyeo', # 0x1c +'kyeog', # 0x1d +'kyeogg', # 0x1e +'kyeogs', # 0x1f +'kyeon', # 0x20 +'kyeonj', # 0x21 +'kyeonh', # 0x22 +'kyeod', # 0x23 +'kyeol', # 0x24 +'kyeolg', # 0x25 +'kyeolm', # 0x26 +'kyeolb', # 0x27 +'kyeols', # 0x28 +'kyeolt', # 0x29 +'kyeolp', # 0x2a +'kyeolh', # 0x2b +'kyeom', # 0x2c +'kyeob', # 0x2d +'kyeobs', # 0x2e +'kyeos', # 0x2f +'kyeoss', # 0x30 +'kyeong', # 0x31 +'kyeoj', # 0x32 +'kyeoc', # 0x33 +'kyeok', # 0x34 +'kyeot', # 0x35 +'kyeop', # 0x36 +'kyeoh', # 0x37 +'kye', # 0x38 +'kyeg', # 0x39 +'kyegg', # 0x3a +'kyegs', # 0x3b +'kyen', # 0x3c +'kyenj', # 0x3d +'kyenh', # 0x3e +'kyed', # 0x3f +'kyel', # 0x40 +'kyelg', # 0x41 +'kyelm', # 0x42 +'kyelb', # 0x43 +'kyels', # 0x44 +'kyelt', # 0x45 +'kyelp', # 0x46 +'kyelh', # 0x47 +'kyem', # 0x48 +'kyeb', # 0x49 +'kyebs', # 0x4a +'kyes', # 0x4b +'kyess', # 0x4c +'kyeng', # 0x4d +'kyej', # 0x4e +'kyec', # 0x4f +'kyek', # 0x50 +'kyet', # 0x51 +'kyep', # 0x52 +'kyeh', # 0x53 +'ko', # 0x54 +'kog', # 0x55 +'kogg', # 0x56 +'kogs', # 0x57 +'kon', # 0x58 +'konj', # 0x59 +'konh', # 0x5a +'kod', # 0x5b +'kol', # 0x5c +'kolg', # 0x5d +'kolm', # 0x5e +'kolb', # 0x5f +'kols', # 0x60 +'kolt', # 0x61 +'kolp', # 0x62 +'kolh', # 0x63 +'kom', # 0x64 +'kob', # 0x65 +'kobs', # 0x66 +'kos', # 0x67 +'koss', # 0x68 +'kong', # 0x69 +'koj', # 0x6a +'koc', # 0x6b +'kok', # 0x6c +'kot', # 0x6d +'kop', # 0x6e +'koh', # 0x6f +'kwa', # 0x70 +'kwag', # 0x71 +'kwagg', # 0x72 +'kwags', # 0x73 +'kwan', # 0x74 +'kwanj', # 0x75 +'kwanh', # 0x76 +'kwad', # 0x77 +'kwal', # 0x78 +'kwalg', # 0x79 +'kwalm', # 0x7a +'kwalb', # 0x7b +'kwals', # 0x7c +'kwalt', # 0x7d +'kwalp', # 0x7e +'kwalh', # 0x7f +'kwam', # 0x80 +'kwab', # 0x81 +'kwabs', # 0x82 +'kwas', # 0x83 +'kwass', # 0x84 +'kwang', # 0x85 +'kwaj', # 0x86 +'kwac', # 0x87 +'kwak', # 0x88 +'kwat', # 0x89 +'kwap', # 0x8a +'kwah', # 0x8b +'kwae', # 0x8c +'kwaeg', # 0x8d +'kwaegg', # 0x8e +'kwaegs', # 0x8f +'kwaen', # 0x90 +'kwaenj', # 0x91 +'kwaenh', # 0x92 +'kwaed', # 0x93 +'kwael', # 0x94 +'kwaelg', # 0x95 +'kwaelm', # 0x96 +'kwaelb', # 0x97 +'kwaels', # 0x98 +'kwaelt', # 0x99 +'kwaelp', # 0x9a +'kwaelh', # 0x9b +'kwaem', # 0x9c +'kwaeb', # 0x9d +'kwaebs', # 0x9e +'kwaes', # 0x9f +'kwaess', # 0xa0 +'kwaeng', # 0xa1 +'kwaej', # 0xa2 +'kwaec', # 0xa3 +'kwaek', # 0xa4 +'kwaet', # 0xa5 +'kwaep', # 0xa6 +'kwaeh', # 0xa7 +'koe', # 0xa8 +'koeg', # 0xa9 +'koegg', # 0xaa +'koegs', # 0xab +'koen', # 0xac +'koenj', # 0xad +'koenh', # 0xae +'koed', # 0xaf +'koel', # 0xb0 +'koelg', # 0xb1 +'koelm', # 0xb2 +'koelb', # 0xb3 +'koels', # 0xb4 +'koelt', # 0xb5 +'koelp', # 0xb6 +'koelh', # 0xb7 +'koem', # 0xb8 +'koeb', # 0xb9 +'koebs', # 0xba +'koes', # 0xbb +'koess', # 0xbc +'koeng', # 0xbd +'koej', # 0xbe +'koec', # 0xbf +'koek', # 0xc0 +'koet', # 0xc1 +'koep', # 0xc2 +'koeh', # 0xc3 +'kyo', # 0xc4 +'kyog', # 0xc5 +'kyogg', # 0xc6 +'kyogs', # 0xc7 +'kyon', # 0xc8 +'kyonj', # 0xc9 +'kyonh', # 0xca +'kyod', # 0xcb +'kyol', # 0xcc +'kyolg', # 0xcd +'kyolm', # 0xce +'kyolb', # 0xcf +'kyols', # 0xd0 +'kyolt', # 0xd1 +'kyolp', # 0xd2 +'kyolh', # 0xd3 +'kyom', # 0xd4 +'kyob', # 0xd5 +'kyobs', # 0xd6 +'kyos', # 0xd7 +'kyoss', # 0xd8 +'kyong', # 0xd9 +'kyoj', # 0xda +'kyoc', # 0xdb +'kyok', # 0xdc +'kyot', # 0xdd +'kyop', # 0xde +'kyoh', # 0xdf +'ku', # 0xe0 +'kug', # 0xe1 +'kugg', # 0xe2 +'kugs', # 0xe3 +'kun', # 0xe4 +'kunj', # 0xe5 +'kunh', # 0xe6 +'kud', # 0xe7 +'kul', # 0xe8 +'kulg', # 0xe9 +'kulm', # 0xea +'kulb', # 0xeb +'kuls', # 0xec +'kult', # 0xed +'kulp', # 0xee +'kulh', # 0xef +'kum', # 0xf0 +'kub', # 0xf1 +'kubs', # 0xf2 +'kus', # 0xf3 +'kuss', # 0xf4 +'kung', # 0xf5 +'kuj', # 0xf6 +'kuc', # 0xf7 +'kuk', # 0xf8 +'kut', # 0xf9 +'kup', # 0xfa +'kuh', # 0xfb +'kweo', # 0xfc +'kweog', # 0xfd +'kweogg', # 0xfe +'kweogs', # 0xff +) diff --git a/libs/unidecode/x0d0.py b/libs/unidecode/x0d0.py new file mode 100644 index 00000000..d6b38294 --- /dev/null +++ b/libs/unidecode/x0d0.py @@ -0,0 +1,258 @@ +data = ( +'kweon', # 0x00 +'kweonj', # 0x01 +'kweonh', # 0x02 +'kweod', # 0x03 +'kweol', # 0x04 +'kweolg', # 0x05 +'kweolm', # 0x06 +'kweolb', # 0x07 +'kweols', # 0x08 +'kweolt', # 0x09 +'kweolp', # 0x0a +'kweolh', # 0x0b +'kweom', # 0x0c +'kweob', # 0x0d +'kweobs', # 0x0e +'kweos', # 0x0f +'kweoss', # 0x10 +'kweong', # 0x11 +'kweoj', # 0x12 +'kweoc', # 0x13 +'kweok', # 0x14 +'kweot', # 0x15 +'kweop', # 0x16 +'kweoh', # 0x17 +'kwe', # 0x18 +'kweg', # 0x19 +'kwegg', # 0x1a +'kwegs', # 0x1b +'kwen', # 0x1c +'kwenj', # 0x1d +'kwenh', # 0x1e +'kwed', # 0x1f +'kwel', # 0x20 +'kwelg', # 0x21 +'kwelm', # 0x22 +'kwelb', # 0x23 +'kwels', # 0x24 +'kwelt', # 0x25 +'kwelp', # 0x26 +'kwelh', # 0x27 +'kwem', # 0x28 +'kweb', # 0x29 +'kwebs', # 0x2a +'kwes', # 0x2b +'kwess', # 0x2c +'kweng', # 0x2d +'kwej', # 0x2e +'kwec', # 0x2f +'kwek', # 0x30 +'kwet', # 0x31 +'kwep', # 0x32 +'kweh', # 0x33 +'kwi', # 0x34 +'kwig', # 0x35 +'kwigg', # 0x36 +'kwigs', # 0x37 +'kwin', # 0x38 +'kwinj', # 0x39 +'kwinh', # 0x3a +'kwid', # 0x3b +'kwil', # 0x3c +'kwilg', # 0x3d +'kwilm', # 0x3e +'kwilb', # 0x3f +'kwils', # 0x40 +'kwilt', # 0x41 +'kwilp', # 0x42 +'kwilh', # 0x43 +'kwim', # 0x44 +'kwib', # 0x45 +'kwibs', # 0x46 +'kwis', # 0x47 +'kwiss', # 0x48 +'kwing', # 0x49 +'kwij', # 0x4a +'kwic', # 0x4b +'kwik', # 0x4c +'kwit', # 0x4d +'kwip', # 0x4e +'kwih', # 0x4f +'kyu', # 0x50 +'kyug', # 0x51 +'kyugg', # 0x52 +'kyugs', # 0x53 +'kyun', # 0x54 +'kyunj', # 0x55 +'kyunh', # 0x56 +'kyud', # 0x57 +'kyul', # 0x58 +'kyulg', # 0x59 +'kyulm', # 0x5a +'kyulb', # 0x5b +'kyuls', # 0x5c +'kyult', # 0x5d +'kyulp', # 0x5e +'kyulh', # 0x5f +'kyum', # 0x60 +'kyub', # 0x61 +'kyubs', # 0x62 +'kyus', # 0x63 +'kyuss', # 0x64 +'kyung', # 0x65 +'kyuj', # 0x66 +'kyuc', # 0x67 +'kyuk', # 0x68 +'kyut', # 0x69 +'kyup', # 0x6a +'kyuh', # 0x6b +'keu', # 0x6c +'keug', # 0x6d +'keugg', # 0x6e +'keugs', # 0x6f +'keun', # 0x70 +'keunj', # 0x71 +'keunh', # 0x72 +'keud', # 0x73 +'keul', # 0x74 +'keulg', # 0x75 +'keulm', # 0x76 +'keulb', # 0x77 +'keuls', # 0x78 +'keult', # 0x79 +'keulp', # 0x7a +'keulh', # 0x7b +'keum', # 0x7c +'keub', # 0x7d +'keubs', # 0x7e +'keus', # 0x7f +'keuss', # 0x80 +'keung', # 0x81 +'keuj', # 0x82 +'keuc', # 0x83 +'keuk', # 0x84 +'keut', # 0x85 +'keup', # 0x86 +'keuh', # 0x87 +'kyi', # 0x88 +'kyig', # 0x89 +'kyigg', # 0x8a +'kyigs', # 0x8b +'kyin', # 0x8c +'kyinj', # 0x8d +'kyinh', # 0x8e +'kyid', # 0x8f +'kyil', # 0x90 +'kyilg', # 0x91 +'kyilm', # 0x92 +'kyilb', # 0x93 +'kyils', # 0x94 +'kyilt', # 0x95 +'kyilp', # 0x96 +'kyilh', # 0x97 +'kyim', # 0x98 +'kyib', # 0x99 +'kyibs', # 0x9a +'kyis', # 0x9b +'kyiss', # 0x9c +'kying', # 0x9d +'kyij', # 0x9e +'kyic', # 0x9f +'kyik', # 0xa0 +'kyit', # 0xa1 +'kyip', # 0xa2 +'kyih', # 0xa3 +'ki', # 0xa4 +'kig', # 0xa5 +'kigg', # 0xa6 +'kigs', # 0xa7 +'kin', # 0xa8 +'kinj', # 0xa9 +'kinh', # 0xaa +'kid', # 0xab +'kil', # 0xac +'kilg', # 0xad +'kilm', # 0xae +'kilb', # 0xaf +'kils', # 0xb0 +'kilt', # 0xb1 +'kilp', # 0xb2 +'kilh', # 0xb3 +'kim', # 0xb4 +'kib', # 0xb5 +'kibs', # 0xb6 +'kis', # 0xb7 +'kiss', # 0xb8 +'king', # 0xb9 +'kij', # 0xba +'kic', # 0xbb +'kik', # 0xbc +'kit', # 0xbd +'kip', # 0xbe +'kih', # 0xbf +'ta', # 0xc0 +'tag', # 0xc1 +'tagg', # 0xc2 +'tags', # 0xc3 +'tan', # 0xc4 +'tanj', # 0xc5 +'tanh', # 0xc6 +'tad', # 0xc7 +'tal', # 0xc8 +'talg', # 0xc9 +'talm', # 0xca +'talb', # 0xcb +'tals', # 0xcc +'talt', # 0xcd +'talp', # 0xce +'talh', # 0xcf +'tam', # 0xd0 +'tab', # 0xd1 +'tabs', # 0xd2 +'tas', # 0xd3 +'tass', # 0xd4 +'tang', # 0xd5 +'taj', # 0xd6 +'tac', # 0xd7 +'tak', # 0xd8 +'tat', # 0xd9 +'tap', # 0xda +'tah', # 0xdb +'tae', # 0xdc +'taeg', # 0xdd +'taegg', # 0xde +'taegs', # 0xdf +'taen', # 0xe0 +'taenj', # 0xe1 +'taenh', # 0xe2 +'taed', # 0xe3 +'tael', # 0xe4 +'taelg', # 0xe5 +'taelm', # 0xe6 +'taelb', # 0xe7 +'taels', # 0xe8 +'taelt', # 0xe9 +'taelp', # 0xea +'taelh', # 0xeb +'taem', # 0xec +'taeb', # 0xed +'taebs', # 0xee +'taes', # 0xef +'taess', # 0xf0 +'taeng', # 0xf1 +'taej', # 0xf2 +'taec', # 0xf3 +'taek', # 0xf4 +'taet', # 0xf5 +'taep', # 0xf6 +'taeh', # 0xf7 +'tya', # 0xf8 +'tyag', # 0xf9 +'tyagg', # 0xfa +'tyags', # 0xfb +'tyan', # 0xfc +'tyanj', # 0xfd +'tyanh', # 0xfe +'tyad', # 0xff +) diff --git a/libs/unidecode/x0d1.py b/libs/unidecode/x0d1.py new file mode 100644 index 00000000..c2bbd16d --- /dev/null +++ b/libs/unidecode/x0d1.py @@ -0,0 +1,258 @@ +data = ( +'tyal', # 0x00 +'tyalg', # 0x01 +'tyalm', # 0x02 +'tyalb', # 0x03 +'tyals', # 0x04 +'tyalt', # 0x05 +'tyalp', # 0x06 +'tyalh', # 0x07 +'tyam', # 0x08 +'tyab', # 0x09 +'tyabs', # 0x0a +'tyas', # 0x0b +'tyass', # 0x0c +'tyang', # 0x0d +'tyaj', # 0x0e +'tyac', # 0x0f +'tyak', # 0x10 +'tyat', # 0x11 +'tyap', # 0x12 +'tyah', # 0x13 +'tyae', # 0x14 +'tyaeg', # 0x15 +'tyaegg', # 0x16 +'tyaegs', # 0x17 +'tyaen', # 0x18 +'tyaenj', # 0x19 +'tyaenh', # 0x1a +'tyaed', # 0x1b +'tyael', # 0x1c +'tyaelg', # 0x1d +'tyaelm', # 0x1e +'tyaelb', # 0x1f +'tyaels', # 0x20 +'tyaelt', # 0x21 +'tyaelp', # 0x22 +'tyaelh', # 0x23 +'tyaem', # 0x24 +'tyaeb', # 0x25 +'tyaebs', # 0x26 +'tyaes', # 0x27 +'tyaess', # 0x28 +'tyaeng', # 0x29 +'tyaej', # 0x2a +'tyaec', # 0x2b +'tyaek', # 0x2c +'tyaet', # 0x2d +'tyaep', # 0x2e +'tyaeh', # 0x2f +'teo', # 0x30 +'teog', # 0x31 +'teogg', # 0x32 +'teogs', # 0x33 +'teon', # 0x34 +'teonj', # 0x35 +'teonh', # 0x36 +'teod', # 0x37 +'teol', # 0x38 +'teolg', # 0x39 +'teolm', # 0x3a +'teolb', # 0x3b +'teols', # 0x3c +'teolt', # 0x3d +'teolp', # 0x3e +'teolh', # 0x3f +'teom', # 0x40 +'teob', # 0x41 +'teobs', # 0x42 +'teos', # 0x43 +'teoss', # 0x44 +'teong', # 0x45 +'teoj', # 0x46 +'teoc', # 0x47 +'teok', # 0x48 +'teot', # 0x49 +'teop', # 0x4a +'teoh', # 0x4b +'te', # 0x4c +'teg', # 0x4d +'tegg', # 0x4e +'tegs', # 0x4f +'ten', # 0x50 +'tenj', # 0x51 +'tenh', # 0x52 +'ted', # 0x53 +'tel', # 0x54 +'telg', # 0x55 +'telm', # 0x56 +'telb', # 0x57 +'tels', # 0x58 +'telt', # 0x59 +'telp', # 0x5a +'telh', # 0x5b +'tem', # 0x5c +'teb', # 0x5d +'tebs', # 0x5e +'tes', # 0x5f +'tess', # 0x60 +'teng', # 0x61 +'tej', # 0x62 +'tec', # 0x63 +'tek', # 0x64 +'tet', # 0x65 +'tep', # 0x66 +'teh', # 0x67 +'tyeo', # 0x68 +'tyeog', # 0x69 +'tyeogg', # 0x6a +'tyeogs', # 0x6b +'tyeon', # 0x6c +'tyeonj', # 0x6d +'tyeonh', # 0x6e +'tyeod', # 0x6f +'tyeol', # 0x70 +'tyeolg', # 0x71 +'tyeolm', # 0x72 +'tyeolb', # 0x73 +'tyeols', # 0x74 +'tyeolt', # 0x75 +'tyeolp', # 0x76 +'tyeolh', # 0x77 +'tyeom', # 0x78 +'tyeob', # 0x79 +'tyeobs', # 0x7a +'tyeos', # 0x7b +'tyeoss', # 0x7c +'tyeong', # 0x7d +'tyeoj', # 0x7e +'tyeoc', # 0x7f +'tyeok', # 0x80 +'tyeot', # 0x81 +'tyeop', # 0x82 +'tyeoh', # 0x83 +'tye', # 0x84 +'tyeg', # 0x85 +'tyegg', # 0x86 +'tyegs', # 0x87 +'tyen', # 0x88 +'tyenj', # 0x89 +'tyenh', # 0x8a +'tyed', # 0x8b +'tyel', # 0x8c +'tyelg', # 0x8d +'tyelm', # 0x8e +'tyelb', # 0x8f +'tyels', # 0x90 +'tyelt', # 0x91 +'tyelp', # 0x92 +'tyelh', # 0x93 +'tyem', # 0x94 +'tyeb', # 0x95 +'tyebs', # 0x96 +'tyes', # 0x97 +'tyess', # 0x98 +'tyeng', # 0x99 +'tyej', # 0x9a +'tyec', # 0x9b +'tyek', # 0x9c +'tyet', # 0x9d +'tyep', # 0x9e +'tyeh', # 0x9f +'to', # 0xa0 +'tog', # 0xa1 +'togg', # 0xa2 +'togs', # 0xa3 +'ton', # 0xa4 +'tonj', # 0xa5 +'tonh', # 0xa6 +'tod', # 0xa7 +'tol', # 0xa8 +'tolg', # 0xa9 +'tolm', # 0xaa +'tolb', # 0xab +'tols', # 0xac +'tolt', # 0xad +'tolp', # 0xae +'tolh', # 0xaf +'tom', # 0xb0 +'tob', # 0xb1 +'tobs', # 0xb2 +'tos', # 0xb3 +'toss', # 0xb4 +'tong', # 0xb5 +'toj', # 0xb6 +'toc', # 0xb7 +'tok', # 0xb8 +'tot', # 0xb9 +'top', # 0xba +'toh', # 0xbb +'twa', # 0xbc +'twag', # 0xbd +'twagg', # 0xbe +'twags', # 0xbf +'twan', # 0xc0 +'twanj', # 0xc1 +'twanh', # 0xc2 +'twad', # 0xc3 +'twal', # 0xc4 +'twalg', # 0xc5 +'twalm', # 0xc6 +'twalb', # 0xc7 +'twals', # 0xc8 +'twalt', # 0xc9 +'twalp', # 0xca +'twalh', # 0xcb +'twam', # 0xcc +'twab', # 0xcd +'twabs', # 0xce +'twas', # 0xcf +'twass', # 0xd0 +'twang', # 0xd1 +'twaj', # 0xd2 +'twac', # 0xd3 +'twak', # 0xd4 +'twat', # 0xd5 +'twap', # 0xd6 +'twah', # 0xd7 +'twae', # 0xd8 +'twaeg', # 0xd9 +'twaegg', # 0xda +'twaegs', # 0xdb +'twaen', # 0xdc +'twaenj', # 0xdd +'twaenh', # 0xde +'twaed', # 0xdf +'twael', # 0xe0 +'twaelg', # 0xe1 +'twaelm', # 0xe2 +'twaelb', # 0xe3 +'twaels', # 0xe4 +'twaelt', # 0xe5 +'twaelp', # 0xe6 +'twaelh', # 0xe7 +'twaem', # 0xe8 +'twaeb', # 0xe9 +'twaebs', # 0xea +'twaes', # 0xeb +'twaess', # 0xec +'twaeng', # 0xed +'twaej', # 0xee +'twaec', # 0xef +'twaek', # 0xf0 +'twaet', # 0xf1 +'twaep', # 0xf2 +'twaeh', # 0xf3 +'toe', # 0xf4 +'toeg', # 0xf5 +'toegg', # 0xf6 +'toegs', # 0xf7 +'toen', # 0xf8 +'toenj', # 0xf9 +'toenh', # 0xfa +'toed', # 0xfb +'toel', # 0xfc +'toelg', # 0xfd +'toelm', # 0xfe +'toelb', # 0xff +) diff --git a/libs/unidecode/x0d2.py b/libs/unidecode/x0d2.py new file mode 100644 index 00000000..052d462a --- /dev/null +++ b/libs/unidecode/x0d2.py @@ -0,0 +1,258 @@ +data = ( +'toels', # 0x00 +'toelt', # 0x01 +'toelp', # 0x02 +'toelh', # 0x03 +'toem', # 0x04 +'toeb', # 0x05 +'toebs', # 0x06 +'toes', # 0x07 +'toess', # 0x08 +'toeng', # 0x09 +'toej', # 0x0a +'toec', # 0x0b +'toek', # 0x0c +'toet', # 0x0d +'toep', # 0x0e +'toeh', # 0x0f +'tyo', # 0x10 +'tyog', # 0x11 +'tyogg', # 0x12 +'tyogs', # 0x13 +'tyon', # 0x14 +'tyonj', # 0x15 +'tyonh', # 0x16 +'tyod', # 0x17 +'tyol', # 0x18 +'tyolg', # 0x19 +'tyolm', # 0x1a +'tyolb', # 0x1b +'tyols', # 0x1c +'tyolt', # 0x1d +'tyolp', # 0x1e +'tyolh', # 0x1f +'tyom', # 0x20 +'tyob', # 0x21 +'tyobs', # 0x22 +'tyos', # 0x23 +'tyoss', # 0x24 +'tyong', # 0x25 +'tyoj', # 0x26 +'tyoc', # 0x27 +'tyok', # 0x28 +'tyot', # 0x29 +'tyop', # 0x2a +'tyoh', # 0x2b +'tu', # 0x2c +'tug', # 0x2d +'tugg', # 0x2e +'tugs', # 0x2f +'tun', # 0x30 +'tunj', # 0x31 +'tunh', # 0x32 +'tud', # 0x33 +'tul', # 0x34 +'tulg', # 0x35 +'tulm', # 0x36 +'tulb', # 0x37 +'tuls', # 0x38 +'tult', # 0x39 +'tulp', # 0x3a +'tulh', # 0x3b +'tum', # 0x3c +'tub', # 0x3d +'tubs', # 0x3e +'tus', # 0x3f +'tuss', # 0x40 +'tung', # 0x41 +'tuj', # 0x42 +'tuc', # 0x43 +'tuk', # 0x44 +'tut', # 0x45 +'tup', # 0x46 +'tuh', # 0x47 +'tweo', # 0x48 +'tweog', # 0x49 +'tweogg', # 0x4a +'tweogs', # 0x4b +'tweon', # 0x4c +'tweonj', # 0x4d +'tweonh', # 0x4e +'tweod', # 0x4f +'tweol', # 0x50 +'tweolg', # 0x51 +'tweolm', # 0x52 +'tweolb', # 0x53 +'tweols', # 0x54 +'tweolt', # 0x55 +'tweolp', # 0x56 +'tweolh', # 0x57 +'tweom', # 0x58 +'tweob', # 0x59 +'tweobs', # 0x5a +'tweos', # 0x5b +'tweoss', # 0x5c +'tweong', # 0x5d +'tweoj', # 0x5e +'tweoc', # 0x5f +'tweok', # 0x60 +'tweot', # 0x61 +'tweop', # 0x62 +'tweoh', # 0x63 +'twe', # 0x64 +'tweg', # 0x65 +'twegg', # 0x66 +'twegs', # 0x67 +'twen', # 0x68 +'twenj', # 0x69 +'twenh', # 0x6a +'twed', # 0x6b +'twel', # 0x6c +'twelg', # 0x6d +'twelm', # 0x6e +'twelb', # 0x6f +'twels', # 0x70 +'twelt', # 0x71 +'twelp', # 0x72 +'twelh', # 0x73 +'twem', # 0x74 +'tweb', # 0x75 +'twebs', # 0x76 +'twes', # 0x77 +'twess', # 0x78 +'tweng', # 0x79 +'twej', # 0x7a +'twec', # 0x7b +'twek', # 0x7c +'twet', # 0x7d +'twep', # 0x7e +'tweh', # 0x7f +'twi', # 0x80 +'twig', # 0x81 +'twigg', # 0x82 +'twigs', # 0x83 +'twin', # 0x84 +'twinj', # 0x85 +'twinh', # 0x86 +'twid', # 0x87 +'twil', # 0x88 +'twilg', # 0x89 +'twilm', # 0x8a +'twilb', # 0x8b +'twils', # 0x8c +'twilt', # 0x8d +'twilp', # 0x8e +'twilh', # 0x8f +'twim', # 0x90 +'twib', # 0x91 +'twibs', # 0x92 +'twis', # 0x93 +'twiss', # 0x94 +'twing', # 0x95 +'twij', # 0x96 +'twic', # 0x97 +'twik', # 0x98 +'twit', # 0x99 +'twip', # 0x9a +'twih', # 0x9b +'tyu', # 0x9c +'tyug', # 0x9d +'tyugg', # 0x9e +'tyugs', # 0x9f +'tyun', # 0xa0 +'tyunj', # 0xa1 +'tyunh', # 0xa2 +'tyud', # 0xa3 +'tyul', # 0xa4 +'tyulg', # 0xa5 +'tyulm', # 0xa6 +'tyulb', # 0xa7 +'tyuls', # 0xa8 +'tyult', # 0xa9 +'tyulp', # 0xaa +'tyulh', # 0xab +'tyum', # 0xac +'tyub', # 0xad +'tyubs', # 0xae +'tyus', # 0xaf +'tyuss', # 0xb0 +'tyung', # 0xb1 +'tyuj', # 0xb2 +'tyuc', # 0xb3 +'tyuk', # 0xb4 +'tyut', # 0xb5 +'tyup', # 0xb6 +'tyuh', # 0xb7 +'teu', # 0xb8 +'teug', # 0xb9 +'teugg', # 0xba +'teugs', # 0xbb +'teun', # 0xbc +'teunj', # 0xbd +'teunh', # 0xbe +'teud', # 0xbf +'teul', # 0xc0 +'teulg', # 0xc1 +'teulm', # 0xc2 +'teulb', # 0xc3 +'teuls', # 0xc4 +'teult', # 0xc5 +'teulp', # 0xc6 +'teulh', # 0xc7 +'teum', # 0xc8 +'teub', # 0xc9 +'teubs', # 0xca +'teus', # 0xcb +'teuss', # 0xcc +'teung', # 0xcd +'teuj', # 0xce +'teuc', # 0xcf +'teuk', # 0xd0 +'teut', # 0xd1 +'teup', # 0xd2 +'teuh', # 0xd3 +'tyi', # 0xd4 +'tyig', # 0xd5 +'tyigg', # 0xd6 +'tyigs', # 0xd7 +'tyin', # 0xd8 +'tyinj', # 0xd9 +'tyinh', # 0xda +'tyid', # 0xdb +'tyil', # 0xdc +'tyilg', # 0xdd +'tyilm', # 0xde +'tyilb', # 0xdf +'tyils', # 0xe0 +'tyilt', # 0xe1 +'tyilp', # 0xe2 +'tyilh', # 0xe3 +'tyim', # 0xe4 +'tyib', # 0xe5 +'tyibs', # 0xe6 +'tyis', # 0xe7 +'tyiss', # 0xe8 +'tying', # 0xe9 +'tyij', # 0xea +'tyic', # 0xeb +'tyik', # 0xec +'tyit', # 0xed +'tyip', # 0xee +'tyih', # 0xef +'ti', # 0xf0 +'tig', # 0xf1 +'tigg', # 0xf2 +'tigs', # 0xf3 +'tin', # 0xf4 +'tinj', # 0xf5 +'tinh', # 0xf6 +'tid', # 0xf7 +'til', # 0xf8 +'tilg', # 0xf9 +'tilm', # 0xfa +'tilb', # 0xfb +'tils', # 0xfc +'tilt', # 0xfd +'tilp', # 0xfe +'tilh', # 0xff +) diff --git a/libs/unidecode/x0d3.py b/libs/unidecode/x0d3.py new file mode 100644 index 00000000..70a4701e --- /dev/null +++ b/libs/unidecode/x0d3.py @@ -0,0 +1,258 @@ +data = ( +'tim', # 0x00 +'tib', # 0x01 +'tibs', # 0x02 +'tis', # 0x03 +'tiss', # 0x04 +'ting', # 0x05 +'tij', # 0x06 +'tic', # 0x07 +'tik', # 0x08 +'tit', # 0x09 +'tip', # 0x0a +'tih', # 0x0b +'pa', # 0x0c +'pag', # 0x0d +'pagg', # 0x0e +'pags', # 0x0f +'pan', # 0x10 +'panj', # 0x11 +'panh', # 0x12 +'pad', # 0x13 +'pal', # 0x14 +'palg', # 0x15 +'palm', # 0x16 +'palb', # 0x17 +'pals', # 0x18 +'palt', # 0x19 +'palp', # 0x1a +'palh', # 0x1b +'pam', # 0x1c +'pab', # 0x1d +'pabs', # 0x1e +'pas', # 0x1f +'pass', # 0x20 +'pang', # 0x21 +'paj', # 0x22 +'pac', # 0x23 +'pak', # 0x24 +'pat', # 0x25 +'pap', # 0x26 +'pah', # 0x27 +'pae', # 0x28 +'paeg', # 0x29 +'paegg', # 0x2a +'paegs', # 0x2b +'paen', # 0x2c +'paenj', # 0x2d +'paenh', # 0x2e +'paed', # 0x2f +'pael', # 0x30 +'paelg', # 0x31 +'paelm', # 0x32 +'paelb', # 0x33 +'paels', # 0x34 +'paelt', # 0x35 +'paelp', # 0x36 +'paelh', # 0x37 +'paem', # 0x38 +'paeb', # 0x39 +'paebs', # 0x3a +'paes', # 0x3b +'paess', # 0x3c +'paeng', # 0x3d +'paej', # 0x3e +'paec', # 0x3f +'paek', # 0x40 +'paet', # 0x41 +'paep', # 0x42 +'paeh', # 0x43 +'pya', # 0x44 +'pyag', # 0x45 +'pyagg', # 0x46 +'pyags', # 0x47 +'pyan', # 0x48 +'pyanj', # 0x49 +'pyanh', # 0x4a +'pyad', # 0x4b +'pyal', # 0x4c +'pyalg', # 0x4d +'pyalm', # 0x4e +'pyalb', # 0x4f +'pyals', # 0x50 +'pyalt', # 0x51 +'pyalp', # 0x52 +'pyalh', # 0x53 +'pyam', # 0x54 +'pyab', # 0x55 +'pyabs', # 0x56 +'pyas', # 0x57 +'pyass', # 0x58 +'pyang', # 0x59 +'pyaj', # 0x5a +'pyac', # 0x5b +'pyak', # 0x5c +'pyat', # 0x5d +'pyap', # 0x5e +'pyah', # 0x5f +'pyae', # 0x60 +'pyaeg', # 0x61 +'pyaegg', # 0x62 +'pyaegs', # 0x63 +'pyaen', # 0x64 +'pyaenj', # 0x65 +'pyaenh', # 0x66 +'pyaed', # 0x67 +'pyael', # 0x68 +'pyaelg', # 0x69 +'pyaelm', # 0x6a +'pyaelb', # 0x6b +'pyaels', # 0x6c +'pyaelt', # 0x6d +'pyaelp', # 0x6e +'pyaelh', # 0x6f +'pyaem', # 0x70 +'pyaeb', # 0x71 +'pyaebs', # 0x72 +'pyaes', # 0x73 +'pyaess', # 0x74 +'pyaeng', # 0x75 +'pyaej', # 0x76 +'pyaec', # 0x77 +'pyaek', # 0x78 +'pyaet', # 0x79 +'pyaep', # 0x7a +'pyaeh', # 0x7b +'peo', # 0x7c +'peog', # 0x7d +'peogg', # 0x7e +'peogs', # 0x7f +'peon', # 0x80 +'peonj', # 0x81 +'peonh', # 0x82 +'peod', # 0x83 +'peol', # 0x84 +'peolg', # 0x85 +'peolm', # 0x86 +'peolb', # 0x87 +'peols', # 0x88 +'peolt', # 0x89 +'peolp', # 0x8a +'peolh', # 0x8b +'peom', # 0x8c +'peob', # 0x8d +'peobs', # 0x8e +'peos', # 0x8f +'peoss', # 0x90 +'peong', # 0x91 +'peoj', # 0x92 +'peoc', # 0x93 +'peok', # 0x94 +'peot', # 0x95 +'peop', # 0x96 +'peoh', # 0x97 +'pe', # 0x98 +'peg', # 0x99 +'pegg', # 0x9a +'pegs', # 0x9b +'pen', # 0x9c +'penj', # 0x9d +'penh', # 0x9e +'ped', # 0x9f +'pel', # 0xa0 +'pelg', # 0xa1 +'pelm', # 0xa2 +'pelb', # 0xa3 +'pels', # 0xa4 +'pelt', # 0xa5 +'pelp', # 0xa6 +'pelh', # 0xa7 +'pem', # 0xa8 +'peb', # 0xa9 +'pebs', # 0xaa +'pes', # 0xab +'pess', # 0xac +'peng', # 0xad +'pej', # 0xae +'pec', # 0xaf +'pek', # 0xb0 +'pet', # 0xb1 +'pep', # 0xb2 +'peh', # 0xb3 +'pyeo', # 0xb4 +'pyeog', # 0xb5 +'pyeogg', # 0xb6 +'pyeogs', # 0xb7 +'pyeon', # 0xb8 +'pyeonj', # 0xb9 +'pyeonh', # 0xba +'pyeod', # 0xbb +'pyeol', # 0xbc +'pyeolg', # 0xbd +'pyeolm', # 0xbe +'pyeolb', # 0xbf +'pyeols', # 0xc0 +'pyeolt', # 0xc1 +'pyeolp', # 0xc2 +'pyeolh', # 0xc3 +'pyeom', # 0xc4 +'pyeob', # 0xc5 +'pyeobs', # 0xc6 +'pyeos', # 0xc7 +'pyeoss', # 0xc8 +'pyeong', # 0xc9 +'pyeoj', # 0xca +'pyeoc', # 0xcb +'pyeok', # 0xcc +'pyeot', # 0xcd +'pyeop', # 0xce +'pyeoh', # 0xcf +'pye', # 0xd0 +'pyeg', # 0xd1 +'pyegg', # 0xd2 +'pyegs', # 0xd3 +'pyen', # 0xd4 +'pyenj', # 0xd5 +'pyenh', # 0xd6 +'pyed', # 0xd7 +'pyel', # 0xd8 +'pyelg', # 0xd9 +'pyelm', # 0xda +'pyelb', # 0xdb +'pyels', # 0xdc +'pyelt', # 0xdd +'pyelp', # 0xde +'pyelh', # 0xdf +'pyem', # 0xe0 +'pyeb', # 0xe1 +'pyebs', # 0xe2 +'pyes', # 0xe3 +'pyess', # 0xe4 +'pyeng', # 0xe5 +'pyej', # 0xe6 +'pyec', # 0xe7 +'pyek', # 0xe8 +'pyet', # 0xe9 +'pyep', # 0xea +'pyeh', # 0xeb +'po', # 0xec +'pog', # 0xed +'pogg', # 0xee +'pogs', # 0xef +'pon', # 0xf0 +'ponj', # 0xf1 +'ponh', # 0xf2 +'pod', # 0xf3 +'pol', # 0xf4 +'polg', # 0xf5 +'polm', # 0xf6 +'polb', # 0xf7 +'pols', # 0xf8 +'polt', # 0xf9 +'polp', # 0xfa +'polh', # 0xfb +'pom', # 0xfc +'pob', # 0xfd +'pobs', # 0xfe +'pos', # 0xff +) diff --git a/libs/unidecode/x0d4.py b/libs/unidecode/x0d4.py new file mode 100644 index 00000000..87caad48 --- /dev/null +++ b/libs/unidecode/x0d4.py @@ -0,0 +1,258 @@ +data = ( +'poss', # 0x00 +'pong', # 0x01 +'poj', # 0x02 +'poc', # 0x03 +'pok', # 0x04 +'pot', # 0x05 +'pop', # 0x06 +'poh', # 0x07 +'pwa', # 0x08 +'pwag', # 0x09 +'pwagg', # 0x0a +'pwags', # 0x0b +'pwan', # 0x0c +'pwanj', # 0x0d +'pwanh', # 0x0e +'pwad', # 0x0f +'pwal', # 0x10 +'pwalg', # 0x11 +'pwalm', # 0x12 +'pwalb', # 0x13 +'pwals', # 0x14 +'pwalt', # 0x15 +'pwalp', # 0x16 +'pwalh', # 0x17 +'pwam', # 0x18 +'pwab', # 0x19 +'pwabs', # 0x1a +'pwas', # 0x1b +'pwass', # 0x1c +'pwang', # 0x1d +'pwaj', # 0x1e +'pwac', # 0x1f +'pwak', # 0x20 +'pwat', # 0x21 +'pwap', # 0x22 +'pwah', # 0x23 +'pwae', # 0x24 +'pwaeg', # 0x25 +'pwaegg', # 0x26 +'pwaegs', # 0x27 +'pwaen', # 0x28 +'pwaenj', # 0x29 +'pwaenh', # 0x2a +'pwaed', # 0x2b +'pwael', # 0x2c +'pwaelg', # 0x2d +'pwaelm', # 0x2e +'pwaelb', # 0x2f +'pwaels', # 0x30 +'pwaelt', # 0x31 +'pwaelp', # 0x32 +'pwaelh', # 0x33 +'pwaem', # 0x34 +'pwaeb', # 0x35 +'pwaebs', # 0x36 +'pwaes', # 0x37 +'pwaess', # 0x38 +'pwaeng', # 0x39 +'pwaej', # 0x3a +'pwaec', # 0x3b +'pwaek', # 0x3c +'pwaet', # 0x3d +'pwaep', # 0x3e +'pwaeh', # 0x3f +'poe', # 0x40 +'poeg', # 0x41 +'poegg', # 0x42 +'poegs', # 0x43 +'poen', # 0x44 +'poenj', # 0x45 +'poenh', # 0x46 +'poed', # 0x47 +'poel', # 0x48 +'poelg', # 0x49 +'poelm', # 0x4a +'poelb', # 0x4b +'poels', # 0x4c +'poelt', # 0x4d +'poelp', # 0x4e +'poelh', # 0x4f +'poem', # 0x50 +'poeb', # 0x51 +'poebs', # 0x52 +'poes', # 0x53 +'poess', # 0x54 +'poeng', # 0x55 +'poej', # 0x56 +'poec', # 0x57 +'poek', # 0x58 +'poet', # 0x59 +'poep', # 0x5a +'poeh', # 0x5b +'pyo', # 0x5c +'pyog', # 0x5d +'pyogg', # 0x5e +'pyogs', # 0x5f +'pyon', # 0x60 +'pyonj', # 0x61 +'pyonh', # 0x62 +'pyod', # 0x63 +'pyol', # 0x64 +'pyolg', # 0x65 +'pyolm', # 0x66 +'pyolb', # 0x67 +'pyols', # 0x68 +'pyolt', # 0x69 +'pyolp', # 0x6a +'pyolh', # 0x6b +'pyom', # 0x6c +'pyob', # 0x6d +'pyobs', # 0x6e +'pyos', # 0x6f +'pyoss', # 0x70 +'pyong', # 0x71 +'pyoj', # 0x72 +'pyoc', # 0x73 +'pyok', # 0x74 +'pyot', # 0x75 +'pyop', # 0x76 +'pyoh', # 0x77 +'pu', # 0x78 +'pug', # 0x79 +'pugg', # 0x7a +'pugs', # 0x7b +'pun', # 0x7c +'punj', # 0x7d +'punh', # 0x7e +'pud', # 0x7f +'pul', # 0x80 +'pulg', # 0x81 +'pulm', # 0x82 +'pulb', # 0x83 +'puls', # 0x84 +'pult', # 0x85 +'pulp', # 0x86 +'pulh', # 0x87 +'pum', # 0x88 +'pub', # 0x89 +'pubs', # 0x8a +'pus', # 0x8b +'puss', # 0x8c +'pung', # 0x8d +'puj', # 0x8e +'puc', # 0x8f +'puk', # 0x90 +'put', # 0x91 +'pup', # 0x92 +'puh', # 0x93 +'pweo', # 0x94 +'pweog', # 0x95 +'pweogg', # 0x96 +'pweogs', # 0x97 +'pweon', # 0x98 +'pweonj', # 0x99 +'pweonh', # 0x9a +'pweod', # 0x9b +'pweol', # 0x9c +'pweolg', # 0x9d +'pweolm', # 0x9e +'pweolb', # 0x9f +'pweols', # 0xa0 +'pweolt', # 0xa1 +'pweolp', # 0xa2 +'pweolh', # 0xa3 +'pweom', # 0xa4 +'pweob', # 0xa5 +'pweobs', # 0xa6 +'pweos', # 0xa7 +'pweoss', # 0xa8 +'pweong', # 0xa9 +'pweoj', # 0xaa +'pweoc', # 0xab +'pweok', # 0xac +'pweot', # 0xad +'pweop', # 0xae +'pweoh', # 0xaf +'pwe', # 0xb0 +'pweg', # 0xb1 +'pwegg', # 0xb2 +'pwegs', # 0xb3 +'pwen', # 0xb4 +'pwenj', # 0xb5 +'pwenh', # 0xb6 +'pwed', # 0xb7 +'pwel', # 0xb8 +'pwelg', # 0xb9 +'pwelm', # 0xba +'pwelb', # 0xbb +'pwels', # 0xbc +'pwelt', # 0xbd +'pwelp', # 0xbe +'pwelh', # 0xbf +'pwem', # 0xc0 +'pweb', # 0xc1 +'pwebs', # 0xc2 +'pwes', # 0xc3 +'pwess', # 0xc4 +'pweng', # 0xc5 +'pwej', # 0xc6 +'pwec', # 0xc7 +'pwek', # 0xc8 +'pwet', # 0xc9 +'pwep', # 0xca +'pweh', # 0xcb +'pwi', # 0xcc +'pwig', # 0xcd +'pwigg', # 0xce +'pwigs', # 0xcf +'pwin', # 0xd0 +'pwinj', # 0xd1 +'pwinh', # 0xd2 +'pwid', # 0xd3 +'pwil', # 0xd4 +'pwilg', # 0xd5 +'pwilm', # 0xd6 +'pwilb', # 0xd7 +'pwils', # 0xd8 +'pwilt', # 0xd9 +'pwilp', # 0xda +'pwilh', # 0xdb +'pwim', # 0xdc +'pwib', # 0xdd +'pwibs', # 0xde +'pwis', # 0xdf +'pwiss', # 0xe0 +'pwing', # 0xe1 +'pwij', # 0xe2 +'pwic', # 0xe3 +'pwik', # 0xe4 +'pwit', # 0xe5 +'pwip', # 0xe6 +'pwih', # 0xe7 +'pyu', # 0xe8 +'pyug', # 0xe9 +'pyugg', # 0xea +'pyugs', # 0xeb +'pyun', # 0xec +'pyunj', # 0xed +'pyunh', # 0xee +'pyud', # 0xef +'pyul', # 0xf0 +'pyulg', # 0xf1 +'pyulm', # 0xf2 +'pyulb', # 0xf3 +'pyuls', # 0xf4 +'pyult', # 0xf5 +'pyulp', # 0xf6 +'pyulh', # 0xf7 +'pyum', # 0xf8 +'pyub', # 0xf9 +'pyubs', # 0xfa +'pyus', # 0xfb +'pyuss', # 0xfc +'pyung', # 0xfd +'pyuj', # 0xfe +'pyuc', # 0xff +) diff --git a/libs/unidecode/x0d5.py b/libs/unidecode/x0d5.py new file mode 100644 index 00000000..4dc55f8e --- /dev/null +++ b/libs/unidecode/x0d5.py @@ -0,0 +1,258 @@ +data = ( +'pyuk', # 0x00 +'pyut', # 0x01 +'pyup', # 0x02 +'pyuh', # 0x03 +'peu', # 0x04 +'peug', # 0x05 +'peugg', # 0x06 +'peugs', # 0x07 +'peun', # 0x08 +'peunj', # 0x09 +'peunh', # 0x0a +'peud', # 0x0b +'peul', # 0x0c +'peulg', # 0x0d +'peulm', # 0x0e +'peulb', # 0x0f +'peuls', # 0x10 +'peult', # 0x11 +'peulp', # 0x12 +'peulh', # 0x13 +'peum', # 0x14 +'peub', # 0x15 +'peubs', # 0x16 +'peus', # 0x17 +'peuss', # 0x18 +'peung', # 0x19 +'peuj', # 0x1a +'peuc', # 0x1b +'peuk', # 0x1c +'peut', # 0x1d +'peup', # 0x1e +'peuh', # 0x1f +'pyi', # 0x20 +'pyig', # 0x21 +'pyigg', # 0x22 +'pyigs', # 0x23 +'pyin', # 0x24 +'pyinj', # 0x25 +'pyinh', # 0x26 +'pyid', # 0x27 +'pyil', # 0x28 +'pyilg', # 0x29 +'pyilm', # 0x2a +'pyilb', # 0x2b +'pyils', # 0x2c +'pyilt', # 0x2d +'pyilp', # 0x2e +'pyilh', # 0x2f +'pyim', # 0x30 +'pyib', # 0x31 +'pyibs', # 0x32 +'pyis', # 0x33 +'pyiss', # 0x34 +'pying', # 0x35 +'pyij', # 0x36 +'pyic', # 0x37 +'pyik', # 0x38 +'pyit', # 0x39 +'pyip', # 0x3a +'pyih', # 0x3b +'pi', # 0x3c +'pig', # 0x3d +'pigg', # 0x3e +'pigs', # 0x3f +'pin', # 0x40 +'pinj', # 0x41 +'pinh', # 0x42 +'pid', # 0x43 +'pil', # 0x44 +'pilg', # 0x45 +'pilm', # 0x46 +'pilb', # 0x47 +'pils', # 0x48 +'pilt', # 0x49 +'pilp', # 0x4a +'pilh', # 0x4b +'pim', # 0x4c +'pib', # 0x4d +'pibs', # 0x4e +'pis', # 0x4f +'piss', # 0x50 +'ping', # 0x51 +'pij', # 0x52 +'pic', # 0x53 +'pik', # 0x54 +'pit', # 0x55 +'pip', # 0x56 +'pih', # 0x57 +'ha', # 0x58 +'hag', # 0x59 +'hagg', # 0x5a +'hags', # 0x5b +'han', # 0x5c +'hanj', # 0x5d +'hanh', # 0x5e +'had', # 0x5f +'hal', # 0x60 +'halg', # 0x61 +'halm', # 0x62 +'halb', # 0x63 +'hals', # 0x64 +'halt', # 0x65 +'halp', # 0x66 +'halh', # 0x67 +'ham', # 0x68 +'hab', # 0x69 +'habs', # 0x6a +'has', # 0x6b +'hass', # 0x6c +'hang', # 0x6d +'haj', # 0x6e +'hac', # 0x6f +'hak', # 0x70 +'hat', # 0x71 +'hap', # 0x72 +'hah', # 0x73 +'hae', # 0x74 +'haeg', # 0x75 +'haegg', # 0x76 +'haegs', # 0x77 +'haen', # 0x78 +'haenj', # 0x79 +'haenh', # 0x7a +'haed', # 0x7b +'hael', # 0x7c +'haelg', # 0x7d +'haelm', # 0x7e +'haelb', # 0x7f +'haels', # 0x80 +'haelt', # 0x81 +'haelp', # 0x82 +'haelh', # 0x83 +'haem', # 0x84 +'haeb', # 0x85 +'haebs', # 0x86 +'haes', # 0x87 +'haess', # 0x88 +'haeng', # 0x89 +'haej', # 0x8a +'haec', # 0x8b +'haek', # 0x8c +'haet', # 0x8d +'haep', # 0x8e +'haeh', # 0x8f +'hya', # 0x90 +'hyag', # 0x91 +'hyagg', # 0x92 +'hyags', # 0x93 +'hyan', # 0x94 +'hyanj', # 0x95 +'hyanh', # 0x96 +'hyad', # 0x97 +'hyal', # 0x98 +'hyalg', # 0x99 +'hyalm', # 0x9a +'hyalb', # 0x9b +'hyals', # 0x9c +'hyalt', # 0x9d +'hyalp', # 0x9e +'hyalh', # 0x9f +'hyam', # 0xa0 +'hyab', # 0xa1 +'hyabs', # 0xa2 +'hyas', # 0xa3 +'hyass', # 0xa4 +'hyang', # 0xa5 +'hyaj', # 0xa6 +'hyac', # 0xa7 +'hyak', # 0xa8 +'hyat', # 0xa9 +'hyap', # 0xaa +'hyah', # 0xab +'hyae', # 0xac +'hyaeg', # 0xad +'hyaegg', # 0xae +'hyaegs', # 0xaf +'hyaen', # 0xb0 +'hyaenj', # 0xb1 +'hyaenh', # 0xb2 +'hyaed', # 0xb3 +'hyael', # 0xb4 +'hyaelg', # 0xb5 +'hyaelm', # 0xb6 +'hyaelb', # 0xb7 +'hyaels', # 0xb8 +'hyaelt', # 0xb9 +'hyaelp', # 0xba +'hyaelh', # 0xbb +'hyaem', # 0xbc +'hyaeb', # 0xbd +'hyaebs', # 0xbe +'hyaes', # 0xbf +'hyaess', # 0xc0 +'hyaeng', # 0xc1 +'hyaej', # 0xc2 +'hyaec', # 0xc3 +'hyaek', # 0xc4 +'hyaet', # 0xc5 +'hyaep', # 0xc6 +'hyaeh', # 0xc7 +'heo', # 0xc8 +'heog', # 0xc9 +'heogg', # 0xca +'heogs', # 0xcb +'heon', # 0xcc +'heonj', # 0xcd +'heonh', # 0xce +'heod', # 0xcf +'heol', # 0xd0 +'heolg', # 0xd1 +'heolm', # 0xd2 +'heolb', # 0xd3 +'heols', # 0xd4 +'heolt', # 0xd5 +'heolp', # 0xd6 +'heolh', # 0xd7 +'heom', # 0xd8 +'heob', # 0xd9 +'heobs', # 0xda +'heos', # 0xdb +'heoss', # 0xdc +'heong', # 0xdd +'heoj', # 0xde +'heoc', # 0xdf +'heok', # 0xe0 +'heot', # 0xe1 +'heop', # 0xe2 +'heoh', # 0xe3 +'he', # 0xe4 +'heg', # 0xe5 +'hegg', # 0xe6 +'hegs', # 0xe7 +'hen', # 0xe8 +'henj', # 0xe9 +'henh', # 0xea +'hed', # 0xeb +'hel', # 0xec +'helg', # 0xed +'helm', # 0xee +'helb', # 0xef +'hels', # 0xf0 +'helt', # 0xf1 +'help', # 0xf2 +'helh', # 0xf3 +'hem', # 0xf4 +'heb', # 0xf5 +'hebs', # 0xf6 +'hes', # 0xf7 +'hess', # 0xf8 +'heng', # 0xf9 +'hej', # 0xfa +'hec', # 0xfb +'hek', # 0xfc +'het', # 0xfd +'hep', # 0xfe +'heh', # 0xff +) diff --git a/libs/unidecode/x0d6.py b/libs/unidecode/x0d6.py new file mode 100644 index 00000000..042ce2bd --- /dev/null +++ b/libs/unidecode/x0d6.py @@ -0,0 +1,258 @@ +data = ( +'hyeo', # 0x00 +'hyeog', # 0x01 +'hyeogg', # 0x02 +'hyeogs', # 0x03 +'hyeon', # 0x04 +'hyeonj', # 0x05 +'hyeonh', # 0x06 +'hyeod', # 0x07 +'hyeol', # 0x08 +'hyeolg', # 0x09 +'hyeolm', # 0x0a +'hyeolb', # 0x0b +'hyeols', # 0x0c +'hyeolt', # 0x0d +'hyeolp', # 0x0e +'hyeolh', # 0x0f +'hyeom', # 0x10 +'hyeob', # 0x11 +'hyeobs', # 0x12 +'hyeos', # 0x13 +'hyeoss', # 0x14 +'hyeong', # 0x15 +'hyeoj', # 0x16 +'hyeoc', # 0x17 +'hyeok', # 0x18 +'hyeot', # 0x19 +'hyeop', # 0x1a +'hyeoh', # 0x1b +'hye', # 0x1c +'hyeg', # 0x1d +'hyegg', # 0x1e +'hyegs', # 0x1f +'hyen', # 0x20 +'hyenj', # 0x21 +'hyenh', # 0x22 +'hyed', # 0x23 +'hyel', # 0x24 +'hyelg', # 0x25 +'hyelm', # 0x26 +'hyelb', # 0x27 +'hyels', # 0x28 +'hyelt', # 0x29 +'hyelp', # 0x2a +'hyelh', # 0x2b +'hyem', # 0x2c +'hyeb', # 0x2d +'hyebs', # 0x2e +'hyes', # 0x2f +'hyess', # 0x30 +'hyeng', # 0x31 +'hyej', # 0x32 +'hyec', # 0x33 +'hyek', # 0x34 +'hyet', # 0x35 +'hyep', # 0x36 +'hyeh', # 0x37 +'ho', # 0x38 +'hog', # 0x39 +'hogg', # 0x3a +'hogs', # 0x3b +'hon', # 0x3c +'honj', # 0x3d +'honh', # 0x3e +'hod', # 0x3f +'hol', # 0x40 +'holg', # 0x41 +'holm', # 0x42 +'holb', # 0x43 +'hols', # 0x44 +'holt', # 0x45 +'holp', # 0x46 +'holh', # 0x47 +'hom', # 0x48 +'hob', # 0x49 +'hobs', # 0x4a +'hos', # 0x4b +'hoss', # 0x4c +'hong', # 0x4d +'hoj', # 0x4e +'hoc', # 0x4f +'hok', # 0x50 +'hot', # 0x51 +'hop', # 0x52 +'hoh', # 0x53 +'hwa', # 0x54 +'hwag', # 0x55 +'hwagg', # 0x56 +'hwags', # 0x57 +'hwan', # 0x58 +'hwanj', # 0x59 +'hwanh', # 0x5a +'hwad', # 0x5b +'hwal', # 0x5c +'hwalg', # 0x5d +'hwalm', # 0x5e +'hwalb', # 0x5f +'hwals', # 0x60 +'hwalt', # 0x61 +'hwalp', # 0x62 +'hwalh', # 0x63 +'hwam', # 0x64 +'hwab', # 0x65 +'hwabs', # 0x66 +'hwas', # 0x67 +'hwass', # 0x68 +'hwang', # 0x69 +'hwaj', # 0x6a +'hwac', # 0x6b +'hwak', # 0x6c +'hwat', # 0x6d +'hwap', # 0x6e +'hwah', # 0x6f +'hwae', # 0x70 +'hwaeg', # 0x71 +'hwaegg', # 0x72 +'hwaegs', # 0x73 +'hwaen', # 0x74 +'hwaenj', # 0x75 +'hwaenh', # 0x76 +'hwaed', # 0x77 +'hwael', # 0x78 +'hwaelg', # 0x79 +'hwaelm', # 0x7a +'hwaelb', # 0x7b +'hwaels', # 0x7c +'hwaelt', # 0x7d +'hwaelp', # 0x7e +'hwaelh', # 0x7f +'hwaem', # 0x80 +'hwaeb', # 0x81 +'hwaebs', # 0x82 +'hwaes', # 0x83 +'hwaess', # 0x84 +'hwaeng', # 0x85 +'hwaej', # 0x86 +'hwaec', # 0x87 +'hwaek', # 0x88 +'hwaet', # 0x89 +'hwaep', # 0x8a +'hwaeh', # 0x8b +'hoe', # 0x8c +'hoeg', # 0x8d +'hoegg', # 0x8e +'hoegs', # 0x8f +'hoen', # 0x90 +'hoenj', # 0x91 +'hoenh', # 0x92 +'hoed', # 0x93 +'hoel', # 0x94 +'hoelg', # 0x95 +'hoelm', # 0x96 +'hoelb', # 0x97 +'hoels', # 0x98 +'hoelt', # 0x99 +'hoelp', # 0x9a +'hoelh', # 0x9b +'hoem', # 0x9c +'hoeb', # 0x9d +'hoebs', # 0x9e +'hoes', # 0x9f +'hoess', # 0xa0 +'hoeng', # 0xa1 +'hoej', # 0xa2 +'hoec', # 0xa3 +'hoek', # 0xa4 +'hoet', # 0xa5 +'hoep', # 0xa6 +'hoeh', # 0xa7 +'hyo', # 0xa8 +'hyog', # 0xa9 +'hyogg', # 0xaa +'hyogs', # 0xab +'hyon', # 0xac +'hyonj', # 0xad +'hyonh', # 0xae +'hyod', # 0xaf +'hyol', # 0xb0 +'hyolg', # 0xb1 +'hyolm', # 0xb2 +'hyolb', # 0xb3 +'hyols', # 0xb4 +'hyolt', # 0xb5 +'hyolp', # 0xb6 +'hyolh', # 0xb7 +'hyom', # 0xb8 +'hyob', # 0xb9 +'hyobs', # 0xba +'hyos', # 0xbb +'hyoss', # 0xbc +'hyong', # 0xbd +'hyoj', # 0xbe +'hyoc', # 0xbf +'hyok', # 0xc0 +'hyot', # 0xc1 +'hyop', # 0xc2 +'hyoh', # 0xc3 +'hu', # 0xc4 +'hug', # 0xc5 +'hugg', # 0xc6 +'hugs', # 0xc7 +'hun', # 0xc8 +'hunj', # 0xc9 +'hunh', # 0xca +'hud', # 0xcb +'hul', # 0xcc +'hulg', # 0xcd +'hulm', # 0xce +'hulb', # 0xcf +'huls', # 0xd0 +'hult', # 0xd1 +'hulp', # 0xd2 +'hulh', # 0xd3 +'hum', # 0xd4 +'hub', # 0xd5 +'hubs', # 0xd6 +'hus', # 0xd7 +'huss', # 0xd8 +'hung', # 0xd9 +'huj', # 0xda +'huc', # 0xdb +'huk', # 0xdc +'hut', # 0xdd +'hup', # 0xde +'huh', # 0xdf +'hweo', # 0xe0 +'hweog', # 0xe1 +'hweogg', # 0xe2 +'hweogs', # 0xe3 +'hweon', # 0xe4 +'hweonj', # 0xe5 +'hweonh', # 0xe6 +'hweod', # 0xe7 +'hweol', # 0xe8 +'hweolg', # 0xe9 +'hweolm', # 0xea +'hweolb', # 0xeb +'hweols', # 0xec +'hweolt', # 0xed +'hweolp', # 0xee +'hweolh', # 0xef +'hweom', # 0xf0 +'hweob', # 0xf1 +'hweobs', # 0xf2 +'hweos', # 0xf3 +'hweoss', # 0xf4 +'hweong', # 0xf5 +'hweoj', # 0xf6 +'hweoc', # 0xf7 +'hweok', # 0xf8 +'hweot', # 0xf9 +'hweop', # 0xfa +'hweoh', # 0xfb +'hwe', # 0xfc +'hweg', # 0xfd +'hwegg', # 0xfe +'hwegs', # 0xff +) diff --git a/libs/unidecode/x0d7.py b/libs/unidecode/x0d7.py new file mode 100644 index 00000000..1dfb7296 --- /dev/null +++ b/libs/unidecode/x0d7.py @@ -0,0 +1,257 @@ +data = ( +'hwen', # 0x00 +'hwenj', # 0x01 +'hwenh', # 0x02 +'hwed', # 0x03 +'hwel', # 0x04 +'hwelg', # 0x05 +'hwelm', # 0x06 +'hwelb', # 0x07 +'hwels', # 0x08 +'hwelt', # 0x09 +'hwelp', # 0x0a +'hwelh', # 0x0b +'hwem', # 0x0c +'hweb', # 0x0d +'hwebs', # 0x0e +'hwes', # 0x0f +'hwess', # 0x10 +'hweng', # 0x11 +'hwej', # 0x12 +'hwec', # 0x13 +'hwek', # 0x14 +'hwet', # 0x15 +'hwep', # 0x16 +'hweh', # 0x17 +'hwi', # 0x18 +'hwig', # 0x19 +'hwigg', # 0x1a +'hwigs', # 0x1b +'hwin', # 0x1c +'hwinj', # 0x1d +'hwinh', # 0x1e +'hwid', # 0x1f +'hwil', # 0x20 +'hwilg', # 0x21 +'hwilm', # 0x22 +'hwilb', # 0x23 +'hwils', # 0x24 +'hwilt', # 0x25 +'hwilp', # 0x26 +'hwilh', # 0x27 +'hwim', # 0x28 +'hwib', # 0x29 +'hwibs', # 0x2a +'hwis', # 0x2b +'hwiss', # 0x2c +'hwing', # 0x2d +'hwij', # 0x2e +'hwic', # 0x2f +'hwik', # 0x30 +'hwit', # 0x31 +'hwip', # 0x32 +'hwih', # 0x33 +'hyu', # 0x34 +'hyug', # 0x35 +'hyugg', # 0x36 +'hyugs', # 0x37 +'hyun', # 0x38 +'hyunj', # 0x39 +'hyunh', # 0x3a +'hyud', # 0x3b +'hyul', # 0x3c +'hyulg', # 0x3d +'hyulm', # 0x3e +'hyulb', # 0x3f +'hyuls', # 0x40 +'hyult', # 0x41 +'hyulp', # 0x42 +'hyulh', # 0x43 +'hyum', # 0x44 +'hyub', # 0x45 +'hyubs', # 0x46 +'hyus', # 0x47 +'hyuss', # 0x48 +'hyung', # 0x49 +'hyuj', # 0x4a +'hyuc', # 0x4b +'hyuk', # 0x4c +'hyut', # 0x4d +'hyup', # 0x4e +'hyuh', # 0x4f +'heu', # 0x50 +'heug', # 0x51 +'heugg', # 0x52 +'heugs', # 0x53 +'heun', # 0x54 +'heunj', # 0x55 +'heunh', # 0x56 +'heud', # 0x57 +'heul', # 0x58 +'heulg', # 0x59 +'heulm', # 0x5a +'heulb', # 0x5b +'heuls', # 0x5c +'heult', # 0x5d +'heulp', # 0x5e +'heulh', # 0x5f +'heum', # 0x60 +'heub', # 0x61 +'heubs', # 0x62 +'heus', # 0x63 +'heuss', # 0x64 +'heung', # 0x65 +'heuj', # 0x66 +'heuc', # 0x67 +'heuk', # 0x68 +'heut', # 0x69 +'heup', # 0x6a +'heuh', # 0x6b +'hyi', # 0x6c +'hyig', # 0x6d +'hyigg', # 0x6e +'hyigs', # 0x6f +'hyin', # 0x70 +'hyinj', # 0x71 +'hyinh', # 0x72 +'hyid', # 0x73 +'hyil', # 0x74 +'hyilg', # 0x75 +'hyilm', # 0x76 +'hyilb', # 0x77 +'hyils', # 0x78 +'hyilt', # 0x79 +'hyilp', # 0x7a +'hyilh', # 0x7b +'hyim', # 0x7c +'hyib', # 0x7d +'hyibs', # 0x7e +'hyis', # 0x7f +'hyiss', # 0x80 +'hying', # 0x81 +'hyij', # 0x82 +'hyic', # 0x83 +'hyik', # 0x84 +'hyit', # 0x85 +'hyip', # 0x86 +'hyih', # 0x87 +'hi', # 0x88 +'hig', # 0x89 +'higg', # 0x8a +'higs', # 0x8b +'hin', # 0x8c +'hinj', # 0x8d +'hinh', # 0x8e +'hid', # 0x8f +'hil', # 0x90 +'hilg', # 0x91 +'hilm', # 0x92 +'hilb', # 0x93 +'hils', # 0x94 +'hilt', # 0x95 +'hilp', # 0x96 +'hilh', # 0x97 +'him', # 0x98 +'hib', # 0x99 +'hibs', # 0x9a +'his', # 0x9b +'hiss', # 0x9c +'hing', # 0x9d +'hij', # 0x9e +'hic', # 0x9f +'hik', # 0xa0 +'hit', # 0xa1 +'hip', # 0xa2 +'hih', # 0xa3 +'[?]', # 0xa4 +'[?]', # 0xa5 +'[?]', # 0xa6 +'[?]', # 0xa7 +'[?]', # 0xa8 +'[?]', # 0xa9 +'[?]', # 0xaa +'[?]', # 0xab +'[?]', # 0xac +'[?]', # 0xad +'[?]', # 0xae +'[?]', # 0xaf +'[?]', # 0xb0 +'[?]', # 0xb1 +'[?]', # 0xb2 +'[?]', # 0xb3 +'[?]', # 0xb4 +'[?]', # 0xb5 +'[?]', # 0xb6 +'[?]', # 0xb7 +'[?]', # 0xb8 +'[?]', # 0xb9 +'[?]', # 0xba +'[?]', # 0xbb +'[?]', # 0xbc +'[?]', # 0xbd +'[?]', # 0xbe +'[?]', # 0xbf +'[?]', # 0xc0 +'[?]', # 0xc1 +'[?]', # 0xc2 +'[?]', # 0xc3 +'[?]', # 0xc4 +'[?]', # 0xc5 +'[?]', # 0xc6 +'[?]', # 0xc7 +'[?]', # 0xc8 +'[?]', # 0xc9 +'[?]', # 0xca +'[?]', # 0xcb +'[?]', # 0xcc +'[?]', # 0xcd +'[?]', # 0xce +'[?]', # 0xcf +'[?]', # 0xd0 +'[?]', # 0xd1 +'[?]', # 0xd2 +'[?]', # 0xd3 +'[?]', # 0xd4 +'[?]', # 0xd5 +'[?]', # 0xd6 +'[?]', # 0xd7 +'[?]', # 0xd8 +'[?]', # 0xd9 +'[?]', # 0xda +'[?]', # 0xdb +'[?]', # 0xdc +'[?]', # 0xdd +'[?]', # 0xde +'[?]', # 0xdf +'[?]', # 0xe0 +'[?]', # 0xe1 +'[?]', # 0xe2 +'[?]', # 0xe3 +'[?]', # 0xe4 +'[?]', # 0xe5 +'[?]', # 0xe6 +'[?]', # 0xe7 +'[?]', # 0xe8 +'[?]', # 0xe9 +'[?]', # 0xea +'[?]', # 0xeb +'[?]', # 0xec +'[?]', # 0xed +'[?]', # 0xee +'[?]', # 0xef +'[?]', # 0xf0 +'[?]', # 0xf1 +'[?]', # 0xf2 +'[?]', # 0xf3 +'[?]', # 0xf4 +'[?]', # 0xf5 +'[?]', # 0xf6 +'[?]', # 0xf7 +'[?]', # 0xf8 +'[?]', # 0xf9 +'[?]', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x0f9.py b/libs/unidecode/x0f9.py new file mode 100644 index 00000000..6cc9e4cb --- /dev/null +++ b/libs/unidecode/x0f9.py @@ -0,0 +1,258 @@ +data = ( +'Kay ', # 0x00 +'Kayng ', # 0x01 +'Ke ', # 0x02 +'Ko ', # 0x03 +'Kol ', # 0x04 +'Koc ', # 0x05 +'Kwi ', # 0x06 +'Kwi ', # 0x07 +'Kyun ', # 0x08 +'Kul ', # 0x09 +'Kum ', # 0x0a +'Na ', # 0x0b +'Na ', # 0x0c +'Na ', # 0x0d +'La ', # 0x0e +'Na ', # 0x0f +'Na ', # 0x10 +'Na ', # 0x11 +'Na ', # 0x12 +'Na ', # 0x13 +'Nak ', # 0x14 +'Nak ', # 0x15 +'Nak ', # 0x16 +'Nak ', # 0x17 +'Nak ', # 0x18 +'Nak ', # 0x19 +'Nak ', # 0x1a +'Nan ', # 0x1b +'Nan ', # 0x1c +'Nan ', # 0x1d +'Nan ', # 0x1e +'Nan ', # 0x1f +'Nan ', # 0x20 +'Nam ', # 0x21 +'Nam ', # 0x22 +'Nam ', # 0x23 +'Nam ', # 0x24 +'Nap ', # 0x25 +'Nap ', # 0x26 +'Nap ', # 0x27 +'Nang ', # 0x28 +'Nang ', # 0x29 +'Nang ', # 0x2a +'Nang ', # 0x2b +'Nang ', # 0x2c +'Nay ', # 0x2d +'Nayng ', # 0x2e +'No ', # 0x2f +'No ', # 0x30 +'No ', # 0x31 +'No ', # 0x32 +'No ', # 0x33 +'No ', # 0x34 +'No ', # 0x35 +'No ', # 0x36 +'No ', # 0x37 +'No ', # 0x38 +'No ', # 0x39 +'No ', # 0x3a +'Nok ', # 0x3b +'Nok ', # 0x3c +'Nok ', # 0x3d +'Nok ', # 0x3e +'Nok ', # 0x3f +'Nok ', # 0x40 +'Non ', # 0x41 +'Nong ', # 0x42 +'Nong ', # 0x43 +'Nong ', # 0x44 +'Nong ', # 0x45 +'Noy ', # 0x46 +'Noy ', # 0x47 +'Noy ', # 0x48 +'Noy ', # 0x49 +'Nwu ', # 0x4a +'Nwu ', # 0x4b +'Nwu ', # 0x4c +'Nwu ', # 0x4d +'Nwu ', # 0x4e +'Nwu ', # 0x4f +'Nwu ', # 0x50 +'Nwu ', # 0x51 +'Nuk ', # 0x52 +'Nuk ', # 0x53 +'Num ', # 0x54 +'Nung ', # 0x55 +'Nung ', # 0x56 +'Nung ', # 0x57 +'Nung ', # 0x58 +'Nung ', # 0x59 +'Twu ', # 0x5a +'La ', # 0x5b +'Lak ', # 0x5c +'Lak ', # 0x5d +'Lan ', # 0x5e +'Lyeng ', # 0x5f +'Lo ', # 0x60 +'Lyul ', # 0x61 +'Li ', # 0x62 +'Pey ', # 0x63 +'Pen ', # 0x64 +'Pyen ', # 0x65 +'Pwu ', # 0x66 +'Pwul ', # 0x67 +'Pi ', # 0x68 +'Sak ', # 0x69 +'Sak ', # 0x6a +'Sam ', # 0x6b +'Sayk ', # 0x6c +'Sayng ', # 0x6d +'Sep ', # 0x6e +'Sey ', # 0x6f +'Sway ', # 0x70 +'Sin ', # 0x71 +'Sim ', # 0x72 +'Sip ', # 0x73 +'Ya ', # 0x74 +'Yak ', # 0x75 +'Yak ', # 0x76 +'Yang ', # 0x77 +'Yang ', # 0x78 +'Yang ', # 0x79 +'Yang ', # 0x7a +'Yang ', # 0x7b +'Yang ', # 0x7c +'Yang ', # 0x7d +'Yang ', # 0x7e +'Ye ', # 0x7f +'Ye ', # 0x80 +'Ye ', # 0x81 +'Ye ', # 0x82 +'Ye ', # 0x83 +'Ye ', # 0x84 +'Ye ', # 0x85 +'Ye ', # 0x86 +'Ye ', # 0x87 +'Ye ', # 0x88 +'Ye ', # 0x89 +'Yek ', # 0x8a +'Yek ', # 0x8b +'Yek ', # 0x8c +'Yek ', # 0x8d +'Yen ', # 0x8e +'Yen ', # 0x8f +'Yen ', # 0x90 +'Yen ', # 0x91 +'Yen ', # 0x92 +'Yen ', # 0x93 +'Yen ', # 0x94 +'Yen ', # 0x95 +'Yen ', # 0x96 +'Yen ', # 0x97 +'Yen ', # 0x98 +'Yen ', # 0x99 +'Yen ', # 0x9a +'Yen ', # 0x9b +'Yel ', # 0x9c +'Yel ', # 0x9d +'Yel ', # 0x9e +'Yel ', # 0x9f +'Yel ', # 0xa0 +'Yel ', # 0xa1 +'Yem ', # 0xa2 +'Yem ', # 0xa3 +'Yem ', # 0xa4 +'Yem ', # 0xa5 +'Yem ', # 0xa6 +'Yep ', # 0xa7 +'Yeng ', # 0xa8 +'Yeng ', # 0xa9 +'Yeng ', # 0xaa +'Yeng ', # 0xab +'Yeng ', # 0xac +'Yeng ', # 0xad +'Yeng ', # 0xae +'Yeng ', # 0xaf +'Yeng ', # 0xb0 +'Yeng ', # 0xb1 +'Yeng ', # 0xb2 +'Yeng ', # 0xb3 +'Yeng ', # 0xb4 +'Yey ', # 0xb5 +'Yey ', # 0xb6 +'Yey ', # 0xb7 +'Yey ', # 0xb8 +'O ', # 0xb9 +'Yo ', # 0xba +'Yo ', # 0xbb +'Yo ', # 0xbc +'Yo ', # 0xbd +'Yo ', # 0xbe +'Yo ', # 0xbf +'Yo ', # 0xc0 +'Yo ', # 0xc1 +'Yo ', # 0xc2 +'Yo ', # 0xc3 +'Yong ', # 0xc4 +'Wun ', # 0xc5 +'Wen ', # 0xc6 +'Yu ', # 0xc7 +'Yu ', # 0xc8 +'Yu ', # 0xc9 +'Yu ', # 0xca +'Yu ', # 0xcb +'Yu ', # 0xcc +'Yu ', # 0xcd +'Yu ', # 0xce +'Yu ', # 0xcf +'Yu ', # 0xd0 +'Yuk ', # 0xd1 +'Yuk ', # 0xd2 +'Yuk ', # 0xd3 +'Yun ', # 0xd4 +'Yun ', # 0xd5 +'Yun ', # 0xd6 +'Yun ', # 0xd7 +'Yul ', # 0xd8 +'Yul ', # 0xd9 +'Yul ', # 0xda +'Yul ', # 0xdb +'Yung ', # 0xdc +'I ', # 0xdd +'I ', # 0xde +'I ', # 0xdf +'I ', # 0xe0 +'I ', # 0xe1 +'I ', # 0xe2 +'I ', # 0xe3 +'I ', # 0xe4 +'I ', # 0xe5 +'I ', # 0xe6 +'I ', # 0xe7 +'I ', # 0xe8 +'I ', # 0xe9 +'I ', # 0xea +'Ik ', # 0xeb +'Ik ', # 0xec +'In ', # 0xed +'In ', # 0xee +'In ', # 0xef +'In ', # 0xf0 +'In ', # 0xf1 +'In ', # 0xf2 +'In ', # 0xf3 +'Im ', # 0xf4 +'Im ', # 0xf5 +'Im ', # 0xf6 +'Ip ', # 0xf7 +'Ip ', # 0xf8 +'Ip ', # 0xf9 +'Cang ', # 0xfa +'Cek ', # 0xfb +'Ci ', # 0xfc +'Cip ', # 0xfd +'Cha ', # 0xfe +'Chek ', # 0xff +) diff --git a/libs/unidecode/x0fa.py b/libs/unidecode/x0fa.py new file mode 100644 index 00000000..3d4e705c --- /dev/null +++ b/libs/unidecode/x0fa.py @@ -0,0 +1,257 @@ +data = ( +'Chey ', # 0x00 +'Thak ', # 0x01 +'Thak ', # 0x02 +'Thang ', # 0x03 +'Thayk ', # 0x04 +'Thong ', # 0x05 +'Pho ', # 0x06 +'Phok ', # 0x07 +'Hang ', # 0x08 +'Hang ', # 0x09 +'Hyen ', # 0x0a +'Hwak ', # 0x0b +'Wu ', # 0x0c +'Huo ', # 0x0d +'[?] ', # 0x0e +'[?] ', # 0x0f +'Zhong ', # 0x10 +'[?] ', # 0x11 +'Qing ', # 0x12 +'[?] ', # 0x13 +'[?] ', # 0x14 +'Xi ', # 0x15 +'Zhu ', # 0x16 +'Yi ', # 0x17 +'Li ', # 0x18 +'Shen ', # 0x19 +'Xiang ', # 0x1a +'Fu ', # 0x1b +'Jing ', # 0x1c +'Jing ', # 0x1d +'Yu ', # 0x1e +'[?] ', # 0x1f +'Hagi ', # 0x20 +'[?] ', # 0x21 +'Zhu ', # 0x22 +'[?] ', # 0x23 +'[?] ', # 0x24 +'Yi ', # 0x25 +'Du ', # 0x26 +'[?] ', # 0x27 +'[?] ', # 0x28 +'[?] ', # 0x29 +'Fan ', # 0x2a +'Si ', # 0x2b +'Guan ', # 0x2c +'[?]', # 0x2d +'[?]', # 0x2e +'[?]', # 0x2f +'[?]', # 0x30 +'[?]', # 0x31 +'[?]', # 0x32 +'[?]', # 0x33 +'[?]', # 0x34 +'[?]', # 0x35 +'[?]', # 0x36 +'[?]', # 0x37 +'[?]', # 0x38 +'[?]', # 0x39 +'[?]', # 0x3a +'[?]', # 0x3b +'[?]', # 0x3c +'[?]', # 0x3d +'[?]', # 0x3e +'[?]', # 0x3f +'[?]', # 0x40 +'[?]', # 0x41 +'[?]', # 0x42 +'[?]', # 0x43 +'[?]', # 0x44 +'[?]', # 0x45 +'[?]', # 0x46 +'[?]', # 0x47 +'[?]', # 0x48 +'[?]', # 0x49 +'[?]', # 0x4a +'[?]', # 0x4b +'[?]', # 0x4c +'[?]', # 0x4d +'[?]', # 0x4e +'[?]', # 0x4f +'[?]', # 0x50 +'[?]', # 0x51 +'[?]', # 0x52 +'[?]', # 0x53 +'[?]', # 0x54 +'[?]', # 0x55 +'[?]', # 0x56 +'[?]', # 0x57 +'[?]', # 0x58 +'[?]', # 0x59 +'[?]', # 0x5a +'[?]', # 0x5b +'[?]', # 0x5c +'[?]', # 0x5d +'[?]', # 0x5e +'[?]', # 0x5f +'[?]', # 0x60 +'[?]', # 0x61 +'[?]', # 0x62 +'[?]', # 0x63 +'[?]', # 0x64 +'[?]', # 0x65 +'[?]', # 0x66 +'[?]', # 0x67 +'[?]', # 0x68 +'[?]', # 0x69 +'[?]', # 0x6a +'[?]', # 0x6b +'[?]', # 0x6c +'[?]', # 0x6d +'[?]', # 0x6e +'[?]', # 0x6f +'[?]', # 0x70 +'[?]', # 0x71 +'[?]', # 0x72 +'[?]', # 0x73 +'[?]', # 0x74 +'[?]', # 0x75 +'[?]', # 0x76 +'[?]', # 0x77 +'[?]', # 0x78 +'[?]', # 0x79 +'[?]', # 0x7a +'[?]', # 0x7b +'[?]', # 0x7c +'[?]', # 0x7d +'[?]', # 0x7e +'[?]', # 0x7f +'[?]', # 0x80 +'[?]', # 0x81 +'[?]', # 0x82 +'[?]', # 0x83 +'[?]', # 0x84 +'[?]', # 0x85 +'[?]', # 0x86 +'[?]', # 0x87 +'[?]', # 0x88 +'[?]', # 0x89 +'[?]', # 0x8a +'[?]', # 0x8b +'[?]', # 0x8c +'[?]', # 0x8d +'[?]', # 0x8e +'[?]', # 0x8f +'[?]', # 0x90 +'[?]', # 0x91 +'[?]', # 0x92 +'[?]', # 0x93 +'[?]', # 0x94 +'[?]', # 0x95 +'[?]', # 0x96 +'[?]', # 0x97 +'[?]', # 0x98 +'[?]', # 0x99 +'[?]', # 0x9a +'[?]', # 0x9b +'[?]', # 0x9c +'[?]', # 0x9d +'[?]', # 0x9e +'[?]', # 0x9f +'[?]', # 0xa0 +'[?]', # 0xa1 +'[?]', # 0xa2 +'[?]', # 0xa3 +'[?]', # 0xa4 +'[?]', # 0xa5 +'[?]', # 0xa6 +'[?]', # 0xa7 +'[?]', # 0xa8 +'[?]', # 0xa9 +'[?]', # 0xaa +'[?]', # 0xab +'[?]', # 0xac +'[?]', # 0xad +'[?]', # 0xae +'[?]', # 0xaf +'[?]', # 0xb0 +'[?]', # 0xb1 +'[?]', # 0xb2 +'[?]', # 0xb3 +'[?]', # 0xb4 +'[?]', # 0xb5 +'[?]', # 0xb6 +'[?]', # 0xb7 +'[?]', # 0xb8 +'[?]', # 0xb9 +'[?]', # 0xba +'[?]', # 0xbb +'[?]', # 0xbc +'[?]', # 0xbd +'[?]', # 0xbe +'[?]', # 0xbf +'[?]', # 0xc0 +'[?]', # 0xc1 +'[?]', # 0xc2 +'[?]', # 0xc3 +'[?]', # 0xc4 +'[?]', # 0xc5 +'[?]', # 0xc6 +'[?]', # 0xc7 +'[?]', # 0xc8 +'[?]', # 0xc9 +'[?]', # 0xca +'[?]', # 0xcb +'[?]', # 0xcc +'[?]', # 0xcd +'[?]', # 0xce +'[?]', # 0xcf +'[?]', # 0xd0 +'[?]', # 0xd1 +'[?]', # 0xd2 +'[?]', # 0xd3 +'[?]', # 0xd4 +'[?]', # 0xd5 +'[?]', # 0xd6 +'[?]', # 0xd7 +'[?]', # 0xd8 +'[?]', # 0xd9 +'[?]', # 0xda +'[?]', # 0xdb +'[?]', # 0xdc +'[?]', # 0xdd +'[?]', # 0xde +'[?]', # 0xdf +'[?]', # 0xe0 +'[?]', # 0xe1 +'[?]', # 0xe2 +'[?]', # 0xe3 +'[?]', # 0xe4 +'[?]', # 0xe5 +'[?]', # 0xe6 +'[?]', # 0xe7 +'[?]', # 0xe8 +'[?]', # 0xe9 +'[?]', # 0xea +'[?]', # 0xeb +'[?]', # 0xec +'[?]', # 0xed +'[?]', # 0xee +'[?]', # 0xef +'[?]', # 0xf0 +'[?]', # 0xf1 +'[?]', # 0xf2 +'[?]', # 0xf3 +'[?]', # 0xf4 +'[?]', # 0xf5 +'[?]', # 0xf6 +'[?]', # 0xf7 +'[?]', # 0xf8 +'[?]', # 0xf9 +'[?]', # 0xfa +'[?]', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x0fb.py b/libs/unidecode/x0fb.py new file mode 100644 index 00000000..bf69dbb9 --- /dev/null +++ b/libs/unidecode/x0fb.py @@ -0,0 +1,258 @@ +data = ( +'ff', # 0x00 +'fi', # 0x01 +'fl', # 0x02 +'ffi', # 0x03 +'ffl', # 0x04 +'st', # 0x05 +'st', # 0x06 +'[?]', # 0x07 +'[?]', # 0x08 +'[?]', # 0x09 +'[?]', # 0x0a +'[?]', # 0x0b +'[?]', # 0x0c +'[?]', # 0x0d +'[?]', # 0x0e +'[?]', # 0x0f +'[?]', # 0x10 +'[?]', # 0x11 +'[?]', # 0x12 +'mn', # 0x13 +'me', # 0x14 +'mi', # 0x15 +'vn', # 0x16 +'mkh', # 0x17 +'[?]', # 0x18 +'[?]', # 0x19 +'[?]', # 0x1a +'[?]', # 0x1b +'[?]', # 0x1c +'yi', # 0x1d +'', # 0x1e +'ay', # 0x1f +'`', # 0x20 +'', # 0x21 +'d', # 0x22 +'h', # 0x23 +'k', # 0x24 +'l', # 0x25 +'m', # 0x26 +'m', # 0x27 +'t', # 0x28 +'+', # 0x29 +'sh', # 0x2a +'s', # 0x2b +'sh', # 0x2c +'s', # 0x2d +'a', # 0x2e +'a', # 0x2f +'', # 0x30 +'b', # 0x31 +'g', # 0x32 +'d', # 0x33 +'h', # 0x34 +'v', # 0x35 +'z', # 0x36 +'[?]', # 0x37 +'t', # 0x38 +'y', # 0x39 +'k', # 0x3a +'k', # 0x3b +'l', # 0x3c +'[?]', # 0x3d +'l', # 0x3e +'[?]', # 0x3f +'n', # 0x40 +'n', # 0x41 +'[?]', # 0x42 +'p', # 0x43 +'p', # 0x44 +'[?]', # 0x45 +'ts', # 0x46 +'ts', # 0x47 +'r', # 0x48 +'sh', # 0x49 +'t', # 0x4a +'vo', # 0x4b +'b', # 0x4c +'k', # 0x4d +'p', # 0x4e +'l', # 0x4f +'', # 0x50 +'', # 0x51 +'', # 0x52 +'', # 0x53 +'', # 0x54 +'', # 0x55 +'', # 0x56 +'', # 0x57 +'', # 0x58 +'', # 0x59 +'', # 0x5a +'', # 0x5b +'', # 0x5c +'', # 0x5d +'', # 0x5e +'', # 0x5f +'', # 0x60 +'', # 0x61 +'', # 0x62 +'', # 0x63 +'', # 0x64 +'', # 0x65 +'', # 0x66 +'', # 0x67 +'', # 0x68 +'', # 0x69 +'', # 0x6a +'', # 0x6b +'', # 0x6c +'', # 0x6d +'', # 0x6e +'', # 0x6f +'', # 0x70 +'', # 0x71 +'', # 0x72 +'', # 0x73 +'', # 0x74 +'', # 0x75 +'', # 0x76 +'', # 0x77 +'', # 0x78 +'', # 0x79 +'', # 0x7a +'', # 0x7b +'', # 0x7c +'', # 0x7d +'', # 0x7e +'', # 0x7f +'', # 0x80 +'', # 0x81 +'', # 0x82 +'', # 0x83 +'', # 0x84 +'', # 0x85 +'', # 0x86 +'', # 0x87 +'', # 0x88 +'', # 0x89 +'', # 0x8a +'', # 0x8b +'', # 0x8c +'', # 0x8d +'', # 0x8e +'', # 0x8f +'', # 0x90 +'', # 0x91 +'', # 0x92 +'', # 0x93 +'', # 0x94 +'', # 0x95 +'', # 0x96 +'', # 0x97 +'', # 0x98 +'', # 0x99 +'', # 0x9a +'', # 0x9b +'', # 0x9c +'', # 0x9d +'', # 0x9e +'', # 0x9f +'', # 0xa0 +'', # 0xa1 +'', # 0xa2 +'', # 0xa3 +'', # 0xa4 +'', # 0xa5 +'', # 0xa6 +'', # 0xa7 +'', # 0xa8 +'', # 0xa9 +'', # 0xaa +'', # 0xab +'', # 0xac +'', # 0xad +'', # 0xae +'', # 0xaf +'', # 0xb0 +'', # 0xb1 +'[?]', # 0xb2 +'[?]', # 0xb3 +'[?]', # 0xb4 +'[?]', # 0xb5 +'[?]', # 0xb6 +'[?]', # 0xb7 +'[?]', # 0xb8 +'[?]', # 0xb9 +'[?]', # 0xba +'[?]', # 0xbb +'[?]', # 0xbc +'[?]', # 0xbd +'[?]', # 0xbe +'[?]', # 0xbf +'[?]', # 0xc0 +'[?]', # 0xc1 +'[?]', # 0xc2 +'[?]', # 0xc3 +'[?]', # 0xc4 +'[?]', # 0xc5 +'[?]', # 0xc6 +'[?]', # 0xc7 +'[?]', # 0xc8 +'[?]', # 0xc9 +'[?]', # 0xca +'[?]', # 0xcb +'[?]', # 0xcc +'[?]', # 0xcd +'[?]', # 0xce +'[?]', # 0xcf +'[?]', # 0xd0 +'[?]', # 0xd1 +'[?]', # 0xd2 +'', # 0xd3 +'', # 0xd4 +'', # 0xd5 +'', # 0xd6 +'', # 0xd7 +'', # 0xd8 +'', # 0xd9 +'', # 0xda +'', # 0xdb +'', # 0xdc +'', # 0xdd +'', # 0xde +'', # 0xdf +'', # 0xe0 +'', # 0xe1 +'', # 0xe2 +'', # 0xe3 +'', # 0xe4 +'', # 0xe5 +'', # 0xe6 +'', # 0xe7 +'', # 0xe8 +'', # 0xe9 +'', # 0xea +'', # 0xeb +'', # 0xec +'', # 0xed +'', # 0xee +'', # 0xef +'', # 0xf0 +'', # 0xf1 +'', # 0xf2 +'', # 0xf3 +'', # 0xf4 +'', # 0xf5 +'', # 0xf6 +'', # 0xf7 +'', # 0xf8 +'', # 0xf9 +'', # 0xfa +'', # 0xfb +'', # 0xfc +'', # 0xfd +'', # 0xfe +'', # 0xff +) diff --git a/libs/unidecode/x0fc.py b/libs/unidecode/x0fc.py new file mode 100644 index 00000000..298b1dc3 --- /dev/null +++ b/libs/unidecode/x0fc.py @@ -0,0 +1,258 @@ +data = ( +'', # 0x00 +'', # 0x01 +'', # 0x02 +'', # 0x03 +'', # 0x04 +'', # 0x05 +'', # 0x06 +'', # 0x07 +'', # 0x08 +'', # 0x09 +'', # 0x0a +'', # 0x0b +'', # 0x0c +'', # 0x0d +'', # 0x0e +'', # 0x0f +'', # 0x10 +'', # 0x11 +'', # 0x12 +'', # 0x13 +'', # 0x14 +'', # 0x15 +'', # 0x16 +'', # 0x17 +'', # 0x18 +'', # 0x19 +'', # 0x1a +'', # 0x1b +'', # 0x1c +'', # 0x1d +'', # 0x1e +'', # 0x1f +'', # 0x20 +'', # 0x21 +'', # 0x22 +'', # 0x23 +'', # 0x24 +'', # 0x25 +'', # 0x26 +'', # 0x27 +'', # 0x28 +'', # 0x29 +'', # 0x2a +'', # 0x2b +'', # 0x2c +'', # 0x2d +'', # 0x2e +'', # 0x2f +'', # 0x30 +'', # 0x31 +'', # 0x32 +'', # 0x33 +'', # 0x34 +'', # 0x35 +'', # 0x36 +'', # 0x37 +'', # 0x38 +'', # 0x39 +'', # 0x3a +'', # 0x3b +'', # 0x3c +'', # 0x3d +'', # 0x3e +'', # 0x3f +'', # 0x40 +'', # 0x41 +'', # 0x42 +'', # 0x43 +'', # 0x44 +'', # 0x45 +'', # 0x46 +'', # 0x47 +'', # 0x48 +'', # 0x49 +'', # 0x4a +'', # 0x4b +'', # 0x4c +'', # 0x4d +'', # 0x4e +'', # 0x4f +'', # 0x50 +'', # 0x51 +'', # 0x52 +'', # 0x53 +'', # 0x54 +'', # 0x55 +'', # 0x56 +'', # 0x57 +'', # 0x58 +'', # 0x59 +'', # 0x5a +'', # 0x5b +'', # 0x5c +'', # 0x5d +'', # 0x5e +'', # 0x5f +'', # 0x60 +'', # 0x61 +'', # 0x62 +'', # 0x63 +'', # 0x64 +'', # 0x65 +'', # 0x66 +'', # 0x67 +'', # 0x68 +'', # 0x69 +'', # 0x6a +'', # 0x6b +'', # 0x6c +'', # 0x6d +'', # 0x6e +'', # 0x6f +'', # 0x70 +'', # 0x71 +'', # 0x72 +'', # 0x73 +'', # 0x74 +'', # 0x75 +'', # 0x76 +'', # 0x77 +'', # 0x78 +'', # 0x79 +'', # 0x7a +'', # 0x7b +'', # 0x7c +'', # 0x7d +'', # 0x7e +'', # 0x7f +'', # 0x80 +'', # 0x81 +'', # 0x82 +'', # 0x83 +'', # 0x84 +'', # 0x85 +'', # 0x86 +'', # 0x87 +'', # 0x88 +'', # 0x89 +'', # 0x8a +'', # 0x8b +'', # 0x8c +'', # 0x8d +'', # 0x8e +'', # 0x8f +'', # 0x90 +'', # 0x91 +'', # 0x92 +'', # 0x93 +'', # 0x94 +'', # 0x95 +'', # 0x96 +'', # 0x97 +'', # 0x98 +'', # 0x99 +'', # 0x9a +'', # 0x9b +'', # 0x9c +'', # 0x9d +'', # 0x9e +'', # 0x9f +'', # 0xa0 +'', # 0xa1 +'', # 0xa2 +'', # 0xa3 +'', # 0xa4 +'', # 0xa5 +'', # 0xa6 +'', # 0xa7 +'', # 0xa8 +'', # 0xa9 +'', # 0xaa +'', # 0xab +'', # 0xac +'', # 0xad +'', # 0xae +'', # 0xaf +'', # 0xb0 +'', # 0xb1 +'', # 0xb2 +'', # 0xb3 +'', # 0xb4 +'', # 0xb5 +'', # 0xb6 +'', # 0xb7 +'', # 0xb8 +'', # 0xb9 +'', # 0xba +'', # 0xbb +'', # 0xbc +'', # 0xbd +'', # 0xbe +'', # 0xbf +'', # 0xc0 +'', # 0xc1 +'', # 0xc2 +'', # 0xc3 +'', # 0xc4 +'', # 0xc5 +'', # 0xc6 +'', # 0xc7 +'', # 0xc8 +'', # 0xc9 +'', # 0xca +'', # 0xcb +'', # 0xcc +'', # 0xcd +'', # 0xce +'', # 0xcf +'', # 0xd0 +'', # 0xd1 +'', # 0xd2 +'', # 0xd3 +'', # 0xd4 +'', # 0xd5 +'', # 0xd6 +'', # 0xd7 +'', # 0xd8 +'', # 0xd9 +'', # 0xda +'', # 0xdb +'', # 0xdc +'', # 0xdd +'', # 0xde +'', # 0xdf +'', # 0xe0 +'', # 0xe1 +'', # 0xe2 +'', # 0xe3 +'', # 0xe4 +'', # 0xe5 +'', # 0xe6 +'', # 0xe7 +'', # 0xe8 +'', # 0xe9 +'', # 0xea +'', # 0xeb +'', # 0xec +'', # 0xed +'', # 0xee +'', # 0xef +'', # 0xf0 +'', # 0xf1 +'', # 0xf2 +'', # 0xf3 +'', # 0xf4 +'', # 0xf5 +'', # 0xf6 +'', # 0xf7 +'', # 0xf8 +'', # 0xf9 +'', # 0xfa +'', # 0xfb +'', # 0xfc +'', # 0xfd +'', # 0xfe +'', # 0xff +) diff --git a/libs/unidecode/x0fd.py b/libs/unidecode/x0fd.py new file mode 100644 index 00000000..892bcb05 --- /dev/null +++ b/libs/unidecode/x0fd.py @@ -0,0 +1,257 @@ +data = ( +'', # 0x00 +'', # 0x01 +'', # 0x02 +'', # 0x03 +'', # 0x04 +'', # 0x05 +'', # 0x06 +'', # 0x07 +'', # 0x08 +'', # 0x09 +'', # 0x0a +'', # 0x0b +'', # 0x0c +'', # 0x0d +'', # 0x0e +'', # 0x0f +'', # 0x10 +'', # 0x11 +'', # 0x12 +'', # 0x13 +'', # 0x14 +'', # 0x15 +'', # 0x16 +'', # 0x17 +'', # 0x18 +'', # 0x19 +'', # 0x1a +'', # 0x1b +'', # 0x1c +'', # 0x1d +'', # 0x1e +'', # 0x1f +'', # 0x20 +'', # 0x21 +'', # 0x22 +'', # 0x23 +'', # 0x24 +'', # 0x25 +'', # 0x26 +'', # 0x27 +'', # 0x28 +'', # 0x29 +'', # 0x2a +'', # 0x2b +'', # 0x2c +'', # 0x2d +'', # 0x2e +'', # 0x2f +'', # 0x30 +'', # 0x31 +'', # 0x32 +'', # 0x33 +'', # 0x34 +'', # 0x35 +'', # 0x36 +'', # 0x37 +'', # 0x38 +'', # 0x39 +'', # 0x3a +'', # 0x3b +'', # 0x3c +'', # 0x3d +'', # 0x3e +'', # 0x3f +'[?]', # 0x40 +'[?]', # 0x41 +'[?]', # 0x42 +'[?]', # 0x43 +'[?]', # 0x44 +'[?]', # 0x45 +'[?]', # 0x46 +'[?]', # 0x47 +'[?]', # 0x48 +'[?]', # 0x49 +'[?]', # 0x4a +'[?]', # 0x4b +'[?]', # 0x4c +'[?]', # 0x4d +'[?]', # 0x4e +'[?]', # 0x4f +'', # 0x50 +'', # 0x51 +'', # 0x52 +'', # 0x53 +'', # 0x54 +'', # 0x55 +'', # 0x56 +'', # 0x57 +'', # 0x58 +'', # 0x59 +'', # 0x5a +'', # 0x5b +'', # 0x5c +'', # 0x5d +'', # 0x5e +'', # 0x5f +'', # 0x60 +'', # 0x61 +'', # 0x62 +'', # 0x63 +'', # 0x64 +'', # 0x65 +'', # 0x66 +'', # 0x67 +'', # 0x68 +'', # 0x69 +'', # 0x6a +'', # 0x6b +'', # 0x6c +'', # 0x6d +'', # 0x6e +'', # 0x6f +'', # 0x70 +'', # 0x71 +'', # 0x72 +'', # 0x73 +'', # 0x74 +'', # 0x75 +'', # 0x76 +'', # 0x77 +'', # 0x78 +'', # 0x79 +'', # 0x7a +'', # 0x7b +'', # 0x7c +'', # 0x7d +'', # 0x7e +'', # 0x7f +'', # 0x80 +'', # 0x81 +'', # 0x82 +'', # 0x83 +'', # 0x84 +'', # 0x85 +'', # 0x86 +'', # 0x87 +'', # 0x88 +'', # 0x89 +'', # 0x8a +'', # 0x8b +'', # 0x8c +'', # 0x8d +'', # 0x8e +'', # 0x8f +'[?]', # 0x90 +'[?]', # 0x91 +'', # 0x92 +'', # 0x93 +'', # 0x94 +'', # 0x95 +'', # 0x96 +'', # 0x97 +'', # 0x98 +'', # 0x99 +'', # 0x9a +'', # 0x9b +'', # 0x9c +'', # 0x9d +'', # 0x9e +'', # 0x9f +'', # 0xa0 +'', # 0xa1 +'', # 0xa2 +'', # 0xa3 +'', # 0xa4 +'', # 0xa5 +'', # 0xa6 +'', # 0xa7 +'', # 0xa8 +'', # 0xa9 +'', # 0xaa +'', # 0xab +'', # 0xac +'', # 0xad +'', # 0xae +'', # 0xaf +'', # 0xb0 +'', # 0xb1 +'', # 0xb2 +'', # 0xb3 +'', # 0xb4 +'', # 0xb5 +'', # 0xb6 +'', # 0xb7 +'', # 0xb8 +'', # 0xb9 +'', # 0xba +'', # 0xbb +'', # 0xbc +'', # 0xbd +'', # 0xbe +'', # 0xbf +'', # 0xc0 +'', # 0xc1 +'', # 0xc2 +'', # 0xc3 +'', # 0xc4 +'', # 0xc5 +'', # 0xc6 +'', # 0xc7 +'[?]', # 0xc8 +'[?]', # 0xc9 +'[?]', # 0xca +'[?]', # 0xcb +'[?]', # 0xcc +'[?]', # 0xcd +'[?]', # 0xce +'[?]', # 0xcf +'[?]', # 0xd0 +'[?]', # 0xd1 +'[?]', # 0xd2 +'[?]', # 0xd3 +'[?]', # 0xd4 +'[?]', # 0xd5 +'[?]', # 0xd6 +'[?]', # 0xd7 +'[?]', # 0xd8 +'[?]', # 0xd9 +'[?]', # 0xda +'[?]', # 0xdb +'[?]', # 0xdc +'[?]', # 0xdd +'[?]', # 0xde +'[?]', # 0xdf +'[?]', # 0xe0 +'[?]', # 0xe1 +'[?]', # 0xe2 +'[?]', # 0xe3 +'[?]', # 0xe4 +'[?]', # 0xe5 +'[?]', # 0xe6 +'[?]', # 0xe7 +'[?]', # 0xe8 +'[?]', # 0xe9 +'[?]', # 0xea +'[?]', # 0xeb +'[?]', # 0xec +'[?]', # 0xed +'[?]', # 0xee +'[?]', # 0xef +'', # 0xf0 +'', # 0xf1 +'', # 0xf2 +'', # 0xf3 +'', # 0xf4 +'', # 0xf5 +'', # 0xf6 +'', # 0xf7 +'', # 0xf8 +'', # 0xf9 +'', # 0xfa +'', # 0xfb +'[?]', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +) diff --git a/libs/unidecode/x0fe.py b/libs/unidecode/x0fe.py new file mode 100644 index 00000000..60e86179 --- /dev/null +++ b/libs/unidecode/x0fe.py @@ -0,0 +1,258 @@ +data = ( +'[?]', # 0x00 +'[?]', # 0x01 +'[?]', # 0x02 +'[?]', # 0x03 +'[?]', # 0x04 +'[?]', # 0x05 +'[?]', # 0x06 +'[?]', # 0x07 +'[?]', # 0x08 +'[?]', # 0x09 +'[?]', # 0x0a +'[?]', # 0x0b +'[?]', # 0x0c +'[?]', # 0x0d +'[?]', # 0x0e +'[?]', # 0x0f +'[?]', # 0x10 +'[?]', # 0x11 +'[?]', # 0x12 +'[?]', # 0x13 +'[?]', # 0x14 +'[?]', # 0x15 +'[?]', # 0x16 +'[?]', # 0x17 +'[?]', # 0x18 +'[?]', # 0x19 +'[?]', # 0x1a +'[?]', # 0x1b +'[?]', # 0x1c +'[?]', # 0x1d +'[?]', # 0x1e +'[?]', # 0x1f +'', # 0x20 +'', # 0x21 +'', # 0x22 +'~', # 0x23 +'[?]', # 0x24 +'[?]', # 0x25 +'[?]', # 0x26 +'[?]', # 0x27 +'[?]', # 0x28 +'[?]', # 0x29 +'[?]', # 0x2a +'[?]', # 0x2b +'[?]', # 0x2c +'[?]', # 0x2d +'[?]', # 0x2e +'[?]', # 0x2f +'..', # 0x30 +'--', # 0x31 +'-', # 0x32 +'_', # 0x33 +'_', # 0x34 +'(', # 0x35 +') ', # 0x36 +'{', # 0x37 +'} ', # 0x38 +'[', # 0x39 +'] ', # 0x3a +'[(', # 0x3b +')] ', # 0x3c +'<<', # 0x3d +'>> ', # 0x3e +'<', # 0x3f +'> ', # 0x40 +'[', # 0x41 +'] ', # 0x42 +'{', # 0x43 +'}', # 0x44 +'[?]', # 0x45 +'[?]', # 0x46 +'[?]', # 0x47 +'[?]', # 0x48 +'', # 0x49 +'', # 0x4a +'', # 0x4b +'', # 0x4c +'', # 0x4d +'', # 0x4e +'', # 0x4f +',', # 0x50 +',', # 0x51 +'.', # 0x52 +'', # 0x53 +';', # 0x54 +':', # 0x55 +'?', # 0x56 +'!', # 0x57 +'-', # 0x58 +'(', # 0x59 +')', # 0x5a +'{', # 0x5b +'}', # 0x5c +'{', # 0x5d +'}', # 0x5e +'#', # 0x5f +'&', # 0x60 +'*', # 0x61 +'+', # 0x62 +'-', # 0x63 +'<', # 0x64 +'>', # 0x65 +'=', # 0x66 +'', # 0x67 +'\\', # 0x68 +'$', # 0x69 +'%', # 0x6a +'@', # 0x6b +'[?]', # 0x6c +'[?]', # 0x6d +'[?]', # 0x6e +'[?]', # 0x6f +'', # 0x70 +'', # 0x71 +'', # 0x72 +'[?]', # 0x73 +'', # 0x74 +'[?]', # 0x75 +'', # 0x76 +'', # 0x77 +'', # 0x78 +'', # 0x79 +'', # 0x7a +'', # 0x7b +'', # 0x7c +'', # 0x7d +'', # 0x7e +'', # 0x7f +'', # 0x80 +'', # 0x81 +'', # 0x82 +'', # 0x83 +'', # 0x84 +'', # 0x85 +'', # 0x86 +'', # 0x87 +'', # 0x88 +'', # 0x89 +'', # 0x8a +'', # 0x8b +'', # 0x8c +'', # 0x8d +'', # 0x8e +'', # 0x8f +'', # 0x90 +'', # 0x91 +'', # 0x92 +'', # 0x93 +'', # 0x94 +'', # 0x95 +'', # 0x96 +'', # 0x97 +'', # 0x98 +'', # 0x99 +'', # 0x9a +'', # 0x9b +'', # 0x9c +'', # 0x9d +'', # 0x9e +'', # 0x9f +'', # 0xa0 +'', # 0xa1 +'', # 0xa2 +'', # 0xa3 +'', # 0xa4 +'', # 0xa5 +'', # 0xa6 +'', # 0xa7 +'', # 0xa8 +'', # 0xa9 +'', # 0xaa +'', # 0xab +'', # 0xac +'', # 0xad +'', # 0xae +'', # 0xaf +'', # 0xb0 +'', # 0xb1 +'', # 0xb2 +'', # 0xb3 +'', # 0xb4 +'', # 0xb5 +'', # 0xb6 +'', # 0xb7 +'', # 0xb8 +'', # 0xb9 +'', # 0xba +'', # 0xbb +'', # 0xbc +'', # 0xbd +'', # 0xbe +'', # 0xbf +'', # 0xc0 +'', # 0xc1 +'', # 0xc2 +'', # 0xc3 +'', # 0xc4 +'', # 0xc5 +'', # 0xc6 +'', # 0xc7 +'', # 0xc8 +'', # 0xc9 +'', # 0xca +'', # 0xcb +'', # 0xcc +'', # 0xcd +'', # 0xce +'', # 0xcf +'', # 0xd0 +'', # 0xd1 +'', # 0xd2 +'', # 0xd3 +'', # 0xd4 +'', # 0xd5 +'', # 0xd6 +'', # 0xd7 +'', # 0xd8 +'', # 0xd9 +'', # 0xda +'', # 0xdb +'', # 0xdc +'', # 0xdd +'', # 0xde +'', # 0xdf +'', # 0xe0 +'', # 0xe1 +'', # 0xe2 +'', # 0xe3 +'', # 0xe4 +'', # 0xe5 +'', # 0xe6 +'', # 0xe7 +'', # 0xe8 +'', # 0xe9 +'', # 0xea +'', # 0xeb +'', # 0xec +'', # 0xed +'', # 0xee +'', # 0xef +'', # 0xf0 +'', # 0xf1 +'', # 0xf2 +'', # 0xf3 +'', # 0xf4 +'', # 0xf5 +'', # 0xf6 +'', # 0xf7 +'', # 0xf8 +'', # 0xf9 +'', # 0xfa +'', # 0xfb +'', # 0xfc +'[?]', # 0xfd +'[?]', # 0xfe +'', # 0xff +) diff --git a/libs/unidecode/x0ff.py b/libs/unidecode/x0ff.py new file mode 100644 index 00000000..04410151 --- /dev/null +++ b/libs/unidecode/x0ff.py @@ -0,0 +1,258 @@ +data = ( +'[?]', # 0x00 +'!', # 0x01 +'"', # 0x02 +'#', # 0x03 +'$', # 0x04 +'%', # 0x05 +'&', # 0x06 +'\'', # 0x07 +'(', # 0x08 +')', # 0x09 +'*', # 0x0a +'+', # 0x0b +',', # 0x0c +'-', # 0x0d +'.', # 0x0e +'/', # 0x0f +'0', # 0x10 +'1', # 0x11 +'2', # 0x12 +'3', # 0x13 +'4', # 0x14 +'5', # 0x15 +'6', # 0x16 +'7', # 0x17 +'8', # 0x18 +'9', # 0x19 +':', # 0x1a +';', # 0x1b +'<', # 0x1c +'=', # 0x1d +'>', # 0x1e +'?', # 0x1f +'@', # 0x20 +'A', # 0x21 +'B', # 0x22 +'C', # 0x23 +'D', # 0x24 +'E', # 0x25 +'F', # 0x26 +'G', # 0x27 +'H', # 0x28 +'I', # 0x29 +'J', # 0x2a +'K', # 0x2b +'L', # 0x2c +'M', # 0x2d +'N', # 0x2e +'O', # 0x2f +'P', # 0x30 +'Q', # 0x31 +'R', # 0x32 +'S', # 0x33 +'T', # 0x34 +'U', # 0x35 +'V', # 0x36 +'W', # 0x37 +'X', # 0x38 +'Y', # 0x39 +'Z', # 0x3a +'[', # 0x3b +'\\', # 0x3c +']', # 0x3d +'^', # 0x3e +'_', # 0x3f +'`', # 0x40 +'a', # 0x41 +'b', # 0x42 +'c', # 0x43 +'d', # 0x44 +'e', # 0x45 +'f', # 0x46 +'g', # 0x47 +'h', # 0x48 +'i', # 0x49 +'j', # 0x4a +'k', # 0x4b +'l', # 0x4c +'m', # 0x4d +'n', # 0x4e +'o', # 0x4f +'p', # 0x50 +'q', # 0x51 +'r', # 0x52 +'s', # 0x53 +'t', # 0x54 +'u', # 0x55 +'v', # 0x56 +'w', # 0x57 +'x', # 0x58 +'y', # 0x59 +'z', # 0x5a +'{', # 0x5b +'|', # 0x5c +'}', # 0x5d +'~', # 0x5e +'[?]', # 0x5f +'[?]', # 0x60 +'.', # 0x61 +'[', # 0x62 +']', # 0x63 +',', # 0x64 +'*', # 0x65 +'wo', # 0x66 +'a', # 0x67 +'i', # 0x68 +'u', # 0x69 +'e', # 0x6a +'o', # 0x6b +'ya', # 0x6c +'yu', # 0x6d +'yo', # 0x6e +'tu', # 0x6f +'+', # 0x70 +'a', # 0x71 +'i', # 0x72 +'u', # 0x73 +'e', # 0x74 +'o', # 0x75 +'ka', # 0x76 +'ki', # 0x77 +'ku', # 0x78 +'ke', # 0x79 +'ko', # 0x7a +'sa', # 0x7b +'si', # 0x7c +'su', # 0x7d +'se', # 0x7e +'so', # 0x7f +'ta', # 0x80 +'ti', # 0x81 +'tu', # 0x82 +'te', # 0x83 +'to', # 0x84 +'na', # 0x85 +'ni', # 0x86 +'nu', # 0x87 +'ne', # 0x88 +'no', # 0x89 +'ha', # 0x8a +'hi', # 0x8b +'hu', # 0x8c +'he', # 0x8d +'ho', # 0x8e +'ma', # 0x8f +'mi', # 0x90 +'mu', # 0x91 +'me', # 0x92 +'mo', # 0x93 +'ya', # 0x94 +'yu', # 0x95 +'yo', # 0x96 +'ra', # 0x97 +'ri', # 0x98 +'ru', # 0x99 +'re', # 0x9a +'ro', # 0x9b +'wa', # 0x9c +'n', # 0x9d +':', # 0x9e +';', # 0x9f +'', # 0xa0 +'g', # 0xa1 +'gg', # 0xa2 +'gs', # 0xa3 +'n', # 0xa4 +'nj', # 0xa5 +'nh', # 0xa6 +'d', # 0xa7 +'dd', # 0xa8 +'r', # 0xa9 +'lg', # 0xaa +'lm', # 0xab +'lb', # 0xac +'ls', # 0xad +'lt', # 0xae +'lp', # 0xaf +'rh', # 0xb0 +'m', # 0xb1 +'b', # 0xb2 +'bb', # 0xb3 +'bs', # 0xb4 +'s', # 0xb5 +'ss', # 0xb6 +'', # 0xb7 +'j', # 0xb8 +'jj', # 0xb9 +'c', # 0xba +'k', # 0xbb +'t', # 0xbc +'p', # 0xbd +'h', # 0xbe +'[?]', # 0xbf +'[?]', # 0xc0 +'[?]', # 0xc1 +'a', # 0xc2 +'ae', # 0xc3 +'ya', # 0xc4 +'yae', # 0xc5 +'eo', # 0xc6 +'e', # 0xc7 +'[?]', # 0xc8 +'[?]', # 0xc9 +'yeo', # 0xca +'ye', # 0xcb +'o', # 0xcc +'wa', # 0xcd +'wae', # 0xce +'oe', # 0xcf +'[?]', # 0xd0 +'[?]', # 0xd1 +'yo', # 0xd2 +'u', # 0xd3 +'weo', # 0xd4 +'we', # 0xd5 +'wi', # 0xd6 +'yu', # 0xd7 +'[?]', # 0xd8 +'[?]', # 0xd9 +'eu', # 0xda +'yi', # 0xdb +'i', # 0xdc +'[?]', # 0xdd +'[?]', # 0xde +'[?]', # 0xdf +'/C', # 0xe0 +'PS', # 0xe1 +'!', # 0xe2 +'-', # 0xe3 +'|', # 0xe4 +'Y=', # 0xe5 +'W=', # 0xe6 +'[?]', # 0xe7 +'|', # 0xe8 +'-', # 0xe9 +'|', # 0xea +'-', # 0xeb +'|', # 0xec +'#', # 0xed +'O', # 0xee +'[?]', # 0xef +'[?]', # 0xf0 +'[?]', # 0xf1 +'[?]', # 0xf2 +'[?]', # 0xf3 +'[?]', # 0xf4 +'[?]', # 0xf5 +'[?]', # 0xf6 +'[?]', # 0xf7 +'[?]', # 0xf8 +'{', # 0xf9 +'|', # 0xfa +'}', # 0xfb +'', # 0xfc +'', # 0xfd +'', # 0xfe +'', # 0xff +) diff --git a/libs/unidecode/x1d4.py b/libs/unidecode/x1d4.py new file mode 100644 index 00000000..53795931 --- /dev/null +++ b/libs/unidecode/x1d4.py @@ -0,0 +1,258 @@ +data = ( +'A', # 0x00 +'B', # 0x01 +'C', # 0x02 +'D', # 0x03 +'E', # 0x04 +'F', # 0x05 +'G', # 0x06 +'H', # 0x07 +'I', # 0x08 +'J', # 0x09 +'K', # 0x0a +'L', # 0x0b +'M', # 0x0c +'N', # 0x0d +'O', # 0x0e +'P', # 0x0f +'Q', # 0x10 +'R', # 0x11 +'S', # 0x12 +'T', # 0x13 +'U', # 0x14 +'V', # 0x15 +'W', # 0x16 +'X', # 0x17 +'Y', # 0x18 +'Z', # 0x19 +'a', # 0x1a +'b', # 0x1b +'c', # 0x1c +'d', # 0x1d +'e', # 0x1e +'f', # 0x1f +'g', # 0x20 +'h', # 0x21 +'i', # 0x22 +'j', # 0x23 +'k', # 0x24 +'l', # 0x25 +'m', # 0x26 +'n', # 0x27 +'o', # 0x28 +'p', # 0x29 +'q', # 0x2a +'r', # 0x2b +'s', # 0x2c +'t', # 0x2d +'u', # 0x2e +'v', # 0x2f +'w', # 0x30 +'x', # 0x31 +'y', # 0x32 +'z', # 0x33 +'A', # 0x34 +'B', # 0x35 +'C', # 0x36 +'D', # 0x37 +'E', # 0x38 +'F', # 0x39 +'G', # 0x3a +'H', # 0x3b +'I', # 0x3c +'J', # 0x3d +'K', # 0x3e +'L', # 0x3f +'M', # 0x40 +'N', # 0x41 +'O', # 0x42 +'P', # 0x43 +'Q', # 0x44 +'R', # 0x45 +'S', # 0x46 +'T', # 0x47 +'U', # 0x48 +'V', # 0x49 +'W', # 0x4a +'X', # 0x4b +'Y', # 0x4c +'Z', # 0x4d +'a', # 0x4e +'b', # 0x4f +'c', # 0x50 +'d', # 0x51 +'e', # 0x52 +'f', # 0x53 +'g', # 0x54 +'', # 0x55 +'i', # 0x56 +'j', # 0x57 +'k', # 0x58 +'l', # 0x59 +'m', # 0x5a +'n', # 0x5b +'o', # 0x5c +'p', # 0x5d +'q', # 0x5e +'r', # 0x5f +'s', # 0x60 +'t', # 0x61 +'u', # 0x62 +'v', # 0x63 +'w', # 0x64 +'x', # 0x65 +'y', # 0x66 +'z', # 0x67 +'A', # 0x68 +'B', # 0x69 +'C', # 0x6a +'D', # 0x6b +'E', # 0x6c +'F', # 0x6d +'G', # 0x6e +'H', # 0x6f +'I', # 0x70 +'J', # 0x71 +'K', # 0x72 +'L', # 0x73 +'M', # 0x74 +'N', # 0x75 +'O', # 0x76 +'P', # 0x77 +'Q', # 0x78 +'R', # 0x79 +'S', # 0x7a +'T', # 0x7b +'U', # 0x7c +'V', # 0x7d +'W', # 0x7e +'X', # 0x7f +'Y', # 0x80 +'Z', # 0x81 +'a', # 0x82 +'b', # 0x83 +'c', # 0x84 +'d', # 0x85 +'e', # 0x86 +'f', # 0x87 +'g', # 0x88 +'h', # 0x89 +'i', # 0x8a +'j', # 0x8b +'k', # 0x8c +'l', # 0x8d +'m', # 0x8e +'n', # 0x8f +'o', # 0x90 +'p', # 0x91 +'q', # 0x92 +'r', # 0x93 +'s', # 0x94 +'t', # 0x95 +'u', # 0x96 +'v', # 0x97 +'w', # 0x98 +'x', # 0x99 +'y', # 0x9a +'z', # 0x9b +'A', # 0x9c +'', # 0x9d +'C', # 0x9e +'D', # 0x9f +'', # 0xa0 +'', # 0xa1 +'G', # 0xa2 +'', # 0xa3 +'', # 0xa4 +'J', # 0xa5 +'K', # 0xa6 +'', # 0xa7 +'', # 0xa8 +'N', # 0xa9 +'O', # 0xaa +'P', # 0xab +'Q', # 0xac +'', # 0xad +'S', # 0xae +'T', # 0xaf +'U', # 0xb0 +'V', # 0xb1 +'W', # 0xb2 +'X', # 0xb3 +'Y', # 0xb4 +'Z', # 0xb5 +'a', # 0xb6 +'b', # 0xb7 +'c', # 0xb8 +'d', # 0xb9 +'', # 0xba +'f', # 0xbb +'', # 0xbc +'h', # 0xbd +'i', # 0xbe +'j', # 0xbf +'k', # 0xc0 +'l', # 0xc1 +'m', # 0xc2 +'n', # 0xc3 +'', # 0xc4 +'p', # 0xc5 +'q', # 0xc6 +'r', # 0xc7 +'s', # 0xc8 +'t', # 0xc9 +'u', # 0xca +'v', # 0xcb +'w', # 0xcc +'x', # 0xcd +'y', # 0xce +'z', # 0xcf +'A', # 0xd0 +'B', # 0xd1 +'C', # 0xd2 +'D', # 0xd3 +'E', # 0xd4 +'F', # 0xd5 +'G', # 0xd6 +'H', # 0xd7 +'I', # 0xd8 +'J', # 0xd9 +'K', # 0xda +'L', # 0xdb +'M', # 0xdc +'N', # 0xdd +'O', # 0xde +'P', # 0xdf +'Q', # 0xe0 +'R', # 0xe1 +'S', # 0xe2 +'T', # 0xe3 +'U', # 0xe4 +'V', # 0xe5 +'W', # 0xe6 +'X', # 0xe7 +'Y', # 0xe8 +'Z', # 0xe9 +'a', # 0xea +'b', # 0xeb +'c', # 0xec +'d', # 0xed +'e', # 0xee +'f', # 0xef +'g', # 0xf0 +'h', # 0xf1 +'i', # 0xf2 +'j', # 0xf3 +'k', # 0xf4 +'l', # 0xf5 +'m', # 0xf6 +'n', # 0xf7 +'o', # 0xf8 +'p', # 0xf9 +'q', # 0xfa +'r', # 0xfb +'s', # 0xfc +'t', # 0xfd +'u', # 0xfe +'v', # 0xff +) diff --git a/libs/unidecode/x1d5.py b/libs/unidecode/x1d5.py new file mode 100644 index 00000000..6ec605ba --- /dev/null +++ b/libs/unidecode/x1d5.py @@ -0,0 +1,258 @@ +data = ( +'w', # 0x00 +'x', # 0x01 +'y', # 0x02 +'z', # 0x03 +'A', # 0x04 +'B', # 0x05 +'', # 0x06 +'D', # 0x07 +'E', # 0x08 +'F', # 0x09 +'G', # 0x0a +'', # 0x0b +'', # 0x0c +'J', # 0x0d +'K', # 0x0e +'L', # 0x0f +'M', # 0x10 +'N', # 0x11 +'O', # 0x12 +'P', # 0x13 +'Q', # 0x14 +'', # 0x15 +'S', # 0x16 +'T', # 0x17 +'U', # 0x18 +'V', # 0x19 +'W', # 0x1a +'X', # 0x1b +'Y', # 0x1c +'', # 0x1d +'a', # 0x1e +'b', # 0x1f +'c', # 0x20 +'d', # 0x21 +'e', # 0x22 +'f', # 0x23 +'g', # 0x24 +'h', # 0x25 +'i', # 0x26 +'j', # 0x27 +'k', # 0x28 +'l', # 0x29 +'m', # 0x2a +'n', # 0x2b +'o', # 0x2c +'p', # 0x2d +'q', # 0x2e +'r', # 0x2f +'s', # 0x30 +'t', # 0x31 +'u', # 0x32 +'v', # 0x33 +'w', # 0x34 +'x', # 0x35 +'y', # 0x36 +'z', # 0x37 +'A', # 0x38 +'B', # 0x39 +'', # 0x3a +'D', # 0x3b +'E', # 0x3c +'F', # 0x3d +'G', # 0x3e +'', # 0x3f +'I', # 0x40 +'J', # 0x41 +'K', # 0x42 +'L', # 0x43 +'M', # 0x44 +'', # 0x45 +'O', # 0x46 +'', # 0x47 +'', # 0x48 +'', # 0x49 +'S', # 0x4a +'T', # 0x4b +'U', # 0x4c +'V', # 0x4d +'W', # 0x4e +'X', # 0x4f +'Y', # 0x50 +'', # 0x51 +'a', # 0x52 +'b', # 0x53 +'c', # 0x54 +'d', # 0x55 +'e', # 0x56 +'f', # 0x57 +'g', # 0x58 +'h', # 0x59 +'i', # 0x5a +'j', # 0x5b +'k', # 0x5c +'l', # 0x5d +'m', # 0x5e +'n', # 0x5f +'o', # 0x60 +'p', # 0x61 +'q', # 0x62 +'r', # 0x63 +'s', # 0x64 +'t', # 0x65 +'u', # 0x66 +'v', # 0x67 +'w', # 0x68 +'x', # 0x69 +'y', # 0x6a +'z', # 0x6b +'A', # 0x6c +'B', # 0x6d +'C', # 0x6e +'D', # 0x6f +'E', # 0x70 +'F', # 0x71 +'G', # 0x72 +'H', # 0x73 +'I', # 0x74 +'J', # 0x75 +'K', # 0x76 +'L', # 0x77 +'M', # 0x78 +'N', # 0x79 +'O', # 0x7a +'P', # 0x7b +'Q', # 0x7c +'R', # 0x7d +'S', # 0x7e +'T', # 0x7f +'U', # 0x80 +'V', # 0x81 +'W', # 0x82 +'X', # 0x83 +'Y', # 0x84 +'Z', # 0x85 +'a', # 0x86 +'b', # 0x87 +'c', # 0x88 +'d', # 0x89 +'e', # 0x8a +'f', # 0x8b +'g', # 0x8c +'h', # 0x8d +'i', # 0x8e +'j', # 0x8f +'k', # 0x90 +'l', # 0x91 +'m', # 0x92 +'n', # 0x93 +'o', # 0x94 +'p', # 0x95 +'q', # 0x96 +'r', # 0x97 +'s', # 0x98 +'t', # 0x99 +'u', # 0x9a +'v', # 0x9b +'w', # 0x9c +'x', # 0x9d +'y', # 0x9e +'z', # 0x9f +'A', # 0xa0 +'B', # 0xa1 +'C', # 0xa2 +'D', # 0xa3 +'E', # 0xa4 +'F', # 0xa5 +'G', # 0xa6 +'H', # 0xa7 +'I', # 0xa8 +'J', # 0xa9 +'K', # 0xaa +'L', # 0xab +'M', # 0xac +'N', # 0xad +'O', # 0xae +'P', # 0xaf +'Q', # 0xb0 +'R', # 0xb1 +'S', # 0xb2 +'T', # 0xb3 +'U', # 0xb4 +'V', # 0xb5 +'W', # 0xb6 +'X', # 0xb7 +'Y', # 0xb8 +'Z', # 0xb9 +'a', # 0xba +'b', # 0xbb +'c', # 0xbc +'d', # 0xbd +'e', # 0xbe +'f', # 0xbf +'g', # 0xc0 +'h', # 0xc1 +'i', # 0xc2 +'j', # 0xc3 +'k', # 0xc4 +'l', # 0xc5 +'m', # 0xc6 +'n', # 0xc7 +'o', # 0xc8 +'p', # 0xc9 +'q', # 0xca +'r', # 0xcb +'s', # 0xcc +'t', # 0xcd +'u', # 0xce +'v', # 0xcf +'w', # 0xd0 +'x', # 0xd1 +'y', # 0xd2 +'z', # 0xd3 +'A', # 0xd4 +'B', # 0xd5 +'C', # 0xd6 +'D', # 0xd7 +'E', # 0xd8 +'F', # 0xd9 +'G', # 0xda +'H', # 0xdb +'I', # 0xdc +'J', # 0xdd +'K', # 0xde +'L', # 0xdf +'M', # 0xe0 +'N', # 0xe1 +'O', # 0xe2 +'P', # 0xe3 +'Q', # 0xe4 +'R', # 0xe5 +'S', # 0xe6 +'T', # 0xe7 +'U', # 0xe8 +'V', # 0xe9 +'W', # 0xea +'X', # 0xeb +'Y', # 0xec +'Z', # 0xed +'a', # 0xee +'b', # 0xef +'c', # 0xf0 +'d', # 0xf1 +'e', # 0xf2 +'f', # 0xf3 +'g', # 0xf4 +'h', # 0xf5 +'i', # 0xf6 +'j', # 0xf7 +'k', # 0xf8 +'l', # 0xf9 +'m', # 0xfa +'n', # 0xfb +'o', # 0xfc +'p', # 0xfd +'q', # 0xfe +'r', # 0xff +) diff --git a/libs/unidecode/x1d6.py b/libs/unidecode/x1d6.py new file mode 100644 index 00000000..c06a855d --- /dev/null +++ b/libs/unidecode/x1d6.py @@ -0,0 +1,258 @@ +data = ( +'s', # 0x00 +'t', # 0x01 +'u', # 0x02 +'v', # 0x03 +'w', # 0x04 +'x', # 0x05 +'y', # 0x06 +'z', # 0x07 +'A', # 0x08 +'B', # 0x09 +'C', # 0x0a +'D', # 0x0b +'E', # 0x0c +'F', # 0x0d +'G', # 0x0e +'H', # 0x0f +'I', # 0x10 +'J', # 0x11 +'K', # 0x12 +'L', # 0x13 +'M', # 0x14 +'N', # 0x15 +'O', # 0x16 +'P', # 0x17 +'Q', # 0x18 +'R', # 0x19 +'S', # 0x1a +'T', # 0x1b +'U', # 0x1c +'V', # 0x1d +'W', # 0x1e +'X', # 0x1f +'Y', # 0x20 +'Z', # 0x21 +'a', # 0x22 +'b', # 0x23 +'c', # 0x24 +'d', # 0x25 +'e', # 0x26 +'f', # 0x27 +'g', # 0x28 +'h', # 0x29 +'i', # 0x2a +'j', # 0x2b +'k', # 0x2c +'l', # 0x2d +'m', # 0x2e +'n', # 0x2f +'o', # 0x30 +'p', # 0x31 +'q', # 0x32 +'r', # 0x33 +'s', # 0x34 +'t', # 0x35 +'u', # 0x36 +'v', # 0x37 +'w', # 0x38 +'x', # 0x39 +'y', # 0x3a +'z', # 0x3b +'A', # 0x3c +'B', # 0x3d +'C', # 0x3e +'D', # 0x3f +'E', # 0x40 +'F', # 0x41 +'G', # 0x42 +'H', # 0x43 +'I', # 0x44 +'J', # 0x45 +'K', # 0x46 +'L', # 0x47 +'M', # 0x48 +'N', # 0x49 +'O', # 0x4a +'P', # 0x4b +'Q', # 0x4c +'R', # 0x4d +'S', # 0x4e +'T', # 0x4f +'U', # 0x50 +'V', # 0x51 +'W', # 0x52 +'X', # 0x53 +'Y', # 0x54 +'Z', # 0x55 +'a', # 0x56 +'b', # 0x57 +'c', # 0x58 +'d', # 0x59 +'e', # 0x5a +'f', # 0x5b +'g', # 0x5c +'h', # 0x5d +'i', # 0x5e +'j', # 0x5f +'k', # 0x60 +'l', # 0x61 +'m', # 0x62 +'n', # 0x63 +'o', # 0x64 +'p', # 0x65 +'q', # 0x66 +'r', # 0x67 +'s', # 0x68 +'t', # 0x69 +'u', # 0x6a +'v', # 0x6b +'w', # 0x6c +'x', # 0x6d +'y', # 0x6e +'z', # 0x6f +'A', # 0x70 +'B', # 0x71 +'C', # 0x72 +'D', # 0x73 +'E', # 0x74 +'F', # 0x75 +'G', # 0x76 +'H', # 0x77 +'I', # 0x78 +'J', # 0x79 +'K', # 0x7a +'L', # 0x7b +'M', # 0x7c +'N', # 0x7d +'O', # 0x7e +'P', # 0x7f +'Q', # 0x80 +'R', # 0x81 +'S', # 0x82 +'T', # 0x83 +'U', # 0x84 +'V', # 0x85 +'W', # 0x86 +'X', # 0x87 +'Y', # 0x88 +'Z', # 0x89 +'a', # 0x8a +'b', # 0x8b +'c', # 0x8c +'d', # 0x8d +'e', # 0x8e +'f', # 0x8f +'g', # 0x90 +'h', # 0x91 +'i', # 0x92 +'j', # 0x93 +'k', # 0x94 +'l', # 0x95 +'m', # 0x96 +'n', # 0x97 +'o', # 0x98 +'p', # 0x99 +'q', # 0x9a +'r', # 0x9b +'s', # 0x9c +'t', # 0x9d +'u', # 0x9e +'v', # 0x9f +'w', # 0xa0 +'x', # 0xa1 +'y', # 0xa2 +'z', # 0xa3 +'i', # 0xa4 +'j', # 0xa5 +'', # 0xa6 +'', # 0xa7 +'Alpha', # 0xa8 +'Beta', # 0xa9 +'Gamma', # 0xaa +'Delta', # 0xab +'Epsilon', # 0xac +'Zeta', # 0xad +'Eta', # 0xae +'Theta', # 0xaf +'Iota', # 0xb0 +'Kappa', # 0xb1 +'Lamda', # 0xb2 +'Mu', # 0xb3 +'Nu', # 0xb4 +'Xi', # 0xb5 +'Omicron', # 0xb6 +'Pi', # 0xb7 +'Rho', # 0xb8 +'Theta', # 0xb9 +'Sigma', # 0xba +'Tau', # 0xbb +'Upsilon', # 0xbc +'Phi', # 0xbd +'Chi', # 0xbe +'Psi', # 0xbf +'Omega', # 0xc0 +'nabla', # 0xc1 +'alpha', # 0xc2 +'beta', # 0xc3 +'gamma', # 0xc4 +'delta', # 0xc5 +'epsilon', # 0xc6 +'zeta', # 0xc7 +'eta', # 0xc8 +'theta', # 0xc9 +'iota', # 0xca +'kappa', # 0xcb +'lamda', # 0xcc +'mu', # 0xcd +'nu', # 0xce +'xi', # 0xcf +'omicron', # 0xd0 +'pi', # 0xd1 +'rho', # 0xd2 +'sigma', # 0xd3 +'sigma', # 0xd4 +'tai', # 0xd5 +'upsilon', # 0xd6 +'phi', # 0xd7 +'chi', # 0xd8 +'psi', # 0xd9 +'omega', # 0xda +'', # 0xdb +'', # 0xdc +'', # 0xdd +'', # 0xde +'', # 0xdf +'', # 0xe0 +'', # 0xe1 +'', # 0xe2 +'', # 0xe3 +'', # 0xe4 +'', # 0xe5 +'', # 0xe6 +'', # 0xe7 +'', # 0xe8 +'', # 0xe9 +'', # 0xea +'', # 0xeb +'', # 0xec +'', # 0xed +'', # 0xee +'', # 0xef +'', # 0xf0 +'', # 0xf1 +'', # 0xf2 +'', # 0xf3 +'', # 0xf4 +'', # 0xf5 +'', # 0xf6 +'', # 0xf7 +'', # 0xf8 +'', # 0xf9 +'', # 0xfa +'', # 0xfb +'', # 0xfc +'', # 0xfd +'', # 0xfe +'', # 0xff +) diff --git a/libs/unidecode/x1d7.py b/libs/unidecode/x1d7.py new file mode 100644 index 00000000..6943bf45 --- /dev/null +++ b/libs/unidecode/x1d7.py @@ -0,0 +1,258 @@ +data = ( +'', # 0x00 +'', # 0x01 +'', # 0x02 +'', # 0x03 +'', # 0x04 +'', # 0x05 +'', # 0x06 +'', # 0x07 +'', # 0x08 +'', # 0x09 +'', # 0x0a +'', # 0x0b +'', # 0x0c +'', # 0x0d +'', # 0x0e +'', # 0x0f +'', # 0x10 +'', # 0x11 +'', # 0x12 +'', # 0x13 +'', # 0x14 +'', # 0x15 +'', # 0x16 +'', # 0x17 +'', # 0x18 +'', # 0x19 +'', # 0x1a +'', # 0x1b +'', # 0x1c +'', # 0x1d +'', # 0x1e +'', # 0x1f +'', # 0x20 +'', # 0x21 +'', # 0x22 +'', # 0x23 +'', # 0x24 +'', # 0x25 +'', # 0x26 +'', # 0x27 +'', # 0x28 +'', # 0x29 +'', # 0x2a +'', # 0x2b +'', # 0x2c +'', # 0x2d +'', # 0x2e +'', # 0x2f +'', # 0x30 +'', # 0x31 +'', # 0x32 +'', # 0x33 +'', # 0x34 +'', # 0x35 +'', # 0x36 +'', # 0x37 +'', # 0x38 +'', # 0x39 +'', # 0x3a +'', # 0x3b +'', # 0x3c +'', # 0x3d +'', # 0x3e +'', # 0x3f +'', # 0x40 +'', # 0x41 +'', # 0x42 +'', # 0x43 +'', # 0x44 +'', # 0x45 +'', # 0x46 +'', # 0x47 +'', # 0x48 +'', # 0x49 +'', # 0x4a +'', # 0x4b +'', # 0x4c +'', # 0x4d +'', # 0x4e +'', # 0x4f +'', # 0x50 +'', # 0x51 +'', # 0x52 +'', # 0x53 +'', # 0x54 +'', # 0x55 +'', # 0x56 +'', # 0x57 +'', # 0x58 +'', # 0x59 +'', # 0x5a +'', # 0x5b +'', # 0x5c +'', # 0x5d +'', # 0x5e +'', # 0x5f +'', # 0x60 +'', # 0x61 +'', # 0x62 +'', # 0x63 +'', # 0x64 +'', # 0x65 +'', # 0x66 +'', # 0x67 +'', # 0x68 +'', # 0x69 +'', # 0x6a +'', # 0x6b +'', # 0x6c +'', # 0x6d +'', # 0x6e +'', # 0x6f +'', # 0x70 +'', # 0x71 +'', # 0x72 +'', # 0x73 +'', # 0x74 +'', # 0x75 +'', # 0x76 +'', # 0x77 +'', # 0x78 +'', # 0x79 +'', # 0x7a +'', # 0x7b +'', # 0x7c +'', # 0x7d +'', # 0x7e +'', # 0x7f +'', # 0x80 +'', # 0x81 +'', # 0x82 +'', # 0x83 +'', # 0x84 +'', # 0x85 +'', # 0x86 +'', # 0x87 +'', # 0x88 +'', # 0x89 +'', # 0x8a +'', # 0x8b +'', # 0x8c +'', # 0x8d +'', # 0x8e +'', # 0x8f +'', # 0x90 +'', # 0x91 +'', # 0x92 +'', # 0x93 +'', # 0x94 +'', # 0x95 +'', # 0x96 +'', # 0x97 +'', # 0x98 +'', # 0x99 +'', # 0x9a +'', # 0x9b +'', # 0x9c +'', # 0x9d +'', # 0x9e +'', # 0x9f +'', # 0xa0 +'', # 0xa1 +'', # 0xa2 +'', # 0xa3 +'', # 0xa4 +'', # 0xa5 +'', # 0xa6 +'', # 0xa7 +'', # 0xa8 +'', # 0xa9 +'', # 0xaa +'', # 0xab +'', # 0xac +'', # 0xad +'', # 0xae +'', # 0xaf +'', # 0xb0 +'', # 0xb1 +'', # 0xb2 +'', # 0xb3 +'', # 0xb4 +'', # 0xb5 +'', # 0xb6 +'', # 0xb7 +'', # 0xb8 +'', # 0xb9 +'', # 0xba +'', # 0xbb +'', # 0xbc +'', # 0xbd +'', # 0xbe +'', # 0xbf +'', # 0xc0 +'', # 0xc1 +'', # 0xc2 +'', # 0xc3 +'', # 0xc4 +'', # 0xc5 +'', # 0xc6 +'', # 0xc7 +'', # 0xc8 +'', # 0xc9 +'', # 0xca +'', # 0xcb +'', # 0xcc +'', # 0xcd +'0', # 0xce +'1', # 0xcf +'2', # 0xd0 +'3', # 0xd1 +'4', # 0xd2 +'5', # 0xd3 +'6', # 0xd4 +'7', # 0xd5 +'8', # 0xd6 +'9', # 0xd7 +'0', # 0xd8 +'1', # 0xd9 +'2', # 0xda +'3', # 0xdb +'4', # 0xdc +'5', # 0xdd +'6', # 0xde +'7', # 0xdf +'8', # 0xe0 +'9', # 0xe1 +'0', # 0xe2 +'1', # 0xe3 +'2', # 0xe4 +'3', # 0xe5 +'4', # 0xe6 +'5', # 0xe7 +'6', # 0xe8 +'7', # 0xe9 +'8', # 0xea +'9', # 0xeb +'0', # 0xec +'1', # 0xed +'2', # 0xee +'3', # 0xef +'4', # 0xf0 +'5', # 0xf1 +'6', # 0xf2 +'7', # 0xf3 +'8', # 0xf4 +'9', # 0xf5 +'0', # 0xf6 +'1', # 0xf7 +'2', # 0xf8 +'3', # 0xf9 +'4', # 0xfa +'5', # 0xfb +'6', # 0xfc +'7', # 0xfd +'8', # 0xfe +'9', # 0xff +) diff --git a/nzbToMedia.py b/nzbToMedia.py index 389e7a60..930dc967 100755 --- a/nzbToMedia.py +++ b/nzbToMedia.py @@ -282,7 +282,7 @@ from nzbtomedia.autoProcess.autoProcessGames import autoProcessGames from nzbtomedia.autoProcess.autoProcessMovie import autoProcessMovie from nzbtomedia.autoProcess.autoProcessMusic import autoProcessMusic from nzbtomedia.autoProcess.autoProcessTV import autoProcessTV -from nzbtomedia.nzbToMediaUtil import get_dirnames, extractFiles, cleanProcDirs, update_downloadInfoStatus, get_downloadInfo +from nzbtomedia.nzbToMediaUtil import getDirs, extractFiles, cleanProcDirs, update_downloadInfoStatus, get_downloadInfo from nzbtomedia import logger, nzbToMediaDB # post-processing @@ -438,7 +438,7 @@ def main(args, section=None): for section, subsection in nzbtomedia.SUBSECTIONS.items(): for category in subsection: if nzbtomedia.CFG[section][category].isenabled(): - dirNames = get_dirnames(section, category) + dirNames = getDirs(section, category) for dirName in dirNames: clientAgent = 'manual' download_id = None diff --git a/nzbtomedia/__init__.py b/nzbtomedia/__init__.py index cf3e3214..960383f1 100644 --- a/nzbtomedia/__init__.py +++ b/nzbtomedia/__init__.py @@ -27,9 +27,9 @@ from nzbtomedia.autoProcess.autoProcessMusic import autoProcessMusic from nzbtomedia.autoProcess.autoProcessTV import autoProcessTV from nzbtomedia import logger, versionCheck, nzbToMediaDB from nzbtomedia.nzbToMediaConfig import config -from nzbtomedia.nzbToMediaUtil import category_search, sanitizeFileName, copy_link, parse_args, flatten, get_dirnames, \ - remove_read_only, pause_torrent, resume_torrent, remove_torrent, listMediaFiles, joinPath, \ - extractFiles, cleanProcDirs, update_downloadInfoStatus, get_downloadInfo, WakeUp, makeDir, joinPath, cleanProcDirs, \ +from nzbtomedia.nzbToMediaUtil import category_search, sanitizeName, copy_link, parse_args, flatten, getDirs, \ + rmReadOnly,rmDir, pause_torrent, resume_torrent, remove_torrent, listMediaFiles, \ + extractFiles, cleanProcDirs, update_downloadInfoStatus, get_downloadInfo, WakeUp, makeDir, cleanProcDirs, \ create_torrent_class, listMediaFiles from nzbtomedia.transcoder import transcoder from nzbtomedia.databases import mainDB @@ -289,8 +289,8 @@ def initialize(section=None): # Setup FFMPEG and FFPROBE locations if platform.system() == 'Windows': - FFMPEG = joinPath(FFMPEG_PATH, 'ffmpeg.exe') - FFPROBE = joinPath(FFMPEG_PATH, 'ffprobe.exe') + FFMPEG = os.path.join(FFMPEG_PATH, 'ffmpeg.exe') + FFPROBE = os.path.join(FFMPEG_PATH, 'ffprobe.exe') if not (os.path.isfile(FFMPEG)): # problem FFMPEG = None diff --git a/nzbtomedia/autoProcess/autoProcessComics.py b/nzbtomedia/autoProcess/autoProcessComics.py index 4825d7ee..2a0bf093 100644 --- a/nzbtomedia/autoProcess/autoProcessComics.py +++ b/nzbtomedia/autoProcess/autoProcessComics.py @@ -2,7 +2,7 @@ import os import time import nzbtomedia import requests -from nzbtomedia.nzbToMediaUtil import convert_to_ascii, joinPath +from nzbtomedia.nzbToMediaUtil import convert_to_ascii from nzbtomedia import logger class autoProcessComics: @@ -39,7 +39,7 @@ class autoProcessComics: params = {} params['nzb_folder'] = dirName if remote_path: - params['nzb_folder'] = joinPath(remote_path, os.path.basename(dirName)) + params['nzb_folder'] = os.path.join(remote_path, os.path.basename(dirName)) if inputName != None: params['nzb_name'] = inputName diff --git a/nzbtomedia/autoProcess/autoProcessMovie.py b/nzbtomedia/autoProcess/autoProcessMovie.py index 45731063..72481876 100644 --- a/nzbtomedia/autoProcess/autoProcessMovie.py +++ b/nzbtomedia/autoProcess/autoProcessMovie.py @@ -4,7 +4,7 @@ import requests import nzbtomedia from nzbtomedia.nzbToMediaSceneExceptions import process_all_exceptions -from nzbtomedia.nzbToMediaUtil import convert_to_ascii, rmDir, find_imdbid, find_download, joinPath, listMediaFiles +from nzbtomedia.nzbToMediaUtil import convert_to_ascii, rmDir, find_imdbid, find_download, listMediaFiles from nzbtomedia import logger from nzbtomedia.transcoder import transcoder @@ -169,7 +169,7 @@ class autoProcessMovie: params['media_folder'] = dirName if remote_path: - params['media_folder'] = joinPath(remote_path, os.path.basename(dirName)) + params['media_folder'] = os.path.join(remote_path, os.path.basename(dirName)) url = "%s%s" % (baseURL, command) diff --git a/nzbtomedia/autoProcess/autoProcessMusic.py b/nzbtomedia/autoProcess/autoProcessMusic.py index 8398f166..7bf885d7 100644 --- a/nzbtomedia/autoProcess/autoProcessMusic.py +++ b/nzbtomedia/autoProcess/autoProcessMusic.py @@ -3,7 +3,7 @@ import time import requests import nzbtomedia -from nzbtomedia.nzbToMediaUtil import convert_to_ascii, joinPath +from nzbtomedia.nzbToMediaUtil import convert_to_ascii from nzbtomedia import logger class autoProcessMusic: @@ -75,7 +75,7 @@ class autoProcessMusic: params['dir'] = os.path.dirname(dirName) if remote_path: - params['dir'] = joinPath(remote_path, os.path.basename(os.path.dirname(dirName))) + params['dir'] = os.path.join(remote_path, os.path.basename(os.path.dirname(dirName))) release_status = self.get_status(url, apikey, dirName) if not release_status: diff --git a/nzbtomedia/autoProcess/autoProcessTV.py b/nzbtomedia/autoProcess/autoProcessTV.py index 4171b940..d14448d7 100644 --- a/nzbtomedia/autoProcess/autoProcessTV.py +++ b/nzbtomedia/autoProcess/autoProcessTV.py @@ -5,7 +5,7 @@ import nzbtomedia from nzbtomedia.nzbToMediaAutoFork import autoFork from nzbtomedia.nzbToMediaSceneExceptions import process_all_exceptions -from nzbtomedia.nzbToMediaUtil import convert_to_ascii, flatten, rmDir, joinPath, listMediaFiles +from nzbtomedia.nzbToMediaUtil import convert_to_ascii, flatten, rmDir, listMediaFiles from nzbtomedia import logger from nzbtomedia.transcoder import transcoder @@ -64,7 +64,7 @@ class autoProcessTV: if not os.path.isdir(dirName) and os.path.isfile(dirName): # If the input directory is a file, assume single file download and split dir/name. dirName = os.path.split(os.path.normpath(dirName))[0] - SpecificPath = joinPath(dirName, str(inputName)) + SpecificPath = os.path.join(dirName, str(inputName)) cleanName = os.path.splitext(SpecificPath) if cleanName[1] == ".nzb": SpecificPath = cleanName[0] @@ -99,7 +99,7 @@ class autoProcessTV: if param in ["dirName", "dir"]: fork_params[param] = dirName if remote_path: - fork_params[param] = joinPath(remote_path, os.path.basename(dirName)) + fork_params[param] = os.path.join(remote_path, os.path.basename(dirName)) if param == "process_method": if process_method: diff --git a/nzbtomedia/extractor/extractor.py b/nzbtomedia/extractor/extractor.py index 1f09f5c1..e8b6795c 100644 --- a/nzbtomedia/extractor/extractor.py +++ b/nzbtomedia/extractor/extractor.py @@ -7,8 +7,8 @@ from subprocess import call, Popen def extract(filePath, outputDestination): # Using Windows if platform.system() == 'Windows': - chplocation = nzbtomedia.joinPath(nzbtomedia.PROGRAM_DIR, 'nzbtomedia/extractor/bin/chp.exe') - sevenzipLocation = nzbtomedia.joinPath(nzbtomedia.PROGRAM_DIR, 'nzbtomedia/extractor/bin/' + platform.machine() + '/7z.exe') + chplocation = nzbtomedia.os.path.join(nzbtomedia.PROGRAM_DIR, 'nzbtomedia/extractor/bin/chp.exe') + sevenzipLocation = nzbtomedia.os.path.join(nzbtomedia.PROGRAM_DIR, 'nzbtomedia/extractor/bin/' + platform.machine() + '/7z.exe') if not os.path.exists(sevenzipLocation): nzbtomedia.logger.error("EXTRACTOR: Could not find 7-zip, Exiting") diff --git a/nzbtomedia/linktastic/linktastic.py b/nzbtomedia/linktastic/linktastic.py index cfbcdc1f..9e5e96ed 100644 --- a/nzbtomedia/linktastic/linktastic.py +++ b/nzbtomedia/linktastic/linktastic.py @@ -58,6 +58,29 @@ def _symlink_windows(src, dest): # print(stdout) # assume if they ret-coded 0 we're good +def _dirlink_windows(src, dest): + try: + subprocess.check_output( + 'cmd /C mklink /J %s %s' % (_escape_param(dest), _escape_param(src)), + stderr=subprocess.STDOUT) + except CalledProcessError as err: + raise IOError(err.output.decode('utf-8')) + + # TODO, find out what kind of messages Windows sends us from mklink + # print(stdout) + # assume if they ret-coded 0 we're good + +def _junctionlink_windows(src, dest): + try: + subprocess.check_output( + 'cmd /C mklink /D %s %s' % (_escape_param(dest), _escape_param(src)), + stderr=subprocess.STDOUT) + except CalledProcessError as err: + raise IOError(err.output.decode('utf-8')) + + # TODO, find out what kind of messages Windows sends us from mklink + # print(stdout) + # assume if they ret-coded 0 we're good # Create a hard link to src named as dest # This version of link, unlike os.link, supports nt systems as well @@ -74,3 +97,17 @@ def symlink(src, dest): _symlink_windows(src, dest) else: os.symlink(src, dest) + +# Create a symlink to src named as dest, but don't fail if you're on nt +def dirlink(src, dest): + if os.name == 'nt': + _dirlink_windows(src, dest) + else: + os.symlink(src, dest) + +# Create a symlink to src named as dest, but don't fail if you're on nt +def junctionlink(src, dest): + if os.name == 'nt': + _junctionlink_windows(src, dest) + else: + os.symlink(src, dest) \ No newline at end of file diff --git a/nzbtomedia/nzbToMediaDB.py b/nzbtomedia/nzbToMediaDB.py index 6cdf629b..cece2cde 100644 --- a/nzbtomedia/nzbToMediaDB.py +++ b/nzbtomedia/nzbToMediaDB.py @@ -17,7 +17,7 @@ def dbFilename(filename="nzbtomedia.db", suffix=None): """ if suffix: filename = "%s.%s" % (filename, suffix) - return nzbtomedia.joinPath(nzbtomedia.PROGRAM_DIR, filename) + return nzbtomedia.os.path.join(nzbtomedia.PROGRAM_DIR, filename) class DBConnection: diff --git a/nzbtomedia/nzbToMediaSceneExceptions.py b/nzbtomedia/nzbToMediaSceneExceptions.py index 01f74f95..36c40970 100644 --- a/nzbtomedia/nzbToMediaSceneExceptions.py +++ b/nzbtomedia/nzbToMediaSceneExceptions.py @@ -1,6 +1,5 @@ import os import logging -from nzbtomedia.nzbToMediaUtil import listMediaFiles, joinPath Logger = logging.getLogger() @@ -20,7 +19,7 @@ def process_qoq(filename, dirname): head, fileExtension = os.path.splitext(os.path.basename(filename)) newname = head[::-1] newfile = newname + fileExtension - newfilePath = joinPath(dirname, newfile) + newfilePath = os.path.join(dirname, newfile) os.rename(filename, newfilePath) logging.debug("New file name is %s", newfile) diff --git a/nzbtomedia/nzbToMediaUtil.py b/nzbtomedia/nzbToMediaUtil.py index 5bfbf3ef..3eb42325 100644 --- a/nzbtomedia/nzbToMediaUtil.py +++ b/nzbtomedia/nzbToMediaUtil.py @@ -7,6 +7,7 @@ import shutil import time import datetime import guessit +import beets import requests import nzbtomedia @@ -17,15 +18,15 @@ from nzbtomedia.utorrent.client import UTorrentClient from nzbtomedia.transmissionrpc.client import Client as TransmissionClient from nzbtomedia import logger, nzbToMediaDB -def sanitizeFileName(name): +def sanitizeName(name): ''' - >>> sanitizeFileName('a/b/c') + >>> sanitizeName('a/b/c') 'a-b-c' - >>> sanitizeFileName('abc') + >>> sanitizeName('abc') 'abc' - >>> sanitizeFileName('a"b') + >>> sanitizeName('a"b') 'ab' - >>> sanitizeFileName('.a.b..') + >>> sanitizeName('.a.b..') 'a.b' ''' @@ -42,13 +43,10 @@ def makeDir(path): if not os.path.isdir(path): try: os.makedirs(path) - except OSError: + except Exception, e: return False return True -def joinPath(path, *paths): - return os.path.join(path, *paths).replace('\\','/') - def category_search(inputDirectory, inputName, inputCategory, root, categories): single = False tordir = False @@ -70,20 +68,20 @@ def category_search(inputDirectory, inputName, inputCategory, root, categories): if not inputName: inputName = os.path.split(os.path.normpath(inputDirectory))[1] return inputDirectory, inputName, inputCategory, root, single - if inputCategory and os.path.isdir(joinPath(inputDirectory, inputCategory)): + if inputCategory and os.path.isdir(os.path.join(inputDirectory, inputCategory)): logger.info( "SEARCH: Found category directory %s in input directory directory %s" % (inputCategory, inputDirectory)) - inputDirectory = joinPath(inputDirectory, inputCategory) + inputDirectory = os.path.join(inputDirectory, inputCategory) logger.info("SEARCH: Setting inputDirectory to %s" % (inputDirectory)) - if inputName and os.path.isdir(joinPath(inputDirectory, inputName)): + if inputName and os.path.isdir(os.path.join(inputDirectory, inputName)): logger.info("SEARCH: Found torrent directory %s in input directory directory %s" % (inputName, inputDirectory)) - inputDirectory = joinPath(inputDirectory, inputName) + inputDirectory = os.path.join(inputDirectory, inputName) logger.info("SEARCH: Setting inputDirectory to %s" % (inputDirectory)) tordir = True - if inputName and os.path.isdir(joinPath(inputDirectory, sanitizeFileName(inputName))): + if inputName and os.path.isdir(os.path.join(inputDirectory, sanitizeName(inputName))): logger.info("SEARCH: Found torrent directory %s in input directory directory %s" % ( - sanitizeFileName(inputName), inputDirectory)) - inputDirectory = joinPath(inputDirectory, sanitizeFileName(inputName)) + sanitizeName(inputName), inputDirectory)) + inputDirectory = os.path.join(inputDirectory, sanitizeName(inputName)) logger.info("SEARCH: Setting inputDirectory to %s" % (inputDirectory)) tordir = True @@ -103,7 +101,7 @@ def category_search(inputDirectory, inputName, inputCategory, root, categories): pass if inputName and not tordir: - if inputName in pathlist or sanitizeFileName(inputName) in pathlist: + if inputName in pathlist or sanitizeName(inputName) in pathlist: logger.info("SEARCH: Found torrent directory %s in the directory structure" % (inputName)) tordir = True else: @@ -140,44 +138,44 @@ def is_sample(inputName): if re.search('(^|[\W_])sample\d*[\W_]', inputName.lower()): return True -def copy_link(filePath, targetDirectory, useLink, outputDestination): - if os.path.isfile(targetDirectory): - logger.info("%s already exists. skipping ..." % (targetDirectory), 'COPYLINK') +def copy_link(src, targetLink, useLink): + if os.path.exists(targetLink): + logger.info("%s already exists. skipping ..." % (os.path.basename(targetLink)), 'COPYLINK') return True - makeDir(outputDestination) - if useLink == "hard": - try: - logger.info("Hard linking %s to %s" % (filePath, targetDirectory), 'COPYLINK') - linktastic.link(filePath, targetDirectory) - except: - if os.path.isfile(targetDirectory): - logger.warning( - "Something went wrong in linktastic.link, but the destination file was created", 'COPYLINK') - else: - logger.warning("Something went wrong in linktastic.link, copying instead", 'COPYLINK') - logger.debug("Copying %s to %s" % (filePath, targetDirectory), 'COPYLINK') - shutil.copy(filePath, targetDirectory) - elif useLink == "sym": - try: - logger.info("Moving %s to %s before sym linking" % (filePath, targetDirectory), 'COPYLINK') - shutil.move(filePath, targetDirectory) - logger.info("Sym linking %s to %s" % (targetDirectory, filePath), 'COPYLINK') - linktastic.symlink(targetDirectory, filePath) - except: - if os.path.isfile(targetDirectory): - logger.warning( - "Something went wrong in linktastic.link, but the destination file was created", 'COPYLINK') - else: - logger.info("Something went wrong in linktastic.link, copying instead", 'COPYLINK') - logger.debug("Copying %s to %s" % (filePath, targetDirectory), 'COPYLINK') - shutil.copy(filePath, targetDirectory) - elif useLink == "move": - logger.debug("Moving %s to %s" % (filePath, targetDirectory)) - shutil.move(filePath, targetDirectory) - else: - logger.debug("Copying %s to %s" % (filePath, targetDirectory)) - shutil.copy(filePath, targetDirectory) + makeDir(os.path.dirname(targetLink)) + + try: + if useLink == 'dir': + logger.info("Directory linking %s to %s" % (src, targetLink), 'COPYLINK') + linktastic.dirlink(src, targetLink) + return True + if useLink == 'junction': + logger.info("Directory junction linking %s to %s" % (src, targetLink), 'COPYLINK') + linktastic.dirlink(src, targetLink) + return True + elif useLink == "hard": + logger.info("Hard linking %s to %s" % (src, targetLink), 'COPYLINK') + linktastic.link(src, targetLink) + return True + elif useLink == "sym": + logger.info("Moving %s to %s before sym linking" % (src, targetLink), 'COPYLINK') + shutil.move(src, targetLink) + logger.info("Sym linking %s to %s" % (targetLink, src), 'COPYLINK') + linktastic.symlink(targetLink, src) + return True + elif useLink == "move": + logger.debug("Moving %s to %s" % (src, targetLink)) + shutil.move(src, targetLink) + return True + except Exception, e: + logger.warning("Error: %s, copying instead ... " % (e), 'COPYLINK') + logger.debug("Copying %s to %s" % (src, targetLink), 'COPYLINK') + shutil.copy(src, targetLink) + + logger.debug("Copying %s to %s" % (src, targetLink)) + shutil.copy(src, targetLink) + return True @@ -190,7 +188,7 @@ def flatten(outputDestination): if dirPath == outputDestination: continue - target = joinPath(outputDestination, fileName) + target = os.path.join(outputDestination, fileName) try: shutil.move(outputFile, target) @@ -208,7 +206,7 @@ def removeEmptyFolders(path): files = os.listdir(path) if len(files): for f in files: - fullpath = joinPath(path, f) + fullpath = os.path.join(path, f) if os.path.isdir(fullpath): removeEmptyFolders(fullpath) @@ -218,14 +216,17 @@ def removeEmptyFolders(path): logger.debug("Removing empty folder: %s" % (path), 'REMOVER') os.rmdir(path) -def remove_read_only(path): - if not os.path.isdir(path): - return - for dirpath, dirnames, filenames in os.walk(path): - for filename in filenames: - logger.debug("Removing Read Only Flag for: %s" % (filename)) - os.chmod(joinPath(dirpath, filename), stat.S_IWRITE) - +def rmReadOnly(filename): + if os.path.isfile(filename): + #check first the read-only attribute + file_attribute = os.stat(filename)[0] + if (not file_attribute & stat.S_IWRITE): + # File is read-only, so make it writeable + logger.debug('Read only mode on file ' + filename + ' Will try to make it writeable') + try: + os.chmod(filename, stat.S_IWRITE) + except: + logger.warning('Cannot change permissions of ' + filename, logger.WARNING) #Wake function def WakeOnLan(ethernet_address): @@ -381,8 +382,8 @@ def parse_args(clientAgent, args): return None, None, None, None, None -def get_dirnames(section, subsections=None): - dirNames = [] +def getDirs(section, subsections=None): + to_return = [] if subsections is None: subsections = nzbtomedia.SUBSECTIONS[section].sections @@ -390,52 +391,66 @@ def get_dirnames(section, subsections=None): if not isinstance(subsections, list): subsections = [subsections] + def processDir(path): + folders = [] + # search for single files and move them into there own folder for post-processing + for mediafile in listMediaFiles(path): + parentDir = os.path.dirname(mediafile) + if parentDir == path: + newPath = None + fileExt = os.path.splitext(os.path.basename(mediafile))[1] + + try: + if fileExt in nzbtomedia.AUDIOCONTAINER: + f = beets.mediafile.MediaFile(mediafile) + + # get artist and album info + artist = f.artist + album = f.album + + # create new path + newPath = os.path.join(parentDir, "%s - %s" % (sanitizeName(artist), sanitizeName(album))) + elif fileExt in nzbtomedia.MEDIACONTAINER: + f = guessit.guess_video_info(mediafile) + + # get title + title = None + try: + title = f['series'] + except: + title = f['title'] + + if not title: + title = os.path.basename(mediafile) + + newPath = os.path.join(parentDir, sanitizeName(title)) + except Exception, e: + logger.info("Exception from MediaFile for: %s: %s" % (dir, e)) + + # create new path if it does not exist + if not os.path.exists(newPath): + makeDir(newPath) + + # move file to its new path + shutil.move(mediafile, newPath) + + folders.extend([os.path.join(path, o) for o in os.listdir(path) if + os.path.isdir(os.path.join(path, o))]) + return folders + for subsection in subsections: - try: - watch_dir = nzbtomedia.CFG[section][subsection]["watch_dir"] - if not os.path.exists(watch_dir): - watch_dir = None - except: - watch_dir = None + watch_dir = os.path.abspath(nzbtomedia.CFG[section][subsection]["watch_dir"]) + if os.path.exists(watch_dir): + to_return.extend(processDir(watch_dir)) - try: - outputDirectory = joinPath(nzbtomedia.OUTPUTDIRECTORY, subsection) - if not os.path.exists(outputDirectory): - outputDirectory = None - except: - outputDirectory = None + outputDirectory = os.path.join(nzbtomedia.OUTPUTDIRECTORY, subsection) + if os.path.exists(outputDirectory): + to_return.extend(processDir(outputDirectory)) - if watch_dir: - # search for single files and move them into there own folder for post-processing - for mediafile in listMediaFiles(watch_dir): - parentDir = os.path.dirname(mediafile) - if parentDir == watch_dir: - p = joinPath(parentDir, (os.path.splitext(os.path.splitext(mediafile)[0])[0])) - if not os.path.exists(p): - os.mkdir(p) - shutil.move(mediafile, p) - - dirNames.extend([joinPath(watch_dir, o) for o in os.listdir(watch_dir) if - os.path.isdir(joinPath(watch_dir, o))]) - - if outputDirectory: - # search for single files and move them into there own folder for post-processing - for mediafile in listMediaFiles(outputDirectory): - parentDir = os.path.dirname(mediafile) - if parentDir == outputDirectory: - p = joinPath(parentDir, (os.path.splitext(os.path.splitext(mediafile)[0])[0])) - if not os.path.exists(p): - os.mkdir(p) - shutil.move(mediafile, p) - - dirNames.extend([joinPath(outputDirectory, o) for o in os.listdir(outputDirectory) if - os.path.isdir(joinPath(outputDirectory, o))]) - - if not dirNames: + if not to_return: logger.debug("No directories identified in %s for post-processing" % (subsection), section) - return list(set(dirNames)) - + return list(set(to_return)) def rmDir(dirName): logger.info("Deleting %s" % (dirName)) @@ -449,7 +464,7 @@ def cleanProcDirs(): for section, subsection in nzbtomedia.SUBSECTIONS.items(): for category in subsection: if nzbtomedia.CFG[section][category].isenabled(): - dirNames = get_dirnames(section, category) + dirNames = getDirs(section, category) for dirName in dirNames: try: minSize = int(nzbtomedia.CFG[section][category]['minSize']) @@ -606,12 +621,12 @@ def isMediaFile(mediafile, media=True, audio=True, meta=True, archives=True): return False def listMediaFiles(path, minSize=0, delete_ignored=0, media=True, audio=True, meta=True, archives=True): - if not dir or not os.path.isdir(path): + if not os.path.isdir(path): return [] files = [] for curFile in os.listdir(path): - fullCurFile = joinPath(path, curFile) + fullCurFile = os.path.join(path, curFile) # if it's a folder do it recursively if os.path.isdir(fullCurFile) and not curFile.startswith('.'): diff --git a/nzbtomedia/versionCheck.py b/nzbtomedia/versionCheck.py index 13a6b86d..7a647e23 100644 --- a/nzbtomedia/versionCheck.py +++ b/nzbtomedia/versionCheck.py @@ -14,8 +14,6 @@ import gh_api as github import nzbtomedia from nzbtomedia import logger -from nzbtomedia.nzbToMediaUtil import joinPath - class CheckVersion(): """ @@ -48,7 +46,7 @@ class CheckVersion(): """ # check if we're a windows build - if os.path.isdir(joinPath(nzbtomedia.PROGRAM_DIR, u'.git')): + if os.path.isdir(os.path.join(nzbtomedia.PROGRAM_DIR, u'.git')): install_type = 'git' else: install_type = 'source' @@ -337,7 +335,7 @@ class SourceUpdateManager(UpdateManager): def _find_installed_version(self): - version_file = joinPath(nzbtomedia.PROGRAM_DIR, u'version.txt') + version_file = os.path.join(nzbtomedia.PROGRAM_DIR, u'version.txt') if not os.path.isfile(version_file): self._cur_commit_hash = None @@ -433,11 +431,11 @@ class SourceUpdateManager(UpdateManager): """ base_url = 'https://github.com/' + self.github_repo_user + '/' + self.github_repo tar_download_url = base_url + '/tarball/' + self.branch - version_path = joinPath(nzbtomedia.PROGRAM_DIR, u'version.txt') + version_path = os.path.join(nzbtomedia.PROGRAM_DIR, u'version.txt') try: # prepare the update dir - sb_update_dir = joinPath(nzbtomedia.PROGRAM_DIR, u'sb-update') + sb_update_dir = os.path.join(nzbtomedia.PROGRAM_DIR, u'sb-update') if os.path.isdir(sb_update_dir): logger.log(u"Clearing out update folder " + sb_update_dir + " before extracting") @@ -448,7 +446,7 @@ class SourceUpdateManager(UpdateManager): # retrieve file logger.log(u"Downloading update from " + repr(tar_download_url)) - tar_download_path = joinPath(sb_update_dir, u'nzbtomedia-update.tar') + tar_download_path = os.path.join(sb_update_dir, u'nzbtomedia-update.tar') urllib.urlretrieve(tar_download_url, tar_download_path) if not os.path.isfile(tar_download_path): @@ -471,19 +469,19 @@ class SourceUpdateManager(UpdateManager): # find update dir name update_dir_contents = [x for x in os.listdir(sb_update_dir) if - os.path.isdir(joinPath(sb_update_dir, x))] + os.path.isdir(os.path.join(sb_update_dir, x))] if len(update_dir_contents) != 1: logger.log(u"Invalid update data, update failed: " + str(update_dir_contents), logger.ERROR) return False - content_dir = joinPath(sb_update_dir, update_dir_contents[0]) + content_dir = os.path.join(sb_update_dir, update_dir_contents[0]) # walk temp folder and move files to main folder logger.log(u"Moving files from " + content_dir + " to " + nzbtomedia.PROGRAM_DIR) for dirname, dirnames, filenames in os.walk(content_dir): # @UnusedVariable dirname = dirname[len(content_dir) + 1:] for curfile in filenames: - old_path = joinPath(content_dir, dirname, curfile) - new_path = joinPath(nzbtomedia.PROGRAM_DIR, dirname, curfile) + old_path = os.path.join(content_dir, dirname, curfile) + new_path = os.path.join(nzbtomedia.PROGRAM_DIR, dirname, curfile) #Avoid DLL access problem on WIN32/64 #These files needing to be updated manually diff --git a/tests/general.py b/tests/general.py index 1afea58c..1fd114ee 100644 --- a/tests/general.py +++ b/tests/general.py @@ -1,12 +1,29 @@ +import os +import datetime import nzbtomedia -from nzbtomedia.nzbToMediaUtil import extractFiles, append_downloadID +from nzbtomedia import nzbToMediaDB +from nzbtomedia.nzbToMediaUtil import get_downloadInfo # Initialize the config nzbtomedia.initialize() -inputDirectory = "Z:\complete\tv\Game.of.Thrones.S04E03.HDTV.XviD-RARBG" -inputName = "Game of Thrones - S04E03 - Breaker of Chains" -inputHash = 'wdfc8fdn09w1wn908ede0820d8berd434213' +inputDirectory = 'Z:/complete/music/B.O.A.T.S. II_ Me Time [2013]' +outputDestination = 'Z:\\test\\music\\B.O.A.T.S. II_ Me Time [2013]' +outputDestinationMaster = outputDestination # Save the original, so we can change this within the loop below, and reset afterwards. -outputDestination = append_downloadID(inputDirectory, inputHash) -print outputDestination \ No newline at end of file +now = datetime.datetime.now() +for dirpath, dirnames, filenames in os.walk(inputDirectory): + for file in filenames: + + filePath = os.path.join(dirpath, file) + fileName, fileExtension = os.path.splitext(file) + newDir = dirpath # find the full path + newDir = newDir.replace(inputDirectory, "") #find the extra-depth directory + if len(newDir) > 0 and newDir[0] == "/": + newDir = newDir[1:] # remove leading "/" to enable join to work. + outputDestination = os.path.join(outputDestinationMaster, newDir) # join this extra directory to output. + + targetDirectory = os.path.join(outputDestination, file) + +outputDestination = outputDestinationMaster +nzbtomedia.flatten(outputDestination) \ No newline at end of file