From e731c87789e5532c8d1ce0774f19a251a67cccba Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Tue, 17 Jan 2023 19:14:58 -0800 Subject: [PATCH 01/89] Trying to fix this branch (had to recreate and lost all commits) --- README.rst | 3 +- changelog_temp.md | 7 + extract_msg/attachment.py | 28 ++- extract_msg/attachment_base.py | 35 ++- extract_msg/custom_attachments/__init__.py | 51 +++++ .../custom_attachments/custom_handler.py | 54 +++++ .../custom_attachments/outlook_image.py | 98 +++++++++ extract_msg/custom_attachments/utils.py | 201 ++++++++++++++++++ extract_msg/enums.py | 12 ++ extract_msg/exceptions.py | 17 +- extract_msg/message_base.py | 14 +- extract_msg/msg.py | 8 +- extract_msg/ole_writer.py | 1 + 13 files changed, 499 insertions(+), 30 deletions(-) create mode 100644 changelog_temp.md create mode 100644 extract_msg/custom_attachments/__init__.py create mode 100644 extract_msg/custom_attachments/custom_handler.py create mode 100644 extract_msg/custom_attachments/outlook_image.py create mode 100644 extract_msg/custom_attachments/utils.py diff --git a/README.rst b/README.rst index 33efaec7..76e73266 100644 --- a/README.rst +++ b/README.rst @@ -19,7 +19,7 @@ This module has a Discord server for general discussion. You can find it here: Changelog --------- -- `Changelog `__ +- `Changelog`_ Usage ----- @@ -252,3 +252,4 @@ your access to the newest major version of extract-msg. .. _Ko-fi: https://ko-fi.com/destructione .. _Patreon: https://www.patreon.com/DestructionE .. _msg-explorer: https://pypi.org/project/msg-explorer/ +.. _Changelog: https://github.com/TeamMsgExtractor/msg-extractor/blob/master/CHANGELOG.md diff --git a/changelog_temp.md b/changelog_temp.md new file mode 100644 index 00000000..bb6f63f4 --- /dev/null +++ b/changelog_temp.md @@ -0,0 +1,7 @@ +Temporary location for the changelog entry to ensure it doesn't conflict. + +**v0.??.??** +* Added new submodule `custom_attachments`. This submodule provides an extendable way to handle custom attachment types, attachment types whose structure and formatting are not defined in the Microsoft documentation for MSG files. +* Added new property `AttachmentBase.clsid` which returns the listed CLSID value of the data stream/storage of the attachment. +* Changed internal behavior of `MSGFile.attachments`. This should not cause any noticeable changes to the output. +* Removed some debug code that was left behind. diff --git a/extract_msg/attachment.py b/extract_msg/attachment.py index cf02bc82..0655f8e9 100644 --- a/extract_msg/attachment.py +++ b/extract_msg/attachment.py @@ -5,10 +5,11 @@ import string import zipfile -from typing import Optional, Union +from typing import Any, Dict, Optional, Union from . import constants from .attachment_base import AttachmentBase +from .custom_attachments import CustomAttachmentHandler, getHandler from .enums import AttachmentType from .exceptions import StandardViolationError from .utils import createZipOpen, inputToString, openMsg, prepareFilename @@ -33,6 +34,7 @@ def __init__(self, msg, dir_): located. """ super().__init__(msg, dir_) + self.__customHandler = None if '37050003' not in self.props: from .prop import createProp @@ -65,9 +67,11 @@ def __init__(self, msg, dir_): self.__data = self._getStream('__substg1.0_37010102') elif self.exists('__substg1.0_3701000D'): if (self.props['37050003'].value & 0x7) != 0x5: - raise NotImplementedError( - 'Current version of extract_msg does not support extraction of containers that are not embedded msg files.') - # TODO add implementation. + self.__type = AttachmentType.CUSTOM + # Check if we have any custom handlers. If not, it will raise + # an error automatically. + self.__customHandler = getHandler(self) + self.__data = self.__customHandler.data else: self.__prefix = msg.prefixList + [dir_, '__substg1.0_3701000D'] self.__type = AttachmentType.MSG @@ -103,8 +107,10 @@ def getFilename(self, **kwargs) -> str: # Check if user wants to save the file under the Content-ID. if kwargs.get('contentId', False): filename = self.cid - # If filename is None at this point, use long filename as first - # preference. + # If we are using a custom handler, prefer it's name. + if self.type is AttachmentType.CUSTOM: + filename = self.__customHandler.name + # If we are here, try to get the filename however else we can. if not filename: filename = self.name # Otherwise just make something up! @@ -198,7 +204,7 @@ def save(self, **kwargs) -> Optional[Union[str, 'MSGFile']]: fullFilename = customPath / filename - if self.type is AttachmentType.DATA: + if self.type is AttachmentType.DATA or (self.type is AttachmentType.CUSTOM and isinstance(self.__data, bytes)): if _zip: name, ext = os.path.splitext(filename) nameList = _zip.namelist() @@ -254,6 +260,14 @@ def saveEmbededMessage(self, **kwargs) -> None: """ self.data.save(**kwargs) + @property + def customHandler(self) -> Optional[CustomAttachmentHandler]: + """ + The instance of the custom handler associated with this attachment, if + it has one. + """ + return self.__customHandler + @property def data(self) -> Optional[Union[bytes, 'MSGFile']]: """ diff --git a/extract_msg/attachment_base.py b/extract_msg/attachment_base.py index 2b5a10ee..ef7c3bef 100644 --- a/extract_msg/attachment_base.py +++ b/extract_msg/attachment_base.py @@ -34,7 +34,6 @@ def __init__(self, msg, dir_): self.__props = Properties(self._getStream('__properties_version1.0'), PropertiesType.ATTACHMENT) self.__namedProperties = NamedProperties(msg.named, self) - def _ensureSet(self, variable, streamID, stringStream = True, **kwargs): """ Ensures that the variable exists, otherwise will set it using the @@ -271,9 +270,39 @@ def cid(self) -> Optional[str]: contendId = cid @property - def dir(self): + def clsid(self) -> str: + """ + Returns the CLSID for the data stream/storage of the attachment. + """ + try: + return self.__clsid + except AttributeError: + # Set some default values. + self.__clsid = '00000000-0000-0000-0000-000000000000' + dataStream = None + + # See if we can find the data stream/storage. + if self.type in (AttachmentType.CUSTOM, AttachmentType.MSG): + dataStream = [self.__dir, '__substg1.0_3701000D'] + elif self.type is AttachmentType.DATA: + dataStream = [self.__dir, '__substg1.0_37010102'] + elif self.type is AttachmentType.UNSUPPORTED: + # Special check for custom attachments. + if self.exists('__substg1.0_3701000D'): + dataStream = [self.__dir, '__substg1.0_3701000D'] + elif self.exists('__substg1.0_37010102'): + dataStream = [self.__dir, '__substg1.0_37010102'] + + # If we found the right item, get the CLSID. + if dataStream: + self.__clsid = self.__msg._getOleEntry(dataStream).clsid or '00000000-0000-0000-0000-000000000000' + + return self.__clsid + + @property + def dir(self) -> str: """ - Returns the directory inside the msg file where the attachment is + Returns the directory inside the MSG file where the attachment is located. """ return self.__dir diff --git a/extract_msg/custom_attachments/__init__.py b/extract_msg/custom_attachments/__init__.py new file mode 100644 index 00000000..1b153c6f --- /dev/null +++ b/extract_msg/custom_attachments/__init__.py @@ -0,0 +1,51 @@ +""" +Submodule designed to help with saving and using custom attachments. Custom +attachments are those follow standards not defined in the MSG documentation. Use +the function `getHandler` to get an instance of a subclass of +CustomAttachmentHandler. + +CustomAttachmentHandler subclasses will all define the following methods: + injectHtml: A method which takes HTML and inserts the + +It should hopefully be completely unnecessary for your code to know what type of +handler it is using, as the abstract base class should give all of the functions +you would typically want. + +If you would like to add your own handler, simply subclass +CustomAttachmentHandler and add it using the `registerHandler` function. +""" + +from typing import List + +from .custom_handler import CustomAttachmentHandler + + +# Create a way to register handlers. +_knownHandlers : List[CustomAttachmentHandler] = [] +# This line is cheating a little bit, but is more efficient than wrapping it in +# a function. +registerHandler = _knownHandlers.append + + +# Import built-in handler modules. THey will all automatically register their +# respecive handler(s). +from .outlook_image import OutlookImage + + + + +# Function designed to route to the correct handler. +def getHandler(attachment : 'Attachment') -> CustomAttachmentHandler: + """ + Takes an attachment and uses it to find the correct handler. Returns an + instance created using the specified attachment. + + :raises NotImplementedError: No handler could be found. + :raises ValueError: A handler was found, but something was wrong with the + attachment data. + """ + for handler in _knownHandlers: + if handler.isCorrectHandler(attachment): + return handler(attachment) + + raise NotImplementedError('No valid handler could be found for the attachment. Contact the developers for help.') diff --git a/extract_msg/custom_attachments/custom_handler.py b/extract_msg/custom_attachments/custom_handler.py new file mode 100644 index 00000000..c844151a --- /dev/null +++ b/extract_msg/custom_attachments/custom_handler.py @@ -0,0 +1,54 @@ +import abc + +from typing import List, Optional, Tuple + + +class CustomAttachmentHandler(abc.ABC): + """ + A class designed to help with custom attachments that may require parsing in + special ways that are completely different from one another. + """ + def __init__(self, attachment : 'Attachment'): + super().__init__() + self.__att = attachment + + @classmethod + @abc.abstractmethod + def isCorrectHandler(cls, attachment : 'Attachment') -> bool: + """ + Checks if this is the correct handler for the attachment. + """ + + @abc.abstractmethod + def injectHTML(self, html : bytes, renderedList : Optional[List[str]] = None) -> Tuple[bytes, Optional[List[str]]]: + """ + Adds the relevent tag, if any, to the HTML for making prepared HTML. + + If this function should do nothing, returns the two arguments without + modification. + + :param html: The HTML body to inject into (if at all). + :param renderedList: The list to use (if needed) of "rendered + characters" which will be returned and matches the HTML returned. + """ + + @property + def attachment(self): + """ + The attachment this handler is associated with. + """ + return self.__att + + @property + @abc.abstractmethod + def data(self) -> bytes: + """ + Gets the data for the attachment. + """ + + @property + @abc.abstractmethod + def name(self) -> str: + """ + Returns the name to be used when saving the attachment. + """ diff --git a/extract_msg/custom_attachments/outlook_image.py b/extract_msg/custom_attachments/outlook_image.py new file mode 100644 index 00000000..54428599 --- /dev/null +++ b/extract_msg/custom_attachments/outlook_image.py @@ -0,0 +1,98 @@ +import base64 +import struct + +from typing import List, Optional, Tuple + +from . import registerHandler +from .custom_handler import CustomAttachmentHandler +from .utils import htmlSplitRendered +from ..enums import DVAspect +from ..exceptions import CustomAttachmentError + + +_ST_OLE = struct.Struct('' + + @classmethod + def isCorrectHandler(cls, attachment : 'Attachment') -> bool: + if attachment.clsid != '00000316-0000-0000-C000-000000000046': + return False + + # Check for the required streams. + if not attachment.exists('__substg1.0_3701000D/CONTENTS'): + return False + if not attachment.exists('__substg1.0_3701000D/\x01Ole'): + return False + if not attachment.exists('__substg1.0_3701000D/\x03MailStream'): + return False + + return True + + def injectHTML(self, html : bytes, renderedList : Optional[List[str]] = None) -> Tuple[bytes, Optional[List[str]]]: + if not renderedList: + renderedList = htmlSplitRendered(html) + + rp = self.attachment.renderingPosition + + if rp >= len(renderedList): + raise CustomAttachmentError(f'Rendering position beyond calculated number of rendered characters (expected less than {len(renderedList)}, got {rp}).') + + renderedList[rp] = self.__htmlTag + renderedList[rp] + + return (''.join(renderedList).encode('utf-8'), renderedList) + + @property + def data(self) -> bytes: + return self.__data + + @property + def name(self) -> str: + return self.attachment.shortFilename + '.bmp' + + + + +registerHandler(OutlookImage) diff --git a/extract_msg/custom_attachments/utils.py b/extract_msg/custom_attachments/utils.py new file mode 100644 index 00000000..8a61e3ec --- /dev/null +++ b/extract_msg/custom_attachments/utils.py @@ -0,0 +1,201 @@ +""" +Utilities for extract-msg that are more specialized for the custom_attachments +submodule than for the main module. +""" + +import bs4 + +from typing import List + + +_WHITESPACE_BREAKERS = ( + ' bool: + """ + Helper function to indicate that a tag breaks a chain of whitespace. + """ + for x in _WHITESPACE_BREAKERS: + if token.startswith(x) and len(token) > len(x) and token[len(x)] in ('>', ' ', '/'): + return True + + return False + + +def _isWhitespaceToken(token : str) -> bool: + if token[0] == '<': + for x in _WHITESPACE_TAGS: + if token.startswith(x) and len(token) > len(x) and token[len(x)] in ('>', ' ', '/'): + return True + elif token in (' ', ' ', ' ', ' ', ' '): + return True + else: + return token.isspace() + + return False + + +def htmlSplitRendered(html : bytes) -> List[str]: + """ + Takes html bytes and returns a list of the rendered characters, with data + that is not being rendered being attached to the next rendered character. + """ + # Unfortunately bs4 didn't seem particularly great for tokenizing, so I did + # my own function that works well enough. First, let's tokenize the html. + tokens = tokenizeHtml(bs4.BeautifulSoup(html, features = 'html.parser').decode()) + + # Next, let's break things down further. + breakDown = [] + for token in tokens: + # We tell what we are looking at by checking the first character of the + # token. If it's a <, then it is an HTML tag. If it is a & then it is an + # escape. Otherwise, it is plain text. For both tags and escapes, just + # dump them into the list. + if token[0] in ('<', '&'): + breakDown.append(token) + else: + # If we are looking at plain text, add it by extending the list. + breakDown.extend(token) + + # Now that we have broken things down further, let's go through and join our + # pieces togethered into rendered tokens. Here is were we actually need to + # know what an html tag is. If it's an escape or just a non-whitespace + # character, we can just shove it onto what we currently have. + current = '' + renderedCharacters = [] + lastWhitespace = None + for item in breakDown: + if item[0] == '&': + if _isWhitespaceToken(item): + if lastWhitespace is None: + lastWhitespace == item + else: + if lastWhitespace is not None and lastWhitespace[0] != '<': + current += lastWhitespace + renderedCharacters.append(current) + current = '' + lastWhitespace = None + current += item + renderedCharacters.append(current) + current = '' + elif item[0] == '<': + if _isWhitespaceToken(item): + # If we are here, add it to current, push current, and set this + # tag as the last whitespace. + current += item + renderedCharacters.append(current) + current = '' + lastWhitespace = item + else: + + # Some tags will break whitespace chains. + if _isWhitespaceBreaker(item): + if lastWhitespace is not None and lastWhitespace[0] != '<': + current += lastWhitespace + renderedCharacters.append(current) + current = '' + lastWhitespace = None + + current += item + else: + # Here is where we handle text, which is not particularly fun. + # Basically if it is whitespace and lastWhitespace is not none, we + # set the whitespace. + if _isWhitespaceToken(item): + if lastWhitespace is None: + lastWhitespace = item + else: + if lastWhitespace is not None and lastWhitespace[0] != '<': + current += lastWhitespace + renderedCharacters.append(current) + current = '' + lastWhitespace = None + current += item + renderedCharacters.append(current) + current = '' + + if current: + renderedCharacters.append(current) + + return renderedCharacters + + +def tokenizeHtml(html : str) -> List[str]: + # Setup a few variables for state tracking. + inTag = False + # Used for tracking escapes starting with &. If your escape ends up at 100 + # characters because it is missing the semicolon, we are going to throw an + # error. + inEscape = False + inString = False + # Only used when in string. Last character was a backslash. + isBackslash = False + # Tells which quote type we are in. + isDoubleQuote = False + + tokens = [] + currentToken = '' + + # Finally, let's start breaking things up. Our rules are that if we start a + # quote while in a tag, then we acknowledge it, otherwise it is treated as + # plain text. + for character in html: + # First we need to know our state, as our state determines what how we + # process a character. + if inTag: + currentToken += character + if inString: + if character == '"' and isDoubleQuote: + # If isBackslash then we stay in the quote, otherwise... + isQuote = isBackslash + elif character == "'" and not isDoubleQuote: + # If isBackslash then we stay in the quote, otherwise... + isQuote = isBackslash + elif character == '\\': + isBackslash = not isBackslash + if character != '\\': + isBackslash = False + else: + if character == '>': + inTag = False + tokens.append(currentToken) + currentToken = '' + elif inEscape: + currentToken += character + if len(currentToken) > 99: + raise ValueError('Found escape that was too long (is a ; missing?)') + if character == ';': + tokens.append(currentToken) + currentToken = '' + inEscape = False + elif inString: + # This is an error. We should *never* be in a quote if we are not in + # a tag. + raise ValueError('Found to be inQuote when not in tag.') + else: + # We are currently processing plain text, so let's just handle. + if character == '&': + if currentToken: + tokens.append(currentToken) + currentToken = character + inEscape = True + elif character == '<': + if currentToken: + tokens.append(currentToken) + currentToken = character + inTag = True + inString = False + else: + currentToken += character + + if currentToken: + tokens.append(currentToken) + + return tokens diff --git a/extract_msg/enums.py b/extract_msg/enums.py index 3f746da4..93ea5bb1 100644 --- a/extract_msg/enums.py +++ b/extract_msg/enums.py @@ -113,6 +113,7 @@ class AttachmentType(enum.Enum): SIGNED = 3 BROKEN = 4 UNSUPPORTED = 5 + CUSTOM = 6 UNKNOWN = 0xFFFFFFFF @@ -316,6 +317,7 @@ class Color(enum.IntEnum): BLACK = 1 + class ContactAddressIndex(enum.Enum): EMAIL_1 = 0 EMAIL_2 = 1 @@ -376,6 +378,16 @@ class DisplayType(enum.Enum): +class DVAspect(enum.IntEnum): + """ + Part of the extra data for Outlook signatures. Different sources seem to + disagree on the meanings, so I'm sticking to the meanings in the official + Microsoft documentation of the DVASPECT enumeration. + """ + CONTENT = 1 + ICON = 4 + + class ElectronicAddressProperties(enum.Enum): @classmethod def fromBits(cls, value : int) -> Set['ElectronicAddressProperties']: diff --git a/extract_msg/exceptions.py b/extract_msg/exceptions.py index e835df64..1ce1fc88 100644 --- a/extract_msg/exceptions.py +++ b/extract_msg/exceptions.py @@ -17,19 +17,21 @@ class BadHtmlError(ValueError): """ HTML failed to pass validation. """ - pass class ConversionError(Exception): """ An error occured during type conversion. """ - pass + +class CustomAttachmentError(Exception): + """ + A generic error used for issues handling custom attachments. + """ class DataNotFoundError(Exception): """ Requested stream type was unavailable. """ - pass class DeencapMalformedData(Exception): """ @@ -45,7 +47,6 @@ class ExecutableNotFound(Exception): """ Could not find the specified executable. """ - pass class IncompatibleOptionsError(Exception): """ @@ -56,26 +57,22 @@ class InvalidFileFormatError(OSError): """ An Invalid File Format Error occurred. """ - pass class InvaildPropertyIdError(Exception): """ The provided property ID was invalid. """ - pass class InvalidVersionError(Exception): """ The version specified is invalid. """ - pass class StandardViolationError(Exception): """ A critical violation of the MSG standards was detected and could not be recovered from. Recoverable violations will result in log messages instead. """ - pass class TZError(Exception): """ @@ -91,13 +88,11 @@ class UnknownCodepageError(Exception): """ The codepage provided was not one we know of. """ - pass class UnknownTypeError(Exception): """ The type specified is not one that is recognized. """ - pass class UnsupportedMSGTypeError(NotImplementedError): """ @@ -110,10 +105,8 @@ class UnrecognizedMSGTypeError(TypeError): An exception that is raised when the module cannot determine how to properly open a specific class of msg file. """ - pass class WKError(RuntimeError): """ An error occured while running wkhtmltopdf. """ - pass diff --git a/extract_msg/message_base.py b/extract_msg/message_base.py index 841654d4..334e322d 100644 --- a/extract_msg/message_base.py +++ b/extract_msg/message_base.py @@ -19,7 +19,7 @@ from typing import Callable, Dict, Optional, Tuple, Union from . import constants -from .enums import DeencapType, RecipientType +from .enums import AttachmentType, DeencapType, RecipientType from .exceptions import ( DataNotFoundError, DeencapMalformedData, DeencapNotEncapsulated, IncompatibleOptionsError, WKError @@ -1178,8 +1178,18 @@ def htmlBodyPrepared(self) -> Optional[bytes]: if not self.htmlBody: return self.htmlBody + html = self.htmlBody + + renderedCharacters = None + + # Iterate through all attachments, and inject all of the custom data + # from them. + for x in self.attachments: + if x.type is AttachmentType.CUSTOM: + html, renderedCharacters = x.customHandler.injectHTML(html, renderedCharacters) + # Create the BeautifulSoup instance to use. - soup = bs4.BeautifulSoup(self.htmlBody, 'html.parser') + soup = bs4.BeautifulSoup(html, 'html.parser') # Get a list of image tags to see if we can inject into. If the source # of an image starts with "cid:" that means it is one of the attachments diff --git a/extract_msg/msg.py b/extract_msg/msg.py index 6fecb2b0..9db13122 100644 --- a/extract_msg/msg.py +++ b/extract_msg/msg.py @@ -631,10 +631,9 @@ def attachments(self) -> List: # Get the attachments. attachmentDirs = [] prefixLen = self.prefixLen - for dir_ in self.listDir(False, True): - if dir_[prefixLen].startswith('__attach') and \ - dir_[prefixLen] not in attachmentDirs: - attachmentDirs.append(dir_[prefixLen]) + for dir_ in self.listDir(False, True, False): + if dir_[0].startswith('__attach') and dir_[0] not in attachmentDirs: + attachmentDirs.append(dir_[0]) self._attachments = [] @@ -642,7 +641,6 @@ def attachments(self) -> List: try: self._attachments.append(self.attachmentClass(self, attachmentDir)) except (NotImplementedError, UnrecognizedMSGTypeError) as e: - print("Hello") if self.attachmentErrorBehavior != AttachErrorBehavior.THROW: logger.error(f'Error processing attachment at {attachmentDir}') logger.exception(e) diff --git a/extract_msg/ole_writer.py b/extract_msg/ole_writer.py index 69a9cf44..53ce1593 100644 --- a/extract_msg/ole_writer.py +++ b/extract_msg/ole_writer.py @@ -631,6 +631,7 @@ def addOleEntry(self, path, entry : OleDirectoryEntry, data : Optional[bytes] = """ path = inputToMsgPath(path) # First, find the current place in our dict to add the item. + _dir = self.__getContainingStorage(path, False) # Now, check that the item *is not* already in our dict, as that would # cause problems. From 558c61f10ca1566ec86e519348f06e12cf34bdac Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Tue, 17 Jan 2023 19:17:02 -0800 Subject: [PATCH 02/89] Fix typo --- extract_msg/custom_attachments/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extract_msg/custom_attachments/__init__.py b/extract_msg/custom_attachments/__init__.py index 1b153c6f..a8f84904 100644 --- a/extract_msg/custom_attachments/__init__.py +++ b/extract_msg/custom_attachments/__init__.py @@ -27,7 +27,7 @@ registerHandler = _knownHandlers.append -# Import built-in handler modules. THey will all automatically register their +# Import built-in handler modules. They will all automatically register their # respecive handler(s). from .outlook_image import OutlookImage From 4f01d61d7781e79b16343a07c638d61bd50ae8e4 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Sun, 12 Feb 2023 23:53:24 -0800 Subject: [PATCH 03/89] Attempting to fix merge --- extract_msg/attachment_base.py | 1 + 1 file changed, 1 insertion(+) diff --git a/extract_msg/attachment_base.py b/extract_msg/attachment_base.py index ef7c3bef..aa6066a6 100644 --- a/extract_msg/attachment_base.py +++ b/extract_msg/attachment_base.py @@ -34,6 +34,7 @@ def __init__(self, msg, dir_): self.__props = Properties(self._getStream('__properties_version1.0'), PropertiesType.ATTACHMENT) self.__namedProperties = NamedProperties(msg.named, self) + def _ensureSet(self, variable, streamID, stringStream = True, **kwargs): """ Ensures that the variable exists, otherwise will set it using the From 8384e1662adadcd3c72c980b8bc511f8e4b8b085 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Sun, 12 Feb 2023 23:55:31 -0800 Subject: [PATCH 04/89] Final fix for merge --- extract_msg/enums.py | 1 - 1 file changed, 1 deletion(-) diff --git a/extract_msg/enums.py b/extract_msg/enums.py index 93ea5bb1..aeb6ca1b 100644 --- a/extract_msg/enums.py +++ b/extract_msg/enums.py @@ -113,7 +113,6 @@ class AttachmentType(enum.Enum): SIGNED = 3 BROKEN = 4 UNSUPPORTED = 5 - CUSTOM = 6 UNKNOWN = 0xFFFFFFFF From 5ce8cb2dd3d59c96b4ea7179aeea1bb03020720f Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Sun, 12 Feb 2023 23:56:43 -0800 Subject: [PATCH 05/89] Add back CUSTOM to AttachmentType enum --- extract_msg/enums.py | 1 + 1 file changed, 1 insertion(+) diff --git a/extract_msg/enums.py b/extract_msg/enums.py index a2c7b420..c59a488b 100644 --- a/extract_msg/enums.py +++ b/extract_msg/enums.py @@ -124,6 +124,7 @@ class AttachmentType(enum.Enum): BROKEN = 4 UNSUPPORTED = 5 SIGNED_EMBEDDED = 6 + CUSTOM = 7 UNKNOWN = 0xFFFFFFFF From 340168b4d88d1335fb255f5db76fcc6a3cd29d94 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Sat, 18 Mar 2023 16:00:35 -0700 Subject: [PATCH 06/89] Revert and adjust some changes to sync with next-release --- README.rst | 3 +-- extract_msg/message_base.py | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/README.rst b/README.rst index 9788fe6d..5eec4e65 100644 --- a/README.rst +++ b/README.rst @@ -19,7 +19,7 @@ This module has a Discord server for general discussion. You can find it here: Changelog --------- -- `Changelog`_ +- `Changelog `__ Usage ----- @@ -252,4 +252,3 @@ your access to the newest major version of extract-msg. .. _Ko-fi: https://ko-fi.com/destructione .. _Patreon: https://www.patreon.com/DestructionE .. _msg-explorer: https://pypi.org/project/msg-explorer/ -.. _Changelog: https://github.com/TeamMsgExtractor/msg-extractor/blob/master/CHANGELOG.md diff --git a/extract_msg/message_base.py b/extract_msg/message_base.py index 334e322d..f1505a82 100644 --- a/extract_msg/message_base.py +++ b/extract_msg/message_base.py @@ -19,7 +19,7 @@ from typing import Callable, Dict, Optional, Tuple, Union from . import constants -from .enums import AttachmentType, DeencapType, RecipientType +from .enums import DeencapType, RecipientType from .exceptions import ( DataNotFoundError, DeencapMalformedData, DeencapNotEncapsulated, IncompatibleOptionsError, WKError From 1f30ab8dd90b120ce6a812f169fa2b882d79da36 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Sat, 18 Mar 2023 16:06:31 -0700 Subject: [PATCH 07/89] Add back change that was blocking merge --- extract_msg/message_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extract_msg/message_base.py b/extract_msg/message_base.py index 5bc481af..a56ea225 100644 --- a/extract_msg/message_base.py +++ b/extract_msg/message_base.py @@ -21,7 +21,7 @@ from . import constants from ._rtf.create_doc import createDocument from ._rtf.inject_rtf import injectStartRTF -from .enums import DeencapType, RecipientType +from .enums import AttachmentType, DeencapType, RecipientType from .exceptions import ( DataNotFoundError, DeencapMalformedData, DeencapNotEncapsulated, IncompatibleOptionsError, WKError From d2fdda734b508935c82c2f7e1730ddaad1479851 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Tue, 9 May 2023 14:46:24 -0700 Subject: [PATCH 08/89] Remove unneded imports (also resolve merge) --- extract_msg/attachment.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extract_msg/attachment.py b/extract_msg/attachment.py index 8ff0f3fb..b23cb8bf 100644 --- a/extract_msg/attachment.py +++ b/extract_msg/attachment.py @@ -5,7 +5,7 @@ import string import zipfile -from typing import Any, Dict, Optional, Union +from typing import Optional, Union from . import constants from .attachment_base import AttachmentBase From 88fd211c643fb8567770f50dced621de2bc31eba Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Tue, 9 May 2023 14:47:51 -0700 Subject: [PATCH 09/89] Attempting to resolve merge --- extract_msg/attachment.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/extract_msg/attachment.py b/extract_msg/attachment.py index b23cb8bf..6b87b1d1 100644 --- a/extract_msg/attachment.py +++ b/extract_msg/attachment.py @@ -260,14 +260,6 @@ def saveEmbededMessage(self, **kwargs) -> None: """ self.data.save(**kwargs) - @property - def customHandler(self) -> Optional[CustomAttachmentHandler]: - """ - The instance of the custom handler associated with this attachment, if - it has one. - """ - return self.__customHandler - @property def data(self) -> Optional[Union[bytes, 'MSGFile']]: """ From 3a20c74902c768fb02d4f8879b014cf034d3a74a Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Tue, 9 May 2023 14:53:09 -0700 Subject: [PATCH 10/89] More resolving merge --- extract_msg/exceptions.py | 5 ----- 1 file changed, 5 deletions(-) diff --git a/extract_msg/exceptions.py b/extract_msg/exceptions.py index 1ce1fc88..acd3567f 100644 --- a/extract_msg/exceptions.py +++ b/extract_msg/exceptions.py @@ -23,11 +23,6 @@ class ConversionError(Exception): An error occured during type conversion. """ -class CustomAttachmentError(Exception): - """ - A generic error used for issues handling custom attachments. - """ - class DataNotFoundError(Exception): """ Requested stream type was unavailable. From 2a1b0f41584ec6344dde2c6d10a8d57397d751a0 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Tue, 9 May 2023 14:57:12 -0700 Subject: [PATCH 11/89] Checking if that was one of the merge issues --- extract_msg/msg.py | 1 + 1 file changed, 1 insertion(+) diff --git a/extract_msg/msg.py b/extract_msg/msg.py index 8dc73585..f88b5638 100644 --- a/extract_msg/msg.py +++ b/extract_msg/msg.py @@ -653,6 +653,7 @@ def attachments(self) -> List: try: self._attachments.append(self.attachmentClass(self, attachmentDir)) except (NotImplementedError, UnrecognizedMSGTypeError) as e: + print("Hello") if self.attachmentErrorBehavior != AttachErrorBehavior.THROW: logger.error(f'Error processing attachment at {attachmentDir}') logger.exception(e) From 7c1a48080051f02a399d014c881a10d26e9d93d3 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Tue, 9 May 2023 14:57:59 -0700 Subject: [PATCH 12/89] Is this the issue? --- extract_msg/exceptions.py | 1 + 1 file changed, 1 insertion(+) diff --git a/extract_msg/exceptions.py b/extract_msg/exceptions.py index acd3567f..762a1d65 100644 --- a/extract_msg/exceptions.py +++ b/extract_msg/exceptions.py @@ -83,6 +83,7 @@ class UnknownCodepageError(Exception): """ The codepage provided was not one we know of. """ + pass class UnknownTypeError(Exception): """ From f0cfe3ecd78c53972097ca0b91c70544698d67a4 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Tue, 9 May 2023 14:59:46 -0700 Subject: [PATCH 13/89] Add changed that prevented merge back --- extract_msg/attachment.py | 8 ++++++++ extract_msg/exceptions.py | 7 ++++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/extract_msg/attachment.py b/extract_msg/attachment.py index 96cd6d73..3dd65d3d 100644 --- a/extract_msg/attachment.py +++ b/extract_msg/attachment.py @@ -274,6 +274,14 @@ def saveEmbededMessage(self, **kwargs) -> None: """ self.data.save(**kwargs) + @property + def customHandler(self) -> Optional[CustomAttachmentHandler]: + """ + The instance of the custom handler associated with this attachment, if + it has one. + """ + return self.__customHandler + @property def data(self) -> Optional[Union[bytes, MSGFile]]: """ diff --git a/extract_msg/exceptions.py b/extract_msg/exceptions.py index d323746e..2223faca 100644 --- a/extract_msg/exceptions.py +++ b/extract_msg/exceptions.py @@ -46,6 +46,11 @@ class ConversionError(Exception): An error occured during type conversion. """ +class CustomAttachmentError(Exception): + """ + A generic error used for issues handling custom attachments. + """ + class DataNotFoundError(Exception): """ Requested stream type was unavailable. @@ -91,7 +96,7 @@ class StandardViolationError(InvalidFileFormatError): A critical violation of the MSG standards was detected and could not be recovered from. Recoverable violations will result in log messages instead. - Any that could reasonably be skipped, although are likely to still cause + Any that could reasonably be skipped, although are likely to still cause errors down the line, can be suppressed. """ From ac8e1b2398a99581073075e14580daec104be97c Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Tue, 9 May 2023 18:44:18 -0700 Subject: [PATCH 14/89] Update organization to match current version --- extract_msg/custom_attachments/__init__.py | 20 +++++++++++++++++-- .../custom_attachments/custom_handler.py | 18 ++++++++++++++--- .../custom_attachments/outlook_image.py | 17 +++++++++++++--- extract_msg/custom_attachments/utils.py | 6 ++++++ 4 files changed, 53 insertions(+), 8 deletions(-) diff --git a/extract_msg/custom_attachments/__init__.py b/extract_msg/custom_attachments/__init__.py index a8f84904..702bb9bf 100644 --- a/extract_msg/custom_attachments/__init__.py +++ b/extract_msg/custom_attachments/__init__.py @@ -1,3 +1,6 @@ +from __future__ import annotations + + """ Submodule designed to help with saving and using custom attachments. Custom attachments are those follow standards not defined in the MSG documentation. Use @@ -15,7 +18,18 @@ CustomAttachmentHandler and add it using the `registerHandler` function. """ -from typing import List +__all__ = [ + # Classes. + 'CustomAttachmentHandler', + 'OutlookImage', + + # Functions. + 'getHandler', + 'registerHandler', +] + + +from typing import List, TYPE_CHECKING from .custom_handler import CustomAttachmentHandler @@ -32,10 +46,12 @@ from .outlook_image import OutlookImage +if TYPE_CHECKING: + from ..attachment import Attachment # Function designed to route to the correct handler. -def getHandler(attachment : 'Attachment') -> CustomAttachmentHandler: +def getHandler(attachment : Attachment) -> CustomAttachmentHandler: """ Takes an attachment and uses it to find the correct handler. Returns an instance created using the specified attachment. diff --git a/extract_msg/custom_attachments/custom_handler.py b/extract_msg/custom_attachments/custom_handler.py index c844151a..08dbccba 100644 --- a/extract_msg/custom_attachments/custom_handler.py +++ b/extract_msg/custom_attachments/custom_handler.py @@ -1,6 +1,18 @@ +from __future__ import annotations + + +__all__ = [ + 'CustomAttachmentHandler', +] + + import abc -from typing import List, Optional, Tuple +from typing import List, Optional, Tuple, TYPE_CHECKING + + +if TYPE_CHECKING: + from ..attachment import Attachment class CustomAttachmentHandler(abc.ABC): @@ -8,13 +20,13 @@ class CustomAttachmentHandler(abc.ABC): A class designed to help with custom attachments that may require parsing in special ways that are completely different from one another. """ - def __init__(self, attachment : 'Attachment'): + def __init__(self, attachment : Attachment): super().__init__() self.__att = attachment @classmethod @abc.abstractmethod - def isCorrectHandler(cls, attachment : 'Attachment') -> bool: + def isCorrectHandler(cls, attachment : Attachment) -> bool: """ Checks if this is the correct handler for the attachment. """ diff --git a/extract_msg/custom_attachments/outlook_image.py b/extract_msg/custom_attachments/outlook_image.py index 54428599..09b295a8 100644 --- a/extract_msg/custom_attachments/outlook_image.py +++ b/extract_msg/custom_attachments/outlook_image.py @@ -1,7 +1,15 @@ +from __future__ import annotations + + +__all__ = [ + 'OutlookImage', +] + + import base64 import struct -from typing import List, Optional, Tuple +from typing import List, Optional, Tuple, TYPE_CHECKING from . import registerHandler from .custom_handler import CustomAttachmentHandler @@ -10,12 +18,15 @@ from ..exceptions import CustomAttachmentError +if TYPE_CHECKING: + from ..attachment import Attachment + _ST_OLE = struct.Struct('' @classmethod - def isCorrectHandler(cls, attachment : 'Attachment') -> bool: + def isCorrectHandler(cls, attachment : Attachment) -> bool: if attachment.clsid != '00000316-0000-0000-C000-000000000046': return False diff --git a/extract_msg/custom_attachments/utils.py b/extract_msg/custom_attachments/utils.py index 8a61e3ec..18d8507e 100644 --- a/extract_msg/custom_attachments/utils.py +++ b/extract_msg/custom_attachments/utils.py @@ -3,6 +3,12 @@ submodule than for the main module. """ +__all__ = [ + 'htmlSplitRendered', + 'tokenizeHtml', +] + + import bs4 from typing import List From 68538adb9129143af8ae56c924fa01b97b84793a Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Sat, 10 Jun 2023 15:24:04 -0700 Subject: [PATCH 15/89] Changing the way custom attachments work --- extract_msg/custom_attachments/__init__.py | 24 ++++++++++++++----- .../custom_attachments/custom_handler.py | 12 ++++------ ...{outlook_image.py => outlook_image_dib.py} | 23 +++++++----------- extract_msg/message_base.py | 14 ++--------- 4 files changed, 33 insertions(+), 40 deletions(-) rename extract_msg/custom_attachments/{outlook_image.py => outlook_image_dib.py} (82%) diff --git a/extract_msg/custom_attachments/__init__.py b/extract_msg/custom_attachments/__init__.py index 702bb9bf..13e32914 100644 --- a/extract_msg/custom_attachments/__init__.py +++ b/extract_msg/custom_attachments/__init__.py @@ -21,7 +21,7 @@ __all__ = [ # Classes. 'CustomAttachmentHandler', - 'OutlookImage', + 'OutlookImageDIB', # Functions. 'getHandler', @@ -29,21 +29,33 @@ ] -from typing import List, TYPE_CHECKING +from typing import List, Type, TYPE_CHECKING from .custom_handler import CustomAttachmentHandler # Create a way to register handlers. _knownHandlers : List[CustomAttachmentHandler] = [] -# This line is cheating a little bit, but is more efficient than wrapping it in -# a function. -registerHandler = _knownHandlers.append + +def registerHandler(handler : Type[CustomAttachmentHandler]) -> None: + """ + Registers the CustomAttachmentHandler subclass as a handler. + + :raises TypeError: The handler was not a subclass of + CustomAttachmentHandler. + """ + # Make sure it is a subclass of CustomAttachmentHandler. + if not isinstance(handler, type): + raise ValueError(':param handler: must be a class, not an instance of a class.') + if not issubclass(handler, CustomAttachmentHandler): + raise ValueError(':param handler: must be a subclass of CustomAttachmentHandler.') + _knownHandlers.append(handler) + # Import built-in handler modules. They will all automatically register their # respecive handler(s). -from .outlook_image import OutlookImage +from .outlook_image_dib import OutlookImageDIB if TYPE_CHECKING: diff --git a/extract_msg/custom_attachments/custom_handler.py b/extract_msg/custom_attachments/custom_handler.py index 08dbccba..90efa186 100644 --- a/extract_msg/custom_attachments/custom_handler.py +++ b/extract_msg/custom_attachments/custom_handler.py @@ -20,6 +20,7 @@ class CustomAttachmentHandler(abc.ABC): A class designed to help with custom attachments that may require parsing in special ways that are completely different from one another. """ + def __init__(self, attachment : Attachment): super().__init__() self.__att = attachment @@ -32,16 +33,11 @@ def isCorrectHandler(cls, attachment : Attachment) -> bool: """ @abc.abstractmethod - def injectHTML(self, html : bytes, renderedList : Optional[List[str]] = None) -> Tuple[bytes, Optional[List[str]]]: + def generateRtf(self) -> Optional[bytes]: """ - Adds the relevent tag, if any, to the HTML for making prepared HTML. - - If this function should do nothing, returns the two arguments without - modification. + Generates the RTF to inject in place of the \objattph tag. - :param html: The HTML body to inject into (if at all). - :param renderedList: The list to use (if needed) of "rendered - characters" which will be returned and matches the HTML returned. + If this function should do nothing, returns None """ @property diff --git a/extract_msg/custom_attachments/outlook_image.py b/extract_msg/custom_attachments/outlook_image_dib.py similarity index 82% rename from extract_msg/custom_attachments/outlook_image.py rename to extract_msg/custom_attachments/outlook_image_dib.py index 09b295a8..e05b71f6 100644 --- a/extract_msg/custom_attachments/outlook_image.py +++ b/extract_msg/custom_attachments/outlook_image_dib.py @@ -25,7 +25,12 @@ _ST_MAILSTREAM = struct.Struct(' bool: return True - def injectHTML(self, html : bytes, renderedList : Optional[List[str]] = None) -> Tuple[bytes, Optional[List[str]]]: - if not renderedList: - renderedList = htmlSplitRendered(html) - - rp = self.attachment.renderingPosition - - if rp >= len(renderedList): - raise CustomAttachmentError(f'Rendering position beyond calculated number of rendered characters (expected less than {len(renderedList)}, got {rp}).') - - renderedList[rp] = self.__htmlTag + renderedList[rp] - - return (''.join(renderedList).encode('utf-8'), renderedList) + def generateRtf(self) -> Optional[bytes]: + pass @property def data(self) -> bytes: @@ -106,4 +101,4 @@ def name(self) -> str: -registerHandler(OutlookImage) +registerHandler(OutlookImageDIB) diff --git a/extract_msg/message_base.py b/extract_msg/message_base.py index 381a0a4c..6c16e6ab 100644 --- a/extract_msg/message_base.py +++ b/extract_msg/message_base.py @@ -26,7 +26,7 @@ from . import constants from ._rtf.create_doc import createDocument from ._rtf.inject_rtf import injectStartRTF -from .enums import AttachmentType, DeencapType, RecipientType +from .enums import DeencapType, RecipientType from .exceptions import ( BadHtmlError, DataNotFoundError, DeencapMalformedData, DeencapNotEncapsulated, IncompatibleOptionsError, WKError @@ -1148,18 +1148,8 @@ def htmlBodyPrepared(self) -> Optional[bytes]: if not self.htmlBody: return self.htmlBody - html = self.htmlBody - - renderedCharacters = None - - # Iterate through all attachments, and inject all of the custom data - # from them. - for x in self.attachments: - if x.type is AttachmentType.CUSTOM: - html, renderedCharacters = x.customHandler.injectHTML(html, renderedCharacters) - # Create the BeautifulSoup instance to use. - soup = bs4.BeautifulSoup(html, 'html.parser') + soup = bs4.BeautifulSoup(self.htmlBody, 'html.parser') # Get a list of image tags to see if we can inject into. If the source # of an image starts with "cid:" that means it is one of the attachments From 197fc532bd7da04bff0aad278b61e42808dcaf90 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Sat, 10 Jun 2023 15:26:54 -0700 Subject: [PATCH 16/89] Remove odd newline --- extract_msg/ole_writer.py | 1 - 1 file changed, 1 deletion(-) diff --git a/extract_msg/ole_writer.py b/extract_msg/ole_writer.py index ec57f2d9..8642ca6b 100644 --- a/extract_msg/ole_writer.py +++ b/extract_msg/ole_writer.py @@ -648,7 +648,6 @@ def addOleEntry(self, path, entry : OleDirectoryEntry, data : Optional[bytes] = """ path = inputToMsgPath(path) # First, find the current place in our dict to add the item. - _dir = self.__getContainingStorage(path, False) # Now, check that the item *is not* already in our dict, as that would # cause problems. From 68cfb2531dca0b5ed163102008e85cbfa243c526 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Tue, 13 Jun 2023 15:08:53 -0700 Subject: [PATCH 17/89] Changed and finished the RTF code --- .../custom_attachments/custom_handler.py | 2 +- .../custom_attachments/outlook_image_dib.py | 42 ++++++++++++++++--- 2 files changed, 37 insertions(+), 7 deletions(-) diff --git a/extract_msg/custom_attachments/custom_handler.py b/extract_msg/custom_attachments/custom_handler.py index 90efa186..e721754d 100644 --- a/extract_msg/custom_attachments/custom_handler.py +++ b/extract_msg/custom_attachments/custom_handler.py @@ -37,7 +37,7 @@ def generateRtf(self) -> Optional[bytes]: """ Generates the RTF to inject in place of the \objattph tag. - If this function should do nothing, returns None + If this function should do nothing, returns None. """ @property diff --git a/extract_msg/custom_attachments/outlook_image_dib.py b/extract_msg/custom_attachments/outlook_image_dib.py index e05b71f6..4ed48a45 100644 --- a/extract_msg/custom_attachments/outlook_image_dib.py +++ b/extract_msg/custom_attachments/outlook_image_dib.py @@ -66,11 +66,11 @@ def __init__(self, attachment : Attachment): # Unpack the mailstream and create the HTML tag. vals = _ST_MAILSTREAM.unpack(stream) self.__dvaspect = DVAspect(vals[0]) - self.__y = vals[1] - self.__x = vals[2] - hwStyle = f'height: {self.__x / 100.0:.2f}mm; width: {self.__y / 100.0:.2f}mm;' - imgData = f'data:image;base64,{base64.b64encode(self.__data).decode("ascii")}' - self.__htmlTag = f'' + self.__x = vals[1] + self.__y = vals[2] + # Convert to twips for RTF. + self.__xtwips = int(round(self.__x / 1.7639)) + self.__ytwips = int(round(self.__y / 1.7639)) @classmethod def isCorrectHandler(cls, attachment : Attachment) -> bool: @@ -88,7 +88,37 @@ def isCorrectHandler(cls, attachment : Attachment) -> bool: return True def generateRtf(self) -> Optional[bytes]: - pass + """ + Generates the RTF to inject in place of the \objattph tag. + + If this function should do nothing, returns None. + + This function requires PIL or Pillow. If neither are found, raises an + import error. + """ + try: + import PIL.Image + except ImportError: + raise ImportError('PIL or Pillow is required for inserting an Outlook Image into the body.') + + # First, convert the bitmap into a PNG so we can insert it into the + # body. + import io + + # Note, use self.data instead of self.__data to allow support for + # extensions. + with PIL.Image.open(io.BytesIO(self.data)) as img: + out = io.BytesIO() + img.save(out, 'PNG') + + hexData = out.getvalue().hex() + + inject = '{\\*\\shppict\n{\\pict\\picscalex100\\picscaley100' + inject += f'\\picw{img.width}\\pich{img.height}' + inject += f'\\picwgoal{self.__xtwips}\\pichgoal{self.__ytwips}\n' + inject += '\\pngblip ' + hexData + '}}' + + return inject.encode() @property def data(self) -> bytes: From beb9125a5bb770280da82c30b86ad666149a5100 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Tue, 13 Jun 2023 15:55:10 -0700 Subject: [PATCH 18/89] Finalize changes for transfer back to next-release --- CHANGELOG.md | 5 ++ extract_msg/attachment.py | 4 +- extract_msg/attachment_base.py | 47 +++++++++---------- .../custom_attachments/custom_handler.py | 3 ++ 4 files changed, 32 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0145e45d..39603a93 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +**v0.42.0** +* Added new submodule `custom_attachments`. This submodule provides an extendable way to handle custom attachment types, attachment types whose structure and formatting are not defined in the Microsoft documentation for MSG files. +* Added new property `AttachmentBase.clsid` which returns the listed CLSID value of the data stream/storage of the attachment. +* Changed internal behavior of `MSGFile.attachments`. This should not cause any noticeable changes to the output. + **v0.41.5** * Fixed an issue from version `0.41.3` where the header being present but missing the `From` field would cause an exception. diff --git a/extract_msg/attachment.py b/extract_msg/attachment.py index 3dd65d3d..34cb797c 100644 --- a/extract_msg/attachment.py +++ b/extract_msg/attachment.py @@ -219,7 +219,7 @@ def save(self, **kwargs) -> Optional[Union[str, MSGFile]]: fullFilename = customPath / filename - if self.type is AttachmentType.DATA or (self.type is AttachmentType.CUSTOM and isinstance(self.__data, bytes)): + if isinstance(self.__data, bytes): if _zip: name, ext = os.path.splitext(filename) nameList = _zip.namelist() @@ -254,7 +254,7 @@ def save(self, **kwargs) -> Optional[Union[str, MSGFile]]: _zip.close() return str(fullFilename) - else: + elif self.__data: if kwargs.get('extractEmbedded', False): with _open(str(fullFilename), mode) as f: self.data.export(f) diff --git a/extract_msg/attachment_base.py b/extract_msg/attachment_base.py index 4659a325..1f1996a7 100644 --- a/extract_msg/attachment_base.py +++ b/extract_msg/attachment_base.py @@ -9,7 +9,7 @@ import datetime import logging -from functools import partial +from functools import cached_property, partial from typing import Optional, Tuple, TYPE_CHECKING from .enums import AttachmentType, ErrorBehavior, PropertiesType @@ -262,7 +262,7 @@ def existsTypedProperty(self, id, _type = None) -> bool: def attachmentEncoding(self) -> Optional[bytes]: """ The encoding information about the attachment object. Will return - b'*\x86H\x86\xf7\x14\x03\x0b\x01' if encoded in MacBinary format, + b'*\\x86H\\x86\\xf7\\x14\\x03\\x0b\\x01' if encoded in MacBinary format, otherwise it is unset. """ return self._ensureSet('_attachmentEncoding', '__substg1.0_37020102', False) @@ -287,35 +287,32 @@ def cid(self) -> Optional[str]: contendId = cid - @property + @cached_property def clsid(self) -> str: """ Returns the CLSID for the data stream/storage of the attachment. """ - try: - return self.__clsid - except AttributeError: - # Set some default values. - self.__clsid = '00000000-0000-0000-0000-000000000000' - dataStream = None - - # See if we can find the data stream/storage. - if self.type in (AttachmentType.CUSTOM, AttachmentType.MSG): + # Set some default values. + clsid = '00000000-0000-0000-0000-000000000000' + dataStream = None + + # See if we can find the data stream/storage. + if self.type in (AttachmentType.CUSTOM, AttachmentType.MSG): + dataStream = [self.__dir, '__substg1.0_3701000D'] + elif self.type is AttachmentType.DATA: + dataStream = [self.__dir, '__substg1.0_37010102'] + elif self.type is AttachmentType.UNSUPPORTED: + # Special check for custom attachments. + if self.exists('__substg1.0_3701000D'): dataStream = [self.__dir, '__substg1.0_3701000D'] - elif self.type is AttachmentType.DATA: + elif self.exists('__substg1.0_37010102'): dataStream = [self.__dir, '__substg1.0_37010102'] - elif self.type is AttachmentType.UNSUPPORTED: - # Special check for custom attachments. - if self.exists('__substg1.0_3701000D'): - dataStream = [self.__dir, '__substg1.0_3701000D'] - elif self.exists('__substg1.0_37010102'): - dataStream = [self.__dir, '__substg1.0_37010102'] - - # If we found the right item, get the CLSID. - if dataStream: - self.__clsid = self.__msg._getOleEntry(dataStream).clsid or '00000000-0000-0000-0000-000000000000' - - return self.__clsid + + # If we found the right item, get the CLSID. + if dataStream: + clsid = self.__msg._getOleEntry(dataStream).clsid or clsid + + return self.__clsid @property def dir(self) -> str: diff --git a/extract_msg/custom_attachments/custom_handler.py b/extract_msg/custom_attachments/custom_handler.py index e721754d..f6ebe21c 100644 --- a/extract_msg/custom_attachments/custom_handler.py +++ b/extract_msg/custom_attachments/custom_handler.py @@ -52,6 +52,9 @@ def attachment(self): def data(self) -> bytes: """ Gets the data for the attachment. + + If an attachment should do nothing when saving, return None from this + property. """ @property From dfbd32a6c66e51f1887f0c52a0052d846050d268 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Tue, 13 Jun 2023 16:13:54 -0700 Subject: [PATCH 19/89] Delete file that was meant to be deleted before --- changelog_temp.md | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 changelog_temp.md diff --git a/changelog_temp.md b/changelog_temp.md deleted file mode 100644 index bb6f63f4..00000000 --- a/changelog_temp.md +++ /dev/null @@ -1,7 +0,0 @@ -Temporary location for the changelog entry to ensure it doesn't conflict. - -**v0.??.??** -* Added new submodule `custom_attachments`. This submodule provides an extendable way to handle custom attachment types, attachment types whose structure and formatting are not defined in the Microsoft documentation for MSG files. -* Added new property `AttachmentBase.clsid` which returns the listed CLSID value of the data stream/storage of the attachment. -* Changed internal behavior of `MSGFile.attachments`. This should not cause any noticeable changes to the output. -* Removed some debug code that was left behind. From 267e86c888f8323b3a6f76f4b6371fb7f6c4d07e Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Tue, 13 Jun 2023 17:55:06 -0700 Subject: [PATCH 20/89] Significant refactoring and bug fixes --- .gitignore | 1 - CHANGELOG.md | 2 + README.rst | 4 +- extract_msg/__init__.py | 49 ++--- extract_msg/attachments/__init__.py | 24 ++ extract_msg/{ => attachments}/attachment.py | 13 +- .../{ => attachments}/attachment_base.py | 18 +- .../custom_attachments/__init__.py | 0 .../custom_attachments/custom_handler.py | 2 +- .../custom_attachments/outlook_image_dib.py | 7 +- .../{ => attachments}/signed_attachment.py | 7 +- extract_msg/custom_attachments/utils.py | 207 ------------------ .../{ => data}/logging-config/logging-nt.json | 0 .../logging-config/logging-posix.json | 0 extract_msg/exceptions.py | 13 -- extract_msg/msg_classes/__init__.py | 45 ++++ extract_msg/{ => msg_classes}/appointment.py | 6 +- extract_msg/{ => msg_classes}/calendar.py | 4 +- .../{ => msg_classes}/calendar_base.py | 14 +- extract_msg/{ => msg_classes}/contact.py | 8 +- .../{ => msg_classes}/meeting_cancellation.py | 4 +- .../{ => msg_classes}/meeting_exception.py | 2 +- .../{ => msg_classes}/meeting_forward.py | 4 +- .../{ => msg_classes}/meeting_related.py | 4 +- .../{ => msg_classes}/meeting_request.py | 4 +- .../{ => msg_classes}/meeting_response.py | 4 +- extract_msg/{ => msg_classes}/message.py | 0 extract_msg/{ => msg_classes}/message_base.py | 16 +- .../{ => msg_classes}/message_signed.py | 0 .../{ => msg_classes}/message_signed_base.py | 8 +- extract_msg/{ => msg_classes}/msg.py | 26 +-- extract_msg/{ => msg_classes}/post.py | 4 +- extract_msg/{ => msg_classes}/task.py | 8 +- extract_msg/{ => msg_classes}/task_request.py | 6 +- extract_msg/ole_writer.py | 3 +- extract_msg/open_msg.py | 190 ++++++++++++++++ extract_msg/properties/__init__.py | 23 ++ extract_msg/{ => properties}/named.py | 8 +- extract_msg/{ => properties}/prop.py | 6 +- .../properties_store.py} | 10 +- extract_msg/recipient.py | 10 +- extract_msg/utils.py | 200 +---------------- pyrightconfig.json | 4 + 43 files changed, 421 insertions(+), 547 deletions(-) create mode 100644 extract_msg/attachments/__init__.py rename extract_msg/{ => attachments}/attachment.py (97%) rename extract_msg/{ => attachments}/attachment_base.py (97%) rename extract_msg/{ => attachments}/custom_attachments/__init__.py (100%) rename extract_msg/{ => attachments}/custom_attachments/custom_handler.py (96%) rename extract_msg/{ => attachments}/custom_attachments/outlook_image_dib.py (96%) rename extract_msg/{ => attachments}/signed_attachment.py (98%) delete mode 100644 extract_msg/custom_attachments/utils.py rename extract_msg/{ => data}/logging-config/logging-nt.json (100%) rename extract_msg/{ => data}/logging-config/logging-posix.json (100%) create mode 100644 extract_msg/msg_classes/__init__.py rename extract_msg/{ => msg_classes}/appointment.py (97%) rename extract_msg/{ => msg_classes}/calendar.py (98%) rename extract_msg/{ => msg_classes}/calendar_base.py (97%) rename extract_msg/{ => msg_classes}/contact.py (99%) rename extract_msg/{ => msg_classes}/meeting_cancellation.py (97%) rename extract_msg/{ => msg_classes}/meeting_exception.py (98%) rename extract_msg/{ => msg_classes}/meeting_forward.py (98%) rename extract_msg/{ => msg_classes}/meeting_related.py (96%) rename extract_msg/{ => msg_classes}/meeting_request.py (97%) rename extract_msg/{ => msg_classes}/meeting_response.py (97%) rename extract_msg/{ => msg_classes}/message.py (100%) rename extract_msg/{ => msg_classes}/message_base.py (99%) rename extract_msg/{ => msg_classes}/message_signed.py (100%) rename extract_msg/{ => msg_classes}/message_signed_base.py (97%) rename extract_msg/{ => msg_classes}/msg.py (98%) rename extract_msg/{ => msg_classes}/post.py (97%) rename extract_msg/{ => msg_classes}/task.py (98%) rename extract_msg/{ => msg_classes}/task_request.py (96%) create mode 100644 extract_msg/open_msg.py create mode 100644 extract_msg/properties/__init__.py rename extract_msg/{ => properties}/named.py (98%) rename extract_msg/{ => properties}/prop.py (98%) rename extract_msg/{properties.py => properties/properties_store.py} (97%) create mode 100644 pyrightconfig.json diff --git a/.gitignore b/.gitignore index 33d387b5..111ab755 100644 --- a/.gitignore +++ b/.gitignore @@ -19,7 +19,6 @@ __pycache__/ # Ignore new .msg files added from testing - /example-msg-files/expected-outputs/ /example-msg-files/*.msg diff --git a/CHANGELOG.md b/CHANGELOG.md index 39603a93..d44a0ee1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ * Added new submodule `custom_attachments`. This submodule provides an extendable way to handle custom attachment types, attachment types whose structure and formatting are not defined in the Microsoft documentation for MSG files. * Added new property `AttachmentBase.clsid` which returns the listed CLSID value of the data stream/storage of the attachment. * Changed internal behavior of `MSGFile.attachments`. This should not cause any noticeable changes to the output. +* Refactored code significantly to make it more organized. +* Changed the exports from the main module to only include an important subset of the module. For other items, you'll have to import the submodule that it falls under to access it. Submodules export all important pieces, so it will be easier to find. **v0.41.5** * Fixed an issue from version `0.41.3` where the header being present but missing the `From` field would cause an exception. diff --git a/README.rst b/README.rst index 4020af6b..8adbffa1 100644 --- a/README.rst +++ b/README.rst @@ -250,8 +250,8 @@ your access to the newest major version of extract-msg. .. |License: GPL v3| image:: https://img.shields.io/badge/License-GPLv3-blue.svg :target: LICENSE.txt -.. |PyPI3| image:: https://img.shields.io/badge/pypi-0.41.5-blue.svg - :target: https://pypi.org/project/extract-msg/0.41.5/ +.. |PyPI3| image:: https://img.shields.io/badge/pypi-0.42.0-blue.svg + :target: https://pypi.org/project/extract-msg/0.42.0/ .. |PyPI2| image:: https://img.shields.io/badge/python-3.8+-brightgreen.svg :target: https://www.python.org/downloads/release/python-3816/ diff --git a/extract_msg/__init__.py b/extract_msg/__init__.py index 088987ac..3fb88c2c 100644 --- a/extract_msg/__init__.py +++ b/extract_msg/__init__.py @@ -27,53 +27,38 @@ # along with this program. If not, see . __author__ = 'Destiny Peterson & Matthew Walker' -__date__ = '2023-06-11' -__version__ = '0.41.5' +__date__ = '2023-06-13' +__version__ = '0.42.0' __all__ = [ # Modules: - 'constants', + 'attachments', 'enums', 'exceptions', + 'msg_classes', + 'properties', # Classes: - 'AppointmentMeeting', 'Attachment', - 'Contact', - 'MeetingForwardNotification', - 'MeetingRequest', - 'MeetingResponse', + 'AttachmentBase', 'Message', - 'MessageBase', - 'MessageSigned', - 'MessageSignedBase', 'MSGFile', - 'Post', - 'Properties', + 'Named', + 'NamedProperties', + 'OleWriter', + 'PropertiesStore', 'Recipient', - 'Task', + 'SignedAttachment', #Functions: - 'createProp', 'openMsg', 'openMsgBulk', ] -from . import constants, enums, exceptions -from .appointment import AppointmentMeeting -from .attachment import Attachment -from .contact import Contact -from .meeting_forward import MeetingForwardNotification -from .meeting_request import MeetingRequest -from .meeting_response import MeetingResponse -from .message import Message -from .message_base import MessageBase -from .message_signed import MessageSigned -from .message_signed_base import MessageSignedBase -from .msg import MSGFile -from .post import Post -from .prop import createProp -from .properties import Properties +from . import attachments, enums, exceptions, msg_classes, properties +from .attachments import Attachment, AttachmentBase, SignedAttachment +from .msg_classes import Message, MSGFile +from .ole_writer import OleWriter +from .open_msg import openMsg, openMsgBulk +from .properties import Named, NamedProperties, PropertiesStore from .recipient import Recipient -from .task import Task -from .utils import openMsg, openMsgBulk diff --git a/extract_msg/attachments/__init__.py b/extract_msg/attachments/__init__.py new file mode 100644 index 00000000..8e07dd0f --- /dev/null +++ b/extract_msg/attachments/__init__.py @@ -0,0 +1,24 @@ +""" +Submodule for attachment classes. +""" + +__all__ = [ + # Modules. + 'custom_attachments', + + # Classes. + 'Attachment', + 'AttachmentBase', + 'CustomAttachmentHandler', + 'SignedAttachment', + + # Functions. + 'registerHandler', +] + + +from . import custom_attachments +from .attachment import Attachment +from .attachment_base import AttachmentBase +from .custom_attachments import CustomAttachmentHandler, registerHandler +from .signed_attachment import SignedAttachment \ No newline at end of file diff --git a/extract_msg/attachment.py b/extract_msg/attachments/attachment.py similarity index 97% rename from extract_msg/attachment.py rename to extract_msg/attachments/attachment.py index 34cb797c..b2131036 100644 --- a/extract_msg/attachment.py +++ b/extract_msg/attachments/attachment.py @@ -17,17 +17,18 @@ from typing import Optional, TYPE_CHECKING, Union -from . import constants +from .. import constants from .attachment_base import AttachmentBase from .custom_attachments import CustomAttachmentHandler, getHandler -from .enums import AttachmentType -from .exceptions import StandardViolationError -from .utils import createZipOpen, inputToString, openMsg, prepareFilename +from ..enums import AttachmentType +from ..exceptions import StandardViolationError +from ..open_msg import openMsg +from ..utils import createZipOpen, inputToString, prepareFilename # Allow for nice type checking. if TYPE_CHECKING: - from .msg import MSGFile + from ..msg_classes.msg import MSGFile logger = logging.getLogger(__name__) logger.addHandler(logging.NullHandler()) @@ -51,7 +52,7 @@ def __init__(self, msg, dir_): self.__customHandler = None if '37050003' not in self.props: - from .prop import createProp + from ..properties.prop import createProp logger.warning(f'Attachment method property not found on attachment {dir_}. Code will attempt to guess the type.') logger.log(5, self.props) diff --git a/extract_msg/attachment_base.py b/extract_msg/attachments/attachment_base.py similarity index 97% rename from extract_msg/attachment_base.py rename to extract_msg/attachments/attachment_base.py index 1f1996a7..1d4417d7 100644 --- a/extract_msg/attachment_base.py +++ b/extract_msg/attachments/attachment_base.py @@ -12,17 +12,17 @@ from functools import cached_property, partial from typing import Optional, Tuple, TYPE_CHECKING -from .enums import AttachmentType, ErrorBehavior, PropertiesType -from .exceptions import StandardViolationError -from .named import NamedProperties -from .prop import FixedLengthProp -from .properties import Properties -from .utils import tryGetMimetype, verifyPropertyId, verifyType +from ..enums import AttachmentType, ErrorBehavior, PropertiesType +from ..exceptions import StandardViolationError +from ..properties.named import NamedProperties +from ..properties.prop import FixedLengthProp +from ..properties.properties_store import PropertiesStore +from ..utils import tryGetMimetype, verifyPropertyId, verifyType # Allow for nice type checking. if TYPE_CHECKING: - from .msg import MSGFile + from ..msg_classes.msg import MSGFile logger = logging.getLogger(__name__) logger.addHandler(logging.NullHandler()) @@ -48,7 +48,7 @@ def __init__(self, msg, dir_): logger.error('Attachments MUST have a property stream.') else: raise StandardViolationError('Attachments MUST have a property stream.') from None - self.__props = Properties(self._getStream('__properties_version1.0'), PropertiesType.ATTACHMENT) + self.__props = PropertiesStore(self._getStream('__properties_version1.0'), PropertiesType.ATTACHMENT) self.__namedProperties = NamedProperties(msg.named, self) self.__treePath = msg.treePath + (self,) @@ -407,7 +407,7 @@ def payloadClass(self) -> Optional[str]: return self._ensureSet('_payloadClass', '__substg1.0_371A') @property - def props(self) -> Properties: + def props(self) -> PropertiesStore: """ Returns the Properties instance of the attachment. """ diff --git a/extract_msg/custom_attachments/__init__.py b/extract_msg/attachments/custom_attachments/__init__.py similarity index 100% rename from extract_msg/custom_attachments/__init__.py rename to extract_msg/attachments/custom_attachments/__init__.py diff --git a/extract_msg/custom_attachments/custom_handler.py b/extract_msg/attachments/custom_attachments/custom_handler.py similarity index 96% rename from extract_msg/custom_attachments/custom_handler.py rename to extract_msg/attachments/custom_attachments/custom_handler.py index f6ebe21c..a787ae1f 100644 --- a/extract_msg/custom_attachments/custom_handler.py +++ b/extract_msg/attachments/custom_attachments/custom_handler.py @@ -8,7 +8,7 @@ import abc -from typing import List, Optional, Tuple, TYPE_CHECKING +from typing import Optional, TYPE_CHECKING if TYPE_CHECKING: diff --git a/extract_msg/custom_attachments/outlook_image_dib.py b/extract_msg/attachments/custom_attachments/outlook_image_dib.py similarity index 96% rename from extract_msg/custom_attachments/outlook_image_dib.py rename to extract_msg/attachments/custom_attachments/outlook_image_dib.py index 4ed48a45..92cc168b 100644 --- a/extract_msg/custom_attachments/outlook_image_dib.py +++ b/extract_msg/attachments/custom_attachments/outlook_image_dib.py @@ -9,13 +9,11 @@ import base64 import struct -from typing import List, Optional, Tuple, TYPE_CHECKING +from typing import Optional, TYPE_CHECKING from . import registerHandler from .custom_handler import CustomAttachmentHandler -from .utils import htmlSplitRendered -from ..enums import DVAspect -from ..exceptions import CustomAttachmentError +from ...enums import DVAspect if TYPE_CHECKING: @@ -130,5 +128,4 @@ def name(self) -> str: - registerHandler(OutlookImageDIB) diff --git a/extract_msg/signed_attachment.py b/extract_msg/attachments/signed_attachment.py similarity index 98% rename from extract_msg/signed_attachment.py rename to extract_msg/attachments/signed_attachment.py index 17d1bc97..a58f3706 100644 --- a/extract_msg/signed_attachment.py +++ b/extract_msg/attachments/signed_attachment.py @@ -14,13 +14,14 @@ from typing import Tuple, TYPE_CHECKING, Union -from .enums import AttachmentType -from .utils import createZipOpen, inputToString, openMsg, prepareFilename +from ..enums import AttachmentType +from ..open_msg import openMsg +from ..utils import createZipOpen, inputToString, prepareFilename # Allow for nice type checking. if TYPE_CHECKING: - from .msg import MSGFile + from ..msg_classes.msg import MSGFile logger = logging.getLogger(__name__) logger.addHandler(logging.NullHandler()) diff --git a/extract_msg/custom_attachments/utils.py b/extract_msg/custom_attachments/utils.py deleted file mode 100644 index 18d8507e..00000000 --- a/extract_msg/custom_attachments/utils.py +++ /dev/null @@ -1,207 +0,0 @@ -""" -Utilities for extract-msg that are more specialized for the custom_attachments -submodule than for the main module. -""" - -__all__ = [ - 'htmlSplitRendered', - 'tokenizeHtml', -] - - -import bs4 - -from typing import List - - -_WHITESPACE_BREAKERS = ( - ' bool: - """ - Helper function to indicate that a tag breaks a chain of whitespace. - """ - for x in _WHITESPACE_BREAKERS: - if token.startswith(x) and len(token) > len(x) and token[len(x)] in ('>', ' ', '/'): - return True - - return False - - -def _isWhitespaceToken(token : str) -> bool: - if token[0] == '<': - for x in _WHITESPACE_TAGS: - if token.startswith(x) and len(token) > len(x) and token[len(x)] in ('>', ' ', '/'): - return True - elif token in (' ', ' ', ' ', ' ', ' '): - return True - else: - return token.isspace() - - return False - - -def htmlSplitRendered(html : bytes) -> List[str]: - """ - Takes html bytes and returns a list of the rendered characters, with data - that is not being rendered being attached to the next rendered character. - """ - # Unfortunately bs4 didn't seem particularly great for tokenizing, so I did - # my own function that works well enough. First, let's tokenize the html. - tokens = tokenizeHtml(bs4.BeautifulSoup(html, features = 'html.parser').decode()) - - # Next, let's break things down further. - breakDown = [] - for token in tokens: - # We tell what we are looking at by checking the first character of the - # token. If it's a <, then it is an HTML tag. If it is a & then it is an - # escape. Otherwise, it is plain text. For both tags and escapes, just - # dump them into the list. - if token[0] in ('<', '&'): - breakDown.append(token) - else: - # If we are looking at plain text, add it by extending the list. - breakDown.extend(token) - - # Now that we have broken things down further, let's go through and join our - # pieces togethered into rendered tokens. Here is were we actually need to - # know what an html tag is. If it's an escape or just a non-whitespace - # character, we can just shove it onto what we currently have. - current = '' - renderedCharacters = [] - lastWhitespace = None - for item in breakDown: - if item[0] == '&': - if _isWhitespaceToken(item): - if lastWhitespace is None: - lastWhitespace == item - else: - if lastWhitespace is not None and lastWhitespace[0] != '<': - current += lastWhitespace - renderedCharacters.append(current) - current = '' - lastWhitespace = None - current += item - renderedCharacters.append(current) - current = '' - elif item[0] == '<': - if _isWhitespaceToken(item): - # If we are here, add it to current, push current, and set this - # tag as the last whitespace. - current += item - renderedCharacters.append(current) - current = '' - lastWhitespace = item - else: - - # Some tags will break whitespace chains. - if _isWhitespaceBreaker(item): - if lastWhitespace is not None and lastWhitespace[0] != '<': - current += lastWhitespace - renderedCharacters.append(current) - current = '' - lastWhitespace = None - - current += item - else: - # Here is where we handle text, which is not particularly fun. - # Basically if it is whitespace and lastWhitespace is not none, we - # set the whitespace. - if _isWhitespaceToken(item): - if lastWhitespace is None: - lastWhitespace = item - else: - if lastWhitespace is not None and lastWhitespace[0] != '<': - current += lastWhitespace - renderedCharacters.append(current) - current = '' - lastWhitespace = None - current += item - renderedCharacters.append(current) - current = '' - - if current: - renderedCharacters.append(current) - - return renderedCharacters - - -def tokenizeHtml(html : str) -> List[str]: - # Setup a few variables for state tracking. - inTag = False - # Used for tracking escapes starting with &. If your escape ends up at 100 - # characters because it is missing the semicolon, we are going to throw an - # error. - inEscape = False - inString = False - # Only used when in string. Last character was a backslash. - isBackslash = False - # Tells which quote type we are in. - isDoubleQuote = False - - tokens = [] - currentToken = '' - - # Finally, let's start breaking things up. Our rules are that if we start a - # quote while in a tag, then we acknowledge it, otherwise it is treated as - # plain text. - for character in html: - # First we need to know our state, as our state determines what how we - # process a character. - if inTag: - currentToken += character - if inString: - if character == '"' and isDoubleQuote: - # If isBackslash then we stay in the quote, otherwise... - isQuote = isBackslash - elif character == "'" and not isDoubleQuote: - # If isBackslash then we stay in the quote, otherwise... - isQuote = isBackslash - elif character == '\\': - isBackslash = not isBackslash - if character != '\\': - isBackslash = False - else: - if character == '>': - inTag = False - tokens.append(currentToken) - currentToken = '' - elif inEscape: - currentToken += character - if len(currentToken) > 99: - raise ValueError('Found escape that was too long (is a ; missing?)') - if character == ';': - tokens.append(currentToken) - currentToken = '' - inEscape = False - elif inString: - # This is an error. We should *never* be in a quote if we are not in - # a tag. - raise ValueError('Found to be inQuote when not in tag.') - else: - # We are currently processing plain text, so let's just handle. - if character == '&': - if currentToken: - tokens.append(currentToken) - currentToken = character - inEscape = True - elif character == '<': - if currentToken: - tokens.append(currentToken) - currentToken = character - inTag = True - inString = False - else: - currentToken += character - - if currentToken: - tokens.append(currentToken) - - return tokens diff --git a/extract_msg/logging-config/logging-nt.json b/extract_msg/data/logging-config/logging-nt.json similarity index 100% rename from extract_msg/logging-config/logging-nt.json rename to extract_msg/data/logging-config/logging-nt.json diff --git a/extract_msg/logging-config/logging-posix.json b/extract_msg/data/logging-config/logging-posix.json similarity index 100% rename from extract_msg/logging-config/logging-posix.json rename to extract_msg/data/logging-config/logging-posix.json diff --git a/extract_msg/exceptions.py b/extract_msg/exceptions.py index 2223faca..6971cda0 100644 --- a/extract_msg/exceptions.py +++ b/extract_msg/exceptions.py @@ -28,14 +28,6 @@ ] -import logging - - -# Add logger bus. -logger = logging.getLogger(__name__) -logger.addHandler(logging.NullHandler()) - - class BadHtmlError(ValueError): """ HTML failed to pass validation. @@ -46,11 +38,6 @@ class ConversionError(Exception): An error occured during type conversion. """ -class CustomAttachmentError(Exception): - """ - A generic error used for issues handling custom attachments. - """ - class DataNotFoundError(Exception): """ Requested stream type was unavailable. diff --git a/extract_msg/msg_classes/__init__.py b/extract_msg/msg_classes/__init__.py new file mode 100644 index 00000000..0d5c9efa --- /dev/null +++ b/extract_msg/msg_classes/__init__.py @@ -0,0 +1,45 @@ +""" +Classes for opening an MSG file with. +""" + +__all__ = [ + # Classes. + 'AppointmentMeeting', + 'Calendar', + 'CalendarBase', + 'Contact', + 'MeetingCancellation', + 'MeetingException', + 'MeetingForwardNotification', + 'MeetingRelated', + 'MeetingRequest', + 'MeetingResponse', + 'Message', + 'MessageBase', + 'MessageSigned', + 'MessageSignedBase', + 'MSGFile', + 'Post', + 'Task', + 'TaskRequest', +] + + +from .appointment import AppointmentMeeting +from .calendar_base import CalendarBase +from .calendar import Calendar +from .contact import Contact +from .meeting_cancellation import MeetingCancellation +from .meeting_exception import MeetingException +from .meeting_forward import MeetingForwardNotification +from .meeting_related import MeetingRelated +from .meeting_request import MeetingRequest +from .meeting_response import MeetingResponse +from .message import Message +from .message_base import MessageBase +from .message_signed import MessageSigned +from .message_signed_base import MessageSignedBase +from .msg import MSGFile +from .post import Post +from .task import Task +from .task_request import TaskRequest \ No newline at end of file diff --git a/extract_msg/appointment.py b/extract_msg/msg_classes/appointment.py similarity index 97% rename from extract_msg/appointment.py rename to extract_msg/msg_classes/appointment.py index 303e9b92..1dcc5cfa 100644 --- a/extract_msg/appointment.py +++ b/extract_msg/msg_classes/appointment.py @@ -7,10 +7,10 @@ from typing import Optional -from . import constants -from .enums import AppointmentStateFlag, RecurPatternType, ResponseStatus +from .. import constants +from ..enums import AppointmentStateFlag, RecurPatternType, ResponseStatus from .calendar import Calendar -from .structures.entry_id import EntryID +from ..structures.entry_id import EntryID class AppointmentMeeting(Calendar): diff --git a/extract_msg/calendar.py b/extract_msg/msg_classes/calendar.py similarity index 98% rename from extract_msg/calendar.py rename to extract_msg/msg_classes/calendar.py index b73f796e..b78f5c9a 100644 --- a/extract_msg/calendar.py +++ b/extract_msg/msg_classes/calendar.py @@ -7,9 +7,9 @@ from typing import Optional, Set -from . import constants +from .. import constants from .calendar_base import CalendarBase -from .enums import ClientIntentFlag +from ..enums import ClientIntentFlag class Calendar(CalendarBase): diff --git a/extract_msg/calendar_base.py b/extract_msg/msg_classes/calendar_base.py similarity index 97% rename from extract_msg/calendar_base.py rename to extract_msg/msg_classes/calendar_base.py index 79b89e29..9e369be0 100644 --- a/extract_msg/calendar_base.py +++ b/extract_msg/msg_classes/calendar_base.py @@ -8,14 +8,14 @@ from typing import List, Optional, Set, Tuple, Union -from . import constants -from .enums import AppointmentAuxilaryFlag, AppointmentColor, AppointmentStateFlag, BusyStatus, IconIndex, MeetingRecipientType, ResponseStatus +from .. import constants +from ..enums import AppointmentAuxilaryFlag, AppointmentColor, AppointmentStateFlag, BusyStatus, IconIndex, MeetingRecipientType, ResponseStatus from .message_base import MessageBase -from .structures.entry_id import EntryID -from .structures.misc_id import GlobalObjectID -from .structures.recurrence_pattern import RecurrencePattern -from .structures.time_zone_definition import TimeZoneDefinition -from .structures.time_zone_struct import TimeZoneStruct +from ..structures.entry_id import EntryID +from ..structures.misc_id import GlobalObjectID +from ..structures.recurrence_pattern import RecurrencePattern +from ..structures.time_zone_definition import TimeZoneDefinition +from ..structures.time_zone_struct import TimeZoneStruct logger = logging.getLogger(__name__) diff --git a/extract_msg/contact.py b/extract_msg/msg_classes/contact.py similarity index 99% rename from extract_msg/contact.py rename to extract_msg/msg_classes/contact.py index 740ab8e1..c35f8ea4 100644 --- a/extract_msg/contact.py +++ b/extract_msg/msg_classes/contact.py @@ -7,11 +7,11 @@ from typing import Dict, List, Optional, Set, Tuple, TYPE_CHECKING,Union -from . import constants -from .enums import ContactLinkState, ElectronicAddressProperties, Gender, PostalAddressID +from .. import constants +from ..enums import ContactLinkState, ElectronicAddressProperties, Gender, PostalAddressID from .message_base import MessageBase -from .structures.entry_id import EntryID -from .structures.business_card import BusinessCardDisplayDefinition +from ..structures.entry_id import EntryID +from ..structures.business_card import BusinessCardDisplayDefinition # Allow for type checking an optional dependency. diff --git a/extract_msg/meeting_cancellation.py b/extract_msg/msg_classes/meeting_cancellation.py similarity index 97% rename from extract_msg/meeting_cancellation.py rename to extract_msg/msg_classes/meeting_cancellation.py index 1f96bc4a..2d184659 100644 --- a/extract_msg/meeting_cancellation.py +++ b/extract_msg/msg_classes/meeting_cancellation.py @@ -3,8 +3,8 @@ ] -from . import constants -from .enums import RecurPatternType, ResponseStatus +from .. import constants +from ..enums import RecurPatternType, ResponseStatus from .meeting_related import MeetingRelated diff --git a/extract_msg/meeting_exception.py b/extract_msg/msg_classes/meeting_exception.py similarity index 98% rename from extract_msg/meeting_exception.py rename to extract_msg/msg_classes/meeting_exception.py index 09fbc6eb..543b8af5 100644 --- a/extract_msg/meeting_exception.py +++ b/extract_msg/msg_classes/meeting_exception.py @@ -7,7 +7,7 @@ from typing import Optional -from . import constants +from .. import constants from .meeting_related import MeetingRelated diff --git a/extract_msg/meeting_forward.py b/extract_msg/msg_classes/meeting_forward.py similarity index 98% rename from extract_msg/meeting_forward.py rename to extract_msg/msg_classes/meeting_forward.py index c1e490c3..361e173f 100644 --- a/extract_msg/meeting_forward.py +++ b/extract_msg/msg_classes/meeting_forward.py @@ -5,9 +5,9 @@ from typing import Optional -from . import constants +from .. import constants from .meeting_related import MeetingRelated -from .enums import RecurPatternType +from ..enums import RecurPatternType class MeetingForwardNotification(MeetingRelated): diff --git a/extract_msg/meeting_related.py b/extract_msg/msg_classes/meeting_related.py similarity index 96% rename from extract_msg/meeting_related.py rename to extract_msg/msg_classes/meeting_related.py index 983c92cd..9b881293 100644 --- a/extract_msg/meeting_related.py +++ b/extract_msg/msg_classes/meeting_related.py @@ -7,9 +7,9 @@ from typing import Optional, Set -from . import constants +from .. import constants from .calendar_base import CalendarBase -from .enums import ServerProcessingAction +from ..enums import ServerProcessingAction class MeetingRelated(CalendarBase): diff --git a/extract_msg/meeting_request.py b/extract_msg/msg_classes/meeting_request.py similarity index 97% rename from extract_msg/meeting_request.py rename to extract_msg/msg_classes/meeting_request.py index 4e4fd167..6214fd18 100644 --- a/extract_msg/meeting_request.py +++ b/extract_msg/msg_classes/meeting_request.py @@ -7,9 +7,9 @@ from typing import List, Optional, Set -from . import constants +from .. import constants from .meeting_related import MeetingRelated -from .enums import BusyStatus, MeetingObjectChange, MeetingType, RecurCalendarType, RecurPatternType, ResponseStatus +from ..enums import BusyStatus, MeetingObjectChange, MeetingType, RecurCalendarType, RecurPatternType, ResponseStatus class MeetingRequest(MeetingRelated): diff --git a/extract_msg/meeting_response.py b/extract_msg/msg_classes/meeting_response.py similarity index 97% rename from extract_msg/meeting_response.py rename to extract_msg/msg_classes/meeting_response.py index 2d81f38d..7bf30c22 100644 --- a/extract_msg/meeting_response.py +++ b/extract_msg/msg_classes/meeting_response.py @@ -7,8 +7,8 @@ from typing import Optional -from . import constants -from .enums import ResponseType +from .. import constants +from ..enums import ResponseType from .meeting_related import MeetingRelated diff --git a/extract_msg/message.py b/extract_msg/msg_classes/message.py similarity index 100% rename from extract_msg/message.py rename to extract_msg/msg_classes/message.py diff --git a/extract_msg/message_base.py b/extract_msg/msg_classes/message_base.py similarity index 99% rename from extract_msg/message_base.py rename to extract_msg/msg_classes/message_base.py index f126a923..250d3c24 100644 --- a/extract_msg/message_base.py +++ b/extract_msg/msg_classes/message_base.py @@ -27,18 +27,18 @@ from email.parser import Parser as EmailParser from typing import Callable, List, Optional, Union -from . import constants -from ._rtf.create_doc import createDocument -from ._rtf.inject_rtf import injectStartRTF -from .enums import BodyTypes, DeencapType, RecipientType -from .exceptions import ( +from .. import constants +from .._rtf.create_doc import createDocument +from .._rtf.inject_rtf import injectStartRTF +from ..enums import BodyTypes, DeencapType, RecipientType +from ..exceptions import ( BadHtmlError, DataNotFoundError, DeencapMalformedData, DeencapNotEncapsulated, IncompatibleOptionsError, WKError ) from .msg import MSGFile -from .structures.report_tag import ReportTag -from .recipient import Recipient -from .utils import ( +from ..structures.report_tag import ReportTag +from ..recipient import Recipient +from ..utils import ( addNumToDir, addNumToZipDir, createZipOpen, decodeRfc2047, findWk, htmlSanitize, inputToBytes, inputToString, isEncapsulatedRtf, prepareFilename, rtfSanitizeHtml, rtfSanitizePlain, validateHtml diff --git a/extract_msg/message_signed.py b/extract_msg/msg_classes/message_signed.py similarity index 100% rename from extract_msg/message_signed.py rename to extract_msg/msg_classes/message_signed.py diff --git a/extract_msg/message_signed_base.py b/extract_msg/msg_classes/message_signed_base.py similarity index 97% rename from extract_msg/message_signed_base.py rename to extract_msg/msg_classes/message_signed_base.py index 84a8145b..ab65cc50 100644 --- a/extract_msg/message_signed_base.py +++ b/extract_msg/msg_classes/message_signed_base.py @@ -9,11 +9,11 @@ from typing import List, Optional -from .enums import ErrorBehavior -from .exceptions import StandardViolationError +from ..enums import ErrorBehavior +from ..exceptions import StandardViolationError from .message_base import MessageBase -from .signed_attachment import SignedAttachment -from .utils import inputToBytes, inputToString, unwrapMultipart +from ..attachments import SignedAttachment +from ..utils import inputToBytes, inputToString, unwrapMultipart logger = logging.getLogger(__name__) diff --git a/extract_msg/msg.py b/extract_msg/msg_classes/msg.py similarity index 98% rename from extract_msg/msg.py rename to extract_msg/msg_classes/msg.py index 8b7a55ff..a06f99e4 100644 --- a/extract_msg/msg.py +++ b/extract_msg/msg_classes/msg.py @@ -16,19 +16,19 @@ from typing import List, Optional, Set, Tuple, Union -from . import constants -from .attachment import Attachment, BrokenAttachment, UnsupportedAttachment -from .enums import ( +from .. import constants +from ..attachments.attachment import Attachment, BrokenAttachment, UnsupportedAttachment +from ..enums import ( AttachErrorBehavior, ErrorBehavior, Importance, Priority, PropertiesType, Sensitivity, SideEffect ) -from .exceptions import ( +from ..exceptions import ( InvalidFileFormatError, StandardViolationError, UnrecognizedMSGTypeError ) -from .named import Named, NamedProperties -from .prop import FixedLengthProp -from .properties import Properties -from .utils import ( +from ..properties.named import Named, NamedProperties +from ..properties.prop import FixedLengthProp +from ..properties.properties_store import PropertiesStore +from ..utils import ( divide, getEncodingName, hasLen, inputToMsgPath, inputToString, msgPathToString, parseType, properHex, verifyPropertyId, verifyType, windowsUnicode @@ -71,7 +71,7 @@ def __init__(self, path, **kwargs): :raises InvalidFileFormatError: If the file is not an OleFile or could not be parsed as an MSG file. - :raises StandardViolationError: If some part of the file badly violates + :raises StandardViolationError: If some part of the file badly violates the standard. :raises IOError: If there is an issue opening the MSG file. :raises NameError: If the encoding provided is not supported. @@ -534,7 +534,7 @@ def export(self, path) -> None: :param path: An IO device with a write method which accepts bytes or a path-like object (including strings and pathlib.Path objects). """ - from .ole_writer import OleWriter + from ..ole_writer import OleWriter # Create an instance of the class used for writing a new OLE file. writer = OleWriter() @@ -764,7 +764,7 @@ def currentVersionName(self) -> Optional[str]: Specifies the name of the client application that sent the message. """ return self._ensureSetNamed('_currentVersionName', '8554', constants.PSETID_COMMON) - + @property def errorBehavior(self) -> ErrorBehavior: """ @@ -881,7 +881,7 @@ def priority(self) -> Optional[Priority]: return self._ensureSetProperty('_priority', '00260003', overrideClass = Priority) @property - def props(self) -> Properties: + def props(self) -> PropertiesStore: """ Returns the Properties instance used by the MSGFile instance. """ @@ -895,7 +895,7 @@ def props(self) -> Properties: # Raise the exception from None so we don't get all the "during # the handling of the above exception" stuff. raise StandardViolationError('File does not contain a property stream.') from None - self._prop = Properties(stream, + self._prop = PropertiesStore(stream, PropertiesType.MESSAGE if self.prefix == '' else PropertiesType.MESSAGE_EMBED) return self._prop diff --git a/extract_msg/post.py b/extract_msg/msg_classes/post.py similarity index 97% rename from extract_msg/post.py rename to extract_msg/msg_classes/post.py index 8b87727d..be393f33 100644 --- a/extract_msg/post.py +++ b/extract_msg/msg_classes/post.py @@ -7,9 +7,9 @@ from typing import Optional -from . import constants +from .. import constants from .message_base import MessageBase -from .utils import inputToString +from ..utils import inputToString from imapclient.imapclient import decode_utf7 diff --git a/extract_msg/task.py b/extract_msg/msg_classes/task.py similarity index 98% rename from extract_msg/task.py rename to extract_msg/msg_classes/task.py index e99c14b8..f6ecc93e 100644 --- a/extract_msg/task.py +++ b/extract_msg/msg_classes/task.py @@ -8,14 +8,14 @@ from typing import Optional, Set -from . import constants -from .enums import ( +from .. import constants +from ..enums import ( TaskAcceptance, TaskHistory, TaskMode, TaskMultipleRecipients, TaskOwnership, TaskState, TaskStatus ) from .message_base import MessageBase -from .structures.recurrence_pattern import RecurrencePattern -from .utils import unsignedToSignedInt +from ..structures.recurrence_pattern import RecurrencePattern +from ..utils import unsignedToSignedInt logger = logging.getLogger(__name__) diff --git a/extract_msg/task_request.py b/extract_msg/msg_classes/task_request.py similarity index 96% rename from extract_msg/task_request.py rename to extract_msg/msg_classes/task_request.py index 6b2ea8cf..8550d0ca 100644 --- a/extract_msg/task_request.py +++ b/extract_msg/msg_classes/task_request.py @@ -7,9 +7,9 @@ from typing import Optional -from . import constants -from .enums import ErrorBehavior, TaskMode, TaskRequestType -from .exceptions import StandardViolationError +from .. import constants +from ..enums import ErrorBehavior, TaskMode, TaskRequestType +from ..exceptions import StandardViolationError from .message_base import MessageBase from .task import Task diff --git a/extract_msg/ole_writer.py b/extract_msg/ole_writer.py index 8642ca6b..dd8a6967 100644 --- a/extract_msg/ole_writer.py +++ b/extract_msg/ole_writer.py @@ -21,8 +21,7 @@ # Allow for nice type checking. if TYPE_CHECKING: - from .msg import MSGFile - + from .msg_classes import MSGFile class DirectoryEntry: diff --git a/extract_msg/open_msg.py b/extract_msg/open_msg.py new file mode 100644 index 00000000..27f14e6c --- /dev/null +++ b/extract_msg/open_msg.py @@ -0,0 +1,190 @@ +from __future__ import annotations + + +__all__ = [ + 'openMsg', + 'openMsgBulk', +] + + +import glob +import logging + +from typing import List, Tuple, TYPE_CHECKING, Union + +from . import constants +from .exceptions import ( + InvalidFileFormatError, UnrecognizedMSGTypeError, + UnsupportedMSGTypeError + ) + + +logger = logging.getLogger(__name__) +logger.addHandler(logging.NullHandler()) + +if TYPE_CHECKING: + from .msg_classes import MSGFile + + +def knownMsgClass(classType : str) -> bool: + """ + Checks if the specified class type is recognized by the module. Usually used + for checking if a type is simply unsupported rather than unknown. + """ + classType = classType.lower() + if classType == 'ipm': + return True + + for item in constants.KNOWN_CLASS_TYPES: + if classType.startswith(item): + return True + + return False + + +def openMsg(path, **kwargs) -> MSGFile: + """ + Function to automatically open an MSG file and detect what type it is. + :param path: Path to the msg file in the system or is the raw msg file. + :param prefix: Used for extracting embeded msg files inside the main one. + Do not set manually unless you know what you are doing. + :param parentMsg: Used for syncronizing named properties instances. Do not + set this unless you know what you are doing. + :param attachmentClass: Optional, the class the Message object will use for + attachments. You probably should not change this value unless you know + what you are doing. + :param signedAttachmentClass: Optional, the class the object will use for + signed attachments. + :param filename: Optional, the filename to be used by default when saving. + :param delayAttachments: Optional, delays the initialization of attachments + until the user attempts to retrieve them. Allows MSG files with bad + attachments to be initialized so the other data can be retrieved. + :param overrideEncoding: Optional, overrides the specified encoding of the + MSG file. + :param attachmentErrorBehavior: Optional, the behaviour to use in the event + of an error when parsing the attachments. + :param recipientSeparator: Optional, Separator string to use between + recipients. + :param ignoreRtfDeErrors: Optional, specifies that any errors that occur + from the usage of RTFDE should be ignored (default: False). + If :param strict: is set to `True`, this function will raise an exception + when it cannot identify what MSGFile derivitive to use. Otherwise, it will + log the error and return a basic MSGFile instance. + :raises UnsupportedMSGTypeError: if the type is recognized but not suppoted. + :raises UnrecognizedMSGTypeError: if the type is not recognized. + """ + from .msg_classes import ( + AppointmentMeeting, Contact, MeetingCancellation, MeetingException, + MeetingForwardNotification, MeetingRequest, MeetingResponse, + Message, MSGFile, MessageSigned, Post, Task, TaskRequest + ) + + # When the initial MSG file is opened, it should *always* delay attachments + # so it can get the main class type. We only need to load them after that + # if we are directly returning the MSGFile instance *and* delayAttachments + # is False. + # + # So first let's store the original value. + delayAttachments = kwargs.get('delayAttachments', False) + kwargs['delayAttachments'] = True + + msg = MSGFile(path, **kwargs) + + # Restore the option in the kwargs so we don't have to worry about it. + kwargs['delayAttachments'] = delayAttachments + + # After rechecking the docs, all comparisons should be case-insensitive, not + # case-sensitive. My reading ability is great. + # + # Also after consideration, I realized we need to be very careful here, as + # other file types (like doc, ppt, etc.) might open but not return a class + # type. If the stream is not found, classType returns None, which has no + # lower function. So let's make sure we got a good return first. + if not msg.classType: + if kwargs.get('strict', True): + raise InvalidFileFormatError('File was confirmed to be an olefile, but was not an MSG file.') + else: + # If strict mode is off, we'll just return an MSGFile anyways. + logger.critical('Received file that was an olefile but was not an MSG file. Returning MSGFile anyways because strict mode is off.') + return msg + classType = msg.classType.lower() + # Put the message class first as it is most common. + if classType.startswith('ipm.note') or classType.startswith('report'): + msg.close() + if classType.endswith('smime.multipartsigned') or classType.endswith('smime'): + return MessageSigned(path, **kwargs) + else: + return Message(path, **kwargs) + elif classType.startswith('ipm.appointment'): + msg.close() + return AppointmentMeeting(path, **kwargs) + elif classType.startswith('ipm.contact') or classType.startswith('ipm.distlist'): + msg.close() + return Contact(path, **kwargs) + elif classType.startswith('ipm.post'): + msg.close() + return Post(path, **kwargs) + elif classType.startswith('ipm.schedule.meeting.request'): + msg.close() + return MeetingRequest(path, **kwargs) + elif classType.startswith('ipm.schedule.meeting.canceled'): + msg.close() + return MeetingCancellation(path, **kwargs) + elif classType.startswith('ipm.schedule.meeting.notification.forward'): + msg.close() + return MeetingForwardNotification(path, **kwargs) + elif classType.startswith('ipm.schedule.meeting.resp'): + msg.close() + return MeetingResponse(path, **kwargs) + elif classType.startswith('ipm.taskrequest'): + msg.close() + return TaskRequest(path, **kwargs) + elif classType.startswith('ipm.task'): + msg.close() + return Task(path, **kwargs) + elif classType.startswith('ipm.ole.class.{00061055-0000-0000-c000-000000000046}'): + # Exception objects have a weird class type. + msg.close() + return MeetingException(path, **kwargs) + elif classType == 'ipm': + # Unspecified format. It should be equal to this and not just start with + # it. + if not delayAttachments: + msg.attachments + return msg + elif kwargs.get('strict', True): + # Because we are closing it, we need to store it in a variable first. + ct = msg.classType + msg.close() + if knownMsgClass(classType): + raise UnsupportedMSGTypeError(f'MSG type "{ct}" currently is not supported by the module. If you would like support, please make a feature request.') + raise UnrecognizedMSGTypeError(f'Could not recognize msg class type "{ct}".') + else: + logger.error(f'Could not recognize msg class type "{msg.classType}". This most likely means it hasn\'t been implemented yet, and you should ask the developers to add support for it.') + if not delayAttachments: + msg.attachments + return msg + + +def openMsgBulk(path, **kwargs) -> Union[List[MSGFile], Tuple[Exception, Union[str, bytes]]]: + """ + Takes the same arguments as openMsg, but opens a collection of msg files + based on a wild card. Returns a list if successful, otherwise returns a + tuple. + + :param ignoreFailures: If this is True, will return a list of all successful + files, ignoring any failures. Otherwise, will close all that + successfully opened, and return a tuple of the exception and the path of + the file that failed. + """ + files = [] + for x in glob.glob(str(path)): + try: + files.append(openMsg(x, **kwargs)) + except Exception as e: + if not kwargs.get('ignoreFailures', False): + for msg in files: + msg.close() + return (e, x) + + return files \ No newline at end of file diff --git a/extract_msg/properties/__init__.py b/extract_msg/properties/__init__.py new file mode 100644 index 00000000..0a56ac61 --- /dev/null +++ b/extract_msg/properties/__init__.py @@ -0,0 +1,23 @@ +""" +Classes and functions involved with managing properties. +""" + +__all__ = [ + 'FixedLengthProp', + 'Named', + 'NamedProperties', + 'NamedPropertyBase', + 'NumericalNamedProperty', + 'PropBase', + 'PropertiesStore', + 'StringNamedProperty', + 'VariableLengthProp', +] + + +from .named import ( + Named, NamedProperties, NamedPropertyBase, NumericalNamedProperty, + StringNamedProperty + ) +from .prop import FixedLengthProp, PropBase, VariableLengthProp +from .properties_store import PropertiesStore \ No newline at end of file diff --git a/extract_msg/named.py b/extract_msg/properties/named.py similarity index 98% rename from extract_msg/named.py rename to extract_msg/properties/named.py index 61008b68..e90e323d 100644 --- a/extract_msg/named.py +++ b/extract_msg/properties/named.py @@ -16,15 +16,15 @@ from typing import Dict, Optional, TYPE_CHECKING -from . import constants -from .enums import NamedPropertyType -from .utils import bytesToGuid, divide, properHex +from .. import constants +from ..enums import NamedPropertyType +from ..utils import bytesToGuid, divide, properHex from compressed_rtf.crc32 import crc32 # Allow for nice type checking. if TYPE_CHECKING: - from .msg import MSGFile + from ..msg_classes.msg import MSGFile logger = logging.getLogger(__name__) logger.addHandler(logging.NullHandler()) diff --git a/extract_msg/prop.py b/extract_msg/properties/prop.py similarity index 98% rename from extract_msg/prop.py rename to extract_msg/properties/prop.py index e72b7ae1..fcb80956 100644 --- a/extract_msg/prop.py +++ b/extract_msg/properties/prop.py @@ -14,9 +14,9 @@ from typing import Any -from . import constants -from .enums import ErrorCode, ErrorCodeType -from .utils import filetimeToDatetime, properHex +from .. import constants +from ..enums import ErrorCode, ErrorCodeType +from ..utils import filetimeToDatetime, properHex logger = logging.getLogger(__name__) diff --git a/extract_msg/properties.py b/extract_msg/properties/properties_store.py similarity index 97% rename from extract_msg/properties.py rename to extract_msg/properties/properties_store.py index 54055260..abffb0b4 100644 --- a/extract_msg/properties.py +++ b/extract_msg/properties/properties_store.py @@ -1,5 +1,5 @@ __all__ = [ - 'Properties', + 'PropertiesStore', ] @@ -11,17 +11,17 @@ from typing import Any, Dict, Optional, Union from warnings import warn -from . import constants -from .enums import Intelligence, PropertiesType +from .. import constants +from ..enums import Intelligence, PropertiesType from .prop import createProp, PropBase -from .utils import divide, properHex +from ..utils import divide, properHex logger = logging.getLogger(__name__) logger.addHandler(logging.NullHandler()) -class Properties: +class PropertiesStore: """ Parser for msg properties files. """ diff --git a/extract_msg/recipient.py b/extract_msg/recipient.py index 7cb61478..1cbe189e 100644 --- a/extract_msg/recipient.py +++ b/extract_msg/recipient.py @@ -9,8 +9,8 @@ from .enums import ErrorBehavior, MeetingRecipientType, PropertiesType, RecipientType from .exceptions import StandardViolationError -from .prop import FixedLengthProp -from .properties import Properties +from .properties.prop import FixedLengthProp +from .properties.properties_store import PropertiesStore from .structures.entry_id import PermanentEntryID from .utils import verifyPropertyId, verifyType @@ -32,13 +32,13 @@ def __init__(self, _dir, msg): logger.error('Recipients MUST have a property stream.') else: raise StandardViolationError('Recipients MUST have a property stream.') from None - self.__props = Properties(self._getStream('__properties_version1.0'), PropertiesType.RECIPIENT) + self.__props = PropertiesStore(self._getStream('__properties_version1.0'), PropertiesType.RECIPIENT) self.__email = self._getStringStream('__substg1.0_39FE') if not self.__email: self.__email = self._getStringStream('__substg1.0_3003') self.__name = self._getStringStream('__substg1.0_3001') self.__typeFlags = self.__props.get('0C150003').value or 0 - from .calendar_base import CalendarBase + from .msg_classes.calendar_base import CalendarBase if isinstance(msg, CalendarBase): self.__type = MeetingRecipientType(0xF & self.__typeFlags) else: @@ -267,7 +267,7 @@ def name(self) -> Optional[str]: return self.__name @property - def props(self) -> Properties: + def props(self) -> PropertiesStore: """ Returns the Properties instance of the recipient. """ diff --git a/extract_msg/utils.py b/extract_msg/utils.py index 76b8c380..fc9c48aa 100644 --- a/extract_msg/utils.py +++ b/extract_msg/utils.py @@ -11,12 +11,11 @@ 'dictGetCasedKey', 'divide', 'filetimeToDatetime', 'findWk', 'fromTimeStamp', 'getCommandArgs', 'getEncodingName', 'getFullClassName', 'hasLen', 'htmlSanitize', 'inputToBytes', 'inputToMsgPath', 'inputToString', - 'isEncapsulatedRtf', 'isEmptyString', 'knownMsgClass', 'filetimeToUtc', - 'msgPathToString', 'openMsg', 'openMsgBulk', 'parseType', 'prepareFilename', - 'properHex', 'roundUp', 'rtfSanitizeHtml', 'rtfSanitizePlain', - 'setupLogging', 'tryGetMimetype', 'unsignedToSignedInt', 'unwrapMsg', - 'unwrapMultipart', 'validateHtml', 'verifyPropertyId', 'verifyType', - 'windowsUnicode', + 'isEncapsulatedRtf', 'isEmptyString', 'filetimeToUtc', 'msgPathToString', + 'parseType', 'prepareFilename', 'properHex', 'roundUp', 'rtfSanitizeHtml' + 'rtfSanitizePlain', 'setupLogging', 'tryGetMimetype', + 'unsignedToSignedInt', 'unwrapMsg', 'unwrapMultipart', 'validateHtml', + 'verifyPropertyId', 'verifyType', 'windowsUnicode', ] @@ -45,21 +44,20 @@ import tzlocal from html import escape as htmlEscape -from typing import Any, Dict, List, Optional, Tuple, TYPE_CHECKING, Union +from typing import Any, Dict, List, Optional, TYPE_CHECKING, Union from . import constants from .enums import AttachmentType from .exceptions import ( ConversionError, ExecutableNotFound, IncompatibleOptionsError, - InvalidFileFormatError, InvaildPropertyIdError, TZError, - UnknownCodepageError, UnknownTypeError, UnrecognizedMSGTypeError, - UnsupportedEncodingError, UnsupportedMSGTypeError + InvaildPropertyIdError, TZError, + UnknownCodepageError, UnknownTypeError, UnsupportedEncodingError ) # Allow for nice type checking. if TYPE_CHECKING: - from .msg import MSGFile + from .msg_classes.msg import MSGFile logger = logging.getLogger(__name__) logger.addHandler(logging.NullHandler()) @@ -588,22 +586,6 @@ def isEmptyString(inp : str) -> bool: return (inp == '' or inp is None) -def knownMsgClass(classType : str) -> bool: - """ - Checks if the specified class type is recognized by the module. Usually used - for checking if a type is simply unsupported rather than unknown. - """ - classType = classType.lower() - if classType == 'ipm': - return True - - for item in constants.KNOWN_CLASS_TYPES: - if classType.startswith(item): - return True - - return False - - def filetimeToUtc(inp : int) -> float: """ Converts a FILETIME into a unix timestamp. @@ -624,165 +606,6 @@ def msgPathToString(inp) -> str: return inp -def openMsg(path, **kwargs) -> MSGFile: - """ - Function to automatically open an MSG file and detect what type it is. - - :param path: Path to the msg file in the system or is the raw msg file. - :param prefix: Used for extracting embeded msg files inside the main one. - Do not set manually unless you know what you are doing. - :param parentMsg: Used for syncronizing named properties instances. Do not - set this unless you know what you are doing. - :param attachmentClass: Optional, the class the Message object will use for - attachments. You probably should not change this value unless you know - what you are doing. - :param signedAttachmentClass: Optional, the class the object will use for - signed attachments. - :param filename: Optional, the filename to be used by default when saving. - :param delayAttachments: Optional, delays the initialization of attachments - until the user attempts to retrieve them. Allows MSG files with bad - attachments to be initialized so the other data can be retrieved. - :param overrideEncoding: Optional, overrides the specified encoding of the - MSG file. - :param attachmentErrorBehavior: Optional, the behaviour to use in the event - of an error when parsing the attachments. - :param recipientSeparator: Optional, Separator string to use between - recipients. - :param ignoreRtfDeErrors: Optional, specifies that any errors that occur - from the usage of RTFDE should be ignored (default: False). - - If :param strict: is set to `True`, this function will raise an exception - when it cannot identify what MSGFile derivitive to use. Otherwise, it will - log the error and return a basic MSGFile instance. - - :raises UnsupportedMSGTypeError: if the type is recognized but not suppoted. - :raises UnrecognizedMSGTypeError: if the type is not recognized. - """ - from .appointment import AppointmentMeeting - from .contact import Contact - from .meeting_cancellation import MeetingCancellation - from .meeting_exception import MeetingException - from .meeting_forward import MeetingForwardNotification - from .meeting_request import MeetingRequest - from .meeting_response import MeetingResponse - from .message import Message - from .msg import MSGFile - from .message_signed import MessageSigned - from .post import Post - from .task import Task - from .task_request import TaskRequest - - # When the initial MSG file is opened, it should *always* delay attachments - # so it can get the main class type. We only need to load them after that - # if we are directly returning the MSGFile instance *and* delayAttachments - # is False. - # - # So first let's store the original value. - delayAttachments = kwargs.get('delayAttachments', False) - kwargs['delayAttachments'] = True - - msg = MSGFile(path, **kwargs) - - # Restore the option in the kwargs so we don't have to worry about it. - kwargs['delayAttachments'] = delayAttachments - - # After rechecking the docs, all comparisons should be case-insensitive, not - # case-sensitive. My reading ability is great. - # - # Also after consideration, I realized we need to be very careful here, as - # other file types (like doc, ppt, etc.) might open but not return a class - # type. If the stream is not found, classType returns None, which has no - # lower function. So let's make sure we got a good return first. - if not msg.classType: - if kwargs.get('strict', True): - raise InvalidFileFormatError('File was confirmed to be an olefile, but was not an MSG file.') - else: - # If strict mode is off, we'll just return an MSGFile anyways. - logging.critical('Received file that was an olefile but was not an MSG file. Returning MSGFile anyways because strict mode is off.') - return msg - classType = msg.classType.lower() - # Put the message class first as it is most common. - if classType.startswith('ipm.note') or classType.startswith('report'): - msg.close() - if classType.endswith('smime.multipartsigned') or classType.endswith('smime'): - return MessageSigned(path, **kwargs) - else: - return Message(path, **kwargs) - elif classType.startswith('ipm.appointment'): - msg.close() - return AppointmentMeeting(path, **kwargs) - elif classType.startswith('ipm.contact') or classType.startswith('ipm.distlist'): - msg.close() - return Contact(path, **kwargs) - elif classType.startswith('ipm.post'): - msg.close() - return Post(path, **kwargs) - elif classType.startswith('ipm.schedule.meeting.request'): - msg.close() - return MeetingRequest(path, **kwargs) - elif classType.startswith('ipm.schedule.meeting.canceled'): - msg.close() - return MeetingCancellation(path, **kwargs) - elif classType.startswith('ipm.schedule.meeting.notification.forward'): - msg.close() - return MeetingForwardNotification(path, **kwargs) - elif classType.startswith('ipm.schedule.meeting.resp'): - msg.close() - return MeetingResponse(path, **kwargs) - elif classType.startswith('ipm.taskrequest'): - msg.close() - return TaskRequest(path, **kwargs) - elif classType.startswith('ipm.task'): - msg.close() - return Task(path, **kwargs) - elif classType.startswith('ipm.ole.class.{00061055-0000-0000-c000-000000000046}'): - # Exception objects have a weird class type. - msg.close() - return MeetingException(path, **kwargs) - elif classType == 'ipm': - # Unspecified format. It should be equal to this and not just start with - # it. - if not delayAttachments: - msg.attachments - return msg - elif kwargs.get('strict', True): - # Because we are closing it, we need to store it in a variable first. - ct = msg.classType - msg.close() - if knownMsgClass(classType): - raise UnsupportedMSGTypeError(f'MSG type "{ct}" currently is not supported by the module. If you would like support, please make a feature request.') - raise UnrecognizedMSGTypeError(f'Could not recognize msg class type "{ct}".') - else: - logger.error(f'Could not recognize msg class type "{msg.classType}". This most likely means it hasn\'t been implemented yet, and you should ask the developers to add support for it.') - if not delayAttachments: - msg.attachments - return msg - - -def openMsgBulk(path, **kwargs) -> Union[List[MSGFile], Tuple[Exception, Union[str, bytes]]]: - """ - Takes the same arguments as openMsg, but opens a collection of msg files - based on a wild card. Returns a list if successful, otherwise returns a - tuple. - - :param ignoreFailures: If this is True, will return a list of all successful - files, ignoring any failures. Otherwise, will close all that - successfully opened, and return a tuple of the exception and the path of - the file that failed. - """ - files = [] - for x in glob.glob(str(path)): - try: - files.append(openMsg(x, **kwargs)) - except Exception as e: - if not kwargs.get('ignoreFailures', False): - for msg in files: - msg.close() - return (e, x) - - return files - - def parseType(_type : int, stream, encoding, extras): """ Converts the data in :param stream: to a much more accurate type, specified @@ -1022,7 +845,7 @@ def setupLogging(defaultPath = None, defaultLevel = logging.WARN, logfile = None Returns: bool: True if the configuration file was found and applied, False otherwise """ - shippedConfig = pathlib.Path(__file__).parent / 'logging-config' + shippedConfig = pathlib.Path(__file__).parent / 'data' / 'logging-config' if os.name == 'nt': null = 'NUL' shippedConfig /= 'logging-nt.json' @@ -1139,7 +962,7 @@ def unwrapMsg(msg : MSGFile) -> Dict: (including the original in the first index), and "raw_attachments" for raw attachments from signed messages. """ - from .message_signed_base import MessageSignedBase + from .msg_classes import MessageSignedBase # Here is where we store main attachments. attachments = [] @@ -1359,3 +1182,4 @@ def verifyType(_type) -> str: def windowsUnicode(string) -> Optional[str]: return str(string, 'utf-16-le') if string is not None else None + diff --git a/pyrightconfig.json b/pyrightconfig.json new file mode 100644 index 00000000..31845b85 --- /dev/null +++ b/pyrightconfig.json @@ -0,0 +1,4 @@ +{ + "pythonVersion": "3.8", + "pythonPlatform": "All" +} \ No newline at end of file From de364e7ea30b5063708a1eac8f365ea6e259151f Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Tue, 13 Jun 2023 22:05:22 -0700 Subject: [PATCH 21/89] Correct variable name --- extract_msg/attachments/attachment_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extract_msg/attachments/attachment_base.py b/extract_msg/attachments/attachment_base.py index 1d4417d7..909aa611 100644 --- a/extract_msg/attachments/attachment_base.py +++ b/extract_msg/attachments/attachment_base.py @@ -312,7 +312,7 @@ def clsid(self) -> str: if dataStream: clsid = self.__msg._getOleEntry(dataStream).clsid or clsid - return self.__clsid + return clsid @property def dir(self) -> str: From df0ef4639a7b3ff71f6b66e59f250c6cd7fc005b Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Wed, 14 Jun 2023 12:53:31 -0700 Subject: [PATCH 22/89] Fixed issues in __main__ --- CHANGELOG.md | 1 + extract_msg/__main__.py | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d44a0ee1..c3184ec8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * Changed internal behavior of `MSGFile.attachments`. This should not cause any noticeable changes to the output. * Refactored code significantly to make it more organized. * Changed the exports from the main module to only include an important subset of the module. For other items, you'll have to import the submodule that it falls under to access it. Submodules export all important pieces, so it will be easier to find. +* Fixed `__main__` using the wrong enum for error behavior. **v0.41.5** * Fixed an issue from version `0.41.3` where the header being present but missing the `From` field would cause an exception. diff --git a/extract_msg/__main__.py b/extract_msg/__main__.py index 4af7ed3c..174e9e43 100644 --- a/extract_msg/__main__.py +++ b/extract_msg/__main__.py @@ -7,8 +7,8 @@ import traceback import zipfile -from extract_msg import __doc__, utils -from extract_msg.enums import AttachErrorBehavior +from extract_msg import __doc__, openMsg, utils +from extract_msg.enums import ErrorBehavior def main() -> None: @@ -70,7 +70,7 @@ def main() -> None: # If we are skipping the NotImplementedError attachments, we need to # suppress the error. if args.skipNotImplemented: - openKwargs['attachmentErrorBehavior'] = AttachErrorBehavior.NOT_IMPLEMENTED + openKwargs['errorBehavior'] = ErrorBehavior.ATTACH_NOT_IMPLEMENTED def strSanitize(inp): """ @@ -91,7 +91,7 @@ def strSanitize(inp): except UnicodeEncodeError: print(f'Saving file "{strSanitize(x)}" (failed to print without repr)...') try: - with utils.openMsg(x, **openKwargs) as msg: + with openMsg(x, **openKwargs) as msg: if args.dumpStdout: print(msg.body) elif args.noFolders: From a0ffb776eb421c239ad5f01e68cf6960543c751b Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Wed, 14 Jun 2023 16:21:37 -0700 Subject: [PATCH 23/89] Bug fixes + change to weakref --- CHANGELOG.md | 6 ++ extract_msg/__main__.py | 1 + extract_msg/attachments/attachment.py | 4 +- extract_msg/attachments/attachment_base.py | 77 +++++++++++++--- extract_msg/attachments/signed_attachment.py | 21 +++-- extract_msg/msg_classes/msg.py | 37 ++++---- extract_msg/properties/named.py | 97 +++++++++++++++----- extract_msg/recipient.py | 76 ++++++++++++--- extract_msg/utils.py | 13 +++ 9 files changed, 258 insertions(+), 74 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c3184ec8..23533bd3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ * Refactored code significantly to make it more organized. * Changed the exports from the main module to only include an important subset of the module. For other items, you'll have to import the submodule that it falls under to access it. Submodules export all important pieces, so it will be easier to find. * Fixed `__main__` using the wrong enum for error behavior. +* Fixed `Named.get` being severely out of date (it's not used anywhere by the module which is why it wasn't noticed). +* Fixed `Named.__getitem__` being entirely case-sensitive. +* Switched much of the internal code (and the `treePath` property of all classes that have it) to using `weakref.ReferenceType` to avoid hard cyclic references. +* Fixed `Recipient._getTypedStream` never returning a value. +* Added additional type hints in various places. +* Corrected `Attachment.save` so that saving an embedded msg file returns that embedded msg file instead of the parent msg file. **v0.41.5** * Fixed an issue from version `0.41.3` where the header being present but missing the `From` field would cause an exception. diff --git a/extract_msg/__main__.py b/extract_msg/__main__.py index 174e9e43..e148690e 100644 --- a/extract_msg/__main__.py +++ b/extract_msg/__main__.py @@ -2,6 +2,7 @@ 'main', ] + import os import sys import traceback diff --git a/extract_msg/attachments/attachment.py b/extract_msg/attachments/attachment.py index b2131036..242e075d 100644 --- a/extract_msg/attachments/attachment.py +++ b/extract_msg/attachments/attachment.py @@ -255,7 +255,7 @@ def save(self, **kwargs) -> Optional[Union[str, MSGFile]]: _zip.close() return str(fullFilename) - elif self.__data: + elif self.type is AttachmentType.MSG: if kwargs.get('extractEmbedded', False): with _open(str(fullFilename), mode) as f: self.data.export(f) @@ -266,7 +266,7 @@ def save(self, **kwargs) -> Optional[Union[str, MSGFile]]: if _zip and createdZip: _zip.close() - return self.msg + return self.__data def saveEmbededMessage(self, **kwargs) -> None: """ diff --git a/extract_msg/attachments/attachment_base.py b/extract_msg/attachments/attachment_base.py index 909aa611..155ae692 100644 --- a/extract_msg/attachments/attachment_base.py +++ b/extract_msg/attachments/attachment_base.py @@ -8,16 +8,17 @@ import datetime import logging +import weakref from functools import cached_property, partial -from typing import Optional, Tuple, TYPE_CHECKING +from typing import List, Optional, Tuple, TYPE_CHECKING from ..enums import AttachmentType, ErrorBehavior, PropertiesType from ..exceptions import StandardViolationError from ..properties.named import NamedProperties from ..properties.prop import FixedLengthProp from ..properties.properties_store import PropertiesStore -from ..utils import tryGetMimetype, verifyPropertyId, verifyType +from ..utils import makeWeakRef, tryGetMimetype, verifyPropertyId, verifyType # Allow for nice type checking. @@ -41,7 +42,7 @@ def __init__(self, msg, dir_): :param msg: the Message instance that the attachment belongs to. :param dir_: the directory inside the msg file where the attachment is located. """ - self.__msg = msg + self.__msg = makeWeakRef(msg) self.__dir = dir_ if not self.exists('__properties_version1.0'): if (msg.errorBehavior & ErrorBehavior.STANDARDS_VIOLATION): @@ -50,7 +51,7 @@ def __init__(self, msg, dir_): raise StandardViolationError('Attachments MUST have a property stream.') from None self.__props = PropertiesStore(self._getStream('__properties_version1.0'), PropertiesType.ATTACHMENT) self.__namedProperties = NamedProperties(msg.named, self) - self.__treePath = msg.treePath + (self,) + self.__treePath = msg.treePath + [makeWeakRef(self)] def _ensureSet(self, variable, streamID, stringStream = True, **kwargs): """ @@ -95,6 +96,9 @@ def _ensureSetNamed(self, variable, propertyName : str, guid : str, **kwargs): :param preserveNone: If true (default), causes the function to ignore :param overrideClass: when the value could not be found (is None). If this is changed to False, then the value will be used regardless. + + :raises ReferenceError: The associated MSGFile instance has been garbage + collected. """ try: return getattr(self, variable) @@ -149,6 +153,9 @@ def _ensureSetTyped(self, variable, _id, **kwargs): :param preserveNone: If true (default), causes the function to ignore :param overrideClass: when the value could not be found (is None). If this is changed to False, then the value will be used regardless. + + :raises ReferenceError: The associated MSGFile instance has been garbage + collected. """ try: return getattr(self, variable) @@ -163,7 +170,18 @@ def _ensureSetTyped(self, variable, _id, **kwargs): return value def _getStream(self, filename) -> Optional[bytes]: - return self.__msg._getStream([self.__dir, filename]) + """ + Gets a binary representation of the requested filename. + + This should ALWAYS return a bytes object if it was found, otherwise + returns None. + + :raises ReferenceError: The associated MSGFile instance has been garbage + collected. + """ + if (msg := self.__msg()) is None: + raise ReferenceError('The msg file for this Attachment instance has been garbage collected.') + return msg._getStream([self.__dir, filename]) def _getStringStream(self, filename) -> Optional[str]: """ @@ -172,8 +190,13 @@ def _getStringStream(self, filename) -> Optional[str]: a value if possible. If there are both ASCII and Unicode versions, then :param prefer: specifies which will be returned. + + :raises ReferenceError: The associated MSGFile instance has been garbage + collected. """ - return self.__msg._getStringStream([self.__dir, filename]) + if (msg := self.__msg()) is None: + raise ReferenceError('The msg file for this Attachment instance has been garbage collected.') + return msg._getStringStream([self.__dir, filename]) def _getTypedData(self, id, _type = None): """ @@ -185,6 +208,9 @@ def _getTypedData(self, id, _type = None): you can specify it as being one of the strings in the constant FIXED_LENGTH_PROPS_STRING or VARIABLE_LENGTH_PROPS_STRING. + + :raises ReferenceError: The associated MSGFile instance has been garbage + collected. """ verifyPropertyId(id) id = id.upper() @@ -195,7 +221,7 @@ def _getTypedData(self, id, _type = None): found, result = self._getTypedProperty(id, _type) return result if found else None - def _getTypedProperty(self, propertyID, _type = None): + def _getTypedProperty(self, propertyID, _type = None) -> Tuple[bool, Optional[object]]: """ Gets the property with the specified id as the type that it is supposed to be. :param id: MUST be a 4 digit hexadecimal @@ -235,28 +261,48 @@ def _getTypedStream(self, filename, _type = None): using this function it is best for you to check the type that it returns. If the function returns None, that means it could not find the stream specified. + + :raises ReferenceError: The associated MSGFile instance has been garbage + collected. """ - return self.__msg._getTypedStream([self.__dir, filename], True, _type) + if (msg := self.__msg()) is None: + raise ReferenceError('The msg file for this Attachment instance has been garbage collected.') + return msg._getTypedStream([self.__dir, filename], True, _type) def exists(self, filename) -> bool: """ Checks if stream exists inside the attachment folder. + + :raises ReferenceError: The associated MSGFile instance has been garbage + collected. """ - return self.__msg.exists([self.__dir, filename]) + if (msg := self.__msg()) is None: + raise ReferenceError('The msg file for this Attachment instance has been garbage collected.') + return msg.exists([self.__dir, filename]) def sExists(self, filename) -> bool: """ Checks if the string stream exists inside the attachment folder. + + :raises ReferenceError: The associated MSGFile instance has been garbage + collected. """ - return self.__msg.sExists([self.__dir, filename]) + if (msg := self.__msg()) is None: + raise ReferenceError('The msg file for this Attachment instance has been garbage collected.') + return msg.sExists([self.__dir, filename]) def existsTypedProperty(self, id, _type = None) -> bool: """ Determines if the stream with the provided id exists. The return of this function is 2 values, the first being a boolean for if anything was found, and the second being how many were found. + + :raises ReferenceError: The associated MSGFile instance has been garbage + collected. """ - return self.__msg.existsTypedProperty(id, self.__dir, _type, True, self.__props) + if (msg := self.__msg()) is None: + raise ReferenceError('The msg file for this Attachment instance has been garbage collected.') + return msg.existsTypedProperty(id, self.__dir, _type, True, self.__props) @property def attachmentEncoding(self) -> Optional[bytes]: @@ -378,8 +424,13 @@ def mimetype(self) -> Optional[str]: def msg(self) -> MSGFile: """ Returns the Message instance the attachment belongs to. + + :raises ReferenceError: The associated MSGFile instance has been garbage + collected. """ - return self.__msg + if (msg := self.__msg()) is None: + raise ReferenceError('The msg file for this Attachment instance has been garbage collected.') + return msg @property def name(self) -> Optional[str]: @@ -430,7 +481,7 @@ def shortFilename(self) -> Optional[str]: return self._ensureSet('_shortFilename', '__substg1.0_3704') @property - def treePath(self) -> Tuple: + def treePath(self) -> List[weakref.ReferenceType]: """ A path, as a tuple of instances, needed to get to this instance through the MSGFile-Attachment tree. diff --git a/extract_msg/attachments/signed_attachment.py b/extract_msg/attachments/signed_attachment.py index a58f3706..f2c63a9f 100644 --- a/extract_msg/attachments/signed_attachment.py +++ b/extract_msg/attachments/signed_attachment.py @@ -10,13 +10,14 @@ import logging import os import pathlib +import weakref import zipfile -from typing import Tuple, TYPE_CHECKING, Union +from typing import List, TYPE_CHECKING, Union from ..enums import AttachmentType from ..open_msg import openMsg -from ..utils import createZipOpen, inputToString, prepareFilename +from ..utils import createZipOpen, inputToString, makeWeakRef, prepareFilename # Allow for nice type checking. @@ -39,9 +40,9 @@ def __init__(self, msg, data : bytes, name : str, mimetype : str, node : email.m self.__asBytes = data self.__name = name self.__mimetype = mimetype - self.__msg = msg + self.__msg = makeWeakRef(msg) self.__node = node - self.__treePath = msg.treePath + (self,) + self.__treePath = msg.treePath + [makeWeakRef(self)] self.__data = None # To add support for embedded MSG files, we are going to completely @@ -84,6 +85,9 @@ def save(self, **kwargs): either pass a path to where you want to create one or pass an instance to :param zip:. If :param zip: is an instance, :param customPath: will refer to a location inside the zip file. + + :raises ReferenceError: The associated MSGFile instance has been garbage + collected. """ # First check if we are skipping embedded messages and stop # *immediately* if we are. @@ -215,8 +219,13 @@ def mimetype(self) -> str: def msg(self) -> MSGFile: """ The MSGFile instance this attachment belongs to. + + :raises ReferenceError: The associated MSGFile instance has been garbage + collected. """ - return self.__msg + if (msg := self.__msg()) is None: + raise ReferenceError('The msg file for this Attachment instance has been garbage collected.') + return msg @property def name(self) -> str: @@ -229,7 +238,7 @@ def name(self) -> str: shortFilename = name @property - def treePath(self) -> Tuple: + def treePath(self) -> List[weakref.ReferenceType]: """ A path, as a tuple of instances, needed to get to this instance through the MSGFile-Attachment tree. diff --git a/extract_msg/msg_classes/msg.py b/extract_msg/msg_classes/msg.py index a06f99e4..9a6229c7 100644 --- a/extract_msg/msg_classes/msg.py +++ b/extract_msg/msg_classes/msg.py @@ -10,6 +10,7 @@ import logging import os import pathlib +import weakref import zipfile import olefile @@ -30,8 +31,8 @@ from ..properties.properties_store import PropertiesStore from ..utils import ( divide, getEncodingName, hasLen, inputToMsgPath, inputToString, - msgPathToString, parseType, properHex, verifyPropertyId, verifyType, - windowsUnicode + makeWeakRef, msgPathToString, parseType, properHex, verifyPropertyId, + verifyType, windowsUnicode ) @@ -85,10 +86,10 @@ def __init__(self, path, **kwargs): """ # Retrieve all the kwargs that we need. prefix = kwargs.get('prefix', '') - self.__parentMsg = kwargs.get('parentMsg') - self.__treePath = kwargs.get('treePath', tuple()) + (self,) + self.__parentMsg = makeWeakRef(kwargs.get('parentMsg')) + self.__treePath = kwargs.get('treePath', []) + [makeWeakRef(self)] # Verify it is a valid class. - if self.__parentMsg is not None and not isinstance(self.__parentMsg, MSGFile): + if self.__parentMsg and not isinstance(self.__parentMsg(), MSGFile): raise TypeError(':param parentMsg: must be an instance of MSGFile or a subclass.') filename = kwargs.get('filename', None) overrideEncoding = kwargs.get('overrideEncoding', None) @@ -108,7 +109,6 @@ def __init__(self, path, **kwargs): # necessary. self.__errorBehavior = AttachErrorBehavior(kwargs['attachmentErrorBehavior']) - self.__waitingProperties = [] if overrideEncoding is not None: codecs.lookup(overrideEncoding) logger.warning('You have chosen to override the string encoding. Do not report encoding errors caused by this.') @@ -123,7 +123,7 @@ def __init__(self, path, **kwargs): if self.__parentMsg: # We should be able to directly access the private variables of # another instance with no issue. - self.__ole = self.__parentMsg.__ole + self.__ole = self.__parentMsg().__ole self.__oleOwner = False else: try: @@ -370,7 +370,7 @@ def _getTypedData(self, _id : str, _type = None, prefix : bool = True): found, result = self._getTypedProperty(_id, _type) return result if found else None - def _getTypedProperty(self, propertyID : str, _type = None): + def _getTypedProperty(self, propertyID : str, _type = None) -> Tuple[bool, Optional[object]]: """ Gets the property with the specified id as the type that it is supposed to be. :param id: MUST be a 4 digit hexadecimal string. @@ -806,6 +806,9 @@ def named(self) -> Named: """ The main named properties storage. This is not usable to access the data of the properties directly. + + :raises ReferenceError: The parent MSGFile instance has been garbage + collected. """ try: return self.__named @@ -815,12 +818,12 @@ def named(self) -> Named: if self.__parentMsg: # Try to get the named properties and use that for our main # instance. - try: - self.__named = self.__parentMsg.named - except Exception: - pass - if not self.__named: + if (msg := self.__parentMsg()) is None: + raise ReferenceError('Parent MSGFile instance has been garbage collected.') + self.__named = msg.named + else: self.__named = Named(self) + return self.__named @property @@ -938,9 +941,11 @@ def stringEncoding(self): return self.__stringEncoding @property - def treePath(self) -> Tuple: + def treePath(self) -> List[weakref.ReferenceType]: """ - A path, as a tuple of instances, needed to get to this instance through - the MSGFile-Attachment tree. + A path, as a list of weak reference to the instances needed to get to + this instance through the MSGFile-Attachment tree. These are weak + references to ensure the garbage collector doesn't see the references + back to higher objects. """ return self.__treePath diff --git a/extract_msg/properties/named.py b/extract_msg/properties/named.py index e90e323d..f28f6598 100644 --- a/extract_msg/properties/named.py +++ b/extract_msg/properties/named.py @@ -14,11 +14,11 @@ import logging import pprint -from typing import Dict, Optional, TYPE_CHECKING +from typing import Dict, Optional, Tuple, TYPE_CHECKING from .. import constants from ..enums import NamedPropertyType -from ..utils import bytesToGuid, divide, properHex +from ..utils import bytesToGuid, divide, makeWeakRef, properHex from compressed_rtf.crc32 import crc32 @@ -31,9 +31,14 @@ class Named: + """ + Class for handling access to the named properties themselves. + """ + __dir = '__nameid_version1.0' + def __init__(self, msg): - self.__msg = msg + self.__msg = makeWeakRef(msg) # Get the basic streams. If all are emtpy, then nothing to do. guidStream = self._getStream('__substg1.0_00020102') or self._getStream('__substg1.0_00020102', False) entryStream = self._getStream('__substg1.0_00030102') or self._getStream('__substg1.0_00030102', False) @@ -78,8 +83,18 @@ def __init__(self, msg): def __contains__(self, key) -> bool: return key in self.__propertiesDict - def __getitem__(self, key): - return self.__propertiesDict[key] + def __getitem__(self, propertyName : Tuple[str, str]): + # Validate the key. + if not hasattr(propertyName, '__len__') or len(propertyName) != 2: + raise TypeError('Named property key must be a tuple of two strings.') + + # Case insensitive search of the dictionary. + propertyName = (propertyName[0].upper(), propertyName[1].upper()) + for key in self.__propertiesDict.keys(): + if propertyName == (key[0].upper(), key[1].upper()): + return self.__propertiesDict[key] + + raise KeyError(propertyName) def __iter__(self): return self.__propertiesDict.__iter__() @@ -114,29 +129,58 @@ def __getName(self, offset : int) -> str: return self.namesStream[offset:offset + length].decode('utf-16-le') def _getStream(self, filename, prefix = True) -> Optional[bytes]: - return self.__msg._getStream([self.__dir, filename], prefix = prefix) + """ + Gets a binary representation of the requested filename. + + This should ALWAYS return a bytes object if it was found, otherwise + returns None. + + :raises ReferenceError: The associated MSGFile instance has been garbage + collected. + """ + if (msg := self.__msg()) is None: + raise ReferenceError('The msg file for this Named instance has been garbage collected.') + return msg._getStream([self.__dir, filename], prefix = prefix) def _getStringStream(self, filename, prefix = True) -> Optional[str]: """ Gets a string representation of the requested filename. - Checks for both ASCII and Unicode representations and returns - a value if possible. If there are both ASCII and Unicode - versions, then :param prefer: specifies which will be - returned. + + Rather than the full filename, you should only feed this function the + filename sans the type. So if the full name is "__substg1.0_001A001F", + the filename this function should receive should be "__substg1.0_001A". + + This should ALWAYS return a string if it was found, otherwise returns + None. + + :raises ReferenceError: The associated MSGFile instance has been garbage + collected. """ - return self.__msg._getStringStream([self.__dir, filename], prefix = prefix) + if (msg := self.__msg()) is None: + raise ReferenceError('The msg file for this Named instance has been garbage collected.') + return msg._getStringStream([self.__dir, filename], prefix = prefix) def exists(self, filename) -> bool: """ Checks if stream exists inside the named properties folder. + + :raises ReferenceError: The associated MSGFile instance has been garbage + collected. """ - return self.__msg.exists([self.__dir, filename]) + if (msg := self.__msg()) is None: + raise ReferenceError('The msg file for this Named instance has been garbage collected.') + return msg.exists([self.__dir, filename]) def sExists(self, filename) -> bool: """ Checks if the string stream exists inside the named properties folder. + + :raises ReferenceError: The associated MSGFile instance has been garbage + collected. """ - return self.__msg.sExists([self.__dir, filename]) + if (msg := self.__msg()) is None: + raise ReferenceError('The msg file for this Named instance has been garbage collected.') + return msg.sExists([self.__dir, filename]) def get(self, propertyName, default = None): """ @@ -144,12 +188,8 @@ def get(self, propertyName, default = None): if not found. Key is a tuple of the name and the property set GUID. """ try: - return self.__propertiesDict[propertyName] + return self[propertyName] except KeyError: - propertyName = propertyName.upper() - for key in self.__propertiesDict.keys(): - if propertyName == key.upper(): - return self.__propertiesDict[key] return default def keys(self): @@ -175,8 +215,13 @@ def dir(self): def msg(self) -> MSGFile: """ Returns the Message instance the attachment belongs to. + + :raises ReferenceError: The associated MSGFile instance has been garbage + collected. """ - return self.__msg + if (msg := self.__msg()) is None: + raise ReferenceError('The msg file for this Named instance has been garbage collected.') + return msg @property def namedProperties(self) -> Dict: @@ -200,22 +245,30 @@ def __init__(self, named, streamSource): property. """ self.__named = named - self.__streamSource = streamSource + self.__streamSource = makeWeakRef(streamSource) def __getitem__(self, item): """ Get a named property using the [] operator. Item must be a named property instance or a tuple with 2 items: the name and the GUID string. + + :raises ReferenceError: The associated instance for getting actual + property data has been garbage collected. """ + if (source := self.__streamSource()) is None: + raise ReferenceError('The stream source for the NamedProperties instance has been garbage collected.') if isinstance(item, NamedPropertyBase): - return self.__streamSource._getTypedData(item.propertyStreamID) + return source._getTypedData(item.propertyStreamID) else: - return self.__streamSource._getTypedData(self.__named[item].propertyStreamID) + return source._getTypedData(self.__named[item].propertyStreamID) def get(self, item, default = None): """ Get a named property, returning the value of :param default: if not found. Item must be a tuple with 2 items: the name and the GUID string. + + :raises ReferenceError: The associated instance for getting actual + property data has been garbage collected. """ try: return self[item] diff --git a/extract_msg/recipient.py b/extract_msg/recipient.py index 1cbe189e..1ce9be4c 100644 --- a/extract_msg/recipient.py +++ b/extract_msg/recipient.py @@ -5,14 +5,14 @@ import logging -from typing import Optional, Union +from typing import Optional, Tuple, Union from .enums import ErrorBehavior, MeetingRecipientType, PropertiesType, RecipientType from .exceptions import StandardViolationError from .properties.prop import FixedLengthProp from .properties.properties_store import PropertiesStore from .structures.entry_id import PermanentEntryID -from .utils import verifyPropertyId, verifyType +from .utils import makeWeakRef, verifyPropertyId, verifyType logger = logging.getLogger(__name__) @@ -21,11 +21,11 @@ class Recipient: """ - Contains the data of one of the recipients in an msg file. + Contains the data of one of the recipients in an MSG file. """ def __init__(self, _dir, msg): - self.__msg = msg # Allows calls to original msg file. + self.__msg = makeWeakRef(msg) # Allows calls to original msg file. self.__dir = _dir if not self.exists('__properties_version1.0'): if msg.errorBehavior & ErrorBehavior.STANDARDS_VIOLATION: @@ -60,6 +60,9 @@ def _ensureSet(self, variable, streamID, stringStream : bool = True, **kwargs): :param preserveNone: If true (default), causes the function to ignore :param overrideClass: when the value could not be found (is None). If this is changed to False, then the value will be used regardless. + + :raises ReferenceError: The associated MSGFile instance has been garbage + collected. """ try: return getattr(self, variable) @@ -88,6 +91,9 @@ def _ensureSetProperty(self, variable : str, propertyName : str, **kwargs): :param preserveNone: If true (default), causes the function to ignore :param overrideClass: when the value could not be found (is None). If this is changed to False, then the value will be used regardless. + + :raises ReferenceError: The associated MSGFile instance has been garbage + collected. """ try: return getattr(self, variable) @@ -117,6 +123,9 @@ def _ensureSetTyped(self, variable : str, _id, **kwargs): :param preserveNone: If true (default), causes the function to ignore :param overrideClass: when the value could not be found (is None). If this is changed to False, then the value will be used regardless. + + :raises ReferenceError: The associated MSGFile instance has been garbage + collected. """ try: return getattr(self, variable) @@ -136,17 +145,31 @@ def _getStream(self, filename) -> Optional[bytes]: This should ALWAYS return a bytes object if it was found, otherwise returns None. + + :raises ReferenceError: The associated MSGFile instance has been garbage + collected. """ - return self.__msg._getStream([self.__dir, filename]) + if (msg := self.__msg()) is None: + raise ReferenceError('The msg file for this Recipient instance has been garbage collected.') + return msg._getStream([self.__dir, filename]) def _getStringStream(self, filename) -> Optional[str]: """ - Gets a string representation of the requested filename. Checks for both - Unicode and Non-Unicode representations and returns a value if possible. - If there are both Unicode and Non-Unicode versions, then :param prefer: - specifies which will be returned. + Gets a string representation of the requested filename. + + Rather than the full filename, you should only feed this function the + filename sans the type. So if the full name is "__substg1.0_001A001F", + the filename this function should receive should be "__substg1.0_001A". + + This should ALWAYS return a string if it was found, otherwise returns + None. + + :raises ReferenceError: The associated MSGFile instance has been garbage + collected. """ - return self.__msg._getStringStream([self.__dir, filename]) + if (msg := self.__msg()) is None: + raise ReferenceError('The msg file for this Recipient instance has been garbage collected.') + return msg._getStringStream([self.__dir, filename]) def _getTypedData(self, _id, _type = None): """ @@ -156,6 +179,9 @@ def _getTypedData(self, _id, _type = None): If you know for sure what type the data is before hand, you can specify it as being one of the strings in the constant FIXED_LENGTH_PROPS_STRING or VARIABLE_LENGTH_PROPS_STRING. + + :raises ReferenceError: The associated MSGFile instance has been garbage + collected. """ verifyPropertyId(id) _id = _id.upper() @@ -166,7 +192,7 @@ def _getTypedData(self, _id, _type = None): found, result = self._getTypedProperty(_id, _type) return result if found else None - def _getTypedProperty(self, propertyID : str, _type = None): + def _getTypedProperty(self, propertyID : str, _type = None) -> Tuple[bool, Optional[object]]: """ Gets the property with the specified id as the type that it is supposed to be. :param id: MUST be a 4 digit hexadecimal string. @@ -201,28 +227,48 @@ def _getTypedStream(self, filename, _type = None): many cases cannot be predicted. As such, when using this function it is best for you to check the type that it returns. If the function returns None, that means it could not find the stream specified. + + :raises ReferenceError: The associated MSGFile instance has been garbage + collected. """ - self.__msg._getTypedStream(self, [self.__dir, filename], True, _type) + if (msg := self.__msg()) is None: + raise ReferenceError('The msg file for this Recipient instance has been garbage collected.') + return msg._getTypedStream(self, [self.__dir, filename], True, _type) def exists(self, filename) -> bool: """ Checks if stream exists inside the recipient folder. + + :raises ReferenceError: The associated MSGFile instance has been garbage + collected. """ - return self.__msg.exists([self.__dir, filename]) + if (msg := self.__msg()) is None: + raise ReferenceError('The msg file for this Recipient instance has been garbage collected.') + return msg.exists([self.__dir, filename]) def sExists(self, filename) -> bool: """ Checks if the string stream exists inside the recipient folder. + + :raises ReferenceError: The associated MSGFile instance has been garbage + collected. """ - return self.__msg.sExists([self.__dir, filename]) + if (msg := self.__msg()) is None: + raise ReferenceError('The msg file for this Recipient instance has been garbage collected.') + return msg.sExists([self.__dir, filename]) def existsTypedProperty(self, id, _type = None) -> bool: """ Determines if the stream with the provided id exists. The return of this function is 2 values, the first being a boolean for if anything was found, and the second being how many were found. + + :raises ReferenceError: The associated MSGFile instance has been garbage + collected. """ - return self.__msg.existsTypedProperty(id, self.__dir, _type, True, self.__props) + if (msg := self.__msg()) is None: + raise ReferenceError('The msg file for this Recipient instance has been garbage collected.') + return msg.existsTypedProperty(id, self.__dir, _type, True, self.__props) @property def account(self) -> Optional[str]: diff --git a/extract_msg/utils.py b/extract_msg/utils.py index fc9c48aa..08124dce 100644 --- a/extract_msg/utils.py +++ b/extract_msg/utils.py @@ -37,6 +37,7 @@ import struct # Not actually sure if this needs to be here for the logging, so just in case. import sys +import weakref import zipfile import bs4 @@ -593,6 +594,17 @@ def filetimeToUtc(inp : int) -> float: return (inp - 116444736000000000) / 10000000.0 +def makeWeakRef(obj : Optional[object]) -> Optional[weakref.ReferenceType]: + """ + Attempts to return a weak reference to the object, returning None if not + possible. + """ + try: + return weakref.ref(obj) + except TypeError: + return None + + def msgPathToString(inp) -> str: """ Converts an MSG path (one of the internal paths inside an MSG file) into a @@ -1138,6 +1150,7 @@ def unwrapMultipart(mp : Union[bytes, str, email.message.Message]) -> Dict: 'html_body': htmlBody, } + def validateHtml(html : bytes) -> bool: """ Checks whether the HTML is considered valid. To be valid, the HTML must, at From 29e36a9b614996ead0413d8f6c4f5e4d11ff0e19 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Wed, 14 Jun 2023 21:54:28 -0700 Subject: [PATCH 24/89] Change tests.py to only run tests if file ran --- CHANGELOG.md | 1 + tests.py | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 23533bd3..b015c361 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ * Fixed `Recipient._getTypedStream` never returning a value. * Added additional type hints in various places. * Corrected `Attachment.save` so that saving an embedded msg file returns that embedded msg file instead of the parent msg file. +* Modified tests.py to only run if it is run as a file instead of imported. **v0.41.5** * Fixed an issue from version `0.41.3` where the header being present but missing the `From` field would cause an exception. diff --git a/tests.py b/tests.py index a2ea3872..b133ec71 100644 --- a/tests.py +++ b/tests.py @@ -9,4 +9,5 @@ from extract_msg_tests import * -unittest.main(verbosity = 2) +if __name__ == '__main__': + unittest.main(verbosity = 2) From cedbf782516d2da4ecb57851eb5d86491019d6e1 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Wed, 14 Jun 2023 22:03:35 -0700 Subject: [PATCH 25/89] Add backup handling for outlook image with no name --- .../attachments/custom_attachments/outlook_image_dib.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/extract_msg/attachments/custom_attachments/outlook_image_dib.py b/extract_msg/attachments/custom_attachments/outlook_image_dib.py index 92cc168b..9d3d0e63 100644 --- a/extract_msg/attachments/custom_attachments/outlook_image_dib.py +++ b/extract_msg/attachments/custom_attachments/outlook_image_dib.py @@ -124,7 +124,11 @@ def data(self) -> bytes: @property def name(self) -> str: - return self.attachment.shortFilename + '.bmp' + # Try to get the name from the attachment. If that fails, name it based + # on the number. + if not (name := self.attachment.name): + name = f'attachment {int(self.attachment.dir[-8:], 16)}' + return name + '.bmp' From 0bf3d625c7a2d78bbee8692add10b30e959e1748 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Thu, 15 Jun 2023 11:20:57 -0700 Subject: [PATCH 26/89] Fix clsid still using hard ref --- extract_msg/attachments/attachment_base.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/extract_msg/attachments/attachment_base.py b/extract_msg/attachments/attachment_base.py index 155ae692..2e116b10 100644 --- a/extract_msg/attachments/attachment_base.py +++ b/extract_msg/attachments/attachment_base.py @@ -356,7 +356,9 @@ def clsid(self) -> str: # If we found the right item, get the CLSID. if dataStream: - clsid = self.__msg._getOleEntry(dataStream).clsid or clsid + if (msg := self.__msg()) is None: + raise ReferenceError('The msg file for this Attachment instance has been garbage collected.') + clsid = msg._getOleEntry(dataStream).clsid or clsid return clsid From b660c3ebd4c33b450d3fd221485a81c3ff310382 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Thu, 15 Jun 2023 11:43:32 -0700 Subject: [PATCH 27/89] Removed unneeded import --- extract_msg/utils.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/extract_msg/utils.py b/extract_msg/utils.py index 08124dce..e13a1bba 100644 --- a/extract_msg/utils.py +++ b/extract_msg/utils.py @@ -35,8 +35,6 @@ import pathlib import shutil import struct -# Not actually sure if this needs to be here for the logging, so just in case. -import sys import weakref import zipfile From 2659f33da213b862529008fba5b0bfb56e5565d1 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Thu, 15 Jun 2023 11:54:39 -0700 Subject: [PATCH 28/89] changed `knownMsgClass` to a private function --- CHANGELOG.md | 1 + extract_msg/open_msg.py | 4 ++-- extract_msg/utils.py | 12 ++++++------ 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b015c361..be1405eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ * Added additional type hints in various places. * Corrected `Attachment.save` so that saving an embedded msg file returns that embedded msg file instead of the parent msg file. * Modified tests.py to only run if it is run as a file instead of imported. +* Changed `knownMsgClass` to a private function since it is explicitly not being exported by any part of the module. **v0.41.5** * Fixed an issue from version `0.41.3` where the header being present but missing the `From` field would cause an exception. diff --git a/extract_msg/open_msg.py b/extract_msg/open_msg.py index 27f14e6c..14b8e018 100644 --- a/extract_msg/open_msg.py +++ b/extract_msg/open_msg.py @@ -26,7 +26,7 @@ from .msg_classes import MSGFile -def knownMsgClass(classType : str) -> bool: +def _knownMsgClass(classType : str) -> bool: """ Checks if the specified class type is recognized by the module. Usually used for checking if a type is simply unsupported rather than unknown. @@ -156,7 +156,7 @@ def openMsg(path, **kwargs) -> MSGFile: # Because we are closing it, we need to store it in a variable first. ct = msg.classType msg.close() - if knownMsgClass(classType): + if _knownMsgClass(classType): raise UnsupportedMSGTypeError(f'MSG type "{ct}" currently is not supported by the module. If you would like support, please make a feature request.') raise UnrecognizedMSGTypeError(f'Could not recognize msg class type "{ct}".') else: diff --git a/extract_msg/utils.py b/extract_msg/utils.py index e13a1bba..008cd4d8 100644 --- a/extract_msg/utils.py +++ b/extract_msg/utils.py @@ -8,12 +8,12 @@ __all__ = [ 'addNumToDir', 'addNumToZipDir', 'bitwiseAdjust', 'bitwiseAdjustedAnd', 'bytesToGuid', 'ceilDiv', 'cloneOleFile', 'createZipOpen', - 'dictGetCasedKey', 'divide', 'filetimeToDatetime', 'findWk', - 'fromTimeStamp', 'getCommandArgs', 'getEncodingName', 'getFullClassName', - 'hasLen', 'htmlSanitize', 'inputToBytes', 'inputToMsgPath', 'inputToString', - 'isEncapsulatedRtf', 'isEmptyString', 'filetimeToUtc', 'msgPathToString', - 'parseType', 'prepareFilename', 'properHex', 'roundUp', 'rtfSanitizeHtml' - 'rtfSanitizePlain', 'setupLogging', 'tryGetMimetype', + 'dictGetCasedKey', 'divide', 'filetimeToDatetime', 'filetimeToUtc', + 'findWk', 'fromTimeStamp', 'getCommandArgs', 'getEncodingName', + 'getFullClassName', 'hasLen', 'htmlSanitize', 'inputToBytes', + 'inputToMsgPath', 'inputToString', 'isEncapsulatedRtf', 'isEmptyString', + 'msgPathToString', 'parseType', 'prepareFilename', 'properHex', 'roundUp', + 'rtfSanitizeHtml', 'rtfSanitizePlain', 'setupLogging', 'tryGetMimetype', 'unsignedToSignedInt', 'unwrapMsg', 'unwrapMultipart', 'validateHtml', 'verifyPropertyId', 'verifyType', 'windowsUnicode', ] From 4d8d8c913e70eeb52ce126210a3e016e44f1bf3f Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Thu, 15 Jun 2023 12:04:21 -0700 Subject: [PATCH 29/89] Removed unused function `getFullClassName` --- CHANGELOG.md | 1 + extract_msg/utils.py | 53 ++++++++++++++++++++++++++++++++------------ 2 files changed, 40 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index be1405eb..90925869 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ * Corrected `Attachment.save` so that saving an embedded msg file returns that embedded msg file instead of the parent msg file. * Modified tests.py to only run if it is run as a file instead of imported. * Changed `knownMsgClass` to a private function since it is explicitly not being exported by any part of the module. +* Removed unusued function `getFullClassName`. **v0.41.5** * Fixed an issue from version `0.41.3` where the header being present but missing the `From` field would cause an exception. diff --git a/extract_msg/utils.py b/extract_msg/utils.py index 008cd4d8..d51b4c4b 100644 --- a/extract_msg/utils.py +++ b/extract_msg/utils.py @@ -6,16 +6,45 @@ __all__ = [ - 'addNumToDir', 'addNumToZipDir', 'bitwiseAdjust', 'bitwiseAdjustedAnd', - 'bytesToGuid', 'ceilDiv', 'cloneOleFile', 'createZipOpen', - 'dictGetCasedKey', 'divide', 'filetimeToDatetime', 'filetimeToUtc', - 'findWk', 'fromTimeStamp', 'getCommandArgs', 'getEncodingName', - 'getFullClassName', 'hasLen', 'htmlSanitize', 'inputToBytes', - 'inputToMsgPath', 'inputToString', 'isEncapsulatedRtf', 'isEmptyString', - 'msgPathToString', 'parseType', 'prepareFilename', 'properHex', 'roundUp', - 'rtfSanitizeHtml', 'rtfSanitizePlain', 'setupLogging', 'tryGetMimetype', - 'unsignedToSignedInt', 'unwrapMsg', 'unwrapMultipart', 'validateHtml', - 'verifyPropertyId', 'verifyType', 'windowsUnicode', + 'addNumToDir', + 'addNumToZipDir', + 'bitwiseAdjust', + 'bitwiseAdjustedAnd', + 'bytesToGuid', + 'ceilDiv', + 'cloneOleFile', + 'createZipOpen', + 'dictGetCasedKey', + 'divide', + 'filetimeToDatetime', + 'filetimeToUtc', + 'findWk', + 'fromTimeStamp', + 'getCommandArgs', + 'getEncodingName', + 'hasLen', + 'htmlSanitize', + 'inputToBytes', + 'inputToMsgPath', + 'inputToString', + 'isEncapsulatedRtf', + 'isEmptyString', + 'msgPathToString', + 'parseType', + 'prepareFilename', + 'properHex', + 'roundUp', + 'rtfSanitizeHtml', + 'rtfSanitizePlain', + 'setupLogging', + 'tryGetMimetype', + 'unsignedToSignedInt', + 'unwrapMsg', + 'unwrapMultipart', + 'validateHtml', + 'verifyPropertyId', + 'verifyType', + 'windowsUnicode', ] @@ -483,10 +512,6 @@ def getEncodingName(codepage : int) -> str: raise UnsupportedEncodingError(f'The codepage {codepage} ({constants.CODE_PAGES[codepage]}) is not currently supported by your version of Python.') -def getFullClassName(inp) -> str: - return inp.__class__.__module__ + '.' + inp.__class__.__name__ - - def hasLen(obj) -> bool: """ Checks if :param obj: has a __len__ attribute. From 6f5c1f4a13cde720f126eb2a2ccc4166888f1a27 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Thu, 15 Jun 2023 14:42:03 -0700 Subject: [PATCH 30/89] Changed HTML fixes to no longer need prepared --- CHANGELOG.md | 1 + extract_msg/msg_classes/message_base.py | 21 +++++++++------------ 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 90925869..1438919f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ * Modified tests.py to only run if it is run as a file instead of imported. * Changed `knownMsgClass` to a private function since it is explicitly not being exported by any part of the module. * Removed unusued function `getFullClassName`. +* Fixes to the HTML body when saving as HTML will no longer require the `preparedHtml`/`--prepared-html` option. **v0.41.5** * Fixed an issue from version `0.41.3` where the header being present but missing the `From` field would cause an exception. diff --git a/extract_msg/msg_classes/message_base.py b/extract_msg/msg_classes/message_base.py index 250d3c24..567d4a1a 100644 --- a/extract_msg/msg_classes/message_base.py +++ b/extract_msg/msg_classes/message_base.py @@ -472,18 +472,15 @@ def injectHtmlHeader(self, prepared : bool = False) -> bytes: # Validate the HTML. if not validateHtml(body): - # If we are not preparing the HTML body, then raise an - # exception. - if not prepared: - raise BadHtmlError('HTML body failed to pass validation.') - - # If we are here, then we need to do what we can to fix the HTML body. - # Unfortunately this gets complicated because of the various ways the - # body could be wrong. If only the tag is missing, then we just - # need to insert it at the end and be done. If both the and - # tag are missing, we determine where to put the body tag (around - # everything if there is no tag, otherwise at the end) and then - # wrap it all in the tag. + logger.warning('HTML body failed to validate. Code will attempt to correct it.') + + # If we are here, then we need to do what we can to fix the HTML + # body. Unfortunately this gets complicated because of the various + # ways the body could be wrong. If only the tag is missing, + # then we just need to insert it at the end and be done. If both + # the and tag are missing, we determine where to put + # the body tag (around everything if there is no tag, + # otherwise at the end) and then wrap it all in the tag. parser = bs4.BeautifulSoup(body, features = 'html.parser') if not parser.find('html') and not parser.find('body'): if parser.find('head') or parser.find('footer'): From fca8951f219e9da1d6b4feca6880b1d5390e822f Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Thu, 15 Jun 2023 14:42:30 -0700 Subject: [PATCH 31/89] Update __init__ with current date --- extract_msg/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extract_msg/__init__.py b/extract_msg/__init__.py index 3fb88c2c..bbb02a4e 100644 --- a/extract_msg/__init__.py +++ b/extract_msg/__init__.py @@ -27,7 +27,7 @@ # along with this program. If not, see . __author__ = 'Destiny Peterson & Matthew Walker' -__date__ = '2023-06-13' +__date__ = '2023-06-15' __version__ = '0.42.0' __all__ = [ From 3f6aff795328272cf58efec692bcd917da5a94a0 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Thu, 15 Jun 2023 15:04:35 -0700 Subject: [PATCH 32/89] Fix docstrings, remove exception --- CHANGELOG.md | 1 + extract_msg/exceptions.py | 6 ------ extract_msg/msg_classes/contact.py | 2 +- extract_msg/msg_classes/message_base.py | 11 +++-------- extract_msg/msg_classes/message_signed_base.py | 2 +- extract_msg/open_msg.py | 2 +- 6 files changed, 7 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1438919f..55695101 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ * Changed `knownMsgClass` to a private function since it is explicitly not being exported by any part of the module. * Removed unusued function `getFullClassName`. * Fixes to the HTML body when saving as HTML will no longer require the `preparedHtml`/`--prepared-html` option. +* Removed the exception `BadHtmlError` since it is no longer used. **v0.41.5** * Fixed an issue from version `0.41.3` where the header being present but missing the `From` field would cause an exception. diff --git a/extract_msg/exceptions.py b/extract_msg/exceptions.py index 6971cda0..5004b512 100644 --- a/extract_msg/exceptions.py +++ b/extract_msg/exceptions.py @@ -7,7 +7,6 @@ """ __all__ = [ - 'BadHtmlError', 'ConversionError', 'DataNotFoundError', 'DeencapMalformedData', @@ -28,11 +27,6 @@ ] -class BadHtmlError(ValueError): - """ - HTML failed to pass validation. - """ - class ConversionError(Exception): """ An error occured during type conversion. diff --git a/extract_msg/msg_classes/contact.py b/extract_msg/msg_classes/contact.py index c35f8ea4..22d6929e 100644 --- a/extract_msg/msg_classes/contact.py +++ b/extract_msg/msg_classes/contact.py @@ -43,7 +43,7 @@ def __init__(self, path, **kwargs): be retrieved. :param filename: optional, the filename to be used by default when saving. - :param attachmentErrorBehavior: Optional, the behavior to use in the + :param errorBehavior: Optional, the behavior to use in the event of an error when parsing the attachments. :param overrideEncoding: optional, an encoding to use instead of the one specified by the msg file. Do not report encoding errors caused by diff --git a/extract_msg/msg_classes/message_base.py b/extract_msg/msg_classes/message_base.py index 567d4a1a..c3c8e058 100644 --- a/extract_msg/msg_classes/message_base.py +++ b/extract_msg/msg_classes/message_base.py @@ -32,8 +32,8 @@ from .._rtf.inject_rtf import injectStartRTF from ..enums import BodyTypes, DeencapType, RecipientType from ..exceptions import ( - BadHtmlError, DataNotFoundError, DeencapMalformedData, - DeencapNotEncapsulated, IncompatibleOptionsError, WKError + DataNotFoundError, DeencapMalformedData, DeencapNotEncapsulated, + IncompatibleOptionsError, WKError ) from .msg import MSGFile from ..structures.report_tag import ReportTag @@ -77,7 +77,7 @@ def __init__(self, path, **kwargs): :param overrideEncoding: Optional, an encoding to use instead of the one specified by the msg file. Do not report encoding errors caused by this. - :param attachmentErrorBehavior: Optional, the behavior to use in the + :param errorBehavior: Optional, the behavior to use in the event of an error when parsing the attachments. :param recipientSeparator: Optional, separator string to use between recipients. @@ -327,9 +327,6 @@ def getSaveHtmlBody(self, preparedHtml : bool = False, charset : str = 'utf-8', `None` or an empty string to not insert the tag (Default: 'utf-8'). :param kwargs: Used to allow kwargs expansion in the save function. Arguments absorbed by this are simply ignored. - - :raises BadHtmlError: if :param preparedHtml: is False and the HTML - fails to validate. """ if self.htmlBody: # Inject the header into the data. @@ -452,8 +449,6 @@ def injectHtmlHeader(self, prepared : bool = False) -> bytes: the prepared HTML (True) body (Default: False). :raises AttributeError: if the correct HTML body cannot be acquired. - :raises BadHtmlError: if :param preparedHtml: is False and the HTML fails to - validate. """ if not self.htmlBody: raise AttributeError('Cannot inject the HTML header without an HTML body attribute.') diff --git a/extract_msg/msg_classes/message_signed_base.py b/extract_msg/msg_classes/message_signed_base.py index ab65cc50..77c7d5dd 100644 --- a/extract_msg/msg_classes/message_signed_base.py +++ b/extract_msg/msg_classes/message_signed_base.py @@ -46,7 +46,7 @@ def __init__(self, path, **kwargs): :param overrideEncoding: optional, an encoding to use instead of the one specified by the msg file. Do not report encoding errors caused by this. - :param attachmentErrorBehavior: Optional, the behavior to use in the + :param errorBehavior: Optional, the behavior to use in the event of an error when parsing the attachments. :param recipientSeparator: Optional, Separator string to use between recipients. diff --git a/extract_msg/open_msg.py b/extract_msg/open_msg.py index 14b8e018..42077a68 100644 --- a/extract_msg/open_msg.py +++ b/extract_msg/open_msg.py @@ -61,7 +61,7 @@ def openMsg(path, **kwargs) -> MSGFile: attachments to be initialized so the other data can be retrieved. :param overrideEncoding: Optional, overrides the specified encoding of the MSG file. - :param attachmentErrorBehavior: Optional, the behaviour to use in the event + :param errorBehavior: Optional, the behaviour to use in the event of an error when parsing the attachments. :param recipientSeparator: Optional, Separator string to use between recipients. From 078f4d1e9648c1160f297de7790dd11ac6f4a9da Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Thu, 15 Jun 2023 15:06:02 -0700 Subject: [PATCH 33/89] Removed unused variable --- extract_msg/msg_classes/message_base.py | 1 - 1 file changed, 1 deletion(-) diff --git a/extract_msg/msg_classes/message_base.py b/extract_msg/msg_classes/message_base.py index c3c8e058..844f630c 100644 --- a/extract_msg/msg_classes/message_base.py +++ b/extract_msg/msg_classes/message_base.py @@ -96,7 +96,6 @@ def __init__(self, path, **kwargs): method will not run if this is set. """ super().__init__(path, **kwargs) - recipientSeparator = ';' self.__recipientSeparator = kwargs.get('recipientSeparator', ';') self.__ignoreRtfDeErrors = kwargs.get('ignoreRtfDeErrors', False) self.__deencap = kwargs.get('deencapsulationFunc') From 01808850e8bf8ddf4370fdb86f5bb199399b2ef2 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Thu, 15 Jun 2023 18:56:41 -0700 Subject: [PATCH 34/89] Large scale reorganization of attachments --- CHANGELOG.md | 2 + extract_msg/attachments/__init__.py | 111 ++++++++- extract_msg/attachments/attachment.py | 211 ++++-------------- extract_msg/attachments/attachment_base.py | 76 +++++-- extract_msg/attachments/broken_att.py | 29 +++ extract_msg/attachments/custom_att.py | 200 +++++++++++++++++ .../__init__.py | 4 +- .../custom_handler.py | 8 +- .../outlook_image_dib.py | 7 +- extract_msg/attachments/emb_msg_att.py | 134 +++++++++++ .../{signed_attachment.py => signed_att.py} | 0 extract_msg/attachments/unsupported_att.py | 35 +++ extract_msg/msg_classes/contact.py | 7 +- extract_msg/msg_classes/message_base.py | 8 +- .../msg_classes/message_signed_base.py | 9 +- extract_msg/msg_classes/msg.py | 63 ++---- extract_msg/open_msg.py | 7 +- 17 files changed, 661 insertions(+), 250 deletions(-) create mode 100644 extract_msg/attachments/broken_att.py create mode 100644 extract_msg/attachments/custom_att.py rename extract_msg/attachments/{custom_attachments => custom_att_handler}/__init__.py (95%) rename extract_msg/attachments/{custom_attachments => custom_att_handler}/custom_handler.py (86%) rename extract_msg/attachments/{custom_attachments => custom_att_handler}/outlook_image_dib.py (96%) create mode 100644 extract_msg/attachments/emb_msg_att.py rename extract_msg/attachments/{signed_attachment.py => signed_att.py} (100%) create mode 100644 extract_msg/attachments/unsupported_att.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 55695101..4ac84a8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ * Removed unusued function `getFullClassName`. * Fixes to the HTML body when saving as HTML will no longer require the `preparedHtml`/`--prepared-html` option. * Removed the exception `BadHtmlError` since it is no longer used. +* Entirely reoganized the way attachments are initialized, including the class that will be used in various circumstances. Embedded MSG files, custom attachments, and web attachments will all use dedicated classes that are subclasses of AttachmentBase. + * With this change, the way to specify a new Attachment class is to override the function used when creating attachments. This can be done by passing `attachmentInit = myFunction` as an option to `openMsg`. This function MUST return an instance of AttachmentBase. **v0.41.5** * Fixed an issue from version `0.41.3` where the header being present but missing the `From` field would cause an exception. diff --git a/extract_msg/attachments/__init__.py b/extract_msg/attachments/__init__.py index 8e07dd0f..8aea627f 100644 --- a/extract_msg/attachments/__init__.py +++ b/extract_msg/attachments/__init__.py @@ -1,24 +1,127 @@ +from __future__ import annotations + + """ Submodule for attachment classes. """ __all__ = [ # Modules. - 'custom_attachments', + 'custom_att_handler', # Classes. 'Attachment', 'AttachmentBase', + 'BrokenAttachment', 'CustomAttachmentHandler', + 'EmbeddedMsgAttachment', 'SignedAttachment', + 'UnsupportedAttachment' # Functions. + 'initStandardAttachment', 'registerHandler', ] -from . import custom_attachments +from . import custom_att_handler from .attachment import Attachment from .attachment_base import AttachmentBase -from .custom_attachments import CustomAttachmentHandler, registerHandler -from .signed_attachment import SignedAttachment \ No newline at end of file +from .broken_att import BrokenAttachment +from .custom_att import CustomAttachment +from .custom_att_handler import CustomAttachmentHandler, registerHandler +from .emb_msg_att import EmbeddedMsgAttachment +from .signed_att import SignedAttachment +from .unsupported_att import UnsupportedAttachment + + +import logging as _logging + +from typing import TYPE_CHECKING as _TYPE_CHECKING + + +if _TYPE_CHECKING: + from ..msg_classes import MSGFile + +_logger = _logging.getLogger(__name__) +_logger.addHandler(_logging.NullHandler()) + +def initStandardAttachment(msg : MSGFile, dir_) -> AttachmentBase: + """ + Returns an instance of AttachmentBase for the attachment in the MSG file at + the specified internal directory. + + :param errorBehavior: Used to tell the function what to do on errors. + """ + from ..properties import PropertiesStore + from ..enums import ErrorBehavior, PropertiesType + from ..exceptions import UnrecognizedMSGTypeError, StandardViolationError + + # First, create the properties store to check things like attachment type. + propertiesStream = msg._getStream([dir_, '__properties_version1.0']) + propStore = PropertiesStore(propertiesStream, PropertiesType.ATTACHMENT) + + try: + # Now that we have the properties store, attempt to check what type it + # is. + if '37050003' not in propStore: + from ..properties.prop import createProp + + _logger.warning(f'Attachment method property not found on attachment {dir_}. Code will attempt to guess the type.') + _logger.log(5, propStore) + + # Because this condition is actually kind of a violation of the + # standard, we are just going to do this in a dumb way. + # Basically we are going to try to set the attach method + # *manually* just so I don't have to go and modify the + # following code. + if msg.exists([dir_, '__substg1.0_37010102']): + # Set it as data and call it a day. + propData = b'\x03\x00\x057\x07\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00' + elif msg.exists([dir_, '__substg1.0_3701000D']): + # If it is a folder and we have properties, call it an MSG + # file. + if msg.exists([dir_, '__substg1.0_3701000D/__properties_version1.0']): + propData = b'\x03\x00\x057\x07\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00' + else: + # Call if custom attachment data. + propData = b'\x03\x00\x057\x07\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00' + else: + # Can't autodetect it, so throw an error. + raise StandardViolationError(f'Attachment method missing on attachment {dir_}, and it could not be determined automatically.') + + propStore._propDict['37050003'] = createProp(propData) + + # If it is a plain data attachment, create a standard attachment and + # return it. + if msg.exists([dir_, '__substg1.0_37010102']): + return Attachment(msg, dir_, propStore) + + if msg.exists([dir_, '__substg1.0_3701000D']): + if (propStore['37050003'].value & 0x7) != 0x5: + return CustomAttachment(msg, dir_, propStore) + else: + return EmbeddedMsgAttachment(msg, dir_, propStore) + + if (propStore['37050003'].value & 0x7) == 0x7: + # TODO Handling for special attacment type 0x7. + raise NotImplementedError('Attachments of type afByWebReference are not currently supported.') + + except (NotImplementedError, UnrecognizedMSGTypeError) as e: + if msg.errorBehavior & ErrorBehavior.ATTACH_NOT_IMPLEMENTED: + _logger.exception(f'Error processing attachment at {dir_}') + return UnsupportedAttachment(msg, dir_) + else: + raise + except StandardViolationError as e: + if msg.errorBehavior & ErrorBehavior.STANDARDS_VIOLATION: + _logger.exception(f'Unresolvable standards violation in {dir_}') + return BrokenAttachment(msg, dir_) + else: + raise + except Exception as e: + if msg.errorBehavior & ErrorBehavior.ATTACH_BROKEN: + _logger.exception(f'Error processing attachment at {dir_}') + return BrokenAttachment(msg, dir_) + else: + raise diff --git a/extract_msg/attachments/attachment.py b/extract_msg/attachments/attachment.py index 242e075d..b21db94b 100644 --- a/extract_msg/attachments/attachment.py +++ b/extract_msg/attachments/attachment.py @@ -19,11 +19,9 @@ from .. import constants from .attachment_base import AttachmentBase -from .custom_attachments import CustomAttachmentHandler, getHandler from ..enums import AttachmentType -from ..exceptions import StandardViolationError -from ..open_msg import openMsg from ..utils import createZipOpen, inputToString, prepareFilename +from ..properties import PropertiesStore # Allow for nice type checking. @@ -36,68 +34,19 @@ class Attachment(AttachmentBase): """ - Stores the attachment data of a Message instance. - Should the attachment be an embeded message, the - class used to create it will be the same as the - Message class used to create the attachment. + A standard data attachment of an MSG file. """ - def __init__(self, msg, dir_): + def __init__(self, msg : MSGFile, dir_, propStore : PropertiesStore): """ - :param msg: the Message instance that the attachment belongs to. - :param dir_: the directory inside the msg file where the attachment is + :param msg: The MSGFile instance that the attachment belongs to. + :param dir_: The directory inside the MSG file where the attachment is located. + :param propStore: The PropertiesStore instance for the attachment to + use. """ - super().__init__(msg, dir_) - self.__customHandler = None - - if '37050003' not in self.props: - from ..properties.prop import createProp - - logger.warning(f'Attachment method property not found on attachment {dir_}. Code will attempt to guess the type.') - logger.log(5, self.props) - - # Because this condition is actually kind of a violation of the - # standard, we are just going to do this in a dumb way. Basically we - # are going to try to set the attach method *manually* just so I - # don't have to go and modify the following code. - if self.exists('__substg1.0_37010102'): - # Set it as data and call it a day. - propData = b'\x03\x00\x057\x07\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00' - elif self.exists('__substg1.0_3701000D'): - # If it is a folder and we have properties, call it an MSG file. - if self.exists('__substg1.0_3701000D/__properties_version1.0'): - propData = b'\x03\x00\x057\x07\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00' - else: - # Call if custom attachment data. - propData = b'\x03\x00\x057\x07\x00\x00\x00\x06\x00\x00\x00\x00\x00\x00\x00' - else: - # Can't autodetect it, so throw an error. - raise StandardViolationError(f'Attachment method missing on attachment {dir_}, and it could not be determined automatically.') - - self.props._propDict['37050003'] = createProp(propData) - - # Get attachment data. - if self.exists('__substg1.0_37010102'): - self.__type = AttachmentType.DATA - self.__data = self._getStream('__substg1.0_37010102') - elif self.exists('__substg1.0_3701000D'): - if (self.props['37050003'].value & 0x7) != 0x5: - self.__type = AttachmentType.CUSTOM - # Check if we have any custom handlers. If not, it will raise - # an error automatically. - self.__customHandler = getHandler(self) - self.__data = self.__customHandler.data - else: - self.__prefix = msg.prefixList + [dir_, '__substg1.0_3701000D'] - self.__type = AttachmentType.MSG - self.__data = openMsg(self.msg.path, prefix = self.__prefix, parentMsg = self.msg, treePath = self.treePath, **self.msg.kwargs) - elif (self.props['37050003'].value & 0x7) == 0x7: - # TODO Handling for special attacment type 0x7. - self.__type = AttachmentType.WEB - raise NotImplementedError('Attachments of type afByWebReference are not currently supported.') - else: - raise TypeError('Unknown attachment type.') + super().__init__(msg, dir_, propStore) + self.__data = self._getStream('__substg1.0_37010102') def getFilename(self, **kwargs) -> str: """ @@ -123,9 +72,6 @@ def getFilename(self, **kwargs) -> str: # Check if user wants to save the file under the Content-ID. if kwargs.get('contentId', False): filename = self.cid - # If we are using a custom handler, prefer it's name. - if self.type is AttachmentType.CUSTOM: - filename = self.__customHandler.name # If we are here, try to get the filename however else we can. if not filename: filename = self.name @@ -175,15 +121,11 @@ def save(self, **kwargs) -> Optional[Union[str, MSGFile]]: :param skipEmbedded: If True, skips saving this attachment if it is an embedded MSG file. """ - # First check if we are skipping embedded messages and stop - # *immediately* if we are. - if self.type is AttachmentType.MSG and kwargs.get('skipEmbedded'): - return None - # Get the filename to use. filename = self.getFilename(**kwargs) - # Someone managed to have a null character here, so let's get rid of that + # Someone managed to have a null character here, so let's get rid of + # that filename = prepareFilename(inputToString(filename, self.msg.stringEncoding)) # Get the maximum name length. @@ -220,73 +162,45 @@ def save(self, **kwargs) -> Optional[Union[str, MSGFile]]: fullFilename = customPath / filename - if isinstance(self.__data, bytes): - if _zip: + if _zip: + name, ext = os.path.splitext(filename) + nameList = _zip.namelist() + if str(fullFilename).replace('\\', '/') in nameList: + for i in range(2, 100): + testName = customPath / f'{name} ({i}){ext}' + if str(testName).replace('\\', '/') not in nameList: + fullFilename = testName + break + else: + # If we couldn't find one that didn't exist. + raise FileExistsError(f'Could not create the specified file because it already exists ("{fullFilename}").') + else: + if fullFilename.exists(): + # Try to split the filename into a name and extention. name, ext = os.path.splitext(filename) - nameList = _zip.namelist() - if str(fullFilename).replace('\\', '/') in nameList: - for i in range(2, 100): - testName = customPath / f'{name} ({i}){ext}' - if str(testName).replace('\\', '/') not in nameList: - fullFilename = testName - break - else: - # If we couldn't find one that didn't exist. - raise FileExistsError(f'Could not create the specified file because it already exists ("{fullFilename}").') - else: - if fullFilename.exists(): - # Try to split the filename into a name and extention. - name, ext = os.path.splitext(filename) - # Try to add a number to it so that we can save without overwriting. - for i in range(2, 100): - testName = customPath / f'{name} ({i}){ext}' - if not testName.exists(): - fullFilename = testName - break - else: - # If we couldn't find one that didn't exist. - raise FileExistsError(f'Could not create the specified file because it already exists ("{fullFilename}").') - - with _open(str(fullFilename), mode) as f: - f.write(self.__data) - - # Close the ZipFile if this function created it. - if _zip and createdZip: - _zip.close() - - return str(fullFilename) - elif self.type is AttachmentType.MSG: - if kwargs.get('extractEmbedded', False): - with _open(str(fullFilename), mode) as f: - self.data.export(f) - else: - self.saveEmbededMessage(**kwargs) + # Try to add a number to it so that we can save without overwriting. + for i in range(2, 100): + testName = customPath / f'{name} ({i}){ext}' + if not testName.exists(): + fullFilename = testName + break + else: + # If we couldn't find one that didn't exist. + raise FileExistsError(f'Could not create the specified file because it already exists ("{fullFilename}").') - # Close the ZipFile if this function created it. - if _zip and createdZip: - _zip.close() + with _open(str(fullFilename), mode) as f: + f.write(self.__data) - return self.__data + # Close the ZipFile if this function created it. + if _zip and createdZip: + _zip.close() - def saveEmbededMessage(self, **kwargs) -> None: - """ - Seperate function from save to allow it to easily be overridden by a - subclass. - """ - self.data.save(**kwargs) - - @property - def customHandler(self) -> Optional[CustomAttachmentHandler]: - """ - The instance of the custom handler associated with this attachment, if - it has one. - """ - return self.__customHandler + return str(fullFilename) @property - def data(self) -> Optional[Union[bytes, MSGFile]]: + def data(self) -> bytes: """ - Returns the attachment data. + The bytes making up the attachment data. """ return self.__data @@ -306,41 +220,4 @@ def type(self) -> AttachmentType: """ Returns the (internally used) type of the data. """ - return self.__type - - - -class BrokenAttachment(AttachmentBase): - """ - An attachment that has suffered a fatal error. Will not generate from a - NotImplementedError exception. - """ - - @property - def type(self) -> AttachmentType: - """ - Returns the (internally used) type of the data. - """ - return AttachmentType.BROKEN - -class UnsupportedAttachment(AttachmentBase): - """ - An attachment whose type is not currently supported. - """ - - def save(self, **kwargs) -> None: - """ - Raises a NotImplementedError unless :param skipNotImplemented: is set to - True. If it is, returns None to signify the attachment was skipped. This - allows for the easy implementation of the option to skip this type of - attachment. - """ - if not kwargs.get('skipNotImplemented', False): - raise NotImplementedError('Unsupported attachments cannot be saved.') - - @property - def type(self) -> AttachmentType: - """ - Returns the (internally used) type of the data. - """ - return AttachmentType.UNSUPPORTED + return AttachmentType.DATA diff --git a/extract_msg/attachments/attachment_base.py b/extract_msg/attachments/attachment_base.py index 2e116b10..3809fd97 100644 --- a/extract_msg/attachments/attachment_base.py +++ b/extract_msg/attachments/attachment_base.py @@ -6,6 +6,7 @@ ] +import abc import datetime import logging import weakref @@ -13,8 +14,7 @@ from functools import cached_property, partial from typing import List, Optional, Tuple, TYPE_CHECKING -from ..enums import AttachmentType, ErrorBehavior, PropertiesType -from ..exceptions import StandardViolationError +from ..enums import AttachmentType from ..properties.named import NamedProperties from ..properties.prop import FixedLengthProp from ..properties.properties_store import PropertiesStore @@ -29,27 +29,21 @@ logger.addHandler(logging.NullHandler()) -class AttachmentBase: +class AttachmentBase(abc.ABC): """ - Stores the attachment data of a Message instance. - Should the attachment be an embeded message, the - class used to create it will be the same as the - Message class used to create the attachment. + The base class for all Attachments used by the module, if not overriden. """ - def __init__(self, msg, dir_): + def __init__(self, msg : MSGFile, dir_, propStore : PropertiesStore): """ :param msg: the Message instance that the attachment belongs to. :param dir_: the directory inside the msg file where the attachment is located. + :param propStore: The PropertiesStore instance for the attachment. If + not provided, it will be found automatically. """ self.__msg = makeWeakRef(msg) self.__dir = dir_ - if not self.exists('__properties_version1.0'): - if (msg.errorBehavior & ErrorBehavior.STANDARDS_VIOLATION): - logger.error('Attachments MUST have a property stream.') - else: - raise StandardViolationError('Attachments MUST have a property stream.') from None - self.__props = PropertiesStore(self._getStream('__properties_version1.0'), PropertiesType.ATTACHMENT) + self.__props = propStore self.__namedProperties = NamedProperties(msg.named, self) self.__treePath = msg.treePath + [makeWeakRef(self)] @@ -304,6 +298,51 @@ def existsTypedProperty(self, id, _type = None) -> bool: raise ReferenceError('The msg file for this Attachment instance has been garbage collected.') return msg.existsTypedProperty(id, self.__dir, _type, True, self.__props) + @abc.abstractmethod + def getFilename(self, **kwargs) -> str: + """ + Returns the filename to use for the attachment. + + :param contentId: Use the contentId, if available. + :param customFilename: A custom name to use for the file. + + If the filename starts with "UnknownFilename" then there is no guarentee + that the files will have exactly the same filename. + """ + + @abc.abstractmethod + def save(self, **kwargs): + """ + Saves the attachment data. + + The name of the file is determined by several factors. The first + thing that is checked is if you have provided :param customFilename: + to this function. If you have, that is the name that will be used. + If no custom name has been provided and :param contentId: is True, + the file will be saved using the content ID of the attachment. If + it is not found or :param contentId: is False, the long filename + will be used. If the long filename is not found, the short one will + be used. If after all of this a usable filename has not been found, a + random one will be used (accessible from `Attachment.randomFilename`). + After the name to use has been determined, it will then be shortened to + make sure that it is not more than the value of :param maxNameLength:. + + To change the directory that the attachment is saved to, set the value + of :param customPath: when calling this function. The default save + directory is the working directory. + + If you want to save the contents into a ZipFile or similar object, + either pass a path to where you want to create one or pass an instance + to :param zip:. If :param zip: is an instance, :param customPath: will + refer to a location inside the zip file. + + :param extractEmbedded: If True, causes the attachment, should it be an + embedded MSG file, to save as a .msg file instead of calling it's + save function. + :param skipEmbedded: If True, skips saving this attachment if it is an + embedded MSG file. + """ + @property def attachmentEncoding(self) -> Optional[bytes]: """ @@ -362,6 +401,13 @@ def clsid(self) -> str: return clsid + @property + @abc.abstractmethod + def data(self) -> Optional[object]: + """ + The attachment data, if any. Returns None if there is no data to save. + """ + @property def dir(self) -> str: """ @@ -491,8 +537,8 @@ def treePath(self) -> List[weakref.ReferenceType]: return self.__treePath @property + @abc.abstractmethod def type(self) -> AttachmentType: """ Returns the (internally used) type of the data. """ - return AttachmentType.UNKNOWN diff --git a/extract_msg/attachments/broken_att.py b/extract_msg/attachments/broken_att.py new file mode 100644 index 00000000..c9570992 --- /dev/null +++ b/extract_msg/attachments/broken_att.py @@ -0,0 +1,29 @@ +from .attachment_base import AttachmentBase +from ..enums import AttachmentType + + +class BrokenAttachment(AttachmentBase): + """ + An attachment that has suffered a fatal error. Will not generate from a + NotImplementedError exception. + """ + + def getFilename(self, **kwargs) -> str: + raise NotImplementedError('Broken attachments cannot be saved.') + + def save(self, **kwargs): + raise NotImplementedError('Broken attachments cannot be saved.') + + @property + def data(self) -> None: + """ + Broken attachments have no data. + """ + return None + + @property + def type(self) -> AttachmentType: + """ + Returns the (internally used) type of the data. + """ + return AttachmentType.BROKEN \ No newline at end of file diff --git a/extract_msg/attachments/custom_att.py b/extract_msg/attachments/custom_att.py new file mode 100644 index 00000000..4e9f686c --- /dev/null +++ b/extract_msg/attachments/custom_att.py @@ -0,0 +1,200 @@ +from __future__ import annotations + + +__all__ = [ + 'EmbeddedMsgAttachment', +] + + +import os +import pathlib +import random +import string +import zipfile + +from .. import constants +from .attachment_base import AttachmentBase +from .custom_att_handler import CustomAttachmentHandler, getHandler +from ..enums import AttachmentType +from ..utils import createZipOpen, inputToString, prepareFilename + +from typing import Optional, TYPE_CHECKING + + +if TYPE_CHECKING: + from ..msg_classes import MSGFile + from ..properties import PropertiesStore + + +_saveDoc = AttachmentBase.save.__doc__ + + +class CustomAttachment(AttachmentBase): + """ + The attachment entry for custom attachments. + """ + + def __init__(self, msg : MSGFile, dir_, propStore : PropertiesStore): + super().__init__(msg, dir_, propStore) + + self.__customHandler = getHandler(self) + self.__data = self.__customHandler.data + + + def getFilename(self, **kwargs) -> str: + """ + Returns the filename to use for the attachment. + + :param contentId: Use the contentId, if available. + :param customFilename: A custom name to use for the file. + + If the filename starts with "UnknownFilename" then there is no guarentee + that the files will have exactly the same filename. + """ + filename = None + customFilename = kwargs.get('customFilename') + if customFilename: + customFilename = str(customFilename) + # First we need to validate it. If there are invalid characters, + # this will detect it. + if constants.RE_INVALID_FILENAME_CHARACTERS.search(customFilename): + raise ValueError('Invalid character found in customFilename. Must not contain any of the following characters: \\/:*?"<>|') + filename = customFilename + else: + # If not... + # Check if user wants to save the file under the Content-ID. + if kwargs.get('contentId', False): + filename = self.cid + # Try to get the name from the custom handler. + filename = self.customHandler.name + # If we are here, try to get the filename however else we can. + if not filename: + filename = self.name + # Otherwise just make something up! + if not filename: + return self.randomFilename + + return filename + + def regenerateRandomName(self) -> str: + """ + Used to regenerate the random filename used if the attachment cannot + find a usable filename. + """ + self.__randomName = 'UnknownFilename ' + \ + ''.join(random.choice(string.ascii_uppercase + string.digits) + for _ in range(5)) + '.bin' + + def save(self, **kwargs) -> Optional[str]: + # Immediate check to see if there is anything to save. + if self.data is None: + return None + + # Get the filename to use. + filename = self.getFilename(**kwargs) + + # Someone managed to have a null character here, so let's get rid of + # that + filename = prepareFilename(inputToString(filename, self.msg.stringEncoding)) + + # Get the maximum name length. + maxNameLength = kwargs.get('maxNameLength', 256) + + # Make sure the filename is not longer than it should be. + if len(filename) > maxNameLength: + name, ext = os.path.splitext(filename) + filename = name[:maxNameLength - len(ext)] + ext + + # Check if we are doing a zip file. + _zip = kwargs.get('zip') + + # ZipFile handling. + if _zip: + # If we are doing a zip file, first check that we have been given a path. + if isinstance(_zip, (str, pathlib.Path)): + # If we have a path then we use the zip file. + _zip = zipfile.ZipFile(_zip, 'a', zipfile.ZIP_DEFLATED) + kwargs['zip'] = _zip + createdZip = True + else: + createdZip = False + # Path needs to be done in a special way if we are in a zip file. + customPath = pathlib.Path(kwargs.get('customPath', '')) + # Set the open command to be that of the zip file. + _open = createZipOpen(_zip.open) + # Zip files use w for writing in binary. + mode = 'w' + else: + customPath = pathlib.Path(kwargs.get('customPath', '.')).absolute() + mode = 'wb' + _open = open + + fullFilename = customPath / filename + + if _zip: + name, ext = os.path.splitext(filename) + nameList = _zip.namelist() + if str(fullFilename).replace('\\', '/') in nameList: + for i in range(2, 100): + testName = customPath / f'{name} ({i}){ext}' + if str(testName).replace('\\', '/') not in nameList: + fullFilename = testName + break + else: + # If we couldn't find one that didn't exist. + raise FileExistsError(f'Could not create the specified file because it already exists ("{fullFilename}").') + else: + if fullFilename.exists(): + # Try to split the filename into a name and extention. + name, ext = os.path.splitext(filename) + # Try to add a number to it so that we can save without overwriting. + for i in range(2, 100): + testName = customPath / f'{name} ({i}){ext}' + if not testName.exists(): + fullFilename = testName + break + else: + # If we couldn't find one that didn't exist. + raise FileExistsError(f'Could not create the specified file because it already exists ("{fullFilename}").') + + with _open(str(fullFilename), mode) as f: + f.write(self.__data) + + # Close the ZipFile if this function created it. + if _zip and createdZip: + _zip.close() + + return str(fullFilename) + + @property + def customHandler(self) -> Optional[CustomAttachmentHandler]: + """ + The instance of the custom handler associated with this attachment, if + it has one. + """ + return self.__customHandler + + @property + def data(self) -> Optional[bytes]: + """ + The attachment data, if any. Returns None if there is no data to save. + """ + return self.__data + + @property + def randomFilename(self) -> str: + """ + Returns the random filename to be used by this attachment. + """ + try: + return self.__randomName + except AttributeError: + self.regenerateRandomName() + return self.__randomName + + @property + def type(self) -> AttachmentType: + """ + Returns the (internally used) type of the data. + """ + return AttachmentType.CUSTOM diff --git a/extract_msg/attachments/custom_attachments/__init__.py b/extract_msg/attachments/custom_att_handler/__init__.py similarity index 95% rename from extract_msg/attachments/custom_attachments/__init__.py rename to extract_msg/attachments/custom_att_handler/__init__.py index 13e32914..b3318f4a 100644 --- a/extract_msg/attachments/custom_attachments/__init__.py +++ b/extract_msg/attachments/custom_att_handler/__init__.py @@ -59,11 +59,11 @@ def registerHandler(handler : Type[CustomAttachmentHandler]) -> None: if TYPE_CHECKING: - from ..attachment import Attachment + from ..attachment_base import AttachmentBase # Function designed to route to the correct handler. -def getHandler(attachment : Attachment) -> CustomAttachmentHandler: +def getHandler(attachment : AttachmentBase) -> CustomAttachmentHandler: """ Takes an attachment and uses it to find the correct handler. Returns an instance created using the specified attachment. diff --git a/extract_msg/attachments/custom_attachments/custom_handler.py b/extract_msg/attachments/custom_att_handler/custom_handler.py similarity index 86% rename from extract_msg/attachments/custom_attachments/custom_handler.py rename to extract_msg/attachments/custom_att_handler/custom_handler.py index a787ae1f..40fe75f8 100644 --- a/extract_msg/attachments/custom_attachments/custom_handler.py +++ b/extract_msg/attachments/custom_att_handler/custom_handler.py @@ -12,7 +12,7 @@ if TYPE_CHECKING: - from ..attachment import Attachment + from ..attachment_base import AttachmentBase class CustomAttachmentHandler(abc.ABC): @@ -21,13 +21,13 @@ class CustomAttachmentHandler(abc.ABC): special ways that are completely different from one another. """ - def __init__(self, attachment : Attachment): + def __init__(self, attachment : AttachmentBase): super().__init__() self.__att = attachment @classmethod @abc.abstractmethod - def isCorrectHandler(cls, attachment : Attachment) -> bool: + def isCorrectHandler(cls, attachment : AttachmentBase) -> bool: """ Checks if this is the correct handler for the attachment. """ @@ -59,7 +59,7 @@ def data(self) -> bytes: @property @abc.abstractmethod - def name(self) -> str: + def name(self) -> Optional[str]: """ Returns the name to be used when saving the attachment. """ diff --git a/extract_msg/attachments/custom_attachments/outlook_image_dib.py b/extract_msg/attachments/custom_att_handler/outlook_image_dib.py similarity index 96% rename from extract_msg/attachments/custom_attachments/outlook_image_dib.py rename to extract_msg/attachments/custom_att_handler/outlook_image_dib.py index 9d3d0e63..73a00abf 100644 --- a/extract_msg/attachments/custom_attachments/outlook_image_dib.py +++ b/extract_msg/attachments/custom_att_handler/outlook_image_dib.py @@ -6,7 +6,6 @@ ] -import base64 import struct from typing import Optional, TYPE_CHECKING @@ -17,7 +16,7 @@ if TYPE_CHECKING: - from ..attachment import Attachment + from ..attachment_base import AttachmentBase _ST_OLE = struct.Struct(' bool: + def isCorrectHandler(cls, attachment : AttachmentBase) -> bool: if attachment.clsid != '00000316-0000-0000-C000-000000000046': return False diff --git a/extract_msg/attachments/emb_msg_att.py b/extract_msg/attachments/emb_msg_att.py new file mode 100644 index 00000000..0e0e1314 --- /dev/null +++ b/extract_msg/attachments/emb_msg_att.py @@ -0,0 +1,134 @@ +from __future__ import annotations + + +__all__ = [ + 'EmbeddedMsgAttachment', +] + + +import os +import pathlib +import zipfile + +from .. import constants +from .attachment_base import AttachmentBase +from ..enums import AttachmentType +from ..open_msg import openMsg +from ..utils import createZipOpen, prepareFilename + +from typing import Optional, TYPE_CHECKING + + +if TYPE_CHECKING: + from ..msg_classes import MSGFile + from ..properties import PropertiesStore + + +_saveDoc = AttachmentBase.save.__doc__ + + +class EmbeddedMsgAttachment(AttachmentBase): + """ + The attachment entry for an Embedded MSG file. + """ + + def __init__(self, msg : MSGFile, dir_, propertiesStore : PropertiesStore): + super().__init__(msg, dir_, propertiesStore) + self.__prefix = msg.prefixList + [dir_, '__substg1.0_3701000D'] + self.__data = openMsg(self.msg.path, prefix = self.__prefix, parentMsg = self.msg, treePath = self.treePath, **self.msg.kwargs) + + def getFilename(self, **kwargs) -> str: + """ + Returns the filename to use for the attachment. + + :param contentId: Use the contentId, if available. + :param customFilename: A custom name to use for the file. + + If the filename starts with "UnknownFilename" then there is no guarentee + that the files will have exactly the same filename. + """ + customFilename = kwargs.get('customFilename') + if customFilename: + customFilename = str(customFilename) + # First we need to validate it. If there are invalid characters, + # this will detect it. + if constants.RE_INVALID_FILENAME_CHARACTERS.search(customFilename): + raise ValueError('Invalid character found in customFilename. Must not contain any of the following characters: \\/:*?"<>|') + return customFilename + else: + return self.name + + def save(self, **kwargs) -> Optional[MSGFile]: + # First check if we are skipping embedded messages and stop + # *immediately* if we are. + if kwargs.get('skipEmbedded'): + return None + + # Get the filename to use. + filename = self.getFilename(**kwargs) + + # Someone managed to have a null character here, so let's get rid of + # that + filename = prepareFilename(filename) + + # Get the maximum name length. + maxNameLength = kwargs.get('maxNameLength', 256) + + # Make sure the filename is not longer than it should be. + if len(filename) > maxNameLength: + name, ext = os.path.splitext(filename) + filename = name[:maxNameLength - len(ext)] + ext + + # Check if we are doing a zip file. + _zip = kwargs.get('zip') + + # ZipFile handling. + if _zip: + # If we are doing a zip file, first check that we have been given a path. + if isinstance(_zip, (str, pathlib.Path)): + # If we have a path then we use the zip file. + _zip = zipfile.ZipFile(_zip, 'a', zipfile.ZIP_DEFLATED) + kwargs['zip'] = _zip + createdZip = True + else: + createdZip = False + # Path needs to be done in a special way if we are in a zip file. + customPath = pathlib.Path(kwargs.get('customPath', '')) + # Set the open command to be that of the zip file. + _open = createZipOpen(_zip.open) + # Zip files use w for writing in binary. + mode = 'w' + else: + customPath = pathlib.Path(kwargs.get('customPath', '.')).absolute() + mode = 'wb' + _open = open + + fullFilename = customPath / filename + + if kwargs.get('extractEmbedded', False): + with _open(str(fullFilename), mode) as f: + self.data.export(f) + else: + self.data.save(**kwargs) + + # Close the ZipFile if this function created it. + if _zip and createdZip: + _zip.close() + + return self.__data + + save.__doc__ = _saveDoc + + @property + def data(self) -> MSGFile: + """ + Returns the attachment data. + """ + return self.__data + + @property + def type(self) -> AttachmentType: + """ + Returns the (internally used) type of the data. + """ + return AttachmentType.MSG \ No newline at end of file diff --git a/extract_msg/attachments/signed_attachment.py b/extract_msg/attachments/signed_att.py similarity index 100% rename from extract_msg/attachments/signed_attachment.py rename to extract_msg/attachments/signed_att.py diff --git a/extract_msg/attachments/unsupported_att.py b/extract_msg/attachments/unsupported_att.py new file mode 100644 index 00000000..e89569fe --- /dev/null +++ b/extract_msg/attachments/unsupported_att.py @@ -0,0 +1,35 @@ +from .attachment_base import AttachmentBase +from ..enums import AttachmentType + + +class UnsupportedAttachment(AttachmentBase): + """ + An attachment whose type is not currently supported. + """ + + def getFilename(self, **kwargs) -> str: + raise NotImplementedError('Unsupported attachments cannot be saved.') + + def save(self, **kwargs) -> None: + """ + Raises a NotImplementedError unless :param skipNotImplemented: is set to + True. If it is, returns None to signify the attachment was skipped. This + allows for the easy implementation of the option to skip this type of + attachment. + """ + if not kwargs.get('skipNotImplemented', False): + raise NotImplementedError('Unsupported attachments cannot be saved.') + + @property + def data(self) -> None: + """ + Broken attachments have no data. + """ + return None + + @property + def type(self) -> AttachmentType: + """ + Returns the (internally used) type of the data. + """ + return AttachmentType.UNSUPPORTED \ No newline at end of file diff --git a/extract_msg/msg_classes/contact.py b/extract_msg/msg_classes/contact.py index 22d6929e..f46a77d6 100644 --- a/extract_msg/msg_classes/contact.py +++ b/extract_msg/msg_classes/contact.py @@ -34,9 +34,10 @@ def __init__(self, path, **kwargs): one. Do not set manually unless you know what you are doing. :param parentMsg: Used for synchronizing named properties instances. Do not set this unless you know what you are doing. - :param attachmentClass: optional, the class the MSGFile object will use - for attachments. You probably should not change this value unless - you know what you are doing. + :param initAttachment: Optional, the method used when creating an + attachment for an MSG file. MUST be a function that takes 2 + arguments (the MSGFile instance and the directory in the MSG file + where the attachment is) and returns an instance of AttachmentBase. :param delayAttachments: optional, delays the initialization of attachments until the user attempts to retrieve them. Allows MSG files with bad attachments to be initialized so the other data can diff --git a/extract_msg/msg_classes/message_base.py b/extract_msg/msg_classes/message_base.py index 844f630c..741c93a4 100644 --- a/extract_msg/msg_classes/message_base.py +++ b/extract_msg/msg_classes/message_base.py @@ -64,10 +64,10 @@ def __init__(self, path, **kwargs): you know what you are doing. :param parentMsg: Used for syncronizing named properties instances. Do not set this unless you know what you are doing. - :param attachmentClass: Optional, the class the Message object - will use for attachments. You probably should - not change this value unless you know what you - are doing. + :param initAttachment: Optional, the method used when creating an + attachment for an MSG file. MUST be a function that takes 2 + arguments (the MSGFile instance and the directory in the MSG file + where the attachment is) and returns an instance of AttachmentBase. :param filename: Optional, the filename to be used by default when saving. :param delayAttachments: Optional, delays the initialization of diff --git a/extract_msg/msg_classes/message_signed_base.py b/extract_msg/msg_classes/message_signed_base.py index 77c7d5dd..83eb6099 100644 --- a/extract_msg/msg_classes/message_signed_base.py +++ b/extract_msg/msg_classes/message_signed_base.py @@ -31,10 +31,10 @@ def __init__(self, path, **kwargs): :param prefix: used for extracting embeded msg files inside the main one. Do not set manually unless you know what you are doing. - :param attachmentClass: optional, the class the Message object - will use for attachments. You probably should - not change this value unless you know what you - are doing. + :param initAttachment: Optional, the method used when creating an + attachment for an MSG file. MUST be a function that takes 2 + arguments (the MSGFile instance and the directory in the MSG file + where the attachment is) and returns an instance of AttachmentBase. :param signedAttachmentClass: optional, the class the object will use for signed attachments. :param filename: optional, the filename to be used by default when @@ -51,7 +51,6 @@ def __init__(self, path, **kwargs): :param recipientSeparator: Optional, Separator string to use between recipients. """ - self.__recipientSeparator = kwargs.get('recipientSeparator', ';') self.__signedAttachmentClass = kwargs.get('signedAttachmentClass', SignedAttachment) super().__init__(path, **kwargs) # Initialize properties in the order that is least likely to cause bugs. diff --git a/extract_msg/msg_classes/msg.py b/extract_msg/msg_classes/msg.py index 9a6229c7..d7742c35 100644 --- a/extract_msg/msg_classes/msg.py +++ b/extract_msg/msg_classes/msg.py @@ -1,3 +1,6 @@ +from __future__ import annotations + + __all__ = [ 'MSGFile', ] @@ -15,16 +18,16 @@ import olefile -from typing import List, Optional, Set, Tuple, Union +from typing import Any, Callable, List, Optional, Set, Tuple, Union from .. import constants -from ..attachments.attachment import Attachment, BrokenAttachment, UnsupportedAttachment +from ..attachments import AttachmentBase, initStandardAttachment from ..enums import ( AttachErrorBehavior, ErrorBehavior, Importance, Priority, PropertiesType, Sensitivity, SideEffect ) from ..exceptions import ( - InvalidFileFormatError, StandardViolationError, UnrecognizedMSGTypeError + InvalidFileFormatError, StandardViolationError ) from ..properties.named import Named, NamedProperties from ..properties.prop import FixedLengthProp @@ -52,9 +55,10 @@ def __init__(self, path, **kwargs): one. Do not set manually unless you know what you are doing. :param parentMsg: Used for synchronizing named properties instances. Do not set this unless you know what you are doing. - :param attachmentClass: Optional, the class the MSGFile object will use - for attachments. You probably should not change this value unless - you know what you are doing. + :param initAttachment: Optional, the method used when creating an + attachment for an MSG file. MUST be a function that takes 2 + arguments (the MSGFile instance and the directory in the MSG file + where the attachment is) and returns an instance of AttachmentBase. :param delayAttachments: Optional, delays the initialization of attachments until the user attempts to retrieve them. Allows MSG files with bad attachments to be initialized so the other data can @@ -96,7 +100,7 @@ def __init__(self, path, **kwargs): # WARNING DO NOT MANUALLY MODIFY PREFIX. Let the program set it. self.__path = path - self.__attachmentClass = kwargs.get('attachmentClass', Attachment) + self.__initAttachmentFunc = kwargs.get('initAttachment', initStandardAttachment) self.__attachmentsDelayed = kwargs.get('delayAttachments', False) self.__attachmentsReady = False self.__errorBehavior = ErrorBehavior(kwargs.get('errorBehavior', ErrorBehavior.THROW)) @@ -186,11 +190,11 @@ def __init__(self, path, **kwargs): if not self.__attachmentsDelayed: self.attachments - def __enter__(self): + def __enter__(self) -> MSGFile: self.__ole.__enter__() return self - def __exit__(self, *args, **kwargs): + def __exit__(self, *_) -> None: self.close() def _ensureSet(self, variable : str, streamID, stringStream : bool = True, **kwargs): @@ -657,7 +661,7 @@ def areStringsUnicode(self) -> bool: return self.__bStringsUnicode @property - def attachments(self) -> List: + def attachments(self) -> List[AttachmentBase]: """ Returns a list of all attachments. """ @@ -674,39 +678,12 @@ def attachments(self) -> List: self._attachments = [] for attachmentDir in attachmentDirs: - try: - self._attachments.append(self.attachmentClass(self, attachmentDir)) - except (NotImplementedError, UnrecognizedMSGTypeError) as e: - if self.errorBehavior & ErrorBehavior.ATTACH_NOT_IMPLEMENTED: - logger.exception(f'Error processing attachment at {attachmentDir}') - self._attachments.append(UnsupportedAttachment(self, attachmentDir)) - else: - raise - except StandardViolationError as e: - if self.errorBehavior & ErrorBehavior.STANDARDS_VIOLATION: - logger.exception(f'Unresolvable standards violation in {attachmentDir}') - self._attachments.append(BrokenAttachment(self, attachmentDir)) - else: - raise - except Exception as e: - if self.errorBehavior & ErrorBehavior.ATTACH_BROKEN: - logger.exception(f'Error processing attachment at {attachmentDir}') - self._attachments.append(BrokenAttachment(self, attachmentDir)) - else: - raise + self._attachments.append(self.initAttachmentFunc(self, attachmentDir)) self.__attachmentsReady = True return self._attachments - @property - def attachmentClass(self): - """ - Returns the Attachment class being used, should you need to use it - externally for whatever reason. - """ - return self.__attachmentClass - @property def attachmentsDelayed(self) -> bool: """ @@ -789,10 +766,18 @@ def importanceString(self) -> Union[str, None]: return { Importance.HIGH: 'High', Importance.MEDIUM: None, - Importance.LOW: 'low', + Importance.LOW: 'Low', None: None, }[self.importance] + @property + def initAttachmentFunc(self) -> Callable[[MSGFile, Any], AttachmentBase]: + """ + Returns the method for initializing attachments being used, should you + need to use it externally for whatever reason. + """ + return self.__initAttachmentFunc + @property def kwargs(self) -> dict: """ diff --git a/extract_msg/open_msg.py b/extract_msg/open_msg.py index 42077a68..489552ae 100644 --- a/extract_msg/open_msg.py +++ b/extract_msg/open_msg.py @@ -50,9 +50,10 @@ def openMsg(path, **kwargs) -> MSGFile: Do not set manually unless you know what you are doing. :param parentMsg: Used for syncronizing named properties instances. Do not set this unless you know what you are doing. - :param attachmentClass: Optional, the class the Message object will use for - attachments. You probably should not change this value unless you know - what you are doing. + :param initAttachment: Optional, the method used when creating an attachment + for an MSG file. MUST be a function that takes 2 arguments (the MSGFile + instance and the directory in the MSG file where the attachment is) and + returns an instance of AttachmentBase. :param signedAttachmentClass: Optional, the class the object will use for signed attachments. :param filename: Optional, the filename to be used by default when saving. From 0aaaf5492449127e21599ce1d04defbd407d59fb Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Thu, 15 Jun 2023 19:03:21 -0700 Subject: [PATCH 35/89] Fix type hint and remove unnecesary line --- extract_msg/msg_classes/msg.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/extract_msg/msg_classes/msg.py b/extract_msg/msg_classes/msg.py index d7742c35..57d1e708 100644 --- a/extract_msg/msg_classes/msg.py +++ b/extract_msg/msg_classes/msg.py @@ -21,7 +21,9 @@ from typing import Any, Callable, List, Optional, Set, Tuple, Union from .. import constants -from ..attachments import AttachmentBase, initStandardAttachment +from ..attachments import ( + AttachmentBase, initStandardAttachment, SignedAttachment + ) from ..enums import ( AttachErrorBehavior, ErrorBehavior, Importance, Priority, PropertiesType, Sensitivity, SideEffect @@ -661,7 +663,7 @@ def areStringsUnicode(self) -> bool: return self.__bStringsUnicode @property - def attachments(self) -> List[AttachmentBase]: + def attachments(self) -> Union[List[AttachmentBase], List[SignedAttachment]]: """ Returns a list of all attachments. """ @@ -670,7 +672,6 @@ def attachments(self) -> List[AttachmentBase]: except AttributeError: # Get the attachments. attachmentDirs = [] - prefixLen = self.prefixLen for dir_ in self.listDir(False, True, False): if dir_[0].startswith('__attach') and dir_[0] not in attachmentDirs: attachmentDirs.append(dir_[0]) From 1816e28d982e87058423469dfa87abf4a4c4ea24 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Thu, 15 Jun 2023 21:08:38 -0700 Subject: [PATCH 36/89] Fix exports for various attachment modules --- extract_msg/attachments/attachment.py | 2 -- extract_msg/attachments/broken_att.py | 5 +++++ extract_msg/attachments/custom_att.py | 2 +- extract_msg/attachments/unsupported_att.py | 5 +++++ 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/extract_msg/attachments/attachment.py b/extract_msg/attachments/attachment.py index b21db94b..32ffb475 100644 --- a/extract_msg/attachments/attachment.py +++ b/extract_msg/attachments/attachment.py @@ -3,8 +3,6 @@ __all__ = [ 'Attachment', - 'BrokenAttachment', - 'UnsupportedAttachment', ] diff --git a/extract_msg/attachments/broken_att.py b/extract_msg/attachments/broken_att.py index c9570992..b73ec9dc 100644 --- a/extract_msg/attachments/broken_att.py +++ b/extract_msg/attachments/broken_att.py @@ -1,3 +1,8 @@ +__all__ = [ + 'BrokenAttachment', +] + + from .attachment_base import AttachmentBase from ..enums import AttachmentType diff --git a/extract_msg/attachments/custom_att.py b/extract_msg/attachments/custom_att.py index 4e9f686c..0f76d052 100644 --- a/extract_msg/attachments/custom_att.py +++ b/extract_msg/attachments/custom_att.py @@ -2,7 +2,7 @@ __all__ = [ - 'EmbeddedMsgAttachment', + 'CustomAttachment', ] diff --git a/extract_msg/attachments/unsupported_att.py b/extract_msg/attachments/unsupported_att.py index e89569fe..91c23cd0 100644 --- a/extract_msg/attachments/unsupported_att.py +++ b/extract_msg/attachments/unsupported_att.py @@ -1,3 +1,8 @@ +__all__ = [ + 'UnsupportedAttachment', +] + + from .attachment_base import AttachmentBase from ..enums import AttachmentType From d7aaba656f07a1a55d3450b9faa17c5dc1b3ff87 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Thu, 15 Jun 2023 22:27:27 -0700 Subject: [PATCH 37/89] Fix minor bugs and add web attachments (alpha) --- extract_msg/attachments/__init__.py | 7 ++- extract_msg/attachments/attachment_base.py | 9 ++- extract_msg/attachments/web_att.py | 67 ++++++++++++++++++++++ extract_msg/enums.py | 10 ++++ 4 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 extract_msg/attachments/web_att.py diff --git a/extract_msg/attachments/__init__.py b/extract_msg/attachments/__init__.py index 8aea627f..729917a8 100644 --- a/extract_msg/attachments/__init__.py +++ b/extract_msg/attachments/__init__.py @@ -16,7 +16,8 @@ 'CustomAttachmentHandler', 'EmbeddedMsgAttachment', 'SignedAttachment', - 'UnsupportedAttachment' + 'UnsupportedAttachment', + 'WebAttachment', # Functions. 'initStandardAttachment', @@ -33,6 +34,7 @@ from .emb_msg_att import EmbeddedMsgAttachment from .signed_att import SignedAttachment from .unsupported_att import UnsupportedAttachment +from .web_att import WebAttachment import logging as _logging @@ -104,8 +106,7 @@ def initStandardAttachment(msg : MSGFile, dir_) -> AttachmentBase: return EmbeddedMsgAttachment(msg, dir_, propStore) if (propStore['37050003'].value & 0x7) == 0x7: - # TODO Handling for special attacment type 0x7. - raise NotImplementedError('Attachments of type afByWebReference are not currently supported.') + return WebAttachment(msg, dir_, propStore) except (NotImplementedError, UnrecognizedMSGTypeError) as e: if msg.errorBehavior & ErrorBehavior.ATTACH_NOT_IMPLEMENTED: diff --git a/extract_msg/attachments/attachment_base.py b/extract_msg/attachments/attachment_base.py index 3809fd97..5b6be71f 100644 --- a/extract_msg/attachments/attachment_base.py +++ b/extract_msg/attachments/attachment_base.py @@ -78,7 +78,7 @@ def _ensureSet(self, variable, streamID, stringStream = True, **kwargs): setattr(self, variable, value) return value - def _ensureSetNamed(self, variable, propertyName : str, guid : str, **kwargs): + def _ensureSetNamed(self, variable : str, propertyName : str, guid : str, **kwargs): """ Ensures that the variable exists, otherwise will set it using the named property. After that, return said variable. @@ -461,6 +461,13 @@ def longFilename(self) -> Optional[str]: """ return self._ensureSet('_longFilename', '__substg1.0_3707') + @property + def longPathname(self) -> Optional[str]: + """ + The fully qualified path and file name with extension. + """ + return self._ensureSet('_longPathname', '__substg1.0_370D') + @property def mimetype(self) -> Optional[str]: """ diff --git a/extract_msg/attachments/web_att.py b/extract_msg/attachments/web_att.py new file mode 100644 index 00000000..74442d76 --- /dev/null +++ b/extract_msg/attachments/web_att.py @@ -0,0 +1,67 @@ +__all__ = [ + 'WebAttachment', +] + + +from .. import constants +from .attachment_base import AttachmentBase +from ..enums import AttachmentPermissionType, AttachmentType + + +from typing import Optional + + +class WebAttachment(AttachmentBase): + """ + An attachment that exists on the internet and not attached to the MSGFile + directly. + """ + + def getFilename(self) -> str: + raise NotImplementedError('Cannot get the filename of a web attachment.') + + def save(self, **_) -> None: + raise NotImplementedError('Cannot save a web attachment.') + + @property + def data(self) -> None: + """ + The bytes making up the attachment data. + """ + raise NotImplementedError('Cannot get the data of a web attachment') + + @property + def originalPermissionType(self) -> Optional[AttachmentPermissionType]: + """ + The permission type data associated with a web reference attachment. + """ + return self._ensureSetNamed('_oPermissionType', 'AttachmentOriginalPermissionType', constants.PSETID_ATTACHMENT, overrideClass = AttachmentPermissionType, preserveNone = True) + + @property + def permissionType(self) -> Optional[AttachmentPermissionType]: + """ + The permission type data associated with a web reference attachment. + """ + return self._ensureSetNamed('_permissionType', 'AttachmentPermissionType', constants.PSETID_ATTACHMENT, overrideClass = AttachmentPermissionType, preserveNone = True) + + @property + def providerName(self) -> Optional[str]: + """ + The type of web service manipulating the attachment. + """ + return self._ensureSetNamed('_permissionType', 'AttachmentProviderType', constants.PSETID_ATTACHMENT) + + @property + def type(self) -> AttachmentType: + """ + Returns the (internally used) type of the data. + """ + return AttachmentType.WEB + + @property + def url(self) -> Optional[str]: + """ + The url for the web attachment. If this is not set, that is probably an + error. + """ + return self.longPathname \ No newline at end of file diff --git a/extract_msg/enums.py b/extract_msg/enums.py index b51c9c29..fa501b4c 100644 --- a/extract_msg/enums.py +++ b/extract_msg/enums.py @@ -110,6 +110,16 @@ def fromBits(cls, value : int) -> Set['AppointmentStateFlag']: +class AttachmentPermissionType(enum.Enum): + """ + The permission type data associated with a web reference attachment. + """ + NONE = 0 + VIEW = 1 + EDIT = 2 + + + class AttachmentType(enum.Enum): """ The type represented by the attachment. From 8c36cf1291f4ba3c113ce913dad96805611fdb6e Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Thu, 15 Jun 2023 22:37:07 -0700 Subject: [PATCH 38/89] Update changelog, fix bug --- CHANGELOG.md | 1 + extract_msg/attachments/web_att.py | 12 ++++++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ac84a8e..9f654124 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ * Removed the exception `BadHtmlError` since it is no longer used. * Entirely reoganized the way attachments are initialized, including the class that will be used in various circumstances. Embedded MSG files, custom attachments, and web attachments will all use dedicated classes that are subclasses of AttachmentBase. * With this change, the way to specify a new Attachment class is to override the function used when creating attachments. This can be done by passing `attachmentInit = myFunction` as an option to `openMsg`. This function MUST return an instance of AttachmentBase. +* Added first implementation of web attachments. Saving is not currently possible, but basic relevent property access is now possible. Saving will not be stopped by this attachment if `skipNotImplemented = True` is passed to the save function. **v0.41.5** * Fixed an issue from version `0.41.3` where the header being present but missing the `From` field would cause an exception. diff --git a/extract_msg/attachments/web_att.py b/extract_msg/attachments/web_att.py index 74442d76..832c0b8b 100644 --- a/extract_msg/attachments/web_att.py +++ b/extract_msg/attachments/web_att.py @@ -20,8 +20,16 @@ class WebAttachment(AttachmentBase): def getFilename(self) -> str: raise NotImplementedError('Cannot get the filename of a web attachment.') - def save(self, **_) -> None: - raise NotImplementedError('Cannot save a web attachment.') + def save(self, **kwargs) -> None: + """ + Raises a NotImplementedError unless :param skipNotImplemented: is set to + True. If it is, returns None to signify the attachment was skipped. This + allows for the easy implementation of the option to skip this type of + attachment. + """ + if not kwargs.get('skipNotImplemented', False): + raise NotImplementedError('Web attachments cannot be saved.') + @property def data(self) -> None: From 5f51a79756f84451f20ba64d606f5b219e91d423 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Sun, 18 Jun 2023 14:06:20 -0700 Subject: [PATCH 39/89] Added a way for the custom handler to return obj --- .../custom_att_handler/custom_handler.py | 14 ++++++++++++-- .../custom_att_handler/outlook_image_dib.py | 4 ++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/extract_msg/attachments/custom_att_handler/custom_handler.py b/extract_msg/attachments/custom_att_handler/custom_handler.py index 40fe75f8..69419f85 100644 --- a/extract_msg/attachments/custom_att_handler/custom_handler.py +++ b/extract_msg/attachments/custom_att_handler/custom_handler.py @@ -53,8 +53,7 @@ def data(self) -> bytes: """ Gets the data for the attachment. - If an attachment should do nothing when saving, return None from this - property. + If an attachment should do nothing when saving, returns None. """ @property @@ -63,3 +62,14 @@ def name(self) -> Optional[str]: """ Returns the name to be used when saving the attachment. """ + + @property + @abc.abstractmethod + def obj(self) -> Optional[object]: + """ + Returns an object representing the data. May return the same as + :property data:. + + If there is no object to represent the custom attachment, including + bytes, returns None. + """ \ No newline at end of file diff --git a/extract_msg/attachments/custom_att_handler/outlook_image_dib.py b/extract_msg/attachments/custom_att_handler/outlook_image_dib.py index 73a00abf..986e63ab 100644 --- a/extract_msg/attachments/custom_att_handler/outlook_image_dib.py +++ b/extract_msg/attachments/custom_att_handler/outlook_image_dib.py @@ -129,6 +129,10 @@ def name(self) -> str: name = f'attachment {int(self.attachment.dir[-8:], 16)}' return name + '.bmp' + @property + def obj(self) -> bytes: + return self.data + registerHandler(OutlookImageDIB) From b271a2200e7b715e03070afdf3f3f5f3ae16e827 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Tue, 20 Jun 2023 13:50:31 -0700 Subject: [PATCH 40/89] Correct code for unwrapMsg --- extract_msg/utils.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/extract_msg/utils.py b/extract_msg/utils.py index d51b4c4b..4695a385 100644 --- a/extract_msg/utils.py +++ b/extract_msg/utils.py @@ -1025,9 +1025,9 @@ def unwrapMsg(msg : MSGFile) -> Dict: for att in currentItem.attachments: # If it is a regular attachment, add it to the list. Otherwise, add # it to be processed - if att.type in (AttachmentType.DATA, AttachmentType.SIGNED): + if att.type not in (AttachmentType.MSG, AttachmentType.SIGNED_EMBEDDED): attachments.append(att) - elif att.type is AttachmentType.MSG: + elif: # Here we do two things. The first is we store it to the output # so we can return it. The second is we add it to the processing # list. The reason this is two steps is because we need to be From 63f4a053e37f741a7972fc2cb06a532fe679ecfd Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Tue, 20 Jun 2023 13:50:51 -0700 Subject: [PATCH 41/89] Fix typo in utils.py --- extract_msg/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extract_msg/utils.py b/extract_msg/utils.py index 4695a385..556a3fc2 100644 --- a/extract_msg/utils.py +++ b/extract_msg/utils.py @@ -1027,7 +1027,7 @@ def unwrapMsg(msg : MSGFile) -> Dict: # it to be processed if att.type not in (AttachmentType.MSG, AttachmentType.SIGNED_EMBEDDED): attachments.append(att) - elif: + else: # Here we do two things. The first is we store it to the output # so we can return it. The second is we add it to the processing # list. The reason this is two steps is because we need to be From b36e0bad3240564218ad7677a4feb93196ba4287 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Tue, 20 Jun 2023 15:07:34 -0700 Subject: [PATCH 42/89] Deprecate ignoreRtfDeErrors open option --- CHANGELOG.md | 1 + extract_msg/__main__.py | 4 ++-- extract_msg/enums.py | 7 +++++-- extract_msg/msg_classes/message_base.py | 16 +++++++++++----- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f654124..97856987 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ * Entirely reoganized the way attachments are initialized, including the class that will be used in various circumstances. Embedded MSG files, custom attachments, and web attachments will all use dedicated classes that are subclasses of AttachmentBase. * With this change, the way to specify a new Attachment class is to override the function used when creating attachments. This can be done by passing `attachmentInit = myFunction` as an option to `openMsg`. This function MUST return an instance of AttachmentBase. * Added first implementation of web attachments. Saving is not currently possible, but basic relevent property access is now possible. Saving will not be stopped by this attachment if `skipNotImplemented = True` is passed to the save function. +* Changed the option to suppress RTFDE errors to fall under the `ErrorBehavior` enum. Usage of the original option will be allowable, but is being marked as deprecated. However, it is still a dedicated option from the command line. **v0.41.5** * Fixed an issue from version `0.41.3` where the header being present but missing the `From` field would cause an exception. diff --git a/extract_msg/__main__.py b/extract_msg/__main__.py index e148690e..ac29a6d3 100644 --- a/extract_msg/__main__.py +++ b/extract_msg/__main__.py @@ -65,13 +65,13 @@ def main() -> None: } openKwargs = { - 'ignoreRtfDeErrors': args.ignoreRtfDeErrors, + 'errorBehavior': ErrorBehavior.RTFDE if args.ignoreRtfDeErrors else ErrorBehavior.THROW, } # If we are skipping the NotImplementedError attachments, we need to # suppress the error. if args.skipNotImplemented: - openKwargs['errorBehavior'] = ErrorBehavior.ATTACH_NOT_IMPLEMENTED + openKwargs['errorBehavior'] |= ErrorBehavior.ATTACH_NOT_IMPLEMENTED def strSanitize(inp): """ diff --git a/extract_msg/enums.py b/extract_msg/enums.py index fa501b4c..a9492401 100644 --- a/extract_msg/enums.py +++ b/extract_msg/enums.py @@ -519,14 +519,17 @@ class ErrorBehavior(enum.IntFlag): ATTACH_BROKEN: Silence the exception for broken attachments. ATTACH_SUPPRESS_ALL: Silence the exception for NotImplementedError and for broken attachments. - STANDARDS_VIOLATION + STANDARDS_VIOLATION: Silences StandardViolationError where acceptable. + RTFDE: Silences errors from RTFDE. + SUPPRESS_ALL: Silences all of the above. """ THROW = 0b000 ATTACH_NOT_IMPLEMENTED = 0b001 ATTACH_BROKEN = 0b010 ATTACH_SUPPRESS_ALL = 0b011 STANDARDS_VIOLATION = 0b100 - SUPPRESS_ALL = 0b111 + RTFDE = 0b1000 + SUPPRESS_ALL = 0b1111 diff --git a/extract_msg/msg_classes/message_base.py b/extract_msg/msg_classes/message_base.py index 741c93a4..1b00f66b 100644 --- a/extract_msg/msg_classes/message_base.py +++ b/extract_msg/msg_classes/message_base.py @@ -30,7 +30,7 @@ from .. import constants from .._rtf.create_doc import createDocument from .._rtf.inject_rtf import injectStartRTF -from ..enums import BodyTypes, DeencapType, RecipientType +from ..enums import BodyTypes, DeencapType, ErrorBehavior, RecipientType from ..exceptions import ( DataNotFoundError, DeencapMalformedData, DeencapNotEncapsulated, IncompatibleOptionsError, WKError @@ -81,8 +81,6 @@ def __init__(self, path, **kwargs): event of an error when parsing the attachments. :param recipientSeparator: Optional, separator string to use between recipients. - :param ignoreRtfDeErrors: Optional, specifies that any errors that occur - from the usage of RTFDE should be ignored (default: False). :param deencapsulationFunc: Optional, if specified must be a callable that will override the way that HTML/text is deencapsulated from the RTF body. This function must take exactly 2 arguments, the first @@ -95,9 +93,17 @@ def __init__(self, path, **kwargs): internally or they will not be caught. The original deencapsulation method will not run if this is set. """ + if 'ignoreRtfDeErrors' in kwargs is not None: + import warnings + warnings.warn(':param ignoreRtfDeErrors: is deprecated. Use :param ErrorBehavior: instead.', DeprecationWarning) + + if kwargs.get('ignoreRtfDeErrors', False): + errorBehavior = kwargs.get('errorBehavior', ErrorBehavior.THROW) + errorBehavior |= ErrorBehavior.RTFDE + kwargs['errorBehavior'] = errorBehavior + super().__init__(path, **kwargs) self.__recipientSeparator = kwargs.get('recipientSeparator', ';') - self.__ignoreRtfDeErrors = kwargs.get('ignoreRtfDeErrors', False) self.__deencap = kwargs.get('deencapsulationFunc') # Initialize properties in the order that is least likely to cause bugs. # TODO have each function check for initialization of needed data so @@ -998,7 +1004,7 @@ def deencapsulatedRtf(self) -> Optional[RTFDE.DeEncapsulator]: except Exception: # If we are just ignoring the errors, log it then set to # None. Otherwise, continue the exception. - if not self.__ignoreRtfDeErrors: + if not (self.errorBehavior & ErrorBehavior.RTFDE): raise logger.exception('Unhandled error happened while using RTFDE. You have choosen to ignore these errors.') self._deencapsultor = None From cb35add3af5d933d5bbca80bdf7f439f59f674b6 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Tue, 20 Jun 2023 15:07:59 -0700 Subject: [PATCH 43/89] Bump date --- extract_msg/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extract_msg/__init__.py b/extract_msg/__init__.py index bbb02a4e..b94d6d13 100644 --- a/extract_msg/__init__.py +++ b/extract_msg/__init__.py @@ -27,7 +27,7 @@ # along with this program. If not, see . __author__ = 'Destiny Peterson & Matthew Walker' -__date__ = '2023-06-15' +__date__ = '2023-06-20' __version__ = '0.42.0' __all__ = [ From d3b2ef4fdd4cbf09d422d2264e74a084665b67c1 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Tue, 20 Jun 2023 21:46:50 -0700 Subject: [PATCH 44/89] Fixed errors in new attachment code --- extract_msg/attachments/__init__.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/extract_msg/attachments/__init__.py b/extract_msg/attachments/__init__.py index 729917a8..23b978ec 100644 --- a/extract_msg/attachments/__init__.py +++ b/extract_msg/attachments/__init__.py @@ -108,21 +108,23 @@ def initStandardAttachment(msg : MSGFile, dir_) -> AttachmentBase: if (propStore['37050003'].value & 0x7) == 0x7: return WebAttachment(msg, dir_, propStore) + raise NotImplementedError('Could not determine attachment type!') + except (NotImplementedError, UnrecognizedMSGTypeError) as e: if msg.errorBehavior & ErrorBehavior.ATTACH_NOT_IMPLEMENTED: _logger.exception(f'Error processing attachment at {dir_}') - return UnsupportedAttachment(msg, dir_) + return UnsupportedAttachment(msg, dir_, propStore) else: raise except StandardViolationError as e: if msg.errorBehavior & ErrorBehavior.STANDARDS_VIOLATION: _logger.exception(f'Unresolvable standards violation in {dir_}') - return BrokenAttachment(msg, dir_) + return BrokenAttachment(msg, dir_, propStore) else: raise except Exception as e: if msg.errorBehavior & ErrorBehavior.ATTACH_BROKEN: _logger.exception(f'Error processing attachment at {dir_}') - return BrokenAttachment(msg, dir_) + return BrokenAttachment(msg, dir_, propStore) else: raise From 71ccf6bf7b50f53670857c1b4047e51916198fa1 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Tue, 20 Jun 2023 22:55:56 -0700 Subject: [PATCH 45/89] Reorganize and add encoding module --- CHANGELOG.md | 3 + extract_msg/__init__.py | 2 +- extract_msg/attachments/__init__.py | 25 +- extract_msg/attachments/attachment.py | 2 +- extract_msg/attachments/custom_att.py | 2 +- extract_msg/attachments/emb_msg_att.py | 2 +- extract_msg/attachments/web_att.py | 6 +- extract_msg/constants.py | 805 ------------------- extract_msg/constants/__init__.py | 258 ++++++ extract_msg/constants/ps.py | 44 + extract_msg/constants/re.py | 33 + extract_msg/constants/st.py | 126 +++ extract_msg/encoding/__init__.py | 270 +++++++ extract_msg/encoding/_win950_dec.py | 5 + extract_msg/encoding/utils.py | 129 +++ extract_msg/encoding/win950.py | 59 ++ extract_msg/msg_classes/appointment.py | 18 +- extract_msg/msg_classes/calendar.py | 18 +- extract_msg/msg_classes/calendar_base.py | 98 +-- extract_msg/msg_classes/contact.py | 146 ++-- extract_msg/msg_classes/meeting_exception.py | 6 +- extract_msg/msg_classes/meeting_forward.py | 4 +- extract_msg/msg_classes/meeting_related.py | 10 +- extract_msg/msg_classes/meeting_request.py | 18 +- extract_msg/msg_classes/meeting_response.py | 12 +- extract_msg/msg_classes/message_base.py | 10 +- extract_msg/msg_classes/msg.py | 21 +- extract_msg/msg_classes/task.py | 72 +- extract_msg/msg_classes/task_request.py | 2 +- extract_msg/ole_writer.py | 32 +- extract_msg/properties/named.py | 8 +- extract_msg/properties/prop.py | 28 +- extract_msg/properties/properties_store.py | 4 +- extract_msg/structures/_helpers.py | 40 +- extract_msg/structures/business_card.py | 4 +- extract_msg/structures/entry_id.py | 8 +- extract_msg/structures/misc_id.py | 12 +- extract_msg/structures/system_time.py | 4 +- extract_msg/structures/time_zone_struct.py | 2 +- extract_msg/utils.py | 64 +- 40 files changed, 1264 insertions(+), 1148 deletions(-) delete mode 100644 extract_msg/constants.py create mode 100644 extract_msg/constants/__init__.py create mode 100644 extract_msg/constants/ps.py create mode 100644 extract_msg/constants/re.py create mode 100644 extract_msg/constants/st.py create mode 100644 extract_msg/encoding/__init__.py create mode 100644 extract_msg/encoding/_win950_dec.py create mode 100644 extract_msg/encoding/utils.py create mode 100644 extract_msg/encoding/win950.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 97856987..41fc9bf6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ * Changed internal behavior of `MSGFile.attachments`. This should not cause any noticeable changes to the output. * Refactored code significantly to make it more organized. * Changed the exports from the main module to only include an important subset of the module. For other items, you'll have to import the submodule that it falls under to access it. Submodules export all important pieces, so it will be easier to find. + * This includes having many modules be under entirely new paths. Some of these changes have been done with no deprecation, something I generally try to avoid. This is happening at the same time as the public api is significantly changing, which makes it more acceptable. * Fixed `__main__` using the wrong enum for error behavior. * Fixed `Named.get` being severely out of date (it's not used anywhere by the module which is why it wasn't noticed). * Fixed `Named.__getitem__` being entirely case-sensitive. @@ -20,6 +21,8 @@ * With this change, the way to specify a new Attachment class is to override the function used when creating attachments. This can be done by passing `attachmentInit = myFunction` as an option to `openMsg`. This function MUST return an instance of AttachmentBase. * Added first implementation of web attachments. Saving is not currently possible, but basic relevent property access is now possible. Saving will not be stopped by this attachment if `skipNotImplemented = True` is passed to the save function. * Changed the option to suppress RTFDE errors to fall under the `ErrorBehavior` enum. Usage of the original option will be allowable, but is being marked as deprecated. However, it is still a dedicated option from the command line. +* Removed some constants that are not used by the module. +* Added the `encoding` submodule for encoding tasks, including proper support for Microsoft's implementation of cp950. This gets added to the codecs list as windows-950. **v0.41.5** * Fixed an issue from version `0.41.3` where the header being present but missing the `From` field would cause an exception. diff --git a/extract_msg/__init__.py b/extract_msg/__init__.py index b94d6d13..f3da265e 100644 --- a/extract_msg/__init__.py +++ b/extract_msg/__init__.py @@ -61,4 +61,4 @@ from .ole_writer import OleWriter from .open_msg import openMsg, openMsgBulk from .properties import Named, NamedProperties, PropertiesStore -from .recipient import Recipient +from .recipient import Recipient \ No newline at end of file diff --git a/extract_msg/attachments/__init__.py b/extract_msg/attachments/__init__.py index 23b978ec..431166f9 100644 --- a/extract_msg/attachments/__init__.py +++ b/extract_msg/attachments/__init__.py @@ -94,21 +94,30 @@ def initStandardAttachment(msg : MSGFile, dir_) -> AttachmentBase: propStore._propDict['37050003'] = createProp(propData) - # If it is a plain data attachment, create a standard attachment and - # return it. - if msg.exists([dir_, '__substg1.0_37010102']): - return Attachment(msg, dir_, propStore) + attMethod = propStore['3705003'] & 7 + if msg.exists([dir_, '__substg1.0_37010102']): + return Attachment(msg, dir_, propStore) if msg.exists([dir_, '__substg1.0_3701000D']): - if (propStore['37050003'].value & 0x7) != 0x5: + if attMethod != 5: return CustomAttachment(msg, dir_, propStore) else: return EmbeddedMsgAttachment(msg, dir_, propStore) - if (propStore['37050003'].value & 0x7) == 0x7: + if attMethod == 7: return WebAttachment(msg, dir_, propStore) - raise NotImplementedError('Could not determine attachment type!') + # Error handling. + if attMethod == 1: + raise StandardViolationError('Attachments of type data MUST have a data stream.') + if attMethod == 0: + raise NotImplementedError('extract-msg does not support attachments of type afNone.') + if attMethod == 2: + raise NotImplementedError('extract-msg does not support attachments of type afByReference. Contact the developer for support.') + if attMethod == 4: + raise NotImplementedError('extract-msg does not support attachments of type afByReferenceOnly. Contact the developer for support.') + + raise NotImplementedError(f'Could not determine attachment type ({attMethod})!') except (NotImplementedError, UnrecognizedMSGTypeError) as e: if msg.errorBehavior & ErrorBehavior.ATTACH_NOT_IMPLEMENTED: @@ -125,6 +134,6 @@ def initStandardAttachment(msg : MSGFile, dir_) -> AttachmentBase: except Exception as e: if msg.errorBehavior & ErrorBehavior.ATTACH_BROKEN: _logger.exception(f'Error processing attachment at {dir_}') - return BrokenAttachment(msg, dir_, propStore) + return BrokenAttachment(msg, dir_) else: raise diff --git a/extract_msg/attachments/attachment.py b/extract_msg/attachments/attachment.py index 32ffb475..e57cd9a8 100644 --- a/extract_msg/attachments/attachment.py +++ b/extract_msg/attachments/attachment.py @@ -62,7 +62,7 @@ def getFilename(self, **kwargs) -> str: customFilename = str(customFilename) # First we need to validate it. If there are invalid characters, # this will detect it. - if constants.RE_INVALID_FILENAME_CHARACTERS.search(customFilename): + if constants.re.INVALID_FILENAME_CHARACTERS.search(customFilename): raise ValueError('Invalid character found in customFilename. Must not contain any of the following characters: \\/:*?"<>|') filename = customFilename else: diff --git a/extract_msg/attachments/custom_att.py b/extract_msg/attachments/custom_att.py index 0f76d052..536cdf57 100644 --- a/extract_msg/attachments/custom_att.py +++ b/extract_msg/attachments/custom_att.py @@ -57,7 +57,7 @@ def getFilename(self, **kwargs) -> str: customFilename = str(customFilename) # First we need to validate it. If there are invalid characters, # this will detect it. - if constants.RE_INVALID_FILENAME_CHARACTERS.search(customFilename): + if constants.re.INVALID_FILENAME_CHARACTERS.search(customFilename): raise ValueError('Invalid character found in customFilename. Must not contain any of the following characters: \\/:*?"<>|') filename = customFilename else: diff --git a/extract_msg/attachments/emb_msg_att.py b/extract_msg/attachments/emb_msg_att.py index 0e0e1314..d1c31d89 100644 --- a/extract_msg/attachments/emb_msg_att.py +++ b/extract_msg/attachments/emb_msg_att.py @@ -52,7 +52,7 @@ def getFilename(self, **kwargs) -> str: customFilename = str(customFilename) # First we need to validate it. If there are invalid characters, # this will detect it. - if constants.RE_INVALID_FILENAME_CHARACTERS.search(customFilename): + if constants.re.INVALID_FILENAME_CHARACTERS.search(customFilename): raise ValueError('Invalid character found in customFilename. Must not contain any of the following characters: \\/:*?"<>|') return customFilename else: diff --git a/extract_msg/attachments/web_att.py b/extract_msg/attachments/web_att.py index 832c0b8b..fff6fdc4 100644 --- a/extract_msg/attachments/web_att.py +++ b/extract_msg/attachments/web_att.py @@ -43,21 +43,21 @@ def originalPermissionType(self) -> Optional[AttachmentPermissionType]: """ The permission type data associated with a web reference attachment. """ - return self._ensureSetNamed('_oPermissionType', 'AttachmentOriginalPermissionType', constants.PSETID_ATTACHMENT, overrideClass = AttachmentPermissionType, preserveNone = True) + return self._ensureSetNamed('_oPermissionType', 'AttachmentOriginalPermissionType', constants.ps.PSETID_ATTACHMENT, overrideClass = AttachmentPermissionType, preserveNone = True) @property def permissionType(self) -> Optional[AttachmentPermissionType]: """ The permission type data associated with a web reference attachment. """ - return self._ensureSetNamed('_permissionType', 'AttachmentPermissionType', constants.PSETID_ATTACHMENT, overrideClass = AttachmentPermissionType, preserveNone = True) + return self._ensureSetNamed('_permissionType', 'AttachmentPermissionType', constants.ps.PSETID_ATTACHMENT, overrideClass = AttachmentPermissionType, preserveNone = True) @property def providerName(self) -> Optional[str]: """ The type of web service manipulating the attachment. """ - return self._ensureSetNamed('_permissionType', 'AttachmentProviderType', constants.PSETID_ATTACHMENT) + return self._ensureSetNamed('_permissionType', 'AttachmentProviderType', constants.ps.PSETID_ATTACHMENT) @property def type(self) -> AttachmentType: diff --git a/extract_msg/constants.py b/extract_msg/constants.py deleted file mode 100644 index 9b049a90..00000000 --- a/extract_msg/constants.py +++ /dev/null @@ -1,805 +0,0 @@ -""" -The constants used in extract_msg. If you modify any of these -without explicit instruction to do so from one of the -contributers, please do not complain about bugs. -""" - -__all__ = [ - 'CODE_PAGES', 'DEFAULT_CLSID', 'FIXED_LENGTH_PROPS', - 'FIXED_LENGTH_PROPS_STRING', 'HEADER_FORMAT', 'HEADER_FORMAT_TYPE', - 'HEADER_FORMAT_VALUE_TYPE', 'KNOWN_CLASS_TYPES', 'KNOWN_FILE_FLAGS', - 'MAINDOC', 'MULTIPLE_16_BYTES', 'MULTIPLE_16_BYTES_HEX', - 'MULTIPLE_2_BYTES', 'MULTIPLE_2_BYTES_HEX', 'MULTIPLE_4_BYTES', - 'MULTIPLE_4_BYTES_HEX', 'MULTIPLE_8_BYTES', 'MULTIPLE_8_BYTES_HEX', - 'NEEDS_ARG', 'NULL_DATE', 'PROPERTIES', 'PSETID_ADDRESS', 'PSETID_AIRSYNC', - 'PSETID_APPOINTMENT', 'PSETID_ATTACHMENT', 'PSETID_CALENDAR_ASSISTANT', - 'PSETID_COMMON', 'PSETID_LOG', 'PSETID_MEETING', 'PSETID_MESSAGING', - 'PSETID_NOTE', 'PSETID_POSTRSS', 'PSETID_SHARING', 'PSETID_TASK', - 'PSETID_UNIFIEDMESSAGING', 'PSETID_XMLEXTRACTEDENTITIES', - 'PS_INTERNET_HEADERS', 'PS_MAPI', 'PS_PUBLIC_STRINGS', 'PTYPES', - 'PYTPFLOATINGTIME_START', 'RE_BIN', 'RE_HTML_BODY_START', - 'RE_HTML_SAN_SPACE', 'RE_INVALID_FILENAME_CHARACTERS', - 'RE_INVALID_OLE_PATH', 'RE_RTF_ENC_BODY_START', 'ST1', 'ST2', 'ST3', - 'STF32', 'STF64', 'STFIX', 'STI16', 'STI32', 'STI64', 'STI8', 'STMF32', - 'STMF64', 'STMI16', 'STMI32', 'STMI64', 'STNP_ENT', 'STNP_NAM', 'STPEID', - 'STUI32', 'STVAR', 'ST_BC_FIELD_INFO', 'ST_BC_HEAD', 'ST_BE_F32', - 'ST_BE_F64', 'ST_BE_I16', 'ST_BE_I32', 'ST_BE_I64', 'ST_BE_I8', - 'ST_BE_UI16', 'ST_BE_UI32', 'ST_BE_UI64', 'ST_BE_UI8', 'ST_CF_DIR_ENTRY', - 'ST_DATA_UI16', 'ST_DATA_UI32', 'ST_DATA_UI8', 'ST_GUID', 'ST_LE_F32', - 'ST_LE_F64', 'ST_LE_I16', 'ST_LE_I32', 'ST_LE_I64', 'ST_LE_I8', - 'ST_LE_UI16', 'ST_LE_UI32', 'ST_LE_UI64', 'ST_LE_UI8', 'ST_SYSTEMTIME', - 'ST_TZ', 'VARIABLE_LENGTH_PROPS', 'VARIABLE_LENGTH_PROPS_STRING', -] - - -import datetime -import re -import struct - -import ebcdic - -from typing import Dict, Tuple, Union - - -# DEFINE CONSTANTS -# WARNING DO NOT CHANGE ANY OF THESE VALUES UNLESS YOU KNOW -# WHAT YOU ARE DOING! FAILURE TO FOLLOW THIS INSTRUCTION -# CAN AND WILL BREAK THIS SCRIPT! - -# Typing Constants. -HEADER_FORMAT_VALUE_TYPE = Union[str, Tuple[Union[str, None], bool], None] -# Basically a dict of HEADER_FORMAT_TYPE and dicts containing them. -HEADER_FORMAT_TYPE = Dict[str, Union[HEADER_FORMAT_VALUE_TYPE, Dict[str, HEADER_FORMAT_VALUE_TYPE]]] - -# Regular expresion constants. -RE_INVALID_FILENAME_CHARACTERS = re.compile(r'[\\/:*?"<>|]') -# Regular expression to find sections of spaces for htmlSanitize. -RE_HTML_SAN_SPACE = re.compile(' +') -# Regular expression to find the start of the html body. -RE_HTML_BODY_START = re.compile(b']*>') -# Regular expression to find the start of the html body in encapsulated RTF. -# This is used for one of the pattern types that makes life easy. -RE_RTF_ENC_BODY_START = re.compile(br'\{\\\*\\htmltag[0-9]* ?]*>\}') -# This is used in the workaround for decoding issues in RTFDE. We find `\bin` -# sections and try to remove all of them to help with the decoding. -RE_BIN = re.compile(br'\\bin([0-9]+) ?') -# Used in the vaildation of OLE paths. Any of these characters in a name make it -# invalid. -RE_INVALID_OLE_PATH = re.compile(r'[:/\\!]') - -FIXED_LENGTH_PROPS = ( - 0x0000, - 0x0001, - 0x0002, - 0x0003, - 0x0004, - 0x0005, - 0x0006, - 0x0007, - 0x000A, - 0x000B, - 0x0014, - 0x0040, - 0x0048, -) - -FIXED_LENGTH_PROPS_STRING = ( - '0000', - '0001', - '0002', - '0003', - '0004', - '0005', - '0006', - '0007', - '000A', - '000B', - '0014', - '0040', - '0048', -) - -VARIABLE_LENGTH_PROPS = ( - 0x000D, - 0x001E, - 0x001F, - 0x00FB, - 0x00FD, - 0x00FE, - 0X0102, - 0x1002, - 0x1003, - 0x1004, - 0x1005, - 0x1006, - 0x1007, - 0x1014, - 0x101E, - 0x101F, - 0x1040, - 0x1048, - 0x1102, -) - -VARIABLE_LENGTH_PROPS_STRING = ( - '000D', - '001E', - '001F', - '00FB', - '00FD', - '00FE', - '0102', - '1002', - '1003', - '1004', - '1005', - '1006', - '1007', - '1014', - '101E', - '101F', - '1040', - '1048', - '1102', -) - -# Multiple type properties that take up 2 bytes -MULTIPLE_2_BYTES = ( - '1002', -) - -MULTIPLE_2_BYTES_HEX = ( - 0x1002, -) - -# Multiple type properties that take up 4 bytes -MULTIPLE_4_BYTES = ( - '1003', - '1004', -) - -MULTIPLE_4_BYTES_HEX = ( - 0x1003, - 0x1004, -) - -# Multiple type properties that take up 4 bytes -MULTIPLE_8_BYTES = ( - '1005', - '1007', - '1014', - '1040', -) - -MULTIPLE_8_BYTES_HEX = ( - 0x1005, - 0x1007, - 0x1014, - 0x1040, -) - -# Multiple type properties that take up 4 bytes -MULTIPLE_16_BYTES = ( - '1048', -) - -MULTIPLE_16_BYTES_HEX = ( - 0x1048, -) - - -# Used to format the header for saving only the header. -HEADER_FORMAT = """From: {From} -To: {To} -Cc: {Cc} -Bcc: {Bcc} -Subject: {subject} -Date: {Date} -Message-ID: {Message-Id} -""" - - -KNOWN_CLASS_TYPES = ( - 'ipm.activity', - 'ipm.appointment', # [MS-OXOCAL] - 'ipm.contact', # [MS-OXOCNTC] - 'ipm.configuration', # [MS-OXOCFG] - 'ipm.distlist', - 'ipm.document', - 'ipm.ole.class', - 'ipm.outlook.recall', - 'ipm.note', - 'ipm.post', - 'ipm.stickynote', - 'ipm.recall.report', - 'ipm.remote', - 'ipm.report', - 'ipm.resend', - 'ipm.schedule', - 'ipm.task', - 'ipm.taskrequest', - 'report', -) - -# This is a dictionary matching the code page number to it's encoding name. -# The list used to make this can be found here: -# https://docs.microsoft.com/en-us/windows/win32/intl/code-page-identifiers -### TODO: -# Many of these code pages are not supported by Python. As such, we should -# really implement them ourselves to make sure that if someone wants to use an -# msg file with one of those encodings, they are able to. Perhaps we should -# create a seperate module for that? -# Code pages that currently don't have a supported encoding will be preceded by -# `# UNSUPPORTED`. -# For some of these, it is also possible that the name we are trying to find -# them with is not known to Python. I have already confirmed this for a few of -# them, and adjusted their names to ones that python would recognize. It is -# Possible I missed a few. -CODE_PAGES = { - 37: 'IBM037', # IBM EBCDIC US-Canada - 437: 'IBM437', # OEM United States - 500: 'IBM500', # IBM EBCDIC International - 708: 'ASMO-708', # Arabic (ASMO 708) - # UNSUPPORTED. - 709: '', # Arabic (ASMO-449+, BCON V4) - # UNSUPPORTED. - 710: '', # Arabic - Transparent Arabic - # UNSUPPORTED. - 720: 'DOS-720', # Arabic (Transparent ASMO); Arabic (DOS) - 737: 'cp737', # OEM Greek (formerly 437G); Greek (DOS) - 775: 'ibm775', # OEM Baltic; Baltic (DOS) - 850: 'ibm850', # OEM Multilingual Latin 1; Western European (DOS) - 852: 'ibm852', # OEM Latin 2; Central European (DOS) - 855: 'IBM855', # OEM Cyrillic (primarily Russian) - 857: 'ibm857', # OEM Turkish; Turkish (DOS) - 858: 'cp858', # OEM Multilingual Latin 1 + Euro symbol - 860: 'IBM860', # OEM Portuguese; Portuguese (DOS) - 861: 'ibm861', # OEM Icelandic; Icelandic (DOS) - 862: 'cp862', # OEM Hebrew; Hebrew (DOS) - 863: 'IBM863', # OEM French Canadian; French Canadian (DOS) - 864: 'IBM864', # OEM Arabic; Arabic (864) - 865: 'IBM865', # OEM Nordic; Nordic (DOS) - 866: 'cp866', # OEM Russian; Cyrillic (DOS) - 869: 'ibm869', # OEM Modern Greek; Greek, Modern (DOS) - 870: 'cp870', # IBM870 # IBM EBCDIC Multilingual/ROECE (Latin 2); IBM EBCDIC Multilingual Latin 2 - # UNSUPPORTED. - 874: 'windows-874', # ANSI/OEM Thai (ISO 8859-11); Thai (Windows) - 875: 'cp875', # IBM EBCDIC Greek Modern - 932: 'shift_jis', # ANSI/OEM Japanese; Japanese (Shift-JIS) - 936: 'gb2312', # ANSI/OEM Simplified Chinese (PRC, Singapore); Chinese Simplified (GB2312) - 949: 'ks_c_5601-1987', # ANSI/OEM Korean (Unified Hangul Code) - 950: 'big5', # ANSI/OEM Traditional Chinese (Taiwan; Hong Kong SAR, PRC); Chinese Traditional (Big5) - 1026: 'IBM1026', # IBM EBCDIC Turkish (Latin 5) - 1047: 'cp1047', # IBM EBCDIC Latin 1/Open System - 1140: 'cp1140', # IBM EBCDIC US-Canada (037 + Euro symbol); IBM EBCDIC (US-Canada-Euro) - 1141: 'cp1141', # IBM EBCDIC Germany (20273 + Euro symbol); IBM EBCDIC (Germany-Euro) - 1142: 'cp1142', # IBM EBCDIC Denmark-Norway (20277 + Euro symbol); IBM EBCDIC (Denmark-Norway-Euro) - 1143: 'cp1143', # IBM EBCDIC Finland-Sweden (20278 + Euro symbol); IBM EBCDIC (Finland-Sweden-Euro) - 1144: 'cp1144', # IBM EBCDIC Italy (20280 + Euro symbol); IBM EBCDIC (Italy-Euro) - 1145: 'cp1145', # IBM EBCDIC Latin America-Spain (20284 + Euro symbol); IBM EBCDIC (Spain-Euro) - 1146: 'cp1146', # IBM EBCDIC United Kingdom (20285 + Euro symbol); IBM EBCDIC (UK-Euro) - 1147: 'cp1147', # IBM EBCDIC France (20297 + Euro symbol); IBM EBCDIC (France-Euro) - 1148: 'cp1148ms', # IBM EBCDIC International (500 + Euro symbol); IBM EBCDIC (International-Euro) - 1149: 'cp1149', # IBM EBCDIC Icelandic (20871 + Euro symbol); IBM EBCDIC (Icelandic-Euro) - 1200: 'utf-16-le', # Unicode UTF-16, little endian byte order (BMP of ISO 10646); available only to managed applications - 1201: 'utf-16-be', # Unicode UTF-16, big endian byte order; available only to managed applications - 1250: 'windows-1250', # ANSI Central European; Central European (Windows) - 1251: 'windows-1251', # ANSI Cyrillic; Cyrillic (Windows) - 1252: 'windows-1252', # ANSI Latin 1; Western European (Windows) - 1253: 'windows-1253', # ANSI Greek; Greek (Windows) - 1254: 'windows-1254', # ANSI Turkish; Turkish (Windows) - 1255: 'windows-1255', # ANSI Hebrew; Hebrew (Windows) - 1256: 'windows-1256', # ANSI Arabic; Arabic (Windows) - 1257: 'windows-1257', # ANSI Baltic; Baltic (Windows) - 1258: 'windows-1258', # ANSI/OEM Vietnamese; Vietnamese (Windows) - 1361: 'Johab', # Korean (Johab) - 10000: 'macintosh', # MAC Roman; Western European (Mac) - 10001: 'x-mac-japanese', # Japanese (Mac) - # UNSUPPORTED. - 10002: 'x-mac-chinesetrad', # MAC Traditional Chinese (Big5); Chinese Traditional (Mac) - 10003: 'x-mac-korean', # Korean (Mac) - # UNSUPPORTED. - 10004: 'x-mac-arabic', # Arabic (Mac) - # UNSUPPORTED. - 10005: 'x-mac-hebrew', # Hebrew (Mac) - # UNSUPPORTED. - 10006: 'x-mac-greek', # Greek (Mac) - # UNSUPPORTED. - 10007: 'x-mac-cyrillic', # Cyrillic (Mac) - # UNSUPPORTED. - 10008: 'x-mac-chinesesimp', # MAC Simplified Chinese (GB 2312); Chinese Simplified (Mac) - # UNSUPPORTED. - 10010: 'x-mac-romanian', # Romanian (Mac) - # UNSUPPORTED. - 10017: 'x-mac-ukrainian', # Ukrainian (Mac) - # UNSUPPORTED. - 10021: 'x-mac-thai', # Thai (Mac) - # UNSUPPORTED. - 10029: 'x-mac-ce', # MAC Latin 2; Central European (Mac) - # UNSUPPORTED. - 10079: 'x-mac-icelandic', # Icelandic (Mac) - # UNSUPPORTED. - 10081: 'x-mac-turkish', # Turkish (Mac) - # UNSUPPORTED. - 10082: 'x-mac-croatian', # Croatian (Mac) - 12000: 'utf-32', # Unicode UTF-32, little endian byte order; available only to managed applications - 12001: 'utf-32BE', # Unicode UTF-32, big endian byte order; available only to managed applications - # UNSUPPORTED. - 20000: 'x-Chinese_CNS', # CNS Taiwan; Chinese Traditional (CNS) - # UNSUPPORTED. - 20001: 'x-cp20001', # TCA Taiwan - # UNSUPPORTED. - 20002: 'x_Chinese-Eten', # Eten Taiwan; Chinese Traditional (Eten) - # UNSUPPORTED. - 20003: 'x-cp20003', # IBM5550 Taiwan - # UNSUPPORTED. - 20004: 'x-cp20004', # TeleText Taiwan - # UNSUPPORTED. - 20005: 'x-cp20005', # Wang Taiwan - # UNSUPPORTED. - 20105: 'x-IA5', # IA5 (IRV International Alphabet No. 5, 7-bit); Western European (IA5) - # UNSUPPORTED. - 20106: 'x-IA5-German', # IA5 German (7-bit) - # UNSUPPORTED. - 20107: 'x-IA5-Swedish', # IA5 Swedish (7-bit) - # UNSUPPORTED. - 20108: 'x-IA5-Norwegian', # IA5 Norwegian (7-bit) - 20127: 'us-ascii', # US-ASCII (7-bit) - # UNSUPPORTED. - 20261: 'x-cp20261', # T.61 - # UNSUPPORTED. - 20269: 'x-cp20269', # ISO 6937 Non-Spacing Accent - 20273: 'IBM273', # IBM EBCDIC Germany - 20277: 'cp277', # IBM EBCDIC Denmark-Norway - 20278: 'cp278', # IBM EBCDIC Finland-Sweden - 20280: 'cp280', # IBM EBCDIC Italy - 20284: 'cp284', # IBM EBCDIC Latin America-Spain - 20285: 'cp285', # IBM EBCDIC United Kingdom - 20290: 'cp290', # IBM EBCDIC Japanese Katakana Extended - 20297: 'cp297', # IBM EBCDIC France - 20420: 'cp420', # IBM EBCDIC Arabic - # UNSUPPORTED. - 20423: 'IBM423', # IBM EBCDIC Greek - 20424: 'IBM424', # IBM EBCDIC Hebrew - 20833: 'cp833', # IBM EBCDIC Korean Extended - 20838: 'cp838', # IBM EBCDIC Thai - 20866: 'koi8-r', # Russian (KOI8-R); Cyrillic (KOI8-R) - 20871: 'cp871', # IBM EBCDIC Icelandic - # UNSUPPORTED. - 20880: 'IBM880', # IBM EBCDIC Cyrillic Russian - # UNSUPPORTED. - 20905: 'IBM905', # IBM EBCDIC Turkish - # UNSUPPORTED. - 20924: 'IBM00924', # IBM EBCDIC Latin 1/Open System (1047 + Euro symbol) - 20932: 'EUC-JP', # Japanese (JIS 0208-1990 and 0212-1990) - # UNSUPPORTED. - 20936: 'x-cp20936', # Simplified Chinese (GB2312); Chinese Simplified (GB2312-80) - # UNSUPPORTED. - 20949: 'x-cp20949', # Korean Wansung - 21025: 'cp1025', # IBM EBCDIC Cyrillic Serbian-Bulgarian - # UNSUPPORTED. - 21027: '', # (deprecated) - 21866: 'koi8-u', # Ukrainian (KOI8-U); Cyrillic (KOI8-U) - 28591: 'iso-8859-1', # ISO 8859-1 Latin 1; Western European (ISO) - 28592: 'iso-8859-2', # ISO 8859-2 Central European; Central European (ISO) - 28593: 'iso-8859-3', # ISO 8859-3 Latin 3 - 28594: 'iso-8859-4', # ISO 8859-4 Baltic - 28595: 'iso-8859-5', # ISO 8859-5 Cyrillic - 28596: 'iso-8859-6', # ISO 8859-6 Arabic - 28597: 'iso-8859-7', # ISO 8859-7 Greek - 28598: 'iso-8859-8', # ISO 8859-8 Hebrew; Hebrew (ISO-Visual) - 28599: 'iso-8859-9', # ISO 8859-9 Turkish - 28603: 'iso-8859-13', # ISO 8859-13 Estonian - 28605: 'iso-8859-15', # ISO 8859-15 Latin 9 - # UNSUPPORTED. - 29001: 'x-Europa', # Europa 3 - # UNSUPPORTED. - 38598: 'iso-8859-8-i', # ISO 8859-8 Hebrew; Hebrew (ISO-Logical) - 50220: 'iso-2022-jp', # ISO 2022 Japanese with no halfwidth Katakana; Japanese (JIS) - 50221: 'csISO2022JP', # ISO 2022 Japanese with halfwidth Katakana; Japanese (JIS-Allow 1 byte Kana) - 50222: 'iso-2022-jp', # ISO 2022 Japanese JIS X 0201-1989; Japanese (JIS-Allow 1 byte Kana - SO/SI) - 50225: 'iso-2022-kr', # ISO 2022 Korean - # UNSUPPORTED. - 50227: 'x-cp50227', # ISO 2022 Simplified Chinese; Chinese Simplified (ISO 2022) - # UNSUPPORTED. - 50229: '', # ISO 2022 Traditional Chinese - # UNSUPPORTED. - 50930: '', # EBCDIC Japanese (Katakana) Extended - # UNSUPPORTED. - 50931: '', # EBCDIC US-Canada and Japanese - # UNSUPPORTED. - 50933: '', # EBCDIC Korean Extended and Korean - # UNSUPPORTED. - 50935: '', # EBCDIC Simplified Chinese Extended and Simplified Chinese - # UNSUPPORTED. - 50936: '', # EBCDIC Simplified Chinese - # UNSUPPORTED. - 50937: '', # EBCDIC US-Canada and Traditional Chinese - # UNSUPPORTED. - 50939: '', # EBCDIC Japanese (Latin) Extended and Japanese - 51932: 'euc-jp', # EUC Japanese - 51936: 'EUC-CN', # EUC Simplified Chinese; Chinese Simplified (EUC) - 51949: 'euc-kr', # EUC Korean - # UNSUPPORTED. - 51950: '', # EUC Traditional Chinese - 52936: 'hz-gb-2312', # HZ-GB2312 Simplified Chinese; Chinese Simplified (HZ) - 54936: 'GB18030', # Windows XP and later: GB18030 Simplified Chinese (4 byte); Chinese Simplified (GB18030) - # UNSUPPORTED. - 57002: 'x-iscii-de', # ISCII Devanagari - # UNSUPPORTED. - 57003: 'x-iscii-be', # ISCII Bangla - # UNSUPPORTED. - 57004: 'x-iscii-ta', # ISCII Tamil - # UNSUPPORTED. - 57005: 'x-iscii-te', # ISCII Telugu - # UNSUPPORTED. - 57006: 'x-iscii-as', # ISCII Assamese - # UNSUPPORTED. - 57007: 'x-iscii-or', # ISCII Odia - # UNSUPPORTED. - 57008: 'x-iscii-ka', # ISCII Kannada - # UNSUPPORTED. - 57009: 'x-iscii-ma', # ISCII Malayalam - # UNSUPPORTED. - 57010: 'x-iscii-gu', # ISCII Gujarati - # UNSUPPORTED. - 57011: 'x-iscii-pa', # ISCII Punjabi - 65000: 'utf-7', # Unicode (UTF-7) - 65001: 'utf-8', # Unicode (UTF-8) -} - -PYTPFLOATINGTIME_START = datetime.datetime(1899, 12, 30) -NULL_DATE = datetime.datetime(4500, 8, 31, 23, 59) - -# Constants used for argparse stuff -KNOWN_FILE_FLAGS = ( - '--out-name', -) -NEEDS_ARG = ( - '--out-name', -) -MAINDOC = "extract_msg:\n\tExtracts emails and attachments saved in Microsoft Outlook's .msg files.\n\n" \ - "https://github.com/TeamMsgExtractor/msg-extractor" - -# Default class ID for the root entry for OleWriter. This should be -# referencing Outlook if I understand it correctly. -DEFAULT_CLSID = b'\x0b\r\x02\x00\x00\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x00F' - -# Define pre-compiled structs to make unpacking slightly faster. -# General structs. -ST1 = struct.Struct('<8x4I') -ST2 = struct.Struct('b') -ST_BE_I16 = struct.Struct('>h') -ST_BE_I32 = struct.Struct('>i') -ST_BE_I64 = struct.Struct('>q') -ST_BE_UI8 = struct.Struct('>B') -ST_BE_UI16 = struct.Struct('>H') -ST_BE_UI32 = struct.Struct('>I') -ST_BE_UI64 = struct.Struct('>Q') -ST_BE_F32 = struct.Struct('>f') -ST_BE_F64 = struct.Struct('>d') - -PTYPES = { - 0x0000: 'PtypUnspecified', - 0x0001: 'PtypNull', - 0x0002: 'PtypInteger16', # Signed short - 0x0003: 'PtypInteger32', # Signed int - 0x0004: 'PtypFloating32', # Float - 0x0005: 'PtypFloating64', # Double - 0x0006: 'PtypCurrency', - 0x0007: 'PtypFloatingTime', - 0x000A: 'PtypErrorCode', - 0x000B: 'PtypBoolean', - 0x000D: 'PtypObject/PtypEmbeddedTable/Storage', - 0x0014: 'PtypInteger64', # Signed longlong - 0x001E: 'PtypString8', - 0x001F: 'PtypString', - 0x0040: 'PtypTime', # Use filetimeToUtc to convert to unix time stamp - 0x0048: 'PtypGuid', - 0x00FB: 'PtypServerId', - 0x00FD: 'PtypRestriction', - 0x00FE: 'PtypRuleAction', - 0x0102: 'PtypBinary', - 0x1002: 'PtypMultipleInteger16', - 0x1003: 'PtypMultipleInteger32', - 0x1004: 'PtypMultipleFloating32', - 0x1005: 'PtypMultipleFloating64', - 0x1006: 'PtypMultipleCurrency', - 0x1007: 'PtypMultipleFloatingTime', - 0x1014: 'PtypMultipleInteger64', - 0x101E: 'PtypMultipleString8', - 0x101F: 'PtypMultipleString', - 0x1040: 'PtypMultipleTime', - 0x1048: 'PtypMultipleGuid', - 0x1102: 'PtypMultipleBinary', -} - -# This property information was sourced from -# http://www.fileformat.info/format/outlookmsg/index.htm -# on 2013-07-22. -# It was extended by The Elemental of Destruction on 2018-10-12. -PROPERTIES = { - '00010102': 'Template data', - '0002000B': 'Alternate recipient allowed', - '0004001F': 'Auto forward comment', - '00040102': 'Script data', - '0005000B': 'Auto forwarded', - '000F000F': 'Deferred delivery time', - '00100040': 'Deliver time', - '00150040': 'Expiry time', - '00170003': 'Importance', - '001A001F': 'Message class', - '0023001F': 'Originator delivery report requested', - '00250102': 'Parent key', - '00260003': 'Priority', - '0029000B': 'Read receipt requested', - '002A0040': 'Receipt time', - '002B000B': 'Recipient reassignment prohibited', - '002E0003': 'Original sensitivity', - '00300040': 'Reply time', - '00310102': 'Report tag', - '00320040': 'Report time', - '00360003': 'Sensitivity', - '0037001F': 'Subject', - '00390040': 'Client Submit Time', - '003A001F': '', - '003B0102': '', - '003D001F': 'Subject prefix', - '003F0102': '', - '0040001F': 'Received by name', - '00410102': '', - '0042001F': 'Sent repr name', - '00430102': '', - '0044001F': 'Rcvd repr name', - '00450102': '', - '0046001F': '', - '00470102': '', - '0049001F': '', - '004B001F': '', - '004C0102': '', - '004D001F': 'Org author name', - '004E0040': '', - '004F0102': '', - '0050001F': 'Reply rcipnt names', - '00510102': '', - '00520102': '', - '00530102': '', - '00540102': '', - '00550040': '', - '0057000B': '', - '0058000B': '', - '0059000B': '', - '005A001F': 'Org sender name', - '005B0102': '', - '005C0102': '', - '005D001F': '', - '005E0102': '', - '005F0102': '', - '00600040': '', - '00610040': '', - '00620003': '', - '0063000B': '', - '0064001F': 'Sent repr adrtype', - '0065001F': 'Sent repr email', - '0066001F': '', - '00670102': '', - '0068001F': '', - '0069001F': '', - '0070001F': 'Topic', - '00710102': '', - '0072001F': '', - '0073001F': '', - '0074001F': '', - '0075001F': 'Rcvd by adrtype', - '0076001F': 'Rcvd by email', - '0077001F': 'Repr adrtype', - '0078001F': 'Repr email', - '007D001F': 'Message header', - '007F0102': '', - '0080001F': '', - '0081001F': '', - '08070003': '', - '0809001F': '', - '0C040003': '', - '0C050003': '', - '0C06000B': '', - '0C08000B': '', - '0C150003': '', - '0C17000B': '', - '0C190102': '', - '0C1A001F': 'Sender name', - '0C1B001F': '', - '0C1D0102': '', - '0C1E001F': 'Sender adr type', - '0C1F001F': 'Sender email', - '0C200003': '', - '0C21001F': '', - '0E01000B': '', - '0E02001F': 'Display BCC', - '0E03001F': 'Display CC', - '0E04001F': 'Display To', - '0E060040': '', - '0E070003': '', - '0E080003': '', - '0E080014': '', - '0E090102': '', - '0E0F000B': '', - '0E12000D': '', - '0E13000D': '', - '0E170003': '', - '0E1B000B': '', - '0E1D001F': 'Subject (normalized)', - '0E1F000B': '', - '0E200003': '', - '0E210003': '', - '0E28001F': 'Recvd account1 (uncertain)', - '0E29001F': 'Recvd account2 (uncertain)', - '1000001F': 'Message body', - '1008': 'RTF sync body tag', # Where did this come from ??? It's not listed in the docs - '10090102': 'Compressed RTF body', - '1013001F': 'HTML body', - '1035001F': 'Message ID (uncertain)', - '1046001F': 'Sender email (uncertain)', - '3001001F': 'Display name', - '3002001F': 'Address type', - '3003001F': 'Email address', - '30070040': 'Creation date', - '39FE001F': '7-bit email (uncertain)', - '39FF001F': '7-bit display name', - - # Attachments (37xx) - '37010102': 'Attachment data', - '37020102': '', - '3703001F': 'Attachment extension', - '3704001F': 'Attachment short filename', - '37050003': 'Attachment attach method', - '3707001F': 'Attachment long filename', - '370E001F': 'Attachment mime tag', - '3712001F': 'Attachment ID (uncertain)', - - # Address book (3Axx): - '3A00001F': 'Account', - '3A02001F': 'Callback phone no', - '3A05001F': 'Generation', - '3A06001F': 'Given name', - '3A08001F': 'Business phone', - '3A09001F': 'Home phone', - '3A0A001F': 'Initials', - '3A0B001F': 'Keyword', - '3A0C001F': 'Language', - '3A0D001F': 'Location', - '3A11001F': 'Surname', - '3A15001F': 'Postal address', - '3A16001F': 'Company name', - '3A17001F': 'Title', - '3A18001F': 'Department', - '3A19001F': 'Office location', - '3A1A001F': 'Primary phone', - '3A1B101F': 'Business phone 2', - '3A1C001F': 'Mobile phone', - '3A1D001F': 'Radio phone no', - '3A1E001F': 'Car phone no', - '3A1F001F': 'Other phone', - '3A20001F': 'Transmit dispname', - '3A21001F': 'Pager', - '3A220102': 'User certificate', - '3A23001F': 'Primary Fax', - '3A24001F': 'Business Fax', - '3A25001F': 'Home Fax', - '3A26001F': 'Country', - '3A27001F': 'Locality', - '3A28001F': 'State/Province', - '3A29001F': 'Street address', - '3A2A001F': 'Postal Code', - '3A2B001F': 'Post Office Box', - '3A2C001F': 'Telex', - '3A2D001F': 'ISDN', - '3A2E001F': 'Assistant phone', - '3A2F001F': 'Home phone 2', - '3A30001F': 'Assistant', - '3A44001F': 'Middle name', - '3A45001F': 'Dispname prefix', - '3A46001F': 'Profession', - '3A47001F': '', - '3A48001F': 'Spouse name', - '3A4B001F': 'TTYTTD radio phone', - '3A4C001F': 'FTP site', - '3A4E001F': 'Manager name', - '3A4F001F': 'Nickname', - '3A51001F': 'Business homepage', - '3A57001F': 'Company main phone', - '3A58101F': 'Childrens names', - '3A59001F': 'Home City', - '3A5A001F': 'Home Country', - '3A5B001F': 'Home Postal Code', - '3A5C001F': 'Home State/Provnce', - '3A5D001F': 'Home Street', - '3A5F001F': 'Other adr City', - '3A60': 'Other adr Country', - '3A61': 'Other adr PostCode', - '3A62': 'Other adr Province', - '3A63': 'Other adr Street', - '3A64': 'Other adr PO box', - - '3FF7': 'Server (uncertain)', - '3FF8': 'Creator1 (uncertain)', - '3FFA': 'Creator2 (uncertain)', - '3FFC': 'To email (uncertain)', - '403D': 'To adrtype (uncertain)', - '403E': 'To email (uncertain)', - '5FF6': 'To (uncertain)', -} - -PS_MAPI = '{00020328-0000-0000-C000-000000000046}' -PS_PUBLIC_STRINGS = '{00020329-0000-0000-C000-000000000046}' -PSETID_COMMON = '{00062008-0000-0000-C000-000000000046}' -PSETID_ADDRESS = '{00062004-0000-0000-C000-000000000046}' -PS_INTERNET_HEADERS = '{00020386-0000-0000-C000-000000000046}' -PSETID_APPOINTMENT = '{00062002-0000-0000-C000-000000000046}' -PSETID_MEETING = '{6ED8DA90-450B-101B-98DA-00AA003F1305}' -PSETID_LOG = '{0006200A-0000-0000-C000-000000000046}' -PSETID_MESSAGING = '{41F28F13-83F4-4114-A584-EEDB5A6B0BFF}' -PSETID_NOTE = '{0006200E-0000-0000-C000-000000000046}' -PSETID_POSTRSS = '{00062041-0000-0000-C000-000000000046}' -PSETID_TASK = '{00062003-0000-0000-C000-000000000046}' -PSETID_UNIFIEDMESSAGING = '{4442858E-A9E3-4E80-B900-317A210CC15B}' -PSETID_AIRSYNC = '{71035549-0739-4DCB-9163-00F0580DBBDF}' -PSETID_SHARING = '{00062040-0000-0000-C000-000000000046}' -PSETID_XMLEXTRACTEDENTITIES = '{23239608-685D-4732-9C55-4C95CB4E8E33}' -PSETID_ATTACHMENT = '{96357F7F-59E1-47D0-99A7-46515C183B54}' -PSETID_CALENDAR_ASSISTANT = '{11000E07-B51B-40D6-AF21-CAA85EDAB1D0}' - -# END CONSTANTS diff --git a/extract_msg/constants/__init__.py b/extract_msg/constants/__init__.py new file mode 100644 index 00000000..1fe4f5e1 --- /dev/null +++ b/extract_msg/constants/__init__.py @@ -0,0 +1,258 @@ +""" +The constants used in extract_msg. If you modify any of these without explicit +instruction to do so from one of the contributers, please do not complain about +bugs. +""" + +__all__ = [ + # Modules. + 'ps', + 're', + 'st', + + # Constants. + 'DEFAULT_CLSID', + 'FIXED_LENGTH_PROPS', + 'FIXED_LENGTH_PROPS_STRING', + 'HEADER_FORMAT', + 'HEADER_FORMAT_TYPE', + 'HEADER_FORMAT_VALUE_TYPE', + 'KNOWN_CLASS_TYPES', + 'KNOWN_FILE_FLAGS', + 'MAINDOC', + 'MULTIPLE_16_BYTES', + 'MULTIPLE_16_BYTES_HEX', + 'MULTIPLE_2_BYTES', + 'MULTIPLE_2_BYTES_HEX', + 'MULTIPLE_4_BYTES', + 'MULTIPLE_4_BYTES_HEX', + 'MULTIPLE_8_BYTES', + 'MULTIPLE_8_BYTES_HEX', + 'NEEDS_ARG', + 'NULL_DATE', + 'PTYPES', + 'PYTPFLOATINGTIME_START', 'VARIABLE_LENGTH_PROPS', 'VARIABLE_LENGTH_PROPS_STRING', +] + + +import datetime + +from typing import Dict, Tuple, Union + +from . import ps, re, st + + +# Typing Constants. +HEADER_FORMAT_VALUE_TYPE = Union[str, Tuple[Union[str, None], bool], None] +# Basically a dict of HEADER_FORMAT_TYPE and dicts containing them. +HEADER_FORMAT_TYPE = Dict[str, Union[HEADER_FORMAT_VALUE_TYPE, Dict[str, HEADER_FORMAT_VALUE_TYPE]]] + + + +FIXED_LENGTH_PROPS = ( + 0x0000, + 0x0001, + 0x0002, + 0x0003, + 0x0004, + 0x0005, + 0x0006, + 0x0007, + 0x000A, + 0x000B, + 0x0014, + 0x0040, + 0x0048, +) + +FIXED_LENGTH_PROPS_STRING = ( + '0000', + '0001', + '0002', + '0003', + '0004', + '0005', + '0006', + '0007', + '000A', + '000B', + '0014', + '0040', + '0048', +) + +VARIABLE_LENGTH_PROPS = ( + 0x000D, + 0x001E, + 0x001F, + 0x00FB, + 0x00FD, + 0x00FE, + 0X0102, + 0x1002, + 0x1003, + 0x1004, + 0x1005, + 0x1006, + 0x1007, + 0x1014, + 0x101E, + 0x101F, + 0x1040, + 0x1048, + 0x1102, +) + +VARIABLE_LENGTH_PROPS_STRING = ( + '000D', + '001E', + '001F', + '00FB', + '00FD', + '00FE', + '0102', + '1002', + '1003', + '1004', + '1005', + '1006', + '1007', + '1014', + '101E', + '101F', + '1040', + '1048', + '1102', +) + +# Multiple type properties that take up 2 bytes +MULTIPLE_2_BYTES = ( + '1002', +) + +MULTIPLE_2_BYTES_HEX = ( + 0x1002, +) + +# Multiple type properties that take up 4 bytes +MULTIPLE_4_BYTES = ( + '1003', + '1004', +) + +MULTIPLE_4_BYTES_HEX = ( + 0x1003, + 0x1004, +) + +# Multiple type properties that take up 4 bytes +MULTIPLE_8_BYTES = ( + '1005', + '1007', + '1014', + '1040', +) + +MULTIPLE_8_BYTES_HEX = ( + 0x1005, + 0x1007, + 0x1014, + 0x1040, +) + +# Multiple type properties that take up 4 bytes +MULTIPLE_16_BYTES = ( + '1048', +) + +MULTIPLE_16_BYTES_HEX = ( + 0x1048, +) + + +# Used to format the header for saving only the header. +HEADER_FORMAT = """From: {From} +To: {To} +Cc: {Cc} +Bcc: {Bcc} +Subject: {subject} +Date: {Date} +Message-ID: {Message-Id} +""" + + +KNOWN_CLASS_TYPES = ( + 'ipm.activity', + 'ipm.appointment', # [MS-OXOCAL] + 'ipm.contact', # [MS-OXOCNTC] + 'ipm.configuration', # [MS-OXOCFG] + 'ipm.distlist', + 'ipm.document', + 'ipm.ole.class', + 'ipm.outlook.recall', + 'ipm.note', + 'ipm.post', + 'ipm.stickynote', + 'ipm.recall.report', + 'ipm.remote', + 'ipm.report', + 'ipm.resend', + 'ipm.schedule', + 'ipm.task', + 'ipm.taskrequest', + 'report', +) + +PYTPFLOATINGTIME_START = datetime.datetime(1899, 12, 30) +NULL_DATE = datetime.datetime(4500, 8, 31, 23, 59) + +# Constants used for argparse stuff +KNOWN_FILE_FLAGS = ( + '--out-name', +) +NEEDS_ARG = ( + '--out-name', +) +MAINDOC = "extract_msg:\n\tExtracts emails and attachments saved in Microsoft Outlook's .msg files.\n\n" \ + "https://github.com/TeamMsgExtractor/msg-extractor" + +# Default class ID for the root entry for OleWriter. This should be +# referencing Outlook if I understand it correctly. +DEFAULT_CLSID = b'\x0b\r\x02\x00\x00\x00\x00\x00\xc0\x00\x00\x00\x00\x00\x00F' + +PTYPES = { + 0x0000: 'PtypUnspecified', + 0x0001: 'PtypNull', + 0x0002: 'PtypInteger16', # Signed short + 0x0003: 'PtypInteger32', # Signed int + 0x0004: 'PtypFloating32', # Float + 0x0005: 'PtypFloating64', # Double + 0x0006: 'PtypCurrency', + 0x0007: 'PtypFloatingTime', + 0x000A: 'PtypErrorCode', + 0x000B: 'PtypBoolean', + 0x000D: 'PtypObject/PtypEmbeddedTable/Storage', + 0x0014: 'PtypInteger64', # Signed longlong + 0x001E: 'PtypString8', + 0x001F: 'PtypString', + 0x0040: 'PtypTime', # Use filetimeToUtc to convert to unix time stamp + 0x0048: 'PtypGuid', + 0x00FB: 'PtypServerId', + 0x00FD: 'PtypRestriction', + 0x00FE: 'PtypRuleAction', + 0x0102: 'PtypBinary', + 0x1002: 'PtypMultipleInteger16', + 0x1003: 'PtypMultipleInteger32', + 0x1004: 'PtypMultipleFloating32', + 0x1005: 'PtypMultipleFloating64', + 0x1006: 'PtypMultipleCurrency', + 0x1007: 'PtypMultipleFloatingTime', + 0x1014: 'PtypMultipleInteger64', + 0x101E: 'PtypMultipleString8', + 0x101F: 'PtypMultipleString', + 0x1040: 'PtypMultipleTime', + 0x1048: 'PtypMultipleGuid', + 0x1102: 'PtypMultipleBinary', +} + +# END CONSTANTS \ No newline at end of file diff --git a/extract_msg/constants/ps.py b/extract_msg/constants/ps.py new file mode 100644 index 00000000..eb1bf167 --- /dev/null +++ b/extract_msg/constants/ps.py @@ -0,0 +1,44 @@ +""" +Property set identifier constants. +""" + +__all__ = [ + 'PSETID_ADDRESS', + 'PSETID_AIRSYNC', + 'PSETID_APPOINTMENT', + 'PSETID_ATTACHMENT', + 'PSETID_CALENDAR_ASSISTANT', + 'PSETID_COMMON', + 'PSETID_LOG', + 'PSETID_MEETING', + 'PSETID_MESSAGING', + 'PSETID_NOTE', + 'PSETID_POSTRSS', + 'PSETID_SHARING', + 'PSETID_TASK', + 'PSETID_UNIFIEDMESSAGING', + 'PSETID_XMLEXTRACTEDENTITIES', + 'PS_INTERNET_HEADERS', + 'PS_MAPI', + 'PS_PUBLIC_STRINGS', +] + + +PS_MAPI = '{00020328-0000-0000-C000-000000000046}' +PS_PUBLIC_STRINGS = '{00020329-0000-0000-C000-000000000046}' +PSETID_COMMON = '{00062008-0000-0000-C000-000000000046}' +PSETID_ADDRESS = '{00062004-0000-0000-C000-000000000046}' +PS_INTERNET_HEADERS = '{00020386-0000-0000-C000-000000000046}' +PSETID_APPOINTMENT = '{00062002-0000-0000-C000-000000000046}' +PSETID_MEETING = '{6ED8DA90-450B-101B-98DA-00AA003F1305}' +PSETID_LOG = '{0006200A-0000-0000-C000-000000000046}' +PSETID_MESSAGING = '{41F28F13-83F4-4114-A584-EEDB5A6B0BFF}' +PSETID_NOTE = '{0006200E-0000-0000-C000-000000000046}' +PSETID_POSTRSS = '{00062041-0000-0000-C000-000000000046}' +PSETID_TASK = '{00062003-0000-0000-C000-000000000046}' +PSETID_UNIFIEDMESSAGING = '{4442858E-A9E3-4E80-B900-317A210CC15B}' +PSETID_AIRSYNC = '{71035549-0739-4DCB-9163-00F0580DBBDF}' +PSETID_SHARING = '{00062040-0000-0000-C000-000000000046}' +PSETID_XMLEXTRACTEDENTITIES = '{23239608-685D-4732-9C55-4C95CB4E8E33}' +PSETID_ATTACHMENT = '{96357F7F-59E1-47D0-99A7-46515C183B54}' +PSETID_CALENDAR_ASSISTANT = '{11000E07-B51B-40D6-AF21-CAA85EDAB1D0}' \ No newline at end of file diff --git a/extract_msg/constants/re.py b/extract_msg/constants/re.py new file mode 100644 index 00000000..227dc4fa --- /dev/null +++ b/extract_msg/constants/re.py @@ -0,0 +1,33 @@ +""" +Regular expression constants. +""" + +__all__ = [ + 'BIN', + 'HTML_BODY_START', + 'HTML_SAN_SPACE', + 'INVALID_FILENAME_CHARACTERS', + 'INVALID_OLE_PATH', + 'RTF_ENC_BODY_START', +] + + +import re + + +# Characters that are invalid in a filename. +INVALID_FILENAME_CHARACTERS = re.compile(r'[\\/:*?"<>|]') +# Regular expression to find sections of spaces for htmlSanitize. +HTML_SAN_SPACE = re.compile(' +') +# Regular expression to find the start of the html body. +HTML_BODY_START = re.compile(b']*>') +# Regular expression to find the start of the html body in encapsulated RTF. +# This is used for one of the pattern types that makes life easy. +RTF_ENC_BODY_START = re.compile(br'\{\\\*\\htmltag[0-9]* ?]*>\}') +# This is used in the workaround for decoding issues in RTFDE. We find `\bin` +# sections and try to remove all of them to help with the decoding. +BIN = re.compile(br'\\bin([0-9]+) ?') +# Used in the vaildation of OLE paths. Any of these characters in a name make it +# invalid. +INVALID_OLE_PATH = re.compile(r'[:/\\!]') + diff --git a/extract_msg/constants/st.py b/extract_msg/constants/st.py new file mode 100644 index 00000000..7de1534e --- /dev/null +++ b/extract_msg/constants/st.py @@ -0,0 +1,126 @@ +""" +Struct constants. +""" + +__all__ = [ + 'ST1' + 'ST2', + 'ST3', + 'STF32', + 'STF64', + 'STFIX', + 'STI16', + 'STI32', + 'STI64', + 'STI8', + 'STMF32', + 'STMF64', + 'STMI16', + 'STMI32', + 'STMI64', + 'STNP_ENT', + 'STNP_NAM', + 'STPEID', + 'STUI32', + 'STVAR', + 'ST_BC_FIELD_INFO', + 'ST_BC_HEAD', + 'ST_BE_F32', + 'ST_BE_F64', + 'ST_BE_I16', + 'ST_BE_I32', + 'ST_BE_I64', + 'ST_BE_I8', + 'ST_BE_UI16', + 'ST_BE_UI32', + 'ST_BE_UI64', + 'ST_BE_UI8', + 'ST_CF_DIR_ENTRY', + 'ST_DATA_UI16', + 'ST_DATA_UI32', + 'ST_DATA_UI8', + 'ST_GUID', + 'ST_LE_F32', + 'ST_LE_F64', + 'ST_LE_I16', + 'ST_LE_I32', + 'ST_LE_I64', + 'ST_LE_I8', + 'ST_LE_UI16', + 'ST_LE_UI32', + 'ST_LE_UI64', + 'ST_LE_UI8', + 'ST_SYSTEMTIME', + 'ST_TZ', +] + + +import struct + + +# Define pre-compiled structs to make unpacking slightly faster. +# General structs. +ST1 = struct.Struct('<8x4I') +ST2 = struct.Struct('b') +ST_BE_I16 = struct.Struct('>h') +ST_BE_I32 = struct.Struct('>i') +ST_BE_I64 = struct.Struct('>q') +ST_BE_UI8 = struct.Struct('>B') +ST_BE_UI16 = struct.Struct('>H') +ST_BE_UI32 = struct.Struct('>I') +ST_BE_UI64 = struct.Struct('>Q') +ST_BE_F32 = struct.Struct('>f') +ST_BE_F64 = struct.Struct('>d') \ No newline at end of file diff --git a/extract_msg/encoding/__init__.py b/extract_msg/encoding/__init__.py new file mode 100644 index 00000000..2696e220 --- /dev/null +++ b/extract_msg/encoding/__init__.py @@ -0,0 +1,270 @@ +""" +File for handling specialized encoding tasks or information. +""" + +__all__ = [ + 'lookupCodePage', +] + + +# This adds additional encodings to python. +import ebcdic as _ +import codecs + +from . import win950 +from ..exceptions import UnknownCodepageError, UnsupportedEncodingError + + +# This is a dictionary matching the code page number to it's encoding name. +# The list used to make this can be found here: +# https://docs.microsoft.com/en-us/windows/win32/intl/code-page-identifiers +### TODO: +# Many of these code pages are not supported by Python. As such, we should +# really implement them ourselves to make sure that if someone wants to use an +# msg file with one of those encodings, they are able to. Perhaps we should +# create a seperate module for that? +# Code pages that currently don't have a supported encoding will be preceded by +# `# UNSUPPORTED`. +# For some of these, it is also possible that the name we are trying to find +# them with is not known to Python. I have already confirmed this for a few of +# them, and adjusted their names to ones that python would recognize. It is +# Possible I missed a few. +_CODE_PAGES = { + 37: 'IBM037', # IBM EBCDIC US-Canada + 437: 'IBM437', # OEM United States + 500: 'IBM500', # IBM EBCDIC International + 708: 'ASMO-708', # Arabic (ASMO 708) + # UNSUPPORTED. + 709: '', # Arabic (ASMO-449+, BCON V4) + # UNSUPPORTED. + 710: '', # Arabic - Transparent Arabic + # UNSUPPORTED. + 720: 'DOS-720', # Arabic (Transparent ASMO); Arabic (DOS) + 737: 'cp737', # OEM Greek (formerly 437G); Greek (DOS) + 775: 'ibm775', # OEM Baltic; Baltic (DOS) + 850: 'ibm850', # OEM Multilingual Latin 1; Western European (DOS) + 852: 'ibm852', # OEM Latin 2; Central European (DOS) + 855: 'IBM855', # OEM Cyrillic (primarily Russian) + 857: 'ibm857', # OEM Turkish; Turkish (DOS) + 858: 'cp858', # OEM Multilingual Latin 1 + Euro symbol + 860: 'IBM860', # OEM Portuguese; Portuguese (DOS) + 861: 'ibm861', # OEM Icelandic; Icelandic (DOS) + 862: 'cp862', # OEM Hebrew; Hebrew (DOS) + 863: 'IBM863', # OEM French Canadian; French Canadian (DOS) + 864: 'IBM864', # OEM Arabic; Arabic (864) + 865: 'IBM865', # OEM Nordic; Nordic (DOS) + 866: 'cp866', # OEM Russian; Cyrillic (DOS) + 869: 'ibm869', # OEM Modern Greek; Greek, Modern (DOS) + 870: 'cp870', # IBM870 # IBM EBCDIC Multilingual/ROECE (Latin 2); IBM EBCDIC Multilingual Latin 2 + # UNSUPPORTED. + 874: 'windows-874', # ANSI/OEM Thai (ISO 8859-11); Thai (Windows) + 875: 'cp875', # IBM EBCDIC Greek Modern + 932: 'shift_jis', # ANSI/OEM Japanese; Japanese (Shift-JIS) + 936: 'gb2312', # ANSI/OEM Simplified Chinese (PRC, Singapore); Chinese Simplified (GB2312) + 949: 'ks_c_5601-1987', # ANSI/OEM Korean (Unified Hangul Code) + # We *must* use a custom encoding because of a core Python issue. + 950: 'windows-950', # ANSI/OEM Traditional Chinese (Taiwan; Hong Kong SAR, PRC); Chinese Traditional (Big5) + 1026: 'IBM1026', # IBM EBCDIC Turkish (Latin 5) + 1047: 'cp1047', # IBM EBCDIC Latin 1/Open System + 1140: 'cp1140', # IBM EBCDIC US-Canada (037 + Euro symbol); IBM EBCDIC (US-Canada-Euro) + 1141: 'cp1141', # IBM EBCDIC Germany (20273 + Euro symbol); IBM EBCDIC (Germany-Euro) + 1142: 'cp1142', # IBM EBCDIC Denmark-Norway (20277 + Euro symbol); IBM EBCDIC (Denmark-Norway-Euro) + 1143: 'cp1143', # IBM EBCDIC Finland-Sweden (20278 + Euro symbol); IBM EBCDIC (Finland-Sweden-Euro) + 1144: 'cp1144', # IBM EBCDIC Italy (20280 + Euro symbol); IBM EBCDIC (Italy-Euro) + 1145: 'cp1145', # IBM EBCDIC Latin America-Spain (20284 + Euro symbol); IBM EBCDIC (Spain-Euro) + 1146: 'cp1146', # IBM EBCDIC United Kingdom (20285 + Euro symbol); IBM EBCDIC (UK-Euro) + 1147: 'cp1147', # IBM EBCDIC France (20297 + Euro symbol); IBM EBCDIC (France-Euro) + 1148: 'cp1148ms', # IBM EBCDIC International (500 + Euro symbol); IBM EBCDIC (International-Euro) + 1149: 'cp1149', # IBM EBCDIC Icelandic (20871 + Euro symbol); IBM EBCDIC (Icelandic-Euro) + 1200: 'utf-16-le', # Unicode UTF-16, little endian byte order (BMP of ISO 10646); available only to managed applications + 1201: 'utf-16-be', # Unicode UTF-16, big endian byte order; available only to managed applications + 1250: 'windows-1250', # ANSI Central European; Central European (Windows) + 1251: 'windows-1251', # ANSI Cyrillic; Cyrillic (Windows) + 1252: 'windows-1252', # ANSI Latin 1; Western European (Windows) + 1253: 'windows-1253', # ANSI Greek; Greek (Windows) + 1254: 'windows-1254', # ANSI Turkish; Turkish (Windows) + 1255: 'windows-1255', # ANSI Hebrew; Hebrew (Windows) + 1256: 'windows-1256', # ANSI Arabic; Arabic (Windows) + 1257: 'windows-1257', # ANSI Baltic; Baltic (Windows) + 1258: 'windows-1258', # ANSI/OEM Vietnamese; Vietnamese (Windows) + 1361: 'Johab', # Korean (Johab) + 10000: 'macintosh', # MAC Roman; Western European (Mac) + 10001: 'x-mac-japanese', # Japanese (Mac) + # UNSUPPORTED. + 10002: 'x-mac-chinesetrad', # MAC Traditional Chinese (Big5); Chinese Traditional (Mac) + 10003: 'x-mac-korean', # Korean (Mac) + # UNSUPPORTED. + 10004: 'x-mac-arabic', # Arabic (Mac) + # UNSUPPORTED. + 10005: 'x-mac-hebrew', # Hebrew (Mac) + # UNSUPPORTED. + 10006: 'x-mac-greek', # Greek (Mac) + # UNSUPPORTED. + 10007: 'x-mac-cyrillic', # Cyrillic (Mac) + # UNSUPPORTED. + 10008: 'x-mac-chinesesimp', # MAC Simplified Chinese (GB 2312); Chinese Simplified (Mac) + # UNSUPPORTED. + 10010: 'x-mac-romanian', # Romanian (Mac) + # UNSUPPORTED. + 10017: 'x-mac-ukrainian', # Ukrainian (Mac) + # UNSUPPORTED. + 10021: 'x-mac-thai', # Thai (Mac) + # UNSUPPORTED. + 10029: 'x-mac-ce', # MAC Latin 2; Central European (Mac) + # UNSUPPORTED. + 10079: 'x-mac-icelandic', # Icelandic (Mac) + # UNSUPPORTED. + 10081: 'x-mac-turkish', # Turkish (Mac) + # UNSUPPORTED. + 10082: 'x-mac-croatian', # Croatian (Mac) + 12000: 'utf-32', # Unicode UTF-32, little endian byte order; available only to managed applications + 12001: 'utf-32BE', # Unicode UTF-32, big endian byte order; available only to managed applications + # UNSUPPORTED. + 20000: 'x-Chinese_CNS', # CNS Taiwan; Chinese Traditional (CNS) + # UNSUPPORTED. + 20001: 'x-cp20001', # TCA Taiwan + # UNSUPPORTED. + 20002: 'x_Chinese-Eten', # Eten Taiwan; Chinese Traditional (Eten) + # UNSUPPORTED. + 20003: 'x-cp20003', # IBM5550 Taiwan + # UNSUPPORTED. + 20004: 'x-cp20004', # TeleText Taiwan + # UNSUPPORTED. + 20005: 'x-cp20005', # Wang Taiwan + # UNSUPPORTED. + 20105: 'x-IA5', # IA5 (IRV International Alphabet No. 5, 7-bit); Western European (IA5) + # UNSUPPORTED. + 20106: 'x-IA5-German', # IA5 German (7-bit) + # UNSUPPORTED. + 20107: 'x-IA5-Swedish', # IA5 Swedish (7-bit) + # UNSUPPORTED. + 20108: 'x-IA5-Norwegian', # IA5 Norwegian (7-bit) + 20127: 'us-ascii', # US-ASCII (7-bit) + # UNSUPPORTED. + 20261: 'x-cp20261', # T.61 + # UNSUPPORTED. + 20269: 'x-cp20269', # ISO 6937 Non-Spacing Accent + 20273: 'IBM273', # IBM EBCDIC Germany + 20277: 'cp277', # IBM EBCDIC Denmark-Norway + 20278: 'cp278', # IBM EBCDIC Finland-Sweden + 20280: 'cp280', # IBM EBCDIC Italy + 20284: 'cp284', # IBM EBCDIC Latin America-Spain + 20285: 'cp285', # IBM EBCDIC United Kingdom + 20290: 'cp290', # IBM EBCDIC Japanese Katakana Extended + 20297: 'cp297', # IBM EBCDIC France + 20420: 'cp420', # IBM EBCDIC Arabic + # UNSUPPORTED. + 20423: 'IBM423', # IBM EBCDIC Greek + 20424: 'IBM424', # IBM EBCDIC Hebrew + 20833: 'cp833', # IBM EBCDIC Korean Extended + 20838: 'cp838', # IBM EBCDIC Thai + 20866: 'koi8-r', # Russian (KOI8-R); Cyrillic (KOI8-R) + 20871: 'cp871', # IBM EBCDIC Icelandic + # UNSUPPORTED. + 20880: 'IBM880', # IBM EBCDIC Cyrillic Russian + # UNSUPPORTED. + 20905: 'IBM905', # IBM EBCDIC Turkish + # UNSUPPORTED. + 20924: 'IBM00924', # IBM EBCDIC Latin 1/Open System (1047 + Euro symbol) + 20932: 'EUC-JP', # Japanese (JIS 0208-1990 and 0212-1990) + # UNSUPPORTED. + 20936: 'x-cp20936', # Simplified Chinese (GB2312); Chinese Simplified (GB2312-80) + # UNSUPPORTED. + 20949: 'x-cp20949', # Korean Wansung + 21025: 'cp1025', # IBM EBCDIC Cyrillic Serbian-Bulgarian + # UNSUPPORTED. + 21027: '', # (deprecated) + 21866: 'koi8-u', # Ukrainian (KOI8-U); Cyrillic (KOI8-U) + 28591: 'iso-8859-1', # ISO 8859-1 Latin 1; Western European (ISO) + 28592: 'iso-8859-2', # ISO 8859-2 Central European; Central European (ISO) + 28593: 'iso-8859-3', # ISO 8859-3 Latin 3 + 28594: 'iso-8859-4', # ISO 8859-4 Baltic + 28595: 'iso-8859-5', # ISO 8859-5 Cyrillic + 28596: 'iso-8859-6', # ISO 8859-6 Arabic + 28597: 'iso-8859-7', # ISO 8859-7 Greek + 28598: 'iso-8859-8', # ISO 8859-8 Hebrew; Hebrew (ISO-Visual) + 28599: 'iso-8859-9', # ISO 8859-9 Turkish + 28603: 'iso-8859-13', # ISO 8859-13 Estonian + 28605: 'iso-8859-15', # ISO 8859-15 Latin 9 + # UNSUPPORTED. + 29001: 'x-Europa', # Europa 3 + # UNSUPPORTED. + 38598: 'iso-8859-8-i', # ISO 8859-8 Hebrew; Hebrew (ISO-Logical) + 50220: 'iso-2022-jp', # ISO 2022 Japanese with no halfwidth Katakana; Japanese (JIS) + 50221: 'csISO2022JP', # ISO 2022 Japanese with halfwidth Katakana; Japanese (JIS-Allow 1 byte Kana) + 50222: 'iso-2022-jp', # ISO 2022 Japanese JIS X 0201-1989; Japanese (JIS-Allow 1 byte Kana - SO/SI) + 50225: 'iso-2022-kr', # ISO 2022 Korean + # UNSUPPORTED. + 50227: 'x-cp50227', # ISO 2022 Simplified Chinese; Chinese Simplified (ISO 2022) + # UNSUPPORTED. + 50229: '', # ISO 2022 Traditional Chinese + # UNSUPPORTED. + 50930: '', # EBCDIC Japanese (Katakana) Extended + # UNSUPPORTED. + 50931: '', # EBCDIC US-Canada and Japanese + # UNSUPPORTED. + 50933: '', # EBCDIC Korean Extended and Korean + # UNSUPPORTED. + 50935: '', # EBCDIC Simplified Chinese Extended and Simplified Chinese + # UNSUPPORTED. + 50936: '', # EBCDIC Simplified Chinese + # UNSUPPORTED. + 50937: '', # EBCDIC US-Canada and Traditional Chinese + # UNSUPPORTED. + 50939: '', # EBCDIC Japanese (Latin) Extended and Japanese + 51932: 'euc-jp', # EUC Japanese + 51936: 'EUC-CN', # EUC Simplified Chinese; Chinese Simplified (EUC) + 51949: 'euc-kr', # EUC Korean + # UNSUPPORTED. + 51950: '', # EUC Traditional Chinese + 52936: 'hz-gb-2312', # HZ-GB2312 Simplified Chinese; Chinese Simplified (HZ) + 54936: 'GB18030', # Windows XP and later: GB18030 Simplified Chinese (4 byte); Chinese Simplified (GB18030) + # UNSUPPORTED. + 57002: 'x-iscii-de', # ISCII Devanagari + # UNSUPPORTED. + 57003: 'x-iscii-be', # ISCII Bangla + # UNSUPPORTED. + 57004: 'x-iscii-ta', # ISCII Tamil + # UNSUPPORTED. + 57005: 'x-iscii-te', # ISCII Telugu + # UNSUPPORTED. + 57006: 'x-iscii-as', # ISCII Assamese + # UNSUPPORTED. + 57007: 'x-iscii-or', # ISCII Odia + # UNSUPPORTED. + 57008: 'x-iscii-ka', # ISCII Kannada + # UNSUPPORTED. + 57009: 'x-iscii-ma', # ISCII Malayalam + # UNSUPPORTED. + 57010: 'x-iscii-gu', # ISCII Gujarati + # UNSUPPORTED. + 57011: 'x-iscii-pa', # ISCII Punjabi + 65000: 'utf-7', # Unicode (UTF-7) + 65001: 'utf-8', # Unicode (UTF-8) +} + + +def lookupCodePage(id_ : int) -> str: + """ + Converts an encoding id into it's name. + + :raises UnknownCodepageError: The code page was not recognized. + :raises UnsupportedEncodingError: The code page was recognized, but no + encoding exists in the environment with support for it. + """ + if id_ in _CODE_PAGES: + if (page := _CODE_PAGES[id_]): + return page + else: + raise UnsupportedEncodingError(f'Code page {id_} is unsupported.') + else: + raise UnknownCodepageError(f'Unknown code page {id_}.') + +def _lookupEncoding(name): + return _codecsInfo.get(name) + + +_codecsInfo = { + 'windows_950': win950.getregentry(), +} +codecs.register(_lookupEncoding) \ No newline at end of file diff --git a/extract_msg/encoding/_win950_dec.py b/extract_msg/encoding/_win950_dec.py new file mode 100644 index 00000000..bdd7725a --- /dev/null +++ b/extract_msg/encoding/_win950_dec.py @@ -0,0 +1,5 @@ +__all__ = [ + 'decodingTable' +] + +decodingTable={0:'\u0000',1:'\u0001',2:'\u0002',3:'\u0003',4:'\u0004',5:'\u0005',6:'\u0006',7:'\u0007',8:'\u0008',9:'\u0009',10:'\u000A',11:'\u000B',12:'\u000C',13:'\u000D',14:'\u000E',15:'\u000F',16:'\u0010',17:'\u0011',18:'\u0012',19:'\u0013',20:'\u0014',21:'\u0015',22:'\u0016',23:'\u0017',24:'\u0018',25:'\u0019',26:'\u001A',27:'\u001B',28:'\u001C',29:'\u001D',30:'\u001E',31:'\u001F',32:'\u0020',33:'\u0021',34:'\u0022',35:'\u0023',36:'\u0024',37:'\u0025',38:'\u0026',39:'\u0027',40:'\u0028',41:'\u0029',42:'\u002A',43:'\u002B',44:'\u002C',45:'\u002D',46:'\u002E',47:'\u002F',48:'\u0030',49:'\u0031',50:'\u0032',51:'\u0033',52:'\u0034',53:'\u0035',54:'\u0036',55:'\u0037',56:'\u0038',57:'\u0039',58:'\u003A',59:'\u003B',60:'\u003C',61:'\u003D',62:'\u003E',63:'\u003F',64:'\u0040',65:'\u0041',66:'\u0042',67:'\u0043',68:'\u0044',69:'\u0045',70:'\u0046',71:'\u0047',72:'\u0048',73:'\u0049',74:'\u004A',75:'\u004B',76:'\u004C',77:'\u004D',78:'\u004E',79:'\u004F',80:'\u0050',81:'\u0051',82:'\u0052',83:'\u0053',84:'\u0054',85:'\u0055',86:'\u0056',87:'\u0057',88:'\u0058',89:'\u0059',90:'\u005A',91:'\u005B',92:'\u005C',93:'\u005D',94:'\u005E',95:'\u005F',96:'\u0060',97:'\u0061',98:'\u0062',99:'\u0063',100:'\u0064',101:'\u0065',102:'\u0066',103:'\u0067',104:'\u0068',105:'\u0069',106:'\u006A',107:'\u006B',108:'\u006C',109:'\u006D',110:'\u006E',111:'\u006F',112:'\u0070',113:'\u0071',114:'\u0072',115:'\u0073',116:'\u0074',117:'\u0075',118:'\u0076',119:'\u0077',120:'\u0078',121:'\u0079',122:'\u007A',123:'\u007B',124:'\u007C',125:'\u007D',126:'\u007E',127:'\u007F',128:'\u0080',255:'\uF8F8',33088:'\uEEB8',33089:'\uEEB9',33090:'\uEEBA',33091:'\uEEBB',33092:'\uEEBC',33093:'\uEEBD',33094:'\uEEBE',33095:'\uEEBF',33096:'\uEEC0',33097:'\uEEC1',33098:'\uEEC2',33099:'\uEEC3',33100:'\uEEC4',33101:'\uEEC5',33102:'\uEEC6',33103:'\uEEC7',33104:'\uEEC8',33105:'\uEEC9',33106:'\uEECA',33107:'\uEECB',33108:'\uEECC',33109:'\uEECD',33110:'\uEECE',33111:'\uEECF',33112:'\uEED0',33113:'\uEED1',33114:'\uEED2',33115:'\uEED3',33116:'\uEED4',33117:'\uEED5',33118:'\uEED6',33119:'\uEED7',33120:'\uEED8',33121:'\uEED9',33122:'\uEEDA',33123:'\uEEDB',33124:'\uEEDC',33125:'\uEEDD',33126:'\uEEDE',33127:'\uEEDF',33128:'\uEEE0',33129:'\uEEE1',33130:'\uEEE2',33131:'\uEEE3',33132:'\uEEE4',33133:'\uEEE5',33134:'\uEEE6',33135:'\uEEE7',33136:'\uEEE8',33137:'\uEEE9',33138:'\uEEEA',33139:'\uEEEB',33140:'\uEEEC',33141:'\uEEED',33142:'\uEEEE',33143:'\uEEEF',33144:'\uEEF0',33145:'\uEEF1',33146:'\uEEF2',33147:'\uEEF3',33148:'\uEEF4',33149:'\uEEF5',33150:'\uEEF6',33185:'\uEEF7',33186:'\uEEF8',33187:'\uEEF9',33188:'\uEEFA',33189:'\uEEFB',33190:'\uEEFC',33191:'\uEEFD',33192:'\uEEFE',33193:'\uEEFF',33194:'\uEF00',33195:'\uEF01',33196:'\uEF02',33197:'\uEF03',33198:'\uEF04',33199:'\uEF05',33200:'\uEF06',33201:'\uEF07',33202:'\uEF08',33203:'\uEF09',33204:'\uEF0A',33205:'\uEF0B',33206:'\uEF0C',33207:'\uEF0D',33208:'\uEF0E',33209:'\uEF0F',33210:'\uEF10',33211:'\uEF11',33212:'\uEF12',33213:'\uEF13',33214:'\uEF14',33215:'\uEF15',33216:'\uEF16',33217:'\uEF17',33218:'\uEF18',33219:'\uEF19',33220:'\uEF1A',33221:'\uEF1B',33222:'\uEF1C',33223:'\uEF1D',33224:'\uEF1E',33225:'\uEF1F',33226:'\uEF20',33227:'\uEF21',33228:'\uEF22',33229:'\uEF23',33230:'\uEF24',33231:'\uEF25',33232:'\uEF26',33233:'\uEF27',33234:'\uEF28',33235:'\uEF29',33236:'\uEF2A',33237:'\uEF2B',33238:'\uEF2C',33239:'\uEF2D',33240:'\uEF2E',33241:'\uEF2F',33242:'\uEF30',33243:'\uEF31',33244:'\uEF32',33245:'\uEF33',33246:'\uEF34',33247:'\uEF35',33248:'\uEF36',33249:'\uEF37',33250:'\uEF38',33251:'\uEF39',33252:'\uEF3A',33253:'\uEF3B',33254:'\uEF3C',33255:'\uEF3D',33256:'\uEF3E',33257:'\uEF3F',33258:'\uEF40',33259:'\uEF41',33260:'\uEF42',33261:'\uEF43',33262:'\uEF44',33263:'\uEF45',33264:'\uEF46',33265:'\uEF47',33266:'\uEF48',33267:'\uEF49',33268:'\uEF4A',33269:'\uEF4B',33270:'\uEF4C',33271:'\uEF4D',33272:'\uEF4E',33273:'\uEF4F',33274:'\uEF50',33275:'\uEF51',33276:'\uEF52',33277:'\uEF53',33278:'\uEF54',33344:'\uEF55',33345:'\uEF56',33346:'\uEF57',33347:'\uEF58',33348:'\uEF59',33349:'\uEF5A',33350:'\uEF5B',33351:'\uEF5C',33352:'\uEF5D',33353:'\uEF5E',33354:'\uEF5F',33355:'\uEF60',33356:'\uEF61',33357:'\uEF62',33358:'\uEF63',33359:'\uEF64',33360:'\uEF65',33361:'\uEF66',33362:'\uEF67',33363:'\uEF68',33364:'\uEF69',33365:'\uEF6A',33366:'\uEF6B',33367:'\uEF6C',33368:'\uEF6D',33369:'\uEF6E',33370:'\uEF6F',33371:'\uEF70',33372:'\uEF71',33373:'\uEF72',33374:'\uEF73',33375:'\uEF74',33376:'\uEF75',33377:'\uEF76',33378:'\uEF77',33379:'\uEF78',33380:'\uEF79',33381:'\uEF7A',33382:'\uEF7B',33383:'\uEF7C',33384:'\uEF7D',33385:'\uEF7E',33386:'\uEF7F',33387:'\uEF80',33388:'\uEF81',33389:'\uEF82',33390:'\uEF83',33391:'\uEF84',33392:'\uEF85',33393:'\uEF86',33394:'\uEF87',33395:'\uEF88',33396:'\uEF89',33397:'\uEF8A',33398:'\uEF8B',33399:'\uEF8C',33400:'\uEF8D',33401:'\uEF8E',33402:'\uEF8F',33403:'\uEF90',33404:'\uEF91',33405:'\uEF92',33406:'\uEF93',33441:'\uEF94',33442:'\uEF95',33443:'\uEF96',33444:'\uEF97',33445:'\uEF98',33446:'\uEF99',33447:'\uEF9A',33448:'\uEF9B',33449:'\uEF9C',33450:'\uEF9D',33451:'\uEF9E',33452:'\uEF9F',33453:'\uEFA0',33454:'\uEFA1',33455:'\uEFA2',33456:'\uEFA3',33457:'\uEFA4',33458:'\uEFA5',33459:'\uEFA6',33460:'\uEFA7',33461:'\uEFA8',33462:'\uEFA9',33463:'\uEFAA',33464:'\uEFAB',33465:'\uEFAC',33466:'\uEFAD',33467:'\uEFAE',33468:'\uEFAF',33469:'\uEFB0',33470:'\uEFB1',33471:'\uEFB2',33472:'\uEFB3',33473:'\uEFB4',33474:'\uEFB5',33475:'\uEFB6',33476:'\uEFB7',33477:'\uEFB8',33478:'\uEFB9',33479:'\uEFBA',33480:'\uEFBB',33481:'\uEFBC',33482:'\uEFBD',33483:'\uEFBE',33484:'\uEFBF',33485:'\uEFC0',33486:'\uEFC1',33487:'\uEFC2',33488:'\uEFC3',33489:'\uEFC4',33490:'\uEFC5',33491:'\uEFC6',33492:'\uEFC7',33493:'\uEFC8',33494:'\uEFC9',33495:'\uEFCA',33496:'\uEFCB',33497:'\uEFCC',33498:'\uEFCD',33499:'\uEFCE',33500:'\uEFCF',33501:'\uEFD0',33502:'\uEFD1',33503:'\uEFD2',33504:'\uEFD3',33505:'\uEFD4',33506:'\uEFD5',33507:'\uEFD6',33508:'\uEFD7',33509:'\uEFD8',33510:'\uEFD9',33511:'\uEFDA',33512:'\uEFDB',33513:'\uEFDC',33514:'\uEFDD',33515:'\uEFDE',33516:'\uEFDF',33517:'\uEFE0',33518:'\uEFE1',33519:'\uEFE2',33520:'\uEFE3',33521:'\uEFE4',33522:'\uEFE5',33523:'\uEFE6',33524:'\uEFE7',33525:'\uEFE8',33526:'\uEFE9',33527:'\uEFEA',33528:'\uEFEB',33529:'\uEFEC',33530:'\uEFED',33531:'\uEFEE',33532:'\uEFEF',33533:'\uEFF0',33534:'\uEFF1',33600:'\uEFF2',33601:'\uEFF3',33602:'\uEFF4',33603:'\uEFF5',33604:'\uEFF6',33605:'\uEFF7',33606:'\uEFF8',33607:'\uEFF9',33608:'\uEFFA',33609:'\uEFFB',33610:'\uEFFC',33611:'\uEFFD',33612:'\uEFFE',33613:'\uEFFF',33614:'\uF000',33615:'\uF001',33616:'\uF002',33617:'\uF003',33618:'\uF004',33619:'\uF005',33620:'\uF006',33621:'\uF007',33622:'\uF008',33623:'\uF009',33624:'\uF00A',33625:'\uF00B',33626:'\uF00C',33627:'\uF00D',33628:'\uF00E',33629:'\uF00F',33630:'\uF010',33631:'\uF011',33632:'\uF012',33633:'\uF013',33634:'\uF014',33635:'\uF015',33636:'\uF016',33637:'\uF017',33638:'\uF018',33639:'\uF019',33640:'\uF01A',33641:'\uF01B',33642:'\uF01C',33643:'\uF01D',33644:'\uF01E',33645:'\uF01F',33646:'\uF020',33647:'\uF021',33648:'\uF022',33649:'\uF023',33650:'\uF024',33651:'\uF025',33652:'\uF026',33653:'\uF027',33654:'\uF028',33655:'\uF029',33656:'\uF02A',33657:'\uF02B',33658:'\uF02C',33659:'\uF02D',33660:'\uF02E',33661:'\uF02F',33662:'\uF030',33697:'\uF031',33698:'\uF032',33699:'\uF033',33700:'\uF034',33701:'\uF035',33702:'\uF036',33703:'\uF037',33704:'\uF038',33705:'\uF039',33706:'\uF03A',33707:'\uF03B',33708:'\uF03C',33709:'\uF03D',33710:'\uF03E',33711:'\uF03F',33712:'\uF040',33713:'\uF041',33714:'\uF042',33715:'\uF043',33716:'\uF044',33717:'\uF045',33718:'\uF046',33719:'\uF047',33720:'\uF048',33721:'\uF049',33722:'\uF04A',33723:'\uF04B',33724:'\uF04C',33725:'\uF04D',33726:'\uF04E',33727:'\uF04F',33728:'\uF050',33729:'\uF051',33730:'\uF052',33731:'\uF053',33732:'\uF054',33733:'\uF055',33734:'\uF056',33735:'\uF057',33736:'\uF058',33737:'\uF059',33738:'\uF05A',33739:'\uF05B',33740:'\uF05C',33741:'\uF05D',33742:'\uF05E',33743:'\uF05F',33744:'\uF060',33745:'\uF061',33746:'\uF062',33747:'\uF063',33748:'\uF064',33749:'\uF065',33750:'\uF066',33751:'\uF067',33752:'\uF068',33753:'\uF069',33754:'\uF06A',33755:'\uF06B',33756:'\uF06C',33757:'\uF06D',33758:'\uF06E',33759:'\uF06F',33760:'\uF070',33761:'\uF071',33762:'\uF072',33763:'\uF073',33764:'\uF074',33765:'\uF075',33766:'\uF076',33767:'\uF077',33768:'\uF078',33769:'\uF079',33770:'\uF07A',33771:'\uF07B',33772:'\uF07C',33773:'\uF07D',33774:'\uF07E',33775:'\uF07F',33776:'\uF080',33777:'\uF081',33778:'\uF082',33779:'\uF083',33780:'\uF084',33781:'\uF085',33782:'\uF086',33783:'\uF087',33784:'\uF088',33785:'\uF089',33786:'\uF08A',33787:'\uF08B',33788:'\uF08C',33789:'\uF08D',33790:'\uF08E',33856:'\uF08F',33857:'\uF090',33858:'\uF091',33859:'\uF092',33860:'\uF093',33861:'\uF094',33862:'\uF095',33863:'\uF096',33864:'\uF097',33865:'\uF098',33866:'\uF099',33867:'\uF09A',33868:'\uF09B',33869:'\uF09C',33870:'\uF09D',33871:'\uF09E',33872:'\uF09F',33873:'\uF0A0',33874:'\uF0A1',33875:'\uF0A2',33876:'\uF0A3',33877:'\uF0A4',33878:'\uF0A5',33879:'\uF0A6',33880:'\uF0A7',33881:'\uF0A8',33882:'\uF0A9',33883:'\uF0AA',33884:'\uF0AB',33885:'\uF0AC',33886:'\uF0AD',33887:'\uF0AE',33888:'\uF0AF',33889:'\uF0B0',33890:'\uF0B1',33891:'\uF0B2',33892:'\uF0B3',33893:'\uF0B4',33894:'\uF0B5',33895:'\uF0B6',33896:'\uF0B7',33897:'\uF0B8',33898:'\uF0B9',33899:'\uF0BA',33900:'\uF0BB',33901:'\uF0BC',33902:'\uF0BD',33903:'\uF0BE',33904:'\uF0BF',33905:'\uF0C0',33906:'\uF0C1',33907:'\uF0C2',33908:'\uF0C3',33909:'\uF0C4',33910:'\uF0C5',33911:'\uF0C6',33912:'\uF0C7',33913:'\uF0C8',33914:'\uF0C9',33915:'\uF0CA',33916:'\uF0CB',33917:'\uF0CC',33918:'\uF0CD',33953:'\uF0CE',33954:'\uF0CF',33955:'\uF0D0',33956:'\uF0D1',33957:'\uF0D2',33958:'\uF0D3',33959:'\uF0D4',33960:'\uF0D5',33961:'\uF0D6',33962:'\uF0D7',33963:'\uF0D8',33964:'\uF0D9',33965:'\uF0DA',33966:'\uF0DB',33967:'\uF0DC',33968:'\uF0DD',33969:'\uF0DE',33970:'\uF0DF',33971:'\uF0E0',33972:'\uF0E1',33973:'\uF0E2',33974:'\uF0E3',33975:'\uF0E4',33976:'\uF0E5',33977:'\uF0E6',33978:'\uF0E7',33979:'\uF0E8',33980:'\uF0E9',33981:'\uF0EA',33982:'\uF0EB',33983:'\uF0EC',33984:'\uF0ED',33985:'\uF0EE',33986:'\uF0EF',33987:'\uF0F0',33988:'\uF0F1',33989:'\uF0F2',33990:'\uF0F3',33991:'\uF0F4',33992:'\uF0F5',33993:'\uF0F6',33994:'\uF0F7',33995:'\uF0F8',33996:'\uF0F9',33997:'\uF0FA',33998:'\uF0FB',33999:'\uF0FC',34000:'\uF0FD',34001:'\uF0FE',34002:'\uF0FF',34003:'\uF100',34004:'\uF101',34005:'\uF102',34006:'\uF103',34007:'\uF104',34008:'\uF105',34009:'\uF106',34010:'\uF107',34011:'\uF108',34012:'\uF109',34013:'\uF10A',34014:'\uF10B',34015:'\uF10C',34016:'\uF10D',34017:'\uF10E',34018:'\uF10F',34019:'\uF110',34020:'\uF111',34021:'\uF112',34022:'\uF113',34023:'\uF114',34024:'\uF115',34025:'\uF116',34026:'\uF117',34027:'\uF118',34028:'\uF119',34029:'\uF11A',34030:'\uF11B',34031:'\uF11C',34032:'\uF11D',34033:'\uF11E',34034:'\uF11F',34035:'\uF120',34036:'\uF121',34037:'\uF122',34038:'\uF123',34039:'\uF124',34040:'\uF125',34041:'\uF126',34042:'\uF127',34043:'\uF128',34044:'\uF129',34045:'\uF12A',34046:'\uF12B',34112:'\uF12C',34113:'\uF12D',34114:'\uF12E',34115:'\uF12F',34116:'\uF130',34117:'\uF131',34118:'\uF132',34119:'\uF133',34120:'\uF134',34121:'\uF135',34122:'\uF136',34123:'\uF137',34124:'\uF138',34125:'\uF139',34126:'\uF13A',34127:'\uF13B',34128:'\uF13C',34129:'\uF13D',34130:'\uF13E',34131:'\uF13F',34132:'\uF140',34133:'\uF141',34134:'\uF142',34135:'\uF143',34136:'\uF144',34137:'\uF145',34138:'\uF146',34139:'\uF147',34140:'\uF148',34141:'\uF149',34142:'\uF14A',34143:'\uF14B',34144:'\uF14C',34145:'\uF14D',34146:'\uF14E',34147:'\uF14F',34148:'\uF150',34149:'\uF151',34150:'\uF152',34151:'\uF153',34152:'\uF154',34153:'\uF155',34154:'\uF156',34155:'\uF157',34156:'\uF158',34157:'\uF159',34158:'\uF15A',34159:'\uF15B',34160:'\uF15C',34161:'\uF15D',34162:'\uF15E',34163:'\uF15F',34164:'\uF160',34165:'\uF161',34166:'\uF162',34167:'\uF163',34168:'\uF164',34169:'\uF165',34170:'\uF166',34171:'\uF167',34172:'\uF168',34173:'\uF169',34174:'\uF16A',34209:'\uF16B',34210:'\uF16C',34211:'\uF16D',34212:'\uF16E',34213:'\uF16F',34214:'\uF170',34215:'\uF171',34216:'\uF172',34217:'\uF173',34218:'\uF174',34219:'\uF175',34220:'\uF176',34221:'\uF177',34222:'\uF178',34223:'\uF179',34224:'\uF17A',34225:'\uF17B',34226:'\uF17C',34227:'\uF17D',34228:'\uF17E',34229:'\uF17F',34230:'\uF180',34231:'\uF181',34232:'\uF182',34233:'\uF183',34234:'\uF184',34235:'\uF185',34236:'\uF186',34237:'\uF187',34238:'\uF188',34239:'\uF189',34240:'\uF18A',34241:'\uF18B',34242:'\uF18C',34243:'\uF18D',34244:'\uF18E',34245:'\uF18F',34246:'\uF190',34247:'\uF191',34248:'\uF192',34249:'\uF193',34250:'\uF194',34251:'\uF195',34252:'\uF196',34253:'\uF197',34254:'\uF198',34255:'\uF199',34256:'\uF19A',34257:'\uF19B',34258:'\uF19C',34259:'\uF19D',34260:'\uF19E',34261:'\uF19F',34262:'\uF1A0',34263:'\uF1A1',34264:'\uF1A2',34265:'\uF1A3',34266:'\uF1A4',34267:'\uF1A5',34268:'\uF1A6',34269:'\uF1A7',34270:'\uF1A8',34271:'\uF1A9',34272:'\uF1AA',34273:'\uF1AB',34274:'\uF1AC',34275:'\uF1AD',34276:'\uF1AE',34277:'\uF1AF',34278:'\uF1B0',34279:'\uF1B1',34280:'\uF1B2',34281:'\uF1B3',34282:'\uF1B4',34283:'\uF1B5',34284:'\uF1B6',34285:'\uF1B7',34286:'\uF1B8',34287:'\uF1B9',34288:'\uF1BA',34289:'\uF1BB',34290:'\uF1BC',34291:'\uF1BD',34292:'\uF1BE',34293:'\uF1BF',34294:'\uF1C0',34295:'\uF1C1',34296:'\uF1C2',34297:'\uF1C3',34298:'\uF1C4',34299:'\uF1C5',34300:'\uF1C6',34301:'\uF1C7',34302:'\uF1C8',34368:'\uF1C9',34369:'\uF1CA',34370:'\uF1CB',34371:'\uF1CC',34372:'\uF1CD',34373:'\uF1CE',34374:'\uF1CF',34375:'\uF1D0',34376:'\uF1D1',34377:'\uF1D2',34378:'\uF1D3',34379:'\uF1D4',34380:'\uF1D5',34381:'\uF1D6',34382:'\uF1D7',34383:'\uF1D8',34384:'\uF1D9',34385:'\uF1DA',34386:'\uF1DB',34387:'\uF1DC',34388:'\uF1DD',34389:'\uF1DE',34390:'\uF1DF',34391:'\uF1E0',34392:'\uF1E1',34393:'\uF1E2',34394:'\uF1E3',34395:'\uF1E4',34396:'\uF1E5',34397:'\uF1E6',34398:'\uF1E7',34399:'\uF1E8',34400:'\uF1E9',34401:'\uF1EA',34402:'\uF1EB',34403:'\uF1EC',34404:'\uF1ED',34405:'\uF1EE',34406:'\uF1EF',34407:'\uF1F0',34408:'\uF1F1',34409:'\uF1F2',34410:'\uF1F3',34411:'\uF1F4',34412:'\uF1F5',34413:'\uF1F6',34414:'\uF1F7',34415:'\uF1F8',34416:'\uF1F9',34417:'\uF1FA',34418:'\uF1FB',34419:'\uF1FC',34420:'\uF1FD',34421:'\uF1FE',34422:'\uF1FF',34423:'\uF200',34424:'\uF201',34425:'\uF202',34426:'\uF203',34427:'\uF204',34428:'\uF205',34429:'\uF206',34430:'\uF207',34465:'\uF208',34466:'\uF209',34467:'\uF20A',34468:'\uF20B',34469:'\uF20C',34470:'\uF20D',34471:'\uF20E',34472:'\uF20F',34473:'\uF210',34474:'\uF211',34475:'\uF212',34476:'\uF213',34477:'\uF214',34478:'\uF215',34479:'\uF216',34480:'\uF217',34481:'\uF218',34482:'\uF219',34483:'\uF21A',34484:'\uF21B',34485:'\uF21C',34486:'\uF21D',34487:'\uF21E',34488:'\uF21F',34489:'\uF220',34490:'\uF221',34491:'\uF222',34492:'\uF223',34493:'\uF224',34494:'\uF225',34495:'\uF226',34496:'\uF227',34497:'\uF228',34498:'\uF229',34499:'\uF22A',34500:'\uF22B',34501:'\uF22C',34502:'\uF22D',34503:'\uF22E',34504:'\uF22F',34505:'\uF230',34506:'\uF231',34507:'\uF232',34508:'\uF233',34509:'\uF234',34510:'\uF235',34511:'\uF236',34512:'\uF237',34513:'\uF238',34514:'\uF239',34515:'\uF23A',34516:'\uF23B',34517:'\uF23C',34518:'\uF23D',34519:'\uF23E',34520:'\uF23F',34521:'\uF240',34522:'\uF241',34523:'\uF242',34524:'\uF243',34525:'\uF244',34526:'\uF245',34527:'\uF246',34528:'\uF247',34529:'\uF248',34530:'\uF249',34531:'\uF24A',34532:'\uF24B',34533:'\uF24C',34534:'\uF24D',34535:'\uF24E',34536:'\uF24F',34537:'\uF250',34538:'\uF251',34539:'\uF252',34540:'\uF253',34541:'\uF254',34542:'\uF255',34543:'\uF256',34544:'\uF257',34545:'\uF258',34546:'\uF259',34547:'\uF25A',34548:'\uF25B',34549:'\uF25C',34550:'\uF25D',34551:'\uF25E',34552:'\uF25F',34553:'\uF260',34554:'\uF261',34555:'\uF262',34556:'\uF263',34557:'\uF264',34558:'\uF265',34624:'\uF266',34625:'\uF267',34626:'\uF268',34627:'\uF269',34628:'\uF26A',34629:'\uF26B',34630:'\uF26C',34631:'\uF26D',34632:'\uF26E',34633:'\uF26F',34634:'\uF270',34635:'\uF271',34636:'\uF272',34637:'\uF273',34638:'\uF274',34639:'\uF275',34640:'\uF276',34641:'\uF277',34642:'\uF278',34643:'\uF279',34644:'\uF27A',34645:'\uF27B',34646:'\uF27C',34647:'\uF27D',34648:'\uF27E',34649:'\uF27F',34650:'\uF280',34651:'\uF281',34652:'\uF282',34653:'\uF283',34654:'\uF284',34655:'\uF285',34656:'\uF286',34657:'\uF287',34658:'\uF288',34659:'\uF289',34660:'\uF28A',34661:'\uF28B',34662:'\uF28C',34663:'\uF28D',34664:'\uF28E',34665:'\uF28F',34666:'\uF290',34667:'\uF291',34668:'\uF292',34669:'\uF293',34670:'\uF294',34671:'\uF295',34672:'\uF296',34673:'\uF297',34674:'\uF298',34675:'\uF299',34676:'\uF29A',34677:'\uF29B',34678:'\uF29C',34679:'\uF29D',34680:'\uF29E',34681:'\uF29F',34682:'\uF2A0',34683:'\uF2A1',34684:'\uF2A2',34685:'\uF2A3',34686:'\uF2A4',34721:'\uF2A5',34722:'\uF2A6',34723:'\uF2A7',34724:'\uF2A8',34725:'\uF2A9',34726:'\uF2AA',34727:'\uF2AB',34728:'\uF2AC',34729:'\uF2AD',34730:'\uF2AE',34731:'\uF2AF',34732:'\uF2B0',34733:'\uF2B1',34734:'\uF2B2',34735:'\uF2B3',34736:'\uF2B4',34737:'\uF2B5',34738:'\uF2B6',34739:'\uF2B7',34740:'\uF2B8',34741:'\uF2B9',34742:'\uF2BA',34743:'\uF2BB',34744:'\uF2BC',34745:'\uF2BD',34746:'\uF2BE',34747:'\uF2BF',34748:'\uF2C0',34749:'\uF2C1',34750:'\uF2C2',34751:'\uF2C3',34752:'\uF2C4',34753:'\uF2C5',34754:'\uF2C6',34755:'\uF2C7',34756:'\uF2C8',34757:'\uF2C9',34758:'\uF2CA',34759:'\uF2CB',34760:'\uF2CC',34761:'\uF2CD',34762:'\uF2CE',34763:'\uF2CF',34764:'\uF2D0',34765:'\uF2D1',34766:'\uF2D2',34767:'\uF2D3',34768:'\uF2D4',34769:'\uF2D5',34770:'\uF2D6',34771:'\uF2D7',34772:'\uF2D8',34773:'\uF2D9',34774:'\uF2DA',34775:'\uF2DB',34776:'\uF2DC',34777:'\uF2DD',34778:'\uF2DE',34779:'\uF2DF',34780:'\uF2E0',34781:'\uF2E1',34782:'\uF2E2',34783:'\uF2E3',34784:'\uF2E4',34785:'\uF2E5',34786:'\uF2E6',34787:'\uF2E7',34788:'\uF2E8',34789:'\uF2E9',34790:'\uF2EA',34791:'\uF2EB',34792:'\uF2EC',34793:'\uF2ED',34794:'\uF2EE',34795:'\uF2EF',34796:'\uF2F0',34797:'\uF2F1',34798:'\uF2F2',34799:'\uF2F3',34800:'\uF2F4',34801:'\uF2F5',34802:'\uF2F6',34803:'\uF2F7',34804:'\uF2F8',34805:'\uF2F9',34806:'\uF2FA',34807:'\uF2FB',34808:'\uF2FC',34809:'\uF2FD',34810:'\uF2FE',34811:'\uF2FF',34812:'\uF300',34813:'\uF301',34814:'\uF302',34880:'\uF303',34881:'\uF304',34882:'\uF305',34883:'\uF306',34884:'\uF307',34885:'\uF308',34886:'\uF309',34887:'\uF30A',34888:'\uF30B',34889:'\uF30C',34890:'\uF30D',34891:'\uF30E',34892:'\uF30F',34893:'\uF310',34894:'\uF311',34895:'\uF312',34896:'\uF313',34897:'\uF314',34898:'\uF315',34899:'\uF316',34900:'\uF317',34901:'\uF318',34902:'\uF319',34903:'\uF31A',34904:'\uF31B',34905:'\uF31C',34906:'\uF31D',34907:'\uF31E',34908:'\uF31F',34909:'\uF320',34910:'\uF321',34911:'\uF322',34912:'\uF323',34913:'\uF324',34914:'\uF325',34915:'\uF326',34916:'\uF327',34917:'\uF328',34918:'\uF329',34919:'\uF32A',34920:'\uF32B',34921:'\uF32C',34922:'\uF32D',34923:'\uF32E',34924:'\uF32F',34925:'\uF330',34926:'\uF331',34927:'\uF332',34928:'\uF333',34929:'\uF334',34930:'\uF335',34931:'\uF336',34932:'\uF337',34933:'\uF338',34934:'\uF339',34935:'\uF33A',34936:'\uF33B',34937:'\uF33C',34938:'\uF33D',34939:'\uF33E',34940:'\uF33F',34941:'\uF340',34942:'\uF341',34977:'\uF342',34978:'\uF343',34979:'\uF344',34980:'\uF345',34981:'\uF346',34982:'\uF347',34983:'\uF348',34984:'\uF349',34985:'\uF34A',34986:'\uF34B',34987:'\uF34C',34988:'\uF34D',34989:'\uF34E',34990:'\uF34F',34991:'\uF350',34992:'\uF351',34993:'\uF352',34994:'\uF353',34995:'\uF354',34996:'\uF355',34997:'\uF356',34998:'\uF357',34999:'\uF358',35000:'\uF359',35001:'\uF35A',35002:'\uF35B',35003:'\uF35C',35004:'\uF35D',35005:'\uF35E',35006:'\uF35F',35007:'\uF360',35008:'\uF361',35009:'\uF362',35010:'\uF363',35011:'\uF364',35012:'\uF365',35013:'\uF366',35014:'\uF367',35015:'\uF368',35016:'\uF369',35017:'\uF36A',35018:'\uF36B',35019:'\uF36C',35020:'\uF36D',35021:'\uF36E',35022:'\uF36F',35023:'\uF370',35024:'\uF371',35025:'\uF372',35026:'\uF373',35027:'\uF374',35028:'\uF375',35029:'\uF376',35030:'\uF377',35031:'\uF378',35032:'\uF379',35033:'\uF37A',35034:'\uF37B',35035:'\uF37C',35036:'\uF37D',35037:'\uF37E',35038:'\uF37F',35039:'\uF380',35040:'\uF381',35041:'\uF382',35042:'\uF383',35043:'\uF384',35044:'\uF385',35045:'\uF386',35046:'\uF387',35047:'\uF388',35048:'\uF389',35049:'\uF38A',35050:'\uF38B',35051:'\uF38C',35052:'\uF38D',35053:'\uF38E',35054:'\uF38F',35055:'\uF390',35056:'\uF391',35057:'\uF392',35058:'\uF393',35059:'\uF394',35060:'\uF395',35061:'\uF396',35062:'\uF397',35063:'\uF398',35064:'\uF399',35065:'\uF39A',35066:'\uF39B',35067:'\uF39C',35068:'\uF39D',35069:'\uF39E',35070:'\uF39F',35136:'\uF3A0',35137:'\uF3A1',35138:'\uF3A2',35139:'\uF3A3',35140:'\uF3A4',35141:'\uF3A5',35142:'\uF3A6',35143:'\uF3A7',35144:'\uF3A8',35145:'\uF3A9',35146:'\uF3AA',35147:'\uF3AB',35148:'\uF3AC',35149:'\uF3AD',35150:'\uF3AE',35151:'\uF3AF',35152:'\uF3B0',35153:'\uF3B1',35154:'\uF3B2',35155:'\uF3B3',35156:'\uF3B4',35157:'\uF3B5',35158:'\uF3B6',35159:'\uF3B7',35160:'\uF3B8',35161:'\uF3B9',35162:'\uF3BA',35163:'\uF3BB',35164:'\uF3BC',35165:'\uF3BD',35166:'\uF3BE',35167:'\uF3BF',35168:'\uF3C0',35169:'\uF3C1',35170:'\uF3C2',35171:'\uF3C3',35172:'\uF3C4',35173:'\uF3C5',35174:'\uF3C6',35175:'\uF3C7',35176:'\uF3C8',35177:'\uF3C9',35178:'\uF3CA',35179:'\uF3CB',35180:'\uF3CC',35181:'\uF3CD',35182:'\uF3CE',35183:'\uF3CF',35184:'\uF3D0',35185:'\uF3D1',35186:'\uF3D2',35187:'\uF3D3',35188:'\uF3D4',35189:'\uF3D5',35190:'\uF3D6',35191:'\uF3D7',35192:'\uF3D8',35193:'\uF3D9',35194:'\uF3DA',35195:'\uF3DB',35196:'\uF3DC',35197:'\uF3DD',35198:'\uF3DE',35233:'\uF3DF',35234:'\uF3E0',35235:'\uF3E1',35236:'\uF3E2',35237:'\uF3E3',35238:'\uF3E4',35239:'\uF3E5',35240:'\uF3E6',35241:'\uF3E7',35242:'\uF3E8',35243:'\uF3E9',35244:'\uF3EA',35245:'\uF3EB',35246:'\uF3EC',35247:'\uF3ED',35248:'\uF3EE',35249:'\uF3EF',35250:'\uF3F0',35251:'\uF3F1',35252:'\uF3F2',35253:'\uF3F3',35254:'\uF3F4',35255:'\uF3F5',35256:'\uF3F6',35257:'\uF3F7',35258:'\uF3F8',35259:'\uF3F9',35260:'\uF3FA',35261:'\uF3FB',35262:'\uF3FC',35263:'\uF3FD',35264:'\uF3FE',35265:'\uF3FF',35266:'\uF400',35267:'\uF401',35268:'\uF402',35269:'\uF403',35270:'\uF404',35271:'\uF405',35272:'\uF406',35273:'\uF407',35274:'\uF408',35275:'\uF409',35276:'\uF40A',35277:'\uF40B',35278:'\uF40C',35279:'\uF40D',35280:'\uF40E',35281:'\uF40F',35282:'\uF410',35283:'\uF411',35284:'\uF412',35285:'\uF413',35286:'\uF414',35287:'\uF415',35288:'\uF416',35289:'\uF417',35290:'\uF418',35291:'\uF419',35292:'\uF41A',35293:'\uF41B',35294:'\uF41C',35295:'\uF41D',35296:'\uF41E',35297:'\uF41F',35298:'\uF420',35299:'\uF421',35300:'\uF422',35301:'\uF423',35302:'\uF424',35303:'\uF425',35304:'\uF426',35305:'\uF427',35306:'\uF428',35307:'\uF429',35308:'\uF42A',35309:'\uF42B',35310:'\uF42C',35311:'\uF42D',35312:'\uF42E',35313:'\uF42F',35314:'\uF430',35315:'\uF431',35316:'\uF432',35317:'\uF433',35318:'\uF434',35319:'\uF435',35320:'\uF436',35321:'\uF437',35322:'\uF438',35323:'\uF439',35324:'\uF43A',35325:'\uF43B',35326:'\uF43C',35392:'\uF43D',35393:'\uF43E',35394:'\uF43F',35395:'\uF440',35396:'\uF441',35397:'\uF442',35398:'\uF443',35399:'\uF444',35400:'\uF445',35401:'\uF446',35402:'\uF447',35403:'\uF448',35404:'\uF449',35405:'\uF44A',35406:'\uF44B',35407:'\uF44C',35408:'\uF44D',35409:'\uF44E',35410:'\uF44F',35411:'\uF450',35412:'\uF451',35413:'\uF452',35414:'\uF453',35415:'\uF454',35416:'\uF455',35417:'\uF456',35418:'\uF457',35419:'\uF458',35420:'\uF459',35421:'\uF45A',35422:'\uF45B',35423:'\uF45C',35424:'\uF45D',35425:'\uF45E',35426:'\uF45F',35427:'\uF460',35428:'\uF461',35429:'\uF462',35430:'\uF463',35431:'\uF464',35432:'\uF465',35433:'\uF466',35434:'\uF467',35435:'\uF468',35436:'\uF469',35437:'\uF46A',35438:'\uF46B',35439:'\uF46C',35440:'\uF46D',35441:'\uF46E',35442:'\uF46F',35443:'\uF470',35444:'\uF471',35445:'\uF472',35446:'\uF473',35447:'\uF474',35448:'\uF475',35449:'\uF476',35450:'\uF477',35451:'\uF478',35452:'\uF479',35453:'\uF47A',35454:'\uF47B',35489:'\uF47C',35490:'\uF47D',35491:'\uF47E',35492:'\uF47F',35493:'\uF480',35494:'\uF481',35495:'\uF482',35496:'\uF483',35497:'\uF484',35498:'\uF485',35499:'\uF486',35500:'\uF487',35501:'\uF488',35502:'\uF489',35503:'\uF48A',35504:'\uF48B',35505:'\uF48C',35506:'\uF48D',35507:'\uF48E',35508:'\uF48F',35509:'\uF490',35510:'\uF491',35511:'\uF492',35512:'\uF493',35513:'\uF494',35514:'\uF495',35515:'\uF496',35516:'\uF497',35517:'\uF498',35518:'\uF499',35519:'\uF49A',35520:'\uF49B',35521:'\uF49C',35522:'\uF49D',35523:'\uF49E',35524:'\uF49F',35525:'\uF4A0',35526:'\uF4A1',35527:'\uF4A2',35528:'\uF4A3',35529:'\uF4A4',35530:'\uF4A5',35531:'\uF4A6',35532:'\uF4A7',35533:'\uF4A8',35534:'\uF4A9',35535:'\uF4AA',35536:'\uF4AB',35537:'\uF4AC',35538:'\uF4AD',35539:'\uF4AE',35540:'\uF4AF',35541:'\uF4B0',35542:'\uF4B1',35543:'\uF4B2',35544:'\uF4B3',35545:'\uF4B4',35546:'\uF4B5',35547:'\uF4B6',35548:'\uF4B7',35549:'\uF4B8',35550:'\uF4B9',35551:'\uF4BA',35552:'\uF4BB',35553:'\uF4BC',35554:'\uF4BD',35555:'\uF4BE',35556:'\uF4BF',35557:'\uF4C0',35558:'\uF4C1',35559:'\uF4C2',35560:'\uF4C3',35561:'\uF4C4',35562:'\uF4C5',35563:'\uF4C6',35564:'\uF4C7',35565:'\uF4C8',35566:'\uF4C9',35567:'\uF4CA',35568:'\uF4CB',35569:'\uF4CC',35570:'\uF4CD',35571:'\uF4CE',35572:'\uF4CF',35573:'\uF4D0',35574:'\uF4D1',35575:'\uF4D2',35576:'\uF4D3',35577:'\uF4D4',35578:'\uF4D5',35579:'\uF4D6',35580:'\uF4D7',35581:'\uF4D8',35582:'\uF4D9',35648:'\uF4DA',35649:'\uF4DB',35650:'\uF4DC',35651:'\uF4DD',35652:'\uF4DE',35653:'\uF4DF',35654:'\uF4E0',35655:'\uF4E1',35656:'\uF4E2',35657:'\uF4E3',35658:'\uF4E4',35659:'\uF4E5',35660:'\uF4E6',35661:'\uF4E7',35662:'\uF4E8',35663:'\uF4E9',35664:'\uF4EA',35665:'\uF4EB',35666:'\uF4EC',35667:'\uF4ED',35668:'\uF4EE',35669:'\uF4EF',35670:'\uF4F0',35671:'\uF4F1',35672:'\uF4F2',35673:'\uF4F3',35674:'\uF4F4',35675:'\uF4F5',35676:'\uF4F6',35677:'\uF4F7',35678:'\uF4F8',35679:'\uF4F9',35680:'\uF4FA',35681:'\uF4FB',35682:'\uF4FC',35683:'\uF4FD',35684:'\uF4FE',35685:'\uF4FF',35686:'\uF500',35687:'\uF501',35688:'\uF502',35689:'\uF503',35690:'\uF504',35691:'\uF505',35692:'\uF506',35693:'\uF507',35694:'\uF508',35695:'\uF509',35696:'\uF50A',35697:'\uF50B',35698:'\uF50C',35699:'\uF50D',35700:'\uF50E',35701:'\uF50F',35702:'\uF510',35703:'\uF511',35704:'\uF512',35705:'\uF513',35706:'\uF514',35707:'\uF515',35708:'\uF516',35709:'\uF517',35710:'\uF518',35745:'\uF519',35746:'\uF51A',35747:'\uF51B',35748:'\uF51C',35749:'\uF51D',35750:'\uF51E',35751:'\uF51F',35752:'\uF520',35753:'\uF521',35754:'\uF522',35755:'\uF523',35756:'\uF524',35757:'\uF525',35758:'\uF526',35759:'\uF527',35760:'\uF528',35761:'\uF529',35762:'\uF52A',35763:'\uF52B',35764:'\uF52C',35765:'\uF52D',35766:'\uF52E',35767:'\uF52F',35768:'\uF530',35769:'\uF531',35770:'\uF532',35771:'\uF533',35772:'\uF534',35773:'\uF535',35774:'\uF536',35775:'\uF537',35776:'\uF538',35777:'\uF539',35778:'\uF53A',35779:'\uF53B',35780:'\uF53C',35781:'\uF53D',35782:'\uF53E',35783:'\uF53F',35784:'\uF540',35785:'\uF541',35786:'\uF542',35787:'\uF543',35788:'\uF544',35789:'\uF545',35790:'\uF546',35791:'\uF547',35792:'\uF548',35793:'\uF549',35794:'\uF54A',35795:'\uF54B',35796:'\uF54C',35797:'\uF54D',35798:'\uF54E',35799:'\uF54F',35800:'\uF550',35801:'\uF551',35802:'\uF552',35803:'\uF553',35804:'\uF554',35805:'\uF555',35806:'\uF556',35807:'\uF557',35808:'\uF558',35809:'\uF559',35810:'\uF55A',35811:'\uF55B',35812:'\uF55C',35813:'\uF55D',35814:'\uF55E',35815:'\uF55F',35816:'\uF560',35817:'\uF561',35818:'\uF562',35819:'\uF563',35820:'\uF564',35821:'\uF565',35822:'\uF566',35823:'\uF567',35824:'\uF568',35825:'\uF569',35826:'\uF56A',35827:'\uF56B',35828:'\uF56C',35829:'\uF56D',35830:'\uF56E',35831:'\uF56F',35832:'\uF570',35833:'\uF571',35834:'\uF572',35835:'\uF573',35836:'\uF574',35837:'\uF575',35838:'\uF576',35904:'\uF577',35905:'\uF578',35906:'\uF579',35907:'\uF57A',35908:'\uF57B',35909:'\uF57C',35910:'\uF57D',35911:'\uF57E',35912:'\uF57F',35913:'\uF580',35914:'\uF581',35915:'\uF582',35916:'\uF583',35917:'\uF584',35918:'\uF585',35919:'\uF586',35920:'\uF587',35921:'\uF588',35922:'\uF589',35923:'\uF58A',35924:'\uF58B',35925:'\uF58C',35926:'\uF58D',35927:'\uF58E',35928:'\uF58F',35929:'\uF590',35930:'\uF591',35931:'\uF592',35932:'\uF593',35933:'\uF594',35934:'\uF595',35935:'\uF596',35936:'\uF597',35937:'\uF598',35938:'\uF599',35939:'\uF59A',35940:'\uF59B',35941:'\uF59C',35942:'\uF59D',35943:'\uF59E',35944:'\uF59F',35945:'\uF5A0',35946:'\uF5A1',35947:'\uF5A2',35948:'\uF5A3',35949:'\uF5A4',35950:'\uF5A5',35951:'\uF5A6',35952:'\uF5A7',35953:'\uF5A8',35954:'\uF5A9',35955:'\uF5AA',35956:'\uF5AB',35957:'\uF5AC',35958:'\uF5AD',35959:'\uF5AE',35960:'\uF5AF',35961:'\uF5B0',35962:'\uF5B1',35963:'\uF5B2',35964:'\uF5B3',35965:'\uF5B4',35966:'\uF5B5',36001:'\uF5B6',36002:'\uF5B7',36003:'\uF5B8',36004:'\uF5B9',36005:'\uF5BA',36006:'\uF5BB',36007:'\uF5BC',36008:'\uF5BD',36009:'\uF5BE',36010:'\uF5BF',36011:'\uF5C0',36012:'\uF5C1',36013:'\uF5C2',36014:'\uF5C3',36015:'\uF5C4',36016:'\uF5C5',36017:'\uF5C6',36018:'\uF5C7',36019:'\uF5C8',36020:'\uF5C9',36021:'\uF5CA',36022:'\uF5CB',36023:'\uF5CC',36024:'\uF5CD',36025:'\uF5CE',36026:'\uF5CF',36027:'\uF5D0',36028:'\uF5D1',36029:'\uF5D2',36030:'\uF5D3',36031:'\uF5D4',36032:'\uF5D5',36033:'\uF5D6',36034:'\uF5D7',36035:'\uF5D8',36036:'\uF5D9',36037:'\uF5DA',36038:'\uF5DB',36039:'\uF5DC',36040:'\uF5DD',36041:'\uF5DE',36042:'\uF5DF',36043:'\uF5E0',36044:'\uF5E1',36045:'\uF5E2',36046:'\uF5E3',36047:'\uF5E4',36048:'\uF5E5',36049:'\uF5E6',36050:'\uF5E7',36051:'\uF5E8',36052:'\uF5E9',36053:'\uF5EA',36054:'\uF5EB',36055:'\uF5EC',36056:'\uF5ED',36057:'\uF5EE',36058:'\uF5EF',36059:'\uF5F0',36060:'\uF5F1',36061:'\uF5F2',36062:'\uF5F3',36063:'\uF5F4',36064:'\uF5F5',36065:'\uF5F6',36066:'\uF5F7',36067:'\uF5F8',36068:'\uF5F9',36069:'\uF5FA',36070:'\uF5FB',36071:'\uF5FC',36072:'\uF5FD',36073:'\uF5FE',36074:'\uF5FF',36075:'\uF600',36076:'\uF601',36077:'\uF602',36078:'\uF603',36079:'\uF604',36080:'\uF605',36081:'\uF606',36082:'\uF607',36083:'\uF608',36084:'\uF609',36085:'\uF60A',36086:'\uF60B',36087:'\uF60C',36088:'\uF60D',36089:'\uF60E',36090:'\uF60F',36091:'\uF610',36092:'\uF611',36093:'\uF612',36094:'\uF613',36160:'\uF614',36161:'\uF615',36162:'\uF616',36163:'\uF617',36164:'\uF618',36165:'\uF619',36166:'\uF61A',36167:'\uF61B',36168:'\uF61C',36169:'\uF61D',36170:'\uF61E',36171:'\uF61F',36172:'\uF620',36173:'\uF621',36174:'\uF622',36175:'\uF623',36176:'\uF624',36177:'\uF625',36178:'\uF626',36179:'\uF627',36180:'\uF628',36181:'\uF629',36182:'\uF62A',36183:'\uF62B',36184:'\uF62C',36185:'\uF62D',36186:'\uF62E',36187:'\uF62F',36188:'\uF630',36189:'\uF631',36190:'\uF632',36191:'\uF633',36192:'\uF634',36193:'\uF635',36194:'\uF636',36195:'\uF637',36196:'\uF638',36197:'\uF639',36198:'\uF63A',36199:'\uF63B',36200:'\uF63C',36201:'\uF63D',36202:'\uF63E',36203:'\uF63F',36204:'\uF640',36205:'\uF641',36206:'\uF642',36207:'\uF643',36208:'\uF644',36209:'\uF645',36210:'\uF646',36211:'\uF647',36212:'\uF648',36213:'\uF649',36214:'\uF64A',36215:'\uF64B',36216:'\uF64C',36217:'\uF64D',36218:'\uF64E',36219:'\uF64F',36220:'\uF650',36221:'\uF651',36222:'\uF652',36257:'\uF653',36258:'\uF654',36259:'\uF655',36260:'\uF656',36261:'\uF657',36262:'\uF658',36263:'\uF659',36264:'\uF65A',36265:'\uF65B',36266:'\uF65C',36267:'\uF65D',36268:'\uF65E',36269:'\uF65F',36270:'\uF660',36271:'\uF661',36272:'\uF662',36273:'\uF663',36274:'\uF664',36275:'\uF665',36276:'\uF666',36277:'\uF667',36278:'\uF668',36279:'\uF669',36280:'\uF66A',36281:'\uF66B',36282:'\uF66C',36283:'\uF66D',36284:'\uF66E',36285:'\uF66F',36286:'\uF670',36287:'\uF671',36288:'\uF672',36289:'\uF673',36290:'\uF674',36291:'\uF675',36292:'\uF676',36293:'\uF677',36294:'\uF678',36295:'\uF679',36296:'\uF67A',36297:'\uF67B',36298:'\uF67C',36299:'\uF67D',36300:'\uF67E',36301:'\uF67F',36302:'\uF680',36303:'\uF681',36304:'\uF682',36305:'\uF683',36306:'\uF684',36307:'\uF685',36308:'\uF686',36309:'\uF687',36310:'\uF688',36311:'\uF689',36312:'\uF68A',36313:'\uF68B',36314:'\uF68C',36315:'\uF68D',36316:'\uF68E',36317:'\uF68F',36318:'\uF690',36319:'\uF691',36320:'\uF692',36321:'\uF693',36322:'\uF694',36323:'\uF695',36324:'\uF696',36325:'\uF697',36326:'\uF698',36327:'\uF699',36328:'\uF69A',36329:'\uF69B',36330:'\uF69C',36331:'\uF69D',36332:'\uF69E',36333:'\uF69F',36334:'\uF6A0',36335:'\uF6A1',36336:'\uF6A2',36337:'\uF6A3',36338:'\uF6A4',36339:'\uF6A5',36340:'\uF6A6',36341:'\uF6A7',36342:'\uF6A8',36343:'\uF6A9',36344:'\uF6AA',36345:'\uF6AB',36346:'\uF6AC',36347:'\uF6AD',36348:'\uF6AE',36349:'\uF6AF',36350:'\uF6B0',36416:'\uE311',36417:'\uE312',36418:'\uE313',36419:'\uE314',36420:'\uE315',36421:'\uE316',36422:'\uE317',36423:'\uE318',36424:'\uE319',36425:'\uE31A',36426:'\uE31B',36427:'\uE31C',36428:'\uE31D',36429:'\uE31E',36430:'\uE31F',36431:'\uE320',36432:'\uE321',36433:'\uE322',36434:'\uE323',36435:'\uE324',36436:'\uE325',36437:'\uE326',36438:'\uE327',36439:'\uE328',36440:'\uE329',36441:'\uE32A',36442:'\uE32B',36443:'\uE32C',36444:'\uE32D',36445:'\uE32E',36446:'\uE32F',36447:'\uE330',36448:'\uE331',36449:'\uE332',36450:'\uE333',36451:'\uE334',36452:'\uE335',36453:'\uE336',36454:'\uE337',36455:'\uE338',36456:'\uE339',36457:'\uE33A',36458:'\uE33B',36459:'\uE33C',36460:'\uE33D',36461:'\uE33E',36462:'\uE33F',36463:'\uE340',36464:'\uE341',36465:'\uE342',36466:'\uE343',36467:'\uE344',36468:'\uE345',36469:'\uE346',36470:'\uE347',36471:'\uE348',36472:'\uE349',36473:'\uE34A',36474:'\uE34B',36475:'\uE34C',36476:'\uE34D',36477:'\uE34E',36478:'\uE34F',36513:'\uE350',36514:'\uE351',36515:'\uE352',36516:'\uE353',36517:'\uE354',36518:'\uE355',36519:'\uE356',36520:'\uE357',36521:'\uE358',36522:'\uE359',36523:'\uE35A',36524:'\uE35B',36525:'\uE35C',36526:'\uE35D',36527:'\uE35E',36528:'\uE35F',36529:'\uE360',36530:'\uE361',36531:'\uE362',36532:'\uE363',36533:'\uE364',36534:'\uE365',36535:'\uE366',36536:'\uE367',36537:'\uE368',36538:'\uE369',36539:'\uE36A',36540:'\uE36B',36541:'\uE36C',36542:'\uE36D',36543:'\uE36E',36544:'\uE36F',36545:'\uE370',36546:'\uE371',36547:'\uE372',36548:'\uE373',36549:'\uE374',36550:'\uE375',36551:'\uE376',36552:'\uE377',36553:'\uE378',36554:'\uE379',36555:'\uE37A',36556:'\uE37B',36557:'\uE37C',36558:'\uE37D',36559:'\uE37E',36560:'\uE37F',36561:'\uE380',36562:'\uE381',36563:'\uE382',36564:'\uE383',36565:'\uE384',36566:'\uE385',36567:'\uE386',36568:'\uE387',36569:'\uE388',36570:'\uE389',36571:'\uE38A',36572:'\uE38B',36573:'\uE38C',36574:'\uE38D',36575:'\uE38E',36576:'\uE38F',36577:'\uE390',36578:'\uE391',36579:'\uE392',36580:'\uE393',36581:'\uE394',36582:'\uE395',36583:'\uE396',36584:'\uE397',36585:'\uE398',36586:'\uE399',36587:'\uE39A',36588:'\uE39B',36589:'\uE39C',36590:'\uE39D',36591:'\uE39E',36592:'\uE39F',36593:'\uE3A0',36594:'\uE3A1',36595:'\uE3A2',36596:'\uE3A3',36597:'\uE3A4',36598:'\uE3A5',36599:'\uE3A6',36600:'\uE3A7',36601:'\uE3A8',36602:'\uE3A9',36603:'\uE3AA',36604:'\uE3AB',36605:'\uE3AC',36606:'\uE3AD',36672:'\uE3AE',36673:'\uE3AF',36674:'\uE3B0',36675:'\uE3B1',36676:'\uE3B2',36677:'\uE3B3',36678:'\uE3B4',36679:'\uE3B5',36680:'\uE3B6',36681:'\uE3B7',36682:'\uE3B8',36683:'\uE3B9',36684:'\uE3BA',36685:'\uE3BB',36686:'\uE3BC',36687:'\uE3BD',36688:'\uE3BE',36689:'\uE3BF',36690:'\uE3C0',36691:'\uE3C1',36692:'\uE3C2',36693:'\uE3C3',36694:'\uE3C4',36695:'\uE3C5',36696:'\uE3C6',36697:'\uE3C7',36698:'\uE3C8',36699:'\uE3C9',36700:'\uE3CA',36701:'\uE3CB',36702:'\uE3CC',36703:'\uE3CD',36704:'\uE3CE',36705:'\uE3CF',36706:'\uE3D0',36707:'\uE3D1',36708:'\uE3D2',36709:'\uE3D3',36710:'\uE3D4',36711:'\uE3D5',36712:'\uE3D6',36713:'\uE3D7',36714:'\uE3D8',36715:'\uE3D9',36716:'\uE3DA',36717:'\uE3DB',36718:'\uE3DC',36719:'\uE3DD',36720:'\uE3DE',36721:'\uE3DF',36722:'\uE3E0',36723:'\uE3E1',36724:'\uE3E2',36725:'\uE3E3',36726:'\uE3E4',36727:'\uE3E5',36728:'\uE3E6',36729:'\uE3E7',36730:'\uE3E8',36731:'\uE3E9',36732:'\uE3EA',36733:'\uE3EB',36734:'\uE3EC',36769:'\uE3ED',36770:'\uE3EE',36771:'\uE3EF',36772:'\uE3F0',36773:'\uE3F1',36774:'\uE3F2',36775:'\uE3F3',36776:'\uE3F4',36777:'\uE3F5',36778:'\uE3F6',36779:'\uE3F7',36780:'\uE3F8',36781:'\uE3F9',36782:'\uE3FA',36783:'\uE3FB',36784:'\uE3FC',36785:'\uE3FD',36786:'\uE3FE',36787:'\uE3FF',36788:'\uE400',36789:'\uE401',36790:'\uE402',36791:'\uE403',36792:'\uE404',36793:'\uE405',36794:'\uE406',36795:'\uE407',36796:'\uE408',36797:'\uE409',36798:'\uE40A',36799:'\uE40B',36800:'\uE40C',36801:'\uE40D',36802:'\uE40E',36803:'\uE40F',36804:'\uE410',36805:'\uE411',36806:'\uE412',36807:'\uE413',36808:'\uE414',36809:'\uE415',36810:'\uE416',36811:'\uE417',36812:'\uE418',36813:'\uE419',36814:'\uE41A',36815:'\uE41B',36816:'\uE41C',36817:'\uE41D',36818:'\uE41E',36819:'\uE41F',36820:'\uE420',36821:'\uE421',36822:'\uE422',36823:'\uE423',36824:'\uE424',36825:'\uE425',36826:'\uE426',36827:'\uE427',36828:'\uE428',36829:'\uE429',36830:'\uE42A',36831:'\uE42B',36832:'\uE42C',36833:'\uE42D',36834:'\uE42E',36835:'\uE42F',36836:'\uE430',36837:'\uE431',36838:'\uE432',36839:'\uE433',36840:'\uE434',36841:'\uE435',36842:'\uE436',36843:'\uE437',36844:'\uE438',36845:'\uE439',36846:'\uE43A',36847:'\uE43B',36848:'\uE43C',36849:'\uE43D',36850:'\uE43E',36851:'\uE43F',36852:'\uE440',36853:'\uE441',36854:'\uE442',36855:'\uE443',36856:'\uE444',36857:'\uE445',36858:'\uE446',36859:'\uE447',36860:'\uE448',36861:'\uE449',36862:'\uE44A',36928:'\uE44B',36929:'\uE44C',36930:'\uE44D',36931:'\uE44E',36932:'\uE44F',36933:'\uE450',36934:'\uE451',36935:'\uE452',36936:'\uE453',36937:'\uE454',36938:'\uE455',36939:'\uE456',36940:'\uE457',36941:'\uE458',36942:'\uE459',36943:'\uE45A',36944:'\uE45B',36945:'\uE45C',36946:'\uE45D',36947:'\uE45E',36948:'\uE45F',36949:'\uE460',36950:'\uE461',36951:'\uE462',36952:'\uE463',36953:'\uE464',36954:'\uE465',36955:'\uE466',36956:'\uE467',36957:'\uE468',36958:'\uE469',36959:'\uE46A',36960:'\uE46B',36961:'\uE46C',36962:'\uE46D',36963:'\uE46E',36964:'\uE46F',36965:'\uE470',36966:'\uE471',36967:'\uE472',36968:'\uE473',36969:'\uE474',36970:'\uE475',36971:'\uE476',36972:'\uE477',36973:'\uE478',36974:'\uE479',36975:'\uE47A',36976:'\uE47B',36977:'\uE47C',36978:'\uE47D',36979:'\uE47E',36980:'\uE47F',36981:'\uE480',36982:'\uE481',36983:'\uE482',36984:'\uE483',36985:'\uE484',36986:'\uE485',36987:'\uE486',36988:'\uE487',36989:'\uE488',36990:'\uE489',37025:'\uE48A',37026:'\uE48B',37027:'\uE48C',37028:'\uE48D',37029:'\uE48E',37030:'\uE48F',37031:'\uE490',37032:'\uE491',37033:'\uE492',37034:'\uE493',37035:'\uE494',37036:'\uE495',37037:'\uE496',37038:'\uE497',37039:'\uE498',37040:'\uE499',37041:'\uE49A',37042:'\uE49B',37043:'\uE49C',37044:'\uE49D',37045:'\uE49E',37046:'\uE49F',37047:'\uE4A0',37048:'\uE4A1',37049:'\uE4A2',37050:'\uE4A3',37051:'\uE4A4',37052:'\uE4A5',37053:'\uE4A6',37054:'\uE4A7',37055:'\uE4A8',37056:'\uE4A9',37057:'\uE4AA',37058:'\uE4AB',37059:'\uE4AC',37060:'\uE4AD',37061:'\uE4AE',37062:'\uE4AF',37063:'\uE4B0',37064:'\uE4B1',37065:'\uE4B2',37066:'\uE4B3',37067:'\uE4B4',37068:'\uE4B5',37069:'\uE4B6',37070:'\uE4B7',37071:'\uE4B8',37072:'\uE4B9',37073:'\uE4BA',37074:'\uE4BB',37075:'\uE4BC',37076:'\uE4BD',37077:'\uE4BE',37078:'\uE4BF',37079:'\uE4C0',37080:'\uE4C1',37081:'\uE4C2',37082:'\uE4C3',37083:'\uE4C4',37084:'\uE4C5',37085:'\uE4C6',37086:'\uE4C7',37087:'\uE4C8',37088:'\uE4C9',37089:'\uE4CA',37090:'\uE4CB',37091:'\uE4CC',37092:'\uE4CD',37093:'\uE4CE',37094:'\uE4CF',37095:'\uE4D0',37096:'\uE4D1',37097:'\uE4D2',37098:'\uE4D3',37099:'\uE4D4',37100:'\uE4D5',37101:'\uE4D6',37102:'\uE4D7',37103:'\uE4D8',37104:'\uE4D9',37105:'\uE4DA',37106:'\uE4DB',37107:'\uE4DC',37108:'\uE4DD',37109:'\uE4DE',37110:'\uE4DF',37111:'\uE4E0',37112:'\uE4E1',37113:'\uE4E2',37114:'\uE4E3',37115:'\uE4E4',37116:'\uE4E5',37117:'\uE4E6',37118:'\uE4E7',37184:'\uE4E8',37185:'\uE4E9',37186:'\uE4EA',37187:'\uE4EB',37188:'\uE4EC',37189:'\uE4ED',37190:'\uE4EE',37191:'\uE4EF',37192:'\uE4F0',37193:'\uE4F1',37194:'\uE4F2',37195:'\uE4F3',37196:'\uE4F4',37197:'\uE4F5',37198:'\uE4F6',37199:'\uE4F7',37200:'\uE4F8',37201:'\uE4F9',37202:'\uE4FA',37203:'\uE4FB',37204:'\uE4FC',37205:'\uE4FD',37206:'\uE4FE',37207:'\uE4FF',37208:'\uE500',37209:'\uE501',37210:'\uE502',37211:'\uE503',37212:'\uE504',37213:'\uE505',37214:'\uE506',37215:'\uE507',37216:'\uE508',37217:'\uE509',37218:'\uE50A',37219:'\uE50B',37220:'\uE50C',37221:'\uE50D',37222:'\uE50E',37223:'\uE50F',37224:'\uE510',37225:'\uE511',37226:'\uE512',37227:'\uE513',37228:'\uE514',37229:'\uE515',37230:'\uE516',37231:'\uE517',37232:'\uE518',37233:'\uE519',37234:'\uE51A',37235:'\uE51B',37236:'\uE51C',37237:'\uE51D',37238:'\uE51E',37239:'\uE51F',37240:'\uE520',37241:'\uE521',37242:'\uE522',37243:'\uE523',37244:'\uE524',37245:'\uE525',37246:'\uE526',37281:'\uE527',37282:'\uE528',37283:'\uE529',37284:'\uE52A',37285:'\uE52B',37286:'\uE52C',37287:'\uE52D',37288:'\uE52E',37289:'\uE52F',37290:'\uE530',37291:'\uE531',37292:'\uE532',37293:'\uE533',37294:'\uE534',37295:'\uE535',37296:'\uE536',37297:'\uE537',37298:'\uE538',37299:'\uE539',37300:'\uE53A',37301:'\uE53B',37302:'\uE53C',37303:'\uE53D',37304:'\uE53E',37305:'\uE53F',37306:'\uE540',37307:'\uE541',37308:'\uE542',37309:'\uE543',37310:'\uE544',37311:'\uE545',37312:'\uE546',37313:'\uE547',37314:'\uE548',37315:'\uE549',37316:'\uE54A',37317:'\uE54B',37318:'\uE54C',37319:'\uE54D',37320:'\uE54E',37321:'\uE54F',37322:'\uE550',37323:'\uE551',37324:'\uE552',37325:'\uE553',37326:'\uE554',37327:'\uE555',37328:'\uE556',37329:'\uE557',37330:'\uE558',37331:'\uE559',37332:'\uE55A',37333:'\uE55B',37334:'\uE55C',37335:'\uE55D',37336:'\uE55E',37337:'\uE55F',37338:'\uE560',37339:'\uE561',37340:'\uE562',37341:'\uE563',37342:'\uE564',37343:'\uE565',37344:'\uE566',37345:'\uE567',37346:'\uE568',37347:'\uE569',37348:'\uE56A',37349:'\uE56B',37350:'\uE56C',37351:'\uE56D',37352:'\uE56E',37353:'\uE56F',37354:'\uE570',37355:'\uE571',37356:'\uE572',37357:'\uE573',37358:'\uE574',37359:'\uE575',37360:'\uE576',37361:'\uE577',37362:'\uE578',37363:'\uE579',37364:'\uE57A',37365:'\uE57B',37366:'\uE57C',37367:'\uE57D',37368:'\uE57E',37369:'\uE57F',37370:'\uE580',37371:'\uE581',37372:'\uE582',37373:'\uE583',37374:'\uE584',37440:'\uE585',37441:'\uE586',37442:'\uE587',37443:'\uE588',37444:'\uE589',37445:'\uE58A',37446:'\uE58B',37447:'\uE58C',37448:'\uE58D',37449:'\uE58E',37450:'\uE58F',37451:'\uE590',37452:'\uE591',37453:'\uE592',37454:'\uE593',37455:'\uE594',37456:'\uE595',37457:'\uE596',37458:'\uE597',37459:'\uE598',37460:'\uE599',37461:'\uE59A',37462:'\uE59B',37463:'\uE59C',37464:'\uE59D',37465:'\uE59E',37466:'\uE59F',37467:'\uE5A0',37468:'\uE5A1',37469:'\uE5A2',37470:'\uE5A3',37471:'\uE5A4',37472:'\uE5A5',37473:'\uE5A6',37474:'\uE5A7',37475:'\uE5A8',37476:'\uE5A9',37477:'\uE5AA',37478:'\uE5AB',37479:'\uE5AC',37480:'\uE5AD',37481:'\uE5AE',37482:'\uE5AF',37483:'\uE5B0',37484:'\uE5B1',37485:'\uE5B2',37486:'\uE5B3',37487:'\uE5B4',37488:'\uE5B5',37489:'\uE5B6',37490:'\uE5B7',37491:'\uE5B8',37492:'\uE5B9',37493:'\uE5BA',37494:'\uE5BB',37495:'\uE5BC',37496:'\uE5BD',37497:'\uE5BE',37498:'\uE5BF',37499:'\uE5C0',37500:'\uE5C1',37501:'\uE5C2',37502:'\uE5C3',37537:'\uE5C4',37538:'\uE5C5',37539:'\uE5C6',37540:'\uE5C7',37541:'\uE5C8',37542:'\uE5C9',37543:'\uE5CA',37544:'\uE5CB',37545:'\uE5CC',37546:'\uE5CD',37547:'\uE5CE',37548:'\uE5CF',37549:'\uE5D0',37550:'\uE5D1',37551:'\uE5D2',37552:'\uE5D3',37553:'\uE5D4',37554:'\uE5D5',37555:'\uE5D6',37556:'\uE5D7',37557:'\uE5D8',37558:'\uE5D9',37559:'\uE5DA',37560:'\uE5DB',37561:'\uE5DC',37562:'\uE5DD',37563:'\uE5DE',37564:'\uE5DF',37565:'\uE5E0',37566:'\uE5E1',37567:'\uE5E2',37568:'\uE5E3',37569:'\uE5E4',37570:'\uE5E5',37571:'\uE5E6',37572:'\uE5E7',37573:'\uE5E8',37574:'\uE5E9',37575:'\uE5EA',37576:'\uE5EB',37577:'\uE5EC',37578:'\uE5ED',37579:'\uE5EE',37580:'\uE5EF',37581:'\uE5F0',37582:'\uE5F1',37583:'\uE5F2',37584:'\uE5F3',37585:'\uE5F4',37586:'\uE5F5',37587:'\uE5F6',37588:'\uE5F7',37589:'\uE5F8',37590:'\uE5F9',37591:'\uE5FA',37592:'\uE5FB',37593:'\uE5FC',37594:'\uE5FD',37595:'\uE5FE',37596:'\uE5FF',37597:'\uE600',37598:'\uE601',37599:'\uE602',37600:'\uE603',37601:'\uE604',37602:'\uE605',37603:'\uE606',37604:'\uE607',37605:'\uE608',37606:'\uE609',37607:'\uE60A',37608:'\uE60B',37609:'\uE60C',37610:'\uE60D',37611:'\uE60E',37612:'\uE60F',37613:'\uE610',37614:'\uE611',37615:'\uE612',37616:'\uE613',37617:'\uE614',37618:'\uE615',37619:'\uE616',37620:'\uE617',37621:'\uE618',37622:'\uE619',37623:'\uE61A',37624:'\uE61B',37625:'\uE61C',37626:'\uE61D',37627:'\uE61E',37628:'\uE61F',37629:'\uE620',37630:'\uE621',37696:'\uE622',37697:'\uE623',37698:'\uE624',37699:'\uE625',37700:'\uE626',37701:'\uE627',37702:'\uE628',37703:'\uE629',37704:'\uE62A',37705:'\uE62B',37706:'\uE62C',37707:'\uE62D',37708:'\uE62E',37709:'\uE62F',37710:'\uE630',37711:'\uE631',37712:'\uE632',37713:'\uE633',37714:'\uE634',37715:'\uE635',37716:'\uE636',37717:'\uE637',37718:'\uE638',37719:'\uE639',37720:'\uE63A',37721:'\uE63B',37722:'\uE63C',37723:'\uE63D',37724:'\uE63E',37725:'\uE63F',37726:'\uE640',37727:'\uE641',37728:'\uE642',37729:'\uE643',37730:'\uE644',37731:'\uE645',37732:'\uE646',37733:'\uE647',37734:'\uE648',37735:'\uE649',37736:'\uE64A',37737:'\uE64B',37738:'\uE64C',37739:'\uE64D',37740:'\uE64E',37741:'\uE64F',37742:'\uE650',37743:'\uE651',37744:'\uE652',37745:'\uE653',37746:'\uE654',37747:'\uE655',37748:'\uE656',37749:'\uE657',37750:'\uE658',37751:'\uE659',37752:'\uE65A',37753:'\uE65B',37754:'\uE65C',37755:'\uE65D',37756:'\uE65E',37757:'\uE65F',37758:'\uE660',37793:'\uE661',37794:'\uE662',37795:'\uE663',37796:'\uE664',37797:'\uE665',37798:'\uE666',37799:'\uE667',37800:'\uE668',37801:'\uE669',37802:'\uE66A',37803:'\uE66B',37804:'\uE66C',37805:'\uE66D',37806:'\uE66E',37807:'\uE66F',37808:'\uE670',37809:'\uE671',37810:'\uE672',37811:'\uE673',37812:'\uE674',37813:'\uE675',37814:'\uE676',37815:'\uE677',37816:'\uE678',37817:'\uE679',37818:'\uE67A',37819:'\uE67B',37820:'\uE67C',37821:'\uE67D',37822:'\uE67E',37823:'\uE67F',37824:'\uE680',37825:'\uE681',37826:'\uE682',37827:'\uE683',37828:'\uE684',37829:'\uE685',37830:'\uE686',37831:'\uE687',37832:'\uE688',37833:'\uE689',37834:'\uE68A',37835:'\uE68B',37836:'\uE68C',37837:'\uE68D',37838:'\uE68E',37839:'\uE68F',37840:'\uE690',37841:'\uE691',37842:'\uE692',37843:'\uE693',37844:'\uE694',37845:'\uE695',37846:'\uE696',37847:'\uE697',37848:'\uE698',37849:'\uE699',37850:'\uE69A',37851:'\uE69B',37852:'\uE69C',37853:'\uE69D',37854:'\uE69E',37855:'\uE69F',37856:'\uE6A0',37857:'\uE6A1',37858:'\uE6A2',37859:'\uE6A3',37860:'\uE6A4',37861:'\uE6A5',37862:'\uE6A6',37863:'\uE6A7',37864:'\uE6A8',37865:'\uE6A9',37866:'\uE6AA',37867:'\uE6AB',37868:'\uE6AC',37869:'\uE6AD',37870:'\uE6AE',37871:'\uE6AF',37872:'\uE6B0',37873:'\uE6B1',37874:'\uE6B2',37875:'\uE6B3',37876:'\uE6B4',37877:'\uE6B5',37878:'\uE6B6',37879:'\uE6B7',37880:'\uE6B8',37881:'\uE6B9',37882:'\uE6BA',37883:'\uE6BB',37884:'\uE6BC',37885:'\uE6BD',37886:'\uE6BE',37952:'\uE6BF',37953:'\uE6C0',37954:'\uE6C1',37955:'\uE6C2',37956:'\uE6C3',37957:'\uE6C4',37958:'\uE6C5',37959:'\uE6C6',37960:'\uE6C7',37961:'\uE6C8',37962:'\uE6C9',37963:'\uE6CA',37964:'\uE6CB',37965:'\uE6CC',37966:'\uE6CD',37967:'\uE6CE',37968:'\uE6CF',37969:'\uE6D0',37970:'\uE6D1',37971:'\uE6D2',37972:'\uE6D3',37973:'\uE6D4',37974:'\uE6D5',37975:'\uE6D6',37976:'\uE6D7',37977:'\uE6D8',37978:'\uE6D9',37979:'\uE6DA',37980:'\uE6DB',37981:'\uE6DC',37982:'\uE6DD',37983:'\uE6DE',37984:'\uE6DF',37985:'\uE6E0',37986:'\uE6E1',37987:'\uE6E2',37988:'\uE6E3',37989:'\uE6E4',37990:'\uE6E5',37991:'\uE6E6',37992:'\uE6E7',37993:'\uE6E8',37994:'\uE6E9',37995:'\uE6EA',37996:'\uE6EB',37997:'\uE6EC',37998:'\uE6ED',37999:'\uE6EE',38000:'\uE6EF',38001:'\uE6F0',38002:'\uE6F1',38003:'\uE6F2',38004:'\uE6F3',38005:'\uE6F4',38006:'\uE6F5',38007:'\uE6F6',38008:'\uE6F7',38009:'\uE6F8',38010:'\uE6F9',38011:'\uE6FA',38012:'\uE6FB',38013:'\uE6FC',38014:'\uE6FD',38049:'\uE6FE',38050:'\uE6FF',38051:'\uE700',38052:'\uE701',38053:'\uE702',38054:'\uE703',38055:'\uE704',38056:'\uE705',38057:'\uE706',38058:'\uE707',38059:'\uE708',38060:'\uE709',38061:'\uE70A',38062:'\uE70B',38063:'\uE70C',38064:'\uE70D',38065:'\uE70E',38066:'\uE70F',38067:'\uE710',38068:'\uE711',38069:'\uE712',38070:'\uE713',38071:'\uE714',38072:'\uE715',38073:'\uE716',38074:'\uE717',38075:'\uE718',38076:'\uE719',38077:'\uE71A',38078:'\uE71B',38079:'\uE71C',38080:'\uE71D',38081:'\uE71E',38082:'\uE71F',38083:'\uE720',38084:'\uE721',38085:'\uE722',38086:'\uE723',38087:'\uE724',38088:'\uE725',38089:'\uE726',38090:'\uE727',38091:'\uE728',38092:'\uE729',38093:'\uE72A',38094:'\uE72B',38095:'\uE72C',38096:'\uE72D',38097:'\uE72E',38098:'\uE72F',38099:'\uE730',38100:'\uE731',38101:'\uE732',38102:'\uE733',38103:'\uE734',38104:'\uE735',38105:'\uE736',38106:'\uE737',38107:'\uE738',38108:'\uE739',38109:'\uE73A',38110:'\uE73B',38111:'\uE73C',38112:'\uE73D',38113:'\uE73E',38114:'\uE73F',38115:'\uE740',38116:'\uE741',38117:'\uE742',38118:'\uE743',38119:'\uE744',38120:'\uE745',38121:'\uE746',38122:'\uE747',38123:'\uE748',38124:'\uE749',38125:'\uE74A',38126:'\uE74B',38127:'\uE74C',38128:'\uE74D',38129:'\uE74E',38130:'\uE74F',38131:'\uE750',38132:'\uE751',38133:'\uE752',38134:'\uE753',38135:'\uE754',38136:'\uE755',38137:'\uE756',38138:'\uE757',38139:'\uE758',38140:'\uE759',38141:'\uE75A',38142:'\uE75B',38208:'\uE75C',38209:'\uE75D',38210:'\uE75E',38211:'\uE75F',38212:'\uE760',38213:'\uE761',38214:'\uE762',38215:'\uE763',38216:'\uE764',38217:'\uE765',38218:'\uE766',38219:'\uE767',38220:'\uE768',38221:'\uE769',38222:'\uE76A',38223:'\uE76B',38224:'\uE76C',38225:'\uE76D',38226:'\uE76E',38227:'\uE76F',38228:'\uE770',38229:'\uE771',38230:'\uE772',38231:'\uE773',38232:'\uE774',38233:'\uE775',38234:'\uE776',38235:'\uE777',38236:'\uE778',38237:'\uE779',38238:'\uE77A',38239:'\uE77B',38240:'\uE77C',38241:'\uE77D',38242:'\uE77E',38243:'\uE77F',38244:'\uE780',38245:'\uE781',38246:'\uE782',38247:'\uE783',38248:'\uE784',38249:'\uE785',38250:'\uE786',38251:'\uE787',38252:'\uE788',38253:'\uE789',38254:'\uE78A',38255:'\uE78B',38256:'\uE78C',38257:'\uE78D',38258:'\uE78E',38259:'\uE78F',38260:'\uE790',38261:'\uE791',38262:'\uE792',38263:'\uE793',38264:'\uE794',38265:'\uE795',38266:'\uE796',38267:'\uE797',38268:'\uE798',38269:'\uE799',38270:'\uE79A',38305:'\uE79B',38306:'\uE79C',38307:'\uE79D',38308:'\uE79E',38309:'\uE79F',38310:'\uE7A0',38311:'\uE7A1',38312:'\uE7A2',38313:'\uE7A3',38314:'\uE7A4',38315:'\uE7A5',38316:'\uE7A6',38317:'\uE7A7',38318:'\uE7A8',38319:'\uE7A9',38320:'\uE7AA',38321:'\uE7AB',38322:'\uE7AC',38323:'\uE7AD',38324:'\uE7AE',38325:'\uE7AF',38326:'\uE7B0',38327:'\uE7B1',38328:'\uE7B2',38329:'\uE7B3',38330:'\uE7B4',38331:'\uE7B5',38332:'\uE7B6',38333:'\uE7B7',38334:'\uE7B8',38335:'\uE7B9',38336:'\uE7BA',38337:'\uE7BB',38338:'\uE7BC',38339:'\uE7BD',38340:'\uE7BE',38341:'\uE7BF',38342:'\uE7C0',38343:'\uE7C1',38344:'\uE7C2',38345:'\uE7C3',38346:'\uE7C4',38347:'\uE7C5',38348:'\uE7C6',38349:'\uE7C7',38350:'\uE7C8',38351:'\uE7C9',38352:'\uE7CA',38353:'\uE7CB',38354:'\uE7CC',38355:'\uE7CD',38356:'\uE7CE',38357:'\uE7CF',38358:'\uE7D0',38359:'\uE7D1',38360:'\uE7D2',38361:'\uE7D3',38362:'\uE7D4',38363:'\uE7D5',38364:'\uE7D6',38365:'\uE7D7',38366:'\uE7D8',38367:'\uE7D9',38368:'\uE7DA',38369:'\uE7DB',38370:'\uE7DC',38371:'\uE7DD',38372:'\uE7DE',38373:'\uE7DF',38374:'\uE7E0',38375:'\uE7E1',38376:'\uE7E2',38377:'\uE7E3',38378:'\uE7E4',38379:'\uE7E5',38380:'\uE7E6',38381:'\uE7E7',38382:'\uE7E8',38383:'\uE7E9',38384:'\uE7EA',38385:'\uE7EB',38386:'\uE7EC',38387:'\uE7ED',38388:'\uE7EE',38389:'\uE7EF',38390:'\uE7F0',38391:'\uE7F1',38392:'\uE7F2',38393:'\uE7F3',38394:'\uE7F4',38395:'\uE7F5',38396:'\uE7F6',38397:'\uE7F7',38398:'\uE7F8',38464:'\uE7F9',38465:'\uE7FA',38466:'\uE7FB',38467:'\uE7FC',38468:'\uE7FD',38469:'\uE7FE',38470:'\uE7FF',38471:'\uE800',38472:'\uE801',38473:'\uE802',38474:'\uE803',38475:'\uE804',38476:'\uE805',38477:'\uE806',38478:'\uE807',38479:'\uE808',38480:'\uE809',38481:'\uE80A',38482:'\uE80B',38483:'\uE80C',38484:'\uE80D',38485:'\uE80E',38486:'\uE80F',38487:'\uE810',38488:'\uE811',38489:'\uE812',38490:'\uE813',38491:'\uE814',38492:'\uE815',38493:'\uE816',38494:'\uE817',38495:'\uE818',38496:'\uE819',38497:'\uE81A',38498:'\uE81B',38499:'\uE81C',38500:'\uE81D',38501:'\uE81E',38502:'\uE81F',38503:'\uE820',38504:'\uE821',38505:'\uE822',38506:'\uE823',38507:'\uE824',38508:'\uE825',38509:'\uE826',38510:'\uE827',38511:'\uE828',38512:'\uE829',38513:'\uE82A',38514:'\uE82B',38515:'\uE82C',38516:'\uE82D',38517:'\uE82E',38518:'\uE82F',38519:'\uE830',38520:'\uE831',38521:'\uE832',38522:'\uE833',38523:'\uE834',38524:'\uE835',38525:'\uE836',38526:'\uE837',38561:'\uE838',38562:'\uE839',38563:'\uE83A',38564:'\uE83B',38565:'\uE83C',38566:'\uE83D',38567:'\uE83E',38568:'\uE83F',38569:'\uE840',38570:'\uE841',38571:'\uE842',38572:'\uE843',38573:'\uE844',38574:'\uE845',38575:'\uE846',38576:'\uE847',38577:'\uE848',38578:'\uE849',38579:'\uE84A',38580:'\uE84B',38581:'\uE84C',38582:'\uE84D',38583:'\uE84E',38584:'\uE84F',38585:'\uE850',38586:'\uE851',38587:'\uE852',38588:'\uE853',38589:'\uE854',38590:'\uE855',38591:'\uE856',38592:'\uE857',38593:'\uE858',38594:'\uE859',38595:'\uE85A',38596:'\uE85B',38597:'\uE85C',38598:'\uE85D',38599:'\uE85E',38600:'\uE85F',38601:'\uE860',38602:'\uE861',38603:'\uE862',38604:'\uE863',38605:'\uE864',38606:'\uE865',38607:'\uE866',38608:'\uE867',38609:'\uE868',38610:'\uE869',38611:'\uE86A',38612:'\uE86B',38613:'\uE86C',38614:'\uE86D',38615:'\uE86E',38616:'\uE86F',38617:'\uE870',38618:'\uE871',38619:'\uE872',38620:'\uE873',38621:'\uE874',38622:'\uE875',38623:'\uE876',38624:'\uE877',38625:'\uE878',38626:'\uE879',38627:'\uE87A',38628:'\uE87B',38629:'\uE87C',38630:'\uE87D',38631:'\uE87E',38632:'\uE87F',38633:'\uE880',38634:'\uE881',38635:'\uE882',38636:'\uE883',38637:'\uE884',38638:'\uE885',38639:'\uE886',38640:'\uE887',38641:'\uE888',38642:'\uE889',38643:'\uE88A',38644:'\uE88B',38645:'\uE88C',38646:'\uE88D',38647:'\uE88E',38648:'\uE88F',38649:'\uE890',38650:'\uE891',38651:'\uE892',38652:'\uE893',38653:'\uE894',38654:'\uE895',38720:'\uE896',38721:'\uE897',38722:'\uE898',38723:'\uE899',38724:'\uE89A',38725:'\uE89B',38726:'\uE89C',38727:'\uE89D',38728:'\uE89E',38729:'\uE89F',38730:'\uE8A0',38731:'\uE8A1',38732:'\uE8A2',38733:'\uE8A3',38734:'\uE8A4',38735:'\uE8A5',38736:'\uE8A6',38737:'\uE8A7',38738:'\uE8A8',38739:'\uE8A9',38740:'\uE8AA',38741:'\uE8AB',38742:'\uE8AC',38743:'\uE8AD',38744:'\uE8AE',38745:'\uE8AF',38746:'\uE8B0',38747:'\uE8B1',38748:'\uE8B2',38749:'\uE8B3',38750:'\uE8B4',38751:'\uE8B5',38752:'\uE8B6',38753:'\uE8B7',38754:'\uE8B8',38755:'\uE8B9',38756:'\uE8BA',38757:'\uE8BB',38758:'\uE8BC',38759:'\uE8BD',38760:'\uE8BE',38761:'\uE8BF',38762:'\uE8C0',38763:'\uE8C1',38764:'\uE8C2',38765:'\uE8C3',38766:'\uE8C4',38767:'\uE8C5',38768:'\uE8C6',38769:'\uE8C7',38770:'\uE8C8',38771:'\uE8C9',38772:'\uE8CA',38773:'\uE8CB',38774:'\uE8CC',38775:'\uE8CD',38776:'\uE8CE',38777:'\uE8CF',38778:'\uE8D0',38779:'\uE8D1',38780:'\uE8D2',38781:'\uE8D3',38782:'\uE8D4',38817:'\uE8D5',38818:'\uE8D6',38819:'\uE8D7',38820:'\uE8D8',38821:'\uE8D9',38822:'\uE8DA',38823:'\uE8DB',38824:'\uE8DC',38825:'\uE8DD',38826:'\uE8DE',38827:'\uE8DF',38828:'\uE8E0',38829:'\uE8E1',38830:'\uE8E2',38831:'\uE8E3',38832:'\uE8E4',38833:'\uE8E5',38834:'\uE8E6',38835:'\uE8E7',38836:'\uE8E8',38837:'\uE8E9',38838:'\uE8EA',38839:'\uE8EB',38840:'\uE8EC',38841:'\uE8ED',38842:'\uE8EE',38843:'\uE8EF',38844:'\uE8F0',38845:'\uE8F1',38846:'\uE8F2',38847:'\uE8F3',38848:'\uE8F4',38849:'\uE8F5',38850:'\uE8F6',38851:'\uE8F7',38852:'\uE8F8',38853:'\uE8F9',38854:'\uE8FA',38855:'\uE8FB',38856:'\uE8FC',38857:'\uE8FD',38858:'\uE8FE',38859:'\uE8FF',38860:'\uE900',38861:'\uE901',38862:'\uE902',38863:'\uE903',38864:'\uE904',38865:'\uE905',38866:'\uE906',38867:'\uE907',38868:'\uE908',38869:'\uE909',38870:'\uE90A',38871:'\uE90B',38872:'\uE90C',38873:'\uE90D',38874:'\uE90E',38875:'\uE90F',38876:'\uE910',38877:'\uE911',38878:'\uE912',38879:'\uE913',38880:'\uE914',38881:'\uE915',38882:'\uE916',38883:'\uE917',38884:'\uE918',38885:'\uE919',38886:'\uE91A',38887:'\uE91B',38888:'\uE91C',38889:'\uE91D',38890:'\uE91E',38891:'\uE91F',38892:'\uE920',38893:'\uE921',38894:'\uE922',38895:'\uE923',38896:'\uE924',38897:'\uE925',38898:'\uE926',38899:'\uE927',38900:'\uE928',38901:'\uE929',38902:'\uE92A',38903:'\uE92B',38904:'\uE92C',38905:'\uE92D',38906:'\uE92E',38907:'\uE92F',38908:'\uE930',38909:'\uE931',38910:'\uE932',38976:'\uE933',38977:'\uE934',38978:'\uE935',38979:'\uE936',38980:'\uE937',38981:'\uE938',38982:'\uE939',38983:'\uE93A',38984:'\uE93B',38985:'\uE93C',38986:'\uE93D',38987:'\uE93E',38988:'\uE93F',38989:'\uE940',38990:'\uE941',38991:'\uE942',38992:'\uE943',38993:'\uE944',38994:'\uE945',38995:'\uE946',38996:'\uE947',38997:'\uE948',38998:'\uE949',38999:'\uE94A',39000:'\uE94B',39001:'\uE94C',39002:'\uE94D',39003:'\uE94E',39004:'\uE94F',39005:'\uE950',39006:'\uE951',39007:'\uE952',39008:'\uE953',39009:'\uE954',39010:'\uE955',39011:'\uE956',39012:'\uE957',39013:'\uE958',39014:'\uE959',39015:'\uE95A',39016:'\uE95B',39017:'\uE95C',39018:'\uE95D',39019:'\uE95E',39020:'\uE95F',39021:'\uE960',39022:'\uE961',39023:'\uE962',39024:'\uE963',39025:'\uE964',39026:'\uE965',39027:'\uE966',39028:'\uE967',39029:'\uE968',39030:'\uE969',39031:'\uE96A',39032:'\uE96B',39033:'\uE96C',39034:'\uE96D',39035:'\uE96E',39036:'\uE96F',39037:'\uE970',39038:'\uE971',39073:'\uE972',39074:'\uE973',39075:'\uE974',39076:'\uE975',39077:'\uE976',39078:'\uE977',39079:'\uE978',39080:'\uE979',39081:'\uE97A',39082:'\uE97B',39083:'\uE97C',39084:'\uE97D',39085:'\uE97E',39086:'\uE97F',39087:'\uE980',39088:'\uE981',39089:'\uE982',39090:'\uE983',39091:'\uE984',39092:'\uE985',39093:'\uE986',39094:'\uE987',39095:'\uE988',39096:'\uE989',39097:'\uE98A',39098:'\uE98B',39099:'\uE98C',39100:'\uE98D',39101:'\uE98E',39102:'\uE98F',39103:'\uE990',39104:'\uE991',39105:'\uE992',39106:'\uE993',39107:'\uE994',39108:'\uE995',39109:'\uE996',39110:'\uE997',39111:'\uE998',39112:'\uE999',39113:'\uE99A',39114:'\uE99B',39115:'\uE99C',39116:'\uE99D',39117:'\uE99E',39118:'\uE99F',39119:'\uE9A0',39120:'\uE9A1',39121:'\uE9A2',39122:'\uE9A3',39123:'\uE9A4',39124:'\uE9A5',39125:'\uE9A6',39126:'\uE9A7',39127:'\uE9A8',39128:'\uE9A9',39129:'\uE9AA',39130:'\uE9AB',39131:'\uE9AC',39132:'\uE9AD',39133:'\uE9AE',39134:'\uE9AF',39135:'\uE9B0',39136:'\uE9B1',39137:'\uE9B2',39138:'\uE9B3',39139:'\uE9B4',39140:'\uE9B5',39141:'\uE9B6',39142:'\uE9B7',39143:'\uE9B8',39144:'\uE9B9',39145:'\uE9BA',39146:'\uE9BB',39147:'\uE9BC',39148:'\uE9BD',39149:'\uE9BE',39150:'\uE9BF',39151:'\uE9C0',39152:'\uE9C1',39153:'\uE9C2',39154:'\uE9C3',39155:'\uE9C4',39156:'\uE9C5',39157:'\uE9C6',39158:'\uE9C7',39159:'\uE9C8',39160:'\uE9C9',39161:'\uE9CA',39162:'\uE9CB',39163:'\uE9CC',39164:'\uE9CD',39165:'\uE9CE',39166:'\uE9CF',39232:'\uE9D0',39233:'\uE9D1',39234:'\uE9D2',39235:'\uE9D3',39236:'\uE9D4',39237:'\uE9D5',39238:'\uE9D6',39239:'\uE9D7',39240:'\uE9D8',39241:'\uE9D9',39242:'\uE9DA',39243:'\uE9DB',39244:'\uE9DC',39245:'\uE9DD',39246:'\uE9DE',39247:'\uE9DF',39248:'\uE9E0',39249:'\uE9E1',39250:'\uE9E2',39251:'\uE9E3',39252:'\uE9E4',39253:'\uE9E5',39254:'\uE9E6',39255:'\uE9E7',39256:'\uE9E8',39257:'\uE9E9',39258:'\uE9EA',39259:'\uE9EB',39260:'\uE9EC',39261:'\uE9ED',39262:'\uE9EE',39263:'\uE9EF',39264:'\uE9F0',39265:'\uE9F1',39266:'\uE9F2',39267:'\uE9F3',39268:'\uE9F4',39269:'\uE9F5',39270:'\uE9F6',39271:'\uE9F7',39272:'\uE9F8',39273:'\uE9F9',39274:'\uE9FA',39275:'\uE9FB',39276:'\uE9FC',39277:'\uE9FD',39278:'\uE9FE',39279:'\uE9FF',39280:'\uEA00',39281:'\uEA01',39282:'\uEA02',39283:'\uEA03',39284:'\uEA04',39285:'\uEA05',39286:'\uEA06',39287:'\uEA07',39288:'\uEA08',39289:'\uEA09',39290:'\uEA0A',39291:'\uEA0B',39292:'\uEA0C',39293:'\uEA0D',39294:'\uEA0E',39329:'\uEA0F',39330:'\uEA10',39331:'\uEA11',39332:'\uEA12',39333:'\uEA13',39334:'\uEA14',39335:'\uEA15',39336:'\uEA16',39337:'\uEA17',39338:'\uEA18',39339:'\uEA19',39340:'\uEA1A',39341:'\uEA1B',39342:'\uEA1C',39343:'\uEA1D',39344:'\uEA1E',39345:'\uEA1F',39346:'\uEA20',39347:'\uEA21',39348:'\uEA22',39349:'\uEA23',39350:'\uEA24',39351:'\uEA25',39352:'\uEA26',39353:'\uEA27',39354:'\uEA28',39355:'\uEA29',39356:'\uEA2A',39357:'\uEA2B',39358:'\uEA2C',39359:'\uEA2D',39360:'\uEA2E',39361:'\uEA2F',39362:'\uEA30',39363:'\uEA31',39364:'\uEA32',39365:'\uEA33',39366:'\uEA34',39367:'\uEA35',39368:'\uEA36',39369:'\uEA37',39370:'\uEA38',39371:'\uEA39',39372:'\uEA3A',39373:'\uEA3B',39374:'\uEA3C',39375:'\uEA3D',39376:'\uEA3E',39377:'\uEA3F',39378:'\uEA40',39379:'\uEA41',39380:'\uEA42',39381:'\uEA43',39382:'\uEA44',39383:'\uEA45',39384:'\uEA46',39385:'\uEA47',39386:'\uEA48',39387:'\uEA49',39388:'\uEA4A',39389:'\uEA4B',39390:'\uEA4C',39391:'\uEA4D',39392:'\uEA4E',39393:'\uEA4F',39394:'\uEA50',39395:'\uEA51',39396:'\uEA52',39397:'\uEA53',39398:'\uEA54',39399:'\uEA55',39400:'\uEA56',39401:'\uEA57',39402:'\uEA58',39403:'\uEA59',39404:'\uEA5A',39405:'\uEA5B',39406:'\uEA5C',39407:'\uEA5D',39408:'\uEA5E',39409:'\uEA5F',39410:'\uEA60',39411:'\uEA61',39412:'\uEA62',39413:'\uEA63',39414:'\uEA64',39415:'\uEA65',39416:'\uEA66',39417:'\uEA67',39418:'\uEA68',39419:'\uEA69',39420:'\uEA6A',39421:'\uEA6B',39422:'\uEA6C',39488:'\uEA6D',39489:'\uEA6E',39490:'\uEA6F',39491:'\uEA70',39492:'\uEA71',39493:'\uEA72',39494:'\uEA73',39495:'\uEA74',39496:'\uEA75',39497:'\uEA76',39498:'\uEA77',39499:'\uEA78',39500:'\uEA79',39501:'\uEA7A',39502:'\uEA7B',39503:'\uEA7C',39504:'\uEA7D',39505:'\uEA7E',39506:'\uEA7F',39507:'\uEA80',39508:'\uEA81',39509:'\uEA82',39510:'\uEA83',39511:'\uEA84',39512:'\uEA85',39513:'\uEA86',39514:'\uEA87',39515:'\uEA88',39516:'\uEA89',39517:'\uEA8A',39518:'\uEA8B',39519:'\uEA8C',39520:'\uEA8D',39521:'\uEA8E',39522:'\uEA8F',39523:'\uEA90',39524:'\uEA91',39525:'\uEA92',39526:'\uEA93',39527:'\uEA94',39528:'\uEA95',39529:'\uEA96',39530:'\uEA97',39531:'\uEA98',39532:'\uEA99',39533:'\uEA9A',39534:'\uEA9B',39535:'\uEA9C',39536:'\uEA9D',39537:'\uEA9E',39538:'\uEA9F',39539:'\uEAA0',39540:'\uEAA1',39541:'\uEAA2',39542:'\uEAA3',39543:'\uEAA4',39544:'\uEAA5',39545:'\uEAA6',39546:'\uEAA7',39547:'\uEAA8',39548:'\uEAA9',39549:'\uEAAA',39550:'\uEAAB',39585:'\uEAAC',39586:'\uEAAD',39587:'\uEAAE',39588:'\uEAAF',39589:'\uEAB0',39590:'\uEAB1',39591:'\uEAB2',39592:'\uEAB3',39593:'\uEAB4',39594:'\uEAB5',39595:'\uEAB6',39596:'\uEAB7',39597:'\uEAB8',39598:'\uEAB9',39599:'\uEABA',39600:'\uEABB',39601:'\uEABC',39602:'\uEABD',39603:'\uEABE',39604:'\uEABF',39605:'\uEAC0',39606:'\uEAC1',39607:'\uEAC2',39608:'\uEAC3',39609:'\uEAC4',39610:'\uEAC5',39611:'\uEAC6',39612:'\uEAC7',39613:'\uEAC8',39614:'\uEAC9',39615:'\uEACA',39616:'\uEACB',39617:'\uEACC',39618:'\uEACD',39619:'\uEACE',39620:'\uEACF',39621:'\uEAD0',39622:'\uEAD1',39623:'\uEAD2',39624:'\uEAD3',39625:'\uEAD4',39626:'\uEAD5',39627:'\uEAD6',39628:'\uEAD7',39629:'\uEAD8',39630:'\uEAD9',39631:'\uEADA',39632:'\uEADB',39633:'\uEADC',39634:'\uEADD',39635:'\uEADE',39636:'\uEADF',39637:'\uEAE0',39638:'\uEAE1',39639:'\uEAE2',39640:'\uEAE3',39641:'\uEAE4',39642:'\uEAE5',39643:'\uEAE6',39644:'\uEAE7',39645:'\uEAE8',39646:'\uEAE9',39647:'\uEAEA',39648:'\uEAEB',39649:'\uEAEC',39650:'\uEAED',39651:'\uEAEE',39652:'\uEAEF',39653:'\uEAF0',39654:'\uEAF1',39655:'\uEAF2',39656:'\uEAF3',39657:'\uEAF4',39658:'\uEAF5',39659:'\uEAF6',39660:'\uEAF7',39661:'\uEAF8',39662:'\uEAF9',39663:'\uEAFA',39664:'\uEAFB',39665:'\uEAFC',39666:'\uEAFD',39667:'\uEAFE',39668:'\uEAFF',39669:'\uEB00',39670:'\uEB01',39671:'\uEB02',39672:'\uEB03',39673:'\uEB04',39674:'\uEB05',39675:'\uEB06',39676:'\uEB07',39677:'\uEB08',39678:'\uEB09',39744:'\uEB0A',39745:'\uEB0B',39746:'\uEB0C',39747:'\uEB0D',39748:'\uEB0E',39749:'\uEB0F',39750:'\uEB10',39751:'\uEB11',39752:'\uEB12',39753:'\uEB13',39754:'\uEB14',39755:'\uEB15',39756:'\uEB16',39757:'\uEB17',39758:'\uEB18',39759:'\uEB19',39760:'\uEB1A',39761:'\uEB1B',39762:'\uEB1C',39763:'\uEB1D',39764:'\uEB1E',39765:'\uEB1F',39766:'\uEB20',39767:'\uEB21',39768:'\uEB22',39769:'\uEB23',39770:'\uEB24',39771:'\uEB25',39772:'\uEB26',39773:'\uEB27',39774:'\uEB28',39775:'\uEB29',39776:'\uEB2A',39777:'\uEB2B',39778:'\uEB2C',39779:'\uEB2D',39780:'\uEB2E',39781:'\uEB2F',39782:'\uEB30',39783:'\uEB31',39784:'\uEB32',39785:'\uEB33',39786:'\uEB34',39787:'\uEB35',39788:'\uEB36',39789:'\uEB37',39790:'\uEB38',39791:'\uEB39',39792:'\uEB3A',39793:'\uEB3B',39794:'\uEB3C',39795:'\uEB3D',39796:'\uEB3E',39797:'\uEB3F',39798:'\uEB40',39799:'\uEB41',39800:'\uEB42',39801:'\uEB43',39802:'\uEB44',39803:'\uEB45',39804:'\uEB46',39805:'\uEB47',39806:'\uEB48',39841:'\uEB49',39842:'\uEB4A',39843:'\uEB4B',39844:'\uEB4C',39845:'\uEB4D',39846:'\uEB4E',39847:'\uEB4F',39848:'\uEB50',39849:'\uEB51',39850:'\uEB52',39851:'\uEB53',39852:'\uEB54',39853:'\uEB55',39854:'\uEB56',39855:'\uEB57',39856:'\uEB58',39857:'\uEB59',39858:'\uEB5A',39859:'\uEB5B',39860:'\uEB5C',39861:'\uEB5D',39862:'\uEB5E',39863:'\uEB5F',39864:'\uEB60',39865:'\uEB61',39866:'\uEB62',39867:'\uEB63',39868:'\uEB64',39869:'\uEB65',39870:'\uEB66',39871:'\uEB67',39872:'\uEB68',39873:'\uEB69',39874:'\uEB6A',39875:'\uEB6B',39876:'\uEB6C',39877:'\uEB6D',39878:'\uEB6E',39879:'\uEB6F',39880:'\uEB70',39881:'\uEB71',39882:'\uEB72',39883:'\uEB73',39884:'\uEB74',39885:'\uEB75',39886:'\uEB76',39887:'\uEB77',39888:'\uEB78',39889:'\uEB79',39890:'\uEB7A',39891:'\uEB7B',39892:'\uEB7C',39893:'\uEB7D',39894:'\uEB7E',39895:'\uEB7F',39896:'\uEB80',39897:'\uEB81',39898:'\uEB82',39899:'\uEB83',39900:'\uEB84',39901:'\uEB85',39902:'\uEB86',39903:'\uEB87',39904:'\uEB88',39905:'\uEB89',39906:'\uEB8A',39907:'\uEB8B',39908:'\uEB8C',39909:'\uEB8D',39910:'\uEB8E',39911:'\uEB8F',39912:'\uEB90',39913:'\uEB91',39914:'\uEB92',39915:'\uEB93',39916:'\uEB94',39917:'\uEB95',39918:'\uEB96',39919:'\uEB97',39920:'\uEB98',39921:'\uEB99',39922:'\uEB9A',39923:'\uEB9B',39924:'\uEB9C',39925:'\uEB9D',39926:'\uEB9E',39927:'\uEB9F',39928:'\uEBA0',39929:'\uEBA1',39930:'\uEBA2',39931:'\uEBA3',39932:'\uEBA4',39933:'\uEBA5',39934:'\uEBA6',40000:'\uEBA7',40001:'\uEBA8',40002:'\uEBA9',40003:'\uEBAA',40004:'\uEBAB',40005:'\uEBAC',40006:'\uEBAD',40007:'\uEBAE',40008:'\uEBAF',40009:'\uEBB0',40010:'\uEBB1',40011:'\uEBB2',40012:'\uEBB3',40013:'\uEBB4',40014:'\uEBB5',40015:'\uEBB6',40016:'\uEBB7',40017:'\uEBB8',40018:'\uEBB9',40019:'\uEBBA',40020:'\uEBBB',40021:'\uEBBC',40022:'\uEBBD',40023:'\uEBBE',40024:'\uEBBF',40025:'\uEBC0',40026:'\uEBC1',40027:'\uEBC2',40028:'\uEBC3',40029:'\uEBC4',40030:'\uEBC5',40031:'\uEBC6',40032:'\uEBC7',40033:'\uEBC8',40034:'\uEBC9',40035:'\uEBCA',40036:'\uEBCB',40037:'\uEBCC',40038:'\uEBCD',40039:'\uEBCE',40040:'\uEBCF',40041:'\uEBD0',40042:'\uEBD1',40043:'\uEBD2',40044:'\uEBD3',40045:'\uEBD4',40046:'\uEBD5',40047:'\uEBD6',40048:'\uEBD7',40049:'\uEBD8',40050:'\uEBD9',40051:'\uEBDA',40052:'\uEBDB',40053:'\uEBDC',40054:'\uEBDD',40055:'\uEBDE',40056:'\uEBDF',40057:'\uEBE0',40058:'\uEBE1',40059:'\uEBE2',40060:'\uEBE3',40061:'\uEBE4',40062:'\uEBE5',40097:'\uEBE6',40098:'\uEBE7',40099:'\uEBE8',40100:'\uEBE9',40101:'\uEBEA',40102:'\uEBEB',40103:'\uEBEC',40104:'\uEBED',40105:'\uEBEE',40106:'\uEBEF',40107:'\uEBF0',40108:'\uEBF1',40109:'\uEBF2',40110:'\uEBF3',40111:'\uEBF4',40112:'\uEBF5',40113:'\uEBF6',40114:'\uEBF7',40115:'\uEBF8',40116:'\uEBF9',40117:'\uEBFA',40118:'\uEBFB',40119:'\uEBFC',40120:'\uEBFD',40121:'\uEBFE',40122:'\uEBFF',40123:'\uEC00',40124:'\uEC01',40125:'\uEC02',40126:'\uEC03',40127:'\uEC04',40128:'\uEC05',40129:'\uEC06',40130:'\uEC07',40131:'\uEC08',40132:'\uEC09',40133:'\uEC0A',40134:'\uEC0B',40135:'\uEC0C',40136:'\uEC0D',40137:'\uEC0E',40138:'\uEC0F',40139:'\uEC10',40140:'\uEC11',40141:'\uEC12',40142:'\uEC13',40143:'\uEC14',40144:'\uEC15',40145:'\uEC16',40146:'\uEC17',40147:'\uEC18',40148:'\uEC19',40149:'\uEC1A',40150:'\uEC1B',40151:'\uEC1C',40152:'\uEC1D',40153:'\uEC1E',40154:'\uEC1F',40155:'\uEC20',40156:'\uEC21',40157:'\uEC22',40158:'\uEC23',40159:'\uEC24',40160:'\uEC25',40161:'\uEC26',40162:'\uEC27',40163:'\uEC28',40164:'\uEC29',40165:'\uEC2A',40166:'\uEC2B',40167:'\uEC2C',40168:'\uEC2D',40169:'\uEC2E',40170:'\uEC2F',40171:'\uEC30',40172:'\uEC31',40173:'\uEC32',40174:'\uEC33',40175:'\uEC34',40176:'\uEC35',40177:'\uEC36',40178:'\uEC37',40179:'\uEC38',40180:'\uEC39',40181:'\uEC3A',40182:'\uEC3B',40183:'\uEC3C',40184:'\uEC3D',40185:'\uEC3E',40186:'\uEC3F',40187:'\uEC40',40188:'\uEC41',40189:'\uEC42',40190:'\uEC43',40256:'\uEC44',40257:'\uEC45',40258:'\uEC46',40259:'\uEC47',40260:'\uEC48',40261:'\uEC49',40262:'\uEC4A',40263:'\uEC4B',40264:'\uEC4C',40265:'\uEC4D',40266:'\uEC4E',40267:'\uEC4F',40268:'\uEC50',40269:'\uEC51',40270:'\uEC52',40271:'\uEC53',40272:'\uEC54',40273:'\uEC55',40274:'\uEC56',40275:'\uEC57',40276:'\uEC58',40277:'\uEC59',40278:'\uEC5A',40279:'\uEC5B',40280:'\uEC5C',40281:'\uEC5D',40282:'\uEC5E',40283:'\uEC5F',40284:'\uEC60',40285:'\uEC61',40286:'\uEC62',40287:'\uEC63',40288:'\uEC64',40289:'\uEC65',40290:'\uEC66',40291:'\uEC67',40292:'\uEC68',40293:'\uEC69',40294:'\uEC6A',40295:'\uEC6B',40296:'\uEC6C',40297:'\uEC6D',40298:'\uEC6E',40299:'\uEC6F',40300:'\uEC70',40301:'\uEC71',40302:'\uEC72',40303:'\uEC73',40304:'\uEC74',40305:'\uEC75',40306:'\uEC76',40307:'\uEC77',40308:'\uEC78',40309:'\uEC79',40310:'\uEC7A',40311:'\uEC7B',40312:'\uEC7C',40313:'\uEC7D',40314:'\uEC7E',40315:'\uEC7F',40316:'\uEC80',40317:'\uEC81',40318:'\uEC82',40353:'\uEC83',40354:'\uEC84',40355:'\uEC85',40356:'\uEC86',40357:'\uEC87',40358:'\uEC88',40359:'\uEC89',40360:'\uEC8A',40361:'\uEC8B',40362:'\uEC8C',40363:'\uEC8D',40364:'\uEC8E',40365:'\uEC8F',40366:'\uEC90',40367:'\uEC91',40368:'\uEC92',40369:'\uEC93',40370:'\uEC94',40371:'\uEC95',40372:'\uEC96',40373:'\uEC97',40374:'\uEC98',40375:'\uEC99',40376:'\uEC9A',40377:'\uEC9B',40378:'\uEC9C',40379:'\uEC9D',40380:'\uEC9E',40381:'\uEC9F',40382:'\uECA0',40383:'\uECA1',40384:'\uECA2',40385:'\uECA3',40386:'\uECA4',40387:'\uECA5',40388:'\uECA6',40389:'\uECA7',40390:'\uECA8',40391:'\uECA9',40392:'\uECAA',40393:'\uECAB',40394:'\uECAC',40395:'\uECAD',40396:'\uECAE',40397:'\uECAF',40398:'\uECB0',40399:'\uECB1',40400:'\uECB2',40401:'\uECB3',40402:'\uECB4',40403:'\uECB5',40404:'\uECB6',40405:'\uECB7',40406:'\uECB8',40407:'\uECB9',40408:'\uECBA',40409:'\uECBB',40410:'\uECBC',40411:'\uECBD',40412:'\uECBE',40413:'\uECBF',40414:'\uECC0',40415:'\uECC1',40416:'\uECC2',40417:'\uECC3',40418:'\uECC4',40419:'\uECC5',40420:'\uECC6',40421:'\uECC7',40422:'\uECC8',40423:'\uECC9',40424:'\uECCA',40425:'\uECCB',40426:'\uECCC',40427:'\uECCD',40428:'\uECCE',40429:'\uECCF',40430:'\uECD0',40431:'\uECD1',40432:'\uECD2',40433:'\uECD3',40434:'\uECD4',40435:'\uECD5',40436:'\uECD6',40437:'\uECD7',40438:'\uECD8',40439:'\uECD9',40440:'\uECDA',40441:'\uECDB',40442:'\uECDC',40443:'\uECDD',40444:'\uECDE',40445:'\uECDF',40446:'\uECE0',40512:'\uECE1',40513:'\uECE2',40514:'\uECE3',40515:'\uECE4',40516:'\uECE5',40517:'\uECE6',40518:'\uECE7',40519:'\uECE8',40520:'\uECE9',40521:'\uECEA',40522:'\uECEB',40523:'\uECEC',40524:'\uECED',40525:'\uECEE',40526:'\uECEF',40527:'\uECF0',40528:'\uECF1',40529:'\uECF2',40530:'\uECF3',40531:'\uECF4',40532:'\uECF5',40533:'\uECF6',40534:'\uECF7',40535:'\uECF8',40536:'\uECF9',40537:'\uECFA',40538:'\uECFB',40539:'\uECFC',40540:'\uECFD',40541:'\uECFE',40542:'\uECFF',40543:'\uED00',40544:'\uED01',40545:'\uED02',40546:'\uED03',40547:'\uED04',40548:'\uED05',40549:'\uED06',40550:'\uED07',40551:'\uED08',40552:'\uED09',40553:'\uED0A',40554:'\uED0B',40555:'\uED0C',40556:'\uED0D',40557:'\uED0E',40558:'\uED0F',40559:'\uED10',40560:'\uED11',40561:'\uED12',40562:'\uED13',40563:'\uED14',40564:'\uED15',40565:'\uED16',40566:'\uED17',40567:'\uED18',40568:'\uED19',40569:'\uED1A',40570:'\uED1B',40571:'\uED1C',40572:'\uED1D',40573:'\uED1E',40574:'\uED1F',40609:'\uED20',40610:'\uED21',40611:'\uED22',40612:'\uED23',40613:'\uED24',40614:'\uED25',40615:'\uED26',40616:'\uED27',40617:'\uED28',40618:'\uED29',40619:'\uED2A',40620:'\uED2B',40621:'\uED2C',40622:'\uED2D',40623:'\uED2E',40624:'\uED2F',40625:'\uED30',40626:'\uED31',40627:'\uED32',40628:'\uED33',40629:'\uED34',40630:'\uED35',40631:'\uED36',40632:'\uED37',40633:'\uED38',40634:'\uED39',40635:'\uED3A',40636:'\uED3B',40637:'\uED3C',40638:'\uED3D',40639:'\uED3E',40640:'\uED3F',40641:'\uED40',40642:'\uED41',40643:'\uED42',40644:'\uED43',40645:'\uED44',40646:'\uED45',40647:'\uED46',40648:'\uED47',40649:'\uED48',40650:'\uED49',40651:'\uED4A',40652:'\uED4B',40653:'\uED4C',40654:'\uED4D',40655:'\uED4E',40656:'\uED4F',40657:'\uED50',40658:'\uED51',40659:'\uED52',40660:'\uED53',40661:'\uED54',40662:'\uED55',40663:'\uED56',40664:'\uED57',40665:'\uED58',40666:'\uED59',40667:'\uED5A',40668:'\uED5B',40669:'\uED5C',40670:'\uED5D',40671:'\uED5E',40672:'\uED5F',40673:'\uED60',40674:'\uED61',40675:'\uED62',40676:'\uED63',40677:'\uED64',40678:'\uED65',40679:'\uED66',40680:'\uED67',40681:'\uED68',40682:'\uED69',40683:'\uED6A',40684:'\uED6B',40685:'\uED6C',40686:'\uED6D',40687:'\uED6E',40688:'\uED6F',40689:'\uED70',40690:'\uED71',40691:'\uED72',40692:'\uED73',40693:'\uED74',40694:'\uED75',40695:'\uED76',40696:'\uED77',40697:'\uED78',40698:'\uED79',40699:'\uED7A',40700:'\uED7B',40701:'\uED7C',40702:'\uED7D',40768:'\uED7E',40769:'\uED7F',40770:'\uED80',40771:'\uED81',40772:'\uED82',40773:'\uED83',40774:'\uED84',40775:'\uED85',40776:'\uED86',40777:'\uED87',40778:'\uED88',40779:'\uED89',40780:'\uED8A',40781:'\uED8B',40782:'\uED8C',40783:'\uED8D',40784:'\uED8E',40785:'\uED8F',40786:'\uED90',40787:'\uED91',40788:'\uED92',40789:'\uED93',40790:'\uED94',40791:'\uED95',40792:'\uED96',40793:'\uED97',40794:'\uED98',40795:'\uED99',40796:'\uED9A',40797:'\uED9B',40798:'\uED9C',40799:'\uED9D',40800:'\uED9E',40801:'\uED9F',40802:'\uEDA0',40803:'\uEDA1',40804:'\uEDA2',40805:'\uEDA3',40806:'\uEDA4',40807:'\uEDA5',40808:'\uEDA6',40809:'\uEDA7',40810:'\uEDA8',40811:'\uEDA9',40812:'\uEDAA',40813:'\uEDAB',40814:'\uEDAC',40815:'\uEDAD',40816:'\uEDAE',40817:'\uEDAF',40818:'\uEDB0',40819:'\uEDB1',40820:'\uEDB2',40821:'\uEDB3',40822:'\uEDB4',40823:'\uEDB5',40824:'\uEDB6',40825:'\uEDB7',40826:'\uEDB8',40827:'\uEDB9',40828:'\uEDBA',40829:'\uEDBB',40830:'\uEDBC',40865:'\uEDBD',40866:'\uEDBE',40867:'\uEDBF',40868:'\uEDC0',40869:'\uEDC1',40870:'\uEDC2',40871:'\uEDC3',40872:'\uEDC4',40873:'\uEDC5',40874:'\uEDC6',40875:'\uEDC7',40876:'\uEDC8',40877:'\uEDC9',40878:'\uEDCA',40879:'\uEDCB',40880:'\uEDCC',40881:'\uEDCD',40882:'\uEDCE',40883:'\uEDCF',40884:'\uEDD0',40885:'\uEDD1',40886:'\uEDD2',40887:'\uEDD3',40888:'\uEDD4',40889:'\uEDD5',40890:'\uEDD6',40891:'\uEDD7',40892:'\uEDD8',40893:'\uEDD9',40894:'\uEDDA',40895:'\uEDDB',40896:'\uEDDC',40897:'\uEDDD',40898:'\uEDDE',40899:'\uEDDF',40900:'\uEDE0',40901:'\uEDE1',40902:'\uEDE2',40903:'\uEDE3',40904:'\uEDE4',40905:'\uEDE5',40906:'\uEDE6',40907:'\uEDE7',40908:'\uEDE8',40909:'\uEDE9',40910:'\uEDEA',40911:'\uEDEB',40912:'\uEDEC',40913:'\uEDED',40914:'\uEDEE',40915:'\uEDEF',40916:'\uEDF0',40917:'\uEDF1',40918:'\uEDF2',40919:'\uEDF3',40920:'\uEDF4',40921:'\uEDF5',40922:'\uEDF6',40923:'\uEDF7',40924:'\uEDF8',40925:'\uEDF9',40926:'\uEDFA',40927:'\uEDFB',40928:'\uEDFC',40929:'\uEDFD',40930:'\uEDFE',40931:'\uEDFF',40932:'\uEE00',40933:'\uEE01',40934:'\uEE02',40935:'\uEE03',40936:'\uEE04',40937:'\uEE05',40938:'\uEE06',40939:'\uEE07',40940:'\uEE08',40941:'\uEE09',40942:'\uEE0A',40943:'\uEE0B',40944:'\uEE0C',40945:'\uEE0D',40946:'\uEE0E',40947:'\uEE0F',40948:'\uEE10',40949:'\uEE11',40950:'\uEE12',40951:'\uEE13',40952:'\uEE14',40953:'\uEE15',40954:'\uEE16',40955:'\uEE17',40956:'\uEE18',40957:'\uEE19',40958:'\uEE1A',41024:'\uEE1B',41025:'\uEE1C',41026:'\uEE1D',41027:'\uEE1E',41028:'\uEE1F',41029:'\uEE20',41030:'\uEE21',41031:'\uEE22',41032:'\uEE23',41033:'\uEE24',41034:'\uEE25',41035:'\uEE26',41036:'\uEE27',41037:'\uEE28',41038:'\uEE29',41039:'\uEE2A',41040:'\uEE2B',41041:'\uEE2C',41042:'\uEE2D',41043:'\uEE2E',41044:'\uEE2F',41045:'\uEE30',41046:'\uEE31',41047:'\uEE32',41048:'\uEE33',41049:'\uEE34',41050:'\uEE35',41051:'\uEE36',41052:'\uEE37',41053:'\uEE38',41054:'\uEE39',41055:'\uEE3A',41056:'\uEE3B',41057:'\uEE3C',41058:'\uEE3D',41059:'\uEE3E',41060:'\uEE3F',41061:'\uEE40',41062:'\uEE41',41063:'\uEE42',41064:'\uEE43',41065:'\uEE44',41066:'\uEE45',41067:'\uEE46',41068:'\uEE47',41069:'\uEE48',41070:'\uEE49',41071:'\uEE4A',41072:'\uEE4B',41073:'\uEE4C',41074:'\uEE4D',41075:'\uEE4E',41076:'\uEE4F',41077:'\uEE50',41078:'\uEE51',41079:'\uEE52',41080:'\uEE53',41081:'\uEE54',41082:'\uEE55',41083:'\uEE56',41084:'\uEE57',41085:'\uEE58',41086:'\uEE59',41121:'\uEE5A',41122:'\uEE5B',41123:'\uEE5C',41124:'\uEE5D',41125:'\uEE5E',41126:'\uEE5F',41127:'\uEE60',41128:'\uEE61',41129:'\uEE62',41130:'\uEE63',41131:'\uEE64',41132:'\uEE65',41133:'\uEE66',41134:'\uEE67',41135:'\uEE68',41136:'\uEE69',41137:'\uEE6A',41138:'\uEE6B',41139:'\uEE6C',41140:'\uEE6D',41141:'\uEE6E',41142:'\uEE6F',41143:'\uEE70',41144:'\uEE71',41145:'\uEE72',41146:'\uEE73',41147:'\uEE74',41148:'\uEE75',41149:'\uEE76',41150:'\uEE77',41151:'\uEE78',41152:'\uEE79',41153:'\uEE7A',41154:'\uEE7B',41155:'\uEE7C',41156:'\uEE7D',41157:'\uEE7E',41158:'\uEE7F',41159:'\uEE80',41160:'\uEE81',41161:'\uEE82',41162:'\uEE83',41163:'\uEE84',41164:'\uEE85',41165:'\uEE86',41166:'\uEE87',41167:'\uEE88',41168:'\uEE89',41169:'\uEE8A',41170:'\uEE8B',41171:'\uEE8C',41172:'\uEE8D',41173:'\uEE8E',41174:'\uEE8F',41175:'\uEE90',41176:'\uEE91',41177:'\uEE92',41178:'\uEE93',41179:'\uEE94',41180:'\uEE95',41181:'\uEE96',41182:'\uEE97',41183:'\uEE98',41184:'\uEE99',41185:'\uEE9A',41186:'\uEE9B',41187:'\uEE9C',41188:'\uEE9D',41189:'\uEE9E',41190:'\uEE9F',41191:'\uEEA0',41192:'\uEEA1',41193:'\uEEA2',41194:'\uEEA3',41195:'\uEEA4',41196:'\uEEA5',41197:'\uEEA6',41198:'\uEEA7',41199:'\uEEA8',41200:'\uEEA9',41201:'\uEEAA',41202:'\uEEAB',41203:'\uEEAC',41204:'\uEEAD',41205:'\uEEAE',41206:'\uEEAF',41207:'\uEEB0',41208:'\uEEB1',41209:'\uEEB2',41210:'\uEEB3',41211:'\uEEB4',41212:'\uEEB5',41213:'\uEEB6',41214:'\uEEB7',41280:'\u3000',41281:'\uFF0C',41282:'\u3001',41283:'\u3002',41284:'\uFF0E',41285:'\u2027',41286:'\uFF1B',41287:'\uFF1A',41288:'\uFF1F',41289:'\uFF01',41290:'\uFE30',41291:'\u2026',41292:'\u2025',41293:'\uFE50',41294:'\uFE51',41295:'\uFE52',41296:'\u00B7',41297:'\uFE54',41298:'\uFE55',41299:'\uFE56',41300:'\uFE57',41301:'\uFF5C',41302:'\u2013',41303:'\uFE31',41304:'\u2014',41305:'\uFE33',41306:'\u2574',41307:'\uFE34',41308:'\uFE4F',41309:'\uFF08',41310:'\uFF09',41311:'\uFE35',41312:'\uFE36',41313:'\uFF5B',41314:'\uFF5D',41315:'\uFE37',41316:'\uFE38',41317:'\u3014',41318:'\u3015',41319:'\uFE39',41320:'\uFE3A',41321:'\u3010',41322:'\u3011',41323:'\uFE3B',41324:'\uFE3C',41325:'\u300A',41326:'\u300B',41327:'\uFE3D',41328:'\uFE3E',41329:'\u3008',41330:'\u3009',41331:'\uFE3F',41332:'\uFE40',41333:'\u300C',41334:'\u300D',41335:'\uFE41',41336:'\uFE42',41337:'\u300E',41338:'\u300F',41339:'\uFE43',41340:'\uFE44',41341:'\uFE59',41342:'\uFE5A',41377:'\uFE5B',41378:'\uFE5C',41379:'\uFE5D',41380:'\uFE5E',41381:'\u2018',41382:'\u2019',41383:'\u201C',41384:'\u201D',41385:'\u301D',41386:'\u301E',41387:'\u2035',41388:'\u2032',41389:'\uFF03',41390:'\uFF06',41391:'\uFF0A',41392:'\u203B',41393:'\u00A7',41394:'\u3003',41395:'\u25CB',41396:'\u25CF',41397:'\u25B3',41398:'\u25B2',41399:'\u25CE',41400:'\u2606',41401:'\u2605',41402:'\u25C7',41403:'\u25C6',41404:'\u25A1',41405:'\u25A0',41406:'\u25BD',41407:'\u25BC',41408:'\u32A3',41409:'\u2105',41410:'\u00AF',41411:'\uFFE3',41412:'\uFF3F',41413:'\u02CD',41414:'\uFE49',41415:'\uFE4A',41416:'\uFE4D',41417:'\uFE4E',41418:'\uFE4B',41419:'\uFE4C',41420:'\uFE5F',41421:'\uFE60',41422:'\uFE61',41423:'\uFF0B',41424:'\uFF0D',41425:'\u00D7',41426:'\u00F7',41427:'\u00B1',41428:'\u221A',41429:'\uFF1C',41430:'\uFF1E',41431:'\uFF1D',41432:'\u2266',41433:'\u2267',41434:'\u2260',41435:'\u221E',41436:'\u2252',41437:'\u2261',41438:'\uFE62',41439:'\uFE63',41440:'\uFE64',41441:'\uFE65',41442:'\uFE66',41443:'\uFF5E',41444:'\u2229',41445:'\u222A',41446:'\u22A5',41447:'\u2220',41448:'\u221F',41449:'\u22BF',41450:'\u33D2',41451:'\u33D1',41452:'\u222B',41453:'\u222E',41454:'\u2235',41455:'\u2234',41456:'\u2640',41457:'\u2642',41458:'\u2295',41459:'\u2299',41460:'\u2191',41461:'\u2193',41462:'\u2190',41463:'\u2192',41464:'\u2196',41465:'\u2197',41466:'\u2199',41467:'\u2198',41468:'\u2225',41469:'\u2223',41470:'\uFF0F',41536:'\uFF3C',41537:'\u2215',41538:'\uFE68',41539:'\uFF04',41540:'\uFFE5',41541:'\u3012',41542:'\uFFE0',41543:'\uFFE1',41544:'\uFF05',41545:'\uFF20',41546:'\u2103',41547:'\u2109',41548:'\uFE69',41549:'\uFE6A',41550:'\uFE6B',41551:'\u33D5',41552:'\u339C',41553:'\u339D',41554:'\u339E',41555:'\u33CE',41556:'\u33A1',41557:'\u338E',41558:'\u338F',41559:'\u33C4',41560:'\u00B0',41561:'\u5159',41562:'\u515B',41563:'\u515E',41564:'\u515D',41565:'\u5161',41566:'\u5163',41567:'\u55E7',41568:'\u74E9',41569:'\u7CCE',41570:'\u2581',41571:'\u2582',41572:'\u2583',41573:'\u2584',41574:'\u2585',41575:'\u2586',41576:'\u2587',41577:'\u2588',41578:'\u258F',41579:'\u258E',41580:'\u258D',41581:'\u258C',41582:'\u258B',41583:'\u258A',41584:'\u2589',41585:'\u253C',41586:'\u2534',41587:'\u252C',41588:'\u2524',41589:'\u251C',41590:'\u2594',41591:'\u2500',41592:'\u2502',41593:'\u2595',41594:'\u250C',41595:'\u2510',41596:'\u2514',41597:'\u2518',41598:'\u256D',41633:'\u256E',41634:'\u2570',41635:'\u256F',41636:'\u2550',41637:'\u255E',41638:'\u256A',41639:'\u2561',41640:'\u25E2',41641:'\u25E3',41642:'\u25E5',41643:'\u25E4',41644:'\u2571',41645:'\u2572',41646:'\u2573',41647:'\uFF10',41648:'\uFF11',41649:'\uFF12',41650:'\uFF13',41651:'\uFF14',41652:'\uFF15',41653:'\uFF16',41654:'\uFF17',41655:'\uFF18',41656:'\uFF19',41657:'\u2160',41658:'\u2161',41659:'\u2162',41660:'\u2163',41661:'\u2164',41662:'\u2165',41663:'\u2166',41664:'\u2167',41665:'\u2168',41666:'\u2169',41667:'\u3021',41668:'\u3022',41669:'\u3023',41670:'\u3024',41671:'\u3025',41672:'\u3026',41673:'\u3027',41674:'\u3028',41675:'\u3029',41676:'\u5341',41677:'\u5344',41678:'\u5345',41679:'\uFF21',41680:'\uFF22',41681:'\uFF23',41682:'\uFF24',41683:'\uFF25',41684:'\uFF26',41685:'\uFF27',41686:'\uFF28',41687:'\uFF29',41688:'\uFF2A',41689:'\uFF2B',41690:'\uFF2C',41691:'\uFF2D',41692:'\uFF2E',41693:'\uFF2F',41694:'\uFF30',41695:'\uFF31',41696:'\uFF32',41697:'\uFF33',41698:'\uFF34',41699:'\uFF35',41700:'\uFF36',41701:'\uFF37',41702:'\uFF38',41703:'\uFF39',41704:'\uFF3A',41705:'\uFF41',41706:'\uFF42',41707:'\uFF43',41708:'\uFF44',41709:'\uFF45',41710:'\uFF46',41711:'\uFF47',41712:'\uFF48',41713:'\uFF49',41714:'\uFF4A',41715:'\uFF4B',41716:'\uFF4C',41717:'\uFF4D',41718:'\uFF4E',41719:'\uFF4F',41720:'\uFF50',41721:'\uFF51',41722:'\uFF52',41723:'\uFF53',41724:'\uFF54',41725:'\uFF55',41726:'\uFF56',41792:'\uFF57',41793:'\uFF58',41794:'\uFF59',41795:'\uFF5A',41796:'\u0391',41797:'\u0392',41798:'\u0393',41799:'\u0394',41800:'\u0395',41801:'\u0396',41802:'\u0397',41803:'\u0398',41804:'\u0399',41805:'\u039A',41806:'\u039B',41807:'\u039C',41808:'\u039D',41809:'\u039E',41810:'\u039F',41811:'\u03A0',41812:'\u03A1',41813:'\u03A3',41814:'\u03A4',41815:'\u03A5',41816:'\u03A6',41817:'\u03A7',41818:'\u03A8',41819:'\u03A9',41820:'\u03B1',41821:'\u03B2',41822:'\u03B3',41823:'\u03B4',41824:'\u03B5',41825:'\u03B6',41826:'\u03B7',41827:'\u03B8',41828:'\u03B9',41829:'\u03BA',41830:'\u03BB',41831:'\u03BC',41832:'\u03BD',41833:'\u03BE',41834:'\u03BF',41835:'\u03C0',41836:'\u03C1',41837:'\u03C3',41838:'\u03C4',41839:'\u03C5',41840:'\u03C6',41841:'\u03C7',41842:'\u03C8',41843:'\u03C9',41844:'\u3105',41845:'\u3106',41846:'\u3107',41847:'\u3108',41848:'\u3109',41849:'\u310A',41850:'\u310B',41851:'\u310C',41852:'\u310D',41853:'\u310E',41854:'\u310F',41889:'\u3110',41890:'\u3111',41891:'\u3112',41892:'\u3113',41893:'\u3114',41894:'\u3115',41895:'\u3116',41896:'\u3117',41897:'\u3118',41898:'\u3119',41899:'\u311A',41900:'\u311B',41901:'\u311C',41902:'\u311D',41903:'\u311E',41904:'\u311F',41905:'\u3120',41906:'\u3121',41907:'\u3122',41908:'\u3123',41909:'\u3124',41910:'\u3125',41911:'\u3126',41912:'\u3127',41913:'\u3128',41914:'\u3129',41915:'\u02D9',41916:'\u02C9',41917:'\u02CA',41918:'\u02C7',41919:'\u02CB',41953:'\u20AC',42048:'\u4E00',42049:'\u4E59',42050:'\u4E01',42051:'\u4E03',42052:'\u4E43',42053:'\u4E5D',42054:'\u4E86',42055:'\u4E8C',42056:'\u4EBA',42057:'\u513F',42058:'\u5165',42059:'\u516B',42060:'\u51E0',42061:'\u5200',42062:'\u5201',42063:'\u529B',42064:'\u5315',42065:'\u5341',42066:'\u535C',42067:'\u53C8',42068:'\u4E09',42069:'\u4E0B',42070:'\u4E08',42071:'\u4E0A',42072:'\u4E2B',42073:'\u4E38',42074:'\u51E1',42075:'\u4E45',42076:'\u4E48',42077:'\u4E5F',42078:'\u4E5E',42079:'\u4E8E',42080:'\u4EA1',42081:'\u5140',42082:'\u5203',42083:'\u52FA',42084:'\u5343',42085:'\u53C9',42086:'\u53E3',42087:'\u571F',42088:'\u58EB',42089:'\u5915',42090:'\u5927',42091:'\u5973',42092:'\u5B50',42093:'\u5B51',42094:'\u5B53',42095:'\u5BF8',42096:'\u5C0F',42097:'\u5C22',42098:'\u5C38',42099:'\u5C71',42100:'\u5DDD',42101:'\u5DE5',42102:'\u5DF1',42103:'\u5DF2',42104:'\u5DF3',42105:'\u5DFE',42106:'\u5E72',42107:'\u5EFE',42108:'\u5F0B',42109:'\u5F13',42110:'\u624D',42145:'\u4E11',42146:'\u4E10',42147:'\u4E0D',42148:'\u4E2D',42149:'\u4E30',42150:'\u4E39',42151:'\u4E4B',42152:'\u5C39',42153:'\u4E88',42154:'\u4E91',42155:'\u4E95',42156:'\u4E92',42157:'\u4E94',42158:'\u4EA2',42159:'\u4EC1',42160:'\u4EC0',42161:'\u4EC3',42162:'\u4EC6',42163:'\u4EC7',42164:'\u4ECD',42165:'\u4ECA',42166:'\u4ECB',42167:'\u4EC4',42168:'\u5143',42169:'\u5141',42170:'\u5167',42171:'\u516D',42172:'\u516E',42173:'\u516C',42174:'\u5197',42175:'\u51F6',42176:'\u5206',42177:'\u5207',42178:'\u5208',42179:'\u52FB',42180:'\u52FE',42181:'\u52FF',42182:'\u5316',42183:'\u5339',42184:'\u5348',42185:'\u5347',42186:'\u5345',42187:'\u535E',42188:'\u5384',42189:'\u53CB',42190:'\u53CA',42191:'\u53CD',42192:'\u58EC',42193:'\u5929',42194:'\u592B',42195:'\u592A',42196:'\u592D',42197:'\u5B54',42198:'\u5C11',42199:'\u5C24',42200:'\u5C3A',42201:'\u5C6F',42202:'\u5DF4',42203:'\u5E7B',42204:'\u5EFF',42205:'\u5F14',42206:'\u5F15',42207:'\u5FC3',42208:'\u6208',42209:'\u6236',42210:'\u624B',42211:'\u624E',42212:'\u652F',42213:'\u6587',42214:'\u6597',42215:'\u65A4',42216:'\u65B9',42217:'\u65E5',42218:'\u66F0',42219:'\u6708',42220:'\u6728',42221:'\u6B20',42222:'\u6B62',42223:'\u6B79',42224:'\u6BCB',42225:'\u6BD4',42226:'\u6BDB',42227:'\u6C0F',42228:'\u6C34',42229:'\u706B',42230:'\u722A',42231:'\u7236',42232:'\u723B',42233:'\u7247',42234:'\u7259',42235:'\u725B',42236:'\u72AC',42237:'\u738B',42238:'\u4E19',42304:'\u4E16',42305:'\u4E15',42306:'\u4E14',42307:'\u4E18',42308:'\u4E3B',42309:'\u4E4D',42310:'\u4E4F',42311:'\u4E4E',42312:'\u4EE5',42313:'\u4ED8',42314:'\u4ED4',42315:'\u4ED5',42316:'\u4ED6',42317:'\u4ED7',42318:'\u4EE3',42319:'\u4EE4',42320:'\u4ED9',42321:'\u4EDE',42322:'\u5145',42323:'\u5144',42324:'\u5189',42325:'\u518A',42326:'\u51AC',42327:'\u51F9',42328:'\u51FA',42329:'\u51F8',42330:'\u520A',42331:'\u52A0',42332:'\u529F',42333:'\u5305',42334:'\u5306',42335:'\u5317',42336:'\u531D',42337:'\u4EDF',42338:'\u534A',42339:'\u5349',42340:'\u5361',42341:'\u5360',42342:'\u536F',42343:'\u536E',42344:'\u53BB',42345:'\u53EF',42346:'\u53E4',42347:'\u53F3',42348:'\u53EC',42349:'\u53EE',42350:'\u53E9',42351:'\u53E8',42352:'\u53FC',42353:'\u53F8',42354:'\u53F5',42355:'\u53EB',42356:'\u53E6',42357:'\u53EA',42358:'\u53F2',42359:'\u53F1',42360:'\u53F0',42361:'\u53E5',42362:'\u53ED',42363:'\u53FB',42364:'\u56DB',42365:'\u56DA',42366:'\u5916',42401:'\u592E',42402:'\u5931',42403:'\u5974',42404:'\u5976',42405:'\u5B55',42406:'\u5B83',42407:'\u5C3C',42408:'\u5DE8',42409:'\u5DE7',42410:'\u5DE6',42411:'\u5E02',42412:'\u5E03',42413:'\u5E73',42414:'\u5E7C',42415:'\u5F01',42416:'\u5F18',42417:'\u5F17',42418:'\u5FC5',42419:'\u620A',42420:'\u6253',42421:'\u6254',42422:'\u6252',42423:'\u6251',42424:'\u65A5',42425:'\u65E6',42426:'\u672E',42427:'\u672C',42428:'\u672A',42429:'\u672B',42430:'\u672D',42431:'\u6B63',42432:'\u6BCD',42433:'\u6C11',42434:'\u6C10',42435:'\u6C38',42436:'\u6C41',42437:'\u6C40',42438:'\u6C3E',42439:'\u72AF',42440:'\u7384',42441:'\u7389',42442:'\u74DC',42443:'\u74E6',42444:'\u7518',42445:'\u751F',42446:'\u7528',42447:'\u7529',42448:'\u7530',42449:'\u7531',42450:'\u7532',42451:'\u7533',42452:'\u758B',42453:'\u767D',42454:'\u76AE',42455:'\u76BF',42456:'\u76EE',42457:'\u77DB',42458:'\u77E2',42459:'\u77F3',42460:'\u793A',42461:'\u79BE',42462:'\u7A74',42463:'\u7ACB',42464:'\u4E1E',42465:'\u4E1F',42466:'\u4E52',42467:'\u4E53',42468:'\u4E69',42469:'\u4E99',42470:'\u4EA4',42471:'\u4EA6',42472:'\u4EA5',42473:'\u4EFF',42474:'\u4F09',42475:'\u4F19',42476:'\u4F0A',42477:'\u4F15',42478:'\u4F0D',42479:'\u4F10',42480:'\u4F11',42481:'\u4F0F',42482:'\u4EF2',42483:'\u4EF6',42484:'\u4EFB',42485:'\u4EF0',42486:'\u4EF3',42487:'\u4EFD',42488:'\u4F01',42489:'\u4F0B',42490:'\u5149',42491:'\u5147',42492:'\u5146',42493:'\u5148',42494:'\u5168',42560:'\u5171',42561:'\u518D',42562:'\u51B0',42563:'\u5217',42564:'\u5211',42565:'\u5212',42566:'\u520E',42567:'\u5216',42568:'\u52A3',42569:'\u5308',42570:'\u5321',42571:'\u5320',42572:'\u5370',42573:'\u5371',42574:'\u5409',42575:'\u540F',42576:'\u540C',42577:'\u540A',42578:'\u5410',42579:'\u5401',42580:'\u540B',42581:'\u5404',42582:'\u5411',42583:'\u540D',42584:'\u5408',42585:'\u5403',42586:'\u540E',42587:'\u5406',42588:'\u5412',42589:'\u56E0',42590:'\u56DE',42591:'\u56DD',42592:'\u5733',42593:'\u5730',42594:'\u5728',42595:'\u572D',42596:'\u572C',42597:'\u572F',42598:'\u5729',42599:'\u5919',42600:'\u591A',42601:'\u5937',42602:'\u5938',42603:'\u5984',42604:'\u5978',42605:'\u5983',42606:'\u597D',42607:'\u5979',42608:'\u5982',42609:'\u5981',42610:'\u5B57',42611:'\u5B58',42612:'\u5B87',42613:'\u5B88',42614:'\u5B85',42615:'\u5B89',42616:'\u5BFA',42617:'\u5C16',42618:'\u5C79',42619:'\u5DDE',42620:'\u5E06',42621:'\u5E76',42622:'\u5E74',42657:'\u5F0F',42658:'\u5F1B',42659:'\u5FD9',42660:'\u5FD6',42661:'\u620E',42662:'\u620C',42663:'\u620D',42664:'\u6210',42665:'\u6263',42666:'\u625B',42667:'\u6258',42668:'\u6536',42669:'\u65E9',42670:'\u65E8',42671:'\u65EC',42672:'\u65ED',42673:'\u66F2',42674:'\u66F3',42675:'\u6709',42676:'\u673D',42677:'\u6734',42678:'\u6731',42679:'\u6735',42680:'\u6B21',42681:'\u6B64',42682:'\u6B7B',42683:'\u6C16',42684:'\u6C5D',42685:'\u6C57',42686:'\u6C59',42687:'\u6C5F',42688:'\u6C60',42689:'\u6C50',42690:'\u6C55',42691:'\u6C61',42692:'\u6C5B',42693:'\u6C4D',42694:'\u6C4E',42695:'\u7070',42696:'\u725F',42697:'\u725D',42698:'\u767E',42699:'\u7AF9',42700:'\u7C73',42701:'\u7CF8',42702:'\u7F36',42703:'\u7F8A',42704:'\u7FBD',42705:'\u8001',42706:'\u8003',42707:'\u800C',42708:'\u8012',42709:'\u8033',42710:'\u807F',42711:'\u8089',42712:'\u808B',42713:'\u808C',42714:'\u81E3',42715:'\u81EA',42716:'\u81F3',42717:'\u81FC',42718:'\u820C',42719:'\u821B',42720:'\u821F',42721:'\u826E',42722:'\u8272',42723:'\u827E',42724:'\u866B',42725:'\u8840',42726:'\u884C',42727:'\u8863',42728:'\u897F',42729:'\u9621',42730:'\u4E32',42731:'\u4EA8',42732:'\u4F4D',42733:'\u4F4F',42734:'\u4F47',42735:'\u4F57',42736:'\u4F5E',42737:'\u4F34',42738:'\u4F5B',42739:'\u4F55',42740:'\u4F30',42741:'\u4F50',42742:'\u4F51',42743:'\u4F3D',42744:'\u4F3A',42745:'\u4F38',42746:'\u4F43',42747:'\u4F54',42748:'\u4F3C',42749:'\u4F46',42750:'\u4F63',42816:'\u4F5C',42817:'\u4F60',42818:'\u4F2F',42819:'\u4F4E',42820:'\u4F36',42821:'\u4F59',42822:'\u4F5D',42823:'\u4F48',42824:'\u4F5A',42825:'\u514C',42826:'\u514B',42827:'\u514D',42828:'\u5175',42829:'\u51B6',42830:'\u51B7',42831:'\u5225',42832:'\u5224',42833:'\u5229',42834:'\u522A',42835:'\u5228',42836:'\u52AB',42837:'\u52A9',42838:'\u52AA',42839:'\u52AC',42840:'\u5323',42841:'\u5373',42842:'\u5375',42843:'\u541D',42844:'\u542D',42845:'\u541E',42846:'\u543E',42847:'\u5426',42848:'\u544E',42849:'\u5427',42850:'\u5446',42851:'\u5443',42852:'\u5433',42853:'\u5448',42854:'\u5442',42855:'\u541B',42856:'\u5429',42857:'\u544A',42858:'\u5439',42859:'\u543B',42860:'\u5438',42861:'\u542E',42862:'\u5435',42863:'\u5436',42864:'\u5420',42865:'\u543C',42866:'\u5440',42867:'\u5431',42868:'\u542B',42869:'\u541F',42870:'\u542C',42871:'\u56EA',42872:'\u56F0',42873:'\u56E4',42874:'\u56EB',42875:'\u574A',42876:'\u5751',42877:'\u5740',42878:'\u574D',42913:'\u5747',42914:'\u574E',42915:'\u573E',42916:'\u5750',42917:'\u574F',42918:'\u573B',42919:'\u58EF',42920:'\u593E',42921:'\u599D',42922:'\u5992',42923:'\u59A8',42924:'\u599E',42925:'\u59A3',42926:'\u5999',42927:'\u5996',42928:'\u598D',42929:'\u59A4',42930:'\u5993',42931:'\u598A',42932:'\u59A5',42933:'\u5B5D',42934:'\u5B5C',42935:'\u5B5A',42936:'\u5B5B',42937:'\u5B8C',42938:'\u5B8B',42939:'\u5B8F',42940:'\u5C2C',42941:'\u5C40',42942:'\u5C41',42943:'\u5C3F',42944:'\u5C3E',42945:'\u5C90',42946:'\u5C91',42947:'\u5C94',42948:'\u5C8C',42949:'\u5DEB',42950:'\u5E0C',42951:'\u5E8F',42952:'\u5E87',42953:'\u5E8A',42954:'\u5EF7',42955:'\u5F04',42956:'\u5F1F',42957:'\u5F64',42958:'\u5F62',42959:'\u5F77',42960:'\u5F79',42961:'\u5FD8',42962:'\u5FCC',42963:'\u5FD7',42964:'\u5FCD',42965:'\u5FF1',42966:'\u5FEB',42967:'\u5FF8',42968:'\u5FEA',42969:'\u6212',42970:'\u6211',42971:'\u6284',42972:'\u6297',42973:'\u6296',42974:'\u6280',42975:'\u6276',42976:'\u6289',42977:'\u626D',42978:'\u628A',42979:'\u627C',42980:'\u627E',42981:'\u6279',42982:'\u6273',42983:'\u6292',42984:'\u626F',42985:'\u6298',42986:'\u626E',42987:'\u6295',42988:'\u6293',42989:'\u6291',42990:'\u6286',42991:'\u6539',42992:'\u653B',42993:'\u6538',42994:'\u65F1',42995:'\u66F4',42996:'\u675F',42997:'\u674E',42998:'\u674F',42999:'\u6750',43000:'\u6751',43001:'\u675C',43002:'\u6756',43003:'\u675E',43004:'\u6749',43005:'\u6746',43006:'\u6760',43072:'\u6753',43073:'\u6757',43074:'\u6B65',43075:'\u6BCF',43076:'\u6C42',43077:'\u6C5E',43078:'\u6C99',43079:'\u6C81',43080:'\u6C88',43081:'\u6C89',43082:'\u6C85',43083:'\u6C9B',43084:'\u6C6A',43085:'\u6C7A',43086:'\u6C90',43087:'\u6C70',43088:'\u6C8C',43089:'\u6C68',43090:'\u6C96',43091:'\u6C92',43092:'\u6C7D',43093:'\u6C83',43094:'\u6C72',43095:'\u6C7E',43096:'\u6C74',43097:'\u6C86',43098:'\u6C76',43099:'\u6C8D',43100:'\u6C94',43101:'\u6C98',43102:'\u6C82',43103:'\u7076',43104:'\u707C',43105:'\u707D',43106:'\u7078',43107:'\u7262',43108:'\u7261',43109:'\u7260',43110:'\u72C4',43111:'\u72C2',43112:'\u7396',43113:'\u752C',43114:'\u752B',43115:'\u7537',43116:'\u7538',43117:'\u7682',43118:'\u76EF',43119:'\u77E3',43120:'\u79C1',43121:'\u79C0',43122:'\u79BF',43123:'\u7A76',43124:'\u7CFB',43125:'\u7F55',43126:'\u8096',43127:'\u8093',43128:'\u809D',43129:'\u8098',43130:'\u809B',43131:'\u809A',43132:'\u80B2',43133:'\u826F',43134:'\u8292',43169:'\u828B',43170:'\u828D',43171:'\u898B',43172:'\u89D2',43173:'\u8A00',43174:'\u8C37',43175:'\u8C46',43176:'\u8C55',43177:'\u8C9D',43178:'\u8D64',43179:'\u8D70',43180:'\u8DB3',43181:'\u8EAB',43182:'\u8ECA',43183:'\u8F9B',43184:'\u8FB0',43185:'\u8FC2',43186:'\u8FC6',43187:'\u8FC5',43188:'\u8FC4',43189:'\u5DE1',43190:'\u9091',43191:'\u90A2',43192:'\u90AA',43193:'\u90A6',43194:'\u90A3',43195:'\u9149',43196:'\u91C6',43197:'\u91CC',43198:'\u9632',43199:'\u962E',43200:'\u9631',43201:'\u962A',43202:'\u962C',43203:'\u4E26',43204:'\u4E56',43205:'\u4E73',43206:'\u4E8B',43207:'\u4E9B',43208:'\u4E9E',43209:'\u4EAB',43210:'\u4EAC',43211:'\u4F6F',43212:'\u4F9D',43213:'\u4F8D',43214:'\u4F73',43215:'\u4F7F',43216:'\u4F6C',43217:'\u4F9B',43218:'\u4F8B',43219:'\u4F86',43220:'\u4F83',43221:'\u4F70',43222:'\u4F75',43223:'\u4F88',43224:'\u4F69',43225:'\u4F7B',43226:'\u4F96',43227:'\u4F7E',43228:'\u4F8F',43229:'\u4F91',43230:'\u4F7A',43231:'\u5154',43232:'\u5152',43233:'\u5155',43234:'\u5169',43235:'\u5177',43236:'\u5176',43237:'\u5178',43238:'\u51BD',43239:'\u51FD',43240:'\u523B',43241:'\u5238',43242:'\u5237',43243:'\u523A',43244:'\u5230',43245:'\u522E',43246:'\u5236',43247:'\u5241',43248:'\u52BE',43249:'\u52BB',43250:'\u5352',43251:'\u5354',43252:'\u5353',43253:'\u5351',43254:'\u5366',43255:'\u5377',43256:'\u5378',43257:'\u5379',43258:'\u53D6',43259:'\u53D4',43260:'\u53D7',43261:'\u5473',43262:'\u5475',43328:'\u5496',43329:'\u5478',43330:'\u5495',43331:'\u5480',43332:'\u547B',43333:'\u5477',43334:'\u5484',43335:'\u5492',43336:'\u5486',43337:'\u547C',43338:'\u5490',43339:'\u5471',43340:'\u5476',43341:'\u548C',43342:'\u549A',43343:'\u5462',43344:'\u5468',43345:'\u548B',43346:'\u547D',43347:'\u548E',43348:'\u56FA',43349:'\u5783',43350:'\u5777',43351:'\u576A',43352:'\u5769',43353:'\u5761',43354:'\u5766',43355:'\u5764',43356:'\u577C',43357:'\u591C',43358:'\u5949',43359:'\u5947',43360:'\u5948',43361:'\u5944',43362:'\u5954',43363:'\u59BE',43364:'\u59BB',43365:'\u59D4',43366:'\u59B9',43367:'\u59AE',43368:'\u59D1',43369:'\u59C6',43370:'\u59D0',43371:'\u59CD',43372:'\u59CB',43373:'\u59D3',43374:'\u59CA',43375:'\u59AF',43376:'\u59B3',43377:'\u59D2',43378:'\u59C5',43379:'\u5B5F',43380:'\u5B64',43381:'\u5B63',43382:'\u5B97',43383:'\u5B9A',43384:'\u5B98',43385:'\u5B9C',43386:'\u5B99',43387:'\u5B9B',43388:'\u5C1A',43389:'\u5C48',43390:'\u5C45',43425:'\u5C46',43426:'\u5CB7',43427:'\u5CA1',43428:'\u5CB8',43429:'\u5CA9',43430:'\u5CAB',43431:'\u5CB1',43432:'\u5CB3',43433:'\u5E18',43434:'\u5E1A',43435:'\u5E16',43436:'\u5E15',43437:'\u5E1B',43438:'\u5E11',43439:'\u5E78',43440:'\u5E9A',43441:'\u5E97',43442:'\u5E9C',43443:'\u5E95',43444:'\u5E96',43445:'\u5EF6',43446:'\u5F26',43447:'\u5F27',43448:'\u5F29',43449:'\u5F80',43450:'\u5F81',43451:'\u5F7F',43452:'\u5F7C',43453:'\u5FDD',43454:'\u5FE0',43455:'\u5FFD',43456:'\u5FF5',43457:'\u5FFF',43458:'\u600F',43459:'\u6014',43460:'\u602F',43461:'\u6035',43462:'\u6016',43463:'\u602A',43464:'\u6015',43465:'\u6021',43466:'\u6027',43467:'\u6029',43468:'\u602B',43469:'\u601B',43470:'\u6216',43471:'\u6215',43472:'\u623F',43473:'\u623E',43474:'\u6240',43475:'\u627F',43476:'\u62C9',43477:'\u62CC',43478:'\u62C4',43479:'\u62BF',43480:'\u62C2',43481:'\u62B9',43482:'\u62D2',43483:'\u62DB',43484:'\u62AB',43485:'\u62D3',43486:'\u62D4',43487:'\u62CB',43488:'\u62C8',43489:'\u62A8',43490:'\u62BD',43491:'\u62BC',43492:'\u62D0',43493:'\u62D9',43494:'\u62C7',43495:'\u62CD',43496:'\u62B5',43497:'\u62DA',43498:'\u62B1',43499:'\u62D8',43500:'\u62D6',43501:'\u62D7',43502:'\u62C6',43503:'\u62AC',43504:'\u62CE',43505:'\u653E',43506:'\u65A7',43507:'\u65BC',43508:'\u65FA',43509:'\u6614',43510:'\u6613',43511:'\u660C',43512:'\u6606',43513:'\u6602',43514:'\u660E',43515:'\u6600',43516:'\u660F',43517:'\u6615',43518:'\u660A',43584:'\u6607',43585:'\u670D',43586:'\u670B',43587:'\u676D',43588:'\u678B',43589:'\u6795',43590:'\u6771',43591:'\u679C',43592:'\u6773',43593:'\u6777',43594:'\u6787',43595:'\u679D',43596:'\u6797',43597:'\u676F',43598:'\u6770',43599:'\u677F',43600:'\u6789',43601:'\u677E',43602:'\u6790',43603:'\u6775',43604:'\u679A',43605:'\u6793',43606:'\u677C',43607:'\u676A',43608:'\u6772',43609:'\u6B23',43610:'\u6B66',43611:'\u6B67',43612:'\u6B7F',43613:'\u6C13',43614:'\u6C1B',43615:'\u6CE3',43616:'\u6CE8',43617:'\u6CF3',43618:'\u6CB1',43619:'\u6CCC',43620:'\u6CE5',43621:'\u6CB3',43622:'\u6CBD',43623:'\u6CBE',43624:'\u6CBC',43625:'\u6CE2',43626:'\u6CAB',43627:'\u6CD5',43628:'\u6CD3',43629:'\u6CB8',43630:'\u6CC4',43631:'\u6CB9',43632:'\u6CC1',43633:'\u6CAE',43634:'\u6CD7',43635:'\u6CC5',43636:'\u6CF1',43637:'\u6CBF',43638:'\u6CBB',43639:'\u6CE1',43640:'\u6CDB',43641:'\u6CCA',43642:'\u6CAC',43643:'\u6CEF',43644:'\u6CDC',43645:'\u6CD6',43646:'\u6CE0',43681:'\u7095',43682:'\u708E',43683:'\u7092',43684:'\u708A',43685:'\u7099',43686:'\u722C',43687:'\u722D',43688:'\u7238',43689:'\u7248',43690:'\u7267',43691:'\u7269',43692:'\u72C0',43693:'\u72CE',43694:'\u72D9',43695:'\u72D7',43696:'\u72D0',43697:'\u73A9',43698:'\u73A8',43699:'\u739F',43700:'\u73AB',43701:'\u73A5',43702:'\u753D',43703:'\u759D',43704:'\u7599',43705:'\u759A',43706:'\u7684',43707:'\u76C2',43708:'\u76F2',43709:'\u76F4',43710:'\u77E5',43711:'\u77FD',43712:'\u793E',43713:'\u7940',43714:'\u7941',43715:'\u79C9',43716:'\u79C8',43717:'\u7A7A',43718:'\u7A79',43719:'\u7AFA',43720:'\u7CFE',43721:'\u7F54',43722:'\u7F8C',43723:'\u7F8B',43724:'\u8005',43725:'\u80BA',43726:'\u80A5',43727:'\u80A2',43728:'\u80B1',43729:'\u80A1',43730:'\u80AB',43731:'\u80A9',43732:'\u80B4',43733:'\u80AA',43734:'\u80AF',43735:'\u81E5',43736:'\u81FE',43737:'\u820D',43738:'\u82B3',43739:'\u829D',43740:'\u8299',43741:'\u82AD',43742:'\u82BD',43743:'\u829F',43744:'\u82B9',43745:'\u82B1',43746:'\u82AC',43747:'\u82A5',43748:'\u82AF',43749:'\u82B8',43750:'\u82A3',43751:'\u82B0',43752:'\u82BE',43753:'\u82B7',43754:'\u864E',43755:'\u8671',43756:'\u521D',43757:'\u8868',43758:'\u8ECB',43759:'\u8FCE',43760:'\u8FD4',43761:'\u8FD1',43762:'\u90B5',43763:'\u90B8',43764:'\u90B1',43765:'\u90B6',43766:'\u91C7',43767:'\u91D1',43768:'\u9577',43769:'\u9580',43770:'\u961C',43771:'\u9640',43772:'\u963F',43773:'\u963B',43774:'\u9644',43840:'\u9642',43841:'\u96B9',43842:'\u96E8',43843:'\u9752',43844:'\u975E',43845:'\u4E9F',43846:'\u4EAD',43847:'\u4EAE',43848:'\u4FE1',43849:'\u4FB5',43850:'\u4FAF',43851:'\u4FBF',43852:'\u4FE0',43853:'\u4FD1',43854:'\u4FCF',43855:'\u4FDD',43856:'\u4FC3',43857:'\u4FB6',43858:'\u4FD8',43859:'\u4FDF',43860:'\u4FCA',43861:'\u4FD7',43862:'\u4FAE',43863:'\u4FD0',43864:'\u4FC4',43865:'\u4FC2',43866:'\u4FDA',43867:'\u4FCE',43868:'\u4FDE',43869:'\u4FB7',43870:'\u5157',43871:'\u5192',43872:'\u5191',43873:'\u51A0',43874:'\u524E',43875:'\u5243',43876:'\u524A',43877:'\u524D',43878:'\u524C',43879:'\u524B',43880:'\u5247',43881:'\u52C7',43882:'\u52C9',43883:'\u52C3',43884:'\u52C1',43885:'\u530D',43886:'\u5357',43887:'\u537B',43888:'\u539A',43889:'\u53DB',43890:'\u54AC',43891:'\u54C0',43892:'\u54A8',43893:'\u54CE',43894:'\u54C9',43895:'\u54B8',43896:'\u54A6',43897:'\u54B3',43898:'\u54C7',43899:'\u54C2',43900:'\u54BD',43901:'\u54AA',43902:'\u54C1',43937:'\u54C4',43938:'\u54C8',43939:'\u54AF',43940:'\u54AB',43941:'\u54B1',43942:'\u54BB',43943:'\u54A9',43944:'\u54A7',43945:'\u54BF',43946:'\u56FF',43947:'\u5782',43948:'\u578B',43949:'\u57A0',43950:'\u57A3',43951:'\u57A2',43952:'\u57CE',43953:'\u57AE',43954:'\u5793',43955:'\u5955',43956:'\u5951',43957:'\u594F',43958:'\u594E',43959:'\u5950',43960:'\u59DC',43961:'\u59D8',43962:'\u59FF',43963:'\u59E3',43964:'\u59E8',43965:'\u5A03',43966:'\u59E5',43967:'\u59EA',43968:'\u59DA',43969:'\u59E6',43970:'\u5A01',43971:'\u59FB',43972:'\u5B69',43973:'\u5BA3',43974:'\u5BA6',43975:'\u5BA4',43976:'\u5BA2',43977:'\u5BA5',43978:'\u5C01',43979:'\u5C4E',43980:'\u5C4F',43981:'\u5C4D',43982:'\u5C4B',43983:'\u5CD9',43984:'\u5CD2',43985:'\u5DF7',43986:'\u5E1D',43987:'\u5E25',43988:'\u5E1F',43989:'\u5E7D',43990:'\u5EA0',43991:'\u5EA6',43992:'\u5EFA',43993:'\u5F08',43994:'\u5F2D',43995:'\u5F65',43996:'\u5F88',43997:'\u5F85',43998:'\u5F8A',43999:'\u5F8B',44000:'\u5F87',44001:'\u5F8C',44002:'\u5F89',44003:'\u6012',44004:'\u601D',44005:'\u6020',44006:'\u6025',44007:'\u600E',44008:'\u6028',44009:'\u604D',44010:'\u6070',44011:'\u6068',44012:'\u6062',44013:'\u6046',44014:'\u6043',44015:'\u606C',44016:'\u606B',44017:'\u606A',44018:'\u6064',44019:'\u6241',44020:'\u62DC',44021:'\u6316',44022:'\u6309',44023:'\u62FC',44024:'\u62ED',44025:'\u6301',44026:'\u62EE',44027:'\u62FD',44028:'\u6307',44029:'\u62F1',44030:'\u62F7',44096:'\u62EF',44097:'\u62EC',44098:'\u62FE',44099:'\u62F4',44100:'\u6311',44101:'\u6302',44102:'\u653F',44103:'\u6545',44104:'\u65AB',44105:'\u65BD',44106:'\u65E2',44107:'\u6625',44108:'\u662D',44109:'\u6620',44110:'\u6627',44111:'\u662F',44112:'\u661F',44113:'\u6628',44114:'\u6631',44115:'\u6624',44116:'\u66F7',44117:'\u67FF',44118:'\u67D3',44119:'\u67F1',44120:'\u67D4',44121:'\u67D0',44122:'\u67EC',44123:'\u67B6',44124:'\u67AF',44125:'\u67F5',44126:'\u67E9',44127:'\u67EF',44128:'\u67C4',44129:'\u67D1',44130:'\u67B4',44131:'\u67DA',44132:'\u67E5',44133:'\u67B8',44134:'\u67CF',44135:'\u67DE',44136:'\u67F3',44137:'\u67B0',44138:'\u67D9',44139:'\u67E2',44140:'\u67DD',44141:'\u67D2',44142:'\u6B6A',44143:'\u6B83',44144:'\u6B86',44145:'\u6BB5',44146:'\u6BD2',44147:'\u6BD7',44148:'\u6C1F',44149:'\u6CC9',44150:'\u6D0B',44151:'\u6D32',44152:'\u6D2A',44153:'\u6D41',44154:'\u6D25',44155:'\u6D0C',44156:'\u6D31',44157:'\u6D1E',44158:'\u6D17',44193:'\u6D3B',44194:'\u6D3D',44195:'\u6D3E',44196:'\u6D36',44197:'\u6D1B',44198:'\u6CF5',44199:'\u6D39',44200:'\u6D27',44201:'\u6D38',44202:'\u6D29',44203:'\u6D2E',44204:'\u6D35',44205:'\u6D0E',44206:'\u6D2B',44207:'\u70AB',44208:'\u70BA',44209:'\u70B3',44210:'\u70AC',44211:'\u70AF',44212:'\u70AD',44213:'\u70B8',44214:'\u70AE',44215:'\u70A4',44216:'\u7230',44217:'\u7272',44218:'\u726F',44219:'\u7274',44220:'\u72E9',44221:'\u72E0',44222:'\u72E1',44223:'\u73B7',44224:'\u73CA',44225:'\u73BB',44226:'\u73B2',44227:'\u73CD',44228:'\u73C0',44229:'\u73B3',44230:'\u751A',44231:'\u752D',44232:'\u754F',44233:'\u754C',44234:'\u754E',44235:'\u754B',44236:'\u75AB',44237:'\u75A4',44238:'\u75A5',44239:'\u75A2',44240:'\u75A3',44241:'\u7678',44242:'\u7686',44243:'\u7687',44244:'\u7688',44245:'\u76C8',44246:'\u76C6',44247:'\u76C3',44248:'\u76C5',44249:'\u7701',44250:'\u76F9',44251:'\u76F8',44252:'\u7709',44253:'\u770B',44254:'\u76FE',44255:'\u76FC',44256:'\u7707',44257:'\u77DC',44258:'\u7802',44259:'\u7814',44260:'\u780C',44261:'\u780D',44262:'\u7946',44263:'\u7949',44264:'\u7948',44265:'\u7947',44266:'\u79B9',44267:'\u79BA',44268:'\u79D1',44269:'\u79D2',44270:'\u79CB',44271:'\u7A7F',44272:'\u7A81',44273:'\u7AFF',44274:'\u7AFD',44275:'\u7C7D',44276:'\u7D02',44277:'\u7D05',44278:'\u7D00',44279:'\u7D09',44280:'\u7D07',44281:'\u7D04',44282:'\u7D06',44283:'\u7F38',44284:'\u7F8E',44285:'\u7FBF',44286:'\u8004',44352:'\u8010',44353:'\u800D',44354:'\u8011',44355:'\u8036',44356:'\u80D6',44357:'\u80E5',44358:'\u80DA',44359:'\u80C3',44360:'\u80C4',44361:'\u80CC',44362:'\u80E1',44363:'\u80DB',44364:'\u80CE',44365:'\u80DE',44366:'\u80E4',44367:'\u80DD',44368:'\u81F4',44369:'\u8222',44370:'\u82E7',44371:'\u8303',44372:'\u8305',44373:'\u82E3',44374:'\u82DB',44375:'\u82E6',44376:'\u8304',44377:'\u82E5',44378:'\u8302',44379:'\u8309',44380:'\u82D2',44381:'\u82D7',44382:'\u82F1',44383:'\u8301',44384:'\u82DC',44385:'\u82D4',44386:'\u82D1',44387:'\u82DE',44388:'\u82D3',44389:'\u82DF',44390:'\u82EF',44391:'\u8306',44392:'\u8650',44393:'\u8679',44394:'\u867B',44395:'\u867A',44396:'\u884D',44397:'\u886B',44398:'\u8981',44399:'\u89D4',44400:'\u8A08',44401:'\u8A02',44402:'\u8A03',44403:'\u8C9E',44404:'\u8CA0',44405:'\u8D74',44406:'\u8D73',44407:'\u8DB4',44408:'\u8ECD',44409:'\u8ECC',44410:'\u8FF0',44411:'\u8FE6',44412:'\u8FE2',44413:'\u8FEA',44414:'\u8FE5',44449:'\u8FED',44450:'\u8FEB',44451:'\u8FE4',44452:'\u8FE8',44453:'\u90CA',44454:'\u90CE',44455:'\u90C1',44456:'\u90C3',44457:'\u914B',44458:'\u914A',44459:'\u91CD',44460:'\u9582',44461:'\u9650',44462:'\u964B',44463:'\u964C',44464:'\u964D',44465:'\u9762',44466:'\u9769',44467:'\u97CB',44468:'\u97ED',44469:'\u97F3',44470:'\u9801',44471:'\u98A8',44472:'\u98DB',44473:'\u98DF',44474:'\u9996',44475:'\u9999',44476:'\u4E58',44477:'\u4EB3',44478:'\u500C',44479:'\u500D',44480:'\u5023',44481:'\u4FEF',44482:'\u5026',44483:'\u5025',44484:'\u4FF8',44485:'\u5029',44486:'\u5016',44487:'\u5006',44488:'\u503C',44489:'\u501F',44490:'\u501A',44491:'\u5012',44492:'\u5011',44493:'\u4FFA',44494:'\u5000',44495:'\u5014',44496:'\u5028',44497:'\u4FF1',44498:'\u5021',44499:'\u500B',44500:'\u5019',44501:'\u5018',44502:'\u4FF3',44503:'\u4FEE',44504:'\u502D',44505:'\u502A',44506:'\u4FFE',44507:'\u502B',44508:'\u5009',44509:'\u517C',44510:'\u51A4',44511:'\u51A5',44512:'\u51A2',44513:'\u51CD',44514:'\u51CC',44515:'\u51C6',44516:'\u51CB',44517:'\u5256',44518:'\u525C',44519:'\u5254',44520:'\u525B',44521:'\u525D',44522:'\u532A',44523:'\u537F',44524:'\u539F',44525:'\u539D',44526:'\u53DF',44527:'\u54E8',44528:'\u5510',44529:'\u5501',44530:'\u5537',44531:'\u54FC',44532:'\u54E5',44533:'\u54F2',44534:'\u5506',44535:'\u54FA',44536:'\u5514',44537:'\u54E9',44538:'\u54ED',44539:'\u54E1',44540:'\u5509',44541:'\u54EE',44542:'\u54EA',44608:'\u54E6',44609:'\u5527',44610:'\u5507',44611:'\u54FD',44612:'\u550F',44613:'\u5703',44614:'\u5704',44615:'\u57C2',44616:'\u57D4',44617:'\u57CB',44618:'\u57C3',44619:'\u5809',44620:'\u590F',44621:'\u5957',44622:'\u5958',44623:'\u595A',44624:'\u5A11',44625:'\u5A18',44626:'\u5A1C',44627:'\u5A1F',44628:'\u5A1B',44629:'\u5A13',44630:'\u59EC',44631:'\u5A20',44632:'\u5A23',44633:'\u5A29',44634:'\u5A25',44635:'\u5A0C',44636:'\u5A09',44637:'\u5B6B',44638:'\u5C58',44639:'\u5BB0',44640:'\u5BB3',44641:'\u5BB6',44642:'\u5BB4',44643:'\u5BAE',44644:'\u5BB5',44645:'\u5BB9',44646:'\u5BB8',44647:'\u5C04',44648:'\u5C51',44649:'\u5C55',44650:'\u5C50',44651:'\u5CED',44652:'\u5CFD',44653:'\u5CFB',44654:'\u5CEA',44655:'\u5CE8',44656:'\u5CF0',44657:'\u5CF6',44658:'\u5D01',44659:'\u5CF4',44660:'\u5DEE',44661:'\u5E2D',44662:'\u5E2B',44663:'\u5EAB',44664:'\u5EAD',44665:'\u5EA7',44666:'\u5F31',44667:'\u5F92',44668:'\u5F91',44669:'\u5F90',44670:'\u6059',44705:'\u6063',44706:'\u6065',44707:'\u6050',44708:'\u6055',44709:'\u606D',44710:'\u6069',44711:'\u606F',44712:'\u6084',44713:'\u609F',44714:'\u609A',44715:'\u608D',44716:'\u6094',44717:'\u608C',44718:'\u6085',44719:'\u6096',44720:'\u6247',44721:'\u62F3',44722:'\u6308',44723:'\u62FF',44724:'\u634E',44725:'\u633E',44726:'\u632F',44727:'\u6355',44728:'\u6342',44729:'\u6346',44730:'\u634F',44731:'\u6349',44732:'\u633A',44733:'\u6350',44734:'\u633D',44735:'\u632A',44736:'\u632B',44737:'\u6328',44738:'\u634D',44739:'\u634C',44740:'\u6548',44741:'\u6549',44742:'\u6599',44743:'\u65C1',44744:'\u65C5',44745:'\u6642',44746:'\u6649',44747:'\u664F',44748:'\u6643',44749:'\u6652',44750:'\u664C',44751:'\u6645',44752:'\u6641',44753:'\u66F8',44754:'\u6714',44755:'\u6715',44756:'\u6717',44757:'\u6821',44758:'\u6838',44759:'\u6848',44760:'\u6846',44761:'\u6853',44762:'\u6839',44763:'\u6842',44764:'\u6854',44765:'\u6829',44766:'\u68B3',44767:'\u6817',44768:'\u684C',44769:'\u6851',44770:'\u683D',44771:'\u67F4',44772:'\u6850',44773:'\u6840',44774:'\u683C',44775:'\u6843',44776:'\u682A',44777:'\u6845',44778:'\u6813',44779:'\u6818',44780:'\u6841',44781:'\u6B8A',44782:'\u6B89',44783:'\u6BB7',44784:'\u6C23',44785:'\u6C27',44786:'\u6C28',44787:'\u6C26',44788:'\u6C24',44789:'\u6CF0',44790:'\u6D6A',44791:'\u6D95',44792:'\u6D88',44793:'\u6D87',44794:'\u6D66',44795:'\u6D78',44796:'\u6D77',44797:'\u6D59',44798:'\u6D93',44864:'\u6D6C',44865:'\u6D89',44866:'\u6D6E',44867:'\u6D5A',44868:'\u6D74',44869:'\u6D69',44870:'\u6D8C',44871:'\u6D8A',44872:'\u6D79',44873:'\u6D85',44874:'\u6D65',44875:'\u6D94',44876:'\u70CA',44877:'\u70D8',44878:'\u70E4',44879:'\u70D9',44880:'\u70C8',44881:'\u70CF',44882:'\u7239',44883:'\u7279',44884:'\u72FC',44885:'\u72F9',44886:'\u72FD',44887:'\u72F8',44888:'\u72F7',44889:'\u7386',44890:'\u73ED',44891:'\u7409',44892:'\u73EE',44893:'\u73E0',44894:'\u73EA',44895:'\u73DE',44896:'\u7554',44897:'\u755D',44898:'\u755C',44899:'\u755A',44900:'\u7559',44901:'\u75BE',44902:'\u75C5',44903:'\u75C7',44904:'\u75B2',44905:'\u75B3',44906:'\u75BD',44907:'\u75BC',44908:'\u75B9',44909:'\u75C2',44910:'\u75B8',44911:'\u768B',44912:'\u76B0',44913:'\u76CA',44914:'\u76CD',44915:'\u76CE',44916:'\u7729',44917:'\u771F',44918:'\u7720',44919:'\u7728',44920:'\u77E9',44921:'\u7830',44922:'\u7827',44923:'\u7838',44924:'\u781D',44925:'\u7834',44926:'\u7837',44961:'\u7825',44962:'\u782D',44963:'\u7820',44964:'\u781F',44965:'\u7832',44966:'\u7955',44967:'\u7950',44968:'\u7960',44969:'\u795F',44970:'\u7956',44971:'\u795E',44972:'\u795D',44973:'\u7957',44974:'\u795A',44975:'\u79E4',44976:'\u79E3',44977:'\u79E7',44978:'\u79DF',44979:'\u79E6',44980:'\u79E9',44981:'\u79D8',44982:'\u7A84',44983:'\u7A88',44984:'\u7AD9',44985:'\u7B06',44986:'\u7B11',44987:'\u7C89',44988:'\u7D21',44989:'\u7D17',44990:'\u7D0B',44991:'\u7D0A',44992:'\u7D20',44993:'\u7D22',44994:'\u7D14',44995:'\u7D10',44996:'\u7D15',44997:'\u7D1A',44998:'\u7D1C',44999:'\u7D0D',45000:'\u7D19',45001:'\u7D1B',45002:'\u7F3A',45003:'\u7F5F',45004:'\u7F94',45005:'\u7FC5',45006:'\u7FC1',45007:'\u8006',45008:'\u8018',45009:'\u8015',45010:'\u8019',45011:'\u8017',45012:'\u803D',45013:'\u803F',45014:'\u80F1',45015:'\u8102',45016:'\u80F0',45017:'\u8105',45018:'\u80ED',45019:'\u80F4',45020:'\u8106',45021:'\u80F8',45022:'\u80F3',45023:'\u8108',45024:'\u80FD',45025:'\u810A',45026:'\u80FC',45027:'\u80EF',45028:'\u81ED',45029:'\u81EC',45030:'\u8200',45031:'\u8210',45032:'\u822A',45033:'\u822B',45034:'\u8228',45035:'\u822C',45036:'\u82BB',45037:'\u832B',45038:'\u8352',45039:'\u8354',45040:'\u834A',45041:'\u8338',45042:'\u8350',45043:'\u8349',45044:'\u8335',45045:'\u8334',45046:'\u834F',45047:'\u8332',45048:'\u8339',45049:'\u8336',45050:'\u8317',45051:'\u8340',45052:'\u8331',45053:'\u8328',45054:'\u8343',45120:'\u8654',45121:'\u868A',45122:'\u86AA',45123:'\u8693',45124:'\u86A4',45125:'\u86A9',45126:'\u868C',45127:'\u86A3',45128:'\u869C',45129:'\u8870',45130:'\u8877',45131:'\u8881',45132:'\u8882',45133:'\u887D',45134:'\u8879',45135:'\u8A18',45136:'\u8A10',45137:'\u8A0E',45138:'\u8A0C',45139:'\u8A15',45140:'\u8A0A',45141:'\u8A17',45142:'\u8A13',45143:'\u8A16',45144:'\u8A0F',45145:'\u8A11',45146:'\u8C48',45147:'\u8C7A',45148:'\u8C79',45149:'\u8CA1',45150:'\u8CA2',45151:'\u8D77',45152:'\u8EAC',45153:'\u8ED2',45154:'\u8ED4',45155:'\u8ECF',45156:'\u8FB1',45157:'\u9001',45158:'\u9006',45159:'\u8FF7',45160:'\u9000',45161:'\u8FFA',45162:'\u8FF4',45163:'\u9003',45164:'\u8FFD',45165:'\u9005',45166:'\u8FF8',45167:'\u9095',45168:'\u90E1',45169:'\u90DD',45170:'\u90E2',45171:'\u9152',45172:'\u914D',45173:'\u914C',45174:'\u91D8',45175:'\u91DD',45176:'\u91D7',45177:'\u91DC',45178:'\u91D9',45179:'\u9583',45180:'\u9662',45181:'\u9663',45182:'\u9661',45217:'\u965B',45218:'\u965D',45219:'\u9664',45220:'\u9658',45221:'\u965E',45222:'\u96BB',45223:'\u98E2',45224:'\u99AC',45225:'\u9AA8',45226:'\u9AD8',45227:'\u9B25',45228:'\u9B32',45229:'\u9B3C',45230:'\u4E7E',45231:'\u507A',45232:'\u507D',45233:'\u505C',45234:'\u5047',45235:'\u5043',45236:'\u504C',45237:'\u505A',45238:'\u5049',45239:'\u5065',45240:'\u5076',45241:'\u504E',45242:'\u5055',45243:'\u5075',45244:'\u5074',45245:'\u5077',45246:'\u504F',45247:'\u500F',45248:'\u506F',45249:'\u506D',45250:'\u515C',45251:'\u5195',45252:'\u51F0',45253:'\u526A',45254:'\u526F',45255:'\u52D2',45256:'\u52D9',45257:'\u52D8',45258:'\u52D5',45259:'\u5310',45260:'\u530F',45261:'\u5319',45262:'\u533F',45263:'\u5340',45264:'\u533E',45265:'\u53C3',45266:'\u66FC',45267:'\u5546',45268:'\u556A',45269:'\u5566',45270:'\u5544',45271:'\u555E',45272:'\u5561',45273:'\u5543',45274:'\u554A',45275:'\u5531',45276:'\u5556',45277:'\u554F',45278:'\u5555',45279:'\u552F',45280:'\u5564',45281:'\u5538',45282:'\u552E',45283:'\u555C',45284:'\u552C',45285:'\u5563',45286:'\u5533',45287:'\u5541',45288:'\u5557',45289:'\u5708',45290:'\u570B',45291:'\u5709',45292:'\u57DF',45293:'\u5805',45294:'\u580A',45295:'\u5806',45296:'\u57E0',45297:'\u57E4',45298:'\u57FA',45299:'\u5802',45300:'\u5835',45301:'\u57F7',45302:'\u57F9',45303:'\u5920',45304:'\u5962',45305:'\u5A36',45306:'\u5A41',45307:'\u5A49',45308:'\u5A66',45309:'\u5A6A',45310:'\u5A40',45376:'\u5A3C',45377:'\u5A62',45378:'\u5A5A',45379:'\u5A46',45380:'\u5A4A',45381:'\u5B70',45382:'\u5BC7',45383:'\u5BC5',45384:'\u5BC4',45385:'\u5BC2',45386:'\u5BBF',45387:'\u5BC6',45388:'\u5C09',45389:'\u5C08',45390:'\u5C07',45391:'\u5C60',45392:'\u5C5C',45393:'\u5C5D',45394:'\u5D07',45395:'\u5D06',45396:'\u5D0E',45397:'\u5D1B',45398:'\u5D16',45399:'\u5D22',45400:'\u5D11',45401:'\u5D29',45402:'\u5D14',45403:'\u5D19',45404:'\u5D24',45405:'\u5D27',45406:'\u5D17',45407:'\u5DE2',45408:'\u5E38',45409:'\u5E36',45410:'\u5E33',45411:'\u5E37',45412:'\u5EB7',45413:'\u5EB8',45414:'\u5EB6',45415:'\u5EB5',45416:'\u5EBE',45417:'\u5F35',45418:'\u5F37',45419:'\u5F57',45420:'\u5F6C',45421:'\u5F69',45422:'\u5F6B',45423:'\u5F97',45424:'\u5F99',45425:'\u5F9E',45426:'\u5F98',45427:'\u5FA1',45428:'\u5FA0',45429:'\u5F9C',45430:'\u607F',45431:'\u60A3',45432:'\u6089',45433:'\u60A0',45434:'\u60A8',45435:'\u60CB',45436:'\u60B4',45437:'\u60E6',45438:'\u60BD',45473:'\u60C5',45474:'\u60BB',45475:'\u60B5',45476:'\u60DC',45477:'\u60BC',45478:'\u60D8',45479:'\u60D5',45480:'\u60C6',45481:'\u60DF',45482:'\u60B8',45483:'\u60DA',45484:'\u60C7',45485:'\u621A',45486:'\u621B',45487:'\u6248',45488:'\u63A0',45489:'\u63A7',45490:'\u6372',45491:'\u6396',45492:'\u63A2',45493:'\u63A5',45494:'\u6377',45495:'\u6367',45496:'\u6398',45497:'\u63AA',45498:'\u6371',45499:'\u63A9',45500:'\u6389',45501:'\u6383',45502:'\u639B',45503:'\u636B',45504:'\u63A8',45505:'\u6384',45506:'\u6388',45507:'\u6399',45508:'\u63A1',45509:'\u63AC',45510:'\u6392',45511:'\u638F',45512:'\u6380',45513:'\u637B',45514:'\u6369',45515:'\u6368',45516:'\u637A',45517:'\u655D',45518:'\u6556',45519:'\u6551',45520:'\u6559',45521:'\u6557',45522:'\u555F',45523:'\u654F',45524:'\u6558',45525:'\u6555',45526:'\u6554',45527:'\u659C',45528:'\u659B',45529:'\u65AC',45530:'\u65CF',45531:'\u65CB',45532:'\u65CC',45533:'\u65CE',45534:'\u665D',45535:'\u665A',45536:'\u6664',45537:'\u6668',45538:'\u6666',45539:'\u665E',45540:'\u66F9',45541:'\u52D7',45542:'\u671B',45543:'\u6881',45544:'\u68AF',45545:'\u68A2',45546:'\u6893',45547:'\u68B5',45548:'\u687F',45549:'\u6876',45550:'\u68B1',45551:'\u68A7',45552:'\u6897',45553:'\u68B0',45554:'\u6883',45555:'\u68C4',45556:'\u68AD',45557:'\u6886',45558:'\u6885',45559:'\u6894',45560:'\u689D',45561:'\u68A8',45562:'\u689F',45563:'\u68A1',45564:'\u6882',45565:'\u6B32',45566:'\u6BBA',45632:'\u6BEB',45633:'\u6BEC',45634:'\u6C2B',45635:'\u6D8E',45636:'\u6DBC',45637:'\u6DF3',45638:'\u6DD9',45639:'\u6DB2',45640:'\u6DE1',45641:'\u6DCC',45642:'\u6DE4',45643:'\u6DFB',45644:'\u6DFA',45645:'\u6E05',45646:'\u6DC7',45647:'\u6DCB',45648:'\u6DAF',45649:'\u6DD1',45650:'\u6DAE',45651:'\u6DDE',45652:'\u6DF9',45653:'\u6DB8',45654:'\u6DF7',45655:'\u6DF5',45656:'\u6DC5',45657:'\u6DD2',45658:'\u6E1A',45659:'\u6DB5',45660:'\u6DDA',45661:'\u6DEB',45662:'\u6DD8',45663:'\u6DEA',45664:'\u6DF1',45665:'\u6DEE',45666:'\u6DE8',45667:'\u6DC6',45668:'\u6DC4',45669:'\u6DAA',45670:'\u6DEC',45671:'\u6DBF',45672:'\u6DE6',45673:'\u70F9',45674:'\u7109',45675:'\u710A',45676:'\u70FD',45677:'\u70EF',45678:'\u723D',45679:'\u727D',45680:'\u7281',45681:'\u731C',45682:'\u731B',45683:'\u7316',45684:'\u7313',45685:'\u7319',45686:'\u7387',45687:'\u7405',45688:'\u740A',45689:'\u7403',45690:'\u7406',45691:'\u73FE',45692:'\u740D',45693:'\u74E0',45694:'\u74F6',45729:'\u74F7',45730:'\u751C',45731:'\u7522',45732:'\u7565',45733:'\u7566',45734:'\u7562',45735:'\u7570',45736:'\u758F',45737:'\u75D4',45738:'\u75D5',45739:'\u75B5',45740:'\u75CA',45741:'\u75CD',45742:'\u768E',45743:'\u76D4',45744:'\u76D2',45745:'\u76DB',45746:'\u7737',45747:'\u773E',45748:'\u773C',45749:'\u7736',45750:'\u7738',45751:'\u773A',45752:'\u786B',45753:'\u7843',45754:'\u784E',45755:'\u7965',45756:'\u7968',45757:'\u796D',45758:'\u79FB',45759:'\u7A92',45760:'\u7A95',45761:'\u7B20',45762:'\u7B28',45763:'\u7B1B',45764:'\u7B2C',45765:'\u7B26',45766:'\u7B19',45767:'\u7B1E',45768:'\u7B2E',45769:'\u7C92',45770:'\u7C97',45771:'\u7C95',45772:'\u7D46',45773:'\u7D43',45774:'\u7D71',45775:'\u7D2E',45776:'\u7D39',45777:'\u7D3C',45778:'\u7D40',45779:'\u7D30',45780:'\u7D33',45781:'\u7D44',45782:'\u7D2F',45783:'\u7D42',45784:'\u7D32',45785:'\u7D31',45786:'\u7F3D',45787:'\u7F9E',45788:'\u7F9A',45789:'\u7FCC',45790:'\u7FCE',45791:'\u7FD2',45792:'\u801C',45793:'\u804A',45794:'\u8046',45795:'\u812F',45796:'\u8116',45797:'\u8123',45798:'\u812B',45799:'\u8129',45800:'\u8130',45801:'\u8124',45802:'\u8202',45803:'\u8235',45804:'\u8237',45805:'\u8236',45806:'\u8239',45807:'\u838E',45808:'\u839E',45809:'\u8398',45810:'\u8378',45811:'\u83A2',45812:'\u8396',45813:'\u83BD',45814:'\u83AB',45815:'\u8392',45816:'\u838A',45817:'\u8393',45818:'\u8389',45819:'\u83A0',45820:'\u8377',45821:'\u837B',45822:'\u837C',45888:'\u8386',45889:'\u83A7',45890:'\u8655',45891:'\u5F6A',45892:'\u86C7',45893:'\u86C0',45894:'\u86B6',45895:'\u86C4',45896:'\u86B5',45897:'\u86C6',45898:'\u86CB',45899:'\u86B1',45900:'\u86AF',45901:'\u86C9',45902:'\u8853',45903:'\u889E',45904:'\u8888',45905:'\u88AB',45906:'\u8892',45907:'\u8896',45908:'\u888D',45909:'\u888B',45910:'\u8993',45911:'\u898F',45912:'\u8A2A',45913:'\u8A1D',45914:'\u8A23',45915:'\u8A25',45916:'\u8A31',45917:'\u8A2D',45918:'\u8A1F',45919:'\u8A1B',45920:'\u8A22',45921:'\u8C49',45922:'\u8C5A',45923:'\u8CA9',45924:'\u8CAC',45925:'\u8CAB',45926:'\u8CA8',45927:'\u8CAA',45928:'\u8CA7',45929:'\u8D67',45930:'\u8D66',45931:'\u8DBE',45932:'\u8DBA',45933:'\u8EDB',45934:'\u8EDF',45935:'\u9019',45936:'\u900D',45937:'\u901A',45938:'\u9017',45939:'\u9023',45940:'\u901F',45941:'\u901D',45942:'\u9010',45943:'\u9015',45944:'\u901E',45945:'\u9020',45946:'\u900F',45947:'\u9022',45948:'\u9016',45949:'\u901B',45950:'\u9014',45985:'\u90E8',45986:'\u90ED',45987:'\u90FD',45988:'\u9157',45989:'\u91CE',45990:'\u91F5',45991:'\u91E6',45992:'\u91E3',45993:'\u91E7',45994:'\u91ED',45995:'\u91E9',45996:'\u9589',45997:'\u966A',45998:'\u9675',45999:'\u9673',46000:'\u9678',46001:'\u9670',46002:'\u9674',46003:'\u9676',46004:'\u9677',46005:'\u966C',46006:'\u96C0',46007:'\u96EA',46008:'\u96E9',46009:'\u7AE0',46010:'\u7ADF',46011:'\u9802',46012:'\u9803',46013:'\u9B5A',46014:'\u9CE5',46015:'\u9E75',46016:'\u9E7F',46017:'\u9EA5',46018:'\u9EBB',46019:'\u50A2',46020:'\u508D',46021:'\u5085',46022:'\u5099',46023:'\u5091',46024:'\u5080',46025:'\u5096',46026:'\u5098',46027:'\u509A',46028:'\u6700',46029:'\u51F1',46030:'\u5272',46031:'\u5274',46032:'\u5275',46033:'\u5269',46034:'\u52DE',46035:'\u52DD',46036:'\u52DB',46037:'\u535A',46038:'\u53A5',46039:'\u557B',46040:'\u5580',46041:'\u55A7',46042:'\u557C',46043:'\u558A',46044:'\u559D',46045:'\u5598',46046:'\u5582',46047:'\u559C',46048:'\u55AA',46049:'\u5594',46050:'\u5587',46051:'\u558B',46052:'\u5583',46053:'\u55B3',46054:'\u55AE',46055:'\u559F',46056:'\u553E',46057:'\u55B2',46058:'\u559A',46059:'\u55BB',46060:'\u55AC',46061:'\u55B1',46062:'\u557E',46063:'\u5589',46064:'\u55AB',46065:'\u5599',46066:'\u570D',46067:'\u582F',46068:'\u582A',46069:'\u5834',46070:'\u5824',46071:'\u5830',46072:'\u5831',46073:'\u5821',46074:'\u581D',46075:'\u5820',46076:'\u58F9',46077:'\u58FA',46078:'\u5960',46144:'\u5A77',46145:'\u5A9A',46146:'\u5A7F',46147:'\u5A92',46148:'\u5A9B',46149:'\u5AA7',46150:'\u5B73',46151:'\u5B71',46152:'\u5BD2',46153:'\u5BCC',46154:'\u5BD3',46155:'\u5BD0',46156:'\u5C0A',46157:'\u5C0B',46158:'\u5C31',46159:'\u5D4C',46160:'\u5D50',46161:'\u5D34',46162:'\u5D47',46163:'\u5DFD',46164:'\u5E45',46165:'\u5E3D',46166:'\u5E40',46167:'\u5E43',46168:'\u5E7E',46169:'\u5ECA',46170:'\u5EC1',46171:'\u5EC2',46172:'\u5EC4',46173:'\u5F3C',46174:'\u5F6D',46175:'\u5FA9',46176:'\u5FAA',46177:'\u5FA8',46178:'\u60D1',46179:'\u60E1',46180:'\u60B2',46181:'\u60B6',46182:'\u60E0',46183:'\u611C',46184:'\u6123',46185:'\u60FA',46186:'\u6115',46187:'\u60F0',46188:'\u60FB',46189:'\u60F4',46190:'\u6168',46191:'\u60F1',46192:'\u610E',46193:'\u60F6',46194:'\u6109',46195:'\u6100',46196:'\u6112',46197:'\u621F',46198:'\u6249',46199:'\u63A3',46200:'\u638C',46201:'\u63CF',46202:'\u63C0',46203:'\u63E9',46204:'\u63C9',46205:'\u63C6',46206:'\u63CD',46241:'\u63D2',46242:'\u63E3',46243:'\u63D0',46244:'\u63E1',46245:'\u63D6',46246:'\u63ED',46247:'\u63EE',46248:'\u6376',46249:'\u63F4',46250:'\u63EA',46251:'\u63DB',46252:'\u6452',46253:'\u63DA',46254:'\u63F9',46255:'\u655E',46256:'\u6566',46257:'\u6562',46258:'\u6563',46259:'\u6591',46260:'\u6590',46261:'\u65AF',46262:'\u666E',46263:'\u6670',46264:'\u6674',46265:'\u6676',46266:'\u666F',46267:'\u6691',46268:'\u667A',46269:'\u667E',46270:'\u6677',46271:'\u66FE',46272:'\u66FF',46273:'\u671F',46274:'\u671D',46275:'\u68FA',46276:'\u68D5',46277:'\u68E0',46278:'\u68D8',46279:'\u68D7',46280:'\u6905',46281:'\u68DF',46282:'\u68F5',46283:'\u68EE',46284:'\u68E7',46285:'\u68F9',46286:'\u68D2',46287:'\u68F2',46288:'\u68E3',46289:'\u68CB',46290:'\u68CD',46291:'\u690D',46292:'\u6912',46293:'\u690E',46294:'\u68C9',46295:'\u68DA',46296:'\u696E',46297:'\u68FB',46298:'\u6B3E',46299:'\u6B3A',46300:'\u6B3D',46301:'\u6B98',46302:'\u6B96',46303:'\u6BBC',46304:'\u6BEF',46305:'\u6C2E',46306:'\u6C2F',46307:'\u6C2C',46308:'\u6E2F',46309:'\u6E38',46310:'\u6E54',46311:'\u6E21',46312:'\u6E32',46313:'\u6E67',46314:'\u6E4A',46315:'\u6E20',46316:'\u6E25',46317:'\u6E23',46318:'\u6E1B',46319:'\u6E5B',46320:'\u6E58',46321:'\u6E24',46322:'\u6E56',46323:'\u6E6E',46324:'\u6E2D',46325:'\u6E26',46326:'\u6E6F',46327:'\u6E34',46328:'\u6E4D',46329:'\u6E3A',46330:'\u6E2C',46331:'\u6E43',46332:'\u6E1D',46333:'\u6E3E',46334:'\u6ECB',46400:'\u6E89',46401:'\u6E19',46402:'\u6E4E',46403:'\u6E63',46404:'\u6E44',46405:'\u6E72',46406:'\u6E69',46407:'\u6E5F',46408:'\u7119',46409:'\u711A',46410:'\u7126',46411:'\u7130',46412:'\u7121',46413:'\u7136',46414:'\u716E',46415:'\u711C',46416:'\u724C',46417:'\u7284',46418:'\u7280',46419:'\u7336',46420:'\u7325',46421:'\u7334',46422:'\u7329',46423:'\u743A',46424:'\u742A',46425:'\u7433',46426:'\u7422',46427:'\u7425',46428:'\u7435',46429:'\u7436',46430:'\u7434',46431:'\u742F',46432:'\u741B',46433:'\u7426',46434:'\u7428',46435:'\u7525',46436:'\u7526',46437:'\u756B',46438:'\u756A',46439:'\u75E2',46440:'\u75DB',46441:'\u75E3',46442:'\u75D9',46443:'\u75D8',46444:'\u75DE',46445:'\u75E0',46446:'\u767B',46447:'\u767C',46448:'\u7696',46449:'\u7693',46450:'\u76B4',46451:'\u76DC',46452:'\u774F',46453:'\u77ED',46454:'\u785D',46455:'\u786C',46456:'\u786F',46457:'\u7A0D',46458:'\u7A08',46459:'\u7A0B',46460:'\u7A05',46461:'\u7A00',46462:'\u7A98',46497:'\u7A97',46498:'\u7A96',46499:'\u7AE5',46500:'\u7AE3',46501:'\u7B49',46502:'\u7B56',46503:'\u7B46',46504:'\u7B50',46505:'\u7B52',46506:'\u7B54',46507:'\u7B4D',46508:'\u7B4B',46509:'\u7B4F',46510:'\u7B51',46511:'\u7C9F',46512:'\u7CA5',46513:'\u7D5E',46514:'\u7D50',46515:'\u7D68',46516:'\u7D55',46517:'\u7D2B',46518:'\u7D6E',46519:'\u7D72',46520:'\u7D61',46521:'\u7D66',46522:'\u7D62',46523:'\u7D70',46524:'\u7D73',46525:'\u5584',46526:'\u7FD4',46527:'\u7FD5',46528:'\u800B',46529:'\u8052',46530:'\u8085',46531:'\u8155',46532:'\u8154',46533:'\u814B',46534:'\u8151',46535:'\u814E',46536:'\u8139',46537:'\u8146',46538:'\u813E',46539:'\u814C',46540:'\u8153',46541:'\u8174',46542:'\u8212',46543:'\u821C',46544:'\u83E9',46545:'\u8403',46546:'\u83F8',46547:'\u840D',46548:'\u83E0',46549:'\u83C5',46550:'\u840B',46551:'\u83C1',46552:'\u83EF',46553:'\u83F1',46554:'\u83F4',46555:'\u8457',46556:'\u840A',46557:'\u83F0',46558:'\u840C',46559:'\u83CC',46560:'\u83FD',46561:'\u83F2',46562:'\u83CA',46563:'\u8438',46564:'\u840E',46565:'\u8404',46566:'\u83DC',46567:'\u8407',46568:'\u83D4',46569:'\u83DF',46570:'\u865B',46571:'\u86DF',46572:'\u86D9',46573:'\u86ED',46574:'\u86D4',46575:'\u86DB',46576:'\u86E4',46577:'\u86D0',46578:'\u86DE',46579:'\u8857',46580:'\u88C1',46581:'\u88C2',46582:'\u88B1',46583:'\u8983',46584:'\u8996',46585:'\u8A3B',46586:'\u8A60',46587:'\u8A55',46588:'\u8A5E',46589:'\u8A3C',46590:'\u8A41',46656:'\u8A54',46657:'\u8A5B',46658:'\u8A50',46659:'\u8A46',46660:'\u8A34',46661:'\u8A3A',46662:'\u8A36',46663:'\u8A56',46664:'\u8C61',46665:'\u8C82',46666:'\u8CAF',46667:'\u8CBC',46668:'\u8CB3',46669:'\u8CBD',46670:'\u8CC1',46671:'\u8CBB',46672:'\u8CC0',46673:'\u8CB4',46674:'\u8CB7',46675:'\u8CB6',46676:'\u8CBF',46677:'\u8CB8',46678:'\u8D8A',46679:'\u8D85',46680:'\u8D81',46681:'\u8DCE',46682:'\u8DDD',46683:'\u8DCB',46684:'\u8DDA',46685:'\u8DD1',46686:'\u8DCC',46687:'\u8DDB',46688:'\u8DC6',46689:'\u8EFB',46690:'\u8EF8',46691:'\u8EFC',46692:'\u8F9C',46693:'\u902E',46694:'\u9035',46695:'\u9031',46696:'\u9038',46697:'\u9032',46698:'\u9036',46699:'\u9102',46700:'\u90F5',46701:'\u9109',46702:'\u90FE',46703:'\u9163',46704:'\u9165',46705:'\u91CF',46706:'\u9214',46707:'\u9215',46708:'\u9223',46709:'\u9209',46710:'\u921E',46711:'\u920D',46712:'\u9210',46713:'\u9207',46714:'\u9211',46715:'\u9594',46716:'\u958F',46717:'\u958B',46718:'\u9591',46753:'\u9593',46754:'\u9592',46755:'\u958E',46756:'\u968A',46757:'\u968E',46758:'\u968B',46759:'\u967D',46760:'\u9685',46761:'\u9686',46762:'\u968D',46763:'\u9672',46764:'\u9684',46765:'\u96C1',46766:'\u96C5',46767:'\u96C4',46768:'\u96C6',46769:'\u96C7',46770:'\u96EF',46771:'\u96F2',46772:'\u97CC',46773:'\u9805',46774:'\u9806',46775:'\u9808',46776:'\u98E7',46777:'\u98EA',46778:'\u98EF',46779:'\u98E9',46780:'\u98F2',46781:'\u98ED',46782:'\u99AE',46783:'\u99AD',46784:'\u9EC3',46785:'\u9ECD',46786:'\u9ED1',46787:'\u4E82',46788:'\u50AD',46789:'\u50B5',46790:'\u50B2',46791:'\u50B3',46792:'\u50C5',46793:'\u50BE',46794:'\u50AC',46795:'\u50B7',46796:'\u50BB',46797:'\u50AF',46798:'\u50C7',46799:'\u527F',46800:'\u5277',46801:'\u527D',46802:'\u52DF',46803:'\u52E6',46804:'\u52E4',46805:'\u52E2',46806:'\u52E3',46807:'\u532F',46808:'\u55DF',46809:'\u55E8',46810:'\u55D3',46811:'\u55E6',46812:'\u55CE',46813:'\u55DC',46814:'\u55C7',46815:'\u55D1',46816:'\u55E3',46817:'\u55E4',46818:'\u55EF',46819:'\u55DA',46820:'\u55E1',46821:'\u55C5',46822:'\u55C6',46823:'\u55E5',46824:'\u55C9',46825:'\u5712',46826:'\u5713',46827:'\u585E',46828:'\u5851',46829:'\u5858',46830:'\u5857',46831:'\u585A',46832:'\u5854',46833:'\u586B',46834:'\u584C',46835:'\u586D',46836:'\u584A',46837:'\u5862',46838:'\u5852',46839:'\u584B',46840:'\u5967',46841:'\u5AC1',46842:'\u5AC9',46843:'\u5ACC',46844:'\u5ABE',46845:'\u5ABD',46846:'\u5ABC',46912:'\u5AB3',46913:'\u5AC2',46914:'\u5AB2',46915:'\u5D69',46916:'\u5D6F',46917:'\u5E4C',46918:'\u5E79',46919:'\u5EC9',46920:'\u5EC8',46921:'\u5F12',46922:'\u5F59',46923:'\u5FAC',46924:'\u5FAE',46925:'\u611A',46926:'\u610F',46927:'\u6148',46928:'\u611F',46929:'\u60F3',46930:'\u611B',46931:'\u60F9',46932:'\u6101',46933:'\u6108',46934:'\u614E',46935:'\u614C',46936:'\u6144',46937:'\u614D',46938:'\u613E',46939:'\u6134',46940:'\u6127',46941:'\u610D',46942:'\u6106',46943:'\u6137',46944:'\u6221',46945:'\u6222',46946:'\u6413',46947:'\u643E',46948:'\u641E',46949:'\u642A',46950:'\u642D',46951:'\u643D',46952:'\u642C',46953:'\u640F',46954:'\u641C',46955:'\u6414',46956:'\u640D',46957:'\u6436',46958:'\u6416',46959:'\u6417',46960:'\u6406',46961:'\u656C',46962:'\u659F',46963:'\u65B0',46964:'\u6697',46965:'\u6689',46966:'\u6687',46967:'\u6688',46968:'\u6696',46969:'\u6684',46970:'\u6698',46971:'\u668D',46972:'\u6703',46973:'\u6994',46974:'\u696D',47009:'\u695A',47010:'\u6977',47011:'\u6960',47012:'\u6954',47013:'\u6975',47014:'\u6930',47015:'\u6982',47016:'\u694A',47017:'\u6968',47018:'\u696B',47019:'\u695E',47020:'\u6953',47021:'\u6979',47022:'\u6986',47023:'\u695D',47024:'\u6963',47025:'\u695B',47026:'\u6B47',47027:'\u6B72',47028:'\u6BC0',47029:'\u6BBF',47030:'\u6BD3',47031:'\u6BFD',47032:'\u6EA2',47033:'\u6EAF',47034:'\u6ED3',47035:'\u6EB6',47036:'\u6EC2',47037:'\u6E90',47038:'\u6E9D',47039:'\u6EC7',47040:'\u6EC5',47041:'\u6EA5',47042:'\u6E98',47043:'\u6EBC',47044:'\u6EBA',47045:'\u6EAB',47046:'\u6ED1',47047:'\u6E96',47048:'\u6E9C',47049:'\u6EC4',47050:'\u6ED4',47051:'\u6EAA',47052:'\u6EA7',47053:'\u6EB4',47054:'\u714E',47055:'\u7159',47056:'\u7169',47057:'\u7164',47058:'\u7149',47059:'\u7167',47060:'\u715C',47061:'\u716C',47062:'\u7166',47063:'\u714C',47064:'\u7165',47065:'\u715E',47066:'\u7146',47067:'\u7168',47068:'\u7156',47069:'\u723A',47070:'\u7252',47071:'\u7337',47072:'\u7345',47073:'\u733F',47074:'\u733E',47075:'\u746F',47076:'\u745A',47077:'\u7455',47078:'\u745F',47079:'\u745E',47080:'\u7441',47081:'\u743F',47082:'\u7459',47083:'\u745B',47084:'\u745C',47085:'\u7576',47086:'\u7578',47087:'\u7600',47088:'\u75F0',47089:'\u7601',47090:'\u75F2',47091:'\u75F1',47092:'\u75FA',47093:'\u75FF',47094:'\u75F4',47095:'\u75F3',47096:'\u76DE',47097:'\u76DF',47098:'\u775B',47099:'\u776B',47100:'\u7766',47101:'\u775E',47102:'\u7763',47168:'\u7779',47169:'\u776A',47170:'\u776C',47171:'\u775C',47172:'\u7765',47173:'\u7768',47174:'\u7762',47175:'\u77EE',47176:'\u788E',47177:'\u78B0',47178:'\u7897',47179:'\u7898',47180:'\u788C',47181:'\u7889',47182:'\u787C',47183:'\u7891',47184:'\u7893',47185:'\u787F',47186:'\u797A',47187:'\u797F',47188:'\u7981',47189:'\u842C',47190:'\u79BD',47191:'\u7A1C',47192:'\u7A1A',47193:'\u7A20',47194:'\u7A14',47195:'\u7A1F',47196:'\u7A1E',47197:'\u7A9F',47198:'\u7AA0',47199:'\u7B77',47200:'\u7BC0',47201:'\u7B60',47202:'\u7B6E',47203:'\u7B67',47204:'\u7CB1',47205:'\u7CB3',47206:'\u7CB5',47207:'\u7D93',47208:'\u7D79',47209:'\u7D91',47210:'\u7D81',47211:'\u7D8F',47212:'\u7D5B',47213:'\u7F6E',47214:'\u7F69',47215:'\u7F6A',47216:'\u7F72',47217:'\u7FA9',47218:'\u7FA8',47219:'\u7FA4',47220:'\u8056',47221:'\u8058',47222:'\u8086',47223:'\u8084',47224:'\u8171',47225:'\u8170',47226:'\u8178',47227:'\u8165',47228:'\u816E',47229:'\u8173',47230:'\u816B',47265:'\u8179',47266:'\u817A',47267:'\u8166',47268:'\u8205',47269:'\u8247',47270:'\u8482',47271:'\u8477',47272:'\u843D',47273:'\u8431',47274:'\u8475',47275:'\u8466',47276:'\u846B',47277:'\u8449',47278:'\u846C',47279:'\u845B',47280:'\u843C',47281:'\u8435',47282:'\u8461',47283:'\u8463',47284:'\u8469',47285:'\u846D',47286:'\u8446',47287:'\u865E',47288:'\u865C',47289:'\u865F',47290:'\u86F9',47291:'\u8713',47292:'\u8708',47293:'\u8707',47294:'\u8700',47295:'\u86FE',47296:'\u86FB',47297:'\u8702',47298:'\u8703',47299:'\u8706',47300:'\u870A',47301:'\u8859',47302:'\u88DF',47303:'\u88D4',47304:'\u88D9',47305:'\u88DC',47306:'\u88D8',47307:'\u88DD',47308:'\u88E1',47309:'\u88CA',47310:'\u88D5',47311:'\u88D2',47312:'\u899C',47313:'\u89E3',47314:'\u8A6B',47315:'\u8A72',47316:'\u8A73',47317:'\u8A66',47318:'\u8A69',47319:'\u8A70',47320:'\u8A87',47321:'\u8A7C',47322:'\u8A63',47323:'\u8AA0',47324:'\u8A71',47325:'\u8A85',47326:'\u8A6D',47327:'\u8A62',47328:'\u8A6E',47329:'\u8A6C',47330:'\u8A79',47331:'\u8A7B',47332:'\u8A3E',47333:'\u8A68',47334:'\u8C62',47335:'\u8C8A',47336:'\u8C89',47337:'\u8CCA',47338:'\u8CC7',47339:'\u8CC8',47340:'\u8CC4',47341:'\u8CB2',47342:'\u8CC3',47343:'\u8CC2',47344:'\u8CC5',47345:'\u8DE1',47346:'\u8DDF',47347:'\u8DE8',47348:'\u8DEF',47349:'\u8DF3',47350:'\u8DFA',47351:'\u8DEA',47352:'\u8DE4',47353:'\u8DE6',47354:'\u8EB2',47355:'\u8F03',47356:'\u8F09',47357:'\u8EFE',47358:'\u8F0A',47424:'\u8F9F',47425:'\u8FB2',47426:'\u904B',47427:'\u904A',47428:'\u9053',47429:'\u9042',47430:'\u9054',47431:'\u903C',47432:'\u9055',47433:'\u9050',47434:'\u9047',47435:'\u904F',47436:'\u904E',47437:'\u904D',47438:'\u9051',47439:'\u903E',47440:'\u9041',47441:'\u9112',47442:'\u9117',47443:'\u916C',47444:'\u916A',47445:'\u9169',47446:'\u91C9',47447:'\u9237',47448:'\u9257',47449:'\u9238',47450:'\u923D',47451:'\u9240',47452:'\u923E',47453:'\u925B',47454:'\u924B',47455:'\u9264',47456:'\u9251',47457:'\u9234',47458:'\u9249',47459:'\u924D',47460:'\u9245',47461:'\u9239',47462:'\u923F',47463:'\u925A',47464:'\u9598',47465:'\u9698',47466:'\u9694',47467:'\u9695',47468:'\u96CD',47469:'\u96CB',47470:'\u96C9',47471:'\u96CA',47472:'\u96F7',47473:'\u96FB',47474:'\u96F9',47475:'\u96F6',47476:'\u9756',47477:'\u9774',47478:'\u9776',47479:'\u9810',47480:'\u9811',47481:'\u9813',47482:'\u980A',47483:'\u9812',47484:'\u980C',47485:'\u98FC',47486:'\u98F4',47521:'\u98FD',47522:'\u98FE',47523:'\u99B3',47524:'\u99B1',47525:'\u99B4',47526:'\u9AE1',47527:'\u9CE9',47528:'\u9E82',47529:'\u9F0E',47530:'\u9F13',47531:'\u9F20',47532:'\u50E7',47533:'\u50EE',47534:'\u50E5',47535:'\u50D6',47536:'\u50ED',47537:'\u50DA',47538:'\u50D5',47539:'\u50CF',47540:'\u50D1',47541:'\u50F1',47542:'\u50CE',47543:'\u50E9',47544:'\u5162',47545:'\u51F3',47546:'\u5283',47547:'\u5282',47548:'\u5331',47549:'\u53AD',47550:'\u55FE',47551:'\u5600',47552:'\u561B',47553:'\u5617',47554:'\u55FD',47555:'\u5614',47556:'\u5606',47557:'\u5609',47558:'\u560D',47559:'\u560E',47560:'\u55F7',47561:'\u5616',47562:'\u561F',47563:'\u5608',47564:'\u5610',47565:'\u55F6',47566:'\u5718',47567:'\u5716',47568:'\u5875',47569:'\u587E',47570:'\u5883',47571:'\u5893',47572:'\u588A',47573:'\u5879',47574:'\u5885',47575:'\u587D',47576:'\u58FD',47577:'\u5925',47578:'\u5922',47579:'\u5924',47580:'\u596A',47581:'\u5969',47582:'\u5AE1',47583:'\u5AE6',47584:'\u5AE9',47585:'\u5AD7',47586:'\u5AD6',47587:'\u5AD8',47588:'\u5AE3',47589:'\u5B75',47590:'\u5BDE',47591:'\u5BE7',47592:'\u5BE1',47593:'\u5BE5',47594:'\u5BE6',47595:'\u5BE8',47596:'\u5BE2',47597:'\u5BE4',47598:'\u5BDF',47599:'\u5C0D',47600:'\u5C62',47601:'\u5D84',47602:'\u5D87',47603:'\u5E5B',47604:'\u5E63',47605:'\u5E55',47606:'\u5E57',47607:'\u5E54',47608:'\u5ED3',47609:'\u5ED6',47610:'\u5F0A',47611:'\u5F46',47612:'\u5F70',47613:'\u5FB9',47614:'\u6147',47680:'\u613F',47681:'\u614B',47682:'\u6177',47683:'\u6162',47684:'\u6163',47685:'\u615F',47686:'\u615A',47687:'\u6158',47688:'\u6175',47689:'\u622A',47690:'\u6487',47691:'\u6458',47692:'\u6454',47693:'\u64A4',47694:'\u6478',47695:'\u645F',47696:'\u647A',47697:'\u6451',47698:'\u6467',47699:'\u6434',47700:'\u646D',47701:'\u647B',47702:'\u6572',47703:'\u65A1',47704:'\u65D7',47705:'\u65D6',47706:'\u66A2',47707:'\u66A8',47708:'\u669D',47709:'\u699C',47710:'\u69A8',47711:'\u6995',47712:'\u69C1',47713:'\u69AE',47714:'\u69D3',47715:'\u69CB',47716:'\u699B',47717:'\u69B7',47718:'\u69BB',47719:'\u69AB',47720:'\u69B4',47721:'\u69D0',47722:'\u69CD',47723:'\u69AD',47724:'\u69CC',47725:'\u69A6',47726:'\u69C3',47727:'\u69A3',47728:'\u6B49',47729:'\u6B4C',47730:'\u6C33',47731:'\u6F33',47732:'\u6F14',47733:'\u6EFE',47734:'\u6F13',47735:'\u6EF4',47736:'\u6F29',47737:'\u6F3E',47738:'\u6F20',47739:'\u6F2C',47740:'\u6F0F',47741:'\u6F02',47742:'\u6F22',47777:'\u6EFF',47778:'\u6EEF',47779:'\u6F06',47780:'\u6F31',47781:'\u6F38',47782:'\u6F32',47783:'\u6F23',47784:'\u6F15',47785:'\u6F2B',47786:'\u6F2F',47787:'\u6F88',47788:'\u6F2A',47789:'\u6EEC',47790:'\u6F01',47791:'\u6EF2',47792:'\u6ECC',47793:'\u6EF7',47794:'\u7194',47795:'\u7199',47796:'\u717D',47797:'\u718A',47798:'\u7184',47799:'\u7192',47800:'\u723E',47801:'\u7292',47802:'\u7296',47803:'\u7344',47804:'\u7350',47805:'\u7464',47806:'\u7463',47807:'\u746A',47808:'\u7470',47809:'\u746D',47810:'\u7504',47811:'\u7591',47812:'\u7627',47813:'\u760D',47814:'\u760B',47815:'\u7609',47816:'\u7613',47817:'\u76E1',47818:'\u76E3',47819:'\u7784',47820:'\u777D',47821:'\u777F',47822:'\u7761',47823:'\u78C1',47824:'\u789F',47825:'\u78A7',47826:'\u78B3',47827:'\u78A9',47828:'\u78A3',47829:'\u798E',47830:'\u798F',47831:'\u798D',47832:'\u7A2E',47833:'\u7A31',47834:'\u7AAA',47835:'\u7AA9',47836:'\u7AED',47837:'\u7AEF',47838:'\u7BA1',47839:'\u7B95',47840:'\u7B8B',47841:'\u7B75',47842:'\u7B97',47843:'\u7B9D',47844:'\u7B94',47845:'\u7B8F',47846:'\u7BB8',47847:'\u7B87',47848:'\u7B84',47849:'\u7CB9',47850:'\u7CBD',47851:'\u7CBE',47852:'\u7DBB',47853:'\u7DB0',47854:'\u7D9C',47855:'\u7DBD',47856:'\u7DBE',47857:'\u7DA0',47858:'\u7DCA',47859:'\u7DB4',47860:'\u7DB2',47861:'\u7DB1',47862:'\u7DBA',47863:'\u7DA2',47864:'\u7DBF',47865:'\u7DB5',47866:'\u7DB8',47867:'\u7DAD',47868:'\u7DD2',47869:'\u7DC7',47870:'\u7DAC',47936:'\u7F70',47937:'\u7FE0',47938:'\u7FE1',47939:'\u7FDF',47940:'\u805E',47941:'\u805A',47942:'\u8087',47943:'\u8150',47944:'\u8180',47945:'\u818F',47946:'\u8188',47947:'\u818A',47948:'\u817F',47949:'\u8182',47950:'\u81E7',47951:'\u81FA',47952:'\u8207',47953:'\u8214',47954:'\u821E',47955:'\u824B',47956:'\u84C9',47957:'\u84BF',47958:'\u84C6',47959:'\u84C4',47960:'\u8499',47961:'\u849E',47962:'\u84B2',47963:'\u849C',47964:'\u84CB',47965:'\u84B8',47966:'\u84C0',47967:'\u84D3',47968:'\u8490',47969:'\u84BC',47970:'\u84D1',47971:'\u84CA',47972:'\u873F',47973:'\u871C',47974:'\u873B',47975:'\u8722',47976:'\u8725',47977:'\u8734',47978:'\u8718',47979:'\u8755',47980:'\u8737',47981:'\u8729',47982:'\u88F3',47983:'\u8902',47984:'\u88F4',47985:'\u88F9',47986:'\u88F8',47987:'\u88FD',47988:'\u88E8',47989:'\u891A',47990:'\u88EF',47991:'\u8AA6',47992:'\u8A8C',47993:'\u8A9E',47994:'\u8AA3',47995:'\u8A8D',47996:'\u8AA1',47997:'\u8A93',47998:'\u8AA4',48033:'\u8AAA',48034:'\u8AA5',48035:'\u8AA8',48036:'\u8A98',48037:'\u8A91',48038:'\u8A9A',48039:'\u8AA7',48040:'\u8C6A',48041:'\u8C8D',48042:'\u8C8C',48043:'\u8CD3',48044:'\u8CD1',48045:'\u8CD2',48046:'\u8D6B',48047:'\u8D99',48048:'\u8D95',48049:'\u8DFC',48050:'\u8F14',48051:'\u8F12',48052:'\u8F15',48053:'\u8F13',48054:'\u8FA3',48055:'\u9060',48056:'\u9058',48057:'\u905C',48058:'\u9063',48059:'\u9059',48060:'\u905E',48061:'\u9062',48062:'\u905D',48063:'\u905B',48064:'\u9119',48065:'\u9118',48066:'\u911E',48067:'\u9175',48068:'\u9178',48069:'\u9177',48070:'\u9174',48071:'\u9278',48072:'\u9280',48073:'\u9285',48074:'\u9298',48075:'\u9296',48076:'\u927B',48077:'\u9293',48078:'\u929C',48079:'\u92A8',48080:'\u927C',48081:'\u9291',48082:'\u95A1',48083:'\u95A8',48084:'\u95A9',48085:'\u95A3',48086:'\u95A5',48087:'\u95A4',48088:'\u9699',48089:'\u969C',48090:'\u969B',48091:'\u96CC',48092:'\u96D2',48093:'\u9700',48094:'\u977C',48095:'\u9785',48096:'\u97F6',48097:'\u9817',48098:'\u9818',48099:'\u98AF',48100:'\u98B1',48101:'\u9903',48102:'\u9905',48103:'\u990C',48104:'\u9909',48105:'\u99C1',48106:'\u9AAF',48107:'\u9AB0',48108:'\u9AE6',48109:'\u9B41',48110:'\u9B42',48111:'\u9CF4',48112:'\u9CF6',48113:'\u9CF3',48114:'\u9EBC',48115:'\u9F3B',48116:'\u9F4A',48117:'\u5104',48118:'\u5100',48119:'\u50FB',48120:'\u50F5',48121:'\u50F9',48122:'\u5102',48123:'\u5108',48124:'\u5109',48125:'\u5105',48126:'\u51DC',48192:'\u5287',48193:'\u5288',48194:'\u5289',48195:'\u528D',48196:'\u528A',48197:'\u52F0',48198:'\u53B2',48199:'\u562E',48200:'\u563B',48201:'\u5639',48202:'\u5632',48203:'\u563F',48204:'\u5634',48205:'\u5629',48206:'\u5653',48207:'\u564E',48208:'\u5657',48209:'\u5674',48210:'\u5636',48211:'\u562F',48212:'\u5630',48213:'\u5880',48214:'\u589F',48215:'\u589E',48216:'\u58B3',48217:'\u589C',48218:'\u58AE',48219:'\u58A9',48220:'\u58A6',48221:'\u596D',48222:'\u5B09',48223:'\u5AFB',48224:'\u5B0B',48225:'\u5AF5',48226:'\u5B0C',48227:'\u5B08',48228:'\u5BEE',48229:'\u5BEC',48230:'\u5BE9',48231:'\u5BEB',48232:'\u5C64',48233:'\u5C65',48234:'\u5D9D',48235:'\u5D94',48236:'\u5E62',48237:'\u5E5F',48238:'\u5E61',48239:'\u5EE2',48240:'\u5EDA',48241:'\u5EDF',48242:'\u5EDD',48243:'\u5EE3',48244:'\u5EE0',48245:'\u5F48',48246:'\u5F71',48247:'\u5FB7',48248:'\u5FB5',48249:'\u6176',48250:'\u6167',48251:'\u616E',48252:'\u615D',48253:'\u6155',48254:'\u6182',48289:'\u617C',48290:'\u6170',48291:'\u616B',48292:'\u617E',48293:'\u61A7',48294:'\u6190',48295:'\u61AB',48296:'\u618E',48297:'\u61AC',48298:'\u619A',48299:'\u61A4',48300:'\u6194',48301:'\u61AE',48302:'\u622E',48303:'\u6469',48304:'\u646F',48305:'\u6479',48306:'\u649E',48307:'\u64B2',48308:'\u6488',48309:'\u6490',48310:'\u64B0',48311:'\u64A5',48312:'\u6493',48313:'\u6495',48314:'\u64A9',48315:'\u6492',48316:'\u64AE',48317:'\u64AD',48318:'\u64AB',48319:'\u649A',48320:'\u64AC',48321:'\u6499',48322:'\u64A2',48323:'\u64B3',48324:'\u6575',48325:'\u6577',48326:'\u6578',48327:'\u66AE',48328:'\u66AB',48329:'\u66B4',48330:'\u66B1',48331:'\u6A23',48332:'\u6A1F',48333:'\u69E8',48334:'\u6A01',48335:'\u6A1E',48336:'\u6A19',48337:'\u69FD',48338:'\u6A21',48339:'\u6A13',48340:'\u6A0A',48341:'\u69F3',48342:'\u6A02',48343:'\u6A05',48344:'\u69ED',48345:'\u6A11',48346:'\u6B50',48347:'\u6B4E',48348:'\u6BA4',48349:'\u6BC5',48350:'\u6BC6',48351:'\u6F3F',48352:'\u6F7C',48353:'\u6F84',48354:'\u6F51',48355:'\u6F66',48356:'\u6F54',48357:'\u6F86',48358:'\u6F6D',48359:'\u6F5B',48360:'\u6F78',48361:'\u6F6E',48362:'\u6F8E',48363:'\u6F7A',48364:'\u6F70',48365:'\u6F64',48366:'\u6F97',48367:'\u6F58',48368:'\u6ED5',48369:'\u6F6F',48370:'\u6F60',48371:'\u6F5F',48372:'\u719F',48373:'\u71AC',48374:'\u71B1',48375:'\u71A8',48376:'\u7256',48377:'\u729B',48378:'\u734E',48379:'\u7357',48380:'\u7469',48381:'\u748B',48382:'\u7483',48448:'\u747E',48449:'\u7480',48450:'\u757F',48451:'\u7620',48452:'\u7629',48453:'\u761F',48454:'\u7624',48455:'\u7626',48456:'\u7621',48457:'\u7622',48458:'\u769A',48459:'\u76BA',48460:'\u76E4',48461:'\u778E',48462:'\u7787',48463:'\u778C',48464:'\u7791',48465:'\u778B',48466:'\u78CB',48467:'\u78C5',48468:'\u78BA',48469:'\u78CA',48470:'\u78BE',48471:'\u78D5',48472:'\u78BC',48473:'\u78D0',48474:'\u7A3F',48475:'\u7A3C',48476:'\u7A40',48477:'\u7A3D',48478:'\u7A37',48479:'\u7A3B',48480:'\u7AAF',48481:'\u7AAE',48482:'\u7BAD',48483:'\u7BB1',48484:'\u7BC4',48485:'\u7BB4',48486:'\u7BC6',48487:'\u7BC7',48488:'\u7BC1',48489:'\u7BA0',48490:'\u7BCC',48491:'\u7CCA',48492:'\u7DE0',48493:'\u7DF4',48494:'\u7DEF',48495:'\u7DFB',48496:'\u7DD8',48497:'\u7DEC',48498:'\u7DDD',48499:'\u7DE8',48500:'\u7DE3',48501:'\u7DDA',48502:'\u7DDE',48503:'\u7DE9',48504:'\u7D9E',48505:'\u7DD9',48506:'\u7DF2',48507:'\u7DF9',48508:'\u7F75',48509:'\u7F77',48510:'\u7FAF',48545:'\u7FE9',48546:'\u8026',48547:'\u819B',48548:'\u819C',48549:'\u819D',48550:'\u81A0',48551:'\u819A',48552:'\u8198',48553:'\u8517',48554:'\u853D',48555:'\u851A',48556:'\u84EE',48557:'\u852C',48558:'\u852D',48559:'\u8513',48560:'\u8511',48561:'\u8523',48562:'\u8521',48563:'\u8514',48564:'\u84EC',48565:'\u8525',48566:'\u84FF',48567:'\u8506',48568:'\u8782',48569:'\u8774',48570:'\u8776',48571:'\u8760',48572:'\u8766',48573:'\u8778',48574:'\u8768',48575:'\u8759',48576:'\u8757',48577:'\u874C',48578:'\u8753',48579:'\u885B',48580:'\u885D',48581:'\u8910',48582:'\u8907',48583:'\u8912',48584:'\u8913',48585:'\u8915',48586:'\u890A',48587:'\u8ABC',48588:'\u8AD2',48589:'\u8AC7',48590:'\u8AC4',48591:'\u8A95',48592:'\u8ACB',48593:'\u8AF8',48594:'\u8AB2',48595:'\u8AC9',48596:'\u8AC2',48597:'\u8ABF',48598:'\u8AB0',48599:'\u8AD6',48600:'\u8ACD',48601:'\u8AB6',48602:'\u8AB9',48603:'\u8ADB',48604:'\u8C4C',48605:'\u8C4E',48606:'\u8C6C',48607:'\u8CE0',48608:'\u8CDE',48609:'\u8CE6',48610:'\u8CE4',48611:'\u8CEC',48612:'\u8CED',48613:'\u8CE2',48614:'\u8CE3',48615:'\u8CDC',48616:'\u8CEA',48617:'\u8CE1',48618:'\u8D6D',48619:'\u8D9F',48620:'\u8DA3',48621:'\u8E2B',48622:'\u8E10',48623:'\u8E1D',48624:'\u8E22',48625:'\u8E0F',48626:'\u8E29',48627:'\u8E1F',48628:'\u8E21',48629:'\u8E1E',48630:'\u8EBA',48631:'\u8F1D',48632:'\u8F1B',48633:'\u8F1F',48634:'\u8F29',48635:'\u8F26',48636:'\u8F2A',48637:'\u8F1C',48638:'\u8F1E',48704:'\u8F25',48705:'\u9069',48706:'\u906E',48707:'\u9068',48708:'\u906D',48709:'\u9077',48710:'\u9130',48711:'\u912D',48712:'\u9127',48713:'\u9131',48714:'\u9187',48715:'\u9189',48716:'\u918B',48717:'\u9183',48718:'\u92C5',48719:'\u92BB',48720:'\u92B7',48721:'\u92EA',48722:'\u92AC',48723:'\u92E4',48724:'\u92C1',48725:'\u92B3',48726:'\u92BC',48727:'\u92D2',48728:'\u92C7',48729:'\u92F0',48730:'\u92B2',48731:'\u95AD',48732:'\u95B1',48733:'\u9704',48734:'\u9706',48735:'\u9707',48736:'\u9709',48737:'\u9760',48738:'\u978D',48739:'\u978B',48740:'\u978F',48741:'\u9821',48742:'\u982B',48743:'\u981C',48744:'\u98B3',48745:'\u990A',48746:'\u9913',48747:'\u9912',48748:'\u9918',48749:'\u99DD',48750:'\u99D0',48751:'\u99DF',48752:'\u99DB',48753:'\u99D1',48754:'\u99D5',48755:'\u99D2',48756:'\u99D9',48757:'\u9AB7',48758:'\u9AEE',48759:'\u9AEF',48760:'\u9B27',48761:'\u9B45',48762:'\u9B44',48763:'\u9B77',48764:'\u9B6F',48765:'\u9D06',48766:'\u9D09',48801:'\u9D03',48802:'\u9EA9',48803:'\u9EBE',48804:'\u9ECE',48805:'\u58A8',48806:'\u9F52',48807:'\u5112',48808:'\u5118',48809:'\u5114',48810:'\u5110',48811:'\u5115',48812:'\u5180',48813:'\u51AA',48814:'\u51DD',48815:'\u5291',48816:'\u5293',48817:'\u52F3',48818:'\u5659',48819:'\u566B',48820:'\u5679',48821:'\u5669',48822:'\u5664',48823:'\u5678',48824:'\u566A',48825:'\u5668',48826:'\u5665',48827:'\u5671',48828:'\u566F',48829:'\u566C',48830:'\u5662',48831:'\u5676',48832:'\u58C1',48833:'\u58BE',48834:'\u58C7',48835:'\u58C5',48836:'\u596E',48837:'\u5B1D',48838:'\u5B34',48839:'\u5B78',48840:'\u5BF0',48841:'\u5C0E',48842:'\u5F4A',48843:'\u61B2',48844:'\u6191',48845:'\u61A9',48846:'\u618A',48847:'\u61CD',48848:'\u61B6',48849:'\u61BE',48850:'\u61CA',48851:'\u61C8',48852:'\u6230',48853:'\u64C5',48854:'\u64C1',48855:'\u64CB',48856:'\u64BB',48857:'\u64BC',48858:'\u64DA',48859:'\u64C4',48860:'\u64C7',48861:'\u64C2',48862:'\u64CD',48863:'\u64BF',48864:'\u64D2',48865:'\u64D4',48866:'\u64BE',48867:'\u6574',48868:'\u66C6',48869:'\u66C9',48870:'\u66B9',48871:'\u66C4',48872:'\u66C7',48873:'\u66B8',48874:'\u6A3D',48875:'\u6A38',48876:'\u6A3A',48877:'\u6A59',48878:'\u6A6B',48879:'\u6A58',48880:'\u6A39',48881:'\u6A44',48882:'\u6A62',48883:'\u6A61',48884:'\u6A4B',48885:'\u6A47',48886:'\u6A35',48887:'\u6A5F',48888:'\u6A48',48889:'\u6B59',48890:'\u6B77',48891:'\u6C05',48892:'\u6FC2',48893:'\u6FB1',48894:'\u6FA1',48960:'\u6FC3',48961:'\u6FA4',48962:'\u6FC1',48963:'\u6FA7',48964:'\u6FB3',48965:'\u6FC0',48966:'\u6FB9',48967:'\u6FB6',48968:'\u6FA6',48969:'\u6FA0',48970:'\u6FB4',48971:'\u71BE',48972:'\u71C9',48973:'\u71D0',48974:'\u71D2',48975:'\u71C8',48976:'\u71D5',48977:'\u71B9',48978:'\u71CE',48979:'\u71D9',48980:'\u71DC',48981:'\u71C3',48982:'\u71C4',48983:'\u7368',48984:'\u749C',48985:'\u74A3',48986:'\u7498',48987:'\u749F',48988:'\u749E',48989:'\u74E2',48990:'\u750C',48991:'\u750D',48992:'\u7634',48993:'\u7638',48994:'\u763A',48995:'\u76E7',48996:'\u76E5',48997:'\u77A0',48998:'\u779E',48999:'\u779F',49000:'\u77A5',49001:'\u78E8',49002:'\u78DA',49003:'\u78EC',49004:'\u78E7',49005:'\u79A6',49006:'\u7A4D',49007:'\u7A4E',49008:'\u7A46',49009:'\u7A4C',49010:'\u7A4B',49011:'\u7ABA',49012:'\u7BD9',49013:'\u7C11',49014:'\u7BC9',49015:'\u7BE4',49016:'\u7BDB',49017:'\u7BE1',49018:'\u7BE9',49019:'\u7BE6',49020:'\u7CD5',49021:'\u7CD6',49022:'\u7E0A',49057:'\u7E11',49058:'\u7E08',49059:'\u7E1B',49060:'\u7E23',49061:'\u7E1E',49062:'\u7E1D',49063:'\u7E09',49064:'\u7E10',49065:'\u7F79',49066:'\u7FB2',49067:'\u7FF0',49068:'\u7FF1',49069:'\u7FEE',49070:'\u8028',49071:'\u81B3',49072:'\u81A9',49073:'\u81A8',49074:'\u81FB',49075:'\u8208',49076:'\u8258',49077:'\u8259',49078:'\u854A',49079:'\u8559',49080:'\u8548',49081:'\u8568',49082:'\u8569',49083:'\u8543',49084:'\u8549',49085:'\u856D',49086:'\u856A',49087:'\u855E',49088:'\u8783',49089:'\u879F',49090:'\u879E',49091:'\u87A2',49092:'\u878D',49093:'\u8861',49094:'\u892A',49095:'\u8932',49096:'\u8925',49097:'\u892B',49098:'\u8921',49099:'\u89AA',49100:'\u89A6',49101:'\u8AE6',49102:'\u8AFA',49103:'\u8AEB',49104:'\u8AF1',49105:'\u8B00',49106:'\u8ADC',49107:'\u8AE7',49108:'\u8AEE',49109:'\u8AFE',49110:'\u8B01',49111:'\u8B02',49112:'\u8AF7',49113:'\u8AED',49114:'\u8AF3',49115:'\u8AF6',49116:'\u8AFC',49117:'\u8C6B',49118:'\u8C6D',49119:'\u8C93',49120:'\u8CF4',49121:'\u8E44',49122:'\u8E31',49123:'\u8E34',49124:'\u8E42',49125:'\u8E39',49126:'\u8E35',49127:'\u8F3B',49128:'\u8F2F',49129:'\u8F38',49130:'\u8F33',49131:'\u8FA8',49132:'\u8FA6',49133:'\u9075',49134:'\u9074',49135:'\u9078',49136:'\u9072',49137:'\u907C',49138:'\u907A',49139:'\u9134',49140:'\u9192',49141:'\u9320',49142:'\u9336',49143:'\u92F8',49144:'\u9333',49145:'\u932F',49146:'\u9322',49147:'\u92FC',49148:'\u932B',49149:'\u9304',49150:'\u931A',49216:'\u9310',49217:'\u9326',49218:'\u9321',49219:'\u9315',49220:'\u932E',49221:'\u9319',49222:'\u95BB',49223:'\u96A7',49224:'\u96A8',49225:'\u96AA',49226:'\u96D5',49227:'\u970E',49228:'\u9711',49229:'\u9716',49230:'\u970D',49231:'\u9713',49232:'\u970F',49233:'\u975B',49234:'\u975C',49235:'\u9766',49236:'\u9798',49237:'\u9830',49238:'\u9838',49239:'\u983B',49240:'\u9837',49241:'\u982D',49242:'\u9839',49243:'\u9824',49244:'\u9910',49245:'\u9928',49246:'\u991E',49247:'\u991B',49248:'\u9921',49249:'\u991A',49250:'\u99ED',49251:'\u99E2',49252:'\u99F1',49253:'\u9AB8',49254:'\u9ABC',49255:'\u9AFB',49256:'\u9AED',49257:'\u9B28',49258:'\u9B91',49259:'\u9D15',49260:'\u9D23',49261:'\u9D26',49262:'\u9D28',49263:'\u9D12',49264:'\u9D1B',49265:'\u9ED8',49266:'\u9ED4',49267:'\u9F8D',49268:'\u9F9C',49269:'\u512A',49270:'\u511F',49271:'\u5121',49272:'\u5132',49273:'\u52F5',49274:'\u568E',49275:'\u5680',49276:'\u5690',49277:'\u5685',49278:'\u5687',49313:'\u568F',49314:'\u58D5',49315:'\u58D3',49316:'\u58D1',49317:'\u58CE',49318:'\u5B30',49319:'\u5B2A',49320:'\u5B24',49321:'\u5B7A',49322:'\u5C37',49323:'\u5C68',49324:'\u5DBC',49325:'\u5DBA',49326:'\u5DBD',49327:'\u5DB8',49328:'\u5E6B',49329:'\u5F4C',49330:'\u5FBD',49331:'\u61C9',49332:'\u61C2',49333:'\u61C7',49334:'\u61E6',49335:'\u61CB',49336:'\u6232',49337:'\u6234',49338:'\u64CE',49339:'\u64CA',49340:'\u64D8',49341:'\u64E0',49342:'\u64F0',49343:'\u64E6',49344:'\u64EC',49345:'\u64F1',49346:'\u64E2',49347:'\u64ED',49348:'\u6582',49349:'\u6583',49350:'\u66D9',49351:'\u66D6',49352:'\u6A80',49353:'\u6A94',49354:'\u6A84',49355:'\u6AA2',49356:'\u6A9C',49357:'\u6ADB',49358:'\u6AA3',49359:'\u6A7E',49360:'\u6A97',49361:'\u6A90',49362:'\u6AA0',49363:'\u6B5C',49364:'\u6BAE',49365:'\u6BDA',49366:'\u6C08',49367:'\u6FD8',49368:'\u6FF1',49369:'\u6FDF',49370:'\u6FE0',49371:'\u6FDB',49372:'\u6FE4',49373:'\u6FEB',49374:'\u6FEF',49375:'\u6F80',49376:'\u6FEC',49377:'\u6FE1',49378:'\u6FE9',49379:'\u6FD5',49380:'\u6FEE',49381:'\u6FF0',49382:'\u71E7',49383:'\u71DF',49384:'\u71EE',49385:'\u71E6',49386:'\u71E5',49387:'\u71ED',49388:'\u71EC',49389:'\u71F4',49390:'\u71E0',49391:'\u7235',49392:'\u7246',49393:'\u7370',49394:'\u7372',49395:'\u74A9',49396:'\u74B0',49397:'\u74A6',49398:'\u74A8',49399:'\u7646',49400:'\u7642',49401:'\u764C',49402:'\u76EA',49403:'\u77B3',49404:'\u77AA',49405:'\u77B0',49406:'\u77AC',49472:'\u77A7',49473:'\u77AD',49474:'\u77EF',49475:'\u78F7',49476:'\u78FA',49477:'\u78F4',49478:'\u78EF',49479:'\u7901',49480:'\u79A7',49481:'\u79AA',49482:'\u7A57',49483:'\u7ABF',49484:'\u7C07',49485:'\u7C0D',49486:'\u7BFE',49487:'\u7BF7',49488:'\u7C0C',49489:'\u7BE0',49490:'\u7CE0',49491:'\u7CDC',49492:'\u7CDE',49493:'\u7CE2',49494:'\u7CDF',49495:'\u7CD9',49496:'\u7CDD',49497:'\u7E2E',49498:'\u7E3E',49499:'\u7E46',49500:'\u7E37',49501:'\u7E32',49502:'\u7E43',49503:'\u7E2B',49504:'\u7E3D',49505:'\u7E31',49506:'\u7E45',49507:'\u7E41',49508:'\u7E34',49509:'\u7E39',49510:'\u7E48',49511:'\u7E35',49512:'\u7E3F',49513:'\u7E2F',49514:'\u7F44',49515:'\u7FF3',49516:'\u7FFC',49517:'\u8071',49518:'\u8072',49519:'\u8070',49520:'\u806F',49521:'\u8073',49522:'\u81C6',49523:'\u81C3',49524:'\u81BA',49525:'\u81C2',49526:'\u81C0',49527:'\u81BF',49528:'\u81BD',49529:'\u81C9',49530:'\u81BE',49531:'\u81E8',49532:'\u8209',49533:'\u8271',49534:'\u85AA',49569:'\u8584',49570:'\u857E',49571:'\u859C',49572:'\u8591',49573:'\u8594',49574:'\u85AF',49575:'\u859B',49576:'\u8587',49577:'\u85A8',49578:'\u858A',49579:'\u8667',49580:'\u87C0',49581:'\u87D1',49582:'\u87B3',49583:'\u87D2',49584:'\u87C6',49585:'\u87AB',49586:'\u87BB',49587:'\u87BA',49588:'\u87C8',49589:'\u87CB',49590:'\u893B',49591:'\u8936',49592:'\u8944',49593:'\u8938',49594:'\u893D',49595:'\u89AC',49596:'\u8B0E',49597:'\u8B17',49598:'\u8B19',49599:'\u8B1B',49600:'\u8B0A',49601:'\u8B20',49602:'\u8B1D',49603:'\u8B04',49604:'\u8B10',49605:'\u8C41',49606:'\u8C3F',49607:'\u8C73',49608:'\u8CFA',49609:'\u8CFD',49610:'\u8CFC',49611:'\u8CF8',49612:'\u8CFB',49613:'\u8DA8',49614:'\u8E49',49615:'\u8E4B',49616:'\u8E48',49617:'\u8E4A',49618:'\u8F44',49619:'\u8F3E',49620:'\u8F42',49621:'\u8F45',49622:'\u8F3F',49623:'\u907F',49624:'\u907D',49625:'\u9084',49626:'\u9081',49627:'\u9082',49628:'\u9080',49629:'\u9139',49630:'\u91A3',49631:'\u919E',49632:'\u919C',49633:'\u934D',49634:'\u9382',49635:'\u9328',49636:'\u9375',49637:'\u934A',49638:'\u9365',49639:'\u934B',49640:'\u9318',49641:'\u937E',49642:'\u936C',49643:'\u935B',49644:'\u9370',49645:'\u935A',49646:'\u9354',49647:'\u95CA',49648:'\u95CB',49649:'\u95CC',49650:'\u95C8',49651:'\u95C6',49652:'\u96B1',49653:'\u96B8',49654:'\u96D6',49655:'\u971C',49656:'\u971E',49657:'\u97A0',49658:'\u97D3',49659:'\u9846',49660:'\u98B6',49661:'\u9935',49662:'\u9A01',49728:'\u99FF',49729:'\u9BAE',49730:'\u9BAB',49731:'\u9BAA',49732:'\u9BAD',49733:'\u9D3B',49734:'\u9D3F',49735:'\u9E8B',49736:'\u9ECF',49737:'\u9EDE',49738:'\u9EDC',49739:'\u9EDD',49740:'\u9EDB',49741:'\u9F3E',49742:'\u9F4B',49743:'\u53E2',49744:'\u5695',49745:'\u56AE',49746:'\u58D9',49747:'\u58D8',49748:'\u5B38',49749:'\u5F5D',49750:'\u61E3',49751:'\u6233',49752:'\u64F4',49753:'\u64F2',49754:'\u64FE',49755:'\u6506',49756:'\u64FA',49757:'\u64FB',49758:'\u64F7',49759:'\u65B7',49760:'\u66DC',49761:'\u6726',49762:'\u6AB3',49763:'\u6AAC',49764:'\u6AC3',49765:'\u6ABB',49766:'\u6AB8',49767:'\u6AC2',49768:'\u6AAE',49769:'\u6AAF',49770:'\u6B5F',49771:'\u6B78',49772:'\u6BAF',49773:'\u7009',49774:'\u700B',49775:'\u6FFE',49776:'\u7006',49777:'\u6FFA',49778:'\u7011',49779:'\u700F',49780:'\u71FB',49781:'\u71FC',49782:'\u71FE',49783:'\u71F8',49784:'\u7377',49785:'\u7375',49786:'\u74A7',49787:'\u74BF',49788:'\u7515',49789:'\u7656',49790:'\u7658',49825:'\u7652',49826:'\u77BD',49827:'\u77BF',49828:'\u77BB',49829:'\u77BC',49830:'\u790E',49831:'\u79AE',49832:'\u7A61',49833:'\u7A62',49834:'\u7A60',49835:'\u7AC4',49836:'\u7AC5',49837:'\u7C2B',49838:'\u7C27',49839:'\u7C2A',49840:'\u7C1E',49841:'\u7C23',49842:'\u7C21',49843:'\u7CE7',49844:'\u7E54',49845:'\u7E55',49846:'\u7E5E',49847:'\u7E5A',49848:'\u7E61',49849:'\u7E52',49850:'\u7E59',49851:'\u7F48',49852:'\u7FF9',49853:'\u7FFB',49854:'\u8077',49855:'\u8076',49856:'\u81CD',49857:'\u81CF',49858:'\u820A',49859:'\u85CF',49860:'\u85A9',49861:'\u85CD',49862:'\u85D0',49863:'\u85C9',49864:'\u85B0',49865:'\u85BA',49866:'\u85B9',49867:'\u85A6',49868:'\u87EF',49869:'\u87EC',49870:'\u87F2',49871:'\u87E0',49872:'\u8986',49873:'\u89B2',49874:'\u89F4',49875:'\u8B28',49876:'\u8B39',49877:'\u8B2C',49878:'\u8B2B',49879:'\u8C50',49880:'\u8D05',49881:'\u8E59',49882:'\u8E63',49883:'\u8E66',49884:'\u8E64',49885:'\u8E5F',49886:'\u8E55',49887:'\u8EC0',49888:'\u8F49',49889:'\u8F4D',49890:'\u9087',49891:'\u9083',49892:'\u9088',49893:'\u91AB',49894:'\u91AC',49895:'\u91D0',49896:'\u9394',49897:'\u938A',49898:'\u9396',49899:'\u93A2',49900:'\u93B3',49901:'\u93AE',49902:'\u93AC',49903:'\u93B0',49904:'\u9398',49905:'\u939A',49906:'\u9397',49907:'\u95D4',49908:'\u95D6',49909:'\u95D0',49910:'\u95D5',49911:'\u96E2',49912:'\u96DC',49913:'\u96D9',49914:'\u96DB',49915:'\u96DE',49916:'\u9724',49917:'\u97A3',49918:'\u97A6',49984:'\u97AD',49985:'\u97F9',49986:'\u984D',49987:'\u984F',49988:'\u984C',49989:'\u984E',49990:'\u9853',49991:'\u98BA',49992:'\u993E',49993:'\u993F',49994:'\u993D',49995:'\u992E',49996:'\u99A5',49997:'\u9A0E',49998:'\u9AC1',49999:'\u9B03',50000:'\u9B06',50001:'\u9B4F',50002:'\u9B4E',50003:'\u9B4D',50004:'\u9BCA',50005:'\u9BC9',50006:'\u9BFD',50007:'\u9BC8',50008:'\u9BC0',50009:'\u9D51',50010:'\u9D5D',50011:'\u9D60',50012:'\u9EE0',50013:'\u9F15',50014:'\u9F2C',50015:'\u5133',50016:'\u56A5',50017:'\u58DE',50018:'\u58DF',50019:'\u58E2',50020:'\u5BF5',50021:'\u9F90',50022:'\u5EEC',50023:'\u61F2',50024:'\u61F7',50025:'\u61F6',50026:'\u61F5',50027:'\u6500',50028:'\u650F',50029:'\u66E0',50030:'\u66DD',50031:'\u6AE5',50032:'\u6ADD',50033:'\u6ADA',50034:'\u6AD3',50035:'\u701B',50036:'\u701F',50037:'\u7028',50038:'\u701A',50039:'\u701D',50040:'\u7015',50041:'\u7018',50042:'\u7206',50043:'\u720D',50044:'\u7258',50045:'\u72A2',50046:'\u7378',50081:'\u737A',50082:'\u74BD',50083:'\u74CA',50084:'\u74E3',50085:'\u7587',50086:'\u7586',50087:'\u765F',50088:'\u7661',50089:'\u77C7',50090:'\u7919',50091:'\u79B1',50092:'\u7A6B',50093:'\u7A69',50094:'\u7C3E',50095:'\u7C3F',50096:'\u7C38',50097:'\u7C3D',50098:'\u7C37',50099:'\u7C40',50100:'\u7E6B',50101:'\u7E6D',50102:'\u7E79',50103:'\u7E69',50104:'\u7E6A',50105:'\u7F85',50106:'\u7E73',50107:'\u7FB6',50108:'\u7FB9',50109:'\u7FB8',50110:'\u81D8',50111:'\u85E9',50112:'\u85DD',50113:'\u85EA',50114:'\u85D5',50115:'\u85E4',50116:'\u85E5',50117:'\u85F7',50118:'\u87FB',50119:'\u8805',50120:'\u880D',50121:'\u87F9',50122:'\u87FE',50123:'\u8960',50124:'\u895F',50125:'\u8956',50126:'\u895E',50127:'\u8B41',50128:'\u8B5C',50129:'\u8B58',50130:'\u8B49',50131:'\u8B5A',50132:'\u8B4E',50133:'\u8B4F',50134:'\u8B46',50135:'\u8B59',50136:'\u8D08',50137:'\u8D0A',50138:'\u8E7C',50139:'\u8E72',50140:'\u8E87',50141:'\u8E76',50142:'\u8E6C',50143:'\u8E7A',50144:'\u8E74',50145:'\u8F54',50146:'\u8F4E',50147:'\u8FAD',50148:'\u908A',50149:'\u908B',50150:'\u91B1',50151:'\u91AE',50152:'\u93E1',50153:'\u93D1',50154:'\u93DF',50155:'\u93C3',50156:'\u93C8',50157:'\u93DC',50158:'\u93DD',50159:'\u93D6',50160:'\u93E2',50161:'\u93CD',50162:'\u93D8',50163:'\u93E4',50164:'\u93D7',50165:'\u93E8',50166:'\u95DC',50167:'\u96B4',50168:'\u96E3',50169:'\u972A',50170:'\u9727',50171:'\u9761',50172:'\u97DC',50173:'\u97FB',50174:'\u985E',50240:'\u9858',50241:'\u985B',50242:'\u98BC',50243:'\u9945',50244:'\u9949',50245:'\u9A16',50246:'\u9A19',50247:'\u9B0D',50248:'\u9BE8',50249:'\u9BE7',50250:'\u9BD6',50251:'\u9BDB',50252:'\u9D89',50253:'\u9D61',50254:'\u9D72',50255:'\u9D6A',50256:'\u9D6C',50257:'\u9E92',50258:'\u9E97',50259:'\u9E93',50260:'\u9EB4',50261:'\u52F8',50262:'\u56A8',50263:'\u56B7',50264:'\u56B6',50265:'\u56B4',50266:'\u56BC',50267:'\u58E4',50268:'\u5B40',50269:'\u5B43',50270:'\u5B7D',50271:'\u5BF6',50272:'\u5DC9',50273:'\u61F8',50274:'\u61FA',50275:'\u6518',50276:'\u6514',50277:'\u6519',50278:'\u66E6',50279:'\u6727',50280:'\u6AEC',50281:'\u703E',50282:'\u7030',50283:'\u7032',50284:'\u7210',50285:'\u737B',50286:'\u74CF',50287:'\u7662',50288:'\u7665',50289:'\u7926',50290:'\u792A',50291:'\u792C',50292:'\u792B',50293:'\u7AC7',50294:'\u7AF6',50295:'\u7C4C',50296:'\u7C43',50297:'\u7C4D',50298:'\u7CEF',50299:'\u7CF0',50300:'\u8FAE',50301:'\u7E7D',50302:'\u7E7C',50337:'\u7E82',50338:'\u7F4C',50339:'\u8000',50340:'\u81DA',50341:'\u8266',50342:'\u85FB',50343:'\u85F9',50344:'\u8611',50345:'\u85FA',50346:'\u8606',50347:'\u860B',50348:'\u8607',50349:'\u860A',50350:'\u8814',50351:'\u8815',50352:'\u8964',50353:'\u89BA',50354:'\u89F8',50355:'\u8B70',50356:'\u8B6C',50357:'\u8B66',50358:'\u8B6F',50359:'\u8B5F',50360:'\u8B6B',50361:'\u8D0F',50362:'\u8D0D',50363:'\u8E89',50364:'\u8E81',50365:'\u8E85',50366:'\u8E82',50367:'\u91B4',50368:'\u91CB',50369:'\u9418',50370:'\u9403',50371:'\u93FD',50372:'\u95E1',50373:'\u9730',50374:'\u98C4',50375:'\u9952',50376:'\u9951',50377:'\u99A8',50378:'\u9A2B',50379:'\u9A30',50380:'\u9A37',50381:'\u9A35',50382:'\u9C13',50383:'\u9C0D',50384:'\u9E79',50385:'\u9EB5',50386:'\u9EE8',50387:'\u9F2F',50388:'\u9F5F',50389:'\u9F63',50390:'\u9F61',50391:'\u5137',50392:'\u5138',50393:'\u56C1',50394:'\u56C0',50395:'\u56C2',50396:'\u5914',50397:'\u5C6C',50398:'\u5DCD',50399:'\u61FC',50400:'\u61FE',50401:'\u651D',50402:'\u651C',50403:'\u6595',50404:'\u66E9',50405:'\u6AFB',50406:'\u6B04',50407:'\u6AFA',50408:'\u6BB2',50409:'\u704C',50410:'\u721B',50411:'\u72A7',50412:'\u74D6',50413:'\u74D4',50414:'\u7669',50415:'\u77D3',50416:'\u7C50',50417:'\u7E8F',50418:'\u7E8C',50419:'\u7FBC',50420:'\u8617',50421:'\u862D',50422:'\u861A',50423:'\u8823',50424:'\u8822',50425:'\u8821',50426:'\u881F',50427:'\u896A',50428:'\u896C',50429:'\u89BD',50430:'\u8B74',50496:'\u8B77',50497:'\u8B7D',50498:'\u8D13',50499:'\u8E8A',50500:'\u8E8D',50501:'\u8E8B',50502:'\u8F5F',50503:'\u8FAF',50504:'\u91BA',50505:'\u942E',50506:'\u9433',50507:'\u9435',50508:'\u943A',50509:'\u9438',50510:'\u9432',50511:'\u942B',50512:'\u95E2',50513:'\u9738',50514:'\u9739',50515:'\u9732',50516:'\u97FF',50517:'\u9867',50518:'\u9865',50519:'\u9957',50520:'\u9A45',50521:'\u9A43',50522:'\u9A40',50523:'\u9A3E',50524:'\u9ACF',50525:'\u9B54',50526:'\u9B51',50527:'\u9C2D',50528:'\u9C25',50529:'\u9DAF',50530:'\u9DB4',50531:'\u9DC2',50532:'\u9DB8',50533:'\u9E9D',50534:'\u9EEF',50535:'\u9F19',50536:'\u9F5C',50537:'\u9F66',50538:'\u9F67',50539:'\u513C',50540:'\u513B',50541:'\u56C8',50542:'\u56CA',50543:'\u56C9',50544:'\u5B7F',50545:'\u5DD4',50546:'\u5DD2',50547:'\u5F4E',50548:'\u61FF',50549:'\u6524',50550:'\u6B0A',50551:'\u6B61',50552:'\u7051',50553:'\u7058',50554:'\u7380',50555:'\u74E4',50556:'\u758A',50557:'\u766E',50558:'\u766C',50593:'\u79B3',50594:'\u7C60',50595:'\u7C5F',50596:'\u807E',50597:'\u807D',50598:'\u81DF',50599:'\u8972',50600:'\u896F',50601:'\u89FC',50602:'\u8B80',50603:'\u8D16',50604:'\u8D17',50605:'\u8E91',50606:'\u8E93',50607:'\u8F61',50608:'\u9148',50609:'\u9444',50610:'\u9451',50611:'\u9452',50612:'\u973D',50613:'\u973E',50614:'\u97C3',50615:'\u97C1',50616:'\u986B',50617:'\u9955',50618:'\u9A55',50619:'\u9A4D',50620:'\u9AD2',50621:'\u9B1A',50622:'\u9C49',50623:'\u9C31',50624:'\u9C3E',50625:'\u9C3B',50626:'\u9DD3',50627:'\u9DD7',50628:'\u9F34',50629:'\u9F6C',50630:'\u9F6A',50631:'\u9F94',50632:'\u56CC',50633:'\u5DD6',50634:'\u6200',50635:'\u6523',50636:'\u652B',50637:'\u652A',50638:'\u66EC',50639:'\u6B10',50640:'\u74DA',50641:'\u7ACA',50642:'\u7C64',50643:'\u7C63',50644:'\u7C65',50645:'\u7E93',50646:'\u7E96',50647:'\u7E94',50648:'\u81E2',50649:'\u8638',50650:'\u863F',50651:'\u8831',50652:'\u8B8A',50653:'\u9090',50654:'\u908F',50655:'\u9463',50656:'\u9460',50657:'\u9464',50658:'\u9768',50659:'\u986F',50660:'\u995C',50661:'\u9A5A',50662:'\u9A5B',50663:'\u9A57',50664:'\u9AD3',50665:'\u9AD4',50666:'\u9AD1',50667:'\u9C54',50668:'\u9C57',50669:'\u9C56',50670:'\u9DE5',50671:'\u9E9F',50672:'\u9EF4',50673:'\u56D1',50674:'\u58E9',50675:'\u652C',50676:'\u705E',50677:'\u7671',50678:'\u7672',50679:'\u77D7',50680:'\u7F50',50681:'\u7F88',50682:'\u8836',50683:'\u8839',50684:'\u8862',50685:'\u8B93',50686:'\u8B92',50752:'\u8B96',50753:'\u8277',50754:'\u8D1B',50755:'\u91C0',50756:'\u946A',50757:'\u9742',50758:'\u9748',50759:'\u9744',50760:'\u97C6',50761:'\u9870',50762:'\u9A5F',50763:'\u9B22',50764:'\u9B58',50765:'\u9C5F',50766:'\u9DF9',50767:'\u9DFA',50768:'\u9E7C',50769:'\u9E7D',50770:'\u9F07',50771:'\u9F77',50772:'\u9F72',50773:'\u5EF3',50774:'\u6B16',50775:'\u7063',50776:'\u7C6C',50777:'\u7C6E',50778:'\u883B',50779:'\u89C0',50780:'\u8EA1',50781:'\u91C1',50782:'\u9472',50783:'\u9470',50784:'\u9871',50785:'\u995E',50786:'\u9AD6',50787:'\u9B23',50788:'\u9ECC',50789:'\u7064',50790:'\u77DA',50791:'\u8B9A',50792:'\u9477',50793:'\u97C9',50794:'\u9A62',50795:'\u9A65',50796:'\u7E9C',50797:'\u8B9C',50798:'\u8EAA',50799:'\u91C5',50800:'\u947D',50801:'\u947E',50802:'\u947C',50803:'\u9C77',50804:'\u9C78',50805:'\u9EF7',50806:'\u8C54',50807:'\u947F',50808:'\u9E1A',50809:'\u7228',50810:'\u9A6A',50811:'\u9B31',50812:'\u9E1B',50813:'\u9E1E',50814:'\u7C72',50849:'\uF6B1',50850:'\uF6B2',50851:'\uF6B3',50852:'\uF6B4',50853:'\uF6B5',50854:'\uF6B6',50855:'\uF6B7',50856:'\uF6B8',50857:'\uF6B9',50858:'\uF6BA',50859:'\uF6BB',50860:'\uF6BC',50861:'\uF6BD',50862:'\uF6BE',50863:'\uF6BF',50864:'\uF6C0',50865:'\uF6C1',50866:'\uF6C2',50867:'\uF6C3',50868:'\uF6C4',50869:'\uF6C5',50870:'\uF6C6',50871:'\uF6C7',50872:'\uF6C8',50873:'\uF6C9',50874:'\uF6CA',50875:'\uF6CB',50876:'\uF6CC',50877:'\uF6CD',50878:'\uF6CE',50879:'\uF6CF',50880:'\uF6D0',50881:'\uF6D1',50882:'\uF6D2',50883:'\uF6D3',50884:'\uF6D4',50885:'\uF6D5',50886:'\uF6D6',50887:'\uF6D7',50888:'\uF6D8',50889:'\uF6D9',50890:'\uF6DA',50891:'\uF6DB',50892:'\uF6DC',50893:'\uF6DD',50894:'\uF6DE',50895:'\uF6DF',50896:'\uF6E0',50897:'\uF6E1',50898:'\uF6E2',50899:'\uF6E3',50900:'\uF6E4',50901:'\uF6E5',50902:'\uF6E6',50903:'\uF6E7',50904:'\uF6E8',50905:'\uF6E9',50906:'\uF6EA',50907:'\uF6EB',50908:'\uF6EC',50909:'\uF6ED',50910:'\uF6EE',50911:'\uF6EF',50912:'\uF6F0',50913:'\uF6F1',50914:'\uF6F2',50915:'\uF6F3',50916:'\uF6F4',50917:'\uF6F5',50918:'\uF6F6',50919:'\uF6F7',50920:'\uF6F8',50921:'\uF6F9',50922:'\uF6FA',50923:'\uF6FB',50924:'\uF6FC',50925:'\uF6FD',50926:'\uF6FE',50927:'\uF6FF',50928:'\uF700',50929:'\uF701',50930:'\uF702',50931:'\uF703',50932:'\uF704',50933:'\uF705',50934:'\uF706',50935:'\uF707',50936:'\uF708',50937:'\uF709',50938:'\uF70A',50939:'\uF70B',50940:'\uF70C',50941:'\uF70D',50942:'\uF70E',51008:'\uF70F',51009:'\uF710',51010:'\uF711',51011:'\uF712',51012:'\uF713',51013:'\uF714',51014:'\uF715',51015:'\uF716',51016:'\uF717',51017:'\uF718',51018:'\uF719',51019:'\uF71A',51020:'\uF71B',51021:'\uF71C',51022:'\uF71D',51023:'\uF71E',51024:'\uF71F',51025:'\uF720',51026:'\uF721',51027:'\uF722',51028:'\uF723',51029:'\uF724',51030:'\uF725',51031:'\uF726',51032:'\uF727',51033:'\uF728',51034:'\uF729',51035:'\uF72A',51036:'\uF72B',51037:'\uF72C',51038:'\uF72D',51039:'\uF72E',51040:'\uF72F',51041:'\uF730',51042:'\uF731',51043:'\uF732',51044:'\uF733',51045:'\uF734',51046:'\uF735',51047:'\uF736',51048:'\uF737',51049:'\uF738',51050:'\uF739',51051:'\uF73A',51052:'\uF73B',51053:'\uF73C',51054:'\uF73D',51055:'\uF73E',51056:'\uF73F',51057:'\uF740',51058:'\uF741',51059:'\uF742',51060:'\uF743',51061:'\uF744',51062:'\uF745',51063:'\uF746',51064:'\uF747',51065:'\uF748',51066:'\uF749',51067:'\uF74A',51068:'\uF74B',51069:'\uF74C',51070:'\uF74D',51105:'\uF74E',51106:'\uF74F',51107:'\uF750',51108:'\uF751',51109:'\uF752',51110:'\uF753',51111:'\uF754',51112:'\uF755',51113:'\uF756',51114:'\uF757',51115:'\uF758',51116:'\uF759',51117:'\uF75A',51118:'\uF75B',51119:'\uF75C',51120:'\uF75D',51121:'\uF75E',51122:'\uF75F',51123:'\uF760',51124:'\uF761',51125:'\uF762',51126:'\uF763',51127:'\uF764',51128:'\uF765',51129:'\uF766',51130:'\uF767',51131:'\uF768',51132:'\uF769',51133:'\uF76A',51134:'\uF76B',51135:'\uF76C',51136:'\uF76D',51137:'\uF76E',51138:'\uF76F',51139:'\uF770',51140:'\uF771',51141:'\uF772',51142:'\uF773',51143:'\uF774',51144:'\uF775',51145:'\uF776',51146:'\uF777',51147:'\uF778',51148:'\uF779',51149:'\uF77A',51150:'\uF77B',51151:'\uF77C',51152:'\uF77D',51153:'\uF77E',51154:'\uF77F',51155:'\uF780',51156:'\uF781',51157:'\uF782',51158:'\uF783',51159:'\uF784',51160:'\uF785',51161:'\uF786',51162:'\uF787',51163:'\uF788',51164:'\uF789',51165:'\uF78A',51166:'\uF78B',51167:'\uF78C',51168:'\uF78D',51169:'\uF78E',51170:'\uF78F',51171:'\uF790',51172:'\uF791',51173:'\uF792',51174:'\uF793',51175:'\uF794',51176:'\uF795',51177:'\uF796',51178:'\uF797',51179:'\uF798',51180:'\uF799',51181:'\uF79A',51182:'\uF79B',51183:'\uF79C',51184:'\uF79D',51185:'\uF79E',51186:'\uF79F',51187:'\uF7A0',51188:'\uF7A1',51189:'\uF7A2',51190:'\uF7A3',51191:'\uF7A4',51192:'\uF7A5',51193:'\uF7A6',51194:'\uF7A7',51195:'\uF7A8',51196:'\uF7A9',51197:'\uF7AA',51198:'\uF7AB',51264:'\uF7AC',51265:'\uF7AD',51266:'\uF7AE',51267:'\uF7AF',51268:'\uF7B0',51269:'\uF7B1',51270:'\uF7B2',51271:'\uF7B3',51272:'\uF7B4',51273:'\uF7B5',51274:'\uF7B6',51275:'\uF7B7',51276:'\uF7B8',51277:'\uF7B9',51278:'\uF7BA',51279:'\uF7BB',51280:'\uF7BC',51281:'\uF7BD',51282:'\uF7BE',51283:'\uF7BF',51284:'\uF7C0',51285:'\uF7C1',51286:'\uF7C2',51287:'\uF7C3',51288:'\uF7C4',51289:'\uF7C5',51290:'\uF7C6',51291:'\uF7C7',51292:'\uF7C8',51293:'\uF7C9',51294:'\uF7CA',51295:'\uF7CB',51296:'\uF7CC',51297:'\uF7CD',51298:'\uF7CE',51299:'\uF7CF',51300:'\uF7D0',51301:'\uF7D1',51302:'\uF7D2',51303:'\uF7D3',51304:'\uF7D4',51305:'\uF7D5',51306:'\uF7D6',51307:'\uF7D7',51308:'\uF7D8',51309:'\uF7D9',51310:'\uF7DA',51311:'\uF7DB',51312:'\uF7DC',51313:'\uF7DD',51314:'\uF7DE',51315:'\uF7DF',51316:'\uF7E0',51317:'\uF7E1',51318:'\uF7E2',51319:'\uF7E3',51320:'\uF7E4',51321:'\uF7E5',51322:'\uF7E6',51323:'\uF7E7',51324:'\uF7E8',51325:'\uF7E9',51326:'\uF7EA',51361:'\uF7EB',51362:'\uF7EC',51363:'\uF7ED',51364:'\uF7EE',51365:'\uF7EF',51366:'\uF7F0',51367:'\uF7F1',51368:'\uF7F2',51369:'\uF7F3',51370:'\uF7F4',51371:'\uF7F5',51372:'\uF7F6',51373:'\uF7F7',51374:'\uF7F8',51375:'\uF7F9',51376:'\uF7FA',51377:'\uF7FB',51378:'\uF7FC',51379:'\uF7FD',51380:'\uF7FE',51381:'\uF7FF',51382:'\uF800',51383:'\uF801',51384:'\uF802',51385:'\uF803',51386:'\uF804',51387:'\uF805',51388:'\uF806',51389:'\uF807',51390:'\uF808',51391:'\uF809',51392:'\uF80A',51393:'\uF80B',51394:'\uF80C',51395:'\uF80D',51396:'\uF80E',51397:'\uF80F',51398:'\uF810',51399:'\uF811',51400:'\uF812',51401:'\uF813',51402:'\uF814',51403:'\uF815',51404:'\uF816',51405:'\uF817',51406:'\uF818',51407:'\uF819',51408:'\uF81A',51409:'\uF81B',51410:'\uF81C',51411:'\uF81D',51412:'\uF81E',51413:'\uF81F',51414:'\uF820',51415:'\uF821',51416:'\uF822',51417:'\uF823',51418:'\uF824',51419:'\uF825',51420:'\uF826',51421:'\uF827',51422:'\uF828',51423:'\uF829',51424:'\uF82A',51425:'\uF82B',51426:'\uF82C',51427:'\uF82D',51428:'\uF82E',51429:'\uF82F',51430:'\uF830',51431:'\uF831',51432:'\uF832',51433:'\uF833',51434:'\uF834',51435:'\uF835',51436:'\uF836',51437:'\uF837',51438:'\uF838',51439:'\uF839',51440:'\uF83A',51441:'\uF83B',51442:'\uF83C',51443:'\uF83D',51444:'\uF83E',51445:'\uF83F',51446:'\uF840',51447:'\uF841',51448:'\uF842',51449:'\uF843',51450:'\uF844',51451:'\uF845',51452:'\uF846',51453:'\uF847',51454:'\uF848',51520:'\u4E42',51521:'\u4E5C',51522:'\u51F5',51523:'\u531A',51524:'\u5382',51525:'\u4E07',51526:'\u4E0C',51527:'\u4E47',51528:'\u4E8D',51529:'\u56D7',51530:'\uFA0C',51531:'\u5C6E',51532:'\u5F73',51533:'\u4E0F',51534:'\u5187',51535:'\u4E0E',51536:'\u4E2E',51537:'\u4E93',51538:'\u4EC2',51539:'\u4EC9',51540:'\u4EC8',51541:'\u5198',51542:'\u52FC',51543:'\u536C',51544:'\u53B9',51545:'\u5720',51546:'\u5903',51547:'\u592C',51548:'\u5C10',51549:'\u5DFF',51550:'\u65E1',51551:'\u6BB3',51552:'\u6BCC',51553:'\u6C14',51554:'\u723F',51555:'\u4E31',51556:'\u4E3C',51557:'\u4EE8',51558:'\u4EDC',51559:'\u4EE9',51560:'\u4EE1',51561:'\u4EDD',51562:'\u4EDA',51563:'\u520C',51564:'\u531C',51565:'\u534C',51566:'\u5722',51567:'\u5723',51568:'\u5917',51569:'\u592F',51570:'\u5B81',51571:'\u5B84',51572:'\u5C12',51573:'\u5C3B',51574:'\u5C74',51575:'\u5C73',51576:'\u5E04',51577:'\u5E80',51578:'\u5E82',51579:'\u5FC9',51580:'\u6209',51581:'\u6250',51582:'\u6C15',51617:'\u6C36',51618:'\u6C43',51619:'\u6C3F',51620:'\u6C3B',51621:'\u72AE',51622:'\u72B0',51623:'\u738A',51624:'\u79B8',51625:'\u808A',51626:'\u961E',51627:'\u4F0E',51628:'\u4F18',51629:'\u4F2C',51630:'\u4EF5',51631:'\u4F14',51632:'\u4EF1',51633:'\u4F00',51634:'\u4EF7',51635:'\u4F08',51636:'\u4F1D',51637:'\u4F02',51638:'\u4F05',51639:'\u4F22',51640:'\u4F13',51641:'\u4F04',51642:'\u4EF4',51643:'\u4F12',51644:'\u51B1',51645:'\u5213',51646:'\u5209',51647:'\u5210',51648:'\u52A6',51649:'\u5322',51650:'\u531F',51651:'\u534D',51652:'\u538A',51653:'\u5407',51654:'\u56E1',51655:'\u56DF',51656:'\u572E',51657:'\u572A',51658:'\u5734',51659:'\u593C',51660:'\u5980',51661:'\u597C',51662:'\u5985',51663:'\u597B',51664:'\u597E',51665:'\u5977',51666:'\u597F',51667:'\u5B56',51668:'\u5C15',51669:'\u5C25',51670:'\u5C7C',51671:'\u5C7A',51672:'\u5C7B',51673:'\u5C7E',51674:'\u5DDF',51675:'\u5E75',51676:'\u5E84',51677:'\u5F02',51678:'\u5F1A',51679:'\u5F74',51680:'\u5FD5',51681:'\u5FD4',51682:'\u5FCF',51683:'\u625C',51684:'\u625E',51685:'\u6264',51686:'\u6261',51687:'\u6266',51688:'\u6262',51689:'\u6259',51690:'\u6260',51691:'\u625A',51692:'\u6265',51693:'\u65EF',51694:'\u65EE',51695:'\u673E',51696:'\u6739',51697:'\u6738',51698:'\u673B',51699:'\u673A',51700:'\u673F',51701:'\u673C',51702:'\u6733',51703:'\u6C18',51704:'\u6C46',51705:'\u6C52',51706:'\u6C5C',51707:'\u6C4F',51708:'\u6C4A',51709:'\u6C54',51710:'\u6C4B',51776:'\u6C4C',51777:'\u7071',51778:'\u725E',51779:'\u72B4',51780:'\u72B5',51781:'\u738E',51782:'\u752A',51783:'\u767F',51784:'\u7A75',51785:'\u7F51',51786:'\u8278',51787:'\u827C',51788:'\u8280',51789:'\u827D',51790:'\u827F',51791:'\u864D',51792:'\u897E',51793:'\u9099',51794:'\u9097',51795:'\u9098',51796:'\u909B',51797:'\u9094',51798:'\u9622',51799:'\u9624',51800:'\u9620',51801:'\u9623',51802:'\u4F56',51803:'\u4F3B',51804:'\u4F62',51805:'\u4F49',51806:'\u4F53',51807:'\u4F64',51808:'\u4F3E',51809:'\u4F67',51810:'\u4F52',51811:'\u4F5F',51812:'\u4F41',51813:'\u4F58',51814:'\u4F2D',51815:'\u4F33',51816:'\u4F3F',51817:'\u4F61',51818:'\u518F',51819:'\u51B9',51820:'\u521C',51821:'\u521E',51822:'\u5221',51823:'\u52AD',51824:'\u52AE',51825:'\u5309',51826:'\u5363',51827:'\u5372',51828:'\u538E',51829:'\u538F',51830:'\u5430',51831:'\u5437',51832:'\u542A',51833:'\u5454',51834:'\u5445',51835:'\u5419',51836:'\u541C',51837:'\u5425',51838:'\u5418',51873:'\u543D',51874:'\u544F',51875:'\u5441',51876:'\u5428',51877:'\u5424',51878:'\u5447',51879:'\u56EE',51880:'\u56E7',51881:'\u56E5',51882:'\u5741',51883:'\u5745',51884:'\u574C',51885:'\u5749',51886:'\u574B',51887:'\u5752',51888:'\u5906',51889:'\u5940',51890:'\u59A6',51891:'\u5998',51892:'\u59A0',51893:'\u5997',51894:'\u598E',51895:'\u59A2',51896:'\u5990',51897:'\u598F',51898:'\u59A7',51899:'\u59A1',51900:'\u5B8E',51901:'\u5B92',51902:'\u5C28',51903:'\u5C2A',51904:'\u5C8D',51905:'\u5C8F',51906:'\u5C88',51907:'\u5C8B',51908:'\u5C89',51909:'\u5C92',51910:'\u5C8A',51911:'\u5C86',51912:'\u5C93',51913:'\u5C95',51914:'\u5DE0',51915:'\u5E0A',51916:'\u5E0E',51917:'\u5E8B',51918:'\u5E89',51919:'\u5E8C',51920:'\u5E88',51921:'\u5E8D',51922:'\u5F05',51923:'\u5F1D',51924:'\u5F78',51925:'\u5F76',51926:'\u5FD2',51927:'\u5FD1',51928:'\u5FD0',51929:'\u5FED',51930:'\u5FE8',51931:'\u5FEE',51932:'\u5FF3',51933:'\u5FE1',51934:'\u5FE4',51935:'\u5FE3',51936:'\u5FFA',51937:'\u5FEF',51938:'\u5FF7',51939:'\u5FFB',51940:'\u6000',51941:'\u5FF4',51942:'\u623A',51943:'\u6283',51944:'\u628C',51945:'\u628E',51946:'\u628F',51947:'\u6294',51948:'\u6287',51949:'\u6271',51950:'\u627B',51951:'\u627A',51952:'\u6270',51953:'\u6281',51954:'\u6288',51955:'\u6277',51956:'\u627D',51957:'\u6272',51958:'\u6274',51959:'\u6537',51960:'\u65F0',51961:'\u65F4',51962:'\u65F3',51963:'\u65F2',51964:'\u65F5',51965:'\u6745',51966:'\u6747',52032:'\u6759',52033:'\u6755',52034:'\u674C',52035:'\u6748',52036:'\u675D',52037:'\u674D',52038:'\u675A',52039:'\u674B',52040:'\u6BD0',52041:'\u6C19',52042:'\u6C1A',52043:'\u6C78',52044:'\u6C67',52045:'\u6C6B',52046:'\u6C84',52047:'\u6C8B',52048:'\u6C8F',52049:'\u6C71',52050:'\u6C6F',52051:'\u6C69',52052:'\u6C9A',52053:'\u6C6D',52054:'\u6C87',52055:'\u6C95',52056:'\u6C9C',52057:'\u6C66',52058:'\u6C73',52059:'\u6C65',52060:'\u6C7B',52061:'\u6C8E',52062:'\u7074',52063:'\u707A',52064:'\u7263',52065:'\u72BF',52066:'\u72BD',52067:'\u72C3',52068:'\u72C6',52069:'\u72C1',52070:'\u72BA',52071:'\u72C5',52072:'\u7395',52073:'\u7397',52074:'\u7393',52075:'\u7394',52076:'\u7392',52077:'\u753A',52078:'\u7539',52079:'\u7594',52080:'\u7595',52081:'\u7681',52082:'\u793D',52083:'\u8034',52084:'\u8095',52085:'\u8099',52086:'\u8090',52087:'\u8092',52088:'\u809C',52089:'\u8290',52090:'\u828F',52091:'\u8285',52092:'\u828E',52093:'\u8291',52094:'\u8293',52129:'\u828A',52130:'\u8283',52131:'\u8284',52132:'\u8C78',52133:'\u8FC9',52134:'\u8FBF',52135:'\u909F',52136:'\u90A1',52137:'\u90A5',52138:'\u909E',52139:'\u90A7',52140:'\u90A0',52141:'\u9630',52142:'\u9628',52143:'\u962F',52144:'\u962D',52145:'\u4E33',52146:'\u4F98',52147:'\u4F7C',52148:'\u4F85',52149:'\u4F7D',52150:'\u4F80',52151:'\u4F87',52152:'\u4F76',52153:'\u4F74',52154:'\u4F89',52155:'\u4F84',52156:'\u4F77',52157:'\u4F4C',52158:'\u4F97',52159:'\u4F6A',52160:'\u4F9A',52161:'\u4F79',52162:'\u4F81',52163:'\u4F78',52164:'\u4F90',52165:'\u4F9C',52166:'\u4F94',52167:'\u4F9E',52168:'\u4F92',52169:'\u4F82',52170:'\u4F95',52171:'\u4F6B',52172:'\u4F6E',52173:'\u519E',52174:'\u51BC',52175:'\u51BE',52176:'\u5235',52177:'\u5232',52178:'\u5233',52179:'\u5246',52180:'\u5231',52181:'\u52BC',52182:'\u530A',52183:'\u530B',52184:'\u533C',52185:'\u5392',52186:'\u5394',52187:'\u5487',52188:'\u547F',52189:'\u5481',52190:'\u5491',52191:'\u5482',52192:'\u5488',52193:'\u546B',52194:'\u547A',52195:'\u547E',52196:'\u5465',52197:'\u546C',52198:'\u5474',52199:'\u5466',52200:'\u548D',52201:'\u546F',52202:'\u5461',52203:'\u5460',52204:'\u5498',52205:'\u5463',52206:'\u5467',52207:'\u5464',52208:'\u56F7',52209:'\u56F9',52210:'\u576F',52211:'\u5772',52212:'\u576D',52213:'\u576B',52214:'\u5771',52215:'\u5770',52216:'\u5776',52217:'\u5780',52218:'\u5775',52219:'\u577B',52220:'\u5773',52221:'\u5774',52222:'\u5762',52288:'\u5768',52289:'\u577D',52290:'\u590C',52291:'\u5945',52292:'\u59B5',52293:'\u59BA',52294:'\u59CF',52295:'\u59CE',52296:'\u59B2',52297:'\u59CC',52298:'\u59C1',52299:'\u59B6',52300:'\u59BC',52301:'\u59C3',52302:'\u59D6',52303:'\u59B1',52304:'\u59BD',52305:'\u59C0',52306:'\u59C8',52307:'\u59B4',52308:'\u59C7',52309:'\u5B62',52310:'\u5B65',52311:'\u5B93',52312:'\u5B95',52313:'\u5C44',52314:'\u5C47',52315:'\u5CAE',52316:'\u5CA4',52317:'\u5CA0',52318:'\u5CB5',52319:'\u5CAF',52320:'\u5CA8',52321:'\u5CAC',52322:'\u5C9F',52323:'\u5CA3',52324:'\u5CAD',52325:'\u5CA2',52326:'\u5CAA',52327:'\u5CA7',52328:'\u5C9D',52329:'\u5CA5',52330:'\u5CB6',52331:'\u5CB0',52332:'\u5CA6',52333:'\u5E17',52334:'\u5E14',52335:'\u5E19',52336:'\u5F28',52337:'\u5F22',52338:'\u5F23',52339:'\u5F24',52340:'\u5F54',52341:'\u5F82',52342:'\u5F7E',52343:'\u5F7D',52344:'\u5FDE',52345:'\u5FE5',52346:'\u602D',52347:'\u6026',52348:'\u6019',52349:'\u6032',52350:'\u600B',52385:'\u6034',52386:'\u600A',52387:'\u6017',52388:'\u6033',52389:'\u601A',52390:'\u601E',52391:'\u602C',52392:'\u6022',52393:'\u600D',52394:'\u6010',52395:'\u602E',52396:'\u6013',52397:'\u6011',52398:'\u600C',52399:'\u6009',52400:'\u601C',52401:'\u6214',52402:'\u623D',52403:'\u62AD',52404:'\u62B4',52405:'\u62D1',52406:'\u62BE',52407:'\u62AA',52408:'\u62B6',52409:'\u62CA',52410:'\u62AE',52411:'\u62B3',52412:'\u62AF',52413:'\u62BB',52414:'\u62A9',52415:'\u62B0',52416:'\u62B8',52417:'\u653D',52418:'\u65A8',52419:'\u65BB',52420:'\u6609',52421:'\u65FC',52422:'\u6604',52423:'\u6612',52424:'\u6608',52425:'\u65FB',52426:'\u6603',52427:'\u660B',52428:'\u660D',52429:'\u6605',52430:'\u65FD',52431:'\u6611',52432:'\u6610',52433:'\u66F6',52434:'\u670A',52435:'\u6785',52436:'\u676C',52437:'\u678E',52438:'\u6792',52439:'\u6776',52440:'\u677B',52441:'\u6798',52442:'\u6786',52443:'\u6784',52444:'\u6774',52445:'\u678D',52446:'\u678C',52447:'\u677A',52448:'\u679F',52449:'\u6791',52450:'\u6799',52451:'\u6783',52452:'\u677D',52453:'\u6781',52454:'\u6778',52455:'\u6779',52456:'\u6794',52457:'\u6B25',52458:'\u6B80',52459:'\u6B7E',52460:'\u6BDE',52461:'\u6C1D',52462:'\u6C93',52463:'\u6CEC',52464:'\u6CEB',52465:'\u6CEE',52466:'\u6CD9',52467:'\u6CB6',52468:'\u6CD4',52469:'\u6CAD',52470:'\u6CE7',52471:'\u6CB7',52472:'\u6CD0',52473:'\u6CC2',52474:'\u6CBA',52475:'\u6CC3',52476:'\u6CC6',52477:'\u6CED',52478:'\u6CF2',52544:'\u6CD2',52545:'\u6CDD',52546:'\u6CB4',52547:'\u6C8A',52548:'\u6C9D',52549:'\u6C80',52550:'\u6CDE',52551:'\u6CC0',52552:'\u6D30',52553:'\u6CCD',52554:'\u6CC7',52555:'\u6CB0',52556:'\u6CF9',52557:'\u6CCF',52558:'\u6CE9',52559:'\u6CD1',52560:'\u7094',52561:'\u7098',52562:'\u7085',52563:'\u7093',52564:'\u7086',52565:'\u7084',52566:'\u7091',52567:'\u7096',52568:'\u7082',52569:'\u709A',52570:'\u7083',52571:'\u726A',52572:'\u72D6',52573:'\u72CB',52574:'\u72D8',52575:'\u72C9',52576:'\u72DC',52577:'\u72D2',52578:'\u72D4',52579:'\u72DA',52580:'\u72CC',52581:'\u72D1',52582:'\u73A4',52583:'\u73A1',52584:'\u73AD',52585:'\u73A6',52586:'\u73A2',52587:'\u73A0',52588:'\u73AC',52589:'\u739D',52590:'\u74DD',52591:'\u74E8',52592:'\u753F',52593:'\u7540',52594:'\u753E',52595:'\u758C',52596:'\u7598',52597:'\u76AF',52598:'\u76F3',52599:'\u76F1',52600:'\u76F0',52601:'\u76F5',52602:'\u77F8',52603:'\u77FC',52604:'\u77F9',52605:'\u77FB',52606:'\u77FA',52641:'\u77F7',52642:'\u7942',52643:'\u793F',52644:'\u79C5',52645:'\u7A78',52646:'\u7A7B',52647:'\u7AFB',52648:'\u7C75',52649:'\u7CFD',52650:'\u8035',52651:'\u808F',52652:'\u80AE',52653:'\u80A3',52654:'\u80B8',52655:'\u80B5',52656:'\u80AD',52657:'\u8220',52658:'\u82A0',52659:'\u82C0',52660:'\u82AB',52661:'\u829A',52662:'\u8298',52663:'\u829B',52664:'\u82B5',52665:'\u82A7',52666:'\u82AE',52667:'\u82BC',52668:'\u829E',52669:'\u82BA',52670:'\u82B4',52671:'\u82A8',52672:'\u82A1',52673:'\u82A9',52674:'\u82C2',52675:'\u82A4',52676:'\u82C3',52677:'\u82B6',52678:'\u82A2',52679:'\u8670',52680:'\u866F',52681:'\u866D',52682:'\u866E',52683:'\u8C56',52684:'\u8FD2',52685:'\u8FCB',52686:'\u8FD3',52687:'\u8FCD',52688:'\u8FD6',52689:'\u8FD5',52690:'\u8FD7',52691:'\u90B2',52692:'\u90B4',52693:'\u90AF',52694:'\u90B3',52695:'\u90B0',52696:'\u9639',52697:'\u963D',52698:'\u963C',52699:'\u963A',52700:'\u9643',52701:'\u4FCD',52702:'\u4FC5',52703:'\u4FD3',52704:'\u4FB2',52705:'\u4FC9',52706:'\u4FCB',52707:'\u4FC1',52708:'\u4FD4',52709:'\u4FDC',52710:'\u4FD9',52711:'\u4FBB',52712:'\u4FB3',52713:'\u4FDB',52714:'\u4FC7',52715:'\u4FD6',52716:'\u4FBA',52717:'\u4FC0',52718:'\u4FB9',52719:'\u4FEC',52720:'\u5244',52721:'\u5249',52722:'\u52C0',52723:'\u52C2',52724:'\u533D',52725:'\u537C',52726:'\u5397',52727:'\u5396',52728:'\u5399',52729:'\u5398',52730:'\u54BA',52731:'\u54A1',52732:'\u54AD',52733:'\u54A5',52734:'\u54CF',52800:'\u54C3',52801:'\u830D',52802:'\u54B7',52803:'\u54AE',52804:'\u54D6',52805:'\u54B6',52806:'\u54C5',52807:'\u54C6',52808:'\u54A0',52809:'\u5470',52810:'\u54BC',52811:'\u54A2',52812:'\u54BE',52813:'\u5472',52814:'\u54DE',52815:'\u54B0',52816:'\u57B5',52817:'\u579E',52818:'\u579F',52819:'\u57A4',52820:'\u578C',52821:'\u5797',52822:'\u579D',52823:'\u579B',52824:'\u5794',52825:'\u5798',52826:'\u578F',52827:'\u5799',52828:'\u57A5',52829:'\u579A',52830:'\u5795',52831:'\u58F4',52832:'\u590D',52833:'\u5953',52834:'\u59E1',52835:'\u59DE',52836:'\u59EE',52837:'\u5A00',52838:'\u59F1',52839:'\u59DD',52840:'\u59FA',52841:'\u59FD',52842:'\u59FC',52843:'\u59F6',52844:'\u59E4',52845:'\u59F2',52846:'\u59F7',52847:'\u59DB',52848:'\u59E9',52849:'\u59F3',52850:'\u59F5',52851:'\u59E0',52852:'\u59FE',52853:'\u59F4',52854:'\u59ED',52855:'\u5BA8',52856:'\u5C4C',52857:'\u5CD0',52858:'\u5CD8',52859:'\u5CCC',52860:'\u5CD7',52861:'\u5CCB',52862:'\u5CDB',52897:'\u5CDE',52898:'\u5CDA',52899:'\u5CC9',52900:'\u5CC7',52901:'\u5CCA',52902:'\u5CD6',52903:'\u5CD3',52904:'\u5CD4',52905:'\u5CCF',52906:'\u5CC8',52907:'\u5CC6',52908:'\u5CCE',52909:'\u5CDF',52910:'\u5CF8',52911:'\u5DF9',52912:'\u5E21',52913:'\u5E22',52914:'\u5E23',52915:'\u5E20',52916:'\u5E24',52917:'\u5EB0',52918:'\u5EA4',52919:'\u5EA2',52920:'\u5E9B',52921:'\u5EA3',52922:'\u5EA5',52923:'\u5F07',52924:'\u5F2E',52925:'\u5F56',52926:'\u5F86',52927:'\u6037',52928:'\u6039',52929:'\u6054',52930:'\u6072',52931:'\u605E',52932:'\u6045',52933:'\u6053',52934:'\u6047',52935:'\u6049',52936:'\u605B',52937:'\u604C',52938:'\u6040',52939:'\u6042',52940:'\u605F',52941:'\u6024',52942:'\u6044',52943:'\u6058',52944:'\u6066',52945:'\u606E',52946:'\u6242',52947:'\u6243',52948:'\u62CF',52949:'\u630D',52950:'\u630B',52951:'\u62F5',52952:'\u630E',52953:'\u6303',52954:'\u62EB',52955:'\u62F9',52956:'\u630F',52957:'\u630C',52958:'\u62F8',52959:'\u62F6',52960:'\u6300',52961:'\u6313',52962:'\u6314',52963:'\u62FA',52964:'\u6315',52965:'\u62FB',52966:'\u62F0',52967:'\u6541',52968:'\u6543',52969:'\u65AA',52970:'\u65BF',52971:'\u6636',52972:'\u6621',52973:'\u6632',52974:'\u6635',52975:'\u661C',52976:'\u6626',52977:'\u6622',52978:'\u6633',52979:'\u662B',52980:'\u663A',52981:'\u661D',52982:'\u6634',52983:'\u6639',52984:'\u662E',52985:'\u670F',52986:'\u6710',52987:'\u67C1',52988:'\u67F2',52989:'\u67C8',52990:'\u67BA',53056:'\u67DC',53057:'\u67BB',53058:'\u67F8',53059:'\u67D8',53060:'\u67C0',53061:'\u67B7',53062:'\u67C5',53063:'\u67EB',53064:'\u67E4',53065:'\u67DF',53066:'\u67B5',53067:'\u67CD',53068:'\u67B3',53069:'\u67F7',53070:'\u67F6',53071:'\u67EE',53072:'\u67E3',53073:'\u67C2',53074:'\u67B9',53075:'\u67CE',53076:'\u67E7',53077:'\u67F0',53078:'\u67B2',53079:'\u67FC',53080:'\u67C6',53081:'\u67ED',53082:'\u67CC',53083:'\u67AE',53084:'\u67E6',53085:'\u67DB',53086:'\u67FA',53087:'\u67C9',53088:'\u67CA',53089:'\u67C3',53090:'\u67EA',53091:'\u67CB',53092:'\u6B28',53093:'\u6B82',53094:'\u6B84',53095:'\u6BB6',53096:'\u6BD6',53097:'\u6BD8',53098:'\u6BE0',53099:'\u6C20',53100:'\u6C21',53101:'\u6D28',53102:'\u6D34',53103:'\u6D2D',53104:'\u6D1F',53105:'\u6D3C',53106:'\u6D3F',53107:'\u6D12',53108:'\u6D0A',53109:'\u6CDA',53110:'\u6D33',53111:'\u6D04',53112:'\u6D19',53113:'\u6D3A',53114:'\u6D1A',53115:'\u6D11',53116:'\u6D00',53117:'\u6D1D',53118:'\u6D42',53153:'\u6D01',53154:'\u6D18',53155:'\u6D37',53156:'\u6D03',53157:'\u6D0F',53158:'\u6D40',53159:'\u6D07',53160:'\u6D20',53161:'\u6D2C',53162:'\u6D08',53163:'\u6D22',53164:'\u6D09',53165:'\u6D10',53166:'\u70B7',53167:'\u709F',53168:'\u70BE',53169:'\u70B1',53170:'\u70B0',53171:'\u70A1',53172:'\u70B4',53173:'\u70B5',53174:'\u70A9',53175:'\u7241',53176:'\u7249',53177:'\u724A',53178:'\u726C',53179:'\u7270',53180:'\u7273',53181:'\u726E',53182:'\u72CA',53183:'\u72E4',53184:'\u72E8',53185:'\u72EB',53186:'\u72DF',53187:'\u72EA',53188:'\u72E6',53189:'\u72E3',53190:'\u7385',53191:'\u73CC',53192:'\u73C2',53193:'\u73C8',53194:'\u73C5',53195:'\u73B9',53196:'\u73B6',53197:'\u73B5',53198:'\u73B4',53199:'\u73EB',53200:'\u73BF',53201:'\u73C7',53202:'\u73BE',53203:'\u73C3',53204:'\u73C6',53205:'\u73B8',53206:'\u73CB',53207:'\u74EC',53208:'\u74EE',53209:'\u752E',53210:'\u7547',53211:'\u7548',53212:'\u75A7',53213:'\u75AA',53214:'\u7679',53215:'\u76C4',53216:'\u7708',53217:'\u7703',53218:'\u7704',53219:'\u7705',53220:'\u770A',53221:'\u76F7',53222:'\u76FB',53223:'\u76FA',53224:'\u77E7',53225:'\u77E8',53226:'\u7806',53227:'\u7811',53228:'\u7812',53229:'\u7805',53230:'\u7810',53231:'\u780F',53232:'\u780E',53233:'\u7809',53234:'\u7803',53235:'\u7813',53236:'\u794A',53237:'\u794C',53238:'\u794B',53239:'\u7945',53240:'\u7944',53241:'\u79D5',53242:'\u79CD',53243:'\u79CF',53244:'\u79D6',53245:'\u79CE',53246:'\u7A80',53312:'\u7A7E',53313:'\u7AD1',53314:'\u7B00',53315:'\u7B01',53316:'\u7C7A',53317:'\u7C78',53318:'\u7C79',53319:'\u7C7F',53320:'\u7C80',53321:'\u7C81',53322:'\u7D03',53323:'\u7D08',53324:'\u7D01',53325:'\u7F58',53326:'\u7F91',53327:'\u7F8D',53328:'\u7FBE',53329:'\u8007',53330:'\u800E',53331:'\u800F',53332:'\u8014',53333:'\u8037',53334:'\u80D8',53335:'\u80C7',53336:'\u80E0',53337:'\u80D1',53338:'\u80C8',53339:'\u80C2',53340:'\u80D0',53341:'\u80C5',53342:'\u80E3',53343:'\u80D9',53344:'\u80DC',53345:'\u80CA',53346:'\u80D5',53347:'\u80C9',53348:'\u80CF',53349:'\u80D7',53350:'\u80E6',53351:'\u80CD',53352:'\u81FF',53353:'\u8221',53354:'\u8294',53355:'\u82D9',53356:'\u82FE',53357:'\u82F9',53358:'\u8307',53359:'\u82E8',53360:'\u8300',53361:'\u82D5',53362:'\u833A',53363:'\u82EB',53364:'\u82D6',53365:'\u82F4',53366:'\u82EC',53367:'\u82E1',53368:'\u82F2',53369:'\u82F5',53370:'\u830C',53371:'\u82FB',53372:'\u82F6',53373:'\u82F0',53374:'\u82EA',53409:'\u82E4',53410:'\u82E0',53411:'\u82FA',53412:'\u82F3',53413:'\u82ED',53414:'\u8677',53415:'\u8674',53416:'\u867C',53417:'\u8673',53418:'\u8841',53419:'\u884E',53420:'\u8867',53421:'\u886A',53422:'\u8869',53423:'\u89D3',53424:'\u8A04',53425:'\u8A07',53426:'\u8D72',53427:'\u8FE3',53428:'\u8FE1',53429:'\u8FEE',53430:'\u8FE0',53431:'\u90F1',53432:'\u90BD',53433:'\u90BF',53434:'\u90D5',53435:'\u90C5',53436:'\u90BE',53437:'\u90C7',53438:'\u90CB',53439:'\u90C8',53440:'\u91D4',53441:'\u91D3',53442:'\u9654',53443:'\u964F',53444:'\u9651',53445:'\u9653',53446:'\u964A',53447:'\u964E',53448:'\u501E',53449:'\u5005',53450:'\u5007',53451:'\u5013',53452:'\u5022',53453:'\u5030',53454:'\u501B',53455:'\u4FF5',53456:'\u4FF4',53457:'\u5033',53458:'\u5037',53459:'\u502C',53460:'\u4FF6',53461:'\u4FF7',53462:'\u5017',53463:'\u501C',53464:'\u5020',53465:'\u5027',53466:'\u5035',53467:'\u502F',53468:'\u5031',53469:'\u500E',53470:'\u515A',53471:'\u5194',53472:'\u5193',53473:'\u51CA',53474:'\u51C4',53475:'\u51C5',53476:'\u51C8',53477:'\u51CE',53478:'\u5261',53479:'\u525A',53480:'\u5252',53481:'\u525E',53482:'\u525F',53483:'\u5255',53484:'\u5262',53485:'\u52CD',53486:'\u530E',53487:'\u539E',53488:'\u5526',53489:'\u54E2',53490:'\u5517',53491:'\u5512',53492:'\u54E7',53493:'\u54F3',53494:'\u54E4',53495:'\u551A',53496:'\u54FF',53497:'\u5504',53498:'\u5508',53499:'\u54EB',53500:'\u5511',53501:'\u5505',53502:'\u54F1',53568:'\u550A',53569:'\u54FB',53570:'\u54F7',53571:'\u54F8',53572:'\u54E0',53573:'\u550E',53574:'\u5503',53575:'\u550B',53576:'\u5701',53577:'\u5702',53578:'\u57CC',53579:'\u5832',53580:'\u57D5',53581:'\u57D2',53582:'\u57BA',53583:'\u57C6',53584:'\u57BD',53585:'\u57BC',53586:'\u57B8',53587:'\u57B6',53588:'\u57BF',53589:'\u57C7',53590:'\u57D0',53591:'\u57B9',53592:'\u57C1',53593:'\u590E',53594:'\u594A',53595:'\u5A19',53596:'\u5A16',53597:'\u5A2D',53598:'\u5A2E',53599:'\u5A15',53600:'\u5A0F',53601:'\u5A17',53602:'\u5A0A',53603:'\u5A1E',53604:'\u5A33',53605:'\u5B6C',53606:'\u5BA7',53607:'\u5BAD',53608:'\u5BAC',53609:'\u5C03',53610:'\u5C56',53611:'\u5C54',53612:'\u5CEC',53613:'\u5CFF',53614:'\u5CEE',53615:'\u5CF1',53616:'\u5CF7',53617:'\u5D00',53618:'\u5CF9',53619:'\u5E29',53620:'\u5E28',53621:'\u5EA8',53622:'\u5EAE',53623:'\u5EAA',53624:'\u5EAC',53625:'\u5F33',53626:'\u5F30',53627:'\u5F67',53628:'\u605D',53629:'\u605A',53630:'\u6067',53665:'\u6041',53666:'\u60A2',53667:'\u6088',53668:'\u6080',53669:'\u6092',53670:'\u6081',53671:'\u609D',53672:'\u6083',53673:'\u6095',53674:'\u609B',53675:'\u6097',53676:'\u6087',53677:'\u609C',53678:'\u608E',53679:'\u6219',53680:'\u6246',53681:'\u62F2',53682:'\u6310',53683:'\u6356',53684:'\u632C',53685:'\u6344',53686:'\u6345',53687:'\u6336',53688:'\u6343',53689:'\u63E4',53690:'\u6339',53691:'\u634B',53692:'\u634A',53693:'\u633C',53694:'\u6329',53695:'\u6341',53696:'\u6334',53697:'\u6358',53698:'\u6354',53699:'\u6359',53700:'\u632D',53701:'\u6347',53702:'\u6333',53703:'\u635A',53704:'\u6351',53705:'\u6338',53706:'\u6357',53707:'\u6340',53708:'\u6348',53709:'\u654A',53710:'\u6546',53711:'\u65C6',53712:'\u65C3',53713:'\u65C4',53714:'\u65C2',53715:'\u664A',53716:'\u665F',53717:'\u6647',53718:'\u6651',53719:'\u6712',53720:'\u6713',53721:'\u681F',53722:'\u681A',53723:'\u6849',53724:'\u6832',53725:'\u6833',53726:'\u683B',53727:'\u684B',53728:'\u684F',53729:'\u6816',53730:'\u6831',53731:'\u681C',53732:'\u6835',53733:'\u682B',53734:'\u682D',53735:'\u682F',53736:'\u684E',53737:'\u6844',53738:'\u6834',53739:'\u681D',53740:'\u6812',53741:'\u6814',53742:'\u6826',53743:'\u6828',53744:'\u682E',53745:'\u684D',53746:'\u683A',53747:'\u6825',53748:'\u6820',53749:'\u6B2C',53750:'\u6B2F',53751:'\u6B2D',53752:'\u6B31',53753:'\u6B34',53754:'\u6B6D',53755:'\u8082',53756:'\u6B88',53757:'\u6BE6',53758:'\u6BE4',53824:'\u6BE8',53825:'\u6BE3',53826:'\u6BE2',53827:'\u6BE7',53828:'\u6C25',53829:'\u6D7A',53830:'\u6D63',53831:'\u6D64',53832:'\u6D76',53833:'\u6D0D',53834:'\u6D61',53835:'\u6D92',53836:'\u6D58',53837:'\u6D62',53838:'\u6D6D',53839:'\u6D6F',53840:'\u6D91',53841:'\u6D8D',53842:'\u6DEF',53843:'\u6D7F',53844:'\u6D86',53845:'\u6D5E',53846:'\u6D67',53847:'\u6D60',53848:'\u6D97',53849:'\u6D70',53850:'\u6D7C',53851:'\u6D5F',53852:'\u6D82',53853:'\u6D98',53854:'\u6D2F',53855:'\u6D68',53856:'\u6D8B',53857:'\u6D7E',53858:'\u6D80',53859:'\u6D84',53860:'\u6D16',53861:'\u6D83',53862:'\u6D7B',53863:'\u6D7D',53864:'\u6D75',53865:'\u6D90',53866:'\u70DC',53867:'\u70D3',53868:'\u70D1',53869:'\u70DD',53870:'\u70CB',53871:'\u7F39',53872:'\u70E2',53873:'\u70D7',53874:'\u70D2',53875:'\u70DE',53876:'\u70E0',53877:'\u70D4',53878:'\u70CD',53879:'\u70C5',53880:'\u70C6',53881:'\u70C7',53882:'\u70DA',53883:'\u70CE',53884:'\u70E1',53885:'\u7242',53886:'\u7278',53921:'\u7277',53922:'\u7276',53923:'\u7300',53924:'\u72FA',53925:'\u72F4',53926:'\u72FE',53927:'\u72F6',53928:'\u72F3',53929:'\u72FB',53930:'\u7301',53931:'\u73D3',53932:'\u73D9',53933:'\u73E5',53934:'\u73D6',53935:'\u73BC',53936:'\u73E7',53937:'\u73E3',53938:'\u73E9',53939:'\u73DC',53940:'\u73D2',53941:'\u73DB',53942:'\u73D4',53943:'\u73DD',53944:'\u73DA',53945:'\u73D7',53946:'\u73D8',53947:'\u73E8',53948:'\u74DE',53949:'\u74DF',53950:'\u74F4',53951:'\u74F5',53952:'\u7521',53953:'\u755B',53954:'\u755F',53955:'\u75B0',53956:'\u75C1',53957:'\u75BB',53958:'\u75C4',53959:'\u75C0',53960:'\u75BF',53961:'\u75B6',53962:'\u75BA',53963:'\u768A',53964:'\u76C9',53965:'\u771D',53966:'\u771B',53967:'\u7710',53968:'\u7713',53969:'\u7712',53970:'\u7723',53971:'\u7711',53972:'\u7715',53973:'\u7719',53974:'\u771A',53975:'\u7722',53976:'\u7727',53977:'\u7823',53978:'\u782C',53979:'\u7822',53980:'\u7835',53981:'\u782F',53982:'\u7828',53983:'\u782E',53984:'\u782B',53985:'\u7821',53986:'\u7829',53987:'\u7833',53988:'\u782A',53989:'\u7831',53990:'\u7954',53991:'\u795B',53992:'\u794F',53993:'\u795C',53994:'\u7953',53995:'\u7952',53996:'\u7951',53997:'\u79EB',53998:'\u79EC',53999:'\u79E0',54000:'\u79EE',54001:'\u79ED',54002:'\u79EA',54003:'\u79DC',54004:'\u79DE',54005:'\u79DD',54006:'\u7A86',54007:'\u7A89',54008:'\u7A85',54009:'\u7A8B',54010:'\u7A8C',54011:'\u7A8A',54012:'\u7A87',54013:'\u7AD8',54014:'\u7B10',54080:'\u7B04',54081:'\u7B13',54082:'\u7B05',54083:'\u7B0F',54084:'\u7B08',54085:'\u7B0A',54086:'\u7B0E',54087:'\u7B09',54088:'\u7B12',54089:'\u7C84',54090:'\u7C91',54091:'\u7C8A',54092:'\u7C8C',54093:'\u7C88',54094:'\u7C8D',54095:'\u7C85',54096:'\u7D1E',54097:'\u7D1D',54098:'\u7D11',54099:'\u7D0E',54100:'\u7D18',54101:'\u7D16',54102:'\u7D13',54103:'\u7D1F',54104:'\u7D12',54105:'\u7D0F',54106:'\u7D0C',54107:'\u7F5C',54108:'\u7F61',54109:'\u7F5E',54110:'\u7F60',54111:'\u7F5D',54112:'\u7F5B',54113:'\u7F96',54114:'\u7F92',54115:'\u7FC3',54116:'\u7FC2',54117:'\u7FC0',54118:'\u8016',54119:'\u803E',54120:'\u8039',54121:'\u80FA',54122:'\u80F2',54123:'\u80F9',54124:'\u80F5',54125:'\u8101',54126:'\u80FB',54127:'\u8100',54128:'\u8201',54129:'\u822F',54130:'\u8225',54131:'\u8333',54132:'\u832D',54133:'\u8344',54134:'\u8319',54135:'\u8351',54136:'\u8325',54137:'\u8356',54138:'\u833F',54139:'\u8341',54140:'\u8326',54141:'\u831C',54142:'\u8322',54177:'\u8342',54178:'\u834E',54179:'\u831B',54180:'\u832A',54181:'\u8308',54182:'\u833C',54183:'\u834D',54184:'\u8316',54185:'\u8324',54186:'\u8320',54187:'\u8337',54188:'\u832F',54189:'\u8329',54190:'\u8347',54191:'\u8345',54192:'\u834C',54193:'\u8353',54194:'\u831E',54195:'\u832C',54196:'\u834B',54197:'\u8327',54198:'\u8348',54199:'\u8653',54200:'\u8652',54201:'\u86A2',54202:'\u86A8',54203:'\u8696',54204:'\u868D',54205:'\u8691',54206:'\u869E',54207:'\u8687',54208:'\u8697',54209:'\u8686',54210:'\u868B',54211:'\u869A',54212:'\u8685',54213:'\u86A5',54214:'\u8699',54215:'\u86A1',54216:'\u86A7',54217:'\u8695',54218:'\u8698',54219:'\u868E',54220:'\u869D',54221:'\u8690',54222:'\u8694',54223:'\u8843',54224:'\u8844',54225:'\u886D',54226:'\u8875',54227:'\u8876',54228:'\u8872',54229:'\u8880',54230:'\u8871',54231:'\u887F',54232:'\u886F',54233:'\u8883',54234:'\u887E',54235:'\u8874',54236:'\u887C',54237:'\u8A12',54238:'\u8C47',54239:'\u8C57',54240:'\u8C7B',54241:'\u8CA4',54242:'\u8CA3',54243:'\u8D76',54244:'\u8D78',54245:'\u8DB5',54246:'\u8DB7',54247:'\u8DB6',54248:'\u8ED1',54249:'\u8ED3',54250:'\u8FFE',54251:'\u8FF5',54252:'\u9002',54253:'\u8FFF',54254:'\u8FFB',54255:'\u9004',54256:'\u8FFC',54257:'\u8FF6',54258:'\u90D6',54259:'\u90E0',54260:'\u90D9',54261:'\u90DA',54262:'\u90E3',54263:'\u90DF',54264:'\u90E5',54265:'\u90D8',54266:'\u90DB',54267:'\u90D7',54268:'\u90DC',54269:'\u90E4',54270:'\u9150',54336:'\u914E',54337:'\u914F',54338:'\u91D5',54339:'\u91E2',54340:'\u91DA',54341:'\u965C',54342:'\u965F',54343:'\u96BC',54344:'\u98E3',54345:'\u9ADF',54346:'\u9B2F',54347:'\u4E7F',54348:'\u5070',54349:'\u506A',54350:'\u5061',54351:'\u505E',54352:'\u5060',54353:'\u5053',54354:'\u504B',54355:'\u505D',54356:'\u5072',54357:'\u5048',54358:'\u504D',54359:'\u5041',54360:'\u505B',54361:'\u504A',54362:'\u5062',54363:'\u5015',54364:'\u5045',54365:'\u505F',54366:'\u5069',54367:'\u506B',54368:'\u5063',54369:'\u5064',54370:'\u5046',54371:'\u5040',54372:'\u506E',54373:'\u5073',54374:'\u5057',54375:'\u5051',54376:'\u51D0',54377:'\u526B',54378:'\u526D',54379:'\u526C',54380:'\u526E',54381:'\u52D6',54382:'\u52D3',54383:'\u532D',54384:'\u539C',54385:'\u5575',54386:'\u5576',54387:'\u553C',54388:'\u554D',54389:'\u5550',54390:'\u5534',54391:'\u552A',54392:'\u5551',54393:'\u5562',54394:'\u5536',54395:'\u5535',54396:'\u5530',54397:'\u5552',54398:'\u5545',54433:'\u550C',54434:'\u5532',54435:'\u5565',54436:'\u554E',54437:'\u5539',54438:'\u5548',54439:'\u552D',54440:'\u553B',54441:'\u5540',54442:'\u554B',54443:'\u570A',54444:'\u5707',54445:'\u57FB',54446:'\u5814',54447:'\u57E2',54448:'\u57F6',54449:'\u57DC',54450:'\u57F4',54451:'\u5800',54452:'\u57ED',54453:'\u57FD',54454:'\u5808',54455:'\u57F8',54456:'\u580B',54457:'\u57F3',54458:'\u57CF',54459:'\u5807',54460:'\u57EE',54461:'\u57E3',54462:'\u57F2',54463:'\u57E5',54464:'\u57EC',54465:'\u57E1',54466:'\u580E',54467:'\u57FC',54468:'\u5810',54469:'\u57E7',54470:'\u5801',54471:'\u580C',54472:'\u57F1',54473:'\u57E9',54474:'\u57F0',54475:'\u580D',54476:'\u5804',54477:'\u595C',54478:'\u5A60',54479:'\u5A58',54480:'\u5A55',54481:'\u5A67',54482:'\u5A5E',54483:'\u5A38',54484:'\u5A35',54485:'\u5A6D',54486:'\u5A50',54487:'\u5A5F',54488:'\u5A65',54489:'\u5A6C',54490:'\u5A53',54491:'\u5A64',54492:'\u5A57',54493:'\u5A43',54494:'\u5A5D',54495:'\u5A52',54496:'\u5A44',54497:'\u5A5B',54498:'\u5A48',54499:'\u5A8E',54500:'\u5A3E',54501:'\u5A4D',54502:'\u5A39',54503:'\u5A4C',54504:'\u5A70',54505:'\u5A69',54506:'\u5A47',54507:'\u5A51',54508:'\u5A56',54509:'\u5A42',54510:'\u5A5C',54511:'\u5B72',54512:'\u5B6E',54513:'\u5BC1',54514:'\u5BC0',54515:'\u5C59',54516:'\u5D1E',54517:'\u5D0B',54518:'\u5D1D',54519:'\u5D1A',54520:'\u5D20',54521:'\u5D0C',54522:'\u5D28',54523:'\u5D0D',54524:'\u5D26',54525:'\u5D25',54526:'\u5D0F',54592:'\u5D30',54593:'\u5D12',54594:'\u5D23',54595:'\u5D1F',54596:'\u5D2E',54597:'\u5E3E',54598:'\u5E34',54599:'\u5EB1',54600:'\u5EB4',54601:'\u5EB9',54602:'\u5EB2',54603:'\u5EB3',54604:'\u5F36',54605:'\u5F38',54606:'\u5F9B',54607:'\u5F96',54608:'\u5F9F',54609:'\u608A',54610:'\u6090',54611:'\u6086',54612:'\u60BE',54613:'\u60B0',54614:'\u60BA',54615:'\u60D3',54616:'\u60D4',54617:'\u60CF',54618:'\u60E4',54619:'\u60D9',54620:'\u60DD',54621:'\u60C8',54622:'\u60B1',54623:'\u60DB',54624:'\u60B7',54625:'\u60CA',54626:'\u60BF',54627:'\u60C3',54628:'\u60CD',54629:'\u60C0',54630:'\u6332',54631:'\u6365',54632:'\u638A',54633:'\u6382',54634:'\u637D',54635:'\u63BD',54636:'\u639E',54637:'\u63AD',54638:'\u639D',54639:'\u6397',54640:'\u63AB',54641:'\u638E',54642:'\u636F',54643:'\u6387',54644:'\u6390',54645:'\u636E',54646:'\u63AF',54647:'\u6375',54648:'\u639C',54649:'\u636D',54650:'\u63AE',54651:'\u637C',54652:'\u63A4',54653:'\u633B',54654:'\u639F',54689:'\u6378',54690:'\u6385',54691:'\u6381',54692:'\u6391',54693:'\u638D',54694:'\u6370',54695:'\u6553',54696:'\u65CD',54697:'\u6665',54698:'\u6661',54699:'\u665B',54700:'\u6659',54701:'\u665C',54702:'\u6662',54703:'\u6718',54704:'\u6879',54705:'\u6887',54706:'\u6890',54707:'\u689C',54708:'\u686D',54709:'\u686E',54710:'\u68AE',54711:'\u68AB',54712:'\u6956',54713:'\u686F',54714:'\u68A3',54715:'\u68AC',54716:'\u68A9',54717:'\u6875',54718:'\u6874',54719:'\u68B2',54720:'\u688F',54721:'\u6877',54722:'\u6892',54723:'\u687C',54724:'\u686B',54725:'\u6872',54726:'\u68AA',54727:'\u6880',54728:'\u6871',54729:'\u687E',54730:'\u689B',54731:'\u6896',54732:'\u688B',54733:'\u68A0',54734:'\u6889',54735:'\u68A4',54736:'\u6878',54737:'\u687B',54738:'\u6891',54739:'\u688C',54740:'\u688A',54741:'\u687D',54742:'\u6B36',54743:'\u6B33',54744:'\u6B37',54745:'\u6B38',54746:'\u6B91',54747:'\u6B8F',54748:'\u6B8D',54749:'\u6B8E',54750:'\u6B8C',54751:'\u6C2A',54752:'\u6DC0',54753:'\u6DAB',54754:'\u6DB4',54755:'\u6DB3',54756:'\u6E74',54757:'\u6DAC',54758:'\u6DE9',54759:'\u6DE2',54760:'\u6DB7',54761:'\u6DF6',54762:'\u6DD4',54763:'\u6E00',54764:'\u6DC8',54765:'\u6DE0',54766:'\u6DDF',54767:'\u6DD6',54768:'\u6DBE',54769:'\u6DE5',54770:'\u6DDC',54771:'\u6DDD',54772:'\u6DDB',54773:'\u6DF4',54774:'\u6DCA',54775:'\u6DBD',54776:'\u6DED',54777:'\u6DF0',54778:'\u6DBA',54779:'\u6DD5',54780:'\u6DC2',54781:'\u6DCF',54782:'\u6DC9',54848:'\u6DD0',54849:'\u6DF2',54850:'\u6DD3',54851:'\u6DFD',54852:'\u6DD7',54853:'\u6DCD',54854:'\u6DE3',54855:'\u6DBB',54856:'\u70FA',54857:'\u710D',54858:'\u70F7',54859:'\u7117',54860:'\u70F4',54861:'\u710C',54862:'\u70F0',54863:'\u7104',54864:'\u70F3',54865:'\u7110',54866:'\u70FC',54867:'\u70FF',54868:'\u7106',54869:'\u7113',54870:'\u7100',54871:'\u70F8',54872:'\u70F6',54873:'\u710B',54874:'\u7102',54875:'\u710E',54876:'\u727E',54877:'\u727B',54878:'\u727C',54879:'\u727F',54880:'\u731D',54881:'\u7317',54882:'\u7307',54883:'\u7311',54884:'\u7318',54885:'\u730A',54886:'\u7308',54887:'\u72FF',54888:'\u730F',54889:'\u731E',54890:'\u7388',54891:'\u73F6',54892:'\u73F8',54893:'\u73F5',54894:'\u7404',54895:'\u7401',54896:'\u73FD',54897:'\u7407',54898:'\u7400',54899:'\u73FA',54900:'\u73FC',54901:'\u73FF',54902:'\u740C',54903:'\u740B',54904:'\u73F4',54905:'\u7408',54906:'\u7564',54907:'\u7563',54908:'\u75CE',54909:'\u75D2',54910:'\u75CF',54945:'\u75CB',54946:'\u75CC',54947:'\u75D1',54948:'\u75D0',54949:'\u768F',54950:'\u7689',54951:'\u76D3',54952:'\u7739',54953:'\u772F',54954:'\u772D',54955:'\u7731',54956:'\u7732',54957:'\u7734',54958:'\u7733',54959:'\u773D',54960:'\u7725',54961:'\u773B',54962:'\u7735',54963:'\u7848',54964:'\u7852',54965:'\u7849',54966:'\u784D',54967:'\u784A',54968:'\u784C',54969:'\u7826',54970:'\u7845',54971:'\u7850',54972:'\u7964',54973:'\u7967',54974:'\u7969',54975:'\u796A',54976:'\u7963',54977:'\u796B',54978:'\u7961',54979:'\u79BB',54980:'\u79FA',54981:'\u79F8',54982:'\u79F6',54983:'\u79F7',54984:'\u7A8F',54985:'\u7A94',54986:'\u7A90',54987:'\u7B35',54988:'\u7B47',54989:'\u7B34',54990:'\u7B25',54991:'\u7B30',54992:'\u7B22',54993:'\u7B24',54994:'\u7B33',54995:'\u7B18',54996:'\u7B2A',54997:'\u7B1D',54998:'\u7B31',54999:'\u7B2B',55000:'\u7B2D',55001:'\u7B2F',55002:'\u7B32',55003:'\u7B38',55004:'\u7B1A',55005:'\u7B23',55006:'\u7C94',55007:'\u7C98',55008:'\u7C96',55009:'\u7CA3',55010:'\u7D35',55011:'\u7D3D',55012:'\u7D38',55013:'\u7D36',55014:'\u7D3A',55015:'\u7D45',55016:'\u7D2C',55017:'\u7D29',55018:'\u7D41',55019:'\u7D47',55020:'\u7D3E',55021:'\u7D3F',55022:'\u7D4A',55023:'\u7D3B',55024:'\u7D28',55025:'\u7F63',55026:'\u7F95',55027:'\u7F9C',55028:'\u7F9D',55029:'\u7F9B',55030:'\u7FCA',55031:'\u7FCB',55032:'\u7FCD',55033:'\u7FD0',55034:'\u7FD1',55035:'\u7FC7',55036:'\u7FCF',55037:'\u7FC9',55038:'\u801F',55104:'\u801E',55105:'\u801B',55106:'\u8047',55107:'\u8043',55108:'\u8048',55109:'\u8118',55110:'\u8125',55111:'\u8119',55112:'\u811B',55113:'\u812D',55114:'\u811F',55115:'\u812C',55116:'\u811E',55117:'\u8121',55118:'\u8115',55119:'\u8127',55120:'\u811D',55121:'\u8122',55122:'\u8211',55123:'\u8238',55124:'\u8233',55125:'\u823A',55126:'\u8234',55127:'\u8232',55128:'\u8274',55129:'\u8390',55130:'\u83A3',55131:'\u83A8',55132:'\u838D',55133:'\u837A',55134:'\u8373',55135:'\u83A4',55136:'\u8374',55137:'\u838F',55138:'\u8381',55139:'\u8395',55140:'\u8399',55141:'\u8375',55142:'\u8394',55143:'\u83A9',55144:'\u837D',55145:'\u8383',55146:'\u838C',55147:'\u839D',55148:'\u839B',55149:'\u83AA',55150:'\u838B',55151:'\u837E',55152:'\u83A5',55153:'\u83AF',55154:'\u8388',55155:'\u8397',55156:'\u83B0',55157:'\u837F',55158:'\u83A6',55159:'\u8387',55160:'\u83AE',55161:'\u8376',55162:'\u839A',55163:'\u8659',55164:'\u8656',55165:'\u86BF',55166:'\u86B7',55201:'\u86C2',55202:'\u86C1',55203:'\u86C5',55204:'\u86BA',55205:'\u86B0',55206:'\u86C8',55207:'\u86B9',55208:'\u86B3',55209:'\u86B8',55210:'\u86CC',55211:'\u86B4',55212:'\u86BB',55213:'\u86BC',55214:'\u86C3',55215:'\u86BD',55216:'\u86BE',55217:'\u8852',55218:'\u8889',55219:'\u8895',55220:'\u88A8',55221:'\u88A2',55222:'\u88AA',55223:'\u889A',55224:'\u8891',55225:'\u88A1',55226:'\u889F',55227:'\u8898',55228:'\u88A7',55229:'\u8899',55230:'\u889B',55231:'\u8897',55232:'\u88A4',55233:'\u88AC',55234:'\u888C',55235:'\u8893',55236:'\u888E',55237:'\u8982',55238:'\u89D6',55239:'\u89D9',55240:'\u89D5',55241:'\u8A30',55242:'\u8A27',55243:'\u8A2C',55244:'\u8A1E',55245:'\u8C39',55246:'\u8C3B',55247:'\u8C5C',55248:'\u8C5D',55249:'\u8C7D',55250:'\u8CA5',55251:'\u8D7D',55252:'\u8D7B',55253:'\u8D79',55254:'\u8DBC',55255:'\u8DC2',55256:'\u8DB9',55257:'\u8DBF',55258:'\u8DC1',55259:'\u8ED8',55260:'\u8EDE',55261:'\u8EDD',55262:'\u8EDC',55263:'\u8ED7',55264:'\u8EE0',55265:'\u8EE1',55266:'\u9024',55267:'\u900B',55268:'\u9011',55269:'\u901C',55270:'\u900C',55271:'\u9021',55272:'\u90EF',55273:'\u90EA',55274:'\u90F0',55275:'\u90F4',55276:'\u90F2',55277:'\u90F3',55278:'\u90D4',55279:'\u90EB',55280:'\u90EC',55281:'\u90E9',55282:'\u9156',55283:'\u9158',55284:'\u915A',55285:'\u9153',55286:'\u9155',55287:'\u91EC',55288:'\u91F4',55289:'\u91F1',55290:'\u91F3',55291:'\u91F8',55292:'\u91E4',55293:'\u91F9',55294:'\u91EA',55360:'\u91EB',55361:'\u91F7',55362:'\u91E8',55363:'\u91EE',55364:'\u957A',55365:'\u9586',55366:'\u9588',55367:'\u967C',55368:'\u966D',55369:'\u966B',55370:'\u9671',55371:'\u966F',55372:'\u96BF',55373:'\u976A',55374:'\u9804',55375:'\u98E5',55376:'\u9997',55377:'\u509B',55378:'\u5095',55379:'\u5094',55380:'\u509E',55381:'\u508B',55382:'\u50A3',55383:'\u5083',55384:'\u508C',55385:'\u508E',55386:'\u509D',55387:'\u5068',55388:'\u509C',55389:'\u5092',55390:'\u5082',55391:'\u5087',55392:'\u515F',55393:'\u51D4',55394:'\u5312',55395:'\u5311',55396:'\u53A4',55397:'\u53A7',55398:'\u5591',55399:'\u55A8',55400:'\u55A5',55401:'\u55AD',55402:'\u5577',55403:'\u5645',55404:'\u55A2',55405:'\u5593',55406:'\u5588',55407:'\u558F',55408:'\u55B5',55409:'\u5581',55410:'\u55A3',55411:'\u5592',55412:'\u55A4',55413:'\u557D',55414:'\u558C',55415:'\u55A6',55416:'\u557F',55417:'\u5595',55418:'\u55A1',55419:'\u558E',55420:'\u570C',55421:'\u5829',55422:'\u5837',55457:'\u5819',55458:'\u581E',55459:'\u5827',55460:'\u5823',55461:'\u5828',55462:'\u57F5',55463:'\u5848',55464:'\u5825',55465:'\u581C',55466:'\u581B',55467:'\u5833',55468:'\u583F',55469:'\u5836',55470:'\u582E',55471:'\u5839',55472:'\u5838',55473:'\u582D',55474:'\u582C',55475:'\u583B',55476:'\u5961',55477:'\u5AAF',55478:'\u5A94',55479:'\u5A9F',55480:'\u5A7A',55481:'\u5AA2',55482:'\u5A9E',55483:'\u5A78',55484:'\u5AA6',55485:'\u5A7C',55486:'\u5AA5',55487:'\u5AAC',55488:'\u5A95',55489:'\u5AAE',55490:'\u5A37',55491:'\u5A84',55492:'\u5A8A',55493:'\u5A97',55494:'\u5A83',55495:'\u5A8B',55496:'\u5AA9',55497:'\u5A7B',55498:'\u5A7D',55499:'\u5A8C',55500:'\u5A9C',55501:'\u5A8F',55502:'\u5A93',55503:'\u5A9D',55504:'\u5BEA',55505:'\u5BCD',55506:'\u5BCB',55507:'\u5BD4',55508:'\u5BD1',55509:'\u5BCA',55510:'\u5BCE',55511:'\u5C0C',55512:'\u5C30',55513:'\u5D37',55514:'\u5D43',55515:'\u5D6B',55516:'\u5D41',55517:'\u5D4B',55518:'\u5D3F',55519:'\u5D35',55520:'\u5D51',55521:'\u5D4E',55522:'\u5D55',55523:'\u5D33',55524:'\u5D3A',55525:'\u5D52',55526:'\u5D3D',55527:'\u5D31',55528:'\u5D59',55529:'\u5D42',55530:'\u5D39',55531:'\u5D49',55532:'\u5D38',55533:'\u5D3C',55534:'\u5D32',55535:'\u5D36',55536:'\u5D40',55537:'\u5D45',55538:'\u5E44',55539:'\u5E41',55540:'\u5F58',55541:'\u5FA6',55542:'\u5FA5',55543:'\u5FAB',55544:'\u60C9',55545:'\u60B9',55546:'\u60CC',55547:'\u60E2',55548:'\u60CE',55549:'\u60C4',55550:'\u6114',55616:'\u60F2',55617:'\u610A',55618:'\u6116',55619:'\u6105',55620:'\u60F5',55621:'\u6113',55622:'\u60F8',55623:'\u60FC',55624:'\u60FE',55625:'\u60C1',55626:'\u6103',55627:'\u6118',55628:'\u611D',55629:'\u6110',55630:'\u60FF',55631:'\u6104',55632:'\u610B',55633:'\u624A',55634:'\u6394',55635:'\u63B1',55636:'\u63B0',55637:'\u63CE',55638:'\u63E5',55639:'\u63E8',55640:'\u63EF',55641:'\u63C3',55642:'\u649D',55643:'\u63F3',55644:'\u63CA',55645:'\u63E0',55646:'\u63F6',55647:'\u63D5',55648:'\u63F2',55649:'\u63F5',55650:'\u6461',55651:'\u63DF',55652:'\u63BE',55653:'\u63DD',55654:'\u63DC',55655:'\u63C4',55656:'\u63D8',55657:'\u63D3',55658:'\u63C2',55659:'\u63C7',55660:'\u63CC',55661:'\u63CB',55662:'\u63C8',55663:'\u63F0',55664:'\u63D7',55665:'\u63D9',55666:'\u6532',55667:'\u6567',55668:'\u656A',55669:'\u6564',55670:'\u655C',55671:'\u6568',55672:'\u6565',55673:'\u658C',55674:'\u659D',55675:'\u659E',55676:'\u65AE',55677:'\u65D0',55678:'\u65D2',55713:'\u667C',55714:'\u666C',55715:'\u667B',55716:'\u6680',55717:'\u6671',55718:'\u6679',55719:'\u666A',55720:'\u6672',55721:'\u6701',55722:'\u690C',55723:'\u68D3',55724:'\u6904',55725:'\u68DC',55726:'\u692A',55727:'\u68EC',55728:'\u68EA',55729:'\u68F1',55730:'\u690F',55731:'\u68D6',55732:'\u68F7',55733:'\u68EB',55734:'\u68E4',55735:'\u68F6',55736:'\u6913',55737:'\u6910',55738:'\u68F3',55739:'\u68E1',55740:'\u6907',55741:'\u68CC',55742:'\u6908',55743:'\u6970',55744:'\u68B4',55745:'\u6911',55746:'\u68EF',55747:'\u68C6',55748:'\u6914',55749:'\u68F8',55750:'\u68D0',55751:'\u68FD',55752:'\u68FC',55753:'\u68E8',55754:'\u690B',55755:'\u690A',55756:'\u6917',55757:'\u68CE',55758:'\u68C8',55759:'\u68DD',55760:'\u68DE',55761:'\u68E6',55762:'\u68F4',55763:'\u68D1',55764:'\u6906',55765:'\u68D4',55766:'\u68E9',55767:'\u6915',55768:'\u6925',55769:'\u68C7',55770:'\u6B39',55771:'\u6B3B',55772:'\u6B3F',55773:'\u6B3C',55774:'\u6B94',55775:'\u6B97',55776:'\u6B99',55777:'\u6B95',55778:'\u6BBD',55779:'\u6BF0',55780:'\u6BF2',55781:'\u6BF3',55782:'\u6C30',55783:'\u6DFC',55784:'\u6E46',55785:'\u6E47',55786:'\u6E1F',55787:'\u6E49',55788:'\u6E88',55789:'\u6E3C',55790:'\u6E3D',55791:'\u6E45',55792:'\u6E62',55793:'\u6E2B',55794:'\u6E3F',55795:'\u6E41',55796:'\u6E5D',55797:'\u6E73',55798:'\u6E1C',55799:'\u6E33',55800:'\u6E4B',55801:'\u6E40',55802:'\u6E51',55803:'\u6E3B',55804:'\u6E03',55805:'\u6E2E',55806:'\u6E5E',55872:'\u6E68',55873:'\u6E5C',55874:'\u6E61',55875:'\u6E31',55876:'\u6E28',55877:'\u6E60',55878:'\u6E71',55879:'\u6E6B',55880:'\u6E39',55881:'\u6E22',55882:'\u6E30',55883:'\u6E53',55884:'\u6E65',55885:'\u6E27',55886:'\u6E78',55887:'\u6E64',55888:'\u6E77',55889:'\u6E55',55890:'\u6E79',55891:'\u6E52',55892:'\u6E66',55893:'\u6E35',55894:'\u6E36',55895:'\u6E5A',55896:'\u7120',55897:'\u711E',55898:'\u712F',55899:'\u70FB',55900:'\u712E',55901:'\u7131',55902:'\u7123',55903:'\u7125',55904:'\u7122',55905:'\u7132',55906:'\u711F',55907:'\u7128',55908:'\u713A',55909:'\u711B',55910:'\u724B',55911:'\u725A',55912:'\u7288',55913:'\u7289',55914:'\u7286',55915:'\u7285',55916:'\u728B',55917:'\u7312',55918:'\u730B',55919:'\u7330',55920:'\u7322',55921:'\u7331',55922:'\u7333',55923:'\u7327',55924:'\u7332',55925:'\u732D',55926:'\u7326',55927:'\u7323',55928:'\u7335',55929:'\u730C',55930:'\u742E',55931:'\u742C',55932:'\u7430',55933:'\u742B',55934:'\u7416',55969:'\u741A',55970:'\u7421',55971:'\u742D',55972:'\u7431',55973:'\u7424',55974:'\u7423',55975:'\u741D',55976:'\u7429',55977:'\u7420',55978:'\u7432',55979:'\u74FB',55980:'\u752F',55981:'\u756F',55982:'\u756C',55983:'\u75E7',55984:'\u75DA',55985:'\u75E1',55986:'\u75E6',55987:'\u75DD',55988:'\u75DF',55989:'\u75E4',55990:'\u75D7',55991:'\u7695',55992:'\u7692',55993:'\u76DA',55994:'\u7746',55995:'\u7747',55996:'\u7744',55997:'\u774D',55998:'\u7745',55999:'\u774A',56000:'\u774E',56001:'\u774B',56002:'\u774C',56003:'\u77DE',56004:'\u77EC',56005:'\u7860',56006:'\u7864',56007:'\u7865',56008:'\u785C',56009:'\u786D',56010:'\u7871',56011:'\u786A',56012:'\u786E',56013:'\u7870',56014:'\u7869',56015:'\u7868',56016:'\u785E',56017:'\u7862',56018:'\u7974',56019:'\u7973',56020:'\u7972',56021:'\u7970',56022:'\u7A02',56023:'\u7A0A',56024:'\u7A03',56025:'\u7A0C',56026:'\u7A04',56027:'\u7A99',56028:'\u7AE6',56029:'\u7AE4',56030:'\u7B4A',56031:'\u7B3B',56032:'\u7B44',56033:'\u7B48',56034:'\u7B4C',56035:'\u7B4E',56036:'\u7B40',56037:'\u7B58',56038:'\u7B45',56039:'\u7CA2',56040:'\u7C9E',56041:'\u7CA8',56042:'\u7CA1',56043:'\u7D58',56044:'\u7D6F',56045:'\u7D63',56046:'\u7D53',56047:'\u7D56',56048:'\u7D67',56049:'\u7D6A',56050:'\u7D4F',56051:'\u7D6D',56052:'\u7D5C',56053:'\u7D6B',56054:'\u7D52',56055:'\u7D54',56056:'\u7D69',56057:'\u7D51',56058:'\u7D5F',56059:'\u7D4E',56060:'\u7F3E',56061:'\u7F3F',56062:'\u7F65',56128:'\u7F66',56129:'\u7FA2',56130:'\u7FA0',56131:'\u7FA1',56132:'\u7FD7',56133:'\u8051',56134:'\u804F',56135:'\u8050',56136:'\u80FE',56137:'\u80D4',56138:'\u8143',56139:'\u814A',56140:'\u8152',56141:'\u814F',56142:'\u8147',56143:'\u813D',56144:'\u814D',56145:'\u813A',56146:'\u81E6',56147:'\u81EE',56148:'\u81F7',56149:'\u81F8',56150:'\u81F9',56151:'\u8204',56152:'\u823C',56153:'\u823D',56154:'\u823F',56155:'\u8275',56156:'\u833B',56157:'\u83CF',56158:'\u83F9',56159:'\u8423',56160:'\u83C0',56161:'\u83E8',56162:'\u8412',56163:'\u83E7',56164:'\u83E4',56165:'\u83FC',56166:'\u83F6',56167:'\u8410',56168:'\u83C6',56169:'\u83C8',56170:'\u83EB',56171:'\u83E3',56172:'\u83BF',56173:'\u8401',56174:'\u83DD',56175:'\u83E5',56176:'\u83D8',56177:'\u83FF',56178:'\u83E1',56179:'\u83CB',56180:'\u83CE',56181:'\u83D6',56182:'\u83F5',56183:'\u83C9',56184:'\u8409',56185:'\u840F',56186:'\u83DE',56187:'\u8411',56188:'\u8406',56189:'\u83C2',56190:'\u83F3',56225:'\u83D5',56226:'\u83FA',56227:'\u83C7',56228:'\u83D1',56229:'\u83EA',56230:'\u8413',56231:'\u83C3',56232:'\u83EC',56233:'\u83EE',56234:'\u83C4',56235:'\u83FB',56236:'\u83D7',56237:'\u83E2',56238:'\u841B',56239:'\u83DB',56240:'\u83FE',56241:'\u86D8',56242:'\u86E2',56243:'\u86E6',56244:'\u86D3',56245:'\u86E3',56246:'\u86DA',56247:'\u86EA',56248:'\u86DD',56249:'\u86EB',56250:'\u86DC',56251:'\u86EC',56252:'\u86E9',56253:'\u86D7',56254:'\u86E8',56255:'\u86D1',56256:'\u8848',56257:'\u8856',56258:'\u8855',56259:'\u88BA',56260:'\u88D7',56261:'\u88B9',56262:'\u88B8',56263:'\u88C0',56264:'\u88BE',56265:'\u88B6',56266:'\u88BC',56267:'\u88B7',56268:'\u88BD',56269:'\u88B2',56270:'\u8901',56271:'\u88C9',56272:'\u8995',56273:'\u8998',56274:'\u8997',56275:'\u89DD',56276:'\u89DA',56277:'\u89DB',56278:'\u8A4E',56279:'\u8A4D',56280:'\u8A39',56281:'\u8A59',56282:'\u8A40',56283:'\u8A57',56284:'\u8A58',56285:'\u8A44',56286:'\u8A45',56287:'\u8A52',56288:'\u8A48',56289:'\u8A51',56290:'\u8A4A',56291:'\u8A4C',56292:'\u8A4F',56293:'\u8C5F',56294:'\u8C81',56295:'\u8C80',56296:'\u8CBA',56297:'\u8CBE',56298:'\u8CB0',56299:'\u8CB9',56300:'\u8CB5',56301:'\u8D84',56302:'\u8D80',56303:'\u8D89',56304:'\u8DD8',56305:'\u8DD3',56306:'\u8DCD',56307:'\u8DC7',56308:'\u8DD6',56309:'\u8DDC',56310:'\u8DCF',56311:'\u8DD5',56312:'\u8DD9',56313:'\u8DC8',56314:'\u8DD7',56315:'\u8DC5',56316:'\u8EEF',56317:'\u8EF7',56318:'\u8EFA',56384:'\u8EF9',56385:'\u8EE6',56386:'\u8EEE',56387:'\u8EE5',56388:'\u8EF5',56389:'\u8EE7',56390:'\u8EE8',56391:'\u8EF6',56392:'\u8EEB',56393:'\u8EF1',56394:'\u8EEC',56395:'\u8EF4',56396:'\u8EE9',56397:'\u902D',56398:'\u9034',56399:'\u902F',56400:'\u9106',56401:'\u912C',56402:'\u9104',56403:'\u90FF',56404:'\u90FC',56405:'\u9108',56406:'\u90F9',56407:'\u90FB',56408:'\u9101',56409:'\u9100',56410:'\u9107',56411:'\u9105',56412:'\u9103',56413:'\u9161',56414:'\u9164',56415:'\u915F',56416:'\u9162',56417:'\u9160',56418:'\u9201',56419:'\u920A',56420:'\u9225',56421:'\u9203',56422:'\u921A',56423:'\u9226',56424:'\u920F',56425:'\u920C',56426:'\u9200',56427:'\u9212',56428:'\u91FF',56429:'\u91FD',56430:'\u9206',56431:'\u9204',56432:'\u9227',56433:'\u9202',56434:'\u921C',56435:'\u9224',56436:'\u9219',56437:'\u9217',56438:'\u9205',56439:'\u9216',56440:'\u957B',56441:'\u958D',56442:'\u958C',56443:'\u9590',56444:'\u9687',56445:'\u967E',56446:'\u9688',56481:'\u9689',56482:'\u9683',56483:'\u9680',56484:'\u96C2',56485:'\u96C8',56486:'\u96C3',56487:'\u96F1',56488:'\u96F0',56489:'\u976C',56490:'\u9770',56491:'\u976E',56492:'\u9807',56493:'\u98A9',56494:'\u98EB',56495:'\u9CE6',56496:'\u9EF9',56497:'\u4E83',56498:'\u4E84',56499:'\u4EB6',56500:'\u50BD',56501:'\u50BF',56502:'\u50C6',56503:'\u50AE',56504:'\u50C4',56505:'\u50CA',56506:'\u50B4',56507:'\u50C8',56508:'\u50C2',56509:'\u50B0',56510:'\u50C1',56511:'\u50BA',56512:'\u50B1',56513:'\u50CB',56514:'\u50C9',56515:'\u50B6',56516:'\u50B8',56517:'\u51D7',56518:'\u527A',56519:'\u5278',56520:'\u527B',56521:'\u527C',56522:'\u55C3',56523:'\u55DB',56524:'\u55CC',56525:'\u55D0',56526:'\u55CB',56527:'\u55CA',56528:'\u55DD',56529:'\u55C0',56530:'\u55D4',56531:'\u55C4',56532:'\u55E9',56533:'\u55BF',56534:'\u55D2',56535:'\u558D',56536:'\u55CF',56537:'\u55D5',56538:'\u55E2',56539:'\u55D6',56540:'\u55C8',56541:'\u55F2',56542:'\u55CD',56543:'\u55D9',56544:'\u55C2',56545:'\u5714',56546:'\u5853',56547:'\u5868',56548:'\u5864',56549:'\u584F',56550:'\u584D',56551:'\u5849',56552:'\u586F',56553:'\u5855',56554:'\u584E',56555:'\u585D',56556:'\u5859',56557:'\u5865',56558:'\u585B',56559:'\u583D',56560:'\u5863',56561:'\u5871',56562:'\u58FC',56563:'\u5AC7',56564:'\u5AC4',56565:'\u5ACB',56566:'\u5ABA',56567:'\u5AB8',56568:'\u5AB1',56569:'\u5AB5',56570:'\u5AB0',56571:'\u5ABF',56572:'\u5AC8',56573:'\u5ABB',56574:'\u5AC6',56640:'\u5AB7',56641:'\u5AC0',56642:'\u5ACA',56643:'\u5AB4',56644:'\u5AB6',56645:'\u5ACD',56646:'\u5AB9',56647:'\u5A90',56648:'\u5BD6',56649:'\u5BD8',56650:'\u5BD9',56651:'\u5C1F',56652:'\u5C33',56653:'\u5D71',56654:'\u5D63',56655:'\u5D4A',56656:'\u5D65',56657:'\u5D72',56658:'\u5D6C',56659:'\u5D5E',56660:'\u5D68',56661:'\u5D67',56662:'\u5D62',56663:'\u5DF0',56664:'\u5E4F',56665:'\u5E4E',56666:'\u5E4A',56667:'\u5E4D',56668:'\u5E4B',56669:'\u5EC5',56670:'\u5ECC',56671:'\u5EC6',56672:'\u5ECB',56673:'\u5EC7',56674:'\u5F40',56675:'\u5FAF',56676:'\u5FAD',56677:'\u60F7',56678:'\u6149',56679:'\u614A',56680:'\u612B',56681:'\u6145',56682:'\u6136',56683:'\u6132',56684:'\u612E',56685:'\u6146',56686:'\u612F',56687:'\u614F',56688:'\u6129',56689:'\u6140',56690:'\u6220',56691:'\u9168',56692:'\u6223',56693:'\u6225',56694:'\u6224',56695:'\u63C5',56696:'\u63F1',56697:'\u63EB',56698:'\u6410',56699:'\u6412',56700:'\u6409',56701:'\u6420',56702:'\u6424',56737:'\u6433',56738:'\u6443',56739:'\u641F',56740:'\u6415',56741:'\u6418',56742:'\u6439',56743:'\u6437',56744:'\u6422',56745:'\u6423',56746:'\u640C',56747:'\u6426',56748:'\u6430',56749:'\u6428',56750:'\u6441',56751:'\u6435',56752:'\u642F',56753:'\u640A',56754:'\u641A',56755:'\u6440',56756:'\u6425',56757:'\u6427',56758:'\u640B',56759:'\u63E7',56760:'\u641B',56761:'\u642E',56762:'\u6421',56763:'\u640E',56764:'\u656F',56765:'\u6592',56766:'\u65D3',56767:'\u6686',56768:'\u668C',56769:'\u6695',56770:'\u6690',56771:'\u668B',56772:'\u668A',56773:'\u6699',56774:'\u6694',56775:'\u6678',56776:'\u6720',56777:'\u6966',56778:'\u695F',56779:'\u6938',56780:'\u694E',56781:'\u6962',56782:'\u6971',56783:'\u693F',56784:'\u6945',56785:'\u696A',56786:'\u6939',56787:'\u6942',56788:'\u6957',56789:'\u6959',56790:'\u697A',56791:'\u6948',56792:'\u6949',56793:'\u6935',56794:'\u696C',56795:'\u6933',56796:'\u693D',56797:'\u6965',56798:'\u68F0',56799:'\u6978',56800:'\u6934',56801:'\u6969',56802:'\u6940',56803:'\u696F',56804:'\u6944',56805:'\u6976',56806:'\u6958',56807:'\u6941',56808:'\u6974',56809:'\u694C',56810:'\u693B',56811:'\u694B',56812:'\u6937',56813:'\u695C',56814:'\u694F',56815:'\u6951',56816:'\u6932',56817:'\u6952',56818:'\u692F',56819:'\u697B',56820:'\u693C',56821:'\u6B46',56822:'\u6B45',56823:'\u6B43',56824:'\u6B42',56825:'\u6B48',56826:'\u6B41',56827:'\u6B9B',56828:'\uFA0D',56829:'\u6BFB',56830:'\u6BFC',56896:'\u6BF9',56897:'\u6BF7',56898:'\u6BF8',56899:'\u6E9B',56900:'\u6ED6',56901:'\u6EC8',56902:'\u6E8F',56903:'\u6EC0',56904:'\u6E9F',56905:'\u6E93',56906:'\u6E94',56907:'\u6EA0',56908:'\u6EB1',56909:'\u6EB9',56910:'\u6EC6',56911:'\u6ED2',56912:'\u6EBD',56913:'\u6EC1',56914:'\u6E9E',56915:'\u6EC9',56916:'\u6EB7',56917:'\u6EB0',56918:'\u6ECD',56919:'\u6EA6',56920:'\u6ECF',56921:'\u6EB2',56922:'\u6EBE',56923:'\u6EC3',56924:'\u6EDC',56925:'\u6ED8',56926:'\u6E99',56927:'\u6E92',56928:'\u6E8E',56929:'\u6E8D',56930:'\u6EA4',56931:'\u6EA1',56932:'\u6EBF',56933:'\u6EB3',56934:'\u6ED0',56935:'\u6ECA',56936:'\u6E97',56937:'\u6EAE',56938:'\u6EA3',56939:'\u7147',56940:'\u7154',56941:'\u7152',56942:'\u7163',56943:'\u7160',56944:'\u7141',56945:'\u715D',56946:'\u7162',56947:'\u7172',56948:'\u7178',56949:'\u716A',56950:'\u7161',56951:'\u7142',56952:'\u7158',56953:'\u7143',56954:'\u714B',56955:'\u7170',56956:'\u715F',56957:'\u7150',56958:'\u7153',56993:'\u7144',56994:'\u714D',56995:'\u715A',56996:'\u724F',56997:'\u728D',56998:'\u728C',56999:'\u7291',57000:'\u7290',57001:'\u728E',57002:'\u733C',57003:'\u7342',57004:'\u733B',57005:'\u733A',57006:'\u7340',57007:'\u734A',57008:'\u7349',57009:'\u7444',57010:'\u744A',57011:'\u744B',57012:'\u7452',57013:'\u7451',57014:'\u7457',57015:'\u7440',57016:'\u744F',57017:'\u7450',57018:'\u744E',57019:'\u7442',57020:'\u7446',57021:'\u744D',57022:'\u7454',57023:'\u74E1',57024:'\u74FF',57025:'\u74FE',57026:'\u74FD',57027:'\u751D',57028:'\u7579',57029:'\u7577',57030:'\u6983',57031:'\u75EF',57032:'\u760F',57033:'\u7603',57034:'\u75F7',57035:'\u75FE',57036:'\u75FC',57037:'\u75F9',57038:'\u75F8',57039:'\u7610',57040:'\u75FB',57041:'\u75F6',57042:'\u75ED',57043:'\u75F5',57044:'\u75FD',57045:'\u7699',57046:'\u76B5',57047:'\u76DD',57048:'\u7755',57049:'\u775F',57050:'\u7760',57051:'\u7752',57052:'\u7756',57053:'\u775A',57054:'\u7769',57055:'\u7767',57056:'\u7754',57057:'\u7759',57058:'\u776D',57059:'\u77E0',57060:'\u7887',57061:'\u789A',57062:'\u7894',57063:'\u788F',57064:'\u7884',57065:'\u7895',57066:'\u7885',57067:'\u7886',57068:'\u78A1',57069:'\u7883',57070:'\u7879',57071:'\u7899',57072:'\u7880',57073:'\u7896',57074:'\u787B',57075:'\u797C',57076:'\u7982',57077:'\u797D',57078:'\u7979',57079:'\u7A11',57080:'\u7A18',57081:'\u7A19',57082:'\u7A12',57083:'\u7A17',57084:'\u7A15',57085:'\u7A22',57086:'\u7A13',57152:'\u7A1B',57153:'\u7A10',57154:'\u7AA3',57155:'\u7AA2',57156:'\u7A9E',57157:'\u7AEB',57158:'\u7B66',57159:'\u7B64',57160:'\u7B6D',57161:'\u7B74',57162:'\u7B69',57163:'\u7B72',57164:'\u7B65',57165:'\u7B73',57166:'\u7B71',57167:'\u7B70',57168:'\u7B61',57169:'\u7B78',57170:'\u7B76',57171:'\u7B63',57172:'\u7CB2',57173:'\u7CB4',57174:'\u7CAF',57175:'\u7D88',57176:'\u7D86',57177:'\u7D80',57178:'\u7D8D',57179:'\u7D7F',57180:'\u7D85',57181:'\u7D7A',57182:'\u7D8E',57183:'\u7D7B',57184:'\u7D83',57185:'\u7D7C',57186:'\u7D8C',57187:'\u7D94',57188:'\u7D84',57189:'\u7D7D',57190:'\u7D92',57191:'\u7F6D',57192:'\u7F6B',57193:'\u7F67',57194:'\u7F68',57195:'\u7F6C',57196:'\u7FA6',57197:'\u7FA5',57198:'\u7FA7',57199:'\u7FDB',57200:'\u7FDC',57201:'\u8021',57202:'\u8164',57203:'\u8160',57204:'\u8177',57205:'\u815C',57206:'\u8169',57207:'\u815B',57208:'\u8162',57209:'\u8172',57210:'\u6721',57211:'\u815E',57212:'\u8176',57213:'\u8167',57214:'\u816F',57249:'\u8144',57250:'\u8161',57251:'\u821D',57252:'\u8249',57253:'\u8244',57254:'\u8240',57255:'\u8242',57256:'\u8245',57257:'\u84F1',57258:'\u843F',57259:'\u8456',57260:'\u8476',57261:'\u8479',57262:'\u848F',57263:'\u848D',57264:'\u8465',57265:'\u8451',57266:'\u8440',57267:'\u8486',57268:'\u8467',57269:'\u8430',57270:'\u844D',57271:'\u847D',57272:'\u845A',57273:'\u8459',57274:'\u8474',57275:'\u8473',57276:'\u845D',57277:'\u8507',57278:'\u845E',57279:'\u8437',57280:'\u843A',57281:'\u8434',57282:'\u847A',57283:'\u8443',57284:'\u8478',57285:'\u8432',57286:'\u8445',57287:'\u8429',57288:'\u83D9',57289:'\u844B',57290:'\u842F',57291:'\u8442',57292:'\u842D',57293:'\u845F',57294:'\u8470',57295:'\u8439',57296:'\u844E',57297:'\u844C',57298:'\u8452',57299:'\u846F',57300:'\u84C5',57301:'\u848E',57302:'\u843B',57303:'\u8447',57304:'\u8436',57305:'\u8433',57306:'\u8468',57307:'\u847E',57308:'\u8444',57309:'\u842B',57310:'\u8460',57311:'\u8454',57312:'\u846E',57313:'\u8450',57314:'\u870B',57315:'\u8704',57316:'\u86F7',57317:'\u870C',57318:'\u86FA',57319:'\u86D6',57320:'\u86F5',57321:'\u874D',57322:'\u86F8',57323:'\u870E',57324:'\u8709',57325:'\u8701',57326:'\u86F6',57327:'\u870D',57328:'\u8705',57329:'\u88D6',57330:'\u88CB',57331:'\u88CD',57332:'\u88CE',57333:'\u88DE',57334:'\u88DB',57335:'\u88DA',57336:'\u88CC',57337:'\u88D0',57338:'\u8985',57339:'\u899B',57340:'\u89DF',57341:'\u89E5',57342:'\u89E4',57408:'\u89E1',57409:'\u89E0',57410:'\u89E2',57411:'\u89DC',57412:'\u89E6',57413:'\u8A76',57414:'\u8A86',57415:'\u8A7F',57416:'\u8A61',57417:'\u8A3F',57418:'\u8A77',57419:'\u8A82',57420:'\u8A84',57421:'\u8A75',57422:'\u8A83',57423:'\u8A81',57424:'\u8A74',57425:'\u8A7A',57426:'\u8C3C',57427:'\u8C4B',57428:'\u8C4A',57429:'\u8C65',57430:'\u8C64',57431:'\u8C66',57432:'\u8C86',57433:'\u8C84',57434:'\u8C85',57435:'\u8CCC',57436:'\u8D68',57437:'\u8D69',57438:'\u8D91',57439:'\u8D8C',57440:'\u8D8E',57441:'\u8D8F',57442:'\u8D8D',57443:'\u8D93',57444:'\u8D94',57445:'\u8D90',57446:'\u8D92',57447:'\u8DF0',57448:'\u8DE0',57449:'\u8DEC',57450:'\u8DF1',57451:'\u8DEE',57452:'\u8DD0',57453:'\u8DE9',57454:'\u8DE3',57455:'\u8DE2',57456:'\u8DE7',57457:'\u8DF2',57458:'\u8DEB',57459:'\u8DF4',57460:'\u8F06',57461:'\u8EFF',57462:'\u8F01',57463:'\u8F00',57464:'\u8F05',57465:'\u8F07',57466:'\u8F08',57467:'\u8F02',57468:'\u8F0B',57469:'\u9052',57470:'\u903F',57505:'\u9044',57506:'\u9049',57507:'\u903D',57508:'\u9110',57509:'\u910D',57510:'\u910F',57511:'\u9111',57512:'\u9116',57513:'\u9114',57514:'\u910B',57515:'\u910E',57516:'\u916E',57517:'\u916F',57518:'\u9248',57519:'\u9252',57520:'\u9230',57521:'\u923A',57522:'\u9266',57523:'\u9233',57524:'\u9265',57525:'\u925E',57526:'\u9283',57527:'\u922E',57528:'\u924A',57529:'\u9246',57530:'\u926D',57531:'\u926C',57532:'\u924F',57533:'\u9260',57534:'\u9267',57535:'\u926F',57536:'\u9236',57537:'\u9261',57538:'\u9270',57539:'\u9231',57540:'\u9254',57541:'\u9263',57542:'\u9250',57543:'\u9272',57544:'\u924E',57545:'\u9253',57546:'\u924C',57547:'\u9256',57548:'\u9232',57549:'\u959F',57550:'\u959C',57551:'\u959E',57552:'\u959B',57553:'\u9692',57554:'\u9693',57555:'\u9691',57556:'\u9697',57557:'\u96CE',57558:'\u96FA',57559:'\u96FD',57560:'\u96F8',57561:'\u96F5',57562:'\u9773',57563:'\u9777',57564:'\u9778',57565:'\u9772',57566:'\u980F',57567:'\u980D',57568:'\u980E',57569:'\u98AC',57570:'\u98F6',57571:'\u98F9',57572:'\u99AF',57573:'\u99B2',57574:'\u99B0',57575:'\u99B5',57576:'\u9AAD',57577:'\u9AAB',57578:'\u9B5B',57579:'\u9CEA',57580:'\u9CED',57581:'\u9CE7',57582:'\u9E80',57583:'\u9EFD',57584:'\u50E6',57585:'\u50D4',57586:'\u50D7',57587:'\u50E8',57588:'\u50F3',57589:'\u50DB',57590:'\u50EA',57591:'\u50DD',57592:'\u50E4',57593:'\u50D3',57594:'\u50EC',57595:'\u50F0',57596:'\u50EF',57597:'\u50E3',57598:'\u50E0',57664:'\u51D8',57665:'\u5280',57666:'\u5281',57667:'\u52E9',57668:'\u52EB',57669:'\u5330',57670:'\u53AC',57671:'\u5627',57672:'\u5615',57673:'\u560C',57674:'\u5612',57675:'\u55FC',57676:'\u560F',57677:'\u561C',57678:'\u5601',57679:'\u5613',57680:'\u5602',57681:'\u55FA',57682:'\u561D',57683:'\u5604',57684:'\u55FF',57685:'\u55F9',57686:'\u5889',57687:'\u587C',57688:'\u5890',57689:'\u5898',57690:'\u5886',57691:'\u5881',57692:'\u587F',57693:'\u5874',57694:'\u588B',57695:'\u587A',57696:'\u5887',57697:'\u5891',57698:'\u588E',57699:'\u5876',57700:'\u5882',57701:'\u5888',57702:'\u587B',57703:'\u5894',57704:'\u588F',57705:'\u58FE',57706:'\u596B',57707:'\u5ADC',57708:'\u5AEE',57709:'\u5AE5',57710:'\u5AD5',57711:'\u5AEA',57712:'\u5ADA',57713:'\u5AED',57714:'\u5AEB',57715:'\u5AF3',57716:'\u5AE2',57717:'\u5AE0',57718:'\u5ADB',57719:'\u5AEC',57720:'\u5ADE',57721:'\u5ADD',57722:'\u5AD9',57723:'\u5AE8',57724:'\u5ADF',57725:'\u5B77',57726:'\u5BE0',57761:'\u5BE3',57762:'\u5C63',57763:'\u5D82',57764:'\u5D80',57765:'\u5D7D',57766:'\u5D86',57767:'\u5D7A',57768:'\u5D81',57769:'\u5D77',57770:'\u5D8A',57771:'\u5D89',57772:'\u5D88',57773:'\u5D7E',57774:'\u5D7C',57775:'\u5D8D',57776:'\u5D79',57777:'\u5D7F',57778:'\u5E58',57779:'\u5E59',57780:'\u5E53',57781:'\u5ED8',57782:'\u5ED1',57783:'\u5ED7',57784:'\u5ECE',57785:'\u5EDC',57786:'\u5ED5',57787:'\u5ED9',57788:'\u5ED2',57789:'\u5ED4',57790:'\u5F44',57791:'\u5F43',57792:'\u5F6F',57793:'\u5FB6',57794:'\u612C',57795:'\u6128',57796:'\u6141',57797:'\u615E',57798:'\u6171',57799:'\u6173',57800:'\u6152',57801:'\u6153',57802:'\u6172',57803:'\u616C',57804:'\u6180',57805:'\u6174',57806:'\u6154',57807:'\u617A',57808:'\u615B',57809:'\u6165',57810:'\u613B',57811:'\u616A',57812:'\u6161',57813:'\u6156',57814:'\u6229',57815:'\u6227',57816:'\u622B',57817:'\u642B',57818:'\u644D',57819:'\u645B',57820:'\u645D',57821:'\u6474',57822:'\u6476',57823:'\u6472',57824:'\u6473',57825:'\u647D',57826:'\u6475',57827:'\u6466',57828:'\u64A6',57829:'\u644E',57830:'\u6482',57831:'\u645E',57832:'\u645C',57833:'\u644B',57834:'\u6453',57835:'\u6460',57836:'\u6450',57837:'\u647F',57838:'\u643F',57839:'\u646C',57840:'\u646B',57841:'\u6459',57842:'\u6465',57843:'\u6477',57844:'\u6573',57845:'\u65A0',57846:'\u66A1',57847:'\u66A0',57848:'\u669F',57849:'\u6705',57850:'\u6704',57851:'\u6722',57852:'\u69B1',57853:'\u69B6',57854:'\u69C9',57920:'\u69A0',57921:'\u69CE',57922:'\u6996',57923:'\u69B0',57924:'\u69AC',57925:'\u69BC',57926:'\u6991',57927:'\u6999',57928:'\u698E',57929:'\u69A7',57930:'\u698D',57931:'\u69A9',57932:'\u69BE',57933:'\u69AF',57934:'\u69BF',57935:'\u69C4',57936:'\u69BD',57937:'\u69A4',57938:'\u69D4',57939:'\u69B9',57940:'\u69CA',57941:'\u699A',57942:'\u69CF',57943:'\u69B3',57944:'\u6993',57945:'\u69AA',57946:'\u69A1',57947:'\u699E',57948:'\u69D9',57949:'\u6997',57950:'\u6990',57951:'\u69C2',57952:'\u69B5',57953:'\u69A5',57954:'\u69C6',57955:'\u6B4A',57956:'\u6B4D',57957:'\u6B4B',57958:'\u6B9E',57959:'\u6B9F',57960:'\u6BA0',57961:'\u6BC3',57962:'\u6BC4',57963:'\u6BFE',57964:'\u6ECE',57965:'\u6EF5',57966:'\u6EF1',57967:'\u6F03',57968:'\u6F25',57969:'\u6EF8',57970:'\u6F37',57971:'\u6EFB',57972:'\u6F2E',57973:'\u6F09',57974:'\u6F4E',57975:'\u6F19',57976:'\u6F1A',57977:'\u6F27',57978:'\u6F18',57979:'\u6F3B',57980:'\u6F12',57981:'\u6EED',57982:'\u6F0A',58017:'\u6F36',58018:'\u6F73',58019:'\u6EF9',58020:'\u6EEE',58021:'\u6F2D',58022:'\u6F40',58023:'\u6F30',58024:'\u6F3C',58025:'\u6F35',58026:'\u6EEB',58027:'\u6F07',58028:'\u6F0E',58029:'\u6F43',58030:'\u6F05',58031:'\u6EFD',58032:'\u6EF6',58033:'\u6F39',58034:'\u6F1C',58035:'\u6EFC',58036:'\u6F3A',58037:'\u6F1F',58038:'\u6F0D',58039:'\u6F1E',58040:'\u6F08',58041:'\u6F21',58042:'\u7187',58043:'\u7190',58044:'\u7189',58045:'\u7180',58046:'\u7185',58047:'\u7182',58048:'\u718F',58049:'\u717B',58050:'\u7186',58051:'\u7181',58052:'\u7197',58053:'\u7244',58054:'\u7253',58055:'\u7297',58056:'\u7295',58057:'\u7293',58058:'\u7343',58059:'\u734D',58060:'\u7351',58061:'\u734C',58062:'\u7462',58063:'\u7473',58064:'\u7471',58065:'\u7475',58066:'\u7472',58067:'\u7467',58068:'\u746E',58069:'\u7500',58070:'\u7502',58071:'\u7503',58072:'\u757D',58073:'\u7590',58074:'\u7616',58075:'\u7608',58076:'\u760C',58077:'\u7615',58078:'\u7611',58079:'\u760A',58080:'\u7614',58081:'\u76B8',58082:'\u7781',58083:'\u777C',58084:'\u7785',58085:'\u7782',58086:'\u776E',58087:'\u7780',58088:'\u776F',58089:'\u777E',58090:'\u7783',58091:'\u78B2',58092:'\u78AA',58093:'\u78B4',58094:'\u78AD',58095:'\u78A8',58096:'\u787E',58097:'\u78AB',58098:'\u789E',58099:'\u78A5',58100:'\u78A0',58101:'\u78AC',58102:'\u78A2',58103:'\u78A4',58104:'\u7998',58105:'\u798A',58106:'\u798B',58107:'\u7996',58108:'\u7995',58109:'\u7994',58110:'\u7993',58176:'\u7997',58177:'\u7988',58178:'\u7992',58179:'\u7990',58180:'\u7A2B',58181:'\u7A4A',58182:'\u7A30',58183:'\u7A2F',58184:'\u7A28',58185:'\u7A26',58186:'\u7AA8',58187:'\u7AAB',58188:'\u7AAC',58189:'\u7AEE',58190:'\u7B88',58191:'\u7B9C',58192:'\u7B8A',58193:'\u7B91',58194:'\u7B90',58195:'\u7B96',58196:'\u7B8D',58197:'\u7B8C',58198:'\u7B9B',58199:'\u7B8E',58200:'\u7B85',58201:'\u7B98',58202:'\u5284',58203:'\u7B99',58204:'\u7BA4',58205:'\u7B82',58206:'\u7CBB',58207:'\u7CBF',58208:'\u7CBC',58209:'\u7CBA',58210:'\u7DA7',58211:'\u7DB7',58212:'\u7DC2',58213:'\u7DA3',58214:'\u7DAA',58215:'\u7DC1',58216:'\u7DC0',58217:'\u7DC5',58218:'\u7D9D',58219:'\u7DCE',58220:'\u7DC4',58221:'\u7DC6',58222:'\u7DCB',58223:'\u7DCC',58224:'\u7DAF',58225:'\u7DB9',58226:'\u7D96',58227:'\u7DBC',58228:'\u7D9F',58229:'\u7DA6',58230:'\u7DAE',58231:'\u7DA9',58232:'\u7DA1',58233:'\u7DC9',58234:'\u7F73',58235:'\u7FE2',58236:'\u7FE3',58237:'\u7FE5',58238:'\u7FDE',58273:'\u8024',58274:'\u805D',58275:'\u805C',58276:'\u8189',58277:'\u8186',58278:'\u8183',58279:'\u8187',58280:'\u818D',58281:'\u818C',58282:'\u818B',58283:'\u8215',58284:'\u8497',58285:'\u84A4',58286:'\u84A1',58287:'\u849F',58288:'\u84BA',58289:'\u84CE',58290:'\u84C2',58291:'\u84AC',58292:'\u84AE',58293:'\u84AB',58294:'\u84B9',58295:'\u84B4',58296:'\u84C1',58297:'\u84CD',58298:'\u84AA',58299:'\u849A',58300:'\u84B1',58301:'\u84D0',58302:'\u849D',58303:'\u84A7',58304:'\u84BB',58305:'\u84A2',58306:'\u8494',58307:'\u84C7',58308:'\u84CC',58309:'\u849B',58310:'\u84A9',58311:'\u84AF',58312:'\u84A8',58313:'\u84D6',58314:'\u8498',58315:'\u84B6',58316:'\u84CF',58317:'\u84A0',58318:'\u84D7',58319:'\u84D4',58320:'\u84D2',58321:'\u84DB',58322:'\u84B0',58323:'\u8491',58324:'\u8661',58325:'\u8733',58326:'\u8723',58327:'\u8728',58328:'\u876B',58329:'\u8740',58330:'\u872E',58331:'\u871E',58332:'\u8721',58333:'\u8719',58334:'\u871B',58335:'\u8743',58336:'\u872C',58337:'\u8741',58338:'\u873E',58339:'\u8746',58340:'\u8720',58341:'\u8732',58342:'\u872A',58343:'\u872D',58344:'\u873C',58345:'\u8712',58346:'\u873A',58347:'\u8731',58348:'\u8735',58349:'\u8742',58350:'\u8726',58351:'\u8727',58352:'\u8738',58353:'\u8724',58354:'\u871A',58355:'\u8730',58356:'\u8711',58357:'\u88F7',58358:'\u88E7',58359:'\u88F1',58360:'\u88F2',58361:'\u88FA',58362:'\u88FE',58363:'\u88EE',58364:'\u88FC',58365:'\u88F6',58366:'\u88FB',58432:'\u88F0',58433:'\u88EC',58434:'\u88EB',58435:'\u899D',58436:'\u89A1',58437:'\u899F',58438:'\u899E',58439:'\u89E9',58440:'\u89EB',58441:'\u89E8',58442:'\u8AAB',58443:'\u8A99',58444:'\u8A8B',58445:'\u8A92',58446:'\u8A8F',58447:'\u8A96',58448:'\u8C3D',58449:'\u8C68',58450:'\u8C69',58451:'\u8CD5',58452:'\u8CCF',58453:'\u8CD7',58454:'\u8D96',58455:'\u8E09',58456:'\u8E02',58457:'\u8DFF',58458:'\u8E0D',58459:'\u8DFD',58460:'\u8E0A',58461:'\u8E03',58462:'\u8E07',58463:'\u8E06',58464:'\u8E05',58465:'\u8DFE',58466:'\u8E00',58467:'\u8E04',58468:'\u8F10',58469:'\u8F11',58470:'\u8F0E',58471:'\u8F0D',58472:'\u9123',58473:'\u911C',58474:'\u9120',58475:'\u9122',58476:'\u911F',58477:'\u911D',58478:'\u911A',58479:'\u9124',58480:'\u9121',58481:'\u911B',58482:'\u917A',58483:'\u9172',58484:'\u9179',58485:'\u9173',58486:'\u92A5',58487:'\u92A4',58488:'\u9276',58489:'\u929B',58490:'\u927A',58491:'\u92A0',58492:'\u9294',58493:'\u92AA',58494:'\u928D',58529:'\u92A6',58530:'\u929A',58531:'\u92AB',58532:'\u9279',58533:'\u9297',58534:'\u927F',58535:'\u92A3',58536:'\u92EE',58537:'\u928E',58538:'\u9282',58539:'\u9295',58540:'\u92A2',58541:'\u927D',58542:'\u9288',58543:'\u92A1',58544:'\u928A',58545:'\u9286',58546:'\u928C',58547:'\u9299',58548:'\u92A7',58549:'\u927E',58550:'\u9287',58551:'\u92A9',58552:'\u929D',58553:'\u928B',58554:'\u922D',58555:'\u969E',58556:'\u96A1',58557:'\u96FF',58558:'\u9758',58559:'\u977D',58560:'\u977A',58561:'\u977E',58562:'\u9783',58563:'\u9780',58564:'\u9782',58565:'\u977B',58566:'\u9784',58567:'\u9781',58568:'\u977F',58569:'\u97CE',58570:'\u97CD',58571:'\u9816',58572:'\u98AD',58573:'\u98AE',58574:'\u9902',58575:'\u9900',58576:'\u9907',58577:'\u999D',58578:'\u999C',58579:'\u99C3',58580:'\u99B9',58581:'\u99BB',58582:'\u99BA',58583:'\u99C2',58584:'\u99BD',58585:'\u99C7',58586:'\u9AB1',58587:'\u9AE3',58588:'\u9AE7',58589:'\u9B3E',58590:'\u9B3F',58591:'\u9B60',58592:'\u9B61',58593:'\u9B5F',58594:'\u9CF1',58595:'\u9CF2',58596:'\u9CF5',58597:'\u9EA7',58598:'\u50FF',58599:'\u5103',58600:'\u5130',58601:'\u50F8',58602:'\u5106',58603:'\u5107',58604:'\u50F6',58605:'\u50FE',58606:'\u510B',58607:'\u510C',58608:'\u50FD',58609:'\u510A',58610:'\u528B',58611:'\u528C',58612:'\u52F1',58613:'\u52EF',58614:'\u5648',58615:'\u5642',58616:'\u564C',58617:'\u5635',58618:'\u5641',58619:'\u564A',58620:'\u5649',58621:'\u5646',58622:'\u5658',58688:'\u565A',58689:'\u5640',58690:'\u5633',58691:'\u563D',58692:'\u562C',58693:'\u563E',58694:'\u5638',58695:'\u562A',58696:'\u563A',58697:'\u571A',58698:'\u58AB',58699:'\u589D',58700:'\u58B1',58701:'\u58A0',58702:'\u58A3',58703:'\u58AF',58704:'\u58AC',58705:'\u58A5',58706:'\u58A1',58707:'\u58FF',58708:'\u5AFF',58709:'\u5AF4',58710:'\u5AFD',58711:'\u5AF7',58712:'\u5AF6',58713:'\u5B03',58714:'\u5AF8',58715:'\u5B02',58716:'\u5AF9',58717:'\u5B01',58718:'\u5B07',58719:'\u5B05',58720:'\u5B0F',58721:'\u5C67',58722:'\u5D99',58723:'\u5D97',58724:'\u5D9F',58725:'\u5D92',58726:'\u5DA2',58727:'\u5D93',58728:'\u5D95',58729:'\u5DA0',58730:'\u5D9C',58731:'\u5DA1',58732:'\u5D9A',58733:'\u5D9E',58734:'\u5E69',58735:'\u5E5D',58736:'\u5E60',58737:'\u5E5C',58738:'\u7DF3',58739:'\u5EDB',58740:'\u5EDE',58741:'\u5EE1',58742:'\u5F49',58743:'\u5FB2',58744:'\u618B',58745:'\u6183',58746:'\u6179',58747:'\u61B1',58748:'\u61B0',58749:'\u61A2',58750:'\u6189',58785:'\u619B',58786:'\u6193',58787:'\u61AF',58788:'\u61AD',58789:'\u619F',58790:'\u6192',58791:'\u61AA',58792:'\u61A1',58793:'\u618D',58794:'\u6166',58795:'\u61B3',58796:'\u622D',58797:'\u646E',58798:'\u6470',58799:'\u6496',58800:'\u64A0',58801:'\u6485',58802:'\u6497',58803:'\u649C',58804:'\u648F',58805:'\u648B',58806:'\u648A',58807:'\u648C',58808:'\u64A3',58809:'\u649F',58810:'\u6468',58811:'\u64B1',58812:'\u6498',58813:'\u6576',58814:'\u657A',58815:'\u6579',58816:'\u657B',58817:'\u65B2',58818:'\u65B3',58819:'\u66B5',58820:'\u66B0',58821:'\u66A9',58822:'\u66B2',58823:'\u66B7',58824:'\u66AA',58825:'\u66AF',58826:'\u6A00',58827:'\u6A06',58828:'\u6A17',58829:'\u69E5',58830:'\u69F8',58831:'\u6A15',58832:'\u69F1',58833:'\u69E4',58834:'\u6A20',58835:'\u69FF',58836:'\u69EC',58837:'\u69E2',58838:'\u6A1B',58839:'\u6A1D',58840:'\u69FE',58841:'\u6A27',58842:'\u69F2',58843:'\u69EE',58844:'\u6A14',58845:'\u69F7',58846:'\u69E7',58847:'\u6A40',58848:'\u6A08',58849:'\u69E6',58850:'\u69FB',58851:'\u6A0D',58852:'\u69FC',58853:'\u69EB',58854:'\u6A09',58855:'\u6A04',58856:'\u6A18',58857:'\u6A25',58858:'\u6A0F',58859:'\u69F6',58860:'\u6A26',58861:'\u6A07',58862:'\u69F4',58863:'\u6A16',58864:'\u6B51',58865:'\u6BA5',58866:'\u6BA3',58867:'\u6BA2',58868:'\u6BA6',58869:'\u6C01',58870:'\u6C00',58871:'\u6BFF',58872:'\u6C02',58873:'\u6F41',58874:'\u6F26',58875:'\u6F7E',58876:'\u6F87',58877:'\u6FC6',58878:'\u6F92',58944:'\u6F8D',58945:'\u6F89',58946:'\u6F8C',58947:'\u6F62',58948:'\u6F4F',58949:'\u6F85',58950:'\u6F5A',58951:'\u6F96',58952:'\u6F76',58953:'\u6F6C',58954:'\u6F82',58955:'\u6F55',58956:'\u6F72',58957:'\u6F52',58958:'\u6F50',58959:'\u6F57',58960:'\u6F94',58961:'\u6F93',58962:'\u6F5D',58963:'\u6F00',58964:'\u6F61',58965:'\u6F6B',58966:'\u6F7D',58967:'\u6F67',58968:'\u6F90',58969:'\u6F53',58970:'\u6F8B',58971:'\u6F69',58972:'\u6F7F',58973:'\u6F95',58974:'\u6F63',58975:'\u6F77',58976:'\u6F6A',58977:'\u6F7B',58978:'\u71B2',58979:'\u71AF',58980:'\u719B',58981:'\u71B0',58982:'\u71A0',58983:'\u719A',58984:'\u71A9',58985:'\u71B5',58986:'\u719D',58987:'\u71A5',58988:'\u719E',58989:'\u71A4',58990:'\u71A1',58991:'\u71AA',58992:'\u719C',58993:'\u71A7',58994:'\u71B3',58995:'\u7298',58996:'\u729A',58997:'\u7358',58998:'\u7352',58999:'\u735E',59000:'\u735F',59001:'\u7360',59002:'\u735D',59003:'\u735B',59004:'\u7361',59005:'\u735A',59006:'\u7359',59041:'\u7362',59042:'\u7487',59043:'\u7489',59044:'\u748A',59045:'\u7486',59046:'\u7481',59047:'\u747D',59048:'\u7485',59049:'\u7488',59050:'\u747C',59051:'\u7479',59052:'\u7508',59053:'\u7507',59054:'\u757E',59055:'\u7625',59056:'\u761E',59057:'\u7619',59058:'\u761D',59059:'\u761C',59060:'\u7623',59061:'\u761A',59062:'\u7628',59063:'\u761B',59064:'\u769C',59065:'\u769D',59066:'\u769E',59067:'\u769B',59068:'\u778D',59069:'\u778F',59070:'\u7789',59071:'\u7788',59072:'\u78CD',59073:'\u78BB',59074:'\u78CF',59075:'\u78CC',59076:'\u78D1',59077:'\u78CE',59078:'\u78D4',59079:'\u78C8',59080:'\u78C3',59081:'\u78C4',59082:'\u78C9',59083:'\u799A',59084:'\u79A1',59085:'\u79A0',59086:'\u799C',59087:'\u79A2',59088:'\u799B',59089:'\u6B76',59090:'\u7A39',59091:'\u7AB2',59092:'\u7AB4',59093:'\u7AB3',59094:'\u7BB7',59095:'\u7BCB',59096:'\u7BBE',59097:'\u7BAC',59098:'\u7BCE',59099:'\u7BAF',59100:'\u7BB9',59101:'\u7BCA',59102:'\u7BB5',59103:'\u7CC5',59104:'\u7CC8',59105:'\u7CCC',59106:'\u7CCB',59107:'\u7DF7',59108:'\u7DDB',59109:'\u7DEA',59110:'\u7DE7',59111:'\u7DD7',59112:'\u7DE1',59113:'\u7E03',59114:'\u7DFA',59115:'\u7DE6',59116:'\u7DF6',59117:'\u7DF1',59118:'\u7DF0',59119:'\u7DEE',59120:'\u7DDF',59121:'\u7F76',59122:'\u7FAC',59123:'\u7FB0',59124:'\u7FAD',59125:'\u7FED',59126:'\u7FEB',59127:'\u7FEA',59128:'\u7FEC',59129:'\u7FE6',59130:'\u7FE8',59131:'\u8064',59132:'\u8067',59133:'\u81A3',59134:'\u819F',59200:'\u819E',59201:'\u8195',59202:'\u81A2',59203:'\u8199',59204:'\u8197',59205:'\u8216',59206:'\u824F',59207:'\u8253',59208:'\u8252',59209:'\u8250',59210:'\u824E',59211:'\u8251',59212:'\u8524',59213:'\u853B',59214:'\u850F',59215:'\u8500',59216:'\u8529',59217:'\u850E',59218:'\u8509',59219:'\u850D',59220:'\u851F',59221:'\u850A',59222:'\u8527',59223:'\u851C',59224:'\u84FB',59225:'\u852B',59226:'\u84FA',59227:'\u8508',59228:'\u850C',59229:'\u84F4',59230:'\u852A',59231:'\u84F2',59232:'\u8515',59233:'\u84F7',59234:'\u84EB',59235:'\u84F3',59236:'\u84FC',59237:'\u8512',59238:'\u84EA',59239:'\u84E9',59240:'\u8516',59241:'\u84FE',59242:'\u8528',59243:'\u851D',59244:'\u852E',59245:'\u8502',59246:'\u84FD',59247:'\u851E',59248:'\u84F6',59249:'\u8531',59250:'\u8526',59251:'\u84E7',59252:'\u84E8',59253:'\u84F0',59254:'\u84EF',59255:'\u84F9',59256:'\u8518',59257:'\u8520',59258:'\u8530',59259:'\u850B',59260:'\u8519',59261:'\u852F',59262:'\u8662',59297:'\u8756',59298:'\u8763',59299:'\u8764',59300:'\u8777',59301:'\u87E1',59302:'\u8773',59303:'\u8758',59304:'\u8754',59305:'\u875B',59306:'\u8752',59307:'\u8761',59308:'\u875A',59309:'\u8751',59310:'\u875E',59311:'\u876D',59312:'\u876A',59313:'\u8750',59314:'\u874E',59315:'\u875F',59316:'\u875D',59317:'\u876F',59318:'\u876C',59319:'\u877A',59320:'\u876E',59321:'\u875C',59322:'\u8765',59323:'\u874F',59324:'\u877B',59325:'\u8775',59326:'\u8762',59327:'\u8767',59328:'\u8769',59329:'\u885A',59330:'\u8905',59331:'\u890C',59332:'\u8914',59333:'\u890B',59334:'\u8917',59335:'\u8918',59336:'\u8919',59337:'\u8906',59338:'\u8916',59339:'\u8911',59340:'\u890E',59341:'\u8909',59342:'\u89A2',59343:'\u89A4',59344:'\u89A3',59345:'\u89ED',59346:'\u89F0',59347:'\u89EC',59348:'\u8ACF',59349:'\u8AC6',59350:'\u8AB8',59351:'\u8AD3',59352:'\u8AD1',59353:'\u8AD4',59354:'\u8AD5',59355:'\u8ABB',59356:'\u8AD7',59357:'\u8ABE',59358:'\u8AC0',59359:'\u8AC5',59360:'\u8AD8',59361:'\u8AC3',59362:'\u8ABA',59363:'\u8ABD',59364:'\u8AD9',59365:'\u8C3E',59366:'\u8C4D',59367:'\u8C8F',59368:'\u8CE5',59369:'\u8CDF',59370:'\u8CD9',59371:'\u8CE8',59372:'\u8CDA',59373:'\u8CDD',59374:'\u8CE7',59375:'\u8DA0',59376:'\u8D9C',59377:'\u8DA1',59378:'\u8D9B',59379:'\u8E20',59380:'\u8E23',59381:'\u8E25',59382:'\u8E24',59383:'\u8E2E',59384:'\u8E15',59385:'\u8E1B',59386:'\u8E16',59387:'\u8E11',59388:'\u8E19',59389:'\u8E26',59390:'\u8E27',59456:'\u8E14',59457:'\u8E12',59458:'\u8E18',59459:'\u8E13',59460:'\u8E1C',59461:'\u8E17',59462:'\u8E1A',59463:'\u8F2C',59464:'\u8F24',59465:'\u8F18',59466:'\u8F1A',59467:'\u8F20',59468:'\u8F23',59469:'\u8F16',59470:'\u8F17',59471:'\u9073',59472:'\u9070',59473:'\u906F',59474:'\u9067',59475:'\u906B',59476:'\u912F',59477:'\u912B',59478:'\u9129',59479:'\u912A',59480:'\u9132',59481:'\u9126',59482:'\u912E',59483:'\u9185',59484:'\u9186',59485:'\u918A',59486:'\u9181',59487:'\u9182',59488:'\u9184',59489:'\u9180',59490:'\u92D0',59491:'\u92C3',59492:'\u92C4',59493:'\u92C0',59494:'\u92D9',59495:'\u92B6',59496:'\u92CF',59497:'\u92F1',59498:'\u92DF',59499:'\u92D8',59500:'\u92E9',59501:'\u92D7',59502:'\u92DD',59503:'\u92CC',59504:'\u92EF',59505:'\u92C2',59506:'\u92E8',59507:'\u92CA',59508:'\u92C8',59509:'\u92CE',59510:'\u92E6',59511:'\u92CD',59512:'\u92D5',59513:'\u92C9',59514:'\u92E0',59515:'\u92DE',59516:'\u92E7',59517:'\u92D1',59518:'\u92D3',59553:'\u92B5',59554:'\u92E1',59555:'\u92C6',59556:'\u92B4',59557:'\u957C',59558:'\u95AC',59559:'\u95AB',59560:'\u95AE',59561:'\u95B0',59562:'\u96A4',59563:'\u96A2',59564:'\u96D3',59565:'\u9705',59566:'\u9708',59567:'\u9702',59568:'\u975A',59569:'\u978A',59570:'\u978E',59571:'\u9788',59572:'\u97D0',59573:'\u97CF',59574:'\u981E',59575:'\u981D',59576:'\u9826',59577:'\u9829',59578:'\u9828',59579:'\u9820',59580:'\u981B',59581:'\u9827',59582:'\u98B2',59583:'\u9908',59584:'\u98FA',59585:'\u9911',59586:'\u9914',59587:'\u9916',59588:'\u9917',59589:'\u9915',59590:'\u99DC',59591:'\u99CD',59592:'\u99CF',59593:'\u99D3',59594:'\u99D4',59595:'\u99CE',59596:'\u99C9',59597:'\u99D6',59598:'\u99D8',59599:'\u99CB',59600:'\u99D7',59601:'\u99CC',59602:'\u9AB3',59603:'\u9AEC',59604:'\u9AEB',59605:'\u9AF3',59606:'\u9AF2',59607:'\u9AF1',59608:'\u9B46',59609:'\u9B43',59610:'\u9B67',59611:'\u9B74',59612:'\u9B71',59613:'\u9B66',59614:'\u9B76',59615:'\u9B75',59616:'\u9B70',59617:'\u9B68',59618:'\u9B64',59619:'\u9B6C',59620:'\u9CFC',59621:'\u9CFA',59622:'\u9CFD',59623:'\u9CFF',59624:'\u9CF7',59625:'\u9D07',59626:'\u9D00',59627:'\u9CF9',59628:'\u9CFB',59629:'\u9D08',59630:'\u9D05',59631:'\u9D04',59632:'\u9E83',59633:'\u9ED3',59634:'\u9F0F',59635:'\u9F10',59636:'\u511C',59637:'\u5113',59638:'\u5117',59639:'\u511A',59640:'\u5111',59641:'\u51DE',59642:'\u5334',59643:'\u53E1',59644:'\u5670',59645:'\u5660',59646:'\u566E',59712:'\u5673',59713:'\u5666',59714:'\u5663',59715:'\u566D',59716:'\u5672',59717:'\u565E',59718:'\u5677',59719:'\u571C',59720:'\u571B',59721:'\u58C8',59722:'\u58BD',59723:'\u58C9',59724:'\u58BF',59725:'\u58BA',59726:'\u58C2',59727:'\u58BC',59728:'\u58C6',59729:'\u5B17',59730:'\u5B19',59731:'\u5B1B',59732:'\u5B21',59733:'\u5B14',59734:'\u5B13',59735:'\u5B10',59736:'\u5B16',59737:'\u5B28',59738:'\u5B1A',59739:'\u5B20',59740:'\u5B1E',59741:'\u5BEF',59742:'\u5DAC',59743:'\u5DB1',59744:'\u5DA9',59745:'\u5DA7',59746:'\u5DB5',59747:'\u5DB0',59748:'\u5DAE',59749:'\u5DAA',59750:'\u5DA8',59751:'\u5DB2',59752:'\u5DAD',59753:'\u5DAF',59754:'\u5DB4',59755:'\u5E67',59756:'\u5E68',59757:'\u5E66',59758:'\u5E6F',59759:'\u5EE9',59760:'\u5EE7',59761:'\u5EE6',59762:'\u5EE8',59763:'\u5EE5',59764:'\u5F4B',59765:'\u5FBC',59766:'\u619D',59767:'\u61A8',59768:'\u6196',59769:'\u61C5',59770:'\u61B4',59771:'\u61C6',59772:'\u61C1',59773:'\u61CC',59774:'\u61BA',59809:'\u61BF',59810:'\u61B8',59811:'\u618C',59812:'\u64D7',59813:'\u64D6',59814:'\u64D0',59815:'\u64CF',59816:'\u64C9',59817:'\u64BD',59818:'\u6489',59819:'\u64C3',59820:'\u64DB',59821:'\u64F3',59822:'\u64D9',59823:'\u6533',59824:'\u657F',59825:'\u657C',59826:'\u65A2',59827:'\u66C8',59828:'\u66BE',59829:'\u66C0',59830:'\u66CA',59831:'\u66CB',59832:'\u66CF',59833:'\u66BD',59834:'\u66BB',59835:'\u66BA',59836:'\u66CC',59837:'\u6723',59838:'\u6A34',59839:'\u6A66',59840:'\u6A49',59841:'\u6A67',59842:'\u6A32',59843:'\u6A68',59844:'\u6A3E',59845:'\u6A5D',59846:'\u6A6D',59847:'\u6A76',59848:'\u6A5B',59849:'\u6A51',59850:'\u6A28',59851:'\u6A5A',59852:'\u6A3B',59853:'\u6A3F',59854:'\u6A41',59855:'\u6A6A',59856:'\u6A64',59857:'\u6A50',59858:'\u6A4F',59859:'\u6A54',59860:'\u6A6F',59861:'\u6A69',59862:'\u6A60',59863:'\u6A3C',59864:'\u6A5E',59865:'\u6A56',59866:'\u6A55',59867:'\u6A4D',59868:'\u6A4E',59869:'\u6A46',59870:'\u6B55',59871:'\u6B54',59872:'\u6B56',59873:'\u6BA7',59874:'\u6BAA',59875:'\u6BAB',59876:'\u6BC8',59877:'\u6BC7',59878:'\u6C04',59879:'\u6C03',59880:'\u6C06',59881:'\u6FAD',59882:'\u6FCB',59883:'\u6FA3',59884:'\u6FC7',59885:'\u6FBC',59886:'\u6FCE',59887:'\u6FC8',59888:'\u6F5E',59889:'\u6FC4',59890:'\u6FBD',59891:'\u6F9E',59892:'\u6FCA',59893:'\u6FA8',59894:'\u7004',59895:'\u6FA5',59896:'\u6FAE',59897:'\u6FBA',59898:'\u6FAC',59899:'\u6FAA',59900:'\u6FCF',59901:'\u6FBF',59902:'\u6FB8',59968:'\u6FA2',59969:'\u6FC9',59970:'\u6FAB',59971:'\u6FCD',59972:'\u6FAF',59973:'\u6FB2',59974:'\u6FB0',59975:'\u71C5',59976:'\u71C2',59977:'\u71BF',59978:'\u71B8',59979:'\u71D6',59980:'\u71C0',59981:'\u71C1',59982:'\u71CB',59983:'\u71D4',59984:'\u71CA',59985:'\u71C7',59986:'\u71CF',59987:'\u71BD',59988:'\u71D8',59989:'\u71BC',59990:'\u71C6',59991:'\u71DA',59992:'\u71DB',59993:'\u729D',59994:'\u729E',59995:'\u7369',59996:'\u7366',59997:'\u7367',59998:'\u736C',59999:'\u7365',60000:'\u736B',60001:'\u736A',60002:'\u747F',60003:'\u749A',60004:'\u74A0',60005:'\u7494',60006:'\u7492',60007:'\u7495',60008:'\u74A1',60009:'\u750B',60010:'\u7580',60011:'\u762F',60012:'\u762D',60013:'\u7631',60014:'\u763D',60015:'\u7633',60016:'\u763C',60017:'\u7635',60018:'\u7632',60019:'\u7630',60020:'\u76BB',60021:'\u76E6',60022:'\u779A',60023:'\u779D',60024:'\u77A1',60025:'\u779C',60026:'\u779B',60027:'\u77A2',60028:'\u77A3',60029:'\u7795',60030:'\u7799',60065:'\u7797',60066:'\u78DD',60067:'\u78E9',60068:'\u78E5',60069:'\u78EA',60070:'\u78DE',60071:'\u78E3',60072:'\u78DB',60073:'\u78E1',60074:'\u78E2',60075:'\u78ED',60076:'\u78DF',60077:'\u78E0',60078:'\u79A4',60079:'\u7A44',60080:'\u7A48',60081:'\u7A47',60082:'\u7AB6',60083:'\u7AB8',60084:'\u7AB5',60085:'\u7AB1',60086:'\u7AB7',60087:'\u7BDE',60088:'\u7BE3',60089:'\u7BE7',60090:'\u7BDD',60091:'\u7BD5',60092:'\u7BE5',60093:'\u7BDA',60094:'\u7BE8',60095:'\u7BF9',60096:'\u7BD4',60097:'\u7BEA',60098:'\u7BE2',60099:'\u7BDC',60100:'\u7BEB',60101:'\u7BD8',60102:'\u7BDF',60103:'\u7CD2',60104:'\u7CD4',60105:'\u7CD7',60106:'\u7CD0',60107:'\u7CD1',60108:'\u7E12',60109:'\u7E21',60110:'\u7E17',60111:'\u7E0C',60112:'\u7E1F',60113:'\u7E20',60114:'\u7E13',60115:'\u7E0E',60116:'\u7E1C',60117:'\u7E15',60118:'\u7E1A',60119:'\u7E22',60120:'\u7E0B',60121:'\u7E0F',60122:'\u7E16',60123:'\u7E0D',60124:'\u7E14',60125:'\u7E25',60126:'\u7E24',60127:'\u7F43',60128:'\u7F7B',60129:'\u7F7C',60130:'\u7F7A',60131:'\u7FB1',60132:'\u7FEF',60133:'\u802A',60134:'\u8029',60135:'\u806C',60136:'\u81B1',60137:'\u81A6',60138:'\u81AE',60139:'\u81B9',60140:'\u81B5',60141:'\u81AB',60142:'\u81B0',60143:'\u81AC',60144:'\u81B4',60145:'\u81B2',60146:'\u81B7',60147:'\u81A7',60148:'\u81F2',60149:'\u8255',60150:'\u8256',60151:'\u8257',60152:'\u8556',60153:'\u8545',60154:'\u856B',60155:'\u854D',60156:'\u8553',60157:'\u8561',60158:'\u8558',60224:'\u8540',60225:'\u8546',60226:'\u8564',60227:'\u8541',60228:'\u8562',60229:'\u8544',60230:'\u8551',60231:'\u8547',60232:'\u8563',60233:'\u853E',60234:'\u855B',60235:'\u8571',60236:'\u854E',60237:'\u856E',60238:'\u8575',60239:'\u8555',60240:'\u8567',60241:'\u8560',60242:'\u858C',60243:'\u8566',60244:'\u855D',60245:'\u8554',60246:'\u8565',60247:'\u856C',60248:'\u8663',60249:'\u8665',60250:'\u8664',60251:'\u879B',60252:'\u878F',60253:'\u8797',60254:'\u8793',60255:'\u8792',60256:'\u8788',60257:'\u8781',60258:'\u8796',60259:'\u8798',60260:'\u8779',60261:'\u8787',60262:'\u87A3',60263:'\u8785',60264:'\u8790',60265:'\u8791',60266:'\u879D',60267:'\u8784',60268:'\u8794',60269:'\u879C',60270:'\u879A',60271:'\u8789',60272:'\u891E',60273:'\u8926',60274:'\u8930',60275:'\u892D',60276:'\u892E',60277:'\u8927',60278:'\u8931',60279:'\u8922',60280:'\u8929',60281:'\u8923',60282:'\u892F',60283:'\u892C',60284:'\u891F',60285:'\u89F1',60286:'\u8AE0',60321:'\u8AE2',60322:'\u8AF2',60323:'\u8AF4',60324:'\u8AF5',60325:'\u8ADD',60326:'\u8B14',60327:'\u8AE4',60328:'\u8ADF',60329:'\u8AF0',60330:'\u8AC8',60331:'\u8ADE',60332:'\u8AE1',60333:'\u8AE8',60334:'\u8AFF',60335:'\u8AEF',60336:'\u8AFB',60337:'\u8C91',60338:'\u8C92',60339:'\u8C90',60340:'\u8CF5',60341:'\u8CEE',60342:'\u8CF1',60343:'\u8CF0',60344:'\u8CF3',60345:'\u8D6C',60346:'\u8D6E',60347:'\u8DA5',60348:'\u8DA7',60349:'\u8E33',60350:'\u8E3E',60351:'\u8E38',60352:'\u8E40',60353:'\u8E45',60354:'\u8E36',60355:'\u8E3C',60356:'\u8E3D',60357:'\u8E41',60358:'\u8E30',60359:'\u8E3F',60360:'\u8EBD',60361:'\u8F36',60362:'\u8F2E',60363:'\u8F35',60364:'\u8F32',60365:'\u8F39',60366:'\u8F37',60367:'\u8F34',60368:'\u9076',60369:'\u9079',60370:'\u907B',60371:'\u9086',60372:'\u90FA',60373:'\u9133',60374:'\u9135',60375:'\u9136',60376:'\u9193',60377:'\u9190',60378:'\u9191',60379:'\u918D',60380:'\u918F',60381:'\u9327',60382:'\u931E',60383:'\u9308',60384:'\u931F',60385:'\u9306',60386:'\u930F',60387:'\u937A',60388:'\u9338',60389:'\u933C',60390:'\u931B',60391:'\u9323',60392:'\u9312',60393:'\u9301',60394:'\u9346',60395:'\u932D',60396:'\u930E',60397:'\u930D',60398:'\u92CB',60399:'\u931D',60400:'\u92FA',60401:'\u9325',60402:'\u9313',60403:'\u92F9',60404:'\u92F7',60405:'\u9334',60406:'\u9302',60407:'\u9324',60408:'\u92FF',60409:'\u9329',60410:'\u9339',60411:'\u9335',60412:'\u932A',60413:'\u9314',60414:'\u930C',60480:'\u930B',60481:'\u92FE',60482:'\u9309',60483:'\u9300',60484:'\u92FB',60485:'\u9316',60486:'\u95BC',60487:'\u95CD',60488:'\u95BE',60489:'\u95B9',60490:'\u95BA',60491:'\u95B6',60492:'\u95BF',60493:'\u95B5',60494:'\u95BD',60495:'\u96A9',60496:'\u96D4',60497:'\u970B',60498:'\u9712',60499:'\u9710',60500:'\u9799',60501:'\u9797',60502:'\u9794',60503:'\u97F0',60504:'\u97F8',60505:'\u9835',60506:'\u982F',60507:'\u9832',60508:'\u9924',60509:'\u991F',60510:'\u9927',60511:'\u9929',60512:'\u999E',60513:'\u99EE',60514:'\u99EC',60515:'\u99E5',60516:'\u99E4',60517:'\u99F0',60518:'\u99E3',60519:'\u99EA',60520:'\u99E9',60521:'\u99E7',60522:'\u9AB9',60523:'\u9ABF',60524:'\u9AB4',60525:'\u9ABB',60526:'\u9AF6',60527:'\u9AFA',60528:'\u9AF9',60529:'\u9AF7',60530:'\u9B33',60531:'\u9B80',60532:'\u9B85',60533:'\u9B87',60534:'\u9B7C',60535:'\u9B7E',60536:'\u9B7B',60537:'\u9B82',60538:'\u9B93',60539:'\u9B92',60540:'\u9B90',60541:'\u9B7A',60542:'\u9B95',60577:'\u9B7D',60578:'\u9B88',60579:'\u9D25',60580:'\u9D17',60581:'\u9D20',60582:'\u9D1E',60583:'\u9D14',60584:'\u9D29',60585:'\u9D1D',60586:'\u9D18',60587:'\u9D22',60588:'\u9D10',60589:'\u9D19',60590:'\u9D1F',60591:'\u9E88',60592:'\u9E86',60593:'\u9E87',60594:'\u9EAE',60595:'\u9EAD',60596:'\u9ED5',60597:'\u9ED6',60598:'\u9EFA',60599:'\u9F12',60600:'\u9F3D',60601:'\u5126',60602:'\u5125',60603:'\u5122',60604:'\u5124',60605:'\u5120',60606:'\u5129',60607:'\u52F4',60608:'\u5693',60609:'\u568C',60610:'\u568D',60611:'\u5686',60612:'\u5684',60613:'\u5683',60614:'\u567E',60615:'\u5682',60616:'\u567F',60617:'\u5681',60618:'\u58D6',60619:'\u58D4',60620:'\u58CF',60621:'\u58D2',60622:'\u5B2D',60623:'\u5B25',60624:'\u5B32',60625:'\u5B23',60626:'\u5B2C',60627:'\u5B27',60628:'\u5B26',60629:'\u5B2F',60630:'\u5B2E',60631:'\u5B7B',60632:'\u5BF1',60633:'\u5BF2',60634:'\u5DB7',60635:'\u5E6C',60636:'\u5E6A',60637:'\u5FBE',60638:'\u5FBB',60639:'\u61C3',60640:'\u61B5',60641:'\u61BC',60642:'\u61E7',60643:'\u61E0',60644:'\u61E5',60645:'\u61E4',60646:'\u61E8',60647:'\u61DE',60648:'\u64EF',60649:'\u64E9',60650:'\u64E3',60651:'\u64EB',60652:'\u64E4',60653:'\u64E8',60654:'\u6581',60655:'\u6580',60656:'\u65B6',60657:'\u65DA',60658:'\u66D2',60659:'\u6A8D',60660:'\u6A96',60661:'\u6A81',60662:'\u6AA5',60663:'\u6A89',60664:'\u6A9F',60665:'\u6A9B',60666:'\u6AA1',60667:'\u6A9E',60668:'\u6A87',60669:'\u6A93',60670:'\u6A8E',60736:'\u6A95',60737:'\u6A83',60738:'\u6AA8',60739:'\u6AA4',60740:'\u6A91',60741:'\u6A7F',60742:'\u6AA6',60743:'\u6A9A',60744:'\u6A85',60745:'\u6A8C',60746:'\u6A92',60747:'\u6B5B',60748:'\u6BAD',60749:'\u6C09',60750:'\u6FCC',60751:'\u6FA9',60752:'\u6FF4',60753:'\u6FD4',60754:'\u6FE3',60755:'\u6FDC',60756:'\u6FED',60757:'\u6FE7',60758:'\u6FE6',60759:'\u6FDE',60760:'\u6FF2',60761:'\u6FDD',60762:'\u6FE2',60763:'\u6FE8',60764:'\u71E1',60765:'\u71F1',60766:'\u71E8',60767:'\u71F2',60768:'\u71E4',60769:'\u71F0',60770:'\u71E2',60771:'\u7373',60772:'\u736E',60773:'\u736F',60774:'\u7497',60775:'\u74B2',60776:'\u74AB',60777:'\u7490',60778:'\u74AA',60779:'\u74AD',60780:'\u74B1',60781:'\u74A5',60782:'\u74AF',60783:'\u7510',60784:'\u7511',60785:'\u7512',60786:'\u750F',60787:'\u7584',60788:'\u7643',60789:'\u7648',60790:'\u7649',60791:'\u7647',60792:'\u76A4',60793:'\u76E9',60794:'\u77B5',60795:'\u77AB',60796:'\u77B2',60797:'\u77B7',60798:'\u77B6',60833:'\u77B4',60834:'\u77B1',60835:'\u77A8',60836:'\u77F0',60837:'\u78F3',60838:'\u78FD',60839:'\u7902',60840:'\u78FB',60841:'\u78FC',60842:'\u78F2',60843:'\u7905',60844:'\u78F9',60845:'\u78FE',60846:'\u7904',60847:'\u79AB',60848:'\u79A8',60849:'\u7A5C',60850:'\u7A5B',60851:'\u7A56',60852:'\u7A58',60853:'\u7A54',60854:'\u7A5A',60855:'\u7ABE',60856:'\u7AC0',60857:'\u7AC1',60858:'\u7C05',60859:'\u7C0F',60860:'\u7BF2',60861:'\u7C00',60862:'\u7BFF',60863:'\u7BFB',60864:'\u7C0E',60865:'\u7BF4',60866:'\u7C0B',60867:'\u7BF3',60868:'\u7C02',60869:'\u7C09',60870:'\u7C03',60871:'\u7C01',60872:'\u7BF8',60873:'\u7BFD',60874:'\u7C06',60875:'\u7BF0',60876:'\u7BF1',60877:'\u7C10',60878:'\u7C0A',60879:'\u7CE8',60880:'\u7E2D',60881:'\u7E3C',60882:'\u7E42',60883:'\u7E33',60884:'\u9848',60885:'\u7E38',60886:'\u7E2A',60887:'\u7E49',60888:'\u7E40',60889:'\u7E47',60890:'\u7E29',60891:'\u7E4C',60892:'\u7E30',60893:'\u7E3B',60894:'\u7E36',60895:'\u7E44',60896:'\u7E3A',60897:'\u7F45',60898:'\u7F7F',60899:'\u7F7E',60900:'\u7F7D',60901:'\u7FF4',60902:'\u7FF2',60903:'\u802C',60904:'\u81BB',60905:'\u81C4',60906:'\u81CC',60907:'\u81CA',60908:'\u81C5',60909:'\u81C7',60910:'\u81BC',60911:'\u81E9',60912:'\u825B',60913:'\u825A',60914:'\u825C',60915:'\u8583',60916:'\u8580',60917:'\u858F',60918:'\u85A7',60919:'\u8595',60920:'\u85A0',60921:'\u858B',60922:'\u85A3',60923:'\u857B',60924:'\u85A4',60925:'\u859A',60926:'\u859E',60992:'\u8577',60993:'\u857C',60994:'\u8589',60995:'\u85A1',60996:'\u857A',60997:'\u8578',60998:'\u8557',60999:'\u858E',61000:'\u8596',61001:'\u8586',61002:'\u858D',61003:'\u8599',61004:'\u859D',61005:'\u8581',61006:'\u85A2',61007:'\u8582',61008:'\u8588',61009:'\u8585',61010:'\u8579',61011:'\u8576',61012:'\u8598',61013:'\u8590',61014:'\u859F',61015:'\u8668',61016:'\u87BE',61017:'\u87AA',61018:'\u87AD',61019:'\u87C5',61020:'\u87B0',61021:'\u87AC',61022:'\u87B9',61023:'\u87B5',61024:'\u87BC',61025:'\u87AE',61026:'\u87C9',61027:'\u87C3',61028:'\u87C2',61029:'\u87CC',61030:'\u87B7',61031:'\u87AF',61032:'\u87C4',61033:'\u87CA',61034:'\u87B4',61035:'\u87B6',61036:'\u87BF',61037:'\u87B8',61038:'\u87BD',61039:'\u87DE',61040:'\u87B2',61041:'\u8935',61042:'\u8933',61043:'\u893C',61044:'\u893E',61045:'\u8941',61046:'\u8952',61047:'\u8937',61048:'\u8942',61049:'\u89AD',61050:'\u89AF',61051:'\u89AE',61052:'\u89F2',61053:'\u89F3',61054:'\u8B1E',61089:'\u8B18',61090:'\u8B16',61091:'\u8B11',61092:'\u8B05',61093:'\u8B0B',61094:'\u8B22',61095:'\u8B0F',61096:'\u8B12',61097:'\u8B15',61098:'\u8B07',61099:'\u8B0D',61100:'\u8B08',61101:'\u8B06',61102:'\u8B1C',61103:'\u8B13',61104:'\u8B1A',61105:'\u8C4F',61106:'\u8C70',61107:'\u8C72',61108:'\u8C71',61109:'\u8C6F',61110:'\u8C95',61111:'\u8C94',61112:'\u8CF9',61113:'\u8D6F',61114:'\u8E4E',61115:'\u8E4D',61116:'\u8E53',61117:'\u8E50',61118:'\u8E4C',61119:'\u8E47',61120:'\u8F43',61121:'\u8F40',61122:'\u9085',61123:'\u907E',61124:'\u9138',61125:'\u919A',61126:'\u91A2',61127:'\u919B',61128:'\u9199',61129:'\u919F',61130:'\u91A1',61131:'\u919D',61132:'\u91A0',61133:'\u93A1',61134:'\u9383',61135:'\u93AF',61136:'\u9364',61137:'\u9356',61138:'\u9347',61139:'\u937C',61140:'\u9358',61141:'\u935C',61142:'\u9376',61143:'\u9349',61144:'\u9350',61145:'\u9351',61146:'\u9360',61147:'\u936D',61148:'\u938F',61149:'\u934C',61150:'\u936A',61151:'\u9379',61152:'\u9357',61153:'\u9355',61154:'\u9352',61155:'\u934F',61156:'\u9371',61157:'\u9377',61158:'\u937B',61159:'\u9361',61160:'\u935E',61161:'\u9363',61162:'\u9367',61163:'\u9380',61164:'\u934E',61165:'\u9359',61166:'\u95C7',61167:'\u95C0',61168:'\u95C9',61169:'\u95C3',61170:'\u95C5',61171:'\u95B7',61172:'\u96AE',61173:'\u96B0',61174:'\u96AC',61175:'\u9720',61176:'\u971F',61177:'\u9718',61178:'\u971D',61179:'\u9719',61180:'\u979A',61181:'\u97A1',61182:'\u979C',61248:'\u979E',61249:'\u979D',61250:'\u97D5',61251:'\u97D4',61252:'\u97F1',61253:'\u9841',61254:'\u9844',61255:'\u984A',61256:'\u9849',61257:'\u9845',61258:'\u9843',61259:'\u9925',61260:'\u992B',61261:'\u992C',61262:'\u992A',61263:'\u9933',61264:'\u9932',61265:'\u992F',61266:'\u992D',61267:'\u9931',61268:'\u9930',61269:'\u9998',61270:'\u99A3',61271:'\u99A1',61272:'\u9A02',61273:'\u99FA',61274:'\u99F4',61275:'\u99F7',61276:'\u99F9',61277:'\u99F8',61278:'\u99F6',61279:'\u99FB',61280:'\u99FD',61281:'\u99FE',61282:'\u99FC',61283:'\u9A03',61284:'\u9ABE',61285:'\u9AFE',61286:'\u9AFD',61287:'\u9B01',61288:'\u9AFC',61289:'\u9B48',61290:'\u9B9A',61291:'\u9BA8',61292:'\u9B9E',61293:'\u9B9B',61294:'\u9BA6',61295:'\u9BA1',61296:'\u9BA5',61297:'\u9BA4',61298:'\u9B86',61299:'\u9BA2',61300:'\u9BA0',61301:'\u9BAF',61302:'\u9D33',61303:'\u9D41',61304:'\u9D67',61305:'\u9D36',61306:'\u9D2E',61307:'\u9D2F',61308:'\u9D31',61309:'\u9D38',61310:'\u9D30',61345:'\u9D45',61346:'\u9D42',61347:'\u9D43',61348:'\u9D3E',61349:'\u9D37',61350:'\u9D40',61351:'\u9D3D',61352:'\u7FF5',61353:'\u9D2D',61354:'\u9E8A',61355:'\u9E89',61356:'\u9E8D',61357:'\u9EB0',61358:'\u9EC8',61359:'\u9EDA',61360:'\u9EFB',61361:'\u9EFF',61362:'\u9F24',61363:'\u9F23',61364:'\u9F22',61365:'\u9F54',61366:'\u9FA0',61367:'\u5131',61368:'\u512D',61369:'\u512E',61370:'\u5698',61371:'\u569C',61372:'\u5697',61373:'\u569A',61374:'\u569D',61375:'\u5699',61376:'\u5970',61377:'\u5B3C',61378:'\u5C69',61379:'\u5C6A',61380:'\u5DC0',61381:'\u5E6D',61382:'\u5E6E',61383:'\u61D8',61384:'\u61DF',61385:'\u61ED',61386:'\u61EE',61387:'\u61F1',61388:'\u61EA',61389:'\u61F0',61390:'\u61EB',61391:'\u61D6',61392:'\u61E9',61393:'\u64FF',61394:'\u6504',61395:'\u64FD',61396:'\u64F8',61397:'\u6501',61398:'\u6503',61399:'\u64FC',61400:'\u6594',61401:'\u65DB',61402:'\u66DA',61403:'\u66DB',61404:'\u66D8',61405:'\u6AC5',61406:'\u6AB9',61407:'\u6ABD',61408:'\u6AE1',61409:'\u6AC6',61410:'\u6ABA',61411:'\u6AB6',61412:'\u6AB7',61413:'\u6AC7',61414:'\u6AB4',61415:'\u6AAD',61416:'\u6B5E',61417:'\u6BC9',61418:'\u6C0B',61419:'\u7007',61420:'\u700C',61421:'\u700D',61422:'\u7001',61423:'\u7005',61424:'\u7014',61425:'\u700E',61426:'\u6FFF',61427:'\u7000',61428:'\u6FFB',61429:'\u7026',61430:'\u6FFC',61431:'\u6FF7',61432:'\u700A',61433:'\u7201',61434:'\u71FF',61435:'\u71F9',61436:'\u7203',61437:'\u71FD',61438:'\u7376',61504:'\u74B8',61505:'\u74C0',61506:'\u74B5',61507:'\u74C1',61508:'\u74BE',61509:'\u74B6',61510:'\u74BB',61511:'\u74C2',61512:'\u7514',61513:'\u7513',61514:'\u765C',61515:'\u7664',61516:'\u7659',61517:'\u7650',61518:'\u7653',61519:'\u7657',61520:'\u765A',61521:'\u76A6',61522:'\u76BD',61523:'\u76EC',61524:'\u77C2',61525:'\u77BA',61526:'\u78FF',61527:'\u790C',61528:'\u7913',61529:'\u7914',61530:'\u7909',61531:'\u7910',61532:'\u7912',61533:'\u7911',61534:'\u79AD',61535:'\u79AC',61536:'\u7A5F',61537:'\u7C1C',61538:'\u7C29',61539:'\u7C19',61540:'\u7C20',61541:'\u7C1F',61542:'\u7C2D',61543:'\u7C1D',61544:'\u7C26',61545:'\u7C28',61546:'\u7C22',61547:'\u7C25',61548:'\u7C30',61549:'\u7E5C',61550:'\u7E50',61551:'\u7E56',61552:'\u7E63',61553:'\u7E58',61554:'\u7E62',61555:'\u7E5F',61556:'\u7E51',61557:'\u7E60',61558:'\u7E57',61559:'\u7E53',61560:'\u7FB5',61561:'\u7FB3',61562:'\u7FF7',61563:'\u7FF8',61564:'\u8075',61565:'\u81D1',61566:'\u81D2',61601:'\u81D0',61602:'\u825F',61603:'\u825E',61604:'\u85B4',61605:'\u85C6',61606:'\u85C0',61607:'\u85C3',61608:'\u85C2',61609:'\u85B3',61610:'\u85B5',61611:'\u85BD',61612:'\u85C7',61613:'\u85C4',61614:'\u85BF',61615:'\u85CB',61616:'\u85CE',61617:'\u85C8',61618:'\u85C5',61619:'\u85B1',61620:'\u85B6',61621:'\u85D2',61622:'\u8624',61623:'\u85B8',61624:'\u85B7',61625:'\u85BE',61626:'\u8669',61627:'\u87E7',61628:'\u87E6',61629:'\u87E2',61630:'\u87DB',61631:'\u87EB',61632:'\u87EA',61633:'\u87E5',61634:'\u87DF',61635:'\u87F3',61636:'\u87E4',61637:'\u87D4',61638:'\u87DC',61639:'\u87D3',61640:'\u87ED',61641:'\u87D8',61642:'\u87E3',61643:'\u87A4',61644:'\u87D7',61645:'\u87D9',61646:'\u8801',61647:'\u87F4',61648:'\u87E8',61649:'\u87DD',61650:'\u8953',61651:'\u894B',61652:'\u894F',61653:'\u894C',61654:'\u8946',61655:'\u8950',61656:'\u8951',61657:'\u8949',61658:'\u8B2A',61659:'\u8B27',61660:'\u8B23',61661:'\u8B33',61662:'\u8B30',61663:'\u8B35',61664:'\u8B47',61665:'\u8B2F',61666:'\u8B3C',61667:'\u8B3E',61668:'\u8B31',61669:'\u8B25',61670:'\u8B37',61671:'\u8B26',61672:'\u8B36',61673:'\u8B2E',61674:'\u8B24',61675:'\u8B3B',61676:'\u8B3D',61677:'\u8B3A',61678:'\u8C42',61679:'\u8C75',61680:'\u8C99',61681:'\u8C98',61682:'\u8C97',61683:'\u8CFE',61684:'\u8D04',61685:'\u8D02',61686:'\u8D00',61687:'\u8E5C',61688:'\u8E62',61689:'\u8E60',61690:'\u8E57',61691:'\u8E56',61692:'\u8E5E',61693:'\u8E65',61694:'\u8E67',61760:'\u8E5B',61761:'\u8E5A',61762:'\u8E61',61763:'\u8E5D',61764:'\u8E69',61765:'\u8E54',61766:'\u8F46',61767:'\u8F47',61768:'\u8F48',61769:'\u8F4B',61770:'\u9128',61771:'\u913A',61772:'\u913B',61773:'\u913E',61774:'\u91A8',61775:'\u91A5',61776:'\u91A7',61777:'\u91AF',61778:'\u91AA',61779:'\u93B5',61780:'\u938C',61781:'\u9392',61782:'\u93B7',61783:'\u939B',61784:'\u939D',61785:'\u9389',61786:'\u93A7',61787:'\u938E',61788:'\u93AA',61789:'\u939E',61790:'\u93A6',61791:'\u9395',61792:'\u9388',61793:'\u9399',61794:'\u939F',61795:'\u938D',61796:'\u93B1',61797:'\u9391',61798:'\u93B2',61799:'\u93A4',61800:'\u93A8',61801:'\u93B4',61802:'\u93A3',61803:'\u93A5',61804:'\u95D2',61805:'\u95D3',61806:'\u95D1',61807:'\u96B3',61808:'\u96D7',61809:'\u96DA',61810:'\u5DC2',61811:'\u96DF',61812:'\u96D8',61813:'\u96DD',61814:'\u9723',61815:'\u9722',61816:'\u9725',61817:'\u97AC',61818:'\u97AE',61819:'\u97A8',61820:'\u97AB',61821:'\u97A4',61822:'\u97AA',61857:'\u97A2',61858:'\u97A5',61859:'\u97D7',61860:'\u97D9',61861:'\u97D6',61862:'\u97D8',61863:'\u97FA',61864:'\u9850',61865:'\u9851',61866:'\u9852',61867:'\u98B8',61868:'\u9941',61869:'\u993C',61870:'\u993A',61871:'\u9A0F',61872:'\u9A0B',61873:'\u9A09',61874:'\u9A0D',61875:'\u9A04',61876:'\u9A11',61877:'\u9A0A',61878:'\u9A05',61879:'\u9A07',61880:'\u9A06',61881:'\u9AC0',61882:'\u9ADC',61883:'\u9B08',61884:'\u9B04',61885:'\u9B05',61886:'\u9B29',61887:'\u9B35',61888:'\u9B4A',61889:'\u9B4C',61890:'\u9B4B',61891:'\u9BC7',61892:'\u9BC6',61893:'\u9BC3',61894:'\u9BBF',61895:'\u9BC1',61896:'\u9BB5',61897:'\u9BB8',61898:'\u9BD3',61899:'\u9BB6',61900:'\u9BC4',61901:'\u9BB9',61902:'\u9BBD',61903:'\u9D5C',61904:'\u9D53',61905:'\u9D4F',61906:'\u9D4A',61907:'\u9D5B',61908:'\u9D4B',61909:'\u9D59',61910:'\u9D56',61911:'\u9D4C',61912:'\u9D57',61913:'\u9D52',61914:'\u9D54',61915:'\u9D5F',61916:'\u9D58',61917:'\u9D5A',61918:'\u9E8E',61919:'\u9E8C',61920:'\u9EDF',61921:'\u9F01',61922:'\u9F00',61923:'\u9F16',61924:'\u9F25',61925:'\u9F2B',61926:'\u9F2A',61927:'\u9F29',61928:'\u9F28',61929:'\u9F4C',61930:'\u9F55',61931:'\u5134',61932:'\u5135',61933:'\u5296',61934:'\u52F7',61935:'\u53B4',61936:'\u56AB',61937:'\u56AD',61938:'\u56A6',61939:'\u56A7',61940:'\u56AA',61941:'\u56AC',61942:'\u58DA',61943:'\u58DD',61944:'\u58DB',61945:'\u5912',61946:'\u5B3D',61947:'\u5B3E',61948:'\u5B3F',61949:'\u5DC3',61950:'\u5E70',62016:'\u5FBF',62017:'\u61FB',62018:'\u6507',62019:'\u6510',62020:'\u650D',62021:'\u6509',62022:'\u650C',62023:'\u650E',62024:'\u6584',62025:'\u65DE',62026:'\u65DD',62027:'\u66DE',62028:'\u6AE7',62029:'\u6AE0',62030:'\u6ACC',62031:'\u6AD1',62032:'\u6AD9',62033:'\u6ACB',62034:'\u6ADF',62035:'\u6ADC',62036:'\u6AD0',62037:'\u6AEB',62038:'\u6ACF',62039:'\u6ACD',62040:'\u6ADE',62041:'\u6B60',62042:'\u6BB0',62043:'\u6C0C',62044:'\u7019',62045:'\u7027',62046:'\u7020',62047:'\u7016',62048:'\u702B',62049:'\u7021',62050:'\u7022',62051:'\u7023',62052:'\u7029',62053:'\u7017',62054:'\u7024',62055:'\u701C',62056:'\u702A',62057:'\u720C',62058:'\u720A',62059:'\u7207',62060:'\u7202',62061:'\u7205',62062:'\u72A5',62063:'\u72A6',62064:'\u72A4',62065:'\u72A3',62066:'\u72A1',62067:'\u74CB',62068:'\u74C5',62069:'\u74B7',62070:'\u74C3',62071:'\u7516',62072:'\u7660',62073:'\u77C9',62074:'\u77CA',62075:'\u77C4',62076:'\u77F1',62077:'\u791D',62078:'\u791B',62113:'\u7921',62114:'\u791C',62115:'\u7917',62116:'\u791E',62117:'\u79B0',62118:'\u7A67',62119:'\u7A68',62120:'\u7C33',62121:'\u7C3C',62122:'\u7C39',62123:'\u7C2C',62124:'\u7C3B',62125:'\u7CEC',62126:'\u7CEA',62127:'\u7E76',62128:'\u7E75',62129:'\u7E78',62130:'\u7E70',62131:'\u7E77',62132:'\u7E6F',62133:'\u7E7A',62134:'\u7E72',62135:'\u7E74',62136:'\u7E68',62137:'\u7F4B',62138:'\u7F4A',62139:'\u7F83',62140:'\u7F86',62141:'\u7FB7',62142:'\u7FFD',62143:'\u7FFE',62144:'\u8078',62145:'\u81D7',62146:'\u81D5',62147:'\u8264',62148:'\u8261',62149:'\u8263',62150:'\u85EB',62151:'\u85F1',62152:'\u85ED',62153:'\u85D9',62154:'\u85E1',62155:'\u85E8',62156:'\u85DA',62157:'\u85D7',62158:'\u85EC',62159:'\u85F2',62160:'\u85F8',62161:'\u85D8',62162:'\u85DF',62163:'\u85E3',62164:'\u85DC',62165:'\u85D1',62166:'\u85F0',62167:'\u85E6',62168:'\u85EF',62169:'\u85DE',62170:'\u85E2',62171:'\u8800',62172:'\u87FA',62173:'\u8803',62174:'\u87F6',62175:'\u87F7',62176:'\u8809',62177:'\u880C',62178:'\u880B',62179:'\u8806',62180:'\u87FC',62181:'\u8808',62182:'\u87FF',62183:'\u880A',62184:'\u8802',62185:'\u8962',62186:'\u895A',62187:'\u895B',62188:'\u8957',62189:'\u8961',62190:'\u895C',62191:'\u8958',62192:'\u895D',62193:'\u8959',62194:'\u8988',62195:'\u89B7',62196:'\u89B6',62197:'\u89F6',62198:'\u8B50',62199:'\u8B48',62200:'\u8B4A',62201:'\u8B40',62202:'\u8B53',62203:'\u8B56',62204:'\u8B54',62205:'\u8B4B',62206:'\u8B55',62272:'\u8B51',62273:'\u8B42',62274:'\u8B52',62275:'\u8B57',62276:'\u8C43',62277:'\u8C77',62278:'\u8C76',62279:'\u8C9A',62280:'\u8D06',62281:'\u8D07',62282:'\u8D09',62283:'\u8DAC',62284:'\u8DAA',62285:'\u8DAD',62286:'\u8DAB',62287:'\u8E6D',62288:'\u8E78',62289:'\u8E73',62290:'\u8E6A',62291:'\u8E6F',62292:'\u8E7B',62293:'\u8EC2',62294:'\u8F52',62295:'\u8F51',62296:'\u8F4F',62297:'\u8F50',62298:'\u8F53',62299:'\u8FB4',62300:'\u9140',62301:'\u913F',62302:'\u91B0',62303:'\u91AD',62304:'\u93DE',62305:'\u93C7',62306:'\u93CF',62307:'\u93C2',62308:'\u93DA',62309:'\u93D0',62310:'\u93F9',62311:'\u93EC',62312:'\u93CC',62313:'\u93D9',62314:'\u93A9',62315:'\u93E6',62316:'\u93CA',62317:'\u93D4',62318:'\u93EE',62319:'\u93E3',62320:'\u93D5',62321:'\u93C4',62322:'\u93CE',62323:'\u93C0',62324:'\u93D2',62325:'\u93E7',62326:'\u957D',62327:'\u95DA',62328:'\u95DB',62329:'\u96E1',62330:'\u9729',62331:'\u972B',62332:'\u972C',62333:'\u9728',62334:'\u9726',62369:'\u97B3',62370:'\u97B7',62371:'\u97B6',62372:'\u97DD',62373:'\u97DE',62374:'\u97DF',62375:'\u985C',62376:'\u9859',62377:'\u985D',62378:'\u9857',62379:'\u98BF',62380:'\u98BD',62381:'\u98BB',62382:'\u98BE',62383:'\u9948',62384:'\u9947',62385:'\u9943',62386:'\u99A6',62387:'\u99A7',62388:'\u9A1A',62389:'\u9A15',62390:'\u9A25',62391:'\u9A1D',62392:'\u9A24',62393:'\u9A1B',62394:'\u9A22',62395:'\u9A20',62396:'\u9A27',62397:'\u9A23',62398:'\u9A1E',62399:'\u9A1C',62400:'\u9A14',62401:'\u9AC2',62402:'\u9B0B',62403:'\u9B0A',62404:'\u9B0E',62405:'\u9B0C',62406:'\u9B37',62407:'\u9BEA',62408:'\u9BEB',62409:'\u9BE0',62410:'\u9BDE',62411:'\u9BE4',62412:'\u9BE6',62413:'\u9BE2',62414:'\u9BF0',62415:'\u9BD4',62416:'\u9BD7',62417:'\u9BEC',62418:'\u9BDC',62419:'\u9BD9',62420:'\u9BE5',62421:'\u9BD5',62422:'\u9BE1',62423:'\u9BDA',62424:'\u9D77',62425:'\u9D81',62426:'\u9D8A',62427:'\u9D84',62428:'\u9D88',62429:'\u9D71',62430:'\u9D80',62431:'\u9D78',62432:'\u9D86',62433:'\u9D8B',62434:'\u9D8C',62435:'\u9D7D',62436:'\u9D6B',62437:'\u9D74',62438:'\u9D75',62439:'\u9D70',62440:'\u9D69',62441:'\u9D85',62442:'\u9D73',62443:'\u9D7B',62444:'\u9D82',62445:'\u9D6F',62446:'\u9D79',62447:'\u9D7F',62448:'\u9D87',62449:'\u9D68',62450:'\u9E94',62451:'\u9E91',62452:'\u9EC0',62453:'\u9EFC',62454:'\u9F2D',62455:'\u9F40',62456:'\u9F41',62457:'\u9F4D',62458:'\u9F56',62459:'\u9F57',62460:'\u9F58',62461:'\u5337',62462:'\u56B2',62528:'\u56B5',62529:'\u56B3',62530:'\u58E3',62531:'\u5B45',62532:'\u5DC6',62533:'\u5DC7',62534:'\u5EEE',62535:'\u5EEF',62536:'\u5FC0',62537:'\u5FC1',62538:'\u61F9',62539:'\u6517',62540:'\u6516',62541:'\u6515',62542:'\u6513',62543:'\u65DF',62544:'\u66E8',62545:'\u66E3',62546:'\u66E4',62547:'\u6AF3',62548:'\u6AF0',62549:'\u6AEA',62550:'\u6AE8',62551:'\u6AF9',62552:'\u6AF1',62553:'\u6AEE',62554:'\u6AEF',62555:'\u703C',62556:'\u7035',62557:'\u702F',62558:'\u7037',62559:'\u7034',62560:'\u7031',62561:'\u7042',62562:'\u7038',62563:'\u703F',62564:'\u703A',62565:'\u7039',62566:'\u7040',62567:'\u703B',62568:'\u7033',62569:'\u7041',62570:'\u7213',62571:'\u7214',62572:'\u72A8',62573:'\u737D',62574:'\u737C',62575:'\u74BA',62576:'\u76AB',62577:'\u76AA',62578:'\u76BE',62579:'\u76ED',62580:'\u77CC',62581:'\u77CE',62582:'\u77CF',62583:'\u77CD',62584:'\u77F2',62585:'\u7925',62586:'\u7923',62587:'\u7927',62588:'\u7928',62589:'\u7924',62590:'\u7929',62625:'\u79B2',62626:'\u7A6E',62627:'\u7A6C',62628:'\u7A6D',62629:'\u7AF7',62630:'\u7C49',62631:'\u7C48',62632:'\u7C4A',62633:'\u7C47',62634:'\u7C45',62635:'\u7CEE',62636:'\u7E7B',62637:'\u7E7E',62638:'\u7E81',62639:'\u7E80',62640:'\u7FBA',62641:'\u7FFF',62642:'\u8079',62643:'\u81DB',62644:'\u81D9',62645:'\u820B',62646:'\u8268',62647:'\u8269',62648:'\u8622',62649:'\u85FF',62650:'\u8601',62651:'\u85FE',62652:'\u861B',62653:'\u8600',62654:'\u85F6',62655:'\u8604',62656:'\u8609',62657:'\u8605',62658:'\u860C',62659:'\u85FD',62660:'\u8819',62661:'\u8810',62662:'\u8811',62663:'\u8817',62664:'\u8813',62665:'\u8816',62666:'\u8963',62667:'\u8966',62668:'\u89B9',62669:'\u89F7',62670:'\u8B60',62671:'\u8B6A',62672:'\u8B5D',62673:'\u8B68',62674:'\u8B63',62675:'\u8B65',62676:'\u8B67',62677:'\u8B6D',62678:'\u8DAE',62679:'\u8E86',62680:'\u8E88',62681:'\u8E84',62682:'\u8F59',62683:'\u8F56',62684:'\u8F57',62685:'\u8F55',62686:'\u8F58',62687:'\u8F5A',62688:'\u908D',62689:'\u9143',62690:'\u9141',62691:'\u91B7',62692:'\u91B5',62693:'\u91B2',62694:'\u91B3',62695:'\u940B',62696:'\u9413',62697:'\u93FB',62698:'\u9420',62699:'\u940F',62700:'\u9414',62701:'\u93FE',62702:'\u9415',62703:'\u9410',62704:'\u9428',62705:'\u9419',62706:'\u940D',62707:'\u93F5',62708:'\u9400',62709:'\u93F7',62710:'\u9407',62711:'\u940E',62712:'\u9416',62713:'\u9412',62714:'\u93FA',62715:'\u9409',62716:'\u93F8',62717:'\u940A',62718:'\u93FF',62784:'\u93FC',62785:'\u940C',62786:'\u93F6',62787:'\u9411',62788:'\u9406',62789:'\u95DE',62790:'\u95E0',62791:'\u95DF',62792:'\u972E',62793:'\u972F',62794:'\u97B9',62795:'\u97BB',62796:'\u97FD',62797:'\u97FE',62798:'\u9860',62799:'\u9862',62800:'\u9863',62801:'\u985F',62802:'\u98C1',62803:'\u98C2',62804:'\u9950',62805:'\u994E',62806:'\u9959',62807:'\u994C',62808:'\u994B',62809:'\u9953',62810:'\u9A32',62811:'\u9A34',62812:'\u9A31',62813:'\u9A2C',62814:'\u9A2A',62815:'\u9A36',62816:'\u9A29',62817:'\u9A2E',62818:'\u9A38',62819:'\u9A2D',62820:'\u9AC7',62821:'\u9ACA',62822:'\u9AC6',62823:'\u9B10',62824:'\u9B12',62825:'\u9B11',62826:'\u9C0B',62827:'\u9C08',62828:'\u9BF7',62829:'\u9C05',62830:'\u9C12',62831:'\u9BF8',62832:'\u9C40',62833:'\u9C07',62834:'\u9C0E',62835:'\u9C06',62836:'\u9C17',62837:'\u9C14',62838:'\u9C09',62839:'\u9D9F',62840:'\u9D99',62841:'\u9DA4',62842:'\u9D9D',62843:'\u9D92',62844:'\u9D98',62845:'\u9D90',62846:'\u9D9B',62881:'\u9DA0',62882:'\u9D94',62883:'\u9D9C',62884:'\u9DAA',62885:'\u9D97',62886:'\u9DA1',62887:'\u9D9A',62888:'\u9DA2',62889:'\u9DA8',62890:'\u9D9E',62891:'\u9DA3',62892:'\u9DBF',62893:'\u9DA9',62894:'\u9D96',62895:'\u9DA6',62896:'\u9DA7',62897:'\u9E99',62898:'\u9E9B',62899:'\u9E9A',62900:'\u9EE5',62901:'\u9EE4',62902:'\u9EE7',62903:'\u9EE6',62904:'\u9F30',62905:'\u9F2E',62906:'\u9F5B',62907:'\u9F60',62908:'\u9F5E',62909:'\u9F5D',62910:'\u9F59',62911:'\u9F91',62912:'\u513A',62913:'\u5139',62914:'\u5298',62915:'\u5297',62916:'\u56C3',62917:'\u56BD',62918:'\u56BE',62919:'\u5B48',62920:'\u5B47',62921:'\u5DCB',62922:'\u5DCF',62923:'\u5EF1',62924:'\u61FD',62925:'\u651B',62926:'\u6B02',62927:'\u6AFC',62928:'\u6B03',62929:'\u6AF8',62930:'\u6B00',62931:'\u7043',62932:'\u7044',62933:'\u704A',62934:'\u7048',62935:'\u7049',62936:'\u7045',62937:'\u7046',62938:'\u721D',62939:'\u721A',62940:'\u7219',62941:'\u737E',62942:'\u7517',62943:'\u766A',62944:'\u77D0',62945:'\u792D',62946:'\u7931',62947:'\u792F',62948:'\u7C54',62949:'\u7C53',62950:'\u7CF2',62951:'\u7E8A',62952:'\u7E87',62953:'\u7E88',62954:'\u7E8B',62955:'\u7E86',62956:'\u7E8D',62957:'\u7F4D',62958:'\u7FBB',62959:'\u8030',62960:'\u81DD',62961:'\u8618',62962:'\u862A',62963:'\u8626',62964:'\u861F',62965:'\u8623',62966:'\u861C',62967:'\u8619',62968:'\u8627',62969:'\u862E',62970:'\u8621',62971:'\u8620',62972:'\u8629',62973:'\u861E',62974:'\u8625',63040:'\u8829',63041:'\u881D',63042:'\u881B',63043:'\u8820',63044:'\u8824',63045:'\u881C',63046:'\u882B',63047:'\u884A',63048:'\u896D',63049:'\u8969',63050:'\u896E',63051:'\u896B',63052:'\u89FA',63053:'\u8B79',63054:'\u8B78',63055:'\u8B45',63056:'\u8B7A',63057:'\u8B7B',63058:'\u8D10',63059:'\u8D14',63060:'\u8DAF',63061:'\u8E8E',63062:'\u8E8C',63063:'\u8F5E',63064:'\u8F5B',63065:'\u8F5D',63066:'\u9146',63067:'\u9144',63068:'\u9145',63069:'\u91B9',63070:'\u943F',63071:'\u943B',63072:'\u9436',63073:'\u9429',63074:'\u943D',63075:'\u943C',63076:'\u9430',63077:'\u9439',63078:'\u942A',63079:'\u9437',63080:'\u942C',63081:'\u9440',63082:'\u9431',63083:'\u95E5',63084:'\u95E4',63085:'\u95E3',63086:'\u9735',63087:'\u973A',63088:'\u97BF',63089:'\u97E1',63090:'\u9864',63091:'\u98C9',63092:'\u98C6',63093:'\u98C0',63094:'\u9958',63095:'\u9956',63096:'\u9A39',63097:'\u9A3D',63098:'\u9A46',63099:'\u9A44',63100:'\u9A42',63101:'\u9A41',63102:'\u9A3A',63137:'\u9A3F',63138:'\u9ACD',63139:'\u9B15',63140:'\u9B17',63141:'\u9B18',63142:'\u9B16',63143:'\u9B3A',63144:'\u9B52',63145:'\u9C2B',63146:'\u9C1D',63147:'\u9C1C',63148:'\u9C2C',63149:'\u9C23',63150:'\u9C28',63151:'\u9C29',63152:'\u9C24',63153:'\u9C21',63154:'\u9DB7',63155:'\u9DB6',63156:'\u9DBC',63157:'\u9DC1',63158:'\u9DC7',63159:'\u9DCA',63160:'\u9DCF',63161:'\u9DBE',63162:'\u9DC5',63163:'\u9DC3',63164:'\u9DBB',63165:'\u9DB5',63166:'\u9DCE',63167:'\u9DB9',63168:'\u9DBA',63169:'\u9DAC',63170:'\u9DC8',63171:'\u9DB1',63172:'\u9DAD',63173:'\u9DCC',63174:'\u9DB3',63175:'\u9DCD',63176:'\u9DB2',63177:'\u9E7A',63178:'\u9E9C',63179:'\u9EEB',63180:'\u9EEE',63181:'\u9EED',63182:'\u9F1B',63183:'\u9F18',63184:'\u9F1A',63185:'\u9F31',63186:'\u9F4E',63187:'\u9F65',63188:'\u9F64',63189:'\u9F92',63190:'\u4EB9',63191:'\u56C6',63192:'\u56C5',63193:'\u56CB',63194:'\u5971',63195:'\u5B4B',63196:'\u5B4C',63197:'\u5DD5',63198:'\u5DD1',63199:'\u5EF2',63200:'\u6521',63201:'\u6520',63202:'\u6526',63203:'\u6522',63204:'\u6B0B',63205:'\u6B08',63206:'\u6B09',63207:'\u6C0D',63208:'\u7055',63209:'\u7056',63210:'\u7057',63211:'\u7052',63212:'\u721E',63213:'\u721F',63214:'\u72A9',63215:'\u737F',63216:'\u74D8',63217:'\u74D5',63218:'\u74D9',63219:'\u74D7',63220:'\u766D',63221:'\u76AD',63222:'\u7935',63223:'\u79B4',63224:'\u7A70',63225:'\u7A71',63226:'\u7C57',63227:'\u7C5C',63228:'\u7C59',63229:'\u7C5B',63230:'\u7C5A',63296:'\u7CF4',63297:'\u7CF1',63298:'\u7E91',63299:'\u7F4F',63300:'\u7F87',63301:'\u81DE',63302:'\u826B',63303:'\u8634',63304:'\u8635',63305:'\u8633',63306:'\u862C',63307:'\u8632',63308:'\u8636',63309:'\u882C',63310:'\u8828',63311:'\u8826',63312:'\u882A',63313:'\u8825',63314:'\u8971',63315:'\u89BF',63316:'\u89BE',63317:'\u89FB',63318:'\u8B7E',63319:'\u8B84',63320:'\u8B82',63321:'\u8B86',63322:'\u8B85',63323:'\u8B7F',63324:'\u8D15',63325:'\u8E95',63326:'\u8E94',63327:'\u8E9A',63328:'\u8E92',63329:'\u8E90',63330:'\u8E96',63331:'\u8E97',63332:'\u8F60',63333:'\u8F62',63334:'\u9147',63335:'\u944C',63336:'\u9450',63337:'\u944A',63338:'\u944B',63339:'\u944F',63340:'\u9447',63341:'\u9445',63342:'\u9448',63343:'\u9449',63344:'\u9446',63345:'\u973F',63346:'\u97E3',63347:'\u986A',63348:'\u9869',63349:'\u98CB',63350:'\u9954',63351:'\u995B',63352:'\u9A4E',63353:'\u9A53',63354:'\u9A54',63355:'\u9A4C',63356:'\u9A4F',63357:'\u9A48',63358:'\u9A4A',63393:'\u9A49',63394:'\u9A52',63395:'\u9A50',63396:'\u9AD0',63397:'\u9B19',63398:'\u9B2B',63399:'\u9B3B',63400:'\u9B56',63401:'\u9B55',63402:'\u9C46',63403:'\u9C48',63404:'\u9C3F',63405:'\u9C44',63406:'\u9C39',63407:'\u9C33',63408:'\u9C41',63409:'\u9C3C',63410:'\u9C37',63411:'\u9C34',63412:'\u9C32',63413:'\u9C3D',63414:'\u9C36',63415:'\u9DDB',63416:'\u9DD2',63417:'\u9DDE',63418:'\u9DDA',63419:'\u9DCB',63420:'\u9DD0',63421:'\u9DDC',63422:'\u9DD1',63423:'\u9DDF',63424:'\u9DE9',63425:'\u9DD9',63426:'\u9DD8',63427:'\u9DD6',63428:'\u9DF5',63429:'\u9DD5',63430:'\u9DDD',63431:'\u9EB6',63432:'\u9EF0',63433:'\u9F35',63434:'\u9F33',63435:'\u9F32',63436:'\u9F42',63437:'\u9F6B',63438:'\u9F95',63439:'\u9FA2',63440:'\u513D',63441:'\u5299',63442:'\u58E8',63443:'\u58E7',63444:'\u5972',63445:'\u5B4D',63446:'\u5DD8',63447:'\u882F',63448:'\u5F4F',63449:'\u6201',63450:'\u6203',63451:'\u6204',63452:'\u6529',63453:'\u6525',63454:'\u6596',63455:'\u66EB',63456:'\u6B11',63457:'\u6B12',63458:'\u6B0F',63459:'\u6BCA',63460:'\u705B',63461:'\u705A',63462:'\u7222',63463:'\u7382',63464:'\u7381',63465:'\u7383',63466:'\u7670',63467:'\u77D4',63468:'\u7C67',63469:'\u7C66',63470:'\u7E95',63471:'\u826C',63472:'\u863A',63473:'\u8640',63474:'\u8639',63475:'\u863C',63476:'\u8631',63477:'\u863B',63478:'\u863E',63479:'\u8830',63480:'\u8832',63481:'\u882E',63482:'\u8833',63483:'\u8976',63484:'\u8974',63485:'\u8973',63486:'\u89FE',63552:'\u8B8C',63553:'\u8B8E',63554:'\u8B8B',63555:'\u8B88',63556:'\u8C45',63557:'\u8D19',63558:'\u8E98',63559:'\u8F64',63560:'\u8F63',63561:'\u91BC',63562:'\u9462',63563:'\u9455',63564:'\u945D',63565:'\u9457',63566:'\u945E',63567:'\u97C4',63568:'\u97C5',63569:'\u9800',63570:'\u9A56',63571:'\u9A59',63572:'\u9B1E',63573:'\u9B1F',63574:'\u9B20',63575:'\u9C52',63576:'\u9C58',63577:'\u9C50',63578:'\u9C4A',63579:'\u9C4D',63580:'\u9C4B',63581:'\u9C55',63582:'\u9C59',63583:'\u9C4C',63584:'\u9C4E',63585:'\u9DFB',63586:'\u9DF7',63587:'\u9DEF',63588:'\u9DE3',63589:'\u9DEB',63590:'\u9DF8',63591:'\u9DE4',63592:'\u9DF6',63593:'\u9DE1',63594:'\u9DEE',63595:'\u9DE6',63596:'\u9DF2',63597:'\u9DF0',63598:'\u9DE2',63599:'\u9DEC',63600:'\u9DF4',63601:'\u9DF3',63602:'\u9DE8',63603:'\u9DED',63604:'\u9EC2',63605:'\u9ED0',63606:'\u9EF2',63607:'\u9EF3',63608:'\u9F06',63609:'\u9F1C',63610:'\u9F38',63611:'\u9F37',63612:'\u9F36',63613:'\u9F43',63614:'\u9F4F',63649:'\u9F71',63650:'\u9F70',63651:'\u9F6E',63652:'\u9F6F',63653:'\u56D3',63654:'\u56CD',63655:'\u5B4E',63656:'\u5C6D',63657:'\u652D',63658:'\u66ED',63659:'\u66EE',63660:'\u6B13',63661:'\u705F',63662:'\u7061',63663:'\u705D',63664:'\u7060',63665:'\u7223',63666:'\u74DB',63667:'\u74E5',63668:'\u77D5',63669:'\u7938',63670:'\u79B7',63671:'\u79B6',63672:'\u7C6A',63673:'\u7E97',63674:'\u7F89',63675:'\u826D',63676:'\u8643',63677:'\u8838',63678:'\u8837',63679:'\u8835',63680:'\u884B',63681:'\u8B94',63682:'\u8B95',63683:'\u8E9E',63684:'\u8E9F',63685:'\u8EA0',63686:'\u8E9D',63687:'\u91BE',63688:'\u91BD',63689:'\u91C2',63690:'\u946B',63691:'\u9468',63692:'\u9469',63693:'\u96E5',63694:'\u9746',63695:'\u9743',63696:'\u9747',63697:'\u97C7',63698:'\u97E5',63699:'\u9A5E',63700:'\u9AD5',63701:'\u9B59',63702:'\u9C63',63703:'\u9C67',63704:'\u9C66',63705:'\u9C62',63706:'\u9C5E',63707:'\u9C60',63708:'\u9E02',63709:'\u9DFE',63710:'\u9E07',63711:'\u9E03',63712:'\u9E06',63713:'\u9E05',63714:'\u9E00',63715:'\u9E01',63716:'\u9E09',63717:'\u9DFF',63718:'\u9DFD',63719:'\u9E04',63720:'\u9EA0',63721:'\u9F1E',63722:'\u9F46',63723:'\u9F74',63724:'\u9F75',63725:'\u9F76',63726:'\u56D4',63727:'\u652E',63728:'\u65B8',63729:'\u6B18',63730:'\u6B19',63731:'\u6B17',63732:'\u6B1A',63733:'\u7062',63734:'\u7226',63735:'\u72AA',63736:'\u77D8',63737:'\u77D9',63738:'\u7939',63739:'\u7C69',63740:'\u7C6B',63741:'\u7CF6',63742:'\u7E9A',63808:'\u7E98',63809:'\u7E9B',63810:'\u7E99',63811:'\u81E0',63812:'\u81E1',63813:'\u8646',63814:'\u8647',63815:'\u8648',63816:'\u8979',63817:'\u897A',63818:'\u897C',63819:'\u897B',63820:'\u89FF',63821:'\u8B98',63822:'\u8B99',63823:'\u8EA5',63824:'\u8EA4',63825:'\u8EA3',63826:'\u946E',63827:'\u946D',63828:'\u946F',63829:'\u9471',63830:'\u9473',63831:'\u9749',63832:'\u9872',63833:'\u995F',63834:'\u9C68',63835:'\u9C6E',63836:'\u9C6D',63837:'\u9E0B',63838:'\u9E0D',63839:'\u9E10',63840:'\u9E0F',63841:'\u9E12',63842:'\u9E11',63843:'\u9EA1',63844:'\u9EF5',63845:'\u9F09',63846:'\u9F47',63847:'\u9F78',63848:'\u9F7B',63849:'\u9F7A',63850:'\u9F79',63851:'\u571E',63852:'\u7066',63853:'\u7C6F',63854:'\u883C',63855:'\u8DB2',63856:'\u8EA6',63857:'\u91C3',63858:'\u9474',63859:'\u9478',63860:'\u9476',63861:'\u9475',63862:'\u9A60',63863:'\u9C74',63864:'\u9C73',63865:'\u9C71',63866:'\u9C75',63867:'\u9E14',63868:'\u9E13',63869:'\u9EF6',63870:'\u9F0A',63905:'\u9FA4',63906:'\u7068',63907:'\u7065',63908:'\u7CF7',63909:'\u866A',63910:'\u883E',63911:'\u883D',63912:'\u883F',63913:'\u8B9E',63914:'\u8C9C',63915:'\u8EA9',63916:'\u8EC9',63917:'\u974B',63918:'\u9873',63919:'\u9874',63920:'\u98CC',63921:'\u9961',63922:'\u99AB',63923:'\u9A64',63924:'\u9A66',63925:'\u9A67',63926:'\u9B24',63927:'\u9E15',63928:'\u9E17',63929:'\u9F48',63930:'\u6207',63931:'\u6B1E',63932:'\u7227',63933:'\u864C',63934:'\u8EA8',63935:'\u9482',63936:'\u9480',63937:'\u9481',63938:'\u9A69',63939:'\u9A68',63940:'\u9B2E',63941:'\u9E19',63942:'\u7229',63943:'\u864B',63944:'\u8B9F',63945:'\u9483',63946:'\u9C79',63947:'\u9EB7',63948:'\u7675',63949:'\u9A6B',63950:'\u9C7A',63951:'\u9E1D',63952:'\u7069',63953:'\u706A',63954:'\u9EA4',63955:'\u9F7E',63956:'\u9F49',63957:'\u9F98',63958:'\u7881',63959:'\u92B9',63960:'\u88CF',63961:'\u58BB',63962:'\u6052',63963:'\u7CA7',63964:'\u5AFA',63965:'\u2554',63966:'\u2566',63967:'\u2557',63968:'\u2560',63969:'\u256C',63970:'\u2563',63971:'\u255A',63972:'\u2569',63973:'\u255D',63974:'\u2552',63975:'\u2564',63976:'\u2555',63977:'\u255E',63978:'\u256A',63979:'\u2561',63980:'\u2558',63981:'\u2567',63982:'\u255B',63983:'\u2553',63984:'\u2565',63985:'\u2556',63986:'\u255F',63987:'\u256B',63988:'\u2562',63989:'\u2559',63990:'\u2568',63991:'\u255C',63992:'\u2551',63993:'\u2550',63994:'\u256D',63995:'\u256E',63996:'\u2570',63997:'\u256F',63998:'\u2593',64064:'\uE000',64065:'\uE001',64066:'\uE002',64067:'\uE003',64068:'\uE004',64069:'\uE005',64070:'\uE006',64071:'\uE007',64072:'\uE008',64073:'\uE009',64074:'\uE00A',64075:'\uE00B',64076:'\uE00C',64077:'\uE00D',64078:'\uE00E',64079:'\uE00F',64080:'\uE010',64081:'\uE011',64082:'\uE012',64083:'\uE013',64084:'\uE014',64085:'\uE015',64086:'\uE016',64087:'\uE017',64088:'\uE018',64089:'\uE019',64090:'\uE01A',64091:'\uE01B',64092:'\uE01C',64093:'\uE01D',64094:'\uE01E',64095:'\uE01F',64096:'\uE020',64097:'\uE021',64098:'\uE022',64099:'\uE023',64100:'\uE024',64101:'\uE025',64102:'\uE026',64103:'\uE027',64104:'\uE028',64105:'\uE029',64106:'\uE02A',64107:'\uE02B',64108:'\uE02C',64109:'\uE02D',64110:'\uE02E',64111:'\uE02F',64112:'\uE030',64113:'\uE031',64114:'\uE032',64115:'\uE033',64116:'\uE034',64117:'\uE035',64118:'\uE036',64119:'\uE037',64120:'\uE038',64121:'\uE039',64122:'\uE03A',64123:'\uE03B',64124:'\uE03C',64125:'\uE03D',64126:'\uE03E',64161:'\uE03F',64162:'\uE040',64163:'\uE041',64164:'\uE042',64165:'\uE043',64166:'\uE044',64167:'\uE045',64168:'\uE046',64169:'\uE047',64170:'\uE048',64171:'\uE049',64172:'\uE04A',64173:'\uE04B',64174:'\uE04C',64175:'\uE04D',64176:'\uE04E',64177:'\uE04F',64178:'\uE050',64179:'\uE051',64180:'\uE052',64181:'\uE053',64182:'\uE054',64183:'\uE055',64184:'\uE056',64185:'\uE057',64186:'\uE058',64187:'\uE059',64188:'\uE05A',64189:'\uE05B',64190:'\uE05C',64191:'\uE05D',64192:'\uE05E',64193:'\uE05F',64194:'\uE060',64195:'\uE061',64196:'\uE062',64197:'\uE063',64198:'\uE064',64199:'\uE065',64200:'\uE066',64201:'\uE067',64202:'\uE068',64203:'\uE069',64204:'\uE06A',64205:'\uE06B',64206:'\uE06C',64207:'\uE06D',64208:'\uE06E',64209:'\uE06F',64210:'\uE070',64211:'\uE071',64212:'\uE072',64213:'\uE073',64214:'\uE074',64215:'\uE075',64216:'\uE076',64217:'\uE077',64218:'\uE078',64219:'\uE079',64220:'\uE07A',64221:'\uE07B',64222:'\uE07C',64223:'\uE07D',64224:'\uE07E',64225:'\uE07F',64226:'\uE080',64227:'\uE081',64228:'\uE082',64229:'\uE083',64230:'\uE084',64231:'\uE085',64232:'\uE086',64233:'\uE087',64234:'\uE088',64235:'\uE089',64236:'\uE08A',64237:'\uE08B',64238:'\uE08C',64239:'\uE08D',64240:'\uE08E',64241:'\uE08F',64242:'\uE090',64243:'\uE091',64244:'\uE092',64245:'\uE093',64246:'\uE094',64247:'\uE095',64248:'\uE096',64249:'\uE097',64250:'\uE098',64251:'\uE099',64252:'\uE09A',64253:'\uE09B',64254:'\uE09C',64320:'\uE09D',64321:'\uE09E',64322:'\uE09F',64323:'\uE0A0',64324:'\uE0A1',64325:'\uE0A2',64326:'\uE0A3',64327:'\uE0A4',64328:'\uE0A5',64329:'\uE0A6',64330:'\uE0A7',64331:'\uE0A8',64332:'\uE0A9',64333:'\uE0AA',64334:'\uE0AB',64335:'\uE0AC',64336:'\uE0AD',64337:'\uE0AE',64338:'\uE0AF',64339:'\uE0B0',64340:'\uE0B1',64341:'\uE0B2',64342:'\uE0B3',64343:'\uE0B4',64344:'\uE0B5',64345:'\uE0B6',64346:'\uE0B7',64347:'\uE0B8',64348:'\uE0B9',64349:'\uE0BA',64350:'\uE0BB',64351:'\uE0BC',64352:'\uE0BD',64353:'\uE0BE',64354:'\uE0BF',64355:'\uE0C0',64356:'\uE0C1',64357:'\uE0C2',64358:'\uE0C3',64359:'\uE0C4',64360:'\uE0C5',64361:'\uE0C6',64362:'\uE0C7',64363:'\uE0C8',64364:'\uE0C9',64365:'\uE0CA',64366:'\uE0CB',64367:'\uE0CC',64368:'\uE0CD',64369:'\uE0CE',64370:'\uE0CF',64371:'\uE0D0',64372:'\uE0D1',64373:'\uE0D2',64374:'\uE0D3',64375:'\uE0D4',64376:'\uE0D5',64377:'\uE0D6',64378:'\uE0D7',64379:'\uE0D8',64380:'\uE0D9',64381:'\uE0DA',64382:'\uE0DB',64417:'\uE0DC',64418:'\uE0DD',64419:'\uE0DE',64420:'\uE0DF',64421:'\uE0E0',64422:'\uE0E1',64423:'\uE0E2',64424:'\uE0E3',64425:'\uE0E4',64426:'\uE0E5',64427:'\uE0E6',64428:'\uE0E7',64429:'\uE0E8',64430:'\uE0E9',64431:'\uE0EA',64432:'\uE0EB',64433:'\uE0EC',64434:'\uE0ED',64435:'\uE0EE',64436:'\uE0EF',64437:'\uE0F0',64438:'\uE0F1',64439:'\uE0F2',64440:'\uE0F3',64441:'\uE0F4',64442:'\uE0F5',64443:'\uE0F6',64444:'\uE0F7',64445:'\uE0F8',64446:'\uE0F9',64447:'\uE0FA',64448:'\uE0FB',64449:'\uE0FC',64450:'\uE0FD',64451:'\uE0FE',64452:'\uE0FF',64453:'\uE100',64454:'\uE101',64455:'\uE102',64456:'\uE103',64457:'\uE104',64458:'\uE105',64459:'\uE106',64460:'\uE107',64461:'\uE108',64462:'\uE109',64463:'\uE10A',64464:'\uE10B',64465:'\uE10C',64466:'\uE10D',64467:'\uE10E',64468:'\uE10F',64469:'\uE110',64470:'\uE111',64471:'\uE112',64472:'\uE113',64473:'\uE114',64474:'\uE115',64475:'\uE116',64476:'\uE117',64477:'\uE118',64478:'\uE119',64479:'\uE11A',64480:'\uE11B',64481:'\uE11C',64482:'\uE11D',64483:'\uE11E',64484:'\uE11F',64485:'\uE120',64486:'\uE121',64487:'\uE122',64488:'\uE123',64489:'\uE124',64490:'\uE125',64491:'\uE126',64492:'\uE127',64493:'\uE128',64494:'\uE129',64495:'\uE12A',64496:'\uE12B',64497:'\uE12C',64498:'\uE12D',64499:'\uE12E',64500:'\uE12F',64501:'\uE130',64502:'\uE131',64503:'\uE132',64504:'\uE133',64505:'\uE134',64506:'\uE135',64507:'\uE136',64508:'\uE137',64509:'\uE138',64510:'\uE139',64576:'\uE13A',64577:'\uE13B',64578:'\uE13C',64579:'\uE13D',64580:'\uE13E',64581:'\uE13F',64582:'\uE140',64583:'\uE141',64584:'\uE142',64585:'\uE143',64586:'\uE144',64587:'\uE145',64588:'\uE146',64589:'\uE147',64590:'\uE148',64591:'\uE149',64592:'\uE14A',64593:'\uE14B',64594:'\uE14C',64595:'\uE14D',64596:'\uE14E',64597:'\uE14F',64598:'\uE150',64599:'\uE151',64600:'\uE152',64601:'\uE153',64602:'\uE154',64603:'\uE155',64604:'\uE156',64605:'\uE157',64606:'\uE158',64607:'\uE159',64608:'\uE15A',64609:'\uE15B',64610:'\uE15C',64611:'\uE15D',64612:'\uE15E',64613:'\uE15F',64614:'\uE160',64615:'\uE161',64616:'\uE162',64617:'\uE163',64618:'\uE164',64619:'\uE165',64620:'\uE166',64621:'\uE167',64622:'\uE168',64623:'\uE169',64624:'\uE16A',64625:'\uE16B',64626:'\uE16C',64627:'\uE16D',64628:'\uE16E',64629:'\uE16F',64630:'\uE170',64631:'\uE171',64632:'\uE172',64633:'\uE173',64634:'\uE174',64635:'\uE175',64636:'\uE176',64637:'\uE177',64638:'\uE178',64673:'\uE179',64674:'\uE17A',64675:'\uE17B',64676:'\uE17C',64677:'\uE17D',64678:'\uE17E',64679:'\uE17F',64680:'\uE180',64681:'\uE181',64682:'\uE182',64683:'\uE183',64684:'\uE184',64685:'\uE185',64686:'\uE186',64687:'\uE187',64688:'\uE188',64689:'\uE189',64690:'\uE18A',64691:'\uE18B',64692:'\uE18C',64693:'\uE18D',64694:'\uE18E',64695:'\uE18F',64696:'\uE190',64697:'\uE191',64698:'\uE192',64699:'\uE193',64700:'\uE194',64701:'\uE195',64702:'\uE196',64703:'\uE197',64704:'\uE198',64705:'\uE199',64706:'\uE19A',64707:'\uE19B',64708:'\uE19C',64709:'\uE19D',64710:'\uE19E',64711:'\uE19F',64712:'\uE1A0',64713:'\uE1A1',64714:'\uE1A2',64715:'\uE1A3',64716:'\uE1A4',64717:'\uE1A5',64718:'\uE1A6',64719:'\uE1A7',64720:'\uE1A8',64721:'\uE1A9',64722:'\uE1AA',64723:'\uE1AB',64724:'\uE1AC',64725:'\uE1AD',64726:'\uE1AE',64727:'\uE1AF',64728:'\uE1B0',64729:'\uE1B1',64730:'\uE1B2',64731:'\uE1B3',64732:'\uE1B4',64733:'\uE1B5',64734:'\uE1B6',64735:'\uE1B7',64736:'\uE1B8',64737:'\uE1B9',64738:'\uE1BA',64739:'\uE1BB',64740:'\uE1BC',64741:'\uE1BD',64742:'\uE1BE',64743:'\uE1BF',64744:'\uE1C0',64745:'\uE1C1',64746:'\uE1C2',64747:'\uE1C3',64748:'\uE1C4',64749:'\uE1C5',64750:'\uE1C6',64751:'\uE1C7',64752:'\uE1C8',64753:'\uE1C9',64754:'\uE1CA',64755:'\uE1CB',64756:'\uE1CC',64757:'\uE1CD',64758:'\uE1CE',64759:'\uE1CF',64760:'\uE1D0',64761:'\uE1D1',64762:'\uE1D2',64763:'\uE1D3',64764:'\uE1D4',64765:'\uE1D5',64766:'\uE1D6',64832:'\uE1D7',64833:'\uE1D8',64834:'\uE1D9',64835:'\uE1DA',64836:'\uE1DB',64837:'\uE1DC',64838:'\uE1DD',64839:'\uE1DE',64840:'\uE1DF',64841:'\uE1E0',64842:'\uE1E1',64843:'\uE1E2',64844:'\uE1E3',64845:'\uE1E4',64846:'\uE1E5',64847:'\uE1E6',64848:'\uE1E7',64849:'\uE1E8',64850:'\uE1E9',64851:'\uE1EA',64852:'\uE1EB',64853:'\uE1EC',64854:'\uE1ED',64855:'\uE1EE',64856:'\uE1EF',64857:'\uE1F0',64858:'\uE1F1',64859:'\uE1F2',64860:'\uE1F3',64861:'\uE1F4',64862:'\uE1F5',64863:'\uE1F6',64864:'\uE1F7',64865:'\uE1F8',64866:'\uE1F9',64867:'\uE1FA',64868:'\uE1FB',64869:'\uE1FC',64870:'\uE1FD',64871:'\uE1FE',64872:'\uE1FF',64873:'\uE200',64874:'\uE201',64875:'\uE202',64876:'\uE203',64877:'\uE204',64878:'\uE205',64879:'\uE206',64880:'\uE207',64881:'\uE208',64882:'\uE209',64883:'\uE20A',64884:'\uE20B',64885:'\uE20C',64886:'\uE20D',64887:'\uE20E',64888:'\uE20F',64889:'\uE210',64890:'\uE211',64891:'\uE212',64892:'\uE213',64893:'\uE214',64894:'\uE215',64929:'\uE216',64930:'\uE217',64931:'\uE218',64932:'\uE219',64933:'\uE21A',64934:'\uE21B',64935:'\uE21C',64936:'\uE21D',64937:'\uE21E',64938:'\uE21F',64939:'\uE220',64940:'\uE221',64941:'\uE222',64942:'\uE223',64943:'\uE224',64944:'\uE225',64945:'\uE226',64946:'\uE227',64947:'\uE228',64948:'\uE229',64949:'\uE22A',64950:'\uE22B',64951:'\uE22C',64952:'\uE22D',64953:'\uE22E',64954:'\uE22F',64955:'\uE230',64956:'\uE231',64957:'\uE232',64958:'\uE233',64959:'\uE234',64960:'\uE235',64961:'\uE236',64962:'\uE237',64963:'\uE238',64964:'\uE239',64965:'\uE23A',64966:'\uE23B',64967:'\uE23C',64968:'\uE23D',64969:'\uE23E',64970:'\uE23F',64971:'\uE240',64972:'\uE241',64973:'\uE242',64974:'\uE243',64975:'\uE244',64976:'\uE245',64977:'\uE246',64978:'\uE247',64979:'\uE248',64980:'\uE249',64981:'\uE24A',64982:'\uE24B',64983:'\uE24C',64984:'\uE24D',64985:'\uE24E',64986:'\uE24F',64987:'\uE250',64988:'\uE251',64989:'\uE252',64990:'\uE253',64991:'\uE254',64992:'\uE255',64993:'\uE256',64994:'\uE257',64995:'\uE258',64996:'\uE259',64997:'\uE25A',64998:'\uE25B',64999:'\uE25C',65000:'\uE25D',65001:'\uE25E',65002:'\uE25F',65003:'\uE260',65004:'\uE261',65005:'\uE262',65006:'\uE263',65007:'\uE264',65008:'\uE265',65009:'\uE266',65010:'\uE267',65011:'\uE268',65012:'\uE269',65013:'\uE26A',65014:'\uE26B',65015:'\uE26C',65016:'\uE26D',65017:'\uE26E',65018:'\uE26F',65019:'\uE270',65020:'\uE271',65021:'\uE272',65022:'\uE273',65088:'\uE274',65089:'\uE275',65090:'\uE276',65091:'\uE277',65092:'\uE278',65093:'\uE279',65094:'\uE27A',65095:'\uE27B',65096:'\uE27C',65097:'\uE27D',65098:'\uE27E',65099:'\uE27F',65100:'\uE280',65101:'\uE281',65102:'\uE282',65103:'\uE283',65104:'\uE284',65105:'\uE285',65106:'\uE286',65107:'\uE287',65108:'\uE288',65109:'\uE289',65110:'\uE28A',65111:'\uE28B',65112:'\uE28C',65113:'\uE28D',65114:'\uE28E',65115:'\uE28F',65116:'\uE290',65117:'\uE291',65118:'\uE292',65119:'\uE293',65120:'\uE294',65121:'\uE295',65122:'\uE296',65123:'\uE297',65124:'\uE298',65125:'\uE299',65126:'\uE29A',65127:'\uE29B',65128:'\uE29C',65129:'\uE29D',65130:'\uE29E',65131:'\uE29F',65132:'\uE2A0',65133:'\uE2A1',65134:'\uE2A2',65135:'\uE2A3',65136:'\uE2A4',65137:'\uE2A5',65138:'\uE2A6',65139:'\uE2A7',65140:'\uE2A8',65141:'\uE2A9',65142:'\uE2AA',65143:'\uE2AB',65144:'\uE2AC',65145:'\uE2AD',65146:'\uE2AE',65147:'\uE2AF',65148:'\uE2B0',65149:'\uE2B1',65150:'\uE2B2',65185:'\uE2B3',65186:'\uE2B4',65187:'\uE2B5',65188:'\uE2B6',65189:'\uE2B7',65190:'\uE2B8',65191:'\uE2B9',65192:'\uE2BA',65193:'\uE2BB',65194:'\uE2BC',65195:'\uE2BD',65196:'\uE2BE',65197:'\uE2BF',65198:'\uE2C0',65199:'\uE2C1',65200:'\uE2C2',65201:'\uE2C3',65202:'\uE2C4',65203:'\uE2C5',65204:'\uE2C6',65205:'\uE2C7',65206:'\uE2C8',65207:'\uE2C9',65208:'\uE2CA',65209:'\uE2CB',65210:'\uE2CC',65211:'\uE2CD',65212:'\uE2CE',65213:'\uE2CF',65214:'\uE2D0',65215:'\uE2D1',65216:'\uE2D2',65217:'\uE2D3',65218:'\uE2D4',65219:'\uE2D5',65220:'\uE2D6',65221:'\uE2D7',65222:'\uE2D8',65223:'\uE2D9',65224:'\uE2DA',65225:'\uE2DB',65226:'\uE2DC',65227:'\uE2DD',65228:'\uE2DE',65229:'\uE2DF',65230:'\uE2E0',65231:'\uE2E1',65232:'\uE2E2',65233:'\uE2E3',65234:'\uE2E4',65235:'\uE2E5',65236:'\uE2E6',65237:'\uE2E7',65238:'\uE2E8',65239:'\uE2E9',65240:'\uE2EA',65241:'\uE2EB',65242:'\uE2EC',65243:'\uE2ED',65244:'\uE2EE',65245:'\uE2EF',65246:'\uE2F0',65247:'\uE2F1',65248:'\uE2F2',65249:'\uE2F3',65250:'\uE2F4',65251:'\uE2F5',65252:'\uE2F6',65253:'\uE2F7',65254:'\uE2F8',65255:'\uE2F9',65256:'\uE2FA',65257:'\uE2FB',65258:'\uE2FC',65259:'\uE2FD',65260:'\uE2FE',65261:'\uE2FF',65262:'\uE300',65263:'\uE301',65264:'\uE302',65265:'\uE303',65266:'\uE304',65267:'\uE305',65268:'\uE306',65269:'\uE307',65270:'\uE308',65271:'\uE309',65272:'\uE30A',65273:'\uE30B',65274:'\uE30C',65275:'\uE30D',65276:'\uE30E',65277:'\uE30F',65278:'\uE310',129:None,130:None,131:None,132:None,133:None,134:None,135:None,136:None,137:None,138:None,139:None,140:None,141:None,142:None,143:None,144:None,145:None,146:None,147:None,148:None,149:None,150:None,151:None,152:None,153:None,154:None,155:None,156:None,157:None,158:None,159:None,160:None,161:None,162:None,163:None,164:None,165:None,166:None,167:None,168:None,169:None,170:None,171:None,172:None,173:None,174:None,175:None,176:None,177:None,178:None,179:None,180:None,181:None,182:None,183:None,184:None,185:None,186:None,187:None,188:None,189:None,190:None,191:None,192:None,193:None,194:None,195:None,196:None,197:None,198:None,199:None,200:None,201:None,202:None,203:None,204:None,205:None,206:None,207:None,208:None,209:None,210:None,211:None,212:None,213:None,214:None,215:None,216:None,217:None,218:None,219:None,220:None,221:None,222:None,223:None,224:None,225:None,226:None,227:None,228:None,229:None,230:None,231:None,232:None,233:None,234:None,235:None,236:None,237:None,238:None,239:None,240:None,241:None,242:None,243:None,244:None,245:None,246:None,247:None,248:None,249:None,250:None,251:None,252:None,253:None,254:None} \ No newline at end of file diff --git a/extract_msg/encoding/utils.py b/extract_msg/encoding/utils.py new file mode 100644 index 00000000..918a04ae --- /dev/null +++ b/extract_msg/encoding/utils.py @@ -0,0 +1,129 @@ +""" +Internal utilities for extract_msg.encoding. +""" + +__all__ = [ + 'variableByteDecode', + 'variableByteEncode', +] + + +import codecs + +from typing import Dict, Tuple + + +def variableByteDecode(codecName : str, data, errors : str, decodeTable : Dict[int, str]) -> Tuple[str, int]: + """ + Function for decoding variable-byte codecs. + + Checks if a character is less than 0x80, mapping it directly if so. + Otherwise, it reads the next byte and combines the two before looking up the + new value. + + :param codecName: The name of the codec, used for error messages. + :param data: A bytes-like object to decode. + :param errors: The error behavior to use. + :param decodeTable: The mapping of values to use. Continuation bytes MUST be + defined in the table, but SHOULD be set to None. This allows for the + function to detect what bytes are valid for continuation. + """ + if len(data) == 0: + return ('', 0) + + errorHandler = codecs.lookup_error(errors) + output = '' + + iterator = enumerate(data) + for start, byte in iterator: + # Variable byte should be an integer here. + if byte < 0x80: + if byte in decodeTable: + output += decodeTable[byte] + else: + err = UnicodeDecodeError(codecName, + data, + start, + start + 1, + 'character maps to ' + ) + rep = errorHandler(err) + output += rep[0] + # Skip the specified number of characters. + for _ in range(rep[1] - start - 1): + iterator.__next__() + elif byte not in decodeTable: + err = UnicodeDecodeError(codecName, + data, + start, + start + 1, + 'invalid start byte' + ) + rep = errorHandler(err) + output += rep[0] + # Skip the specified number of characters. + for _ in range(rep[1] - start - 1): + iterator.__next__() + + else: + try: + byte = (byte << 8) | iterator.__next__()[1] + if byte in decodeTable: + output += decodeTable[byte] + else: + err = UnicodeDecodeError(codecName, + data, + start, + start + 2, + 'character maps to ' + ) + rep = errorHandler(err) + output += rep[0] + # Skip the specified number of characters. + for _ in range(rep[1] - start - 1): + iterator.__next__() + except StopIteration: + err = UnicodeDecodeError(codecName, + data, + start, + start + 1, + 'unexpected end of data' + ) + rep = errorHandler(err) + output += rep[0] + break + # No more data, so that's all that needs to happen. + return (output, start) + + +def variableByteEncode(codecName : str, data, errors : str, encodeTable : Dict[str, int]) -> Tuple[bytes, int]: + """ + Function for decoding variable-byte codecs. + + :param codecName: The name of the codec, used for error messages. + :param data: A bytes-like object to decode. + :param errors: The error behavior to use. + :param encodeTable: The mapping of values to use. + """ + if len(data) == 0: + return + + errorHandler = codecs.lookup_error(errors) + output = b'' + iterator = enumerate(data) + for start, char in iterator: + if char not in encodeTable: + err = UnicodeEncodeError(codecName, + data, + start, + start + 1, + 'illegal multibyte sequence') + rep = errorHandler(err) + output += rep[0] + # Skip the specified number of characters. + for _ in range(rep[1] - start - 1): + iterator.__next__() + else: + data += encodeTable[char] + + return output diff --git a/extract_msg/encoding/win950.py b/extract_msg/encoding/win950.py new file mode 100644 index 00000000..aeb1bee2 --- /dev/null +++ b/extract_msg/encoding/win950.py @@ -0,0 +1,59 @@ +""" +Support for Microsoft's implementation of CP950 (core python has bad support +for it). +""" + +__all__ = [ + 'getregentry', +] + + +# We use a similar format to what I've seen in core Python encoding files. +import codecs + +from .utils import variableByteDecode, variableByteEncode +from ._win950_dec import decodingTable + +### Codec APIs + +class Codec(codecs.Codec): + def encode(self, text, errors='strict'): + return variableByteEncode('windows-950', text, errors, encodingTable) + + def decode(self, data, errors='strict'): + return variableByteDecode('windows-950', data, errors, decodingTable) + +class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, text, final=False): + return variableByteEncode('windows-950', text, self.errors, encodingTable)[0] + +class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, data, final=False): + return variableByteDecode('windows-950', data, self.errors, decodingTable)[0] + +class StreamWriter(Codec, codecs.StreamWriter): + pass + +class StreamReader(Codec, codecs.StreamReader): + pass + +### encodings module API + +def getregentry(): + return codecs.CodecInfo( + name='windows-950', + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) + + +### Encoding table +encodingTable = {value : bytes((key,)) if key < 256 + else bytes((key >> 8, key & 0xFF)) + for key, value in decodingTable.items() + if value is not None + } \ No newline at end of file diff --git a/extract_msg/msg_classes/appointment.py b/extract_msg/msg_classes/appointment.py index 1dcc5cfa..54ea817c 100644 --- a/extract_msg/msg_classes/appointment.py +++ b/extract_msg/msg_classes/appointment.py @@ -28,14 +28,14 @@ def appointmentCounterProposal(self) -> bool: Indicates to the organizer that there are counter proposals that have not been accepted or rejected by the organizer. """ - return self._ensureSetNamed('_appointmentCounterProposal', '8257', constants.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('_appointmentCounterProposal', '8257', constants.ps.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) @property def appointmentLastSequence(self) -> Optional[int]: """ The last sequence number that was sent to any attendee. """ - return self._ensureSetNamed('_appointmentLastSequence', '8203', constants.PSETID_APPOINTMENT) + return self._ensureSetNamed('_appointmentLastSequence', '8203', constants.ps.PSETID_APPOINTMENT) @property def appointmentProposalNumber(self) -> Optional[int]: @@ -43,14 +43,14 @@ def appointmentProposalNumber(self) -> Optional[int]: The number of attendees who have sent counter propostals that have not been accepted or rejected by the organizer. """ - return self._ensureSetNamed('_appointmentProposalNumber', '8259', constants.PSETID_APPOINTMENT) + return self._ensureSetNamed('_appointmentProposalNumber', '8259', constants.ps.PSETID_APPOINTMENT) @property def appointmentReplyName(self) -> Optional[datetime.datetime]: """ The user who last replied to the meeting request or meeting update. """ - return self._ensureSetNamed('_appointmentReplyName', '8230', constants.PSETID_APPOINTMENT) + return self._ensureSetNamed('_appointmentReplyName', '8230', constants.ps.PSETID_APPOINTMENT) @property def appointmentReplyTime(self) -> Optional[datetime.datetime]: @@ -58,7 +58,7 @@ def appointmentReplyTime(self) -> Optional[datetime.datetime]: The date and time at which the attendee responded to a received Meeting Request object of Meeting Update object in UTC. """ - return self._ensureSetNamed('_appointmentReplyTime', '8220', constants.PSETID_APPOINTMENT) + return self._ensureSetNamed('_appointmentReplyTime', '8220', constants.ps.PSETID_APPOINTMENT) @property def appointmentSequenceTime(self) -> Optional[datetime.datetime]: @@ -66,7 +66,7 @@ def appointmentSequenceTime(self) -> Optional[datetime.datetime]: The date and time at which the appointmentSequence property was last modified. """ - return self._ensureSetNamed('_appointmentSequenceTime', '8202', constants.PSETID_APPOINTMENT) + return self._ensureSetNamed('_appointmentSequenceTime', '8202', constants.ps.PSETID_APPOINTMENT) @property def autoFillLocation(self) -> bool: @@ -78,14 +78,14 @@ def autoFillLocation(self) -> bool: A value of False indicates that the value of the location property is not automatically set. """ - return self._ensureSetNamed('_autoFillLocation', '823A', constants.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('_autoFillLocation', '823A', constants.ps.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) @property def fInvited(self) -> bool: """ Whether a Meeting Request object has been sent out. """ - return self._ensureSetNamed('_fInvited', '8229', constants.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('_fInvited', '8229', constants.ps.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) @property def headerFormatProperties(self) -> constants.HEADER_FORMAT_TYPE: @@ -174,4 +174,4 @@ def originalStoreEntryID(self) -> Optional[EntryID]: """ The EntryID of the delegator's message store. """ - return self._ensureSetNamed('_originalStoreEntryID', '8237', constants.PSETID_APPOINTMENT, overrideClass = EntryID.autoCreate) + return self._ensureSetNamed('_originalStoreEntryID', '8237', constants.ps.PSETID_APPOINTMENT, overrideClass = EntryID.autoCreate) diff --git a/extract_msg/msg_classes/calendar.py b/extract_msg/msg_classes/calendar.py index b78f5c9a..3fb1f4dd 100644 --- a/extract_msg/msg_classes/calendar.py +++ b/extract_msg/msg_classes/calendar.py @@ -22,7 +22,7 @@ def clientIntent(self) -> Optional[Set[ClientIntentFlag]]: """ A set of the actions a user has taken on a Meeting object. """ - return self._ensureSetNamed('_clientIntent', '0015', constants.PSETID_CALENDAR_ASSISTANT, overrideClass = ClientIntentFlag.fromBits) + return self._ensureSetNamed('_clientIntent', '0015', constants.ps.PSETID_CALENDAR_ASSISTANT, overrideClass = ClientIntentFlag.fromBits) @property def fExceptionalAttendees(self) -> Optional[bool]: @@ -34,7 +34,7 @@ def fExceptionalAttendees(self) -> Optional[bool]: SHOULD NOT be set for any Calendar object other than that of the organizer's. """ - return self._ensureSetNamed('_fExceptionalAttendees', '822B', constants.PSETID_APPOINTMENT) + return self._ensureSetNamed('_fExceptionalAttendees', '822B', constants.ps.PSETID_APPOINTMENT) @property def reminderDelta(self) -> Optional[int]: @@ -42,7 +42,7 @@ def reminderDelta(self) -> Optional[int]: The interval, in minutes, between the time at which the reminder first becomes overdue and the start time of the Calendar object. """ - return self._ensureSetNamed('_reminderDelta', '8501', constants.PSETID_COMMON) + return self._ensureSetNamed('_reminderDelta', '8501', constants.ps.PSETID_COMMON) @property def reminderFileParameter(self) -> Optional[str]: @@ -51,7 +51,7 @@ def reminderFileParameter(self) -> Optional[str]: client SHOULD play when the reminder for the Message Object becomes overdue. """ - return self._ensureSetNamed('_reminderFileParameter', '851F', constants.PSETID_COMMON) + return self._ensureSetNamed('_reminderFileParameter', '851F', constants.ps.PSETID_COMMON) @property def reminderOverride(self) -> bool: @@ -59,7 +59,7 @@ def reminderOverride(self) -> bool: Specifies if clients SHOULD respect the value of the reminderPlaySound property and the reminderFileParameter property. """ - return self._ensureSetNamed('_reminderOverride', '851C', constants.PSETID_COMMON, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('_reminderOverride', '851C', constants.ps.PSETID_COMMON, overrideClass = bool, preserveNone = False) @property def reminderPlaySound(self) -> bool: @@ -67,25 +67,25 @@ def reminderPlaySound(self) -> bool: Specified that the cliebnt should play a sound when the reminder becomes overdue. """ - return self._ensureSetNamed('_reminderPlaySound', '851E', constants.PSETID_COMMON, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('_reminderPlaySound', '851E', constants.ps.PSETID_COMMON, overrideClass = bool, preserveNone = False) @property def reminderSet(self) -> bool: """ Specifies whether a reminder is set on the object. """ - return self._ensureSetNamed('_reminderSet', '8503', constants.PSETID_COMMON, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('_reminderSet', '8503', constants.ps.PSETID_COMMON, overrideClass = bool, preserveNone = False) @property def reminderSignalTime(self) -> Optional[datetime.datetime]: """ The point in time when a reminder transitions from pending to overdue. """ - return self._ensureSetNamed('_reminderSignalTime', '8560', constants.PSETID_COMMON) + return self._ensureSetNamed('_reminderSignalTime', '8560', constants.ps.PSETID_COMMON) @property def reminderTime(self) -> Optional[datetime.datetime]: """ The time after which the user would be late. """ - return self._ensureSetNamed('_reminderTime', '8502', constants.PSETID_COMMON) + return self._ensureSetNamed('_reminderTime', '8502', constants.ps.PSETID_COMMON) diff --git a/extract_msg/msg_classes/calendar_base.py b/extract_msg/msg_classes/calendar_base.py index 9e369be0..fc97c8b1 100644 --- a/extract_msg/msg_classes/calendar_base.py +++ b/extract_msg/msg_classes/calendar_base.py @@ -78,35 +78,35 @@ def allAttendeesString(self) -> Optional[str]: """ A list of all attendees, excluding the organizer. """ - return self._ensureSetNamed('_allAttendeesString', '8238', constants.PSETID_APPOINTMENT) + return self._ensureSetNamed('_allAttendeesString', '8238', constants.ps.PSETID_APPOINTMENT) @property def appointmentAuxilaryFlags(self) -> Optional[Set[AppointmentAuxilaryFlag]]: """ The auxiliary state of the object. """ - return self._ensureSetNamed('_appointmentAuxilaryFlags', '8207', constants.PSETID_APPOINTMENT, overrideClass = AppointmentAuxilaryFlag.fromBits) + return self._ensureSetNamed('_appointmentAuxilaryFlags', '8207', constants.ps.PSETID_APPOINTMENT, overrideClass = AppointmentAuxilaryFlag.fromBits) @property def appointmentColor(self) -> Optional[AppointmentColor]: """ The color to be used when displaying a Calendar object. """ - return self._ensureSetNamed('_appointmentColor', '8214', constants.PSETID_APPOINTMENT, overrideClass = AppointmentColor) + return self._ensureSetNamed('_appointmentColor', '8214', constants.ps.PSETID_APPOINTMENT, overrideClass = AppointmentColor) @property def appointmentDuration(self) -> Optional[int]: """ The length of the event, in minutes. """ - return self._ensureSetNamed('_appointmentDuration', '8213', constants.PSETID_APPOINTMENT) + return self._ensureSetNamed('_appointmentDuration', '8213', constants.ps.PSETID_APPOINTMENT) @property def appointmentEndWhole(self) -> Optional[datetime.datetime]: """ The end date and time of the event in UTC. """ - return self._ensureSetNamed('_appointmentEndWhole', '820E', constants.PSETID_APPOINTMENT) + return self._ensureSetNamed('_appointmentEndWhole', '820E', constants.ps.PSETID_APPOINTMENT) @property def appointmentNotAllowPropose(self) -> bool: @@ -114,7 +114,7 @@ def appointmentNotAllowPropose(self) -> bool: Indicates that attendees are not allowed to propose a new date and/or time for the meeting if True. """ - return self._ensureSetNamed('_appointmentNotAllowPropose', '8259', constants.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('_appointmentNotAllowPropose', '8259', constants.ps.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) @property def appointmentRecur(self) -> Optional[RecurrencePattern]: @@ -122,7 +122,7 @@ def appointmentRecur(self) -> Optional[RecurrencePattern]: Specifies the dates and times when a recurring series occurs by using one of the recurrence patterns and ranges specified in this section. """ - return self._ensureSetNamed('_appointmentRecur', '8216', constants.PSETID_APPOINTMENT, overrideClass = RecurrencePattern) + return self._ensureSetNamed('_appointmentRecur', '8216', constants.ps.PSETID_APPOINTMENT, overrideClass = RecurrencePattern) @property def appointmentSequence(self) -> Optional[int]: @@ -131,28 +131,28 @@ def appointmentSequence(self) -> Optional[int]: begins with the sequence number set to 0 and is incremented each time the organizer sends out a Meeting Update object. """ - return self._ensureSetNamed('_appointmentSequence', '8201', constants.PSETID_APPOINTMENT) + return self._ensureSetNamed('_appointmentSequence', '8201', constants.ps.PSETID_APPOINTMENT) @property def appointmentStartWhole(self) -> Optional[datetime.datetime]: """ The start date and time of the event in UTC. """ - return self._ensureSetNamed('_appointmentStartWhole', '820D', constants.PSETID_APPOINTMENT) + return self._ensureSetNamed('_appointmentStartWhole', '820D', constants.ps.PSETID_APPOINTMENT) @property def appointmentStateFlags(self) -> Optional[Set[AppointmentStateFlag]]: """ The appointment state of the object. """ - return self._ensureSetNamed('_appointmentStateFlags', '8217', constants.PSETID_APPOINTMENT, overrideClass = AppointmentStateFlag.fromBits) + return self._ensureSetNamed('_appointmentStateFlags', '8217', constants.ps.PSETID_APPOINTMENT, overrideClass = AppointmentStateFlag.fromBits) @property def appointmentSubType(self) -> bool: """ Whether the event is an all-day event or not. """ - return self._ensureSetNamed('_appointmentSubType', '8215', constants.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('_appointmentSubType', '8215', constants.ps.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) @property def appointmentTimeZoneDefinitionEndDisplay(self) -> Optional[TimeZoneDefinition]: @@ -160,7 +160,7 @@ def appointmentTimeZoneDefinitionEndDisplay(self) -> Optional[TimeZoneDefinition Specifies the time zone information for the appointmentEndWhole property Used to convert the end date and time to and from UTC. """ - return self._ensureSetNamed('_appointmentTimeZoneDefinitionEndDisplay', '825F', constants.PSETID_APPOINTMENT, overrideClass = TimeZoneDefinition) + return self._ensureSetNamed('_appointmentTimeZoneDefinitionEndDisplay', '825F', constants.ps.PSETID_APPOINTMENT, overrideClass = TimeZoneDefinition) @property def appointmentTimeZoneDefinitionRecur(self) -> Optional[TimeZoneDefinition]: @@ -168,7 +168,7 @@ def appointmentTimeZoneDefinitionRecur(self) -> Optional[TimeZoneDefinition]: Specified the time zone information that specifies how to convert the meeting date and time on a recurring series to and from UTC. """ - return self._ensureSetNamed('_appointmentTimeZoneDefinitionRecur', '8260', constants.PSETID_APPOINTMENT, overrideClass = TimeZoneDefinition) + return self._ensureSetNamed('_appointmentTimeZoneDefinitionRecur', '8260', constants.ps.PSETID_APPOINTMENT, overrideClass = TimeZoneDefinition) @property def appointmentTimeZoneDefinitionStartDisplay(self) -> Optional[TimeZoneDefinition]: @@ -176,7 +176,7 @@ def appointmentTimeZoneDefinitionStartDisplay(self) -> Optional[TimeZoneDefiniti Specifies the time zone information for the appointmentStartWhole property. Used to convert the start date and time to and from UTC. """ - return self._ensureSetNamed('_appointmentTimeZoneDefinitionStartDisplay', '825E', constants.PSETID_APPOINTMENT, overrideClass = TimeZoneDefinition) + return self._ensureSetNamed('_appointmentTimeZoneDefinitionStartDisplay', '825E', constants.ps.PSETID_APPOINTMENT, overrideClass = TimeZoneDefinition) @property def appointmentUnsendableRecipients(self) -> Optional[bytes]: @@ -187,7 +187,7 @@ def appointmentUnsendableRecipients(self) -> Optional[bytes]: the specifications. If you have examples, let me know and I can ask you to run a verification on it. """ - return self._ensureSetNamed('_appointmentUnsendableRecipients', '825D', constants.PSETID_APPOINTMENT) + return self._ensureSetNamed('_appointmentUnsendableRecipients', '825D', constants.ps.PSETID_APPOINTMENT) @property def bcc(self) -> Optional[str]: @@ -201,14 +201,14 @@ def birthdayContactAttributionDisplayName(self) -> Optional[str]: """ Indicated the name of the contact associated with the birthday event. """ - return self._ensureSetNamed('_birthdayContactAttributionDisplayName', 'BirthdayContactAttributionDisplayName', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_birthdayContactAttributionDisplayName', 'BirthdayContactAttributionDisplayName', constants.ps.PSETID_ADDRESS) @property def birthdayContactEntryID(self) -> Optional[EntryID]: """ Indicates the EntryID of the contact associated with the birthday event. """ - return self._ensureSetNamed('_birthdayContactEntryID', 'BirthdayContactEntryId', constants.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) + return self._ensureSetNamed('_birthdayContactEntryID', 'BirthdayContactEntryId', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) @property def birthdayContactPersonGuid(self) -> Optional[bytes]: @@ -216,7 +216,7 @@ def birthdayContactPersonGuid(self) -> Optional[bytes]: Indicates the person ID's GUID of the contact associated with the birthday event. """ - return self._ensureSetNamed('_birthdayContactPersonGuid', 'BirthdayContactPersonGuid', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_birthdayContactPersonGuid', 'BirthdayContactPersonGuid', constants.ps.PSETID_ADDRESS) @property def busyStatus(self) -> Optional[BusyStatus]: @@ -224,7 +224,7 @@ def busyStatus(self) -> Optional[BusyStatus]: Specified the availability of a user for the event described by the object. """ - return self._ensureSetNamed('_busyStatus', '8205', constants.PSETID_APPOINTMENT, overrideClass = BusyStatus) + return self._ensureSetNamed('_busyStatus', '8205', constants.ps.PSETID_APPOINTMENT, overrideClass = BusyStatus) @property def cc(self) -> Optional[str]: @@ -238,7 +238,7 @@ def ccAttendeesString(self) -> Optional[str]: """ A list of all the sendable attendees, who are also optional attendees. """ - return self._ensureSetNamed('_ccAttendeesString', '823C', constants.PSETID_APPOINTMENT) + return self._ensureSetNamed('_ccAttendeesString', '823C', constants.ps.PSETID_APPOINTMENT) @property def cleanGlobalObjectID(self) -> Optional[GlobalObjectID]: @@ -247,7 +247,7 @@ def cleanGlobalObjectID(self) -> Optional[GlobalObjectID]: an Exception object to a recurring series, where the year, month, and day fields are all 0. """ - return self._ensureSetNamed('_cleanGlobalObjectID', '0023', constants.PSETID_MEETING, overrideClass = GlobalObjectID) + return self._ensureSetNamed('_cleanGlobalObjectID', '0023', constants.ps.PSETID_MEETING, overrideClass = GlobalObjectID) @property def clipEnd(self) -> Optional[datetime.datetime]: @@ -260,7 +260,7 @@ def clipEnd(self) -> Optional[datetime.datetime]: Honestly, not sure what this is. [MS-OXOCAL]: PidLidClipEnd. """ - return self._ensureSetNamed('_clipEnd', '8236', constants.PSETID_APPOINTMENT) + return self._ensureSetNamed('_clipEnd', '8236', constants.ps.PSETID_APPOINTMENT) @property def clipStart(self) -> Optional[datetime.datetime]: @@ -271,14 +271,14 @@ def clipStart(self) -> Optional[datetime.datetime]: Honestly, not sure what this is. [MS-OXOCAL]: PidLidClipStart. """ - return self._ensureSetNamed('_clipStart', '8235', constants.PSETID_APPOINTMENT) + return self._ensureSetNamed('_clipStart', '8235', constants.ps.PSETID_APPOINTMENT) @property def commonEnd(self) -> Optional[datetime.datetime]: """ The end date and time of an event. MUST be equal to appointmentEndWhole. """ - return self._ensureSetNamed('_commonEnd', '8517', constants.PSETID_COMMON) + return self._ensureSetNamed('_commonEnd', '8517', constants.ps.PSETID_COMMON) @property def commonStart(self) -> Optional[datetime.datetime]: @@ -286,7 +286,7 @@ def commonStart(self) -> Optional[datetime.datetime]: The start date and time of an event. MUST be equal to appointmentStartWhole. """ - return self._ensureSetNamed('_commonStart', '8516', constants.PSETID_COMMON) + return self._ensureSetNamed('_commonStart', '8516', constants.ps.PSETID_COMMON) @property def endDate(self) -> Optional[datetime.datetime]: @@ -300,7 +300,7 @@ def globalObjectID(self) -> Optional[GlobalObjectID]: """ The unique identifier or the Calendar object. """ - return self._ensureSetNamed('_globalObjectID', '0003', constants.PSETID_MEETING, overrideClass = GlobalObjectID) + return self._ensureSetNamed('_globalObjectID', '0003', constants.ps.PSETID_MEETING, overrideClass = GlobalObjectID) @property def iconIndex(self) -> Optional[Union[IconIndex, int]]: @@ -315,7 +315,7 @@ def isBirthdayContactWritable(self) -> bool: Indicates whether the contact associated with the birthday event is writable. """ - return self._ensureSetNamed('_isBirthdayContactWritable', 'IsBirthdayContactWritable', constants.PSETID_ADDRESS, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('_isBirthdayContactWritable', 'IsBirthdayContactWritable', constants.ps.PSETID_ADDRESS, overrideClass = bool, preserveNone = False) @property def isException(self) -> bool: @@ -323,14 +323,14 @@ def isException(self) -> bool: Whether the object represents an exception. False indicates that the object represents a recurring series or a single-instance object. """ - return self._ensureSetNamed('_isException', '000A', constants.PSETID_MEETING, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('_isException', '000A', constants.ps.PSETID_MEETING, overrideClass = bool, preserveNone = False) @property def isRecurring(self) -> bool: """ Whether the object is associated with a recurring series. """ - return self._ensureSetNamed('_isRecurring', '0005', constants.PSETID_MEETING, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('_isRecurring', '0005', constants.ps.PSETID_MEETING, overrideClass = bool, preserveNone = False) @property def keywords(self) -> Optional[List[str]]: @@ -345,21 +345,21 @@ def linkedTaskItems(self) -> Optional[Tuple[EntryID]]: A list of PidTagEntryId properties of Task objects related to the Calendar object that are set by a client. """ - return self._ensureSetNamed('_linkedTaskItems', '820C', constants.PSETID_APPOINTMENT, overrideClass = lambda x : tuple(EntryID.autoCreate(y) for y in x)) + return self._ensureSetNamed('_linkedTaskItems', '820C', constants.ps.PSETID_APPOINTMENT, overrideClass = lambda x : tuple(EntryID.autoCreate(y) for y in x)) @property def location(self) -> Optional[str]: """ Returns the location of the meeting. """ - return self._ensureSetNamed('_location', '8208', constants.PSETID_APPOINTMENT) + return self._ensureSetNamed('_location', '8208', constants.ps.PSETID_APPOINTMENT) @property def meetingDoNotForward(self) -> bool: """ Whether to allow the meeting to be forwarded. True disallows forwarding. """ - return self._ensureSetNamed('_meetingDoNotForward', 'DoNotForward', constants.PS_PUBLIC_STRINGS, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('_meetingDoNotForward', 'DoNotForward', constants.ps.PS_PUBLIC_STRINGS, overrideClass = bool, preserveNone = False) @property def meetingWorkspaceUrl(self) -> Optional[str]: @@ -367,56 +367,56 @@ def meetingWorkspaceUrl(self) -> Optional[str]: The URL of the Meeting Workspace, as specified in [MS-MEETS], that is associated with a Calendar object. """ - return self._ensureSetNamed('_meetingWorkspaceUrl', '8209', constants.PSETID_APPOINTMENT) + return self._ensureSetNamed('_meetingWorkspaceUrl', '8209', constants.ps.PSETID_APPOINTMENT) @property def nonSendableBcc(self) -> Optional[str]: """ A list of all unsendable attendees who are also resource objects. """ - return self._ensureSetNamed('_nonSendableBcc', '8538', constants.PSETID_COMMON) + return self._ensureSetNamed('_nonSendableBcc', '8538', constants.ps.PSETID_COMMON) @property def nonSendableCc(self) -> Optional[str]: """ A list of all unsendable attendees who are also optional attendees. """ - return self._ensureSetNamed('_nonSendableCc', '8537', constants.PSETID_COMMON) + return self._ensureSetNamed('_nonSendableCc', '8537', constants.ps.PSETID_COMMON) @property def nonSendableTo(self) -> Optional[str]: """ A list of all unsendable attendees who are also required attendees. """ - return self._ensureSetNamed('_nonSendableTo', '8536', constants.PSETID_COMMON) + return self._ensureSetNamed('_nonSendableTo', '8536', constants.ps.PSETID_COMMON) @property def nonSendBccTrackStatus(self) -> Optional[List[ResponseStatus]]: """ A ResponseStatus for each of the attendees in nonSendableBcc. """ - return self._ensureSetNamed('_nonSendBccTrackStatus', '8545', constants.PSETID_COMMON, overrideClass = (lambda x : (ResponseStatus(y) for y in x))) + return self._ensureSetNamed('_nonSendBccTrackStatus', '8545', constants.ps.PSETID_COMMON, overrideClass = (lambda x : (ResponseStatus(y) for y in x))) @property def nonSendCcTrackStatus(self) -> Optional[List[ResponseStatus]]: """ A ResponseStatus for each of the attendees in nonSendableCc. """ - return self._ensureSetNamed('_nonSendCcTrackStatus', '8544', constants.PSETID_COMMON, overrideClass = (lambda x : (ResponseStatus(y) for y in x))) + return self._ensureSetNamed('_nonSendCcTrackStatus', '8544', constants.ps.PSETID_COMMON, overrideClass = (lambda x : (ResponseStatus(y) for y in x))) @property def nonSendToTrackStatus(self) -> Optional[List[ResponseStatus]]: """ A ResponseStatus for each of the attendees in nonSendableTo. """ - return self._ensureSetNamed('_nonSendToTrackStatus', '8543', constants.PSETID_COMMON, overrideClass = (lambda x : (ResponseStatus(y) for y in x))) + return self._ensureSetNamed('_nonSendToTrackStatus', '8543', constants.ps.PSETID_COMMON, overrideClass = (lambda x : (ResponseStatus(y) for y in x))) @property def optionalAttendees(self) -> Optional[str]: """ Returns the optional attendees of the meeting. """ - return self._ensureSetNamed('_optionalAttendees', '0007', constants.PSETID_MEETING) + return self._ensureSetNamed('_optionalAttendees', '0007', constants.ps.PSETID_MEETING) @property def organizer(self) -> Optional[str]: @@ -440,7 +440,7 @@ def ownerCriticalChange(self) -> Optional[datetime.datetime]: The date and time at which a Meeting Request object was sent by the organizer, in UTC. """ - return self._ensureSetNamed('_ownerCriticalChange', '001A', constants.PSETID_MEETING) + return self._ensureSetNamed('_ownerCriticalChange', '001A', constants.ps.PSETID_MEETING) @property def recurrencePattern(self) -> Optional[str]: @@ -448,14 +448,14 @@ def recurrencePattern(self) -> Optional[str]: A description of the recurrence specified by the appointmentRecur property. """ - return self._ensureSetNamed('_recurrencePattern', '8232', constants.PSETID_APPOINTMENT) + return self._ensureSetNamed('_recurrencePattern', '8232', constants.ps.PSETID_APPOINTMENT) @property def recurring(self) -> bool: """ Specifies whether the object represents a recurring series. """ - return self._ensureSetNamed('_recurring', '8223', constants.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = True) + return self._ensureSetNamed('_recurring', '8223', constants.ps.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = True) @property def replyRequested(self) -> bool: @@ -469,14 +469,14 @@ def requiredAttendees(self) -> Optional[str]: """ Returns the required attendees of the meeting. """ - return self._ensureSetNamed('_requiredAttendees', '0006', constants.PSETID_MEETING) + return self._ensureSetNamed('_requiredAttendees', '0006', constants.ps.PSETID_MEETING) @property def resourceAttendees(self) -> Optional[str]: """ Returns the resource attendees of the meeting. """ - return self._ensureSetNamed('_resourceAttendees', '0008', constants.PSETID_MEETING) + return self._ensureSetNamed('_resourceAttendees', '0008', constants.ps.PSETID_MEETING) @property def responseRequested(self) -> bool: @@ -490,7 +490,7 @@ def responseStatus(self) -> ResponseStatus: """ The response status of an attendee. """ - return self._ensureSetNamed('_responseStatus', '8218', constants.PSETID_APPOINTMENT, overrideClass = lambda x: ResponseStatus(x or 0), preserveNone = False) + return self._ensureSetNamed('_responseStatus', '8218', constants.ps.PSETID_APPOINTMENT, overrideClass = lambda x: ResponseStatus(x or 0), preserveNone = False) @property def startDate(self) -> Optional[datetime.datetime]: @@ -505,7 +505,7 @@ def timeZoneDescription(self) -> Optional[str]: A human-readable description of the time zone that is represented by the data in the timeZoneStruct property. """ - return self._ensureSetNamed('_timeZoneDescription', '8234', constants.PSETID_APPOINTMENT) + return self._ensureSetNamed('_timeZoneDescription', '8234', constants.ps.PSETID_APPOINTMENT) @property def timeZoneStruct(self) -> Optional[TimeZoneStruct]: @@ -513,7 +513,7 @@ def timeZoneStruct(self) -> Optional[TimeZoneStruct]: Set on a recurring series to specify time zone information. Specifies how to convert time fields between local time and UTC. """ - return self._ensureSetNamed('_timeZoneStruct', '8233', constants.PSETID_APPOINTMENT, overrideClass = TimeZoneStruct) + return self._ensureSetNamed('_timeZoneStruct', '8233', constants.ps.PSETID_APPOINTMENT, overrideClass = TimeZoneStruct) @property def to(self) -> Optional[str]: @@ -527,4 +527,4 @@ def toAttendeesString(self) -> Optional[str]: """ A list of all the sendable attendees, who are also required attendees. """ - return self._ensureSetNamed('_toAttendeesString', '823B', constants.PSETID_APPOINTMENT) + return self._ensureSetNamed('_toAttendeesString', '823B', constants.ps.PSETID_APPOINTMENT) diff --git a/extract_msg/msg_classes/contact.py b/extract_msg/msg_classes/contact.py index f46a77d6..5d7435bd 100644 --- a/extract_msg/msg_classes/contact.py +++ b/extract_msg/msg_classes/contact.py @@ -69,14 +69,14 @@ def addressBookProviderArrayType(self) -> Optional[Set[ElectronicAddressProperti Property is stored in the MSG file as a sinlge int. The result should be identical to addressBookProviderEmailList. """ - return self._ensureSetNamed('_addressBookProviderArrayType', '8029', constants.PSETID_ADDRESS, ElectronicAddressProperties.fromBits) + return self._ensureSetNamed('_addressBookProviderArrayType', '8029', constants.ps.PSETID_ADDRESS, ElectronicAddressProperties.fromBits) @property def addressBookProviderEmailList(self) -> Optional[Set[ElectronicAddressProperties]]: """ A set of which Electronic Address properties are set on the contact. """ - return self._ensureSetNamed('_addressBookProviderEmailList', '8028', constants.PSETID_ADDRESS, overrideClass = lambda x : {ElectronicAddressProperties(y) for y in x}) + return self._ensureSetNamed('_addressBookProviderEmailList', '8028', constants.ps.PSETID_ADDRESS, overrideClass = lambda x : {ElectronicAddressProperties(y) for y in x}) @property def assistant(self) -> Optional[str]: @@ -98,14 +98,14 @@ def autoLog(self) -> bool: Whether the client should create a Journal object for each action associated with the Contact object. """ - return self._ensureSetNamed('_autoLog', '8025', constants.PSETID_ADDRESS, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('_autoLog', '8025', constants.ps.PSETID_ADDRESS, overrideClass = bool, preserveNone = False) @property def billing(self) -> Optional[str]: """ Billing information for the contact. """ - return self._ensureSetNamed('_billing', '8535', constants.PSETID_COMMON) + return self._ensureSetNamed('_billing', '8535', constants.ps.PSETID_COMMON) @property def birthday(self) -> Optional[datetime.datetime]: @@ -120,14 +120,14 @@ def birthdayEventEntryID(self) -> Optional[EntryID]: The EntryID of an optional Appointement object that represents the contact's birtday. """ - return self._ensureSetNamed('_birthdayEventEntryID', '804D', constants.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) + return self._ensureSetNamed('_birthdayEventEntryID', '804D', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) @property def birthdayLocal(self) -> Optional[datetime.datetime]: """ The birthday of the contact at 0:00 in the client's local time zone. """ - return self._ensureSetNamed('_birthdayLocal', '80DE', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_birthdayLocal', '80DE', constants.ps.PSETID_ADDRESS) @property def businessCard(self) -> 'PIL.Image.Image': @@ -161,7 +161,7 @@ def businessCardCardPicture(self) -> Optional[bytes]: The image to be used on a business card. Must be either a PNG file or a JPEG file. """ - return self._ensureSetNamed('_businessCardCardPicture', '8041', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_businessCardCardPicture', '8041', constants.ps.PSETID_ADDRESS) @property def businessCardDisplayDefinition(self) -> Optional[BusinessCardDisplayDefinition]: @@ -169,7 +169,7 @@ def businessCardDisplayDefinition(self) -> Optional[BusinessCardDisplayDefinitio Specifies the customization details for displaying a contact as a business card. """ - return self._ensureSetNamed('_businessCardDisplayDefinition', '8040', constants.PSETID_ADDRESS, overrideClass = BusinessCardDisplayDefinition) + return self._ensureSetNamed('_businessCardDisplayDefinition', '8040', constants.ps.PSETID_ADDRESS, overrideClass = BusinessCardDisplayDefinition) @property def businessFax(self) -> Optional[dict]: @@ -198,7 +198,7 @@ def businessFaxAddressType(self) -> Optional[str]: """ The type of address for the fax. MUST be set to "FAX" if present. """ - return self._ensureSetNamed('_businessFaxAddressType', '80C2', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_businessFaxAddressType', '80C2', constants.ps.PSETID_ADDRESS) @property def businessFaxEmailAddress(self) -> Optional[str]: @@ -206,7 +206,7 @@ def businessFaxEmailAddress(self) -> Optional[str]: Contains a user-readable display name, followed by the "@" character, followed by a fax number. """ - return self._ensureSetNamed('_businessFaxEmailAddress', '80C3', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_businessFaxEmailAddress', '80C3', constants.ps.PSETID_ADDRESS) @property def businessFaxNumber(self) -> Optional[str]: @@ -220,14 +220,14 @@ def businessFaxOriginalDisplayName(self) -> Optional[str]: """ The normalized subject for the contact. """ - return self._ensureSetNamed('_businessFaxOriginalDisplayName', '80C4', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_businessFaxOriginalDisplayName', '80C4', constants.ps.PSETID_ADDRESS) @property def businessFaxOriginalEntryId(self) -> Optional[EntryID]: """ The one-off EntryID corresponding to this fax address. """ - return self._ensureSetNamed('_businessFaxOriginalEntryId', '80C5', constants.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) + return self._ensureSetNamed('_businessFaxOriginalEntryId', '80C5', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) @property def businessTelephoneNumber(self) -> Optional[str]: @@ -297,35 +297,35 @@ def contactCharacterSet(self) -> Optional[int]: """ The character set that is used for this Contact object. """ - return self._ensureSetNamed('_contactCharacterSet', '8023', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_contactCharacterSet', '8023', constants.ps.PSETID_ADDRESS) @property def contactItemData(self) -> Optional[List[int]]: """ Used to help display the contact information. """ - return self._ensureSetNamed('_contactItemData', '8007', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_contactItemData', '8007', constants.ps.PSETID_ADDRESS) @property def contactLinkedGlobalAddressListEntryID(self) -> Optional[EntryID]: """ The EntryID of the GAL object to which the duplicate contact is linked. """ - return self._ensureSetNamed('_contactLinkedGlobalAddressListEntryID', '80E2', constants.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) + return self._ensureSetNamed('_contactLinkedGlobalAddressListEntryID', '80E2', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) @property def contactLinkGlobalAddressListLinkID(self) -> Optional[str]: """ The GUID of the GAL contact to which the duplicate contact is linked. """ - return self._ensureSetNamed('_contactLinkGlobalAddressListLinkId', '80E8', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_contactLinkGlobalAddressListLinkId', '80E8', constants.ps.PSETID_ADDRESS) @property def contactLinkGlobalAddressListLinkState(self) -> Optional[ContactLinkState]: """ The state of linking between the GAL contact and the duplicate contact. """ - return self._ensureSetNamed('_contactLinkGlobalAddressListLinkState', '80E6', constants.PSETID_ADDRESS, overrideClass = ContactLinkState) + return self._ensureSetNamed('_contactLinkGlobalAddressListLinkState', '80E6', constants.ps.PSETID_ADDRESS, overrideClass = ContactLinkState) @property def contactLinkLinkRejectHistory(self) -> Optional[List[bytes]]: @@ -333,7 +333,7 @@ def contactLinkLinkRejectHistory(self) -> Optional[List[bytes]]: A list of any contacts that were previously rejected for linking with the duplicate contact. """ - return self._ensureSetNamed('_contactLinkLinkRejectHistory', '80E5', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_contactLinkLinkRejectHistory', '80E5', constants.ps.PSETID_ADDRESS) @property def contactLinkSMTPAddressCache(self) -> Optional[List[str]]: @@ -341,7 +341,7 @@ def contactLinkSMTPAddressCache(self) -> Optional[List[str]]: A list of the SMTP addresses that are used by the GAL contact that are linked to the duplicate contact. """ - return self._ensureSetNamed('_contactLinkSMTPAddressCache', '80E3', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_contactLinkSMTPAddressCache', '80E3', constants.ps.PSETID_ADDRESS) @property def contactPhoto(self) -> Optional[bytes]: @@ -364,28 +364,28 @@ def contactUserField1(self) -> Optional[str]: """ Used to store custom text for a business card. """ - return self._ensureSetNamed('_contactUserField1', '804F', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_contactUserField1', '804F', constants.ps.PSETID_ADDRESS) @property def contactUserField2(self) -> Optional[str]: """ Used to store custom text for a business card. """ - return self._ensureSetNamed('_contactUserField2', '8050', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_contactUserField2', '8050', constants.ps.PSETID_ADDRESS) @property def contactUserField3(self) -> Optional[str]: """ Used to store custom text for a business card. """ - return self._ensureSetNamed('_contactUserField3', '8051', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_contactUserField3', '8051', constants.ps.PSETID_ADDRESS) @property def contactUserField4(self) -> Optional[str]: """ Used to store custom text for a business card. """ - return self._ensureSetNamed('_contactUserField4', '8052', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_contactUserField4', '8052', constants.ps.PSETID_ADDRESS) @property def customerID(self) -> Optional[str]: @@ -442,21 +442,21 @@ def email1AddressType(self) -> Optional[str]: """ The address type of the first email address. """ - return self._ensureSetNamed('_email1AddressType', '8082', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_email1AddressType', '8082', constants.ps.PSETID_ADDRESS) @property def email1DisplayName(self) -> Optional[str]: """ The user-readable display name of the first email address. """ - return self._ensureSetNamed('_email1DisplayName', '8080', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_email1DisplayName', '8080', constants.ps.PSETID_ADDRESS) @property def email1EmailAddress(self) -> Optional[str]: """ The first email address. """ - return self._ensureSetNamed('_email1EmailAddress', '8083', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_email1EmailAddress', '8083', constants.ps.PSETID_ADDRESS) @property def email1OriginalDisplayName(self) -> Optional[str]: @@ -464,14 +464,14 @@ def email1OriginalDisplayName(self) -> Optional[str]: The first SMTP email address that corresponds to the first email address for the contact. """ - return self._ensureSetNamed('_email1OriginalDisplayName', '8084', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_email1OriginalDisplayName', '8084', constants.ps.PSETID_ADDRESS) @property def email1OriginalEntryId(self) -> Optional[EntryID]: """ The EntryID of the object correspinding to this electronic address. """ - return self._ensureSetNamed('_email1OriginalEntryId', '8085', constants.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) + return self._ensureSetNamed('_email1OriginalEntryId', '8085', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) @property def email2(self) -> Optional[dict]: @@ -497,21 +497,21 @@ def email2AddressType(self) -> Optional[str]: """ The address type of the second email address. """ - return self._ensureSetNamed('_email2AddressType', '8092', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_email2AddressType', '8092', constants.ps.PSETID_ADDRESS) @property def email2DisplayName(self) -> Optional[str]: """ The user-readable display name of the second email address. """ - return self._ensureSetNamed('_email2DisplayName', '8090', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_email2DisplayName', '8090', constants.ps.PSETID_ADDRESS) @property def email2EmailAddress(self) -> Optional[str]: """ The second email address. """ - return self._ensureSetNamed('_email2EmailAddress', '8093', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_email2EmailAddress', '8093', constants.ps.PSETID_ADDRESS) @property def email2OriginalDisplayName(self) -> Optional[str]: @@ -519,14 +519,14 @@ def email2OriginalDisplayName(self) -> Optional[str]: The second SMTP email address that corresponds to the second email address for the contact. """ - return self._ensureSetNamed('_email2OriginalDisplayName', '8094', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_email2OriginalDisplayName', '8094', constants.ps.PSETID_ADDRESS) @property def email2OriginalEntryId(self) -> Optional[EntryID]: """ The EntryID of the object correspinding to this electronic address. """ - return self._ensureSetNamed('_email2OriginalEntryId', '8095', constants.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) + return self._ensureSetNamed('_email2OriginalEntryId', '8095', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) @property def email3(self) -> Optional[dict]: @@ -552,21 +552,21 @@ def email3AddressType(self) -> Optional[str]: """ The address type of the third email address. """ - return self._ensureSetNamed('_email3AddressType', '80A2', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_email3AddressType', '80A2', constants.ps.PSETID_ADDRESS) @property def email3DisplayName(self) -> Optional[str]: """ The user-readable display name of the third email address. """ - return self._ensureSetNamed('_email3DisplayName', '80A0', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_email3DisplayName', '80A0', constants.ps.PSETID_ADDRESS) @property def email3EmailAddress(self) -> Optional[str]: """ The third email address. """ - return self._ensureSetNamed('_email3EmailAddress', '80A3', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_email3EmailAddress', '80A3', constants.ps.PSETID_ADDRESS) @property def email3OriginalDisplayName(self) -> Optional[str]: @@ -574,14 +574,14 @@ def email3OriginalDisplayName(self) -> Optional[str]: The third SMTP email address that corresponds to the third email address for the contact. """ - return self._ensureSetNamed('_email3OriginalDisplayName', '80A4', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_email3OriginalDisplayName', '80A4', constants.ps.PSETID_ADDRESS) @property def email3OriginalEntryId(self) -> Optional[EntryID]: """ The EntryID of the object correspinding to this electronic address. """ - return self._ensureSetNamed('_email3OriginalEntryId', '80A5', constants.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) + return self._ensureSetNamed('_email3OriginalEntryId', '80A5', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) @property def emails(self) -> Tuple[Union[Dict, None], Union[Dict, None], Union[Dict, None]]: @@ -618,7 +618,7 @@ def fileUnder(self) -> Optional[str]: The name under which to file a contact when displaying a list of contacts. """ - return self._ensureSetNamed('_fileUnder', '8005', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_fileUnder', '8005', constants.ps.PSETID_ADDRESS) @property def fileUnderID(self) -> Optional[int]: @@ -626,7 +626,7 @@ def fileUnderID(self) -> Optional[int]: The format to use for fileUnder. See PidLidFileUnderId in [MS-OXOCNTC] for details. """ - return self._ensureSetNamed('_fileUnderID', '8006', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_fileUnderID', '8006', constants.ps.PSETID_ADDRESS) @property def freeBusyLocation(self) -> Optional[str]: @@ -634,7 +634,7 @@ def freeBusyLocation(self) -> Optional[str]: A URL path from which a client can retrieve free/busy status information for the contact as an iCalendat file. """ - return self._ensureSetNamed('_freeBusyLocation', '80D8', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_freeBusyLocation', '80D8', constants.ps.PSETID_ADDRESS) @property def ftpSite(self) -> Optional[str]: @@ -677,7 +677,7 @@ def hasPicture(self) -> bool: """ Whether the contact has a contact photo. """ - return self._ensureSetNamed('_hasPicture', '8015', constants.PSETID_ADDRESS, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('_hasPicture', '8015', constants.ps.PSETID_ADDRESS, overrideClass = bool, preserveNone = False) @property def headerFormatProperties(self) -> constants.HEADER_FORMAT_TYPE: @@ -783,7 +783,7 @@ def homeAddress(self) -> Optional[str]: """ The complete home address of the contact. """ - return self._ensureSetNamed('_homeAddress', '801A', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_homeAddress', '801A', constants.ps.PSETID_ADDRESS) @property def homeAddressCountry(self) -> Optional[str]: @@ -797,7 +797,7 @@ def homeAddressCountryCode(self) -> Optional[str]: """ The country code portion of the contact's home address. """ - return self._ensureSetNamed('_homeAddressCountryCode', '80DA', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_homeAddressCountryCode', '80DA', constants.ps.PSETID_ADDRESS) @property def homeAddressLocality(self) -> Optional[str]: @@ -861,7 +861,7 @@ def homeFaxAddressType(self) -> Optional[str]: """ The type of address for the fax. MUST be set to "FAX" if present. """ - return self._ensureSetNamed('_homeFaxAddressType', '80D2', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_homeFaxAddressType', '80D2', constants.ps.PSETID_ADDRESS) @property def homeFaxEmailAddress(self) -> Optional[str]: @@ -869,7 +869,7 @@ def homeFaxEmailAddress(self) -> Optional[str]: Contains a user-readable display name, followed by the "@" character, followed by a fax number. """ - return self._ensureSetNamed('_homeFaxEmailAddress', '80D3', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_homeFaxEmailAddress', '80D3', constants.ps.PSETID_ADDRESS) @property def homeFaxNumber(self) -> Optional[str]: @@ -883,14 +883,14 @@ def homeFaxOriginalDisplayName(self) -> Optional[str]: """ The normalized subject for the contact. """ - return self._ensureSetNamed('_homeFaxOriginalDisplayName', '80D4', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_homeFaxOriginalDisplayName', '80D4', constants.ps.PSETID_ADDRESS) @property def homeFaxOriginalEntryId(self) -> Optional[EntryID]: """ The one-off EntryID corresponding to this fax address. """ - return self._ensureSetNamed('_homeFaxOriginalEntryId', '80D5', constants.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) + return self._ensureSetNamed('_homeFaxOriginalEntryId', '80D5', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) @property def homeTelephoneNumber(self) -> Optional[str]: @@ -918,14 +918,14 @@ def instantMessagingAddress(self) -> Optional[str]: """ The instant messaging address of the contact. """ - return self._ensureSetNamed('_instantMessagingAddress', '8062', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_instantMessagingAddress', '8062', constants.ps.PSETID_ADDRESS) @property def isContactLinked(self) -> bool: """ Whether the contact is linked to other contacts. """ - return self._ensureSetNamed('_isContactLinked', '80E0', constants.PSETID_ADDRESS, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('_isContactLinked', '80E0', constants.ps.PSETID_ADDRESS, overrideClass = bool, preserveNone = False) @property def isdnNumber(self) -> Optional[str]: @@ -983,7 +983,7 @@ def mailAddressCountryCode(self) -> Optional[str]: """ The country code portion of the contact's mail address. """ - return self._ensureSetNamed('_mailAddressCountryCode', '80DD', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_mailAddressCountryCode', '80DD', constants.ps.PSETID_ADDRESS) @property def mailAddressLocality(self) -> Optional[str]: @@ -1076,7 +1076,7 @@ def otherAddress(self) -> Optional[str]: """ The complete other address of the contact. """ - return self._ensureSetNamed('_otherAddress', '801C', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_otherAddress', '801C', constants.ps.PSETID_ADDRESS) @property def otherAddressCountry(self) -> Optional[str]: @@ -1090,7 +1090,7 @@ def otherAddressCountryCode(self) -> Optional[str]: """ The country code portion of the contact's other address. """ - return self._ensureSetNamed('_otherAddressCountryCode', '80DC', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_otherAddressCountryCode', '80DC', constants.ps.PSETID_ADDRESS) @property def otherAddressLocality(self) -> Optional[str]: @@ -1153,21 +1153,21 @@ def phoneticCompanyName(self) -> Optional[str]: """ The phonetic pronunciation of the contact's company name. """ - return self._ensureSetNamed('_phoneticCompanyName', '802E', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_phoneticCompanyName', '802E', constants.ps.PSETID_ADDRESS) @property def phoneticGivenName(self) -> Optional[str]: """ The phonetic pronunciation of the contact's given name. """ - return self._ensureSetNamed('_phoneticGivenName', '802C', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_phoneticGivenName', '802C', constants.ps.PSETID_ADDRESS) @property def phoneticSurname(self) -> Optional[str]: """ The phonetic pronunciation of the given name of the contact. """ - return self._ensureSetNamed('_phoneticSurname', '802D', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_phoneticSurname', '802D', constants.ps.PSETID_ADDRESS) @property def postalAddressID(self) -> PostalAddressID: @@ -1175,7 +1175,7 @@ def postalAddressID(self) -> PostalAddressID: Indicates which physical address is the Mailing Address for this contact. """ - return self._ensureSetNamed('_postalAddressID', '8022', constants.PSETID_ADDRESS, overrideClass = lambda x : PostalAddressID(x or 0), preserveNone = False) + return self._ensureSetNamed('_postalAddressID', '8022', constants.ps.PSETID_ADDRESS, overrideClass = lambda x : PostalAddressID(x or 0), preserveNone = False) @property def primaryFax(self) -> Optional[dict]: @@ -1204,7 +1204,7 @@ def primaryFaxAddressType(self) -> Optional[str]: """ The type of address for the fax. MUST be set to "FAX" if present. """ - return self._ensureSetNamed('_primaryFaxAddressType', '80B2', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_primaryFaxAddressType', '80B2', constants.ps.PSETID_ADDRESS) @property def primaryFaxEmailAddress(self) -> Optional[str]: @@ -1212,7 +1212,7 @@ def primaryFaxEmailAddress(self) -> Optional[str]: Contains a user-readable display name, followed by the "@" character, followed by a fax number. """ - return self._ensureSetNamed('_primaryFaxEmailAddress', '80B3', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_primaryFaxEmailAddress', '80B3', constants.ps.PSETID_ADDRESS) @property def primaryFaxNumber(self) -> Optional[str]: @@ -1226,14 +1226,14 @@ def primaryFaxOriginalDisplayName(self) -> Optional[str]: """ The normalized subject for the contact. """ - return self._ensureSetNamed('_primaryFaxOriginalDisplayName', '80B4', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_primaryFaxOriginalDisplayName', '80B4', constants.ps.PSETID_ADDRESS) @property def primaryFaxOriginalEntryId(self) -> Optional[EntryID]: """ The one-off EntryID corresponding to this fax address. """ - return self._ensureSetNamed('_primaryFaxOriginalEntryId', '80B5', constants.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) + return self._ensureSetNamed('_primaryFaxOriginalEntryId', '80B5', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) @property def primaryTelephoneNumber(self) -> Optional[str]: @@ -1263,7 +1263,7 @@ def referenceEntryID(self) -> Optional[EntryID]: Contact object unless the Contact object is a copy of an earlier original. """ - return self._ensureSetNamed('_referenceEntryID', '85BD', constants.PSETID_COMMON, overrideClass = EntryID.autoCreate) + return self._ensureSetNamed('_referenceEntryID', '85BD', constants.ps.PSETID_COMMON, overrideClass = EntryID.autoCreate) @property def referredByName(self) -> Optional[str]: @@ -1321,7 +1321,7 @@ def weddingAnniversaryEventEntryID(self) -> Optional[EntryID]: The EntryID of an optional Appointement object that represents the contact's wedding anniversary. """ - return self._ensureSetNamed('_weddingAnniversaryEventEntryID', '804E', constants.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) + return self._ensureSetNamed('_weddingAnniversaryEventEntryID', '804E', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) @property def weddingAnniversaryLocal(self) -> Optional[datetime.datetime]: @@ -1329,67 +1329,67 @@ def weddingAnniversaryLocal(self) -> Optional[datetime.datetime]: The wedding anniversary of the contact at 0:00 in the client's local time zone. """ - return self._ensureSetNamed('_weddingAnniversaryLocal', '80DF', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_weddingAnniversaryLocal', '80DF', constants.ps.PSETID_ADDRESS) @property def webpageUrl(self) -> Optional[str]: """ The contact's business web page url. SHOULD be the same as businessUrl. """ - return self._ensureSetNamed('_webpageUrl', '802B', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_webpageUrl', '802B', constants.ps.PSETID_ADDRESS) @property def workAddress(self) -> Optional[str]: """ The complete work address of the contact. """ - return self._ensureSetNamed('_workAddress', '801B', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_workAddress', '801B', constants.ps.PSETID_ADDRESS) @property def workAddressCountry(self) -> Optional[str]: """ The country portion of the contact's work address. """ - return self._ensureSetNamed('_workAddressCountry', '8049', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_workAddressCountry', '8049', constants.ps.PSETID_ADDRESS) @property def workAddressCountryCode(self) -> Optional[str]: """ The country code portion of the contact's work address. """ - return self._ensureSetNamed('_workAddressCountryCode', '80DB', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_workAddressCountryCode', '80DB', constants.ps.PSETID_ADDRESS) @property def workAddressLocality(self) -> Optional[str]: """ The locality or city portion of the contact's work address. """ - return self._ensureSetNamed('_workAddressLocality', '8046', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_workAddressLocality', '8046', constants.ps.PSETID_ADDRESS) @property def workAddressPostalCode(self) -> Optional[str]: """ The postal code portion of the contact's work address. """ - return self._ensureSetNamed('_workAddressPostalCode', '8048', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_workAddressPostalCode', '8048', constants.ps.PSETID_ADDRESS) @property def workAddressPostOfficeBox(self) -> Optional[str]: """ The number or identifier of the contact's work post office box. """ - return self._ensureSetNamed('_workAddressPostOfficeBox', '804A', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_workAddressPostOfficeBox', '804A', constants.ps.PSETID_ADDRESS) @property def workAddressStateOrProvince(self) -> Optional[str]: """ The state or province portion of the contact's work address. """ - return self._ensureSetNamed('_workAddressStateOrProvince', '8047', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_workAddressStateOrProvince', '8047', constants.ps.PSETID_ADDRESS) @property def workAddressStreet(self) -> Optional[str]: """ The street portion of the contact's work address. """ - return self._ensureSetNamed('_workAddressStreet', '8045', constants.PSETID_ADDRESS) + return self._ensureSetNamed('_workAddressStreet', '8045', constants.ps.PSETID_ADDRESS) diff --git a/extract_msg/msg_classes/meeting_exception.py b/extract_msg/msg_classes/meeting_exception.py index 543b8af5..eb36bb6f 100644 --- a/extract_msg/msg_classes/meeting_exception.py +++ b/extract_msg/msg_classes/meeting_exception.py @@ -33,7 +33,7 @@ def exceptionReplaceTime(self) -> Optional[datetime.datetime]: The date and time within the recurrence pattern that the exception will replace. The value is specified in UTC. """ - return self._ensureSetNamed('_exceptionReplaceTime', '8228', constants.PSETID_APPOINTMENT) + return self._ensureSetNamed('_exceptionReplaceTime', '8228', constants.ps.PSETID_APPOINTMENT) @property def fExceptionalBody(self) -> bool: @@ -42,11 +42,11 @@ def fExceptionalBody(self) -> bool: differs from the Recurring Calendar object. If True, the Exception MUST have a body. """ - return self._ensureSetNamed('_fExceptionalBody', '8206', constants.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('_fExceptionalBody', '8206', constants.ps.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) @property def fInvited(self) -> bool: """ Indicates if invitations have been sent for this exception. """ - return self._ensureSetNamed('_fInvited', '8229', constants.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('_fInvited', '8229', constants.ps.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) diff --git a/extract_msg/msg_classes/meeting_forward.py b/extract_msg/msg_classes/meeting_forward.py index 361e173f..8bcd7b2c 100644 --- a/extract_msg/msg_classes/meeting_forward.py +++ b/extract_msg/msg_classes/meeting_forward.py @@ -24,7 +24,7 @@ def forwardNotificationRecipients(self) -> Optional[bytes]: Incomplete, looks to be the same structure as appointmentUnsendableRecipients, so we need more examples of this. """ - return self._ensureSetNamed('_forwardNotificationRecipients', '8261', constants.PSETID_APPOINTMENT) + return self._ensureSetNamed('_forwardNotificationRecipients', '8261', constants.ps.PSETID_APPOINTMENT) @property def headerFormatProperties(self) -> constants.HEADER_FORMAT_TYPE: @@ -94,4 +94,4 @@ def promptSendUpdate(self) -> bool: Indicates that the Meeting Forward Notification object was out-of-date when it was received. """ - return self._ensureSetNamed('_promptSendUpdate', '8045', constants.PSETID_COMMON, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('_promptSendUpdate', '8045', constants.ps.PSETID_COMMON, overrideClass = bool, preserveNone = False) diff --git a/extract_msg/msg_classes/meeting_related.py b/extract_msg/msg_classes/meeting_related.py index 9b881293..061999fb 100644 --- a/extract_msg/msg_classes/meeting_related.py +++ b/extract_msg/msg_classes/meeting_related.py @@ -22,7 +22,7 @@ def attendeeCriticalChange(self) -> Optional[datetime.datetime]: """ The date and time at which the meeting-related object was sent. """ - return self._ensureSetNamed('_attendeeCriticalChange', '0001', constants.PSETID_MEETING) + return self._ensureSetNamed('_attendeeCriticalChange', '0001', constants.ps.PSETID_MEETING) @property def processed(self) -> bool: @@ -37,7 +37,7 @@ def serverProcessed(self) -> bool: Indicates that the Meeting Request object or Meeting Update object has been processed. """ - return self._ensureSetNamed('_serverProcessed', '85CC', constants.PSETID_CALENDAR_ASSISTANT, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('_serverProcessed', '85CC', constants.ps.PSETID_CALENDAR_ASSISTANT, overrideClass = bool, preserveNone = False) @property def serverProcessingActions(self) -> Optional[Set[ServerProcessingAction]]: @@ -45,7 +45,7 @@ def serverProcessingActions(self) -> Optional[Set[ServerProcessingAction]]: A set of which actions have been taken on the Meeting Request object or Meeting Update object. """ - return self._ensureSetNamed('_serverProcessingActions', '85CD', constants.PSETID_CALENDAR_ASSISTANT, overrideClass = ServerProcessingAction.fromBits) + return self._ensureSetNamed('_serverProcessingActions', '85CD', constants.ps.PSETID_CALENDAR_ASSISTANT, overrideClass = ServerProcessingAction.fromBits) @property def timeZone(self) -> Optional[int]: @@ -54,11 +54,11 @@ def timeZone(self) -> Optional[int]: See PidLidTimeZone in [MS-OXOCAL] for details. """ - return self._ensureSetNamed('_timeZone', '000C', constants.PSETID_MEETING) + return self._ensureSetNamed('_timeZone', '000C', constants.ps.PSETID_MEETING) @property def where(self) -> Optional[str]: """ PidLidWhere. Should be the same as location. """ - return self._ensureSetNamed('_where', '0002', constants.PSETID_MEETING) + return self._ensureSetNamed('_where', '0002', constants.ps.PSETID_MEETING) diff --git a/extract_msg/msg_classes/meeting_request.py b/extract_msg/msg_classes/meeting_request.py index 6214fd18..3ccd6191 100644 --- a/extract_msg/msg_classes/meeting_request.py +++ b/extract_msg/msg_classes/meeting_request.py @@ -24,7 +24,7 @@ def appointmentMessageClass(self) -> Optional[str]: object that is to be generated from the Meeting Request object. MUST start with "IPM.Appointment". """ - return self._ensureSetNamed('_appointmentMessageClass', '0024', constants.PSETID_MEETING) + return self._ensureSetNamed('_appointmentMessageClass', '0024', constants.ps.PSETID_MEETING) @property def calendarType(self) -> Optional[RecurCalendarType]: @@ -33,7 +33,7 @@ def calendarType(self) -> Optional[RecurCalendarType]: property if the Meeting Request object represents a recurring series or an exception. """ - return self._ensureSetNamed('_calendarType', '001C', constants.PSETID_MEETING, overrideClass = RecurCalendarType) + return self._ensureSetNamed('_calendarType', '001C', constants.ps.PSETID_MEETING, overrideClass = RecurCalendarType) @property def changeHighlight(self) -> Optional[Set[MeetingObjectChange]]: @@ -43,7 +43,7 @@ def changeHighlight(self) -> Optional[Set[MeetingObjectChange]]: Returns a set of flags. """ - return self._ensureSetNamed('_changeHighlight', '8204', constants.PSETID_APPOINTMENT, overrideClass = MeetingObjectChange.fromBits) + return self._ensureSetNamed('_changeHighlight', '8204', constants.ps.PSETID_APPOINTMENT, overrideClass = MeetingObjectChange.fromBits) @property def forwardInstance(self) -> bool: @@ -52,7 +52,7 @@ def forwardInstance(self) -> bool: recurring series, and it was forwarded (even when forwarded by the organizer) rather than being an invitation sent by the organizer. """ - return self._ensureSetNamed('_forwardInstance', '820A', constants.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('_forwardInstance', '820A', constants.ps.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) @property def headerFormatProperties(self) -> constants.HEADER_FORMAT_TYPE: @@ -139,21 +139,21 @@ def intendedBusyStatus(self) -> Optional[BusyStatus]: calendar at the time the Meeting Request object or Meeting Update object was sent. """ - return self._ensureSetNamed('_intendedBusyStatus', '8224', constants.PSETID_APPOINTMENT, overrideClass = BusyStatus) + return self._ensureSetNamed('_intendedBusyStatus', '8224', constants.ps.PSETID_APPOINTMENT, overrideClass = BusyStatus) @property def meetingType(self) -> Optional[MeetingType]: """ The type of Meeting Request object or Meeting Update object. """ - return self._ensureSetNamed('_meetingType', '0026', constants.PSETID_MEETING, overrideClass = MeetingType) + return self._ensureSetNamed('_meetingType', '0026', constants.ps.PSETID_MEETING, overrideClass = MeetingType) @property def oldLocation(self) -> Optional[str]: """ The original value of the location property before a meeting update. """ - return self._ensureSetNamed('_oldLocation', '0028', constants.PSETID_MEETING) + return self._ensureSetNamed('_oldLocation', '0028', constants.ps.PSETID_MEETING) @property def oldWhenEndWhole(self) -> Optional[datetime.datetime]: @@ -161,7 +161,7 @@ def oldWhenEndWhole(self) -> Optional[datetime.datetime]: The original value of the appointmentEndWhole property before a meeting update. """ - return self._ensureSetNamed('_oldWhenEndWhole', '002A', constants.PSETID_MEETING) + return self._ensureSetNamed('_oldWhenEndWhole', '002A', constants.ps.PSETID_MEETING) @property def oldWhenStartWhole(self) -> Optional[datetime.datetime]: @@ -169,4 +169,4 @@ def oldWhenStartWhole(self) -> Optional[datetime.datetime]: The original value of the appointmentStartWhole property before a meeting update. """ - return self._ensureSetNamed('_oldWhenStartWhole', '0029', constants.PSETID_MEETING) + return self._ensureSetNamed('_oldWhenStartWhole', '0029', constants.ps.PSETID_MEETING) diff --git a/extract_msg/msg_classes/meeting_response.py b/extract_msg/msg_classes/meeting_response.py index 7bf30c22..4f656ff9 100644 --- a/extract_msg/msg_classes/meeting_response.py +++ b/extract_msg/msg_classes/meeting_response.py @@ -22,7 +22,7 @@ def appointmentCounterProposal(self) -> bool: """ Indicates if the response is a counter proposal. """ - return self._ensureSetNamed('_appointmentCounterProposal', '8257', constants.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('_appointmentCounterProposal', '8257', constants.ps.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) @property def appointmentProposedDuration(self) -> Optional[int]: @@ -30,7 +30,7 @@ def appointmentProposedDuration(self) -> Optional[int]: The proposed value for the appointmentDuration property for a counter proposal. """ - return self._ensureSetNamed('_appointmentProposedDuration', '8256', constants.PSETID_APPOINTMENT) + return self._ensureSetNamed('_appointmentProposedDuration', '8256', constants.ps.PSETID_APPOINTMENT) @property def appointmentProposedEndWhole(self) -> Optional[datetime.datetime]: @@ -38,7 +38,7 @@ def appointmentProposedEndWhole(self) -> Optional[datetime.datetime]: The proposal value for the appointmentEndWhole property for a counter proposal. """ - return self._ensureSetNamed('_appointmentProposedEndWhole', '8251', constants.PSETID_APPOINTMENT) + return self._ensureSetNamed('_appointmentProposedEndWhole', '8251', constants.ps.PSETID_APPOINTMENT) @property def appointmentProposedStartWhole(self) -> Optional[datetime.datetime]: @@ -46,7 +46,7 @@ def appointmentProposedStartWhole(self) -> Optional[datetime.datetime]: The proposal value for the appointmentStartWhole property for a counter proposal. """ - return self._ensureSetNamed('_appointmentProposedStartWhole', '8250', constants.PSETID_APPOINTMENT) + return self._ensureSetNamed('_appointmentProposedStartWhole', '8250', constants.ps.PSETID_APPOINTMENT) @property def isSilent(self) -> bool: @@ -54,7 +54,7 @@ def isSilent(self) -> bool: Indicates if the user did not include any text in the body of the Meeting Response object. """ - return self._ensureSetNamed('_isSilent', '0004', constants.PSETID_MEETING, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('_isSilent', '0004', constants.ps.PSETID_MEETING, overrideClass = bool, preserveNone = False) @property def promptSendUpdate(self) -> bool: @@ -62,7 +62,7 @@ def promptSendUpdate(self) -> bool: Indicates that the Meeting Response object was out-of-date when it was received. """ - return self._ensureSetNamed('_promptSendUpdate', '8045', constants.PSETID_COMMON, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('_promptSendUpdate', '8045', constants.ps.PSETID_COMMON, overrideClass = bool, preserveNone = False) @property def responseType(self) -> Optional[ResponseType]: diff --git a/extract_msg/msg_classes/message_base.py b/extract_msg/msg_classes/message_base.py index 1b00f66b..3e21f04f 100644 --- a/extract_msg/msg_classes/message_base.py +++ b/extract_msg/msg_classes/message_base.py @@ -555,7 +555,7 @@ def replace(bodyMarker): return bodyMarker.group() + self.htmlInjectableHeader.encode('utf-8') # Use the previously defined function to inject the HTML header. - return constants.RE_HTML_BODY_START.sub(replace, body, 1) + return constants.re.HTML_BODY_START.sub(replace, body, 1) def injectRtfHeader(self) -> bytes: """ @@ -584,7 +584,7 @@ def replace(bodyMarker): # This first method only applies to documents with encapsulated HTML # that is formatted in a nice way. if isEncapsulatedRtf(self.rtfBody): - data = constants.RE_RTF_ENC_BODY_START.sub(replace, self.rtfBody, 1) + data = constants.re.RTF_ENC_BODY_START.sub(replace, self.rtfBody, 1) if data != self.rtfBody: logger.debug('Successfully injected RTF header using encapsulation method.') return data @@ -734,7 +734,7 @@ def save(self, **kwargs) -> MessageBase: if customFilename: # First we need to validate it. If there are invalid characters, # this will detect it. - if constants.RE_INVALID_FILENAME_CHARACTERS.search(customFilename): + if constants.re.INVALID_FILENAME_CHARACTERS.search(customFilename): raise ValueError('Invalid character found in customFilename. Must not contain any of the following characters: \\/:*?"<>|') # Quick fix to remove spaces from the end of the filename, if any # are there. @@ -983,7 +983,7 @@ def deencapsulatedRtf(self) -> Optional[RTFDE.DeEncapsulator]: # then log if we removed any of them before trying this. logger.warning(f'RTFDE failed to decode rtfBody for message with subject "{self.subject}". Attempting to cut out unnecessary data and override decoding.') - match = constants.RE_BIN.search(body) + match = constants.re.BIN.search(body) # Because we are going to be actively removing things, # we want to search the entire thing over again. while match: @@ -991,7 +991,7 @@ def deencapsulatedRtf(self) -> Optional[RTFDE.DeEncapsulator]: length = int(match.group(1)) # Extract the entire binary section and replace it. body = body.replace(body[match.start():match.end() + length], b'', 1) - match = constants.RE_BIN.search(body) + match = constants.re.BIN.search(body) self._deencapsultor = RTFDE.DeEncapsulator(body.decode(chardet.detect(body)['encoding'])) self._deencapsultor.deencapsulate() diff --git a/extract_msg/msg_classes/msg.py b/extract_msg/msg_classes/msg.py index 57d1e708..c82f59be 100644 --- a/extract_msg/msg_classes/msg.py +++ b/extract_msg/msg_classes/msg.py @@ -24,6 +24,7 @@ from ..attachments import ( AttachmentBase, initStandardAttachment, SignedAttachment ) +from ..encoding import lookupCodePage from ..enums import ( AttachErrorBehavior, ErrorBehavior, Importance, Priority, PropertiesType, Sensitivity, SideEffect @@ -35,9 +36,9 @@ from ..properties.prop import FixedLengthProp from ..properties.properties_store import PropertiesStore from ..utils import ( - divide, getEncodingName, hasLen, inputToMsgPath, inputToString, - makeWeakRef, msgPathToString, parseType, properHex, verifyPropertyId, - verifyType, windowsUnicode + divide, hasLen, inputToMsgPath, inputToString, makeWeakRef, + msgPathToString, parseType, properHex, verifyPropertyId, verifyType, + windowsUnicode ) @@ -705,7 +706,7 @@ def classified(self) -> bool: Indicates whether the contents of this message are regarded as classified information. """ - return self._ensureSetNamed('_classified', '85B5', constants.PSETID_COMMON, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('_classified', '85B5', constants.ps.PSETID_COMMON, overrideClass = bool, preserveNone = False) @property def classType(self) -> Optional[str]: @@ -719,14 +720,14 @@ def commonEnd(self) -> Optional[datetime.datetime]: """ The end time for the object. """ - return self._ensureSetNamed('_commonEnd', '8517', constants.PSETID_COMMON) + return self._ensureSetNamed('_commonEnd', '8517', constants.ps.PSETID_COMMON) @property def commonStart(self) -> Optional[datetime.datetime]: """ The start time for the object. """ - return self._ensureSetNamed('_commonStart', '8516', constants.PSETID_COMMON) + return self._ensureSetNamed('_commonStart', '8516', constants.ps.PSETID_COMMON) @property def currentVersion(self) -> Optional[int]: @@ -734,14 +735,14 @@ def currentVersion(self) -> Optional[int]: Specifies the build number of the client application that sent the message. """ - return self._ensureSetNamed('_currentVersion', '8552', constants.PSETID_COMMON) + return self._ensureSetNamed('_currentVersion', '8552', constants.ps.PSETID_COMMON) @property def currentVersionName(self) -> Optional[str]: """ Specifies the name of the client application that sent the message. """ - return self._ensureSetNamed('_currentVersionName', '8554', constants.PSETID_COMMON) + return self._ensureSetNamed('_currentVersionName', '8554', constants.ps.PSETID_COMMON) @property def errorBehavior(self) -> ErrorBehavior: @@ -901,7 +902,7 @@ def sideEffects(self) -> Optional[Set[SideEffect]]: Controls how a Message object is handled by the client in relation to certain user interface actions by the user, such as deleting a message. """ - return self._ensureSetNamed('_sideEffects', '8510', constants.PSETID_COMMON, overrideClass = SideEffect.fromBits) + return self._ensureSetNamed('_sideEffects', '8510', constants.ps.PSETID_COMMON, overrideClass = SideEffect.fromBits) @property def stringEncoding(self): @@ -923,7 +924,7 @@ def stringEncoding(self): else: enc = self.props['3FFD0003'].value # Now we just need to translate that value. - self.__stringEncoding = getEncodingName(enc) + self.__stringEncoding = lookupCodePage(enc) return self.__stringEncoding @property diff --git a/extract_msg/msg_classes/task.py b/extract_msg/msg_classes/task.py index f6ecc93e..87ac0e07 100644 --- a/extract_msg/msg_classes/task.py +++ b/extract_msg/msg_classes/task.py @@ -87,14 +87,14 @@ def percentComplete(self) -> Optional[float]: Indicates whether a time-flagged Message object is complete. Returns a percentage in decimal form. 1.0 indicates it is complete. """ - return self._ensureSetNamed('_percentComplete', '8102', constants.PSETID_TASK) + return self._ensureSetNamed('_percentComplete', '8102', constants.ps.PSETID_TASK) @property def taskAcceptanceState(self) -> Optional[TaskAcceptance]: """ Indicates the acceptance state of the task. """ - return self._ensureSetNamed('_taskAcceptanceState', '812A', constants.PSETID_TASK, overrideClass = TaskAcceptance) + return self._ensureSetNamed('_taskAcceptanceState', '812A', constants.ps.PSETID_TASK, overrideClass = TaskAcceptance) @property def taskAccepted(self) -> bool: @@ -102,7 +102,7 @@ def taskAccepted(self) -> bool: Indicates whether a task assignee has replied to a tesk request for this task object. Does not indicate if it was accepted or rejected. """ - return self._ensureSetNamed('_taskAccepted', '8108', constants.PSETID_TASK, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('_taskAccepted', '8108', constants.ps.PSETID_TASK, overrideClass = bool, preserveNone = False) @property def taskActualEffort(self) -> Optional[int]: @@ -110,14 +110,14 @@ def taskActualEffort(self) -> Optional[int]: Indicates the number of minutes that the user actually spent working on a task. """ - return self._ensureSetNamed('_taskActualEffort', '8110', constants.PSETID_TASK) + return self._ensureSetNamed('_taskActualEffort', '8110', constants.ps.PSETID_TASK) @property def taskAssigner(self) -> Optional[str]: """ Specifies the name of the user that last assigned the task. """ - return self._ensureSetNamed('_taskAssigner', '8121', constants.PSETID_TASK) + return self._ensureSetNamed('_taskAssigner', '8121', constants.ps.PSETID_TASK) @property def taskAssigners(self) -> Optional[bytes]: @@ -127,28 +127,28 @@ def taskAssigners(self) -> Optional[bytes]: The documentation on this is weird, so I don't know how to parse it. """ - return self._ensureSetNamed('_taskAssigners', '8117', constants.PSETID_TASK) + return self._ensureSetNamed('_taskAssigners', '8117', constants.ps.PSETID_TASK) @property def taskComplete(self) -> bool: """ Indicates if the task is complete. """ - return self._ensureSetNamed('_taskComplete', '811C', constants.PSETID_TASK, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('_taskComplete', '811C', constants.ps.PSETID_TASK, overrideClass = bool, preserveNone = False) @property def taskCustomFlags(self) -> Optional[int]: """ Custom flags set on the task. """ - return self._ensureSetNamed('_taskCustomFlags', '8139', constants.PSETID_TASK) + return self._ensureSetNamed('_taskCustomFlags', '8139', constants.ps.PSETID_TASK) @property def taskDateCompleted(self) -> Optional[datetime.datetime]: """ The date when the user completed work on the task. """ - return self._ensureSetNamed('_taskDateCompleted', '810F', constants.PSETID_TASK) + return self._ensureSetNamed('_taskDateCompleted', '810F', constants.ps.PSETID_TASK) @property def taskDeadOccurrence(self) -> bool: @@ -157,7 +157,7 @@ def taskDeadOccurrence(self) -> bool: False on a new Task object and True when the client generates the last recurring task. """ - return self._ensureSetNamed('_taskDeadOccurrence', '8109', constants.PSETID_TASK, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('_taskDeadOccurrence', '8109', constants.ps.PSETID_TASK, overrideClass = bool, preserveNone = False) @property def taskDueDate(self) -> Optional[datetime.datetime]: @@ -165,14 +165,14 @@ def taskDueDate(self) -> Optional[datetime.datetime]: Specifies the date by which the user expects work on the task to be complete. """ - return self._ensureSetNamed('_taskDueDate', '8105', constants.PSETID_TASK) + return self._ensureSetNamed('_taskDueDate', '8105', constants.ps.PSETID_TASK) @property def taskEstimatedEffort(self) -> Optional[int]: """ Indicates the number of minutes that the user expects to work on a task. """ - return self._ensureSetNamed('_taskEstimatedEffort', '8111', constants.PSETID_TASK) + return self._ensureSetNamed('_taskEstimatedEffort', '8111', constants.ps.PSETID_TASK) @property def taskFCreator(self) -> bool: @@ -181,21 +181,21 @@ def taskFCreator(self) -> bool: the current user or user agent instead of by the processing of a task request. """ - return self._ensureSetNamed('_taskFCreator', '811E', constants.PSETID_TASK, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('_taskFCreator', '811E', constants.ps.PSETID_TASK, overrideClass = bool, preserveNone = False) @property def taskFFixOffline(self) -> bool: """ Indicates whether the value of the taskOwner property is correct. """ - return self._ensureSetNamed('taskFFixOffline', '812C', constants.PSETID_TASK, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('taskFFixOffline', '812C', constants.ps.PSETID_TASK, overrideClass = bool, preserveNone = False) @property def taskFRecurring(self) -> bool: """ Indicates whether the task includes a recurrence pattern. """ - return self._ensureSetNamed('_taskFRecurring', '8126', constants.PSETID_TASK, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('_taskFRecurring', '8126', constants.ps.PSETID_TASK, overrideClass = bool, preserveNone = False) @property def taskGlobalID(self) -> Optional[bytes]: @@ -203,14 +203,14 @@ def taskGlobalID(self) -> Optional[bytes]: Specifies a unique GUID for this task, used to locate an existing task upon receipt of a task response or task update. """ - return self._ensureSetNamed('_taskGlobalID', '8519', constants.PSETID_COMMON) + return self._ensureSetNamed('_taskGlobalID', '8519', constants.ps.PSETID_COMMON) @property def taskHistory(self) -> Optional[TaskHistory]: """ Indicates the type of change that was last made to the Task object. """ - return self._ensureSetNamed('_taskHistory', '811A', constants.PSETID_TASK, overrideClass = TaskHistory) + return self._ensureSetNamed('_taskHistory', '811A', constants.ps.PSETID_TASK, overrideClass = TaskHistory) @property def taskLastDelegate(self) -> Optional[str]: @@ -218,14 +218,14 @@ def taskLastDelegate(self) -> Optional[str]: Contains the name of the user who most recently assigned the task, or the user to whom it was most recently assigned. """ - return self._ensureSetNamed('_taskLastDelegate', '8125', constants.PSETID_TASK) + return self._ensureSetNamed('_taskLastDelegate', '8125', constants.ps.PSETID_TASK) @property def taskLastUpdate(self) -> Optional[datetime.datetime]: """ The date and time of the most recent change made to the task object. """ - return self._ensureSetNamed('_taskLastUpdate', '8115', constants.PSETID_TASK) + return self._ensureSetNamed('_taskLastUpdate', '8115', constants.ps.PSETID_TASK) @property def taskLastUser(self) -> Optional[str]: @@ -233,14 +233,14 @@ def taskLastUser(self) -> Optional[str]: Contains the name of the most recent user to have been the owner of the task. """ - return self._ensureSetNamed('_taskLastUser', '8122', constants.PSETID_TASK) + return self._ensureSetNamed('_taskLastUser', '8122', constants.ps.PSETID_TASK) @property def taskMode(self) -> Optional[TaskMode]: """ Used in a task communication. Should be 0 (UNASSIGNED) on task objects. """ - return self._ensureSetNamed('_taskMode', '8518', constants.PSETID_COMMON, overrideClass = TaskMode) + return self._ensureSetNamed('_taskMode', '8518', constants.ps.PSETID_COMMON, overrideClass = TaskMode) @property def taskMultipleRecipients(self) -> Optional[Set[TaskMultipleRecipients]]: @@ -248,7 +248,7 @@ def taskMultipleRecipients(self) -> Optional[Set[TaskMultipleRecipients]]: Returns a set of flags that specify optimization hints about the recipients of a Task object. """ - return self._ensureSetNamed('_taskMultipleRecipients', '8120', constants.PSETID_TASK, overrideClass = TaskMultipleRecipients.fromBits) + return self._ensureSetNamed('_taskMultipleRecipients', '8120', constants.ps.PSETID_TASK, overrideClass = TaskMultipleRecipients.fromBits) @property def taskNoCompute(self) -> Optional[bool]: @@ -256,28 +256,28 @@ def taskNoCompute(self) -> Optional[bool]: This value is not used and has no impact on a Task, but is provided for completeness. """ - return self._ensureSetNamed('_taskNoCompute', '8124', constants.PSETID_TASK) + return self._ensureSetNamed('_taskNoCompute', '8124', constants.ps.PSETID_TASK) @property def taskOrdinal(self) -> Optional[int]: """ Specifies a number that aids custom sorting of Task objects. """ - return self._ensureSetNamed('_taskOrdinal', '8123', constants.PSETID_TASK, overrideClass = unsignedToSignedInt) + return self._ensureSetNamed('_taskOrdinal', '8123', constants.ps.PSETID_TASK, overrideClass = unsignedToSignedInt) @property def taskOwner(self) -> Optional[str]: """ Contains the name of the owner of the task. """ - return self._ensureSetNamed('_taskOwner', '811F', constants.PSETID_TASK) + return self._ensureSetNamed('_taskOwner', '811F', constants.ps.PSETID_TASK) @property def taskOwnership(self) -> Optional[TaskOwnership]: """ Contains the name of the owner of the task. """ - return self._ensureSetNamed('_taskOwnership', '8129', constants.PSETID_TASK, overrideClass = TaskOwnership) + return self._ensureSetNamed('_taskOwnership', '8129', constants.ps.PSETID_TASK, overrideClass = TaskOwnership) @property def taskRecurrence(self) -> Optional[RecurrencePattern]: @@ -285,14 +285,14 @@ def taskRecurrence(self) -> Optional[RecurrencePattern]: Contains a RecurrencePattern structure that provides information about recurring tasks. """ - return self._ensureSetNamed('_taskRecurrence', '8116', constants.PSETID_TASK, overrideClass = RecurrencePattern) + return self._ensureSetNamed('_taskRecurrence', '8116', constants.ps.PSETID_TASK, overrideClass = RecurrencePattern) @property def taskResetReminder(self) -> bool: """ Indicates whether future recurring tasks need reminders. """ - return self._ensureSetNamed('_taskResetReminder', '8107', constants.PSETID_TASK, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('_taskResetReminder', '8107', constants.ps.PSETID_TASK, overrideClass = bool, preserveNone = False) @property def taskRole(self) -> Optional[str]: @@ -300,28 +300,28 @@ def taskRole(self) -> Optional[str]: This value is not used and has no impact on a Task, but is provided for completeness. """ - return self._ensureSetNamed('_taskRole', '8127', constants.PSETID_TASK) + return self._ensureSetNamed('_taskRole', '8127', constants.ps.PSETID_TASK) @property def taskStartDate(self) -> Optional[datetime.datetime]: """ Specifies the date on which the user expects work on the task to begin. """ - return self._ensureSetNamed('_taskStartDate', '8104', constants.PSETID_TASK) + return self._ensureSetNamed('_taskStartDate', '8104', constants.ps.PSETID_TASK) @property def taskState(self) -> Optional[TaskState]: """ Indicates the current assignment state of the Task object. """ - return self._ensureSetNamed('_taskState', '8113', constants.PSETID_TASK, overrideClass = TaskState) + return self._ensureSetNamed('_taskState', '8113', constants.ps.PSETID_TASK, overrideClass = TaskState) @property def taskStatus(self) -> Optional[TaskStatus]: """ The completion status of a task. """ - return self._ensureSetNamed('_taskStatus', '8101', constants.PSETID_TASK, overrideClass = TaskStatus) + return self._ensureSetNamed('_taskStatus', '8101', constants.ps.PSETID_TASK, overrideClass = TaskStatus) @property def taskStatusOnComplete(self) -> bool: @@ -329,7 +329,7 @@ def taskStatusOnComplete(self) -> bool: Indicates whether the task assignee has been requested to send an email message upon completion of the assigned task. """ - return self._ensureSetNamed('_taskStatusOnComplete', '8119', constants.PSETID_TASK, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('_taskStatusOnComplete', '8119', constants.ps.PSETID_TASK, overrideClass = bool, preserveNone = False) @property def taskUpdates(self) -> bool: @@ -337,14 +337,14 @@ def taskUpdates(self) -> bool: Indicates whether the task assignee has been requested to send a task update when the assigned Task object changes. """ - return self._ensureSetNamed('_taskUpdates', '811B', constants.PSETID_TASK, overrideClass = bool, preserveNone = False) + return self._ensureSetNamed('_taskUpdates', '811B', constants.ps.PSETID_TASK, overrideClass = bool, preserveNone = False) @property def taskVersion(self) -> Optional[int]: """ Indicates which copy is the latest update of a Task object. """ - return self._ensureSetNamed('_taskVersion', '8112', constants.PSETID_TASK) + return self._ensureSetNamed('_taskVersion', '8112', constants.ps.PSETID_TASK) @property def teamTask(self) -> Optional[bool]: @@ -352,4 +352,4 @@ def teamTask(self) -> Optional[bool]: This value is not used and has no impact on a Task, but is provided for completeness. """ - return self._ensureSetNamed('_teamTask', '8103', constants.PSETID_TASK) + return self._ensureSetNamed('_teamTask', '8103', constants.ps.PSETID_TASK) diff --git a/extract_msg/msg_classes/task_request.py b/extract_msg/msg_classes/task_request.py index 8550d0ca..dbda75d1 100644 --- a/extract_msg/msg_classes/task_request.py +++ b/extract_msg/msg_classes/task_request.py @@ -66,7 +66,7 @@ def taskMode(self) -> Optional[TaskMode]: """ The assignment status of the embedded Task object. """ - return self._ensureSetNamed('_taskMode', '8518', constants.PSETID_COMMON, overrideClass = TaskMode) + return self._ensureSetNamed('_taskMode', '8518', constants.ps.PSETID_COMMON, overrideClass = TaskMode) @property def taskObject(self) -> Task: diff --git a/extract_msg/ole_writer.py b/extract_msg/ole_writer.py index dd8a6967..7158d865 100644 --- a/extract_msg/ole_writer.py +++ b/extract_msg/ole_writer.py @@ -69,7 +69,7 @@ def toBytes(self): nameBytes = self.name.encode('utf-16-le') - return constants.ST_CF_DIR_ENTRY.pack( + return constants.st.ST_CF_DIR_ENTRY.pack( nameBytes, len(nameBytes) + 2, self.type, @@ -435,25 +435,25 @@ def _writeBeginning(self, f) -> int: # Reserved. f.write(b'\x00\x00\x00\x00\x00\x00') # Number of directory sectors. Version 3 says this *must* be 0. - f.write(constants.ST_LE_UI32.pack(0)) + f.write(constants.st.ST_LE_UI32.pack(0)) # Number of FAT sectors. - f.write(constants.ST_LE_UI32.pack(numFat)) + f.write(constants.st.ST_LE_UI32.pack(numFat)) # First directory sector location (Sector for the directory stream). # We place that right after the DIFAT and FAT. - f.write(constants.ST_LE_UI32.pack(numFat + numDifat)) + f.write(constants.st.ST_LE_UI32.pack(numFat + numDifat)) # Transation signature number. f.write(b'\x00\x00\x00\x00') # Mini stream cutoff size. f.write(b'\x00\x10\x00\x00') # First mini FAT sector location. - f.write(constants.ST_LE_UI32.pack((numFat + numDifat + ceilDiv(self.__dirEntryCount, 4)) if self.__numMinifat > 0 else 0xFFFFFFFE)) + f.write(constants.st.ST_LE_UI32.pack((numFat + numDifat + ceilDiv(self.__dirEntryCount, 4)) if self.__numMinifat > 0 else 0xFFFFFFFE)) # Number of mini FAT sectors. - f.write(constants.ST_LE_UI32.pack(ceilDiv(self.__numMinifatSectors, 128))) + f.write(constants.st.ST_LE_UI32.pack(ceilDiv(self.__numMinifatSectors, 128))) # First DIFAT sector location. If there are none, set to 0xFFFFFFFE (End # of chain). - f.write(constants.ST_LE_UI32.pack(0 if numDifat else 0xFFFFFFFE)) + f.write(constants.st.ST_LE_UI32.pack(0 if numDifat else 0xFFFFFFFE)) # Number of DIFAT sectors. - f.write(constants.ST_LE_UI32.pack(numDifat)) + f.write(constants.st.ST_LE_UI32.pack(numDifat)) # To make life easier on me, I'm having the code start with the DIFAT # followed by the FAT sectors, as I can write them all at once before @@ -464,9 +464,9 @@ def _writeBeginning(self, f) -> int: # This kind of sucks to code, ngl. if x > 109 and (x - 109) % 127 == 0: # If we are at the end of a DIFAT sector, write the jump. - f.write(constants.ST_LE_UI32.pack((x - 109) // 127)) + f.write(constants.st.ST_LE_UI32.pack((x - 109) // 127)) # Write the next FAT sector location. - f.write(constants.ST_LE_UI32.pack(x + numDifat)) + f.write(constants.st.ST_LE_UI32.pack(x + numDifat)) # Finally, fill out the last DIFAT sector with null entries. if numFat > 109: @@ -488,7 +488,7 @@ def _writeBeginning(self, f) -> int: # Fill in the values for the directory stream. for x in range(offset + 1, offset + ceilDiv(self.__dirEntryCount, 4)): - f.write(constants.ST_LE_UI32.pack(x)) + f.write(constants.st.ST_LE_UI32.pack(x)) # Write the end of chain marker. f.write(b'\xFE\xFF\xFF\xFF') @@ -499,7 +499,7 @@ def _writeBeginning(self, f) -> int: if self.__numMinifatSectors > 0: # Mini FAT chain. for x in range(offset + 1, offset + ceilDiv(self.__numMinifat, 16)): - f.write(constants.ST_LE_UI32.pack(x)) + f.write(constants.st.ST_LE_UI32.pack(x)) # Write the end of chain marker. f.write(b'\xFE\xFF\xFF\xFF') @@ -508,7 +508,7 @@ def _writeBeginning(self, f) -> int: # The mini stream sectors. for x in range(offset + 1, offset + self.__numMinifat): - f.write(constants.ST_LE_UI32.pack(x)) + f.write(constants.st.ST_LE_UI32.pack(x)) # Write the end of chain marker. f.write(b'\xFE\xFF\xFF\xFF') @@ -523,7 +523,7 @@ def _writeBeginning(self, f) -> int: size = ceilDiv(len(entry.data), 512) entry.startingSectorLocation = offset for x in range(offset + 1, offset + size): - f.write(constants.ST_LE_UI32.pack(x)) + f.write(constants.st.ST_LE_UI32.pack(x)) # Write the end of chain marker. f.write(b'\xFE\xFF\xFF\xFF') @@ -576,7 +576,7 @@ def _writeMini(self, f, entries : List[DirectoryEntry]) -> None: if x.type == DirectoryEntryType.STREAM and len(x.data) < 4096: size = ceilDiv(len(x.data), 64) for x in range(currentSector + 1, currentSector + size): - f.write(constants.ST_LE_UI32.pack(x)) + f.write(constants.st.ST_LE_UI32.pack(x)) if size > 0: f.write(b'\xFE\xFF\xFF\xFF') currentSector += size @@ -878,7 +878,7 @@ def renameEntry(self, path, newName : str) -> None: # First, validate the new name. if not isinstance(newName, str): raise ValueError('New name must be a string.') - if constants.RE_INVALID_OLE_PATH.search(newName): + if constants.re.INVALID_OLE_PATH.search(newName): raise ValueError('Invalid character(s) in new name. Must not contain the following characters: \\//!:') if len(newName) > 31: raise ValueError('New name must be less than 32 characters.') diff --git a/extract_msg/properties/named.py b/extract_msg/properties/named.py index f28f6598..737ec6b7 100644 --- a/extract_msg/properties/named.py +++ b/extract_msg/properties/named.py @@ -56,10 +56,10 @@ def __init__(self, msg): # Check that we even have any entries. If there are none, nothing to do. if entryStream: - guids = tuple([None, constants.PS_MAPI, constants.PS_PUBLIC_STRINGS] + [bytesToGuid(x) for x in divide(guidStream, 16)]) + guids = tuple([None, constants.ps.PS_MAPI, constants.ps.PS_PUBLIC_STRINGS] + [bytesToGuid(x) for x in divide(guidStream, 16)]) entries = [] for rawStream in divide(entryStream, 8): - tmp = constants.STNP_ENT.unpack(rawStream) + tmp = constants.st.STNP_ENT.unpack(rawStream) entry = { 'id': tmp[0], 'pid': tmp[2], @@ -118,7 +118,7 @@ def __getName(self, offset : int) -> str: raise ValueError('Failed to parse named property: offset was not in string stream.') # Get the length, in bytes, of the string. - length = constants.STNP_NAM.unpack(self.namesStream[offset:offset + 4])[0] + length = constants.st.STNP_NAM.unpack(self.namesStream[offset:offset + 4])[0] offset += 4 # Make sure the string can be read entirely. If it can't, something was @@ -348,7 +348,7 @@ def __init__(self, entry, name): # generated by certain versions of Outlook. As such, a little bit of # additional code will need to run to determine exactly what the stream # ID should be if it is in that property set. - if self.guid == constants.PS_INTERNET_HEADERS: + if self.guid == constants.ps.PS_INTERNET_HEADERS: # To be sure if it needs to be lower the most effective method would # be to just get the Stream ID and then check if the entry is in # there. If it isn't, then check the regular case and see. If it is diff --git a/extract_msg/properties/prop.py b/extract_msg/properties/prop.py index fcb80956..a645c673 100644 --- a/extract_msg/properties/prop.py +++ b/extract_msg/properties/prop.py @@ -24,7 +24,7 @@ def createProp(data : bytes) -> 'PropBase': - temp = constants.ST2.unpack(data)[0] + temp = constants.st.ST2.unpack(data)[0] if temp in constants.FIXED_LENGTH_PROPS: return FixedLengthProp(data) else: @@ -42,7 +42,7 @@ class PropBase: def __init__(self, data : bytes): self.__rawData = data self.__name = properHex(data[3::-1]).upper() - self.__type, self.__flags = constants.ST2.unpack(data) + self.__type, self.__flags = constants.st.ST2.unpack(data) self.__fm = self.__flags & 1 == 1 self.__fr = self.__flags & 2 == 2 self.__fw = self.__flags & 4 == 4 @@ -106,7 +106,7 @@ class FixedLengthProp(PropBase): def __init__(self, data : bytes): super().__init__(data) - self.__value = self.parseType(self.type, constants.STFIX.unpack(data)[0]) + self.__value = self.parseType(self.type, constants.st.STFIX.unpack(data)[0]) def parseType(self, _type : int, stream : bytes) -> Any: """ @@ -126,20 +126,20 @@ def parseType(self, _type : int, stream : bytes) -> Any: logger.warning('Property type is PtypNull, but is not equal to 0.') value = None elif _type == 0x0002: # PtypInteger16 - value = constants.STI16.unpack(value)[0] + value = constants.st.STI16.unpack(value)[0] elif _type == 0x0003: # PtypInteger32 - value = constants.STI32.unpack(value)[0] + value = constants.st.STI32.unpack(value)[0] elif _type == 0x0004: # PtypFloating32 - value = constants.STF32.unpack(value)[0] + value = constants.st.STF32.unpack(value)[0] elif _type == 0x0005: # PtypFloating64 - value = constants.STF64.unpack(value)[0] + value = constants.st.STF64.unpack(value)[0] elif _type == 0x0006: # PtypCurrency - value = (constants.STI64.unpack(value))[0] / 10000.0 + value = (constants.st.STI64.unpack(value))[0] / 10000.0 elif _type == 0x0007: # PtypFloatingTime - value = constants.STF64.unpack(value)[0] + value = constants.st.STF64.unpack(value)[0] return constants.PYTPFLOATINGTIME_START + datetime.timedelta(days = value) elif _type == 0x000A: # PtypErrorCode - value = constants.STI32.unpack(value)[0] + value = constants.st.STI32.unpack(value)[0] try: value = ErrorCodeType(value) except ValueError: @@ -152,11 +152,11 @@ def parseType(self, _type : int, stream : bytes) -> Any: except ValueError: pass elif _type == 0x000B: # PtypBoolean - value = constants.ST3.unpack(value)[0] == 1 + value = constants.st.ST3.unpack(value)[0] == 1 elif _type == 0x0014: # PtypInteger64 - value = constants.STI64.unpack(value)[0] + value = constants.st.STI64.unpack(value)[0] elif _type == 0x0040: # PtypTime - rawTime = constants.ST3.unpack(value)[0] + rawTime = constants.st.ST3.unpack(value)[0] try: value = filetimeToDatetime(rawTime) except ValueError as e: @@ -182,7 +182,7 @@ class VariableLengthProp(PropBase): def __init__(self, data : bytes): super().__init__(data) - self.__length, self.__reserved = constants.STVAR.unpack(data) + self.__length, self.__reserved = constants.st.STVAR.unpack(data) if self.type == 0x001E: self.__realLength = self.__length - 1 elif self.type == 0x001F: diff --git a/extract_msg/properties/properties_store.py b/extract_msg/properties/properties_store.py index abffb0b4..c15afdac 100644 --- a/extract_msg/properties/properties_store.py +++ b/extract_msg/properties/properties_store.py @@ -49,10 +49,10 @@ def __init__(self, data : Optional[bytes], _type : Optional[PropertiesType] = No self.__intel = Intelligence.SMART if _type == PropertiesType.MESSAGE: skip = 32 - self.__nrid, self.__naid, self.__rc, self.__ac = constants.ST1.unpack(self.__rawData[:24]) + self.__nrid, self.__naid, self.__rc, self.__ac = constants.st.ST1.unpack(self.__rawData[:24]) elif _type == PropertiesType.MESSAGE_EMBED: skip = 24 - self.__nrid, self.__naid, self.__rc, self.__ac = constants.ST1.unpack(self.__rawData[:24]) + self.__nrid, self.__naid, self.__rc, self.__ac = constants.st.ST1.unpack(self.__rawData[:24]) else: skip = 8 else: diff --git a/extract_msg/structures/_helpers.py b/extract_msg/structures/_helpers.py index a29d074f..7e3331cd 100644 --- a/extract_msg/structures/_helpers.py +++ b/extract_msg/structures/_helpers.py @@ -25,27 +25,27 @@ def __init__(self, *args, littleEndian = True, **kwargs): super().__init__(*args, **kwargs) self.__le = bool(littleEndian) if self.__le: - self.__int8_t = constants.ST_LE_I8 - self.__int16_t = constants.ST_LE_I16 - self.__int32_t = constants.ST_LE_I32 - self.__int64_t = constants.ST_LE_I64 - self.__uint8_t = constants.ST_LE_UI8 - self.__uint16_t = constants.ST_LE_UI16 - self.__uint32_t = constants.ST_LE_UI32 - self.__uint64_t = constants.ST_LE_UI64 - self.__float_t = constants.ST_LE_F32 - self.__double_t = constants.ST_LE_F64 + self.__int8_t = constants.st.ST_LE_I8 + self.__int16_t = constants.st.ST_LE_I16 + self.__int32_t = constants.st.ST_LE_I32 + self.__int64_t = constants.st.ST_LE_I64 + self.__uint8_t = constants.st.ST_LE_UI8 + self.__uint16_t = constants.st.ST_LE_UI16 + self.__uint32_t = constants.st.ST_LE_UI32 + self.__uint64_t = constants.st.ST_LE_UI64 + self.__float_t = constants.st.ST_LE_F32 + self.__double_t = constants.st.ST_LE_F64 else: - self.__int8_t = constants.ST_BE_I8 - self.__int16_t = constants.ST_BE_I16 - self.__int32_t = constants.ST_BE_I32 - self.__int64_t = constants.ST_BE_I64 - self.__uint8_t = constants.ST_BE_UI8 - self.__uint16_t = constants.ST_BE_UI16 - self.__uint32_t = constants.ST_BE_UI32 - self.__uint64_t = constants.ST_BE_UI64 - self.__float_t = constants.ST_BE_F32 - self.__double_t = constants.ST_BE_F64 + self.__int8_t = constants.st.ST_BE_I8 + self.__int16_t = constants.st.ST_BE_I16 + self.__int32_t = constants.st.ST_BE_I32 + self.__int64_t = constants.st.ST_BE_I64 + self.__uint8_t = constants.st.ST_BE_UI8 + self.__uint16_t = constants.st.ST_BE_UI16 + self.__uint32_t = constants.st.ST_BE_UI32 + self.__uint64_t = constants.st.ST_BE_UI64 + self.__float_t = constants.st.ST_BE_F32 + self.__double_t = constants.st.ST_BE_F64 def _readDecodedString(self, encoding, width : int = 1) -> str: """ diff --git a/extract_msg/structures/business_card.py b/extract_msg/structures/business_card.py index 92d3d2e0..24edad88 100644 --- a/extract_msg/structures/business_card.py +++ b/extract_msg/structures/business_card.py @@ -21,7 +21,7 @@ class BusinessCardDisplayDefinition: def __init__(self, data : bytes): self.__rawData = data reader = BytesReader(data) - unpacked = constants.ST_BC_HEAD.unpack(reader.read(13)) + unpacked = constants.st.ST_BC_HEAD.unpack(reader.read(13)) # Because doc says it must be ignored, we don't check the reserved here. reader.read(4) self.__majorVersion = unpacked[0] @@ -139,7 +139,7 @@ def templateID(self) -> BCTemplateID: class FieldInfo: def __init__(self, data : bytes, extraInfo : bytes): self.__raw = data - unpacked = constants.ST_BC_FIELD_INFO.unpack(data) + unpacked = constants.st.ST_BC_FIELD_INFO.unpack(data) self.__textPropertyID = unpacked[0] self.__textFormat = BCTextFormat(unpacked[1]) self.__labelFormat = BCLabelFormat(unpacked[2]) diff --git a/extract_msg/structures/entry_id.py b/extract_msg/structures/entry_id.py index ab0a45c1..0ad03fe3 100644 --- a/extract_msg/structures/entry_id.py +++ b/extract_msg/structures/entry_id.py @@ -222,7 +222,7 @@ def __init__(self, data : bytes): self.__folderType = MessageType(reader.readUnsignedShort()) self.__databaseGuid = bytesToGuid(reader.read(16)) # This entry is 6 bytes, so we pull some shenanigans to unpack it. - self.__globalCounter = constants.ST_LE_UI64.unpack(reader.read(6) + b'\x00\x00') + self.__globalCounter = constants.st.ST_LE_UI64.unpack(reader.read(6) + b'\x00\x00') reader.assertNull(2, 'Pad bytes were not 0.') @property @@ -262,11 +262,11 @@ def __init__(self, data : bytes): self.__messageType = MessageType(reader.readUnsignedShort()) self.__folderDatabaseGuid = bytesToGuid(reader.read(16)) # This entry is 6 bytes, so we pull some shenanigans to unpack it. - self.__folderGlobalCounter = constants.ST_LE_UI64.unpack(reader.read(6) + b'\x00\x00') + self.__folderGlobalCounter = constants.st.ST_LE_UI64.unpack(reader.read(6) + b'\x00\x00') reader.assertNull(2, 'Pad bytes were not 0.') self.__messageDatabaseGuid = bytesToGuid(reader.read(16)) # This entry is 6 bytes, so we pull some shenanigans to unpack it. - self.__messageGlobalCounter = constants.ST_LE_UI64.unpack(reader.read(6) + b'\x00\x00') + self.__messageGlobalCounter = constants.st.ST_LE_UI64.unpack(reader.read(6) + b'\x00\x00') reader.assertNull(2, 'Pad bytes were not 0.') # Not sure why Microsoft decided to say "yes, let's do 2 6-byte integers # followed by 2 pad bits each" instead of just 2 8-byte integers with a @@ -453,7 +453,7 @@ class PermanentEntryID(EntryID): def __init__(self, data : bytes): super().__init__(data) - unpacked = constants.STPEID.unpack(data[:28]) + unpacked = constants.st.STPEID.unpack(data[:28]) if unpacked[0] != 0: raise TypeError(f'Not a PermanentEntryID (expected 0, got {unpacked[0]}).') self.__displayTypeString = DisplayType(unpacked[2]) diff --git a/extract_msg/structures/misc_id.py b/extract_msg/structures/misc_id.py index 166987fd..20011945 100644 --- a/extract_msg/structures/misc_id.py +++ b/extract_msg/structures/misc_id.py @@ -28,9 +28,9 @@ class FolderID: def __init__(self, data : bytes): self.__rawData = data - self.__replicaID = constants.STUI16.unpack(data[:2]) + self.__replicaID = constants.st.STUI16.unpack(data[:2]) # This entry is 6 bytes, so we pull some shenanigans to unpack it. - self.__globalCounter = constants.STUI64.unpack(data[2:8] + b'\x00\x00') + self.__globalCounter = constants.st.STUI64.unpack(data[2:8] + b'\x00\x00') @property def globalCounter(self) -> int: @@ -68,7 +68,7 @@ def __init__(self, data : bytes): self.__byteArrayID = reader.assertRead(expectedBytes, errorMsg) self.__yh = reader.read(1) self.__yl = reader.read(1) - self.__year = constants.ST_BE_UI16.unpack(self.__yh + self.__yl)[0] + self.__year = constants.st.ST_BE_UI16.unpack(self.__yh + self.__yl)[0] self.__month = reader.readUnsignedByte() self.__day = reader.readUnsignedByte() self.__creationTime = filetimeToDatetime(reader.readUnsignedLong()) @@ -141,9 +141,9 @@ class MessageID: def __init__(self, data : bytes): self.__rawData = data - self.__replicaID = constants.STUI16.unpack(data[:2]) + self.__replicaID = constants.st.STUI16.unpack(data[:2]) # This entry is 6 bytes, so we pull some shenanigans to unpack it. - self.__globalCounter = constants.STUI64.unpack(data[2:8] + b'\x00\x00') + self.__globalCounter = constants.st.STUI64.unpack(data[2:8] + b'\x00\x00') @property def globalCounter(self) -> int: @@ -192,7 +192,7 @@ def __init__(self, data : bytes): self.__rawData = data self.__folderID = FolderID(data[1:9]) self.__messageID = MessageID(data[9:17]) - self.__instance = constants.STUI32.unpack(data[17:21]) + self.__instance = constants.st.STUI32.unpack(data[17:21]) @property def folderID(self) -> FolderID: diff --git a/extract_msg/structures/system_time.py b/extract_msg/structures/system_time.py index f5efc750..e9f91067 100644 --- a/extract_msg/structures/system_time.py +++ b/extract_msg/structures/system_time.py @@ -33,7 +33,7 @@ def pack(self) -> bytes: """ Packs the current data into bytes. """ - return constants.ST_SYSTEMTIME.pack(self.year, self.month, + return constants.st.ST_SYSTEMTIME.pack(self.year, self.month, self.dayOfWeek, self.day, self.hour, self.minute, self.second, self.milliseconds) @@ -42,7 +42,7 @@ def unpack(self, data : bytes) -> None: """ Fills out the fields of this instance by unpacking the bytes. """ - unpacked = constants.ST_SYSTEMTIME.unpack(data) + unpacked = constants.st.ST_SYSTEMTIME.unpack(data) self.year = unpacked[0] self.month = unpacked[1] self.dayOfWeek = unpacked[2] diff --git a/extract_msg/structures/time_zone_struct.py b/extract_msg/structures/time_zone_struct.py index c0884e84..f3d97d1a 100644 --- a/extract_msg/structures/time_zone_struct.py +++ b/extract_msg/structures/time_zone_struct.py @@ -14,7 +14,7 @@ class TimeZoneStruct: def __init__(self, data : bytes): self.__rawData = data - unpacked = constants.ST_TZ.unpack(data) + unpacked = constants.st.ST_TZ.unpack(data) self.__bias = unpacked[0] self.__standardBias = unpacked[1] self.__daylightBias = unpacked[2] diff --git a/extract_msg/utils.py b/extract_msg/utils.py index 556a3fc2..79d95bcf 100644 --- a/extract_msg/utils.py +++ b/extract_msg/utils.py @@ -1,5 +1,7 @@ from __future__ import annotations +import extract_msg.encoding + """ Utility functions of extract_msg. """ @@ -21,7 +23,6 @@ 'findWk', 'fromTimeStamp', 'getCommandArgs', - 'getEncodingName', 'hasLen', 'htmlSanitize', 'inputToBytes', @@ -153,7 +154,7 @@ def bytesToGuid(bytesInput : bytes) -> str: """ Converts a bytes instance to a GUID. """ - guidVals = constants.ST_GUID.unpack(bytesInput) + guidVals = constants.st.ST_GUID.unpack(bytesInput) return f'{{{guidVals[0]:08X}-{guidVals[1]:04X}-{guidVals[2]:04X}-{guidVals[3][:2].hex().upper()}-{guidVals[3][2:].hex().upper()}}}' @@ -495,23 +496,6 @@ def getCommandArgs(args) -> argparse.Namespace: return options - -def getEncodingName(codepage : int) -> str: - """ - Returns the name of the encoding with the specified codepage. - - :raises UnknownCodepageError: if the codepage is unrecognized. - :raises UnsupportedEncodingError: if the codepage is not supported. - """ - if codepage not in constants.CODE_PAGES: - raise UnknownCodepageError(str(codepage)) - try: - codecs.lookup(constants.CODE_PAGES[codepage]) - return constants.CODE_PAGES[codepage] - except LookupError: - raise UnsupportedEncodingError(f'The codepage {codepage} ({constants.CODE_PAGES[codepage]}) is not currently supported by your version of Python.') - - def hasLen(obj) -> bool: """ Checks if :param obj: has a __len__ attribute. @@ -531,7 +515,7 @@ def htmlSanitize(inp : str) -> str: inp = inp.replace('\r\n', '\n').replace('\n', '
') # Escape long sections of spaces to ensure they won't be ignored. - inp = constants.RE_HTML_SAN_SPACE.sub((lambda spaces : ' ' * len(spaces.group(0))),inp) + inp = constants.re.HTML_SAN_SPACE.sub((lambda spaces : ' ' * len(spaces.group(0))),inp) return inp @@ -666,21 +650,21 @@ def parseType(_type : int, stream, encoding, extras): logger.warning('Property type is PtypNull, but is not equal to 0.') return None elif _type == 0x0002: # PtypInteger16 - return constants.STI16.unpack(value)[0] + return constants.st.STI16.unpack(value)[0] elif _type == 0x0003: # PtypInteger32 - return constants.STI32.unpack(value)[0] + return constants.st.STI32.unpack(value)[0] elif _type == 0x0004: # PtypFloating32 - return constants.STF32.unpack(value)[0] + return constants.st.STF32.unpack(value)[0] elif _type == 0x0005: # PtypFloating64 - return constants.STF64.unpack(value)[0] + return constants.st.STF64.unpack(value)[0] elif _type == 0x0006: # PtypCurrency - return (constants.STI64.unpack(value)[0]) / 10000.0 + return (constants.st.STI64.unpack(value)[0]) / 10000.0 elif _type == 0x0007: # PtypFloatingTime - value = constants.STF64.unpack(value)[0] + value = constants.st.STF64.unpack(value)[0] return constants.PYTPFLOATINGTIME_START + datetime.timedelta(days = value) elif _type == 0x000A: # PtypErrorCode from .enums import ErrorCode, ErrorCodeType - value = constants.STUI32.unpack(value)[0] + value = constants.st.STUI32.unpack(value)[0] try: value = ErrorCodeType(value) except ValueError: @@ -694,7 +678,7 @@ def parseType(_type : int, stream, encoding, extras): pass return value elif _type == 0x000B: # PtypBoolean - return constants.ST3.unpack(value)[0] == 1 + return constants.st.ST3.unpack(value)[0] == 1 elif _type == 0x000D: # PtypObject/PtypEmbeddedTable # TODO parsing for this. # Wait, that's the extension for an attachment folder, so parsing this @@ -702,18 +686,18 @@ def parseType(_type : int, stream, encoding, extras): # without support for this. raise NotImplementedError('Current version of extract-msg does not support the parsing of PtypObject/PtypEmbeddedTable in this function.') elif _type == 0x0014: # PtypInteger64 - return constants.STI64.unpack(value)[0] + return constants.st.STI64.unpack(value)[0] elif _type == 0x001E: # PtypString8 return value.decode(encoding) elif _type == 0x001F: # PtypString return value.decode('utf-16-le') elif _type == 0x0040: # PtypTime - rawTime = constants.ST3.unpack(value)[0] + rawTime = constants.st.ST3.unpack(value)[0] return filetimeToDatetime(rawTime) elif _type == 0x0048: # PtypGuid return bytesToGuid(value) elif _type == 0x00FB: # PtypServerId - count = constants.STUI16.unpack(value[:2]) + count = constants.st.STUI16.unpack(value[:2]) # If the first byte is a 1 then it uses the ServerID structure. if value[3] == 1: from .structures.misc_id import ServerID @@ -742,7 +726,7 @@ def parseType(_type : int, stream, encoding, extras): return ret elif _type == 0x1102: # PtypMultipleBinary ret = copy.deepcopy(extras) - lengths = tuple(constants.STUI32.unpack(stream[pos*8:(pos+1)*8])[0] for pos in range(len(stream) // 8)) + lengths = tuple(constants.st.STUI32.unpack(stream[pos*8:(pos+1)*8])[0] for pos in range(len(stream) // 8)) lengthLengths = len(lengths) if lengthLengths > lengthExtras: logger.warning(f'Error while parsing multiple type. Expected {lengthLengths} stream{"s" if lengthLengths != 1 else ""}, got {lengthExtras}. Ignoring.') @@ -754,20 +738,20 @@ def parseType(_type : int, stream, encoding, extras): if stream != len(extras): logger.warning(f'Error while parsing multiple type. Expected {stream} entr{"y" if stream == 1 else "ies"}, got {len(extras)}. Ignoring.') if _type == 0x1002: # PtypMultipleInteger16 - return tuple(constants.STMI16.unpack(x)[0] for x in extras) + return tuple(constants.st.STMI16.unpack(x)[0] for x in extras) if _type == 0x1003: # PtypMultipleInteger32 - return tuple(constants.STMI32.unpack(x)[0] for x in extras) + return tuple(constants.st.STMI32.unpack(x)[0] for x in extras) if _type == 0x1004: # PtypMultipleFloating32 - return tuple(constants.STMF32.unpack(x)[0] for x in extras) + return tuple(constants.st.STMF32.unpack(x)[0] for x in extras) if _type == 0x1005: # PtypMultipleFloating64 - return tuple(constants.STMF64.unpack(x)[0] for x in extras) + return tuple(constants.st.STMF64.unpack(x)[0] for x in extras) if _type == 0x1007: # PtypMultipleFloatingTime - values = tuple(constants.STMF64.unpack(x)[0] for x in extras) + values = tuple(constants.st.STMF64.unpack(x)[0] for x in extras) return tuple(constants.PYTPFLOATINGTIME_START + datetime.timedelta(days = amount) for amount in values) if _type == 0x1014: # PtypMultipleInteger64 - return tuple(constants.STMI64.unpack(x)[0] for x in extras) + return tuple(constants.st.STMI64.unpack(x)[0] for x in extras) if _type == 0x1040: # PtypMultipleTime - return tuple(filetimeToUtc(constants.ST3.unpack(x)[0]) for x in extras) + return tuple(filetimeToUtc(constants.st.ST3.unpack(x)[0]) for x in extras) if _type == 0x1048: # PtypMultipleGuid return tuple(bytesToGuid(x) for x in extras) else: @@ -985,7 +969,7 @@ def unsignedToSignedInt(uInt : int) -> int: raise ValueError('Value is too large.') if uInt < 0: raise ValueError('Value is already signed.') - return constants.STI32.unpack(constants.STUI32.pack(uInt))[0] + return constants.st.STI32.unpack(constants.st.STUI32.pack(uInt))[0] def unwrapMsg(msg : MSGFile) -> Dict: From 5f3f20620b0e582d4d36e45c3191f281c020b905 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Wed, 21 Jun 2023 12:27:05 -0700 Subject: [PATCH 46/89] Update to require upcoming version of RTFDE --- CHANGELOG.md | 4 +++- extract_msg/enums.py | 18 ++++++++------ extract_msg/msg_classes/message_base.py | 31 ++++--------------------- requirements.txt | 2 +- 4 files changed, 20 insertions(+), 35 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 41fc9bf6..c2e18e72 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,9 +20,11 @@ * Entirely reoganized the way attachments are initialized, including the class that will be used in various circumstances. Embedded MSG files, custom attachments, and web attachments will all use dedicated classes that are subclasses of AttachmentBase. * With this change, the way to specify a new Attachment class is to override the function used when creating attachments. This can be done by passing `attachmentInit = myFunction` as an option to `openMsg`. This function MUST return an instance of AttachmentBase. * Added first implementation of web attachments. Saving is not currently possible, but basic relevent property access is now possible. Saving will not be stopped by this attachment if `skipNotImplemented = True` is passed to the save function. -* Changed the option to suppress RTFDE errors to fall under the `ErrorBehavior` enum. Usage of the original option will be allowable, but is being marked as deprecated. However, it is still a dedicated option from the command line. +* Changed the option to suppress `RTFDE` errors to fall under the `ErrorBehavior` enum. Usage of the original option will be allowable, but is being marked as deprecated. However, it is still a dedicated option from the command line. + * Also fixed the option not properly ignoring some RTFDE errors, specifically the ones that it is normal for the module to throw. * Removed some constants that are not used by the module. * Added the `encoding` submodule for encoding tasks, including proper support for Microsoft's implementation of cp950. This gets added to the codecs list as windows-950. +* Updated to support `RTFDE` version `0.1.0`. Users encountering random erros from that module should find that those errors have disappeared. If you get errors from it still, bring up the issue on their GitHub. **v0.41.5** * Fixed an issue from version `0.41.3` where the header being present but missing the `From` field would cause an exception. diff --git a/extract_msg/enums.py b/extract_msg/enums.py index a9492401..511282b4 100644 --- a/extract_msg/enums.py +++ b/extract_msg/enums.py @@ -520,15 +520,19 @@ class ErrorBehavior(enum.IntFlag): ATTACH_SUPPRESS_ALL: Silence the exception for NotImplementedError and for broken attachments. STANDARDS_VIOLATION: Silences StandardViolationError where acceptable. - RTFDE: Silences errors from RTFDE. + RTFDE_UNKNOWN_ERROR: Silences errors from RTFDE that are not normal. + RTFDE_MALFORMED: Silences errors about malformed RTF data. + RTFDE: Silences all errors from RTFDE. SUPPRESS_ALL: Silences all of the above. """ - THROW = 0b000 - ATTACH_NOT_IMPLEMENTED = 0b001 - ATTACH_BROKEN = 0b010 - ATTACH_SUPPRESS_ALL = 0b011 - STANDARDS_VIOLATION = 0b100 - RTFDE = 0b1000 + THROW = 0b00000 + ATTACH_NOT_IMPLEMENTED = 0b00001 + ATTACH_BROKEN = 0b00010 + ATTACH_SUPPRESS_ALL = 0b00011 + STANDARDS_VIOLATION = 0b00100 + RTFDE_UNKNOWN_ERROR = 0b01000 + RTFDE_MALFORMED = 0b10000 + RTFDE = 0b11000 SUPPRESS_ALL = 0b1111 diff --git a/extract_msg/msg_classes/message_base.py b/extract_msg/msg_classes/message_base.py index 3e21f04f..39eb503b 100644 --- a/extract_msg/msg_classes/message_base.py +++ b/extract_msg/msg_classes/message_base.py @@ -206,7 +206,7 @@ def deencapsulateBody(self, rtfBody : bytes, bodyType : DeencapType) -> Optional logger.exception('Custom deencapsulation function reported data is not encapsulated.') else: if self.deencapsulatedRtf and self.deencapsulatedRtf.content_type == 'html': - return self.deencapsulatedRtf.html.encode('utf-8') + return self.deencapsulatedRtf.html if bodyType == DeencapType.PLAIN: logger.info('Could not deencapsulate plain text from RTF body.') @@ -970,41 +970,20 @@ def deencapsulatedRtf(self) -> Optional[RTFDE.DeEncapsulator]: body = body[:-1] try: - try: - self._deencapsultor = RTFDE.DeEncapsulator(body) - except UnicodeDecodeError: - # There is a known issue that bytes are not well decoded - # by RTFDE right now, so let's see if we can't manually - # decode it and see if that will work. - # - # There is also the fact that it is decoded *at all* - # before binary data is stripped out. This data should - # almost certainly be stripped out, so let's log it and - # then log if we removed any of them before trying this. - logger.warning(f'RTFDE failed to decode rtfBody for message with subject "{self.subject}". Attempting to cut out unnecessary data and override decoding.') - - match = constants.re.BIN.search(body) - # Because we are going to be actively removing things, - # we want to search the entire thing over again. - while match: - logger.info(f'Found match to bin data starting at location {match.start()}. Replacing with nothing.') - length = int(match.group(1)) - # Extract the entire binary section and replace it. - body = body.replace(body[match.start():match.end() + length], b'', 1) - match = constants.re.BIN.search(body) - - self._deencapsultor = RTFDE.DeEncapsulator(body.decode(chardet.detect(body)['encoding'])) + self._deencapsultor = RTFDE.DeEncapsulator(body) self._deencapsultor.deencapsulate() except RTFDE.exceptions.NotEncapsulatedRtf as e: logger.debug('RTF body is not encapsulated.') self._deencapsultor = None except RTFDE.exceptions.MalformedEncapsulatedRtf as _e: + if not (self.errorBehavior & ErrorBehavior.RTFDE_MALFORMED): + raise logger.info('RTF body contains malformed encapsulated content.') self._deencapsultor = None except Exception: # If we are just ignoring the errors, log it then set to # None. Otherwise, continue the exception. - if not (self.errorBehavior & ErrorBehavior.RTFDE): + if not (self.errorBehavior & ErrorBehavior.RTFDE_UNKNOWN_ERROR): raise logger.exception('Unhandled error happened while using RTFDE. You have choosen to ignore these errors.') self._deencapsultor = None diff --git a/requirements.txt b/requirements.txt index 3125d5d8..ee75d38f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,6 +6,6 @@ tzlocal>=4.2,<6 compressed_rtf>=1.0.6,<2 ebcdic>=1.1.1,<2 beautifulsoup4>=4.11.1,<4.13 -RTFDE==0.0.2 +RTFDE>=0.1.0,<0.2 chardet>=4.0.0,<6 red-black-tree-mod==1.20 From 3d81489910ceb76fc833d3157d145b2818b15ee1 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Wed, 21 Jun 2023 13:39:08 -0700 Subject: [PATCH 47/89] Add support for sticky note --- extract_msg/enums.py | 9 +++++ extract_msg/msg_classes/__init__.py | 2 + extract_msg/msg_classes/sticky_note.py | 55 ++++++++++++++++++++++++++ extract_msg/open_msg.py | 5 ++- 4 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 extract_msg/msg_classes/sticky_note.py diff --git a/extract_msg/enums.py b/extract_msg/enums.py index 511282b4..b01e3518 100644 --- a/extract_msg/enums.py +++ b/extract_msg/enums.py @@ -1299,6 +1299,15 @@ class NamedPropertyType(enum.Enum): +class NoteColor(enum.Enum): + BLUE = 0 + GREEN = 1 + PINK = 2 + YELLOW = 3 + WHITE = 4 + + + class OORBodyFormat(enum.Enum): """ The body format for One Off Recipients. diff --git a/extract_msg/msg_classes/__init__.py b/extract_msg/msg_classes/__init__.py index 0d5c9efa..989e3b8e 100644 --- a/extract_msg/msg_classes/__init__.py +++ b/extract_msg/msg_classes/__init__.py @@ -20,6 +20,7 @@ 'MessageSignedBase', 'MSGFile', 'Post', + 'StickyNote', 'Task', 'TaskRequest', ] @@ -41,5 +42,6 @@ from .message_signed_base import MessageSignedBase from .msg import MSGFile from .post import Post +from .sticky_note import StickyNote from .task import Task from .task_request import TaskRequest \ No newline at end of file diff --git a/extract_msg/msg_classes/sticky_note.py b/extract_msg/msg_classes/sticky_note.py new file mode 100644 index 00000000..3c2d300d --- /dev/null +++ b/extract_msg/msg_classes/sticky_note.py @@ -0,0 +1,55 @@ +from typing import Optional + +from ..constants import HEADER_FORMAT_TYPE +from ..constants.ps import PSETID_NOTE +from ..enums import NoteColor +from .message_base import MessageBase + + +# Note: Sticky note is basically just text and a background color, so we don't +# really do much when saving it. +class StickyNote(MessageBase): + """ + A sticky note. + """ + + @property + def headerFormatProperties(self) -> HEADER_FORMAT_TYPE: + return None + + @property + def noteColor(self) -> Optional[NoteColor]: + """ + The color of the sticky note. + """ + return self._ensureSetNamed('_noteColor', '8B00', PSETID_NOTE, preserveNone = True, overrideClass = NoteColor) + + @property + def noteHeight(self) -> Optional[int]: + """ + The height of the note window, in pixels. + """ + return self._ensureSetNamed('_noteWidth', '8B03', PSETID_NOTE) + + @property + def noteWidth(self) -> Optional[int]: + """ + The width of the note window, in pixels. + """ + return self._ensureSetNamed('_noteWidth', '8B02', PSETID_NOTE) + + @property + def noteX(self) -> Optional[int]: + """ + The distance, in pixels, from the left edge of the screen that a user + interface displays the note. + """ + return self._ensureSetNamed('_noteX', '8B02', PSETID_NOTE) + + @property + def noteY(self) -> Optional[int]: + """ + The distance, in pixels, from the top edge of the screen that a user + interafce displays the note. + """ + return self._ensureSetNamed('_noteY', '8B02', PSETID_NOTE) \ No newline at end of file diff --git a/extract_msg/open_msg.py b/extract_msg/open_msg.py index 489552ae..48ef9832 100644 --- a/extract_msg/open_msg.py +++ b/extract_msg/open_msg.py @@ -77,7 +77,7 @@ def openMsg(path, **kwargs) -> MSGFile: from .msg_classes import ( AppointmentMeeting, Contact, MeetingCancellation, MeetingException, MeetingForwardNotification, MeetingRequest, MeetingResponse, - Message, MSGFile, MessageSigned, Post, Task, TaskRequest + Message, MSGFile, MessageSigned, Post, StickyNote, Task, TaskRequest ) # When the initial MSG file is opened, it should *always* delay attachments @@ -137,6 +137,9 @@ def openMsg(path, **kwargs) -> MSGFile: elif classType.startswith('ipm.schedule.meeting.resp'): msg.close() return MeetingResponse(path, **kwargs) + elif classType.startswith('ipm.stickynote'): + msg.close() + return StickyNote(path, **kwargs) elif classType.startswith('ipm.taskrequest'): msg.close() return TaskRequest(path, **kwargs) From 516bb4959cea352a5981c420cbd71f6fe2a15f65 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Wed, 21 Jun 2023 13:45:01 -0700 Subject: [PATCH 48/89] Fix bugs with opening MSG files --- CHANGELOG.md | 5 + extract_msg/__init__.py | 2 +- extract_msg/msg_classes/contact.py | 27 ----- extract_msg/msg_classes/message_base.py | 52 +++++---- .../msg_classes/message_signed_base.py | 5 - extract_msg/msg_classes/msg.py | 106 ++++++++++-------- requirements.txt | 1 - 7 files changed, 96 insertions(+), 102 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c2e18e72..38663abc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,11 @@ * Removed some constants that are not used by the module. * Added the `encoding` submodule for encoding tasks, including proper support for Microsoft's implementation of cp950. This gets added to the codecs list as windows-950. * Updated to support `RTFDE` version `0.1.0`. Users encountering random erros from that module should find that those errors have disappeared. If you get errors from it still, bring up the issue on their GitHub. +* Fixed bug that would cause weird behavior if you gave an empty string as the path for an MSG file. +* Added support for `IPM.StickyNote`. +* Fixed an issue that would cause MSG file to never close if an error happened during any of the `__init__` functions for MSG classes. +* removed unneeded `chardet` dependency. +* Removed `Contact.__init__` as it didn't provide any unique behavior. **v0.41.5** * Fixed an issue from version `0.41.3` where the header being present but missing the `From` field would cause an exception. diff --git a/extract_msg/__init__.py b/extract_msg/__init__.py index f3da265e..4676a8cc 100644 --- a/extract_msg/__init__.py +++ b/extract_msg/__init__.py @@ -27,7 +27,7 @@ # along with this program. If not, see . __author__ = 'Destiny Peterson & Matthew Walker' -__date__ = '2023-06-20' +__date__ = '2023-06-21' __version__ = '0.42.0' __all__ = [ diff --git a/extract_msg/msg_classes/contact.py b/extract_msg/msg_classes/contact.py index 5d7435bd..8b11aac6 100644 --- a/extract_msg/msg_classes/contact.py +++ b/extract_msg/msg_classes/contact.py @@ -27,33 +27,6 @@ class Contact(MessageBase): Class used for parsing contacts. """ - def __init__(self, path, **kwargs): - """ - :param path: path to the msg file in the system or is the raw msg file. - :param prefix: used for extracting embeded msg files inside the main - one. Do not set manually unless you know what you are doing. - :param parentMsg: Used for synchronizing named properties instances. Do - not set this unless you know what you are doing. - :param initAttachment: Optional, the method used when creating an - attachment for an MSG file. MUST be a function that takes 2 - arguments (the MSGFile instance and the directory in the MSG file - where the attachment is) and returns an instance of AttachmentBase. - :param delayAttachments: optional, delays the initialization of - attachments until the user attempts to retrieve them. Allows MSG - files with bad attachments to be initialized so the other data can - be retrieved. - :param filename: optional, the filename to be used by default when - saving. - :param errorBehavior: Optional, the behavior to use in the - event of an error when parsing the attachments. - :param overrideEncoding: optional, an encoding to use instead of the one - specified by the msg file. Do not report encoding errors caused by - this. - """ - super().__init__(path, **kwargs) - self.named - self.namedProperties - @property def account(self) -> Optional[str]: """ diff --git a/extract_msg/msg_classes/message_base.py b/extract_msg/msg_classes/message_base.py index 39eb503b..45dc5e22 100644 --- a/extract_msg/msg_classes/message_base.py +++ b/extract_msg/msg_classes/message_base.py @@ -20,7 +20,6 @@ import zipfile import bs4 -import chardet import compressed_rtf import RTFDE @@ -103,28 +102,37 @@ def __init__(self, path, **kwargs): kwargs['errorBehavior'] = errorBehavior super().__init__(path, **kwargs) - self.__recipientSeparator = kwargs.get('recipientSeparator', ';') - self.__deencap = kwargs.get('deencapsulationFunc') - # Initialize properties in the order that is least likely to cause bugs. - # TODO have each function check for initialization of needed data so - # these lines will be unnecessary. - self.props - self.header - self.recipients - - self.to - self.cc - self.sender - self.date - # This variable keeps track of what the new line character should be. - self.__crlf = '\n' + # The rest needs to be in a try-except block to ensure the file closes + # if an error occurs. try: - self.body - except Exception as e: - # Prevent an error in the body from preventing opening. - logger.exception('Critical error accessing the body. File opened but accessing the body will throw an exception.') - self.named - self.namedProperties + self.__recipientSeparator = kwargs.get('recipientSeparator', ';') + self.__deencap = kwargs.get('deencapsulationFunc') + # Initialize properties in the order that is least likely to cause bugs. + # TODO have each function check for initialization of needed data so + # these lines will be unnecessary. + self.props + self.header + self.recipients + + self.to + self.cc + self.sender + self.date + # This variable keeps track of what the new line character should be. + self.__crlf = '\n' + try: + self.body + except Exception as e: + # Prevent an error in the body from preventing opening. + logger.exception('Critical error accessing the body. File opened but accessing the body will throw an exception.') + self.named + self.namedProperties + except: + try: + self.close() + except: + pass + raise def _genRecipient(self, recipientType, recipientInt : RecipientType) -> Optional[str]: """ diff --git a/extract_msg/msg_classes/message_signed_base.py b/extract_msg/msg_classes/message_signed_base.py index 83eb6099..8aae5bab 100644 --- a/extract_msg/msg_classes/message_signed_base.py +++ b/extract_msg/msg_classes/message_signed_base.py @@ -53,11 +53,6 @@ def __init__(self, path, **kwargs): """ self.__signedAttachmentClass = kwargs.get('signedAttachmentClass', SignedAttachment) super().__init__(path, **kwargs) - # Initialize properties in the order that is least likely to cause bugs. - # TODO have each function check for initialization of needed data so these - # lines will be unnecessary. - if not kwargs.get('delayAttachments', False): - self.attachments @property def attachments(self) -> List: diff --git a/extract_msg/msg_classes/msg.py b/extract_msg/msg_classes/msg.py index c82f59be..f96d37cc 100644 --- a/extract_msg/msg_classes/msg.py +++ b/extract_msg/msg_classes/msg.py @@ -124,15 +124,16 @@ def __init__(self, path, **kwargs): self.__listDirRes = {} - # This is a variable that tells whether we own the olefile. Used for - # closing. - self.__oleOwner = True if self.__parentMsg: # We should be able to directly access the private variables of # another instance with no issue. self.__ole = self.__parentMsg().__ole self.__oleOwner = False else: + # Verify the path at least evaluates to True, as not doing so can + # allow an OleFile to be created without a path. + if not path: + raise ValueError(':param path: must be set and must not be empty.') try: self.__ole = olefile.OleFileIO(path) except OSError as e: @@ -141,57 +142,70 @@ def __init__(self, path, **kwargs): raise InvalidFileFormatError(e) else: raise + # This is a variable that tells whether we own the olefile. Used for + # closing. We set it here for error handling. + self.__oleOwner = True - kwargsCopy = copy.copy(kwargs) - if 'prefix' in kwargsCopy: - del kwargsCopy['prefix'] - if 'parentMsg' in kwargsCopy: - del kwargsCopy['parentMsg'] - if 'filename' in kwargsCopy: - del kwargsCopy['filename'] - if 'treePath' in kwargsCopy: - del kwargsCopy['treePath'] - self.__kwargs = kwargsCopy - - prefixl = [] - if prefix: - try: - prefix = inputToString(prefix, 'utf-8') - except Exception: + # The rest *must* be in a try-except block to ensure we close the file. + try: + kwargsCopy = copy.copy(kwargs) + if 'prefix' in kwargsCopy: + del kwargsCopy['prefix'] + if 'parentMsg' in kwargsCopy: + del kwargsCopy['parentMsg'] + if 'filename' in kwargsCopy: + del kwargsCopy['filename'] + if 'treePath' in kwargsCopy: + del kwargsCopy['treePath'] + self.__kwargs = kwargsCopy + + prefixl = [] + if prefix: try: - prefix = '/'.join(prefix) + prefix = inputToString(prefix, 'utf-8') except Exception: - raise TypeError(f'Invalid prefix type: {type(prefix)}\n' + - '(This was probably caused by you setting it manually).') - prefix = prefix.replace('\\', '/') - g = prefix.split('/') - if g[-1] == '': - g.pop() - prefixl = g - if prefix[-1] != '/': - prefix += '/' - self.__prefix = prefix - self.__prefixList = prefixl - self.__prefixLen = len(prefixl) - if prefix and not filename: - filename = self._getStringStream(prefixl[:-1] + ['__substg1.0_3001'], prefix = False) - if filename: - self.filename = filename - elif hasLen(path): - if len(path) < 1536: + try: + prefix = '/'.join(prefix) + except Exception: + raise TypeError(f'Invalid prefix type: {type(prefix)}\n' + + '(This was probably caused by you setting it manually).') + prefix = prefix.replace('\\', '/') + g = prefix.split('/') + if g[-1] == '': + g.pop() + prefixl = g + if prefix[-1] != '/': + prefix += '/' + self.__prefix = prefix + self.__prefixList = prefixl + self.__prefixLen = len(prefixl) + if prefix and not filename: + filename = self._getStringStream(prefixl[:-1] + ['__substg1.0_3001'], prefix = False) + if filename: + self.filename = filename + elif hasLen(path): + if len(path) < 1536: + self.filename = str(path) + else: + self.filename = None + elif isinstance(path, pathlib.Path): self.filename = str(path) else: self.filename = None - elif isinstance(path, pathlib.Path): - self.filename = str(path) - else: - self.filename = None - self.__open = True + self.__open = True - # Now, load the attachments if we are not delaying them. - if not self.__attachmentsDelayed: - self.attachments + # Now, load the attachments if we are not delaying them. + if not self.__attachmentsDelayed: + self.attachments + except: + # *Any* exception here requires that we close the file. + try: + self.close() + except: + pass + # Raise the exception after trying to close the file. + raise def __enter__(self) -> MSGFile: self.__ole.__enter__() diff --git a/requirements.txt b/requirements.txt index ee75d38f..def1fce6 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,5 +7,4 @@ compressed_rtf>=1.0.6,<2 ebcdic>=1.1.1,<2 beautifulsoup4>=4.11.1,<4.13 RTFDE>=0.1.0,<0.2 -chardet>=4.0.0,<6 red-black-tree-mod==1.20 From ba042899d7523d9a08da5d6f184696c6765e8814 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Wed, 21 Jun 2023 13:49:10 -0700 Subject: [PATCH 49/89] Fixed casing in changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 38663abc..cb207eb7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -28,7 +28,7 @@ * Fixed bug that would cause weird behavior if you gave an empty string as the path for an MSG file. * Added support for `IPM.StickyNote`. * Fixed an issue that would cause MSG file to never close if an error happened during any of the `__init__` functions for MSG classes. -* removed unneeded `chardet` dependency. +* Removed unneeded `chardet` dependency. * Removed `Contact.__init__` as it didn't provide any unique behavior. **v0.41.5** From 97a426988d4b79cc88f7d713d050a91f9d3c0df3 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Wed, 21 Jun 2023 14:02:32 -0700 Subject: [PATCH 50/89] Add pillow to optional requirements --- setup.cfg | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup.cfg b/setup.cfg index 951dc042..7975332f 100644 --- a/setup.cfg +++ b/setup.cfg @@ -4,5 +4,8 @@ universal=1 [options.extras_require] all = extract-msg[mime] + extract-msg[image] mime = python-magic>=0.4.27,<0.5 +image = + Pillow>=9.5.0<10 \ No newline at end of file From 05e0dd83a264f7912dd9d3c905d3761c3e41fc1d Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Sun, 25 Jun 2023 17:02:35 -0700 Subject: [PATCH 51/89] Fix issue in setup.cfg --- setup.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.cfg b/setup.cfg index 7975332f..dc7d7bb5 100644 --- a/setup.cfg +++ b/setup.cfg @@ -8,4 +8,4 @@ all = mime = python-magic>=0.4.27,<0.5 image = - Pillow>=9.5.0<10 \ No newline at end of file + Pillow>=9.5.0,<10 \ No newline at end of file From 71e896daad674321045e26fb0b370bc7cc5391af Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Sun, 25 Jun 2023 17:05:22 -0700 Subject: [PATCH 52/89] Fix typo in property ID in initStandardAttachment --- extract_msg/attachments/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extract_msg/attachments/__init__.py b/extract_msg/attachments/__init__.py index 431166f9..97b25108 100644 --- a/extract_msg/attachments/__init__.py +++ b/extract_msg/attachments/__init__.py @@ -94,7 +94,7 @@ def initStandardAttachment(msg : MSGFile, dir_) -> AttachmentBase: propStore._propDict['37050003'] = createProp(propData) - attMethod = propStore['3705003'] & 7 + attMethod = propStore['37050003'] & 7 if msg.exists([dir_, '__substg1.0_37010102']): return Attachment(msg, dir_, propStore) From f2bfd3474ddf5b2a36d686d37d5b28dd88099d19 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Sun, 25 Jun 2023 19:43:37 -0700 Subject: [PATCH 53/89] Docstrings, new property, fix bug in MessageBase --- CHANGELOG.md | 3 ++ extract_msg/attachments/__init__.py | 8 ++-- extract_msg/attachments/attachment.py | 2 +- extract_msg/attachments/attachment_base.py | 19 +++++++++- extract_msg/attachments/broken_att.py | 2 +- extract_msg/attachments/custom_att.py | 2 +- extract_msg/attachments/emb_msg_att.py | 2 +- extract_msg/attachments/signed_att.py | 19 +++++++++- extract_msg/attachments/unsupported_att.py | 2 +- extract_msg/attachments/web_att.py | 2 +- extract_msg/msg_classes/message.py | 3 -- extract_msg/msg_classes/message_base.py | 26 ++----------- .../msg_classes/message_signed_base.py | 24 ++---------- extract_msg/msg_classes/msg.py | 7 +++- extract_msg/open_msg.py | 37 ++++++------------- extract_msg/properties/prop.py | 10 ++++- extract_msg/properties/properties_store.py | 5 +-- 17 files changed, 80 insertions(+), 93 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cb207eb7..21ba62c0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,9 @@ * Fixed an issue that would cause MSG file to never close if an error happened during any of the `__init__` functions for MSG classes. * Removed unneeded `chardet` dependency. * Removed `Contact.__init__` as it didn't provide any unique behavior. +* Changed the documentation of `openMsg` to specify that it accepts all options recognized by MSGFile subclasses, allowing the doc string to not be modified every time one of them is changed. + * Changed the documentaion of various `__init__` methods to do the same thing. +* Added `dataType` property to `AttachmentBase` and `SignedAttachment` for checking the class that the data will be, if accessible. Returns `None` if the data is inaccessible, including because accessing it would throw an exception. **v0.41.5** * Fixed an issue from version `0.41.3` where the header being present but missing the `From` field would cause an exception. diff --git a/extract_msg/attachments/__init__.py b/extract_msg/attachments/__init__.py index 97b25108..72e57911 100644 --- a/extract_msg/attachments/__init__.py +++ b/extract_msg/attachments/__init__.py @@ -36,18 +36,18 @@ from .unsupported_att import UnsupportedAttachment from .web_att import WebAttachment - import logging as _logging -from typing import TYPE_CHECKING as _TYPE_CHECKING +from typing import TYPE_CHECKING -if _TYPE_CHECKING: +if TYPE_CHECKING: from ..msg_classes import MSGFile _logger = _logging.getLogger(__name__) _logger.addHandler(_logging.NullHandler()) + def initStandardAttachment(msg : MSGFile, dir_) -> AttachmentBase: """ Returns an instance of AttachmentBase for the attachment in the MSG file at @@ -94,7 +94,7 @@ def initStandardAttachment(msg : MSGFile, dir_) -> AttachmentBase: propStore._propDict['37050003'] = createProp(propData) - attMethod = propStore['37050003'] & 7 + attMethod = propStore['37050003'].value & 7 if msg.exists([dir_, '__substg1.0_37010102']): return Attachment(msg, dir_, propStore) diff --git a/extract_msg/attachments/attachment.py b/extract_msg/attachments/attachment.py index e57cd9a8..6996a083 100644 --- a/extract_msg/attachments/attachment.py +++ b/extract_msg/attachments/attachment.py @@ -216,6 +216,6 @@ def randomFilename(self) -> str: @property def type(self) -> AttachmentType: """ - Returns the (internally used) type of the data. + Returns an enum value that identifies the type of attachment. """ return AttachmentType.DATA diff --git a/extract_msg/attachments/attachment_base.py b/extract_msg/attachments/attachment_base.py index 5b6be71f..1d41f287 100644 --- a/extract_msg/attachments/attachment_base.py +++ b/extract_msg/attachments/attachment_base.py @@ -12,7 +12,7 @@ import weakref from functools import cached_property, partial -from typing import List, Optional, Tuple, TYPE_CHECKING +from typing import List, Optional, Tuple, Type, TYPE_CHECKING from ..enums import AttachmentType from ..properties.named import NamedProperties @@ -408,6 +408,21 @@ def data(self) -> Optional[object]: The attachment data, if any. Returns None if there is no data to save. """ + @property + def dataType(self) -> Optional[Type[type]]: + """ + The class that the data type will use, if it can be retrieved. + + This is a safe way to do type checking on data before knowing if it will + raise an exception. Returns None if no data will be returns or if an + exception will be raised. + """ + try: + return None if self.data is None else self.data.__class__ + except Exception: + # All exceptions that accessing data would cause should be silenced. + return None + @property def dir(self) -> str: """ @@ -547,5 +562,5 @@ def treePath(self) -> List[weakref.ReferenceType]: @abc.abstractmethod def type(self) -> AttachmentType: """ - Returns the (internally used) type of the data. + Returns an enum value that identifies the type of attachment. """ diff --git a/extract_msg/attachments/broken_att.py b/extract_msg/attachments/broken_att.py index b73ec9dc..8cdf0d88 100644 --- a/extract_msg/attachments/broken_att.py +++ b/extract_msg/attachments/broken_att.py @@ -29,6 +29,6 @@ def data(self) -> None: @property def type(self) -> AttachmentType: """ - Returns the (internally used) type of the data. + Returns an enum value that identifies the type of attachment. """ return AttachmentType.BROKEN \ No newline at end of file diff --git a/extract_msg/attachments/custom_att.py b/extract_msg/attachments/custom_att.py index 536cdf57..f36e7d54 100644 --- a/extract_msg/attachments/custom_att.py +++ b/extract_msg/attachments/custom_att.py @@ -195,6 +195,6 @@ def randomFilename(self) -> str: @property def type(self) -> AttachmentType: """ - Returns the (internally used) type of the data. + Returns an enum value that identifies the type of attachment. """ return AttachmentType.CUSTOM diff --git a/extract_msg/attachments/emb_msg_att.py b/extract_msg/attachments/emb_msg_att.py index d1c31d89..0fc1cc40 100644 --- a/extract_msg/attachments/emb_msg_att.py +++ b/extract_msg/attachments/emb_msg_att.py @@ -129,6 +129,6 @@ def data(self) -> MSGFile: @property def type(self) -> AttachmentType: """ - Returns the (internally used) type of the data. + Returns an enum value that identifies the type of attachment. """ return AttachmentType.MSG \ No newline at end of file diff --git a/extract_msg/attachments/signed_att.py b/extract_msg/attachments/signed_att.py index f2c63a9f..d4926186 100644 --- a/extract_msg/attachments/signed_att.py +++ b/extract_msg/attachments/signed_att.py @@ -13,7 +13,7 @@ import weakref import zipfile -from typing import List, TYPE_CHECKING, Union +from typing import List, Optional, Type, TYPE_CHECKING, Union from ..enums import AttachmentType from ..open_msg import openMsg @@ -201,6 +201,21 @@ def data(self) -> Union[bytes, MSGFile]: """ return self.__data + @property + def dataType(self) -> Optional[Type[type]]: + """ + The class that the data type will use, if it can be retrieved. + + This is a safe way to do type checking on data before knowing if it will + raise an exception. Returns None if no data will be returns or if an + exception will be raised. + """ + try: + return None if self.data is None else self.data.__class__ + except Exception: + # All exceptions that accessing data would cause should be silenced. + return None + @property def emailMessage(self) -> email.message.Message: """ @@ -248,6 +263,6 @@ def treePath(self) -> List[weakref.ReferenceType]: @property def type(self) -> AttachmentType: """ - The AttachmentType. + Returns an enum value that identifies the type of attachment. """ return AttachmentType.SIGNED if isinstance(self.__data, bytes) else AttachmentType.SIGNED_EMBEDDED diff --git a/extract_msg/attachments/unsupported_att.py b/extract_msg/attachments/unsupported_att.py index 91c23cd0..e7696366 100644 --- a/extract_msg/attachments/unsupported_att.py +++ b/extract_msg/attachments/unsupported_att.py @@ -35,6 +35,6 @@ def data(self) -> None: @property def type(self) -> AttachmentType: """ - Returns the (internally used) type of the data. + Returns an enum value that identifies the type of attachment. """ return AttachmentType.UNSUPPORTED \ No newline at end of file diff --git a/extract_msg/attachments/web_att.py b/extract_msg/attachments/web_att.py index fff6fdc4..6465a4f0 100644 --- a/extract_msg/attachments/web_att.py +++ b/extract_msg/attachments/web_att.py @@ -62,7 +62,7 @@ def providerName(self) -> Optional[str]: @property def type(self) -> AttachmentType: """ - Returns the (internally used) type of the data. + Returns an enum value that identifies the type of attachment. """ return AttachmentType.WEB diff --git a/extract_msg/msg_classes/message.py b/extract_msg/msg_classes/message.py index 33a0fe6f..79f62f75 100644 --- a/extract_msg/msg_classes/message.py +++ b/extract_msg/msg_classes/message.py @@ -6,9 +6,6 @@ from .message_base import MessageBase -# Due to changes to how saving works, Message is now identical to MessageBase, -# just with a different name. This is for backwards compatability, type -# identification, and possible future specializations to it. class Message(MessageBase): """ Parser for Microsoft Outlook message files. diff --git a/extract_msg/msg_classes/message_base.py b/extract_msg/msg_classes/message_base.py index 45dc5e22..43e69593 100644 --- a/extract_msg/msg_classes/message_base.py +++ b/extract_msg/msg_classes/message_base.py @@ -57,27 +57,9 @@ class MessageBase(MSGFile): def __init__(self, path, **kwargs): """ - :param path: path to the msg file in the system or is the raw msg file. - :param prefix: used for extracting embeded msg files - inside the main one. Do not set manually unless - you know what you are doing. - :param parentMsg: Used for syncronizing named properties instances. Do - not set this unless you know what you are doing. - :param initAttachment: Optional, the method used when creating an - attachment for an MSG file. MUST be a function that takes 2 - arguments (the MSGFile instance and the directory in the MSG file - where the attachment is) and returns an instance of AttachmentBase. - :param filename: Optional, the filename to be used by default when - saving. - :param delayAttachments: Optional, delays the initialization of - attachments until the user attempts to retrieve them. Allows MSG - files with bad attachments to be initialized so the other data can - be retrieved. - :param overrideEncoding: Optional, an encoding to use instead of the one - specified by the msg file. Do not report encoding errors caused by - this. - :param errorBehavior: Optional, the behavior to use in the - event of an error when parsing the attachments. + Supports all of the options from :method MSGFile.__init__: with some + additional ones. + :param recipientSeparator: Optional, separator string to use between recipients. :param deencapsulationFunc: Optional, if specified must be a callable @@ -92,7 +74,7 @@ def __init__(self, path, **kwargs): internally or they will not be caught. The original deencapsulation method will not run if this is set. """ - if 'ignoreRtfDeErrors' in kwargs is not None: + if 'ignoreRtfDeErrors' in kwargs: import warnings warnings.warn(':param ignoreRtfDeErrors: is deprecated. Use :param ErrorBehavior: instead.', DeprecationWarning) diff --git a/extract_msg/msg_classes/message_signed_base.py b/extract_msg/msg_classes/message_signed_base.py index 8aae5bab..b862e3bf 100644 --- a/extract_msg/msg_classes/message_signed_base.py +++ b/extract_msg/msg_classes/message_signed_base.py @@ -27,29 +27,11 @@ class MessageSignedBase(MessageBase): def __init__(self, path, **kwargs): """ - :param path: path to the msg file in the system or is the raw msg file. - :param prefix: used for extracting embeded msg files - inside the main one. Do not set manually unless - you know what you are doing. - :param initAttachment: Optional, the method used when creating an - attachment for an MSG file. MUST be a function that takes 2 - arguments (the MSGFile instance and the directory in the MSG file - where the attachment is) and returns an instance of AttachmentBase. + Supports all of the options from :method MessageBase.__init__: with some + additional ones. + :param signedAttachmentClass: optional, the class the object will use for signed attachments. - :param filename: optional, the filename to be used by default when - saving. - :param delayAttachments: optional, delays the initialization of - attachments until the user attempts to retrieve them. Allows MSG - files with bad attachments to be initialized so the other data can - be retrieved. - :param overrideEncoding: optional, an encoding to use instead of the one - specified by the msg file. Do not report encoding errors caused by - this. - :param errorBehavior: Optional, the behavior to use in the - event of an error when parsing the attachments. - :param recipientSeparator: Optional, Separator string to use between - recipients. """ self.__signedAttachmentClass = kwargs.get('signedAttachmentClass', SignedAttachment) super().__init__(path, **kwargs) diff --git a/extract_msg/msg_classes/msg.py b/extract_msg/msg_classes/msg.py index f96d37cc..c0d0ff31 100644 --- a/extract_msg/msg_classes/msg.py +++ b/extract_msg/msg_classes/msg.py @@ -68,14 +68,17 @@ def __init__(self, path, **kwargs): be retrieved. :param filename: Optional, the filename to be used by default when saving. - :param errorBehavior: Optional, the behavior to use in the event of an - certain types of errors. + :param errorBehavior: Optional, the behavior to use in the event of + certain types of errors. Uses the ErrorBehavior enum. :param overrideEncoding: Optional, an encoding to use instead of the one specified by the msg file. Do not report encoding errors caused by this. :param treePath: Internal variable used for giving representation of the path, as a tuple of objects, of the MSGFile. When passing, this is the path to the parent object of this instance. + :param insecureFeatures: Optional, an enum value that specifies if + certain insecure features should be enabled. These features should + only be used on data that you trust. Uses the InsecureFeatures enum. :raises InvalidFileFormatError: If the file is not an OleFile or could not be parsed as an MSG file. diff --git a/extract_msg/open_msg.py b/extract_msg/open_msg.py index 48ef9832..f39acd74 100644 --- a/extract_msg/open_msg.py +++ b/extract_msg/open_msg.py @@ -45,32 +45,17 @@ def _knownMsgClass(classType : str) -> bool: def openMsg(path, **kwargs) -> MSGFile: """ Function to automatically open an MSG file and detect what type it is. - :param path: Path to the msg file in the system or is the raw msg file. - :param prefix: Used for extracting embeded msg files inside the main one. - Do not set manually unless you know what you are doing. - :param parentMsg: Used for syncronizing named properties instances. Do not - set this unless you know what you are doing. - :param initAttachment: Optional, the method used when creating an attachment - for an MSG file. MUST be a function that takes 2 arguments (the MSGFile - instance and the directory in the MSG file where the attachment is) and - returns an instance of AttachmentBase. - :param signedAttachmentClass: Optional, the class the object will use for - signed attachments. - :param filename: Optional, the filename to be used by default when saving. - :param delayAttachments: Optional, delays the initialization of attachments - until the user attempts to retrieve them. Allows MSG files with bad - attachments to be initialized so the other data can be retrieved. - :param overrideEncoding: Optional, overrides the specified encoding of the - MSG file. - :param errorBehavior: Optional, the behaviour to use in the event - of an error when parsing the attachments. - :param recipientSeparator: Optional, Separator string to use between - recipients. - :param ignoreRtfDeErrors: Optional, specifies that any errors that occur - from the usage of RTFDE should be ignored (default: False). - If :param strict: is set to `True`, this function will raise an exception - when it cannot identify what MSGFile derivitive to use. Otherwise, it will - log the error and return a basic MSGFile instance. + + Accepts all of the same arguments as the __init__ method for the class it + creates. Extra options will be ignored if the class doesn't know what to do + with them, but child instances may end up using them if they understand + them. See :method MSGFile.__init__: for a list of all globally recognized + options. + + If :param strict: is set to True, this function will raise an exception when + it cannot identify what MSGFile derivitive to use. Otherwise, it will log + the error and return a basic MSGFile instance. Default is True. + :raises UnsupportedMSGTypeError: if the type is recognized but not suppoted. :raises UnrecognizedMSGTypeError: if the type is not recognized. """ diff --git a/extract_msg/properties/prop.py b/extract_msg/properties/prop.py index a645c673..c73c56c2 100644 --- a/extract_msg/properties/prop.py +++ b/extract_msg/properties/prop.py @@ -1,3 +1,6 @@ +from __future__ import annotations + + __all__ = [ # Classes. 'FixedLengthProp' @@ -9,6 +12,7 @@ ] +import abc import datetime import logging @@ -23,13 +27,13 @@ logger.addHandler(logging.NullHandler()) -def createProp(data : bytes) -> 'PropBase': +def createProp(data : bytes) -> PropBase: temp = constants.st.ST2.unpack(data)[0] if temp in constants.FIXED_LENGTH_PROPS: return FixedLengthProp(data) else: if temp not in constants.VARIABLE_LENGTH_PROPS: - # DEBUG + # DEBUG. logger.warning(f'Unknown property type: {properHex(temp)}') return VariableLengthProp(data) @@ -97,6 +101,7 @@ def type(self) -> int: return self.__type + class FixedLengthProp(PropBase): """ Class to contain the data for a single fixed length property. @@ -175,6 +180,7 @@ def value(self) -> Any: return self.__value + class VariableLengthProp(PropBase): """ Class to contain the data for a single variable length property. diff --git a/extract_msg/properties/properties_store.py b/extract_msg/properties/properties_store.py index c15afdac..16244d35 100644 --- a/extract_msg/properties/properties_store.py +++ b/extract_msg/properties/properties_store.py @@ -33,9 +33,8 @@ def __init__(self, data : Optional[bytes], _type : Optional[PropertiesType] = No if not isinstance(data, bytes): raise TypeError(':param data: MUST be bytes.') self.__rawData = data - self.__pos = 0 self.__len = len(data) - self.__props = {} + self.__props : Dict[PropBase] = {} self.__naid = None self.__nrid = None self.__ac = None @@ -80,7 +79,7 @@ def __init__(self, data : Optional[bytes], _type : Optional[PropertiesType] = No def __contains__(self, key) -> bool: return self.__props.__contains__(key) - def __getitem__(self, key): + def __getitem__(self, key) -> PropBase: return self.__props.__getitem__(key) def __iter__(self): From 0b59f06069c67f5228db0f6226d83de8a95a06ea Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Sun, 25 Jun 2023 21:31:05 -0700 Subject: [PATCH 54/89] Updated exceptions and added insecureFeatures arg. --- CHANGELOG.md | 8 ++- extract_msg/attachments/__init__.py | 6 +- .../custom_att_handler/outlook_image_dib.py | 6 +- extract_msg/enums.py | 23 ++++++++ extract_msg/exceptions.py | 57 +++++++++++++------ extract_msg/msg_classes/msg.py | 47 ++++++++------- extract_msg/utils.py | 5 +- 7 files changed, 101 insertions(+), 51 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 21ba62c0..34213ee3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,14 +16,14 @@ * Changed `knownMsgClass` to a private function since it is explicitly not being exported by any part of the module. * Removed unusued function `getFullClassName`. * Fixes to the HTML body when saving as HTML will no longer require the `preparedHtml`/`--prepared-html` option. -* Removed the exception `BadHtmlError` since it is no longer used. +* Removed unused exceptions. * Entirely reoganized the way attachments are initialized, including the class that will be used in various circumstances. Embedded MSG files, custom attachments, and web attachments will all use dedicated classes that are subclasses of AttachmentBase. * With this change, the way to specify a new Attachment class is to override the function used when creating attachments. This can be done by passing `attachmentInit = myFunction` as an option to `openMsg`. This function MUST return an instance of AttachmentBase. * Added first implementation of web attachments. Saving is not currently possible, but basic relevent property access is now possible. Saving will not be stopped by this attachment if `skipNotImplemented = True` is passed to the save function. * Changed the option to suppress `RTFDE` errors to fall under the `ErrorBehavior` enum. Usage of the original option will be allowable, but is being marked as deprecated. However, it is still a dedicated option from the command line. * Also fixed the option not properly ignoring some RTFDE errors, specifically the ones that it is normal for the module to throw. * Removed some constants that are not used by the module. -* Added the `encoding` submodule for encoding tasks, including proper support for Microsoft's implementation of cp950. This gets added to the codecs list as windows-950. +* Added the `encoding` submodule for encoding tasks, including proper support for Microsoft's implementation of cp950. This gets added to the codecs list as "windows-950". * Updated to support `RTFDE` version `0.1.0`. Users encountering random erros from that module should find that those errors have disappeared. If you get errors from it still, bring up the issue on their GitHub. * Fixed bug that would cause weird behavior if you gave an empty string as the path for an MSG file. * Added support for `IPM.StickyNote`. @@ -33,6 +33,10 @@ * Changed the documentation of `openMsg` to specify that it accepts all options recognized by MSGFile subclasses, allowing the doc string to not be modified every time one of them is changed. * Changed the documentaion of various `__init__` methods to do the same thing. * Added `dataType` property to `AttachmentBase` and `SignedAttachment` for checking the class that the data will be, if accessible. Returns `None` if the data is inaccessible, including because accessing it would throw an exception. +* Added new enum `InsecureFeatures` and option `insecureFeatures`. This option will allow certain features with security implcations to be used for files that you trust. Currently the only feature it supports is the usage of `PIL`/`Pillow` to open and modify images. All features like this will be opt-in to reduce possible vulnerabilities. +* Modified all custom exceptions the module uses to derive from a single base class for better organization. + * Added new exceptions to handle some of the situations previously handled by base Python exceptions. +* Changed internal handling of the `prefix` option for `MSGFile.__init__` (and therefore `openMsg`). If you are not setting this manually, you should notice little difference. **v0.41.5** * Fixed an issue from version `0.41.3` where the header being present but missing the `From` field would cause an exception. diff --git a/extract_msg/attachments/__init__.py b/extract_msg/attachments/__init__.py index 72e57911..8ec1b90e 100644 --- a/extract_msg/attachments/__init__.py +++ b/extract_msg/attachments/__init__.py @@ -119,19 +119,19 @@ def initStandardAttachment(msg : MSGFile, dir_) -> AttachmentBase: raise NotImplementedError(f'Could not determine attachment type ({attMethod})!') - except (NotImplementedError, UnrecognizedMSGTypeError) as e: + except (NotImplementedError, UnrecognizedMSGTypeError): if msg.errorBehavior & ErrorBehavior.ATTACH_NOT_IMPLEMENTED: _logger.exception(f'Error processing attachment at {dir_}') return UnsupportedAttachment(msg, dir_, propStore) else: raise - except StandardViolationError as e: + except StandardViolationError: if msg.errorBehavior & ErrorBehavior.STANDARDS_VIOLATION: _logger.exception(f'Unresolvable standards violation in {dir_}') return BrokenAttachment(msg, dir_, propStore) else: raise - except Exception as e: + except Exception: if msg.errorBehavior & ErrorBehavior.ATTACH_BROKEN: _logger.exception(f'Error processing attachment at {dir_}') return BrokenAttachment(msg, dir_) diff --git a/extract_msg/attachments/custom_att_handler/outlook_image_dib.py b/extract_msg/attachments/custom_att_handler/outlook_image_dib.py index 986e63ab..10fa8abe 100644 --- a/extract_msg/attachments/custom_att_handler/outlook_image_dib.py +++ b/extract_msg/attachments/custom_att_handler/outlook_image_dib.py @@ -12,7 +12,8 @@ from . import registerHandler from .custom_handler import CustomAttachmentHandler -from ...enums import DVAspect +from ...enums import DVAspect, InsecureFeatures +from ...exceptions import SecurityError if TYPE_CHECKING: @@ -93,6 +94,9 @@ def generateRtf(self) -> Optional[bytes]: This function requires PIL or Pillow. If neither are found, raises an import error. """ + if not self.attachment.msg.insecureFeatures & InsecureFeatures.PIL_IMAGE_PARSING: + raise SecurityError('Generating the RTF for a custom attachment requires the insecure feature PIL_IMAGE_PARSING.') + try: import PIL.Image except ImportError: diff --git a/extract_msg/enums.py b/extract_msg/enums.py index b01e3518..6c4b3a9e 100644 --- a/extract_msg/enums.py +++ b/extract_msg/enums.py @@ -1179,6 +1179,29 @@ class Importance(enum.Enum): +class InsecureFeatures(enum.IntFlag): + """ + Insecure options that can be enabled for an MSG file. + + Using ALL is not recommended unless you check this list before updating to + a new version of the module, as new features may have been added. It is + also not recommended to use these on files you do not trust. + + The following features are avilable: + NONE: No insecure features are allowed (default). + PIL_IMAGE_PARSING: Various operations requiring PIL or Pillow that will read + image data from parts of the MSG file. These operations are usually + constructing new images or are converting from one format to another. + This may expose you to security issues from those libraries. + + ALL: All of the previously listed features will be enabled for the MSG file. + """ + NONE = 0b0000 + PIL_IMAGE_PARSING = 0b0001 + ALL = 0b1111 + + + class Intelligence(enum.Enum): ERROR = -1 DUMB = 0 diff --git a/extract_msg/exceptions.py b/extract_msg/exceptions.py index 5004b512..4034daaa 100644 --- a/extract_msg/exceptions.py +++ b/extract_msg/exceptions.py @@ -7,6 +7,8 @@ """ __all__ = [ + 'ExMsgBaseException', + 'ConversionError', 'DataNotFoundError', 'DeencapMalformedData', @@ -26,50 +28,71 @@ 'WKError', ] +# Base exception types. + +class ExMsgBaseException(Exception): + """ + The base class for all custom exceptions the module uses. + """ + +class FeatureNotImplemented(ExMsgBaseException, NotImplementedError): + """ + The base class for a feature not yet being implemented in the module. + """ + +# More specific exceptions. + -class ConversionError(Exception): +class ConversionError(ExMsgBaseException): """ An error occured during type conversion. """ -class DataNotFoundError(Exception): +class DataNotFoundError(ExMsgBaseException): """ Requested stream type was unavailable. """ -class DeencapMalformedData(Exception): +class DeencapMalformedData(ExMsgBaseException): """ Data to deencapsulate was malformed in some way. """ -class DeencapNotEncapsulated(Exception): +class DeencapNotEncapsulated(ExMsgBaseException): """ Data to deencapsulate did not contain any encapsulated data. """ -class ExecutableNotFound(Exception): +class ExecutableNotFound(ExMsgBaseException): """ Could not find the specified executable. """ -class IncompatibleOptionsError(Exception): +class IncompatibleOptionsError(ExMsgBaseException): """ Provided options are incompatible with each other. """ -class InvalidFileFormatError(OSError): +class InvalidFileFormatError(ExMsgBaseException): """ An Invalid File Format Error occurred. """ -class InvaildPropertyIdError(Exception): +class InvaildPropertyIdError(ExMsgBaseException): """ The provided property ID was invalid. """ -class InvalidVersionError(Exception): +class PrefixError(ExMsgBaseException): + """ + An issue was detected with the provided prefix. This should never occur if + you have no manually provided a prefix. + """ + +class SecurityError(ExMsgBaseException): """ - The version specified is invalid. + A code path was triggered that would use an insecure feature, but that + insecure feature was not enabled. """ class StandardViolationError(InvalidFileFormatError): @@ -81,7 +104,7 @@ class StandardViolationError(InvalidFileFormatError): errors down the line, can be suppressed. """ -class TZError(Exception): +class TZError(ExMsgBaseException): """ Specifically not an OSError to avoid being caught by parts of the module. This error represents a fatal error in the datetime parsing as it usually @@ -91,34 +114,34 @@ class TZError(Exception): TeamMsgExtractor#169 for information on why you are getting this error. """ -class UnknownCodepageError(Exception): +class UnknownCodepageError(ExMsgBaseException): """ The codepage provided was not one we know of. """ -class UnsupportedEncodingError(NotImplementedError): +class UnsupportedEncodingError(FeatureNotImplemented): """ The codepage provided is known but is not supported. """ -class UnknownTypeError(Exception): +class UnknownTypeError(ExMsgBaseException): """ The type specified is not one that is recognized. """ -class UnsupportedMSGTypeError(NotImplementedError): +class UnsupportedMSGTypeError(FeatureNotImplemented): """ An exception that is raised when an MSG class is recognized by not supported. """ -class UnrecognizedMSGTypeError(TypeError): +class UnrecognizedMSGTypeError(ExMsgBaseException): """ An exception that is raised when the module cannot determine how to properly open a specific class of msg file. """ -class WKError(RuntimeError): +class WKError(ExMsgBaseException): """ An error occured while running wkhtmltopdf. """ diff --git a/extract_msg/msg_classes/msg.py b/extract_msg/msg_classes/msg.py index c0d0ff31..af79669c 100644 --- a/extract_msg/msg_classes/msg.py +++ b/extract_msg/msg_classes/msg.py @@ -26,19 +26,19 @@ ) from ..encoding import lookupCodePage from ..enums import ( - AttachErrorBehavior, ErrorBehavior, Importance, Priority, - PropertiesType, Sensitivity, SideEffect + AttachErrorBehavior, ErrorBehavior, InsecureFeatures, Importance, + Priority, PropertiesType, Sensitivity, SideEffect ) from ..exceptions import ( - InvalidFileFormatError, StandardViolationError + ConversionError, InvalidFileFormatError, PrefixError, + StandardViolationError ) from ..properties.named import Named, NamedProperties from ..properties.prop import FixedLengthProp from ..properties.properties_store import PropertiesStore from ..utils import ( - divide, hasLen, inputToMsgPath, inputToString, makeWeakRef, - msgPathToString, parseType, properHex, verifyPropertyId, verifyType, - windowsUnicode + divide, hasLen, inputToMsgPath, makeWeakRef, msgPathToString, + parseType, properHex, verifyPropertyId, verifyType, windowsUnicode ) @@ -86,7 +86,7 @@ def __init__(self, path, **kwargs): the standard. :raises IOError: If there is an issue opening the MSG file. :raises NameError: If the encoding provided is not supported. - :raises TypeError: If the prefix is not a supported type. + :raises PrefixError: If the prefix is not a supported type. :raises TypeError: If the parent is not an instance of MSGFile or a subclass. :raises ValueError: If the attachment error behavior is not valid. @@ -95,6 +95,7 @@ def __init__(self, path, **kwargs): specific exceptions was raised. """ # Retrieve all the kwargs that we need. + self.__inscFeat = kwargs.get('insecureFeatures', InsecureFeatures.NONE) prefix = kwargs.get('prefix', '') self.__parentMsg = makeWeakRef(kwargs.get('parentMsg')) self.__treePath = kwargs.get('treePath', []) + [makeWeakRef(self)] @@ -165,20 +166,10 @@ def __init__(self, path, **kwargs): prefixl = [] if prefix: try: - prefix = inputToString(prefix, 'utf-8') - except Exception: - try: - prefix = '/'.join(prefix) - except Exception: - raise TypeError(f'Invalid prefix type: {type(prefix)}\n' + - '(This was probably caused by you setting it manually).') - prefix = prefix.replace('\\', '/') - g = prefix.split('/') - if g[-1] == '': - g.pop() - prefixl = g - if prefix[-1] != '/': - prefix += '/' + prefixl = inputToMsgPath(prefix) + prefix = '/'.join(prefixl) + '/' + except ConversionError: + raise PrefixError(f'The provided prefix could not be used: {prefix}') self.__prefix = prefix self.__prefixList = prefixl self.__prefixLen = len(prefixl) @@ -764,8 +755,8 @@ def currentVersionName(self) -> Optional[str]: @property def errorBehavior(self) -> ErrorBehavior: """ - The behavior to follow when an attachment raises an exception. Will be - a member of the ErrorBehavior enum. + The behavior to follow when certain errors occur. Will be an instance of + the ErrorBehavior enum. """ return self.__errorBehavior @@ -797,6 +788,14 @@ def initAttachmentFunc(self) -> Callable[[MSGFile, Any], AttachmentBase]: """ return self.__initAttachmentFunc + @property + def insecureFeatures(self) -> InsecureFeatures: + """ + An enum specifying what insecure features have been enabled for this + file. + """ + return self.__inscFeat + @property def kwargs(self) -> dict: """ @@ -873,7 +872,7 @@ def prefixLen(self) -> int: return self.__prefixLen @property - def prefixList(self): + def prefixList(self) -> List[str]: """ Returns the prefix list of the Message instance. Intended for developer use. diff --git a/extract_msg/utils.py b/extract_msg/utils.py index 79d95bcf..35cb5ad5 100644 --- a/extract_msg/utils.py +++ b/extract_msg/utils.py @@ -1,6 +1,5 @@ from __future__ import annotations -import extract_msg.encoding """ Utility functions of extract_msg. @@ -50,7 +49,6 @@ import argparse -import codecs import collections import copy import datetime @@ -79,8 +77,7 @@ from .enums import AttachmentType from .exceptions import ( ConversionError, ExecutableNotFound, IncompatibleOptionsError, - InvaildPropertyIdError, TZError, - UnknownCodepageError, UnknownTypeError, UnsupportedEncodingError + InvaildPropertyIdError, TZError, UnknownTypeError ) From 97836874dcd938a6b2371b709c09adb97c964340 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Fri, 30 Jun 2023 18:02:41 -0700 Subject: [PATCH 55/89] Attempt to address #372 --- CHANGELOG.md | 2 +- extract_msg/attachments/attachment_base.py | 11 +++++++++-- extract_msg/attachments/emb_msg_att.py | 8 +++++--- extract_msg/attachments/signed_att.py | 6 ++++-- 4 files changed, 19 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 34213ee3..407dc1c2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,5 @@ **v0.42.0** +* [[TeamMsgExtractor #372](https://github.com/TeamMsgExtractor/msg-extractor/issues/372)] Addressed an issue where the save functions would sometimes return unexpected types. This has been addressed by fixing some of the underlying bugs (wrong type returned, wrong object returned, etc.) and adding typing information so the return types would be properly documented. * Added new submodule `custom_attachments`. This submodule provides an extendable way to handle custom attachment types, attachment types whose structure and formatting are not defined in the Microsoft documentation for MSG files. * Added new property `AttachmentBase.clsid` which returns the listed CLSID value of the data stream/storage of the attachment. * Changed internal behavior of `MSGFile.attachments`. This should not cause any noticeable changes to the output. @@ -11,7 +12,6 @@ * Switched much of the internal code (and the `treePath` property of all classes that have it) to using `weakref.ReferenceType` to avoid hard cyclic references. * Fixed `Recipient._getTypedStream` never returning a value. * Added additional type hints in various places. -* Corrected `Attachment.save` so that saving an embedded msg file returns that embedded msg file instead of the parent msg file. * Modified tests.py to only run if it is run as a file instead of imported. * Changed `knownMsgClass` to a private function since it is explicitly not being exported by any part of the module. * Removed unusued function `getFullClassName`. diff --git a/extract_msg/attachments/attachment_base.py b/extract_msg/attachments/attachment_base.py index 1d41f287..a8a24255 100644 --- a/extract_msg/attachments/attachment_base.py +++ b/extract_msg/attachments/attachment_base.py @@ -12,7 +12,7 @@ import weakref from functools import cached_property, partial -from typing import List, Optional, Tuple, Type, TYPE_CHECKING +from typing import List, Optional, Tuple, Type, TYPE_CHECKING, Union from ..enums import AttachmentType from ..properties.named import NamedProperties @@ -311,7 +311,7 @@ def getFilename(self, **kwargs) -> str: """ @abc.abstractmethod - def save(self, **kwargs): + def save(self, **kwargs) -> Optional[Union[str, object]]: """ Saves the attachment data. @@ -341,6 +341,13 @@ def save(self, **kwargs): save function. :param skipEmbedded: If True, skips saving this attachment if it is an embedded MSG file. + + The return type from this function can be anything, but it SHOULD follow + the following rules: + * Returns None if nothing is saved. + * Returns a non-string object if the attachment is saved but not as + pure bytes. + * Returns a string with the path to the file that was saved. """ @property diff --git a/extract_msg/attachments/emb_msg_att.py b/extract_msg/attachments/emb_msg_att.py index 0fc1cc40..9c860ff5 100644 --- a/extract_msg/attachments/emb_msg_att.py +++ b/extract_msg/attachments/emb_msg_att.py @@ -16,7 +16,7 @@ from ..open_msg import openMsg from ..utils import createZipOpen, prepareFilename -from typing import Optional, TYPE_CHECKING +from typing import Optional, TYPE_CHECKING, Union if TYPE_CHECKING: @@ -58,7 +58,7 @@ def getFilename(self, **kwargs) -> str: else: return self.name - def save(self, **kwargs) -> Optional[MSGFile]: + def save(self, **kwargs) -> Optional[Union[str, MSGFile]]: # First check if we are skipping embedded messages and stop # *immediately* if we are. if kwargs.get('skipEmbedded'): @@ -106,16 +106,18 @@ def save(self, **kwargs) -> Optional[MSGFile]: fullFilename = customPath / filename if kwargs.get('extractEmbedded', False): + ret = str(fullFilename) with _open(str(fullFilename), mode) as f: self.data.export(f) else: + ret = self.data self.data.save(**kwargs) # Close the ZipFile if this function created it. if _zip and createdZip: _zip.close() - return self.__data + return ret save.__doc__ = _saveDoc diff --git a/extract_msg/attachments/signed_att.py b/extract_msg/attachments/signed_att.py index d4926186..3cff6dd0 100644 --- a/extract_msg/attachments/signed_att.py +++ b/extract_msg/attachments/signed_att.py @@ -61,7 +61,7 @@ def __init__(self, msg, data : bytes, name : str, mimetype : str, node : email.m if self.__data is None: self.__data = data - def save(self, **kwargs): + def save(self, **kwargs) -> Optional[Union[str, MSGFile]]: """ Saves the attachment data. @@ -171,17 +171,19 @@ def save(self, **kwargs): return str(fullFilename) else: if kwargs.get('extractEmbedded', False): + ret = str(fullFilename) with _open(str(fullFilename), mode) as f: # We just use the data we were given for this one. f.write(self.__asBytes) else: + ret = self.data self.saveEmbededMessage(**kwargs) # Close the ZipFile if this function created it. if _zip and createdZip: _zip.close() - return self.msg + return ret def saveEmbededMessage(self, **kwargs) -> None: """ From 21a9dae8e7bc5454e156cb93e5e078a142ca1a2c Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Fri, 30 Jun 2023 18:06:16 -0700 Subject: [PATCH 56/89] Ensured all attachment types can have save skipped --- extract_msg/attachments/broken_att.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/extract_msg/attachments/broken_att.py b/extract_msg/attachments/broken_att.py index 8cdf0d88..aa898730 100644 --- a/extract_msg/attachments/broken_att.py +++ b/extract_msg/attachments/broken_att.py @@ -16,8 +16,9 @@ class BrokenAttachment(AttachmentBase): def getFilename(self, **kwargs) -> str: raise NotImplementedError('Broken attachments cannot be saved.') - def save(self, **kwargs): - raise NotImplementedError('Broken attachments cannot be saved.') + def save(self, **kwargs) -> None: + if not kwargs.get('skipNotImplemented', False): + raise NotImplementedError('Broken attachments cannot be saved.') @property def data(self) -> None: From 187f357c287bbfd03b587d57aa7424c87cfd4856 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Fri, 30 Jun 2023 18:38:54 -0700 Subject: [PATCH 57/89] Fix minor exception typo --- extract_msg/attachments/web_att.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extract_msg/attachments/web_att.py b/extract_msg/attachments/web_att.py index 6465a4f0..996aa86b 100644 --- a/extract_msg/attachments/web_att.py +++ b/extract_msg/attachments/web_att.py @@ -36,7 +36,7 @@ def data(self) -> None: """ The bytes making up the attachment data. """ - raise NotImplementedError('Cannot get the data of a web attachment') + raise NotImplementedError('Cannot get the data of a web attachment.') @property def originalPermissionType(self) -> Optional[AttachmentPermissionType]: From d440e3f432d392781fd7064ac04c9a2ae3f80c22 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Sat, 1 Jul 2023 17:56:16 -0700 Subject: [PATCH 58/89] Update save functions, change code for some props --- CHANGELOG.md | 3 +- extract_msg/attachments/attachment.py | 117 +++--- extract_msg/attachments/attachment_base.py | 26 +- extract_msg/attachments/broken_att.py | 9 +- extract_msg/attachments/custom_att.py | 116 +++--- extract_msg/attachments/emb_msg_att.py | 10 +- extract_msg/attachments/signed_att.py | 136 ++++--- extract_msg/attachments/unsupported_att.py | 7 +- extract_msg/attachments/web_att.py | 11 +- extract_msg/constants/__init__.py | 4 +- extract_msg/constants/re.py | 2 +- extract_msg/enums.py | 25 ++ extract_msg/msg_classes/message_base.py | 436 ++++++++++----------- 13 files changed, 453 insertions(+), 449 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 407dc1c2..1373a1e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ **v0.42.0** -* [[TeamMsgExtractor #372](https://github.com/TeamMsgExtractor/msg-extractor/issues/372)] Addressed an issue where the save functions would sometimes return unexpected types. This has been addressed by fixing some of the underlying bugs (wrong type returned, wrong object returned, etc.) and adding typing information so the return types would be properly documented. +* [[TeamMsgExtractor #372](https://github.com/TeamMsgExtractor/msg-extractor/issues/372)] Changed the way that the save functions return a value. This makes the return value from all save functions much more informative, allowing a user to separate if a fole or folder (or if more than one) was saved from the function. It also guarentees that all classes from this module will return the relevent path(s) if data is actually saved. +* Fixed an issue in the save functions that left the possibility for the zip files to not end up closing if the save function created it and then had an exception. * Added new submodule `custom_attachments`. This submodule provides an extendable way to handle custom attachment types, attachment types whose structure and formatting are not defined in the Microsoft documentation for MSG files. * Added new property `AttachmentBase.clsid` which returns the listed CLSID value of the data stream/storage of the attachment. * Changed internal behavior of `MSGFile.attachments`. This should not cause any noticeable changes to the output. diff --git a/extract_msg/attachments/attachment.py b/extract_msg/attachments/attachment.py index 6996a083..9d05676a 100644 --- a/extract_msg/attachments/attachment.py +++ b/extract_msg/attachments/attachment.py @@ -13,11 +13,11 @@ import string import zipfile -from typing import Optional, TYPE_CHECKING, Union +from typing import TYPE_CHECKING from .. import constants from .attachment_base import AttachmentBase -from ..enums import AttachmentType +from ..enums import AttachmentType, SaveType from ..utils import createZipOpen, inputToString, prepareFilename from ..properties import PropertiesStore @@ -88,7 +88,7 @@ def regenerateRandomName(self) -> str: ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(5)) + '.bin', 'ascii') - def save(self, **kwargs) -> Optional[Union[str, MSGFile]]: + def save(self, **kwargs) -> constants.SAVE_TYPE: """ Saves the attachment data. @@ -137,63 +137,68 @@ def save(self, **kwargs) -> Optional[Union[str, MSGFile]]: # Check if we are doing a zip file. _zip = kwargs.get('zip') - # ZipFile handling. - if _zip: - # If we are doing a zip file, first check that we have been given a path. - if isinstance(_zip, (str, pathlib.Path)): - # If we have a path then we use the zip file. - _zip = zipfile.ZipFile(_zip, 'a', zipfile.ZIP_DEFLATED) - kwargs['zip'] = _zip - createdZip = True + try: + # ZipFile handling. + if _zip: + # If we are doing a zip file, first check that we have been + # given a path. + if isinstance(_zip, (str, pathlib.Path)): + # If we have a path then we use the zip file. + _zip = zipfile.ZipFile(_zip, 'a', zipfile.ZIP_DEFLATED) + kwargs['zip'] = _zip + createdZip = True + else: + createdZip = False + # Path needs to be done in a special way if we are in a zip + # file. + customPath = pathlib.Path(kwargs.get('customPath', '')) + # Set the open command to be that of the zip file. + _open = createZipOpen(_zip.open) + # Zip files use w for writing in binary. + mode = 'w' else: - createdZip = False - # Path needs to be done in a special way if we are in a zip file. - customPath = pathlib.Path(kwargs.get('customPath', '')) - # Set the open command to be that of the zip file. - _open = createZipOpen(_zip.open) - # Zip files use w for writing in binary. - mode = 'w' - else: - customPath = pathlib.Path(kwargs.get('customPath', '.')).absolute() - mode = 'wb' - _open = open + customPath = pathlib.Path(kwargs.get('customPath', '.')).absolute() + mode = 'wb' + _open = open - fullFilename = customPath / filename + fullFilename = customPath / filename - if _zip: - name, ext = os.path.splitext(filename) - nameList = _zip.namelist() - if str(fullFilename).replace('\\', '/') in nameList: - for i in range(2, 100): - testName = customPath / f'{name} ({i}){ext}' - if str(testName).replace('\\', '/') not in nameList: - fullFilename = testName - break - else: - # If we couldn't find one that didn't exist. - raise FileExistsError(f'Could not create the specified file because it already exists ("{fullFilename}").') - else: - if fullFilename.exists(): - # Try to split the filename into a name and extention. + if _zip: name, ext = os.path.splitext(filename) - # Try to add a number to it so that we can save without overwriting. - for i in range(2, 100): - testName = customPath / f'{name} ({i}){ext}' - if not testName.exists(): - fullFilename = testName - break - else: - # If we couldn't find one that didn't exist. - raise FileExistsError(f'Could not create the specified file because it already exists ("{fullFilename}").') - - with _open(str(fullFilename), mode) as f: - f.write(self.__data) - - # Close the ZipFile if this function created it. - if _zip and createdZip: - _zip.close() - - return str(fullFilename) + nameList = _zip.namelist() + if str(fullFilename).replace('\\', '/') in nameList: + for i in range(2, 100): + testName = customPath / f'{name} ({i}){ext}' + if str(testName).replace('\\', '/') not in nameList: + fullFilename = testName + break + else: + # If we couldn't find one that didn't exist. + raise FileExistsError(f'Could not create the specified file because it already exists ("{fullFilename}").') + else: + if fullFilename.exists(): + # Try to split the filename into a name and extention. + name, ext = os.path.splitext(filename) + # Try to add a number to it so that we can save without + # overwriting. + for i in range(2, 100): + testName = customPath / f'{name} ({i}){ext}' + if not testName.exists(): + fullFilename = testName + break + else: + # If we couldn't find one that didn't exist. + raise FileExistsError(f'Could not create the specified file because it already exists ("{fullFilename}").') + + with _open(str(fullFilename), mode) as f: + f.write(self.__data) + + return (SaveType.FILE, str(fullFilename)) + + finally: + # Close the ZipFile if this function created it. + if _zip and createdZip: + _zip.close() @property def data(self) -> bytes: diff --git a/extract_msg/attachments/attachment_base.py b/extract_msg/attachments/attachment_base.py index a8a24255..c480cb84 100644 --- a/extract_msg/attachments/attachment_base.py +++ b/extract_msg/attachments/attachment_base.py @@ -12,8 +12,9 @@ import weakref from functools import cached_property, partial -from typing import List, Optional, Tuple, Type, TYPE_CHECKING, Union +from typing import List, Optional, Tuple, Type, TYPE_CHECKING +from .. import constants from ..enums import AttachmentType from ..properties.named import NamedProperties from ..properties.prop import FixedLengthProp @@ -311,21 +312,12 @@ def getFilename(self, **kwargs) -> str: """ @abc.abstractmethod - def save(self, **kwargs) -> Optional[Union[str, object]]: + def save(self, **kwargs) -> constants.SAVE_TYPE: """ Saves the attachment data. - The name of the file is determined by several factors. The first - thing that is checked is if you have provided :param customFilename: - to this function. If you have, that is the name that will be used. - If no custom name has been provided and :param contentId: is True, - the file will be saved using the content ID of the attachment. If - it is not found or :param contentId: is False, the long filename - will be used. If the long filename is not found, the short one will - be used. If after all of this a usable filename has not been found, a - random one will be used (accessible from `Attachment.randomFilename`). - After the name to use has been determined, it will then be shortened to - make sure that it is not more than the value of :param maxNameLength:. + The name of the file is determined by the logic of the getFilename + function. If you are a developer, ensure that you use this behavior. To change the directory that the attachment is saved to, set the value of :param customPath: when calling this function. The default save @@ -342,12 +334,8 @@ def save(self, **kwargs) -> Optional[Union[str, object]]: :param skipEmbedded: If True, skips saving this attachment if it is an embedded MSG file. - The return type from this function can be anything, but it SHOULD follow - the following rules: - * Returns None if nothing is saved. - * Returns a non-string object if the attachment is saved but not as - pure bytes. - * Returns a string with the path to the file that was saved. + :returns: A tuple that specifies how the data was saved. The value of + the first item specifies what the second value will be. """ @property diff --git a/extract_msg/attachments/broken_att.py b/extract_msg/attachments/broken_att.py index aa898730..2bbfaff0 100644 --- a/extract_msg/attachments/broken_att.py +++ b/extract_msg/attachments/broken_att.py @@ -3,8 +3,9 @@ ] +from .. import constants from .attachment_base import AttachmentBase -from ..enums import AttachmentType +from ..enums import AttachmentType, SaveType class BrokenAttachment(AttachmentBase): @@ -13,13 +14,15 @@ class BrokenAttachment(AttachmentBase): NotImplementedError exception. """ - def getFilename(self, **kwargs) -> str: + def getFilename(self, **_) -> str: raise NotImplementedError('Broken attachments cannot be saved.') - def save(self, **kwargs) -> None: + def save(self, **kwargs) -> constants.SAVE_TYPE: if not kwargs.get('skipNotImplemented', False): raise NotImplementedError('Broken attachments cannot be saved.') + return (SaveType.NONE, None) + @property def data(self) -> None: """ diff --git a/extract_msg/attachments/custom_att.py b/extract_msg/attachments/custom_att.py index f36e7d54..2ecfcc50 100644 --- a/extract_msg/attachments/custom_att.py +++ b/extract_msg/attachments/custom_att.py @@ -12,14 +12,14 @@ import string import zipfile +from typing import Optional, TYPE_CHECKING + from .. import constants from .attachment_base import AttachmentBase from .custom_att_handler import CustomAttachmentHandler, getHandler -from ..enums import AttachmentType +from ..enums import AttachmentType, SaveType from ..utils import createZipOpen, inputToString, prepareFilename -from typing import Optional, TYPE_CHECKING - if TYPE_CHECKING: from ..msg_classes import MSGFile @@ -85,10 +85,10 @@ def regenerateRandomName(self) -> str: ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(5)) + '.bin' - def save(self, **kwargs) -> Optional[str]: + def save(self, **kwargs) -> constants.SAVE_TYPE: # Immediate check to see if there is anything to save. if self.data is None: - return None + return (SaveType.NONE, None) # Get the filename to use. filename = self.getFilename(**kwargs) @@ -108,63 +108,65 @@ def save(self, **kwargs) -> Optional[str]: # Check if we are doing a zip file. _zip = kwargs.get('zip') - # ZipFile handling. - if _zip: - # If we are doing a zip file, first check that we have been given a path. - if isinstance(_zip, (str, pathlib.Path)): - # If we have a path then we use the zip file. - _zip = zipfile.ZipFile(_zip, 'a', zipfile.ZIP_DEFLATED) - kwargs['zip'] = _zip - createdZip = True + try: + # ZipFile handling. + if _zip: + # If we are doing a zip file, first check that we have been given a path. + if isinstance(_zip, (str, pathlib.Path)): + # If we have a path then we use the zip file. + _zip = zipfile.ZipFile(_zip, 'a', zipfile.ZIP_DEFLATED) + kwargs['zip'] = _zip + createdZip = True + else: + createdZip = False + # Path needs to be done in a special way if we are in a zip file. + customPath = pathlib.Path(kwargs.get('customPath', '')) + # Set the open command to be that of the zip file. + _open = createZipOpen(_zip.open) + # Zip files use w for writing in binary. + mode = 'w' else: - createdZip = False - # Path needs to be done in a special way if we are in a zip file. - customPath = pathlib.Path(kwargs.get('customPath', '')) - # Set the open command to be that of the zip file. - _open = createZipOpen(_zip.open) - # Zip files use w for writing in binary. - mode = 'w' - else: - customPath = pathlib.Path(kwargs.get('customPath', '.')).absolute() - mode = 'wb' - _open = open + customPath = pathlib.Path(kwargs.get('customPath', '.')).absolute() + mode = 'wb' + _open = open - fullFilename = customPath / filename + fullFilename = customPath / filename - if _zip: - name, ext = os.path.splitext(filename) - nameList = _zip.namelist() - if str(fullFilename).replace('\\', '/') in nameList: - for i in range(2, 100): - testName = customPath / f'{name} ({i}){ext}' - if str(testName).replace('\\', '/') not in nameList: - fullFilename = testName - break - else: - # If we couldn't find one that didn't exist. - raise FileExistsError(f'Could not create the specified file because it already exists ("{fullFilename}").') - else: - if fullFilename.exists(): - # Try to split the filename into a name and extention. + if _zip: name, ext = os.path.splitext(filename) - # Try to add a number to it so that we can save without overwriting. - for i in range(2, 100): - testName = customPath / f'{name} ({i}){ext}' - if not testName.exists(): - fullFilename = testName - break - else: - # If we couldn't find one that didn't exist. - raise FileExistsError(f'Could not create the specified file because it already exists ("{fullFilename}").') - - with _open(str(fullFilename), mode) as f: - f.write(self.__data) - - # Close the ZipFile if this function created it. - if _zip and createdZip: - _zip.close() + nameList = _zip.namelist() + if str(fullFilename).replace('\\', '/') in nameList: + for i in range(2, 100): + testName = customPath / f'{name} ({i}){ext}' + if str(testName).replace('\\', '/') not in nameList: + fullFilename = testName + break + else: + # If we couldn't find one that didn't exist. + raise FileExistsError(f'Could not create the specified file because it already exists ("{fullFilename}").') + else: + if fullFilename.exists(): + # Try to split the filename into a name and extention. + name, ext = os.path.splitext(filename) + # Try to add a number to it so that we can save without overwriting. + for i in range(2, 100): + testName = customPath / f'{name} ({i}){ext}' + if not testName.exists(): + fullFilename = testName + break + else: + # If we couldn't find one that didn't exist. + raise FileExistsError(f'Could not create the specified file because it already exists ("{fullFilename}").') + + with _open(str(fullFilename), mode) as f: + f.write(self.__data) + + return (SaveType.FILE, str(fullFilename)) + finally: + # Close the ZipFile if this function created it. + if _zip and createdZip: + _zip.close() - return str(fullFilename) @property def customHandler(self) -> Optional[CustomAttachmentHandler]: diff --git a/extract_msg/attachments/emb_msg_att.py b/extract_msg/attachments/emb_msg_att.py index 9c860ff5..64fa305b 100644 --- a/extract_msg/attachments/emb_msg_att.py +++ b/extract_msg/attachments/emb_msg_att.py @@ -10,14 +10,14 @@ import pathlib import zipfile +from typing import TYPE_CHECKING + from .. import constants from .attachment_base import AttachmentBase -from ..enums import AttachmentType +from ..enums import AttachmentType, SaveType from ..open_msg import openMsg from ..utils import createZipOpen, prepareFilename -from typing import Optional, TYPE_CHECKING, Union - if TYPE_CHECKING: from ..msg_classes import MSGFile @@ -58,11 +58,11 @@ def getFilename(self, **kwargs) -> str: else: return self.name - def save(self, **kwargs) -> Optional[Union[str, MSGFile]]: + def save(self, **kwargs) -> constants.SAVE_TYPE: # First check if we are skipping embedded messages and stop # *immediately* if we are. if kwargs.get('skipEmbedded'): - return None + return (SaveType.NONE, None) # Get the filename to use. filename = self.getFilename(**kwargs) diff --git a/extract_msg/attachments/signed_att.py b/extract_msg/attachments/signed_att.py index 3cff6dd0..91664c6c 100644 --- a/extract_msg/attachments/signed_att.py +++ b/extract_msg/attachments/signed_att.py @@ -15,7 +15,8 @@ from typing import List, Optional, Type, TYPE_CHECKING, Union -from ..enums import AttachmentType +from .. import constants +from ..enums import AttachmentType, SaveType from ..open_msg import openMsg from ..utils import createZipOpen, inputToString, makeWeakRef, prepareFilename @@ -61,7 +62,7 @@ def __init__(self, msg, data : bytes, name : str, mimetype : str, node : email.m if self.__data is None: self.__data = data - def save(self, **kwargs) -> Optional[Union[str, MSGFile]]: + def save(self, **kwargs) -> constants.SAVE_TYPE: """ Saves the attachment data. @@ -92,7 +93,7 @@ def save(self, **kwargs) -> Optional[Union[str, MSGFile]]: # First check if we are skipping embedded messages and stop # *immediately* if we are. if self.type is AttachmentType.SIGNED_EMBEDDED and kwargs.get('skipEmbedded'): - return None + return (SaveType.NONE, None) # Check if the user has specified a custom filename filename = self.name @@ -111,86 +112,83 @@ def save(self, **kwargs) -> Optional[Union[str, MSGFile]]: # Check if we are doing a zip file. _zip = kwargs.get('zip') - # ZipFile handling. - if _zip: - # If we are doing a zip file, first check that we have been given a path. - if isinstance(_zip, (str, pathlib.Path)): - # If we have a path then we use the zip file. - _zip = zipfile.ZipFile(_zip, 'a', zipfile.ZIP_DEFLATED) - kwargs['zip'] = _zip - createdZip = True - else: - createdZip = False - # Path needs to be done in a special way if we are in a zip file. - customPath = pathlib.Path(kwargs.get('customPath', '')) - # Set the open command to be that of the zip file. - _open = createZipOpen(_zip.open) - # Zip files use w for writing in binary. - mode = 'w' - else: - customPath = pathlib.Path(kwargs.get('customPath', '.')).absolute() - mode = 'wb' - _open = open - - fullFilename = customPath / filename - - if self.type is AttachmentType.DATA: + try: + # ZipFile handling. if _zip: - name, ext = os.path.splitext(filename) - nameList = _zip.namelist() - if fullFilename in nameList: - for i in range(2, 100): - testName = customPath / f'{name} ({i}){ext}' - if testName not in nameList: - fullFilename = testName - break - else: - # If we couldn't find one that didn't exist. - raise FileExistsError(f'Could not create the specified file because it already exists ("{fullFilename}").') + # If we are doing a zip file, first check that we have been + # given a path. + if isinstance(_zip, (str, pathlib.Path)): + # If we have a path then we use the zip file. + _zip = zipfile.ZipFile(_zip, 'a', zipfile.ZIP_DEFLATED) + kwargs['zip'] = _zip + createdZip = True + else: + createdZip = False + # Path needs to be done in a special way if we are in a zip + # file. + customPath = pathlib.Path(kwargs.get('customPath', '')) + # Set the open command to be that of the zip file. + _open = createZipOpen(_zip.open) + # Zip files use w for writing in binary. + mode = 'w' else: - if fullFilename.exists(): - # Try to split the filename into a name and extention. - name, ext = os.path.splitext(filename) - # Try to add a number to it so that we can save without overwriting. - for i in range(2, 100): - testName = customPath / f'{name} ({i}){ext}' - if not testName.exists(): - fullFilename = testName - break - else: - # If we couldn't find one that didn't exist. - raise FileExistsError(f'Could not create the specified file because it already exists ("{fullFilename}").') - - with _open(str(fullFilename), mode) as f: - f.write(self.__data) + customPath = pathlib.Path(kwargs.get('customPath', '.')).absolute() + mode = 'wb' + _open = open - # Close the ZipFile if this function created it. - if _zip and createdZip: - _zip.close() + fullFilename = customPath / filename + + if self.type is AttachmentType.DATA: + if _zip: + name, ext = os.path.splitext(filename) + nameList = _zip.namelist() + if fullFilename in nameList: + for i in range(2, 100): + testName = customPath / f'{name} ({i}){ext}' + if testName not in nameList: + fullFilename = testName + break + else: + # If we couldn't find one that didn't exist. + raise FileExistsError(f'Could not create the specified file because it already exists ("{fullFilename}").') + else: + if fullFilename.exists(): + # Try to split the filename into a name and extention. + name, ext = os.path.splitext(filename) + # Try to add a number to it so that we can save without + # overwriting. + for i in range(2, 100): + testName = customPath / f'{name} ({i}){ext}' + if not testName.exists(): + fullFilename = testName + break + else: + # If we couldn't find one that didn't exist. + raise FileExistsError(f'Could not create the specified file because it already exists ("{fullFilename}").') - return str(fullFilename) - else: - if kwargs.get('extractEmbedded', False): - ret = str(fullFilename) with _open(str(fullFilename), mode) as f: - # We just use the data we were given for this one. - f.write(self.__asBytes) - else: - ret = self.data - self.saveEmbededMessage(**kwargs) + f.write(self.__data) + return (SaveType.FILE, str(fullFilename)) + else: + if kwargs.get('extractEmbedded', False): + with _open(str(fullFilename), mode) as f: + # We just use the data we were given for this one. + f.write(self.__asBytes) + return (SaveType.FILE, str(fullFilename)) + else: + return self.saveEmbededMessage(**kwargs) + finally: # Close the ZipFile if this function created it. if _zip and createdZip: _zip.close() - return ret - - def saveEmbededMessage(self, **kwargs) -> None: + def saveEmbededMessage(self, **kwargs) -> constants.SAVE_TYPE: """ Seperate function from save to allow it to easily be overridden by a subclass. """ - self.data.save(**kwargs) + return self.data.save(**kwargs) @property def asBytes(self) -> bytes: diff --git a/extract_msg/attachments/unsupported_att.py b/extract_msg/attachments/unsupported_att.py index e7696366..07745383 100644 --- a/extract_msg/attachments/unsupported_att.py +++ b/extract_msg/attachments/unsupported_att.py @@ -3,8 +3,9 @@ ] +from .. import constants from .attachment_base import AttachmentBase -from ..enums import AttachmentType +from ..enums import AttachmentType, SaveType class UnsupportedAttachment(AttachmentBase): @@ -12,10 +13,10 @@ class UnsupportedAttachment(AttachmentBase): An attachment whose type is not currently supported. """ - def getFilename(self, **kwargs) -> str: + def getFilename(self, **_) -> str: raise NotImplementedError('Unsupported attachments cannot be saved.') - def save(self, **kwargs) -> None: + def save(self, **kwargs) -> constants.SAVE_TYPE: """ Raises a NotImplementedError unless :param skipNotImplemented: is set to True. If it is, returns None to signify the attachment was skipped. This diff --git a/extract_msg/attachments/web_att.py b/extract_msg/attachments/web_att.py index 996aa86b..c72ee2ca 100644 --- a/extract_msg/attachments/web_att.py +++ b/extract_msg/attachments/web_att.py @@ -3,12 +3,11 @@ ] +from typing import Optional + from .. import constants from .attachment_base import AttachmentBase -from ..enums import AttachmentPermissionType, AttachmentType - - -from typing import Optional +from ..enums import AttachmentPermissionType, AttachmentType, SaveType class WebAttachment(AttachmentBase): @@ -20,7 +19,7 @@ class WebAttachment(AttachmentBase): def getFilename(self) -> str: raise NotImplementedError('Cannot get the filename of a web attachment.') - def save(self, **kwargs) -> None: + def save(self, **kwargs) -> constants.SAVE_TYPE: """ Raises a NotImplementedError unless :param skipNotImplemented: is set to True. If it is, returns None to signify the attachment was skipped. This @@ -30,6 +29,8 @@ def save(self, **kwargs) -> None: if not kwargs.get('skipNotImplemented', False): raise NotImplementedError('Web attachments cannot be saved.') + return (SaveType.NONE, None) + @property def data(self) -> None: diff --git a/extract_msg/constants/__init__.py b/extract_msg/constants/__init__.py index 1fe4f5e1..e17cc29a 100644 --- a/extract_msg/constants/__init__.py +++ b/extract_msg/constants/__init__.py @@ -37,15 +37,17 @@ import datetime -from typing import Dict, Tuple, Union +from typing import Dict, List, Tuple, Union from . import ps, re, st +from ..enums import SaveType # Typing Constants. HEADER_FORMAT_VALUE_TYPE = Union[str, Tuple[Union[str, None], bool], None] # Basically a dict of HEADER_FORMAT_TYPE and dicts containing them. HEADER_FORMAT_TYPE = Dict[str, Union[HEADER_FORMAT_VALUE_TYPE, Dict[str, HEADER_FORMAT_VALUE_TYPE]]] +SAVE_TYPE = Tuple[SaveType, Union[List[str], str, None]] diff --git a/extract_msg/constants/re.py b/extract_msg/constants/re.py index 227dc4fa..0dcd05b9 100644 --- a/extract_msg/constants/re.py +++ b/extract_msg/constants/re.py @@ -16,7 +16,7 @@ # Characters that are invalid in a filename. -INVALID_FILENAME_CHARACTERS = re.compile(r'[\\/:*?"<>|]') +INVALID_FILENAME_CHARS = re.compile(r'[\\/:*?"<>|]') # Regular expression to find sections of spaces for htmlSanitize. HTML_SAN_SPACE = re.compile(' +') # Regular expression to find the start of the html body. diff --git a/extract_msg/enums.py b/extract_msg/enums.py index 6c4b3a9e..2913772e 100644 --- a/extract_msg/enums.py +++ b/extract_msg/enums.py @@ -1544,6 +1544,31 @@ class RuleActionType(enum.Enum): +class SaveType(enum.Enum): + """ + Specifies the way that a function saved the data. Used to determine how the + return value from a save function should be read. + + CUSTOM: An unlisted save method was used, and the second value is + unspecified. + NONE: No data was saved, and the second tuple value should be None. + FILE: A single file was save, and the location is the second value. + FILES: Multiple files were created, and the second value is a list of the + locations. + FOLDER: A folder was created to store data, and the location is the second + value. + FOLDERS: Multiple folders were created to store data, and the second value + is a list of the locations. + """ + CUSTOM = -1 + NONE = 0 + FILE = 1 + FILES = 2 + FOLDER = 3 + FOLDERS = 4 + + + class Sensitivity(enum.Enum): NORMAL = 0 PERSONAL = 1 diff --git a/extract_msg/msg_classes/message_base.py b/extract_msg/msg_classes/message_base.py index 43e69593..8e45d77a 100644 --- a/extract_msg/msg_classes/message_base.py +++ b/extract_msg/msg_classes/message_base.py @@ -1,6 +1,3 @@ -from __future__ import annotations - - __all__ = [ 'MessageBase', ] @@ -29,7 +26,9 @@ from .. import constants from .._rtf.create_doc import createDocument from .._rtf.inject_rtf import injectStartRTF -from ..enums import BodyTypes, DeencapType, ErrorBehavior, RecipientType +from ..enums import ( + BodyTypes, DeencapType, ErrorBehavior, RecipientType, SaveType + ) from ..exceptions import ( DataNotFoundError, DeencapMalformedData, DeencapNotEncapsulated, IncompatibleOptionsError, WKError @@ -120,48 +119,41 @@ def _genRecipient(self, recipientType, recipientInt : RecipientType) -> Optional """ Returns the specified recipient field. """ - private = '_' + recipientType recipientInt = RecipientType(recipientInt) - try: - return getattr(self, private) - except AttributeError: - value = None - # Check header first. - if self.headerInit(): - value = self.header[recipientType] - if value: - value = decodeRfc2047(value) - value = value.replace(',', self.__recipientSeparator) - - # If the header had a blank field or didn't have the field, generate - # it manually. - if not value: - # Check if the header has initialized. - if self.headerInit(): - logger.info(f'Header found, but "{recipientType}" is not included. Will be generated from other streams.') + value = None + # Check header first. + if self.headerInit(): + value = self.header[recipientType] + if value: + value = decodeRfc2047(value) + value = value.replace(',', self.__recipientSeparator) - # Get a list of the recipients of the specified type. - foundRecipients = tuple(recipient.formatted for recipient in self.recipients if recipient.type == recipientInt) + # If the header had a blank field or didn't have the field, generate + # it manually. + if not value: + # Check if the header has initialized. + if self.headerInit(): + logger.info(f'Header found, but "{recipientType}" is not included. Will be generated from other streams.') - # If we found recipients, join them with the recipient separator - # and a space. - if len(foundRecipients) > 0: - value = (self.__recipientSeparator + ' ').join(foundRecipients) + # Get a list of the recipients of the specified type. + foundRecipients = tuple(recipient.formatted for recipient in self.recipients if recipient.type == recipientInt) - # Code to fix the formatting so it's all a single line. This allows - # the user to format it themself if they want. This should probably - # be redone to use re or something, but I can do that later. This - # shouldn't be a huge problem for now. - if value: - value = value.replace(' \r\n\t', ' ').replace('\r\n\t ', ' ').replace('\r\n\t', ' ') - value = value.replace('\r\n', ' ').replace('\r', ' ').replace('\n', ' ') - while value.find(' ') != -1: - value = value.replace(' ', ' ') + # If we found recipients, join them with the recipient separator + # and a space. + if len(foundRecipients) > 0: + value = (self.__recipientSeparator + ' ').join(foundRecipients) - # Set the field in the class. - setattr(self, private, value) + # Code to fix the formatting so it's all a single line. This allows + # the user to format it themself if they want. This should probably + # be redone to use re or something, but I can do that later. This + # shouldn't be a huge problem for now. + if value: + value = value.replace(' \r\n\t', ' ').replace('\r\n\t ', ' ').replace('\r\n\t', ' ') + value = value.replace('\r\n', ' ').replace('\r', ' ').replace('\n', ' ') + while value.find(' ') != -1: + value = value.replace(' ', ' ') - return value + return value def deencapsulateBody(self, rtfBody : bytes, bodyType : DeencapType) -> Optional[Union[bytes, str]]: """ @@ -289,7 +281,7 @@ def getJson(self) -> str: 'body': decode_utf7(self.body), }) - def getSaveBody(self, **kwargs) -> bytes: + def getSaveBody(self, **_) -> bytes: """ Returns the plain text body that will be used in saving based on the arguments. @@ -585,7 +577,7 @@ def replace(bodyMarker): logger.debug('Using _rtf module to inject RTF text header.') return createDocument(injectStartRTF(self.rtfBody, injectableHeader)) - def save(self, **kwargs) -> MessageBase: + def save(self, **kwargs) -> constants.SAVE_TYPE: """ Saves the message body and attachments found in the message. @@ -686,164 +678,165 @@ def save(self, **kwargs) -> MessageBase: if pdf: kwargs['preparedHtml'] = True - # ZipFile handling. - if _zip: - # `raw` and `zip` are incompatible. - if raw: - raise IncompatibleOptionsError('The options `raw` and `zip` are incompatible.') - # If we are doing a zip file, first check that we have been given a - # path. - if isinstance(_zip, (str, pathlib.Path)): - # If we have a path then we use the zip file. - _zip = zipfile.ZipFile(_zip, 'a', zipfile.ZIP_DEFLATED) - kwargs['zip'] = _zip - createdZip = True - else: - createdZip = False - # Path needs to be done in a special way if we are in a zip file. - path = pathlib.Path(kwargs.get('customPath', '')) - # Set the open command to be that of the zip file. - _open = createZipOpen(_zip.open) - # Zip files use w for writing in binary. - mode = 'w' - else: - path = pathlib.Path(kwargs.get('customPath', '.')).absolute() - mode = 'wb' - _open = open - - # Reset this for sub save calls. - kwargs['customFilename'] = None - - # Check if incompatible options have been provided in any way. - if _json + html + rtf + raw + attachOnly + pdf > 1: - raise IncompatibleOptionsError('Only one of the following options may be used at a time: json, raw, html, rtf, attachmentsOnly, pdf.') - - # TODO: insert code here that will handle checking all of the msg files - # to see if the path with overflow. - - if customFilename: - # First we need to validate it. If there are invalid characters, - # this will detect it. - if constants.re.INVALID_FILENAME_CHARACTERS.search(customFilename): - raise ValueError('Invalid character found in customFilename. Must not contain any of the following characters: \\/:*?"<>|') - # Quick fix to remove spaces from the end of the filename, if any - # are there. - customFilename = customFilename.strip() - path /= customFilename[:maxNameLength] - elif useMsgFilename: - if not self.filename: - raise ValueError(':param useMsgFilename: is only available if you are using an msg file on the disk or have provided a filename.') - # Get the actual name of the file. - filename = os.path.split(self.filename)[1] - # Remove the extensions. - filename = os.path.splitext(filename)[0] - # Prepare the filename by removing any special characters. - filename = prepareFilename(filename) - # Shorted the filename. - filename = filename[:maxNameLength] - # Check to make sure we actually have a filename to use. - if not filename: - raise ValueError(f'Invalid filename found in self.filename: "{self.filename}"') - - # Add the file name to the path. - path /= filename[:maxNameLength] - else: - path /= self.defaultFolderName[:maxNameLength] + # Try to get the body, if needed, before messing with the path. + if not attachOnly: + # Check what to save the body with. + fext = 'json' if _json else 'txt' + + fallbackToPlain = False + useHtml = False + usePdf = False + useRtf = False + if html: + if self.htmlBody: + useHtml = True + fext = 'html' + elif not allowFallback: + if skipBodyNotFound: + fext = None + else: + raise DataNotFoundError('Could not find the htmlBody.') + + if pdf: + if self.htmlBody: + usePdf = True + fext = 'pdf' + elif not allowFallback: + if skipBodyNotFound: + fext = None + else: + raise DataNotFoundError('Count not find the htmlBody to convert to pdf.') - # Create the folders. - if not _zip: - try: - os.makedirs(path) - except Exception: - newDirName = addNumToDir(path) - if newDirName: - path = newDirName + if rtf or (html and not useHtml) or (pdf and not usePdf): + if self.rtfBody: + useRtf = True + fext = 'rtf' + elif not allowFallback: + if skipBodyNotFound: + fext = None + else: + raise DataNotFoundError('Could not find the rtfBody.') else: - raise Exception(f'Failed to create directory "{path}". Does it already exist?') - else: - # In my testing I ended up with multiple files in a zip at the same - # location so let's try to handle that. - pathCompare = str(path).replace('\\', '/').rstrip('/') + '/' - if any(x.startswith(pathCompare) for x in _zip.namelist()): - newDirName = addNumToZipDir(path, _zip) - if newDirName: - path = newDirName + # This was the last resort before plain text, so fall + # back to that. + fallbackToPlain = True + + # After all other options, try to go with plain text if + # possible. + if not (rtf or html or pdf) or fallbackToPlain: + # We need to check if the plain text body was found. If it + # was found but was empty that is considered valid, so we + # specifically check against None. + if self.body is None: + if skipBodyNotFound: + fext = None + else: + if allowFallback: + raise DataNotFoundError('Could not find a valid body using current options.') + else: + raise DataNotFoundError('Plain text body could not be found.') + + try: + # ZipFile handling. + if _zip: + # `raw` and `zip` are incompatible. + if raw: + raise IncompatibleOptionsError('The options `raw` and `zip` are incompatible.') + # If we are doing a zip file, first check that we have been given a + # path. + if isinstance(_zip, (str, pathlib.Path)): + # If we have a path then we use the zip file. + _zip = zipfile.ZipFile(_zip, 'a', zipfile.ZIP_DEFLATED) + kwargs['zip'] = _zip + createdZip = True else: - raise Exception(f'Failed to create directory "{path}". Does it already exist?') + createdZip = False + # Path needs to be done in a special way if we are in a zip file. + path = pathlib.Path(kwargs.get('customPath', '')) + # Set the open command to be that of the zip file. + _open = createZipOpen(_zip.open) + # Zip files use w for writing in binary. + mode = 'w' + else: + path = pathlib.Path(kwargs.get('customPath', '.')).absolute() + mode = 'wb' + _open = open + + # Reset this for sub save calls. + kwargs['customFilename'] = None + + # Check if incompatible options have been provided in any way. + if _json + html + rtf + raw + attachOnly + pdf > 1: + raise IncompatibleOptionsError('Only one of the following options may be used at a time: json, raw, html, rtf, attachmentsOnly, pdf.') + + # TODO: insert code here that will handle checking all of the msg + # files to see if the path with overflow. + + if customFilename: + # First we need to validate it. If there are invalid characters, + # this will detect it. + if constants.re.INVALID_FILENAME_CHARS.search(customFilename): + raise ValueError('Invalid character found in customFilename. Must not contain any of the following characters: \\/:*?"<>|') + # Quick fix to remove spaces from the end of the filename, if + # any are there. + customFilename = customFilename.strip() + path /= customFilename[:maxNameLength] + elif useMsgFilename: + if not self.filename: + raise ValueError(':param useMsgFilename: is only available if you are using an msg file on the disk or have provided a filename.') + # Get the actual name of the file. + filename = os.path.split(self.filename)[1] + # Remove the extensions. + filename = os.path.splitext(filename)[0] + # Prepare the filename by removing any special characters. + filename = prepareFilename(filename) + # Shorted the filename. + filename = filename[:maxNameLength] + # Check to make sure we actually have a filename to use. + if not filename: + raise ValueError(f'Invalid filename found in self.filename: "{self.filename}"') + + # Add the file name to the path. + path /= filename[:maxNameLength] + else: + path /= self.defaultFolderName[:maxNameLength] - # Update the kwargs. - kwargs['customPath'] = path + # Create the folders. + if not _zip: + try: + os.makedirs(path) + except Exception: + newDirName = addNumToDir(path) + if newDirName: + path = newDirName + else: + raise OSError(f'Failed to create directory "{path}". Does it already exist?') + else: + # In my testing I ended up with multiple files in a zip at the same + # location so let's try to handle that. + pathCompare = str(path).replace('\\', '/').rstrip('/') + '/' + if any(x.startswith(pathCompare) for x in _zip.namelist()): + newDirName = addNumToZipDir(path, _zip) + if newDirName: + path = newDirName + else: + raise Exception(f'Failed to create directory "{path}". Does it already exist?') - if raw: - self.saveRaw(path) - return self + # Update the kwargs. + kwargs['customPath'] = path - # If the user has requested the headers for this file, save it now. - if kwargs.get('saveHeader', False): - headerText = self.headerText - if not headerText: - headerText = constants.HEADER_FORMAT.format(subject = self.subject, **self.header) + if raw: + self.saveRaw(path) + return (SaveType.FOLDER, str(path)) - with _open(str(path / 'header.txt'), mode) as f: - f.write(headerText.encode('utf-8')) + # If the user has requested the headers for this file, save it now. + if kwargs.get('saveHeader', False): + headerText = self.headerText + if not headerText: + headerText = constants.HEADER_FORMAT.format(subject = self.subject, **self.header) - try: - if not attachOnly: - # Check what to save the body with. - fext = 'json' if _json else 'txt' - - fallbackToPlain = False - useHtml = False - usePdf = False - useRtf = False - if html: - if self.htmlBody: - useHtml = True - fext = 'html' - elif not allowFallback: - if skipBodyNotFound: - fext = None - else: - raise DataNotFoundError('Could not find the htmlBody.') - - if pdf: - if self.htmlBody: - usePdf = True - fext = 'pdf' - elif not allowFallback: - if skipBodyNotFound: - fext = None - else: - raise DataNotFoundError('Count not find the htmlBody to convert to pdf.') - - if rtf or (html and not useHtml) or (pdf and not usePdf): - if self.rtfBody: - useRtf = True - fext = 'rtf' - elif not allowFallback: - if skipBodyNotFound: - fext = None - else: - raise DataNotFoundError('Could not find the rtfBody.') - else: - # This was the last resort before plain text, so fall - # back to that. - fallbackToPlain = True - - # After all other options, try to go with plain text if - # possible. - if not (rtf or html or pdf) or fallbackToPlain: - # We need to check if the plain text body was found. If it - # was found but was empty that is considered valid, so we - # specifically check against None. - if self.body is None: - if skipBodyNotFound: - fext = None - else: - if allowFallback: - raise DataNotFoundError('Could not find a valid body using current options.') - else: - raise DataNotFoundError('Plain text body could not be found.') + with _open(str(path / 'header.txt'), mode) as f: + f.write(headerText.encode('utf-8')) if not skipAttachments: @@ -868,15 +861,14 @@ def save(self, **kwargs) -> MessageBase: f.write(self.getSaveRtfBody(**kwargs)) else: f.write(self.getSaveBody(**kwargs)) + + return (SaveType.FOLDER, str(path)) finally: # Close the ZipFile if this function created it. if _zip and createdZip: _zip.close() - # Return the instance so that functions can easily be chained. - return self - - @property + @functools.cached_property def bcc(self) -> Optional[str]: """ Returns the bcc field, if it exists. @@ -891,7 +883,8 @@ def body(self) -> Optional[str]: try: return self._body except AttributeError: - if self._ensureSet('_body', '__substg1.0_1000'): + # If the body exists but is empty, that means it should be returned. + if self._ensureSet('_body', '__substg1.0_1000') is not None: pass else: # If the body doesn't exist, see if we can get it from the RTF @@ -901,13 +894,12 @@ def body(self) -> Optional[str]: if self._body: self._body = inputToString(self._body, 'utf-8') - a = re.search('\n', self._body) - if a is not None: + if re.search('\n', self._body) is not None: if re.search('\r\n', self._body) is not None: self.__crlf = '\r\n' return self._body - @property + @functools.cached_property def cc(self) -> Optional[str]: """ Returns the cc field, if it exists. @@ -927,19 +919,14 @@ def crlf(self) -> str: Returns the value of self.__crlf, should you need it for whatever reason. """ - self.body return self.__crlf - @property - def date(self) -> Optional[str]: + @functools.cached_property + def date(self) -> Optional[datetime.datetime]: """ - Returns the send date, if it exists. + Returns the string for the send date, if it exists. """ - try: - return self._date - except AttributeError: - self._date = self._prop.date if self.isSent else None - return self._date + return self._prop.date if self.isSent else None @property def deencapsulatedRtf(self) -> Optional[RTFDE.DeEncapsulator]: @@ -1228,28 +1215,19 @@ def receivedTime(self) -> Optional[datetime.datetime]: def recipientSeparator(self) -> str: return self.__recipientSeparator - @property + @functools.cached_property def recipients(self) -> List[Recipient]: """ Returns a list of all recipients. """ - try: - return self._recipients - except AttributeError: - # Get the recipients - recipientDirs = [] - prefixLen = self.prefixLen - for dir_ in self.listDir(): - if dir_[prefixLen].startswith('__recip') and\ - dir_[prefixLen] not in recipientDirs: - recipientDirs.append(dir_[prefixLen]) - - self._recipients = [] + recipientDirs = [] + prefixLen = self.prefixLen + for dir_ in self.listDir(): + if dir_[prefixLen].startswith('__recip') and\ + dir_[prefixLen] not in recipientDirs: + recipientDirs.append(dir_[prefixLen]) - for recipientDir in recipientDirs: - self._recipients.append(Recipient(recipientDir, self)) - - return self._recipients + return [Recipient(recipientDir, self) for recipientDir in recipientDirs] @property def reportTag(self) -> Optional[ReportTag]: @@ -1288,8 +1266,8 @@ def rtfPlainInjectableHeader(self) -> bytes: body. """ prefix = '{' - suffix = r'\par\par}' - joinStr = r'\line' + suffix = '\\par\\par}' + joinStr = '\\line' formatter = (lambda name, value : fr'{{\b {name}: \b0 {inputToString(rtfSanitizePlain(value), self.stringEncoding)}}}') return self.getInjectableHeader(prefix, joinStr, suffix, formatter).encode('utf-8') @@ -1331,7 +1309,7 @@ def subject(self) -> Optional[str]: """ return self._ensureSet('_subject', '__substg1.0_0037') - @property + @functools.cached_property def to(self) -> Optional[str]: """ Returns the to field, if it exists. From 0bff90cd2597c6fae205b1cc9c0932629d06b1e7 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Sat, 1 Jul 2023 18:13:24 -0700 Subject: [PATCH 59/89] Finish new attachment save code --- extract_msg/attachments/attachment.py | 3 +- extract_msg/attachments/broken_att.py | 10 +- extract_msg/attachments/custom_att.py | 3 +- extract_msg/attachments/emb_msg_att.py | 105 +++++++++++---------- extract_msg/attachments/signed_att.py | 18 ++-- extract_msg/attachments/unsupported_att.py | 8 +- extract_msg/attachments/web_att.py | 11 +-- extract_msg/msg_classes/message_base.py | 14 +-- 8 files changed, 88 insertions(+), 84 deletions(-) diff --git a/extract_msg/attachments/attachment.py b/extract_msg/attachments/attachment.py index 9d05676a..8ab3164a 100644 --- a/extract_msg/attachments/attachment.py +++ b/extract_msg/attachments/attachment.py @@ -137,6 +137,7 @@ def save(self, **kwargs) -> constants.SAVE_TYPE: # Check if we are doing a zip file. _zip = kwargs.get('zip') + createdZip = False try: # ZipFile handling. if _zip: @@ -147,8 +148,6 @@ def save(self, **kwargs) -> constants.SAVE_TYPE: _zip = zipfile.ZipFile(_zip, 'a', zipfile.ZIP_DEFLATED) kwargs['zip'] = _zip createdZip = True - else: - createdZip = False # Path needs to be done in a special way if we are in a zip # file. customPath = pathlib.Path(kwargs.get('customPath', '')) diff --git a/extract_msg/attachments/broken_att.py b/extract_msg/attachments/broken_att.py index 2bbfaff0..d272bb3e 100644 --- a/extract_msg/attachments/broken_att.py +++ b/extract_msg/attachments/broken_att.py @@ -18,10 +18,14 @@ def getFilename(self, **_) -> str: raise NotImplementedError('Broken attachments cannot be saved.') def save(self, **kwargs) -> constants.SAVE_TYPE: - if not kwargs.get('skipNotImplemented', False): - raise NotImplementedError('Broken attachments cannot be saved.') + """ + Raises a NotImplementedError unless :param skipNotImplemented: is set to + True. If it is, returns a value that indicates no data was saved. + """ + if kwargs.get('skipNotImplemented', False): + return (SaveType.NONE, None) - return (SaveType.NONE, None) + raise NotImplementedError('Broken attachments cannot be saved.') @property def data(self) -> None: diff --git a/extract_msg/attachments/custom_att.py b/extract_msg/attachments/custom_att.py index 2ecfcc50..ab8c83af 100644 --- a/extract_msg/attachments/custom_att.py +++ b/extract_msg/attachments/custom_att.py @@ -108,6 +108,7 @@ def save(self, **kwargs) -> constants.SAVE_TYPE: # Check if we are doing a zip file. _zip = kwargs.get('zip') + createdZip = False try: # ZipFile handling. if _zip: @@ -117,8 +118,6 @@ def save(self, **kwargs) -> constants.SAVE_TYPE: _zip = zipfile.ZipFile(_zip, 'a', zipfile.ZIP_DEFLATED) kwargs['zip'] = _zip createdZip = True - else: - createdZip = False # Path needs to be done in a special way if we are in a zip file. customPath = pathlib.Path(kwargs.get('customPath', '')) # Set the open command to be that of the zip file. diff --git a/extract_msg/attachments/emb_msg_att.py b/extract_msg/attachments/emb_msg_att.py index 64fa305b..b3784ef9 100644 --- a/extract_msg/attachments/emb_msg_att.py +++ b/extract_msg/attachments/emb_msg_att.py @@ -64,60 +64,61 @@ def save(self, **kwargs) -> constants.SAVE_TYPE: if kwargs.get('skipEmbedded'): return (SaveType.NONE, None) - # Get the filename to use. - filename = self.getFilename(**kwargs) - - # Someone managed to have a null character here, so let's get rid of - # that - filename = prepareFilename(filename) - - # Get the maximum name length. - maxNameLength = kwargs.get('maxNameLength', 256) - - # Make sure the filename is not longer than it should be. - if len(filename) > maxNameLength: - name, ext = os.path.splitext(filename) - filename = name[:maxNameLength - len(ext)] + ext - - # Check if we are doing a zip file. - _zip = kwargs.get('zip') - - # ZipFile handling. - if _zip: - # If we are doing a zip file, first check that we have been given a path. - if isinstance(_zip, (str, pathlib.Path)): - # If we have a path then we use the zip file. - _zip = zipfile.ZipFile(_zip, 'a', zipfile.ZIP_DEFLATED) - kwargs['zip'] = _zip - createdZip = True - else: - createdZip = False - # Path needs to be done in a special way if we are in a zip file. - customPath = pathlib.Path(kwargs.get('customPath', '')) - # Set the open command to be that of the zip file. - _open = createZipOpen(_zip.open) - # Zip files use w for writing in binary. - mode = 'w' - else: - customPath = pathlib.Path(kwargs.get('customPath', '.')).absolute() - mode = 'wb' - _open = open - - fullFilename = customPath / filename - + # We only need to handle things if we are saving as bytes. if kwargs.get('extractEmbedded', False): - ret = str(fullFilename) - with _open(str(fullFilename), mode) as f: - self.data.export(f) + # Get the filename to use. + filename = self.getFilename(**kwargs) + + # Someone managed to have a null character here, so let's get rid of + # that + filename = prepareFilename(filename) + + # Get the maximum name length. + maxNameLength = kwargs.get('maxNameLength', 256) + + # Make sure the filename is not longer than it should be. + if len(filename) > maxNameLength: + name, ext = os.path.splitext(filename) + filename = name[:maxNameLength - len(ext)] + ext + + # Check if we are doing a zip file. + _zip = kwargs.get('zip') + + createdZip = False + try: + # ZipFile handling. + if _zip: + # If we are doing a zip file, first check that we have been given a path. + if isinstance(_zip, (str, pathlib.Path)): + # If we have a path then we use the zip file. + _zip = zipfile.ZipFile(_zip, 'a', zipfile.ZIP_DEFLATED) + kwargs['zip'] = _zip + createdZip = True + # Path needs to be done in a special way if we are in a zip file. + customPath = pathlib.Path(kwargs.get('customPath', '')) + # Set the open command to be that of the zip file. + _open = createZipOpen(_zip.open) + # Zip files use w for writing in binary. + mode = 'w' + else: + customPath = pathlib.Path(kwargs.get('customPath', '.')).absolute() + mode = 'wb' + _open = open + + fullFilename = customPath / filename + + with _open(str(fullFilename), mode) as f: + self.data.export(f) + + return (SaveType.FILE, str(fullFilename)) + finally: + # Close the ZipFile if this function created it. + if _zip and createdZip: + _zip.close() else: - ret = self.data - self.data.save(**kwargs) - - # Close the ZipFile if this function created it. - if _zip and createdZip: - _zip.close() - - return ret + # If we are letting the MSG file create stuff, just let it handle + # everything. + return self.data.save(**kwargs) save.__doc__ = _saveDoc diff --git a/extract_msg/attachments/signed_att.py b/extract_msg/attachments/signed_att.py index 91664c6c..a1802852 100644 --- a/extract_msg/attachments/signed_att.py +++ b/extract_msg/attachments/signed_att.py @@ -95,6 +95,12 @@ def save(self, **kwargs) -> constants.SAVE_TYPE: if self.type is AttachmentType.SIGNED_EMBEDDED and kwargs.get('skipEmbedded'): return (SaveType.NONE, None) + # If we are running the save function for the MSG file, just let it + # handle everything. + if (self.type is AttachmentType.SIGNED_EMBEDDED and + not kwargs.get('extractEmbedded', False)): + return self.saveEmbededMessage(**kwargs) + # Check if the user has specified a custom filename filename = self.name @@ -112,6 +118,7 @@ def save(self, **kwargs) -> constants.SAVE_TYPE: # Check if we are doing a zip file. _zip = kwargs.get('zip') + createdZip = True try: # ZipFile handling. if _zip: @@ -171,13 +178,10 @@ def save(self, **kwargs) -> constants.SAVE_TYPE: return (SaveType.FILE, str(fullFilename)) else: - if kwargs.get('extractEmbedded', False): - with _open(str(fullFilename), mode) as f: - # We just use the data we were given for this one. - f.write(self.__asBytes) - return (SaveType.FILE, str(fullFilename)) - else: - return self.saveEmbededMessage(**kwargs) + with _open(str(fullFilename), mode) as f: + # We just use the data we were given for this one. + f.write(self.__asBytes) + return (SaveType.FILE, str(fullFilename)) finally: # Close the ZipFile if this function created it. if _zip and createdZip: diff --git a/extract_msg/attachments/unsupported_att.py b/extract_msg/attachments/unsupported_att.py index 07745383..97a756e9 100644 --- a/extract_msg/attachments/unsupported_att.py +++ b/extract_msg/attachments/unsupported_att.py @@ -19,12 +19,12 @@ def getFilename(self, **_) -> str: def save(self, **kwargs) -> constants.SAVE_TYPE: """ Raises a NotImplementedError unless :param skipNotImplemented: is set to - True. If it is, returns None to signify the attachment was skipped. This - allows for the easy implementation of the option to skip this type of - attachment. + True. If it is, returns a value that indicates no data was saved. """ if not kwargs.get('skipNotImplemented', False): - raise NotImplementedError('Unsupported attachments cannot be saved.') + return (SaveType.NONE, None) + + raise NotImplementedError('Unsupported attachments cannot be saved.') @property def data(self) -> None: diff --git a/extract_msg/attachments/web_att.py b/extract_msg/attachments/web_att.py index c72ee2ca..c44d4c04 100644 --- a/extract_msg/attachments/web_att.py +++ b/extract_msg/attachments/web_att.py @@ -22,15 +22,12 @@ def getFilename(self) -> str: def save(self, **kwargs) -> constants.SAVE_TYPE: """ Raises a NotImplementedError unless :param skipNotImplemented: is set to - True. If it is, returns None to signify the attachment was skipped. This - allows for the easy implementation of the option to skip this type of - attachment. + True. If it is, returns a value that indicates no data was saved. """ - if not kwargs.get('skipNotImplemented', False): - raise NotImplementedError('Web attachments cannot be saved.') - - return (SaveType.NONE, None) + if kwargs.get('skipNotImplemented', False): + return (SaveType.NONE, None) + raise NotImplementedError('Web attachments cannot be saved.') @property def data(self) -> None: diff --git a/extract_msg/msg_classes/message_base.py b/extract_msg/msg_classes/message_base.py index 8e45d77a..46132384 100644 --- a/extract_msg/msg_classes/message_base.py +++ b/extract_msg/msg_classes/message_base.py @@ -736,22 +736,22 @@ def save(self, **kwargs) -> constants.SAVE_TYPE: else: raise DataNotFoundError('Plain text body could not be found.') + createdZip = False try: # ZipFile handling. if _zip: # `raw` and `zip` are incompatible. if raw: raise IncompatibleOptionsError('The options `raw` and `zip` are incompatible.') - # If we are doing a zip file, first check that we have been given a - # path. + # If we are doing a zip file, first check that we have been + # given a path. if isinstance(_zip, (str, pathlib.Path)): # If we have a path then we use the zip file. _zip = zipfile.ZipFile(_zip, 'a', zipfile.ZIP_DEFLATED) kwargs['zip'] = _zip createdZip = True - else: - createdZip = False - # Path needs to be done in a special way if we are in a zip file. + # Path needs to be done in a special way if we are in a zip + # file. path = pathlib.Path(kwargs.get('customPath', '')) # Set the open command to be that of the zip file. _open = createZipOpen(_zip.open) @@ -812,8 +812,8 @@ def save(self, **kwargs) -> constants.SAVE_TYPE: else: raise OSError(f'Failed to create directory "{path}". Does it already exist?') else: - # In my testing I ended up with multiple files in a zip at the same - # location so let's try to handle that. + # In my testing I ended up with multiple files in a zip at the + # same location so let's try to handle that. pathCompare = str(path).replace('\\', '/').rstrip('/') + '/' if any(x.startswith(pathCompare) for x in _zip.namelist()): newDirName = addNumToZipDir(path, _zip) From 3bf47a80adcaab2d7d9bd394b27822224356b23f Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Sat, 1 Jul 2023 18:22:18 -0700 Subject: [PATCH 60/89] Fix attachment handling in MessageBase.save --- extract_msg/msg_classes/message_base.py | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/extract_msg/msg_classes/message_base.py b/extract_msg/msg_classes/message_base.py index 46132384..e5785c0a 100644 --- a/extract_msg/msg_classes/message_base.py +++ b/extract_msg/msg_classes/message_base.py @@ -300,7 +300,7 @@ def getSaveBody(self, **_) -> bytes: header = self.getInjectableHeader(prefix, joinStr, suffix, formatter).encode('utf-8') return header + inputToBytes(self.body, 'utf-8') - def getSaveHtmlBody(self, preparedHtml : bool = False, charset : str = 'utf-8', **kwargs) -> bytes: + def getSaveHtmlBody(self, preparedHtml : bool = False, charset : str = 'utf-8', **_) -> bytes: """ Returns the HTML body that will be used in saving based on the arguments. @@ -348,7 +348,7 @@ def getSaveHtmlBody(self, preparedHtml : bool = False, charset : str = 'utf-8', else: return self.htmlBody - def getSavePdfBody(self, **kwargs) -> bytes: + def getSavePdfBody(self, wkPath = None, wkOptions = None, **kwargs) -> bytes: """ Returns the PDF body that will be used in saving based on the arguments. @@ -367,10 +367,9 @@ def getSavePdfBody(self, **kwargs) -> bytes: :raises WKError: Something went wrong in creating the PDF body. """ # Immediately try to find the executable. - wkPath = findWk(kwargs.get('wkPath')) + wkPath = findWk(wkPath) # First thing is first, we need to parse our wkOptions if they exist. - wkOptions = kwargs.get('wkOptions') if wkOptions: try: # Try to convert to a list, whatever it is, and fail if it is @@ -407,7 +406,7 @@ def getSavePdfBody(self, **kwargs) -> bytes: return process.stdout - def getSaveRtfBody(self, **kwargs) -> bytes: + def getSaveRtfBody(self, **_) -> bytes: """ Returns the RTF body that will be used in saving based on the arguments. @@ -841,9 +840,14 @@ def save(self, **kwargs) -> constants.SAVE_TYPE: if not skipAttachments: # Save the attachments. - attachmentNames = [attachment.save(**kwargs) for attachment in self.attachments if not (skipHidden and attachment.hidden)] - # Remove skipped attachments. - attachmentNames = [x for x in attachmentNames if x and isinstance(x, str)] + attachmentReturns = [attachment.save(**kwargs) for attachment in self.attachments if not (skipHidden and attachment.hidden)] + # Get the names from each. + attachmentNames = [] + for x in attachmentReturns: + if isinstance(x[1], str): + attachmentNames.append(x[1]) + elif isinstance(x[1], list): + attachmentNames.extend(x[1]) if not attachOnly and fext: with _open(str(path / ('message.' + fext)), mode) as f: @@ -852,7 +856,7 @@ def save(self, **kwargs) -> constants.SAVE_TYPE: if not skipAttachments: emailObj['attachments'] = attachmentNames - f.write(inputToBytes(json.dumps(emailObj), 'utf-8')) + f.write(json.dumps(emailObj).encode('utf-8')) elif useHtml: f.write(self.getSaveHtmlBody(**kwargs)) elif usePdf: From fec08d17682e5e5156618eb12f271d80cd2e2bc9 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Sat, 1 Jul 2023 18:26:08 -0700 Subject: [PATCH 61/89] Change some more things to cached property --- extract_msg/msg_classes/message_base.py | 40 +++++++++++-------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/extract_msg/msg_classes/message_base.py b/extract_msg/msg_classes/message_base.py index e5785c0a..8e60842e 100644 --- a/extract_msg/msg_classes/message_base.py +++ b/extract_msg/msg_classes/message_base.py @@ -1004,33 +1004,29 @@ def detectedBodies(self) -> BodyTypes: return bodies - @property + @functools.cached_property def header(self) -> email.message.Message: """ Returns the message header, if it exists. Otherwise it will generate one. """ - try: - return self._header - except AttributeError: - headerText = self.headerText - if headerText: - self._header = EmailParser().parsestr(headerText) - self._header['date'] = self.date - else: - logger.info('Header is empty or was not found. Header will be generated from other streams.') - header = EmailParser().parsestr('') - header.add_header('Date', self.date) - header.add_header('From', self.sender) - header.add_header('To', self.to) - header.add_header('Cc', self.cc) - header.add_header('Bcc', self.bcc) - header.add_header('Message-Id', self.messageId) - # TODO find authentication results outside of header - header.add_header('Authentication-Results', None) - self._header = header - - return self._header + headerText = self.headerText + if headerText: + header = EmailParser().parsestr(headerText) + header['date'] = self.date + else: + logger.info('Header is empty or was not found. Header will be generated from other streams.') + header = EmailParser().parsestr('') + header.add_header('Date', self.date) + header.add_header('From', self.sender) + header.add_header('To', self.to) + header.add_header('Cc', self.cc) + header.add_header('Bcc', self.bcc) + header.add_header('Message-Id', self.messageId) + # TODO find authentication results outside of header + header.add_header('Authentication-Results', None) + + return header @property def headerDict(self) -> dict: From 7ba32bf2ac9c0b1c4bf6ec3a98d7caae2dfde70d Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Sat, 1 Jul 2023 19:10:54 -0700 Subject: [PATCH 62/89] Typing and cached property stuff --- extract_msg/msg_classes/msg.py | 94 ++++++++++++++------------------- extract_msg/properties/named.py | 9 ++-- extract_msg/utils.py | 7 ++- 3 files changed, 49 insertions(+), 61 deletions(-) diff --git a/extract_msg/msg_classes/msg.py b/extract_msg/msg_classes/msg.py index af79669c..c12c3398 100644 --- a/extract_msg/msg_classes/msg.py +++ b/extract_msg/msg_classes/msg.py @@ -9,6 +9,7 @@ import codecs import copy import datetime +import functools import io import logging import os @@ -18,7 +19,7 @@ import olefile -from typing import Any, Callable, List, Optional, Set, Tuple, Union +from typing import Any, Callable, cast, List, Optional, Set, Tuple, Union from .. import constants from ..attachments import ( @@ -27,7 +28,7 @@ from ..encoding import lookupCodePage from ..enums import ( AttachErrorBehavior, ErrorBehavior, InsecureFeatures, Importance, - Priority, PropertiesType, Sensitivity, SideEffect + Priority, PropertiesType, SaveType, Sensitivity, SideEffect ) from ..exceptions import ( ConversionError, InvalidFileFormatError, PrefixError, @@ -97,7 +98,7 @@ def __init__(self, path, **kwargs): # Retrieve all the kwargs that we need. self.__inscFeat = kwargs.get('insecureFeatures', InsecureFeatures.NONE) prefix = kwargs.get('prefix', '') - self.__parentMsg = makeWeakRef(kwargs.get('parentMsg')) + self.__parentMsg = makeWeakRef(cast(MSGFile, kwargs.get('parentMsg'))) self.__treePath = kwargs.get('treePath', []) + [makeWeakRef(self)] # Verify it is a valid class. if self.__parentMsg and not isinstance(self.__parentMsg(), MSGFile): @@ -469,14 +470,11 @@ def _oleListDir(self, streams : bool = True, storages : bool = False) -> List: def close(self) -> None: if self.__open: - try: - # If this throws an AttributeError then we have not loaded the attachments. - self._attachments + if self.attachmentsReady: for attachment in self.attachments: if attachment.type == 'msg': attachment.data.close() - except AttributeError: - pass + if self.__oleOwner: self.__ole.close() @@ -609,7 +607,10 @@ def slistDir(self, streams : bool = True, storages : bool = False) -> List[str]: """ return [msgPathToString(x) for x in self.listDir(streams, storages)] - def save(self, *args, **kwargs): + def save(self, **kwargs) -> constants.SAVE_TYPE: + if kwargs.get('skipNotImplemented', False): + return (SaveType.NONE, None) + raise NotImplementedError(f'Saving is not yet supported for the {self.__class__.__name__} class.') def saveAttachments(self, **kwargs) -> None: @@ -656,43 +657,36 @@ def saveRaw(self, path): if data is not None: f.write(data) - @property + @functools.cached_property def areStringsUnicode(self) -> bool: """ Returns a boolean telling if the strings are unicode encoded. """ - try: - return self.__bStringsUnicode - except AttributeError: - if '340D0003' in self.props: - if (self.props['340D0003'].value & 0x40000) != 0: - self.__bStringsUnicode = True - return self.__bStringsUnicode - self.__bStringsUnicode = False - return self.__bStringsUnicode + if '340D0003' in self.props: + if (self.props['340D0003'].value & 0x40000) != 0: + return True - @property + return False + + @functools.cached_property def attachments(self) -> Union[List[AttachmentBase], List[SignedAttachment]]: """ Returns a list of all attachments. """ - try: - return self._attachments - except AttributeError: - # Get the attachments. - attachmentDirs = [] - for dir_ in self.listDir(False, True, False): - if dir_[0].startswith('__attach') and dir_[0] not in attachmentDirs: - attachmentDirs.append(dir_[0]) + # Get the attachments. + attachmentDirs = [] + for dir_ in self.listDir(False, True, False): + if dir_[0].startswith('__attach') and dir_[0] not in attachmentDirs: + attachmentDirs.append(dir_[0]) - self._attachments = [] + attachments = [] - for attachmentDir in attachmentDirs: - self._attachments.append(self.initAttachmentFunc(self, attachmentDir)) + for attachmentDir in attachmentDirs: + attachments.append(self.initAttachmentFunc(self, attachmentDir)) - self.__attachmentsReady = True + self.__attachmentsReady = True - return self._attachments + return attachments @property def attachmentsDelayed(self) -> bool: @@ -804,7 +798,7 @@ def kwargs(self) -> dict: """ return self.__kwargs - @property + @functools.cached_property def named(self) -> Named: """ The main named properties storage. This is not usable to access the data @@ -813,33 +807,23 @@ def named(self) -> Named: :raises ReferenceError: The parent MSGFile instance has been garbage collected. """ - try: - return self.__named - except AttributeError: - self.__named = None - # Handle the parent msg file existing. - if self.__parentMsg: - # Try to get the named properties and use that for our main - # instance. - if (msg := self.__parentMsg()) is None: - raise ReferenceError('Parent MSGFile instance has been garbage collected.') - self.__named = msg.named - else: - self.__named = Named(self) - - return self.__named + # Handle the parent msg file existing. + if self.__parentMsg: + # Try to get the named properties and use that for our main + # instance. + if (msg := self.__parentMsg()) is None: + raise ReferenceError('Parent MSGFile instance has been garbage collected.') + return msg.named + else: + return Named(self) - @property + @functools.cached_property def namedProperties(self) -> NamedProperties: """ The NamedProperties instances usable to access the data for named properties. """ - try: - return self.__namedProperties - except AttributeError: - self.__namedProperties = NamedProperties(self.named, self) - return self.__namedProperties + return NamedProperties(self.named, self) @property def overrideEncoding(self): diff --git a/extract_msg/properties/named.py b/extract_msg/properties/named.py index 737ec6b7..d7431ed4 100644 --- a/extract_msg/properties/named.py +++ b/extract_msg/properties/named.py @@ -14,7 +14,7 @@ import logging import pprint -from typing import Dict, Optional, Tuple, TYPE_CHECKING +from typing import Any, Dict, List, Optional, Tuple, TYPE_CHECKING, Union from .. import constants from ..enums import NamedPropertyType @@ -25,6 +25,7 @@ # Allow for nice type checking. if TYPE_CHECKING: from ..msg_classes.msg import MSGFile + from ..attachments.attachment_base import AttachmentBase logger = logging.getLogger(__name__) logger.addHandler(logging.NullHandler()) @@ -37,7 +38,7 @@ class Named: __dir = '__nameid_version1.0' - def __init__(self, msg): + def __init__(self, msg : MSGFile): self.__msg = makeWeakRef(msg) # Get the basic streams. If all are emtpy, then nothing to do. guidStream = self._getStream('__substg1.0_00020102') or self._getStream('__substg1.0_00020102', False) @@ -57,7 +58,7 @@ def __init__(self, msg): # Check that we even have any entries. If there are none, nothing to do. if entryStream: guids = tuple([None, constants.ps.PS_MAPI, constants.ps.PS_PUBLIC_STRINGS] + [bytesToGuid(x) for x in divide(guidStream, 16)]) - entries = [] + entries : List[Dict[str, Any]]= [] for rawStream in divide(entryStream, 8): tmp = constants.st.STNP_ENT.unpack(rawStream) entry = { @@ -237,7 +238,7 @@ class NamedProperties: An instance that uses a Named instance and an extract-msg class to read the data of named properties. """ - def __init__(self, named, streamSource): + def __init__(self, named, streamSource : Union[MSGFile, AttachmentBase]): """ :param named: The named instance to refer to for named properties entries. diff --git a/extract_msg/utils.py b/extract_msg/utils.py index 35cb5ad5..26fba656 100644 --- a/extract_msg/utils.py +++ b/extract_msg/utils.py @@ -29,6 +29,7 @@ 'inputToString', 'isEncapsulatedRtf', 'isEmptyString', + 'makeWeakRef', 'msgPathToString', 'parseType', 'prepareFilename', @@ -71,7 +72,7 @@ import tzlocal from html import escape as htmlEscape -from typing import Any, Dict, List, Optional, TYPE_CHECKING, Union +from typing import Any, Dict, List, Optional, TypeVar, TYPE_CHECKING, Union from . import constants from .enums import AttachmentType @@ -89,6 +90,8 @@ logger.addHandler(logging.NullHandler()) logging.addLevelName(5, 'DEVELOPER') +_T = TypeVar("_T") + def addNumToDir(dirName : pathlib.Path) -> Optional[pathlib.Path]: """ @@ -598,7 +601,7 @@ def filetimeToUtc(inp : int) -> float: return (inp - 116444736000000000) / 10000000.0 -def makeWeakRef(obj : Optional[object]) -> Optional[weakref.ReferenceType]: +def makeWeakRef(obj : Optional[_T]) -> Optional[weakref.ReferenceType[_T]]: """ Attempts to return a weak reference to the object, returning None if not possible. From 5bdb5dc82f4ccedd2df0a4b1dd461ddddd59995a Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Sat, 1 Jul 2023 23:24:02 -0700 Subject: [PATCH 63/89] Update usage of intflags and change prop internals --- CHANGELOG.md | 2 + extract_msg/attachments/__init__.py | 6 +- extract_msg/attachments/attachment_base.py | 43 ++- .../custom_att_handler/outlook_image_dib.py | 2 +- extract_msg/enums.py | 42 +-- extract_msg/msg_classes/appointment.py | 39 +-- extract_msg/msg_classes/calendar.py | 41 +-- extract_msg/msg_classes/calendar_base.py | 306 +++++++++--------- extract_msg/msg_classes/contact.py | 188 +++++------ extract_msg/msg_classes/meeting_exception.py | 6 +- extract_msg/msg_classes/meeting_forward.py | 4 +- extract_msg/msg_classes/meeting_related.py | 15 +- extract_msg/msg_classes/meeting_request.py | 18 +- extract_msg/msg_classes/meeting_response.py | 29 +- extract_msg/msg_classes/message_base.py | 47 ++- .../msg_classes/message_signed_base.py | 25 +- extract_msg/msg_classes/msg.py | 114 +++---- extract_msg/msg_classes/sticky_note.py | 27 +- extract_msg/msg_classes/task.py | 149 ++++----- extract_msg/msg_classes/task_request.py | 61 ++-- extract_msg/recipient.py | 2 +- 21 files changed, 558 insertions(+), 608 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1373a1e5..408be216 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,8 @@ * Modified all custom exceptions the module uses to derive from a single base class for better organization. * Added new exceptions to handle some of the situations previously handled by base Python exceptions. * Changed internal handling of the `prefix` option for `MSGFile.__init__` (and therefore `openMsg`). If you are not setting this manually, you should notice little difference. +* Made enums less strict and converted all using `fromBits` to be `IntFlag` enums. +* Fixed `CalendarBase.keywords` being blatantly incorrect (it was so bad I don't know how it slipped through). **v0.41.5** * Fixed an issue from version `0.41.3` where the header being present but missing the `From` field would cause an exception. diff --git a/extract_msg/attachments/__init__.py b/extract_msg/attachments/__init__.py index 8ec1b90e..1c86d3e1 100644 --- a/extract_msg/attachments/__init__.py +++ b/extract_msg/attachments/__init__.py @@ -120,19 +120,19 @@ def initStandardAttachment(msg : MSGFile, dir_) -> AttachmentBase: raise NotImplementedError(f'Could not determine attachment type ({attMethod})!') except (NotImplementedError, UnrecognizedMSGTypeError): - if msg.errorBehavior & ErrorBehavior.ATTACH_NOT_IMPLEMENTED: + if ErrorBehavior.ATTACH_NOT_IMPLEMENTED in msg.errorBehavior: _logger.exception(f'Error processing attachment at {dir_}') return UnsupportedAttachment(msg, dir_, propStore) else: raise except StandardViolationError: - if msg.errorBehavior & ErrorBehavior.STANDARDS_VIOLATION: + if ErrorBehavior.STANDARDS_VIOLATION in msg.errorBehavior: _logger.exception(f'Unresolvable standards violation in {dir_}') return BrokenAttachment(msg, dir_, propStore) else: raise except Exception: - if msg.errorBehavior & ErrorBehavior.ATTACH_BROKEN: + if ErrorBehavior.ATTACH_BROKEN in msg.errorBehavior: _logger.exception(f'Error processing attachment at {dir_}') return BrokenAttachment(msg, dir_) else: diff --git a/extract_msg/attachments/attachment_base.py b/extract_msg/attachments/attachment_base.py index c480cb84..9cb88f58 100644 --- a/extract_msg/attachments/attachment_base.py +++ b/extract_msg/attachments/attachment_base.py @@ -8,6 +8,7 @@ import abc import datetime +import functools import logging import weakref @@ -107,7 +108,7 @@ def _ensureSetNamed(self, variable : str, propertyName : str, guid : str, **kwar setattr(self, variable, value) return value - def _ensureSetProperty(self, variable, propertyName, **kwargs): + def _getPropertyAs(self, propertyName, overrideClass = None, preserveNone : bool = True): """ Ensures that the variable exists, otherwise will set it using the property. After that, return said variable. @@ -116,24 +117,20 @@ def _ensureSetProperty(self, variable, propertyName, **kwargs): read. The data will be the first argument to the class's __init__ function or the function itself, if that is what is provided. By default, this will be completely ignored if the value was not found. - :param preserveNone: If true (default), causes the function to ignore + :param preserveNone: If True (default), causes the function to ignore :param overrideClass: when the value could not be found (is None). If this is changed to False, then the value will be used regardless. """ try: - return getattr(self, variable) - except AttributeError: - try: - value = self.props[propertyName].value - except (KeyError, AttributeError): - value = None - # Check if we should be overriding the data type for this instance. - if kwargs: - overrideClass = kwargs.get('overrideClass') - if overrideClass is not None and (value is not None or not kwargs.get('preserveNone', True)): - value = overrideClass(value) - setattr(self, variable, value) - return value + value = self.props[propertyName].value + except (KeyError, AttributeError): + value = None + # Check if we should be overriding the data type for this instance. + if overrideClass is not None: + if (value is not None or not preserveNone): + value = overrideClass(value) + + return value def _ensureSetTyped(self, variable, _id, **kwargs): """ @@ -433,7 +430,7 @@ def displayName(self) -> Optional[str]: """ return self._ensureSet('_displayName', '__substg1.0_3001') - @property + @functools.cached_property def exceptionReplaceTime(self) -> Optional[datetime.datetime]: """ The original date and time at which the instance in the recurrence @@ -441,7 +438,7 @@ def exceptionReplaceTime(self) -> Optional[datetime.datetime]: Only applicable if the attachment is an Exception object. """ - return self._ensureSetProperty('_exceptionReplaceTime', '7FF90040') + return self._getPropertyAs('7FF90040') @property def extension(self) -> Optional[str]: @@ -450,19 +447,19 @@ def extension(self) -> Optional[str]: """ return self._ensureSet('_extension', '__substg1.0_3703') - @property + @functools.cached_property def hidden(self) -> bool: """ Indicates whether an Attachment object is hidden from the end user. """ - return self._ensureSetProperty('_hidden', '7FFE000B', overrideClass = bool, preserveNone = False) + return self._getPropertyAs('7FFE000B', overrideClass = bool, preserveNone = False) - @property + @functools.cached_property def isAttachmentContactPhoto(self) -> bool: """ Whether the attachment is a contact photo for a Contact object. """ - return self._ensureSetProperty('_isAttachmentContactPhoto', '7FFF000B', overrideClass = bool, preserveNone = False) + return self._getPropertyAs('7FFF000B', overrideClass = bool, preserveNone = False) @property def longFilename(self) -> Optional[str]: @@ -529,14 +526,14 @@ def props(self) -> PropertiesStore: """ return self.__props - @property + @functools.cached_property def renderingPosition(self) -> Optional[int]: """ The offset, in redered characters, to use when rendering the attachment within the main message text. A value of 0xFFFFFFFF indicates a hidden attachment that is not to be rendered. """ - return self._ensureSetProperty('_renderingPosition', '370B0003') + return self._getPropertyAs('370B0003') @property def shortFilename(self) -> Optional[str]: diff --git a/extract_msg/attachments/custom_att_handler/outlook_image_dib.py b/extract_msg/attachments/custom_att_handler/outlook_image_dib.py index 10fa8abe..b51c87c8 100644 --- a/extract_msg/attachments/custom_att_handler/outlook_image_dib.py +++ b/extract_msg/attachments/custom_att_handler/outlook_image_dib.py @@ -94,7 +94,7 @@ def generateRtf(self) -> Optional[bytes]: This function requires PIL or Pillow. If neither are found, raises an import error. """ - if not self.attachment.msg.insecureFeatures & InsecureFeatures.PIL_IMAGE_PARSING: + if InsecureFeatures.PIL_IMAGE_PARSING not in self.attachment.msg.insecureFeatures: raise SecurityError('Generating the RTF for a custom attachment requires the insecure feature PIL_IMAGE_PARSING.') try: diff --git a/extract_msg/enums.py b/extract_msg/enums.py index 2913772e..2c5bc0c2 100644 --- a/extract_msg/enums.py +++ b/extract_msg/enums.py @@ -43,7 +43,7 @@ class AddressBookType(enum.Enum): -class AppointmentAuxilaryFlag(enum.Enum): +class AppointmentAuxilaryFlag(enum.IntEnum): """ Describes the auxilary state of the object. @@ -54,21 +54,6 @@ class AppointmentAuxilaryFlag(enum.Enum): REPAIR_UPDATE_MESSAGE: The meeting request is a Repair Update Message sent from a server-side calendar repair system. """ - @classmethod - def fromBits(cls, value : int) -> Set['AppointmentAuxilaryFlag']: - """ - Takes an int and returns a set of the flags. - """ - flags = set() - for x in range(7): - bit = value & (1 << x) - if bit: - if x in (3, 4, 6): - raise ValueError('Reserved bit was set.') - flags.add(cls(bit)) - - return flags - COPIED = 0b1 FORCE_MEETING_RESPONSE = 0b10 FORWARDED = 0b100 @@ -282,11 +267,10 @@ class BodyTypes(enum.IntFlag): method for generated bodies (if you check a body and it is not null, but it is not listed in the enum, then it was generated from another body). - This is an IntFlag enum, so to check if a body was found use the & operator - with the body you are checking and ensuring the result isn't BodyTypes.None. - You can also convert the result to a bool. For example: + This is an IntFlag enum, so to check if a body was found use the in operator + with the body you are checking. For example: - >>> rtfFound = bool(msg.detectedBodies & BodyTypes.RTF) + >>> rtfFound = BodyTypes.RTF msg.detectedBodies """ NONE = 0b000 PLAIN = 0b001 @@ -315,7 +299,7 @@ class BusyStatus(enum.Enum): -class ClientIntentFlag(enum.Enum): +class ClientIntentFlag(enum.IntFlag): """ An action a user has taken on a Meeting object. @@ -338,13 +322,6 @@ class ClientIntentFlag(enum.Enum): CANCELED: The user canceled a meeting request. EXCEPTION_CANCELED: The user canceled an exception to a recurring series. """ - @classmethod - def fromBits(cls, value : int) -> Set['ClientIntentFlag']: - """ - Takes an int and returns a set of the flags. - """ - return {cls(1 << x) for x in range(13) if (value & (1 << x))} - MANAGER = 0b1 DELEGATE = 0b10 DELETED_WITH_NO_RESPONSE = 0b100 @@ -1690,14 +1667,7 @@ class TaskMode(enum.Enum): -class TaskMultipleRecipients(enum.Enum): - @classmethod - def fromBits(cls, value : int) -> Set['TaskMultipleRecipients']: - """ - Takes an int and returns a set of the flags. - """ - return {cls(1 << x) for x in range(2) if (value & (1 << x))} - +class TaskMultipleRecipients(enum.IntFlag): SENT = 0x00000001 RECEIVED = 0x00000002 diff --git a/extract_msg/msg_classes/appointment.py b/extract_msg/msg_classes/appointment.py index 54ea817c..88a69fb3 100644 --- a/extract_msg/msg_classes/appointment.py +++ b/extract_msg/msg_classes/appointment.py @@ -4,6 +4,7 @@ import datetime +import functools from typing import Optional @@ -22,53 +23,53 @@ class AppointmentMeeting(Calendar): object. """ - @property + @functools.cached_property def appointmentCounterProposal(self) -> bool: """ Indicates to the organizer that there are counter proposals that have not been accepted or rejected by the organizer. """ - return self._ensureSetNamed('_appointmentCounterProposal', '8257', constants.ps.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) + return self._getNamedAs('8257', constants.ps.PSETID_APPOINTMENT, bool, False) - @property + @functools.cached_property def appointmentLastSequence(self) -> Optional[int]: """ The last sequence number that was sent to any attendee. """ - return self._ensureSetNamed('_appointmentLastSequence', '8203', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8203', constants.ps.PSETID_APPOINTMENT) - @property + @functools.cached_property def appointmentProposalNumber(self) -> Optional[int]: """ The number of attendees who have sent counter propostals that have not been accepted or rejected by the organizer. """ - return self._ensureSetNamed('_appointmentProposalNumber', '8259', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8259', constants.ps.PSETID_APPOINTMENT) - @property + @functools.cached_property def appointmentReplyName(self) -> Optional[datetime.datetime]: """ The user who last replied to the meeting request or meeting update. """ - return self._ensureSetNamed('_appointmentReplyName', '8230', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8230', constants.ps.PSETID_APPOINTMENT) - @property + @functools.cached_property def appointmentReplyTime(self) -> Optional[datetime.datetime]: """ The date and time at which the attendee responded to a received Meeting Request object of Meeting Update object in UTC. """ - return self._ensureSetNamed('_appointmentReplyTime', '8220', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8220', constants.ps.PSETID_APPOINTMENT) - @property + @functools.cached_property def appointmentSequenceTime(self) -> Optional[datetime.datetime]: """ The date and time at which the appointmentSequence property was last modified. """ - return self._ensureSetNamed('_appointmentSequenceTime', '8202', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8202', constants.ps.PSETID_APPOINTMENT) - @property + @functools.cached_property def autoFillLocation(self) -> bool: """ A value of True indicates that the value of the location property is set @@ -78,14 +79,14 @@ def autoFillLocation(self) -> bool: A value of False indicates that the value of the location property is not automatically set. """ - return self._ensureSetNamed('_autoFillLocation', '823A', constants.ps.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) + return self._getNamedAs('823A', constants.ps.PSETID_APPOINTMENT, bool, False) - @property + @functools.cached_property def fInvited(self) -> bool: """ Whether a Meeting Request object has been sent out. """ - return self._ensureSetNamed('_fInvited', '8229', constants.ps.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) + return self._getNamedAs('8229', constants.ps.PSETID_APPOINTMENT, bool, False) @property def headerFormatProperties(self) -> constants.HEADER_FORMAT_TYPE: @@ -161,7 +162,7 @@ def headerFormatProperties(self) -> constants.HEADER_FORMAT_TYPE: }, } - @property + @functools.cached_property def isMeeting(self) -> bool: """ Attempts to determine if the object is a Meeting. True if meeting, False @@ -169,9 +170,9 @@ def isMeeting(self) -> bool: """ return self.appointmentStateFlags and AppointmentStateFlag.MEETING in self.appointmentStateFlags - @property + @functools.cached_property def originalStoreEntryID(self) -> Optional[EntryID]: """ The EntryID of the delegator's message store. """ - return self._ensureSetNamed('_originalStoreEntryID', '8237', constants.ps.PSETID_APPOINTMENT, overrideClass = EntryID.autoCreate) + return self._getNamedAs('8237', constants.ps.PSETID_APPOINTMENT, EntryID.autoCreate) diff --git a/extract_msg/msg_classes/calendar.py b/extract_msg/msg_classes/calendar.py index 3fb1f4dd..fa1c7e44 100644 --- a/extract_msg/msg_classes/calendar.py +++ b/extract_msg/msg_classes/calendar.py @@ -4,8 +4,9 @@ import datetime +import functools -from typing import Optional, Set +from typing import Optional from .. import constants from .calendar_base import CalendarBase @@ -17,14 +18,14 @@ class Calendar(CalendarBase): A calendar object. """ - @property - def clientIntent(self) -> Optional[Set[ClientIntentFlag]]: + @functools.cached_property + def clientIntent(self) -> Optional[ClientIntentFlag]: """ A set of the actions a user has taken on a Meeting object. """ - return self._ensureSetNamed('_clientIntent', '0015', constants.ps.PSETID_CALENDAR_ASSISTANT, overrideClass = ClientIntentFlag.fromBits) + return self._getNamedAs('0015', constants.ps.PSETID_CALENDAR_ASSISTANT, ClientIntentFlag) - @property + @functools.cached_property def fExceptionalAttendees(self) -> Optional[bool]: """ Indicates that it is a Recurring Calendar object with one or more @@ -34,58 +35,58 @@ def fExceptionalAttendees(self) -> Optional[bool]: SHOULD NOT be set for any Calendar object other than that of the organizer's. """ - return self._ensureSetNamed('_fExceptionalAttendees', '822B', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('822B', constants.ps.PSETID_APPOINTMENT) - @property + @functools.cached_property def reminderDelta(self) -> Optional[int]: """ The interval, in minutes, between the time at which the reminder first becomes overdue and the start time of the Calendar object. """ - return self._ensureSetNamed('_reminderDelta', '8501', constants.ps.PSETID_COMMON) + return self._getNamedAs('8501', constants.ps.PSETID_COMMON) - @property + @functools.cached_property def reminderFileParameter(self) -> Optional[str]: """ The full path (MAY only specify the file name) of the sound that a client SHOULD play when the reminder for the Message Object becomes overdue. """ - return self._ensureSetNamed('_reminderFileParameter', '851F', constants.ps.PSETID_COMMON) + return self._getNamedAs('851F', constants.ps.PSETID_COMMON) - @property + @functools.cached_property def reminderOverride(self) -> bool: """ Specifies if clients SHOULD respect the value of the reminderPlaySound property and the reminderFileParameter property. """ - return self._ensureSetNamed('_reminderOverride', '851C', constants.ps.PSETID_COMMON, overrideClass = bool, preserveNone = False) + return self._getNamedAs('851C', constants.ps.PSETID_COMMON, bool, False) - @property + @functools.cached_property def reminderPlaySound(self) -> bool: """ Specified that the cliebnt should play a sound when the reminder becomes overdue. """ - return self._ensureSetNamed('_reminderPlaySound', '851E', constants.ps.PSETID_COMMON, overrideClass = bool, preserveNone = False) + return self._getNamedAs('851E', constants.ps.PSETID_COMMON, bool, False) - @property + @functools.cached_property def reminderSet(self) -> bool: """ Specifies whether a reminder is set on the object. """ - return self._ensureSetNamed('_reminderSet', '8503', constants.ps.PSETID_COMMON, overrideClass = bool, preserveNone = False) + return self._getNamedAs('8503', constants.ps.PSETID_COMMON, bool, False) - @property + @functools.cached_property def reminderSignalTime(self) -> Optional[datetime.datetime]: """ The point in time when a reminder transitions from pending to overdue. """ - return self._ensureSetNamed('_reminderSignalTime', '8560', constants.ps.PSETID_COMMON) + return self._getNamedAs('8560', constants.ps.PSETID_COMMON) - @property + @functools.cached_property def reminderTime(self) -> Optional[datetime.datetime]: """ The time after which the user would be late. """ - return self._ensureSetNamed('_reminderTime', '8502', constants.ps.PSETID_COMMON) + return self._getNamedAs('8502', constants.ps.PSETID_COMMON) diff --git a/extract_msg/msg_classes/calendar_base.py b/extract_msg/msg_classes/calendar_base.py index fc97c8b1..b7047a17 100644 --- a/extract_msg/msg_classes/calendar_base.py +++ b/extract_msg/msg_classes/calendar_base.py @@ -4,9 +4,10 @@ import datetime +import functools import logging -from typing import List, Optional, Set, Tuple, Union +from typing import List, Optional, Union from .. import constants from ..enums import AppointmentAuxilaryFlag, AppointmentColor, AppointmentStateFlag, BusyStatus, IconIndex, MeetingRecipientType, ResponseStatus @@ -31,154 +32,147 @@ def _genRecipient(self, recipientType, recipientInt : MeetingRecipientType) -> O """ Returns the specified recipient field. """ - private = '_' + recipientType recipientInt = MeetingRecipientType(recipientInt) - try: - return getattr(self, private) - except AttributeError: - value = None - # Check header first. - if self.headerInit(): - value = self.header[recipientType] - if value: - value = value.replace(',', self.recipientSeparator) - - # If the header had a blank field or didn't have the field, generate - # it manually. - if not value: - # Check if the header has initialized. - if self.headerInit(): - logger.info(f'Header found, but "{recipientType}" is not included. Will be generated from other streams.') - - # Get a list of the recipients of the specified type. - foundRecipients = tuple(recipient.formatted for recipient in self.recipients if recipient.type == recipientInt) - - # If we found recipients, join them with the recipient separator - # and a space. - if len(foundRecipients) > 0: - value = (self.recipientSeparator + ' ').join(foundRecipients) - - # Code to fix the formatting so it's all a single line. This allows - # the user to format it themself if they want. This should probably - # be redone to use re or something, but I can do that later. This - # shouldn't be a huge problem for now. + value = None + # Check header first. + if self.headerInit(): + value = self.header[recipientType] if value: - value = value.replace(' \r\n\t', ' ').replace('\r\n\t ', ' ').replace('\r\n\t', ' ') - value = value.replace('\r\n', ' ').replace('\r', ' ').replace('\n', ' ') - while value.find(' ') != -1: - value = value.replace(' ', ' ') + value = value.replace(',', self.recipientSeparator) + + # If the header had a blank field or didn't have the field, generate + # it manually. + if not value: + # Check if the header has initialized. + if self.headerInit(): + logger.info(f'Header found, but "{recipientType}" is not included. Will be generated from other streams.') - # Set the field in the class. - setattr(self, private, value) + # Get a list of the recipients of the specified type. + foundRecipients = tuple(recipient.formatted for recipient in self.recipients if recipient.type == recipientInt) - return value + # If we found recipients, join them with the recipient separator + # and a space. + if len(foundRecipients) > 0: + value = (self.recipientSeparator + ' ').join(foundRecipients) - @property + # Code to fix the formatting so it's all a single line. This allows + # the user to format it themself if they want. This should probably + # be redone to use re or something, but I can do that later. This + # shouldn't be a huge problem for now. + if value: + value = value.replace(' \r\n\t', ' ').replace('\r\n\t ', ' ').replace('\r\n\t', ' ') + value = value.replace('\r\n', ' ').replace('\r', ' ').replace('\n', ' ') + while value.find(' ') != -1: + value = value.replace(' ', ' ') + + return value + + @functools.cached_property def allAttendeesString(self) -> Optional[str]: """ A list of all attendees, excluding the organizer. """ - return self._ensureSetNamed('_allAttendeesString', '8238', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8238', constants.ps.PSETID_APPOINTMENT) - @property - def appointmentAuxilaryFlags(self) -> Optional[Set[AppointmentAuxilaryFlag]]: + @functools.cached_property + def appointmentAuxilaryFlags(self) -> Optional[AppointmentAuxilaryFlag]: """ The auxiliary state of the object. """ - return self._ensureSetNamed('_appointmentAuxilaryFlags', '8207', constants.ps.PSETID_APPOINTMENT, overrideClass = AppointmentAuxilaryFlag.fromBits) + return self._getNamedAs('8207', constants.ps.PSETID_APPOINTMENT, AppointmentAuxilaryFlag) - @property + @functools.cached_property def appointmentColor(self) -> Optional[AppointmentColor]: """ The color to be used when displaying a Calendar object. """ - return self._ensureSetNamed('_appointmentColor', '8214', constants.ps.PSETID_APPOINTMENT, overrideClass = AppointmentColor) + return self._getNamedAs('8214', constants.ps.PSETID_APPOINTMENT, AppointmentColor) - @property + @functools.cached_property def appointmentDuration(self) -> Optional[int]: """ The length of the event, in minutes. """ - return self._ensureSetNamed('_appointmentDuration', '8213', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8213', constants.ps.PSETID_APPOINTMENT) - @property + @functools.cached_property def appointmentEndWhole(self) -> Optional[datetime.datetime]: """ The end date and time of the event in UTC. """ - return self._ensureSetNamed('_appointmentEndWhole', '820E', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('820E', constants.ps.PSETID_APPOINTMENT) - @property + @functools.cached_property def appointmentNotAllowPropose(self) -> bool: """ Indicates that attendees are not allowed to propose a new date and/or time for the meeting if True. """ - return self._ensureSetNamed('_appointmentNotAllowPropose', '8259', constants.ps.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) + return self._getNamedAs('8259', constants.ps.PSETID_APPOINTMENT, bool, False) - @property + @functools.cached_property def appointmentRecur(self) -> Optional[RecurrencePattern]: """ Specifies the dates and times when a recurring series occurs by using one of the recurrence patterns and ranges specified in this section. """ - return self._ensureSetNamed('_appointmentRecur', '8216', constants.ps.PSETID_APPOINTMENT, overrideClass = RecurrencePattern) + return self._getNamedAs('8216', constants.ps.PSETID_APPOINTMENT, RecurrencePattern) - @property + @functools.cached_property def appointmentSequence(self) -> Optional[int]: """ Specified the sequence number of a Meeting object. A meeting object begins with the sequence number set to 0 and is incremented each time the organizer sends out a Meeting Update object. """ - return self._ensureSetNamed('_appointmentSequence', '8201', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8201', constants.ps.PSETID_APPOINTMENT) - @property + @functools.cached_property def appointmentStartWhole(self) -> Optional[datetime.datetime]: """ The start date and time of the event in UTC. """ - return self._ensureSetNamed('_appointmentStartWhole', '820D', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('820D', constants.ps.PSETID_APPOINTMENT) - @property - def appointmentStateFlags(self) -> Optional[Set[AppointmentStateFlag]]: + @functools.cached_property + def appointmentStateFlags(self) -> Optional[AppointmentStateFlag]: """ The appointment state of the object. """ - return self._ensureSetNamed('_appointmentStateFlags', '8217', constants.ps.PSETID_APPOINTMENT, overrideClass = AppointmentStateFlag.fromBits) + return self._getNamedAs('8217', constants.ps.PSETID_APPOINTMENT, AppointmentStateFlag) - @property + @functools.cached_property def appointmentSubType(self) -> bool: """ Whether the event is an all-day event or not. """ - return self._ensureSetNamed('_appointmentSubType', '8215', constants.ps.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) + return self._getNamedAs('8215', constants.ps.PSETID_APPOINTMENT, bool, False) - @property + @functools.cached_property def appointmentTimeZoneDefinitionEndDisplay(self) -> Optional[TimeZoneDefinition]: """ Specifies the time zone information for the appointmentEndWhole property Used to convert the end date and time to and from UTC. """ - return self._ensureSetNamed('_appointmentTimeZoneDefinitionEndDisplay', '825F', constants.ps.PSETID_APPOINTMENT, overrideClass = TimeZoneDefinition) + return self._getNamedAs('825F', constants.ps.PSETID_APPOINTMENT, TimeZoneDefinition) - @property + @functools.cached_property def appointmentTimeZoneDefinitionRecur(self) -> Optional[TimeZoneDefinition]: """ Specified the time zone information that specifies how to convert the meeting date and time on a recurring series to and from UTC. """ - return self._ensureSetNamed('_appointmentTimeZoneDefinitionRecur', '8260', constants.ps.PSETID_APPOINTMENT, overrideClass = TimeZoneDefinition) + return self._getNamedAs('8260', constants.ps.PSETID_APPOINTMENT, TimeZoneDefinition) - @property + @functools.cached_property def appointmentTimeZoneDefinitionStartDisplay(self) -> Optional[TimeZoneDefinition]: """ Specifies the time zone information for the appointmentStartWhole property. Used to convert the start date and time to and from UTC. """ - return self._ensureSetNamed('_appointmentTimeZoneDefinitionStartDisplay', '825E', constants.ps.PSETID_APPOINTMENT, overrideClass = TimeZoneDefinition) + return self._getNamedAs('825E', constants.ps.PSETID_APPOINTMENT, TimeZoneDefinition) - @property + @functools.cached_property def appointmentUnsendableRecipients(self) -> Optional[bytes]: """ A list of unsendable attendees. @@ -187,69 +181,69 @@ def appointmentUnsendableRecipients(self) -> Optional[bytes]: the specifications. If you have examples, let me know and I can ask you to run a verification on it. """ - return self._ensureSetNamed('_appointmentUnsendableRecipients', '825D', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('825D', constants.ps.PSETID_APPOINTMENT) - @property + @functools.cached_property def bcc(self) -> Optional[str]: """ Returns the bcc field, if it exists. """ return self._genRecipient('bcc', MeetingRecipientType.SENDABLE_RESOURCE_OBJECT) - @property + @functools.cached_property def birthdayContactAttributionDisplayName(self) -> Optional[str]: """ Indicated the name of the contact associated with the birthday event. """ - return self._ensureSetNamed('_birthdayContactAttributionDisplayName', 'BirthdayContactAttributionDisplayName', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('BirthdayContactAttributionDisplayName', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def birthdayContactEntryID(self) -> Optional[EntryID]: """ Indicates the EntryID of the contact associated with the birthday event. """ - return self._ensureSetNamed('_birthdayContactEntryID', 'BirthdayContactEntryId', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) + return self._getNamedAs('BirthdayContactEntryId', constants.ps.PSETID_ADDRESS, EntryID.autoCreate) - @property + @functools.cached_property def birthdayContactPersonGuid(self) -> Optional[bytes]: """ Indicates the person ID's GUID of the contact associated with the birthday event. """ - return self._ensureSetNamed('_birthdayContactPersonGuid', 'BirthdayContactPersonGuid', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('BirthdayContactPersonGuid', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def busyStatus(self) -> Optional[BusyStatus]: """ Specified the availability of a user for the event described by the object. """ - return self._ensureSetNamed('_busyStatus', '8205', constants.ps.PSETID_APPOINTMENT, overrideClass = BusyStatus) + return self._getNamedAs('8205', constants.ps.PSETID_APPOINTMENT, BusyStatus) - @property + @functools.cached_property def cc(self) -> Optional[str]: """ Returns the cc field, if it exists. """ return self._genRecipient('cc', MeetingRecipientType.SENDABLE_OPTIONAL_ATTENDEE) - @property + @functools.cached_property def ccAttendeesString(self) -> Optional[str]: """ A list of all the sendable attendees, who are also optional attendees. """ - return self._ensureSetNamed('_ccAttendeesString', '823C', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('823C', constants.ps.PSETID_APPOINTMENT) - @property + @functools.cached_property def cleanGlobalObjectID(self) -> Optional[GlobalObjectID]: """ The value of the globalObjectID property for an object that represents an Exception object to a recurring series, where the year, month, and day fields are all 0. """ - return self._ensureSetNamed('_cleanGlobalObjectID', '0023', constants.ps.PSETID_MEETING, overrideClass = GlobalObjectID) + return self._getNamedAs('0023', constants.ps.PSETID_MEETING, GlobalObjectID) - @property + @functools.cached_property def clipEnd(self) -> Optional[datetime.datetime]: """ For single-instance Calendar objects, the end date and time of the @@ -260,9 +254,9 @@ def clipEnd(self) -> Optional[datetime.datetime]: Honestly, not sure what this is. [MS-OXOCAL]: PidLidClipEnd. """ - return self._ensureSetNamed('_clipEnd', '8236', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8236', constants.ps.PSETID_APPOINTMENT) - @property + @functools.cached_property def clipStart(self) -> Optional[datetime.datetime]: """ For single-instance Calendar objects, the start date and time of the @@ -271,152 +265,152 @@ def clipStart(self) -> Optional[datetime.datetime]: Honestly, not sure what this is. [MS-OXOCAL]: PidLidClipStart. """ - return self._ensureSetNamed('_clipStart', '8235', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8235', constants.ps.PSETID_APPOINTMENT) - @property + @functools.cached_property def commonEnd(self) -> Optional[datetime.datetime]: """ The end date and time of an event. MUST be equal to appointmentEndWhole. """ - return self._ensureSetNamed('_commonEnd', '8517', constants.ps.PSETID_COMMON) + return self._getNamedAs('8517', constants.ps.PSETID_COMMON) - @property + @functools.cached_property def commonStart(self) -> Optional[datetime.datetime]: """ The start date and time of an event. MUST be equal to appointmentStartWhole. """ - return self._ensureSetNamed('_commonStart', '8516', constants.ps.PSETID_COMMON) + return self._getNamedAs('8516', constants.ps.PSETID_COMMON) - @property + @functools.cached_property def endDate(self) -> Optional[datetime.datetime]: """ The end date of the appointment. """ - return self._ensureSetProperty('_endDate', '00610040') + return self._getPropertyAs('00610040') - @property + @functools.cached_property def globalObjectID(self) -> Optional[GlobalObjectID]: """ The unique identifier or the Calendar object. """ - return self._ensureSetNamed('_globalObjectID', '0003', constants.ps.PSETID_MEETING, overrideClass = GlobalObjectID) + return self._getNamedAs('0003', constants.ps.PSETID_MEETING, GlobalObjectID) - @property + @functools.cached_property def iconIndex(self) -> Optional[Union[IconIndex, int]]: """ The icon to use for the object. """ - return self._ensureSetProperty('_iconIndex', '10800003', overrideClass = IconIndex.tryMake) + return self._getPropertyAs('10800003', IconIndex.tryMake) - @property + @functools.cached_property def isBirthdayContactWritable(self) -> bool: """ Indicates whether the contact associated with the birthday event is writable. """ - return self._ensureSetNamed('_isBirthdayContactWritable', 'IsBirthdayContactWritable', constants.ps.PSETID_ADDRESS, overrideClass = bool, preserveNone = False) + return self._getNamedAs('IsBirthdayContactWritable', constants.ps.PSETID_ADDRESS, bool, False) - @property + @functools.cached_property def isException(self) -> bool: """ Whether the object represents an exception. False indicates that the object represents a recurring series or a single-instance object. """ - return self._ensureSetNamed('_isException', '000A', constants.ps.PSETID_MEETING, overrideClass = bool, preserveNone = False) + return self._getNamedAs('000A', constants.ps.PSETID_MEETING, bool, False) - @property + @functools.cached_property def isRecurring(self) -> bool: """ Whether the object is associated with a recurring series. """ - return self._ensureSetNamed('_isRecurring', '0005', constants.ps.PSETID_MEETING, overrideClass = bool, preserveNone = False) + return self._getNamedAs('0005', constants.ps.PSETID_MEETING, bool, False) - @property + @functools.cached_property def keywords(self) -> Optional[List[str]]: """ The color to be used when displaying a Calendar object. """ - return self._ensureSet('_keywords', 'Keywords') + return self._getNamedAs('Keywords', constants.ps.PS_PUBLIC_STRINGS) - @property - def linkedTaskItems(self) -> Optional[Tuple[EntryID]]: + @functools.cached_property + def linkedTaskItems(self) -> Optional[List[EntryID]]: """ A list of PidTagEntryId properties of Task objects related to the Calendar object that are set by a client. """ - return self._ensureSetNamed('_linkedTaskItems', '820C', constants.ps.PSETID_APPOINTMENT, overrideClass = lambda x : tuple(EntryID.autoCreate(y) for y in x)) + return self._getNamedAs('820C', constants.ps.PSETID_APPOINTMENT, lambda x : list(EntryID.autoCreate(y) for y in x)) - @property + @functools.cached_property def location(self) -> Optional[str]: """ Returns the location of the meeting. """ - return self._ensureSetNamed('_location', '8208', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8208', constants.ps.PSETID_APPOINTMENT) - @property + @functools.cached_property def meetingDoNotForward(self) -> bool: """ Whether to allow the meeting to be forwarded. True disallows forwarding. """ - return self._ensureSetNamed('_meetingDoNotForward', 'DoNotForward', constants.ps.PS_PUBLIC_STRINGS, overrideClass = bool, preserveNone = False) + return self._getNamedAs('DoNotForward', constants.ps.PS_PUBLIC_STRINGS, bool, False) - @property + @functools.cached_property def meetingWorkspaceUrl(self) -> Optional[str]: """ The URL of the Meeting Workspace, as specified in [MS-MEETS], that is associated with a Calendar object. """ - return self._ensureSetNamed('_meetingWorkspaceUrl', '8209', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8209', constants.ps.PSETID_APPOINTMENT) - @property + @functools.cached_property def nonSendableBcc(self) -> Optional[str]: """ A list of all unsendable attendees who are also resource objects. """ - return self._ensureSetNamed('_nonSendableBcc', '8538', constants.ps.PSETID_COMMON) + return self._getNamedAs('8538', constants.ps.PSETID_COMMON) - @property + @functools.cached_property def nonSendableCc(self) -> Optional[str]: """ A list of all unsendable attendees who are also optional attendees. """ - return self._ensureSetNamed('_nonSendableCc', '8537', constants.ps.PSETID_COMMON) + return self._getNamedAs('8537', constants.ps.PSETID_COMMON) - @property + @functools.cached_property def nonSendableTo(self) -> Optional[str]: """ A list of all unsendable attendees who are also required attendees. """ - return self._ensureSetNamed('_nonSendableTo', '8536', constants.ps.PSETID_COMMON) + return self._getNamedAs('8536', constants.ps.PSETID_COMMON) - @property + @functools.cached_property def nonSendBccTrackStatus(self) -> Optional[List[ResponseStatus]]: """ A ResponseStatus for each of the attendees in nonSendableBcc. """ - return self._ensureSetNamed('_nonSendBccTrackStatus', '8545', constants.ps.PSETID_COMMON, overrideClass = (lambda x : (ResponseStatus(y) for y in x))) + return self._getNamedAs('8545', constants.ps.PSETID_COMMON, lambda x : list(ResponseStatus(y) for y in x)) - @property + @functools.cached_property def nonSendCcTrackStatus(self) -> Optional[List[ResponseStatus]]: """ A ResponseStatus for each of the attendees in nonSendableCc. """ - return self._ensureSetNamed('_nonSendCcTrackStatus', '8544', constants.ps.PSETID_COMMON, overrideClass = (lambda x : (ResponseStatus(y) for y in x))) + return self._getNamedAs('8544', constants.ps.PSETID_COMMON, lambda x : list(ResponseStatus(y) for y in x)) - @property + @functools.cached_property def nonSendToTrackStatus(self) -> Optional[List[ResponseStatus]]: """ A ResponseStatus for each of the attendees in nonSendableTo. """ - return self._ensureSetNamed('_nonSendToTrackStatus', '8543', constants.ps.PSETID_COMMON, overrideClass = (lambda x : (ResponseStatus(y) for y in x))) + return self._getNamedAs('8543', constants.ps.PSETID_COMMON, lambda x : list(ResponseStatus(y) for y in x)) - @property + @functools.cached_property def optionalAttendees(self) -> Optional[str]: """ Returns the optional attendees of the meeting. """ - return self._ensureSetNamed('_optionalAttendees', '0007', constants.ps.PSETID_MEETING) + return self._getNamedAs('0007', constants.ps.PSETID_MEETING) @property def organizer(self) -> Optional[str]: @@ -425,106 +419,106 @@ def organizer(self) -> Optional[str]: """ return self._ensureSet('_organizer', '__substg1.0_0042') - @property + @functools.cached_property def ownerAppointmentID(self) -> Optional[int]: """ A quasi-unique value amond all Calendar objects in a user's mailbox. Assists a client or server in finding a Calendar object but is not guarenteed to be unique amoung all objects. """ - return self._ensureSetProperty('_ownerAppointmentID', '00620003') + return self._getPropertyAs('00620003') - @property + @functools.cached_property def ownerCriticalChange(self) -> Optional[datetime.datetime]: """ The date and time at which a Meeting Request object was sent by the organizer, in UTC. """ - return self._ensureSetNamed('_ownerCriticalChange', '001A', constants.ps.PSETID_MEETING) + return self._getNamedAs('001A', constants.ps.PSETID_MEETING) - @property + @functools.cached_property def recurrencePattern(self) -> Optional[str]: """ A description of the recurrence specified by the appointmentRecur property. """ - return self._ensureSetNamed('_recurrencePattern', '8232', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8232', constants.ps.PSETID_APPOINTMENT) - @property + @functools.cached_property def recurring(self) -> bool: """ Specifies whether the object represents a recurring series. """ - return self._ensureSetNamed('_recurring', '8223', constants.ps.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = True) + return self._getNamedAs('8223', constants.ps.PSETID_APPOINTMENT, bool, True) - @property + @functools.cached_property def replyRequested(self) -> bool: """ Whether the organizer requests a reply from attendees. """ - return self._ensureSetProperty('_replyRequested', '0C17000B', overrideClass = bool, preserveNone = False) + return self._getPropertyAs('0C17000B', overrideClass = bool, preserveNone = False) - @property + @functools.cached_property def requiredAttendees(self) -> Optional[str]: """ Returns the required attendees of the meeting. """ - return self._ensureSetNamed('_requiredAttendees', '0006', constants.ps.PSETID_MEETING) + return self._getNamedAs('0006', constants.ps.PSETID_MEETING) - @property + @functools.cached_property def resourceAttendees(self) -> Optional[str]: """ Returns the resource attendees of the meeting. """ - return self._ensureSetNamed('_resourceAttendees', '0008', constants.ps.PSETID_MEETING) + return self._getNamedAs('0008', constants.ps.PSETID_MEETING) - @property + @functools.cached_property def responseRequested(self) -> bool: """ Whether to send Meeting Response objects to the organizer. """ - return self._ensureSetProperty('_responseRequested', '0063000B', overrideClass = bool, preserveNone = False) + return self._getPropertyAs('0063000B', bool, False) - @property + @functools.cached_property def responseStatus(self) -> ResponseStatus: """ The response status of an attendee. """ - return self._ensureSetNamed('_responseStatus', '8218', constants.ps.PSETID_APPOINTMENT, overrideClass = lambda x: ResponseStatus(x or 0), preserveNone = False) + return self._getNamedAs('8218', constants.ps.PSETID_APPOINTMENT, lambda x: ResponseStatus(x or 0), False) - @property + @functools.cached_property def startDate(self) -> Optional[datetime.datetime]: """ The start date of the appointment. """ - return self._ensureSetProperty('_startDate', '00600040') + return self._getPropertyAs('00600040') - @property + @functools.cached_property def timeZoneDescription(self) -> Optional[str]: """ A human-readable description of the time zone that is represented by the data in the timeZoneStruct property. """ - return self._ensureSetNamed('_timeZoneDescription', '8234', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8234', constants.ps.PSETID_APPOINTMENT) - @property + @functools.cached_property def timeZoneStruct(self) -> Optional[TimeZoneStruct]: """ Set on a recurring series to specify time zone information. Specifies how to convert time fields between local time and UTC. """ - return self._ensureSetNamed('_timeZoneStruct', '8233', constants.ps.PSETID_APPOINTMENT, overrideClass = TimeZoneStruct) + return self._getNamedAs('8233', constants.ps.PSETID_APPOINTMENT, TimeZoneStruct) - @property + @functools.cached_property def to(self) -> Optional[str]: """ Returns the to field, if it exists. """ return self._genRecipient('to', MeetingRecipientType.SENDABLE_REQUIRED_ATTENDEE) - @property + @functools.cached_property def toAttendeesString(self) -> Optional[str]: """ A list of all the sendable attendees, who are also required attendees. """ - return self._ensureSetNamed('_toAttendeesString', '823B', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('823B', constants.ps.PSETID_APPOINTMENT) diff --git a/extract_msg/msg_classes/contact.py b/extract_msg/msg_classes/contact.py index 8b11aac6..36de3276 100644 --- a/extract_msg/msg_classes/contact.py +++ b/extract_msg/msg_classes/contact.py @@ -3,25 +3,23 @@ ] +import io import datetime +import functools -from typing import Dict, List, Optional, Set, Tuple, TYPE_CHECKING,Union +from typing import Dict, List, Optional, Set, Tuple, Union from .. import constants -from ..enums import ContactLinkState, ElectronicAddressProperties, Gender, PostalAddressID +from ..enums import ( + ContactLinkState, ElectronicAddressProperties, Gender, + InsecureFeatures, PostalAddressID + ) +from ..exceptions import SecurityError from .message_base import MessageBase from ..structures.entry_id import EntryID from ..structures.business_card import BusinessCardDisplayDefinition -# Allow for type checking an optional dependency. -if TYPE_CHECKING: - try: - import PIL.Image - except ImportError: - pass - - class Contact(MessageBase): """ Class used for parsing contacts. @@ -42,14 +40,14 @@ def addressBookProviderArrayType(self) -> Optional[Set[ElectronicAddressProperti Property is stored in the MSG file as a sinlge int. The result should be identical to addressBookProviderEmailList. """ - return self._ensureSetNamed('_addressBookProviderArrayType', '8029', constants.ps.PSETID_ADDRESS, ElectronicAddressProperties.fromBits) + return self._getNamedAs('_addressBookProviderArrayType', '8029', constants.ps.PSETID_ADDRESS, ElectronicAddressProperties.fromBits) @property def addressBookProviderEmailList(self) -> Optional[Set[ElectronicAddressProperties]]: """ A set of which Electronic Address properties are set on the contact. """ - return self._ensureSetNamed('_addressBookProviderEmailList', '8028', constants.ps.PSETID_ADDRESS, overrideClass = lambda x : {ElectronicAddressProperties(y) for y in x}) + return self._getNamedAs('_addressBookProviderEmailList', '8028', constants.ps.PSETID_ADDRESS, overrideClass = lambda x : {ElectronicAddressProperties(y) for y in x}) @property def assistant(self) -> Optional[str]: @@ -71,21 +69,21 @@ def autoLog(self) -> bool: Whether the client should create a Journal object for each action associated with the Contact object. """ - return self._ensureSetNamed('_autoLog', '8025', constants.ps.PSETID_ADDRESS, overrideClass = bool, preserveNone = False) + return self._getNamedAs('_autoLog', '8025', constants.ps.PSETID_ADDRESS, overrideClass = bool, preserveNone = False) @property def billing(self) -> Optional[str]: """ Billing information for the contact. """ - return self._ensureSetNamed('_billing', '8535', constants.ps.PSETID_COMMON) + return self._getNamedAs('_billing', '8535', constants.ps.PSETID_COMMON) - @property + @functools.cached_property def birthday(self) -> Optional[datetime.datetime]: """ The birthday of the contact at 11:59 UTC. """ - return self._ensureSetProperty('_birthday', '3A420040') + return self._getPropertyAs('3A420040') @property def birthdayEventEntryID(self) -> Optional[EntryID]: @@ -93,17 +91,19 @@ def birthdayEventEntryID(self) -> Optional[EntryID]: The EntryID of an optional Appointement object that represents the contact's birtday. """ - return self._ensureSetNamed('_birthdayEventEntryID', '804D', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) + return self._getNamedAs('_birthdayEventEntryID', '804D', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) @property def birthdayLocal(self) -> Optional[datetime.datetime]: """ The birthday of the contact at 0:00 in the client's local time zone. """ - return self._ensureSetNamed('_birthdayLocal', '80DE', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_birthdayLocal', '80DE', constants.ps.PSETID_ADDRESS) - @property - def businessCard(self) -> 'PIL.Image.Image': + @functools.cached_property + def businessCard(self) -> bytes: + if InsecureFeatures.PIL_IMAGE_PARSING not in self.insecureFeatures: + return SecurityError('PIL_IMAGE_PARSING must be enabled to create a business card image.') # First import PIL here so it's an optional dependency. try: import PIL.Image @@ -122,11 +122,13 @@ def businessCard(self) -> 'PIL.Image.Image': imDraw = PIL.ImageDraw.ImageDraw(im) # Create the border of the image: - imDraw.rectangle(((0, 0,), (249, 149)), outline = (109, 109, 109)) + imDraw.rectangle(((0, 0), (249, 149)), outline = (109, 109, 109)) # Finally, return the image. - return im + out = io.BytesIO() + im.save(out, 'png') + return out @property def businessCardCardPicture(self) -> Optional[bytes]: @@ -134,7 +136,7 @@ def businessCardCardPicture(self) -> Optional[bytes]: The image to be used on a business card. Must be either a PNG file or a JPEG file. """ - return self._ensureSetNamed('_businessCardCardPicture', '8041', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_businessCardCardPicture', '8041', constants.ps.PSETID_ADDRESS) @property def businessCardDisplayDefinition(self) -> Optional[BusinessCardDisplayDefinition]: @@ -142,7 +144,7 @@ def businessCardDisplayDefinition(self) -> Optional[BusinessCardDisplayDefinitio Specifies the customization details for displaying a contact as a business card. """ - return self._ensureSetNamed('_businessCardDisplayDefinition', '8040', constants.ps.PSETID_ADDRESS, overrideClass = BusinessCardDisplayDefinition) + return self._getNamedAs('_businessCardDisplayDefinition', '8040', constants.ps.PSETID_ADDRESS, overrideClass = BusinessCardDisplayDefinition) @property def businessFax(self) -> Optional[dict]: @@ -171,7 +173,7 @@ def businessFaxAddressType(self) -> Optional[str]: """ The type of address for the fax. MUST be set to "FAX" if present. """ - return self._ensureSetNamed('_businessFaxAddressType', '80C2', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_businessFaxAddressType', '80C2', constants.ps.PSETID_ADDRESS) @property def businessFaxEmailAddress(self) -> Optional[str]: @@ -179,7 +181,7 @@ def businessFaxEmailAddress(self) -> Optional[str]: Contains a user-readable display name, followed by the "@" character, followed by a fax number. """ - return self._ensureSetNamed('_businessFaxEmailAddress', '80C3', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_businessFaxEmailAddress', '80C3', constants.ps.PSETID_ADDRESS) @property def businessFaxNumber(self) -> Optional[str]: @@ -193,14 +195,14 @@ def businessFaxOriginalDisplayName(self) -> Optional[str]: """ The normalized subject for the contact. """ - return self._ensureSetNamed('_businessFaxOriginalDisplayName', '80C4', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_businessFaxOriginalDisplayName', '80C4', constants.ps.PSETID_ADDRESS) @property def businessFaxOriginalEntryId(self) -> Optional[EntryID]: """ The one-off EntryID corresponding to this fax address. """ - return self._ensureSetNamed('_businessFaxOriginalEntryId', '80C5', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) + return self._getNamedAs('_businessFaxOriginalEntryId', '80C5', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) @property def businessTelephoneNumber(self) -> Optional[str]: @@ -270,35 +272,35 @@ def contactCharacterSet(self) -> Optional[int]: """ The character set that is used for this Contact object. """ - return self._ensureSetNamed('_contactCharacterSet', '8023', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_contactCharacterSet', '8023', constants.ps.PSETID_ADDRESS) @property def contactItemData(self) -> Optional[List[int]]: """ Used to help display the contact information. """ - return self._ensureSetNamed('_contactItemData', '8007', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_contactItemData', '8007', constants.ps.PSETID_ADDRESS) @property def contactLinkedGlobalAddressListEntryID(self) -> Optional[EntryID]: """ The EntryID of the GAL object to which the duplicate contact is linked. """ - return self._ensureSetNamed('_contactLinkedGlobalAddressListEntryID', '80E2', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) + return self._getNamedAs('_contactLinkedGlobalAddressListEntryID', '80E2', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) @property def contactLinkGlobalAddressListLinkID(self) -> Optional[str]: """ The GUID of the GAL contact to which the duplicate contact is linked. """ - return self._ensureSetNamed('_contactLinkGlobalAddressListLinkId', '80E8', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_contactLinkGlobalAddressListLinkId', '80E8', constants.ps.PSETID_ADDRESS) @property def contactLinkGlobalAddressListLinkState(self) -> Optional[ContactLinkState]: """ The state of linking between the GAL contact and the duplicate contact. """ - return self._ensureSetNamed('_contactLinkGlobalAddressListLinkState', '80E6', constants.ps.PSETID_ADDRESS, overrideClass = ContactLinkState) + return self._getNamedAs('_contactLinkGlobalAddressListLinkState', '80E6', constants.ps.PSETID_ADDRESS, overrideClass = ContactLinkState) @property def contactLinkLinkRejectHistory(self) -> Optional[List[bytes]]: @@ -306,7 +308,7 @@ def contactLinkLinkRejectHistory(self) -> Optional[List[bytes]]: A list of any contacts that were previously rejected for linking with the duplicate contact. """ - return self._ensureSetNamed('_contactLinkLinkRejectHistory', '80E5', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_contactLinkLinkRejectHistory', '80E5', constants.ps.PSETID_ADDRESS) @property def contactLinkSMTPAddressCache(self) -> Optional[List[str]]: @@ -314,7 +316,7 @@ def contactLinkSMTPAddressCache(self) -> Optional[List[str]]: A list of the SMTP addresses that are used by the GAL contact that are linked to the duplicate contact. """ - return self._ensureSetNamed('_contactLinkSMTPAddressCache', '80E3', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_contactLinkSMTPAddressCache', '80E3', constants.ps.PSETID_ADDRESS) @property def contactPhoto(self) -> Optional[bytes]: @@ -337,28 +339,28 @@ def contactUserField1(self) -> Optional[str]: """ Used to store custom text for a business card. """ - return self._ensureSetNamed('_contactUserField1', '804F', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_contactUserField1', '804F', constants.ps.PSETID_ADDRESS) @property def contactUserField2(self) -> Optional[str]: """ Used to store custom text for a business card. """ - return self._ensureSetNamed('_contactUserField2', '8050', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_contactUserField2', '8050', constants.ps.PSETID_ADDRESS) @property def contactUserField3(self) -> Optional[str]: """ Used to store custom text for a business card. """ - return self._ensureSetNamed('_contactUserField3', '8051', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_contactUserField3', '8051', constants.ps.PSETID_ADDRESS) @property def contactUserField4(self) -> Optional[str]: """ Used to store custom text for a business card. """ - return self._ensureSetNamed('_contactUserField4', '8052', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_contactUserField4', '8052', constants.ps.PSETID_ADDRESS) @property def customerID(self) -> Optional[str]: @@ -415,21 +417,21 @@ def email1AddressType(self) -> Optional[str]: """ The address type of the first email address. """ - return self._ensureSetNamed('_email1AddressType', '8082', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_email1AddressType', '8082', constants.ps.PSETID_ADDRESS) @property def email1DisplayName(self) -> Optional[str]: """ The user-readable display name of the first email address. """ - return self._ensureSetNamed('_email1DisplayName', '8080', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_email1DisplayName', '8080', constants.ps.PSETID_ADDRESS) @property def email1EmailAddress(self) -> Optional[str]: """ The first email address. """ - return self._ensureSetNamed('_email1EmailAddress', '8083', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_email1EmailAddress', '8083', constants.ps.PSETID_ADDRESS) @property def email1OriginalDisplayName(self) -> Optional[str]: @@ -437,14 +439,14 @@ def email1OriginalDisplayName(self) -> Optional[str]: The first SMTP email address that corresponds to the first email address for the contact. """ - return self._ensureSetNamed('_email1OriginalDisplayName', '8084', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_email1OriginalDisplayName', '8084', constants.ps.PSETID_ADDRESS) @property def email1OriginalEntryId(self) -> Optional[EntryID]: """ The EntryID of the object correspinding to this electronic address. """ - return self._ensureSetNamed('_email1OriginalEntryId', '8085', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) + return self._getNamedAs('_email1OriginalEntryId', '8085', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) @property def email2(self) -> Optional[dict]: @@ -470,21 +472,21 @@ def email2AddressType(self) -> Optional[str]: """ The address type of the second email address. """ - return self._ensureSetNamed('_email2AddressType', '8092', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_email2AddressType', '8092', constants.ps.PSETID_ADDRESS) @property def email2DisplayName(self) -> Optional[str]: """ The user-readable display name of the second email address. """ - return self._ensureSetNamed('_email2DisplayName', '8090', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_email2DisplayName', '8090', constants.ps.PSETID_ADDRESS) @property def email2EmailAddress(self) -> Optional[str]: """ The second email address. """ - return self._ensureSetNamed('_email2EmailAddress', '8093', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_email2EmailAddress', '8093', constants.ps.PSETID_ADDRESS) @property def email2OriginalDisplayName(self) -> Optional[str]: @@ -492,14 +494,14 @@ def email2OriginalDisplayName(self) -> Optional[str]: The second SMTP email address that corresponds to the second email address for the contact. """ - return self._ensureSetNamed('_email2OriginalDisplayName', '8094', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_email2OriginalDisplayName', '8094', constants.ps.PSETID_ADDRESS) @property def email2OriginalEntryId(self) -> Optional[EntryID]: """ The EntryID of the object correspinding to this electronic address. """ - return self._ensureSetNamed('_email2OriginalEntryId', '8095', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) + return self._getNamedAs('_email2OriginalEntryId', '8095', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) @property def email3(self) -> Optional[dict]: @@ -525,21 +527,21 @@ def email3AddressType(self) -> Optional[str]: """ The address type of the third email address. """ - return self._ensureSetNamed('_email3AddressType', '80A2', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_email3AddressType', '80A2', constants.ps.PSETID_ADDRESS) @property def email3DisplayName(self) -> Optional[str]: """ The user-readable display name of the third email address. """ - return self._ensureSetNamed('_email3DisplayName', '80A0', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_email3DisplayName', '80A0', constants.ps.PSETID_ADDRESS) @property def email3EmailAddress(self) -> Optional[str]: """ The third email address. """ - return self._ensureSetNamed('_email3EmailAddress', '80A3', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_email3EmailAddress', '80A3', constants.ps.PSETID_ADDRESS) @property def email3OriginalDisplayName(self) -> Optional[str]: @@ -547,14 +549,14 @@ def email3OriginalDisplayName(self) -> Optional[str]: The third SMTP email address that corresponds to the third email address for the contact. """ - return self._ensureSetNamed('_email3OriginalDisplayName', '80A4', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_email3OriginalDisplayName', '80A4', constants.ps.PSETID_ADDRESS) @property def email3OriginalEntryId(self) -> Optional[EntryID]: """ The EntryID of the object correspinding to this electronic address. """ - return self._ensureSetNamed('_email3OriginalEntryId', '80A5', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) + return self._getNamedAs('_email3OriginalEntryId', '80A5', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) @property def emails(self) -> Tuple[Union[Dict, None], Union[Dict, None], Union[Dict, None]]: @@ -591,7 +593,7 @@ def fileUnder(self) -> Optional[str]: The name under which to file a contact when displaying a list of contacts. """ - return self._ensureSetNamed('_fileUnder', '8005', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_fileUnder', '8005', constants.ps.PSETID_ADDRESS) @property def fileUnderID(self) -> Optional[int]: @@ -599,7 +601,7 @@ def fileUnderID(self) -> Optional[int]: The format to use for fileUnder. See PidLidFileUnderId in [MS-OXOCNTC] for details. """ - return self._ensureSetNamed('_fileUnderID', '8006', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_fileUnderID', '8006', constants.ps.PSETID_ADDRESS) @property def freeBusyLocation(self) -> Optional[str]: @@ -607,7 +609,7 @@ def freeBusyLocation(self) -> Optional[str]: A URL path from which a client can retrieve free/busy status information for the contact as an iCalendat file. """ - return self._ensureSetNamed('_freeBusyLocation', '80D8', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_freeBusyLocation', '80D8', constants.ps.PSETID_ADDRESS) @property def ftpSite(self) -> Optional[str]: @@ -650,7 +652,7 @@ def hasPicture(self) -> bool: """ Whether the contact has a contact photo. """ - return self._ensureSetNamed('_hasPicture', '8015', constants.ps.PSETID_ADDRESS, overrideClass = bool, preserveNone = False) + return self._getNamedAs('_hasPicture', '8015', constants.ps.PSETID_ADDRESS, overrideClass = bool, preserveNone = False) @property def headerFormatProperties(self) -> constants.HEADER_FORMAT_TYPE: @@ -756,7 +758,7 @@ def homeAddress(self) -> Optional[str]: """ The complete home address of the contact. """ - return self._ensureSetNamed('_homeAddress', '801A', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_homeAddress', '801A', constants.ps.PSETID_ADDRESS) @property def homeAddressCountry(self) -> Optional[str]: @@ -770,7 +772,7 @@ def homeAddressCountryCode(self) -> Optional[str]: """ The country code portion of the contact's home address. """ - return self._ensureSetNamed('_homeAddressCountryCode', '80DA', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_homeAddressCountryCode', '80DA', constants.ps.PSETID_ADDRESS) @property def homeAddressLocality(self) -> Optional[str]: @@ -834,7 +836,7 @@ def homeFaxAddressType(self) -> Optional[str]: """ The type of address for the fax. MUST be set to "FAX" if present. """ - return self._ensureSetNamed('_homeFaxAddressType', '80D2', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_homeFaxAddressType', '80D2', constants.ps.PSETID_ADDRESS) @property def homeFaxEmailAddress(self) -> Optional[str]: @@ -842,7 +844,7 @@ def homeFaxEmailAddress(self) -> Optional[str]: Contains a user-readable display name, followed by the "@" character, followed by a fax number. """ - return self._ensureSetNamed('_homeFaxEmailAddress', '80D3', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_homeFaxEmailAddress', '80D3', constants.ps.PSETID_ADDRESS) @property def homeFaxNumber(self) -> Optional[str]: @@ -856,14 +858,14 @@ def homeFaxOriginalDisplayName(self) -> Optional[str]: """ The normalized subject for the contact. """ - return self._ensureSetNamed('_homeFaxOriginalDisplayName', '80D4', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_homeFaxOriginalDisplayName', '80D4', constants.ps.PSETID_ADDRESS) @property def homeFaxOriginalEntryId(self) -> Optional[EntryID]: """ The one-off EntryID corresponding to this fax address. """ - return self._ensureSetNamed('_homeFaxOriginalEntryId', '80D5', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) + return self._getNamedAs('_homeFaxOriginalEntryId', '80D5', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) @property def homeTelephoneNumber(self) -> Optional[str]: @@ -891,14 +893,14 @@ def instantMessagingAddress(self) -> Optional[str]: """ The instant messaging address of the contact. """ - return self._ensureSetNamed('_instantMessagingAddress', '8062', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_instantMessagingAddress', '8062', constants.ps.PSETID_ADDRESS) @property def isContactLinked(self) -> bool: """ Whether the contact is linked to other contacts. """ - return self._ensureSetNamed('_isContactLinked', '80E0', constants.ps.PSETID_ADDRESS, overrideClass = bool, preserveNone = False) + return self._getNamedAs('_isContactLinked', '80E0', constants.ps.PSETID_ADDRESS, overrideClass = bool, preserveNone = False) @property def isdnNumber(self) -> Optional[str]: @@ -956,7 +958,7 @@ def mailAddressCountryCode(self) -> Optional[str]: """ The country code portion of the contact's mail address. """ - return self._ensureSetNamed('_mailAddressCountryCode', '80DD', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_mailAddressCountryCode', '80DD', constants.ps.PSETID_ADDRESS) @property def mailAddressLocality(self) -> Optional[str]: @@ -1036,20 +1038,20 @@ def organizationalIDNumber(self) -> Optional[str]: """ return self._ensureSet('_organizationalIdNumber', '__substg1.0_3A10') - @property + @functools.cached_property def oscSyncEnabled(self) -> bool: """ Whether contact synchronization with an external source (such as a social networking site) is handled by the server. """ - return self._ensureSetProperty('_oscSyncEnabled', '7C24000B', overrideClass = bool, preserveNone = False) + return self._getPropertyAs('7C24000B', overrideClass = bool, preserveNone = False) @property def otherAddress(self) -> Optional[str]: """ The complete other address of the contact. """ - return self._ensureSetNamed('_otherAddress', '801C', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_otherAddress', '801C', constants.ps.PSETID_ADDRESS) @property def otherAddressCountry(self) -> Optional[str]: @@ -1063,7 +1065,7 @@ def otherAddressCountryCode(self) -> Optional[str]: """ The country code portion of the contact's other address. """ - return self._ensureSetNamed('_otherAddressCountryCode', '80DC', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_otherAddressCountryCode', '80DC', constants.ps.PSETID_ADDRESS) @property def otherAddressLocality(self) -> Optional[str]: @@ -1126,21 +1128,21 @@ def phoneticCompanyName(self) -> Optional[str]: """ The phonetic pronunciation of the contact's company name. """ - return self._ensureSetNamed('_phoneticCompanyName', '802E', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_phoneticCompanyName', '802E', constants.ps.PSETID_ADDRESS) @property def phoneticGivenName(self) -> Optional[str]: """ The phonetic pronunciation of the contact's given name. """ - return self._ensureSetNamed('_phoneticGivenName', '802C', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_phoneticGivenName', '802C', constants.ps.PSETID_ADDRESS) @property def phoneticSurname(self) -> Optional[str]: """ The phonetic pronunciation of the given name of the contact. """ - return self._ensureSetNamed('_phoneticSurname', '802D', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_phoneticSurname', '802D', constants.ps.PSETID_ADDRESS) @property def postalAddressID(self) -> PostalAddressID: @@ -1148,7 +1150,7 @@ def postalAddressID(self) -> PostalAddressID: Indicates which physical address is the Mailing Address for this contact. """ - return self._ensureSetNamed('_postalAddressID', '8022', constants.ps.PSETID_ADDRESS, overrideClass = lambda x : PostalAddressID(x or 0), preserveNone = False) + return self._getNamedAs('_postalAddressID', '8022', constants.ps.PSETID_ADDRESS, overrideClass = lambda x : PostalAddressID(x or 0), preserveNone = False) @property def primaryFax(self) -> Optional[dict]: @@ -1177,7 +1179,7 @@ def primaryFaxAddressType(self) -> Optional[str]: """ The type of address for the fax. MUST be set to "FAX" if present. """ - return self._ensureSetNamed('_primaryFaxAddressType', '80B2', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_primaryFaxAddressType', '80B2', constants.ps.PSETID_ADDRESS) @property def primaryFaxEmailAddress(self) -> Optional[str]: @@ -1185,7 +1187,7 @@ def primaryFaxEmailAddress(self) -> Optional[str]: Contains a user-readable display name, followed by the "@" character, followed by a fax number. """ - return self._ensureSetNamed('_primaryFaxEmailAddress', '80B3', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_primaryFaxEmailAddress', '80B3', constants.ps.PSETID_ADDRESS) @property def primaryFaxNumber(self) -> Optional[str]: @@ -1199,14 +1201,14 @@ def primaryFaxOriginalDisplayName(self) -> Optional[str]: """ The normalized subject for the contact. """ - return self._ensureSetNamed('_primaryFaxOriginalDisplayName', '80B4', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_primaryFaxOriginalDisplayName', '80B4', constants.ps.PSETID_ADDRESS) @property def primaryFaxOriginalEntryId(self) -> Optional[EntryID]: """ The one-off EntryID corresponding to this fax address. """ - return self._ensureSetNamed('_primaryFaxOriginalEntryId', '80B5', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) + return self._getNamedAs('_primaryFaxOriginalEntryId', '80B5', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) @property def primaryTelephoneNumber(self) -> Optional[str]: @@ -1236,7 +1238,7 @@ def referenceEntryID(self) -> Optional[EntryID]: Contact object unless the Contact object is a copy of an earlier original. """ - return self._ensureSetNamed('_referenceEntryID', '85BD', constants.ps.PSETID_COMMON, overrideClass = EntryID.autoCreate) + return self._getNamedAs('_referenceEntryID', '85BD', constants.ps.PSETID_COMMON, overrideClass = EntryID.autoCreate) @property def referredByName(self) -> Optional[str]: @@ -1281,12 +1283,12 @@ def userX509Certificate(self) -> Optional[List[bytes]]: """ return self._ensureSetTyped('_userX509Certificate', '3A70') - @property + @functools.cached_property def weddingAnniversary(self) -> Optional[datetime.datetime]: """ The wedding anniversary of the contact at 11:59 UTC. """ - return self._ensureSetProperty('_weddingAnniversary', '3A410040') + return self._getPropertyAs('3A410040') @property def weddingAnniversaryEventEntryID(self) -> Optional[EntryID]: @@ -1294,7 +1296,7 @@ def weddingAnniversaryEventEntryID(self) -> Optional[EntryID]: The EntryID of an optional Appointement object that represents the contact's wedding anniversary. """ - return self._ensureSetNamed('_weddingAnniversaryEventEntryID', '804E', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) + return self._getNamedAs('_weddingAnniversaryEventEntryID', '804E', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) @property def weddingAnniversaryLocal(self) -> Optional[datetime.datetime]: @@ -1302,67 +1304,67 @@ def weddingAnniversaryLocal(self) -> Optional[datetime.datetime]: The wedding anniversary of the contact at 0:00 in the client's local time zone. """ - return self._ensureSetNamed('_weddingAnniversaryLocal', '80DF', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_weddingAnniversaryLocal', '80DF', constants.ps.PSETID_ADDRESS) @property def webpageUrl(self) -> Optional[str]: """ The contact's business web page url. SHOULD be the same as businessUrl. """ - return self._ensureSetNamed('_webpageUrl', '802B', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_webpageUrl', '802B', constants.ps.PSETID_ADDRESS) @property def workAddress(self) -> Optional[str]: """ The complete work address of the contact. """ - return self._ensureSetNamed('_workAddress', '801B', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_workAddress', '801B', constants.ps.PSETID_ADDRESS) @property def workAddressCountry(self) -> Optional[str]: """ The country portion of the contact's work address. """ - return self._ensureSetNamed('_workAddressCountry', '8049', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_workAddressCountry', '8049', constants.ps.PSETID_ADDRESS) @property def workAddressCountryCode(self) -> Optional[str]: """ The country code portion of the contact's work address. """ - return self._ensureSetNamed('_workAddressCountryCode', '80DB', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_workAddressCountryCode', '80DB', constants.ps.PSETID_ADDRESS) @property def workAddressLocality(self) -> Optional[str]: """ The locality or city portion of the contact's work address. """ - return self._ensureSetNamed('_workAddressLocality', '8046', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_workAddressLocality', '8046', constants.ps.PSETID_ADDRESS) @property def workAddressPostalCode(self) -> Optional[str]: """ The postal code portion of the contact's work address. """ - return self._ensureSetNamed('_workAddressPostalCode', '8048', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_workAddressPostalCode', '8048', constants.ps.PSETID_ADDRESS) @property def workAddressPostOfficeBox(self) -> Optional[str]: """ The number or identifier of the contact's work post office box. """ - return self._ensureSetNamed('_workAddressPostOfficeBox', '804A', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_workAddressPostOfficeBox', '804A', constants.ps.PSETID_ADDRESS) @property def workAddressStateOrProvince(self) -> Optional[str]: """ The state or province portion of the contact's work address. """ - return self._ensureSetNamed('_workAddressStateOrProvince', '8047', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_workAddressStateOrProvince', '8047', constants.ps.PSETID_ADDRESS) @property def workAddressStreet(self) -> Optional[str]: """ The street portion of the contact's work address. """ - return self._ensureSetNamed('_workAddressStreet', '8045', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('_workAddressStreet', '8045', constants.ps.PSETID_ADDRESS) diff --git a/extract_msg/msg_classes/meeting_exception.py b/extract_msg/msg_classes/meeting_exception.py index eb36bb6f..a9a29894 100644 --- a/extract_msg/msg_classes/meeting_exception.py +++ b/extract_msg/msg_classes/meeting_exception.py @@ -33,7 +33,7 @@ def exceptionReplaceTime(self) -> Optional[datetime.datetime]: The date and time within the recurrence pattern that the exception will replace. The value is specified in UTC. """ - return self._ensureSetNamed('_exceptionReplaceTime', '8228', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('_exceptionReplaceTime', '8228', constants.ps.PSETID_APPOINTMENT) @property def fExceptionalBody(self) -> bool: @@ -42,11 +42,11 @@ def fExceptionalBody(self) -> bool: differs from the Recurring Calendar object. If True, the Exception MUST have a body. """ - return self._ensureSetNamed('_fExceptionalBody', '8206', constants.ps.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) + return self._getNamedAs('_fExceptionalBody', '8206', constants.ps.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) @property def fInvited(self) -> bool: """ Indicates if invitations have been sent for this exception. """ - return self._ensureSetNamed('_fInvited', '8229', constants.ps.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) + return self._getNamedAs('_fInvited', '8229', constants.ps.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) diff --git a/extract_msg/msg_classes/meeting_forward.py b/extract_msg/msg_classes/meeting_forward.py index 8bcd7b2c..2ca8a002 100644 --- a/extract_msg/msg_classes/meeting_forward.py +++ b/extract_msg/msg_classes/meeting_forward.py @@ -24,7 +24,7 @@ def forwardNotificationRecipients(self) -> Optional[bytes]: Incomplete, looks to be the same structure as appointmentUnsendableRecipients, so we need more examples of this. """ - return self._ensureSetNamed('_forwardNotificationRecipients', '8261', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('_forwardNotificationRecipients', '8261', constants.ps.PSETID_APPOINTMENT) @property def headerFormatProperties(self) -> constants.HEADER_FORMAT_TYPE: @@ -94,4 +94,4 @@ def promptSendUpdate(self) -> bool: Indicates that the Meeting Forward Notification object was out-of-date when it was received. """ - return self._ensureSetNamed('_promptSendUpdate', '8045', constants.ps.PSETID_COMMON, overrideClass = bool, preserveNone = False) + return self._getNamedAs('_promptSendUpdate', '8045', constants.ps.PSETID_COMMON, overrideClass = bool, preserveNone = False) diff --git a/extract_msg/msg_classes/meeting_related.py b/extract_msg/msg_classes/meeting_related.py index 061999fb..9004ec8f 100644 --- a/extract_msg/msg_classes/meeting_related.py +++ b/extract_msg/msg_classes/meeting_related.py @@ -4,6 +4,7 @@ import datetime +import functools from typing import Optional, Set @@ -22,14 +23,14 @@ def attendeeCriticalChange(self) -> Optional[datetime.datetime]: """ The date and time at which the meeting-related object was sent. """ - return self._ensureSetNamed('_attendeeCriticalChange', '0001', constants.ps.PSETID_MEETING) + return self._getNamedAs('_attendeeCriticalChange', '0001', constants.ps.PSETID_MEETING) - @property + @functools.cached_property def processed(self) -> bool: """ Indicates whether a client has processed a meeting-related object. """ - return self._ensureSetProperty('_processed', '7D01000B', overrideClass = bool, preserveNone = False) + return self._getPropertyAs('7D01000B', overrideClass = bool, preserveNone = False) @property def serverProcessed(self) -> bool: @@ -37,7 +38,7 @@ def serverProcessed(self) -> bool: Indicates that the Meeting Request object or Meeting Update object has been processed. """ - return self._ensureSetNamed('_serverProcessed', '85CC', constants.ps.PSETID_CALENDAR_ASSISTANT, overrideClass = bool, preserveNone = False) + return self._getNamedAs('_serverProcessed', '85CC', constants.ps.PSETID_CALENDAR_ASSISTANT, overrideClass = bool, preserveNone = False) @property def serverProcessingActions(self) -> Optional[Set[ServerProcessingAction]]: @@ -45,7 +46,7 @@ def serverProcessingActions(self) -> Optional[Set[ServerProcessingAction]]: A set of which actions have been taken on the Meeting Request object or Meeting Update object. """ - return self._ensureSetNamed('_serverProcessingActions', '85CD', constants.ps.PSETID_CALENDAR_ASSISTANT, overrideClass = ServerProcessingAction.fromBits) + return self._getNamedAs('_serverProcessingActions', '85CD', constants.ps.PSETID_CALENDAR_ASSISTANT, overrideClass = ServerProcessingAction.fromBits) @property def timeZone(self) -> Optional[int]: @@ -54,11 +55,11 @@ def timeZone(self) -> Optional[int]: See PidLidTimeZone in [MS-OXOCAL] for details. """ - return self._ensureSetNamed('_timeZone', '000C', constants.ps.PSETID_MEETING) + return self._getNamedAs('_timeZone', '000C', constants.ps.PSETID_MEETING) @property def where(self) -> Optional[str]: """ PidLidWhere. Should be the same as location. """ - return self._ensureSetNamed('_where', '0002', constants.ps.PSETID_MEETING) + return self._getNamedAs('_where', '0002', constants.ps.PSETID_MEETING) diff --git a/extract_msg/msg_classes/meeting_request.py b/extract_msg/msg_classes/meeting_request.py index 3ccd6191..58a0ebc0 100644 --- a/extract_msg/msg_classes/meeting_request.py +++ b/extract_msg/msg_classes/meeting_request.py @@ -24,7 +24,7 @@ def appointmentMessageClass(self) -> Optional[str]: object that is to be generated from the Meeting Request object. MUST start with "IPM.Appointment". """ - return self._ensureSetNamed('_appointmentMessageClass', '0024', constants.ps.PSETID_MEETING) + return self._getNamedAs('_appointmentMessageClass', '0024', constants.ps.PSETID_MEETING) @property def calendarType(self) -> Optional[RecurCalendarType]: @@ -33,7 +33,7 @@ def calendarType(self) -> Optional[RecurCalendarType]: property if the Meeting Request object represents a recurring series or an exception. """ - return self._ensureSetNamed('_calendarType', '001C', constants.ps.PSETID_MEETING, overrideClass = RecurCalendarType) + return self._getNamedAs('_calendarType', '001C', constants.ps.PSETID_MEETING, overrideClass = RecurCalendarType) @property def changeHighlight(self) -> Optional[Set[MeetingObjectChange]]: @@ -43,7 +43,7 @@ def changeHighlight(self) -> Optional[Set[MeetingObjectChange]]: Returns a set of flags. """ - return self._ensureSetNamed('_changeHighlight', '8204', constants.ps.PSETID_APPOINTMENT, overrideClass = MeetingObjectChange.fromBits) + return self._getNamedAs('_changeHighlight', '8204', constants.ps.PSETID_APPOINTMENT, overrideClass = MeetingObjectChange.fromBits) @property def forwardInstance(self) -> bool: @@ -52,7 +52,7 @@ def forwardInstance(self) -> bool: recurring series, and it was forwarded (even when forwarded by the organizer) rather than being an invitation sent by the organizer. """ - return self._ensureSetNamed('_forwardInstance', '820A', constants.ps.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) + return self._getNamedAs('_forwardInstance', '820A', constants.ps.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) @property def headerFormatProperties(self) -> constants.HEADER_FORMAT_TYPE: @@ -139,21 +139,21 @@ def intendedBusyStatus(self) -> Optional[BusyStatus]: calendar at the time the Meeting Request object or Meeting Update object was sent. """ - return self._ensureSetNamed('_intendedBusyStatus', '8224', constants.ps.PSETID_APPOINTMENT, overrideClass = BusyStatus) + return self._getNamedAs('_intendedBusyStatus', '8224', constants.ps.PSETID_APPOINTMENT, overrideClass = BusyStatus) @property def meetingType(self) -> Optional[MeetingType]: """ The type of Meeting Request object or Meeting Update object. """ - return self._ensureSetNamed('_meetingType', '0026', constants.ps.PSETID_MEETING, overrideClass = MeetingType) + return self._getNamedAs('_meetingType', '0026', constants.ps.PSETID_MEETING, overrideClass = MeetingType) @property def oldLocation(self) -> Optional[str]: """ The original value of the location property before a meeting update. """ - return self._ensureSetNamed('_oldLocation', '0028', constants.ps.PSETID_MEETING) + return self._getNamedAs('_oldLocation', '0028', constants.ps.PSETID_MEETING) @property def oldWhenEndWhole(self) -> Optional[datetime.datetime]: @@ -161,7 +161,7 @@ def oldWhenEndWhole(self) -> Optional[datetime.datetime]: The original value of the appointmentEndWhole property before a meeting update. """ - return self._ensureSetNamed('_oldWhenEndWhole', '002A', constants.ps.PSETID_MEETING) + return self._getNamedAs('_oldWhenEndWhole', '002A', constants.ps.PSETID_MEETING) @property def oldWhenStartWhole(self) -> Optional[datetime.datetime]: @@ -169,4 +169,4 @@ def oldWhenStartWhole(self) -> Optional[datetime.datetime]: The original value of the appointmentStartWhole property before a meeting update. """ - return self._ensureSetNamed('_oldWhenStartWhole', '0029', constants.ps.PSETID_MEETING) + return self._getNamedAs('_oldWhenStartWhole', '0029', constants.ps.PSETID_MEETING) diff --git a/extract_msg/msg_classes/meeting_response.py b/extract_msg/msg_classes/meeting_response.py index 4f656ff9..d13d9b63 100644 --- a/extract_msg/msg_classes/meeting_response.py +++ b/extract_msg/msg_classes/meeting_response.py @@ -4,6 +4,7 @@ import datetime +import functools from typing import Optional @@ -17,55 +18,55 @@ class MeetingResponse(MeetingRelated): Class for handling meeting response objects. """ - @property + @functools.cached_property def appointmentCounterProposal(self) -> bool: """ Indicates if the response is a counter proposal. """ - return self._ensureSetNamed('_appointmentCounterProposal', '8257', constants.ps.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) + return self._getNamedAs('8257', constants.ps.PSETID_APPOINTMENT, bool, False) - @property + @functools.cached_property def appointmentProposedDuration(self) -> Optional[int]: """ The proposed value for the appointmentDuration property for a counter proposal. """ - return self._ensureSetNamed('_appointmentProposedDuration', '8256', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8256', constants.ps.PSETID_APPOINTMENT) - @property + @functools.cached_property def appointmentProposedEndWhole(self) -> Optional[datetime.datetime]: """ The proposal value for the appointmentEndWhole property for a counter proposal. """ - return self._ensureSetNamed('_appointmentProposedEndWhole', '8251', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8251', constants.ps.PSETID_APPOINTMENT) - @property + @functools.cached_property def appointmentProposedStartWhole(self) -> Optional[datetime.datetime]: """ The proposal value for the appointmentStartWhole property for a counter proposal. """ - return self._ensureSetNamed('_appointmentProposedStartWhole', '8250', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8250', constants.ps.PSETID_APPOINTMENT) - @property + @functools.cached_property def isSilent(self) -> bool: """ Indicates if the user did not include any text in the body of the Meeting Response object. """ - return self._ensureSetNamed('_isSilent', '0004', constants.ps.PSETID_MEETING, overrideClass = bool, preserveNone = False) + return self._getNamedAs('0004', constants.ps.PSETID_MEETING, bool, False) - @property + @functools.cached_property def promptSendUpdate(self) -> bool: """ Indicates that the Meeting Response object was out-of-date when it was received. """ - return self._ensureSetNamed('_promptSendUpdate', '8045', constants.ps.PSETID_COMMON, overrideClass = bool, preserveNone = False) + return self._getNamedAs('8045', constants.ps.PSETID_COMMON, bool, False) - @property - def responseType(self) -> Optional[ResponseType]: + @functools.cached_property + def responseType(self) -> ResponseType: """ The type of Meeting Response object. """ diff --git a/extract_msg/msg_classes/message_base.py b/extract_msg/msg_classes/message_base.py index 8e60842e..ca858533 100644 --- a/extract_msg/msg_classes/message_base.py +++ b/extract_msg/msg_classes/message_base.py @@ -957,14 +957,14 @@ def deencapsulatedRtf(self) -> Optional[RTFDE.DeEncapsulator]: logger.debug('RTF body is not encapsulated.') self._deencapsultor = None except RTFDE.exceptions.MalformedEncapsulatedRtf as _e: - if not (self.errorBehavior & ErrorBehavior.RTFDE_MALFORMED): + if ErrorBehavior.RTFDE_MALFORMED not in self.errorBehavior: raise logger.info('RTF body contains malformed encapsulated content.') self._deencapsultor = None except Exception: # If we are just ignoring the errors, log it then set to # None. Otherwise, continue the exception. - if not (self.errorBehavior & ErrorBehavior.RTFDE_UNKNOWN_ERROR): + if ErrorBehavior.RTFDE_UNKNOWN_ERROR not in self.errorBehavior: raise logger.exception('Unhandled error happened while using RTFDE. You have choosen to ignore these errors.') self._deencapsultor = None @@ -1119,7 +1119,7 @@ def htmlBody(self) -> Optional[bytes]: return self._htmlBody - @property + @functools.cached_property def htmlBodyPrepared(self) -> Optional[bytes]: """ Returns the HTML body that has (where possible) the embedded attachments @@ -1147,7 +1147,7 @@ def htmlBodyPrepared(self) -> Optional[bytes]: return soup.prettify('utf-8') - @property + @functools.cached_property def htmlInjectableHeader(self) -> str: """ The header that can be formatted and injected into the html body. @@ -1166,14 +1166,17 @@ def inReplyTo(self) -> Optional[str]: """ return self._ensureSet('_in_reply_to', '__substg1.0_1042') - @property + @functools.cached_property def isRead(self) -> bool: """ Returns if this email has been marked as read. """ - return bool(self.props['0E070003'].value & 1) + try: + return bool(self.props['0E070003'].value & 1) + except (AttributeError, KeyError): + return False - @property + @functools.cached_property def isSent(self) -> bool: """ Returns if this email has been marked as sent. Assumes True if no flags @@ -1184,32 +1187,28 @@ def isSent(self) -> bool: else: return not bool(self.props['0E070003'].value & 8) - @property + @functools.cached_property def messageId(self) -> Optional[str]: - try: - return self._messageId - except AttributeError: - headerResult = None - if self.headerInit(): - headerResult = self.header['message-id'] - if headerResult is not None: - self._messageId = headerResult - else: - if self.headerInit(): - logger.info('Header found, but "Message-Id" is not included. Will be generated from other streams.') - self._messageId = self._getStringStream('__substg1.0_1035') - return self._messageId + headerResult = None + if self.headerInit(): + headerResult = self.header['message-id'] + if headerResult is not None: + return headerResult - @property + if self.headerInit(): + logger.info('Header found, but "Message-Id" is not included. Will be generated from other streams.') + return self._getStringStream('__substg1.0_1035') + + @functools.cached_property def parsedDate(self): return email.utils.parsedate(self.date) - @property + @functools.cached_property def receivedTime(self) -> Optional[datetime.datetime]: """ The date and time the message was received by the server. """ - return self._ensureSetProperty('_receivedTime', '0E060040') + return self._getPropertyAs('0E060040') @property def recipientSeparator(self) -> str: diff --git a/extract_msg/msg_classes/message_signed_base.py b/extract_msg/msg_classes/message_signed_base.py index b862e3bf..2360c630 100644 --- a/extract_msg/msg_classes/message_signed_base.py +++ b/extract_msg/msg_classes/message_signed_base.py @@ -3,6 +3,7 @@ ] +import functools import html import logging import re @@ -50,10 +51,10 @@ def attachments(self) -> List: atts = super().attachments if len(atts) != 1: - if self.errorBehavior & ErrorBehavior.STANDARDS_VIOLATION: + if ErrorBehavior.STANDARDS_VIOLATION in self.errorBehavior: if len(atts) == 0: logger.error('Signed message has no attachments, a violation of the standard.') - self._sAttachments = None + self._sAttachments = [] self._signedBody = None self._signedHtmlBody = None return @@ -128,7 +129,7 @@ def htmlBody(self) -> Optional[bytes]: return self._htmlBody - @property + @functools.cached_property def _rawAttachments(self) -> List: """ A property to allow access to the non-signed attachments. @@ -142,24 +143,18 @@ def signedAttachmentClass(self): """ return self.__signedAttachmentClass - @property + @functools.cached_property def signedBody(self) -> Optional[str]: """ Returns the body from the signed message if it exists. """ - try: - return self._signedBody - except AttributeError: - self.attachments - return self._signedBody + self.attachments + return self._signedBody - @property + @functools.cached_property def signedHtmlBody(self) -> Optional[bytes]: """ Returns the HTML body from the signed message if it exists. """ - try: - return self._signedHtmlBody - except AttributeError: - self.attachments - return self._signedHtmlBody + self.attachments + return self._signedHtmlBody diff --git a/extract_msg/msg_classes/msg.py b/extract_msg/msg_classes/msg.py index c12c3398..f3bdc2d5 100644 --- a/extract_msg/msg_classes/msg.py +++ b/extract_msg/msg_classes/msg.py @@ -240,10 +240,9 @@ def _ensureSet(self, variable : str, streamID, stringStream : bool = True, **kwa setattr(self, variable, value) return value - def _ensureSetNamed(self, variable : str, propertyName : str, guid : str, **kwargs): + def _getNamedAs(self, propertyName : str, guid : str, overrideClass = None, preserveNone : bool = True): """ - Ensures that the variable exists, otherwise will set it using the named - property. After that, return said variable. + Returns the named property, setting the class if specified. :param overrideClass: Class/function to use to morph the data that was read. The data will be the first argument to the class's __init__ @@ -253,45 +252,36 @@ def _ensureSetNamed(self, variable : str, propertyName : str, guid : str, **kwar :param overrideClass: when the value could not be found (is None). If this is changed to False, then the value will be used regardless. """ - try: - return getattr(self, variable) - except AttributeError: - value = self.namedProperties.get((propertyName, guid)) - # Check if we should be overriding the data type for this instance. - if kwargs: - overrideClass = kwargs.get('overrideClass') - if overrideClass is not None and (value is not None or not kwargs.get('preserveNone', True)): - value = overrideClass(value) - setattr(self, variable, value) - return value + value = self.namedProperties.get((propertyName, guid)) + # Check if we should be overriding the data type for this instance. + if overrideClass is not None: + if value is not None or not preserveNone: + value = overrideClass(value) + + return value - def _ensureSetProperty(self, variable : str, propertyName, **kwargs): + def _getPropertyAs(self, propertyName, overrideClass = None, preserveNone : bool = True): """ - Ensures that the variable exists, otherwise will set it using the - property. After that, return said variable. + Returns the property, setting the class if specified. :param overrideClass: Class/function to use to morph the data that was read. The data will be the first argument to the class's __init__ function or the function itself, if that is what is provided. By default, this will be completely ignored if the value was not found. - :param preserveNone: If true (default), causes the function to ignore + :param preserveNone: If True (default), causes the function to ignore :param overrideClass: when the value could not be found (is None). If this is changed to False, then the value will be used regardless. """ try: - return getattr(self, variable) - except AttributeError: - try: - value = self.props[propertyName].value - except (KeyError, AttributeError): - value = None - # Check if we should be overriding the data type for this instance. - if kwargs: - overrideClass = kwargs.get('overrideClass') - if overrideClass is not None and (value is not None or not kwargs.get('preserveNone', True)): - value = overrideClass(value) - setattr(self, variable, value) - return value + value = self.props[propertyName].value + except (KeyError, AttributeError): + value = None + # Check if we should be overriding the data type for this instance. + if overrideClass is not None: + if (value is not None or not preserveNone): + value = overrideClass(value) + + return value def _ensureSetTyped(self, variable : str, _id, **kwargs): """ @@ -702,13 +692,13 @@ def attachmentsReady(self) -> bool: """ return self.__attachmentsReady - @property + @functools.cached_property def classified(self) -> bool: """ Indicates whether the contents of this message are regarded as classified information. """ - return self._ensureSetNamed('_classified', '85B5', constants.ps.PSETID_COMMON, overrideClass = bool, preserveNone = False) + return self._getNamedAs('85B5', constants.ps.PSETID_COMMON, overrideClass = bool, preserveNone = False) @property def classType(self) -> Optional[str]: @@ -717,34 +707,34 @@ def classType(self) -> Optional[str]: """ return self._ensureSet('_classType', '__substg1.0_001A') - @property + @functools.cached_property def commonEnd(self) -> Optional[datetime.datetime]: """ The end time for the object. """ - return self._ensureSetNamed('_commonEnd', '8517', constants.ps.PSETID_COMMON) + return self._getNamedAs('8517', constants.ps.PSETID_COMMON) - @property + @functools.cached_property def commonStart(self) -> Optional[datetime.datetime]: """ The start time for the object. """ - return self._ensureSetNamed('_commonStart', '8516', constants.ps.PSETID_COMMON) + return self._getNamedAs('8516', constants.ps.PSETID_COMMON) - @property + @functools.cached_property def currentVersion(self) -> Optional[int]: """ Specifies the build number of the client application that sent the message. """ - return self._ensureSetNamed('_currentVersion', '8552', constants.ps.PSETID_COMMON) + return self._getNamedAs('8552', constants.ps.PSETID_COMMON) - @property + @functools.cached_property def currentVersionName(self) -> Optional[str]: """ Specifies the name of the client application that sent the message. """ - return self._ensureSetNamed('_currentVersionName', '8554', constants.ps.PSETID_COMMON) + return self._getNamedAs('8554', constants.ps.PSETID_COMMON) @property def errorBehavior(self) -> ErrorBehavior: @@ -754,12 +744,12 @@ def errorBehavior(self) -> ErrorBehavior: """ return self.__errorBehavior - @property + @functools.cached_property def importance(self) -> Optional[Importance]: """ The specified importance of the msg file. """ - return self._ensureSetProperty('_importance', '00170003', overrideClass = Importance) + return self._getPropertyAs('00170003', overrideClass = Importance) @property def importanceString(self) -> Union[str, None]: @@ -863,46 +853,42 @@ def prefixList(self) -> List[str]: """ return copy.deepcopy(self.__prefixList) - @property + @functools.cached_property def priority(self) -> Optional[Priority]: """ The specified priority of the msg file. """ - return self._ensureSetProperty('_priority', '00260003', overrideClass = Priority) + return self._getPropertyAs('00260003', Priority) - @property + @functools.cached_property def props(self) -> PropertiesStore: """ Returns the Properties instance used by the MSGFile instance. """ - try: - return self._prop - except AttributeError: - if not (stream := self._getStream('__properties_version1.0')): - if self.__errorBehavior & ErrorBehavior.STANDARDS_VIOLATION: - logger.error('File does not contain a property stream.') - else: - # Raise the exception from None so we don't get all the "during - # the handling of the above exception" stuff. - raise StandardViolationError('File does not contain a property stream.') from None - self._prop = PropertiesStore(stream, - PropertiesType.MESSAGE if self.prefix == '' else PropertiesType.MESSAGE_EMBED) - return self._prop + if not (stream := self._getStream('__properties_version1.0')): + if ErrorBehavior.STANDARDS_VIOLATION in self.__errorBehavior: + logger.error('File does not contain a property stream.') + else: + # Raise the exception from None so we don't get all the "during + # the handling of the above exception" stuff. + raise StandardViolationError('File does not contain a property stream.') from None + return PropertiesStore(stream, + PropertiesType.MESSAGE if self.prefix == '' else PropertiesType.MESSAGE_EMBED) - @property + @functools.cached_property def sensitivity(self) -> Optional[Sensitivity]: """ The specified sensitivity of the msg file. """ - return self._ensureSetProperty('_sensitivity', '00360003', overrideClass = Sensitivity) + return self._getPropertyAs('00360003', Sensitivity) - @property - def sideEffects(self) -> Optional[Set[SideEffect]]: + @functools.cached_property + def sideEffects(self) -> Optional[SideEffect]: """ Controls how a Message object is handled by the client in relation to certain user interface actions by the user, such as deleting a message. """ - return self._ensureSetNamed('_sideEffects', '8510', constants.ps.PSETID_COMMON, overrideClass = SideEffect.fromBits) + return self._getNamedAs('8510', constants.ps.PSETID_COMMON, SideEffect) @property def stringEncoding(self): diff --git a/extract_msg/msg_classes/sticky_note.py b/extract_msg/msg_classes/sticky_note.py index 3c2d300d..ca9eaa00 100644 --- a/extract_msg/msg_classes/sticky_note.py +++ b/extract_msg/msg_classes/sticky_note.py @@ -1,7 +1,8 @@ +import functools + from typing import Optional -from ..constants import HEADER_FORMAT_TYPE -from ..constants.ps import PSETID_NOTE +from .. import constants from ..enums import NoteColor from .message_base import MessageBase @@ -14,42 +15,42 @@ class StickyNote(MessageBase): """ @property - def headerFormatProperties(self) -> HEADER_FORMAT_TYPE: + def headerFormatProperties(self) -> constants.HEADER_FORMAT_TYPE: return None - @property + @functools.cached_property def noteColor(self) -> Optional[NoteColor]: """ The color of the sticky note. """ - return self._ensureSetNamed('_noteColor', '8B00', PSETID_NOTE, preserveNone = True, overrideClass = NoteColor) + return self._getNamedAs('8B00', constants.ps.PSETID_NOTE, NoteColor) - @property + @functools.cached_property def noteHeight(self) -> Optional[int]: """ The height of the note window, in pixels. """ - return self._ensureSetNamed('_noteWidth', '8B03', PSETID_NOTE) + return self._getNamedAs('8B03', constants.ps.PSETID_NOTE) - @property + @functools.cached_property def noteWidth(self) -> Optional[int]: """ The width of the note window, in pixels. """ - return self._ensureSetNamed('_noteWidth', '8B02', PSETID_NOTE) + return self._getNamedAs('8B02', constants.ps.PSETID_NOTE) - @property + @functools.cached_property def noteX(self) -> Optional[int]: """ The distance, in pixels, from the left edge of the screen that a user interface displays the note. """ - return self._ensureSetNamed('_noteX', '8B02', PSETID_NOTE) + return self._getNamedAs('8B02', constants.ps.PSETID_NOTE) - @property + @functools.cached_property def noteY(self) -> Optional[int]: """ The distance, in pixels, from the top edge of the screen that a user interafce displays the note. """ - return self._ensureSetNamed('_noteY', '8B02', PSETID_NOTE) \ No newline at end of file + return self._getNamedAs('8B02', constants.ps.PSETID_NOTE) \ No newline at end of file diff --git a/extract_msg/msg_classes/task.py b/extract_msg/msg_classes/task.py index 87ac0e07..13ae5499 100644 --- a/extract_msg/msg_classes/task.py +++ b/extract_msg/msg_classes/task.py @@ -4,9 +4,10 @@ import datetime +import functools import logging -from typing import Optional, Set +from typing import Optional from .. import constants from ..enums import ( @@ -81,45 +82,45 @@ def headerFormatProperties(self) -> constants.HEADER_FORMAT_TYPE: }, } - @property + @functools.cached_property def percentComplete(self) -> Optional[float]: """ Indicates whether a time-flagged Message object is complete. Returns a percentage in decimal form. 1.0 indicates it is complete. """ - return self._ensureSetNamed('_percentComplete', '8102', constants.ps.PSETID_TASK) + return self._getNamedAs('8102', constants.ps.PSETID_TASK) - @property + @functools.cached_property def taskAcceptanceState(self) -> Optional[TaskAcceptance]: """ Indicates the acceptance state of the task. """ - return self._ensureSetNamed('_taskAcceptanceState', '812A', constants.ps.PSETID_TASK, overrideClass = TaskAcceptance) + return self._getNamedAs('812A', constants.ps.PSETID_TASK, TaskAcceptance) - @property + @functools.cached_property def taskAccepted(self) -> bool: """ Indicates whether a task assignee has replied to a tesk request for this task object. Does not indicate if it was accepted or rejected. """ - return self._ensureSetNamed('_taskAccepted', '8108', constants.ps.PSETID_TASK, overrideClass = bool, preserveNone = False) + return self._getNamedAs('8108', constants.ps.PSETID_TASK, bool, False) - @property + @functools.cached_property def taskActualEffort(self) -> Optional[int]: """ Indicates the number of minutes that the user actually spent working on a task. """ - return self._ensureSetNamed('_taskActualEffort', '8110', constants.ps.PSETID_TASK) + return self._getNamedAs('8110', constants.ps.PSETID_TASK) - @property + @functools.cached_property def taskAssigner(self) -> Optional[str]: """ Specifies the name of the user that last assigned the task. """ - return self._ensureSetNamed('_taskAssigner', '8121', constants.ps.PSETID_TASK) + return self._getNamedAs('8121', constants.ps.PSETID_TASK) - @property + @functools.cached_property def taskAssigners(self) -> Optional[bytes]: """ A stack of entries, each representing a task assigner. The most recent @@ -127,229 +128,229 @@ def taskAssigners(self) -> Optional[bytes]: The documentation on this is weird, so I don't know how to parse it. """ - return self._ensureSetNamed('_taskAssigners', '8117', constants.ps.PSETID_TASK) + return self._getNamedAs('8117', constants.ps.PSETID_TASK) - @property + @functools.cached_property def taskComplete(self) -> bool: """ Indicates if the task is complete. """ - return self._ensureSetNamed('_taskComplete', '811C', constants.ps.PSETID_TASK, overrideClass = bool, preserveNone = False) + return self._getNamedAs('811C', constants.ps.PSETID_TASK, bool, False) - @property + @functools.cached_property def taskCustomFlags(self) -> Optional[int]: """ Custom flags set on the task. """ - return self._ensureSetNamed('_taskCustomFlags', '8139', constants.ps.PSETID_TASK) + return self._getNamedAs('8139', constants.ps.PSETID_TASK) - @property + @functools.cached_property def taskDateCompleted(self) -> Optional[datetime.datetime]: """ The date when the user completed work on the task. """ - return self._ensureSetNamed('_taskDateCompleted', '810F', constants.ps.PSETID_TASK) + return self._getNamedAs('810F', constants.ps.PSETID_TASK) - @property + @functools.cached_property def taskDeadOccurrence(self) -> bool: """ Indicates whether a new recurring task remains to be generated. Set to False on a new Task object and True when the client generates the last recurring task. """ - return self._ensureSetNamed('_taskDeadOccurrence', '8109', constants.ps.PSETID_TASK, overrideClass = bool, preserveNone = False) + return self._getNamedAs('8109', constants.ps.PSETID_TASK, bool, False) - @property + @functools.cached_property def taskDueDate(self) -> Optional[datetime.datetime]: """ Specifies the date by which the user expects work on the task to be complete. """ - return self._ensureSetNamed('_taskDueDate', '8105', constants.ps.PSETID_TASK) + return self._getNamedAs('8105', constants.ps.PSETID_TASK) - @property + @functools.cached_property def taskEstimatedEffort(self) -> Optional[int]: """ Indicates the number of minutes that the user expects to work on a task. """ - return self._ensureSetNamed('_taskEstimatedEffort', '8111', constants.ps.PSETID_TASK) + return self._getNamedAs('8111', constants.ps.PSETID_TASK) - @property + @functools.cached_property def taskFCreator(self) -> bool: """ Indicates that the task object was originally created by the action of the current user or user agent instead of by the processing of a task request. """ - return self._ensureSetNamed('_taskFCreator', '811E', constants.ps.PSETID_TASK, overrideClass = bool, preserveNone = False) + return self._getNamedAs('811E', constants.ps.PSETID_TASK, bool, False) - @property + @functools.cached_property def taskFFixOffline(self) -> bool: """ Indicates whether the value of the taskOwner property is correct. """ - return self._ensureSetNamed('taskFFixOffline', '812C', constants.ps.PSETID_TASK, overrideClass = bool, preserveNone = False) + return self._getNamedAs('812C', constants.ps.PSETID_TASK, bool, False) - @property + @functools.cached_property def taskFRecurring(self) -> bool: """ Indicates whether the task includes a recurrence pattern. """ - return self._ensureSetNamed('_taskFRecurring', '8126', constants.ps.PSETID_TASK, overrideClass = bool, preserveNone = False) + return self._getNamedAs('8126', constants.ps.PSETID_TASK, bool, False) - @property + @functools.cached_property def taskGlobalID(self) -> Optional[bytes]: """ Specifies a unique GUID for this task, used to locate an existing task upon receipt of a task response or task update. """ - return self._ensureSetNamed('_taskGlobalID', '8519', constants.ps.PSETID_COMMON) + return self._getNamedAs('8519', constants.ps.PSETID_COMMON) - @property + @functools.cached_property def taskHistory(self) -> Optional[TaskHistory]: """ Indicates the type of change that was last made to the Task object. """ - return self._ensureSetNamed('_taskHistory', '811A', constants.ps.PSETID_TASK, overrideClass = TaskHistory) + return self._getNamedAs('811A', constants.ps.PSETID_TASK, TaskHistory) - @property + @functools.cached_property def taskLastDelegate(self) -> Optional[str]: """ Contains the name of the user who most recently assigned the task, or the user to whom it was most recently assigned. """ - return self._ensureSetNamed('_taskLastDelegate', '8125', constants.ps.PSETID_TASK) + return self._getNamedAs('8125', constants.ps.PSETID_TASK) - @property + @functools.cached_property def taskLastUpdate(self) -> Optional[datetime.datetime]: """ The date and time of the most recent change made to the task object. """ - return self._ensureSetNamed('_taskLastUpdate', '8115', constants.ps.PSETID_TASK) + return self._getNamedAs('8115', constants.ps.PSETID_TASK) - @property + @functools.cached_property def taskLastUser(self) -> Optional[str]: """ Contains the name of the most recent user to have been the owner of the task. """ - return self._ensureSetNamed('_taskLastUser', '8122', constants.ps.PSETID_TASK) + return self._getNamedAs('8122', constants.ps.PSETID_TASK) - @property + @functools.cached_property def taskMode(self) -> Optional[TaskMode]: """ Used in a task communication. Should be 0 (UNASSIGNED) on task objects. """ - return self._ensureSetNamed('_taskMode', '8518', constants.ps.PSETID_COMMON, overrideClass = TaskMode) + return self._getNamedAs('8518', constants.ps.PSETID_COMMON, TaskMode) - @property - def taskMultipleRecipients(self) -> Optional[Set[TaskMultipleRecipients]]: + @functools.cached_property + def taskMultipleRecipients(self) -> Optional[TaskMultipleRecipients]: """ Returns a set of flags that specify optimization hints about the recipients of a Task object. """ - return self._ensureSetNamed('_taskMultipleRecipients', '8120', constants.ps.PSETID_TASK, overrideClass = TaskMultipleRecipients.fromBits) + return self._getNamedAs('8120', constants.ps.PSETID_TASK, TaskMultipleRecipients) - @property + @functools.cached_property def taskNoCompute(self) -> Optional[bool]: """ This value is not used and has no impact on a Task, but is provided for completeness. """ - return self._ensureSetNamed('_taskNoCompute', '8124', constants.ps.PSETID_TASK) + return self._getNamedAs('8124', constants.ps.PSETID_TASK) - @property + @functools.cached_property def taskOrdinal(self) -> Optional[int]: """ Specifies a number that aids custom sorting of Task objects. """ - return self._ensureSetNamed('_taskOrdinal', '8123', constants.ps.PSETID_TASK, overrideClass = unsignedToSignedInt) + return self._getNamedAs('8123', constants.ps.PSETID_TASK, unsignedToSignedInt) - @property + @functools.cached_property def taskOwner(self) -> Optional[str]: """ Contains the name of the owner of the task. """ - return self._ensureSetNamed('_taskOwner', '811F', constants.ps.PSETID_TASK) + return self._getNamedAs('811F', constants.ps.PSETID_TASK) - @property + @functools.cached_property def taskOwnership(self) -> Optional[TaskOwnership]: """ Contains the name of the owner of the task. """ - return self._ensureSetNamed('_taskOwnership', '8129', constants.ps.PSETID_TASK, overrideClass = TaskOwnership) + return self._getNamedAs('8129', constants.ps.PSETID_TASK, TaskOwnership) - @property + @functools.cached_property def taskRecurrence(self) -> Optional[RecurrencePattern]: """ Contains a RecurrencePattern structure that provides information about recurring tasks. """ - return self._ensureSetNamed('_taskRecurrence', '8116', constants.ps.PSETID_TASK, overrideClass = RecurrencePattern) + return self._getNamedAs('8116', constants.ps.PSETID_TASK, RecurrencePattern) - @property + @functools.cached_property def taskResetReminder(self) -> bool: """ Indicates whether future recurring tasks need reminders. """ - return self._ensureSetNamed('_taskResetReminder', '8107', constants.ps.PSETID_TASK, overrideClass = bool, preserveNone = False) + return self._getNamedAs('8107', constants.ps.PSETID_TASK, bool, False) - @property + @functools.cached_property def taskRole(self) -> Optional[str]: """ This value is not used and has no impact on a Task, but is provided for completeness. """ - return self._ensureSetNamed('_taskRole', '8127', constants.ps.PSETID_TASK) + return self._getNamedAs('8127', constants.ps.PSETID_TASK) - @property + @functools.cached_property def taskStartDate(self) -> Optional[datetime.datetime]: """ Specifies the date on which the user expects work on the task to begin. """ - return self._ensureSetNamed('_taskStartDate', '8104', constants.ps.PSETID_TASK) + return self._getNamedAs('8104', constants.ps.PSETID_TASK) - @property + @functools.cached_property def taskState(self) -> Optional[TaskState]: """ Indicates the current assignment state of the Task object. """ - return self._ensureSetNamed('_taskState', '8113', constants.ps.PSETID_TASK, overrideClass = TaskState) + return self._getNamedAs('8113', constants.ps.PSETID_TASK, TaskState) - @property + @functools.cached_property def taskStatus(self) -> Optional[TaskStatus]: """ The completion status of a task. """ - return self._ensureSetNamed('_taskStatus', '8101', constants.ps.PSETID_TASK, overrideClass = TaskStatus) + return self._getNamedAs('8101', constants.ps.PSETID_TASK, TaskStatus) - @property + @functools.cached_property def taskStatusOnComplete(self) -> bool: """ Indicates whether the task assignee has been requested to send an email message upon completion of the assigned task. """ - return self._ensureSetNamed('_taskStatusOnComplete', '8119', constants.ps.PSETID_TASK, overrideClass = bool, preserveNone = False) + return self._getNamedAs('8119', constants.ps.PSETID_TASK, bool, False) - @property + @functools.cached_property def taskUpdates(self) -> bool: """ Indicates whether the task assignee has been requested to send a task update when the assigned Task object changes. """ - return self._ensureSetNamed('_taskUpdates', '811B', constants.ps.PSETID_TASK, overrideClass = bool, preserveNone = False) + return self._getNamedAs('811B', constants.ps.PSETID_TASK, bool, False) - @property + @functools.cached_property def taskVersion(self) -> Optional[int]: """ Indicates which copy is the latest update of a Task object. """ - return self._ensureSetNamed('_taskVersion', '8112', constants.ps.PSETID_TASK) + return self._getNamedAs('8112', constants.ps.PSETID_TASK) - @property + @functools.cached_property def teamTask(self) -> Optional[bool]: """ This value is not used and has no impact on a Task, but is provided for completeness. """ - return self._ensureSetNamed('_teamTask', '8103', constants.ps.PSETID_TASK) + return self._getNamedAs('8103', constants.ps.PSETID_TASK) diff --git a/extract_msg/msg_classes/task_request.py b/extract_msg/msg_classes/task_request.py index dbda75d1..7ef281d7 100644 --- a/extract_msg/msg_classes/task_request.py +++ b/extract_msg/msg_classes/task_request.py @@ -3,6 +3,7 @@ ] +import functools import logging from typing import Optional @@ -53,23 +54,23 @@ def headerFormatProperties(self) -> constants.HEADER_FORMAT_TYPE: # print. So I guess we just return None and handle that. return None - @property + @functools.cached_property def processed(self) -> bool: """ Indicates whether a client has already processed a received task communication. """ - return self._ensureSetProperty('_processed', '7D01000B', overrideClass = bool, preserveNone = False) + return self._getPropertyAs('7D01000B', bool, False) - @property + @functools.cached_property def taskMode(self) -> Optional[TaskMode]: """ The assignment status of the embedded Task object. """ - return self._ensureSetNamed('_taskMode', '8518', constants.ps.PSETID_COMMON, overrideClass = TaskMode) + return self._getNamedAs('8518', constants.ps.PSETID_COMMON, TaskMode) - @property - def taskObject(self) -> Task: + @functools.cached_property + def taskObject(self) -> Optional[Task]: """ The task object embedded in this Task Request object. @@ -79,33 +80,31 @@ def taskObject(self) -> Task: :raises StandardViolationError: A standard was blatently violated in a way that program does not tolerate. """ - try: - return self._taskObject - except AttributeError: - # Get the task object. - # - # The task object MUST be the first attachment, but we will be - # lenient and allow it to be in any position. It not existing, - # however, will not be tolerated. - task = next(((index, att) for index, att in self.attachments if isinstance(att.data, Task)), None) - if task is None: - if self.errorBehavior & ErrorBehavior.STANDARDS_VIOLATION: - logger.error('Task object not found on TaskRequest object.') - return - raise StandardViolationError('Task object not found on TaskRequest object.') - - # We know we have the task, let's make sure it's at index 0. If not, - # log it. - if task[0] != 0: - logger.warning('Embedded task object was not located at index 0.') - - self._taskObject = task[1] - - return self._taskObject + # Get the task object. + # + # The task object MUST be the first attachment, but we will be + # lenient and allow it to be in any position. It not existing, + # however, will not be tolerated. + task = next(((index, att) for index, att in self.attachments if isinstance(att.data, Task)), None) - @property + if task is None: + if ErrorBehavior.STANDARDS_VIOLATION in self.errorBehavior: + logger.error('Task object not found on TaskRequest object.') + return + raise StandardViolationError('Task object not found on TaskRequest object.') + + # We know we have the task, let's make sure it's at index 0. If not, + # log it. + if task[0] != 0: + logger.warning('Embedded task object was not located at index 0.') + + self._taskObject = task[1] + + return self._taskObject + + @functools.cached_property def taskRequestType(self) -> TaskRequestType: """ The type of task request. """ - return self._ensureSet('_taskRequestType', '__substg1.0_001A', TaskRequestType.fromClassType) + return self._ensureSet('__substg1.0_001A', TaskRequestType.fromClassType) diff --git a/extract_msg/recipient.py b/extract_msg/recipient.py index 1ce9be4c..62346109 100644 --- a/extract_msg/recipient.py +++ b/extract_msg/recipient.py @@ -28,7 +28,7 @@ def __init__(self, _dir, msg): self.__msg = makeWeakRef(msg) # Allows calls to original msg file. self.__dir = _dir if not self.exists('__properties_version1.0'): - if msg.errorBehavior & ErrorBehavior.STANDARDS_VIOLATION: + if ErrorBehavior.STANDARDS_VIOLATION in msg.errorBehavior: logger.error('Recipients MUST have a property stream.') else: raise StandardViolationError('Recipients MUST have a property stream.') from None From 934e717533842318a0b3cfebb269eb86d1da3639 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Sun, 2 Jul 2023 00:31:40 -0700 Subject: [PATCH 64/89] Progress on redoing property internals --- CHANGELOG.md | 1 + extract_msg/msg_classes/contact.py | 758 +++++++++---------- extract_msg/msg_classes/meeting_exception.py | 18 +- extract_msg/msg_classes/meeting_forward.py | 10 +- extract_msg/msg_classes/meeting_related.py | 30 +- extract_msg/msg_classes/meeting_request.py | 43 +- extract_msg/msg_classes/task.py | 2 +- 7 files changed, 417 insertions(+), 445 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 408be216..8cd9b472 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -40,6 +40,7 @@ * Changed internal handling of the `prefix` option for `MSGFile.__init__` (and therefore `openMsg`). If you are not setting this manually, you should notice little difference. * Made enums less strict and converted all using `fromBits` to be `IntFlag` enums. * Fixed `CalendarBase.keywords` being blatantly incorrect (it was so bad I don't know how it slipped through). +* Fixed `Contact.gender` being blatantly incorrect. **v0.41.5** * Fixed an issue from version `0.41.3` where the header being present but missing the `From` field would cause an exception. diff --git a/extract_msg/msg_classes/contact.py b/extract_msg/msg_classes/contact.py index 36de3276..e66183d2 100644 --- a/extract_msg/msg_classes/contact.py +++ b/extract_msg/msg_classes/contact.py @@ -25,58 +25,58 @@ class Contact(MessageBase): Class used for parsing contacts. """ - @property + @functools.cached_property def account(self) -> Optional[str]: """ The account name of the contact. """ - return self._ensureSet('_account', '__substg1.0_3A00') + return self._getStringStream('__substg1.0_3A00') - @property - def addressBookProviderArrayType(self) -> Optional[Set[ElectronicAddressProperties]]: + @functools.cached_property + def addressBookProviderArrayType(self) -> Optional[ElectronicAddressProperties]: """ - A set of which Electronic Address properties are set on the contact. + A union of which Electronic Address properties are set on the contact. Property is stored in the MSG file as a sinlge int. The result should be identical to addressBookProviderEmailList. """ - return self._getNamedAs('_addressBookProviderArrayType', '8029', constants.ps.PSETID_ADDRESS, ElectronicAddressProperties.fromBits) + return self._getNamedAs('8029', constants.ps.PSETID_ADDRESS, ElectronicAddressProperties) - @property + @functools.cached_property def addressBookProviderEmailList(self) -> Optional[Set[ElectronicAddressProperties]]: """ A set of which Electronic Address properties are set on the contact. """ - return self._getNamedAs('_addressBookProviderEmailList', '8028', constants.ps.PSETID_ADDRESS, overrideClass = lambda x : {ElectronicAddressProperties(y) for y in x}) + return self._getNamedAs('8028', constants.ps.PSETID_ADDRESS, lambda x : {ElectronicAddressProperties(y) for y in x}) - @property + @functools.cached_property def assistant(self) -> Optional[str]: """ The name of the contact's assistant. """ - return self._ensureSet('_assistant', '__substg1.0_3A30') + return self._getStringStream('__substg1.0_3A30') - @property + @functools.cached_property def assistantTelephoneNumber(self) -> Optional[str]: """ Contains the telephone number of the contact's administrative assistant. """ - return self._ensureSet('_assistantTelephoneNumber', '__substg1.0_3A2E') + return self._getStringStream('__substg1.0_3A2E') - @property + @functools.cached_property def autoLog(self) -> bool: """ Whether the client should create a Journal object for each action associated with the Contact object. """ - return self._getNamedAs('_autoLog', '8025', constants.ps.PSETID_ADDRESS, overrideClass = bool, preserveNone = False) + return self._getNamedAs('8025', constants.ps.PSETID_ADDRESS, bool, False) - @property + @functools.cached_property def billing(self) -> Optional[str]: """ Billing information for the contact. """ - return self._getNamedAs('_billing', '8535', constants.ps.PSETID_COMMON) + return self._getNamedAs('8535', constants.ps.PSETID_COMMON) @functools.cached_property def birthday(self) -> Optional[datetime.datetime]: @@ -85,20 +85,20 @@ def birthday(self) -> Optional[datetime.datetime]: """ return self._getPropertyAs('3A420040') - @property + @functools.cached_property def birthdayEventEntryID(self) -> Optional[EntryID]: """ The EntryID of an optional Appointement object that represents the contact's birtday. """ - return self._getNamedAs('_birthdayEventEntryID', '804D', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) + return self._getNamedAs('804D', constants.ps.PSETID_ADDRESS, EntryID.autoCreate) - @property + @functools.cached_property def birthdayLocal(self) -> Optional[datetime.datetime]: """ The birthday of the contact at 0:00 in the client's local time zone. """ - return self._getNamedAs('_birthdayLocal', '80DE', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80DE', constants.ps.PSETID_ADDRESS) @functools.cached_property def businessCard(self) -> bytes: @@ -130,24 +130,24 @@ def businessCard(self) -> bytes: im.save(out, 'png') return out - @property + @functools.cached_property def businessCardCardPicture(self) -> Optional[bytes]: """ The image to be used on a business card. Must be either a PNG file or a JPEG file. """ - return self._getNamedAs('_businessCardCardPicture', '8041', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8041', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def businessCardDisplayDefinition(self) -> Optional[BusinessCardDisplayDefinition]: """ Specifies the customization details for displaying a contact as a business card. """ - return self._getNamedAs('_businessCardDisplayDefinition', '8040', constants.ps.PSETID_ADDRESS, overrideClass = BusinessCardDisplayDefinition) + return self._getNamedAs('8040', constants.ps.PSETID_ADDRESS, BusinessCardDisplayDefinition) - @property - def businessFax(self) -> Optional[dict]: + @functools.cached_property + def businessFax(self) -> Optional[Dict]: """ Returns a dict of the data for the business fax. Returns None if no fields are set. @@ -155,243 +155,235 @@ def businessFax(self) -> Optional[dict]: Keys are "address_type", "email_address", "number", "original_display_name", and "original_entry_id". """ - try: - return self._businessFax - except AttributeError: - data = { - 'address_type': self.businessFaxAddressType, - 'email_address': self.businessFaxEmailAddress, - 'number': self.businessFaxNumber, - 'original_display_name': self.businessFaxOriginalDisplayName, - 'original_entry_id': self.businessFaxOriginalEntryId, - } - self._businessFax = data if any(data[x] for x in data) else None - return self._businessFax + data = { + 'address_type': self.businessFaxAddressType, + 'email_address': self.businessFaxEmailAddress, + 'number': self.businessFaxNumber, + 'original_display_name': self.businessFaxOriginalDisplayName, + 'original_entry_id': self.businessFaxOriginalEntryId, + } + return data if any(data[x] for x in data) else None - @property + @functools.cached_property def businessFaxAddressType(self) -> Optional[str]: """ The type of address for the fax. MUST be set to "FAX" if present. """ - return self._getNamedAs('_businessFaxAddressType', '80C2', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80C2', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def businessFaxEmailAddress(self) -> Optional[str]: """ Contains a user-readable display name, followed by the "@" character, followed by a fax number. """ - return self._getNamedAs('_businessFaxEmailAddress', '80C3', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80C3', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def businessFaxNumber(self) -> Optional[str]: """ Contains the number of the contact's business fax. """ - return self._ensureSet('_businessFaxNumber', '__substg1.0_3A24') + return self._getStringStream('__substg1.0_3A24') - @property + @functools.cached_property def businessFaxOriginalDisplayName(self) -> Optional[str]: """ The normalized subject for the contact. """ - return self._getNamedAs('_businessFaxOriginalDisplayName', '80C4', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80C4', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def businessFaxOriginalEntryId(self) -> Optional[EntryID]: """ The one-off EntryID corresponding to this fax address. """ - return self._getNamedAs('_businessFaxOriginalEntryId', '80C5', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) + return self._getNamedAs('80C5', constants.ps.PSETID_ADDRESS, EntryID.autoCreate) - @property + @functools.cached_property def businessTelephoneNumber(self) -> Optional[str]: """ Contains the number of the contact's business telephone. """ - return self._ensureSet('_businessTelephoneNumber', '__substg1.0_3A08') + return self._getStringStream('__substg1.0_3A08') - @property + @functools.cached_property def businessTelephone2Number(self) -> Optional[Union[str, List[str]]]: """ Contains the second number or numbers of the contact's business. """ - return self._ensureSetTyped('_businessTelephone2Number', '3A1B') + return self._ensureSetTyped('3A1B') - @property + @functools.cached_property def businessHomePage(self) -> Optional[str]: """ Contains the url of the homepage of the contact's business. """ - return self._ensureSet('_businessHomePage', '__substg1.0_3A51') + return self._getStringStream('__substg1.0_3A51') - @property + @functools.cached_property def callbackTelephoneNumber(self) -> Optional[str]: """ Contains the contact's callback telephone number. """ - return self._ensureSet('_callbackTelephoneNumber', '__substg1.0_3A02') + return self._getStringStream('__substg1.0_3A02') - @property + @functools.cached_property def carTelephoneNumber(self) -> Optional[str]: """ Contains the number of the contact's car telephone. """ - return self._ensureSet('_carTelephoneNumber', '__substg1.0_3A1E') + return self._getStringStream('__substg1.0_3A1E') - @property + @functools.cached_property def childrensNames(self) -> Optional[List[str]]: """ A list of the named of the contact's children. """ - return self._ensureSetTyped('_childrensNames', '3A58') + return self._getStringStream('3A58') - @property + @functools.cached_property def companyMainTelephoneNumber(self) -> Optional[str]: """ Contains the number of the main telephone of the contact's company. """ - return self._ensureSet('_companyMainTelephoneNumber', '__substg1.0_3A57') + return self._getStringStream('__substg1.0_3A57') - @property + @functools.cached_property def companyName(self) -> Optional[str]: """ The name of the company the contact works at. """ - return self._ensureSet('_companyName', '__substg1.0_3A16') + return self._getStringStream('__substg1.0_3A16') - @property + @functools.cached_property def computerNetworkName(self) -> Optional[str]: """ The name of the network to wwhich the contact's computer is connected. """ - return self._ensureSet('_computerNetworkName', '__substg1.0_3A49') + return self._getStringStream('__substg1.0_3A49') - @property + @functools.cached_property def contactCharacterSet(self) -> Optional[int]: """ The character set that is used for this Contact object. """ - return self._getNamedAs('_contactCharacterSet', '8023', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8023', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def contactItemData(self) -> Optional[List[int]]: """ Used to help display the contact information. """ - return self._getNamedAs('_contactItemData', '8007', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8007', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def contactLinkedGlobalAddressListEntryID(self) -> Optional[EntryID]: """ The EntryID of the GAL object to which the duplicate contact is linked. """ - return self._getNamedAs('_contactLinkedGlobalAddressListEntryID', '80E2', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) + return self._getNamedAs('80E2', constants.ps.PSETID_ADDRESS, EntryID.autoCreate) - @property + @functools.cached_property def contactLinkGlobalAddressListLinkID(self) -> Optional[str]: """ The GUID of the GAL contact to which the duplicate contact is linked. """ - return self._getNamedAs('_contactLinkGlobalAddressListLinkId', '80E8', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80E8', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def contactLinkGlobalAddressListLinkState(self) -> Optional[ContactLinkState]: """ The state of linking between the GAL contact and the duplicate contact. """ - return self._getNamedAs('_contactLinkGlobalAddressListLinkState', '80E6', constants.ps.PSETID_ADDRESS, overrideClass = ContactLinkState) + return self._getNamedAs('80E6', constants.ps.PSETID_ADDRESS, ContactLinkState) - @property + @functools.cached_property def contactLinkLinkRejectHistory(self) -> Optional[List[bytes]]: """ A list of any contacts that were previously rejected for linking with the duplicate contact. """ - return self._getNamedAs('_contactLinkLinkRejectHistory', '80E5', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80E5', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def contactLinkSMTPAddressCache(self) -> Optional[List[str]]: """ A list of the SMTP addresses that are used by the GAL contact that are linked to the duplicate contact. """ - return self._getNamedAs('_contactLinkSMTPAddressCache', '80E3', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80E3', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def contactPhoto(self) -> Optional[bytes]: """ The contact photo, if it exists. """ - try: - return self._contactPhoto - except AttributeError: - self._contactPhoto = None - if self.hasPicture: - if len(self.attachments) > 0: - contactPhotoAtt = next((att for att in self.attachments if att.isAttachmentContactPhoto), None) - if contactPhotoAtt: - self._contactPhoto = contactPhotoAtt.data - return self._contactPhoto + if self.hasPicture: + if len(self.attachments) > 0: + contactPhotoAtt = next((att for att in self.attachments if att.isAttachmentContactPhoto), None) + if contactPhotoAtt: + return contactPhotoAtt.data + return None - @property + @functools.cached_property def contactUserField1(self) -> Optional[str]: """ Used to store custom text for a business card. """ - return self._getNamedAs('_contactUserField1', '804F', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('804F', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def contactUserField2(self) -> Optional[str]: """ Used to store custom text for a business card. """ - return self._getNamedAs('_contactUserField2', '8050', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8050', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def contactUserField3(self) -> Optional[str]: """ Used to store custom text for a business card. """ - return self._getNamedAs('_contactUserField3', '8051', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8051', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def contactUserField4(self) -> Optional[str]: """ Used to store custom text for a business card. """ - return self._getNamedAs('_contactUserField4', '8052', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8052', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def customerID(self) -> Optional[str]: """ The contact's customer ID number. """ - return self._ensureSet('_customerID', '__substg1.0_3A4A') + return self._getStringStream('__substg1.0_3A4A') - @property + @functools.cached_property def departmentName(self) -> Optional[str]: """ The name of the department the contact works in. """ - return self._ensureSet('_departmentName', '__substg1.0_3A18') + return self._getStringStream('__substg1.0_3A18') - @property + @functools.cached_property def displayName(self) -> Optional[str]: """ The full name of the contact. """ - return self._ensureSet('_displayName', '__substg1.0_3001') + return self._getStringStream('__substg1.0_3001') - @property + @functools.cached_property def displayNamePrefix(self) -> Optional[str]: """ The contact's honorific title. """ - return self._ensureSet('_displayNamePrefix', '__substg1.0_3A45') + return self._getStringStream('__substg1.0_3A45') - @property - def email1(self) -> Optional[dict]: + @functools.cached_property + def email1(self) -> Optional[Dict]: """ Returns a dict of the data for email 1. Returns None if no fields are set. @@ -399,260 +391,242 @@ def email1(self) -> Optional[dict]: Keys are "address_type", "display_name", "email_address", "original_display_name", and "original_entry_id". """ - try: - return self._email1 - except AttributeError: - data = { - 'address_type': self.email1AddressType, - 'display_name': self.email1DisplayName, - 'email_address': self.email1EmailAddress, - 'original_display_name': self.email1OriginalDisplayName, - 'original_entry_id': self.email1OriginalEntryId, - } - self._email1 = data if any(data[x] for x in data) else None - return self._email1 + data = { + 'address_type': self.email1AddressType, + 'display_name': self.email1DisplayName, + 'email_address': self.email1EmailAddress, + 'original_display_name': self.email1OriginalDisplayName, + 'original_entry_id': self.email1OriginalEntryId, + } + return data if any(data[x] for x in data) else None - @property + @functools.cached_property def email1AddressType(self) -> Optional[str]: """ The address type of the first email address. """ - return self._getNamedAs('_email1AddressType', '8082', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8082', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def email1DisplayName(self) -> Optional[str]: """ The user-readable display name of the first email address. """ - return self._getNamedAs('_email1DisplayName', '8080', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8080', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def email1EmailAddress(self) -> Optional[str]: """ The first email address. """ - return self._getNamedAs('_email1EmailAddress', '8083', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8083', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def email1OriginalDisplayName(self) -> Optional[str]: """ The first SMTP email address that corresponds to the first email address for the contact. """ - return self._getNamedAs('_email1OriginalDisplayName', '8084', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8084', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def email1OriginalEntryId(self) -> Optional[EntryID]: """ The EntryID of the object correspinding to this electronic address. """ - return self._getNamedAs('_email1OriginalEntryId', '8085', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) + return self._getNamedAs('8085', constants.ps.PSETID_ADDRESS, EntryID.autoCreate) - @property + @functools.cached_property def email2(self) -> Optional[dict]: """ Returns a dict of the data for email 2. Returns None if no fields are set. """ - try: - return self._email2 - except AttributeError: - data = { - 'address_type': self.email2AddressType, - 'display_name': self.email2DisplayName, - 'email_address': self.email2EmailAddress, - 'original_display_name': self.email2OriginalDisplayName, - 'original_entry_id': self.email2OriginalEntryId, - } - self._email2 = data if any(data[x] for x in data) else None - return self._email2 + data = { + 'address_type': self.email2AddressType, + 'display_name': self.email2DisplayName, + 'email_address': self.email2EmailAddress, + 'original_display_name': self.email2OriginalDisplayName, + 'original_entry_id': self.email2OriginalEntryId, + } + return data if any(data[x] for x in data) else None - @property + @functools.cached_property def email2AddressType(self) -> Optional[str]: """ The address type of the second email address. """ - return self._getNamedAs('_email2AddressType', '8092', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8092', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def email2DisplayName(self) -> Optional[str]: """ The user-readable display name of the second email address. """ - return self._getNamedAs('_email2DisplayName', '8090', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8090', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def email2EmailAddress(self) -> Optional[str]: """ The second email address. """ - return self._getNamedAs('_email2EmailAddress', '8093', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8093', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def email2OriginalDisplayName(self) -> Optional[str]: """ The second SMTP email address that corresponds to the second email address for the contact. """ - return self._getNamedAs('_email2OriginalDisplayName', '8094', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8094', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def email2OriginalEntryId(self) -> Optional[EntryID]: """ The EntryID of the object correspinding to this electronic address. """ return self._getNamedAs('_email2OriginalEntryId', '8095', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) - @property + @functools.cached_property def email3(self) -> Optional[dict]: """ Returns a dict of the data for email 3. Returns None if no fields are set. """ - try: - return self._email3 - except AttributeError: - data = { - 'address_type': self.email3AddressType, - 'display_name': self.email3DisplayName, - 'email_address': self.email3EmailAddress, - 'original_display_name': self.email3OriginalDisplayName, - 'original_entry_id': self.email3OriginalEntryId, - } - self._email3 = data if any(data[x] for x in data) else None - return self._email3 + data = { + 'address_type': self.email3AddressType, + 'display_name': self.email3DisplayName, + 'email_address': self.email3EmailAddress, + 'original_display_name': self.email3OriginalDisplayName, + 'original_entry_id': self.email3OriginalEntryId, + } + return data if any(data[x] for x in data) else None - @property + @functools.cached_property def email3AddressType(self) -> Optional[str]: """ The address type of the third email address. """ - return self._getNamedAs('_email3AddressType', '80A2', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80A2', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def email3DisplayName(self) -> Optional[str]: """ The user-readable display name of the third email address. """ - return self._getNamedAs('_email3DisplayName', '80A0', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80A0', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def email3EmailAddress(self) -> Optional[str]: """ The third email address. """ - return self._getNamedAs('_email3EmailAddress', '80A3', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80A3', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def email3OriginalDisplayName(self) -> Optional[str]: """ The third SMTP email address that corresponds to the third email address for the contact. """ - return self._getNamedAs('_email3OriginalDisplayName', '80A4', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80A4', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def email3OriginalEntryId(self) -> Optional[EntryID]: """ The EntryID of the object correspinding to this electronic address. """ - return self._getNamedAs('_email3OriginalEntryId', '80A5', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) + return self._getNamedAs('80A5', constants.ps.PSETID_ADDRESS, EntryID.autoCreate) - @property + @functools.cached_property def emails(self) -> Tuple[Union[Dict, None], Union[Dict, None], Union[Dict, None]]: """ Returns a tuple of all the email dicts. Value for an email will be None if no fields were set. """ - try: - return self._emails - except AttributeError: - self._emails = (self.email1, self.email2, self.email3) - return self._emails + return (self.email1, self.email2, self.email3) - @property - def faxNumbers(self) -> Optional[dict]: + @functools.cached_property + def faxNumbers(self) -> Optional[Dict]: """ Returns a dictionary of the fax numbers. Entry will be None if no fields were set. Keys are "business", "home", and "primary". """ - try: - return self._faxNumbers - except AttributeError: - self._faxNumbers = { - 'business': self.businessFax, - 'home': self.homeFax, - 'primary': self.primaryFax, - } + return { + 'business': self.businessFax, + 'home': self.homeFax, + 'primary': self.primaryFax, + } - @property + + @functools.cached_property def fileUnder(self) -> Optional[str]: """ The name under which to file a contact when displaying a list of contacts. """ - return self._getNamedAs('_fileUnder', '8005', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8005', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def fileUnderID(self) -> Optional[int]: """ The format to use for fileUnder. See PidLidFileUnderId in [MS-OXOCNTC] for details. """ - return self._getNamedAs('_fileUnderID', '8006', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8006', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def freeBusyLocation(self) -> Optional[str]: """ A URL path from which a client can retrieve free/busy status information for the contact as an iCalendat file. """ - return self._getNamedAs('_freeBusyLocation', '80D8', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80D8', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def ftpSite(self) -> Optional[str]: """ The contact's File Transfer Protocol url. """ - return self._ensureSet('_ftpSite', '__substg1.0_3A4C') + return self._getStringStream('__substg1.0_3A4C') - @property + @functools.cached_property def gender(self) -> Optional[Gender]: """ The gender of the contact. """ - return self._ensureSet('_gender', '__substg1.0_3A4D', overrideClass = Gender) + return self._getPropertyAs('3A4D0002', lambda x : Gender(x or 0), False) - @property + @functools.cached_property def generation(self) -> Optional[str]: """ A generational abbreviation that follows the full name of the contact. """ - return self._ensureSet('_generation', '__substg1.0_3A05') + return self._getStringStream('__substg1.0_3A05') - @property + @functools.cached_property def givenName(self) -> Optional[str]: """ The first name of the contact. """ - return self._ensureSet('_givenName', '__substg1.0_3A06') + return self._getStringStream('__substg1.0_3A06') - @property + @functools.cached_property def governmentIDNumber(self) -> Optional[str]: """ The contact's government ID number. """ - return self._ensureSet('_governmentIDNumber', '__substg1.0_3A07') + return self._getStringStream('__substg1.0_3A07') - @property + @functools.cached_property def hasPicture(self) -> bool: """ Whether the contact has a contact photo. """ - return self._getNamedAs('_hasPicture', '8015', constants.ps.PSETID_ADDRESS, overrideClass = bool, preserveNone = False) + return self._getNamedAs('8015', constants.ps.PSETID_ADDRESS, bool, False) @property def headerFormatProperties(self) -> constants.HEADER_FORMAT_TYPE: @@ -746,71 +720,71 @@ def strListToStr(inp : Optional[Union[str, List[str]]]): }, } - @property + @functools.cached_property def hobbies(self) -> Optional[str]: """ The hobies of the contact. """ - return self._ensureSet('_hobbies', '__substg1.0_3A43') + return self._getStringStream('__substg1.0_3A43') - @property + @functools.cached_property def homeAddress(self) -> Optional[str]: """ The complete home address of the contact. """ - return self._getNamedAs('_homeAddress', '801A', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('801A', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def homeAddressCountry(self) -> Optional[str]: """ The country portion of the contact's home address. """ - return self._ensureSet('_homeAddressCountry', '__substg1.0_3A5A') + return self._getStringStream('__substg1.0_3A5A') - @property + @functools.cached_property def homeAddressCountryCode(self) -> Optional[str]: """ The country code portion of the contact's home address. """ - return self._getNamedAs('_homeAddressCountryCode', '80DA', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80DA', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def homeAddressLocality(self) -> Optional[str]: """ The locality or city portion of the contact's home address. """ - return self._ensureSet('_homeAddressLocality', '__substg1.0_3A59') + return self._getStringStream('__substg1.0_3A59') - @property + @functools.cached_property def homeAddressPostalCode(self) -> Optional[str]: """ The postal code portion of the contact's home address. """ - return self._ensureSet('_homeAddressPostalCode', '__substg1.0_3A5B') + return self._getStringStream('__substg1.0_3A5B') - @property + @functools.cached_property def homeAddressPostOfficeBox(self) -> Optional[str]: """ The number or identifier of the contact's home post office box. """ - return self._ensureSet('_homeAddressPostOfficeBox', '__substg1.0_3A5E') + return self._getStringStream('__substg1.0_3A5E') - @property + @functools.cached_property def homeAddressStateOrProvince(self) -> Optional[str]: """ The state or province portion of the contact's home address. """ - return self._ensureSet('_homeAddressStateOrProvince', '__substg1.0_3A5C') + return self._getStringStream('__substg1.0_3A5C') - @property + @functools.cached_property def homeAddressStreet(self) -> Optional[str]: """ The street portion of the contact's home address. """ - return self._ensureSet('_homeAddressStreet', '__substg1.0_3A5D') + return self._getStringStream('__substg1.0_3A5D') - @property - def homeFax(self) -> Optional[dict]: + @functools.cached_property + def homeFax(self) -> Optional[Dict]: """ Returns a dict of the data for the home fax. Returns None if no fields are set. @@ -818,225 +792,221 @@ def homeFax(self) -> Optional[dict]: Keys are "address_type", "email_address", "number", "original_display_name", and "original_entry_id". """ - try: - return self._homeFax - except AttributeError: - data = { - 'address_type': self.homeFaxAddressType, - 'email_address': self.homeFaxEmailAddress, - 'number': self.homeFaxNumber, - 'original_display_name': self.homeFaxOriginalDisplayName, - 'original_entry_id': self.homeFaxOriginalEntryId, - } - self._homeFax = data if any(data[x] for x in data) else None - return self._homeFax + data = { + 'address_type': self.homeFaxAddressType, + 'email_address': self.homeFaxEmailAddress, + 'number': self.homeFaxNumber, + 'original_display_name': self.homeFaxOriginalDisplayName, + 'original_entry_id': self.homeFaxOriginalEntryId, + } + return data if any(data[x] for x in data) else None - @property + @functools.cached_property def homeFaxAddressType(self) -> Optional[str]: """ The type of address for the fax. MUST be set to "FAX" if present. """ - return self._getNamedAs('_homeFaxAddressType', '80D2', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80D2', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def homeFaxEmailAddress(self) -> Optional[str]: """ Contains a user-readable display name, followed by the "@" character, followed by a fax number. """ - return self._getNamedAs('_homeFaxEmailAddress', '80D3', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80D3', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def homeFaxNumber(self) -> Optional[str]: """ Contains the number of the contact's home fax. """ - return self._ensureSet('_homeFaxNumber', '__substg1.0_3A25') + return self._getStringStream('__substg1.0_3A25') - @property + @functools.cached_property def homeFaxOriginalDisplayName(self) -> Optional[str]: """ The normalized subject for the contact. """ - return self._getNamedAs('_homeFaxOriginalDisplayName', '80D4', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80D4', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def homeFaxOriginalEntryId(self) -> Optional[EntryID]: """ The one-off EntryID corresponding to this fax address. """ - return self._getNamedAs('_homeFaxOriginalEntryId', '80D5', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) + return self._getNamedAs('80D5', constants.ps.PSETID_ADDRESS, EntryID.autoCreate) - @property + @functools.cached_property def homeTelephoneNumber(self) -> Optional[str]: """ The number of the contact's home telephone. """ - return self._ensureSet('_homeTelephoneNumber', '__substg1.0_3A09') + return self._getStringStream('__substg1.0_3A09') - @property + @functools.cached_property def homeTelephone2Number(self) -> Optional[Union[str, List[str]]]: """ The number(s) of the contact's second home telephone. """ - return self._ensureSetTyped('_homeTelephone2Number', '3A2F') + return self._ensureSetTyped('3A2F') - @property + @functools.cached_property def initials(self) -> Optional[str]: """ The initials of the contact. """ - return self._ensureSet('_initials', '__substg1.0_3A0A') + return self._getStringStream('__substg1.0_3A0A') - @property + @functools.cached_property def instantMessagingAddress(self) -> Optional[str]: """ The instant messaging address of the contact. """ - return self._getNamedAs('_instantMessagingAddress', '8062', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8062', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def isContactLinked(self) -> bool: """ Whether the contact is linked to other contacts. """ - return self._getNamedAs('_isContactLinked', '80E0', constants.ps.PSETID_ADDRESS, overrideClass = bool, preserveNone = False) + return self._getNamedAs('80E0', constants.ps.PSETID_ADDRESS, bool, False) - @property + @functools.cached_property def isdnNumber(self) -> Optional[str]: """ The Integrated Services Digital Network (ISDN) telephone number of the contact. """ - return self._ensureSet('_isdnNumber', '__substg1.0_3A2D') + return self._getStringStream('__substg1.0_3A2D') - @property + @functools.cached_property def jobTitle(self) -> Optional[str]: """ The job title of the contact. """ - return self._ensureSet('_jobTitle', '__substg1.0_3A17') + return self._getStringStream('__substg1.0_3A17') - @property + @functools.cached_property def language(self) -> Optional[str]: """ The language that the contact uses. """ - return self._ensureSet('_language', '__substg1.0_3A0C') + return self._getStringStream('__substg1.0_3A0C') - @property + @functools.cached_property def lastModifiedBy(self) -> Optional[str]: """ The name of the last user to modify the contact file. """ - return self._ensureSet('_lastModifiedBy', '__substg1.0_3FFA') + return self._getStringStream('__substg1.0_3FFA') - @property + @functools.cached_property def location(self) -> Optional[str]: """ The location of the contact. For example, this could be the building or office number of the contact. """ - return self._ensureSet('_location', '__substg1.0_3A0D') + return self._getStringStream('__substg1.0_3A0D') - @property + @functools.cached_property def mailAddress(self) -> Optional[str]: """ The complete mail address of the contact. """ - return self._ensureSet('_mailAddress', '__substg1.0_3A15') + return self._getStringStream('__substg1.0_3A15') - @property + @functools.cached_property def mailAddressCountry(self) -> Optional[str]: """ The country portion of the contact's mail address. """ - return self._ensureSet('_mailAddressCountry', '__substg1.0_3A26') + return self._getStringStream('__substg1.0_3A26') - @property + @functools.cached_property def mailAddressCountryCode(self) -> Optional[str]: """ The country code portion of the contact's mail address. """ - return self._getNamedAs('_mailAddressCountryCode', '80DD', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80DD', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def mailAddressLocality(self) -> Optional[str]: """ The locality or city portion of the contact's mail address. """ - return self._ensureSet('_mailAddressLocality', '__substg1.0_3A27') + return self._getStringStream('__substg1.0_3A27') - @property + @functools.cached_property def mailAddressPostalCode(self) -> Optional[str]: """ The postal code portion of the contact's mail address. """ - return self._ensureSet('_mailAddressPostalCode', '__substg1.0_3A2A') + return self._getStringStream('__substg1.0_3A2A') - @property + @functools.cached_property def mailAddressPostOfficeBox(self) -> Optional[str]: """ The number or identifier of the contact's mail post office box. """ - return self._ensureSet('_mailAddressPostOfficeBox', '__substg1.0_3A2B') + return self._getStringStream('__substg1.0_3A2B') - @property + @functools.cached_property def mailAddressStateOrProvince(self) -> Optional[str]: """ The state or province portion of the contact's mail address. """ - return self._ensureSet('_mailAddressStateOrProvince', '__substg1.0_3A28') + return self._getStringStream('__substg1.0_3A28') - @property + @functools.cached_property def mailAddressStreet(self) -> Optional[str]: """ The street portion of the contact's mail address. """ - return self._ensureSet('_mailAddressStreet', '__substg1.0_3A29') + return self._getStringStream('__substg1.0_3A29') - @property + @functools.cached_property def managerName(self) -> Optional[str]: """ The name of the contact's manager. """ - return self._ensureSet('_managerName', '__substg1.0_3A4E') + return self._getStringStream('__substg1.0_3A4E') - @property + @functools.cached_property def middleName(self) -> Optional[str]: """ The middle name(s) of the contact. """ - return self._ensureSet('_middleNames', '__substg1.0_3A44') + return self._getStringStream('__substg1.0_3A44') - @property + @functools.cached_property def mobileTelephoneNumber(self) -> Optional[str]: """ The mobile telephone number of the contact. """ - return self._ensureSet('_mobileTelephoneNumber', '__substg1.0_3A1C') + return self._getStringStream('__substg1.0_3A1C') - @property + @functools.cached_property def nickname(self) -> Optional[str]: """ The nickname of the contanct. """ - return self._ensureSet('_nickname', '__substg1.0_3A4F') + return self._getStringStream('__substg1.0_3A4F') - @property + @functools.cached_property def officeLocation(self) -> Optional[str]: """ The location of the office that the contact works in. """ - return self._ensureSet('_officeLocation', '__substg1.0_3A19') + return self._getStringStream('__substg1.0_3A19') - @property + @functools.cached_property def organizationalIDNumber(self) -> Optional[str]: """ The organizational ID number for the contact, such as an employee ID number. """ - return self._ensureSet('_organizationalIdNumber', '__substg1.0_3A10') + return self._getStringStream('__substg1.0_3A10') @functools.cached_property def oscSyncEnabled(self) -> bool: @@ -1044,115 +1014,115 @@ def oscSyncEnabled(self) -> bool: Whether contact synchronization with an external source (such as a social networking site) is handled by the server. """ - return self._getPropertyAs('7C24000B', overrideClass = bool, preserveNone = False) + return self._getPropertyAs('7C24000B', bool, False) - @property + @functools.cached_property def otherAddress(self) -> Optional[str]: """ The complete other address of the contact. """ - return self._getNamedAs('_otherAddress', '801C', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('801C', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def otherAddressCountry(self) -> Optional[str]: """ The country portion of the contact's other address. """ - return self._ensureSet('_otherAddressCountry', '__substg1.0_3A60') + return self._getStringStream('__substg1.0_3A60') - @property + @functools.cached_property def otherAddressCountryCode(self) -> Optional[str]: """ The country code portion of the contact's other address. """ - return self._getNamedAs('_otherAddressCountryCode', '80DC', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80DC', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def otherAddressLocality(self) -> Optional[str]: """ The locality or city portion of the contact's other address. """ - return self._ensureSet('_otherAddressLocality', '__substg1.0_3A5F') + return self._getStringStream('__substg1.0_3A5F') - @property + @functools.cached_property def otherAddressPostalCode(self) -> Optional[str]: """ The postal code portion of the contact's other address. """ - return self._ensureSet('_otherAddressPostalCode', '__substg1.0_3A61') + return self._getStringStream('__substg1.0_3A61') - @property + @functools.cached_property def otherAddressPostOfficeBox(self) -> Optional[str]: """ The number or identifier of the contact's other post office box. """ - return self._ensureSet('_otherAddressPostOfficeBox', '__substg1.0_3A64') + return self._getStringStream('__substg1.0_3A64') - @property + @functools.cached_property def otherAddressStateOrProvince(self) -> Optional[str]: """ The state or province portion of the contact's other address. """ - return self._ensureSet('_otherAddressStateOrProvince', '__substg1.0_3A62') + return self._getStringStream('__substg1.0_3A62') - @property + @functools.cached_property def otherAddressStreet(self) -> Optional[str]: """ The street portion of the contact's other address. """ - return self._ensureSet('_otherAddressStreet', '__substg1.0_3A63') + return self._getStringStream('__substg1.0_3A63') - @property + @functools.cached_property def otherTelephoneNumber(self) -> Optional[str]: """ Contains the number of the contact's other telephone. """ - return self._ensureSet('_otherTelephoneNumber', '__substg1.0_3A1F') + return self._getStringStream('__substg1.0_3A1F') - @property + @functools.cached_property def pagerTelephoneNumber(self) -> Optional[str]: """ The contact's pager telephone number. """ - return self._ensureSet('_pagerTelephoneNumber', '__substg1.0_3A21') + return self._getStringStream('__substg1.0_3A21') - @property + @functools.cached_property def personalHomePage(self) -> Optional[str]: """ The contact's personal web page UL. """ - return self._ensureSet('_personalHomePage', '__substg1.0_3A50') + return self._getStringStream('__substg1.0_3A50') - @property + @functools.cached_property def phoneticCompanyName(self) -> Optional[str]: """ The phonetic pronunciation of the contact's company name. """ - return self._getNamedAs('_phoneticCompanyName', '802E', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('802E', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def phoneticGivenName(self) -> Optional[str]: """ The phonetic pronunciation of the contact's given name. """ - return self._getNamedAs('_phoneticGivenName', '802C', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('802C', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def phoneticSurname(self) -> Optional[str]: """ The phonetic pronunciation of the given name of the contact. """ - return self._getNamedAs('_phoneticSurname', '802D', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('802D', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def postalAddressID(self) -> PostalAddressID: """ Indicates which physical address is the Mailing Address for this contact. """ - return self._getNamedAs('_postalAddressID', '8022', constants.ps.PSETID_ADDRESS, overrideClass = lambda x : PostalAddressID(x or 0), preserveNone = False) + return self._getNamedAs('8022', constants.ps.PSETID_ADDRESS, lambda x : PostalAddressID(x or 0), False) - @property + @functools.cached_property def primaryFax(self) -> Optional[dict]: """ Returns a dict of the data for the primary fax. Returns None if no @@ -1161,127 +1131,123 @@ def primaryFax(self) -> Optional[dict]: Keys are "address_type", "email_address", "number", "original_display_name", and "original_entry_id". """ - try: - return self._primaryFax - except AttributeError: - data = { - 'address_type': self.primaryFaxAddressType, - 'email_address': self.primaryFaxEmailAddress, - 'number': self.primaryFaxNumber, - 'original_display_name': self.primaryFaxOriginalDisplayName, - 'original_entry_id': self.primaryFaxOriginalEntryId, - } - self._primaryFax = data if any(data[x] for x in data) else None - return self._primaryFax + data = { + 'address_type': self.primaryFaxAddressType, + 'email_address': self.primaryFaxEmailAddress, + 'number': self.primaryFaxNumber, + 'original_display_name': self.primaryFaxOriginalDisplayName, + 'original_entry_id': self.primaryFaxOriginalEntryId, + } + return data if any(data[x] for x in data) else None - @property + @functools.cached_property def primaryFaxAddressType(self) -> Optional[str]: """ The type of address for the fax. MUST be set to "FAX" if present. """ - return self._getNamedAs('_primaryFaxAddressType', '80B2', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80B2', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def primaryFaxEmailAddress(self) -> Optional[str]: """ Contains a user-readable display name, followed by the "@" character, followed by a fax number. """ - return self._getNamedAs('_primaryFaxEmailAddress', '80B3', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80B3', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def primaryFaxNumber(self) -> Optional[str]: """ Contains the number of the contact's primary fax. """ - return self._ensureSet('_primaryFaxNumber', '__substg1.0_3A23') + return self._getStringStream('__substg1.0_3A23') - @property + @functools.cached_property def primaryFaxOriginalDisplayName(self) -> Optional[str]: """ The normalized subject for the contact. """ - return self._getNamedAs('_primaryFaxOriginalDisplayName', '80B4', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80B4', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def primaryFaxOriginalEntryId(self) -> Optional[EntryID]: """ The one-off EntryID corresponding to this fax address. """ - return self._getNamedAs('_primaryFaxOriginalEntryId', '80B5', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) + return self._getNamedAs('80B5', constants.ps.PSETID_ADDRESS, EntryID.autoCreate) - @property + @functools.cached_property def primaryTelephoneNumber(self) -> Optional[str]: """ Contains the number of the contact's primary telephone. """ - return self._ensureSet('_primaryTelephoneNumber', '__substg1.0_3A1A') + return self._getStringStream('__substg1.0_3A1A') - @property + @functools.cached_property def profession(self) -> Optional[str]: """ The profession of the contact. """ - return self._ensureSet('_profession', '__substg1.0_3A46') + return self._getStringStream('__substg1.0_3A46') - @property + @functools.cached_property def radioTelephoneNumber(self) -> Optional[str]: """ Contains the number of the contact's radio telephone. """ - return self._ensureSet('_radioTelephoneNumber', '__substg1.0_3A1D') + return self._getStringStream('__substg1.0_3A1D') - @property + @functools.cached_property def referenceEntryID(self) -> Optional[EntryID]: """ Contains a value that is equal to the value of the EntryID of the Contact object unless the Contact object is a copy of an earlier original. """ - return self._getNamedAs('_referenceEntryID', '85BD', constants.ps.PSETID_COMMON, overrideClass = EntryID.autoCreate) + return self._getNamedAs('85BD', constants.ps.PSETID_COMMON, EntryID.autoCreate) - @property + @functools.cached_property def referredByName(self) -> Optional[str]: """ The name of the person who referred this contact to the user. """ - return self._ensureSet('_referredByName', '__substg1.0_3A47') + return self._getStringStream('__substg1.0_3A47') - @property + @functools.cached_property def spouseName(self) -> Optional[str]: """ The name of the contact's spouse. """ - return self._ensureSet('_spouseName', '__substg1.0_3A48') + return self._getStringStream('__substg1.0_3A48') - @property + @functools.cached_property def surname(self) -> Optional[str]: """ The surname of the contact. """ - return self._ensureSet('_surname', '__substg1.0_3A11') + return self._getStringStream('__substg1.0_3A11') - @property + @functools.cached_property def tddTelephoneNumber(self) -> Optional[str]: """ The telephone number for the contact's text telephone (TTY) or telecommunication device for the deaf (TDD). """ - return self._ensureSet('_tddTelephoneNumber', '__substg1.0_3A4B') + return self._getStringStream('__substg1.0_3A4B') - @property + @functools.cached_property def telexNumber(self) -> Optional[Union[str, List[str]]]: """ The contact's telex number(s). """ - return self._ensureSetTyped('_telexNumber', '3A2C') + return self._ensureSetTyped('3A2C') - @property + @functools.cached_property def userX509Certificate(self) -> Optional[List[bytes]]: """ A list of certificates for the contact. """ - return self._ensureSetTyped('_userX509Certificate', '3A70') + return self._ensureSetTyped('3A70') @functools.cached_property def weddingAnniversary(self) -> Optional[datetime.datetime]: @@ -1290,81 +1256,81 @@ def weddingAnniversary(self) -> Optional[datetime.datetime]: """ return self._getPropertyAs('3A410040') - @property + @functools.cached_property def weddingAnniversaryEventEntryID(self) -> Optional[EntryID]: """ The EntryID of an optional Appointement object that represents the contact's wedding anniversary. """ - return self._getNamedAs('_weddingAnniversaryEventEntryID', '804E', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) + return self._getNamedAs('804E', constants.ps.PSETID_ADDRESS, EntryID.autoCreate) - @property + @functools.cached_property def weddingAnniversaryLocal(self) -> Optional[datetime.datetime]: """ The wedding anniversary of the contact at 0:00 in the client's local time zone. """ - return self._getNamedAs('_weddingAnniversaryLocal', '80DF', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80DF', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def webpageUrl(self) -> Optional[str]: """ The contact's business web page url. SHOULD be the same as businessUrl. """ - return self._getNamedAs('_webpageUrl', '802B', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('802B', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def workAddress(self) -> Optional[str]: """ The complete work address of the contact. """ - return self._getNamedAs('_workAddress', '801B', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('801B', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def workAddressCountry(self) -> Optional[str]: """ The country portion of the contact's work address. """ - return self._getNamedAs('_workAddressCountry', '8049', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8049', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def workAddressCountryCode(self) -> Optional[str]: """ The country code portion of the contact's work address. """ - return self._getNamedAs('_workAddressCountryCode', '80DB', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80DB', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def workAddressLocality(self) -> Optional[str]: """ The locality or city portion of the contact's work address. """ - return self._getNamedAs('_workAddressLocality', '8046', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8046', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def workAddressPostalCode(self) -> Optional[str]: """ The postal code portion of the contact's work address. """ - return self._getNamedAs('_workAddressPostalCode', '8048', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8048', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def workAddressPostOfficeBox(self) -> Optional[str]: """ The number or identifier of the contact's work post office box. """ - return self._getNamedAs('_workAddressPostOfficeBox', '804A', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('804A', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def workAddressStateOrProvince(self) -> Optional[str]: """ The state or province portion of the contact's work address. """ - return self._getNamedAs('_workAddressStateOrProvince', '8047', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8047', constants.ps.PSETID_ADDRESS) - @property + @functools.cached_property def workAddressStreet(self) -> Optional[str]: """ The street portion of the contact's work address. """ - return self._getNamedAs('_workAddressStreet', '8045', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8045', constants.ps.PSETID_ADDRESS) diff --git a/extract_msg/msg_classes/meeting_exception.py b/extract_msg/msg_classes/meeting_exception.py index a9a29894..3748be0c 100644 --- a/extract_msg/msg_classes/meeting_exception.py +++ b/extract_msg/msg_classes/meeting_exception.py @@ -4,10 +4,12 @@ import datetime +import functools from typing import Optional from .. import constants +from ..enums import SaveType from .meeting_related import MeetingRelated @@ -16,7 +18,7 @@ class MeetingException(MeetingRelated): Class for handling Meeting Exceptions. """ - def save(self, *args, **kwargs): + def save(self, **_) -> constants.SAVE_TYPE: """ Meeting Exceptions are hidden attachments with no save behaviors. As such, for saving we literally just return the object and do nothing @@ -25,28 +27,28 @@ def save(self, *args, **kwargs): If you want something to happen for saving, you can call the save of a parent class or write your own code. """ - return self + return (SaveType.NONE, None) - @property + @functools.cached_property def exceptionReplaceTime(self) -> Optional[datetime.datetime]: """ The date and time within the recurrence pattern that the exception will replace. The value is specified in UTC. """ - return self._getNamedAs('_exceptionReplaceTime', '8228', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8228', constants.ps.PSETID_APPOINTMENT) - @property + @functools.cached_property def fExceptionalBody(self) -> bool: """ Indicates that the Exception Embedded Message object has a body that differs from the Recurring Calendar object. If True, the Exception MUST have a body. """ - return self._getNamedAs('_fExceptionalBody', '8206', constants.ps.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) + return self._getNamedAs('8206', constants.ps.PSETID_APPOINTMENT, bool, False) - @property + @functools.cached_property def fInvited(self) -> bool: """ Indicates if invitations have been sent for this exception. """ - return self._getNamedAs('_fInvited', '8229', constants.ps.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) + return self._getNamedAs('8229', constants.ps.PSETID_APPOINTMENT, bool, False) diff --git a/extract_msg/msg_classes/meeting_forward.py b/extract_msg/msg_classes/meeting_forward.py index 2ca8a002..a4d0625f 100644 --- a/extract_msg/msg_classes/meeting_forward.py +++ b/extract_msg/msg_classes/meeting_forward.py @@ -3,6 +3,8 @@ ] +import functools + from typing import Optional from .. import constants @@ -15,7 +17,7 @@ class MeetingForwardNotification(MeetingRelated): Class for handling Meeting Forward Notification objects. """ - @property + @functools.cached_property def forwardNotificationRecipients(self) -> Optional[bytes]: """ Bytes containing a list of RecipientRow structures that indicate the @@ -24,7 +26,7 @@ def forwardNotificationRecipients(self) -> Optional[bytes]: Incomplete, looks to be the same structure as appointmentUnsendableRecipients, so we need more examples of this. """ - return self._getNamedAs('_forwardNotificationRecipients', '8261', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8261', constants.ps.PSETID_APPOINTMENT) @property def headerFormatProperties(self) -> constants.HEADER_FORMAT_TYPE: @@ -88,10 +90,10 @@ def headerFormatProperties(self) -> constants.HEADER_FORMAT_TYPE: }, } - @property + @functools.cached_property def promptSendUpdate(self) -> bool: """ Indicates that the Meeting Forward Notification object was out-of-date when it was received. """ - return self._getNamedAs('_promptSendUpdate', '8045', constants.ps.PSETID_COMMON, overrideClass = bool, preserveNone = False) + return self._getNamedAs('8045', constants.ps.PSETID_COMMON, bool, False) diff --git a/extract_msg/msg_classes/meeting_related.py b/extract_msg/msg_classes/meeting_related.py index 9004ec8f..7782a10c 100644 --- a/extract_msg/msg_classes/meeting_related.py +++ b/extract_msg/msg_classes/meeting_related.py @@ -6,7 +6,7 @@ import datetime import functools -from typing import Optional, Set +from typing import Optional from .. import constants from .calendar_base import CalendarBase @@ -18,48 +18,48 @@ class MeetingRelated(CalendarBase): Base class for meeting-related objects. """ - @property + @functools.cached_property def attendeeCriticalChange(self) -> Optional[datetime.datetime]: """ The date and time at which the meeting-related object was sent. """ - return self._getNamedAs('_attendeeCriticalChange', '0001', constants.ps.PSETID_MEETING) + return self._getNamedAs('0001', constants.ps.PSETID_MEETING) @functools.cached_property def processed(self) -> bool: """ Indicates whether a client has processed a meeting-related object. """ - return self._getPropertyAs('7D01000B', overrideClass = bool, preserveNone = False) + return self._getPropertyAs('7D01000B', bool, False) - @property + @functools.cached_property def serverProcessed(self) -> bool: """ Indicates that the Meeting Request object or Meeting Update object has been processed. """ - return self._getNamedAs('_serverProcessed', '85CC', constants.ps.PSETID_CALENDAR_ASSISTANT, overrideClass = bool, preserveNone = False) + return self._getNamedAs('85CC', constants.ps.PSETID_CALENDAR_ASSISTANT, bool, False) - @property - def serverProcessingActions(self) -> Optional[Set[ServerProcessingAction]]: + @functools.cached_property + def serverProcessingActions(self) -> Optional[ServerProcessingAction]: """ - A set of which actions have been taken on the Meeting Request object or - Meeting Update object. + A union of which actions have been taken on the Meeting Request object + or Meeting Update object. """ - return self._getNamedAs('_serverProcessingActions', '85CD', constants.ps.PSETID_CALENDAR_ASSISTANT, overrideClass = ServerProcessingAction.fromBits) + return self._getNamedAs('85CD', constants.ps.PSETID_CALENDAR_ASSISTANT, ServerProcessingAction) - @property + @functools.cached_property def timeZone(self) -> Optional[int]: """ Specifies information about the time zone of a recurring meeting. See PidLidTimeZone in [MS-OXOCAL] for details. """ - return self._getNamedAs('_timeZone', '000C', constants.ps.PSETID_MEETING) + return self._getNamedAs('000C', constants.ps.PSETID_MEETING) - @property + @functools.cached_property def where(self) -> Optional[str]: """ PidLidWhere. Should be the same as location. """ - return self._getNamedAs('_where', '0002', constants.ps.PSETID_MEETING) + return self._getNamedAs('0002', constants.ps.PSETID_MEETING) diff --git a/extract_msg/msg_classes/meeting_request.py b/extract_msg/msg_classes/meeting_request.py index 58a0ebc0..84f638cd 100644 --- a/extract_msg/msg_classes/meeting_request.py +++ b/extract_msg/msg_classes/meeting_request.py @@ -4,8 +4,9 @@ import datetime +import functools -from typing import List, Optional, Set +from typing import List, Optional from .. import constants from .meeting_related import MeetingRelated @@ -17,42 +18,42 @@ class MeetingRequest(MeetingRelated): Class for handling Meeting Request and Meeting Update objects. """ - @property + @functools.cached_property def appointmentMessageClass(self) -> Optional[str]: """ Indicates the value of the PidTagMessageClass property of the Meeting object that is to be generated from the Meeting Request object. MUST start with "IPM.Appointment". """ - return self._getNamedAs('_appointmentMessageClass', '0024', constants.ps.PSETID_MEETING) + return self._getNamedAs('0024', constants.ps.PSETID_MEETING) - @property + @functools.cached_property def calendarType(self) -> Optional[RecurCalendarType]: """ The value of the CalendarType field from the PidLidAppointmentRecur property if the Meeting Request object represents a recurring series or an exception. """ - return self._getNamedAs('_calendarType', '001C', constants.ps.PSETID_MEETING, overrideClass = RecurCalendarType) + return self._getNamedAs('001C', constants.ps.PSETID_MEETING, RecurCalendarType) - @property - def changeHighlight(self) -> Optional[Set[MeetingObjectChange]]: + @functools.cached_property + def changeHighlight(self) -> Optional[MeetingObjectChange]: """ Soecifies a bit field that indicates how the Meeting object has been changed. - Returns a set of flags. + Returns a union of the set flags. """ - return self._getNamedAs('_changeHighlight', '8204', constants.ps.PSETID_APPOINTMENT, overrideClass = MeetingObjectChange.fromBits) + return self._getNamedAs('8204', constants.ps.PSETID_APPOINTMENT, MeetingObjectChange) - @property + @functools.cached_property def forwardInstance(self) -> bool: """ Indicates that the Meeting Request object represents an exception to a recurring series, and it was forwarded (even when forwarded by the organizer) rather than being an invitation sent by the organizer. """ - return self._getNamedAs('_forwardInstance', '820A', constants.ps.PSETID_APPOINTMENT, overrideClass = bool, preserveNone = False) + return self._getNamedAs('820A', constants.ps.PSETID_APPOINTMENT, bool, False) @property def headerFormatProperties(self) -> constants.HEADER_FORMAT_TYPE: @@ -132,41 +133,41 @@ def headerFormatProperties(self) -> constants.HEADER_FORMAT_TYPE: } - @property + @functools.cached_property def intendedBusyStatus(self) -> Optional[BusyStatus]: """ The value of the busyStatus on the Meeting object in the organizer's calendar at the time the Meeting Request object or Meeting Update object was sent. """ - return self._getNamedAs('_intendedBusyStatus', '8224', constants.ps.PSETID_APPOINTMENT, overrideClass = BusyStatus) + return self._getNamedAs('8224', constants.ps.PSETID_APPOINTMENT, BusyStatus) - @property + @functools.cached_property def meetingType(self) -> Optional[MeetingType]: """ The type of Meeting Request object or Meeting Update object. """ - return self._getNamedAs('_meetingType', '0026', constants.ps.PSETID_MEETING, overrideClass = MeetingType) + return self._getNamedAs('0026', constants.ps.PSETID_MEETING, MeetingType) - @property + @functools.cached_property def oldLocation(self) -> Optional[str]: """ The original value of the location property before a meeting update. """ - return self._getNamedAs('_oldLocation', '0028', constants.ps.PSETID_MEETING) + return self._getNamedAs('0028', constants.ps.PSETID_MEETING) - @property + @functools.cached_property def oldWhenEndWhole(self) -> Optional[datetime.datetime]: """ The original value of the appointmentEndWhole property before a meeting update. """ - return self._getNamedAs('_oldWhenEndWhole', '002A', constants.ps.PSETID_MEETING) + return self._getNamedAs('002A', constants.ps.PSETID_MEETING) - @property + @functools.cached_property def oldWhenStartWhole(self) -> Optional[datetime.datetime]: """ The original value of the appointmentStartWhole property before a meeting update. """ - return self._getNamedAs('_oldWhenStartWhole', '0029', constants.ps.PSETID_MEETING) + return self._getNamedAs('0029', constants.ps.PSETID_MEETING) diff --git a/extract_msg/msg_classes/task.py b/extract_msg/msg_classes/task.py index 13ae5499..71533955 100644 --- a/extract_msg/msg_classes/task.py +++ b/extract_msg/msg_classes/task.py @@ -246,7 +246,7 @@ def taskMode(self) -> Optional[TaskMode]: @functools.cached_property def taskMultipleRecipients(self) -> Optional[TaskMultipleRecipients]: """ - Returns a set of flags that specify optimization hints about the + Returns a union of flags that specify optimization hints about the recipients of a Task object. """ return self._getNamedAs('8120', constants.ps.PSETID_TASK, TaskMultipleRecipients) From 580785c117b6f8a3f1986d2620ad69c84c5f55b5 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Sun, 2 Jul 2023 00:56:26 -0700 Subject: [PATCH 65/89] Further property internals progress --- CHANGELOG.md | 1 + extract_msg/msg_classes/calendar_base.py | 2 +- extract_msg/msg_classes/message_base.py | 149 ++++++++---------- .../msg_classes/message_signed_base.py | 81 ++++------ extract_msg/msg_classes/msg.py | 31 ++-- extract_msg/msg_classes/post.py | 5 +- extract_msg/msg_classes/task_request.py | 2 +- 7 files changed, 122 insertions(+), 149 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cd9b472..b341104a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,7 @@ * Made enums less strict and converted all using `fromBits` to be `IntFlag` enums. * Fixed `CalendarBase.keywords` being blatantly incorrect (it was so bad I don't know how it slipped through). * Fixed `Contact.gender` being blatantly incorrect. +* Fixed sender not being properly decoded in some circumstances. **v0.41.5** * Fixed an issue from version `0.41.3` where the header being present but missing the `From` field would cause an exception. diff --git a/extract_msg/msg_classes/calendar_base.py b/extract_msg/msg_classes/calendar_base.py index b7047a17..8a722c86 100644 --- a/extract_msg/msg_classes/calendar_base.py +++ b/extract_msg/msg_classes/calendar_base.py @@ -417,7 +417,7 @@ def organizer(self) -> Optional[str]: """ The meeting organizer. """ - return self._ensureSet('_organizer', '__substg1.0_0042') + return self._getStringStream('__substg1.0_0042') @functools.cached_property def ownerAppointmentID(self) -> Optional[int]: diff --git a/extract_msg/msg_classes/message_base.py b/extract_msg/msg_classes/message_base.py index ca858533..8693a1c8 100644 --- a/extract_msg/msg_classes/message_base.py +++ b/extract_msg/msg_classes/message_base.py @@ -100,7 +100,7 @@ def __init__(self, path, **kwargs): self.sender self.date # This variable keeps track of what the new line character should be. - self.__crlf = '\n' + self._crlf = '\n' try: self.body except Exception as e: @@ -879,29 +879,26 @@ def bcc(self) -> Optional[str]: """ return self._genRecipient('bcc', RecipientType.BCC) - @property + @functools.cached_property def body(self) -> Optional[str]: """ Returns the message body, if it exists. """ - try: - return self._body - except AttributeError: - # If the body exists but is empty, that means it should be returned. - if self._ensureSet('_body', '__substg1.0_1000') is not None: - pass - else: - # If the body doesn't exist, see if we can get it from the RTF - # body. - if self.rtfBody: - self._body = self.deencapsulateBody(self.rtfBody, DeencapType.PLAIN) + # If the body exists but is empty, that means it should be returned. + if (body := self._getStringStream('__substg1.0_1000')) is not None: + pass + elif self.rtfBody: + # If the body doesn't exist, see if we can get it from the RTF + # body. + body = self.deencapsulateBody(self.rtfBody, DeencapType.PLAIN) + + if body: + body = inputToString(body, 'utf-8') + if re.search('\n', body) is not None: + if re.search('\r\n', body) is not None: + self._crlf = '\r\n' - if self._body: - self._body = inputToString(self._body, 'utf-8') - if re.search('\n', self._body) is not None: - if re.search('\r\n', self._body) is not None: - self.__crlf = '\r\n' - return self._body + return body @functools.cached_property def cc(self) -> Optional[str]: @@ -910,12 +907,12 @@ def cc(self) -> Optional[str]: """ return self._genRecipient('cc', RecipientType.CC) - @property + @functools.cached_property def compressedRtf(self) -> Optional[bytes]: """ Returns the compressed RTF stream, if it exists. """ - return self._ensureSet('_compressedRtf', '__substg1.0_10090102', False) + return self._getStream('__substg1.0_10090102') @property def crlf(self) -> str: @@ -923,7 +920,7 @@ def crlf(self) -> str: Returns the value of self.__crlf, should you need it for whatever reason. """ - return self.__crlf + return self._crlf @functools.cached_property def date(self) -> Optional[datetime.datetime]: @@ -1092,32 +1089,28 @@ def headerText(self) -> Optional[str]: """ return self._getStringStream('__substg1.0_007D') - @property + @functools.cached_property def htmlBody(self) -> Optional[bytes]: """ Returns the html body, if it exists. """ - try: - return self._htmlBody - except AttributeError: - if self._ensureSet('_htmlBody', '__substg1.0_10130102', False): - # Reducing line repetition. - pass - elif self.rtfBody: - logger.info('HTML body was not found, attempting to generate from RTF.') - self._htmlBody = self.deencapsulateBody(self.rtfBody, DeencapType.HTML) - # This is it's own if statement so we can ensure it will generate - # even if there is an rtfBody, in the event it doesn't have HTML. - if not self._htmlBody and self.body: - # Convert the plain text body to html. - logger.info('HTML body was not found, attempting to generate from plain text body.') - correctedBody = html.escape(self.body).replace('\r', '').replace('\n', '
') - self._htmlBody = f'{correctedBody}'.encode('utf-8') - - if not self._htmlBody: - logger.info('HTML body could not be found nor generated.') - - return self._htmlBody + if (htmlBody := self._getStream('__substg1.0_10130102')) is not None: + pass + elif self.rtfBody: + logger.info('HTML body was not found, attempting to generate from RTF.') + htmlBody = self.deencapsulateBody(self.rtfBody, DeencapType.HTML) + # This is it's own if statement so we can ensure it will generate + # even if there is an rtfBody, in the event it doesn't have HTML. + if not htmlBody and self.body: + # Convert the plain text body to html. + logger.info('HTML body was not found, attempting to generate from plain text body.') + correctedBody = html.escape(self.body).replace('\r', '').replace('\n', '
') + htmlBody = f'{correctedBody}'.encode('utf-8') + + if not htmlBody: + logger.info('HTML body could not be found nor generated.') + + return htmlBody @functools.cached_property def htmlBodyPrepared(self) -> Optional[bytes]: @@ -1159,12 +1152,12 @@ def htmlInjectableHeader(self) -> str: return self.getInjectableHeader(prefix, joinStr, suffix, formatter) - @property + @functools.cached_property def inReplyTo(self) -> Optional[str]: """ Returns the message id that this message is in reply to. """ - return self._ensureSet('_in_reply_to', '__substg1.0_1042') + return self._getStringStream('__substg1.0_1042') @functools.cached_property def isRead(self) -> bool: @@ -1228,25 +1221,21 @@ def recipients(self) -> List[Recipient]: return [Recipient(recipientDir, self) for recipientDir in recipientDirs] - @property + @functools.cached_property def reportTag(self) -> Optional[ReportTag]: """ Data that is used to correlate the report and the original message. """ - return self._ensureSet('_reportTag', '__substg1.0_00310102', False, overrideClass = ReportTag) + return self._getStreamAs('__substg1.0_00310102', False, ReportTag) - @property + @functools.cached_property def rtfBody(self) -> Optional[bytes]: """ Returns the decompressed Rtf body from the message. """ - try: - return self._rtfBody - except AttributeError: - self._rtfBody = compressed_rtf.decompress(self.compressedRtf) if self.compressedRtf else None - return self._rtfBody + return compressed_rtf.decompress(self.compressedRtf) if self.compressedRtf else None - @property + @functools.cached_property def rtfEncapInjectableHeader(self) -> bytes: """ The header that can be formatted and injected into the plain RTF body. @@ -1258,7 +1247,7 @@ def rtfEncapInjectableHeader(self) -> bytes: return self.getInjectableHeader(prefix, joinStr, suffix, formatter).encode('utf-8') - @property + @functools.cached_property def rtfPlainInjectableHeader(self) -> bytes: """ The header that can be formatted and injected into the encapsulated RTF @@ -1271,42 +1260,38 @@ def rtfPlainInjectableHeader(self) -> bytes: return self.getInjectableHeader(prefix, joinStr, suffix, formatter).encode('utf-8') - @property + @functools.cached_property def sender(self) -> Optional[str]: """ Returns the message sender, if it exists. """ - try: - return self._sender - except AttributeError: - # Check header first - if self.headerInit(): - headerResult = self.header['from'] - if headerResult is not None: - self._sender = decodeRfc2047(headerResult) - return headerResult - logger.info('Header found, but "sender" is not included. Will be generated from other streams.') - # Extract from other fields - text = self._getStringStream('__substg1.0_0C1A') - email = self._getStringStream('__substg1.0_5D01') - # Will not give an email address sometimes. Seems to exclude the email address if YOU are the sender. - result = None - if text is None: - result = email - else: - result = text - if email is not None: - result += ' <' + email + '>' + # Check header first + if self.headerInit(): + headerResult = self.header['from'] + if headerResult is not None: + return decodeRfc2047(headerResult) + logger.info('Header found, but "sender" is not included. Will be generated from other streams.') + # Extract from other fields + text = self._getStringStream('__substg1.0_0C1A') + email = self._getStringStream('__substg1.0_5D01') + # Will not give an email address sometimes. Seems to exclude the email + # address if YOU are the sender. + result = None + if text is None: + result = email + else: + result = text + if email is not None: + result += ' <' + email + '>' - self._sender = result - return result + return result - @property + @functools.cached_property def subject(self) -> Optional[str]: """ Returns the message subject, if it exists. """ - return self._ensureSet('_subject', '__substg1.0_0037') + return self._getStringStream('__substg1.0_0037') @functools.cached_property def to(self) -> Optional[str]: diff --git a/extract_msg/msg_classes/message_signed_base.py b/extract_msg/msg_classes/message_signed_base.py index 2360c630..08bcc297 100644 --- a/extract_msg/msg_classes/message_signed_base.py +++ b/extract_msg/msg_classes/message_signed_base.py @@ -10,7 +10,7 @@ from typing import List, Optional -from ..enums import ErrorBehavior +from ..enums import DeencapType, ErrorBehavior from ..exceptions import StandardViolationError from .message_base import MessageBase from ..attachments import SignedAttachment @@ -74,60 +74,49 @@ def attachments(self) -> List: return self._sAttachments - @property + @functools.cached_property def body(self) -> Optional[str]: """ Returns the message body, if it exists. """ - try: - return self._body - except AttributeError: - if self._ensureSet('_body', '__substg1.0_1000'): - pass - elif self.signedBody: - self._body = self.signedBody - else: - # If the body doesn't exist, see if we can get it from the RTF - # body. - if self.deencapsulatedRtf and self.deencapsulatedRtf.content_type == 'text': - self._body = self.deencapsulatedRtf.text - - if self._body: - self._body = inputToString(self._body, 'utf-8') - a = re.search('\n', self._body) - if a is not None: - if re.search('\r\n', self._body) is not None: - self.__crlf = '\r\n' - return self._body + if (body := self._getStringStream('__substg1.0_1000')) is not None: + pass + elif self.signedBody: + body = self.signedBody + elif self.rtfBody: + # If the body doesn't exist, see if we can get it from the RTF + # body. + body = self.deencapsulateBody(self.rtfBody, DeencapType.PLAIN) - @property + if body: + body = inputToString(body, 'utf-8') + if re.search('\n', body): + if re.search('\r\n', body): + self._crlf = '\r\n' + + return body + + @functools.cached_property def htmlBody(self) -> Optional[bytes]: """ Returns the html body, if it exists. """ - try: - return self._htmlBody - except AttributeError: - if self._ensureSet('_htmlBody', '__substg1.0_10130102', False): - # Reducing line repetition. - pass - elif self.signedHtmlBody: - self._htmlBody = self.signedHtmlBody - elif self.rtfBody: - logger.info('HTML body was not found, attempting to generate from RTF.') - if self.deencapsulatedRtf and self.deencapsulatedRtf.content_type == 'html': - self._htmlBody = self.deencapsulatedRtf.html.encode('utf-8') - else: - logger.info('Could not deencapsulate HTML from RTF body.') - elif self.body: - # Convert the plain text body to html. - logger.info('HTML body was not found, attempting to generate from plain text body.') - correctedBody = html.escpae(self.body).replace('\r', '').replace('\n', '
') - self._htmlBody = f'{correctedBody}'.encode('utf-8') - else: - logger.info('HTML body could not be found nor generated.') - - return self._htmlBody + if (htmlBody := self._getStream('__substg1.0_10130102')) is not None: + pass + elif self.signedHtmlBody: + htmlBody = self.signedHtmlBody + elif self.rtfBody: + logger.info('HTML body was not found, attempting to generate from RTF.') + htmlBody = self.deencapsulateBody(self.rtfBody, DeencapType.HTML) + elif self.body: + # Convert the plain text body to html. + logger.info('HTML body was not found, attempting to generate from plain text body.') + correctedBody = html.escpae(self.body).replace('\r', '').replace('\n', '
') + htmlBody = f'{correctedBody}'.encode('utf-8') + else: + logger.info('HTML body could not be found nor generated.') + + return htmlBody @functools.cached_property def _rawAttachments(self) -> List: diff --git a/extract_msg/msg_classes/msg.py b/extract_msg/msg_classes/msg.py index f3bdc2d5..d6a4169f 100644 --- a/extract_msg/msg_classes/msg.py +++ b/extract_msg/msg_classes/msg.py @@ -209,7 +209,7 @@ def __enter__(self) -> MSGFile: def __exit__(self, *_) -> None: self.close() - def _ensureSet(self, variable : str, streamID, stringStream : bool = True, **kwargs): + def _getStreamAs(self, streamID, stringStream : bool = True, overrideClass = None, preserveNone : bool = True): """ Ensures that the variable exists, otherwise will set it using the specified stream. After that, return said variable. @@ -225,20 +225,17 @@ def _ensureSet(self, variable : str, streamID, stringStream : bool = True, **kwa :param overrideClass: when the value could not be found (is None). If this is changed to False, then the value will be used regardless. """ - try: - return getattr(self, variable) - except AttributeError: - if stringStream: - value = self._getStringStream(streamID) - else: - value = self._getStream(streamID) - # Check if we should be overriding the data type for this instance. - if kwargs: - overrideClass = kwargs.get('overrideClass') - if overrideClass is not None and (value is not None or not kwargs.get('preserveNone', True)): - value = overrideClass(value) - setattr(self, variable, value) - return value + if stringStream: + value = self._getStringStream(streamID) + else: + value = self._getStream(streamID) + + # Check if we should be overriding the data type for this instance. + if overrideClass is not None: + if value is not None or not preserveNone: + value = overrideClass(value) + + return value def _getNamedAs(self, propertyName : str, guid : str, overrideClass = None, preserveNone : bool = True): """ @@ -700,12 +697,12 @@ def classified(self) -> bool: """ return self._getNamedAs('85B5', constants.ps.PSETID_COMMON, overrideClass = bool, preserveNone = False) - @property + @functools.cached_property def classType(self) -> Optional[str]: """ The class type of the MSG file. """ - return self._ensureSet('_classType', '__substg1.0_001A') + return self._getStringStream('_classType', '__substg1.0_001A') @functools.cached_property def commonEnd(self) -> Optional[datetime.datetime]: diff --git a/extract_msg/msg_classes/post.py b/extract_msg/msg_classes/post.py index be393f33..8167c260 100644 --- a/extract_msg/msg_classes/post.py +++ b/extract_msg/msg_classes/post.py @@ -3,6 +3,7 @@ ] +import functools import json from typing import Optional @@ -31,12 +32,12 @@ def getJson(self) -> str: 'body': decode_utf7(self.body), }) - @property + @functools.cached_property def conversation(self) -> Optional[str]: """ The name of the conversation being posted to. """ - return self._ensureSet('_convo', '__substg1.0_0070') + return self._getStringStream('__substg1.0_0070') @property def headerFormatProperties(self) -> constants.HEADER_FORMAT_TYPE: diff --git a/extract_msg/msg_classes/task_request.py b/extract_msg/msg_classes/task_request.py index 7ef281d7..0a19c9c1 100644 --- a/extract_msg/msg_classes/task_request.py +++ b/extract_msg/msg_classes/task_request.py @@ -107,4 +107,4 @@ def taskRequestType(self) -> TaskRequestType: """ The type of task request. """ - return self._ensureSet('__substg1.0_001A', TaskRequestType.fromClassType) + return self._getStreamAs('__substg1.0_001A', TaskRequestType.fromClassType) From c9d3ae9fa6c842e1bcbaadaa9b7118e5ec645ca5 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Sun, 2 Jul 2023 01:23:05 -0700 Subject: [PATCH 66/89] Near done with prop internals --- extract_msg/attachments/attachment_base.py | 182 +++++++++---------- extract_msg/attachments/web_att.py | 14 +- extract_msg/enums.py | 80 +------- extract_msg/msg_classes/calendar_base.py | 2 +- extract_msg/msg_classes/contact.py | 10 +- extract_msg/msg_classes/msg.py | 135 +++++++------- extract_msg/structures/recurrence_pattern.py | 4 +- extract_msg/structures/tz_rule.py | 2 +- 8 files changed, 170 insertions(+), 259 deletions(-) diff --git a/extract_msg/attachments/attachment_base.py b/extract_msg/attachments/attachment_base.py index 9cb88f58..39a5c68b 100644 --- a/extract_msg/attachments/attachment_base.py +++ b/extract_msg/attachments/attachment_base.py @@ -49,13 +49,9 @@ def __init__(self, msg : MSGFile, dir_, propStore : PropertiesStore): self.__namedProperties = NamedProperties(msg.named, self) self.__treePath = msg.treePath + [makeWeakRef(self)] - def _ensureSet(self, variable, streamID, stringStream = True, **kwargs): + def _getNamedAs(self, propertyName : str, guid : str, overrideClass = None, preserveNone : bool = True): """ - Ensures that the variable exists, otherwise will set it using the - specified stream. After that, return said variable. - - If the specified stream is not a string stream, make sure to set - :param stringStream: to False. + Returns the named property, setting the class if specified. :param overrideClass: Class/function to use to morph the data that was read. The data will be the first argument to the class's __init__ @@ -65,53 +61,17 @@ def _ensureSet(self, variable, streamID, stringStream = True, **kwargs): :param overrideClass: when the value could not be found (is None). If this is changed to False, then the value will be used regardless. """ - try: - return getattr(self, variable) - except AttributeError: - if stringStream: - value = self._getStringStream(streamID) - else: - value = self._getStream(streamID) - # Check if we should be overriding the data type for this instance. - if kwargs: - overrideClass = kwargs.get('overrideClass') - if overrideClass is not None and (value is not None or not kwargs.get('preserveNone', True)): - value = overrideClass(value) - setattr(self, variable, value) - return value - - def _ensureSetNamed(self, variable : str, propertyName : str, guid : str, **kwargs): - """ - Ensures that the variable exists, otherwise will set it using the named - property. After that, return said variable. - - :param overrideClass: Class/function to use to morph the data that was - read. The data will be the first argument to the class's __init__ - function or the function itself, if that is what is provided. By - default, this will be completely ignored if the value was not found. - :param preserveNone: If true (default), causes the function to ignore - :param overrideClass: when the value could not be found (is None). - If this is changed to False, then the value will be used regardless. + value = self.namedProperties.get((propertyName, guid)) + # Check if we should be overriding the data type for this instance. + if overrideClass is not None: + if value is not None or not preserveNone: + value = overrideClass(value) - :raises ReferenceError: The associated MSGFile instance has been garbage - collected. - """ - try: - return getattr(self, variable) - except AttributeError: - value = self.namedProperties.get((propertyName, guid)) - # Check if we should be overriding the data type for this instance. - if kwargs: - overrideClass = kwargs.get('overrideClass') - if overrideClass is not None and (value is not None or not kwargs.get('preserveNone', True)): - value = overrideClass(value) - setattr(self, variable, value) - return value + return value def _getPropertyAs(self, propertyName, overrideClass = None, preserveNone : bool = True): """ - Ensures that the variable exists, otherwise will set it using the - property. After that, return said variable. + Returns the property, setting the class if specified. :param overrideClass: Class/function to use to morph the data that was read. The data will be the first argument to the class's __init__ @@ -132,35 +92,6 @@ def _getPropertyAs(self, propertyName, overrideClass = None, preserveNone : bool return value - def _ensureSetTyped(self, variable, _id, **kwargs): - """ - Like the other ensure set functions, but designed for when something - could be multiple types (where only one will be present). This way you - have no need to set the type, it will be handled for you. - - :param overrideClass: Class/function to use to morph the data that was - read. The data will be the first argument to the class's __init__ - function or the function itself, if that is what is provided. By - default, this will be completely ignored if the value was not found. - :param preserveNone: If true (default), causes the function to ignore - :param overrideClass: when the value could not be found (is None). - If this is changed to False, then the value will be used regardless. - - :raises ReferenceError: The associated MSGFile instance has been garbage - collected. - """ - try: - return getattr(self, variable) - except AttributeError: - value = self._getTypedData(_id) - # Check if we should be overriding the data type for this instance. - if kwargs: - overrideClass = kwargs.get('overrideClass') - if overrideClass is not None and (value is not None or not kwargs.get('preserveNone', True)): - value = overrideClass(value) - setattr(self, variable, value) - return value - def _getStream(self, filename) -> Optional[bytes]: """ Gets a binary representation of the requested filename. @@ -175,6 +106,33 @@ def _getStream(self, filename) -> Optional[bytes]: raise ReferenceError('The msg file for this Attachment instance has been garbage collected.') return msg._getStream([self.__dir, filename]) + def _getStreamAs(self, streamID, stringStream : bool = True, overrideClass = None, preserveNone : bool = True): + """ + Returns the specified stream, modifying it to the class if specified. + + If the specified stream is not a string stream, make sure to set + :param stringStream: to False. + + :param overrideClass: Class/function to use to morph the data that was + read. The data will be the first argument to the class's __init__ + function or the function itself, if that is what is provided. By + default, this will be completely ignored if the value was not found. + :param preserveNone: If true (default), causes the function to ignore + :param overrideClass: when the value could not be found (is None). + If this is changed to False, then the value will be used regardless. + """ + if stringStream: + value = self._getStringStream(streamID) + else: + value = self._getStream(streamID) + + # Check if we should be overriding the data type for this instance. + if overrideClass is not None: + if value is not None or not preserveNone: + value = overrideClass(value) + + return value + def _getStringStream(self, filename) -> Optional[str]: """ Gets a string representation of the requested filename. @@ -190,6 +148,28 @@ def _getStringStream(self, filename) -> Optional[str]: raise ReferenceError('The msg file for this Attachment instance has been garbage collected.') return msg._getStringStream([self.__dir, filename]) + def _getTypedAs(self, _id : str, overrideClass = None, preserveNone : bool = True): + """ + Like the other get as functions, but designed for when something + could be multiple types (where only one will be present). This way you + have no need to set the type, it will be handled for you. + + :param overrideClass: Class/function to use to morph the data that was + read. The data will be the first argument to the class's __init__ + function or the function itself, if that is what is provided. By + default, this will be completely ignored if the value was not found. + :param preserveNone: If true (default), causes the function to ignore + :param overrideClass: when the value could not be found (is None). + If this is changed to False, then the value will be used regardless. + """ + value = self._getTypedData(_id) + # Check if we should be overriding the data type for this instance. + if overrideClass is not None: + if value is not None or not preserveNone: + value = overrideClass(value) + + return value + def _getTypedData(self, id, _type = None): """ Gets the data for the specified id as the type that it is @@ -335,16 +315,16 @@ def save(self, **kwargs) -> constants.SAVE_TYPE: the first item specifies what the second value will be. """ - @property + @functools.cached_property def attachmentEncoding(self) -> Optional[bytes]: """ The encoding information about the attachment object. Will return b'*\\x86H\\x86\\xf7\\x14\\x03\\x0b\\x01' if encoded in MacBinary format, otherwise it is unset. """ - return self._ensureSet('_attachmentEncoding', '__substg1.0_37020102', False) + return self._getStream('__substg1.0_37020102') - @property + @functools.cached_property def additionalInformation(self) -> Optional[str]: """ The additional information about the attachment. This property MUST be @@ -353,14 +333,14 @@ def additionalInformation(self) -> Optional[str]: four-letter Macintosh file creator code and ":TYPE" is a four-letter Macintosh type code. """ - return self._ensureSet('_additionalInformation', '__substg1.0_370F') + return self._getStringStream('__substg1.0_370F') - @property + @functools.cached_property def cid(self) -> Optional[str]: """ Returns the Content ID of the attachment, if it exists. """ - return self._ensureSet('_cid', '__substg1.0_3712') + return self._getStringStream('__substg1.0_3712') contendId = cid @@ -400,7 +380,7 @@ def data(self) -> Optional[object]: The attachment data, if any. Returns None if there is no data to save. """ - @property + @functools.cached_property def dataType(self) -> Optional[Type[type]]: """ The class that the data type will use, if it can be retrieved. @@ -423,12 +403,12 @@ def dir(self) -> str: """ return self.__dir - @property + @functools.cached_property def displayName(self) -> Optional[str]: """ Returns the display name of the folder. """ - return self._ensureSet('_displayName', '__substg1.0_3001') + return self._getStringStream('__substg1.0_3001') @functools.cached_property def exceptionReplaceTime(self) -> Optional[datetime.datetime]: @@ -440,47 +420,47 @@ def exceptionReplaceTime(self) -> Optional[datetime.datetime]: """ return self._getPropertyAs('7FF90040') - @property + @functools.cached_property def extension(self) -> Optional[str]: """ The reported extension for the file. """ - return self._ensureSet('_extension', '__substg1.0_3703') + return self._getStringStream('__substg1.0_3703') @functools.cached_property def hidden(self) -> bool: """ Indicates whether an Attachment object is hidden from the end user. """ - return self._getPropertyAs('7FFE000B', overrideClass = bool, preserveNone = False) + return self._getPropertyAs('7FFE000B', bool, False) @functools.cached_property def isAttachmentContactPhoto(self) -> bool: """ Whether the attachment is a contact photo for a Contact object. """ - return self._getPropertyAs('7FFF000B', overrideClass = bool, preserveNone = False) + return self._getPropertyAs('7FFF000B', bool, False) - @property + @functools.cached_property def longFilename(self) -> Optional[str]: """ Returns the long file name of the attachment, if it exists. """ - return self._ensureSet('_longFilename', '__substg1.0_3707') + return self._getStringStream('__substg1.0_3707') - @property + @functools.cached_property def longPathname(self) -> Optional[str]: """ The fully qualified path and file name with extension. """ - return self._ensureSet('_longPathname', '__substg1.0_370D') + return self._getStringStream('__substg1.0_370D') - @property + @functools.cached_property def mimetype(self) -> Optional[str]: """ The content-type mime header of the attachment, if specified. """ - return self._ensureSet('_mimetype', '__substg1.0_370E', overrideClass = partial(tryGetMimetype, self), preserveNone = False) + return self._getStreamAs('__substg1.0_370E', partial(tryGetMimetype, self), False) @property def msg(self) -> MSGFile: @@ -494,7 +474,7 @@ def msg(self) -> MSGFile: raise ReferenceError('The msg file for this Attachment instance has been garbage collected.') return msg - @property + @functools.cached_property def name(self) -> Optional[str]: """ The best name available for the file. Uses long filename before short. @@ -511,13 +491,13 @@ def namedProperties(self) -> NamedProperties: """ return self.__namedProperties - @property + @functools.cached_property def payloadClass(self) -> Optional[str]: """ The class name of an object that can display the contents of the message. """ - return self._ensureSet('_payloadClass', '__substg1.0_371A') + return self._getStringStream('__substg1.0_371A') @property def props(self) -> PropertiesStore: @@ -540,7 +520,7 @@ def shortFilename(self) -> Optional[str]: """ Returns the short file name of the attachment, if it exists. """ - return self._ensureSet('_shortFilename', '__substg1.0_3704') + return self._getStringStream('__substg1.0_3704') @property def treePath(self) -> List[weakref.ReferenceType]: diff --git a/extract_msg/attachments/web_att.py b/extract_msg/attachments/web_att.py index c44d4c04..669fe0fe 100644 --- a/extract_msg/attachments/web_att.py +++ b/extract_msg/attachments/web_att.py @@ -3,6 +3,8 @@ ] +import functools + from typing import Optional from .. import constants @@ -36,26 +38,26 @@ def data(self) -> None: """ raise NotImplementedError('Cannot get the data of a web attachment.') - @property + @functools.cached_property def originalPermissionType(self) -> Optional[AttachmentPermissionType]: """ The permission type data associated with a web reference attachment. """ - return self._ensureSetNamed('_oPermissionType', 'AttachmentOriginalPermissionType', constants.ps.PSETID_ATTACHMENT, overrideClass = AttachmentPermissionType, preserveNone = True) + return self._getNamedAs('AttachmentOriginalPermissionType', constants.ps.PSETID_ATTACHMENT, AttachmentPermissionType) - @property + @functools.cached_property def permissionType(self) -> Optional[AttachmentPermissionType]: """ The permission type data associated with a web reference attachment. """ - return self._ensureSetNamed('_permissionType', 'AttachmentPermissionType', constants.ps.PSETID_ATTACHMENT, overrideClass = AttachmentPermissionType, preserveNone = True) + return self._getNamedAs('AttachmentPermissionType', constants.ps.PSETID_ATTACHMENT, AttachmentPermissionType) - @property + @functools.cached_property def providerName(self) -> Optional[str]: """ The type of web service manipulating the attachment. """ - return self._ensureSetNamed('_permissionType', 'AttachmentProviderType', constants.ps.PSETID_ATTACHMENT) + return self._getNamedAs('AttachmentProviderType', constants.ps.PSETID_ATTACHMENT) @property def type(self) -> AttachmentType: diff --git a/extract_msg/enums.py b/extract_msg/enums.py index 2c5bc0c2..909df543 100644 --- a/extract_msg/enums.py +++ b/extract_msg/enums.py @@ -43,7 +43,7 @@ class AddressBookType(enum.Enum): -class AppointmentAuxilaryFlag(enum.IntEnum): +class AppointmentAuxilaryFlag(enum.IntFlag): """ Describes the auxilary state of the object. @@ -76,19 +76,12 @@ class AppointmentColor(enum.Enum): -class AppointmentStateFlag(enum.Enum): +class AppointmentStateFlag(enum.IntFlag): """ MEETING: The object is a Meeting object or meeting-related object. RECEIVED: The represented object was received from someone else. CANCELED: The Meeting object that is represented has been canceled. """ - @classmethod - def fromBits(cls, value : int) -> Set['AppointmentStateFlag']: - """ - Takes an int and returns a set of the flags. - """ - return {cls(1 << x) for x in range(3) if (value & (1 << x)) != 0} - MEETING = 0b1 RECEIVED = 0b10 CANCELED = 0b100 @@ -415,20 +408,6 @@ class DVAspect(enum.IntEnum): class ElectronicAddressProperties(enum.Enum): - @classmethod - def fromBits(cls, value : int) -> Set['ElectronicAddressProperties']: - """ - Converts an int, with the left most bit referring to 0x00000000, to a - set of this enum. - - :raises ValueError: The value was less than 0. - """ - if value < 0: - raise ValueError('Value must not be negative.') - # This is a quick compressed way to convert the bits in the int into - # a tuple of instances of this class should any bit be a 1. - return {cls(int(index)) for index, val in enumerate(bin(value)[:1:-1]) if val == '1'} - EMAIL_1 = 0x00000000 EMAIL_2 = 0x00000001 EMAIL_3 = 0x00000002 @@ -1197,7 +1176,7 @@ class MacintoshEncoding(enum.Enum): -class MeetingObjectChange(enum.Enum): +class MeetingObjectChange(enum.IntFlag): """ Indicates a property that has changed on a meeting object. @@ -1212,23 +1191,6 @@ class MeetingObjectChange(enum.Enum): RESPONSE: The responseRequested or replyRequested property has changed. ALLOW_PROPOSE: The appointmentNotAllowPropose property has changed. """ - @classmethod - def fromBits(cls, value : int) -> Set['MeetingObjectChange']: - """ - Takes an int and returns a set of the changes. - """ - changes = set() - for x in range(32): - if x in (8, 11) or (12 < x < 31): - continue - bit = value & (1 << x) - if bit: - if x in (12, 31): - raise ValueError('Reserved bit was set.') - changes.add(cls(bit)) - - return changes - START = 0b1 END = 0b10 RECUR = 0b100 @@ -1440,17 +1402,10 @@ class RecurMonthNthWeek(enum.Enum): -class RecurPatternTypeSpecificWeekday(enum.Enum): +class RecurPatternTypeSpecificWeekday(enum.IntFlag): """ See [MS-OXOCAL] for details. """ - @classmethod - def fromBits(cls, value : int) -> Set['RecurPatternTypeSpecificWeekday']: - """ - Takes an int and returns a set of the weekdays. - """ - return {cls(1 << x) for x in range(1, 8) if (value & (1 << x))} - SATURDAY = 0b10 FRIDAY = 0b100 THURSDAY = 0b1000 @@ -1554,17 +1509,10 @@ class Sensitivity(enum.Enum): -class ServerProcessingAction(enum.Enum): +class ServerProcessingAction(enum.IntFlag): """ Actions taken on a meeting-related object. """ - @classmethod - def fromBits(cls, value : int) -> Set['ServerProcessingAction']: - """ - Takes an int and returns a set of the weekdays. - """ - return {cls(1 << x) for x in range(16) if (value & (1 << x))} - DELEGATOR_WANTS_COPY = 0x00000002 CREATED_ON_PRINCIPLE = 0x00000010 UPDATED_CAL_ITEM = 0x00000080 @@ -1575,7 +1523,7 @@ def fromBits(cls, value : int) -> Set['ServerProcessingAction']: -class SideEffect(enum.Enum): +class SideEffect(enum.IntFlag): """ A flag for how a Message object is handled by the client in relation to certain user interface actions. @@ -1601,13 +1549,6 @@ class SideEffect(enum.Enum): OPEN_TO_PERM_DELETE: The client opens the Message object to permanently delete it. """ - @classmethod - def fromBits(cls, value : int) -> Set['SideEffect']: - """ - Takes an int and returns a set of the side effects. - """ - return {cls(1 << x) for x in range(15) if (value & (1 << x))} - OPEN_TO_DELETE = 0b1 NO_FRAME = 0b1000 COERCE_TO_INDEX = 0b10000 @@ -1758,20 +1699,13 @@ class TaskStatus(enum.Enum): -class TZFlag(enum.Enum): +class TZFlag(enum.IntFlag): """ Flags for a TZRule object as defined in [MS-OXOCAL]. RECUR_CURRENT_TZREG: The rule is associated with a recurring series. EFFECTIVE_TZREG: The rule is the effective rule. """ - @classmethod - def fromBits(cls, value : int) -> Set['TZFlag']: - """ - Takes an int and returns a set of the flags. - """ - return {cls(1 << x) for x in range(2) if (value & (1 << x))} - RECUR_CURRENT_TZREG = 0b1 EFFECTIVE_TZREG = 0b10 diff --git a/extract_msg/msg_classes/calendar_base.py b/extract_msg/msg_classes/calendar_base.py index 8a722c86..5b22109b 100644 --- a/extract_msg/msg_classes/calendar_base.py +++ b/extract_msg/msg_classes/calendar_base.py @@ -456,7 +456,7 @@ def replyRequested(self) -> bool: """ Whether the organizer requests a reply from attendees. """ - return self._getPropertyAs('0C17000B', overrideClass = bool, preserveNone = False) + return self._getPropertyAs('0C17000B', bool, False) @functools.cached_property def requiredAttendees(self) -> Optional[str]: diff --git a/extract_msg/msg_classes/contact.py b/extract_msg/msg_classes/contact.py index e66183d2..09e8b216 100644 --- a/extract_msg/msg_classes/contact.py +++ b/extract_msg/msg_classes/contact.py @@ -212,7 +212,7 @@ def businessTelephone2Number(self) -> Optional[Union[str, List[str]]]: """ Contains the second number or numbers of the contact's business. """ - return self._ensureSetTyped('3A1B') + return self._getTypedAs('3A1B') @functools.cached_property def businessHomePage(self) -> Optional[str]: @@ -485,7 +485,7 @@ def email2OriginalEntryId(self) -> Optional[EntryID]: """ The EntryID of the object correspinding to this electronic address. """ - return self._getNamedAs('_email2OriginalEntryId', '8095', constants.ps.PSETID_ADDRESS, overrideClass = EntryID.autoCreate) + return self._getNamedAs('8095', constants.ps.PSETID_ADDRESS, EntryID.autoCreate) @functools.cached_property def email3(self) -> Optional[dict]: @@ -849,7 +849,7 @@ def homeTelephone2Number(self) -> Optional[Union[str, List[str]]]: """ The number(s) of the contact's second home telephone. """ - return self._ensureSetTyped('3A2F') + return self._getTypedAs('3A2F') @functools.cached_property def initials(self) -> Optional[str]: @@ -1240,14 +1240,14 @@ def telexNumber(self) -> Optional[Union[str, List[str]]]: """ The contact's telex number(s). """ - return self._ensureSetTyped('3A2C') + return self._getTypedAs('3A2C') @functools.cached_property def userX509Certificate(self) -> Optional[List[bytes]]: """ A list of certificates for the contact. """ - return self._ensureSetTyped('3A70') + return self._getTypedAs('3A70') @functools.cached_property def weddingAnniversary(self) -> Optional[datetime.datetime]: diff --git a/extract_msg/msg_classes/msg.py b/extract_msg/msg_classes/msg.py index d6a4169f..c6a4ef95 100644 --- a/extract_msg/msg_classes/msg.py +++ b/extract_msg/msg_classes/msg.py @@ -209,13 +209,9 @@ def __enter__(self) -> MSGFile: def __exit__(self, *_) -> None: self.close() - def _getStreamAs(self, streamID, stringStream : bool = True, overrideClass = None, preserveNone : bool = True): + def _getNamedAs(self, propertyName : str, guid : str, overrideClass = None, preserveNone : bool = True): """ - Ensures that the variable exists, otherwise will set it using the - specified stream. After that, return said variable. - - If the specified stream is not a string stream, make sure to set - :param stringStream: to False. + Returns the named property, setting the class if specified. :param overrideClass: Class/function to use to morph the data that was read. The data will be the first argument to the class's __init__ @@ -225,11 +221,7 @@ def _getStreamAs(self, streamID, stringStream : bool = True, overrideClass = Non :param overrideClass: when the value could not be found (is None). If this is changed to False, then the value will be used regardless. """ - if stringStream: - value = self._getStringStream(streamID) - else: - value = self._getStream(streamID) - + value = self.namedProperties.get((propertyName, guid)) # Check if we should be overriding the data type for this instance. if overrideClass is not None: if value is not None or not preserveNone: @@ -237,25 +229,21 @@ def _getStreamAs(self, streamID, stringStream : bool = True, overrideClass = Non return value - def _getNamedAs(self, propertyName : str, guid : str, overrideClass = None, preserveNone : bool = True): + def _getOleEntry(self, filename, prefix : bool = True) -> olefile.olefile.OleDirectoryEntry: """ - Returns the named property, setting the class if specified. - - :param overrideClass: Class/function to use to morph the data that was - read. The data will be the first argument to the class's __init__ - function or the function itself, if that is what is provided. By - default, this will be completely ignored if the value was not found. - :param preserveNone: If true (default), causes the function to ignore - :param overrideClass: when the value could not be found (is None). - If this is changed to False, then the value will be used regardless. + Finds the directory entry from the olefile for the stream or storage + specified. Use '/' to get the root entry. """ - value = self.namedProperties.get((propertyName, guid)) - # Check if we should be overriding the data type for this instance. - if overrideClass is not None: - if value is not None or not preserveNone: - value = overrideClass(value) + sid = -1 + if filename == '/': + if prefix and self.__prefix: + sid = self.__ole._find(self.__prefixList) + else: + return self.__ole.direntries[0] + else: + sid = self.__ole._find(self.fixPath(filename, prefix)) - return value + return self.__ole.direntries[sid] def _getPropertyAs(self, propertyName, overrideClass = None, preserveNone : bool = True): """ @@ -280,48 +268,6 @@ def _getPropertyAs(self, propertyName, overrideClass = None, preserveNone : bool return value - def _ensureSetTyped(self, variable : str, _id, **kwargs): - """ - Like the other ensure set functions, but designed for when something - could be multiple types (where only one will be present). This way you - have no need to set the type, it will be handled for you. - - :param overrideClass: Class/function to use to morph the data that was - read. The data will be the first argument to the class's __init__ - function or the function itself, if that is what is provided. By - default, this will be completely ignored if the value was not found. - :param preserveNone: If true (default), causes the function to ignore - :param overrideClass: when the value could not be found (is None). - If this is changed to False, then the value will be used regardless. - """ - try: - return getattr(self, variable) - except AttributeError: - value = self._getTypedData(_id) - # Check if we should be overriding the data type for this instance. - if kwargs: - overrideClass = kwargs.get('overrideClass') - if overrideClass is not None and (value is not None or not kwargs.get('preserveNone', True)): - value = overrideClass(value) - setattr(self, variable, value) - return value - - def _getOleEntry(self, filename, prefix : bool = True) -> olefile.olefile.OleDirectoryEntry: - """ - Finds the directory entry from the olefile for the stream or storage - specified. Use '/' to get the root entry. - """ - sid = -1 - if filename == '/': - if prefix and self.__prefix: - sid = self.__ole._find(self.__prefixList) - else: - return self.__ole.direntries[0] - else: - sid = self.__ole._find(self.fixPath(filename, prefix)) - - return self.__ole.direntries[sid] - def _getStream(self, filename, prefix : bool = True) -> Optional[bytes]: """ Gets a binary representation of the requested filename. @@ -337,6 +283,33 @@ def _getStream(self, filename, prefix : bool = True) -> Optional[bytes]: logger.info(f'Stream "{filename}" was requested but could not be found. Returning `None`.') return None + def _getStreamAs(self, streamID, stringStream : bool = True, overrideClass = None, preserveNone : bool = True): + """ + Returns the specified stream, modifying it to the class if specified. + + If the specified stream is not a string stream, make sure to set + :param stringStream: to False. + + :param overrideClass: Class/function to use to morph the data that was + read. The data will be the first argument to the class's __init__ + function or the function itself, if that is what is provided. By + default, this will be completely ignored if the value was not found. + :param preserveNone: If true (default), causes the function to ignore + :param overrideClass: when the value could not be found (is None). + If this is changed to False, then the value will be used regardless. + """ + if stringStream: + value = self._getStringStream(streamID) + else: + value = self._getStream(streamID) + + # Check if we should be overriding the data type for this instance. + if overrideClass is not None: + if value is not None or not preserveNone: + value = overrideClass(value) + + return value + def _getStringStream(self, filename, prefix : bool = True) -> Optional[str]: """ Gets a string representation of the requested filename. @@ -355,6 +328,28 @@ def _getStringStream(self, filename, prefix : bool = True) -> Optional[str]: tmp = self._getStream(filename + '001E', prefix = False) return None if tmp is None else tmp.decode(self.stringEncoding) + def _getTypedAs(self, _id : str, overrideClass = None, preserveNone : bool = True): + """ + Like the other get as functions, but designed for when something + could be multiple types (where only one will be present). This way you + have no need to set the type, it will be handled for you. + + :param overrideClass: Class/function to use to morph the data that was + read. The data will be the first argument to the class's __init__ + function or the function itself, if that is what is provided. By + default, this will be completely ignored if the value was not found. + :param preserveNone: If true (default), causes the function to ignore + :param overrideClass: when the value could not be found (is None). + If this is changed to False, then the value will be used regardless. + """ + value = self._getTypedData(_id) + # Check if we should be overriding the data type for this instance. + if overrideClass is not None: + if value is not None or not preserveNone: + value = overrideClass(value) + + return value + def _getTypedData(self, _id : str, _type = None, prefix : bool = True): """ Gets the data for the specified id as the type that it is supposed to @@ -746,7 +741,7 @@ def importance(self) -> Optional[Importance]: """ The specified importance of the msg file. """ - return self._getPropertyAs('00170003', overrideClass = Importance) + return self._getPropertyAs('00170003', Importance) @property def importanceString(self) -> Union[str, None]: diff --git a/extract_msg/structures/recurrence_pattern.py b/extract_msg/structures/recurrence_pattern.py index c2cb2f56..5743f8d6 100644 --- a/extract_msg/structures/recurrence_pattern.py +++ b/extract_msg/structures/recurrence_pattern.py @@ -35,11 +35,11 @@ def __init__(self, data : bytes): if self.__patternType == RecurPatternType.DAY: self.__patternTypeSpecific = None elif self.__patternType == RecurPatternType.WEEK: - self.__patternTypeSpecific = RPTSW.fromBits(reader.readUnsignedInt()) + self.__patternTypeSpecific = RPTSW(reader.readUnsignedInt()) elif self.__patternType in (RecurPatternType.MONTH_NTH, RecurPatternType.HJ_MONTH_NTH): self.__patternTypeSpecific = reader.readUnsignedInt() else: - self.__patternTypeSpecific = (RPTSW.fromBits(reader.readUnsignedInt()), + self.__patternTypeSpecific = (RPTSW(reader.readUnsignedInt()), RecurMonthNthWeek(reader.readUnsignedInt())) self.__endType = RecurEndType.fromInt(reader.readUnsignedInt()) diff --git a/extract_msg/structures/tz_rule.py b/extract_msg/structures/tz_rule.py index e7017206..d5427ac8 100644 --- a/extract_msg/structures/tz_rule.py +++ b/extract_msg/structures/tz_rule.py @@ -24,7 +24,7 @@ def __init__(self, data : bytes): self.__majorVersion = reader.readByte() self.__minorVersion = reader.readByte() reader.assertRead(b'\x3E\x00') - self.__flags = TZFlag.fromBits(reader.readUnsignedShort()) + self.__flags = TZFlag(reader.readUnsignedShort()) self.__year = reader.readShort() # We *should* be doing this, but Outlook is violating the standard so... #reader.assertNull(14) From 2bdba8b990deb8ecf770c76877a546ccacf5eba0 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Sun, 2 Jul 2023 01:28:18 -0700 Subject: [PATCH 67/89] Finish prop internals --- extract_msg/recipient.py | 165 +++++++++++++++++---------------------- 1 file changed, 72 insertions(+), 93 deletions(-) diff --git a/extract_msg/recipient.py b/extract_msg/recipient.py index 62346109..66e54ce9 100644 --- a/extract_msg/recipient.py +++ b/extract_msg/recipient.py @@ -3,6 +3,7 @@ ] +import functools import logging from typing import Optional, Tuple, Union @@ -45,76 +46,49 @@ def __init__(self, _dir, msg): self.__type = RecipientType(0xF & self.__typeFlags) self.__formatted = f'{self.__name} <{self.__email}>' - def _ensureSet(self, variable, streamID, stringStream : bool = True, **kwargs): + def _getPropertyAs(self, propertyName, overrideClass = None, preserveNone : bool = True): """ - Ensures that the variable exists, otherwise will set it using the - specified stream. After that, return said variable. - - If the specified stream is not a string stream, make sure to set - :param string stream: to False. + Returns the property, setting the class if specified. :param overrideClass: Class/function to use to morph the data that was read. The data will be the first argument to the class's __init__ function or the function itself, if that is what is provided. By default, this will be completely ignored if the value was not found. - :param preserveNone: If true (default), causes the function to ignore + :param preserveNone: If True (default), causes the function to ignore :param overrideClass: when the value could not be found (is None). If this is changed to False, then the value will be used regardless. - - :raises ReferenceError: The associated MSGFile instance has been garbage - collected. """ try: - return getattr(self, variable) - except AttributeError: - if stringStream: - value = self._getStringStream(streamID) - else: - value = self._getStream(streamID) - # Check if we should be overriding the data type for this instance. - if kwargs: - overrideClass = kwargs.get('overrideClass') - if overrideClass is not None and (value is not None or not kwargs.get('preserveNone', True)): - value = overrideClass(value) - setattr(self, variable, value) - return value + value = self.props[propertyName].value + except (KeyError, AttributeError): + value = None + # Check if we should be overriding the data type for this instance. + if overrideClass is not None: + if (value is not None or not preserveNone): + value = overrideClass(value) - def _ensureSetProperty(self, variable : str, propertyName : str, **kwargs): + return value + + def _getStream(self, filename) -> Optional[bytes]: """ - Ensures that the variable exists, otherwise will set it using the - property. After that, return said variable. + Gets a binary representation of the requested filename. - :param overrideClass: Class/function to use to morph the data that was - read. The data will be the first argument to the class's __init__ - function or the function itself, if that is what is provided. By - default, this will be completely ignored if the value was not found. - :param preserveNone: If true (default), causes the function to ignore - :param overrideClass: when the value could not be found (is None). - If this is changed to False, then the value will be used regardless. + This should ALWAYS return a bytes object if it was found, otherwise + returns None. :raises ReferenceError: The associated MSGFile instance has been garbage collected. """ - try: - return getattr(self, variable) - except AttributeError: - try: - value = self.props[propertyName].value - except (KeyError, AttributeError): - value = None - # Check if we should be overriding the data type for this instance. - if kwargs: - overrideClass = kwargs.get('overrideClass') - if overrideClass is not None and (value is not None or not kwargs.get('preserveNone', True)): - value = overrideClass(value) - setattr(self, variable, value) - return value - - def _ensureSetTyped(self, variable : str, _id, **kwargs): - """ - Like the other ensure set functions, but designed for when something - could be multiple types (where only one will be present). This way you - have no need to set the type, it will be handled for you. + if (msg := self.__msg()) is None: + raise ReferenceError('The msg file for this Recipient instance has been garbage collected.') + return msg._getStream([self.__dir, filename]) + + def _getStreamAs(self, streamID, stringStream : bool = True, overrideClass = None, preserveNone : bool = True): + """ + Returns the specified stream, modifying it to the class if specified. + + If the specified stream is not a string stream, make sure to set + :param stringStream: to False. :param overrideClass: Class/function to use to morph the data that was read. The data will be the first argument to the class's __init__ @@ -123,35 +97,18 @@ def _ensureSetTyped(self, variable : str, _id, **kwargs): :param preserveNone: If true (default), causes the function to ignore :param overrideClass: when the value could not be found (is None). If this is changed to False, then the value will be used regardless. - - :raises ReferenceError: The associated MSGFile instance has been garbage - collected. """ - try: - return getattr(self, variable) - except AttributeError: - value = self._getTypedData(_id) - # Check if we should be overriding the data type for this instance. - if kwargs: - overrideClass = kwargs.get('overrideClass') - if overrideClass is not None and (value is not None or not kwargs.get('preserveNone', True)): - value = overrideClass(value) - setattr(self, variable, value) - return value - - def _getStream(self, filename) -> Optional[bytes]: - """ - Gets a binary representation of the requested filename. + if stringStream: + value = self._getStringStream(streamID) + else: + value = self._getStream(streamID) - This should ALWAYS return a bytes object if it was found, otherwise - returns None. + # Check if we should be overriding the data type for this instance. + if overrideClass is not None: + if value is not None or not preserveNone: + value = overrideClass(value) - :raises ReferenceError: The associated MSGFile instance has been garbage - collected. - """ - if (msg := self.__msg()) is None: - raise ReferenceError('The msg file for this Recipient instance has been garbage collected.') - return msg._getStream([self.__dir, filename]) + return value def _getStringStream(self, filename) -> Optional[str]: """ @@ -171,6 +128,28 @@ def _getStringStream(self, filename) -> Optional[str]: raise ReferenceError('The msg file for this Recipient instance has been garbage collected.') return msg._getStringStream([self.__dir, filename]) + def _getTypedAs(self, _id : str, overrideClass = None, preserveNone : bool = True): + """ + Like the other get as functions, but designed for when something + could be multiple types (where only one will be present). This way you + have no need to set the type, it will be handled for you. + + :param overrideClass: Class/function to use to morph the data that was + read. The data will be the first argument to the class's __init__ + function or the function itself, if that is what is provided. By + default, this will be completely ignored if the value was not found. + :param preserveNone: If true (default), causes the function to ignore + :param overrideClass: when the value could not be found (is None). + If this is changed to False, then the value will be used regardless. + """ + value = self._getTypedData(_id) + # Check if we should be overriding the data type for this instance. + if overrideClass is not None: + if value is not None or not preserveNone: + value = overrideClass(value) + + return value + def _getTypedData(self, _id, _type = None): """ Gets the data for the specified id as the type that it is supposed to @@ -270,12 +249,12 @@ def existsTypedProperty(self, id, _type = None) -> bool: raise ReferenceError('The msg file for this Recipient instance has been garbage collected.') return msg.existsTypedProperty(id, self.__dir, _type, True, self.__props) - @property + @functools.cached_property def account(self) -> Optional[str]: """ Returns the account of this recipient. """ - return self._ensureSet('_account', '__substg1.0_3A00') + return self._getStringStream('__substg1.0_3A00') @property def email(self) -> Optional[str]: @@ -284,12 +263,12 @@ def email(self) -> Optional[str]: """ return self.__email - @property + @functools.cached_property def entryID(self) -> Optional[PermanentEntryID]: """ Returns the recipient's Entry ID. """ - return self._ensureSet('_entryID', '__substg1.0_0FFF0102', False, overrideClass = PermanentEntryID) + return self._getStreamAs('__substg1.0_0FFF0102', False, PermanentEntryID) @property def formatted(self) -> str: @@ -298,12 +277,12 @@ def formatted(self) -> str: """ return self.__formatted - @property + @functools.cached_property def instanceKey(self) -> Optional[bytes]: """ Returns the instance key of this recipient. """ - return self._ensureSet('_instanceKey', '__substg1.0_0FF60102', False) + return self._getStream('__substg1.0_0FF60102') @property def name(self) -> Optional[str]: @@ -319,33 +298,33 @@ def props(self) -> PropertiesStore: """ return self.__props - @property + @functools.cached_property def recordKey(self) -> Optional[bytes]: """ Returns the instance key of this recipient. """ - return self._ensureSet('_recordKey', '__substg1.0_0FF90102', False) + return self._getStream('__substg1.0_0FF90102') - @property + @functools.cached_property def searchKey(self) -> Optional[bytes]: """ Returns the search key of this recipient. """ - return self._ensureSet('_searchKey', '__substg1.0_300B0102', False) + return self._getStream('__substg1.0_300B0102') - @property + @functools.cached_property def smtpAddress(self) -> Optional[str]: """ Returns the SMTP address of this recipient. """ - return self._ensureSet('_smtpAddress', '__substg1.0_39FE') + return self._getStringStream('__substg1.0_39FE') - @property + @functools.cached_property def transmittableDisplayName(self) -> Optional[str]: """ Returns the transmittable display name of this recipient. """ - return self._ensureSet('_transmittableDisplayName', '__substg1.0_3A20') + return self._getStringStream('__substg1.0_3A20') @property def type(self) -> Union[RecipientType, MeetingRecipientType]: From 1bca36f987ec875510a0792de1d427d20efb2822 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Sun, 2 Jul 2023 01:36:26 -0700 Subject: [PATCH 68/89] Fix minor issues --- extract_msg/attachments/attachment_base.py | 6 ++++-- extract_msg/msg_classes/contact.py | 2 +- extract_msg/msg_classes/message_base.py | 4 ++-- extract_msg/msg_classes/msg.py | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/extract_msg/attachments/attachment_base.py b/extract_msg/attachments/attachment_base.py index 39a5c68b..f5a54a04 100644 --- a/extract_msg/attachments/attachment_base.py +++ b/extract_msg/attachments/attachment_base.py @@ -342,8 +342,6 @@ def cid(self) -> Optional[str]: """ return self._getStringStream('__substg1.0_3712') - contendId = cid - @cached_property def clsid(self) -> str: """ @@ -373,6 +371,10 @@ def clsid(self) -> str: return clsid + @property + def contentId(self) -> Optional[str]: + return self.cid + @property @abc.abstractmethod def data(self) -> Optional[object]: diff --git a/extract_msg/msg_classes/contact.py b/extract_msg/msg_classes/contact.py index 09e8b216..656c9b95 100644 --- a/extract_msg/msg_classes/contact.py +++ b/extract_msg/msg_classes/contact.py @@ -240,7 +240,7 @@ def childrensNames(self) -> Optional[List[str]]: """ A list of the named of the contact's children. """ - return self._getStringStream('3A58') + return self._getTypedAs('3A58') @functools.cached_property def companyMainTelephoneNumber(self) -> Optional[str]: diff --git a/extract_msg/msg_classes/message_base.py b/extract_msg/msg_classes/message_base.py index 8693a1c8..8907c9e8 100644 --- a/extract_msg/msg_classes/message_base.py +++ b/extract_msg/msg_classes/message_base.py @@ -925,9 +925,9 @@ def crlf(self) -> str: @functools.cached_property def date(self) -> Optional[datetime.datetime]: """ - Returns the string for the send date, if it exists. + Returns the send date, if it exists. """ - return self._prop.date if self.isSent else None + return self.props.date if self.isSent else None @property def deencapsulatedRtf(self) -> Optional[RTFDE.DeEncapsulator]: diff --git a/extract_msg/msg_classes/msg.py b/extract_msg/msg_classes/msg.py index c6a4ef95..f7007809 100644 --- a/extract_msg/msg_classes/msg.py +++ b/extract_msg/msg_classes/msg.py @@ -697,7 +697,7 @@ def classType(self) -> Optional[str]: """ The class type of the MSG file. """ - return self._getStringStream('_classType', '__substg1.0_001A') + return self._getStringStream('__substg1.0_001A') @functools.cached_property def commonEnd(self) -> Optional[datetime.datetime]: From 114465eebfa69934a23576ffbafabfefee0c015e Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Sun, 2 Jul 2023 15:56:57 -0700 Subject: [PATCH 69/89] Start update for helper script --- helper-scripts/detect-prop-overlap.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/helper-scripts/detect-prop-overlap.py b/helper-scripts/detect-prop-overlap.py index f3209b51..14e94a47 100644 --- a/helper-scripts/detect-prop-overlap.py +++ b/helper-scripts/detect-prop-overlap.py @@ -10,26 +10,27 @@ def main(args): overlapping if they share the same variable name or come from the same property. This may be intentional for some properties. """ + raise Exception('This script needs to be rewritten for the new property system.') if len(args) < 2: print('Please specify a file to read.') sys.exit(1) - pattern = re.compile(r"(?<=self._ensureSet)((Named)|(Property)|(Typed))?\('(.*?)', '(.*?)'") + pattern = re.compile(r"(?<=self._get)((Named)|(Property)|(Typed)|(Stream))As\('(.*?)'") for patt in args[1:]: for name in glob.glob(patt): with open(name, 'r', encoding = 'utf-8') as f: data = f.read() - names = tuple(sorted(x.group(5) for x in pattern.finditer(data))) + #names = tuple(sorted(x.group(5) for x in pattern.finditer(data))) ids = tuple(sorted(x.group(6) for x in pattern.finditer(data))) - duplicateNamesFound = len(names) != len(list(set(names))) + #duplicateNamesFound = len(names) != len(list(set(names))) duplicateIdsFound = len(ids) != len(list(set(names))) print(name) - if duplicateNamesFound: + if False:#duplicateNamesFound: print('\tVariable Names:') counts = {x: 0 for x in names} for x in names: @@ -47,7 +48,7 @@ def main(args): if counts[x] > 1: print(f'\t\t{x}') - if not duplicateIdsFound and not duplicateNamesFound: + if not duplicateIdsFound:# and not duplicateNamesFound: print('\tNo duplicates detected.') print() From 0edcb0833d708bf905b8fa4a415e82fb40c77a3c Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Sun, 2 Jul 2023 17:11:33 -0700 Subject: [PATCH 70/89] Fix exports of enum. --- extract_msg/enums.py | 90 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 71 insertions(+), 19 deletions(-) diff --git a/extract_msg/enums.py b/extract_msg/enums.py index 909df543..e1c4d459 100644 --- a/extract_msg/enums.py +++ b/extract_msg/enums.py @@ -1,27 +1,79 @@ __all__ = [ - 'AddressBookType', 'AppointmentAuxilaryFlag', 'AppointmentColor', - 'AppointmentStateFlag', 'AttachErrorBehavior', 'AttachmentType', - 'BCImageAlignment', 'BCImageSource', 'BCLabelFormat', 'BCTemplateID', - 'BCTextFormat', 'BodyTypes', 'BusyStatus', 'ClientIntentFlag', 'Color', - 'ContactAddressIndex', 'ContactLinkState', 'DeencapType', - 'DirectoryEntryType', 'DisplayType', 'ElectronicAddressProperties', - 'EntryIDType', 'EntryIDTypeHex', 'ErrorCode', 'ErrorCodeType', 'Gender', - 'IconIndex', 'Importance', 'Intelligence', 'MacintoshEncoding', - 'MeetingObjectChange', 'MeetingRecipientType', 'MeetingType', - 'MessageFormat', 'MessageType', 'NamedPropertyType', 'OORBodyFormat', - 'PostalAddressID', 'Priority', 'PropertiesType', 'RecipientRowFlagType', - 'RecipientType', 'RecurCalendarType', 'RecurDOW', 'RecurEndType', - 'RecurFrequency', 'RecurMonthNthWeek', 'RecurPatternTypeSpecificWeekday', - 'RecurPatternType', 'ResponseStatus', 'ResponseType', 'RuleActionType', - 'Sensitivity', 'ServerProcessingAction', 'SideEffect', 'TaskAcceptance', - 'TaskHistory', 'TaskMode', 'TaskMultipleRecipients', 'TaskOwnership', - 'TaskRequestType', 'TaskState', 'TaskStatus', 'TZFlag', + 'AddressBookType', + 'AppointmentAuxilaryFlag', + 'AppointmentColor', + 'AppointmentStateFlag', + 'AttachmentPermissionType', + 'AttachmentType', + 'BCImageAlignment', + 'BCImageSource', + 'BCLabelFormat', + 'BCTemplateID', + 'BCTextFormat', + 'BodyTypes', + 'BusyStatus', + 'ClientIntentFlag', + 'Color', + 'ContactAddressIndex', + 'ContactLinkState', + 'DeencapType', + 'DirectoryEntryType', + 'DisplayType', + 'DVAspect', + 'ElectronicAddressProperties', + 'EntryIDType', + 'EntryIDTypeHex', + 'ErrorBehavior', + 'ErrorCode', + 'ErrorCodeType', + 'Gender', + 'IconIndex', + 'Importance', + 'InsecureFeatures', + 'Intelligence', + 'MacintoshEncoding', + 'MeetingObjectChange', + 'MeetingRecipientType', + 'MeetingType', + 'MessageFormat', + 'MessageType', + 'NamedPropertyType', + 'NoteColor', + 'OORBodyFormat', + 'PostalAddressID', + 'Priority', + 'PropertiesType', + 'RecipientRowFlagType', + 'RecipientType', + 'RecurCalendarType', + 'RecurDOW', + 'RecurEndType', + 'RecurFrequency', + 'RecurMonthNthWeek', + 'RecurPatternTypeSpecificWeekday', + 'RecurPatternType', + 'ResponseStatus', + 'ResponseType', + 'RuleActionType', + 'SaveType', + 'Sensitivity', + 'ServerProcessingAction', + 'SideEffect', + 'TaskAcceptance', + 'TaskHistory', + 'TaskMode', + 'TaskMultipleRecipients', + 'TaskOwnership', + 'TaskRequestType', + 'TaskState', + 'TaskStatus', + 'TZFlag', ] import enum -from typing import Set, Union +from typing import Union class AddressBookType(enum.Enum): @@ -1754,7 +1806,7 @@ def __getitem__(self, name): -# Deprecated Enums +# Deprecated Enums. These are not exported but may be directly accessed. AttachErrorBehavior = _EnumDeprecator( 'AttachErrorBehavior', ErrorBehavior, From 00b7446ad9b028a51ff92056d40d41d066c2e017 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Sun, 2 Jul 2023 17:18:04 -0700 Subject: [PATCH 71/89] Export fixes and internal updates --- extract_msg/__init__.py | 8 +- extract_msg/constants/__init__.py | 20 ++- extract_msg/msg_classes/__init__.py | 2 +- extract_msg/msg_classes/appointment.py | 24 ++-- extract_msg/msg_classes/calendar.py | 20 +-- extract_msg/msg_classes/calendar_base.py | 102 +++++++-------- extract_msg/msg_classes/contact.py | 150 +++++++++++------------ extract_msg/open_msg.py | 34 +++-- extract_msg/properties/prop.py | 5 +- 9 files changed, 200 insertions(+), 165 deletions(-) diff --git a/extract_msg/__init__.py b/extract_msg/__init__.py index 4676a8cc..eb2670ce 100644 --- a/extract_msg/__init__.py +++ b/extract_msg/__init__.py @@ -50,12 +50,16 @@ 'Recipient', 'SignedAttachment', - #Functions: + # Functions: 'openMsg', 'openMsgBulk', ] -from . import attachments, enums, exceptions, msg_classes, properties + +# Ensure these are imported before anything else. +from . import constants, enums, exceptions + +from . import attachments, msg_classes, properties from .attachments import Attachment, AttachmentBase, SignedAttachment from .msg_classes import Message, MSGFile from .ole_writer import OleWriter diff --git a/extract_msg/constants/__init__.py b/extract_msg/constants/__init__.py index e17cc29a..4371e030 100644 --- a/extract_msg/constants/__init__.py +++ b/extract_msg/constants/__init__.py @@ -31,7 +31,12 @@ 'NEEDS_ARG', 'NULL_DATE', 'PTYPES', - 'PYTPFLOATINGTIME_START', 'VARIABLE_LENGTH_PROPS', 'VARIABLE_LENGTH_PROPS_STRING', + 'PYTPFLOATINGTIME_START', + 'REFUSED_CLASS_TYPES', + 'REPOSITORY_URL', + 'SAVE_TYPE', + 'VARIABLE_LENGTH_PROPS', + 'VARIABLE_LENGTH_PROPS_STRING', ] @@ -205,6 +210,12 @@ 'report', ) +# Each item is a tuple of the lowercase class type and the issue number +# associated with it. +REFUSED_CLASS_TYPES = ( + ('ipm.outlook.recall', '235'), +) + PYTPFLOATINGTIME_START = datetime.datetime(1899, 12, 30) NULL_DATE = datetime.datetime(4500, 8, 31, 23, 59) @@ -215,8 +226,11 @@ NEEDS_ARG = ( '--out-name', ) -MAINDOC = "extract_msg:\n\tExtracts emails and attachments saved in Microsoft Outlook's .msg files.\n\n" \ - "https://github.com/TeamMsgExtractor/msg-extractor" +REPOSITORY_URL = 'https://github.com/TeamMsgExtractor/msg-extractor' +MAINDOC = f"""extract_msg: +\tExtracts emails and attachments saved in Microsoft Outlook's .msg files. + +{REPOSITORY_URL}""" # Default class ID for the root entry for OleWriter. This should be # referencing Outlook if I understand it correctly. diff --git a/extract_msg/msg_classes/__init__.py b/extract_msg/msg_classes/__init__.py index 989e3b8e..e22dd0b4 100644 --- a/extract_msg/msg_classes/__init__.py +++ b/extract_msg/msg_classes/__init__.py @@ -3,7 +3,7 @@ """ __all__ = [ - # Classes. + # Classes: 'AppointmentMeeting', 'Calendar', 'CalendarBase', diff --git a/extract_msg/msg_classes/appointment.py b/extract_msg/msg_classes/appointment.py index 88a69fb3..e205c3fd 100644 --- a/extract_msg/msg_classes/appointment.py +++ b/extract_msg/msg_classes/appointment.py @@ -8,9 +8,9 @@ from typing import Optional -from .. import constants -from ..enums import AppointmentStateFlag, RecurPatternType, ResponseStatus +from ..constants import HEADER_FORMAT_TYPE, ps from .calendar import Calendar +from ..enums import AppointmentStateFlag, RecurPatternType, ResponseStatus from ..structures.entry_id import EntryID @@ -29,14 +29,14 @@ def appointmentCounterProposal(self) -> bool: Indicates to the organizer that there are counter proposals that have not been accepted or rejected by the organizer. """ - return self._getNamedAs('8257', constants.ps.PSETID_APPOINTMENT, bool, False) + return self._getNamedAs('8257', ps.PSETID_APPOINTMENT, bool, False) @functools.cached_property def appointmentLastSequence(self) -> Optional[int]: """ The last sequence number that was sent to any attendee. """ - return self._getNamedAs('8203', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8203', ps.PSETID_APPOINTMENT) @functools.cached_property def appointmentProposalNumber(self) -> Optional[int]: @@ -44,14 +44,14 @@ def appointmentProposalNumber(self) -> Optional[int]: The number of attendees who have sent counter propostals that have not been accepted or rejected by the organizer. """ - return self._getNamedAs('8259', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8259', ps.PSETID_APPOINTMENT) @functools.cached_property def appointmentReplyName(self) -> Optional[datetime.datetime]: """ The user who last replied to the meeting request or meeting update. """ - return self._getNamedAs('8230', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8230', ps.PSETID_APPOINTMENT) @functools.cached_property def appointmentReplyTime(self) -> Optional[datetime.datetime]: @@ -59,7 +59,7 @@ def appointmentReplyTime(self) -> Optional[datetime.datetime]: The date and time at which the attendee responded to a received Meeting Request object of Meeting Update object in UTC. """ - return self._getNamedAs('8220', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8220', ps.PSETID_APPOINTMENT) @functools.cached_property def appointmentSequenceTime(self) -> Optional[datetime.datetime]: @@ -67,7 +67,7 @@ def appointmentSequenceTime(self) -> Optional[datetime.datetime]: The date and time at which the appointmentSequence property was last modified. """ - return self._getNamedAs('8202', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8202', ps.PSETID_APPOINTMENT) @functools.cached_property def autoFillLocation(self) -> bool: @@ -79,17 +79,17 @@ def autoFillLocation(self) -> bool: A value of False indicates that the value of the location property is not automatically set. """ - return self._getNamedAs('823A', constants.ps.PSETID_APPOINTMENT, bool, False) + return self._getNamedAs('823A', ps.PSETID_APPOINTMENT, bool, False) @functools.cached_property def fInvited(self) -> bool: """ Whether a Meeting Request object has been sent out. """ - return self._getNamedAs('8229', constants.ps.PSETID_APPOINTMENT, bool, False) + return self._getNamedAs('8229', ps.PSETID_APPOINTMENT, bool, False) @property - def headerFormatProperties(self) -> constants.HEADER_FORMAT_TYPE: + def headerFormatProperties(self) -> HEADER_FORMAT_TYPE: """ Returns a dictionary of properties, in order, to be formatted into the header. Keys are the names to use in the header while the values are one @@ -175,4 +175,4 @@ def originalStoreEntryID(self) -> Optional[EntryID]: """ The EntryID of the delegator's message store. """ - return self._getNamedAs('8237', constants.ps.PSETID_APPOINTMENT, EntryID.autoCreate) + return self._getNamedAs('8237', ps.PSETID_APPOINTMENT, EntryID.autoCreate) diff --git a/extract_msg/msg_classes/calendar.py b/extract_msg/msg_classes/calendar.py index fa1c7e44..c97144e0 100644 --- a/extract_msg/msg_classes/calendar.py +++ b/extract_msg/msg_classes/calendar.py @@ -8,7 +8,7 @@ from typing import Optional -from .. import constants +from ..constants import ps from .calendar_base import CalendarBase from ..enums import ClientIntentFlag @@ -23,7 +23,7 @@ def clientIntent(self) -> Optional[ClientIntentFlag]: """ A set of the actions a user has taken on a Meeting object. """ - return self._getNamedAs('0015', constants.ps.PSETID_CALENDAR_ASSISTANT, ClientIntentFlag) + return self._getNamedAs('0015', ps.PSETID_CALENDAR_ASSISTANT, ClientIntentFlag) @functools.cached_property def fExceptionalAttendees(self) -> Optional[bool]: @@ -35,7 +35,7 @@ def fExceptionalAttendees(self) -> Optional[bool]: SHOULD NOT be set for any Calendar object other than that of the organizer's. """ - return self._getNamedAs('822B', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('822B', ps.PSETID_APPOINTMENT) @functools.cached_property def reminderDelta(self) -> Optional[int]: @@ -43,7 +43,7 @@ def reminderDelta(self) -> Optional[int]: The interval, in minutes, between the time at which the reminder first becomes overdue and the start time of the Calendar object. """ - return self._getNamedAs('8501', constants.ps.PSETID_COMMON) + return self._getNamedAs('8501', ps.PSETID_COMMON) @functools.cached_property def reminderFileParameter(self) -> Optional[str]: @@ -52,7 +52,7 @@ def reminderFileParameter(self) -> Optional[str]: client SHOULD play when the reminder for the Message Object becomes overdue. """ - return self._getNamedAs('851F', constants.ps.PSETID_COMMON) + return self._getNamedAs('851F', ps.PSETID_COMMON) @functools.cached_property def reminderOverride(self) -> bool: @@ -60,7 +60,7 @@ def reminderOverride(self) -> bool: Specifies if clients SHOULD respect the value of the reminderPlaySound property and the reminderFileParameter property. """ - return self._getNamedAs('851C', constants.ps.PSETID_COMMON, bool, False) + return self._getNamedAs('851C', ps.PSETID_COMMON, bool, False) @functools.cached_property def reminderPlaySound(self) -> bool: @@ -68,25 +68,25 @@ def reminderPlaySound(self) -> bool: Specified that the cliebnt should play a sound when the reminder becomes overdue. """ - return self._getNamedAs('851E', constants.ps.PSETID_COMMON, bool, False) + return self._getNamedAs('851E', ps.PSETID_COMMON, bool, False) @functools.cached_property def reminderSet(self) -> bool: """ Specifies whether a reminder is set on the object. """ - return self._getNamedAs('8503', constants.ps.PSETID_COMMON, bool, False) + return self._getNamedAs('8503', ps.PSETID_COMMON, bool, False) @functools.cached_property def reminderSignalTime(self) -> Optional[datetime.datetime]: """ The point in time when a reminder transitions from pending to overdue. """ - return self._getNamedAs('8560', constants.ps.PSETID_COMMON) + return self._getNamedAs('8560', ps.PSETID_COMMON) @functools.cached_property def reminderTime(self) -> Optional[datetime.datetime]: """ The time after which the user would be late. """ - return self._getNamedAs('8502', constants.ps.PSETID_COMMON) + return self._getNamedAs('8502', ps.PSETID_COMMON) diff --git a/extract_msg/msg_classes/calendar_base.py b/extract_msg/msg_classes/calendar_base.py index 5b22109b..73e1ed75 100644 --- a/extract_msg/msg_classes/calendar_base.py +++ b/extract_msg/msg_classes/calendar_base.py @@ -9,7 +9,7 @@ from typing import List, Optional, Union -from .. import constants +from ..constants import ps from ..enums import AppointmentAuxilaryFlag, AppointmentColor, AppointmentStateFlag, BusyStatus, IconIndex, MeetingRecipientType, ResponseStatus from .message_base import MessageBase from ..structures.entry_id import EntryID @@ -72,35 +72,35 @@ def allAttendeesString(self) -> Optional[str]: """ A list of all attendees, excluding the organizer. """ - return self._getNamedAs('8238', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8238', ps.PSETID_APPOINTMENT) @functools.cached_property def appointmentAuxilaryFlags(self) -> Optional[AppointmentAuxilaryFlag]: """ The auxiliary state of the object. """ - return self._getNamedAs('8207', constants.ps.PSETID_APPOINTMENT, AppointmentAuxilaryFlag) + return self._getNamedAs('8207', ps.PSETID_APPOINTMENT, AppointmentAuxilaryFlag) @functools.cached_property def appointmentColor(self) -> Optional[AppointmentColor]: """ The color to be used when displaying a Calendar object. """ - return self._getNamedAs('8214', constants.ps.PSETID_APPOINTMENT, AppointmentColor) + return self._getNamedAs('8214', ps.PSETID_APPOINTMENT, AppointmentColor) @functools.cached_property def appointmentDuration(self) -> Optional[int]: """ The length of the event, in minutes. """ - return self._getNamedAs('8213', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8213', ps.PSETID_APPOINTMENT) @functools.cached_property def appointmentEndWhole(self) -> Optional[datetime.datetime]: """ The end date and time of the event in UTC. """ - return self._getNamedAs('820E', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('820E', ps.PSETID_APPOINTMENT) @functools.cached_property def appointmentNotAllowPropose(self) -> bool: @@ -108,7 +108,7 @@ def appointmentNotAllowPropose(self) -> bool: Indicates that attendees are not allowed to propose a new date and/or time for the meeting if True. """ - return self._getNamedAs('8259', constants.ps.PSETID_APPOINTMENT, bool, False) + return self._getNamedAs('8259', ps.PSETID_APPOINTMENT, bool, False) @functools.cached_property def appointmentRecur(self) -> Optional[RecurrencePattern]: @@ -116,7 +116,7 @@ def appointmentRecur(self) -> Optional[RecurrencePattern]: Specifies the dates and times when a recurring series occurs by using one of the recurrence patterns and ranges specified in this section. """ - return self._getNamedAs('8216', constants.ps.PSETID_APPOINTMENT, RecurrencePattern) + return self._getNamedAs('8216', ps.PSETID_APPOINTMENT, RecurrencePattern) @functools.cached_property def appointmentSequence(self) -> Optional[int]: @@ -125,28 +125,28 @@ def appointmentSequence(self) -> Optional[int]: begins with the sequence number set to 0 and is incremented each time the organizer sends out a Meeting Update object. """ - return self._getNamedAs('8201', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8201', ps.PSETID_APPOINTMENT) @functools.cached_property def appointmentStartWhole(self) -> Optional[datetime.datetime]: """ The start date and time of the event in UTC. """ - return self._getNamedAs('820D', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('820D', ps.PSETID_APPOINTMENT) @functools.cached_property def appointmentStateFlags(self) -> Optional[AppointmentStateFlag]: """ The appointment state of the object. """ - return self._getNamedAs('8217', constants.ps.PSETID_APPOINTMENT, AppointmentStateFlag) + return self._getNamedAs('8217', ps.PSETID_APPOINTMENT, AppointmentStateFlag) @functools.cached_property def appointmentSubType(self) -> bool: """ Whether the event is an all-day event or not. """ - return self._getNamedAs('8215', constants.ps.PSETID_APPOINTMENT, bool, False) + return self._getNamedAs('8215', ps.PSETID_APPOINTMENT, bool, False) @functools.cached_property def appointmentTimeZoneDefinitionEndDisplay(self) -> Optional[TimeZoneDefinition]: @@ -154,7 +154,7 @@ def appointmentTimeZoneDefinitionEndDisplay(self) -> Optional[TimeZoneDefinition Specifies the time zone information for the appointmentEndWhole property Used to convert the end date and time to and from UTC. """ - return self._getNamedAs('825F', constants.ps.PSETID_APPOINTMENT, TimeZoneDefinition) + return self._getNamedAs('825F', ps.PSETID_APPOINTMENT, TimeZoneDefinition) @functools.cached_property def appointmentTimeZoneDefinitionRecur(self) -> Optional[TimeZoneDefinition]: @@ -162,7 +162,7 @@ def appointmentTimeZoneDefinitionRecur(self) -> Optional[TimeZoneDefinition]: Specified the time zone information that specifies how to convert the meeting date and time on a recurring series to and from UTC. """ - return self._getNamedAs('8260', constants.ps.PSETID_APPOINTMENT, TimeZoneDefinition) + return self._getNamedAs('8260', ps.PSETID_APPOINTMENT, TimeZoneDefinition) @functools.cached_property def appointmentTimeZoneDefinitionStartDisplay(self) -> Optional[TimeZoneDefinition]: @@ -170,7 +170,7 @@ def appointmentTimeZoneDefinitionStartDisplay(self) -> Optional[TimeZoneDefiniti Specifies the time zone information for the appointmentStartWhole property. Used to convert the start date and time to and from UTC. """ - return self._getNamedAs('825E', constants.ps.PSETID_APPOINTMENT, TimeZoneDefinition) + return self._getNamedAs('825E', ps.PSETID_APPOINTMENT, TimeZoneDefinition) @functools.cached_property def appointmentUnsendableRecipients(self) -> Optional[bytes]: @@ -181,7 +181,7 @@ def appointmentUnsendableRecipients(self) -> Optional[bytes]: the specifications. If you have examples, let me know and I can ask you to run a verification on it. """ - return self._getNamedAs('825D', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('825D', ps.PSETID_APPOINTMENT) @functools.cached_property def bcc(self) -> Optional[str]: @@ -195,14 +195,14 @@ def birthdayContactAttributionDisplayName(self) -> Optional[str]: """ Indicated the name of the contact associated with the birthday event. """ - return self._getNamedAs('BirthdayContactAttributionDisplayName', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('BirthdayContactAttributionDisplayName', ps.PSETID_ADDRESS) @functools.cached_property def birthdayContactEntryID(self) -> Optional[EntryID]: """ Indicates the EntryID of the contact associated with the birthday event. """ - return self._getNamedAs('BirthdayContactEntryId', constants.ps.PSETID_ADDRESS, EntryID.autoCreate) + return self._getNamedAs('BirthdayContactEntryId', ps.PSETID_ADDRESS, EntryID.autoCreate) @functools.cached_property def birthdayContactPersonGuid(self) -> Optional[bytes]: @@ -210,7 +210,7 @@ def birthdayContactPersonGuid(self) -> Optional[bytes]: Indicates the person ID's GUID of the contact associated with the birthday event. """ - return self._getNamedAs('BirthdayContactPersonGuid', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('BirthdayContactPersonGuid', ps.PSETID_ADDRESS) @functools.cached_property def busyStatus(self) -> Optional[BusyStatus]: @@ -218,7 +218,7 @@ def busyStatus(self) -> Optional[BusyStatus]: Specified the availability of a user for the event described by the object. """ - return self._getNamedAs('8205', constants.ps.PSETID_APPOINTMENT, BusyStatus) + return self._getNamedAs('8205', ps.PSETID_APPOINTMENT, BusyStatus) @functools.cached_property def cc(self) -> Optional[str]: @@ -232,7 +232,7 @@ def ccAttendeesString(self) -> Optional[str]: """ A list of all the sendable attendees, who are also optional attendees. """ - return self._getNamedAs('823C', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('823C', ps.PSETID_APPOINTMENT) @functools.cached_property def cleanGlobalObjectID(self) -> Optional[GlobalObjectID]: @@ -241,7 +241,7 @@ def cleanGlobalObjectID(self) -> Optional[GlobalObjectID]: an Exception object to a recurring series, where the year, month, and day fields are all 0. """ - return self._getNamedAs('0023', constants.ps.PSETID_MEETING, GlobalObjectID) + return self._getNamedAs('0023', ps.PSETID_MEETING, GlobalObjectID) @functools.cached_property def clipEnd(self) -> Optional[datetime.datetime]: @@ -254,7 +254,7 @@ def clipEnd(self) -> Optional[datetime.datetime]: Honestly, not sure what this is. [MS-OXOCAL]: PidLidClipEnd. """ - return self._getNamedAs('8236', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8236', ps.PSETID_APPOINTMENT) @functools.cached_property def clipStart(self) -> Optional[datetime.datetime]: @@ -265,14 +265,14 @@ def clipStart(self) -> Optional[datetime.datetime]: Honestly, not sure what this is. [MS-OXOCAL]: PidLidClipStart. """ - return self._getNamedAs('8235', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8235', ps.PSETID_APPOINTMENT) @functools.cached_property def commonEnd(self) -> Optional[datetime.datetime]: """ The end date and time of an event. MUST be equal to appointmentEndWhole. """ - return self._getNamedAs('8517', constants.ps.PSETID_COMMON) + return self._getNamedAs('8517', ps.PSETID_COMMON) @functools.cached_property def commonStart(self) -> Optional[datetime.datetime]: @@ -280,7 +280,7 @@ def commonStart(self) -> Optional[datetime.datetime]: The start date and time of an event. MUST be equal to appointmentStartWhole. """ - return self._getNamedAs('8516', constants.ps.PSETID_COMMON) + return self._getNamedAs('8516', ps.PSETID_COMMON) @functools.cached_property def endDate(self) -> Optional[datetime.datetime]: @@ -294,7 +294,7 @@ def globalObjectID(self) -> Optional[GlobalObjectID]: """ The unique identifier or the Calendar object. """ - return self._getNamedAs('0003', constants.ps.PSETID_MEETING, GlobalObjectID) + return self._getNamedAs('0003', ps.PSETID_MEETING, GlobalObjectID) @functools.cached_property def iconIndex(self) -> Optional[Union[IconIndex, int]]: @@ -309,7 +309,7 @@ def isBirthdayContactWritable(self) -> bool: Indicates whether the contact associated with the birthday event is writable. """ - return self._getNamedAs('IsBirthdayContactWritable', constants.ps.PSETID_ADDRESS, bool, False) + return self._getNamedAs('IsBirthdayContactWritable', ps.PSETID_ADDRESS, bool, False) @functools.cached_property def isException(self) -> bool: @@ -317,21 +317,21 @@ def isException(self) -> bool: Whether the object represents an exception. False indicates that the object represents a recurring series or a single-instance object. """ - return self._getNamedAs('000A', constants.ps.PSETID_MEETING, bool, False) + return self._getNamedAs('000A', ps.PSETID_MEETING, bool, False) @functools.cached_property def isRecurring(self) -> bool: """ Whether the object is associated with a recurring series. """ - return self._getNamedAs('0005', constants.ps.PSETID_MEETING, bool, False) + return self._getNamedAs('0005', ps.PSETID_MEETING, bool, False) @functools.cached_property def keywords(self) -> Optional[List[str]]: """ The color to be used when displaying a Calendar object. """ - return self._getNamedAs('Keywords', constants.ps.PS_PUBLIC_STRINGS) + return self._getNamedAs('Keywords', ps.PS_PUBLIC_STRINGS) @functools.cached_property def linkedTaskItems(self) -> Optional[List[EntryID]]: @@ -339,21 +339,21 @@ def linkedTaskItems(self) -> Optional[List[EntryID]]: A list of PidTagEntryId properties of Task objects related to the Calendar object that are set by a client. """ - return self._getNamedAs('820C', constants.ps.PSETID_APPOINTMENT, lambda x : list(EntryID.autoCreate(y) for y in x)) + return self._getNamedAs('820C', ps.PSETID_APPOINTMENT, lambda x : list(EntryID.autoCreate(y) for y in x)) @functools.cached_property def location(self) -> Optional[str]: """ Returns the location of the meeting. """ - return self._getNamedAs('8208', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8208', ps.PSETID_APPOINTMENT) @functools.cached_property def meetingDoNotForward(self) -> bool: """ Whether to allow the meeting to be forwarded. True disallows forwarding. """ - return self._getNamedAs('DoNotForward', constants.ps.PS_PUBLIC_STRINGS, bool, False) + return self._getNamedAs('DoNotForward', ps.PS_PUBLIC_STRINGS, bool, False) @functools.cached_property def meetingWorkspaceUrl(self) -> Optional[str]: @@ -361,56 +361,56 @@ def meetingWorkspaceUrl(self) -> Optional[str]: The URL of the Meeting Workspace, as specified in [MS-MEETS], that is associated with a Calendar object. """ - return self._getNamedAs('8209', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8209', ps.PSETID_APPOINTMENT) @functools.cached_property def nonSendableBcc(self) -> Optional[str]: """ A list of all unsendable attendees who are also resource objects. """ - return self._getNamedAs('8538', constants.ps.PSETID_COMMON) + return self._getNamedAs('8538', ps.PSETID_COMMON) @functools.cached_property def nonSendableCc(self) -> Optional[str]: """ A list of all unsendable attendees who are also optional attendees. """ - return self._getNamedAs('8537', constants.ps.PSETID_COMMON) + return self._getNamedAs('8537', ps.PSETID_COMMON) @functools.cached_property def nonSendableTo(self) -> Optional[str]: """ A list of all unsendable attendees who are also required attendees. """ - return self._getNamedAs('8536', constants.ps.PSETID_COMMON) + return self._getNamedAs('8536', ps.PSETID_COMMON) @functools.cached_property def nonSendBccTrackStatus(self) -> Optional[List[ResponseStatus]]: """ A ResponseStatus for each of the attendees in nonSendableBcc. """ - return self._getNamedAs('8545', constants.ps.PSETID_COMMON, lambda x : list(ResponseStatus(y) for y in x)) + return self._getNamedAs('8545', ps.PSETID_COMMON, lambda x : list(ResponseStatus(y) for y in x)) @functools.cached_property def nonSendCcTrackStatus(self) -> Optional[List[ResponseStatus]]: """ A ResponseStatus for each of the attendees in nonSendableCc. """ - return self._getNamedAs('8544', constants.ps.PSETID_COMMON, lambda x : list(ResponseStatus(y) for y in x)) + return self._getNamedAs('8544', ps.PSETID_COMMON, lambda x : list(ResponseStatus(y) for y in x)) @functools.cached_property def nonSendToTrackStatus(self) -> Optional[List[ResponseStatus]]: """ A ResponseStatus for each of the attendees in nonSendableTo. """ - return self._getNamedAs('8543', constants.ps.PSETID_COMMON, lambda x : list(ResponseStatus(y) for y in x)) + return self._getNamedAs('8543', ps.PSETID_COMMON, lambda x : list(ResponseStatus(y) for y in x)) @functools.cached_property def optionalAttendees(self) -> Optional[str]: """ Returns the optional attendees of the meeting. """ - return self._getNamedAs('0007', constants.ps.PSETID_MEETING) + return self._getNamedAs('0007', ps.PSETID_MEETING) @property def organizer(self) -> Optional[str]: @@ -434,7 +434,7 @@ def ownerCriticalChange(self) -> Optional[datetime.datetime]: The date and time at which a Meeting Request object was sent by the organizer, in UTC. """ - return self._getNamedAs('001A', constants.ps.PSETID_MEETING) + return self._getNamedAs('001A', ps.PSETID_MEETING) @functools.cached_property def recurrencePattern(self) -> Optional[str]: @@ -442,14 +442,14 @@ def recurrencePattern(self) -> Optional[str]: A description of the recurrence specified by the appointmentRecur property. """ - return self._getNamedAs('8232', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8232', ps.PSETID_APPOINTMENT) @functools.cached_property def recurring(self) -> bool: """ Specifies whether the object represents a recurring series. """ - return self._getNamedAs('8223', constants.ps.PSETID_APPOINTMENT, bool, True) + return self._getNamedAs('8223', ps.PSETID_APPOINTMENT, bool, True) @functools.cached_property def replyRequested(self) -> bool: @@ -463,14 +463,14 @@ def requiredAttendees(self) -> Optional[str]: """ Returns the required attendees of the meeting. """ - return self._getNamedAs('0006', constants.ps.PSETID_MEETING) + return self._getNamedAs('0006', ps.PSETID_MEETING) @functools.cached_property def resourceAttendees(self) -> Optional[str]: """ Returns the resource attendees of the meeting. """ - return self._getNamedAs('0008', constants.ps.PSETID_MEETING) + return self._getNamedAs('0008', ps.PSETID_MEETING) @functools.cached_property def responseRequested(self) -> bool: @@ -484,7 +484,7 @@ def responseStatus(self) -> ResponseStatus: """ The response status of an attendee. """ - return self._getNamedAs('8218', constants.ps.PSETID_APPOINTMENT, lambda x: ResponseStatus(x or 0), False) + return self._getNamedAs('8218', ps.PSETID_APPOINTMENT, lambda x: ResponseStatus(x or 0), False) @functools.cached_property def startDate(self) -> Optional[datetime.datetime]: @@ -499,7 +499,7 @@ def timeZoneDescription(self) -> Optional[str]: A human-readable description of the time zone that is represented by the data in the timeZoneStruct property. """ - return self._getNamedAs('8234', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8234', ps.PSETID_APPOINTMENT) @functools.cached_property def timeZoneStruct(self) -> Optional[TimeZoneStruct]: @@ -507,7 +507,7 @@ def timeZoneStruct(self) -> Optional[TimeZoneStruct]: Set on a recurring series to specify time zone information. Specifies how to convert time fields between local time and UTC. """ - return self._getNamedAs('8233', constants.ps.PSETID_APPOINTMENT, TimeZoneStruct) + return self._getNamedAs('8233', ps.PSETID_APPOINTMENT, TimeZoneStruct) @functools.cached_property def to(self) -> Optional[str]: @@ -521,4 +521,4 @@ def toAttendeesString(self) -> Optional[str]: """ A list of all the sendable attendees, who are also required attendees. """ - return self._getNamedAs('823B', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('823B', ps.PSETID_APPOINTMENT) diff --git a/extract_msg/msg_classes/contact.py b/extract_msg/msg_classes/contact.py index 656c9b95..d9cc40c1 100644 --- a/extract_msg/msg_classes/contact.py +++ b/extract_msg/msg_classes/contact.py @@ -9,7 +9,7 @@ from typing import Dict, List, Optional, Set, Tuple, Union -from .. import constants +from ..constants import HEADER_FORMAT_TYPE, ps from ..enums import ( ContactLinkState, ElectronicAddressProperties, Gender, InsecureFeatures, PostalAddressID @@ -40,14 +40,14 @@ def addressBookProviderArrayType(self) -> Optional[ElectronicAddressProperties]: Property is stored in the MSG file as a sinlge int. The result should be identical to addressBookProviderEmailList. """ - return self._getNamedAs('8029', constants.ps.PSETID_ADDRESS, ElectronicAddressProperties) + return self._getNamedAs('8029', ps.PSETID_ADDRESS, ElectronicAddressProperties) @functools.cached_property def addressBookProviderEmailList(self) -> Optional[Set[ElectronicAddressProperties]]: """ A set of which Electronic Address properties are set on the contact. """ - return self._getNamedAs('8028', constants.ps.PSETID_ADDRESS, lambda x : {ElectronicAddressProperties(y) for y in x}) + return self._getNamedAs('8028', ps.PSETID_ADDRESS, lambda x : {ElectronicAddressProperties(y) for y in x}) @functools.cached_property def assistant(self) -> Optional[str]: @@ -69,14 +69,14 @@ def autoLog(self) -> bool: Whether the client should create a Journal object for each action associated with the Contact object. """ - return self._getNamedAs('8025', constants.ps.PSETID_ADDRESS, bool, False) + return self._getNamedAs('8025', ps.PSETID_ADDRESS, bool, False) @functools.cached_property def billing(self) -> Optional[str]: """ Billing information for the contact. """ - return self._getNamedAs('8535', constants.ps.PSETID_COMMON) + return self._getNamedAs('8535', ps.PSETID_COMMON) @functools.cached_property def birthday(self) -> Optional[datetime.datetime]: @@ -91,14 +91,14 @@ def birthdayEventEntryID(self) -> Optional[EntryID]: The EntryID of an optional Appointement object that represents the contact's birtday. """ - return self._getNamedAs('804D', constants.ps.PSETID_ADDRESS, EntryID.autoCreate) + return self._getNamedAs('804D', ps.PSETID_ADDRESS, EntryID.autoCreate) @functools.cached_property def birthdayLocal(self) -> Optional[datetime.datetime]: """ The birthday of the contact at 0:00 in the client's local time zone. """ - return self._getNamedAs('80DE', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80DE', ps.PSETID_ADDRESS) @functools.cached_property def businessCard(self) -> bytes: @@ -136,7 +136,7 @@ def businessCardCardPicture(self) -> Optional[bytes]: The image to be used on a business card. Must be either a PNG file or a JPEG file. """ - return self._getNamedAs('8041', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8041', ps.PSETID_ADDRESS) @functools.cached_property def businessCardDisplayDefinition(self) -> Optional[BusinessCardDisplayDefinition]: @@ -144,7 +144,7 @@ def businessCardDisplayDefinition(self) -> Optional[BusinessCardDisplayDefinitio Specifies the customization details for displaying a contact as a business card. """ - return self._getNamedAs('8040', constants.ps.PSETID_ADDRESS, BusinessCardDisplayDefinition) + return self._getNamedAs('8040', ps.PSETID_ADDRESS, BusinessCardDisplayDefinition) @functools.cached_property def businessFax(self) -> Optional[Dict]: @@ -169,7 +169,7 @@ def businessFaxAddressType(self) -> Optional[str]: """ The type of address for the fax. MUST be set to "FAX" if present. """ - return self._getNamedAs('80C2', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80C2', ps.PSETID_ADDRESS) @functools.cached_property def businessFaxEmailAddress(self) -> Optional[str]: @@ -177,7 +177,7 @@ def businessFaxEmailAddress(self) -> Optional[str]: Contains a user-readable display name, followed by the "@" character, followed by a fax number. """ - return self._getNamedAs('80C3', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80C3', ps.PSETID_ADDRESS) @functools.cached_property def businessFaxNumber(self) -> Optional[str]: @@ -191,14 +191,14 @@ def businessFaxOriginalDisplayName(self) -> Optional[str]: """ The normalized subject for the contact. """ - return self._getNamedAs('80C4', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80C4', ps.PSETID_ADDRESS) @functools.cached_property def businessFaxOriginalEntryId(self) -> Optional[EntryID]: """ The one-off EntryID corresponding to this fax address. """ - return self._getNamedAs('80C5', constants.ps.PSETID_ADDRESS, EntryID.autoCreate) + return self._getNamedAs('80C5', ps.PSETID_ADDRESS, EntryID.autoCreate) @functools.cached_property def businessTelephoneNumber(self) -> Optional[str]: @@ -268,35 +268,35 @@ def contactCharacterSet(self) -> Optional[int]: """ The character set that is used for this Contact object. """ - return self._getNamedAs('8023', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8023', ps.PSETID_ADDRESS) @functools.cached_property def contactItemData(self) -> Optional[List[int]]: """ Used to help display the contact information. """ - return self._getNamedAs('8007', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8007', ps.PSETID_ADDRESS) @functools.cached_property def contactLinkedGlobalAddressListEntryID(self) -> Optional[EntryID]: """ The EntryID of the GAL object to which the duplicate contact is linked. """ - return self._getNamedAs('80E2', constants.ps.PSETID_ADDRESS, EntryID.autoCreate) + return self._getNamedAs('80E2', ps.PSETID_ADDRESS, EntryID.autoCreate) @functools.cached_property def contactLinkGlobalAddressListLinkID(self) -> Optional[str]: """ The GUID of the GAL contact to which the duplicate contact is linked. """ - return self._getNamedAs('80E8', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80E8', ps.PSETID_ADDRESS) @functools.cached_property def contactLinkGlobalAddressListLinkState(self) -> Optional[ContactLinkState]: """ The state of linking between the GAL contact and the duplicate contact. """ - return self._getNamedAs('80E6', constants.ps.PSETID_ADDRESS, ContactLinkState) + return self._getNamedAs('80E6', ps.PSETID_ADDRESS, ContactLinkState) @functools.cached_property def contactLinkLinkRejectHistory(self) -> Optional[List[bytes]]: @@ -304,7 +304,7 @@ def contactLinkLinkRejectHistory(self) -> Optional[List[bytes]]: A list of any contacts that were previously rejected for linking with the duplicate contact. """ - return self._getNamedAs('80E5', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80E5', ps.PSETID_ADDRESS) @functools.cached_property def contactLinkSMTPAddressCache(self) -> Optional[List[str]]: @@ -312,7 +312,7 @@ def contactLinkSMTPAddressCache(self) -> Optional[List[str]]: A list of the SMTP addresses that are used by the GAL contact that are linked to the duplicate contact. """ - return self._getNamedAs('80E3', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80E3', ps.PSETID_ADDRESS) @functools.cached_property def contactPhoto(self) -> Optional[bytes]: @@ -331,28 +331,28 @@ def contactUserField1(self) -> Optional[str]: """ Used to store custom text for a business card. """ - return self._getNamedAs('804F', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('804F', ps.PSETID_ADDRESS) @functools.cached_property def contactUserField2(self) -> Optional[str]: """ Used to store custom text for a business card. """ - return self._getNamedAs('8050', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8050', ps.PSETID_ADDRESS) @functools.cached_property def contactUserField3(self) -> Optional[str]: """ Used to store custom text for a business card. """ - return self._getNamedAs('8051', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8051', ps.PSETID_ADDRESS) @functools.cached_property def contactUserField4(self) -> Optional[str]: """ Used to store custom text for a business card. """ - return self._getNamedAs('8052', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8052', ps.PSETID_ADDRESS) @functools.cached_property def customerID(self) -> Optional[str]: @@ -405,21 +405,21 @@ def email1AddressType(self) -> Optional[str]: """ The address type of the first email address. """ - return self._getNamedAs('8082', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8082', ps.PSETID_ADDRESS) @functools.cached_property def email1DisplayName(self) -> Optional[str]: """ The user-readable display name of the first email address. """ - return self._getNamedAs('8080', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8080', ps.PSETID_ADDRESS) @functools.cached_property def email1EmailAddress(self) -> Optional[str]: """ The first email address. """ - return self._getNamedAs('8083', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8083', ps.PSETID_ADDRESS) @functools.cached_property def email1OriginalDisplayName(self) -> Optional[str]: @@ -427,14 +427,14 @@ def email1OriginalDisplayName(self) -> Optional[str]: The first SMTP email address that corresponds to the first email address for the contact. """ - return self._getNamedAs('8084', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8084', ps.PSETID_ADDRESS) @functools.cached_property def email1OriginalEntryId(self) -> Optional[EntryID]: """ The EntryID of the object correspinding to this electronic address. """ - return self._getNamedAs('8085', constants.ps.PSETID_ADDRESS, EntryID.autoCreate) + return self._getNamedAs('8085', ps.PSETID_ADDRESS, EntryID.autoCreate) @functools.cached_property def email2(self) -> Optional[dict]: @@ -456,21 +456,21 @@ def email2AddressType(self) -> Optional[str]: """ The address type of the second email address. """ - return self._getNamedAs('8092', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8092', ps.PSETID_ADDRESS) @functools.cached_property def email2DisplayName(self) -> Optional[str]: """ The user-readable display name of the second email address. """ - return self._getNamedAs('8090', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8090', ps.PSETID_ADDRESS) @functools.cached_property def email2EmailAddress(self) -> Optional[str]: """ The second email address. """ - return self._getNamedAs('8093', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8093', ps.PSETID_ADDRESS) @functools.cached_property def email2OriginalDisplayName(self) -> Optional[str]: @@ -478,14 +478,14 @@ def email2OriginalDisplayName(self) -> Optional[str]: The second SMTP email address that corresponds to the second email address for the contact. """ - return self._getNamedAs('8094', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8094', ps.PSETID_ADDRESS) @functools.cached_property def email2OriginalEntryId(self) -> Optional[EntryID]: """ The EntryID of the object correspinding to this electronic address. """ - return self._getNamedAs('8095', constants.ps.PSETID_ADDRESS, EntryID.autoCreate) + return self._getNamedAs('8095', ps.PSETID_ADDRESS, EntryID.autoCreate) @functools.cached_property def email3(self) -> Optional[dict]: @@ -507,21 +507,21 @@ def email3AddressType(self) -> Optional[str]: """ The address type of the third email address. """ - return self._getNamedAs('80A2', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80A2', ps.PSETID_ADDRESS) @functools.cached_property def email3DisplayName(self) -> Optional[str]: """ The user-readable display name of the third email address. """ - return self._getNamedAs('80A0', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80A0', ps.PSETID_ADDRESS) @functools.cached_property def email3EmailAddress(self) -> Optional[str]: """ The third email address. """ - return self._getNamedAs('80A3', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80A3', ps.PSETID_ADDRESS) @functools.cached_property def email3OriginalDisplayName(self) -> Optional[str]: @@ -529,14 +529,14 @@ def email3OriginalDisplayName(self) -> Optional[str]: The third SMTP email address that corresponds to the third email address for the contact. """ - return self._getNamedAs('80A4', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80A4', ps.PSETID_ADDRESS) @functools.cached_property def email3OriginalEntryId(self) -> Optional[EntryID]: """ The EntryID of the object correspinding to this electronic address. """ - return self._getNamedAs('80A5', constants.ps.PSETID_ADDRESS, EntryID.autoCreate) + return self._getNamedAs('80A5', ps.PSETID_ADDRESS, EntryID.autoCreate) @functools.cached_property def emails(self) -> Tuple[Union[Dict, None], Union[Dict, None], Union[Dict, None]]: @@ -567,7 +567,7 @@ def fileUnder(self) -> Optional[str]: The name under which to file a contact when displaying a list of contacts. """ - return self._getNamedAs('8005', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8005', ps.PSETID_ADDRESS) @functools.cached_property def fileUnderID(self) -> Optional[int]: @@ -575,7 +575,7 @@ def fileUnderID(self) -> Optional[int]: The format to use for fileUnder. See PidLidFileUnderId in [MS-OXOCNTC] for details. """ - return self._getNamedAs('8006', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8006', ps.PSETID_ADDRESS) @functools.cached_property def freeBusyLocation(self) -> Optional[str]: @@ -583,7 +583,7 @@ def freeBusyLocation(self) -> Optional[str]: A URL path from which a client can retrieve free/busy status information for the contact as an iCalendat file. """ - return self._getNamedAs('80D8', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80D8', ps.PSETID_ADDRESS) @functools.cached_property def ftpSite(self) -> Optional[str]: @@ -626,10 +626,10 @@ def hasPicture(self) -> bool: """ Whether the contact has a contact photo. """ - return self._getNamedAs('8015', constants.ps.PSETID_ADDRESS, bool, False) + return self._getNamedAs('8015', ps.PSETID_ADDRESS, bool, False) @property - def headerFormatProperties(self) -> constants.HEADER_FORMAT_TYPE: + def headerFormatProperties(self) -> HEADER_FORMAT_TYPE: """ Returns a dictionary of properties, in order, to be formatted into the header. Keys are the names to use in the header while the values are one @@ -732,7 +732,7 @@ def homeAddress(self) -> Optional[str]: """ The complete home address of the contact. """ - return self._getNamedAs('801A', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('801A', ps.PSETID_ADDRESS) @functools.cached_property def homeAddressCountry(self) -> Optional[str]: @@ -746,7 +746,7 @@ def homeAddressCountryCode(self) -> Optional[str]: """ The country code portion of the contact's home address. """ - return self._getNamedAs('80DA', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80DA', ps.PSETID_ADDRESS) @functools.cached_property def homeAddressLocality(self) -> Optional[str]: @@ -806,7 +806,7 @@ def homeFaxAddressType(self) -> Optional[str]: """ The type of address for the fax. MUST be set to "FAX" if present. """ - return self._getNamedAs('80D2', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80D2', ps.PSETID_ADDRESS) @functools.cached_property def homeFaxEmailAddress(self) -> Optional[str]: @@ -814,7 +814,7 @@ def homeFaxEmailAddress(self) -> Optional[str]: Contains a user-readable display name, followed by the "@" character, followed by a fax number. """ - return self._getNamedAs('80D3', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80D3', ps.PSETID_ADDRESS) @functools.cached_property def homeFaxNumber(self) -> Optional[str]: @@ -828,14 +828,14 @@ def homeFaxOriginalDisplayName(self) -> Optional[str]: """ The normalized subject for the contact. """ - return self._getNamedAs('80D4', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80D4', ps.PSETID_ADDRESS) @functools.cached_property def homeFaxOriginalEntryId(self) -> Optional[EntryID]: """ The one-off EntryID corresponding to this fax address. """ - return self._getNamedAs('80D5', constants.ps.PSETID_ADDRESS, EntryID.autoCreate) + return self._getNamedAs('80D5', ps.PSETID_ADDRESS, EntryID.autoCreate) @functools.cached_property def homeTelephoneNumber(self) -> Optional[str]: @@ -863,14 +863,14 @@ def instantMessagingAddress(self) -> Optional[str]: """ The instant messaging address of the contact. """ - return self._getNamedAs('8062', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8062', ps.PSETID_ADDRESS) @functools.cached_property def isContactLinked(self) -> bool: """ Whether the contact is linked to other contacts. """ - return self._getNamedAs('80E0', constants.ps.PSETID_ADDRESS, bool, False) + return self._getNamedAs('80E0', ps.PSETID_ADDRESS, bool, False) @functools.cached_property def isdnNumber(self) -> Optional[str]: @@ -928,7 +928,7 @@ def mailAddressCountryCode(self) -> Optional[str]: """ The country code portion of the contact's mail address. """ - return self._getNamedAs('80DD', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80DD', ps.PSETID_ADDRESS) @functools.cached_property def mailAddressLocality(self) -> Optional[str]: @@ -1021,7 +1021,7 @@ def otherAddress(self) -> Optional[str]: """ The complete other address of the contact. """ - return self._getNamedAs('801C', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('801C', ps.PSETID_ADDRESS) @functools.cached_property def otherAddressCountry(self) -> Optional[str]: @@ -1035,7 +1035,7 @@ def otherAddressCountryCode(self) -> Optional[str]: """ The country code portion of the contact's other address. """ - return self._getNamedAs('80DC', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80DC', ps.PSETID_ADDRESS) @functools.cached_property def otherAddressLocality(self) -> Optional[str]: @@ -1098,21 +1098,21 @@ def phoneticCompanyName(self) -> Optional[str]: """ The phonetic pronunciation of the contact's company name. """ - return self._getNamedAs('802E', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('802E', ps.PSETID_ADDRESS) @functools.cached_property def phoneticGivenName(self) -> Optional[str]: """ The phonetic pronunciation of the contact's given name. """ - return self._getNamedAs('802C', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('802C', ps.PSETID_ADDRESS) @functools.cached_property def phoneticSurname(self) -> Optional[str]: """ The phonetic pronunciation of the given name of the contact. """ - return self._getNamedAs('802D', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('802D', ps.PSETID_ADDRESS) @functools.cached_property def postalAddressID(self) -> PostalAddressID: @@ -1120,7 +1120,7 @@ def postalAddressID(self) -> PostalAddressID: Indicates which physical address is the Mailing Address for this contact. """ - return self._getNamedAs('8022', constants.ps.PSETID_ADDRESS, lambda x : PostalAddressID(x or 0), False) + return self._getNamedAs('8022', ps.PSETID_ADDRESS, lambda x : PostalAddressID(x or 0), False) @functools.cached_property def primaryFax(self) -> Optional[dict]: @@ -1145,7 +1145,7 @@ def primaryFaxAddressType(self) -> Optional[str]: """ The type of address for the fax. MUST be set to "FAX" if present. """ - return self._getNamedAs('80B2', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80B2', ps.PSETID_ADDRESS) @functools.cached_property def primaryFaxEmailAddress(self) -> Optional[str]: @@ -1153,7 +1153,7 @@ def primaryFaxEmailAddress(self) -> Optional[str]: Contains a user-readable display name, followed by the "@" character, followed by a fax number. """ - return self._getNamedAs('80B3', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80B3', ps.PSETID_ADDRESS) @functools.cached_property def primaryFaxNumber(self) -> Optional[str]: @@ -1167,14 +1167,14 @@ def primaryFaxOriginalDisplayName(self) -> Optional[str]: """ The normalized subject for the contact. """ - return self._getNamedAs('80B4', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80B4', ps.PSETID_ADDRESS) @functools.cached_property def primaryFaxOriginalEntryId(self) -> Optional[EntryID]: """ The one-off EntryID corresponding to this fax address. """ - return self._getNamedAs('80B5', constants.ps.PSETID_ADDRESS, EntryID.autoCreate) + return self._getNamedAs('80B5', ps.PSETID_ADDRESS, EntryID.autoCreate) @functools.cached_property def primaryTelephoneNumber(self) -> Optional[str]: @@ -1204,7 +1204,7 @@ def referenceEntryID(self) -> Optional[EntryID]: Contact object unless the Contact object is a copy of an earlier original. """ - return self._getNamedAs('85BD', constants.ps.PSETID_COMMON, EntryID.autoCreate) + return self._getNamedAs('85BD', ps.PSETID_COMMON, EntryID.autoCreate) @functools.cached_property def referredByName(self) -> Optional[str]: @@ -1262,7 +1262,7 @@ def weddingAnniversaryEventEntryID(self) -> Optional[EntryID]: The EntryID of an optional Appointement object that represents the contact's wedding anniversary. """ - return self._getNamedAs('804E', constants.ps.PSETID_ADDRESS, EntryID.autoCreate) + return self._getNamedAs('804E', ps.PSETID_ADDRESS, EntryID.autoCreate) @functools.cached_property def weddingAnniversaryLocal(self) -> Optional[datetime.datetime]: @@ -1270,67 +1270,67 @@ def weddingAnniversaryLocal(self) -> Optional[datetime.datetime]: The wedding anniversary of the contact at 0:00 in the client's local time zone. """ - return self._getNamedAs('80DF', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80DF', ps.PSETID_ADDRESS) @functools.cached_property def webpageUrl(self) -> Optional[str]: """ The contact's business web page url. SHOULD be the same as businessUrl. """ - return self._getNamedAs('802B', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('802B', ps.PSETID_ADDRESS) @functools.cached_property def workAddress(self) -> Optional[str]: """ The complete work address of the contact. """ - return self._getNamedAs('801B', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('801B', ps.PSETID_ADDRESS) @functools.cached_property def workAddressCountry(self) -> Optional[str]: """ The country portion of the contact's work address. """ - return self._getNamedAs('8049', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8049', ps.PSETID_ADDRESS) @functools.cached_property def workAddressCountryCode(self) -> Optional[str]: """ The country code portion of the contact's work address. """ - return self._getNamedAs('80DB', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('80DB', ps.PSETID_ADDRESS) @functools.cached_property def workAddressLocality(self) -> Optional[str]: """ The locality or city portion of the contact's work address. """ - return self._getNamedAs('8046', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8046', ps.PSETID_ADDRESS) @functools.cached_property def workAddressPostalCode(self) -> Optional[str]: """ The postal code portion of the contact's work address. """ - return self._getNamedAs('8048', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8048', ps.PSETID_ADDRESS) @functools.cached_property def workAddressPostOfficeBox(self) -> Optional[str]: """ The number or identifier of the contact's work post office box. """ - return self._getNamedAs('804A', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('804A', ps.PSETID_ADDRESS) @functools.cached_property def workAddressStateOrProvince(self) -> Optional[str]: """ The state or province portion of the contact's work address. """ - return self._getNamedAs('8047', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8047', ps.PSETID_ADDRESS) @functools.cached_property def workAddressStreet(self) -> Optional[str]: """ The street portion of the contact's work address. """ - return self._getNamedAs('8045', constants.ps.PSETID_ADDRESS) + return self._getNamedAs('8045', ps.PSETID_ADDRESS) diff --git a/extract_msg/open_msg.py b/extract_msg/open_msg.py index f39acd74..439fa1a0 100644 --- a/extract_msg/open_msg.py +++ b/extract_msg/open_msg.py @@ -10,7 +10,7 @@ import glob import logging -from typing import List, Tuple, TYPE_CHECKING, Union +from typing import List, Optional, Tuple, TYPE_CHECKING, Union from . import constants from .exceptions import ( @@ -26,20 +26,29 @@ from .msg_classes import MSGFile -def _knownMsgClass(classType : str) -> bool: +def _getMsgClassInfo(classType : str) -> Tuple[bool, Optional[str]]: """ Checks if the specified class type is recognized by the module. Usually used for checking if a type is simply unsupported rather than unknown. + + Returns a tuple of two items. The first is whether it is known. If it is + known and support is refused, the second item will be a string of the + relevent issue number. Otherwise, it will be None. """ classType = classType.lower() if classType == 'ipm': - return True + return (True, None) for item in constants.KNOWN_CLASS_TYPES: if classType.startswith(item): - return True + # Check if the found class type has had support refused. + for tup in constants.REFUSED_CLASS_TYPES: + if tup[0] == item: + return (True, tup[1]) + else: + return (True, None) - return False + return (False, None) def openMsg(path, **kwargs) -> MSGFile: @@ -145,11 +154,20 @@ def openMsg(path, **kwargs) -> MSGFile: # Because we are closing it, we need to store it in a variable first. ct = msg.classType msg.close() - if _knownMsgClass(classType): + # Now we need to figure out exactly what we are going to be reporting to + # the user. + if (info := _getMsgClassInfo(classType))[0]: + if info[1]: + raise UnsupportedMSGTypeError(f'Support for MSG type "{ct}" has been refused. See {constants.REPOSITORY_URL}/issues/{info[1]} for more information.') raise UnsupportedMSGTypeError(f'MSG type "{ct}" currently is not supported by the module. If you would like support, please make a feature request.') - raise UnrecognizedMSGTypeError(f'Could not recognize msg class type "{ct}".') + raise UnrecognizedMSGTypeError(f'Could not recognize MSG class type "{ct}". As such, there is a high chance that support may be impossible, but you should contact the developers to find out more.') else: - logger.error(f'Could not recognize msg class type "{msg.classType}". This most likely means it hasn\'t been implemented yet, and you should ask the developers to add support for it.') + if (info := _getMsgClassInfo(classType))[0]: + if info[1]: + logger.error(f'Support for MSG type "{msg.classType}" has been refused. See {constants.REPOSITORY_URL}/issues/{info[1]} for more information.') + else: + logger.error(f'MSG type "{msg.classType}" currently is not supported by the module. If you would like support, please make a feature request.') + logger.error(f'Could not recognize MSG class type "{msg.classType}". As such, there is a high chance that support may be impossible, but you should contact the developers to find out more.') if not delayAttachments: msg.attachments return msg diff --git a/extract_msg/properties/prop.py b/extract_msg/properties/prop.py index c73c56c2..c83fa7f4 100644 --- a/extract_msg/properties/prop.py +++ b/extract_msg/properties/prop.py @@ -2,17 +2,16 @@ __all__ = [ - # Classes. + # Classes: 'FixedLengthProp' 'PropBase', 'VariableLengthProp', - # Functions. + # Functions: 'createProp', ] -import abc import datetime import logging From 7657070dd31ae96045508ec523c0a05ae2f51bbb Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Sun, 2 Jul 2023 17:19:25 -0700 Subject: [PATCH 72/89] Comment fixes. --- extract_msg/constants/__init__.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/extract_msg/constants/__init__.py b/extract_msg/constants/__init__.py index 4371e030..6a908f87 100644 --- a/extract_msg/constants/__init__.py +++ b/extract_msg/constants/__init__.py @@ -132,7 +132,7 @@ '1102', ) -# Multiple type properties that take up 2 bytes +# Multiple type properties that take up 2 bytes. MULTIPLE_2_BYTES = ( '1002', ) @@ -141,7 +141,7 @@ 0x1002, ) -# Multiple type properties that take up 4 bytes +# Multiple type properties that take up 4 bytes. MULTIPLE_4_BYTES = ( '1003', '1004', @@ -152,7 +152,7 @@ 0x1004, ) -# Multiple type properties that take up 4 bytes +# Multiple type properties that take up 8 bytes. MULTIPLE_8_BYTES = ( '1005', '1007', @@ -167,7 +167,7 @@ 0x1040, ) -# Multiple type properties that take up 4 bytes +# Multiple type properties that take up 16 bytes. MULTIPLE_16_BYTES = ( '1048', ) @@ -219,7 +219,7 @@ PYTPFLOATINGTIME_START = datetime.datetime(1899, 12, 30) NULL_DATE = datetime.datetime(4500, 8, 31, 23, 59) -# Constants used for argparse stuff +# Constants used for argparse stuff. KNOWN_FILE_FLAGS = ( '--out-name', ) @@ -239,19 +239,19 @@ PTYPES = { 0x0000: 'PtypUnspecified', 0x0001: 'PtypNull', - 0x0002: 'PtypInteger16', # Signed short - 0x0003: 'PtypInteger32', # Signed int - 0x0004: 'PtypFloating32', # Float - 0x0005: 'PtypFloating64', # Double + 0x0002: 'PtypInteger16', # Signed short. + 0x0003: 'PtypInteger32', # Signed int. + 0x0004: 'PtypFloating32', # Float. + 0x0005: 'PtypFloating64', # Double. 0x0006: 'PtypCurrency', 0x0007: 'PtypFloatingTime', 0x000A: 'PtypErrorCode', 0x000B: 'PtypBoolean', 0x000D: 'PtypObject/PtypEmbeddedTable/Storage', - 0x0014: 'PtypInteger64', # Signed longlong + 0x0014: 'PtypInteger64', # Signed longlong. 0x001E: 'PtypString8', 0x001F: 'PtypString', - 0x0040: 'PtypTime', # Use filetimeToUtc to convert to unix time stamp + 0x0040: 'PtypTime', # Use filetimeToUtc to convert to unix time stamp. 0x0048: 'PtypGuid', 0x00FB: 'PtypServerId', 0x00FD: 'PtypRestriction', @@ -271,4 +271,4 @@ 0x1102: 'PtypMultipleBinary', } -# END CONSTANTS \ No newline at end of file +# END CONSTANTS. \ No newline at end of file From 2a8bb19cbcd2f9ca8b9b226ae7e05b310675e793 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Mon, 3 Jul 2023 17:04:32 -0700 Subject: [PATCH 73/89] Shorten lines a bit --- extract_msg/msg_classes/meeting_related.py | 12 +++++------ extract_msg/msg_classes/meeting_request.py | 24 ++++++++++----------- extract_msg/msg_classes/meeting_response.py | 14 ++++++------ 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/extract_msg/msg_classes/meeting_related.py b/extract_msg/msg_classes/meeting_related.py index 7782a10c..6d2f8bef 100644 --- a/extract_msg/msg_classes/meeting_related.py +++ b/extract_msg/msg_classes/meeting_related.py @@ -8,7 +8,7 @@ from typing import Optional -from .. import constants +from ..constants import ps from .calendar_base import CalendarBase from ..enums import ServerProcessingAction @@ -23,7 +23,7 @@ def attendeeCriticalChange(self) -> Optional[datetime.datetime]: """ The date and time at which the meeting-related object was sent. """ - return self._getNamedAs('0001', constants.ps.PSETID_MEETING) + return self._getNamedAs('0001', ps.PSETID_MEETING) @functools.cached_property def processed(self) -> bool: @@ -38,7 +38,7 @@ def serverProcessed(self) -> bool: Indicates that the Meeting Request object or Meeting Update object has been processed. """ - return self._getNamedAs('85CC', constants.ps.PSETID_CALENDAR_ASSISTANT, bool, False) + return self._getNamedAs('85CC', ps.PSETID_CALENDAR_ASSISTANT, bool, False) @functools.cached_property def serverProcessingActions(self) -> Optional[ServerProcessingAction]: @@ -46,7 +46,7 @@ def serverProcessingActions(self) -> Optional[ServerProcessingAction]: A union of which actions have been taken on the Meeting Request object or Meeting Update object. """ - return self._getNamedAs('85CD', constants.ps.PSETID_CALENDAR_ASSISTANT, ServerProcessingAction) + return self._getNamedAs('85CD', ps.PSETID_CALENDAR_ASSISTANT, ServerProcessingAction) @functools.cached_property def timeZone(self) -> Optional[int]: @@ -55,11 +55,11 @@ def timeZone(self) -> Optional[int]: See PidLidTimeZone in [MS-OXOCAL] for details. """ - return self._getNamedAs('000C', constants.ps.PSETID_MEETING) + return self._getNamedAs('000C', ps.PSETID_MEETING) @functools.cached_property def where(self) -> Optional[str]: """ PidLidWhere. Should be the same as location. """ - return self._getNamedAs('0002', constants.ps.PSETID_MEETING) + return self._getNamedAs('0002', ps.PSETID_MEETING) diff --git a/extract_msg/msg_classes/meeting_request.py b/extract_msg/msg_classes/meeting_request.py index 84f638cd..5893ea75 100644 --- a/extract_msg/msg_classes/meeting_request.py +++ b/extract_msg/msg_classes/meeting_request.py @@ -6,9 +6,9 @@ import datetime import functools -from typing import List, Optional +from typing import Optional -from .. import constants +from ..constants import HEADER_FORMAT_TYPE, ps from .meeting_related import MeetingRelated from ..enums import BusyStatus, MeetingObjectChange, MeetingType, RecurCalendarType, RecurPatternType, ResponseStatus @@ -25,7 +25,7 @@ def appointmentMessageClass(self) -> Optional[str]: object that is to be generated from the Meeting Request object. MUST start with "IPM.Appointment". """ - return self._getNamedAs('0024', constants.ps.PSETID_MEETING) + return self._getNamedAs('0024', ps.PSETID_MEETING) @functools.cached_property def calendarType(self) -> Optional[RecurCalendarType]: @@ -34,7 +34,7 @@ def calendarType(self) -> Optional[RecurCalendarType]: property if the Meeting Request object represents a recurring series or an exception. """ - return self._getNamedAs('001C', constants.ps.PSETID_MEETING, RecurCalendarType) + return self._getNamedAs('001C', ps.PSETID_MEETING, RecurCalendarType) @functools.cached_property def changeHighlight(self) -> Optional[MeetingObjectChange]: @@ -44,7 +44,7 @@ def changeHighlight(self) -> Optional[MeetingObjectChange]: Returns a union of the set flags. """ - return self._getNamedAs('8204', constants.ps.PSETID_APPOINTMENT, MeetingObjectChange) + return self._getNamedAs('8204', ps.PSETID_APPOINTMENT, MeetingObjectChange) @functools.cached_property def forwardInstance(self) -> bool: @@ -53,10 +53,10 @@ def forwardInstance(self) -> bool: recurring series, and it was forwarded (even when forwarded by the organizer) rather than being an invitation sent by the organizer. """ - return self._getNamedAs('820A', constants.ps.PSETID_APPOINTMENT, bool, False) + return self._getNamedAs('820A', ps.PSETID_APPOINTMENT, bool, False) @property - def headerFormatProperties(self) -> constants.HEADER_FORMAT_TYPE: + def headerFormatProperties(self) -> HEADER_FORMAT_TYPE: """ Returns a dictionary of properties, in order, to be formatted into the header. Keys are the names to use in the header while the values are one @@ -140,21 +140,21 @@ def intendedBusyStatus(self) -> Optional[BusyStatus]: calendar at the time the Meeting Request object or Meeting Update object was sent. """ - return self._getNamedAs('8224', constants.ps.PSETID_APPOINTMENT, BusyStatus) + return self._getNamedAs('8224', ps.PSETID_APPOINTMENT, BusyStatus) @functools.cached_property def meetingType(self) -> Optional[MeetingType]: """ The type of Meeting Request object or Meeting Update object. """ - return self._getNamedAs('0026', constants.ps.PSETID_MEETING, MeetingType) + return self._getNamedAs('0026', ps.PSETID_MEETING, MeetingType) @functools.cached_property def oldLocation(self) -> Optional[str]: """ The original value of the location property before a meeting update. """ - return self._getNamedAs('0028', constants.ps.PSETID_MEETING) + return self._getNamedAs('0028', ps.PSETID_MEETING) @functools.cached_property def oldWhenEndWhole(self) -> Optional[datetime.datetime]: @@ -162,7 +162,7 @@ def oldWhenEndWhole(self) -> Optional[datetime.datetime]: The original value of the appointmentEndWhole property before a meeting update. """ - return self._getNamedAs('002A', constants.ps.PSETID_MEETING) + return self._getNamedAs('002A', ps.PSETID_MEETING) @functools.cached_property def oldWhenStartWhole(self) -> Optional[datetime.datetime]: @@ -170,4 +170,4 @@ def oldWhenStartWhole(self) -> Optional[datetime.datetime]: The original value of the appointmentStartWhole property before a meeting update. """ - return self._getNamedAs('0029', constants.ps.PSETID_MEETING) + return self._getNamedAs('0029', ps.PSETID_MEETING) diff --git a/extract_msg/msg_classes/meeting_response.py b/extract_msg/msg_classes/meeting_response.py index d13d9b63..67bd1d93 100644 --- a/extract_msg/msg_classes/meeting_response.py +++ b/extract_msg/msg_classes/meeting_response.py @@ -8,7 +8,7 @@ from typing import Optional -from .. import constants +from ..constants import ps from ..enums import ResponseType from .meeting_related import MeetingRelated @@ -23,7 +23,7 @@ def appointmentCounterProposal(self) -> bool: """ Indicates if the response is a counter proposal. """ - return self._getNamedAs('8257', constants.ps.PSETID_APPOINTMENT, bool, False) + return self._getNamedAs('8257', ps.PSETID_APPOINTMENT, bool, False) @functools.cached_property def appointmentProposedDuration(self) -> Optional[int]: @@ -31,7 +31,7 @@ def appointmentProposedDuration(self) -> Optional[int]: The proposed value for the appointmentDuration property for a counter proposal. """ - return self._getNamedAs('8256', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8256', ps.PSETID_APPOINTMENT) @functools.cached_property def appointmentProposedEndWhole(self) -> Optional[datetime.datetime]: @@ -39,7 +39,7 @@ def appointmentProposedEndWhole(self) -> Optional[datetime.datetime]: The proposal value for the appointmentEndWhole property for a counter proposal. """ - return self._getNamedAs('8251', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8251', ps.PSETID_APPOINTMENT) @functools.cached_property def appointmentProposedStartWhole(self) -> Optional[datetime.datetime]: @@ -47,7 +47,7 @@ def appointmentProposedStartWhole(self) -> Optional[datetime.datetime]: The proposal value for the appointmentStartWhole property for a counter proposal. """ - return self._getNamedAs('8250', constants.ps.PSETID_APPOINTMENT) + return self._getNamedAs('8250', ps.PSETID_APPOINTMENT) @functools.cached_property def isSilent(self) -> bool: @@ -55,7 +55,7 @@ def isSilent(self) -> bool: Indicates if the user did not include any text in the body of the Meeting Response object. """ - return self._getNamedAs('0004', constants.ps.PSETID_MEETING, bool, False) + return self._getNamedAs('0004', ps.PSETID_MEETING, bool, False) @functools.cached_property def promptSendUpdate(self) -> bool: @@ -63,7 +63,7 @@ def promptSendUpdate(self) -> bool: Indicates that the Meeting Response object was out-of-date when it was received. """ - return self._getNamedAs('8045', constants.ps.PSETID_COMMON, bool, False) + return self._getNamedAs('8045', ps.PSETID_COMMON, bool, False) @functools.cached_property def responseType(self) -> ResponseType: From 44998bb0740f6cb14d4146d68ea8315db6add987 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Tue, 4 Jul 2023 01:02:18 -0700 Subject: [PATCH 74/89] Fix exceptions, change behavior of ole defects --- CHANGELOG.md | 1 + extract_msg/attachments/__init__.py | 9 +++++-- extract_msg/enums.py | 38 +++++++++++++++++------------ extract_msg/exceptions.py | 5 +++- extract_msg/msg_classes/msg.py | 6 ++++- 5 files changed, 40 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b341104a..e9838918 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -42,6 +42,7 @@ * Fixed `CalendarBase.keywords` being blatantly incorrect (it was so bad I don't know how it slipped through). * Fixed `Contact.gender` being blatantly incorrect. * Fixed sender not being properly decoded in some circumstances. +* Changed behavior of `MSGFile` to have olefile raise defects of type `DEFECT_INCORRECT` and above instead of just `DEFECT_FATAL`. Uncaught issues of `DEFECT_INCORRECT` can often cause the module to have parsing issues that may be misleading, this just ensures the issue is clarified. This behavior can be reverted back to the previous with `ErrorBehavior.OLE_DEFECT_INCORRECT`. **v0.41.5** * Fixed an issue from version `0.41.3` where the header being present but missing the `From` field would cause an exception. diff --git a/extract_msg/attachments/__init__.py b/extract_msg/attachments/__init__.py index 1c86d3e1..4edf59b6 100644 --- a/extract_msg/attachments/__init__.py +++ b/extract_msg/attachments/__init__.py @@ -57,7 +57,10 @@ def initStandardAttachment(msg : MSGFile, dir_) -> AttachmentBase: """ from ..properties import PropertiesStore from ..enums import ErrorBehavior, PropertiesType - from ..exceptions import UnrecognizedMSGTypeError, StandardViolationError + from ..exceptions import ( + FeatureNotImplemented, StandardViolationError, + UnrecognizedMSGTypeError + ) # First, create the properties store to check things like attachment type. propertiesStream = msg._getStream([dir_, '__properties_version1.0']) @@ -119,7 +122,9 @@ def initStandardAttachment(msg : MSGFile, dir_) -> AttachmentBase: raise NotImplementedError(f'Could not determine attachment type ({attMethod})!') - except (NotImplementedError, UnrecognizedMSGTypeError): + except (FeatureNotImplemented, + NotImplementedError, + UnrecognizedMSGTypeError): if ErrorBehavior.ATTACH_NOT_IMPLEMENTED in msg.errorBehavior: _logger.exception(f'Error processing attachment at {dir_}') return UnsupportedAttachment(msg, dir_, propStore) diff --git a/extract_msg/enums.py b/extract_msg/enums.py index e1c4d459..0d81454f 100644 --- a/extract_msg/enums.py +++ b/extract_msg/enums.py @@ -519,29 +519,37 @@ def toRaw(self): class ErrorBehavior(enum.IntFlag): """ The behavior to follow when handling an error in an MSG file and it's - attachments. This is an int flag enum, so the options you want will be ORed - with each other. + attachments. Specifying an option indicates the behavior for the situation + is to log a message, if anything, instead of raising an exception. This is + an int flag enum, so the options you want will be ORed with each other. THROW: Throw the exception regardless of type. ATTACH_NOT_IMPLEMENTED: Silence the exception for NotImplementedError. ATTACH_BROKEN: Silence the exception for broken attachments. - ATTACH_SUPPRESS_ALL: Silence the exception for NotImplementedError and for broken - attachments. - STANDARDS_VIOLATION: Silences StandardViolationError where acceptable. - RTFDE_UNKNOWN_ERROR: Silences errors from RTFDE that are not normal. + ATTACH_SUPPRESS_ALL: Silence the exception for NotImplementedError and for + broken attachments. RTFDE_MALFORMED: Silences errors about malformed RTF data. + RTFDE_UNKNOWN_ERROR: Silences errors from RTFDE that are not normal. RTFDE: Silences all errors from RTFDE. + STANDARDS_VIOLATION: Silences StandardViolationError where acceptable. + OLE_DEFECT_INCORRECT: Silences defects of type DEFECT_INCORRECT that are + enabled by default. This can lead to strange bugs. SUPPRESS_ALL: Silences all of the above. """ - THROW = 0b00000 - ATTACH_NOT_IMPLEMENTED = 0b00001 - ATTACH_BROKEN = 0b00010 - ATTACH_SUPPRESS_ALL = 0b00011 - STANDARDS_VIOLATION = 0b00100 - RTFDE_UNKNOWN_ERROR = 0b01000 - RTFDE_MALFORMED = 0b10000 - RTFDE = 0b11000 - SUPPRESS_ALL = 0b1111 + THROW = 0b000000 + # Attachments. + ATTACH_NOT_IMPLEMENTED = 0b000001 + ATTACH_BROKEN = 0b000010 + ATTACH_SUPPRESS_ALL = 0b000011 + # RTFDE. + RTFDE_MALFORMED = 0b000100 + RTFDE_UNKNOWN_ERROR = 0b001000 + RTFDE = 0b001100 + # General. + STANDARDS_VIOLATION = 0b010000 + OLE_DEFECT_INCORRECT = 0b100000 + + SUPPRESS_ALL = 0b111111 diff --git a/extract_msg/exceptions.py b/extract_msg/exceptions.py index 4034daaa..17793ac1 100644 --- a/extract_msg/exceptions.py +++ b/extract_msg/exceptions.py @@ -35,7 +35,10 @@ class ExMsgBaseException(Exception): The base class for all custom exceptions the module uses. """ -class FeatureNotImplemented(ExMsgBaseException, NotImplementedError): +# I would want this to also be a subclass of NotImplementedError, but Python +# docs say that CPython can make that a bit problematic due to things from the C +# side of the code. +class FeatureNotImplemented(ExMsgBaseException): """ The base class for a feature not yet being implemented in the module. """ diff --git a/extract_msg/msg_classes/msg.py b/extract_msg/msg_classes/msg.py index f7007809..4b23f330 100644 --- a/extract_msg/msg_classes/msg.py +++ b/extract_msg/msg_classes/msg.py @@ -140,7 +140,11 @@ def __init__(self, path, **kwargs): if not path: raise ValueError(':param path: must be set and must not be empty.') try: - self.__ole = olefile.OleFileIO(path) + if ErrorBehavior.OLE_DEFECT_INCORRECT in self.errorBehavior: + defect = olefile.DEFECT_FATAL + else: + defect = olefile.DEFECT_INCORRECT + self.__ole = olefile.OleFileIO(path, raise_defects = defect) except OSError as e: logger.error(e) if str(e) == 'not an OLE2 structured storage file': From f62436f72109605add1c6d0e52c492513a0260f5 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Tue, 4 Jul 2023 01:17:57 -0700 Subject: [PATCH 75/89] Update date in __init__ --- extract_msg/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extract_msg/__init__.py b/extract_msg/__init__.py index eb2670ce..56376918 100644 --- a/extract_msg/__init__.py +++ b/extract_msg/__init__.py @@ -27,7 +27,7 @@ # along with this program. If not, see . __author__ = 'Destiny Peterson & Matthew Walker' -__date__ = '2023-06-21' +__date__ = '2023-07-04' __version__ = '0.42.0' __all__ = [ From 61e5a101704af06a9d5b1ebd765a40b38d8cfbd3 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Tue, 4 Jul 2023 01:41:50 -0700 Subject: [PATCH 76/89] Fix attachment code, add feature #288 --- CHANGELOG.md | 2 + extract_msg/attachments/attachment.py | 29 +------------- extract_msg/attachments/attachment_base.py | 44 ++++++++++++++++++++++ extract_msg/attachments/custom_att.py | 28 +------------- extract_msg/attachments/emb_msg_att.py | 2 +- extract_msg/attachments/signed_att.py | 29 +------------- 6 files changed, 50 insertions(+), 84 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e9838918..c1779894 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ **v0.42.0** * [[TeamMsgExtractor #372](https://github.com/TeamMsgExtractor/msg-extractor/issues/372)] Changed the way that the save functions return a value. This makes the return value from all save functions much more informative, allowing a user to separate if a fole or folder (or if more than one) was saved from the function. It also guarentees that all classes from this module will return the relevent path(s) if data is actually saved. +* [[TeamMsgExtractor #288](https://github.com/TeamMsgExtractor/msg-extractor/issues/288)] Added feature to allow attachment save functions to simply overwrite existing files of the same name. * Fixed an issue in the save functions that left the possibility for the zip files to not end up closing if the save function created it and then had an exception. * Added new submodule `custom_attachments`. This submodule provides an extendable way to handle custom attachment types, attachment types whose structure and formatting are not defined in the Microsoft documentation for MSG files. * Added new property `AttachmentBase.clsid` which returns the listed CLSID value of the data stream/storage of the attachment. @@ -43,6 +44,7 @@ * Fixed `Contact.gender` being blatantly incorrect. * Fixed sender not being properly decoded in some circumstances. * Changed behavior of `MSGFile` to have olefile raise defects of type `DEFECT_INCORRECT` and above instead of just `DEFECT_FATAL`. Uncaught issues of `DEFECT_INCORRECT` can often cause the module to have parsing issues that may be misleading, this just ensures the issue is clarified. This behavior can be reverted back to the previous with `ErrorBehavior.OLE_DEFECT_INCORRECT`. +* Fixed potential issues that may have made is possible for certain attachments to ignore filename conflict resolution code. **v0.41.5** * Fixed an issue from version `0.41.3` where the header being present but missing the `From` field would cause an exception. diff --git a/extract_msg/attachments/attachment.py b/extract_msg/attachments/attachment.py index 8ab3164a..2f056a26 100644 --- a/extract_msg/attachments/attachment.py +++ b/extract_msg/attachments/attachment.py @@ -160,34 +160,7 @@ def save(self, **kwargs) -> constants.SAVE_TYPE: mode = 'wb' _open = open - fullFilename = customPath / filename - - if _zip: - name, ext = os.path.splitext(filename) - nameList = _zip.namelist() - if str(fullFilename).replace('\\', '/') in nameList: - for i in range(2, 100): - testName = customPath / f'{name} ({i}){ext}' - if str(testName).replace('\\', '/') not in nameList: - fullFilename = testName - break - else: - # If we couldn't find one that didn't exist. - raise FileExistsError(f'Could not create the specified file because it already exists ("{fullFilename}").') - else: - if fullFilename.exists(): - # Try to split the filename into a name and extention. - name, ext = os.path.splitext(filename) - # Try to add a number to it so that we can save without - # overwriting. - for i in range(2, 100): - testName = customPath / f'{name} ({i}){ext}' - if not testName.exists(): - fullFilename = testName - break - else: - # If we couldn't find one that didn't exist. - raise FileExistsError(f'Could not create the specified file because it already exists ("{fullFilename}").') + fullFilename = self._handleFnc(_zip, filename, customPath, kwargs) with _open(str(fullFilename), mode) as f: f.write(self.__data) diff --git a/extract_msg/attachments/attachment_base.py b/extract_msg/attachments/attachment_base.py index f5a54a04..f6e2683f 100644 --- a/extract_msg/attachments/attachment_base.py +++ b/extract_msg/attachments/attachment_base.py @@ -10,6 +10,8 @@ import datetime import functools import logging +import os +import pathlib import weakref from functools import cached_property, partial @@ -241,6 +243,48 @@ def _getTypedStream(self, filename, _type = None): raise ReferenceError('The msg file for this Attachment instance has been garbage collected.') return msg._getTypedStream([self.__dir, filename], True, _type) + def _handleFnc(self, _zip, filename, customPath, kwargs) -> pathlib.Path: + """ + "Handle Filename Conflict" + + Internal function for use in determining how to modify the saving path + when a file with the same name already exists. This is mainly because + any save function that uses files will need to do this functionality. + + :returns: A pathlib.Path object to where the file should be saved. + """ + fullFilename = customPath / filename + + overwriteExisting = kwargs.get('overwriteExisting', False) + + if _zip: + # If we are writing to a zip file and are not overwriting. + if not overwriteExisting: + name, ext = os.path.splitext(filename) + nameList = _zip.namelist() + if str(fullFilename).replace('\\', '/') in nameList: + for i in range(2, 100): + testName = customPath / f'{name} ({i}){ext}' + if str(testName).replace('\\', '/') not in nameList: + return testName + else: + # If we couldn't find one that didn't exist. + raise FileExistsError(f'Could not create the specified file because it already exists ("{fullFilename}").') + else: + if not overwriteExisting and fullFilename.exists(): + # Try to split the filename into a name and extention. + name, ext = os.path.splitext(filename) + # Try to add a number to it so that we can save without overwriting. + for i in range(2, 100): + testName = customPath / f'{name} ({i}){ext}' + if not testName.exists(): + return testName + else: + # If we couldn't find one that didn't exist. + raise FileExistsError(f'Could not create the specified file because it already exists ("{fullFilename}").') + + return fullFilename + def exists(self, filename) -> bool: """ Checks if stream exists inside the attachment folder. diff --git a/extract_msg/attachments/custom_att.py b/extract_msg/attachments/custom_att.py index ab8c83af..93f424e1 100644 --- a/extract_msg/attachments/custom_att.py +++ b/extract_msg/attachments/custom_att.py @@ -129,33 +129,7 @@ def save(self, **kwargs) -> constants.SAVE_TYPE: mode = 'wb' _open = open - fullFilename = customPath / filename - - if _zip: - name, ext = os.path.splitext(filename) - nameList = _zip.namelist() - if str(fullFilename).replace('\\', '/') in nameList: - for i in range(2, 100): - testName = customPath / f'{name} ({i}){ext}' - if str(testName).replace('\\', '/') not in nameList: - fullFilename = testName - break - else: - # If we couldn't find one that didn't exist. - raise FileExistsError(f'Could not create the specified file because it already exists ("{fullFilename}").') - else: - if fullFilename.exists(): - # Try to split the filename into a name and extention. - name, ext = os.path.splitext(filename) - # Try to add a number to it so that we can save without overwriting. - for i in range(2, 100): - testName = customPath / f'{name} ({i}){ext}' - if not testName.exists(): - fullFilename = testName - break - else: - # If we couldn't find one that didn't exist. - raise FileExistsError(f'Could not create the specified file because it already exists ("{fullFilename}").') + fullFilename = self._handleFnc(_zip, filename, customPath, kwargs) with _open(str(fullFilename), mode) as f: f.write(self.__data) diff --git a/extract_msg/attachments/emb_msg_att.py b/extract_msg/attachments/emb_msg_att.py index b3784ef9..8ead803a 100644 --- a/extract_msg/attachments/emb_msg_att.py +++ b/extract_msg/attachments/emb_msg_att.py @@ -105,7 +105,7 @@ def save(self, **kwargs) -> constants.SAVE_TYPE: mode = 'wb' _open = open - fullFilename = customPath / filename + fullFilename = self._handleFnc(_zip, filename, customPath, kwargs) with _open(str(fullFilename), mode) as f: self.data.export(f) diff --git a/extract_msg/attachments/signed_att.py b/extract_msg/attachments/signed_att.py index a1802852..aafcf104 100644 --- a/extract_msg/attachments/signed_att.py +++ b/extract_msg/attachments/signed_att.py @@ -143,36 +143,9 @@ def save(self, **kwargs) -> constants.SAVE_TYPE: mode = 'wb' _open = open - fullFilename = customPath / filename + fullFilename = self._handleFnc(_zip, filename, customPath, kwargs) if self.type is AttachmentType.DATA: - if _zip: - name, ext = os.path.splitext(filename) - nameList = _zip.namelist() - if fullFilename in nameList: - for i in range(2, 100): - testName = customPath / f'{name} ({i}){ext}' - if testName not in nameList: - fullFilename = testName - break - else: - # If we couldn't find one that didn't exist. - raise FileExistsError(f'Could not create the specified file because it already exists ("{fullFilename}").') - else: - if fullFilename.exists(): - # Try to split the filename into a name and extention. - name, ext = os.path.splitext(filename) - # Try to add a number to it so that we can save without - # overwriting. - for i in range(2, 100): - testName = customPath / f'{name} ({i}){ext}' - if not testName.exists(): - fullFilename = testName - break - else: - # If we couldn't find one that didn't exist. - raise FileExistsError(f'Could not create the specified file because it already exists ("{fullFilename}").') - with _open(str(fullFilename), mode) as f: f.write(self.__data) From b1ae20b93eb69c4f19a2b60d891d03017d3bfc5e Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Tue, 4 Jul 2023 01:47:47 -0700 Subject: [PATCH 77/89] Added command line argument for #288 --- CHANGELOG.md | 2 +- extract_msg/__main__.py | 1 + extract_msg/utils.py | 3 +++ 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c1779894..96c01652 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ **v0.42.0** * [[TeamMsgExtractor #372](https://github.com/TeamMsgExtractor/msg-extractor/issues/372)] Changed the way that the save functions return a value. This makes the return value from all save functions much more informative, allowing a user to separate if a fole or folder (or if more than one) was saved from the function. It also guarentees that all classes from this module will return the relevent path(s) if data is actually saved. -* [[TeamMsgExtractor #288](https://github.com/TeamMsgExtractor/msg-extractor/issues/288)] Added feature to allow attachment save functions to simply overwrite existing files of the same name. +* [[TeamMsgExtractor #288](https://github.com/TeamMsgExtractor/msg-extractor/issues/288)] Added feature to allow attachment save functions to simply overwrite existing files of the same name. This can be done with the `overwriteExisting` keyword argument from code or the `--overwrite-existing` option from the command line. * Fixed an issue in the save functions that left the possibility for the zip files to not end up closing if the save function created it and then had an exception. * Added new submodule `custom_attachments`. This submodule provides an extendable way to handle custom attachment types, attachment types whose structure and formatting are not defined in the Microsoft documentation for MSG files. * Added new property `AttachmentBase.clsid` which returns the listed CLSID value of the data stream/storage of the attachment. diff --git a/extract_msg/__main__.py b/extract_msg/__main__.py index ac29a6d3..78055ff5 100644 --- a/extract_msg/__main__.py +++ b/extract_msg/__main__.py @@ -50,6 +50,7 @@ def main() -> None: 'extractEmbedded': args.extractEmbedded, 'html': args.html, 'json': args.json, + 'overwriteExisting': args.overwriteExisting, 'pdf': args.pdf, 'preparedHtml': args.preparedHtml, 'rtf': args.rtf, diff --git a/extract_msg/utils.py b/extract_msg/utils.py index 26fba656..45e66e20 100644 --- a/extract_msg/utils.py +++ b/extract_msg/utils.py @@ -406,6 +406,9 @@ def getCommandArgs(args) -> argparse.Namespace: # --extract-embedded parser.add_argument('--extract-embedded', dest='extractEmbedded', action='store_true', help='Extracts the embedded MSG files as MSG files instead of running their save functions.') + # --overwrite-existing + parser.add_argument('--overwrite-existing', dest='overwriteExisting', action='store_true', + help='Disables filename conflict resolution code for attachments when saving a file, causing files to be overwriten if two attachments with the same filename are on an MSG file.') # --skip-not-implemented parser.add_argument('--skip-not-implemented', '--skip-ni', dest='skipNotImplemented', action='store_true', help='Skips any attachments that are not implemented, allowing saving of the rest of the message.') From c0085b326714daaffdd024e7313820a2ed91e07b Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Tue, 4 Jul 2023 01:51:20 -0700 Subject: [PATCH 78/89] Update readme --- README.rst | 104 +++++++++++++++++++++++++---------------------------- 1 file changed, 48 insertions(+), 56 deletions(-) diff --git a/README.rst b/README.rst index 8adbffa1..3032c880 100644 --- a/README.rst +++ b/README.rst @@ -59,62 +59,54 @@ Currently, the README is in the process of being redone. For now, please refer to the usage information provided from the program's help dialog: :: - usage: extract_msg [-h] [--use-content-id] [--validate] [--json] [--file-logging] [-v] [--log LOG] [--config CONFIGPATH] - [--out OUTPATH] [--use-filename] [--dump-stdout] [--html] [--pdf] [--wk-path WKPATH] - [--wk-options [WKOPTIONS ...]] [--prepared-html] [--charset CHARSET] [--raw] [--rtf] [--allow-fallback] - [--skip-body-not-found] [--zip ZIP] [--save-header] [--attachments-only] [--skip-hidden] [--no-folders] - [--skip-embedded] [--extract-embedded] [--skip-not-implemented] [--out-name OUTNAME | --glob] [--ignore-rtfde] - [--progress] - msg [msg ...] - - extract_msg: Extracts emails and attachments saved in Microsoft Outlook's .msg files. https://github.com/TeamMsgExtractor/msg- - extractor - - positional arguments: - msg An MSG file to be parsed. - - optional arguments: - -h, --help show this help message and exit - --use-content-id, --cid - Save attachments by their Content ID, if they have one. Useful when working with the HTML body. - --validate Turns on file validation mode. Turns off regular file output. - --json Changes to write output files as json. - --file-logging Enables file logging. Implies --verbose level 1. - -v, --verbose Turns on console logging. Specify more than once for higher verbosity. - --log LOG Set the path to write the file log to. - --config CONFIGPATH Set the path to load the logging config from. - --out OUTPATH Set the folder to use for the program output. (Default: Current directory) - --use-filename Sets whether the name of each output is based on the msg filename. - --dump-stdout Tells the program to dump the message body (plain text) to stdout. Overrides saving arguments. - --html Sets whether the output should be HTML. If this is not possible, will error. - --pdf Saves the body as a PDF. If this is not possible, will error. - --wk-path WKPATH Overrides the path for finding wkhtmltopdf. - --wk-options [WKOPTIONS ...] - Sets additional options to be used in wkhtmltopdf. Should be a series of options and values, replacing the - - or -- in the beginning with + or ++, respectively. For example: --wk-options "+O Landscape" - --prepared-html When used in conjunction with --html, sets whether the HTML output should be prepared for embedded - attachments. - --charset CHARSET Character set to use for the prepared HTML in the added tag. (Default: utf-8) - --raw Sets whether the output should be raw. If this is not possible, will error. - --rtf Sets whether the output should be RTF. If this is not possible, will error. - --allow-fallback Tells the program to fallback to a different save type if the selected one is not possible. - --skip-body-not-found - Skips saving the body if the body cannot be found, rather than throwing an error. - --zip ZIP Path to use for saving to a zip file. - --save-header Store the header in a separate file. - --attachments-only Specify to only save attachments from an msg file. - --skip-hidden Skips any attachment marked as hidden (usually ones embedded in the body). - --no-folders Stores everything in the location specified by --out. Requires --attachments-only and is incompatible with - --out-name. - --skip-embedded Skips all embedded MSG files when saving attachments. - --extract-embedded Extracts the embedded MSG files as MSG files instead of running their save functions. - --skip-not-implemented, --skip-ni - Skips any attachments that are not implemented, allowing saving of the rest of the message. - --out-name OUTNAME Name to be used with saving the file output. Cannot be used if you are saving more than one file. - --glob, --wildcard Interpret all paths as having wildcards. Incompatible with --out-name. - --ignore-rtfde Ignores all errors thrown from RTFDE when trying to save. Useful for allowing fallback to continue when an - exception happens. - --progress Shows what file the program is currently working on during it's progress. + usage: extract_msg [-h] [--use-content-id] [--json] [--file-logging] [-v] [--log LOG] [--config CONFIGPATH] [--out OUTPATH] [--use-filename] [--dump-stdout] [--html] [--pdf] [--wk-path WKPATH] [--wk-options [WKOPTIONS ...]] + [--prepared-html] [--charset CHARSET] [--raw] [--rtf] [--allow-fallback] [--skip-body-not-found] [--zip ZIP] [--save-header] [--attachments-only] [--skip-hidden] [--no-folders] [--skip-embedded] [--extract-embedded] + [--overwrite-existing] [--skip-not-implemented] [--out-name OUTNAME | --glob] [--ignore-rtfde] [--progress] + msg [msg ...] + + extract_msg: Extracts emails and attachments saved in Microsoft Outlook's .msg files. https://github.com/TeamMsgExtractor/msg-extractor + + positional arguments: + msg An MSG file to be parsed. + + options: + -h, --help show this help message and exit + --use-content-id, --cid + Save attachments by their Content ID, if they have one. Useful when working with the HTML body. + --json Changes to write output files as json. + --file-logging Enables file logging. Implies --verbose level 1. + -v, --verbose Turns on console logging. Specify more than once for higher verbosity. + --log LOG Set the path to write the file log to. + --config CONFIGPATH Set the path to load the logging config from. + --out OUTPATH Set the folder to use for the program output. (Default: Current directory) + --use-filename Sets whether the name of each output is based on the msg filename. + --dump-stdout Tells the program to dump the message body (plain text) to stdout. Overrides saving arguments. + --html Sets whether the output should be HTML. If this is not possible, will error. + --pdf Saves the body as a PDF. If this is not possible, will error. + --wk-path WKPATH Overrides the path for finding wkhtmltopdf. + --wk-options [WKOPTIONS ...] + Sets additional options to be used in wkhtmltopdf. Should be a series of options and values, replacing the - or -- in the beginning with + or ++, respectively. For example: --wk-options "+O Landscape" + --prepared-html When used in conjunction with --html, sets whether the HTML output should be prepared for embedded attachments. + --charset CHARSET Character set to use for the prepared HTML in the added tag. (Default: utf-8) + --raw Sets whether the output should be raw. If this is not possible, will error. + --rtf Sets whether the output should be RTF. If this is not possible, will error. + --allow-fallback Tells the program to fallback to a different save type if the selected one is not possible. + --skip-body-not-found + Skips saving the body if the body cannot be found, rather than throwing an error. + --zip ZIP Path to use for saving to a zip file. + --save-header Store the header in a separate file. + --attachments-only Specify to only save attachments from an msg file. + --skip-hidden Skips any attachment marked as hidden (usually ones embedded in the body). + --no-folders Stores everything in the location specified by --out. Requires --attachments-only and is incompatible with --out-name. + --skip-embedded Skips all embedded MSG files when saving attachments. + --extract-embedded Extracts the embedded MSG files as MSG files instead of running their save functions. + --overwrite-existing Disables filename conflict resolution code for attachments when saving a file, causing files to be overwriten if two attachments with the same filename are on an MSG file. + --skip-not-implemented, --skip-ni + Skips any attachments that are not implemented, allowing saving of the rest of the message. + --out-name OUTNAME Name to be used with saving the file output. Cannot be used if you are saving more than one file. + --glob, --wildcard Interpret all paths as having wildcards. Incompatible with --out-name. + --ignore-rtfde Ignores all errors thrown from RTFDE when trying to save. Useful for allowing fallback to continue when an exception happens. + --progress Shows what file the program is currently working on during it's progress. **To use this in your own script**, start by using: From c42c54f88dc1f513fe52b467290bb4d4cb60b059 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Tue, 4 Jul 2023 01:52:29 -0700 Subject: [PATCH 79/89] Fix readme spacing issue --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index 3032c880..647e6761 100644 --- a/README.rst +++ b/README.rst @@ -92,7 +92,7 @@ refer to the usage information provided from the program's help dialog: --rtf Sets whether the output should be RTF. If this is not possible, will error. --allow-fallback Tells the program to fallback to a different save type if the selected one is not possible. --skip-body-not-found - Skips saving the body if the body cannot be found, rather than throwing an error. + Skips saving the body if the body cannot be found, rather than throwing an error. --zip ZIP Path to use for saving to a zip file. --save-header Store the header in a separate file. --attachments-only Specify to only save attachments from an msg file. @@ -102,7 +102,7 @@ refer to the usage information provided from the program's help dialog: --extract-embedded Extracts the embedded MSG files as MSG files instead of running their save functions. --overwrite-existing Disables filename conflict resolution code for attachments when saving a file, causing files to be overwriten if two attachments with the same filename are on an MSG file. --skip-not-implemented, --skip-ni - Skips any attachments that are not implemented, allowing saving of the rest of the message. + Skips any attachments that are not implemented, allowing saving of the rest of the message. --out-name OUTNAME Name to be used with saving the file output. Cannot be used if you are saving more than one file. --glob, --wildcard Interpret all paths as having wildcards. Incompatible with --out-name. --ignore-rtfde Ignores all errors thrown from RTFDE when trying to save. Useful for allowing fallback to continue when an exception happens. From 81f777524f88118c1a18c1ff44632760f4d23b3d Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Tue, 4 Jul 2023 02:07:32 -0700 Subject: [PATCH 80/89] Update changelog to reference #40 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 96c01652..c482c196 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,8 @@ **v0.42.0** * [[TeamMsgExtractor #372](https://github.com/TeamMsgExtractor/msg-extractor/issues/372)] Changed the way that the save functions return a value. This makes the return value from all save functions much more informative, allowing a user to separate if a fole or folder (or if more than one) was saved from the function. It also guarentees that all classes from this module will return the relevent path(s) if data is actually saved. * [[TeamMsgExtractor #288](https://github.com/TeamMsgExtractor/msg-extractor/issues/288)] Added feature to allow attachment save functions to simply overwrite existing files of the same name. This can be done with the `overwriteExisting` keyword argument from code or the `--overwrite-existing` option from the command line. +* [[TeamMsgExtractor #40](https://github.com/TeamMsgExtractor/msg-extractor/issues/40)] Added new submodule `custom_attachments`. This submodule provides an extendable way to handle custom attachment types, attachment types whose structure and formatting are not defined in the Microsoft documentation for MSG files. This includes a handler to at least partially cover support for Outlook images. * Fixed an issue in the save functions that left the possibility for the zip files to not end up closing if the save function created it and then had an exception. -* Added new submodule `custom_attachments`. This submodule provides an extendable way to handle custom attachment types, attachment types whose structure and formatting are not defined in the Microsoft documentation for MSG files. * Added new property `AttachmentBase.clsid` which returns the listed CLSID value of the data stream/storage of the attachment. * Changed internal behavior of `MSGFile.attachments`. This should not cause any noticeable changes to the output. * Refactored code significantly to make it more organized. From d4cdaef0422152ae98a8eb809f1145844ac763ff Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Thu, 6 Jul 2023 21:09:27 -0700 Subject: [PATCH 81/89] Update changelog to reference new issue --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c482c196..59c3dfc5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ * [[TeamMsgExtractor #372](https://github.com/TeamMsgExtractor/msg-extractor/issues/372)] Changed the way that the save functions return a value. This makes the return value from all save functions much more informative, allowing a user to separate if a fole or folder (or if more than one) was saved from the function. It also guarentees that all classes from this module will return the relevent path(s) if data is actually saved. * [[TeamMsgExtractor #288](https://github.com/TeamMsgExtractor/msg-extractor/issues/288)] Added feature to allow attachment save functions to simply overwrite existing files of the same name. This can be done with the `overwriteExisting` keyword argument from code or the `--overwrite-existing` option from the command line. * [[TeamMsgExtractor #40](https://github.com/TeamMsgExtractor/msg-extractor/issues/40)] Added new submodule `custom_attachments`. This submodule provides an extendable way to handle custom attachment types, attachment types whose structure and formatting are not defined in the Microsoft documentation for MSG files. This includes a handler to at least partially cover support for Outlook images. +* [[TeamMsgExtractor #373](https://github.com/TeamMsgExtractor/msg-extractor/issues/373)] Added the `encoding` submodule for encoding tasks, including proper support for Microsoft's implementation of cp950. This gets added to the codecs list as "windows-950". * Fixed an issue in the save functions that left the possibility for the zip files to not end up closing if the save function created it and then had an exception. * Added new property `AttachmentBase.clsid` which returns the listed CLSID value of the data stream/storage of the attachment. * Changed internal behavior of `MSGFile.attachments`. This should not cause any noticeable changes to the output. @@ -25,7 +26,6 @@ * Changed the option to suppress `RTFDE` errors to fall under the `ErrorBehavior` enum. Usage of the original option will be allowable, but is being marked as deprecated. However, it is still a dedicated option from the command line. * Also fixed the option not properly ignoring some RTFDE errors, specifically the ones that it is normal for the module to throw. * Removed some constants that are not used by the module. -* Added the `encoding` submodule for encoding tasks, including proper support for Microsoft's implementation of cp950. This gets added to the codecs list as "windows-950". * Updated to support `RTFDE` version `0.1.0`. Users encountering random erros from that module should find that those errors have disappeared. If you get errors from it still, bring up the issue on their GitHub. * Fixed bug that would cause weird behavior if you gave an empty string as the path for an MSG file. * Added support for `IPM.StickyNote`. @@ -45,6 +45,7 @@ * Fixed sender not being properly decoded in some circumstances. * Changed behavior of `MSGFile` to have olefile raise defects of type `DEFECT_INCORRECT` and above instead of just `DEFECT_FATAL`. Uncaught issues of `DEFECT_INCORRECT` can often cause the module to have parsing issues that may be misleading, this just ensures the issue is clarified. This behavior can be reverted back to the previous with `ErrorBehavior.OLE_DEFECT_INCORRECT`. * Fixed potential issues that may have made is possible for certain attachments to ignore filename conflict resolution code. +* Changed the **v0.41.5** * Fixed an issue from version `0.41.3` where the header being present but missing the `From` field would cause an exception. From 6f91856a5ffa730d08dbed843c845c4d34f70d87 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Thu, 6 Jul 2023 23:23:37 -0700 Subject: [PATCH 82/89] Update some comments --- extract_msg/encoding/__init__.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/extract_msg/encoding/__init__.py b/extract_msg/encoding/__init__.py index 2696e220..0dab8a00 100644 --- a/extract_msg/encoding/__init__.py +++ b/extract_msg/encoding/__init__.py @@ -62,7 +62,8 @@ 932: 'shift_jis', # ANSI/OEM Japanese; Japanese (Shift-JIS) 936: 'gb2312', # ANSI/OEM Simplified Chinese (PRC, Singapore); Chinese Simplified (GB2312) 949: 'ks_c_5601-1987', # ANSI/OEM Korean (Unified Hangul Code) - # We *must* use a custom encoding because of a core Python issue. + # We *must* use a custom encoding because the Python implementation differs + # from the Microsoft implementation. 950: 'windows-950', # ANSI/OEM Traditional Chinese (Taiwan; Hong Kong SAR, PRC); Chinese Traditional (Big5) 1026: 'IBM1026', # IBM EBCDIC Turkish (Latin 5) 1047: 'cp1047', # IBM EBCDIC Latin 1/Open System @@ -117,8 +118,8 @@ 10081: 'x-mac-turkish', # Turkish (Mac) # UNSUPPORTED. 10082: 'x-mac-croatian', # Croatian (Mac) - 12000: 'utf-32', # Unicode UTF-32, little endian byte order; available only to managed applications - 12001: 'utf-32BE', # Unicode UTF-32, big endian byte order; available only to managed applications + 12000: 'utf-32', # Unicode UTF-32, little endian byte order + 12001: 'utf-32BE', # Unicode UTF-32, big endian byte order # UNSUPPORTED. 20000: 'x-Chinese_CNS', # CNS Taiwan; Chinese Traditional (CNS) # UNSUPPORTED. From 0cc2219e334c5dc0189e0211277561e9d846862d Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Fri, 7 Jul 2023 21:23:07 -0700 Subject: [PATCH 83/89] Add windows-874. Fix issues in encoding --- CHANGELOG.md | 2 +- extract_msg/encoding/__init__.py | 8 +- extract_msg/encoding/_dt/__init__.py | 4 + extract_msg/encoding/_dt/_win874_dec.py | 6 + extract_msg/encoding/_dt/_win950_dec.py | 6 + extract_msg/encoding/_win950_dec.py | 5 - extract_msg/encoding/utils.py | 232 ++++++++++++++++++++++-- extract_msg/encoding/win950.py | 59 ------ 8 files changed, 237 insertions(+), 85 deletions(-) create mode 100644 extract_msg/encoding/_dt/__init__.py create mode 100644 extract_msg/encoding/_dt/_win874_dec.py create mode 100644 extract_msg/encoding/_dt/_win950_dec.py delete mode 100644 extract_msg/encoding/_win950_dec.py delete mode 100644 extract_msg/encoding/win950.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 59c3dfc5..421e6bed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,7 +45,7 @@ * Fixed sender not being properly decoded in some circumstances. * Changed behavior of `MSGFile` to have olefile raise defects of type `DEFECT_INCORRECT` and above instead of just `DEFECT_FATAL`. Uncaught issues of `DEFECT_INCORRECT` can often cause the module to have parsing issues that may be misleading, this just ensures the issue is clarified. This behavior can be reverted back to the previous with `ErrorBehavior.OLE_DEFECT_INCORRECT`. * Fixed potential issues that may have made is possible for certain attachments to ignore filename conflict resolution code. -* Changed the +* Added support for the windows-874 encoding. This includes infrastructure to more easily support new single-byte encodings, only needing a decoding table to make them work. **v0.41.5** * Fixed an issue from version `0.41.3` where the header being present but missing the `From` field would cause an exception. diff --git a/extract_msg/encoding/__init__.py b/extract_msg/encoding/__init__.py index 0dab8a00..a1470818 100644 --- a/extract_msg/encoding/__init__.py +++ b/extract_msg/encoding/__init__.py @@ -11,8 +11,8 @@ import ebcdic as _ import codecs -from . import win950 from ..exceptions import UnknownCodepageError, UnsupportedEncodingError +from .utils import createSBEncoding, createVBEncoding # This is a dictionary matching the code page number to it's encoding name. @@ -264,8 +264,10 @@ def lookupCodePage(id_ : int) -> str: def _lookupEncoding(name): return _codecsInfo.get(name) - +from ._dt import _win874_dec, _win950_dec _codecsInfo = { - 'windows_950': win950.getregentry(), + 'windows_950': createVBEncoding('windows-950', _win950_dec.decodingTable), + 'windows_874': createSBEncoding('windows-874', _win874_dec.decodingTable), } + codecs.register(_lookupEncoding) \ No newline at end of file diff --git a/extract_msg/encoding/_dt/__init__.py b/extract_msg/encoding/_dt/__init__.py new file mode 100644 index 00000000..f23634ca --- /dev/null +++ b/extract_msg/encoding/_dt/__init__.py @@ -0,0 +1,4 @@ +""" +Decoding tables for the various encodings implemented. This allows the encoding +definitions to be neater. +""" \ No newline at end of file diff --git a/extract_msg/encoding/_dt/_win874_dec.py b/extract_msg/encoding/_dt/_win874_dec.py new file mode 100644 index 00000000..c80429fd --- /dev/null +++ b/extract_msg/encoding/_dt/_win874_dec.py @@ -0,0 +1,6 @@ +__all__ = [ + 'decodingTable', +] + + +decodingTable={0:'\x00',1:'\x01',2:'\x02',3:'\x03',4:'\x04',5:'\x05',6:'\x06',7:'\x07',8:'\x08',9:'\t',10:'\n',11:'\x0B',12:'\x0C',13:'\r',14:'\x0E',15:'\x0F',16:'\x10',17:'\x11',18:'\x12',19:'\x13',20:'\x14',21:'\x15',22:'\x16',23:'\x17',24:'\x18',25:'\x19',26:'\x1A',27:'\x1B',28:'\x1C',29:'\x1D',30:'\x1E',31:'\x1F',32:' ',33:'!',34:'"',35:'#',36:'$',37:'%',38:'&',39:"'",40:'(',41:')',42:'*',43:'+',44:',',45:'-',46:'.',47:'/',48:'0',49:'1',50:'2',51:'3',52:'4',53:'5',54:'6',55:'7',56:'8',57:'9',58:':',59:';',60:'<',61:'=',62:'>',63:'?',64:'@',65:'A',66:'B',67:'C',68:'D',69:'E',70:'F',71:'G',72:'H',73:'I',74:'J',75:'K',76:'L',77:'M',78:'N',79:'O',80:'P',81:'Q',82:'R',83:'S',84:'T',85:'U',86:'V',87:'W',88:'X',89:'Y',90:'Z',91:'[',92:'\\',93:']',94:'^',95:'_',96:'`',97:'a',98:'b',99:'c',100:'d',101:'e',102:'f',103:'g',104:'h',105:'i',106:'j',107:'k',108:'l',109:'m',110:'n',111:'o',112:'p',113:'q',114:'r',115:'s',116:'t',117:'u',118:'v',119:'w',120:'x',121:'y',122:'z',123:'{',124:'|',125:'}',126:'~',127:'\x7F',128:'\x80',129:'\u20AC',133:'\u2026',145:'\u2018',146:'\u2019',147:'\u201C',148:'\u201D',149:'\u2022',150:'\u2013',151:'\u2014',160:'\xA0',161:'\u0E01',162:'\u0E02',163:'\u0E03',164:'\u0E04',165:'\u0E05',166:'\u0E06',167:'\u0E07',168:'\u0E08',169:'\u0E09',170:'\u0E0A',171:'\u0E0B',172:'\u0E0C',173:'\u0E0D',174:'\u0E0E',175:'\u0E0F',176:'\u0E10',177:'\u0E11',178:'\u0E12',179:'\u0E13',180:'\u0E14',181:'\u0E15',182:'\u0E16',183:'\u0E17',184:'\u0E18',185:'\u0E19',186:'\u0E1A',187:'\u0E1B',188:'\u0E1C',189:'\u0E1D',190:'\u0E1E',191:'\u0E1F',192:'\u0E20',193:'\u0E21',194:'\u0E22',195:'\u0E23',196:'\u0E24',197:'\u0E25',198:'\u0E26',199:'\u0E27',200:'\u0E28',201:'\u0E29',202:'\u0E2A',203:'\u0E2B',204:'\u0E2C',205:'\u0E2D',206:'\u0E2E',207:'\u0E2F',208:'\u0E30',209:'\u0E31',210:'\u0E32',211:'\u0E33',212:'\u0E34',213:'\u0E35',214:'\u0E36',215:'\u0E37',216:'\u0E38',217:'\u0E39',218:'\u0E3A',224:'\u0E3F',225:'\u0E40',226:'\u0E41',227:'\u0E42',228:'\u0E43',229:'\u0E44',230:'\u0E45',231:'\u0E46',232:'\u0E47',233:'\u0E48',234:'\u0E49',235:'\u0E4A',236:'\u0E4B',237:'\u0E4C',238:'\u0E4D',239:'\u0E4E',240:'\u0E4F',241:'\u0E50',242:'\u0E51',243:'\u0E52',244:'\u0E53',245:'\u0E54',246:'\u0E55',247:'\u0E56',248:'\u0E57',249:'\u0E58',250:'\u0E59',251:'\u0E5A',252:'\u0E5B'} \ No newline at end of file diff --git a/extract_msg/encoding/_dt/_win950_dec.py b/extract_msg/encoding/_dt/_win950_dec.py new file mode 100644 index 00000000..49785b22 --- /dev/null +++ b/extract_msg/encoding/_dt/_win950_dec.py @@ -0,0 +1,6 @@ +__all__ = [ + 'decodingTable' +] + + +decodingTable={0:'\x00',1:'\x01',2:'\x02',3:'\x03',4:'\x04',5:'\x05',6:'\x06',7:'\x07',8:'\x08',9:'\t',10:'\n',11:'\x0B',12:'\x0C',13:'\r',14:'\x0E',15:'\x0F',16:'\x10',17:'\x11',18:'\x12',19:'\x13',20:'\x14',21:'\x15',22:'\x16',23:'\x17',24:'\x18',25:'\x19',26:'\x1A',27:'\x1B',28:'\x1C',29:'\x1D',30:'\x1E',31:'\x1F',32:' ',33:'!',34:'"',35:'#',36:'$',37:'%',38:'&',39:"'",40:'(',41:')',42:'*',43:'+',44:',',45:'-',46:'.',47:'/',48:'0',49:'1',50:'2',51:'3',52:'4',53:'5',54:'6',55:'7',56:'8',57:'9',58:':',59:';',60:'<',61:'=',62:'>',63:'?',64:'@',65:'A',66:'B',67:'C',68:'D',69:'E',70:'F',71:'G',72:'H',73:'I',74:'J',75:'K',76:'L',77:'M',78:'N',79:'O',80:'P',81:'Q',82:'R',83:'S',84:'T',85:'U',86:'V',87:'W',88:'X',89:'Y',90:'Z',91:'[',92:'\\',93:']',94:'^',95:'_',96:'`',97:'a',98:'b',99:'c',100:'d',101:'e',102:'f',103:'g',104:'h',105:'i',106:'j',107:'k',108:'l',109:'m',110:'n',111:'o',112:'p',113:'q',114:'r',115:'s',116:'t',117:'u',118:'v',119:'w',120:'x',121:'y',122:'z',123:'{',124:'|',125:'}',126:'~',127:'\x7F',128:'\x80',255:'\uF8F8',33088:'\uEEB8',33089:'\uEEB9',33090:'\uEEBA',33091:'\uEEBB',33092:'\uEEBC',33093:'\uEEBD',33094:'\uEEBE',33095:'\uEEBF',33096:'\uEEC0',33097:'\uEEC1',33098:'\uEEC2',33099:'\uEEC3',33100:'\uEEC4',33101:'\uEEC5',33102:'\uEEC6',33103:'\uEEC7',33104:'\uEEC8',33105:'\uEEC9',33106:'\uEECA',33107:'\uEECB',33108:'\uEECC',33109:'\uEECD',33110:'\uEECE',33111:'\uEECF',33112:'\uEED0',33113:'\uEED1',33114:'\uEED2',33115:'\uEED3',33116:'\uEED4',33117:'\uEED5',33118:'\uEED6',33119:'\uEED7',33120:'\uEED8',33121:'\uEED9',33122:'\uEEDA',33123:'\uEEDB',33124:'\uEEDC',33125:'\uEEDD',33126:'\uEEDE',33127:'\uEEDF',33128:'\uEEE0',33129:'\uEEE1',33130:'\uEEE2',33131:'\uEEE3',33132:'\uEEE4',33133:'\uEEE5',33134:'\uEEE6',33135:'\uEEE7',33136:'\uEEE8',33137:'\uEEE9',33138:'\uEEEA',33139:'\uEEEB',33140:'\uEEEC',33141:'\uEEED',33142:'\uEEEE',33143:'\uEEEF',33144:'\uEEF0',33145:'\uEEF1',33146:'\uEEF2',33147:'\uEEF3',33148:'\uEEF4',33149:'\uEEF5',33150:'\uEEF6',33185:'\uEEF7',33186:'\uEEF8',33187:'\uEEF9',33188:'\uEEFA',33189:'\uEEFB',33190:'\uEEFC',33191:'\uEEFD',33192:'\uEEFE',33193:'\uEEFF',33194:'\uEF00',33195:'\uEF01',33196:'\uEF02',33197:'\uEF03',33198:'\uEF04',33199:'\uEF05',33200:'\uEF06',33201:'\uEF07',33202:'\uEF08',33203:'\uEF09',33204:'\uEF0A',33205:'\uEF0B',33206:'\uEF0C',33207:'\uEF0D',33208:'\uEF0E',33209:'\uEF0F',33210:'\uEF10',33211:'\uEF11',33212:'\uEF12',33213:'\uEF13',33214:'\uEF14',33215:'\uEF15',33216:'\uEF16',33217:'\uEF17',33218:'\uEF18',33219:'\uEF19',33220:'\uEF1A',33221:'\uEF1B',33222:'\uEF1C',33223:'\uEF1D',33224:'\uEF1E',33225:'\uEF1F',33226:'\uEF20',33227:'\uEF21',33228:'\uEF22',33229:'\uEF23',33230:'\uEF24',33231:'\uEF25',33232:'\uEF26',33233:'\uEF27',33234:'\uEF28',33235:'\uEF29',33236:'\uEF2A',33237:'\uEF2B',33238:'\uEF2C',33239:'\uEF2D',33240:'\uEF2E',33241:'\uEF2F',33242:'\uEF30',33243:'\uEF31',33244:'\uEF32',33245:'\uEF33',33246:'\uEF34',33247:'\uEF35',33248:'\uEF36',33249:'\uEF37',33250:'\uEF38',33251:'\uEF39',33252:'\uEF3A',33253:'\uEF3B',33254:'\uEF3C',33255:'\uEF3D',33256:'\uEF3E',33257:'\uEF3F',33258:'\uEF40',33259:'\uEF41',33260:'\uEF42',33261:'\uEF43',33262:'\uEF44',33263:'\uEF45',33264:'\uEF46',33265:'\uEF47',33266:'\uEF48',33267:'\uEF49',33268:'\uEF4A',33269:'\uEF4B',33270:'\uEF4C',33271:'\uEF4D',33272:'\uEF4E',33273:'\uEF4F',33274:'\uEF50',33275:'\uEF51',33276:'\uEF52',33277:'\uEF53',33278:'\uEF54',33344:'\uEF55',33345:'\uEF56',33346:'\uEF57',33347:'\uEF58',33348:'\uEF59',33349:'\uEF5A',33350:'\uEF5B',33351:'\uEF5C',33352:'\uEF5D',33353:'\uEF5E',33354:'\uEF5F',33355:'\uEF60',33356:'\uEF61',33357:'\uEF62',33358:'\uEF63',33359:'\uEF64',33360:'\uEF65',33361:'\uEF66',33362:'\uEF67',33363:'\uEF68',33364:'\uEF69',33365:'\uEF6A',33366:'\uEF6B',33367:'\uEF6C',33368:'\uEF6D',33369:'\uEF6E',33370:'\uEF6F',33371:'\uEF70',33372:'\uEF71',33373:'\uEF72',33374:'\uEF73',33375:'\uEF74',33376:'\uEF75',33377:'\uEF76',33378:'\uEF77',33379:'\uEF78',33380:'\uEF79',33381:'\uEF7A',33382:'\uEF7B',33383:'\uEF7C',33384:'\uEF7D',33385:'\uEF7E',33386:'\uEF7F',33387:'\uEF80',33388:'\uEF81',33389:'\uEF82',33390:'\uEF83',33391:'\uEF84',33392:'\uEF85',33393:'\uEF86',33394:'\uEF87',33395:'\uEF88',33396:'\uEF89',33397:'\uEF8A',33398:'\uEF8B',33399:'\uEF8C',33400:'\uEF8D',33401:'\uEF8E',33402:'\uEF8F',33403:'\uEF90',33404:'\uEF91',33405:'\uEF92',33406:'\uEF93',33441:'\uEF94',33442:'\uEF95',33443:'\uEF96',33444:'\uEF97',33445:'\uEF98',33446:'\uEF99',33447:'\uEF9A',33448:'\uEF9B',33449:'\uEF9C',33450:'\uEF9D',33451:'\uEF9E',33452:'\uEF9F',33453:'\uEFA0',33454:'\uEFA1',33455:'\uEFA2',33456:'\uEFA3',33457:'\uEFA4',33458:'\uEFA5',33459:'\uEFA6',33460:'\uEFA7',33461:'\uEFA8',33462:'\uEFA9',33463:'\uEFAA',33464:'\uEFAB',33465:'\uEFAC',33466:'\uEFAD',33467:'\uEFAE',33468:'\uEFAF',33469:'\uEFB0',33470:'\uEFB1',33471:'\uEFB2',33472:'\uEFB3',33473:'\uEFB4',33474:'\uEFB5',33475:'\uEFB6',33476:'\uEFB7',33477:'\uEFB8',33478:'\uEFB9',33479:'\uEFBA',33480:'\uEFBB',33481:'\uEFBC',33482:'\uEFBD',33483:'\uEFBE',33484:'\uEFBF',33485:'\uEFC0',33486:'\uEFC1',33487:'\uEFC2',33488:'\uEFC3',33489:'\uEFC4',33490:'\uEFC5',33491:'\uEFC6',33492:'\uEFC7',33493:'\uEFC8',33494:'\uEFC9',33495:'\uEFCA',33496:'\uEFCB',33497:'\uEFCC',33498:'\uEFCD',33499:'\uEFCE',33500:'\uEFCF',33501:'\uEFD0',33502:'\uEFD1',33503:'\uEFD2',33504:'\uEFD3',33505:'\uEFD4',33506:'\uEFD5',33507:'\uEFD6',33508:'\uEFD7',33509:'\uEFD8',33510:'\uEFD9',33511:'\uEFDA',33512:'\uEFDB',33513:'\uEFDC',33514:'\uEFDD',33515:'\uEFDE',33516:'\uEFDF',33517:'\uEFE0',33518:'\uEFE1',33519:'\uEFE2',33520:'\uEFE3',33521:'\uEFE4',33522:'\uEFE5',33523:'\uEFE6',33524:'\uEFE7',33525:'\uEFE8',33526:'\uEFE9',33527:'\uEFEA',33528:'\uEFEB',33529:'\uEFEC',33530:'\uEFED',33531:'\uEFEE',33532:'\uEFEF',33533:'\uEFF0',33534:'\uEFF1',33600:'\uEFF2',33601:'\uEFF3',33602:'\uEFF4',33603:'\uEFF5',33604:'\uEFF6',33605:'\uEFF7',33606:'\uEFF8',33607:'\uEFF9',33608:'\uEFFA',33609:'\uEFFB',33610:'\uEFFC',33611:'\uEFFD',33612:'\uEFFE',33613:'\uEFFF',33614:'\uF000',33615:'\uF001',33616:'\uF002',33617:'\uF003',33618:'\uF004',33619:'\uF005',33620:'\uF006',33621:'\uF007',33622:'\uF008',33623:'\uF009',33624:'\uF00A',33625:'\uF00B',33626:'\uF00C',33627:'\uF00D',33628:'\uF00E',33629:'\uF00F',33630:'\uF010',33631:'\uF011',33632:'\uF012',33633:'\uF013',33634:'\uF014',33635:'\uF015',33636:'\uF016',33637:'\uF017',33638:'\uF018',33639:'\uF019',33640:'\uF01A',33641:'\uF01B',33642:'\uF01C',33643:'\uF01D',33644:'\uF01E',33645:'\uF01F',33646:'\uF020',33647:'\uF021',33648:'\uF022',33649:'\uF023',33650:'\uF024',33651:'\uF025',33652:'\uF026',33653:'\uF027',33654:'\uF028',33655:'\uF029',33656:'\uF02A',33657:'\uF02B',33658:'\uF02C',33659:'\uF02D',33660:'\uF02E',33661:'\uF02F',33662:'\uF030',33697:'\uF031',33698:'\uF032',33699:'\uF033',33700:'\uF034',33701:'\uF035',33702:'\uF036',33703:'\uF037',33704:'\uF038',33705:'\uF039',33706:'\uF03A',33707:'\uF03B',33708:'\uF03C',33709:'\uF03D',33710:'\uF03E',33711:'\uF03F',33712:'\uF040',33713:'\uF041',33714:'\uF042',33715:'\uF043',33716:'\uF044',33717:'\uF045',33718:'\uF046',33719:'\uF047',33720:'\uF048',33721:'\uF049',33722:'\uF04A',33723:'\uF04B',33724:'\uF04C',33725:'\uF04D',33726:'\uF04E',33727:'\uF04F',33728:'\uF050',33729:'\uF051',33730:'\uF052',33731:'\uF053',33732:'\uF054',33733:'\uF055',33734:'\uF056',33735:'\uF057',33736:'\uF058',33737:'\uF059',33738:'\uF05A',33739:'\uF05B',33740:'\uF05C',33741:'\uF05D',33742:'\uF05E',33743:'\uF05F',33744:'\uF060',33745:'\uF061',33746:'\uF062',33747:'\uF063',33748:'\uF064',33749:'\uF065',33750:'\uF066',33751:'\uF067',33752:'\uF068',33753:'\uF069',33754:'\uF06A',33755:'\uF06B',33756:'\uF06C',33757:'\uF06D',33758:'\uF06E',33759:'\uF06F',33760:'\uF070',33761:'\uF071',33762:'\uF072',33763:'\uF073',33764:'\uF074',33765:'\uF075',33766:'\uF076',33767:'\uF077',33768:'\uF078',33769:'\uF079',33770:'\uF07A',33771:'\uF07B',33772:'\uF07C',33773:'\uF07D',33774:'\uF07E',33775:'\uF07F',33776:'\uF080',33777:'\uF081',33778:'\uF082',33779:'\uF083',33780:'\uF084',33781:'\uF085',33782:'\uF086',33783:'\uF087',33784:'\uF088',33785:'\uF089',33786:'\uF08A',33787:'\uF08B',33788:'\uF08C',33789:'\uF08D',33790:'\uF08E',33856:'\uF08F',33857:'\uF090',33858:'\uF091',33859:'\uF092',33860:'\uF093',33861:'\uF094',33862:'\uF095',33863:'\uF096',33864:'\uF097',33865:'\uF098',33866:'\uF099',33867:'\uF09A',33868:'\uF09B',33869:'\uF09C',33870:'\uF09D',33871:'\uF09E',33872:'\uF09F',33873:'\uF0A0',33874:'\uF0A1',33875:'\uF0A2',33876:'\uF0A3',33877:'\uF0A4',33878:'\uF0A5',33879:'\uF0A6',33880:'\uF0A7',33881:'\uF0A8',33882:'\uF0A9',33883:'\uF0AA',33884:'\uF0AB',33885:'\uF0AC',33886:'\uF0AD',33887:'\uF0AE',33888:'\uF0AF',33889:'\uF0B0',33890:'\uF0B1',33891:'\uF0B2',33892:'\uF0B3',33893:'\uF0B4',33894:'\uF0B5',33895:'\uF0B6',33896:'\uF0B7',33897:'\uF0B8',33898:'\uF0B9',33899:'\uF0BA',33900:'\uF0BB',33901:'\uF0BC',33902:'\uF0BD',33903:'\uF0BE',33904:'\uF0BF',33905:'\uF0C0',33906:'\uF0C1',33907:'\uF0C2',33908:'\uF0C3',33909:'\uF0C4',33910:'\uF0C5',33911:'\uF0C6',33912:'\uF0C7',33913:'\uF0C8',33914:'\uF0C9',33915:'\uF0CA',33916:'\uF0CB',33917:'\uF0CC',33918:'\uF0CD',33953:'\uF0CE',33954:'\uF0CF',33955:'\uF0D0',33956:'\uF0D1',33957:'\uF0D2',33958:'\uF0D3',33959:'\uF0D4',33960:'\uF0D5',33961:'\uF0D6',33962:'\uF0D7',33963:'\uF0D8',33964:'\uF0D9',33965:'\uF0DA',33966:'\uF0DB',33967:'\uF0DC',33968:'\uF0DD',33969:'\uF0DE',33970:'\uF0DF',33971:'\uF0E0',33972:'\uF0E1',33973:'\uF0E2',33974:'\uF0E3',33975:'\uF0E4',33976:'\uF0E5',33977:'\uF0E6',33978:'\uF0E7',33979:'\uF0E8',33980:'\uF0E9',33981:'\uF0EA',33982:'\uF0EB',33983:'\uF0EC',33984:'\uF0ED',33985:'\uF0EE',33986:'\uF0EF',33987:'\uF0F0',33988:'\uF0F1',33989:'\uF0F2',33990:'\uF0F3',33991:'\uF0F4',33992:'\uF0F5',33993:'\uF0F6',33994:'\uF0F7',33995:'\uF0F8',33996:'\uF0F9',33997:'\uF0FA',33998:'\uF0FB',33999:'\uF0FC',34000:'\uF0FD',34001:'\uF0FE',34002:'\uF0FF',34003:'\uF100',34004:'\uF101',34005:'\uF102',34006:'\uF103',34007:'\uF104',34008:'\uF105',34009:'\uF106',34010:'\uF107',34011:'\uF108',34012:'\uF109',34013:'\uF10A',34014:'\uF10B',34015:'\uF10C',34016:'\uF10D',34017:'\uF10E',34018:'\uF10F',34019:'\uF110',34020:'\uF111',34021:'\uF112',34022:'\uF113',34023:'\uF114',34024:'\uF115',34025:'\uF116',34026:'\uF117',34027:'\uF118',34028:'\uF119',34029:'\uF11A',34030:'\uF11B',34031:'\uF11C',34032:'\uF11D',34033:'\uF11E',34034:'\uF11F',34035:'\uF120',34036:'\uF121',34037:'\uF122',34038:'\uF123',34039:'\uF124',34040:'\uF125',34041:'\uF126',34042:'\uF127',34043:'\uF128',34044:'\uF129',34045:'\uF12A',34046:'\uF12B',34112:'\uF12C',34113:'\uF12D',34114:'\uF12E',34115:'\uF12F',34116:'\uF130',34117:'\uF131',34118:'\uF132',34119:'\uF133',34120:'\uF134',34121:'\uF135',34122:'\uF136',34123:'\uF137',34124:'\uF138',34125:'\uF139',34126:'\uF13A',34127:'\uF13B',34128:'\uF13C',34129:'\uF13D',34130:'\uF13E',34131:'\uF13F',34132:'\uF140',34133:'\uF141',34134:'\uF142',34135:'\uF143',34136:'\uF144',34137:'\uF145',34138:'\uF146',34139:'\uF147',34140:'\uF148',34141:'\uF149',34142:'\uF14A',34143:'\uF14B',34144:'\uF14C',34145:'\uF14D',34146:'\uF14E',34147:'\uF14F',34148:'\uF150',34149:'\uF151',34150:'\uF152',34151:'\uF153',34152:'\uF154',34153:'\uF155',34154:'\uF156',34155:'\uF157',34156:'\uF158',34157:'\uF159',34158:'\uF15A',34159:'\uF15B',34160:'\uF15C',34161:'\uF15D',34162:'\uF15E',34163:'\uF15F',34164:'\uF160',34165:'\uF161',34166:'\uF162',34167:'\uF163',34168:'\uF164',34169:'\uF165',34170:'\uF166',34171:'\uF167',34172:'\uF168',34173:'\uF169',34174:'\uF16A',34209:'\uF16B',34210:'\uF16C',34211:'\uF16D',34212:'\uF16E',34213:'\uF16F',34214:'\uF170',34215:'\uF171',34216:'\uF172',34217:'\uF173',34218:'\uF174',34219:'\uF175',34220:'\uF176',34221:'\uF177',34222:'\uF178',34223:'\uF179',34224:'\uF17A',34225:'\uF17B',34226:'\uF17C',34227:'\uF17D',34228:'\uF17E',34229:'\uF17F',34230:'\uF180',34231:'\uF181',34232:'\uF182',34233:'\uF183',34234:'\uF184',34235:'\uF185',34236:'\uF186',34237:'\uF187',34238:'\uF188',34239:'\uF189',34240:'\uF18A',34241:'\uF18B',34242:'\uF18C',34243:'\uF18D',34244:'\uF18E',34245:'\uF18F',34246:'\uF190',34247:'\uF191',34248:'\uF192',34249:'\uF193',34250:'\uF194',34251:'\uF195',34252:'\uF196',34253:'\uF197',34254:'\uF198',34255:'\uF199',34256:'\uF19A',34257:'\uF19B',34258:'\uF19C',34259:'\uF19D',34260:'\uF19E',34261:'\uF19F',34262:'\uF1A0',34263:'\uF1A1',34264:'\uF1A2',34265:'\uF1A3',34266:'\uF1A4',34267:'\uF1A5',34268:'\uF1A6',34269:'\uF1A7',34270:'\uF1A8',34271:'\uF1A9',34272:'\uF1AA',34273:'\uF1AB',34274:'\uF1AC',34275:'\uF1AD',34276:'\uF1AE',34277:'\uF1AF',34278:'\uF1B0',34279:'\uF1B1',34280:'\uF1B2',34281:'\uF1B3',34282:'\uF1B4',34283:'\uF1B5',34284:'\uF1B6',34285:'\uF1B7',34286:'\uF1B8',34287:'\uF1B9',34288:'\uF1BA',34289:'\uF1BB',34290:'\uF1BC',34291:'\uF1BD',34292:'\uF1BE',34293:'\uF1BF',34294:'\uF1C0',34295:'\uF1C1',34296:'\uF1C2',34297:'\uF1C3',34298:'\uF1C4',34299:'\uF1C5',34300:'\uF1C6',34301:'\uF1C7',34302:'\uF1C8',34368:'\uF1C9',34369:'\uF1CA',34370:'\uF1CB',34371:'\uF1CC',34372:'\uF1CD',34373:'\uF1CE',34374:'\uF1CF',34375:'\uF1D0',34376:'\uF1D1',34377:'\uF1D2',34378:'\uF1D3',34379:'\uF1D4',34380:'\uF1D5',34381:'\uF1D6',34382:'\uF1D7',34383:'\uF1D8',34384:'\uF1D9',34385:'\uF1DA',34386:'\uF1DB',34387:'\uF1DC',34388:'\uF1DD',34389:'\uF1DE',34390:'\uF1DF',34391:'\uF1E0',34392:'\uF1E1',34393:'\uF1E2',34394:'\uF1E3',34395:'\uF1E4',34396:'\uF1E5',34397:'\uF1E6',34398:'\uF1E7',34399:'\uF1E8',34400:'\uF1E9',34401:'\uF1EA',34402:'\uF1EB',34403:'\uF1EC',34404:'\uF1ED',34405:'\uF1EE',34406:'\uF1EF',34407:'\uF1F0',34408:'\uF1F1',34409:'\uF1F2',34410:'\uF1F3',34411:'\uF1F4',34412:'\uF1F5',34413:'\uF1F6',34414:'\uF1F7',34415:'\uF1F8',34416:'\uF1F9',34417:'\uF1FA',34418:'\uF1FB',34419:'\uF1FC',34420:'\uF1FD',34421:'\uF1FE',34422:'\uF1FF',34423:'\uF200',34424:'\uF201',34425:'\uF202',34426:'\uF203',34427:'\uF204',34428:'\uF205',34429:'\uF206',34430:'\uF207',34465:'\uF208',34466:'\uF209',34467:'\uF20A',34468:'\uF20B',34469:'\uF20C',34470:'\uF20D',34471:'\uF20E',34472:'\uF20F',34473:'\uF210',34474:'\uF211',34475:'\uF212',34476:'\uF213',34477:'\uF214',34478:'\uF215',34479:'\uF216',34480:'\uF217',34481:'\uF218',34482:'\uF219',34483:'\uF21A',34484:'\uF21B',34485:'\uF21C',34486:'\uF21D',34487:'\uF21E',34488:'\uF21F',34489:'\uF220',34490:'\uF221',34491:'\uF222',34492:'\uF223',34493:'\uF224',34494:'\uF225',34495:'\uF226',34496:'\uF227',34497:'\uF228',34498:'\uF229',34499:'\uF22A',34500:'\uF22B',34501:'\uF22C',34502:'\uF22D',34503:'\uF22E',34504:'\uF22F',34505:'\uF230',34506:'\uF231',34507:'\uF232',34508:'\uF233',34509:'\uF234',34510:'\uF235',34511:'\uF236',34512:'\uF237',34513:'\uF238',34514:'\uF239',34515:'\uF23A',34516:'\uF23B',34517:'\uF23C',34518:'\uF23D',34519:'\uF23E',34520:'\uF23F',34521:'\uF240',34522:'\uF241',34523:'\uF242',34524:'\uF243',34525:'\uF244',34526:'\uF245',34527:'\uF246',34528:'\uF247',34529:'\uF248',34530:'\uF249',34531:'\uF24A',34532:'\uF24B',34533:'\uF24C',34534:'\uF24D',34535:'\uF24E',34536:'\uF24F',34537:'\uF250',34538:'\uF251',34539:'\uF252',34540:'\uF253',34541:'\uF254',34542:'\uF255',34543:'\uF256',34544:'\uF257',34545:'\uF258',34546:'\uF259',34547:'\uF25A',34548:'\uF25B',34549:'\uF25C',34550:'\uF25D',34551:'\uF25E',34552:'\uF25F',34553:'\uF260',34554:'\uF261',34555:'\uF262',34556:'\uF263',34557:'\uF264',34558:'\uF265',34624:'\uF266',34625:'\uF267',34626:'\uF268',34627:'\uF269',34628:'\uF26A',34629:'\uF26B',34630:'\uF26C',34631:'\uF26D',34632:'\uF26E',34633:'\uF26F',34634:'\uF270',34635:'\uF271',34636:'\uF272',34637:'\uF273',34638:'\uF274',34639:'\uF275',34640:'\uF276',34641:'\uF277',34642:'\uF278',34643:'\uF279',34644:'\uF27A',34645:'\uF27B',34646:'\uF27C',34647:'\uF27D',34648:'\uF27E',34649:'\uF27F',34650:'\uF280',34651:'\uF281',34652:'\uF282',34653:'\uF283',34654:'\uF284',34655:'\uF285',34656:'\uF286',34657:'\uF287',34658:'\uF288',34659:'\uF289',34660:'\uF28A',34661:'\uF28B',34662:'\uF28C',34663:'\uF28D',34664:'\uF28E',34665:'\uF28F',34666:'\uF290',34667:'\uF291',34668:'\uF292',34669:'\uF293',34670:'\uF294',34671:'\uF295',34672:'\uF296',34673:'\uF297',34674:'\uF298',34675:'\uF299',34676:'\uF29A',34677:'\uF29B',34678:'\uF29C',34679:'\uF29D',34680:'\uF29E',34681:'\uF29F',34682:'\uF2A0',34683:'\uF2A1',34684:'\uF2A2',34685:'\uF2A3',34686:'\uF2A4',34721:'\uF2A5',34722:'\uF2A6',34723:'\uF2A7',34724:'\uF2A8',34725:'\uF2A9',34726:'\uF2AA',34727:'\uF2AB',34728:'\uF2AC',34729:'\uF2AD',34730:'\uF2AE',34731:'\uF2AF',34732:'\uF2B0',34733:'\uF2B1',34734:'\uF2B2',34735:'\uF2B3',34736:'\uF2B4',34737:'\uF2B5',34738:'\uF2B6',34739:'\uF2B7',34740:'\uF2B8',34741:'\uF2B9',34742:'\uF2BA',34743:'\uF2BB',34744:'\uF2BC',34745:'\uF2BD',34746:'\uF2BE',34747:'\uF2BF',34748:'\uF2C0',34749:'\uF2C1',34750:'\uF2C2',34751:'\uF2C3',34752:'\uF2C4',34753:'\uF2C5',34754:'\uF2C6',34755:'\uF2C7',34756:'\uF2C8',34757:'\uF2C9',34758:'\uF2CA',34759:'\uF2CB',34760:'\uF2CC',34761:'\uF2CD',34762:'\uF2CE',34763:'\uF2CF',34764:'\uF2D0',34765:'\uF2D1',34766:'\uF2D2',34767:'\uF2D3',34768:'\uF2D4',34769:'\uF2D5',34770:'\uF2D6',34771:'\uF2D7',34772:'\uF2D8',34773:'\uF2D9',34774:'\uF2DA',34775:'\uF2DB',34776:'\uF2DC',34777:'\uF2DD',34778:'\uF2DE',34779:'\uF2DF',34780:'\uF2E0',34781:'\uF2E1',34782:'\uF2E2',34783:'\uF2E3',34784:'\uF2E4',34785:'\uF2E5',34786:'\uF2E6',34787:'\uF2E7',34788:'\uF2E8',34789:'\uF2E9',34790:'\uF2EA',34791:'\uF2EB',34792:'\uF2EC',34793:'\uF2ED',34794:'\uF2EE',34795:'\uF2EF',34796:'\uF2F0',34797:'\uF2F1',34798:'\uF2F2',34799:'\uF2F3',34800:'\uF2F4',34801:'\uF2F5',34802:'\uF2F6',34803:'\uF2F7',34804:'\uF2F8',34805:'\uF2F9',34806:'\uF2FA',34807:'\uF2FB',34808:'\uF2FC',34809:'\uF2FD',34810:'\uF2FE',34811:'\uF2FF',34812:'\uF300',34813:'\uF301',34814:'\uF302',34880:'\uF303',34881:'\uF304',34882:'\uF305',34883:'\uF306',34884:'\uF307',34885:'\uF308',34886:'\uF309',34887:'\uF30A',34888:'\uF30B',34889:'\uF30C',34890:'\uF30D',34891:'\uF30E',34892:'\uF30F',34893:'\uF310',34894:'\uF311',34895:'\uF312',34896:'\uF313',34897:'\uF314',34898:'\uF315',34899:'\uF316',34900:'\uF317',34901:'\uF318',34902:'\uF319',34903:'\uF31A',34904:'\uF31B',34905:'\uF31C',34906:'\uF31D',34907:'\uF31E',34908:'\uF31F',34909:'\uF320',34910:'\uF321',34911:'\uF322',34912:'\uF323',34913:'\uF324',34914:'\uF325',34915:'\uF326',34916:'\uF327',34917:'\uF328',34918:'\uF329',34919:'\uF32A',34920:'\uF32B',34921:'\uF32C',34922:'\uF32D',34923:'\uF32E',34924:'\uF32F',34925:'\uF330',34926:'\uF331',34927:'\uF332',34928:'\uF333',34929:'\uF334',34930:'\uF335',34931:'\uF336',34932:'\uF337',34933:'\uF338',34934:'\uF339',34935:'\uF33A',34936:'\uF33B',34937:'\uF33C',34938:'\uF33D',34939:'\uF33E',34940:'\uF33F',34941:'\uF340',34942:'\uF341',34977:'\uF342',34978:'\uF343',34979:'\uF344',34980:'\uF345',34981:'\uF346',34982:'\uF347',34983:'\uF348',34984:'\uF349',34985:'\uF34A',34986:'\uF34B',34987:'\uF34C',34988:'\uF34D',34989:'\uF34E',34990:'\uF34F',34991:'\uF350',34992:'\uF351',34993:'\uF352',34994:'\uF353',34995:'\uF354',34996:'\uF355',34997:'\uF356',34998:'\uF357',34999:'\uF358',35000:'\uF359',35001:'\uF35A',35002:'\uF35B',35003:'\uF35C',35004:'\uF35D',35005:'\uF35E',35006:'\uF35F',35007:'\uF360',35008:'\uF361',35009:'\uF362',35010:'\uF363',35011:'\uF364',35012:'\uF365',35013:'\uF366',35014:'\uF367',35015:'\uF368',35016:'\uF369',35017:'\uF36A',35018:'\uF36B',35019:'\uF36C',35020:'\uF36D',35021:'\uF36E',35022:'\uF36F',35023:'\uF370',35024:'\uF371',35025:'\uF372',35026:'\uF373',35027:'\uF374',35028:'\uF375',35029:'\uF376',35030:'\uF377',35031:'\uF378',35032:'\uF379',35033:'\uF37A',35034:'\uF37B',35035:'\uF37C',35036:'\uF37D',35037:'\uF37E',35038:'\uF37F',35039:'\uF380',35040:'\uF381',35041:'\uF382',35042:'\uF383',35043:'\uF384',35044:'\uF385',35045:'\uF386',35046:'\uF387',35047:'\uF388',35048:'\uF389',35049:'\uF38A',35050:'\uF38B',35051:'\uF38C',35052:'\uF38D',35053:'\uF38E',35054:'\uF38F',35055:'\uF390',35056:'\uF391',35057:'\uF392',35058:'\uF393',35059:'\uF394',35060:'\uF395',35061:'\uF396',35062:'\uF397',35063:'\uF398',35064:'\uF399',35065:'\uF39A',35066:'\uF39B',35067:'\uF39C',35068:'\uF39D',35069:'\uF39E',35070:'\uF39F',35136:'\uF3A0',35137:'\uF3A1',35138:'\uF3A2',35139:'\uF3A3',35140:'\uF3A4',35141:'\uF3A5',35142:'\uF3A6',35143:'\uF3A7',35144:'\uF3A8',35145:'\uF3A9',35146:'\uF3AA',35147:'\uF3AB',35148:'\uF3AC',35149:'\uF3AD',35150:'\uF3AE',35151:'\uF3AF',35152:'\uF3B0',35153:'\uF3B1',35154:'\uF3B2',35155:'\uF3B3',35156:'\uF3B4',35157:'\uF3B5',35158:'\uF3B6',35159:'\uF3B7',35160:'\uF3B8',35161:'\uF3B9',35162:'\uF3BA',35163:'\uF3BB',35164:'\uF3BC',35165:'\uF3BD',35166:'\uF3BE',35167:'\uF3BF',35168:'\uF3C0',35169:'\uF3C1',35170:'\uF3C2',35171:'\uF3C3',35172:'\uF3C4',35173:'\uF3C5',35174:'\uF3C6',35175:'\uF3C7',35176:'\uF3C8',35177:'\uF3C9',35178:'\uF3CA',35179:'\uF3CB',35180:'\uF3CC',35181:'\uF3CD',35182:'\uF3CE',35183:'\uF3CF',35184:'\uF3D0',35185:'\uF3D1',35186:'\uF3D2',35187:'\uF3D3',35188:'\uF3D4',35189:'\uF3D5',35190:'\uF3D6',35191:'\uF3D7',35192:'\uF3D8',35193:'\uF3D9',35194:'\uF3DA',35195:'\uF3DB',35196:'\uF3DC',35197:'\uF3DD',35198:'\uF3DE',35233:'\uF3DF',35234:'\uF3E0',35235:'\uF3E1',35236:'\uF3E2',35237:'\uF3E3',35238:'\uF3E4',35239:'\uF3E5',35240:'\uF3E6',35241:'\uF3E7',35242:'\uF3E8',35243:'\uF3E9',35244:'\uF3EA',35245:'\uF3EB',35246:'\uF3EC',35247:'\uF3ED',35248:'\uF3EE',35249:'\uF3EF',35250:'\uF3F0',35251:'\uF3F1',35252:'\uF3F2',35253:'\uF3F3',35254:'\uF3F4',35255:'\uF3F5',35256:'\uF3F6',35257:'\uF3F7',35258:'\uF3F8',35259:'\uF3F9',35260:'\uF3FA',35261:'\uF3FB',35262:'\uF3FC',35263:'\uF3FD',35264:'\uF3FE',35265:'\uF3FF',35266:'\uF400',35267:'\uF401',35268:'\uF402',35269:'\uF403',35270:'\uF404',35271:'\uF405',35272:'\uF406',35273:'\uF407',35274:'\uF408',35275:'\uF409',35276:'\uF40A',35277:'\uF40B',35278:'\uF40C',35279:'\uF40D',35280:'\uF40E',35281:'\uF40F',35282:'\uF410',35283:'\uF411',35284:'\uF412',35285:'\uF413',35286:'\uF414',35287:'\uF415',35288:'\uF416',35289:'\uF417',35290:'\uF418',35291:'\uF419',35292:'\uF41A',35293:'\uF41B',35294:'\uF41C',35295:'\uF41D',35296:'\uF41E',35297:'\uF41F',35298:'\uF420',35299:'\uF421',35300:'\uF422',35301:'\uF423',35302:'\uF424',35303:'\uF425',35304:'\uF426',35305:'\uF427',35306:'\uF428',35307:'\uF429',35308:'\uF42A',35309:'\uF42B',35310:'\uF42C',35311:'\uF42D',35312:'\uF42E',35313:'\uF42F',35314:'\uF430',35315:'\uF431',35316:'\uF432',35317:'\uF433',35318:'\uF434',35319:'\uF435',35320:'\uF436',35321:'\uF437',35322:'\uF438',35323:'\uF439',35324:'\uF43A',35325:'\uF43B',35326:'\uF43C',35392:'\uF43D',35393:'\uF43E',35394:'\uF43F',35395:'\uF440',35396:'\uF441',35397:'\uF442',35398:'\uF443',35399:'\uF444',35400:'\uF445',35401:'\uF446',35402:'\uF447',35403:'\uF448',35404:'\uF449',35405:'\uF44A',35406:'\uF44B',35407:'\uF44C',35408:'\uF44D',35409:'\uF44E',35410:'\uF44F',35411:'\uF450',35412:'\uF451',35413:'\uF452',35414:'\uF453',35415:'\uF454',35416:'\uF455',35417:'\uF456',35418:'\uF457',35419:'\uF458',35420:'\uF459',35421:'\uF45A',35422:'\uF45B',35423:'\uF45C',35424:'\uF45D',35425:'\uF45E',35426:'\uF45F',35427:'\uF460',35428:'\uF461',35429:'\uF462',35430:'\uF463',35431:'\uF464',35432:'\uF465',35433:'\uF466',35434:'\uF467',35435:'\uF468',35436:'\uF469',35437:'\uF46A',35438:'\uF46B',35439:'\uF46C',35440:'\uF46D',35441:'\uF46E',35442:'\uF46F',35443:'\uF470',35444:'\uF471',35445:'\uF472',35446:'\uF473',35447:'\uF474',35448:'\uF475',35449:'\uF476',35450:'\uF477',35451:'\uF478',35452:'\uF479',35453:'\uF47A',35454:'\uF47B',35489:'\uF47C',35490:'\uF47D',35491:'\uF47E',35492:'\uF47F',35493:'\uF480',35494:'\uF481',35495:'\uF482',35496:'\uF483',35497:'\uF484',35498:'\uF485',35499:'\uF486',35500:'\uF487',35501:'\uF488',35502:'\uF489',35503:'\uF48A',35504:'\uF48B',35505:'\uF48C',35506:'\uF48D',35507:'\uF48E',35508:'\uF48F',35509:'\uF490',35510:'\uF491',35511:'\uF492',35512:'\uF493',35513:'\uF494',35514:'\uF495',35515:'\uF496',35516:'\uF497',35517:'\uF498',35518:'\uF499',35519:'\uF49A',35520:'\uF49B',35521:'\uF49C',35522:'\uF49D',35523:'\uF49E',35524:'\uF49F',35525:'\uF4A0',35526:'\uF4A1',35527:'\uF4A2',35528:'\uF4A3',35529:'\uF4A4',35530:'\uF4A5',35531:'\uF4A6',35532:'\uF4A7',35533:'\uF4A8',35534:'\uF4A9',35535:'\uF4AA',35536:'\uF4AB',35537:'\uF4AC',35538:'\uF4AD',35539:'\uF4AE',35540:'\uF4AF',35541:'\uF4B0',35542:'\uF4B1',35543:'\uF4B2',35544:'\uF4B3',35545:'\uF4B4',35546:'\uF4B5',35547:'\uF4B6',35548:'\uF4B7',35549:'\uF4B8',35550:'\uF4B9',35551:'\uF4BA',35552:'\uF4BB',35553:'\uF4BC',35554:'\uF4BD',35555:'\uF4BE',35556:'\uF4BF',35557:'\uF4C0',35558:'\uF4C1',35559:'\uF4C2',35560:'\uF4C3',35561:'\uF4C4',35562:'\uF4C5',35563:'\uF4C6',35564:'\uF4C7',35565:'\uF4C8',35566:'\uF4C9',35567:'\uF4CA',35568:'\uF4CB',35569:'\uF4CC',35570:'\uF4CD',35571:'\uF4CE',35572:'\uF4CF',35573:'\uF4D0',35574:'\uF4D1',35575:'\uF4D2',35576:'\uF4D3',35577:'\uF4D4',35578:'\uF4D5',35579:'\uF4D6',35580:'\uF4D7',35581:'\uF4D8',35582:'\uF4D9',35648:'\uF4DA',35649:'\uF4DB',35650:'\uF4DC',35651:'\uF4DD',35652:'\uF4DE',35653:'\uF4DF',35654:'\uF4E0',35655:'\uF4E1',35656:'\uF4E2',35657:'\uF4E3',35658:'\uF4E4',35659:'\uF4E5',35660:'\uF4E6',35661:'\uF4E7',35662:'\uF4E8',35663:'\uF4E9',35664:'\uF4EA',35665:'\uF4EB',35666:'\uF4EC',35667:'\uF4ED',35668:'\uF4EE',35669:'\uF4EF',35670:'\uF4F0',35671:'\uF4F1',35672:'\uF4F2',35673:'\uF4F3',35674:'\uF4F4',35675:'\uF4F5',35676:'\uF4F6',35677:'\uF4F7',35678:'\uF4F8',35679:'\uF4F9',35680:'\uF4FA',35681:'\uF4FB',35682:'\uF4FC',35683:'\uF4FD',35684:'\uF4FE',35685:'\uF4FF',35686:'\uF500',35687:'\uF501',35688:'\uF502',35689:'\uF503',35690:'\uF504',35691:'\uF505',35692:'\uF506',35693:'\uF507',35694:'\uF508',35695:'\uF509',35696:'\uF50A',35697:'\uF50B',35698:'\uF50C',35699:'\uF50D',35700:'\uF50E',35701:'\uF50F',35702:'\uF510',35703:'\uF511',35704:'\uF512',35705:'\uF513',35706:'\uF514',35707:'\uF515',35708:'\uF516',35709:'\uF517',35710:'\uF518',35745:'\uF519',35746:'\uF51A',35747:'\uF51B',35748:'\uF51C',35749:'\uF51D',35750:'\uF51E',35751:'\uF51F',35752:'\uF520',35753:'\uF521',35754:'\uF522',35755:'\uF523',35756:'\uF524',35757:'\uF525',35758:'\uF526',35759:'\uF527',35760:'\uF528',35761:'\uF529',35762:'\uF52A',35763:'\uF52B',35764:'\uF52C',35765:'\uF52D',35766:'\uF52E',35767:'\uF52F',35768:'\uF530',35769:'\uF531',35770:'\uF532',35771:'\uF533',35772:'\uF534',35773:'\uF535',35774:'\uF536',35775:'\uF537',35776:'\uF538',35777:'\uF539',35778:'\uF53A',35779:'\uF53B',35780:'\uF53C',35781:'\uF53D',35782:'\uF53E',35783:'\uF53F',35784:'\uF540',35785:'\uF541',35786:'\uF542',35787:'\uF543',35788:'\uF544',35789:'\uF545',35790:'\uF546',35791:'\uF547',35792:'\uF548',35793:'\uF549',35794:'\uF54A',35795:'\uF54B',35796:'\uF54C',35797:'\uF54D',35798:'\uF54E',35799:'\uF54F',35800:'\uF550',35801:'\uF551',35802:'\uF552',35803:'\uF553',35804:'\uF554',35805:'\uF555',35806:'\uF556',35807:'\uF557',35808:'\uF558',35809:'\uF559',35810:'\uF55A',35811:'\uF55B',35812:'\uF55C',35813:'\uF55D',35814:'\uF55E',35815:'\uF55F',35816:'\uF560',35817:'\uF561',35818:'\uF562',35819:'\uF563',35820:'\uF564',35821:'\uF565',35822:'\uF566',35823:'\uF567',35824:'\uF568',35825:'\uF569',35826:'\uF56A',35827:'\uF56B',35828:'\uF56C',35829:'\uF56D',35830:'\uF56E',35831:'\uF56F',35832:'\uF570',35833:'\uF571',35834:'\uF572',35835:'\uF573',35836:'\uF574',35837:'\uF575',35838:'\uF576',35904:'\uF577',35905:'\uF578',35906:'\uF579',35907:'\uF57A',35908:'\uF57B',35909:'\uF57C',35910:'\uF57D',35911:'\uF57E',35912:'\uF57F',35913:'\uF580',35914:'\uF581',35915:'\uF582',35916:'\uF583',35917:'\uF584',35918:'\uF585',35919:'\uF586',35920:'\uF587',35921:'\uF588',35922:'\uF589',35923:'\uF58A',35924:'\uF58B',35925:'\uF58C',35926:'\uF58D',35927:'\uF58E',35928:'\uF58F',35929:'\uF590',35930:'\uF591',35931:'\uF592',35932:'\uF593',35933:'\uF594',35934:'\uF595',35935:'\uF596',35936:'\uF597',35937:'\uF598',35938:'\uF599',35939:'\uF59A',35940:'\uF59B',35941:'\uF59C',35942:'\uF59D',35943:'\uF59E',35944:'\uF59F',35945:'\uF5A0',35946:'\uF5A1',35947:'\uF5A2',35948:'\uF5A3',35949:'\uF5A4',35950:'\uF5A5',35951:'\uF5A6',35952:'\uF5A7',35953:'\uF5A8',35954:'\uF5A9',35955:'\uF5AA',35956:'\uF5AB',35957:'\uF5AC',35958:'\uF5AD',35959:'\uF5AE',35960:'\uF5AF',35961:'\uF5B0',35962:'\uF5B1',35963:'\uF5B2',35964:'\uF5B3',35965:'\uF5B4',35966:'\uF5B5',36001:'\uF5B6',36002:'\uF5B7',36003:'\uF5B8',36004:'\uF5B9',36005:'\uF5BA',36006:'\uF5BB',36007:'\uF5BC',36008:'\uF5BD',36009:'\uF5BE',36010:'\uF5BF',36011:'\uF5C0',36012:'\uF5C1',36013:'\uF5C2',36014:'\uF5C3',36015:'\uF5C4',36016:'\uF5C5',36017:'\uF5C6',36018:'\uF5C7',36019:'\uF5C8',36020:'\uF5C9',36021:'\uF5CA',36022:'\uF5CB',36023:'\uF5CC',36024:'\uF5CD',36025:'\uF5CE',36026:'\uF5CF',36027:'\uF5D0',36028:'\uF5D1',36029:'\uF5D2',36030:'\uF5D3',36031:'\uF5D4',36032:'\uF5D5',36033:'\uF5D6',36034:'\uF5D7',36035:'\uF5D8',36036:'\uF5D9',36037:'\uF5DA',36038:'\uF5DB',36039:'\uF5DC',36040:'\uF5DD',36041:'\uF5DE',36042:'\uF5DF',36043:'\uF5E0',36044:'\uF5E1',36045:'\uF5E2',36046:'\uF5E3',36047:'\uF5E4',36048:'\uF5E5',36049:'\uF5E6',36050:'\uF5E7',36051:'\uF5E8',36052:'\uF5E9',36053:'\uF5EA',36054:'\uF5EB',36055:'\uF5EC',36056:'\uF5ED',36057:'\uF5EE',36058:'\uF5EF',36059:'\uF5F0',36060:'\uF5F1',36061:'\uF5F2',36062:'\uF5F3',36063:'\uF5F4',36064:'\uF5F5',36065:'\uF5F6',36066:'\uF5F7',36067:'\uF5F8',36068:'\uF5F9',36069:'\uF5FA',36070:'\uF5FB',36071:'\uF5FC',36072:'\uF5FD',36073:'\uF5FE',36074:'\uF5FF',36075:'\uF600',36076:'\uF601',36077:'\uF602',36078:'\uF603',36079:'\uF604',36080:'\uF605',36081:'\uF606',36082:'\uF607',36083:'\uF608',36084:'\uF609',36085:'\uF60A',36086:'\uF60B',36087:'\uF60C',36088:'\uF60D',36089:'\uF60E',36090:'\uF60F',36091:'\uF610',36092:'\uF611',36093:'\uF612',36094:'\uF613',36160:'\uF614',36161:'\uF615',36162:'\uF616',36163:'\uF617',36164:'\uF618',36165:'\uF619',36166:'\uF61A',36167:'\uF61B',36168:'\uF61C',36169:'\uF61D',36170:'\uF61E',36171:'\uF61F',36172:'\uF620',36173:'\uF621',36174:'\uF622',36175:'\uF623',36176:'\uF624',36177:'\uF625',36178:'\uF626',36179:'\uF627',36180:'\uF628',36181:'\uF629',36182:'\uF62A',36183:'\uF62B',36184:'\uF62C',36185:'\uF62D',36186:'\uF62E',36187:'\uF62F',36188:'\uF630',36189:'\uF631',36190:'\uF632',36191:'\uF633',36192:'\uF634',36193:'\uF635',36194:'\uF636',36195:'\uF637',36196:'\uF638',36197:'\uF639',36198:'\uF63A',36199:'\uF63B',36200:'\uF63C',36201:'\uF63D',36202:'\uF63E',36203:'\uF63F',36204:'\uF640',36205:'\uF641',36206:'\uF642',36207:'\uF643',36208:'\uF644',36209:'\uF645',36210:'\uF646',36211:'\uF647',36212:'\uF648',36213:'\uF649',36214:'\uF64A',36215:'\uF64B',36216:'\uF64C',36217:'\uF64D',36218:'\uF64E',36219:'\uF64F',36220:'\uF650',36221:'\uF651',36222:'\uF652',36257:'\uF653',36258:'\uF654',36259:'\uF655',36260:'\uF656',36261:'\uF657',36262:'\uF658',36263:'\uF659',36264:'\uF65A',36265:'\uF65B',36266:'\uF65C',36267:'\uF65D',36268:'\uF65E',36269:'\uF65F',36270:'\uF660',36271:'\uF661',36272:'\uF662',36273:'\uF663',36274:'\uF664',36275:'\uF665',36276:'\uF666',36277:'\uF667',36278:'\uF668',36279:'\uF669',36280:'\uF66A',36281:'\uF66B',36282:'\uF66C',36283:'\uF66D',36284:'\uF66E',36285:'\uF66F',36286:'\uF670',36287:'\uF671',36288:'\uF672',36289:'\uF673',36290:'\uF674',36291:'\uF675',36292:'\uF676',36293:'\uF677',36294:'\uF678',36295:'\uF679',36296:'\uF67A',36297:'\uF67B',36298:'\uF67C',36299:'\uF67D',36300:'\uF67E',36301:'\uF67F',36302:'\uF680',36303:'\uF681',36304:'\uF682',36305:'\uF683',36306:'\uF684',36307:'\uF685',36308:'\uF686',36309:'\uF687',36310:'\uF688',36311:'\uF689',36312:'\uF68A',36313:'\uF68B',36314:'\uF68C',36315:'\uF68D',36316:'\uF68E',36317:'\uF68F',36318:'\uF690',36319:'\uF691',36320:'\uF692',36321:'\uF693',36322:'\uF694',36323:'\uF695',36324:'\uF696',36325:'\uF697',36326:'\uF698',36327:'\uF699',36328:'\uF69A',36329:'\uF69B',36330:'\uF69C',36331:'\uF69D',36332:'\uF69E',36333:'\uF69F',36334:'\uF6A0',36335:'\uF6A1',36336:'\uF6A2',36337:'\uF6A3',36338:'\uF6A4',36339:'\uF6A5',36340:'\uF6A6',36341:'\uF6A7',36342:'\uF6A8',36343:'\uF6A9',36344:'\uF6AA',36345:'\uF6AB',36346:'\uF6AC',36347:'\uF6AD',36348:'\uF6AE',36349:'\uF6AF',36350:'\uF6B0',36416:'\uE311',36417:'\uE312',36418:'\uE313',36419:'\uE314',36420:'\uE315',36421:'\uE316',36422:'\uE317',36423:'\uE318',36424:'\uE319',36425:'\uE31A',36426:'\uE31B',36427:'\uE31C',36428:'\uE31D',36429:'\uE31E',36430:'\uE31F',36431:'\uE320',36432:'\uE321',36433:'\uE322',36434:'\uE323',36435:'\uE324',36436:'\uE325',36437:'\uE326',36438:'\uE327',36439:'\uE328',36440:'\uE329',36441:'\uE32A',36442:'\uE32B',36443:'\uE32C',36444:'\uE32D',36445:'\uE32E',36446:'\uE32F',36447:'\uE330',36448:'\uE331',36449:'\uE332',36450:'\uE333',36451:'\uE334',36452:'\uE335',36453:'\uE336',36454:'\uE337',36455:'\uE338',36456:'\uE339',36457:'\uE33A',36458:'\uE33B',36459:'\uE33C',36460:'\uE33D',36461:'\uE33E',36462:'\uE33F',36463:'\uE340',36464:'\uE341',36465:'\uE342',36466:'\uE343',36467:'\uE344',36468:'\uE345',36469:'\uE346',36470:'\uE347',36471:'\uE348',36472:'\uE349',36473:'\uE34A',36474:'\uE34B',36475:'\uE34C',36476:'\uE34D',36477:'\uE34E',36478:'\uE34F',36513:'\uE350',36514:'\uE351',36515:'\uE352',36516:'\uE353',36517:'\uE354',36518:'\uE355',36519:'\uE356',36520:'\uE357',36521:'\uE358',36522:'\uE359',36523:'\uE35A',36524:'\uE35B',36525:'\uE35C',36526:'\uE35D',36527:'\uE35E',36528:'\uE35F',36529:'\uE360',36530:'\uE361',36531:'\uE362',36532:'\uE363',36533:'\uE364',36534:'\uE365',36535:'\uE366',36536:'\uE367',36537:'\uE368',36538:'\uE369',36539:'\uE36A',36540:'\uE36B',36541:'\uE36C',36542:'\uE36D',36543:'\uE36E',36544:'\uE36F',36545:'\uE370',36546:'\uE371',36547:'\uE372',36548:'\uE373',36549:'\uE374',36550:'\uE375',36551:'\uE376',36552:'\uE377',36553:'\uE378',36554:'\uE379',36555:'\uE37A',36556:'\uE37B',36557:'\uE37C',36558:'\uE37D',36559:'\uE37E',36560:'\uE37F',36561:'\uE380',36562:'\uE381',36563:'\uE382',36564:'\uE383',36565:'\uE384',36566:'\uE385',36567:'\uE386',36568:'\uE387',36569:'\uE388',36570:'\uE389',36571:'\uE38A',36572:'\uE38B',36573:'\uE38C',36574:'\uE38D',36575:'\uE38E',36576:'\uE38F',36577:'\uE390',36578:'\uE391',36579:'\uE392',36580:'\uE393',36581:'\uE394',36582:'\uE395',36583:'\uE396',36584:'\uE397',36585:'\uE398',36586:'\uE399',36587:'\uE39A',36588:'\uE39B',36589:'\uE39C',36590:'\uE39D',36591:'\uE39E',36592:'\uE39F',36593:'\uE3A0',36594:'\uE3A1',36595:'\uE3A2',36596:'\uE3A3',36597:'\uE3A4',36598:'\uE3A5',36599:'\uE3A6',36600:'\uE3A7',36601:'\uE3A8',36602:'\uE3A9',36603:'\uE3AA',36604:'\uE3AB',36605:'\uE3AC',36606:'\uE3AD',36672:'\uE3AE',36673:'\uE3AF',36674:'\uE3B0',36675:'\uE3B1',36676:'\uE3B2',36677:'\uE3B3',36678:'\uE3B4',36679:'\uE3B5',36680:'\uE3B6',36681:'\uE3B7',36682:'\uE3B8',36683:'\uE3B9',36684:'\uE3BA',36685:'\uE3BB',36686:'\uE3BC',36687:'\uE3BD',36688:'\uE3BE',36689:'\uE3BF',36690:'\uE3C0',36691:'\uE3C1',36692:'\uE3C2',36693:'\uE3C3',36694:'\uE3C4',36695:'\uE3C5',36696:'\uE3C6',36697:'\uE3C7',36698:'\uE3C8',36699:'\uE3C9',36700:'\uE3CA',36701:'\uE3CB',36702:'\uE3CC',36703:'\uE3CD',36704:'\uE3CE',36705:'\uE3CF',36706:'\uE3D0',36707:'\uE3D1',36708:'\uE3D2',36709:'\uE3D3',36710:'\uE3D4',36711:'\uE3D5',36712:'\uE3D6',36713:'\uE3D7',36714:'\uE3D8',36715:'\uE3D9',36716:'\uE3DA',36717:'\uE3DB',36718:'\uE3DC',36719:'\uE3DD',36720:'\uE3DE',36721:'\uE3DF',36722:'\uE3E0',36723:'\uE3E1',36724:'\uE3E2',36725:'\uE3E3',36726:'\uE3E4',36727:'\uE3E5',36728:'\uE3E6',36729:'\uE3E7',36730:'\uE3E8',36731:'\uE3E9',36732:'\uE3EA',36733:'\uE3EB',36734:'\uE3EC',36769:'\uE3ED',36770:'\uE3EE',36771:'\uE3EF',36772:'\uE3F0',36773:'\uE3F1',36774:'\uE3F2',36775:'\uE3F3',36776:'\uE3F4',36777:'\uE3F5',36778:'\uE3F6',36779:'\uE3F7',36780:'\uE3F8',36781:'\uE3F9',36782:'\uE3FA',36783:'\uE3FB',36784:'\uE3FC',36785:'\uE3FD',36786:'\uE3FE',36787:'\uE3FF',36788:'\uE400',36789:'\uE401',36790:'\uE402',36791:'\uE403',36792:'\uE404',36793:'\uE405',36794:'\uE406',36795:'\uE407',36796:'\uE408',36797:'\uE409',36798:'\uE40A',36799:'\uE40B',36800:'\uE40C',36801:'\uE40D',36802:'\uE40E',36803:'\uE40F',36804:'\uE410',36805:'\uE411',36806:'\uE412',36807:'\uE413',36808:'\uE414',36809:'\uE415',36810:'\uE416',36811:'\uE417',36812:'\uE418',36813:'\uE419',36814:'\uE41A',36815:'\uE41B',36816:'\uE41C',36817:'\uE41D',36818:'\uE41E',36819:'\uE41F',36820:'\uE420',36821:'\uE421',36822:'\uE422',36823:'\uE423',36824:'\uE424',36825:'\uE425',36826:'\uE426',36827:'\uE427',36828:'\uE428',36829:'\uE429',36830:'\uE42A',36831:'\uE42B',36832:'\uE42C',36833:'\uE42D',36834:'\uE42E',36835:'\uE42F',36836:'\uE430',36837:'\uE431',36838:'\uE432',36839:'\uE433',36840:'\uE434',36841:'\uE435',36842:'\uE436',36843:'\uE437',36844:'\uE438',36845:'\uE439',36846:'\uE43A',36847:'\uE43B',36848:'\uE43C',36849:'\uE43D',36850:'\uE43E',36851:'\uE43F',36852:'\uE440',36853:'\uE441',36854:'\uE442',36855:'\uE443',36856:'\uE444',36857:'\uE445',36858:'\uE446',36859:'\uE447',36860:'\uE448',36861:'\uE449',36862:'\uE44A',36928:'\uE44B',36929:'\uE44C',36930:'\uE44D',36931:'\uE44E',36932:'\uE44F',36933:'\uE450',36934:'\uE451',36935:'\uE452',36936:'\uE453',36937:'\uE454',36938:'\uE455',36939:'\uE456',36940:'\uE457',36941:'\uE458',36942:'\uE459',36943:'\uE45A',36944:'\uE45B',36945:'\uE45C',36946:'\uE45D',36947:'\uE45E',36948:'\uE45F',36949:'\uE460',36950:'\uE461',36951:'\uE462',36952:'\uE463',36953:'\uE464',36954:'\uE465',36955:'\uE466',36956:'\uE467',36957:'\uE468',36958:'\uE469',36959:'\uE46A',36960:'\uE46B',36961:'\uE46C',36962:'\uE46D',36963:'\uE46E',36964:'\uE46F',36965:'\uE470',36966:'\uE471',36967:'\uE472',36968:'\uE473',36969:'\uE474',36970:'\uE475',36971:'\uE476',36972:'\uE477',36973:'\uE478',36974:'\uE479',36975:'\uE47A',36976:'\uE47B',36977:'\uE47C',36978:'\uE47D',36979:'\uE47E',36980:'\uE47F',36981:'\uE480',36982:'\uE481',36983:'\uE482',36984:'\uE483',36985:'\uE484',36986:'\uE485',36987:'\uE486',36988:'\uE487',36989:'\uE488',36990:'\uE489',37025:'\uE48A',37026:'\uE48B',37027:'\uE48C',37028:'\uE48D',37029:'\uE48E',37030:'\uE48F',37031:'\uE490',37032:'\uE491',37033:'\uE492',37034:'\uE493',37035:'\uE494',37036:'\uE495',37037:'\uE496',37038:'\uE497',37039:'\uE498',37040:'\uE499',37041:'\uE49A',37042:'\uE49B',37043:'\uE49C',37044:'\uE49D',37045:'\uE49E',37046:'\uE49F',37047:'\uE4A0',37048:'\uE4A1',37049:'\uE4A2',37050:'\uE4A3',37051:'\uE4A4',37052:'\uE4A5',37053:'\uE4A6',37054:'\uE4A7',37055:'\uE4A8',37056:'\uE4A9',37057:'\uE4AA',37058:'\uE4AB',37059:'\uE4AC',37060:'\uE4AD',37061:'\uE4AE',37062:'\uE4AF',37063:'\uE4B0',37064:'\uE4B1',37065:'\uE4B2',37066:'\uE4B3',37067:'\uE4B4',37068:'\uE4B5',37069:'\uE4B6',37070:'\uE4B7',37071:'\uE4B8',37072:'\uE4B9',37073:'\uE4BA',37074:'\uE4BB',37075:'\uE4BC',37076:'\uE4BD',37077:'\uE4BE',37078:'\uE4BF',37079:'\uE4C0',37080:'\uE4C1',37081:'\uE4C2',37082:'\uE4C3',37083:'\uE4C4',37084:'\uE4C5',37085:'\uE4C6',37086:'\uE4C7',37087:'\uE4C8',37088:'\uE4C9',37089:'\uE4CA',37090:'\uE4CB',37091:'\uE4CC',37092:'\uE4CD',37093:'\uE4CE',37094:'\uE4CF',37095:'\uE4D0',37096:'\uE4D1',37097:'\uE4D2',37098:'\uE4D3',37099:'\uE4D4',37100:'\uE4D5',37101:'\uE4D6',37102:'\uE4D7',37103:'\uE4D8',37104:'\uE4D9',37105:'\uE4DA',37106:'\uE4DB',37107:'\uE4DC',37108:'\uE4DD',37109:'\uE4DE',37110:'\uE4DF',37111:'\uE4E0',37112:'\uE4E1',37113:'\uE4E2',37114:'\uE4E3',37115:'\uE4E4',37116:'\uE4E5',37117:'\uE4E6',37118:'\uE4E7',37184:'\uE4E8',37185:'\uE4E9',37186:'\uE4EA',37187:'\uE4EB',37188:'\uE4EC',37189:'\uE4ED',37190:'\uE4EE',37191:'\uE4EF',37192:'\uE4F0',37193:'\uE4F1',37194:'\uE4F2',37195:'\uE4F3',37196:'\uE4F4',37197:'\uE4F5',37198:'\uE4F6',37199:'\uE4F7',37200:'\uE4F8',37201:'\uE4F9',37202:'\uE4FA',37203:'\uE4FB',37204:'\uE4FC',37205:'\uE4FD',37206:'\uE4FE',37207:'\uE4FF',37208:'\uE500',37209:'\uE501',37210:'\uE502',37211:'\uE503',37212:'\uE504',37213:'\uE505',37214:'\uE506',37215:'\uE507',37216:'\uE508',37217:'\uE509',37218:'\uE50A',37219:'\uE50B',37220:'\uE50C',37221:'\uE50D',37222:'\uE50E',37223:'\uE50F',37224:'\uE510',37225:'\uE511',37226:'\uE512',37227:'\uE513',37228:'\uE514',37229:'\uE515',37230:'\uE516',37231:'\uE517',37232:'\uE518',37233:'\uE519',37234:'\uE51A',37235:'\uE51B',37236:'\uE51C',37237:'\uE51D',37238:'\uE51E',37239:'\uE51F',37240:'\uE520',37241:'\uE521',37242:'\uE522',37243:'\uE523',37244:'\uE524',37245:'\uE525',37246:'\uE526',37281:'\uE527',37282:'\uE528',37283:'\uE529',37284:'\uE52A',37285:'\uE52B',37286:'\uE52C',37287:'\uE52D',37288:'\uE52E',37289:'\uE52F',37290:'\uE530',37291:'\uE531',37292:'\uE532',37293:'\uE533',37294:'\uE534',37295:'\uE535',37296:'\uE536',37297:'\uE537',37298:'\uE538',37299:'\uE539',37300:'\uE53A',37301:'\uE53B',37302:'\uE53C',37303:'\uE53D',37304:'\uE53E',37305:'\uE53F',37306:'\uE540',37307:'\uE541',37308:'\uE542',37309:'\uE543',37310:'\uE544',37311:'\uE545',37312:'\uE546',37313:'\uE547',37314:'\uE548',37315:'\uE549',37316:'\uE54A',37317:'\uE54B',37318:'\uE54C',37319:'\uE54D',37320:'\uE54E',37321:'\uE54F',37322:'\uE550',37323:'\uE551',37324:'\uE552',37325:'\uE553',37326:'\uE554',37327:'\uE555',37328:'\uE556',37329:'\uE557',37330:'\uE558',37331:'\uE559',37332:'\uE55A',37333:'\uE55B',37334:'\uE55C',37335:'\uE55D',37336:'\uE55E',37337:'\uE55F',37338:'\uE560',37339:'\uE561',37340:'\uE562',37341:'\uE563',37342:'\uE564',37343:'\uE565',37344:'\uE566',37345:'\uE567',37346:'\uE568',37347:'\uE569',37348:'\uE56A',37349:'\uE56B',37350:'\uE56C',37351:'\uE56D',37352:'\uE56E',37353:'\uE56F',37354:'\uE570',37355:'\uE571',37356:'\uE572',37357:'\uE573',37358:'\uE574',37359:'\uE575',37360:'\uE576',37361:'\uE577',37362:'\uE578',37363:'\uE579',37364:'\uE57A',37365:'\uE57B',37366:'\uE57C',37367:'\uE57D',37368:'\uE57E',37369:'\uE57F',37370:'\uE580',37371:'\uE581',37372:'\uE582',37373:'\uE583',37374:'\uE584',37440:'\uE585',37441:'\uE586',37442:'\uE587',37443:'\uE588',37444:'\uE589',37445:'\uE58A',37446:'\uE58B',37447:'\uE58C',37448:'\uE58D',37449:'\uE58E',37450:'\uE58F',37451:'\uE590',37452:'\uE591',37453:'\uE592',37454:'\uE593',37455:'\uE594',37456:'\uE595',37457:'\uE596',37458:'\uE597',37459:'\uE598',37460:'\uE599',37461:'\uE59A',37462:'\uE59B',37463:'\uE59C',37464:'\uE59D',37465:'\uE59E',37466:'\uE59F',37467:'\uE5A0',37468:'\uE5A1',37469:'\uE5A2',37470:'\uE5A3',37471:'\uE5A4',37472:'\uE5A5',37473:'\uE5A6',37474:'\uE5A7',37475:'\uE5A8',37476:'\uE5A9',37477:'\uE5AA',37478:'\uE5AB',37479:'\uE5AC',37480:'\uE5AD',37481:'\uE5AE',37482:'\uE5AF',37483:'\uE5B0',37484:'\uE5B1',37485:'\uE5B2',37486:'\uE5B3',37487:'\uE5B4',37488:'\uE5B5',37489:'\uE5B6',37490:'\uE5B7',37491:'\uE5B8',37492:'\uE5B9',37493:'\uE5BA',37494:'\uE5BB',37495:'\uE5BC',37496:'\uE5BD',37497:'\uE5BE',37498:'\uE5BF',37499:'\uE5C0',37500:'\uE5C1',37501:'\uE5C2',37502:'\uE5C3',37537:'\uE5C4',37538:'\uE5C5',37539:'\uE5C6',37540:'\uE5C7',37541:'\uE5C8',37542:'\uE5C9',37543:'\uE5CA',37544:'\uE5CB',37545:'\uE5CC',37546:'\uE5CD',37547:'\uE5CE',37548:'\uE5CF',37549:'\uE5D0',37550:'\uE5D1',37551:'\uE5D2',37552:'\uE5D3',37553:'\uE5D4',37554:'\uE5D5',37555:'\uE5D6',37556:'\uE5D7',37557:'\uE5D8',37558:'\uE5D9',37559:'\uE5DA',37560:'\uE5DB',37561:'\uE5DC',37562:'\uE5DD',37563:'\uE5DE',37564:'\uE5DF',37565:'\uE5E0',37566:'\uE5E1',37567:'\uE5E2',37568:'\uE5E3',37569:'\uE5E4',37570:'\uE5E5',37571:'\uE5E6',37572:'\uE5E7',37573:'\uE5E8',37574:'\uE5E9',37575:'\uE5EA',37576:'\uE5EB',37577:'\uE5EC',37578:'\uE5ED',37579:'\uE5EE',37580:'\uE5EF',37581:'\uE5F0',37582:'\uE5F1',37583:'\uE5F2',37584:'\uE5F3',37585:'\uE5F4',37586:'\uE5F5',37587:'\uE5F6',37588:'\uE5F7',37589:'\uE5F8',37590:'\uE5F9',37591:'\uE5FA',37592:'\uE5FB',37593:'\uE5FC',37594:'\uE5FD',37595:'\uE5FE',37596:'\uE5FF',37597:'\uE600',37598:'\uE601',37599:'\uE602',37600:'\uE603',37601:'\uE604',37602:'\uE605',37603:'\uE606',37604:'\uE607',37605:'\uE608',37606:'\uE609',37607:'\uE60A',37608:'\uE60B',37609:'\uE60C',37610:'\uE60D',37611:'\uE60E',37612:'\uE60F',37613:'\uE610',37614:'\uE611',37615:'\uE612',37616:'\uE613',37617:'\uE614',37618:'\uE615',37619:'\uE616',37620:'\uE617',37621:'\uE618',37622:'\uE619',37623:'\uE61A',37624:'\uE61B',37625:'\uE61C',37626:'\uE61D',37627:'\uE61E',37628:'\uE61F',37629:'\uE620',37630:'\uE621',37696:'\uE622',37697:'\uE623',37698:'\uE624',37699:'\uE625',37700:'\uE626',37701:'\uE627',37702:'\uE628',37703:'\uE629',37704:'\uE62A',37705:'\uE62B',37706:'\uE62C',37707:'\uE62D',37708:'\uE62E',37709:'\uE62F',37710:'\uE630',37711:'\uE631',37712:'\uE632',37713:'\uE633',37714:'\uE634',37715:'\uE635',37716:'\uE636',37717:'\uE637',37718:'\uE638',37719:'\uE639',37720:'\uE63A',37721:'\uE63B',37722:'\uE63C',37723:'\uE63D',37724:'\uE63E',37725:'\uE63F',37726:'\uE640',37727:'\uE641',37728:'\uE642',37729:'\uE643',37730:'\uE644',37731:'\uE645',37732:'\uE646',37733:'\uE647',37734:'\uE648',37735:'\uE649',37736:'\uE64A',37737:'\uE64B',37738:'\uE64C',37739:'\uE64D',37740:'\uE64E',37741:'\uE64F',37742:'\uE650',37743:'\uE651',37744:'\uE652',37745:'\uE653',37746:'\uE654',37747:'\uE655',37748:'\uE656',37749:'\uE657',37750:'\uE658',37751:'\uE659',37752:'\uE65A',37753:'\uE65B',37754:'\uE65C',37755:'\uE65D',37756:'\uE65E',37757:'\uE65F',37758:'\uE660',37793:'\uE661',37794:'\uE662',37795:'\uE663',37796:'\uE664',37797:'\uE665',37798:'\uE666',37799:'\uE667',37800:'\uE668',37801:'\uE669',37802:'\uE66A',37803:'\uE66B',37804:'\uE66C',37805:'\uE66D',37806:'\uE66E',37807:'\uE66F',37808:'\uE670',37809:'\uE671',37810:'\uE672',37811:'\uE673',37812:'\uE674',37813:'\uE675',37814:'\uE676',37815:'\uE677',37816:'\uE678',37817:'\uE679',37818:'\uE67A',37819:'\uE67B',37820:'\uE67C',37821:'\uE67D',37822:'\uE67E',37823:'\uE67F',37824:'\uE680',37825:'\uE681',37826:'\uE682',37827:'\uE683',37828:'\uE684',37829:'\uE685',37830:'\uE686',37831:'\uE687',37832:'\uE688',37833:'\uE689',37834:'\uE68A',37835:'\uE68B',37836:'\uE68C',37837:'\uE68D',37838:'\uE68E',37839:'\uE68F',37840:'\uE690',37841:'\uE691',37842:'\uE692',37843:'\uE693',37844:'\uE694',37845:'\uE695',37846:'\uE696',37847:'\uE697',37848:'\uE698',37849:'\uE699',37850:'\uE69A',37851:'\uE69B',37852:'\uE69C',37853:'\uE69D',37854:'\uE69E',37855:'\uE69F',37856:'\uE6A0',37857:'\uE6A1',37858:'\uE6A2',37859:'\uE6A3',37860:'\uE6A4',37861:'\uE6A5',37862:'\uE6A6',37863:'\uE6A7',37864:'\uE6A8',37865:'\uE6A9',37866:'\uE6AA',37867:'\uE6AB',37868:'\uE6AC',37869:'\uE6AD',37870:'\uE6AE',37871:'\uE6AF',37872:'\uE6B0',37873:'\uE6B1',37874:'\uE6B2',37875:'\uE6B3',37876:'\uE6B4',37877:'\uE6B5',37878:'\uE6B6',37879:'\uE6B7',37880:'\uE6B8',37881:'\uE6B9',37882:'\uE6BA',37883:'\uE6BB',37884:'\uE6BC',37885:'\uE6BD',37886:'\uE6BE',37952:'\uE6BF',37953:'\uE6C0',37954:'\uE6C1',37955:'\uE6C2',37956:'\uE6C3',37957:'\uE6C4',37958:'\uE6C5',37959:'\uE6C6',37960:'\uE6C7',37961:'\uE6C8',37962:'\uE6C9',37963:'\uE6CA',37964:'\uE6CB',37965:'\uE6CC',37966:'\uE6CD',37967:'\uE6CE',37968:'\uE6CF',37969:'\uE6D0',37970:'\uE6D1',37971:'\uE6D2',37972:'\uE6D3',37973:'\uE6D4',37974:'\uE6D5',37975:'\uE6D6',37976:'\uE6D7',37977:'\uE6D8',37978:'\uE6D9',37979:'\uE6DA',37980:'\uE6DB',37981:'\uE6DC',37982:'\uE6DD',37983:'\uE6DE',37984:'\uE6DF',37985:'\uE6E0',37986:'\uE6E1',37987:'\uE6E2',37988:'\uE6E3',37989:'\uE6E4',37990:'\uE6E5',37991:'\uE6E6',37992:'\uE6E7',37993:'\uE6E8',37994:'\uE6E9',37995:'\uE6EA',37996:'\uE6EB',37997:'\uE6EC',37998:'\uE6ED',37999:'\uE6EE',38000:'\uE6EF',38001:'\uE6F0',38002:'\uE6F1',38003:'\uE6F2',38004:'\uE6F3',38005:'\uE6F4',38006:'\uE6F5',38007:'\uE6F6',38008:'\uE6F7',38009:'\uE6F8',38010:'\uE6F9',38011:'\uE6FA',38012:'\uE6FB',38013:'\uE6FC',38014:'\uE6FD',38049:'\uE6FE',38050:'\uE6FF',38051:'\uE700',38052:'\uE701',38053:'\uE702',38054:'\uE703',38055:'\uE704',38056:'\uE705',38057:'\uE706',38058:'\uE707',38059:'\uE708',38060:'\uE709',38061:'\uE70A',38062:'\uE70B',38063:'\uE70C',38064:'\uE70D',38065:'\uE70E',38066:'\uE70F',38067:'\uE710',38068:'\uE711',38069:'\uE712',38070:'\uE713',38071:'\uE714',38072:'\uE715',38073:'\uE716',38074:'\uE717',38075:'\uE718',38076:'\uE719',38077:'\uE71A',38078:'\uE71B',38079:'\uE71C',38080:'\uE71D',38081:'\uE71E',38082:'\uE71F',38083:'\uE720',38084:'\uE721',38085:'\uE722',38086:'\uE723',38087:'\uE724',38088:'\uE725',38089:'\uE726',38090:'\uE727',38091:'\uE728',38092:'\uE729',38093:'\uE72A',38094:'\uE72B',38095:'\uE72C',38096:'\uE72D',38097:'\uE72E',38098:'\uE72F',38099:'\uE730',38100:'\uE731',38101:'\uE732',38102:'\uE733',38103:'\uE734',38104:'\uE735',38105:'\uE736',38106:'\uE737',38107:'\uE738',38108:'\uE739',38109:'\uE73A',38110:'\uE73B',38111:'\uE73C',38112:'\uE73D',38113:'\uE73E',38114:'\uE73F',38115:'\uE740',38116:'\uE741',38117:'\uE742',38118:'\uE743',38119:'\uE744',38120:'\uE745',38121:'\uE746',38122:'\uE747',38123:'\uE748',38124:'\uE749',38125:'\uE74A',38126:'\uE74B',38127:'\uE74C',38128:'\uE74D',38129:'\uE74E',38130:'\uE74F',38131:'\uE750',38132:'\uE751',38133:'\uE752',38134:'\uE753',38135:'\uE754',38136:'\uE755',38137:'\uE756',38138:'\uE757',38139:'\uE758',38140:'\uE759',38141:'\uE75A',38142:'\uE75B',38208:'\uE75C',38209:'\uE75D',38210:'\uE75E',38211:'\uE75F',38212:'\uE760',38213:'\uE761',38214:'\uE762',38215:'\uE763',38216:'\uE764',38217:'\uE765',38218:'\uE766',38219:'\uE767',38220:'\uE768',38221:'\uE769',38222:'\uE76A',38223:'\uE76B',38224:'\uE76C',38225:'\uE76D',38226:'\uE76E',38227:'\uE76F',38228:'\uE770',38229:'\uE771',38230:'\uE772',38231:'\uE773',38232:'\uE774',38233:'\uE775',38234:'\uE776',38235:'\uE777',38236:'\uE778',38237:'\uE779',38238:'\uE77A',38239:'\uE77B',38240:'\uE77C',38241:'\uE77D',38242:'\uE77E',38243:'\uE77F',38244:'\uE780',38245:'\uE781',38246:'\uE782',38247:'\uE783',38248:'\uE784',38249:'\uE785',38250:'\uE786',38251:'\uE787',38252:'\uE788',38253:'\uE789',38254:'\uE78A',38255:'\uE78B',38256:'\uE78C',38257:'\uE78D',38258:'\uE78E',38259:'\uE78F',38260:'\uE790',38261:'\uE791',38262:'\uE792',38263:'\uE793',38264:'\uE794',38265:'\uE795',38266:'\uE796',38267:'\uE797',38268:'\uE798',38269:'\uE799',38270:'\uE79A',38305:'\uE79B',38306:'\uE79C',38307:'\uE79D',38308:'\uE79E',38309:'\uE79F',38310:'\uE7A0',38311:'\uE7A1',38312:'\uE7A2',38313:'\uE7A3',38314:'\uE7A4',38315:'\uE7A5',38316:'\uE7A6',38317:'\uE7A7',38318:'\uE7A8',38319:'\uE7A9',38320:'\uE7AA',38321:'\uE7AB',38322:'\uE7AC',38323:'\uE7AD',38324:'\uE7AE',38325:'\uE7AF',38326:'\uE7B0',38327:'\uE7B1',38328:'\uE7B2',38329:'\uE7B3',38330:'\uE7B4',38331:'\uE7B5',38332:'\uE7B6',38333:'\uE7B7',38334:'\uE7B8',38335:'\uE7B9',38336:'\uE7BA',38337:'\uE7BB',38338:'\uE7BC',38339:'\uE7BD',38340:'\uE7BE',38341:'\uE7BF',38342:'\uE7C0',38343:'\uE7C1',38344:'\uE7C2',38345:'\uE7C3',38346:'\uE7C4',38347:'\uE7C5',38348:'\uE7C6',38349:'\uE7C7',38350:'\uE7C8',38351:'\uE7C9',38352:'\uE7CA',38353:'\uE7CB',38354:'\uE7CC',38355:'\uE7CD',38356:'\uE7CE',38357:'\uE7CF',38358:'\uE7D0',38359:'\uE7D1',38360:'\uE7D2',38361:'\uE7D3',38362:'\uE7D4',38363:'\uE7D5',38364:'\uE7D6',38365:'\uE7D7',38366:'\uE7D8',38367:'\uE7D9',38368:'\uE7DA',38369:'\uE7DB',38370:'\uE7DC',38371:'\uE7DD',38372:'\uE7DE',38373:'\uE7DF',38374:'\uE7E0',38375:'\uE7E1',38376:'\uE7E2',38377:'\uE7E3',38378:'\uE7E4',38379:'\uE7E5',38380:'\uE7E6',38381:'\uE7E7',38382:'\uE7E8',38383:'\uE7E9',38384:'\uE7EA',38385:'\uE7EB',38386:'\uE7EC',38387:'\uE7ED',38388:'\uE7EE',38389:'\uE7EF',38390:'\uE7F0',38391:'\uE7F1',38392:'\uE7F2',38393:'\uE7F3',38394:'\uE7F4',38395:'\uE7F5',38396:'\uE7F6',38397:'\uE7F7',38398:'\uE7F8',38464:'\uE7F9',38465:'\uE7FA',38466:'\uE7FB',38467:'\uE7FC',38468:'\uE7FD',38469:'\uE7FE',38470:'\uE7FF',38471:'\uE800',38472:'\uE801',38473:'\uE802',38474:'\uE803',38475:'\uE804',38476:'\uE805',38477:'\uE806',38478:'\uE807',38479:'\uE808',38480:'\uE809',38481:'\uE80A',38482:'\uE80B',38483:'\uE80C',38484:'\uE80D',38485:'\uE80E',38486:'\uE80F',38487:'\uE810',38488:'\uE811',38489:'\uE812',38490:'\uE813',38491:'\uE814',38492:'\uE815',38493:'\uE816',38494:'\uE817',38495:'\uE818',38496:'\uE819',38497:'\uE81A',38498:'\uE81B',38499:'\uE81C',38500:'\uE81D',38501:'\uE81E',38502:'\uE81F',38503:'\uE820',38504:'\uE821',38505:'\uE822',38506:'\uE823',38507:'\uE824',38508:'\uE825',38509:'\uE826',38510:'\uE827',38511:'\uE828',38512:'\uE829',38513:'\uE82A',38514:'\uE82B',38515:'\uE82C',38516:'\uE82D',38517:'\uE82E',38518:'\uE82F',38519:'\uE830',38520:'\uE831',38521:'\uE832',38522:'\uE833',38523:'\uE834',38524:'\uE835',38525:'\uE836',38526:'\uE837',38561:'\uE838',38562:'\uE839',38563:'\uE83A',38564:'\uE83B',38565:'\uE83C',38566:'\uE83D',38567:'\uE83E',38568:'\uE83F',38569:'\uE840',38570:'\uE841',38571:'\uE842',38572:'\uE843',38573:'\uE844',38574:'\uE845',38575:'\uE846',38576:'\uE847',38577:'\uE848',38578:'\uE849',38579:'\uE84A',38580:'\uE84B',38581:'\uE84C',38582:'\uE84D',38583:'\uE84E',38584:'\uE84F',38585:'\uE850',38586:'\uE851',38587:'\uE852',38588:'\uE853',38589:'\uE854',38590:'\uE855',38591:'\uE856',38592:'\uE857',38593:'\uE858',38594:'\uE859',38595:'\uE85A',38596:'\uE85B',38597:'\uE85C',38598:'\uE85D',38599:'\uE85E',38600:'\uE85F',38601:'\uE860',38602:'\uE861',38603:'\uE862',38604:'\uE863',38605:'\uE864',38606:'\uE865',38607:'\uE866',38608:'\uE867',38609:'\uE868',38610:'\uE869',38611:'\uE86A',38612:'\uE86B',38613:'\uE86C',38614:'\uE86D',38615:'\uE86E',38616:'\uE86F',38617:'\uE870',38618:'\uE871',38619:'\uE872',38620:'\uE873',38621:'\uE874',38622:'\uE875',38623:'\uE876',38624:'\uE877',38625:'\uE878',38626:'\uE879',38627:'\uE87A',38628:'\uE87B',38629:'\uE87C',38630:'\uE87D',38631:'\uE87E',38632:'\uE87F',38633:'\uE880',38634:'\uE881',38635:'\uE882',38636:'\uE883',38637:'\uE884',38638:'\uE885',38639:'\uE886',38640:'\uE887',38641:'\uE888',38642:'\uE889',38643:'\uE88A',38644:'\uE88B',38645:'\uE88C',38646:'\uE88D',38647:'\uE88E',38648:'\uE88F',38649:'\uE890',38650:'\uE891',38651:'\uE892',38652:'\uE893',38653:'\uE894',38654:'\uE895',38720:'\uE896',38721:'\uE897',38722:'\uE898',38723:'\uE899',38724:'\uE89A',38725:'\uE89B',38726:'\uE89C',38727:'\uE89D',38728:'\uE89E',38729:'\uE89F',38730:'\uE8A0',38731:'\uE8A1',38732:'\uE8A2',38733:'\uE8A3',38734:'\uE8A4',38735:'\uE8A5',38736:'\uE8A6',38737:'\uE8A7',38738:'\uE8A8',38739:'\uE8A9',38740:'\uE8AA',38741:'\uE8AB',38742:'\uE8AC',38743:'\uE8AD',38744:'\uE8AE',38745:'\uE8AF',38746:'\uE8B0',38747:'\uE8B1',38748:'\uE8B2',38749:'\uE8B3',38750:'\uE8B4',38751:'\uE8B5',38752:'\uE8B6',38753:'\uE8B7',38754:'\uE8B8',38755:'\uE8B9',38756:'\uE8BA',38757:'\uE8BB',38758:'\uE8BC',38759:'\uE8BD',38760:'\uE8BE',38761:'\uE8BF',38762:'\uE8C0',38763:'\uE8C1',38764:'\uE8C2',38765:'\uE8C3',38766:'\uE8C4',38767:'\uE8C5',38768:'\uE8C6',38769:'\uE8C7',38770:'\uE8C8',38771:'\uE8C9',38772:'\uE8CA',38773:'\uE8CB',38774:'\uE8CC',38775:'\uE8CD',38776:'\uE8CE',38777:'\uE8CF',38778:'\uE8D0',38779:'\uE8D1',38780:'\uE8D2',38781:'\uE8D3',38782:'\uE8D4',38817:'\uE8D5',38818:'\uE8D6',38819:'\uE8D7',38820:'\uE8D8',38821:'\uE8D9',38822:'\uE8DA',38823:'\uE8DB',38824:'\uE8DC',38825:'\uE8DD',38826:'\uE8DE',38827:'\uE8DF',38828:'\uE8E0',38829:'\uE8E1',38830:'\uE8E2',38831:'\uE8E3',38832:'\uE8E4',38833:'\uE8E5',38834:'\uE8E6',38835:'\uE8E7',38836:'\uE8E8',38837:'\uE8E9',38838:'\uE8EA',38839:'\uE8EB',38840:'\uE8EC',38841:'\uE8ED',38842:'\uE8EE',38843:'\uE8EF',38844:'\uE8F0',38845:'\uE8F1',38846:'\uE8F2',38847:'\uE8F3',38848:'\uE8F4',38849:'\uE8F5',38850:'\uE8F6',38851:'\uE8F7',38852:'\uE8F8',38853:'\uE8F9',38854:'\uE8FA',38855:'\uE8FB',38856:'\uE8FC',38857:'\uE8FD',38858:'\uE8FE',38859:'\uE8FF',38860:'\uE900',38861:'\uE901',38862:'\uE902',38863:'\uE903',38864:'\uE904',38865:'\uE905',38866:'\uE906',38867:'\uE907',38868:'\uE908',38869:'\uE909',38870:'\uE90A',38871:'\uE90B',38872:'\uE90C',38873:'\uE90D',38874:'\uE90E',38875:'\uE90F',38876:'\uE910',38877:'\uE911',38878:'\uE912',38879:'\uE913',38880:'\uE914',38881:'\uE915',38882:'\uE916',38883:'\uE917',38884:'\uE918',38885:'\uE919',38886:'\uE91A',38887:'\uE91B',38888:'\uE91C',38889:'\uE91D',38890:'\uE91E',38891:'\uE91F',38892:'\uE920',38893:'\uE921',38894:'\uE922',38895:'\uE923',38896:'\uE924',38897:'\uE925',38898:'\uE926',38899:'\uE927',38900:'\uE928',38901:'\uE929',38902:'\uE92A',38903:'\uE92B',38904:'\uE92C',38905:'\uE92D',38906:'\uE92E',38907:'\uE92F',38908:'\uE930',38909:'\uE931',38910:'\uE932',38976:'\uE933',38977:'\uE934',38978:'\uE935',38979:'\uE936',38980:'\uE937',38981:'\uE938',38982:'\uE939',38983:'\uE93A',38984:'\uE93B',38985:'\uE93C',38986:'\uE93D',38987:'\uE93E',38988:'\uE93F',38989:'\uE940',38990:'\uE941',38991:'\uE942',38992:'\uE943',38993:'\uE944',38994:'\uE945',38995:'\uE946',38996:'\uE947',38997:'\uE948',38998:'\uE949',38999:'\uE94A',39000:'\uE94B',39001:'\uE94C',39002:'\uE94D',39003:'\uE94E',39004:'\uE94F',39005:'\uE950',39006:'\uE951',39007:'\uE952',39008:'\uE953',39009:'\uE954',39010:'\uE955',39011:'\uE956',39012:'\uE957',39013:'\uE958',39014:'\uE959',39015:'\uE95A',39016:'\uE95B',39017:'\uE95C',39018:'\uE95D',39019:'\uE95E',39020:'\uE95F',39021:'\uE960',39022:'\uE961',39023:'\uE962',39024:'\uE963',39025:'\uE964',39026:'\uE965',39027:'\uE966',39028:'\uE967',39029:'\uE968',39030:'\uE969',39031:'\uE96A',39032:'\uE96B',39033:'\uE96C',39034:'\uE96D',39035:'\uE96E',39036:'\uE96F',39037:'\uE970',39038:'\uE971',39073:'\uE972',39074:'\uE973',39075:'\uE974',39076:'\uE975',39077:'\uE976',39078:'\uE977',39079:'\uE978',39080:'\uE979',39081:'\uE97A',39082:'\uE97B',39083:'\uE97C',39084:'\uE97D',39085:'\uE97E',39086:'\uE97F',39087:'\uE980',39088:'\uE981',39089:'\uE982',39090:'\uE983',39091:'\uE984',39092:'\uE985',39093:'\uE986',39094:'\uE987',39095:'\uE988',39096:'\uE989',39097:'\uE98A',39098:'\uE98B',39099:'\uE98C',39100:'\uE98D',39101:'\uE98E',39102:'\uE98F',39103:'\uE990',39104:'\uE991',39105:'\uE992',39106:'\uE993',39107:'\uE994',39108:'\uE995',39109:'\uE996',39110:'\uE997',39111:'\uE998',39112:'\uE999',39113:'\uE99A',39114:'\uE99B',39115:'\uE99C',39116:'\uE99D',39117:'\uE99E',39118:'\uE99F',39119:'\uE9A0',39120:'\uE9A1',39121:'\uE9A2',39122:'\uE9A3',39123:'\uE9A4',39124:'\uE9A5',39125:'\uE9A6',39126:'\uE9A7',39127:'\uE9A8',39128:'\uE9A9',39129:'\uE9AA',39130:'\uE9AB',39131:'\uE9AC',39132:'\uE9AD',39133:'\uE9AE',39134:'\uE9AF',39135:'\uE9B0',39136:'\uE9B1',39137:'\uE9B2',39138:'\uE9B3',39139:'\uE9B4',39140:'\uE9B5',39141:'\uE9B6',39142:'\uE9B7',39143:'\uE9B8',39144:'\uE9B9',39145:'\uE9BA',39146:'\uE9BB',39147:'\uE9BC',39148:'\uE9BD',39149:'\uE9BE',39150:'\uE9BF',39151:'\uE9C0',39152:'\uE9C1',39153:'\uE9C2',39154:'\uE9C3',39155:'\uE9C4',39156:'\uE9C5',39157:'\uE9C6',39158:'\uE9C7',39159:'\uE9C8',39160:'\uE9C9',39161:'\uE9CA',39162:'\uE9CB',39163:'\uE9CC',39164:'\uE9CD',39165:'\uE9CE',39166:'\uE9CF',39232:'\uE9D0',39233:'\uE9D1',39234:'\uE9D2',39235:'\uE9D3',39236:'\uE9D4',39237:'\uE9D5',39238:'\uE9D6',39239:'\uE9D7',39240:'\uE9D8',39241:'\uE9D9',39242:'\uE9DA',39243:'\uE9DB',39244:'\uE9DC',39245:'\uE9DD',39246:'\uE9DE',39247:'\uE9DF',39248:'\uE9E0',39249:'\uE9E1',39250:'\uE9E2',39251:'\uE9E3',39252:'\uE9E4',39253:'\uE9E5',39254:'\uE9E6',39255:'\uE9E7',39256:'\uE9E8',39257:'\uE9E9',39258:'\uE9EA',39259:'\uE9EB',39260:'\uE9EC',39261:'\uE9ED',39262:'\uE9EE',39263:'\uE9EF',39264:'\uE9F0',39265:'\uE9F1',39266:'\uE9F2',39267:'\uE9F3',39268:'\uE9F4',39269:'\uE9F5',39270:'\uE9F6',39271:'\uE9F7',39272:'\uE9F8',39273:'\uE9F9',39274:'\uE9FA',39275:'\uE9FB',39276:'\uE9FC',39277:'\uE9FD',39278:'\uE9FE',39279:'\uE9FF',39280:'\uEA00',39281:'\uEA01',39282:'\uEA02',39283:'\uEA03',39284:'\uEA04',39285:'\uEA05',39286:'\uEA06',39287:'\uEA07',39288:'\uEA08',39289:'\uEA09',39290:'\uEA0A',39291:'\uEA0B',39292:'\uEA0C',39293:'\uEA0D',39294:'\uEA0E',39329:'\uEA0F',39330:'\uEA10',39331:'\uEA11',39332:'\uEA12',39333:'\uEA13',39334:'\uEA14',39335:'\uEA15',39336:'\uEA16',39337:'\uEA17',39338:'\uEA18',39339:'\uEA19',39340:'\uEA1A',39341:'\uEA1B',39342:'\uEA1C',39343:'\uEA1D',39344:'\uEA1E',39345:'\uEA1F',39346:'\uEA20',39347:'\uEA21',39348:'\uEA22',39349:'\uEA23',39350:'\uEA24',39351:'\uEA25',39352:'\uEA26',39353:'\uEA27',39354:'\uEA28',39355:'\uEA29',39356:'\uEA2A',39357:'\uEA2B',39358:'\uEA2C',39359:'\uEA2D',39360:'\uEA2E',39361:'\uEA2F',39362:'\uEA30',39363:'\uEA31',39364:'\uEA32',39365:'\uEA33',39366:'\uEA34',39367:'\uEA35',39368:'\uEA36',39369:'\uEA37',39370:'\uEA38',39371:'\uEA39',39372:'\uEA3A',39373:'\uEA3B',39374:'\uEA3C',39375:'\uEA3D',39376:'\uEA3E',39377:'\uEA3F',39378:'\uEA40',39379:'\uEA41',39380:'\uEA42',39381:'\uEA43',39382:'\uEA44',39383:'\uEA45',39384:'\uEA46',39385:'\uEA47',39386:'\uEA48',39387:'\uEA49',39388:'\uEA4A',39389:'\uEA4B',39390:'\uEA4C',39391:'\uEA4D',39392:'\uEA4E',39393:'\uEA4F',39394:'\uEA50',39395:'\uEA51',39396:'\uEA52',39397:'\uEA53',39398:'\uEA54',39399:'\uEA55',39400:'\uEA56',39401:'\uEA57',39402:'\uEA58',39403:'\uEA59',39404:'\uEA5A',39405:'\uEA5B',39406:'\uEA5C',39407:'\uEA5D',39408:'\uEA5E',39409:'\uEA5F',39410:'\uEA60',39411:'\uEA61',39412:'\uEA62',39413:'\uEA63',39414:'\uEA64',39415:'\uEA65',39416:'\uEA66',39417:'\uEA67',39418:'\uEA68',39419:'\uEA69',39420:'\uEA6A',39421:'\uEA6B',39422:'\uEA6C',39488:'\uEA6D',39489:'\uEA6E',39490:'\uEA6F',39491:'\uEA70',39492:'\uEA71',39493:'\uEA72',39494:'\uEA73',39495:'\uEA74',39496:'\uEA75',39497:'\uEA76',39498:'\uEA77',39499:'\uEA78',39500:'\uEA79',39501:'\uEA7A',39502:'\uEA7B',39503:'\uEA7C',39504:'\uEA7D',39505:'\uEA7E',39506:'\uEA7F',39507:'\uEA80',39508:'\uEA81',39509:'\uEA82',39510:'\uEA83',39511:'\uEA84',39512:'\uEA85',39513:'\uEA86',39514:'\uEA87',39515:'\uEA88',39516:'\uEA89',39517:'\uEA8A',39518:'\uEA8B',39519:'\uEA8C',39520:'\uEA8D',39521:'\uEA8E',39522:'\uEA8F',39523:'\uEA90',39524:'\uEA91',39525:'\uEA92',39526:'\uEA93',39527:'\uEA94',39528:'\uEA95',39529:'\uEA96',39530:'\uEA97',39531:'\uEA98',39532:'\uEA99',39533:'\uEA9A',39534:'\uEA9B',39535:'\uEA9C',39536:'\uEA9D',39537:'\uEA9E',39538:'\uEA9F',39539:'\uEAA0',39540:'\uEAA1',39541:'\uEAA2',39542:'\uEAA3',39543:'\uEAA4',39544:'\uEAA5',39545:'\uEAA6',39546:'\uEAA7',39547:'\uEAA8',39548:'\uEAA9',39549:'\uEAAA',39550:'\uEAAB',39585:'\uEAAC',39586:'\uEAAD',39587:'\uEAAE',39588:'\uEAAF',39589:'\uEAB0',39590:'\uEAB1',39591:'\uEAB2',39592:'\uEAB3',39593:'\uEAB4',39594:'\uEAB5',39595:'\uEAB6',39596:'\uEAB7',39597:'\uEAB8',39598:'\uEAB9',39599:'\uEABA',39600:'\uEABB',39601:'\uEABC',39602:'\uEABD',39603:'\uEABE',39604:'\uEABF',39605:'\uEAC0',39606:'\uEAC1',39607:'\uEAC2',39608:'\uEAC3',39609:'\uEAC4',39610:'\uEAC5',39611:'\uEAC6',39612:'\uEAC7',39613:'\uEAC8',39614:'\uEAC9',39615:'\uEACA',39616:'\uEACB',39617:'\uEACC',39618:'\uEACD',39619:'\uEACE',39620:'\uEACF',39621:'\uEAD0',39622:'\uEAD1',39623:'\uEAD2',39624:'\uEAD3',39625:'\uEAD4',39626:'\uEAD5',39627:'\uEAD6',39628:'\uEAD7',39629:'\uEAD8',39630:'\uEAD9',39631:'\uEADA',39632:'\uEADB',39633:'\uEADC',39634:'\uEADD',39635:'\uEADE',39636:'\uEADF',39637:'\uEAE0',39638:'\uEAE1',39639:'\uEAE2',39640:'\uEAE3',39641:'\uEAE4',39642:'\uEAE5',39643:'\uEAE6',39644:'\uEAE7',39645:'\uEAE8',39646:'\uEAE9',39647:'\uEAEA',39648:'\uEAEB',39649:'\uEAEC',39650:'\uEAED',39651:'\uEAEE',39652:'\uEAEF',39653:'\uEAF0',39654:'\uEAF1',39655:'\uEAF2',39656:'\uEAF3',39657:'\uEAF4',39658:'\uEAF5',39659:'\uEAF6',39660:'\uEAF7',39661:'\uEAF8',39662:'\uEAF9',39663:'\uEAFA',39664:'\uEAFB',39665:'\uEAFC',39666:'\uEAFD',39667:'\uEAFE',39668:'\uEAFF',39669:'\uEB00',39670:'\uEB01',39671:'\uEB02',39672:'\uEB03',39673:'\uEB04',39674:'\uEB05',39675:'\uEB06',39676:'\uEB07',39677:'\uEB08',39678:'\uEB09',39744:'\uEB0A',39745:'\uEB0B',39746:'\uEB0C',39747:'\uEB0D',39748:'\uEB0E',39749:'\uEB0F',39750:'\uEB10',39751:'\uEB11',39752:'\uEB12',39753:'\uEB13',39754:'\uEB14',39755:'\uEB15',39756:'\uEB16',39757:'\uEB17',39758:'\uEB18',39759:'\uEB19',39760:'\uEB1A',39761:'\uEB1B',39762:'\uEB1C',39763:'\uEB1D',39764:'\uEB1E',39765:'\uEB1F',39766:'\uEB20',39767:'\uEB21',39768:'\uEB22',39769:'\uEB23',39770:'\uEB24',39771:'\uEB25',39772:'\uEB26',39773:'\uEB27',39774:'\uEB28',39775:'\uEB29',39776:'\uEB2A',39777:'\uEB2B',39778:'\uEB2C',39779:'\uEB2D',39780:'\uEB2E',39781:'\uEB2F',39782:'\uEB30',39783:'\uEB31',39784:'\uEB32',39785:'\uEB33',39786:'\uEB34',39787:'\uEB35',39788:'\uEB36',39789:'\uEB37',39790:'\uEB38',39791:'\uEB39',39792:'\uEB3A',39793:'\uEB3B',39794:'\uEB3C',39795:'\uEB3D',39796:'\uEB3E',39797:'\uEB3F',39798:'\uEB40',39799:'\uEB41',39800:'\uEB42',39801:'\uEB43',39802:'\uEB44',39803:'\uEB45',39804:'\uEB46',39805:'\uEB47',39806:'\uEB48',39841:'\uEB49',39842:'\uEB4A',39843:'\uEB4B',39844:'\uEB4C',39845:'\uEB4D',39846:'\uEB4E',39847:'\uEB4F',39848:'\uEB50',39849:'\uEB51',39850:'\uEB52',39851:'\uEB53',39852:'\uEB54',39853:'\uEB55',39854:'\uEB56',39855:'\uEB57',39856:'\uEB58',39857:'\uEB59',39858:'\uEB5A',39859:'\uEB5B',39860:'\uEB5C',39861:'\uEB5D',39862:'\uEB5E',39863:'\uEB5F',39864:'\uEB60',39865:'\uEB61',39866:'\uEB62',39867:'\uEB63',39868:'\uEB64',39869:'\uEB65',39870:'\uEB66',39871:'\uEB67',39872:'\uEB68',39873:'\uEB69',39874:'\uEB6A',39875:'\uEB6B',39876:'\uEB6C',39877:'\uEB6D',39878:'\uEB6E',39879:'\uEB6F',39880:'\uEB70',39881:'\uEB71',39882:'\uEB72',39883:'\uEB73',39884:'\uEB74',39885:'\uEB75',39886:'\uEB76',39887:'\uEB77',39888:'\uEB78',39889:'\uEB79',39890:'\uEB7A',39891:'\uEB7B',39892:'\uEB7C',39893:'\uEB7D',39894:'\uEB7E',39895:'\uEB7F',39896:'\uEB80',39897:'\uEB81',39898:'\uEB82',39899:'\uEB83',39900:'\uEB84',39901:'\uEB85',39902:'\uEB86',39903:'\uEB87',39904:'\uEB88',39905:'\uEB89',39906:'\uEB8A',39907:'\uEB8B',39908:'\uEB8C',39909:'\uEB8D',39910:'\uEB8E',39911:'\uEB8F',39912:'\uEB90',39913:'\uEB91',39914:'\uEB92',39915:'\uEB93',39916:'\uEB94',39917:'\uEB95',39918:'\uEB96',39919:'\uEB97',39920:'\uEB98',39921:'\uEB99',39922:'\uEB9A',39923:'\uEB9B',39924:'\uEB9C',39925:'\uEB9D',39926:'\uEB9E',39927:'\uEB9F',39928:'\uEBA0',39929:'\uEBA1',39930:'\uEBA2',39931:'\uEBA3',39932:'\uEBA4',39933:'\uEBA5',39934:'\uEBA6',40000:'\uEBA7',40001:'\uEBA8',40002:'\uEBA9',40003:'\uEBAA',40004:'\uEBAB',40005:'\uEBAC',40006:'\uEBAD',40007:'\uEBAE',40008:'\uEBAF',40009:'\uEBB0',40010:'\uEBB1',40011:'\uEBB2',40012:'\uEBB3',40013:'\uEBB4',40014:'\uEBB5',40015:'\uEBB6',40016:'\uEBB7',40017:'\uEBB8',40018:'\uEBB9',40019:'\uEBBA',40020:'\uEBBB',40021:'\uEBBC',40022:'\uEBBD',40023:'\uEBBE',40024:'\uEBBF',40025:'\uEBC0',40026:'\uEBC1',40027:'\uEBC2',40028:'\uEBC3',40029:'\uEBC4',40030:'\uEBC5',40031:'\uEBC6',40032:'\uEBC7',40033:'\uEBC8',40034:'\uEBC9',40035:'\uEBCA',40036:'\uEBCB',40037:'\uEBCC',40038:'\uEBCD',40039:'\uEBCE',40040:'\uEBCF',40041:'\uEBD0',40042:'\uEBD1',40043:'\uEBD2',40044:'\uEBD3',40045:'\uEBD4',40046:'\uEBD5',40047:'\uEBD6',40048:'\uEBD7',40049:'\uEBD8',40050:'\uEBD9',40051:'\uEBDA',40052:'\uEBDB',40053:'\uEBDC',40054:'\uEBDD',40055:'\uEBDE',40056:'\uEBDF',40057:'\uEBE0',40058:'\uEBE1',40059:'\uEBE2',40060:'\uEBE3',40061:'\uEBE4',40062:'\uEBE5',40097:'\uEBE6',40098:'\uEBE7',40099:'\uEBE8',40100:'\uEBE9',40101:'\uEBEA',40102:'\uEBEB',40103:'\uEBEC',40104:'\uEBED',40105:'\uEBEE',40106:'\uEBEF',40107:'\uEBF0',40108:'\uEBF1',40109:'\uEBF2',40110:'\uEBF3',40111:'\uEBF4',40112:'\uEBF5',40113:'\uEBF6',40114:'\uEBF7',40115:'\uEBF8',40116:'\uEBF9',40117:'\uEBFA',40118:'\uEBFB',40119:'\uEBFC',40120:'\uEBFD',40121:'\uEBFE',40122:'\uEBFF',40123:'\uEC00',40124:'\uEC01',40125:'\uEC02',40126:'\uEC03',40127:'\uEC04',40128:'\uEC05',40129:'\uEC06',40130:'\uEC07',40131:'\uEC08',40132:'\uEC09',40133:'\uEC0A',40134:'\uEC0B',40135:'\uEC0C',40136:'\uEC0D',40137:'\uEC0E',40138:'\uEC0F',40139:'\uEC10',40140:'\uEC11',40141:'\uEC12',40142:'\uEC13',40143:'\uEC14',40144:'\uEC15',40145:'\uEC16',40146:'\uEC17',40147:'\uEC18',40148:'\uEC19',40149:'\uEC1A',40150:'\uEC1B',40151:'\uEC1C',40152:'\uEC1D',40153:'\uEC1E',40154:'\uEC1F',40155:'\uEC20',40156:'\uEC21',40157:'\uEC22',40158:'\uEC23',40159:'\uEC24',40160:'\uEC25',40161:'\uEC26',40162:'\uEC27',40163:'\uEC28',40164:'\uEC29',40165:'\uEC2A',40166:'\uEC2B',40167:'\uEC2C',40168:'\uEC2D',40169:'\uEC2E',40170:'\uEC2F',40171:'\uEC30',40172:'\uEC31',40173:'\uEC32',40174:'\uEC33',40175:'\uEC34',40176:'\uEC35',40177:'\uEC36',40178:'\uEC37',40179:'\uEC38',40180:'\uEC39',40181:'\uEC3A',40182:'\uEC3B',40183:'\uEC3C',40184:'\uEC3D',40185:'\uEC3E',40186:'\uEC3F',40187:'\uEC40',40188:'\uEC41',40189:'\uEC42',40190:'\uEC43',40256:'\uEC44',40257:'\uEC45',40258:'\uEC46',40259:'\uEC47',40260:'\uEC48',40261:'\uEC49',40262:'\uEC4A',40263:'\uEC4B',40264:'\uEC4C',40265:'\uEC4D',40266:'\uEC4E',40267:'\uEC4F',40268:'\uEC50',40269:'\uEC51',40270:'\uEC52',40271:'\uEC53',40272:'\uEC54',40273:'\uEC55',40274:'\uEC56',40275:'\uEC57',40276:'\uEC58',40277:'\uEC59',40278:'\uEC5A',40279:'\uEC5B',40280:'\uEC5C',40281:'\uEC5D',40282:'\uEC5E',40283:'\uEC5F',40284:'\uEC60',40285:'\uEC61',40286:'\uEC62',40287:'\uEC63',40288:'\uEC64',40289:'\uEC65',40290:'\uEC66',40291:'\uEC67',40292:'\uEC68',40293:'\uEC69',40294:'\uEC6A',40295:'\uEC6B',40296:'\uEC6C',40297:'\uEC6D',40298:'\uEC6E',40299:'\uEC6F',40300:'\uEC70',40301:'\uEC71',40302:'\uEC72',40303:'\uEC73',40304:'\uEC74',40305:'\uEC75',40306:'\uEC76',40307:'\uEC77',40308:'\uEC78',40309:'\uEC79',40310:'\uEC7A',40311:'\uEC7B',40312:'\uEC7C',40313:'\uEC7D',40314:'\uEC7E',40315:'\uEC7F',40316:'\uEC80',40317:'\uEC81',40318:'\uEC82',40353:'\uEC83',40354:'\uEC84',40355:'\uEC85',40356:'\uEC86',40357:'\uEC87',40358:'\uEC88',40359:'\uEC89',40360:'\uEC8A',40361:'\uEC8B',40362:'\uEC8C',40363:'\uEC8D',40364:'\uEC8E',40365:'\uEC8F',40366:'\uEC90',40367:'\uEC91',40368:'\uEC92',40369:'\uEC93',40370:'\uEC94',40371:'\uEC95',40372:'\uEC96',40373:'\uEC97',40374:'\uEC98',40375:'\uEC99',40376:'\uEC9A',40377:'\uEC9B',40378:'\uEC9C',40379:'\uEC9D',40380:'\uEC9E',40381:'\uEC9F',40382:'\uECA0',40383:'\uECA1',40384:'\uECA2',40385:'\uECA3',40386:'\uECA4',40387:'\uECA5',40388:'\uECA6',40389:'\uECA7',40390:'\uECA8',40391:'\uECA9',40392:'\uECAA',40393:'\uECAB',40394:'\uECAC',40395:'\uECAD',40396:'\uECAE',40397:'\uECAF',40398:'\uECB0',40399:'\uECB1',40400:'\uECB2',40401:'\uECB3',40402:'\uECB4',40403:'\uECB5',40404:'\uECB6',40405:'\uECB7',40406:'\uECB8',40407:'\uECB9',40408:'\uECBA',40409:'\uECBB',40410:'\uECBC',40411:'\uECBD',40412:'\uECBE',40413:'\uECBF',40414:'\uECC0',40415:'\uECC1',40416:'\uECC2',40417:'\uECC3',40418:'\uECC4',40419:'\uECC5',40420:'\uECC6',40421:'\uECC7',40422:'\uECC8',40423:'\uECC9',40424:'\uECCA',40425:'\uECCB',40426:'\uECCC',40427:'\uECCD',40428:'\uECCE',40429:'\uECCF',40430:'\uECD0',40431:'\uECD1',40432:'\uECD2',40433:'\uECD3',40434:'\uECD4',40435:'\uECD5',40436:'\uECD6',40437:'\uECD7',40438:'\uECD8',40439:'\uECD9',40440:'\uECDA',40441:'\uECDB',40442:'\uECDC',40443:'\uECDD',40444:'\uECDE',40445:'\uECDF',40446:'\uECE0',40512:'\uECE1',40513:'\uECE2',40514:'\uECE3',40515:'\uECE4',40516:'\uECE5',40517:'\uECE6',40518:'\uECE7',40519:'\uECE8',40520:'\uECE9',40521:'\uECEA',40522:'\uECEB',40523:'\uECEC',40524:'\uECED',40525:'\uECEE',40526:'\uECEF',40527:'\uECF0',40528:'\uECF1',40529:'\uECF2',40530:'\uECF3',40531:'\uECF4',40532:'\uECF5',40533:'\uECF6',40534:'\uECF7',40535:'\uECF8',40536:'\uECF9',40537:'\uECFA',40538:'\uECFB',40539:'\uECFC',40540:'\uECFD',40541:'\uECFE',40542:'\uECFF',40543:'\uED00',40544:'\uED01',40545:'\uED02',40546:'\uED03',40547:'\uED04',40548:'\uED05',40549:'\uED06',40550:'\uED07',40551:'\uED08',40552:'\uED09',40553:'\uED0A',40554:'\uED0B',40555:'\uED0C',40556:'\uED0D',40557:'\uED0E',40558:'\uED0F',40559:'\uED10',40560:'\uED11',40561:'\uED12',40562:'\uED13',40563:'\uED14',40564:'\uED15',40565:'\uED16',40566:'\uED17',40567:'\uED18',40568:'\uED19',40569:'\uED1A',40570:'\uED1B',40571:'\uED1C',40572:'\uED1D',40573:'\uED1E',40574:'\uED1F',40609:'\uED20',40610:'\uED21',40611:'\uED22',40612:'\uED23',40613:'\uED24',40614:'\uED25',40615:'\uED26',40616:'\uED27',40617:'\uED28',40618:'\uED29',40619:'\uED2A',40620:'\uED2B',40621:'\uED2C',40622:'\uED2D',40623:'\uED2E',40624:'\uED2F',40625:'\uED30',40626:'\uED31',40627:'\uED32',40628:'\uED33',40629:'\uED34',40630:'\uED35',40631:'\uED36',40632:'\uED37',40633:'\uED38',40634:'\uED39',40635:'\uED3A',40636:'\uED3B',40637:'\uED3C',40638:'\uED3D',40639:'\uED3E',40640:'\uED3F',40641:'\uED40',40642:'\uED41',40643:'\uED42',40644:'\uED43',40645:'\uED44',40646:'\uED45',40647:'\uED46',40648:'\uED47',40649:'\uED48',40650:'\uED49',40651:'\uED4A',40652:'\uED4B',40653:'\uED4C',40654:'\uED4D',40655:'\uED4E',40656:'\uED4F',40657:'\uED50',40658:'\uED51',40659:'\uED52',40660:'\uED53',40661:'\uED54',40662:'\uED55',40663:'\uED56',40664:'\uED57',40665:'\uED58',40666:'\uED59',40667:'\uED5A',40668:'\uED5B',40669:'\uED5C',40670:'\uED5D',40671:'\uED5E',40672:'\uED5F',40673:'\uED60',40674:'\uED61',40675:'\uED62',40676:'\uED63',40677:'\uED64',40678:'\uED65',40679:'\uED66',40680:'\uED67',40681:'\uED68',40682:'\uED69',40683:'\uED6A',40684:'\uED6B',40685:'\uED6C',40686:'\uED6D',40687:'\uED6E',40688:'\uED6F',40689:'\uED70',40690:'\uED71',40691:'\uED72',40692:'\uED73',40693:'\uED74',40694:'\uED75',40695:'\uED76',40696:'\uED77',40697:'\uED78',40698:'\uED79',40699:'\uED7A',40700:'\uED7B',40701:'\uED7C',40702:'\uED7D',40768:'\uED7E',40769:'\uED7F',40770:'\uED80',40771:'\uED81',40772:'\uED82',40773:'\uED83',40774:'\uED84',40775:'\uED85',40776:'\uED86',40777:'\uED87',40778:'\uED88',40779:'\uED89',40780:'\uED8A',40781:'\uED8B',40782:'\uED8C',40783:'\uED8D',40784:'\uED8E',40785:'\uED8F',40786:'\uED90',40787:'\uED91',40788:'\uED92',40789:'\uED93',40790:'\uED94',40791:'\uED95',40792:'\uED96',40793:'\uED97',40794:'\uED98',40795:'\uED99',40796:'\uED9A',40797:'\uED9B',40798:'\uED9C',40799:'\uED9D',40800:'\uED9E',40801:'\uED9F',40802:'\uEDA0',40803:'\uEDA1',40804:'\uEDA2',40805:'\uEDA3',40806:'\uEDA4',40807:'\uEDA5',40808:'\uEDA6',40809:'\uEDA7',40810:'\uEDA8',40811:'\uEDA9',40812:'\uEDAA',40813:'\uEDAB',40814:'\uEDAC',40815:'\uEDAD',40816:'\uEDAE',40817:'\uEDAF',40818:'\uEDB0',40819:'\uEDB1',40820:'\uEDB2',40821:'\uEDB3',40822:'\uEDB4',40823:'\uEDB5',40824:'\uEDB6',40825:'\uEDB7',40826:'\uEDB8',40827:'\uEDB9',40828:'\uEDBA',40829:'\uEDBB',40830:'\uEDBC',40865:'\uEDBD',40866:'\uEDBE',40867:'\uEDBF',40868:'\uEDC0',40869:'\uEDC1',40870:'\uEDC2',40871:'\uEDC3',40872:'\uEDC4',40873:'\uEDC5',40874:'\uEDC6',40875:'\uEDC7',40876:'\uEDC8',40877:'\uEDC9',40878:'\uEDCA',40879:'\uEDCB',40880:'\uEDCC',40881:'\uEDCD',40882:'\uEDCE',40883:'\uEDCF',40884:'\uEDD0',40885:'\uEDD1',40886:'\uEDD2',40887:'\uEDD3',40888:'\uEDD4',40889:'\uEDD5',40890:'\uEDD6',40891:'\uEDD7',40892:'\uEDD8',40893:'\uEDD9',40894:'\uEDDA',40895:'\uEDDB',40896:'\uEDDC',40897:'\uEDDD',40898:'\uEDDE',40899:'\uEDDF',40900:'\uEDE0',40901:'\uEDE1',40902:'\uEDE2',40903:'\uEDE3',40904:'\uEDE4',40905:'\uEDE5',40906:'\uEDE6',40907:'\uEDE7',40908:'\uEDE8',40909:'\uEDE9',40910:'\uEDEA',40911:'\uEDEB',40912:'\uEDEC',40913:'\uEDED',40914:'\uEDEE',40915:'\uEDEF',40916:'\uEDF0',40917:'\uEDF1',40918:'\uEDF2',40919:'\uEDF3',40920:'\uEDF4',40921:'\uEDF5',40922:'\uEDF6',40923:'\uEDF7',40924:'\uEDF8',40925:'\uEDF9',40926:'\uEDFA',40927:'\uEDFB',40928:'\uEDFC',40929:'\uEDFD',40930:'\uEDFE',40931:'\uEDFF',40932:'\uEE00',40933:'\uEE01',40934:'\uEE02',40935:'\uEE03',40936:'\uEE04',40937:'\uEE05',40938:'\uEE06',40939:'\uEE07',40940:'\uEE08',40941:'\uEE09',40942:'\uEE0A',40943:'\uEE0B',40944:'\uEE0C',40945:'\uEE0D',40946:'\uEE0E',40947:'\uEE0F',40948:'\uEE10',40949:'\uEE11',40950:'\uEE12',40951:'\uEE13',40952:'\uEE14',40953:'\uEE15',40954:'\uEE16',40955:'\uEE17',40956:'\uEE18',40957:'\uEE19',40958:'\uEE1A',41024:'\uEE1B',41025:'\uEE1C',41026:'\uEE1D',41027:'\uEE1E',41028:'\uEE1F',41029:'\uEE20',41030:'\uEE21',41031:'\uEE22',41032:'\uEE23',41033:'\uEE24',41034:'\uEE25',41035:'\uEE26',41036:'\uEE27',41037:'\uEE28',41038:'\uEE29',41039:'\uEE2A',41040:'\uEE2B',41041:'\uEE2C',41042:'\uEE2D',41043:'\uEE2E',41044:'\uEE2F',41045:'\uEE30',41046:'\uEE31',41047:'\uEE32',41048:'\uEE33',41049:'\uEE34',41050:'\uEE35',41051:'\uEE36',41052:'\uEE37',41053:'\uEE38',41054:'\uEE39',41055:'\uEE3A',41056:'\uEE3B',41057:'\uEE3C',41058:'\uEE3D',41059:'\uEE3E',41060:'\uEE3F',41061:'\uEE40',41062:'\uEE41',41063:'\uEE42',41064:'\uEE43',41065:'\uEE44',41066:'\uEE45',41067:'\uEE46',41068:'\uEE47',41069:'\uEE48',41070:'\uEE49',41071:'\uEE4A',41072:'\uEE4B',41073:'\uEE4C',41074:'\uEE4D',41075:'\uEE4E',41076:'\uEE4F',41077:'\uEE50',41078:'\uEE51',41079:'\uEE52',41080:'\uEE53',41081:'\uEE54',41082:'\uEE55',41083:'\uEE56',41084:'\uEE57',41085:'\uEE58',41086:'\uEE59',41121:'\uEE5A',41122:'\uEE5B',41123:'\uEE5C',41124:'\uEE5D',41125:'\uEE5E',41126:'\uEE5F',41127:'\uEE60',41128:'\uEE61',41129:'\uEE62',41130:'\uEE63',41131:'\uEE64',41132:'\uEE65',41133:'\uEE66',41134:'\uEE67',41135:'\uEE68',41136:'\uEE69',41137:'\uEE6A',41138:'\uEE6B',41139:'\uEE6C',41140:'\uEE6D',41141:'\uEE6E',41142:'\uEE6F',41143:'\uEE70',41144:'\uEE71',41145:'\uEE72',41146:'\uEE73',41147:'\uEE74',41148:'\uEE75',41149:'\uEE76',41150:'\uEE77',41151:'\uEE78',41152:'\uEE79',41153:'\uEE7A',41154:'\uEE7B',41155:'\uEE7C',41156:'\uEE7D',41157:'\uEE7E',41158:'\uEE7F',41159:'\uEE80',41160:'\uEE81',41161:'\uEE82',41162:'\uEE83',41163:'\uEE84',41164:'\uEE85',41165:'\uEE86',41166:'\uEE87',41167:'\uEE88',41168:'\uEE89',41169:'\uEE8A',41170:'\uEE8B',41171:'\uEE8C',41172:'\uEE8D',41173:'\uEE8E',41174:'\uEE8F',41175:'\uEE90',41176:'\uEE91',41177:'\uEE92',41178:'\uEE93',41179:'\uEE94',41180:'\uEE95',41181:'\uEE96',41182:'\uEE97',41183:'\uEE98',41184:'\uEE99',41185:'\uEE9A',41186:'\uEE9B',41187:'\uEE9C',41188:'\uEE9D',41189:'\uEE9E',41190:'\uEE9F',41191:'\uEEA0',41192:'\uEEA1',41193:'\uEEA2',41194:'\uEEA3',41195:'\uEEA4',41196:'\uEEA5',41197:'\uEEA6',41198:'\uEEA7',41199:'\uEEA8',41200:'\uEEA9',41201:'\uEEAA',41202:'\uEEAB',41203:'\uEEAC',41204:'\uEEAD',41205:'\uEEAE',41206:'\uEEAF',41207:'\uEEB0',41208:'\uEEB1',41209:'\uEEB2',41210:'\uEEB3',41211:'\uEEB4',41212:'\uEEB5',41213:'\uEEB6',41214:'\uEEB7',41280:'\u3000',41281:'\uFF0C',41282:'\u3001',41283:'\u3002',41284:'\uFF0E',41285:'\u2027',41286:'\uFF1B',41287:'\uFF1A',41288:'\uFF1F',41289:'\uFF01',41290:'\uFE30',41291:'\u2026',41292:'\u2025',41293:'\uFE50',41294:'\uFE51',41295:'\uFE52',41296:'\u00B7',41297:'\uFE54',41298:'\uFE55',41299:'\uFE56',41300:'\uFE57',41301:'\uFF5C',41302:'\u2013',41303:'\uFE31',41304:'\u2014',41305:'\uFE33',41306:'\u2574',41307:'\uFE34',41308:'\uFE4F',41309:'\uFF08',41310:'\uFF09',41311:'\uFE35',41312:'\uFE36',41313:'\uFF5B',41314:'\uFF5D',41315:'\uFE37',41316:'\uFE38',41317:'\u3014',41318:'\u3015',41319:'\uFE39',41320:'\uFE3A',41321:'\u3010',41322:'\u3011',41323:'\uFE3B',41324:'\uFE3C',41325:'\u300A',41326:'\u300B',41327:'\uFE3D',41328:'\uFE3E',41329:'\u3008',41330:'\u3009',41331:'\uFE3F',41332:'\uFE40',41333:'\u300C',41334:'\u300D',41335:'\uFE41',41336:'\uFE42',41337:'\u300E',41338:'\u300F',41339:'\uFE43',41340:'\uFE44',41341:'\uFE59',41342:'\uFE5A',41377:'\uFE5B',41378:'\uFE5C',41379:'\uFE5D',41380:'\uFE5E',41381:'\u2018',41382:'\u2019',41383:'\u201C',41384:'\u201D',41385:'\u301D',41386:'\u301E',41387:'\u2035',41388:'\u2032',41389:'\uFF03',41390:'\uFF06',41391:'\uFF0A',41392:'\u203B',41393:'\u00A7',41394:'\u3003',41395:'\u25CB',41396:'\u25CF',41397:'\u25B3',41398:'\u25B2',41399:'\u25CE',41400:'\u2606',41401:'\u2605',41402:'\u25C7',41403:'\u25C6',41404:'\u25A1',41405:'\u25A0',41406:'\u25BD',41407:'\u25BC',41408:'\u32A3',41409:'\u2105',41410:'\u00AF',41411:'\uFFE3',41412:'\uFF3F',41413:'\u02CD',41414:'\uFE49',41415:'\uFE4A',41416:'\uFE4D',41417:'\uFE4E',41418:'\uFE4B',41419:'\uFE4C',41420:'\uFE5F',41421:'\uFE60',41422:'\uFE61',41423:'\uFF0B',41424:'\uFF0D',41425:'\u00D7',41426:'\u00F7',41427:'\u00B1',41428:'\u221A',41429:'\uFF1C',41430:'\uFF1E',41431:'\uFF1D',41432:'\u2266',41433:'\u2267',41434:'\u2260',41435:'\u221E',41436:'\u2252',41437:'\u2261',41438:'\uFE62',41439:'\uFE63',41440:'\uFE64',41441:'\uFE65',41442:'\uFE66',41443:'\uFF5E',41444:'\u2229',41445:'\u222A',41446:'\u22A5',41447:'\u2220',41448:'\u221F',41449:'\u22BF',41450:'\u33D2',41451:'\u33D1',41452:'\u222B',41453:'\u222E',41454:'\u2235',41455:'\u2234',41456:'\u2640',41457:'\u2642',41458:'\u2295',41459:'\u2299',41460:'\u2191',41461:'\u2193',41462:'\u2190',41463:'\u2192',41464:'\u2196',41465:'\u2197',41466:'\u2199',41467:'\u2198',41468:'\u2225',41469:'\u2223',41470:'\uFF0F',41536:'\uFF3C',41537:'\u2215',41538:'\uFE68',41539:'\uFF04',41540:'\uFFE5',41541:'\u3012',41542:'\uFFE0',41543:'\uFFE1',41544:'\uFF05',41545:'\uFF20',41546:'\u2103',41547:'\u2109',41548:'\uFE69',41549:'\uFE6A',41550:'\uFE6B',41551:'\u33D5',41552:'\u339C',41553:'\u339D',41554:'\u339E',41555:'\u33CE',41556:'\u33A1',41557:'\u338E',41558:'\u338F',41559:'\u33C4',41560:'\u00B0',41561:'\u5159',41562:'\u515B',41563:'\u515E',41564:'\u515D',41565:'\u5161',41566:'\u5163',41567:'\u55E7',41568:'\u74E9',41569:'\u7CCE',41570:'\u2581',41571:'\u2582',41572:'\u2583',41573:'\u2584',41574:'\u2585',41575:'\u2586',41576:'\u2587',41577:'\u2588',41578:'\u258F',41579:'\u258E',41580:'\u258D',41581:'\u258C',41582:'\u258B',41583:'\u258A',41584:'\u2589',41585:'\u253C',41586:'\u2534',41587:'\u252C',41588:'\u2524',41589:'\u251C',41590:'\u2594',41591:'\u2500',41592:'\u2502',41593:'\u2595',41594:'\u250C',41595:'\u2510',41596:'\u2514',41597:'\u2518',41598:'\u256D',41633:'\u256E',41634:'\u2570',41635:'\u256F',41636:'\u2550',41637:'\u255E',41638:'\u256A',41639:'\u2561',41640:'\u25E2',41641:'\u25E3',41642:'\u25E5',41643:'\u25E4',41644:'\u2571',41645:'\u2572',41646:'\u2573',41647:'\uFF10',41648:'\uFF11',41649:'\uFF12',41650:'\uFF13',41651:'\uFF14',41652:'\uFF15',41653:'\uFF16',41654:'\uFF17',41655:'\uFF18',41656:'\uFF19',41657:'\u2160',41658:'\u2161',41659:'\u2162',41660:'\u2163',41661:'\u2164',41662:'\u2165',41663:'\u2166',41664:'\u2167',41665:'\u2168',41666:'\u2169',41667:'\u3021',41668:'\u3022',41669:'\u3023',41670:'\u3024',41671:'\u3025',41672:'\u3026',41673:'\u3027',41674:'\u3028',41675:'\u3029',41676:'\u5341',41677:'\u5344',41678:'\u5345',41679:'\uFF21',41680:'\uFF22',41681:'\uFF23',41682:'\uFF24',41683:'\uFF25',41684:'\uFF26',41685:'\uFF27',41686:'\uFF28',41687:'\uFF29',41688:'\uFF2A',41689:'\uFF2B',41690:'\uFF2C',41691:'\uFF2D',41692:'\uFF2E',41693:'\uFF2F',41694:'\uFF30',41695:'\uFF31',41696:'\uFF32',41697:'\uFF33',41698:'\uFF34',41699:'\uFF35',41700:'\uFF36',41701:'\uFF37',41702:'\uFF38',41703:'\uFF39',41704:'\uFF3A',41705:'\uFF41',41706:'\uFF42',41707:'\uFF43',41708:'\uFF44',41709:'\uFF45',41710:'\uFF46',41711:'\uFF47',41712:'\uFF48',41713:'\uFF49',41714:'\uFF4A',41715:'\uFF4B',41716:'\uFF4C',41717:'\uFF4D',41718:'\uFF4E',41719:'\uFF4F',41720:'\uFF50',41721:'\uFF51',41722:'\uFF52',41723:'\uFF53',41724:'\uFF54',41725:'\uFF55',41726:'\uFF56',41792:'\uFF57',41793:'\uFF58',41794:'\uFF59',41795:'\uFF5A',41796:'\u0391',41797:'\u0392',41798:'\u0393',41799:'\u0394',41800:'\u0395',41801:'\u0396',41802:'\u0397',41803:'\u0398',41804:'\u0399',41805:'\u039A',41806:'\u039B',41807:'\u039C',41808:'\u039D',41809:'\u039E',41810:'\u039F',41811:'\u03A0',41812:'\u03A1',41813:'\u03A3',41814:'\u03A4',41815:'\u03A5',41816:'\u03A6',41817:'\u03A7',41818:'\u03A8',41819:'\u03A9',41820:'\u03B1',41821:'\u03B2',41822:'\u03B3',41823:'\u03B4',41824:'\u03B5',41825:'\u03B6',41826:'\u03B7',41827:'\u03B8',41828:'\u03B9',41829:'\u03BA',41830:'\u03BB',41831:'\u03BC',41832:'\u03BD',41833:'\u03BE',41834:'\u03BF',41835:'\u03C0',41836:'\u03C1',41837:'\u03C3',41838:'\u03C4',41839:'\u03C5',41840:'\u03C6',41841:'\u03C7',41842:'\u03C8',41843:'\u03C9',41844:'\u3105',41845:'\u3106',41846:'\u3107',41847:'\u3108',41848:'\u3109',41849:'\u310A',41850:'\u310B',41851:'\u310C',41852:'\u310D',41853:'\u310E',41854:'\u310F',41889:'\u3110',41890:'\u3111',41891:'\u3112',41892:'\u3113',41893:'\u3114',41894:'\u3115',41895:'\u3116',41896:'\u3117',41897:'\u3118',41898:'\u3119',41899:'\u311A',41900:'\u311B',41901:'\u311C',41902:'\u311D',41903:'\u311E',41904:'\u311F',41905:'\u3120',41906:'\u3121',41907:'\u3122',41908:'\u3123',41909:'\u3124',41910:'\u3125',41911:'\u3126',41912:'\u3127',41913:'\u3128',41914:'\u3129',41915:'\u02D9',41916:'\u02C9',41917:'\u02CA',41918:'\u02C7',41919:'\u02CB',41953:'\u20AC',42048:'\u4E00',42049:'\u4E59',42050:'\u4E01',42051:'\u4E03',42052:'\u4E43',42053:'\u4E5D',42054:'\u4E86',42055:'\u4E8C',42056:'\u4EBA',42057:'\u513F',42058:'\u5165',42059:'\u516B',42060:'\u51E0',42061:'\u5200',42062:'\u5201',42063:'\u529B',42064:'\u5315',42065:'\u5341',42066:'\u535C',42067:'\u53C8',42068:'\u4E09',42069:'\u4E0B',42070:'\u4E08',42071:'\u4E0A',42072:'\u4E2B',42073:'\u4E38',42074:'\u51E1',42075:'\u4E45',42076:'\u4E48',42077:'\u4E5F',42078:'\u4E5E',42079:'\u4E8E',42080:'\u4EA1',42081:'\u5140',42082:'\u5203',42083:'\u52FA',42084:'\u5343',42085:'\u53C9',42086:'\u53E3',42087:'\u571F',42088:'\u58EB',42089:'\u5915',42090:'\u5927',42091:'\u5973',42092:'\u5B50',42093:'\u5B51',42094:'\u5B53',42095:'\u5BF8',42096:'\u5C0F',42097:'\u5C22',42098:'\u5C38',42099:'\u5C71',42100:'\u5DDD',42101:'\u5DE5',42102:'\u5DF1',42103:'\u5DF2',42104:'\u5DF3',42105:'\u5DFE',42106:'\u5E72',42107:'\u5EFE',42108:'\u5F0B',42109:'\u5F13',42110:'\u624D',42145:'\u4E11',42146:'\u4E10',42147:'\u4E0D',42148:'\u4E2D',42149:'\u4E30',42150:'\u4E39',42151:'\u4E4B',42152:'\u5C39',42153:'\u4E88',42154:'\u4E91',42155:'\u4E95',42156:'\u4E92',42157:'\u4E94',42158:'\u4EA2',42159:'\u4EC1',42160:'\u4EC0',42161:'\u4EC3',42162:'\u4EC6',42163:'\u4EC7',42164:'\u4ECD',42165:'\u4ECA',42166:'\u4ECB',42167:'\u4EC4',42168:'\u5143',42169:'\u5141',42170:'\u5167',42171:'\u516D',42172:'\u516E',42173:'\u516C',42174:'\u5197',42175:'\u51F6',42176:'\u5206',42177:'\u5207',42178:'\u5208',42179:'\u52FB',42180:'\u52FE',42181:'\u52FF',42182:'\u5316',42183:'\u5339',42184:'\u5348',42185:'\u5347',42186:'\u5345',42187:'\u535E',42188:'\u5384',42189:'\u53CB',42190:'\u53CA',42191:'\u53CD',42192:'\u58EC',42193:'\u5929',42194:'\u592B',42195:'\u592A',42196:'\u592D',42197:'\u5B54',42198:'\u5C11',42199:'\u5C24',42200:'\u5C3A',42201:'\u5C6F',42202:'\u5DF4',42203:'\u5E7B',42204:'\u5EFF',42205:'\u5F14',42206:'\u5F15',42207:'\u5FC3',42208:'\u6208',42209:'\u6236',42210:'\u624B',42211:'\u624E',42212:'\u652F',42213:'\u6587',42214:'\u6597',42215:'\u65A4',42216:'\u65B9',42217:'\u65E5',42218:'\u66F0',42219:'\u6708',42220:'\u6728',42221:'\u6B20',42222:'\u6B62',42223:'\u6B79',42224:'\u6BCB',42225:'\u6BD4',42226:'\u6BDB',42227:'\u6C0F',42228:'\u6C34',42229:'\u706B',42230:'\u722A',42231:'\u7236',42232:'\u723B',42233:'\u7247',42234:'\u7259',42235:'\u725B',42236:'\u72AC',42237:'\u738B',42238:'\u4E19',42304:'\u4E16',42305:'\u4E15',42306:'\u4E14',42307:'\u4E18',42308:'\u4E3B',42309:'\u4E4D',42310:'\u4E4F',42311:'\u4E4E',42312:'\u4EE5',42313:'\u4ED8',42314:'\u4ED4',42315:'\u4ED5',42316:'\u4ED6',42317:'\u4ED7',42318:'\u4EE3',42319:'\u4EE4',42320:'\u4ED9',42321:'\u4EDE',42322:'\u5145',42323:'\u5144',42324:'\u5189',42325:'\u518A',42326:'\u51AC',42327:'\u51F9',42328:'\u51FA',42329:'\u51F8',42330:'\u520A',42331:'\u52A0',42332:'\u529F',42333:'\u5305',42334:'\u5306',42335:'\u5317',42336:'\u531D',42337:'\u4EDF',42338:'\u534A',42339:'\u5349',42340:'\u5361',42341:'\u5360',42342:'\u536F',42343:'\u536E',42344:'\u53BB',42345:'\u53EF',42346:'\u53E4',42347:'\u53F3',42348:'\u53EC',42349:'\u53EE',42350:'\u53E9',42351:'\u53E8',42352:'\u53FC',42353:'\u53F8',42354:'\u53F5',42355:'\u53EB',42356:'\u53E6',42357:'\u53EA',42358:'\u53F2',42359:'\u53F1',42360:'\u53F0',42361:'\u53E5',42362:'\u53ED',42363:'\u53FB',42364:'\u56DB',42365:'\u56DA',42366:'\u5916',42401:'\u592E',42402:'\u5931',42403:'\u5974',42404:'\u5976',42405:'\u5B55',42406:'\u5B83',42407:'\u5C3C',42408:'\u5DE8',42409:'\u5DE7',42410:'\u5DE6',42411:'\u5E02',42412:'\u5E03',42413:'\u5E73',42414:'\u5E7C',42415:'\u5F01',42416:'\u5F18',42417:'\u5F17',42418:'\u5FC5',42419:'\u620A',42420:'\u6253',42421:'\u6254',42422:'\u6252',42423:'\u6251',42424:'\u65A5',42425:'\u65E6',42426:'\u672E',42427:'\u672C',42428:'\u672A',42429:'\u672B',42430:'\u672D',42431:'\u6B63',42432:'\u6BCD',42433:'\u6C11',42434:'\u6C10',42435:'\u6C38',42436:'\u6C41',42437:'\u6C40',42438:'\u6C3E',42439:'\u72AF',42440:'\u7384',42441:'\u7389',42442:'\u74DC',42443:'\u74E6',42444:'\u7518',42445:'\u751F',42446:'\u7528',42447:'\u7529',42448:'\u7530',42449:'\u7531',42450:'\u7532',42451:'\u7533',42452:'\u758B',42453:'\u767D',42454:'\u76AE',42455:'\u76BF',42456:'\u76EE',42457:'\u77DB',42458:'\u77E2',42459:'\u77F3',42460:'\u793A',42461:'\u79BE',42462:'\u7A74',42463:'\u7ACB',42464:'\u4E1E',42465:'\u4E1F',42466:'\u4E52',42467:'\u4E53',42468:'\u4E69',42469:'\u4E99',42470:'\u4EA4',42471:'\u4EA6',42472:'\u4EA5',42473:'\u4EFF',42474:'\u4F09',42475:'\u4F19',42476:'\u4F0A',42477:'\u4F15',42478:'\u4F0D',42479:'\u4F10',42480:'\u4F11',42481:'\u4F0F',42482:'\u4EF2',42483:'\u4EF6',42484:'\u4EFB',42485:'\u4EF0',42486:'\u4EF3',42487:'\u4EFD',42488:'\u4F01',42489:'\u4F0B',42490:'\u5149',42491:'\u5147',42492:'\u5146',42493:'\u5148',42494:'\u5168',42560:'\u5171',42561:'\u518D',42562:'\u51B0',42563:'\u5217',42564:'\u5211',42565:'\u5212',42566:'\u520E',42567:'\u5216',42568:'\u52A3',42569:'\u5308',42570:'\u5321',42571:'\u5320',42572:'\u5370',42573:'\u5371',42574:'\u5409',42575:'\u540F',42576:'\u540C',42577:'\u540A',42578:'\u5410',42579:'\u5401',42580:'\u540B',42581:'\u5404',42582:'\u5411',42583:'\u540D',42584:'\u5408',42585:'\u5403',42586:'\u540E',42587:'\u5406',42588:'\u5412',42589:'\u56E0',42590:'\u56DE',42591:'\u56DD',42592:'\u5733',42593:'\u5730',42594:'\u5728',42595:'\u572D',42596:'\u572C',42597:'\u572F',42598:'\u5729',42599:'\u5919',42600:'\u591A',42601:'\u5937',42602:'\u5938',42603:'\u5984',42604:'\u5978',42605:'\u5983',42606:'\u597D',42607:'\u5979',42608:'\u5982',42609:'\u5981',42610:'\u5B57',42611:'\u5B58',42612:'\u5B87',42613:'\u5B88',42614:'\u5B85',42615:'\u5B89',42616:'\u5BFA',42617:'\u5C16',42618:'\u5C79',42619:'\u5DDE',42620:'\u5E06',42621:'\u5E76',42622:'\u5E74',42657:'\u5F0F',42658:'\u5F1B',42659:'\u5FD9',42660:'\u5FD6',42661:'\u620E',42662:'\u620C',42663:'\u620D',42664:'\u6210',42665:'\u6263',42666:'\u625B',42667:'\u6258',42668:'\u6536',42669:'\u65E9',42670:'\u65E8',42671:'\u65EC',42672:'\u65ED',42673:'\u66F2',42674:'\u66F3',42675:'\u6709',42676:'\u673D',42677:'\u6734',42678:'\u6731',42679:'\u6735',42680:'\u6B21',42681:'\u6B64',42682:'\u6B7B',42683:'\u6C16',42684:'\u6C5D',42685:'\u6C57',42686:'\u6C59',42687:'\u6C5F',42688:'\u6C60',42689:'\u6C50',42690:'\u6C55',42691:'\u6C61',42692:'\u6C5B',42693:'\u6C4D',42694:'\u6C4E',42695:'\u7070',42696:'\u725F',42697:'\u725D',42698:'\u767E',42699:'\u7AF9',42700:'\u7C73',42701:'\u7CF8',42702:'\u7F36',42703:'\u7F8A',42704:'\u7FBD',42705:'\u8001',42706:'\u8003',42707:'\u800C',42708:'\u8012',42709:'\u8033',42710:'\u807F',42711:'\u8089',42712:'\u808B',42713:'\u808C',42714:'\u81E3',42715:'\u81EA',42716:'\u81F3',42717:'\u81FC',42718:'\u820C',42719:'\u821B',42720:'\u821F',42721:'\u826E',42722:'\u8272',42723:'\u827E',42724:'\u866B',42725:'\u8840',42726:'\u884C',42727:'\u8863',42728:'\u897F',42729:'\u9621',42730:'\u4E32',42731:'\u4EA8',42732:'\u4F4D',42733:'\u4F4F',42734:'\u4F47',42735:'\u4F57',42736:'\u4F5E',42737:'\u4F34',42738:'\u4F5B',42739:'\u4F55',42740:'\u4F30',42741:'\u4F50',42742:'\u4F51',42743:'\u4F3D',42744:'\u4F3A',42745:'\u4F38',42746:'\u4F43',42747:'\u4F54',42748:'\u4F3C',42749:'\u4F46',42750:'\u4F63',42816:'\u4F5C',42817:'\u4F60',42818:'\u4F2F',42819:'\u4F4E',42820:'\u4F36',42821:'\u4F59',42822:'\u4F5D',42823:'\u4F48',42824:'\u4F5A',42825:'\u514C',42826:'\u514B',42827:'\u514D',42828:'\u5175',42829:'\u51B6',42830:'\u51B7',42831:'\u5225',42832:'\u5224',42833:'\u5229',42834:'\u522A',42835:'\u5228',42836:'\u52AB',42837:'\u52A9',42838:'\u52AA',42839:'\u52AC',42840:'\u5323',42841:'\u5373',42842:'\u5375',42843:'\u541D',42844:'\u542D',42845:'\u541E',42846:'\u543E',42847:'\u5426',42848:'\u544E',42849:'\u5427',42850:'\u5446',42851:'\u5443',42852:'\u5433',42853:'\u5448',42854:'\u5442',42855:'\u541B',42856:'\u5429',42857:'\u544A',42858:'\u5439',42859:'\u543B',42860:'\u5438',42861:'\u542E',42862:'\u5435',42863:'\u5436',42864:'\u5420',42865:'\u543C',42866:'\u5440',42867:'\u5431',42868:'\u542B',42869:'\u541F',42870:'\u542C',42871:'\u56EA',42872:'\u56F0',42873:'\u56E4',42874:'\u56EB',42875:'\u574A',42876:'\u5751',42877:'\u5740',42878:'\u574D',42913:'\u5747',42914:'\u574E',42915:'\u573E',42916:'\u5750',42917:'\u574F',42918:'\u573B',42919:'\u58EF',42920:'\u593E',42921:'\u599D',42922:'\u5992',42923:'\u59A8',42924:'\u599E',42925:'\u59A3',42926:'\u5999',42927:'\u5996',42928:'\u598D',42929:'\u59A4',42930:'\u5993',42931:'\u598A',42932:'\u59A5',42933:'\u5B5D',42934:'\u5B5C',42935:'\u5B5A',42936:'\u5B5B',42937:'\u5B8C',42938:'\u5B8B',42939:'\u5B8F',42940:'\u5C2C',42941:'\u5C40',42942:'\u5C41',42943:'\u5C3F',42944:'\u5C3E',42945:'\u5C90',42946:'\u5C91',42947:'\u5C94',42948:'\u5C8C',42949:'\u5DEB',42950:'\u5E0C',42951:'\u5E8F',42952:'\u5E87',42953:'\u5E8A',42954:'\u5EF7',42955:'\u5F04',42956:'\u5F1F',42957:'\u5F64',42958:'\u5F62',42959:'\u5F77',42960:'\u5F79',42961:'\u5FD8',42962:'\u5FCC',42963:'\u5FD7',42964:'\u5FCD',42965:'\u5FF1',42966:'\u5FEB',42967:'\u5FF8',42968:'\u5FEA',42969:'\u6212',42970:'\u6211',42971:'\u6284',42972:'\u6297',42973:'\u6296',42974:'\u6280',42975:'\u6276',42976:'\u6289',42977:'\u626D',42978:'\u628A',42979:'\u627C',42980:'\u627E',42981:'\u6279',42982:'\u6273',42983:'\u6292',42984:'\u626F',42985:'\u6298',42986:'\u626E',42987:'\u6295',42988:'\u6293',42989:'\u6291',42990:'\u6286',42991:'\u6539',42992:'\u653B',42993:'\u6538',42994:'\u65F1',42995:'\u66F4',42996:'\u675F',42997:'\u674E',42998:'\u674F',42999:'\u6750',43000:'\u6751',43001:'\u675C',43002:'\u6756',43003:'\u675E',43004:'\u6749',43005:'\u6746',43006:'\u6760',43072:'\u6753',43073:'\u6757',43074:'\u6B65',43075:'\u6BCF',43076:'\u6C42',43077:'\u6C5E',43078:'\u6C99',43079:'\u6C81',43080:'\u6C88',43081:'\u6C89',43082:'\u6C85',43083:'\u6C9B',43084:'\u6C6A',43085:'\u6C7A',43086:'\u6C90',43087:'\u6C70',43088:'\u6C8C',43089:'\u6C68',43090:'\u6C96',43091:'\u6C92',43092:'\u6C7D',43093:'\u6C83',43094:'\u6C72',43095:'\u6C7E',43096:'\u6C74',43097:'\u6C86',43098:'\u6C76',43099:'\u6C8D',43100:'\u6C94',43101:'\u6C98',43102:'\u6C82',43103:'\u7076',43104:'\u707C',43105:'\u707D',43106:'\u7078',43107:'\u7262',43108:'\u7261',43109:'\u7260',43110:'\u72C4',43111:'\u72C2',43112:'\u7396',43113:'\u752C',43114:'\u752B',43115:'\u7537',43116:'\u7538',43117:'\u7682',43118:'\u76EF',43119:'\u77E3',43120:'\u79C1',43121:'\u79C0',43122:'\u79BF',43123:'\u7A76',43124:'\u7CFB',43125:'\u7F55',43126:'\u8096',43127:'\u8093',43128:'\u809D',43129:'\u8098',43130:'\u809B',43131:'\u809A',43132:'\u80B2',43133:'\u826F',43134:'\u8292',43169:'\u828B',43170:'\u828D',43171:'\u898B',43172:'\u89D2',43173:'\u8A00',43174:'\u8C37',43175:'\u8C46',43176:'\u8C55',43177:'\u8C9D',43178:'\u8D64',43179:'\u8D70',43180:'\u8DB3',43181:'\u8EAB',43182:'\u8ECA',43183:'\u8F9B',43184:'\u8FB0',43185:'\u8FC2',43186:'\u8FC6',43187:'\u8FC5',43188:'\u8FC4',43189:'\u5DE1',43190:'\u9091',43191:'\u90A2',43192:'\u90AA',43193:'\u90A6',43194:'\u90A3',43195:'\u9149',43196:'\u91C6',43197:'\u91CC',43198:'\u9632',43199:'\u962E',43200:'\u9631',43201:'\u962A',43202:'\u962C',43203:'\u4E26',43204:'\u4E56',43205:'\u4E73',43206:'\u4E8B',43207:'\u4E9B',43208:'\u4E9E',43209:'\u4EAB',43210:'\u4EAC',43211:'\u4F6F',43212:'\u4F9D',43213:'\u4F8D',43214:'\u4F73',43215:'\u4F7F',43216:'\u4F6C',43217:'\u4F9B',43218:'\u4F8B',43219:'\u4F86',43220:'\u4F83',43221:'\u4F70',43222:'\u4F75',43223:'\u4F88',43224:'\u4F69',43225:'\u4F7B',43226:'\u4F96',43227:'\u4F7E',43228:'\u4F8F',43229:'\u4F91',43230:'\u4F7A',43231:'\u5154',43232:'\u5152',43233:'\u5155',43234:'\u5169',43235:'\u5177',43236:'\u5176',43237:'\u5178',43238:'\u51BD',43239:'\u51FD',43240:'\u523B',43241:'\u5238',43242:'\u5237',43243:'\u523A',43244:'\u5230',43245:'\u522E',43246:'\u5236',43247:'\u5241',43248:'\u52BE',43249:'\u52BB',43250:'\u5352',43251:'\u5354',43252:'\u5353',43253:'\u5351',43254:'\u5366',43255:'\u5377',43256:'\u5378',43257:'\u5379',43258:'\u53D6',43259:'\u53D4',43260:'\u53D7',43261:'\u5473',43262:'\u5475',43328:'\u5496',43329:'\u5478',43330:'\u5495',43331:'\u5480',43332:'\u547B',43333:'\u5477',43334:'\u5484',43335:'\u5492',43336:'\u5486',43337:'\u547C',43338:'\u5490',43339:'\u5471',43340:'\u5476',43341:'\u548C',43342:'\u549A',43343:'\u5462',43344:'\u5468',43345:'\u548B',43346:'\u547D',43347:'\u548E',43348:'\u56FA',43349:'\u5783',43350:'\u5777',43351:'\u576A',43352:'\u5769',43353:'\u5761',43354:'\u5766',43355:'\u5764',43356:'\u577C',43357:'\u591C',43358:'\u5949',43359:'\u5947',43360:'\u5948',43361:'\u5944',43362:'\u5954',43363:'\u59BE',43364:'\u59BB',43365:'\u59D4',43366:'\u59B9',43367:'\u59AE',43368:'\u59D1',43369:'\u59C6',43370:'\u59D0',43371:'\u59CD',43372:'\u59CB',43373:'\u59D3',43374:'\u59CA',43375:'\u59AF',43376:'\u59B3',43377:'\u59D2',43378:'\u59C5',43379:'\u5B5F',43380:'\u5B64',43381:'\u5B63',43382:'\u5B97',43383:'\u5B9A',43384:'\u5B98',43385:'\u5B9C',43386:'\u5B99',43387:'\u5B9B',43388:'\u5C1A',43389:'\u5C48',43390:'\u5C45',43425:'\u5C46',43426:'\u5CB7',43427:'\u5CA1',43428:'\u5CB8',43429:'\u5CA9',43430:'\u5CAB',43431:'\u5CB1',43432:'\u5CB3',43433:'\u5E18',43434:'\u5E1A',43435:'\u5E16',43436:'\u5E15',43437:'\u5E1B',43438:'\u5E11',43439:'\u5E78',43440:'\u5E9A',43441:'\u5E97',43442:'\u5E9C',43443:'\u5E95',43444:'\u5E96',43445:'\u5EF6',43446:'\u5F26',43447:'\u5F27',43448:'\u5F29',43449:'\u5F80',43450:'\u5F81',43451:'\u5F7F',43452:'\u5F7C',43453:'\u5FDD',43454:'\u5FE0',43455:'\u5FFD',43456:'\u5FF5',43457:'\u5FFF',43458:'\u600F',43459:'\u6014',43460:'\u602F',43461:'\u6035',43462:'\u6016',43463:'\u602A',43464:'\u6015',43465:'\u6021',43466:'\u6027',43467:'\u6029',43468:'\u602B',43469:'\u601B',43470:'\u6216',43471:'\u6215',43472:'\u623F',43473:'\u623E',43474:'\u6240',43475:'\u627F',43476:'\u62C9',43477:'\u62CC',43478:'\u62C4',43479:'\u62BF',43480:'\u62C2',43481:'\u62B9',43482:'\u62D2',43483:'\u62DB',43484:'\u62AB',43485:'\u62D3',43486:'\u62D4',43487:'\u62CB',43488:'\u62C8',43489:'\u62A8',43490:'\u62BD',43491:'\u62BC',43492:'\u62D0',43493:'\u62D9',43494:'\u62C7',43495:'\u62CD',43496:'\u62B5',43497:'\u62DA',43498:'\u62B1',43499:'\u62D8',43500:'\u62D6',43501:'\u62D7',43502:'\u62C6',43503:'\u62AC',43504:'\u62CE',43505:'\u653E',43506:'\u65A7',43507:'\u65BC',43508:'\u65FA',43509:'\u6614',43510:'\u6613',43511:'\u660C',43512:'\u6606',43513:'\u6602',43514:'\u660E',43515:'\u6600',43516:'\u660F',43517:'\u6615',43518:'\u660A',43584:'\u6607',43585:'\u670D',43586:'\u670B',43587:'\u676D',43588:'\u678B',43589:'\u6795',43590:'\u6771',43591:'\u679C',43592:'\u6773',43593:'\u6777',43594:'\u6787',43595:'\u679D',43596:'\u6797',43597:'\u676F',43598:'\u6770',43599:'\u677F',43600:'\u6789',43601:'\u677E',43602:'\u6790',43603:'\u6775',43604:'\u679A',43605:'\u6793',43606:'\u677C',43607:'\u676A',43608:'\u6772',43609:'\u6B23',43610:'\u6B66',43611:'\u6B67',43612:'\u6B7F',43613:'\u6C13',43614:'\u6C1B',43615:'\u6CE3',43616:'\u6CE8',43617:'\u6CF3',43618:'\u6CB1',43619:'\u6CCC',43620:'\u6CE5',43621:'\u6CB3',43622:'\u6CBD',43623:'\u6CBE',43624:'\u6CBC',43625:'\u6CE2',43626:'\u6CAB',43627:'\u6CD5',43628:'\u6CD3',43629:'\u6CB8',43630:'\u6CC4',43631:'\u6CB9',43632:'\u6CC1',43633:'\u6CAE',43634:'\u6CD7',43635:'\u6CC5',43636:'\u6CF1',43637:'\u6CBF',43638:'\u6CBB',43639:'\u6CE1',43640:'\u6CDB',43641:'\u6CCA',43642:'\u6CAC',43643:'\u6CEF',43644:'\u6CDC',43645:'\u6CD6',43646:'\u6CE0',43681:'\u7095',43682:'\u708E',43683:'\u7092',43684:'\u708A',43685:'\u7099',43686:'\u722C',43687:'\u722D',43688:'\u7238',43689:'\u7248',43690:'\u7267',43691:'\u7269',43692:'\u72C0',43693:'\u72CE',43694:'\u72D9',43695:'\u72D7',43696:'\u72D0',43697:'\u73A9',43698:'\u73A8',43699:'\u739F',43700:'\u73AB',43701:'\u73A5',43702:'\u753D',43703:'\u759D',43704:'\u7599',43705:'\u759A',43706:'\u7684',43707:'\u76C2',43708:'\u76F2',43709:'\u76F4',43710:'\u77E5',43711:'\u77FD',43712:'\u793E',43713:'\u7940',43714:'\u7941',43715:'\u79C9',43716:'\u79C8',43717:'\u7A7A',43718:'\u7A79',43719:'\u7AFA',43720:'\u7CFE',43721:'\u7F54',43722:'\u7F8C',43723:'\u7F8B',43724:'\u8005',43725:'\u80BA',43726:'\u80A5',43727:'\u80A2',43728:'\u80B1',43729:'\u80A1',43730:'\u80AB',43731:'\u80A9',43732:'\u80B4',43733:'\u80AA',43734:'\u80AF',43735:'\u81E5',43736:'\u81FE',43737:'\u820D',43738:'\u82B3',43739:'\u829D',43740:'\u8299',43741:'\u82AD',43742:'\u82BD',43743:'\u829F',43744:'\u82B9',43745:'\u82B1',43746:'\u82AC',43747:'\u82A5',43748:'\u82AF',43749:'\u82B8',43750:'\u82A3',43751:'\u82B0',43752:'\u82BE',43753:'\u82B7',43754:'\u864E',43755:'\u8671',43756:'\u521D',43757:'\u8868',43758:'\u8ECB',43759:'\u8FCE',43760:'\u8FD4',43761:'\u8FD1',43762:'\u90B5',43763:'\u90B8',43764:'\u90B1',43765:'\u90B6',43766:'\u91C7',43767:'\u91D1',43768:'\u9577',43769:'\u9580',43770:'\u961C',43771:'\u9640',43772:'\u963F',43773:'\u963B',43774:'\u9644',43840:'\u9642',43841:'\u96B9',43842:'\u96E8',43843:'\u9752',43844:'\u975E',43845:'\u4E9F',43846:'\u4EAD',43847:'\u4EAE',43848:'\u4FE1',43849:'\u4FB5',43850:'\u4FAF',43851:'\u4FBF',43852:'\u4FE0',43853:'\u4FD1',43854:'\u4FCF',43855:'\u4FDD',43856:'\u4FC3',43857:'\u4FB6',43858:'\u4FD8',43859:'\u4FDF',43860:'\u4FCA',43861:'\u4FD7',43862:'\u4FAE',43863:'\u4FD0',43864:'\u4FC4',43865:'\u4FC2',43866:'\u4FDA',43867:'\u4FCE',43868:'\u4FDE',43869:'\u4FB7',43870:'\u5157',43871:'\u5192',43872:'\u5191',43873:'\u51A0',43874:'\u524E',43875:'\u5243',43876:'\u524A',43877:'\u524D',43878:'\u524C',43879:'\u524B',43880:'\u5247',43881:'\u52C7',43882:'\u52C9',43883:'\u52C3',43884:'\u52C1',43885:'\u530D',43886:'\u5357',43887:'\u537B',43888:'\u539A',43889:'\u53DB',43890:'\u54AC',43891:'\u54C0',43892:'\u54A8',43893:'\u54CE',43894:'\u54C9',43895:'\u54B8',43896:'\u54A6',43897:'\u54B3',43898:'\u54C7',43899:'\u54C2',43900:'\u54BD',43901:'\u54AA',43902:'\u54C1',43937:'\u54C4',43938:'\u54C8',43939:'\u54AF',43940:'\u54AB',43941:'\u54B1',43942:'\u54BB',43943:'\u54A9',43944:'\u54A7',43945:'\u54BF',43946:'\u56FF',43947:'\u5782',43948:'\u578B',43949:'\u57A0',43950:'\u57A3',43951:'\u57A2',43952:'\u57CE',43953:'\u57AE',43954:'\u5793',43955:'\u5955',43956:'\u5951',43957:'\u594F',43958:'\u594E',43959:'\u5950',43960:'\u59DC',43961:'\u59D8',43962:'\u59FF',43963:'\u59E3',43964:'\u59E8',43965:'\u5A03',43966:'\u59E5',43967:'\u59EA',43968:'\u59DA',43969:'\u59E6',43970:'\u5A01',43971:'\u59FB',43972:'\u5B69',43973:'\u5BA3',43974:'\u5BA6',43975:'\u5BA4',43976:'\u5BA2',43977:'\u5BA5',43978:'\u5C01',43979:'\u5C4E',43980:'\u5C4F',43981:'\u5C4D',43982:'\u5C4B',43983:'\u5CD9',43984:'\u5CD2',43985:'\u5DF7',43986:'\u5E1D',43987:'\u5E25',43988:'\u5E1F',43989:'\u5E7D',43990:'\u5EA0',43991:'\u5EA6',43992:'\u5EFA',43993:'\u5F08',43994:'\u5F2D',43995:'\u5F65',43996:'\u5F88',43997:'\u5F85',43998:'\u5F8A',43999:'\u5F8B',44000:'\u5F87',44001:'\u5F8C',44002:'\u5F89',44003:'\u6012',44004:'\u601D',44005:'\u6020',44006:'\u6025',44007:'\u600E',44008:'\u6028',44009:'\u604D',44010:'\u6070',44011:'\u6068',44012:'\u6062',44013:'\u6046',44014:'\u6043',44015:'\u606C',44016:'\u606B',44017:'\u606A',44018:'\u6064',44019:'\u6241',44020:'\u62DC',44021:'\u6316',44022:'\u6309',44023:'\u62FC',44024:'\u62ED',44025:'\u6301',44026:'\u62EE',44027:'\u62FD',44028:'\u6307',44029:'\u62F1',44030:'\u62F7',44096:'\u62EF',44097:'\u62EC',44098:'\u62FE',44099:'\u62F4',44100:'\u6311',44101:'\u6302',44102:'\u653F',44103:'\u6545',44104:'\u65AB',44105:'\u65BD',44106:'\u65E2',44107:'\u6625',44108:'\u662D',44109:'\u6620',44110:'\u6627',44111:'\u662F',44112:'\u661F',44113:'\u6628',44114:'\u6631',44115:'\u6624',44116:'\u66F7',44117:'\u67FF',44118:'\u67D3',44119:'\u67F1',44120:'\u67D4',44121:'\u67D0',44122:'\u67EC',44123:'\u67B6',44124:'\u67AF',44125:'\u67F5',44126:'\u67E9',44127:'\u67EF',44128:'\u67C4',44129:'\u67D1',44130:'\u67B4',44131:'\u67DA',44132:'\u67E5',44133:'\u67B8',44134:'\u67CF',44135:'\u67DE',44136:'\u67F3',44137:'\u67B0',44138:'\u67D9',44139:'\u67E2',44140:'\u67DD',44141:'\u67D2',44142:'\u6B6A',44143:'\u6B83',44144:'\u6B86',44145:'\u6BB5',44146:'\u6BD2',44147:'\u6BD7',44148:'\u6C1F',44149:'\u6CC9',44150:'\u6D0B',44151:'\u6D32',44152:'\u6D2A',44153:'\u6D41',44154:'\u6D25',44155:'\u6D0C',44156:'\u6D31',44157:'\u6D1E',44158:'\u6D17',44193:'\u6D3B',44194:'\u6D3D',44195:'\u6D3E',44196:'\u6D36',44197:'\u6D1B',44198:'\u6CF5',44199:'\u6D39',44200:'\u6D27',44201:'\u6D38',44202:'\u6D29',44203:'\u6D2E',44204:'\u6D35',44205:'\u6D0E',44206:'\u6D2B',44207:'\u70AB',44208:'\u70BA',44209:'\u70B3',44210:'\u70AC',44211:'\u70AF',44212:'\u70AD',44213:'\u70B8',44214:'\u70AE',44215:'\u70A4',44216:'\u7230',44217:'\u7272',44218:'\u726F',44219:'\u7274',44220:'\u72E9',44221:'\u72E0',44222:'\u72E1',44223:'\u73B7',44224:'\u73CA',44225:'\u73BB',44226:'\u73B2',44227:'\u73CD',44228:'\u73C0',44229:'\u73B3',44230:'\u751A',44231:'\u752D',44232:'\u754F',44233:'\u754C',44234:'\u754E',44235:'\u754B',44236:'\u75AB',44237:'\u75A4',44238:'\u75A5',44239:'\u75A2',44240:'\u75A3',44241:'\u7678',44242:'\u7686',44243:'\u7687',44244:'\u7688',44245:'\u76C8',44246:'\u76C6',44247:'\u76C3',44248:'\u76C5',44249:'\u7701',44250:'\u76F9',44251:'\u76F8',44252:'\u7709',44253:'\u770B',44254:'\u76FE',44255:'\u76FC',44256:'\u7707',44257:'\u77DC',44258:'\u7802',44259:'\u7814',44260:'\u780C',44261:'\u780D',44262:'\u7946',44263:'\u7949',44264:'\u7948',44265:'\u7947',44266:'\u79B9',44267:'\u79BA',44268:'\u79D1',44269:'\u79D2',44270:'\u79CB',44271:'\u7A7F',44272:'\u7A81',44273:'\u7AFF',44274:'\u7AFD',44275:'\u7C7D',44276:'\u7D02',44277:'\u7D05',44278:'\u7D00',44279:'\u7D09',44280:'\u7D07',44281:'\u7D04',44282:'\u7D06',44283:'\u7F38',44284:'\u7F8E',44285:'\u7FBF',44286:'\u8004',44352:'\u8010',44353:'\u800D',44354:'\u8011',44355:'\u8036',44356:'\u80D6',44357:'\u80E5',44358:'\u80DA',44359:'\u80C3',44360:'\u80C4',44361:'\u80CC',44362:'\u80E1',44363:'\u80DB',44364:'\u80CE',44365:'\u80DE',44366:'\u80E4',44367:'\u80DD',44368:'\u81F4',44369:'\u8222',44370:'\u82E7',44371:'\u8303',44372:'\u8305',44373:'\u82E3',44374:'\u82DB',44375:'\u82E6',44376:'\u8304',44377:'\u82E5',44378:'\u8302',44379:'\u8309',44380:'\u82D2',44381:'\u82D7',44382:'\u82F1',44383:'\u8301',44384:'\u82DC',44385:'\u82D4',44386:'\u82D1',44387:'\u82DE',44388:'\u82D3',44389:'\u82DF',44390:'\u82EF',44391:'\u8306',44392:'\u8650',44393:'\u8679',44394:'\u867B',44395:'\u867A',44396:'\u884D',44397:'\u886B',44398:'\u8981',44399:'\u89D4',44400:'\u8A08',44401:'\u8A02',44402:'\u8A03',44403:'\u8C9E',44404:'\u8CA0',44405:'\u8D74',44406:'\u8D73',44407:'\u8DB4',44408:'\u8ECD',44409:'\u8ECC',44410:'\u8FF0',44411:'\u8FE6',44412:'\u8FE2',44413:'\u8FEA',44414:'\u8FE5',44449:'\u8FED',44450:'\u8FEB',44451:'\u8FE4',44452:'\u8FE8',44453:'\u90CA',44454:'\u90CE',44455:'\u90C1',44456:'\u90C3',44457:'\u914B',44458:'\u914A',44459:'\u91CD',44460:'\u9582',44461:'\u9650',44462:'\u964B',44463:'\u964C',44464:'\u964D',44465:'\u9762',44466:'\u9769',44467:'\u97CB',44468:'\u97ED',44469:'\u97F3',44470:'\u9801',44471:'\u98A8',44472:'\u98DB',44473:'\u98DF',44474:'\u9996',44475:'\u9999',44476:'\u4E58',44477:'\u4EB3',44478:'\u500C',44479:'\u500D',44480:'\u5023',44481:'\u4FEF',44482:'\u5026',44483:'\u5025',44484:'\u4FF8',44485:'\u5029',44486:'\u5016',44487:'\u5006',44488:'\u503C',44489:'\u501F',44490:'\u501A',44491:'\u5012',44492:'\u5011',44493:'\u4FFA',44494:'\u5000',44495:'\u5014',44496:'\u5028',44497:'\u4FF1',44498:'\u5021',44499:'\u500B',44500:'\u5019',44501:'\u5018',44502:'\u4FF3',44503:'\u4FEE',44504:'\u502D',44505:'\u502A',44506:'\u4FFE',44507:'\u502B',44508:'\u5009',44509:'\u517C',44510:'\u51A4',44511:'\u51A5',44512:'\u51A2',44513:'\u51CD',44514:'\u51CC',44515:'\u51C6',44516:'\u51CB',44517:'\u5256',44518:'\u525C',44519:'\u5254',44520:'\u525B',44521:'\u525D',44522:'\u532A',44523:'\u537F',44524:'\u539F',44525:'\u539D',44526:'\u53DF',44527:'\u54E8',44528:'\u5510',44529:'\u5501',44530:'\u5537',44531:'\u54FC',44532:'\u54E5',44533:'\u54F2',44534:'\u5506',44535:'\u54FA',44536:'\u5514',44537:'\u54E9',44538:'\u54ED',44539:'\u54E1',44540:'\u5509',44541:'\u54EE',44542:'\u54EA',44608:'\u54E6',44609:'\u5527',44610:'\u5507',44611:'\u54FD',44612:'\u550F',44613:'\u5703',44614:'\u5704',44615:'\u57C2',44616:'\u57D4',44617:'\u57CB',44618:'\u57C3',44619:'\u5809',44620:'\u590F',44621:'\u5957',44622:'\u5958',44623:'\u595A',44624:'\u5A11',44625:'\u5A18',44626:'\u5A1C',44627:'\u5A1F',44628:'\u5A1B',44629:'\u5A13',44630:'\u59EC',44631:'\u5A20',44632:'\u5A23',44633:'\u5A29',44634:'\u5A25',44635:'\u5A0C',44636:'\u5A09',44637:'\u5B6B',44638:'\u5C58',44639:'\u5BB0',44640:'\u5BB3',44641:'\u5BB6',44642:'\u5BB4',44643:'\u5BAE',44644:'\u5BB5',44645:'\u5BB9',44646:'\u5BB8',44647:'\u5C04',44648:'\u5C51',44649:'\u5C55',44650:'\u5C50',44651:'\u5CED',44652:'\u5CFD',44653:'\u5CFB',44654:'\u5CEA',44655:'\u5CE8',44656:'\u5CF0',44657:'\u5CF6',44658:'\u5D01',44659:'\u5CF4',44660:'\u5DEE',44661:'\u5E2D',44662:'\u5E2B',44663:'\u5EAB',44664:'\u5EAD',44665:'\u5EA7',44666:'\u5F31',44667:'\u5F92',44668:'\u5F91',44669:'\u5F90',44670:'\u6059',44705:'\u6063',44706:'\u6065',44707:'\u6050',44708:'\u6055',44709:'\u606D',44710:'\u6069',44711:'\u606F',44712:'\u6084',44713:'\u609F',44714:'\u609A',44715:'\u608D',44716:'\u6094',44717:'\u608C',44718:'\u6085',44719:'\u6096',44720:'\u6247',44721:'\u62F3',44722:'\u6308',44723:'\u62FF',44724:'\u634E',44725:'\u633E',44726:'\u632F',44727:'\u6355',44728:'\u6342',44729:'\u6346',44730:'\u634F',44731:'\u6349',44732:'\u633A',44733:'\u6350',44734:'\u633D',44735:'\u632A',44736:'\u632B',44737:'\u6328',44738:'\u634D',44739:'\u634C',44740:'\u6548',44741:'\u6549',44742:'\u6599',44743:'\u65C1',44744:'\u65C5',44745:'\u6642',44746:'\u6649',44747:'\u664F',44748:'\u6643',44749:'\u6652',44750:'\u664C',44751:'\u6645',44752:'\u6641',44753:'\u66F8',44754:'\u6714',44755:'\u6715',44756:'\u6717',44757:'\u6821',44758:'\u6838',44759:'\u6848',44760:'\u6846',44761:'\u6853',44762:'\u6839',44763:'\u6842',44764:'\u6854',44765:'\u6829',44766:'\u68B3',44767:'\u6817',44768:'\u684C',44769:'\u6851',44770:'\u683D',44771:'\u67F4',44772:'\u6850',44773:'\u6840',44774:'\u683C',44775:'\u6843',44776:'\u682A',44777:'\u6845',44778:'\u6813',44779:'\u6818',44780:'\u6841',44781:'\u6B8A',44782:'\u6B89',44783:'\u6BB7',44784:'\u6C23',44785:'\u6C27',44786:'\u6C28',44787:'\u6C26',44788:'\u6C24',44789:'\u6CF0',44790:'\u6D6A',44791:'\u6D95',44792:'\u6D88',44793:'\u6D87',44794:'\u6D66',44795:'\u6D78',44796:'\u6D77',44797:'\u6D59',44798:'\u6D93',44864:'\u6D6C',44865:'\u6D89',44866:'\u6D6E',44867:'\u6D5A',44868:'\u6D74',44869:'\u6D69',44870:'\u6D8C',44871:'\u6D8A',44872:'\u6D79',44873:'\u6D85',44874:'\u6D65',44875:'\u6D94',44876:'\u70CA',44877:'\u70D8',44878:'\u70E4',44879:'\u70D9',44880:'\u70C8',44881:'\u70CF',44882:'\u7239',44883:'\u7279',44884:'\u72FC',44885:'\u72F9',44886:'\u72FD',44887:'\u72F8',44888:'\u72F7',44889:'\u7386',44890:'\u73ED',44891:'\u7409',44892:'\u73EE',44893:'\u73E0',44894:'\u73EA',44895:'\u73DE',44896:'\u7554',44897:'\u755D',44898:'\u755C',44899:'\u755A',44900:'\u7559',44901:'\u75BE',44902:'\u75C5',44903:'\u75C7',44904:'\u75B2',44905:'\u75B3',44906:'\u75BD',44907:'\u75BC',44908:'\u75B9',44909:'\u75C2',44910:'\u75B8',44911:'\u768B',44912:'\u76B0',44913:'\u76CA',44914:'\u76CD',44915:'\u76CE',44916:'\u7729',44917:'\u771F',44918:'\u7720',44919:'\u7728',44920:'\u77E9',44921:'\u7830',44922:'\u7827',44923:'\u7838',44924:'\u781D',44925:'\u7834',44926:'\u7837',44961:'\u7825',44962:'\u782D',44963:'\u7820',44964:'\u781F',44965:'\u7832',44966:'\u7955',44967:'\u7950',44968:'\u7960',44969:'\u795F',44970:'\u7956',44971:'\u795E',44972:'\u795D',44973:'\u7957',44974:'\u795A',44975:'\u79E4',44976:'\u79E3',44977:'\u79E7',44978:'\u79DF',44979:'\u79E6',44980:'\u79E9',44981:'\u79D8',44982:'\u7A84',44983:'\u7A88',44984:'\u7AD9',44985:'\u7B06',44986:'\u7B11',44987:'\u7C89',44988:'\u7D21',44989:'\u7D17',44990:'\u7D0B',44991:'\u7D0A',44992:'\u7D20',44993:'\u7D22',44994:'\u7D14',44995:'\u7D10',44996:'\u7D15',44997:'\u7D1A',44998:'\u7D1C',44999:'\u7D0D',45000:'\u7D19',45001:'\u7D1B',45002:'\u7F3A',45003:'\u7F5F',45004:'\u7F94',45005:'\u7FC5',45006:'\u7FC1',45007:'\u8006',45008:'\u8018',45009:'\u8015',45010:'\u8019',45011:'\u8017',45012:'\u803D',45013:'\u803F',45014:'\u80F1',45015:'\u8102',45016:'\u80F0',45017:'\u8105',45018:'\u80ED',45019:'\u80F4',45020:'\u8106',45021:'\u80F8',45022:'\u80F3',45023:'\u8108',45024:'\u80FD',45025:'\u810A',45026:'\u80FC',45027:'\u80EF',45028:'\u81ED',45029:'\u81EC',45030:'\u8200',45031:'\u8210',45032:'\u822A',45033:'\u822B',45034:'\u8228',45035:'\u822C',45036:'\u82BB',45037:'\u832B',45038:'\u8352',45039:'\u8354',45040:'\u834A',45041:'\u8338',45042:'\u8350',45043:'\u8349',45044:'\u8335',45045:'\u8334',45046:'\u834F',45047:'\u8332',45048:'\u8339',45049:'\u8336',45050:'\u8317',45051:'\u8340',45052:'\u8331',45053:'\u8328',45054:'\u8343',45120:'\u8654',45121:'\u868A',45122:'\u86AA',45123:'\u8693',45124:'\u86A4',45125:'\u86A9',45126:'\u868C',45127:'\u86A3',45128:'\u869C',45129:'\u8870',45130:'\u8877',45131:'\u8881',45132:'\u8882',45133:'\u887D',45134:'\u8879',45135:'\u8A18',45136:'\u8A10',45137:'\u8A0E',45138:'\u8A0C',45139:'\u8A15',45140:'\u8A0A',45141:'\u8A17',45142:'\u8A13',45143:'\u8A16',45144:'\u8A0F',45145:'\u8A11',45146:'\u8C48',45147:'\u8C7A',45148:'\u8C79',45149:'\u8CA1',45150:'\u8CA2',45151:'\u8D77',45152:'\u8EAC',45153:'\u8ED2',45154:'\u8ED4',45155:'\u8ECF',45156:'\u8FB1',45157:'\u9001',45158:'\u9006',45159:'\u8FF7',45160:'\u9000',45161:'\u8FFA',45162:'\u8FF4',45163:'\u9003',45164:'\u8FFD',45165:'\u9005',45166:'\u8FF8',45167:'\u9095',45168:'\u90E1',45169:'\u90DD',45170:'\u90E2',45171:'\u9152',45172:'\u914D',45173:'\u914C',45174:'\u91D8',45175:'\u91DD',45176:'\u91D7',45177:'\u91DC',45178:'\u91D9',45179:'\u9583',45180:'\u9662',45181:'\u9663',45182:'\u9661',45217:'\u965B',45218:'\u965D',45219:'\u9664',45220:'\u9658',45221:'\u965E',45222:'\u96BB',45223:'\u98E2',45224:'\u99AC',45225:'\u9AA8',45226:'\u9AD8',45227:'\u9B25',45228:'\u9B32',45229:'\u9B3C',45230:'\u4E7E',45231:'\u507A',45232:'\u507D',45233:'\u505C',45234:'\u5047',45235:'\u5043',45236:'\u504C',45237:'\u505A',45238:'\u5049',45239:'\u5065',45240:'\u5076',45241:'\u504E',45242:'\u5055',45243:'\u5075',45244:'\u5074',45245:'\u5077',45246:'\u504F',45247:'\u500F',45248:'\u506F',45249:'\u506D',45250:'\u515C',45251:'\u5195',45252:'\u51F0',45253:'\u526A',45254:'\u526F',45255:'\u52D2',45256:'\u52D9',45257:'\u52D8',45258:'\u52D5',45259:'\u5310',45260:'\u530F',45261:'\u5319',45262:'\u533F',45263:'\u5340',45264:'\u533E',45265:'\u53C3',45266:'\u66FC',45267:'\u5546',45268:'\u556A',45269:'\u5566',45270:'\u5544',45271:'\u555E',45272:'\u5561',45273:'\u5543',45274:'\u554A',45275:'\u5531',45276:'\u5556',45277:'\u554F',45278:'\u5555',45279:'\u552F',45280:'\u5564',45281:'\u5538',45282:'\u552E',45283:'\u555C',45284:'\u552C',45285:'\u5563',45286:'\u5533',45287:'\u5541',45288:'\u5557',45289:'\u5708',45290:'\u570B',45291:'\u5709',45292:'\u57DF',45293:'\u5805',45294:'\u580A',45295:'\u5806',45296:'\u57E0',45297:'\u57E4',45298:'\u57FA',45299:'\u5802',45300:'\u5835',45301:'\u57F7',45302:'\u57F9',45303:'\u5920',45304:'\u5962',45305:'\u5A36',45306:'\u5A41',45307:'\u5A49',45308:'\u5A66',45309:'\u5A6A',45310:'\u5A40',45376:'\u5A3C',45377:'\u5A62',45378:'\u5A5A',45379:'\u5A46',45380:'\u5A4A',45381:'\u5B70',45382:'\u5BC7',45383:'\u5BC5',45384:'\u5BC4',45385:'\u5BC2',45386:'\u5BBF',45387:'\u5BC6',45388:'\u5C09',45389:'\u5C08',45390:'\u5C07',45391:'\u5C60',45392:'\u5C5C',45393:'\u5C5D',45394:'\u5D07',45395:'\u5D06',45396:'\u5D0E',45397:'\u5D1B',45398:'\u5D16',45399:'\u5D22',45400:'\u5D11',45401:'\u5D29',45402:'\u5D14',45403:'\u5D19',45404:'\u5D24',45405:'\u5D27',45406:'\u5D17',45407:'\u5DE2',45408:'\u5E38',45409:'\u5E36',45410:'\u5E33',45411:'\u5E37',45412:'\u5EB7',45413:'\u5EB8',45414:'\u5EB6',45415:'\u5EB5',45416:'\u5EBE',45417:'\u5F35',45418:'\u5F37',45419:'\u5F57',45420:'\u5F6C',45421:'\u5F69',45422:'\u5F6B',45423:'\u5F97',45424:'\u5F99',45425:'\u5F9E',45426:'\u5F98',45427:'\u5FA1',45428:'\u5FA0',45429:'\u5F9C',45430:'\u607F',45431:'\u60A3',45432:'\u6089',45433:'\u60A0',45434:'\u60A8',45435:'\u60CB',45436:'\u60B4',45437:'\u60E6',45438:'\u60BD',45473:'\u60C5',45474:'\u60BB',45475:'\u60B5',45476:'\u60DC',45477:'\u60BC',45478:'\u60D8',45479:'\u60D5',45480:'\u60C6',45481:'\u60DF',45482:'\u60B8',45483:'\u60DA',45484:'\u60C7',45485:'\u621A',45486:'\u621B',45487:'\u6248',45488:'\u63A0',45489:'\u63A7',45490:'\u6372',45491:'\u6396',45492:'\u63A2',45493:'\u63A5',45494:'\u6377',45495:'\u6367',45496:'\u6398',45497:'\u63AA',45498:'\u6371',45499:'\u63A9',45500:'\u6389',45501:'\u6383',45502:'\u639B',45503:'\u636B',45504:'\u63A8',45505:'\u6384',45506:'\u6388',45507:'\u6399',45508:'\u63A1',45509:'\u63AC',45510:'\u6392',45511:'\u638F',45512:'\u6380',45513:'\u637B',45514:'\u6369',45515:'\u6368',45516:'\u637A',45517:'\u655D',45518:'\u6556',45519:'\u6551',45520:'\u6559',45521:'\u6557',45522:'\u555F',45523:'\u654F',45524:'\u6558',45525:'\u6555',45526:'\u6554',45527:'\u659C',45528:'\u659B',45529:'\u65AC',45530:'\u65CF',45531:'\u65CB',45532:'\u65CC',45533:'\u65CE',45534:'\u665D',45535:'\u665A',45536:'\u6664',45537:'\u6668',45538:'\u6666',45539:'\u665E',45540:'\u66F9',45541:'\u52D7',45542:'\u671B',45543:'\u6881',45544:'\u68AF',45545:'\u68A2',45546:'\u6893',45547:'\u68B5',45548:'\u687F',45549:'\u6876',45550:'\u68B1',45551:'\u68A7',45552:'\u6897',45553:'\u68B0',45554:'\u6883',45555:'\u68C4',45556:'\u68AD',45557:'\u6886',45558:'\u6885',45559:'\u6894',45560:'\u689D',45561:'\u68A8',45562:'\u689F',45563:'\u68A1',45564:'\u6882',45565:'\u6B32',45566:'\u6BBA',45632:'\u6BEB',45633:'\u6BEC',45634:'\u6C2B',45635:'\u6D8E',45636:'\u6DBC',45637:'\u6DF3',45638:'\u6DD9',45639:'\u6DB2',45640:'\u6DE1',45641:'\u6DCC',45642:'\u6DE4',45643:'\u6DFB',45644:'\u6DFA',45645:'\u6E05',45646:'\u6DC7',45647:'\u6DCB',45648:'\u6DAF',45649:'\u6DD1',45650:'\u6DAE',45651:'\u6DDE',45652:'\u6DF9',45653:'\u6DB8',45654:'\u6DF7',45655:'\u6DF5',45656:'\u6DC5',45657:'\u6DD2',45658:'\u6E1A',45659:'\u6DB5',45660:'\u6DDA',45661:'\u6DEB',45662:'\u6DD8',45663:'\u6DEA',45664:'\u6DF1',45665:'\u6DEE',45666:'\u6DE8',45667:'\u6DC6',45668:'\u6DC4',45669:'\u6DAA',45670:'\u6DEC',45671:'\u6DBF',45672:'\u6DE6',45673:'\u70F9',45674:'\u7109',45675:'\u710A',45676:'\u70FD',45677:'\u70EF',45678:'\u723D',45679:'\u727D',45680:'\u7281',45681:'\u731C',45682:'\u731B',45683:'\u7316',45684:'\u7313',45685:'\u7319',45686:'\u7387',45687:'\u7405',45688:'\u740A',45689:'\u7403',45690:'\u7406',45691:'\u73FE',45692:'\u740D',45693:'\u74E0',45694:'\u74F6',45729:'\u74F7',45730:'\u751C',45731:'\u7522',45732:'\u7565',45733:'\u7566',45734:'\u7562',45735:'\u7570',45736:'\u758F',45737:'\u75D4',45738:'\u75D5',45739:'\u75B5',45740:'\u75CA',45741:'\u75CD',45742:'\u768E',45743:'\u76D4',45744:'\u76D2',45745:'\u76DB',45746:'\u7737',45747:'\u773E',45748:'\u773C',45749:'\u7736',45750:'\u7738',45751:'\u773A',45752:'\u786B',45753:'\u7843',45754:'\u784E',45755:'\u7965',45756:'\u7968',45757:'\u796D',45758:'\u79FB',45759:'\u7A92',45760:'\u7A95',45761:'\u7B20',45762:'\u7B28',45763:'\u7B1B',45764:'\u7B2C',45765:'\u7B26',45766:'\u7B19',45767:'\u7B1E',45768:'\u7B2E',45769:'\u7C92',45770:'\u7C97',45771:'\u7C95',45772:'\u7D46',45773:'\u7D43',45774:'\u7D71',45775:'\u7D2E',45776:'\u7D39',45777:'\u7D3C',45778:'\u7D40',45779:'\u7D30',45780:'\u7D33',45781:'\u7D44',45782:'\u7D2F',45783:'\u7D42',45784:'\u7D32',45785:'\u7D31',45786:'\u7F3D',45787:'\u7F9E',45788:'\u7F9A',45789:'\u7FCC',45790:'\u7FCE',45791:'\u7FD2',45792:'\u801C',45793:'\u804A',45794:'\u8046',45795:'\u812F',45796:'\u8116',45797:'\u8123',45798:'\u812B',45799:'\u8129',45800:'\u8130',45801:'\u8124',45802:'\u8202',45803:'\u8235',45804:'\u8237',45805:'\u8236',45806:'\u8239',45807:'\u838E',45808:'\u839E',45809:'\u8398',45810:'\u8378',45811:'\u83A2',45812:'\u8396',45813:'\u83BD',45814:'\u83AB',45815:'\u8392',45816:'\u838A',45817:'\u8393',45818:'\u8389',45819:'\u83A0',45820:'\u8377',45821:'\u837B',45822:'\u837C',45888:'\u8386',45889:'\u83A7',45890:'\u8655',45891:'\u5F6A',45892:'\u86C7',45893:'\u86C0',45894:'\u86B6',45895:'\u86C4',45896:'\u86B5',45897:'\u86C6',45898:'\u86CB',45899:'\u86B1',45900:'\u86AF',45901:'\u86C9',45902:'\u8853',45903:'\u889E',45904:'\u8888',45905:'\u88AB',45906:'\u8892',45907:'\u8896',45908:'\u888D',45909:'\u888B',45910:'\u8993',45911:'\u898F',45912:'\u8A2A',45913:'\u8A1D',45914:'\u8A23',45915:'\u8A25',45916:'\u8A31',45917:'\u8A2D',45918:'\u8A1F',45919:'\u8A1B',45920:'\u8A22',45921:'\u8C49',45922:'\u8C5A',45923:'\u8CA9',45924:'\u8CAC',45925:'\u8CAB',45926:'\u8CA8',45927:'\u8CAA',45928:'\u8CA7',45929:'\u8D67',45930:'\u8D66',45931:'\u8DBE',45932:'\u8DBA',45933:'\u8EDB',45934:'\u8EDF',45935:'\u9019',45936:'\u900D',45937:'\u901A',45938:'\u9017',45939:'\u9023',45940:'\u901F',45941:'\u901D',45942:'\u9010',45943:'\u9015',45944:'\u901E',45945:'\u9020',45946:'\u900F',45947:'\u9022',45948:'\u9016',45949:'\u901B',45950:'\u9014',45985:'\u90E8',45986:'\u90ED',45987:'\u90FD',45988:'\u9157',45989:'\u91CE',45990:'\u91F5',45991:'\u91E6',45992:'\u91E3',45993:'\u91E7',45994:'\u91ED',45995:'\u91E9',45996:'\u9589',45997:'\u966A',45998:'\u9675',45999:'\u9673',46000:'\u9678',46001:'\u9670',46002:'\u9674',46003:'\u9676',46004:'\u9677',46005:'\u966C',46006:'\u96C0',46007:'\u96EA',46008:'\u96E9',46009:'\u7AE0',46010:'\u7ADF',46011:'\u9802',46012:'\u9803',46013:'\u9B5A',46014:'\u9CE5',46015:'\u9E75',46016:'\u9E7F',46017:'\u9EA5',46018:'\u9EBB',46019:'\u50A2',46020:'\u508D',46021:'\u5085',46022:'\u5099',46023:'\u5091',46024:'\u5080',46025:'\u5096',46026:'\u5098',46027:'\u509A',46028:'\u6700',46029:'\u51F1',46030:'\u5272',46031:'\u5274',46032:'\u5275',46033:'\u5269',46034:'\u52DE',46035:'\u52DD',46036:'\u52DB',46037:'\u535A',46038:'\u53A5',46039:'\u557B',46040:'\u5580',46041:'\u55A7',46042:'\u557C',46043:'\u558A',46044:'\u559D',46045:'\u5598',46046:'\u5582',46047:'\u559C',46048:'\u55AA',46049:'\u5594',46050:'\u5587',46051:'\u558B',46052:'\u5583',46053:'\u55B3',46054:'\u55AE',46055:'\u559F',46056:'\u553E',46057:'\u55B2',46058:'\u559A',46059:'\u55BB',46060:'\u55AC',46061:'\u55B1',46062:'\u557E',46063:'\u5589',46064:'\u55AB',46065:'\u5599',46066:'\u570D',46067:'\u582F',46068:'\u582A',46069:'\u5834',46070:'\u5824',46071:'\u5830',46072:'\u5831',46073:'\u5821',46074:'\u581D',46075:'\u5820',46076:'\u58F9',46077:'\u58FA',46078:'\u5960',46144:'\u5A77',46145:'\u5A9A',46146:'\u5A7F',46147:'\u5A92',46148:'\u5A9B',46149:'\u5AA7',46150:'\u5B73',46151:'\u5B71',46152:'\u5BD2',46153:'\u5BCC',46154:'\u5BD3',46155:'\u5BD0',46156:'\u5C0A',46157:'\u5C0B',46158:'\u5C31',46159:'\u5D4C',46160:'\u5D50',46161:'\u5D34',46162:'\u5D47',46163:'\u5DFD',46164:'\u5E45',46165:'\u5E3D',46166:'\u5E40',46167:'\u5E43',46168:'\u5E7E',46169:'\u5ECA',46170:'\u5EC1',46171:'\u5EC2',46172:'\u5EC4',46173:'\u5F3C',46174:'\u5F6D',46175:'\u5FA9',46176:'\u5FAA',46177:'\u5FA8',46178:'\u60D1',46179:'\u60E1',46180:'\u60B2',46181:'\u60B6',46182:'\u60E0',46183:'\u611C',46184:'\u6123',46185:'\u60FA',46186:'\u6115',46187:'\u60F0',46188:'\u60FB',46189:'\u60F4',46190:'\u6168',46191:'\u60F1',46192:'\u610E',46193:'\u60F6',46194:'\u6109',46195:'\u6100',46196:'\u6112',46197:'\u621F',46198:'\u6249',46199:'\u63A3',46200:'\u638C',46201:'\u63CF',46202:'\u63C0',46203:'\u63E9',46204:'\u63C9',46205:'\u63C6',46206:'\u63CD',46241:'\u63D2',46242:'\u63E3',46243:'\u63D0',46244:'\u63E1',46245:'\u63D6',46246:'\u63ED',46247:'\u63EE',46248:'\u6376',46249:'\u63F4',46250:'\u63EA',46251:'\u63DB',46252:'\u6452',46253:'\u63DA',46254:'\u63F9',46255:'\u655E',46256:'\u6566',46257:'\u6562',46258:'\u6563',46259:'\u6591',46260:'\u6590',46261:'\u65AF',46262:'\u666E',46263:'\u6670',46264:'\u6674',46265:'\u6676',46266:'\u666F',46267:'\u6691',46268:'\u667A',46269:'\u667E',46270:'\u6677',46271:'\u66FE',46272:'\u66FF',46273:'\u671F',46274:'\u671D',46275:'\u68FA',46276:'\u68D5',46277:'\u68E0',46278:'\u68D8',46279:'\u68D7',46280:'\u6905',46281:'\u68DF',46282:'\u68F5',46283:'\u68EE',46284:'\u68E7',46285:'\u68F9',46286:'\u68D2',46287:'\u68F2',46288:'\u68E3',46289:'\u68CB',46290:'\u68CD',46291:'\u690D',46292:'\u6912',46293:'\u690E',46294:'\u68C9',46295:'\u68DA',46296:'\u696E',46297:'\u68FB',46298:'\u6B3E',46299:'\u6B3A',46300:'\u6B3D',46301:'\u6B98',46302:'\u6B96',46303:'\u6BBC',46304:'\u6BEF',46305:'\u6C2E',46306:'\u6C2F',46307:'\u6C2C',46308:'\u6E2F',46309:'\u6E38',46310:'\u6E54',46311:'\u6E21',46312:'\u6E32',46313:'\u6E67',46314:'\u6E4A',46315:'\u6E20',46316:'\u6E25',46317:'\u6E23',46318:'\u6E1B',46319:'\u6E5B',46320:'\u6E58',46321:'\u6E24',46322:'\u6E56',46323:'\u6E6E',46324:'\u6E2D',46325:'\u6E26',46326:'\u6E6F',46327:'\u6E34',46328:'\u6E4D',46329:'\u6E3A',46330:'\u6E2C',46331:'\u6E43',46332:'\u6E1D',46333:'\u6E3E',46334:'\u6ECB',46400:'\u6E89',46401:'\u6E19',46402:'\u6E4E',46403:'\u6E63',46404:'\u6E44',46405:'\u6E72',46406:'\u6E69',46407:'\u6E5F',46408:'\u7119',46409:'\u711A',46410:'\u7126',46411:'\u7130',46412:'\u7121',46413:'\u7136',46414:'\u716E',46415:'\u711C',46416:'\u724C',46417:'\u7284',46418:'\u7280',46419:'\u7336',46420:'\u7325',46421:'\u7334',46422:'\u7329',46423:'\u743A',46424:'\u742A',46425:'\u7433',46426:'\u7422',46427:'\u7425',46428:'\u7435',46429:'\u7436',46430:'\u7434',46431:'\u742F',46432:'\u741B',46433:'\u7426',46434:'\u7428',46435:'\u7525',46436:'\u7526',46437:'\u756B',46438:'\u756A',46439:'\u75E2',46440:'\u75DB',46441:'\u75E3',46442:'\u75D9',46443:'\u75D8',46444:'\u75DE',46445:'\u75E0',46446:'\u767B',46447:'\u767C',46448:'\u7696',46449:'\u7693',46450:'\u76B4',46451:'\u76DC',46452:'\u774F',46453:'\u77ED',46454:'\u785D',46455:'\u786C',46456:'\u786F',46457:'\u7A0D',46458:'\u7A08',46459:'\u7A0B',46460:'\u7A05',46461:'\u7A00',46462:'\u7A98',46497:'\u7A97',46498:'\u7A96',46499:'\u7AE5',46500:'\u7AE3',46501:'\u7B49',46502:'\u7B56',46503:'\u7B46',46504:'\u7B50',46505:'\u7B52',46506:'\u7B54',46507:'\u7B4D',46508:'\u7B4B',46509:'\u7B4F',46510:'\u7B51',46511:'\u7C9F',46512:'\u7CA5',46513:'\u7D5E',46514:'\u7D50',46515:'\u7D68',46516:'\u7D55',46517:'\u7D2B',46518:'\u7D6E',46519:'\u7D72',46520:'\u7D61',46521:'\u7D66',46522:'\u7D62',46523:'\u7D70',46524:'\u7D73',46525:'\u5584',46526:'\u7FD4',46527:'\u7FD5',46528:'\u800B',46529:'\u8052',46530:'\u8085',46531:'\u8155',46532:'\u8154',46533:'\u814B',46534:'\u8151',46535:'\u814E',46536:'\u8139',46537:'\u8146',46538:'\u813E',46539:'\u814C',46540:'\u8153',46541:'\u8174',46542:'\u8212',46543:'\u821C',46544:'\u83E9',46545:'\u8403',46546:'\u83F8',46547:'\u840D',46548:'\u83E0',46549:'\u83C5',46550:'\u840B',46551:'\u83C1',46552:'\u83EF',46553:'\u83F1',46554:'\u83F4',46555:'\u8457',46556:'\u840A',46557:'\u83F0',46558:'\u840C',46559:'\u83CC',46560:'\u83FD',46561:'\u83F2',46562:'\u83CA',46563:'\u8438',46564:'\u840E',46565:'\u8404',46566:'\u83DC',46567:'\u8407',46568:'\u83D4',46569:'\u83DF',46570:'\u865B',46571:'\u86DF',46572:'\u86D9',46573:'\u86ED',46574:'\u86D4',46575:'\u86DB',46576:'\u86E4',46577:'\u86D0',46578:'\u86DE',46579:'\u8857',46580:'\u88C1',46581:'\u88C2',46582:'\u88B1',46583:'\u8983',46584:'\u8996',46585:'\u8A3B',46586:'\u8A60',46587:'\u8A55',46588:'\u8A5E',46589:'\u8A3C',46590:'\u8A41',46656:'\u8A54',46657:'\u8A5B',46658:'\u8A50',46659:'\u8A46',46660:'\u8A34',46661:'\u8A3A',46662:'\u8A36',46663:'\u8A56',46664:'\u8C61',46665:'\u8C82',46666:'\u8CAF',46667:'\u8CBC',46668:'\u8CB3',46669:'\u8CBD',46670:'\u8CC1',46671:'\u8CBB',46672:'\u8CC0',46673:'\u8CB4',46674:'\u8CB7',46675:'\u8CB6',46676:'\u8CBF',46677:'\u8CB8',46678:'\u8D8A',46679:'\u8D85',46680:'\u8D81',46681:'\u8DCE',46682:'\u8DDD',46683:'\u8DCB',46684:'\u8DDA',46685:'\u8DD1',46686:'\u8DCC',46687:'\u8DDB',46688:'\u8DC6',46689:'\u8EFB',46690:'\u8EF8',46691:'\u8EFC',46692:'\u8F9C',46693:'\u902E',46694:'\u9035',46695:'\u9031',46696:'\u9038',46697:'\u9032',46698:'\u9036',46699:'\u9102',46700:'\u90F5',46701:'\u9109',46702:'\u90FE',46703:'\u9163',46704:'\u9165',46705:'\u91CF',46706:'\u9214',46707:'\u9215',46708:'\u9223',46709:'\u9209',46710:'\u921E',46711:'\u920D',46712:'\u9210',46713:'\u9207',46714:'\u9211',46715:'\u9594',46716:'\u958F',46717:'\u958B',46718:'\u9591',46753:'\u9593',46754:'\u9592',46755:'\u958E',46756:'\u968A',46757:'\u968E',46758:'\u968B',46759:'\u967D',46760:'\u9685',46761:'\u9686',46762:'\u968D',46763:'\u9672',46764:'\u9684',46765:'\u96C1',46766:'\u96C5',46767:'\u96C4',46768:'\u96C6',46769:'\u96C7',46770:'\u96EF',46771:'\u96F2',46772:'\u97CC',46773:'\u9805',46774:'\u9806',46775:'\u9808',46776:'\u98E7',46777:'\u98EA',46778:'\u98EF',46779:'\u98E9',46780:'\u98F2',46781:'\u98ED',46782:'\u99AE',46783:'\u99AD',46784:'\u9EC3',46785:'\u9ECD',46786:'\u9ED1',46787:'\u4E82',46788:'\u50AD',46789:'\u50B5',46790:'\u50B2',46791:'\u50B3',46792:'\u50C5',46793:'\u50BE',46794:'\u50AC',46795:'\u50B7',46796:'\u50BB',46797:'\u50AF',46798:'\u50C7',46799:'\u527F',46800:'\u5277',46801:'\u527D',46802:'\u52DF',46803:'\u52E6',46804:'\u52E4',46805:'\u52E2',46806:'\u52E3',46807:'\u532F',46808:'\u55DF',46809:'\u55E8',46810:'\u55D3',46811:'\u55E6',46812:'\u55CE',46813:'\u55DC',46814:'\u55C7',46815:'\u55D1',46816:'\u55E3',46817:'\u55E4',46818:'\u55EF',46819:'\u55DA',46820:'\u55E1',46821:'\u55C5',46822:'\u55C6',46823:'\u55E5',46824:'\u55C9',46825:'\u5712',46826:'\u5713',46827:'\u585E',46828:'\u5851',46829:'\u5858',46830:'\u5857',46831:'\u585A',46832:'\u5854',46833:'\u586B',46834:'\u584C',46835:'\u586D',46836:'\u584A',46837:'\u5862',46838:'\u5852',46839:'\u584B',46840:'\u5967',46841:'\u5AC1',46842:'\u5AC9',46843:'\u5ACC',46844:'\u5ABE',46845:'\u5ABD',46846:'\u5ABC',46912:'\u5AB3',46913:'\u5AC2',46914:'\u5AB2',46915:'\u5D69',46916:'\u5D6F',46917:'\u5E4C',46918:'\u5E79',46919:'\u5EC9',46920:'\u5EC8',46921:'\u5F12',46922:'\u5F59',46923:'\u5FAC',46924:'\u5FAE',46925:'\u611A',46926:'\u610F',46927:'\u6148',46928:'\u611F',46929:'\u60F3',46930:'\u611B',46931:'\u60F9',46932:'\u6101',46933:'\u6108',46934:'\u614E',46935:'\u614C',46936:'\u6144',46937:'\u614D',46938:'\u613E',46939:'\u6134',46940:'\u6127',46941:'\u610D',46942:'\u6106',46943:'\u6137',46944:'\u6221',46945:'\u6222',46946:'\u6413',46947:'\u643E',46948:'\u641E',46949:'\u642A',46950:'\u642D',46951:'\u643D',46952:'\u642C',46953:'\u640F',46954:'\u641C',46955:'\u6414',46956:'\u640D',46957:'\u6436',46958:'\u6416',46959:'\u6417',46960:'\u6406',46961:'\u656C',46962:'\u659F',46963:'\u65B0',46964:'\u6697',46965:'\u6689',46966:'\u6687',46967:'\u6688',46968:'\u6696',46969:'\u6684',46970:'\u6698',46971:'\u668D',46972:'\u6703',46973:'\u6994',46974:'\u696D',47009:'\u695A',47010:'\u6977',47011:'\u6960',47012:'\u6954',47013:'\u6975',47014:'\u6930',47015:'\u6982',47016:'\u694A',47017:'\u6968',47018:'\u696B',47019:'\u695E',47020:'\u6953',47021:'\u6979',47022:'\u6986',47023:'\u695D',47024:'\u6963',47025:'\u695B',47026:'\u6B47',47027:'\u6B72',47028:'\u6BC0',47029:'\u6BBF',47030:'\u6BD3',47031:'\u6BFD',47032:'\u6EA2',47033:'\u6EAF',47034:'\u6ED3',47035:'\u6EB6',47036:'\u6EC2',47037:'\u6E90',47038:'\u6E9D',47039:'\u6EC7',47040:'\u6EC5',47041:'\u6EA5',47042:'\u6E98',47043:'\u6EBC',47044:'\u6EBA',47045:'\u6EAB',47046:'\u6ED1',47047:'\u6E96',47048:'\u6E9C',47049:'\u6EC4',47050:'\u6ED4',47051:'\u6EAA',47052:'\u6EA7',47053:'\u6EB4',47054:'\u714E',47055:'\u7159',47056:'\u7169',47057:'\u7164',47058:'\u7149',47059:'\u7167',47060:'\u715C',47061:'\u716C',47062:'\u7166',47063:'\u714C',47064:'\u7165',47065:'\u715E',47066:'\u7146',47067:'\u7168',47068:'\u7156',47069:'\u723A',47070:'\u7252',47071:'\u7337',47072:'\u7345',47073:'\u733F',47074:'\u733E',47075:'\u746F',47076:'\u745A',47077:'\u7455',47078:'\u745F',47079:'\u745E',47080:'\u7441',47081:'\u743F',47082:'\u7459',47083:'\u745B',47084:'\u745C',47085:'\u7576',47086:'\u7578',47087:'\u7600',47088:'\u75F0',47089:'\u7601',47090:'\u75F2',47091:'\u75F1',47092:'\u75FA',47093:'\u75FF',47094:'\u75F4',47095:'\u75F3',47096:'\u76DE',47097:'\u76DF',47098:'\u775B',47099:'\u776B',47100:'\u7766',47101:'\u775E',47102:'\u7763',47168:'\u7779',47169:'\u776A',47170:'\u776C',47171:'\u775C',47172:'\u7765',47173:'\u7768',47174:'\u7762',47175:'\u77EE',47176:'\u788E',47177:'\u78B0',47178:'\u7897',47179:'\u7898',47180:'\u788C',47181:'\u7889',47182:'\u787C',47183:'\u7891',47184:'\u7893',47185:'\u787F',47186:'\u797A',47187:'\u797F',47188:'\u7981',47189:'\u842C',47190:'\u79BD',47191:'\u7A1C',47192:'\u7A1A',47193:'\u7A20',47194:'\u7A14',47195:'\u7A1F',47196:'\u7A1E',47197:'\u7A9F',47198:'\u7AA0',47199:'\u7B77',47200:'\u7BC0',47201:'\u7B60',47202:'\u7B6E',47203:'\u7B67',47204:'\u7CB1',47205:'\u7CB3',47206:'\u7CB5',47207:'\u7D93',47208:'\u7D79',47209:'\u7D91',47210:'\u7D81',47211:'\u7D8F',47212:'\u7D5B',47213:'\u7F6E',47214:'\u7F69',47215:'\u7F6A',47216:'\u7F72',47217:'\u7FA9',47218:'\u7FA8',47219:'\u7FA4',47220:'\u8056',47221:'\u8058',47222:'\u8086',47223:'\u8084',47224:'\u8171',47225:'\u8170',47226:'\u8178',47227:'\u8165',47228:'\u816E',47229:'\u8173',47230:'\u816B',47265:'\u8179',47266:'\u817A',47267:'\u8166',47268:'\u8205',47269:'\u8247',47270:'\u8482',47271:'\u8477',47272:'\u843D',47273:'\u8431',47274:'\u8475',47275:'\u8466',47276:'\u846B',47277:'\u8449',47278:'\u846C',47279:'\u845B',47280:'\u843C',47281:'\u8435',47282:'\u8461',47283:'\u8463',47284:'\u8469',47285:'\u846D',47286:'\u8446',47287:'\u865E',47288:'\u865C',47289:'\u865F',47290:'\u86F9',47291:'\u8713',47292:'\u8708',47293:'\u8707',47294:'\u8700',47295:'\u86FE',47296:'\u86FB',47297:'\u8702',47298:'\u8703',47299:'\u8706',47300:'\u870A',47301:'\u8859',47302:'\u88DF',47303:'\u88D4',47304:'\u88D9',47305:'\u88DC',47306:'\u88D8',47307:'\u88DD',47308:'\u88E1',47309:'\u88CA',47310:'\u88D5',47311:'\u88D2',47312:'\u899C',47313:'\u89E3',47314:'\u8A6B',47315:'\u8A72',47316:'\u8A73',47317:'\u8A66',47318:'\u8A69',47319:'\u8A70',47320:'\u8A87',47321:'\u8A7C',47322:'\u8A63',47323:'\u8AA0',47324:'\u8A71',47325:'\u8A85',47326:'\u8A6D',47327:'\u8A62',47328:'\u8A6E',47329:'\u8A6C',47330:'\u8A79',47331:'\u8A7B',47332:'\u8A3E',47333:'\u8A68',47334:'\u8C62',47335:'\u8C8A',47336:'\u8C89',47337:'\u8CCA',47338:'\u8CC7',47339:'\u8CC8',47340:'\u8CC4',47341:'\u8CB2',47342:'\u8CC3',47343:'\u8CC2',47344:'\u8CC5',47345:'\u8DE1',47346:'\u8DDF',47347:'\u8DE8',47348:'\u8DEF',47349:'\u8DF3',47350:'\u8DFA',47351:'\u8DEA',47352:'\u8DE4',47353:'\u8DE6',47354:'\u8EB2',47355:'\u8F03',47356:'\u8F09',47357:'\u8EFE',47358:'\u8F0A',47424:'\u8F9F',47425:'\u8FB2',47426:'\u904B',47427:'\u904A',47428:'\u9053',47429:'\u9042',47430:'\u9054',47431:'\u903C',47432:'\u9055',47433:'\u9050',47434:'\u9047',47435:'\u904F',47436:'\u904E',47437:'\u904D',47438:'\u9051',47439:'\u903E',47440:'\u9041',47441:'\u9112',47442:'\u9117',47443:'\u916C',47444:'\u916A',47445:'\u9169',47446:'\u91C9',47447:'\u9237',47448:'\u9257',47449:'\u9238',47450:'\u923D',47451:'\u9240',47452:'\u923E',47453:'\u925B',47454:'\u924B',47455:'\u9264',47456:'\u9251',47457:'\u9234',47458:'\u9249',47459:'\u924D',47460:'\u9245',47461:'\u9239',47462:'\u923F',47463:'\u925A',47464:'\u9598',47465:'\u9698',47466:'\u9694',47467:'\u9695',47468:'\u96CD',47469:'\u96CB',47470:'\u96C9',47471:'\u96CA',47472:'\u96F7',47473:'\u96FB',47474:'\u96F9',47475:'\u96F6',47476:'\u9756',47477:'\u9774',47478:'\u9776',47479:'\u9810',47480:'\u9811',47481:'\u9813',47482:'\u980A',47483:'\u9812',47484:'\u980C',47485:'\u98FC',47486:'\u98F4',47521:'\u98FD',47522:'\u98FE',47523:'\u99B3',47524:'\u99B1',47525:'\u99B4',47526:'\u9AE1',47527:'\u9CE9',47528:'\u9E82',47529:'\u9F0E',47530:'\u9F13',47531:'\u9F20',47532:'\u50E7',47533:'\u50EE',47534:'\u50E5',47535:'\u50D6',47536:'\u50ED',47537:'\u50DA',47538:'\u50D5',47539:'\u50CF',47540:'\u50D1',47541:'\u50F1',47542:'\u50CE',47543:'\u50E9',47544:'\u5162',47545:'\u51F3',47546:'\u5283',47547:'\u5282',47548:'\u5331',47549:'\u53AD',47550:'\u55FE',47551:'\u5600',47552:'\u561B',47553:'\u5617',47554:'\u55FD',47555:'\u5614',47556:'\u5606',47557:'\u5609',47558:'\u560D',47559:'\u560E',47560:'\u55F7',47561:'\u5616',47562:'\u561F',47563:'\u5608',47564:'\u5610',47565:'\u55F6',47566:'\u5718',47567:'\u5716',47568:'\u5875',47569:'\u587E',47570:'\u5883',47571:'\u5893',47572:'\u588A',47573:'\u5879',47574:'\u5885',47575:'\u587D',47576:'\u58FD',47577:'\u5925',47578:'\u5922',47579:'\u5924',47580:'\u596A',47581:'\u5969',47582:'\u5AE1',47583:'\u5AE6',47584:'\u5AE9',47585:'\u5AD7',47586:'\u5AD6',47587:'\u5AD8',47588:'\u5AE3',47589:'\u5B75',47590:'\u5BDE',47591:'\u5BE7',47592:'\u5BE1',47593:'\u5BE5',47594:'\u5BE6',47595:'\u5BE8',47596:'\u5BE2',47597:'\u5BE4',47598:'\u5BDF',47599:'\u5C0D',47600:'\u5C62',47601:'\u5D84',47602:'\u5D87',47603:'\u5E5B',47604:'\u5E63',47605:'\u5E55',47606:'\u5E57',47607:'\u5E54',47608:'\u5ED3',47609:'\u5ED6',47610:'\u5F0A',47611:'\u5F46',47612:'\u5F70',47613:'\u5FB9',47614:'\u6147',47680:'\u613F',47681:'\u614B',47682:'\u6177',47683:'\u6162',47684:'\u6163',47685:'\u615F',47686:'\u615A',47687:'\u6158',47688:'\u6175',47689:'\u622A',47690:'\u6487',47691:'\u6458',47692:'\u6454',47693:'\u64A4',47694:'\u6478',47695:'\u645F',47696:'\u647A',47697:'\u6451',47698:'\u6467',47699:'\u6434',47700:'\u646D',47701:'\u647B',47702:'\u6572',47703:'\u65A1',47704:'\u65D7',47705:'\u65D6',47706:'\u66A2',47707:'\u66A8',47708:'\u669D',47709:'\u699C',47710:'\u69A8',47711:'\u6995',47712:'\u69C1',47713:'\u69AE',47714:'\u69D3',47715:'\u69CB',47716:'\u699B',47717:'\u69B7',47718:'\u69BB',47719:'\u69AB',47720:'\u69B4',47721:'\u69D0',47722:'\u69CD',47723:'\u69AD',47724:'\u69CC',47725:'\u69A6',47726:'\u69C3',47727:'\u69A3',47728:'\u6B49',47729:'\u6B4C',47730:'\u6C33',47731:'\u6F33',47732:'\u6F14',47733:'\u6EFE',47734:'\u6F13',47735:'\u6EF4',47736:'\u6F29',47737:'\u6F3E',47738:'\u6F20',47739:'\u6F2C',47740:'\u6F0F',47741:'\u6F02',47742:'\u6F22',47777:'\u6EFF',47778:'\u6EEF',47779:'\u6F06',47780:'\u6F31',47781:'\u6F38',47782:'\u6F32',47783:'\u6F23',47784:'\u6F15',47785:'\u6F2B',47786:'\u6F2F',47787:'\u6F88',47788:'\u6F2A',47789:'\u6EEC',47790:'\u6F01',47791:'\u6EF2',47792:'\u6ECC',47793:'\u6EF7',47794:'\u7194',47795:'\u7199',47796:'\u717D',47797:'\u718A',47798:'\u7184',47799:'\u7192',47800:'\u723E',47801:'\u7292',47802:'\u7296',47803:'\u7344',47804:'\u7350',47805:'\u7464',47806:'\u7463',47807:'\u746A',47808:'\u7470',47809:'\u746D',47810:'\u7504',47811:'\u7591',47812:'\u7627',47813:'\u760D',47814:'\u760B',47815:'\u7609',47816:'\u7613',47817:'\u76E1',47818:'\u76E3',47819:'\u7784',47820:'\u777D',47821:'\u777F',47822:'\u7761',47823:'\u78C1',47824:'\u789F',47825:'\u78A7',47826:'\u78B3',47827:'\u78A9',47828:'\u78A3',47829:'\u798E',47830:'\u798F',47831:'\u798D',47832:'\u7A2E',47833:'\u7A31',47834:'\u7AAA',47835:'\u7AA9',47836:'\u7AED',47837:'\u7AEF',47838:'\u7BA1',47839:'\u7B95',47840:'\u7B8B',47841:'\u7B75',47842:'\u7B97',47843:'\u7B9D',47844:'\u7B94',47845:'\u7B8F',47846:'\u7BB8',47847:'\u7B87',47848:'\u7B84',47849:'\u7CB9',47850:'\u7CBD',47851:'\u7CBE',47852:'\u7DBB',47853:'\u7DB0',47854:'\u7D9C',47855:'\u7DBD',47856:'\u7DBE',47857:'\u7DA0',47858:'\u7DCA',47859:'\u7DB4',47860:'\u7DB2',47861:'\u7DB1',47862:'\u7DBA',47863:'\u7DA2',47864:'\u7DBF',47865:'\u7DB5',47866:'\u7DB8',47867:'\u7DAD',47868:'\u7DD2',47869:'\u7DC7',47870:'\u7DAC',47936:'\u7F70',47937:'\u7FE0',47938:'\u7FE1',47939:'\u7FDF',47940:'\u805E',47941:'\u805A',47942:'\u8087',47943:'\u8150',47944:'\u8180',47945:'\u818F',47946:'\u8188',47947:'\u818A',47948:'\u817F',47949:'\u8182',47950:'\u81E7',47951:'\u81FA',47952:'\u8207',47953:'\u8214',47954:'\u821E',47955:'\u824B',47956:'\u84C9',47957:'\u84BF',47958:'\u84C6',47959:'\u84C4',47960:'\u8499',47961:'\u849E',47962:'\u84B2',47963:'\u849C',47964:'\u84CB',47965:'\u84B8',47966:'\u84C0',47967:'\u84D3',47968:'\u8490',47969:'\u84BC',47970:'\u84D1',47971:'\u84CA',47972:'\u873F',47973:'\u871C',47974:'\u873B',47975:'\u8722',47976:'\u8725',47977:'\u8734',47978:'\u8718',47979:'\u8755',47980:'\u8737',47981:'\u8729',47982:'\u88F3',47983:'\u8902',47984:'\u88F4',47985:'\u88F9',47986:'\u88F8',47987:'\u88FD',47988:'\u88E8',47989:'\u891A',47990:'\u88EF',47991:'\u8AA6',47992:'\u8A8C',47993:'\u8A9E',47994:'\u8AA3',47995:'\u8A8D',47996:'\u8AA1',47997:'\u8A93',47998:'\u8AA4',48033:'\u8AAA',48034:'\u8AA5',48035:'\u8AA8',48036:'\u8A98',48037:'\u8A91',48038:'\u8A9A',48039:'\u8AA7',48040:'\u8C6A',48041:'\u8C8D',48042:'\u8C8C',48043:'\u8CD3',48044:'\u8CD1',48045:'\u8CD2',48046:'\u8D6B',48047:'\u8D99',48048:'\u8D95',48049:'\u8DFC',48050:'\u8F14',48051:'\u8F12',48052:'\u8F15',48053:'\u8F13',48054:'\u8FA3',48055:'\u9060',48056:'\u9058',48057:'\u905C',48058:'\u9063',48059:'\u9059',48060:'\u905E',48061:'\u9062',48062:'\u905D',48063:'\u905B',48064:'\u9119',48065:'\u9118',48066:'\u911E',48067:'\u9175',48068:'\u9178',48069:'\u9177',48070:'\u9174',48071:'\u9278',48072:'\u9280',48073:'\u9285',48074:'\u9298',48075:'\u9296',48076:'\u927B',48077:'\u9293',48078:'\u929C',48079:'\u92A8',48080:'\u927C',48081:'\u9291',48082:'\u95A1',48083:'\u95A8',48084:'\u95A9',48085:'\u95A3',48086:'\u95A5',48087:'\u95A4',48088:'\u9699',48089:'\u969C',48090:'\u969B',48091:'\u96CC',48092:'\u96D2',48093:'\u9700',48094:'\u977C',48095:'\u9785',48096:'\u97F6',48097:'\u9817',48098:'\u9818',48099:'\u98AF',48100:'\u98B1',48101:'\u9903',48102:'\u9905',48103:'\u990C',48104:'\u9909',48105:'\u99C1',48106:'\u9AAF',48107:'\u9AB0',48108:'\u9AE6',48109:'\u9B41',48110:'\u9B42',48111:'\u9CF4',48112:'\u9CF6',48113:'\u9CF3',48114:'\u9EBC',48115:'\u9F3B',48116:'\u9F4A',48117:'\u5104',48118:'\u5100',48119:'\u50FB',48120:'\u50F5',48121:'\u50F9',48122:'\u5102',48123:'\u5108',48124:'\u5109',48125:'\u5105',48126:'\u51DC',48192:'\u5287',48193:'\u5288',48194:'\u5289',48195:'\u528D',48196:'\u528A',48197:'\u52F0',48198:'\u53B2',48199:'\u562E',48200:'\u563B',48201:'\u5639',48202:'\u5632',48203:'\u563F',48204:'\u5634',48205:'\u5629',48206:'\u5653',48207:'\u564E',48208:'\u5657',48209:'\u5674',48210:'\u5636',48211:'\u562F',48212:'\u5630',48213:'\u5880',48214:'\u589F',48215:'\u589E',48216:'\u58B3',48217:'\u589C',48218:'\u58AE',48219:'\u58A9',48220:'\u58A6',48221:'\u596D',48222:'\u5B09',48223:'\u5AFB',48224:'\u5B0B',48225:'\u5AF5',48226:'\u5B0C',48227:'\u5B08',48228:'\u5BEE',48229:'\u5BEC',48230:'\u5BE9',48231:'\u5BEB',48232:'\u5C64',48233:'\u5C65',48234:'\u5D9D',48235:'\u5D94',48236:'\u5E62',48237:'\u5E5F',48238:'\u5E61',48239:'\u5EE2',48240:'\u5EDA',48241:'\u5EDF',48242:'\u5EDD',48243:'\u5EE3',48244:'\u5EE0',48245:'\u5F48',48246:'\u5F71',48247:'\u5FB7',48248:'\u5FB5',48249:'\u6176',48250:'\u6167',48251:'\u616E',48252:'\u615D',48253:'\u6155',48254:'\u6182',48289:'\u617C',48290:'\u6170',48291:'\u616B',48292:'\u617E',48293:'\u61A7',48294:'\u6190',48295:'\u61AB',48296:'\u618E',48297:'\u61AC',48298:'\u619A',48299:'\u61A4',48300:'\u6194',48301:'\u61AE',48302:'\u622E',48303:'\u6469',48304:'\u646F',48305:'\u6479',48306:'\u649E',48307:'\u64B2',48308:'\u6488',48309:'\u6490',48310:'\u64B0',48311:'\u64A5',48312:'\u6493',48313:'\u6495',48314:'\u64A9',48315:'\u6492',48316:'\u64AE',48317:'\u64AD',48318:'\u64AB',48319:'\u649A',48320:'\u64AC',48321:'\u6499',48322:'\u64A2',48323:'\u64B3',48324:'\u6575',48325:'\u6577',48326:'\u6578',48327:'\u66AE',48328:'\u66AB',48329:'\u66B4',48330:'\u66B1',48331:'\u6A23',48332:'\u6A1F',48333:'\u69E8',48334:'\u6A01',48335:'\u6A1E',48336:'\u6A19',48337:'\u69FD',48338:'\u6A21',48339:'\u6A13',48340:'\u6A0A',48341:'\u69F3',48342:'\u6A02',48343:'\u6A05',48344:'\u69ED',48345:'\u6A11',48346:'\u6B50',48347:'\u6B4E',48348:'\u6BA4',48349:'\u6BC5',48350:'\u6BC6',48351:'\u6F3F',48352:'\u6F7C',48353:'\u6F84',48354:'\u6F51',48355:'\u6F66',48356:'\u6F54',48357:'\u6F86',48358:'\u6F6D',48359:'\u6F5B',48360:'\u6F78',48361:'\u6F6E',48362:'\u6F8E',48363:'\u6F7A',48364:'\u6F70',48365:'\u6F64',48366:'\u6F97',48367:'\u6F58',48368:'\u6ED5',48369:'\u6F6F',48370:'\u6F60',48371:'\u6F5F',48372:'\u719F',48373:'\u71AC',48374:'\u71B1',48375:'\u71A8',48376:'\u7256',48377:'\u729B',48378:'\u734E',48379:'\u7357',48380:'\u7469',48381:'\u748B',48382:'\u7483',48448:'\u747E',48449:'\u7480',48450:'\u757F',48451:'\u7620',48452:'\u7629',48453:'\u761F',48454:'\u7624',48455:'\u7626',48456:'\u7621',48457:'\u7622',48458:'\u769A',48459:'\u76BA',48460:'\u76E4',48461:'\u778E',48462:'\u7787',48463:'\u778C',48464:'\u7791',48465:'\u778B',48466:'\u78CB',48467:'\u78C5',48468:'\u78BA',48469:'\u78CA',48470:'\u78BE',48471:'\u78D5',48472:'\u78BC',48473:'\u78D0',48474:'\u7A3F',48475:'\u7A3C',48476:'\u7A40',48477:'\u7A3D',48478:'\u7A37',48479:'\u7A3B',48480:'\u7AAF',48481:'\u7AAE',48482:'\u7BAD',48483:'\u7BB1',48484:'\u7BC4',48485:'\u7BB4',48486:'\u7BC6',48487:'\u7BC7',48488:'\u7BC1',48489:'\u7BA0',48490:'\u7BCC',48491:'\u7CCA',48492:'\u7DE0',48493:'\u7DF4',48494:'\u7DEF',48495:'\u7DFB',48496:'\u7DD8',48497:'\u7DEC',48498:'\u7DDD',48499:'\u7DE8',48500:'\u7DE3',48501:'\u7DDA',48502:'\u7DDE',48503:'\u7DE9',48504:'\u7D9E',48505:'\u7DD9',48506:'\u7DF2',48507:'\u7DF9',48508:'\u7F75',48509:'\u7F77',48510:'\u7FAF',48545:'\u7FE9',48546:'\u8026',48547:'\u819B',48548:'\u819C',48549:'\u819D',48550:'\u81A0',48551:'\u819A',48552:'\u8198',48553:'\u8517',48554:'\u853D',48555:'\u851A',48556:'\u84EE',48557:'\u852C',48558:'\u852D',48559:'\u8513',48560:'\u8511',48561:'\u8523',48562:'\u8521',48563:'\u8514',48564:'\u84EC',48565:'\u8525',48566:'\u84FF',48567:'\u8506',48568:'\u8782',48569:'\u8774',48570:'\u8776',48571:'\u8760',48572:'\u8766',48573:'\u8778',48574:'\u8768',48575:'\u8759',48576:'\u8757',48577:'\u874C',48578:'\u8753',48579:'\u885B',48580:'\u885D',48581:'\u8910',48582:'\u8907',48583:'\u8912',48584:'\u8913',48585:'\u8915',48586:'\u890A',48587:'\u8ABC',48588:'\u8AD2',48589:'\u8AC7',48590:'\u8AC4',48591:'\u8A95',48592:'\u8ACB',48593:'\u8AF8',48594:'\u8AB2',48595:'\u8AC9',48596:'\u8AC2',48597:'\u8ABF',48598:'\u8AB0',48599:'\u8AD6',48600:'\u8ACD',48601:'\u8AB6',48602:'\u8AB9',48603:'\u8ADB',48604:'\u8C4C',48605:'\u8C4E',48606:'\u8C6C',48607:'\u8CE0',48608:'\u8CDE',48609:'\u8CE6',48610:'\u8CE4',48611:'\u8CEC',48612:'\u8CED',48613:'\u8CE2',48614:'\u8CE3',48615:'\u8CDC',48616:'\u8CEA',48617:'\u8CE1',48618:'\u8D6D',48619:'\u8D9F',48620:'\u8DA3',48621:'\u8E2B',48622:'\u8E10',48623:'\u8E1D',48624:'\u8E22',48625:'\u8E0F',48626:'\u8E29',48627:'\u8E1F',48628:'\u8E21',48629:'\u8E1E',48630:'\u8EBA',48631:'\u8F1D',48632:'\u8F1B',48633:'\u8F1F',48634:'\u8F29',48635:'\u8F26',48636:'\u8F2A',48637:'\u8F1C',48638:'\u8F1E',48704:'\u8F25',48705:'\u9069',48706:'\u906E',48707:'\u9068',48708:'\u906D',48709:'\u9077',48710:'\u9130',48711:'\u912D',48712:'\u9127',48713:'\u9131',48714:'\u9187',48715:'\u9189',48716:'\u918B',48717:'\u9183',48718:'\u92C5',48719:'\u92BB',48720:'\u92B7',48721:'\u92EA',48722:'\u92AC',48723:'\u92E4',48724:'\u92C1',48725:'\u92B3',48726:'\u92BC',48727:'\u92D2',48728:'\u92C7',48729:'\u92F0',48730:'\u92B2',48731:'\u95AD',48732:'\u95B1',48733:'\u9704',48734:'\u9706',48735:'\u9707',48736:'\u9709',48737:'\u9760',48738:'\u978D',48739:'\u978B',48740:'\u978F',48741:'\u9821',48742:'\u982B',48743:'\u981C',48744:'\u98B3',48745:'\u990A',48746:'\u9913',48747:'\u9912',48748:'\u9918',48749:'\u99DD',48750:'\u99D0',48751:'\u99DF',48752:'\u99DB',48753:'\u99D1',48754:'\u99D5',48755:'\u99D2',48756:'\u99D9',48757:'\u9AB7',48758:'\u9AEE',48759:'\u9AEF',48760:'\u9B27',48761:'\u9B45',48762:'\u9B44',48763:'\u9B77',48764:'\u9B6F',48765:'\u9D06',48766:'\u9D09',48801:'\u9D03',48802:'\u9EA9',48803:'\u9EBE',48804:'\u9ECE',48805:'\u58A8',48806:'\u9F52',48807:'\u5112',48808:'\u5118',48809:'\u5114',48810:'\u5110',48811:'\u5115',48812:'\u5180',48813:'\u51AA',48814:'\u51DD',48815:'\u5291',48816:'\u5293',48817:'\u52F3',48818:'\u5659',48819:'\u566B',48820:'\u5679',48821:'\u5669',48822:'\u5664',48823:'\u5678',48824:'\u566A',48825:'\u5668',48826:'\u5665',48827:'\u5671',48828:'\u566F',48829:'\u566C',48830:'\u5662',48831:'\u5676',48832:'\u58C1',48833:'\u58BE',48834:'\u58C7',48835:'\u58C5',48836:'\u596E',48837:'\u5B1D',48838:'\u5B34',48839:'\u5B78',48840:'\u5BF0',48841:'\u5C0E',48842:'\u5F4A',48843:'\u61B2',48844:'\u6191',48845:'\u61A9',48846:'\u618A',48847:'\u61CD',48848:'\u61B6',48849:'\u61BE',48850:'\u61CA',48851:'\u61C8',48852:'\u6230',48853:'\u64C5',48854:'\u64C1',48855:'\u64CB',48856:'\u64BB',48857:'\u64BC',48858:'\u64DA',48859:'\u64C4',48860:'\u64C7',48861:'\u64C2',48862:'\u64CD',48863:'\u64BF',48864:'\u64D2',48865:'\u64D4',48866:'\u64BE',48867:'\u6574',48868:'\u66C6',48869:'\u66C9',48870:'\u66B9',48871:'\u66C4',48872:'\u66C7',48873:'\u66B8',48874:'\u6A3D',48875:'\u6A38',48876:'\u6A3A',48877:'\u6A59',48878:'\u6A6B',48879:'\u6A58',48880:'\u6A39',48881:'\u6A44',48882:'\u6A62',48883:'\u6A61',48884:'\u6A4B',48885:'\u6A47',48886:'\u6A35',48887:'\u6A5F',48888:'\u6A48',48889:'\u6B59',48890:'\u6B77',48891:'\u6C05',48892:'\u6FC2',48893:'\u6FB1',48894:'\u6FA1',48960:'\u6FC3',48961:'\u6FA4',48962:'\u6FC1',48963:'\u6FA7',48964:'\u6FB3',48965:'\u6FC0',48966:'\u6FB9',48967:'\u6FB6',48968:'\u6FA6',48969:'\u6FA0',48970:'\u6FB4',48971:'\u71BE',48972:'\u71C9',48973:'\u71D0',48974:'\u71D2',48975:'\u71C8',48976:'\u71D5',48977:'\u71B9',48978:'\u71CE',48979:'\u71D9',48980:'\u71DC',48981:'\u71C3',48982:'\u71C4',48983:'\u7368',48984:'\u749C',48985:'\u74A3',48986:'\u7498',48987:'\u749F',48988:'\u749E',48989:'\u74E2',48990:'\u750C',48991:'\u750D',48992:'\u7634',48993:'\u7638',48994:'\u763A',48995:'\u76E7',48996:'\u76E5',48997:'\u77A0',48998:'\u779E',48999:'\u779F',49000:'\u77A5',49001:'\u78E8',49002:'\u78DA',49003:'\u78EC',49004:'\u78E7',49005:'\u79A6',49006:'\u7A4D',49007:'\u7A4E',49008:'\u7A46',49009:'\u7A4C',49010:'\u7A4B',49011:'\u7ABA',49012:'\u7BD9',49013:'\u7C11',49014:'\u7BC9',49015:'\u7BE4',49016:'\u7BDB',49017:'\u7BE1',49018:'\u7BE9',49019:'\u7BE6',49020:'\u7CD5',49021:'\u7CD6',49022:'\u7E0A',49057:'\u7E11',49058:'\u7E08',49059:'\u7E1B',49060:'\u7E23',49061:'\u7E1E',49062:'\u7E1D',49063:'\u7E09',49064:'\u7E10',49065:'\u7F79',49066:'\u7FB2',49067:'\u7FF0',49068:'\u7FF1',49069:'\u7FEE',49070:'\u8028',49071:'\u81B3',49072:'\u81A9',49073:'\u81A8',49074:'\u81FB',49075:'\u8208',49076:'\u8258',49077:'\u8259',49078:'\u854A',49079:'\u8559',49080:'\u8548',49081:'\u8568',49082:'\u8569',49083:'\u8543',49084:'\u8549',49085:'\u856D',49086:'\u856A',49087:'\u855E',49088:'\u8783',49089:'\u879F',49090:'\u879E',49091:'\u87A2',49092:'\u878D',49093:'\u8861',49094:'\u892A',49095:'\u8932',49096:'\u8925',49097:'\u892B',49098:'\u8921',49099:'\u89AA',49100:'\u89A6',49101:'\u8AE6',49102:'\u8AFA',49103:'\u8AEB',49104:'\u8AF1',49105:'\u8B00',49106:'\u8ADC',49107:'\u8AE7',49108:'\u8AEE',49109:'\u8AFE',49110:'\u8B01',49111:'\u8B02',49112:'\u8AF7',49113:'\u8AED',49114:'\u8AF3',49115:'\u8AF6',49116:'\u8AFC',49117:'\u8C6B',49118:'\u8C6D',49119:'\u8C93',49120:'\u8CF4',49121:'\u8E44',49122:'\u8E31',49123:'\u8E34',49124:'\u8E42',49125:'\u8E39',49126:'\u8E35',49127:'\u8F3B',49128:'\u8F2F',49129:'\u8F38',49130:'\u8F33',49131:'\u8FA8',49132:'\u8FA6',49133:'\u9075',49134:'\u9074',49135:'\u9078',49136:'\u9072',49137:'\u907C',49138:'\u907A',49139:'\u9134',49140:'\u9192',49141:'\u9320',49142:'\u9336',49143:'\u92F8',49144:'\u9333',49145:'\u932F',49146:'\u9322',49147:'\u92FC',49148:'\u932B',49149:'\u9304',49150:'\u931A',49216:'\u9310',49217:'\u9326',49218:'\u9321',49219:'\u9315',49220:'\u932E',49221:'\u9319',49222:'\u95BB',49223:'\u96A7',49224:'\u96A8',49225:'\u96AA',49226:'\u96D5',49227:'\u970E',49228:'\u9711',49229:'\u9716',49230:'\u970D',49231:'\u9713',49232:'\u970F',49233:'\u975B',49234:'\u975C',49235:'\u9766',49236:'\u9798',49237:'\u9830',49238:'\u9838',49239:'\u983B',49240:'\u9837',49241:'\u982D',49242:'\u9839',49243:'\u9824',49244:'\u9910',49245:'\u9928',49246:'\u991E',49247:'\u991B',49248:'\u9921',49249:'\u991A',49250:'\u99ED',49251:'\u99E2',49252:'\u99F1',49253:'\u9AB8',49254:'\u9ABC',49255:'\u9AFB',49256:'\u9AED',49257:'\u9B28',49258:'\u9B91',49259:'\u9D15',49260:'\u9D23',49261:'\u9D26',49262:'\u9D28',49263:'\u9D12',49264:'\u9D1B',49265:'\u9ED8',49266:'\u9ED4',49267:'\u9F8D',49268:'\u9F9C',49269:'\u512A',49270:'\u511F',49271:'\u5121',49272:'\u5132',49273:'\u52F5',49274:'\u568E',49275:'\u5680',49276:'\u5690',49277:'\u5685',49278:'\u5687',49313:'\u568F',49314:'\u58D5',49315:'\u58D3',49316:'\u58D1',49317:'\u58CE',49318:'\u5B30',49319:'\u5B2A',49320:'\u5B24',49321:'\u5B7A',49322:'\u5C37',49323:'\u5C68',49324:'\u5DBC',49325:'\u5DBA',49326:'\u5DBD',49327:'\u5DB8',49328:'\u5E6B',49329:'\u5F4C',49330:'\u5FBD',49331:'\u61C9',49332:'\u61C2',49333:'\u61C7',49334:'\u61E6',49335:'\u61CB',49336:'\u6232',49337:'\u6234',49338:'\u64CE',49339:'\u64CA',49340:'\u64D8',49341:'\u64E0',49342:'\u64F0',49343:'\u64E6',49344:'\u64EC',49345:'\u64F1',49346:'\u64E2',49347:'\u64ED',49348:'\u6582',49349:'\u6583',49350:'\u66D9',49351:'\u66D6',49352:'\u6A80',49353:'\u6A94',49354:'\u6A84',49355:'\u6AA2',49356:'\u6A9C',49357:'\u6ADB',49358:'\u6AA3',49359:'\u6A7E',49360:'\u6A97',49361:'\u6A90',49362:'\u6AA0',49363:'\u6B5C',49364:'\u6BAE',49365:'\u6BDA',49366:'\u6C08',49367:'\u6FD8',49368:'\u6FF1',49369:'\u6FDF',49370:'\u6FE0',49371:'\u6FDB',49372:'\u6FE4',49373:'\u6FEB',49374:'\u6FEF',49375:'\u6F80',49376:'\u6FEC',49377:'\u6FE1',49378:'\u6FE9',49379:'\u6FD5',49380:'\u6FEE',49381:'\u6FF0',49382:'\u71E7',49383:'\u71DF',49384:'\u71EE',49385:'\u71E6',49386:'\u71E5',49387:'\u71ED',49388:'\u71EC',49389:'\u71F4',49390:'\u71E0',49391:'\u7235',49392:'\u7246',49393:'\u7370',49394:'\u7372',49395:'\u74A9',49396:'\u74B0',49397:'\u74A6',49398:'\u74A8',49399:'\u7646',49400:'\u7642',49401:'\u764C',49402:'\u76EA',49403:'\u77B3',49404:'\u77AA',49405:'\u77B0',49406:'\u77AC',49472:'\u77A7',49473:'\u77AD',49474:'\u77EF',49475:'\u78F7',49476:'\u78FA',49477:'\u78F4',49478:'\u78EF',49479:'\u7901',49480:'\u79A7',49481:'\u79AA',49482:'\u7A57',49483:'\u7ABF',49484:'\u7C07',49485:'\u7C0D',49486:'\u7BFE',49487:'\u7BF7',49488:'\u7C0C',49489:'\u7BE0',49490:'\u7CE0',49491:'\u7CDC',49492:'\u7CDE',49493:'\u7CE2',49494:'\u7CDF',49495:'\u7CD9',49496:'\u7CDD',49497:'\u7E2E',49498:'\u7E3E',49499:'\u7E46',49500:'\u7E37',49501:'\u7E32',49502:'\u7E43',49503:'\u7E2B',49504:'\u7E3D',49505:'\u7E31',49506:'\u7E45',49507:'\u7E41',49508:'\u7E34',49509:'\u7E39',49510:'\u7E48',49511:'\u7E35',49512:'\u7E3F',49513:'\u7E2F',49514:'\u7F44',49515:'\u7FF3',49516:'\u7FFC',49517:'\u8071',49518:'\u8072',49519:'\u8070',49520:'\u806F',49521:'\u8073',49522:'\u81C6',49523:'\u81C3',49524:'\u81BA',49525:'\u81C2',49526:'\u81C0',49527:'\u81BF',49528:'\u81BD',49529:'\u81C9',49530:'\u81BE',49531:'\u81E8',49532:'\u8209',49533:'\u8271',49534:'\u85AA',49569:'\u8584',49570:'\u857E',49571:'\u859C',49572:'\u8591',49573:'\u8594',49574:'\u85AF',49575:'\u859B',49576:'\u8587',49577:'\u85A8',49578:'\u858A',49579:'\u8667',49580:'\u87C0',49581:'\u87D1',49582:'\u87B3',49583:'\u87D2',49584:'\u87C6',49585:'\u87AB',49586:'\u87BB',49587:'\u87BA',49588:'\u87C8',49589:'\u87CB',49590:'\u893B',49591:'\u8936',49592:'\u8944',49593:'\u8938',49594:'\u893D',49595:'\u89AC',49596:'\u8B0E',49597:'\u8B17',49598:'\u8B19',49599:'\u8B1B',49600:'\u8B0A',49601:'\u8B20',49602:'\u8B1D',49603:'\u8B04',49604:'\u8B10',49605:'\u8C41',49606:'\u8C3F',49607:'\u8C73',49608:'\u8CFA',49609:'\u8CFD',49610:'\u8CFC',49611:'\u8CF8',49612:'\u8CFB',49613:'\u8DA8',49614:'\u8E49',49615:'\u8E4B',49616:'\u8E48',49617:'\u8E4A',49618:'\u8F44',49619:'\u8F3E',49620:'\u8F42',49621:'\u8F45',49622:'\u8F3F',49623:'\u907F',49624:'\u907D',49625:'\u9084',49626:'\u9081',49627:'\u9082',49628:'\u9080',49629:'\u9139',49630:'\u91A3',49631:'\u919E',49632:'\u919C',49633:'\u934D',49634:'\u9382',49635:'\u9328',49636:'\u9375',49637:'\u934A',49638:'\u9365',49639:'\u934B',49640:'\u9318',49641:'\u937E',49642:'\u936C',49643:'\u935B',49644:'\u9370',49645:'\u935A',49646:'\u9354',49647:'\u95CA',49648:'\u95CB',49649:'\u95CC',49650:'\u95C8',49651:'\u95C6',49652:'\u96B1',49653:'\u96B8',49654:'\u96D6',49655:'\u971C',49656:'\u971E',49657:'\u97A0',49658:'\u97D3',49659:'\u9846',49660:'\u98B6',49661:'\u9935',49662:'\u9A01',49728:'\u99FF',49729:'\u9BAE',49730:'\u9BAB',49731:'\u9BAA',49732:'\u9BAD',49733:'\u9D3B',49734:'\u9D3F',49735:'\u9E8B',49736:'\u9ECF',49737:'\u9EDE',49738:'\u9EDC',49739:'\u9EDD',49740:'\u9EDB',49741:'\u9F3E',49742:'\u9F4B',49743:'\u53E2',49744:'\u5695',49745:'\u56AE',49746:'\u58D9',49747:'\u58D8',49748:'\u5B38',49749:'\u5F5D',49750:'\u61E3',49751:'\u6233',49752:'\u64F4',49753:'\u64F2',49754:'\u64FE',49755:'\u6506',49756:'\u64FA',49757:'\u64FB',49758:'\u64F7',49759:'\u65B7',49760:'\u66DC',49761:'\u6726',49762:'\u6AB3',49763:'\u6AAC',49764:'\u6AC3',49765:'\u6ABB',49766:'\u6AB8',49767:'\u6AC2',49768:'\u6AAE',49769:'\u6AAF',49770:'\u6B5F',49771:'\u6B78',49772:'\u6BAF',49773:'\u7009',49774:'\u700B',49775:'\u6FFE',49776:'\u7006',49777:'\u6FFA',49778:'\u7011',49779:'\u700F',49780:'\u71FB',49781:'\u71FC',49782:'\u71FE',49783:'\u71F8',49784:'\u7377',49785:'\u7375',49786:'\u74A7',49787:'\u74BF',49788:'\u7515',49789:'\u7656',49790:'\u7658',49825:'\u7652',49826:'\u77BD',49827:'\u77BF',49828:'\u77BB',49829:'\u77BC',49830:'\u790E',49831:'\u79AE',49832:'\u7A61',49833:'\u7A62',49834:'\u7A60',49835:'\u7AC4',49836:'\u7AC5',49837:'\u7C2B',49838:'\u7C27',49839:'\u7C2A',49840:'\u7C1E',49841:'\u7C23',49842:'\u7C21',49843:'\u7CE7',49844:'\u7E54',49845:'\u7E55',49846:'\u7E5E',49847:'\u7E5A',49848:'\u7E61',49849:'\u7E52',49850:'\u7E59',49851:'\u7F48',49852:'\u7FF9',49853:'\u7FFB',49854:'\u8077',49855:'\u8076',49856:'\u81CD',49857:'\u81CF',49858:'\u820A',49859:'\u85CF',49860:'\u85A9',49861:'\u85CD',49862:'\u85D0',49863:'\u85C9',49864:'\u85B0',49865:'\u85BA',49866:'\u85B9',49867:'\u85A6',49868:'\u87EF',49869:'\u87EC',49870:'\u87F2',49871:'\u87E0',49872:'\u8986',49873:'\u89B2',49874:'\u89F4',49875:'\u8B28',49876:'\u8B39',49877:'\u8B2C',49878:'\u8B2B',49879:'\u8C50',49880:'\u8D05',49881:'\u8E59',49882:'\u8E63',49883:'\u8E66',49884:'\u8E64',49885:'\u8E5F',49886:'\u8E55',49887:'\u8EC0',49888:'\u8F49',49889:'\u8F4D',49890:'\u9087',49891:'\u9083',49892:'\u9088',49893:'\u91AB',49894:'\u91AC',49895:'\u91D0',49896:'\u9394',49897:'\u938A',49898:'\u9396',49899:'\u93A2',49900:'\u93B3',49901:'\u93AE',49902:'\u93AC',49903:'\u93B0',49904:'\u9398',49905:'\u939A',49906:'\u9397',49907:'\u95D4',49908:'\u95D6',49909:'\u95D0',49910:'\u95D5',49911:'\u96E2',49912:'\u96DC',49913:'\u96D9',49914:'\u96DB',49915:'\u96DE',49916:'\u9724',49917:'\u97A3',49918:'\u97A6',49984:'\u97AD',49985:'\u97F9',49986:'\u984D',49987:'\u984F',49988:'\u984C',49989:'\u984E',49990:'\u9853',49991:'\u98BA',49992:'\u993E',49993:'\u993F',49994:'\u993D',49995:'\u992E',49996:'\u99A5',49997:'\u9A0E',49998:'\u9AC1',49999:'\u9B03',50000:'\u9B06',50001:'\u9B4F',50002:'\u9B4E',50003:'\u9B4D',50004:'\u9BCA',50005:'\u9BC9',50006:'\u9BFD',50007:'\u9BC8',50008:'\u9BC0',50009:'\u9D51',50010:'\u9D5D',50011:'\u9D60',50012:'\u9EE0',50013:'\u9F15',50014:'\u9F2C',50015:'\u5133',50016:'\u56A5',50017:'\u58DE',50018:'\u58DF',50019:'\u58E2',50020:'\u5BF5',50021:'\u9F90',50022:'\u5EEC',50023:'\u61F2',50024:'\u61F7',50025:'\u61F6',50026:'\u61F5',50027:'\u6500',50028:'\u650F',50029:'\u66E0',50030:'\u66DD',50031:'\u6AE5',50032:'\u6ADD',50033:'\u6ADA',50034:'\u6AD3',50035:'\u701B',50036:'\u701F',50037:'\u7028',50038:'\u701A',50039:'\u701D',50040:'\u7015',50041:'\u7018',50042:'\u7206',50043:'\u720D',50044:'\u7258',50045:'\u72A2',50046:'\u7378',50081:'\u737A',50082:'\u74BD',50083:'\u74CA',50084:'\u74E3',50085:'\u7587',50086:'\u7586',50087:'\u765F',50088:'\u7661',50089:'\u77C7',50090:'\u7919',50091:'\u79B1',50092:'\u7A6B',50093:'\u7A69',50094:'\u7C3E',50095:'\u7C3F',50096:'\u7C38',50097:'\u7C3D',50098:'\u7C37',50099:'\u7C40',50100:'\u7E6B',50101:'\u7E6D',50102:'\u7E79',50103:'\u7E69',50104:'\u7E6A',50105:'\u7F85',50106:'\u7E73',50107:'\u7FB6',50108:'\u7FB9',50109:'\u7FB8',50110:'\u81D8',50111:'\u85E9',50112:'\u85DD',50113:'\u85EA',50114:'\u85D5',50115:'\u85E4',50116:'\u85E5',50117:'\u85F7',50118:'\u87FB',50119:'\u8805',50120:'\u880D',50121:'\u87F9',50122:'\u87FE',50123:'\u8960',50124:'\u895F',50125:'\u8956',50126:'\u895E',50127:'\u8B41',50128:'\u8B5C',50129:'\u8B58',50130:'\u8B49',50131:'\u8B5A',50132:'\u8B4E',50133:'\u8B4F',50134:'\u8B46',50135:'\u8B59',50136:'\u8D08',50137:'\u8D0A',50138:'\u8E7C',50139:'\u8E72',50140:'\u8E87',50141:'\u8E76',50142:'\u8E6C',50143:'\u8E7A',50144:'\u8E74',50145:'\u8F54',50146:'\u8F4E',50147:'\u8FAD',50148:'\u908A',50149:'\u908B',50150:'\u91B1',50151:'\u91AE',50152:'\u93E1',50153:'\u93D1',50154:'\u93DF',50155:'\u93C3',50156:'\u93C8',50157:'\u93DC',50158:'\u93DD',50159:'\u93D6',50160:'\u93E2',50161:'\u93CD',50162:'\u93D8',50163:'\u93E4',50164:'\u93D7',50165:'\u93E8',50166:'\u95DC',50167:'\u96B4',50168:'\u96E3',50169:'\u972A',50170:'\u9727',50171:'\u9761',50172:'\u97DC',50173:'\u97FB',50174:'\u985E',50240:'\u9858',50241:'\u985B',50242:'\u98BC',50243:'\u9945',50244:'\u9949',50245:'\u9A16',50246:'\u9A19',50247:'\u9B0D',50248:'\u9BE8',50249:'\u9BE7',50250:'\u9BD6',50251:'\u9BDB',50252:'\u9D89',50253:'\u9D61',50254:'\u9D72',50255:'\u9D6A',50256:'\u9D6C',50257:'\u9E92',50258:'\u9E97',50259:'\u9E93',50260:'\u9EB4',50261:'\u52F8',50262:'\u56A8',50263:'\u56B7',50264:'\u56B6',50265:'\u56B4',50266:'\u56BC',50267:'\u58E4',50268:'\u5B40',50269:'\u5B43',50270:'\u5B7D',50271:'\u5BF6',50272:'\u5DC9',50273:'\u61F8',50274:'\u61FA',50275:'\u6518',50276:'\u6514',50277:'\u6519',50278:'\u66E6',50279:'\u6727',50280:'\u6AEC',50281:'\u703E',50282:'\u7030',50283:'\u7032',50284:'\u7210',50285:'\u737B',50286:'\u74CF',50287:'\u7662',50288:'\u7665',50289:'\u7926',50290:'\u792A',50291:'\u792C',50292:'\u792B',50293:'\u7AC7',50294:'\u7AF6',50295:'\u7C4C',50296:'\u7C43',50297:'\u7C4D',50298:'\u7CEF',50299:'\u7CF0',50300:'\u8FAE',50301:'\u7E7D',50302:'\u7E7C',50337:'\u7E82',50338:'\u7F4C',50339:'\u8000',50340:'\u81DA',50341:'\u8266',50342:'\u85FB',50343:'\u85F9',50344:'\u8611',50345:'\u85FA',50346:'\u8606',50347:'\u860B',50348:'\u8607',50349:'\u860A',50350:'\u8814',50351:'\u8815',50352:'\u8964',50353:'\u89BA',50354:'\u89F8',50355:'\u8B70',50356:'\u8B6C',50357:'\u8B66',50358:'\u8B6F',50359:'\u8B5F',50360:'\u8B6B',50361:'\u8D0F',50362:'\u8D0D',50363:'\u8E89',50364:'\u8E81',50365:'\u8E85',50366:'\u8E82',50367:'\u91B4',50368:'\u91CB',50369:'\u9418',50370:'\u9403',50371:'\u93FD',50372:'\u95E1',50373:'\u9730',50374:'\u98C4',50375:'\u9952',50376:'\u9951',50377:'\u99A8',50378:'\u9A2B',50379:'\u9A30',50380:'\u9A37',50381:'\u9A35',50382:'\u9C13',50383:'\u9C0D',50384:'\u9E79',50385:'\u9EB5',50386:'\u9EE8',50387:'\u9F2F',50388:'\u9F5F',50389:'\u9F63',50390:'\u9F61',50391:'\u5137',50392:'\u5138',50393:'\u56C1',50394:'\u56C0',50395:'\u56C2',50396:'\u5914',50397:'\u5C6C',50398:'\u5DCD',50399:'\u61FC',50400:'\u61FE',50401:'\u651D',50402:'\u651C',50403:'\u6595',50404:'\u66E9',50405:'\u6AFB',50406:'\u6B04',50407:'\u6AFA',50408:'\u6BB2',50409:'\u704C',50410:'\u721B',50411:'\u72A7',50412:'\u74D6',50413:'\u74D4',50414:'\u7669',50415:'\u77D3',50416:'\u7C50',50417:'\u7E8F',50418:'\u7E8C',50419:'\u7FBC',50420:'\u8617',50421:'\u862D',50422:'\u861A',50423:'\u8823',50424:'\u8822',50425:'\u8821',50426:'\u881F',50427:'\u896A',50428:'\u896C',50429:'\u89BD',50430:'\u8B74',50496:'\u8B77',50497:'\u8B7D',50498:'\u8D13',50499:'\u8E8A',50500:'\u8E8D',50501:'\u8E8B',50502:'\u8F5F',50503:'\u8FAF',50504:'\u91BA',50505:'\u942E',50506:'\u9433',50507:'\u9435',50508:'\u943A',50509:'\u9438',50510:'\u9432',50511:'\u942B',50512:'\u95E2',50513:'\u9738',50514:'\u9739',50515:'\u9732',50516:'\u97FF',50517:'\u9867',50518:'\u9865',50519:'\u9957',50520:'\u9A45',50521:'\u9A43',50522:'\u9A40',50523:'\u9A3E',50524:'\u9ACF',50525:'\u9B54',50526:'\u9B51',50527:'\u9C2D',50528:'\u9C25',50529:'\u9DAF',50530:'\u9DB4',50531:'\u9DC2',50532:'\u9DB8',50533:'\u9E9D',50534:'\u9EEF',50535:'\u9F19',50536:'\u9F5C',50537:'\u9F66',50538:'\u9F67',50539:'\u513C',50540:'\u513B',50541:'\u56C8',50542:'\u56CA',50543:'\u56C9',50544:'\u5B7F',50545:'\u5DD4',50546:'\u5DD2',50547:'\u5F4E',50548:'\u61FF',50549:'\u6524',50550:'\u6B0A',50551:'\u6B61',50552:'\u7051',50553:'\u7058',50554:'\u7380',50555:'\u74E4',50556:'\u758A',50557:'\u766E',50558:'\u766C',50593:'\u79B3',50594:'\u7C60',50595:'\u7C5F',50596:'\u807E',50597:'\u807D',50598:'\u81DF',50599:'\u8972',50600:'\u896F',50601:'\u89FC',50602:'\u8B80',50603:'\u8D16',50604:'\u8D17',50605:'\u8E91',50606:'\u8E93',50607:'\u8F61',50608:'\u9148',50609:'\u9444',50610:'\u9451',50611:'\u9452',50612:'\u973D',50613:'\u973E',50614:'\u97C3',50615:'\u97C1',50616:'\u986B',50617:'\u9955',50618:'\u9A55',50619:'\u9A4D',50620:'\u9AD2',50621:'\u9B1A',50622:'\u9C49',50623:'\u9C31',50624:'\u9C3E',50625:'\u9C3B',50626:'\u9DD3',50627:'\u9DD7',50628:'\u9F34',50629:'\u9F6C',50630:'\u9F6A',50631:'\u9F94',50632:'\u56CC',50633:'\u5DD6',50634:'\u6200',50635:'\u6523',50636:'\u652B',50637:'\u652A',50638:'\u66EC',50639:'\u6B10',50640:'\u74DA',50641:'\u7ACA',50642:'\u7C64',50643:'\u7C63',50644:'\u7C65',50645:'\u7E93',50646:'\u7E96',50647:'\u7E94',50648:'\u81E2',50649:'\u8638',50650:'\u863F',50651:'\u8831',50652:'\u8B8A',50653:'\u9090',50654:'\u908F',50655:'\u9463',50656:'\u9460',50657:'\u9464',50658:'\u9768',50659:'\u986F',50660:'\u995C',50661:'\u9A5A',50662:'\u9A5B',50663:'\u9A57',50664:'\u9AD3',50665:'\u9AD4',50666:'\u9AD1',50667:'\u9C54',50668:'\u9C57',50669:'\u9C56',50670:'\u9DE5',50671:'\u9E9F',50672:'\u9EF4',50673:'\u56D1',50674:'\u58E9',50675:'\u652C',50676:'\u705E',50677:'\u7671',50678:'\u7672',50679:'\u77D7',50680:'\u7F50',50681:'\u7F88',50682:'\u8836',50683:'\u8839',50684:'\u8862',50685:'\u8B93',50686:'\u8B92',50752:'\u8B96',50753:'\u8277',50754:'\u8D1B',50755:'\u91C0',50756:'\u946A',50757:'\u9742',50758:'\u9748',50759:'\u9744',50760:'\u97C6',50761:'\u9870',50762:'\u9A5F',50763:'\u9B22',50764:'\u9B58',50765:'\u9C5F',50766:'\u9DF9',50767:'\u9DFA',50768:'\u9E7C',50769:'\u9E7D',50770:'\u9F07',50771:'\u9F77',50772:'\u9F72',50773:'\u5EF3',50774:'\u6B16',50775:'\u7063',50776:'\u7C6C',50777:'\u7C6E',50778:'\u883B',50779:'\u89C0',50780:'\u8EA1',50781:'\u91C1',50782:'\u9472',50783:'\u9470',50784:'\u9871',50785:'\u995E',50786:'\u9AD6',50787:'\u9B23',50788:'\u9ECC',50789:'\u7064',50790:'\u77DA',50791:'\u8B9A',50792:'\u9477',50793:'\u97C9',50794:'\u9A62',50795:'\u9A65',50796:'\u7E9C',50797:'\u8B9C',50798:'\u8EAA',50799:'\u91C5',50800:'\u947D',50801:'\u947E',50802:'\u947C',50803:'\u9C77',50804:'\u9C78',50805:'\u9EF7',50806:'\u8C54',50807:'\u947F',50808:'\u9E1A',50809:'\u7228',50810:'\u9A6A',50811:'\u9B31',50812:'\u9E1B',50813:'\u9E1E',50814:'\u7C72',50849:'\uF6B1',50850:'\uF6B2',50851:'\uF6B3',50852:'\uF6B4',50853:'\uF6B5',50854:'\uF6B6',50855:'\uF6B7',50856:'\uF6B8',50857:'\uF6B9',50858:'\uF6BA',50859:'\uF6BB',50860:'\uF6BC',50861:'\uF6BD',50862:'\uF6BE',50863:'\uF6BF',50864:'\uF6C0',50865:'\uF6C1',50866:'\uF6C2',50867:'\uF6C3',50868:'\uF6C4',50869:'\uF6C5',50870:'\uF6C6',50871:'\uF6C7',50872:'\uF6C8',50873:'\uF6C9',50874:'\uF6CA',50875:'\uF6CB',50876:'\uF6CC',50877:'\uF6CD',50878:'\uF6CE',50879:'\uF6CF',50880:'\uF6D0',50881:'\uF6D1',50882:'\uF6D2',50883:'\uF6D3',50884:'\uF6D4',50885:'\uF6D5',50886:'\uF6D6',50887:'\uF6D7',50888:'\uF6D8',50889:'\uF6D9',50890:'\uF6DA',50891:'\uF6DB',50892:'\uF6DC',50893:'\uF6DD',50894:'\uF6DE',50895:'\uF6DF',50896:'\uF6E0',50897:'\uF6E1',50898:'\uF6E2',50899:'\uF6E3',50900:'\uF6E4',50901:'\uF6E5',50902:'\uF6E6',50903:'\uF6E7',50904:'\uF6E8',50905:'\uF6E9',50906:'\uF6EA',50907:'\uF6EB',50908:'\uF6EC',50909:'\uF6ED',50910:'\uF6EE',50911:'\uF6EF',50912:'\uF6F0',50913:'\uF6F1',50914:'\uF6F2',50915:'\uF6F3',50916:'\uF6F4',50917:'\uF6F5',50918:'\uF6F6',50919:'\uF6F7',50920:'\uF6F8',50921:'\uF6F9',50922:'\uF6FA',50923:'\uF6FB',50924:'\uF6FC',50925:'\uF6FD',50926:'\uF6FE',50927:'\uF6FF',50928:'\uF700',50929:'\uF701',50930:'\uF702',50931:'\uF703',50932:'\uF704',50933:'\uF705',50934:'\uF706',50935:'\uF707',50936:'\uF708',50937:'\uF709',50938:'\uF70A',50939:'\uF70B',50940:'\uF70C',50941:'\uF70D',50942:'\uF70E',51008:'\uF70F',51009:'\uF710',51010:'\uF711',51011:'\uF712',51012:'\uF713',51013:'\uF714',51014:'\uF715',51015:'\uF716',51016:'\uF717',51017:'\uF718',51018:'\uF719',51019:'\uF71A',51020:'\uF71B',51021:'\uF71C',51022:'\uF71D',51023:'\uF71E',51024:'\uF71F',51025:'\uF720',51026:'\uF721',51027:'\uF722',51028:'\uF723',51029:'\uF724',51030:'\uF725',51031:'\uF726',51032:'\uF727',51033:'\uF728',51034:'\uF729',51035:'\uF72A',51036:'\uF72B',51037:'\uF72C',51038:'\uF72D',51039:'\uF72E',51040:'\uF72F',51041:'\uF730',51042:'\uF731',51043:'\uF732',51044:'\uF733',51045:'\uF734',51046:'\uF735',51047:'\uF736',51048:'\uF737',51049:'\uF738',51050:'\uF739',51051:'\uF73A',51052:'\uF73B',51053:'\uF73C',51054:'\uF73D',51055:'\uF73E',51056:'\uF73F',51057:'\uF740',51058:'\uF741',51059:'\uF742',51060:'\uF743',51061:'\uF744',51062:'\uF745',51063:'\uF746',51064:'\uF747',51065:'\uF748',51066:'\uF749',51067:'\uF74A',51068:'\uF74B',51069:'\uF74C',51070:'\uF74D',51105:'\uF74E',51106:'\uF74F',51107:'\uF750',51108:'\uF751',51109:'\uF752',51110:'\uF753',51111:'\uF754',51112:'\uF755',51113:'\uF756',51114:'\uF757',51115:'\uF758',51116:'\uF759',51117:'\uF75A',51118:'\uF75B',51119:'\uF75C',51120:'\uF75D',51121:'\uF75E',51122:'\uF75F',51123:'\uF760',51124:'\uF761',51125:'\uF762',51126:'\uF763',51127:'\uF764',51128:'\uF765',51129:'\uF766',51130:'\uF767',51131:'\uF768',51132:'\uF769',51133:'\uF76A',51134:'\uF76B',51135:'\uF76C',51136:'\uF76D',51137:'\uF76E',51138:'\uF76F',51139:'\uF770',51140:'\uF771',51141:'\uF772',51142:'\uF773',51143:'\uF774',51144:'\uF775',51145:'\uF776',51146:'\uF777',51147:'\uF778',51148:'\uF779',51149:'\uF77A',51150:'\uF77B',51151:'\uF77C',51152:'\uF77D',51153:'\uF77E',51154:'\uF77F',51155:'\uF780',51156:'\uF781',51157:'\uF782',51158:'\uF783',51159:'\uF784',51160:'\uF785',51161:'\uF786',51162:'\uF787',51163:'\uF788',51164:'\uF789',51165:'\uF78A',51166:'\uF78B',51167:'\uF78C',51168:'\uF78D',51169:'\uF78E',51170:'\uF78F',51171:'\uF790',51172:'\uF791',51173:'\uF792',51174:'\uF793',51175:'\uF794',51176:'\uF795',51177:'\uF796',51178:'\uF797',51179:'\uF798',51180:'\uF799',51181:'\uF79A',51182:'\uF79B',51183:'\uF79C',51184:'\uF79D',51185:'\uF79E',51186:'\uF79F',51187:'\uF7A0',51188:'\uF7A1',51189:'\uF7A2',51190:'\uF7A3',51191:'\uF7A4',51192:'\uF7A5',51193:'\uF7A6',51194:'\uF7A7',51195:'\uF7A8',51196:'\uF7A9',51197:'\uF7AA',51198:'\uF7AB',51264:'\uF7AC',51265:'\uF7AD',51266:'\uF7AE',51267:'\uF7AF',51268:'\uF7B0',51269:'\uF7B1',51270:'\uF7B2',51271:'\uF7B3',51272:'\uF7B4',51273:'\uF7B5',51274:'\uF7B6',51275:'\uF7B7',51276:'\uF7B8',51277:'\uF7B9',51278:'\uF7BA',51279:'\uF7BB',51280:'\uF7BC',51281:'\uF7BD',51282:'\uF7BE',51283:'\uF7BF',51284:'\uF7C0',51285:'\uF7C1',51286:'\uF7C2',51287:'\uF7C3',51288:'\uF7C4',51289:'\uF7C5',51290:'\uF7C6',51291:'\uF7C7',51292:'\uF7C8',51293:'\uF7C9',51294:'\uF7CA',51295:'\uF7CB',51296:'\uF7CC',51297:'\uF7CD',51298:'\uF7CE',51299:'\uF7CF',51300:'\uF7D0',51301:'\uF7D1',51302:'\uF7D2',51303:'\uF7D3',51304:'\uF7D4',51305:'\uF7D5',51306:'\uF7D6',51307:'\uF7D7',51308:'\uF7D8',51309:'\uF7D9',51310:'\uF7DA',51311:'\uF7DB',51312:'\uF7DC',51313:'\uF7DD',51314:'\uF7DE',51315:'\uF7DF',51316:'\uF7E0',51317:'\uF7E1',51318:'\uF7E2',51319:'\uF7E3',51320:'\uF7E4',51321:'\uF7E5',51322:'\uF7E6',51323:'\uF7E7',51324:'\uF7E8',51325:'\uF7E9',51326:'\uF7EA',51361:'\uF7EB',51362:'\uF7EC',51363:'\uF7ED',51364:'\uF7EE',51365:'\uF7EF',51366:'\uF7F0',51367:'\uF7F1',51368:'\uF7F2',51369:'\uF7F3',51370:'\uF7F4',51371:'\uF7F5',51372:'\uF7F6',51373:'\uF7F7',51374:'\uF7F8',51375:'\uF7F9',51376:'\uF7FA',51377:'\uF7FB',51378:'\uF7FC',51379:'\uF7FD',51380:'\uF7FE',51381:'\uF7FF',51382:'\uF800',51383:'\uF801',51384:'\uF802',51385:'\uF803',51386:'\uF804',51387:'\uF805',51388:'\uF806',51389:'\uF807',51390:'\uF808',51391:'\uF809',51392:'\uF80A',51393:'\uF80B',51394:'\uF80C',51395:'\uF80D',51396:'\uF80E',51397:'\uF80F',51398:'\uF810',51399:'\uF811',51400:'\uF812',51401:'\uF813',51402:'\uF814',51403:'\uF815',51404:'\uF816',51405:'\uF817',51406:'\uF818',51407:'\uF819',51408:'\uF81A',51409:'\uF81B',51410:'\uF81C',51411:'\uF81D',51412:'\uF81E',51413:'\uF81F',51414:'\uF820',51415:'\uF821',51416:'\uF822',51417:'\uF823',51418:'\uF824',51419:'\uF825',51420:'\uF826',51421:'\uF827',51422:'\uF828',51423:'\uF829',51424:'\uF82A',51425:'\uF82B',51426:'\uF82C',51427:'\uF82D',51428:'\uF82E',51429:'\uF82F',51430:'\uF830',51431:'\uF831',51432:'\uF832',51433:'\uF833',51434:'\uF834',51435:'\uF835',51436:'\uF836',51437:'\uF837',51438:'\uF838',51439:'\uF839',51440:'\uF83A',51441:'\uF83B',51442:'\uF83C',51443:'\uF83D',51444:'\uF83E',51445:'\uF83F',51446:'\uF840',51447:'\uF841',51448:'\uF842',51449:'\uF843',51450:'\uF844',51451:'\uF845',51452:'\uF846',51453:'\uF847',51454:'\uF848',51520:'\u4E42',51521:'\u4E5C',51522:'\u51F5',51523:'\u531A',51524:'\u5382',51525:'\u4E07',51526:'\u4E0C',51527:'\u4E47',51528:'\u4E8D',51529:'\u56D7',51530:'\uFA0C',51531:'\u5C6E',51532:'\u5F73',51533:'\u4E0F',51534:'\u5187',51535:'\u4E0E',51536:'\u4E2E',51537:'\u4E93',51538:'\u4EC2',51539:'\u4EC9',51540:'\u4EC8',51541:'\u5198',51542:'\u52FC',51543:'\u536C',51544:'\u53B9',51545:'\u5720',51546:'\u5903',51547:'\u592C',51548:'\u5C10',51549:'\u5DFF',51550:'\u65E1',51551:'\u6BB3',51552:'\u6BCC',51553:'\u6C14',51554:'\u723F',51555:'\u4E31',51556:'\u4E3C',51557:'\u4EE8',51558:'\u4EDC',51559:'\u4EE9',51560:'\u4EE1',51561:'\u4EDD',51562:'\u4EDA',51563:'\u520C',51564:'\u531C',51565:'\u534C',51566:'\u5722',51567:'\u5723',51568:'\u5917',51569:'\u592F',51570:'\u5B81',51571:'\u5B84',51572:'\u5C12',51573:'\u5C3B',51574:'\u5C74',51575:'\u5C73',51576:'\u5E04',51577:'\u5E80',51578:'\u5E82',51579:'\u5FC9',51580:'\u6209',51581:'\u6250',51582:'\u6C15',51617:'\u6C36',51618:'\u6C43',51619:'\u6C3F',51620:'\u6C3B',51621:'\u72AE',51622:'\u72B0',51623:'\u738A',51624:'\u79B8',51625:'\u808A',51626:'\u961E',51627:'\u4F0E',51628:'\u4F18',51629:'\u4F2C',51630:'\u4EF5',51631:'\u4F14',51632:'\u4EF1',51633:'\u4F00',51634:'\u4EF7',51635:'\u4F08',51636:'\u4F1D',51637:'\u4F02',51638:'\u4F05',51639:'\u4F22',51640:'\u4F13',51641:'\u4F04',51642:'\u4EF4',51643:'\u4F12',51644:'\u51B1',51645:'\u5213',51646:'\u5209',51647:'\u5210',51648:'\u52A6',51649:'\u5322',51650:'\u531F',51651:'\u534D',51652:'\u538A',51653:'\u5407',51654:'\u56E1',51655:'\u56DF',51656:'\u572E',51657:'\u572A',51658:'\u5734',51659:'\u593C',51660:'\u5980',51661:'\u597C',51662:'\u5985',51663:'\u597B',51664:'\u597E',51665:'\u5977',51666:'\u597F',51667:'\u5B56',51668:'\u5C15',51669:'\u5C25',51670:'\u5C7C',51671:'\u5C7A',51672:'\u5C7B',51673:'\u5C7E',51674:'\u5DDF',51675:'\u5E75',51676:'\u5E84',51677:'\u5F02',51678:'\u5F1A',51679:'\u5F74',51680:'\u5FD5',51681:'\u5FD4',51682:'\u5FCF',51683:'\u625C',51684:'\u625E',51685:'\u6264',51686:'\u6261',51687:'\u6266',51688:'\u6262',51689:'\u6259',51690:'\u6260',51691:'\u625A',51692:'\u6265',51693:'\u65EF',51694:'\u65EE',51695:'\u673E',51696:'\u6739',51697:'\u6738',51698:'\u673B',51699:'\u673A',51700:'\u673F',51701:'\u673C',51702:'\u6733',51703:'\u6C18',51704:'\u6C46',51705:'\u6C52',51706:'\u6C5C',51707:'\u6C4F',51708:'\u6C4A',51709:'\u6C54',51710:'\u6C4B',51776:'\u6C4C',51777:'\u7071',51778:'\u725E',51779:'\u72B4',51780:'\u72B5',51781:'\u738E',51782:'\u752A',51783:'\u767F',51784:'\u7A75',51785:'\u7F51',51786:'\u8278',51787:'\u827C',51788:'\u8280',51789:'\u827D',51790:'\u827F',51791:'\u864D',51792:'\u897E',51793:'\u9099',51794:'\u9097',51795:'\u9098',51796:'\u909B',51797:'\u9094',51798:'\u9622',51799:'\u9624',51800:'\u9620',51801:'\u9623',51802:'\u4F56',51803:'\u4F3B',51804:'\u4F62',51805:'\u4F49',51806:'\u4F53',51807:'\u4F64',51808:'\u4F3E',51809:'\u4F67',51810:'\u4F52',51811:'\u4F5F',51812:'\u4F41',51813:'\u4F58',51814:'\u4F2D',51815:'\u4F33',51816:'\u4F3F',51817:'\u4F61',51818:'\u518F',51819:'\u51B9',51820:'\u521C',51821:'\u521E',51822:'\u5221',51823:'\u52AD',51824:'\u52AE',51825:'\u5309',51826:'\u5363',51827:'\u5372',51828:'\u538E',51829:'\u538F',51830:'\u5430',51831:'\u5437',51832:'\u542A',51833:'\u5454',51834:'\u5445',51835:'\u5419',51836:'\u541C',51837:'\u5425',51838:'\u5418',51873:'\u543D',51874:'\u544F',51875:'\u5441',51876:'\u5428',51877:'\u5424',51878:'\u5447',51879:'\u56EE',51880:'\u56E7',51881:'\u56E5',51882:'\u5741',51883:'\u5745',51884:'\u574C',51885:'\u5749',51886:'\u574B',51887:'\u5752',51888:'\u5906',51889:'\u5940',51890:'\u59A6',51891:'\u5998',51892:'\u59A0',51893:'\u5997',51894:'\u598E',51895:'\u59A2',51896:'\u5990',51897:'\u598F',51898:'\u59A7',51899:'\u59A1',51900:'\u5B8E',51901:'\u5B92',51902:'\u5C28',51903:'\u5C2A',51904:'\u5C8D',51905:'\u5C8F',51906:'\u5C88',51907:'\u5C8B',51908:'\u5C89',51909:'\u5C92',51910:'\u5C8A',51911:'\u5C86',51912:'\u5C93',51913:'\u5C95',51914:'\u5DE0',51915:'\u5E0A',51916:'\u5E0E',51917:'\u5E8B',51918:'\u5E89',51919:'\u5E8C',51920:'\u5E88',51921:'\u5E8D',51922:'\u5F05',51923:'\u5F1D',51924:'\u5F78',51925:'\u5F76',51926:'\u5FD2',51927:'\u5FD1',51928:'\u5FD0',51929:'\u5FED',51930:'\u5FE8',51931:'\u5FEE',51932:'\u5FF3',51933:'\u5FE1',51934:'\u5FE4',51935:'\u5FE3',51936:'\u5FFA',51937:'\u5FEF',51938:'\u5FF7',51939:'\u5FFB',51940:'\u6000',51941:'\u5FF4',51942:'\u623A',51943:'\u6283',51944:'\u628C',51945:'\u628E',51946:'\u628F',51947:'\u6294',51948:'\u6287',51949:'\u6271',51950:'\u627B',51951:'\u627A',51952:'\u6270',51953:'\u6281',51954:'\u6288',51955:'\u6277',51956:'\u627D',51957:'\u6272',51958:'\u6274',51959:'\u6537',51960:'\u65F0',51961:'\u65F4',51962:'\u65F3',51963:'\u65F2',51964:'\u65F5',51965:'\u6745',51966:'\u6747',52032:'\u6759',52033:'\u6755',52034:'\u674C',52035:'\u6748',52036:'\u675D',52037:'\u674D',52038:'\u675A',52039:'\u674B',52040:'\u6BD0',52041:'\u6C19',52042:'\u6C1A',52043:'\u6C78',52044:'\u6C67',52045:'\u6C6B',52046:'\u6C84',52047:'\u6C8B',52048:'\u6C8F',52049:'\u6C71',52050:'\u6C6F',52051:'\u6C69',52052:'\u6C9A',52053:'\u6C6D',52054:'\u6C87',52055:'\u6C95',52056:'\u6C9C',52057:'\u6C66',52058:'\u6C73',52059:'\u6C65',52060:'\u6C7B',52061:'\u6C8E',52062:'\u7074',52063:'\u707A',52064:'\u7263',52065:'\u72BF',52066:'\u72BD',52067:'\u72C3',52068:'\u72C6',52069:'\u72C1',52070:'\u72BA',52071:'\u72C5',52072:'\u7395',52073:'\u7397',52074:'\u7393',52075:'\u7394',52076:'\u7392',52077:'\u753A',52078:'\u7539',52079:'\u7594',52080:'\u7595',52081:'\u7681',52082:'\u793D',52083:'\u8034',52084:'\u8095',52085:'\u8099',52086:'\u8090',52087:'\u8092',52088:'\u809C',52089:'\u8290',52090:'\u828F',52091:'\u8285',52092:'\u828E',52093:'\u8291',52094:'\u8293',52129:'\u828A',52130:'\u8283',52131:'\u8284',52132:'\u8C78',52133:'\u8FC9',52134:'\u8FBF',52135:'\u909F',52136:'\u90A1',52137:'\u90A5',52138:'\u909E',52139:'\u90A7',52140:'\u90A0',52141:'\u9630',52142:'\u9628',52143:'\u962F',52144:'\u962D',52145:'\u4E33',52146:'\u4F98',52147:'\u4F7C',52148:'\u4F85',52149:'\u4F7D',52150:'\u4F80',52151:'\u4F87',52152:'\u4F76',52153:'\u4F74',52154:'\u4F89',52155:'\u4F84',52156:'\u4F77',52157:'\u4F4C',52158:'\u4F97',52159:'\u4F6A',52160:'\u4F9A',52161:'\u4F79',52162:'\u4F81',52163:'\u4F78',52164:'\u4F90',52165:'\u4F9C',52166:'\u4F94',52167:'\u4F9E',52168:'\u4F92',52169:'\u4F82',52170:'\u4F95',52171:'\u4F6B',52172:'\u4F6E',52173:'\u519E',52174:'\u51BC',52175:'\u51BE',52176:'\u5235',52177:'\u5232',52178:'\u5233',52179:'\u5246',52180:'\u5231',52181:'\u52BC',52182:'\u530A',52183:'\u530B',52184:'\u533C',52185:'\u5392',52186:'\u5394',52187:'\u5487',52188:'\u547F',52189:'\u5481',52190:'\u5491',52191:'\u5482',52192:'\u5488',52193:'\u546B',52194:'\u547A',52195:'\u547E',52196:'\u5465',52197:'\u546C',52198:'\u5474',52199:'\u5466',52200:'\u548D',52201:'\u546F',52202:'\u5461',52203:'\u5460',52204:'\u5498',52205:'\u5463',52206:'\u5467',52207:'\u5464',52208:'\u56F7',52209:'\u56F9',52210:'\u576F',52211:'\u5772',52212:'\u576D',52213:'\u576B',52214:'\u5771',52215:'\u5770',52216:'\u5776',52217:'\u5780',52218:'\u5775',52219:'\u577B',52220:'\u5773',52221:'\u5774',52222:'\u5762',52288:'\u5768',52289:'\u577D',52290:'\u590C',52291:'\u5945',52292:'\u59B5',52293:'\u59BA',52294:'\u59CF',52295:'\u59CE',52296:'\u59B2',52297:'\u59CC',52298:'\u59C1',52299:'\u59B6',52300:'\u59BC',52301:'\u59C3',52302:'\u59D6',52303:'\u59B1',52304:'\u59BD',52305:'\u59C0',52306:'\u59C8',52307:'\u59B4',52308:'\u59C7',52309:'\u5B62',52310:'\u5B65',52311:'\u5B93',52312:'\u5B95',52313:'\u5C44',52314:'\u5C47',52315:'\u5CAE',52316:'\u5CA4',52317:'\u5CA0',52318:'\u5CB5',52319:'\u5CAF',52320:'\u5CA8',52321:'\u5CAC',52322:'\u5C9F',52323:'\u5CA3',52324:'\u5CAD',52325:'\u5CA2',52326:'\u5CAA',52327:'\u5CA7',52328:'\u5C9D',52329:'\u5CA5',52330:'\u5CB6',52331:'\u5CB0',52332:'\u5CA6',52333:'\u5E17',52334:'\u5E14',52335:'\u5E19',52336:'\u5F28',52337:'\u5F22',52338:'\u5F23',52339:'\u5F24',52340:'\u5F54',52341:'\u5F82',52342:'\u5F7E',52343:'\u5F7D',52344:'\u5FDE',52345:'\u5FE5',52346:'\u602D',52347:'\u6026',52348:'\u6019',52349:'\u6032',52350:'\u600B',52385:'\u6034',52386:'\u600A',52387:'\u6017',52388:'\u6033',52389:'\u601A',52390:'\u601E',52391:'\u602C',52392:'\u6022',52393:'\u600D',52394:'\u6010',52395:'\u602E',52396:'\u6013',52397:'\u6011',52398:'\u600C',52399:'\u6009',52400:'\u601C',52401:'\u6214',52402:'\u623D',52403:'\u62AD',52404:'\u62B4',52405:'\u62D1',52406:'\u62BE',52407:'\u62AA',52408:'\u62B6',52409:'\u62CA',52410:'\u62AE',52411:'\u62B3',52412:'\u62AF',52413:'\u62BB',52414:'\u62A9',52415:'\u62B0',52416:'\u62B8',52417:'\u653D',52418:'\u65A8',52419:'\u65BB',52420:'\u6609',52421:'\u65FC',52422:'\u6604',52423:'\u6612',52424:'\u6608',52425:'\u65FB',52426:'\u6603',52427:'\u660B',52428:'\u660D',52429:'\u6605',52430:'\u65FD',52431:'\u6611',52432:'\u6610',52433:'\u66F6',52434:'\u670A',52435:'\u6785',52436:'\u676C',52437:'\u678E',52438:'\u6792',52439:'\u6776',52440:'\u677B',52441:'\u6798',52442:'\u6786',52443:'\u6784',52444:'\u6774',52445:'\u678D',52446:'\u678C',52447:'\u677A',52448:'\u679F',52449:'\u6791',52450:'\u6799',52451:'\u6783',52452:'\u677D',52453:'\u6781',52454:'\u6778',52455:'\u6779',52456:'\u6794',52457:'\u6B25',52458:'\u6B80',52459:'\u6B7E',52460:'\u6BDE',52461:'\u6C1D',52462:'\u6C93',52463:'\u6CEC',52464:'\u6CEB',52465:'\u6CEE',52466:'\u6CD9',52467:'\u6CB6',52468:'\u6CD4',52469:'\u6CAD',52470:'\u6CE7',52471:'\u6CB7',52472:'\u6CD0',52473:'\u6CC2',52474:'\u6CBA',52475:'\u6CC3',52476:'\u6CC6',52477:'\u6CED',52478:'\u6CF2',52544:'\u6CD2',52545:'\u6CDD',52546:'\u6CB4',52547:'\u6C8A',52548:'\u6C9D',52549:'\u6C80',52550:'\u6CDE',52551:'\u6CC0',52552:'\u6D30',52553:'\u6CCD',52554:'\u6CC7',52555:'\u6CB0',52556:'\u6CF9',52557:'\u6CCF',52558:'\u6CE9',52559:'\u6CD1',52560:'\u7094',52561:'\u7098',52562:'\u7085',52563:'\u7093',52564:'\u7086',52565:'\u7084',52566:'\u7091',52567:'\u7096',52568:'\u7082',52569:'\u709A',52570:'\u7083',52571:'\u726A',52572:'\u72D6',52573:'\u72CB',52574:'\u72D8',52575:'\u72C9',52576:'\u72DC',52577:'\u72D2',52578:'\u72D4',52579:'\u72DA',52580:'\u72CC',52581:'\u72D1',52582:'\u73A4',52583:'\u73A1',52584:'\u73AD',52585:'\u73A6',52586:'\u73A2',52587:'\u73A0',52588:'\u73AC',52589:'\u739D',52590:'\u74DD',52591:'\u74E8',52592:'\u753F',52593:'\u7540',52594:'\u753E',52595:'\u758C',52596:'\u7598',52597:'\u76AF',52598:'\u76F3',52599:'\u76F1',52600:'\u76F0',52601:'\u76F5',52602:'\u77F8',52603:'\u77FC',52604:'\u77F9',52605:'\u77FB',52606:'\u77FA',52641:'\u77F7',52642:'\u7942',52643:'\u793F',52644:'\u79C5',52645:'\u7A78',52646:'\u7A7B',52647:'\u7AFB',52648:'\u7C75',52649:'\u7CFD',52650:'\u8035',52651:'\u808F',52652:'\u80AE',52653:'\u80A3',52654:'\u80B8',52655:'\u80B5',52656:'\u80AD',52657:'\u8220',52658:'\u82A0',52659:'\u82C0',52660:'\u82AB',52661:'\u829A',52662:'\u8298',52663:'\u829B',52664:'\u82B5',52665:'\u82A7',52666:'\u82AE',52667:'\u82BC',52668:'\u829E',52669:'\u82BA',52670:'\u82B4',52671:'\u82A8',52672:'\u82A1',52673:'\u82A9',52674:'\u82C2',52675:'\u82A4',52676:'\u82C3',52677:'\u82B6',52678:'\u82A2',52679:'\u8670',52680:'\u866F',52681:'\u866D',52682:'\u866E',52683:'\u8C56',52684:'\u8FD2',52685:'\u8FCB',52686:'\u8FD3',52687:'\u8FCD',52688:'\u8FD6',52689:'\u8FD5',52690:'\u8FD7',52691:'\u90B2',52692:'\u90B4',52693:'\u90AF',52694:'\u90B3',52695:'\u90B0',52696:'\u9639',52697:'\u963D',52698:'\u963C',52699:'\u963A',52700:'\u9643',52701:'\u4FCD',52702:'\u4FC5',52703:'\u4FD3',52704:'\u4FB2',52705:'\u4FC9',52706:'\u4FCB',52707:'\u4FC1',52708:'\u4FD4',52709:'\u4FDC',52710:'\u4FD9',52711:'\u4FBB',52712:'\u4FB3',52713:'\u4FDB',52714:'\u4FC7',52715:'\u4FD6',52716:'\u4FBA',52717:'\u4FC0',52718:'\u4FB9',52719:'\u4FEC',52720:'\u5244',52721:'\u5249',52722:'\u52C0',52723:'\u52C2',52724:'\u533D',52725:'\u537C',52726:'\u5397',52727:'\u5396',52728:'\u5399',52729:'\u5398',52730:'\u54BA',52731:'\u54A1',52732:'\u54AD',52733:'\u54A5',52734:'\u54CF',52800:'\u54C3',52801:'\u830D',52802:'\u54B7',52803:'\u54AE',52804:'\u54D6',52805:'\u54B6',52806:'\u54C5',52807:'\u54C6',52808:'\u54A0',52809:'\u5470',52810:'\u54BC',52811:'\u54A2',52812:'\u54BE',52813:'\u5472',52814:'\u54DE',52815:'\u54B0',52816:'\u57B5',52817:'\u579E',52818:'\u579F',52819:'\u57A4',52820:'\u578C',52821:'\u5797',52822:'\u579D',52823:'\u579B',52824:'\u5794',52825:'\u5798',52826:'\u578F',52827:'\u5799',52828:'\u57A5',52829:'\u579A',52830:'\u5795',52831:'\u58F4',52832:'\u590D',52833:'\u5953',52834:'\u59E1',52835:'\u59DE',52836:'\u59EE',52837:'\u5A00',52838:'\u59F1',52839:'\u59DD',52840:'\u59FA',52841:'\u59FD',52842:'\u59FC',52843:'\u59F6',52844:'\u59E4',52845:'\u59F2',52846:'\u59F7',52847:'\u59DB',52848:'\u59E9',52849:'\u59F3',52850:'\u59F5',52851:'\u59E0',52852:'\u59FE',52853:'\u59F4',52854:'\u59ED',52855:'\u5BA8',52856:'\u5C4C',52857:'\u5CD0',52858:'\u5CD8',52859:'\u5CCC',52860:'\u5CD7',52861:'\u5CCB',52862:'\u5CDB',52897:'\u5CDE',52898:'\u5CDA',52899:'\u5CC9',52900:'\u5CC7',52901:'\u5CCA',52902:'\u5CD6',52903:'\u5CD3',52904:'\u5CD4',52905:'\u5CCF',52906:'\u5CC8',52907:'\u5CC6',52908:'\u5CCE',52909:'\u5CDF',52910:'\u5CF8',52911:'\u5DF9',52912:'\u5E21',52913:'\u5E22',52914:'\u5E23',52915:'\u5E20',52916:'\u5E24',52917:'\u5EB0',52918:'\u5EA4',52919:'\u5EA2',52920:'\u5E9B',52921:'\u5EA3',52922:'\u5EA5',52923:'\u5F07',52924:'\u5F2E',52925:'\u5F56',52926:'\u5F86',52927:'\u6037',52928:'\u6039',52929:'\u6054',52930:'\u6072',52931:'\u605E',52932:'\u6045',52933:'\u6053',52934:'\u6047',52935:'\u6049',52936:'\u605B',52937:'\u604C',52938:'\u6040',52939:'\u6042',52940:'\u605F',52941:'\u6024',52942:'\u6044',52943:'\u6058',52944:'\u6066',52945:'\u606E',52946:'\u6242',52947:'\u6243',52948:'\u62CF',52949:'\u630D',52950:'\u630B',52951:'\u62F5',52952:'\u630E',52953:'\u6303',52954:'\u62EB',52955:'\u62F9',52956:'\u630F',52957:'\u630C',52958:'\u62F8',52959:'\u62F6',52960:'\u6300',52961:'\u6313',52962:'\u6314',52963:'\u62FA',52964:'\u6315',52965:'\u62FB',52966:'\u62F0',52967:'\u6541',52968:'\u6543',52969:'\u65AA',52970:'\u65BF',52971:'\u6636',52972:'\u6621',52973:'\u6632',52974:'\u6635',52975:'\u661C',52976:'\u6626',52977:'\u6622',52978:'\u6633',52979:'\u662B',52980:'\u663A',52981:'\u661D',52982:'\u6634',52983:'\u6639',52984:'\u662E',52985:'\u670F',52986:'\u6710',52987:'\u67C1',52988:'\u67F2',52989:'\u67C8',52990:'\u67BA',53056:'\u67DC',53057:'\u67BB',53058:'\u67F8',53059:'\u67D8',53060:'\u67C0',53061:'\u67B7',53062:'\u67C5',53063:'\u67EB',53064:'\u67E4',53065:'\u67DF',53066:'\u67B5',53067:'\u67CD',53068:'\u67B3',53069:'\u67F7',53070:'\u67F6',53071:'\u67EE',53072:'\u67E3',53073:'\u67C2',53074:'\u67B9',53075:'\u67CE',53076:'\u67E7',53077:'\u67F0',53078:'\u67B2',53079:'\u67FC',53080:'\u67C6',53081:'\u67ED',53082:'\u67CC',53083:'\u67AE',53084:'\u67E6',53085:'\u67DB',53086:'\u67FA',53087:'\u67C9',53088:'\u67CA',53089:'\u67C3',53090:'\u67EA',53091:'\u67CB',53092:'\u6B28',53093:'\u6B82',53094:'\u6B84',53095:'\u6BB6',53096:'\u6BD6',53097:'\u6BD8',53098:'\u6BE0',53099:'\u6C20',53100:'\u6C21',53101:'\u6D28',53102:'\u6D34',53103:'\u6D2D',53104:'\u6D1F',53105:'\u6D3C',53106:'\u6D3F',53107:'\u6D12',53108:'\u6D0A',53109:'\u6CDA',53110:'\u6D33',53111:'\u6D04',53112:'\u6D19',53113:'\u6D3A',53114:'\u6D1A',53115:'\u6D11',53116:'\u6D00',53117:'\u6D1D',53118:'\u6D42',53153:'\u6D01',53154:'\u6D18',53155:'\u6D37',53156:'\u6D03',53157:'\u6D0F',53158:'\u6D40',53159:'\u6D07',53160:'\u6D20',53161:'\u6D2C',53162:'\u6D08',53163:'\u6D22',53164:'\u6D09',53165:'\u6D10',53166:'\u70B7',53167:'\u709F',53168:'\u70BE',53169:'\u70B1',53170:'\u70B0',53171:'\u70A1',53172:'\u70B4',53173:'\u70B5',53174:'\u70A9',53175:'\u7241',53176:'\u7249',53177:'\u724A',53178:'\u726C',53179:'\u7270',53180:'\u7273',53181:'\u726E',53182:'\u72CA',53183:'\u72E4',53184:'\u72E8',53185:'\u72EB',53186:'\u72DF',53187:'\u72EA',53188:'\u72E6',53189:'\u72E3',53190:'\u7385',53191:'\u73CC',53192:'\u73C2',53193:'\u73C8',53194:'\u73C5',53195:'\u73B9',53196:'\u73B6',53197:'\u73B5',53198:'\u73B4',53199:'\u73EB',53200:'\u73BF',53201:'\u73C7',53202:'\u73BE',53203:'\u73C3',53204:'\u73C6',53205:'\u73B8',53206:'\u73CB',53207:'\u74EC',53208:'\u74EE',53209:'\u752E',53210:'\u7547',53211:'\u7548',53212:'\u75A7',53213:'\u75AA',53214:'\u7679',53215:'\u76C4',53216:'\u7708',53217:'\u7703',53218:'\u7704',53219:'\u7705',53220:'\u770A',53221:'\u76F7',53222:'\u76FB',53223:'\u76FA',53224:'\u77E7',53225:'\u77E8',53226:'\u7806',53227:'\u7811',53228:'\u7812',53229:'\u7805',53230:'\u7810',53231:'\u780F',53232:'\u780E',53233:'\u7809',53234:'\u7803',53235:'\u7813',53236:'\u794A',53237:'\u794C',53238:'\u794B',53239:'\u7945',53240:'\u7944',53241:'\u79D5',53242:'\u79CD',53243:'\u79CF',53244:'\u79D6',53245:'\u79CE',53246:'\u7A80',53312:'\u7A7E',53313:'\u7AD1',53314:'\u7B00',53315:'\u7B01',53316:'\u7C7A',53317:'\u7C78',53318:'\u7C79',53319:'\u7C7F',53320:'\u7C80',53321:'\u7C81',53322:'\u7D03',53323:'\u7D08',53324:'\u7D01',53325:'\u7F58',53326:'\u7F91',53327:'\u7F8D',53328:'\u7FBE',53329:'\u8007',53330:'\u800E',53331:'\u800F',53332:'\u8014',53333:'\u8037',53334:'\u80D8',53335:'\u80C7',53336:'\u80E0',53337:'\u80D1',53338:'\u80C8',53339:'\u80C2',53340:'\u80D0',53341:'\u80C5',53342:'\u80E3',53343:'\u80D9',53344:'\u80DC',53345:'\u80CA',53346:'\u80D5',53347:'\u80C9',53348:'\u80CF',53349:'\u80D7',53350:'\u80E6',53351:'\u80CD',53352:'\u81FF',53353:'\u8221',53354:'\u8294',53355:'\u82D9',53356:'\u82FE',53357:'\u82F9',53358:'\u8307',53359:'\u82E8',53360:'\u8300',53361:'\u82D5',53362:'\u833A',53363:'\u82EB',53364:'\u82D6',53365:'\u82F4',53366:'\u82EC',53367:'\u82E1',53368:'\u82F2',53369:'\u82F5',53370:'\u830C',53371:'\u82FB',53372:'\u82F6',53373:'\u82F0',53374:'\u82EA',53409:'\u82E4',53410:'\u82E0',53411:'\u82FA',53412:'\u82F3',53413:'\u82ED',53414:'\u8677',53415:'\u8674',53416:'\u867C',53417:'\u8673',53418:'\u8841',53419:'\u884E',53420:'\u8867',53421:'\u886A',53422:'\u8869',53423:'\u89D3',53424:'\u8A04',53425:'\u8A07',53426:'\u8D72',53427:'\u8FE3',53428:'\u8FE1',53429:'\u8FEE',53430:'\u8FE0',53431:'\u90F1',53432:'\u90BD',53433:'\u90BF',53434:'\u90D5',53435:'\u90C5',53436:'\u90BE',53437:'\u90C7',53438:'\u90CB',53439:'\u90C8',53440:'\u91D4',53441:'\u91D3',53442:'\u9654',53443:'\u964F',53444:'\u9651',53445:'\u9653',53446:'\u964A',53447:'\u964E',53448:'\u501E',53449:'\u5005',53450:'\u5007',53451:'\u5013',53452:'\u5022',53453:'\u5030',53454:'\u501B',53455:'\u4FF5',53456:'\u4FF4',53457:'\u5033',53458:'\u5037',53459:'\u502C',53460:'\u4FF6',53461:'\u4FF7',53462:'\u5017',53463:'\u501C',53464:'\u5020',53465:'\u5027',53466:'\u5035',53467:'\u502F',53468:'\u5031',53469:'\u500E',53470:'\u515A',53471:'\u5194',53472:'\u5193',53473:'\u51CA',53474:'\u51C4',53475:'\u51C5',53476:'\u51C8',53477:'\u51CE',53478:'\u5261',53479:'\u525A',53480:'\u5252',53481:'\u525E',53482:'\u525F',53483:'\u5255',53484:'\u5262',53485:'\u52CD',53486:'\u530E',53487:'\u539E',53488:'\u5526',53489:'\u54E2',53490:'\u5517',53491:'\u5512',53492:'\u54E7',53493:'\u54F3',53494:'\u54E4',53495:'\u551A',53496:'\u54FF',53497:'\u5504',53498:'\u5508',53499:'\u54EB',53500:'\u5511',53501:'\u5505',53502:'\u54F1',53568:'\u550A',53569:'\u54FB',53570:'\u54F7',53571:'\u54F8',53572:'\u54E0',53573:'\u550E',53574:'\u5503',53575:'\u550B',53576:'\u5701',53577:'\u5702',53578:'\u57CC',53579:'\u5832',53580:'\u57D5',53581:'\u57D2',53582:'\u57BA',53583:'\u57C6',53584:'\u57BD',53585:'\u57BC',53586:'\u57B8',53587:'\u57B6',53588:'\u57BF',53589:'\u57C7',53590:'\u57D0',53591:'\u57B9',53592:'\u57C1',53593:'\u590E',53594:'\u594A',53595:'\u5A19',53596:'\u5A16',53597:'\u5A2D',53598:'\u5A2E',53599:'\u5A15',53600:'\u5A0F',53601:'\u5A17',53602:'\u5A0A',53603:'\u5A1E',53604:'\u5A33',53605:'\u5B6C',53606:'\u5BA7',53607:'\u5BAD',53608:'\u5BAC',53609:'\u5C03',53610:'\u5C56',53611:'\u5C54',53612:'\u5CEC',53613:'\u5CFF',53614:'\u5CEE',53615:'\u5CF1',53616:'\u5CF7',53617:'\u5D00',53618:'\u5CF9',53619:'\u5E29',53620:'\u5E28',53621:'\u5EA8',53622:'\u5EAE',53623:'\u5EAA',53624:'\u5EAC',53625:'\u5F33',53626:'\u5F30',53627:'\u5F67',53628:'\u605D',53629:'\u605A',53630:'\u6067',53665:'\u6041',53666:'\u60A2',53667:'\u6088',53668:'\u6080',53669:'\u6092',53670:'\u6081',53671:'\u609D',53672:'\u6083',53673:'\u6095',53674:'\u609B',53675:'\u6097',53676:'\u6087',53677:'\u609C',53678:'\u608E',53679:'\u6219',53680:'\u6246',53681:'\u62F2',53682:'\u6310',53683:'\u6356',53684:'\u632C',53685:'\u6344',53686:'\u6345',53687:'\u6336',53688:'\u6343',53689:'\u63E4',53690:'\u6339',53691:'\u634B',53692:'\u634A',53693:'\u633C',53694:'\u6329',53695:'\u6341',53696:'\u6334',53697:'\u6358',53698:'\u6354',53699:'\u6359',53700:'\u632D',53701:'\u6347',53702:'\u6333',53703:'\u635A',53704:'\u6351',53705:'\u6338',53706:'\u6357',53707:'\u6340',53708:'\u6348',53709:'\u654A',53710:'\u6546',53711:'\u65C6',53712:'\u65C3',53713:'\u65C4',53714:'\u65C2',53715:'\u664A',53716:'\u665F',53717:'\u6647',53718:'\u6651',53719:'\u6712',53720:'\u6713',53721:'\u681F',53722:'\u681A',53723:'\u6849',53724:'\u6832',53725:'\u6833',53726:'\u683B',53727:'\u684B',53728:'\u684F',53729:'\u6816',53730:'\u6831',53731:'\u681C',53732:'\u6835',53733:'\u682B',53734:'\u682D',53735:'\u682F',53736:'\u684E',53737:'\u6844',53738:'\u6834',53739:'\u681D',53740:'\u6812',53741:'\u6814',53742:'\u6826',53743:'\u6828',53744:'\u682E',53745:'\u684D',53746:'\u683A',53747:'\u6825',53748:'\u6820',53749:'\u6B2C',53750:'\u6B2F',53751:'\u6B2D',53752:'\u6B31',53753:'\u6B34',53754:'\u6B6D',53755:'\u8082',53756:'\u6B88',53757:'\u6BE6',53758:'\u6BE4',53824:'\u6BE8',53825:'\u6BE3',53826:'\u6BE2',53827:'\u6BE7',53828:'\u6C25',53829:'\u6D7A',53830:'\u6D63',53831:'\u6D64',53832:'\u6D76',53833:'\u6D0D',53834:'\u6D61',53835:'\u6D92',53836:'\u6D58',53837:'\u6D62',53838:'\u6D6D',53839:'\u6D6F',53840:'\u6D91',53841:'\u6D8D',53842:'\u6DEF',53843:'\u6D7F',53844:'\u6D86',53845:'\u6D5E',53846:'\u6D67',53847:'\u6D60',53848:'\u6D97',53849:'\u6D70',53850:'\u6D7C',53851:'\u6D5F',53852:'\u6D82',53853:'\u6D98',53854:'\u6D2F',53855:'\u6D68',53856:'\u6D8B',53857:'\u6D7E',53858:'\u6D80',53859:'\u6D84',53860:'\u6D16',53861:'\u6D83',53862:'\u6D7B',53863:'\u6D7D',53864:'\u6D75',53865:'\u6D90',53866:'\u70DC',53867:'\u70D3',53868:'\u70D1',53869:'\u70DD',53870:'\u70CB',53871:'\u7F39',53872:'\u70E2',53873:'\u70D7',53874:'\u70D2',53875:'\u70DE',53876:'\u70E0',53877:'\u70D4',53878:'\u70CD',53879:'\u70C5',53880:'\u70C6',53881:'\u70C7',53882:'\u70DA',53883:'\u70CE',53884:'\u70E1',53885:'\u7242',53886:'\u7278',53921:'\u7277',53922:'\u7276',53923:'\u7300',53924:'\u72FA',53925:'\u72F4',53926:'\u72FE',53927:'\u72F6',53928:'\u72F3',53929:'\u72FB',53930:'\u7301',53931:'\u73D3',53932:'\u73D9',53933:'\u73E5',53934:'\u73D6',53935:'\u73BC',53936:'\u73E7',53937:'\u73E3',53938:'\u73E9',53939:'\u73DC',53940:'\u73D2',53941:'\u73DB',53942:'\u73D4',53943:'\u73DD',53944:'\u73DA',53945:'\u73D7',53946:'\u73D8',53947:'\u73E8',53948:'\u74DE',53949:'\u74DF',53950:'\u74F4',53951:'\u74F5',53952:'\u7521',53953:'\u755B',53954:'\u755F',53955:'\u75B0',53956:'\u75C1',53957:'\u75BB',53958:'\u75C4',53959:'\u75C0',53960:'\u75BF',53961:'\u75B6',53962:'\u75BA',53963:'\u768A',53964:'\u76C9',53965:'\u771D',53966:'\u771B',53967:'\u7710',53968:'\u7713',53969:'\u7712',53970:'\u7723',53971:'\u7711',53972:'\u7715',53973:'\u7719',53974:'\u771A',53975:'\u7722',53976:'\u7727',53977:'\u7823',53978:'\u782C',53979:'\u7822',53980:'\u7835',53981:'\u782F',53982:'\u7828',53983:'\u782E',53984:'\u782B',53985:'\u7821',53986:'\u7829',53987:'\u7833',53988:'\u782A',53989:'\u7831',53990:'\u7954',53991:'\u795B',53992:'\u794F',53993:'\u795C',53994:'\u7953',53995:'\u7952',53996:'\u7951',53997:'\u79EB',53998:'\u79EC',53999:'\u79E0',54000:'\u79EE',54001:'\u79ED',54002:'\u79EA',54003:'\u79DC',54004:'\u79DE',54005:'\u79DD',54006:'\u7A86',54007:'\u7A89',54008:'\u7A85',54009:'\u7A8B',54010:'\u7A8C',54011:'\u7A8A',54012:'\u7A87',54013:'\u7AD8',54014:'\u7B10',54080:'\u7B04',54081:'\u7B13',54082:'\u7B05',54083:'\u7B0F',54084:'\u7B08',54085:'\u7B0A',54086:'\u7B0E',54087:'\u7B09',54088:'\u7B12',54089:'\u7C84',54090:'\u7C91',54091:'\u7C8A',54092:'\u7C8C',54093:'\u7C88',54094:'\u7C8D',54095:'\u7C85',54096:'\u7D1E',54097:'\u7D1D',54098:'\u7D11',54099:'\u7D0E',54100:'\u7D18',54101:'\u7D16',54102:'\u7D13',54103:'\u7D1F',54104:'\u7D12',54105:'\u7D0F',54106:'\u7D0C',54107:'\u7F5C',54108:'\u7F61',54109:'\u7F5E',54110:'\u7F60',54111:'\u7F5D',54112:'\u7F5B',54113:'\u7F96',54114:'\u7F92',54115:'\u7FC3',54116:'\u7FC2',54117:'\u7FC0',54118:'\u8016',54119:'\u803E',54120:'\u8039',54121:'\u80FA',54122:'\u80F2',54123:'\u80F9',54124:'\u80F5',54125:'\u8101',54126:'\u80FB',54127:'\u8100',54128:'\u8201',54129:'\u822F',54130:'\u8225',54131:'\u8333',54132:'\u832D',54133:'\u8344',54134:'\u8319',54135:'\u8351',54136:'\u8325',54137:'\u8356',54138:'\u833F',54139:'\u8341',54140:'\u8326',54141:'\u831C',54142:'\u8322',54177:'\u8342',54178:'\u834E',54179:'\u831B',54180:'\u832A',54181:'\u8308',54182:'\u833C',54183:'\u834D',54184:'\u8316',54185:'\u8324',54186:'\u8320',54187:'\u8337',54188:'\u832F',54189:'\u8329',54190:'\u8347',54191:'\u8345',54192:'\u834C',54193:'\u8353',54194:'\u831E',54195:'\u832C',54196:'\u834B',54197:'\u8327',54198:'\u8348',54199:'\u8653',54200:'\u8652',54201:'\u86A2',54202:'\u86A8',54203:'\u8696',54204:'\u868D',54205:'\u8691',54206:'\u869E',54207:'\u8687',54208:'\u8697',54209:'\u8686',54210:'\u868B',54211:'\u869A',54212:'\u8685',54213:'\u86A5',54214:'\u8699',54215:'\u86A1',54216:'\u86A7',54217:'\u8695',54218:'\u8698',54219:'\u868E',54220:'\u869D',54221:'\u8690',54222:'\u8694',54223:'\u8843',54224:'\u8844',54225:'\u886D',54226:'\u8875',54227:'\u8876',54228:'\u8872',54229:'\u8880',54230:'\u8871',54231:'\u887F',54232:'\u886F',54233:'\u8883',54234:'\u887E',54235:'\u8874',54236:'\u887C',54237:'\u8A12',54238:'\u8C47',54239:'\u8C57',54240:'\u8C7B',54241:'\u8CA4',54242:'\u8CA3',54243:'\u8D76',54244:'\u8D78',54245:'\u8DB5',54246:'\u8DB7',54247:'\u8DB6',54248:'\u8ED1',54249:'\u8ED3',54250:'\u8FFE',54251:'\u8FF5',54252:'\u9002',54253:'\u8FFF',54254:'\u8FFB',54255:'\u9004',54256:'\u8FFC',54257:'\u8FF6',54258:'\u90D6',54259:'\u90E0',54260:'\u90D9',54261:'\u90DA',54262:'\u90E3',54263:'\u90DF',54264:'\u90E5',54265:'\u90D8',54266:'\u90DB',54267:'\u90D7',54268:'\u90DC',54269:'\u90E4',54270:'\u9150',54336:'\u914E',54337:'\u914F',54338:'\u91D5',54339:'\u91E2',54340:'\u91DA',54341:'\u965C',54342:'\u965F',54343:'\u96BC',54344:'\u98E3',54345:'\u9ADF',54346:'\u9B2F',54347:'\u4E7F',54348:'\u5070',54349:'\u506A',54350:'\u5061',54351:'\u505E',54352:'\u5060',54353:'\u5053',54354:'\u504B',54355:'\u505D',54356:'\u5072',54357:'\u5048',54358:'\u504D',54359:'\u5041',54360:'\u505B',54361:'\u504A',54362:'\u5062',54363:'\u5015',54364:'\u5045',54365:'\u505F',54366:'\u5069',54367:'\u506B',54368:'\u5063',54369:'\u5064',54370:'\u5046',54371:'\u5040',54372:'\u506E',54373:'\u5073',54374:'\u5057',54375:'\u5051',54376:'\u51D0',54377:'\u526B',54378:'\u526D',54379:'\u526C',54380:'\u526E',54381:'\u52D6',54382:'\u52D3',54383:'\u532D',54384:'\u539C',54385:'\u5575',54386:'\u5576',54387:'\u553C',54388:'\u554D',54389:'\u5550',54390:'\u5534',54391:'\u552A',54392:'\u5551',54393:'\u5562',54394:'\u5536',54395:'\u5535',54396:'\u5530',54397:'\u5552',54398:'\u5545',54433:'\u550C',54434:'\u5532',54435:'\u5565',54436:'\u554E',54437:'\u5539',54438:'\u5548',54439:'\u552D',54440:'\u553B',54441:'\u5540',54442:'\u554B',54443:'\u570A',54444:'\u5707',54445:'\u57FB',54446:'\u5814',54447:'\u57E2',54448:'\u57F6',54449:'\u57DC',54450:'\u57F4',54451:'\u5800',54452:'\u57ED',54453:'\u57FD',54454:'\u5808',54455:'\u57F8',54456:'\u580B',54457:'\u57F3',54458:'\u57CF',54459:'\u5807',54460:'\u57EE',54461:'\u57E3',54462:'\u57F2',54463:'\u57E5',54464:'\u57EC',54465:'\u57E1',54466:'\u580E',54467:'\u57FC',54468:'\u5810',54469:'\u57E7',54470:'\u5801',54471:'\u580C',54472:'\u57F1',54473:'\u57E9',54474:'\u57F0',54475:'\u580D',54476:'\u5804',54477:'\u595C',54478:'\u5A60',54479:'\u5A58',54480:'\u5A55',54481:'\u5A67',54482:'\u5A5E',54483:'\u5A38',54484:'\u5A35',54485:'\u5A6D',54486:'\u5A50',54487:'\u5A5F',54488:'\u5A65',54489:'\u5A6C',54490:'\u5A53',54491:'\u5A64',54492:'\u5A57',54493:'\u5A43',54494:'\u5A5D',54495:'\u5A52',54496:'\u5A44',54497:'\u5A5B',54498:'\u5A48',54499:'\u5A8E',54500:'\u5A3E',54501:'\u5A4D',54502:'\u5A39',54503:'\u5A4C',54504:'\u5A70',54505:'\u5A69',54506:'\u5A47',54507:'\u5A51',54508:'\u5A56',54509:'\u5A42',54510:'\u5A5C',54511:'\u5B72',54512:'\u5B6E',54513:'\u5BC1',54514:'\u5BC0',54515:'\u5C59',54516:'\u5D1E',54517:'\u5D0B',54518:'\u5D1D',54519:'\u5D1A',54520:'\u5D20',54521:'\u5D0C',54522:'\u5D28',54523:'\u5D0D',54524:'\u5D26',54525:'\u5D25',54526:'\u5D0F',54592:'\u5D30',54593:'\u5D12',54594:'\u5D23',54595:'\u5D1F',54596:'\u5D2E',54597:'\u5E3E',54598:'\u5E34',54599:'\u5EB1',54600:'\u5EB4',54601:'\u5EB9',54602:'\u5EB2',54603:'\u5EB3',54604:'\u5F36',54605:'\u5F38',54606:'\u5F9B',54607:'\u5F96',54608:'\u5F9F',54609:'\u608A',54610:'\u6090',54611:'\u6086',54612:'\u60BE',54613:'\u60B0',54614:'\u60BA',54615:'\u60D3',54616:'\u60D4',54617:'\u60CF',54618:'\u60E4',54619:'\u60D9',54620:'\u60DD',54621:'\u60C8',54622:'\u60B1',54623:'\u60DB',54624:'\u60B7',54625:'\u60CA',54626:'\u60BF',54627:'\u60C3',54628:'\u60CD',54629:'\u60C0',54630:'\u6332',54631:'\u6365',54632:'\u638A',54633:'\u6382',54634:'\u637D',54635:'\u63BD',54636:'\u639E',54637:'\u63AD',54638:'\u639D',54639:'\u6397',54640:'\u63AB',54641:'\u638E',54642:'\u636F',54643:'\u6387',54644:'\u6390',54645:'\u636E',54646:'\u63AF',54647:'\u6375',54648:'\u639C',54649:'\u636D',54650:'\u63AE',54651:'\u637C',54652:'\u63A4',54653:'\u633B',54654:'\u639F',54689:'\u6378',54690:'\u6385',54691:'\u6381',54692:'\u6391',54693:'\u638D',54694:'\u6370',54695:'\u6553',54696:'\u65CD',54697:'\u6665',54698:'\u6661',54699:'\u665B',54700:'\u6659',54701:'\u665C',54702:'\u6662',54703:'\u6718',54704:'\u6879',54705:'\u6887',54706:'\u6890',54707:'\u689C',54708:'\u686D',54709:'\u686E',54710:'\u68AE',54711:'\u68AB',54712:'\u6956',54713:'\u686F',54714:'\u68A3',54715:'\u68AC',54716:'\u68A9',54717:'\u6875',54718:'\u6874',54719:'\u68B2',54720:'\u688F',54721:'\u6877',54722:'\u6892',54723:'\u687C',54724:'\u686B',54725:'\u6872',54726:'\u68AA',54727:'\u6880',54728:'\u6871',54729:'\u687E',54730:'\u689B',54731:'\u6896',54732:'\u688B',54733:'\u68A0',54734:'\u6889',54735:'\u68A4',54736:'\u6878',54737:'\u687B',54738:'\u6891',54739:'\u688C',54740:'\u688A',54741:'\u687D',54742:'\u6B36',54743:'\u6B33',54744:'\u6B37',54745:'\u6B38',54746:'\u6B91',54747:'\u6B8F',54748:'\u6B8D',54749:'\u6B8E',54750:'\u6B8C',54751:'\u6C2A',54752:'\u6DC0',54753:'\u6DAB',54754:'\u6DB4',54755:'\u6DB3',54756:'\u6E74',54757:'\u6DAC',54758:'\u6DE9',54759:'\u6DE2',54760:'\u6DB7',54761:'\u6DF6',54762:'\u6DD4',54763:'\u6E00',54764:'\u6DC8',54765:'\u6DE0',54766:'\u6DDF',54767:'\u6DD6',54768:'\u6DBE',54769:'\u6DE5',54770:'\u6DDC',54771:'\u6DDD',54772:'\u6DDB',54773:'\u6DF4',54774:'\u6DCA',54775:'\u6DBD',54776:'\u6DED',54777:'\u6DF0',54778:'\u6DBA',54779:'\u6DD5',54780:'\u6DC2',54781:'\u6DCF',54782:'\u6DC9',54848:'\u6DD0',54849:'\u6DF2',54850:'\u6DD3',54851:'\u6DFD',54852:'\u6DD7',54853:'\u6DCD',54854:'\u6DE3',54855:'\u6DBB',54856:'\u70FA',54857:'\u710D',54858:'\u70F7',54859:'\u7117',54860:'\u70F4',54861:'\u710C',54862:'\u70F0',54863:'\u7104',54864:'\u70F3',54865:'\u7110',54866:'\u70FC',54867:'\u70FF',54868:'\u7106',54869:'\u7113',54870:'\u7100',54871:'\u70F8',54872:'\u70F6',54873:'\u710B',54874:'\u7102',54875:'\u710E',54876:'\u727E',54877:'\u727B',54878:'\u727C',54879:'\u727F',54880:'\u731D',54881:'\u7317',54882:'\u7307',54883:'\u7311',54884:'\u7318',54885:'\u730A',54886:'\u7308',54887:'\u72FF',54888:'\u730F',54889:'\u731E',54890:'\u7388',54891:'\u73F6',54892:'\u73F8',54893:'\u73F5',54894:'\u7404',54895:'\u7401',54896:'\u73FD',54897:'\u7407',54898:'\u7400',54899:'\u73FA',54900:'\u73FC',54901:'\u73FF',54902:'\u740C',54903:'\u740B',54904:'\u73F4',54905:'\u7408',54906:'\u7564',54907:'\u7563',54908:'\u75CE',54909:'\u75D2',54910:'\u75CF',54945:'\u75CB',54946:'\u75CC',54947:'\u75D1',54948:'\u75D0',54949:'\u768F',54950:'\u7689',54951:'\u76D3',54952:'\u7739',54953:'\u772F',54954:'\u772D',54955:'\u7731',54956:'\u7732',54957:'\u7734',54958:'\u7733',54959:'\u773D',54960:'\u7725',54961:'\u773B',54962:'\u7735',54963:'\u7848',54964:'\u7852',54965:'\u7849',54966:'\u784D',54967:'\u784A',54968:'\u784C',54969:'\u7826',54970:'\u7845',54971:'\u7850',54972:'\u7964',54973:'\u7967',54974:'\u7969',54975:'\u796A',54976:'\u7963',54977:'\u796B',54978:'\u7961',54979:'\u79BB',54980:'\u79FA',54981:'\u79F8',54982:'\u79F6',54983:'\u79F7',54984:'\u7A8F',54985:'\u7A94',54986:'\u7A90',54987:'\u7B35',54988:'\u7B47',54989:'\u7B34',54990:'\u7B25',54991:'\u7B30',54992:'\u7B22',54993:'\u7B24',54994:'\u7B33',54995:'\u7B18',54996:'\u7B2A',54997:'\u7B1D',54998:'\u7B31',54999:'\u7B2B',55000:'\u7B2D',55001:'\u7B2F',55002:'\u7B32',55003:'\u7B38',55004:'\u7B1A',55005:'\u7B23',55006:'\u7C94',55007:'\u7C98',55008:'\u7C96',55009:'\u7CA3',55010:'\u7D35',55011:'\u7D3D',55012:'\u7D38',55013:'\u7D36',55014:'\u7D3A',55015:'\u7D45',55016:'\u7D2C',55017:'\u7D29',55018:'\u7D41',55019:'\u7D47',55020:'\u7D3E',55021:'\u7D3F',55022:'\u7D4A',55023:'\u7D3B',55024:'\u7D28',55025:'\u7F63',55026:'\u7F95',55027:'\u7F9C',55028:'\u7F9D',55029:'\u7F9B',55030:'\u7FCA',55031:'\u7FCB',55032:'\u7FCD',55033:'\u7FD0',55034:'\u7FD1',55035:'\u7FC7',55036:'\u7FCF',55037:'\u7FC9',55038:'\u801F',55104:'\u801E',55105:'\u801B',55106:'\u8047',55107:'\u8043',55108:'\u8048',55109:'\u8118',55110:'\u8125',55111:'\u8119',55112:'\u811B',55113:'\u812D',55114:'\u811F',55115:'\u812C',55116:'\u811E',55117:'\u8121',55118:'\u8115',55119:'\u8127',55120:'\u811D',55121:'\u8122',55122:'\u8211',55123:'\u8238',55124:'\u8233',55125:'\u823A',55126:'\u8234',55127:'\u8232',55128:'\u8274',55129:'\u8390',55130:'\u83A3',55131:'\u83A8',55132:'\u838D',55133:'\u837A',55134:'\u8373',55135:'\u83A4',55136:'\u8374',55137:'\u838F',55138:'\u8381',55139:'\u8395',55140:'\u8399',55141:'\u8375',55142:'\u8394',55143:'\u83A9',55144:'\u837D',55145:'\u8383',55146:'\u838C',55147:'\u839D',55148:'\u839B',55149:'\u83AA',55150:'\u838B',55151:'\u837E',55152:'\u83A5',55153:'\u83AF',55154:'\u8388',55155:'\u8397',55156:'\u83B0',55157:'\u837F',55158:'\u83A6',55159:'\u8387',55160:'\u83AE',55161:'\u8376',55162:'\u839A',55163:'\u8659',55164:'\u8656',55165:'\u86BF',55166:'\u86B7',55201:'\u86C2',55202:'\u86C1',55203:'\u86C5',55204:'\u86BA',55205:'\u86B0',55206:'\u86C8',55207:'\u86B9',55208:'\u86B3',55209:'\u86B8',55210:'\u86CC',55211:'\u86B4',55212:'\u86BB',55213:'\u86BC',55214:'\u86C3',55215:'\u86BD',55216:'\u86BE',55217:'\u8852',55218:'\u8889',55219:'\u8895',55220:'\u88A8',55221:'\u88A2',55222:'\u88AA',55223:'\u889A',55224:'\u8891',55225:'\u88A1',55226:'\u889F',55227:'\u8898',55228:'\u88A7',55229:'\u8899',55230:'\u889B',55231:'\u8897',55232:'\u88A4',55233:'\u88AC',55234:'\u888C',55235:'\u8893',55236:'\u888E',55237:'\u8982',55238:'\u89D6',55239:'\u89D9',55240:'\u89D5',55241:'\u8A30',55242:'\u8A27',55243:'\u8A2C',55244:'\u8A1E',55245:'\u8C39',55246:'\u8C3B',55247:'\u8C5C',55248:'\u8C5D',55249:'\u8C7D',55250:'\u8CA5',55251:'\u8D7D',55252:'\u8D7B',55253:'\u8D79',55254:'\u8DBC',55255:'\u8DC2',55256:'\u8DB9',55257:'\u8DBF',55258:'\u8DC1',55259:'\u8ED8',55260:'\u8EDE',55261:'\u8EDD',55262:'\u8EDC',55263:'\u8ED7',55264:'\u8EE0',55265:'\u8EE1',55266:'\u9024',55267:'\u900B',55268:'\u9011',55269:'\u901C',55270:'\u900C',55271:'\u9021',55272:'\u90EF',55273:'\u90EA',55274:'\u90F0',55275:'\u90F4',55276:'\u90F2',55277:'\u90F3',55278:'\u90D4',55279:'\u90EB',55280:'\u90EC',55281:'\u90E9',55282:'\u9156',55283:'\u9158',55284:'\u915A',55285:'\u9153',55286:'\u9155',55287:'\u91EC',55288:'\u91F4',55289:'\u91F1',55290:'\u91F3',55291:'\u91F8',55292:'\u91E4',55293:'\u91F9',55294:'\u91EA',55360:'\u91EB',55361:'\u91F7',55362:'\u91E8',55363:'\u91EE',55364:'\u957A',55365:'\u9586',55366:'\u9588',55367:'\u967C',55368:'\u966D',55369:'\u966B',55370:'\u9671',55371:'\u966F',55372:'\u96BF',55373:'\u976A',55374:'\u9804',55375:'\u98E5',55376:'\u9997',55377:'\u509B',55378:'\u5095',55379:'\u5094',55380:'\u509E',55381:'\u508B',55382:'\u50A3',55383:'\u5083',55384:'\u508C',55385:'\u508E',55386:'\u509D',55387:'\u5068',55388:'\u509C',55389:'\u5092',55390:'\u5082',55391:'\u5087',55392:'\u515F',55393:'\u51D4',55394:'\u5312',55395:'\u5311',55396:'\u53A4',55397:'\u53A7',55398:'\u5591',55399:'\u55A8',55400:'\u55A5',55401:'\u55AD',55402:'\u5577',55403:'\u5645',55404:'\u55A2',55405:'\u5593',55406:'\u5588',55407:'\u558F',55408:'\u55B5',55409:'\u5581',55410:'\u55A3',55411:'\u5592',55412:'\u55A4',55413:'\u557D',55414:'\u558C',55415:'\u55A6',55416:'\u557F',55417:'\u5595',55418:'\u55A1',55419:'\u558E',55420:'\u570C',55421:'\u5829',55422:'\u5837',55457:'\u5819',55458:'\u581E',55459:'\u5827',55460:'\u5823',55461:'\u5828',55462:'\u57F5',55463:'\u5848',55464:'\u5825',55465:'\u581C',55466:'\u581B',55467:'\u5833',55468:'\u583F',55469:'\u5836',55470:'\u582E',55471:'\u5839',55472:'\u5838',55473:'\u582D',55474:'\u582C',55475:'\u583B',55476:'\u5961',55477:'\u5AAF',55478:'\u5A94',55479:'\u5A9F',55480:'\u5A7A',55481:'\u5AA2',55482:'\u5A9E',55483:'\u5A78',55484:'\u5AA6',55485:'\u5A7C',55486:'\u5AA5',55487:'\u5AAC',55488:'\u5A95',55489:'\u5AAE',55490:'\u5A37',55491:'\u5A84',55492:'\u5A8A',55493:'\u5A97',55494:'\u5A83',55495:'\u5A8B',55496:'\u5AA9',55497:'\u5A7B',55498:'\u5A7D',55499:'\u5A8C',55500:'\u5A9C',55501:'\u5A8F',55502:'\u5A93',55503:'\u5A9D',55504:'\u5BEA',55505:'\u5BCD',55506:'\u5BCB',55507:'\u5BD4',55508:'\u5BD1',55509:'\u5BCA',55510:'\u5BCE',55511:'\u5C0C',55512:'\u5C30',55513:'\u5D37',55514:'\u5D43',55515:'\u5D6B',55516:'\u5D41',55517:'\u5D4B',55518:'\u5D3F',55519:'\u5D35',55520:'\u5D51',55521:'\u5D4E',55522:'\u5D55',55523:'\u5D33',55524:'\u5D3A',55525:'\u5D52',55526:'\u5D3D',55527:'\u5D31',55528:'\u5D59',55529:'\u5D42',55530:'\u5D39',55531:'\u5D49',55532:'\u5D38',55533:'\u5D3C',55534:'\u5D32',55535:'\u5D36',55536:'\u5D40',55537:'\u5D45',55538:'\u5E44',55539:'\u5E41',55540:'\u5F58',55541:'\u5FA6',55542:'\u5FA5',55543:'\u5FAB',55544:'\u60C9',55545:'\u60B9',55546:'\u60CC',55547:'\u60E2',55548:'\u60CE',55549:'\u60C4',55550:'\u6114',55616:'\u60F2',55617:'\u610A',55618:'\u6116',55619:'\u6105',55620:'\u60F5',55621:'\u6113',55622:'\u60F8',55623:'\u60FC',55624:'\u60FE',55625:'\u60C1',55626:'\u6103',55627:'\u6118',55628:'\u611D',55629:'\u6110',55630:'\u60FF',55631:'\u6104',55632:'\u610B',55633:'\u624A',55634:'\u6394',55635:'\u63B1',55636:'\u63B0',55637:'\u63CE',55638:'\u63E5',55639:'\u63E8',55640:'\u63EF',55641:'\u63C3',55642:'\u649D',55643:'\u63F3',55644:'\u63CA',55645:'\u63E0',55646:'\u63F6',55647:'\u63D5',55648:'\u63F2',55649:'\u63F5',55650:'\u6461',55651:'\u63DF',55652:'\u63BE',55653:'\u63DD',55654:'\u63DC',55655:'\u63C4',55656:'\u63D8',55657:'\u63D3',55658:'\u63C2',55659:'\u63C7',55660:'\u63CC',55661:'\u63CB',55662:'\u63C8',55663:'\u63F0',55664:'\u63D7',55665:'\u63D9',55666:'\u6532',55667:'\u6567',55668:'\u656A',55669:'\u6564',55670:'\u655C',55671:'\u6568',55672:'\u6565',55673:'\u658C',55674:'\u659D',55675:'\u659E',55676:'\u65AE',55677:'\u65D0',55678:'\u65D2',55713:'\u667C',55714:'\u666C',55715:'\u667B',55716:'\u6680',55717:'\u6671',55718:'\u6679',55719:'\u666A',55720:'\u6672',55721:'\u6701',55722:'\u690C',55723:'\u68D3',55724:'\u6904',55725:'\u68DC',55726:'\u692A',55727:'\u68EC',55728:'\u68EA',55729:'\u68F1',55730:'\u690F',55731:'\u68D6',55732:'\u68F7',55733:'\u68EB',55734:'\u68E4',55735:'\u68F6',55736:'\u6913',55737:'\u6910',55738:'\u68F3',55739:'\u68E1',55740:'\u6907',55741:'\u68CC',55742:'\u6908',55743:'\u6970',55744:'\u68B4',55745:'\u6911',55746:'\u68EF',55747:'\u68C6',55748:'\u6914',55749:'\u68F8',55750:'\u68D0',55751:'\u68FD',55752:'\u68FC',55753:'\u68E8',55754:'\u690B',55755:'\u690A',55756:'\u6917',55757:'\u68CE',55758:'\u68C8',55759:'\u68DD',55760:'\u68DE',55761:'\u68E6',55762:'\u68F4',55763:'\u68D1',55764:'\u6906',55765:'\u68D4',55766:'\u68E9',55767:'\u6915',55768:'\u6925',55769:'\u68C7',55770:'\u6B39',55771:'\u6B3B',55772:'\u6B3F',55773:'\u6B3C',55774:'\u6B94',55775:'\u6B97',55776:'\u6B99',55777:'\u6B95',55778:'\u6BBD',55779:'\u6BF0',55780:'\u6BF2',55781:'\u6BF3',55782:'\u6C30',55783:'\u6DFC',55784:'\u6E46',55785:'\u6E47',55786:'\u6E1F',55787:'\u6E49',55788:'\u6E88',55789:'\u6E3C',55790:'\u6E3D',55791:'\u6E45',55792:'\u6E62',55793:'\u6E2B',55794:'\u6E3F',55795:'\u6E41',55796:'\u6E5D',55797:'\u6E73',55798:'\u6E1C',55799:'\u6E33',55800:'\u6E4B',55801:'\u6E40',55802:'\u6E51',55803:'\u6E3B',55804:'\u6E03',55805:'\u6E2E',55806:'\u6E5E',55872:'\u6E68',55873:'\u6E5C',55874:'\u6E61',55875:'\u6E31',55876:'\u6E28',55877:'\u6E60',55878:'\u6E71',55879:'\u6E6B',55880:'\u6E39',55881:'\u6E22',55882:'\u6E30',55883:'\u6E53',55884:'\u6E65',55885:'\u6E27',55886:'\u6E78',55887:'\u6E64',55888:'\u6E77',55889:'\u6E55',55890:'\u6E79',55891:'\u6E52',55892:'\u6E66',55893:'\u6E35',55894:'\u6E36',55895:'\u6E5A',55896:'\u7120',55897:'\u711E',55898:'\u712F',55899:'\u70FB',55900:'\u712E',55901:'\u7131',55902:'\u7123',55903:'\u7125',55904:'\u7122',55905:'\u7132',55906:'\u711F',55907:'\u7128',55908:'\u713A',55909:'\u711B',55910:'\u724B',55911:'\u725A',55912:'\u7288',55913:'\u7289',55914:'\u7286',55915:'\u7285',55916:'\u728B',55917:'\u7312',55918:'\u730B',55919:'\u7330',55920:'\u7322',55921:'\u7331',55922:'\u7333',55923:'\u7327',55924:'\u7332',55925:'\u732D',55926:'\u7326',55927:'\u7323',55928:'\u7335',55929:'\u730C',55930:'\u742E',55931:'\u742C',55932:'\u7430',55933:'\u742B',55934:'\u7416',55969:'\u741A',55970:'\u7421',55971:'\u742D',55972:'\u7431',55973:'\u7424',55974:'\u7423',55975:'\u741D',55976:'\u7429',55977:'\u7420',55978:'\u7432',55979:'\u74FB',55980:'\u752F',55981:'\u756F',55982:'\u756C',55983:'\u75E7',55984:'\u75DA',55985:'\u75E1',55986:'\u75E6',55987:'\u75DD',55988:'\u75DF',55989:'\u75E4',55990:'\u75D7',55991:'\u7695',55992:'\u7692',55993:'\u76DA',55994:'\u7746',55995:'\u7747',55996:'\u7744',55997:'\u774D',55998:'\u7745',55999:'\u774A',56000:'\u774E',56001:'\u774B',56002:'\u774C',56003:'\u77DE',56004:'\u77EC',56005:'\u7860',56006:'\u7864',56007:'\u7865',56008:'\u785C',56009:'\u786D',56010:'\u7871',56011:'\u786A',56012:'\u786E',56013:'\u7870',56014:'\u7869',56015:'\u7868',56016:'\u785E',56017:'\u7862',56018:'\u7974',56019:'\u7973',56020:'\u7972',56021:'\u7970',56022:'\u7A02',56023:'\u7A0A',56024:'\u7A03',56025:'\u7A0C',56026:'\u7A04',56027:'\u7A99',56028:'\u7AE6',56029:'\u7AE4',56030:'\u7B4A',56031:'\u7B3B',56032:'\u7B44',56033:'\u7B48',56034:'\u7B4C',56035:'\u7B4E',56036:'\u7B40',56037:'\u7B58',56038:'\u7B45',56039:'\u7CA2',56040:'\u7C9E',56041:'\u7CA8',56042:'\u7CA1',56043:'\u7D58',56044:'\u7D6F',56045:'\u7D63',56046:'\u7D53',56047:'\u7D56',56048:'\u7D67',56049:'\u7D6A',56050:'\u7D4F',56051:'\u7D6D',56052:'\u7D5C',56053:'\u7D6B',56054:'\u7D52',56055:'\u7D54',56056:'\u7D69',56057:'\u7D51',56058:'\u7D5F',56059:'\u7D4E',56060:'\u7F3E',56061:'\u7F3F',56062:'\u7F65',56128:'\u7F66',56129:'\u7FA2',56130:'\u7FA0',56131:'\u7FA1',56132:'\u7FD7',56133:'\u8051',56134:'\u804F',56135:'\u8050',56136:'\u80FE',56137:'\u80D4',56138:'\u8143',56139:'\u814A',56140:'\u8152',56141:'\u814F',56142:'\u8147',56143:'\u813D',56144:'\u814D',56145:'\u813A',56146:'\u81E6',56147:'\u81EE',56148:'\u81F7',56149:'\u81F8',56150:'\u81F9',56151:'\u8204',56152:'\u823C',56153:'\u823D',56154:'\u823F',56155:'\u8275',56156:'\u833B',56157:'\u83CF',56158:'\u83F9',56159:'\u8423',56160:'\u83C0',56161:'\u83E8',56162:'\u8412',56163:'\u83E7',56164:'\u83E4',56165:'\u83FC',56166:'\u83F6',56167:'\u8410',56168:'\u83C6',56169:'\u83C8',56170:'\u83EB',56171:'\u83E3',56172:'\u83BF',56173:'\u8401',56174:'\u83DD',56175:'\u83E5',56176:'\u83D8',56177:'\u83FF',56178:'\u83E1',56179:'\u83CB',56180:'\u83CE',56181:'\u83D6',56182:'\u83F5',56183:'\u83C9',56184:'\u8409',56185:'\u840F',56186:'\u83DE',56187:'\u8411',56188:'\u8406',56189:'\u83C2',56190:'\u83F3',56225:'\u83D5',56226:'\u83FA',56227:'\u83C7',56228:'\u83D1',56229:'\u83EA',56230:'\u8413',56231:'\u83C3',56232:'\u83EC',56233:'\u83EE',56234:'\u83C4',56235:'\u83FB',56236:'\u83D7',56237:'\u83E2',56238:'\u841B',56239:'\u83DB',56240:'\u83FE',56241:'\u86D8',56242:'\u86E2',56243:'\u86E6',56244:'\u86D3',56245:'\u86E3',56246:'\u86DA',56247:'\u86EA',56248:'\u86DD',56249:'\u86EB',56250:'\u86DC',56251:'\u86EC',56252:'\u86E9',56253:'\u86D7',56254:'\u86E8',56255:'\u86D1',56256:'\u8848',56257:'\u8856',56258:'\u8855',56259:'\u88BA',56260:'\u88D7',56261:'\u88B9',56262:'\u88B8',56263:'\u88C0',56264:'\u88BE',56265:'\u88B6',56266:'\u88BC',56267:'\u88B7',56268:'\u88BD',56269:'\u88B2',56270:'\u8901',56271:'\u88C9',56272:'\u8995',56273:'\u8998',56274:'\u8997',56275:'\u89DD',56276:'\u89DA',56277:'\u89DB',56278:'\u8A4E',56279:'\u8A4D',56280:'\u8A39',56281:'\u8A59',56282:'\u8A40',56283:'\u8A57',56284:'\u8A58',56285:'\u8A44',56286:'\u8A45',56287:'\u8A52',56288:'\u8A48',56289:'\u8A51',56290:'\u8A4A',56291:'\u8A4C',56292:'\u8A4F',56293:'\u8C5F',56294:'\u8C81',56295:'\u8C80',56296:'\u8CBA',56297:'\u8CBE',56298:'\u8CB0',56299:'\u8CB9',56300:'\u8CB5',56301:'\u8D84',56302:'\u8D80',56303:'\u8D89',56304:'\u8DD8',56305:'\u8DD3',56306:'\u8DCD',56307:'\u8DC7',56308:'\u8DD6',56309:'\u8DDC',56310:'\u8DCF',56311:'\u8DD5',56312:'\u8DD9',56313:'\u8DC8',56314:'\u8DD7',56315:'\u8DC5',56316:'\u8EEF',56317:'\u8EF7',56318:'\u8EFA',56384:'\u8EF9',56385:'\u8EE6',56386:'\u8EEE',56387:'\u8EE5',56388:'\u8EF5',56389:'\u8EE7',56390:'\u8EE8',56391:'\u8EF6',56392:'\u8EEB',56393:'\u8EF1',56394:'\u8EEC',56395:'\u8EF4',56396:'\u8EE9',56397:'\u902D',56398:'\u9034',56399:'\u902F',56400:'\u9106',56401:'\u912C',56402:'\u9104',56403:'\u90FF',56404:'\u90FC',56405:'\u9108',56406:'\u90F9',56407:'\u90FB',56408:'\u9101',56409:'\u9100',56410:'\u9107',56411:'\u9105',56412:'\u9103',56413:'\u9161',56414:'\u9164',56415:'\u915F',56416:'\u9162',56417:'\u9160',56418:'\u9201',56419:'\u920A',56420:'\u9225',56421:'\u9203',56422:'\u921A',56423:'\u9226',56424:'\u920F',56425:'\u920C',56426:'\u9200',56427:'\u9212',56428:'\u91FF',56429:'\u91FD',56430:'\u9206',56431:'\u9204',56432:'\u9227',56433:'\u9202',56434:'\u921C',56435:'\u9224',56436:'\u9219',56437:'\u9217',56438:'\u9205',56439:'\u9216',56440:'\u957B',56441:'\u958D',56442:'\u958C',56443:'\u9590',56444:'\u9687',56445:'\u967E',56446:'\u9688',56481:'\u9689',56482:'\u9683',56483:'\u9680',56484:'\u96C2',56485:'\u96C8',56486:'\u96C3',56487:'\u96F1',56488:'\u96F0',56489:'\u976C',56490:'\u9770',56491:'\u976E',56492:'\u9807',56493:'\u98A9',56494:'\u98EB',56495:'\u9CE6',56496:'\u9EF9',56497:'\u4E83',56498:'\u4E84',56499:'\u4EB6',56500:'\u50BD',56501:'\u50BF',56502:'\u50C6',56503:'\u50AE',56504:'\u50C4',56505:'\u50CA',56506:'\u50B4',56507:'\u50C8',56508:'\u50C2',56509:'\u50B0',56510:'\u50C1',56511:'\u50BA',56512:'\u50B1',56513:'\u50CB',56514:'\u50C9',56515:'\u50B6',56516:'\u50B8',56517:'\u51D7',56518:'\u527A',56519:'\u5278',56520:'\u527B',56521:'\u527C',56522:'\u55C3',56523:'\u55DB',56524:'\u55CC',56525:'\u55D0',56526:'\u55CB',56527:'\u55CA',56528:'\u55DD',56529:'\u55C0',56530:'\u55D4',56531:'\u55C4',56532:'\u55E9',56533:'\u55BF',56534:'\u55D2',56535:'\u558D',56536:'\u55CF',56537:'\u55D5',56538:'\u55E2',56539:'\u55D6',56540:'\u55C8',56541:'\u55F2',56542:'\u55CD',56543:'\u55D9',56544:'\u55C2',56545:'\u5714',56546:'\u5853',56547:'\u5868',56548:'\u5864',56549:'\u584F',56550:'\u584D',56551:'\u5849',56552:'\u586F',56553:'\u5855',56554:'\u584E',56555:'\u585D',56556:'\u5859',56557:'\u5865',56558:'\u585B',56559:'\u583D',56560:'\u5863',56561:'\u5871',56562:'\u58FC',56563:'\u5AC7',56564:'\u5AC4',56565:'\u5ACB',56566:'\u5ABA',56567:'\u5AB8',56568:'\u5AB1',56569:'\u5AB5',56570:'\u5AB0',56571:'\u5ABF',56572:'\u5AC8',56573:'\u5ABB',56574:'\u5AC6',56640:'\u5AB7',56641:'\u5AC0',56642:'\u5ACA',56643:'\u5AB4',56644:'\u5AB6',56645:'\u5ACD',56646:'\u5AB9',56647:'\u5A90',56648:'\u5BD6',56649:'\u5BD8',56650:'\u5BD9',56651:'\u5C1F',56652:'\u5C33',56653:'\u5D71',56654:'\u5D63',56655:'\u5D4A',56656:'\u5D65',56657:'\u5D72',56658:'\u5D6C',56659:'\u5D5E',56660:'\u5D68',56661:'\u5D67',56662:'\u5D62',56663:'\u5DF0',56664:'\u5E4F',56665:'\u5E4E',56666:'\u5E4A',56667:'\u5E4D',56668:'\u5E4B',56669:'\u5EC5',56670:'\u5ECC',56671:'\u5EC6',56672:'\u5ECB',56673:'\u5EC7',56674:'\u5F40',56675:'\u5FAF',56676:'\u5FAD',56677:'\u60F7',56678:'\u6149',56679:'\u614A',56680:'\u612B',56681:'\u6145',56682:'\u6136',56683:'\u6132',56684:'\u612E',56685:'\u6146',56686:'\u612F',56687:'\u614F',56688:'\u6129',56689:'\u6140',56690:'\u6220',56691:'\u9168',56692:'\u6223',56693:'\u6225',56694:'\u6224',56695:'\u63C5',56696:'\u63F1',56697:'\u63EB',56698:'\u6410',56699:'\u6412',56700:'\u6409',56701:'\u6420',56702:'\u6424',56737:'\u6433',56738:'\u6443',56739:'\u641F',56740:'\u6415',56741:'\u6418',56742:'\u6439',56743:'\u6437',56744:'\u6422',56745:'\u6423',56746:'\u640C',56747:'\u6426',56748:'\u6430',56749:'\u6428',56750:'\u6441',56751:'\u6435',56752:'\u642F',56753:'\u640A',56754:'\u641A',56755:'\u6440',56756:'\u6425',56757:'\u6427',56758:'\u640B',56759:'\u63E7',56760:'\u641B',56761:'\u642E',56762:'\u6421',56763:'\u640E',56764:'\u656F',56765:'\u6592',56766:'\u65D3',56767:'\u6686',56768:'\u668C',56769:'\u6695',56770:'\u6690',56771:'\u668B',56772:'\u668A',56773:'\u6699',56774:'\u6694',56775:'\u6678',56776:'\u6720',56777:'\u6966',56778:'\u695F',56779:'\u6938',56780:'\u694E',56781:'\u6962',56782:'\u6971',56783:'\u693F',56784:'\u6945',56785:'\u696A',56786:'\u6939',56787:'\u6942',56788:'\u6957',56789:'\u6959',56790:'\u697A',56791:'\u6948',56792:'\u6949',56793:'\u6935',56794:'\u696C',56795:'\u6933',56796:'\u693D',56797:'\u6965',56798:'\u68F0',56799:'\u6978',56800:'\u6934',56801:'\u6969',56802:'\u6940',56803:'\u696F',56804:'\u6944',56805:'\u6976',56806:'\u6958',56807:'\u6941',56808:'\u6974',56809:'\u694C',56810:'\u693B',56811:'\u694B',56812:'\u6937',56813:'\u695C',56814:'\u694F',56815:'\u6951',56816:'\u6932',56817:'\u6952',56818:'\u692F',56819:'\u697B',56820:'\u693C',56821:'\u6B46',56822:'\u6B45',56823:'\u6B43',56824:'\u6B42',56825:'\u6B48',56826:'\u6B41',56827:'\u6B9B',56828:'\uFA0D',56829:'\u6BFB',56830:'\u6BFC',56896:'\u6BF9',56897:'\u6BF7',56898:'\u6BF8',56899:'\u6E9B',56900:'\u6ED6',56901:'\u6EC8',56902:'\u6E8F',56903:'\u6EC0',56904:'\u6E9F',56905:'\u6E93',56906:'\u6E94',56907:'\u6EA0',56908:'\u6EB1',56909:'\u6EB9',56910:'\u6EC6',56911:'\u6ED2',56912:'\u6EBD',56913:'\u6EC1',56914:'\u6E9E',56915:'\u6EC9',56916:'\u6EB7',56917:'\u6EB0',56918:'\u6ECD',56919:'\u6EA6',56920:'\u6ECF',56921:'\u6EB2',56922:'\u6EBE',56923:'\u6EC3',56924:'\u6EDC',56925:'\u6ED8',56926:'\u6E99',56927:'\u6E92',56928:'\u6E8E',56929:'\u6E8D',56930:'\u6EA4',56931:'\u6EA1',56932:'\u6EBF',56933:'\u6EB3',56934:'\u6ED0',56935:'\u6ECA',56936:'\u6E97',56937:'\u6EAE',56938:'\u6EA3',56939:'\u7147',56940:'\u7154',56941:'\u7152',56942:'\u7163',56943:'\u7160',56944:'\u7141',56945:'\u715D',56946:'\u7162',56947:'\u7172',56948:'\u7178',56949:'\u716A',56950:'\u7161',56951:'\u7142',56952:'\u7158',56953:'\u7143',56954:'\u714B',56955:'\u7170',56956:'\u715F',56957:'\u7150',56958:'\u7153',56993:'\u7144',56994:'\u714D',56995:'\u715A',56996:'\u724F',56997:'\u728D',56998:'\u728C',56999:'\u7291',57000:'\u7290',57001:'\u728E',57002:'\u733C',57003:'\u7342',57004:'\u733B',57005:'\u733A',57006:'\u7340',57007:'\u734A',57008:'\u7349',57009:'\u7444',57010:'\u744A',57011:'\u744B',57012:'\u7452',57013:'\u7451',57014:'\u7457',57015:'\u7440',57016:'\u744F',57017:'\u7450',57018:'\u744E',57019:'\u7442',57020:'\u7446',57021:'\u744D',57022:'\u7454',57023:'\u74E1',57024:'\u74FF',57025:'\u74FE',57026:'\u74FD',57027:'\u751D',57028:'\u7579',57029:'\u7577',57030:'\u6983',57031:'\u75EF',57032:'\u760F',57033:'\u7603',57034:'\u75F7',57035:'\u75FE',57036:'\u75FC',57037:'\u75F9',57038:'\u75F8',57039:'\u7610',57040:'\u75FB',57041:'\u75F6',57042:'\u75ED',57043:'\u75F5',57044:'\u75FD',57045:'\u7699',57046:'\u76B5',57047:'\u76DD',57048:'\u7755',57049:'\u775F',57050:'\u7760',57051:'\u7752',57052:'\u7756',57053:'\u775A',57054:'\u7769',57055:'\u7767',57056:'\u7754',57057:'\u7759',57058:'\u776D',57059:'\u77E0',57060:'\u7887',57061:'\u789A',57062:'\u7894',57063:'\u788F',57064:'\u7884',57065:'\u7895',57066:'\u7885',57067:'\u7886',57068:'\u78A1',57069:'\u7883',57070:'\u7879',57071:'\u7899',57072:'\u7880',57073:'\u7896',57074:'\u787B',57075:'\u797C',57076:'\u7982',57077:'\u797D',57078:'\u7979',57079:'\u7A11',57080:'\u7A18',57081:'\u7A19',57082:'\u7A12',57083:'\u7A17',57084:'\u7A15',57085:'\u7A22',57086:'\u7A13',57152:'\u7A1B',57153:'\u7A10',57154:'\u7AA3',57155:'\u7AA2',57156:'\u7A9E',57157:'\u7AEB',57158:'\u7B66',57159:'\u7B64',57160:'\u7B6D',57161:'\u7B74',57162:'\u7B69',57163:'\u7B72',57164:'\u7B65',57165:'\u7B73',57166:'\u7B71',57167:'\u7B70',57168:'\u7B61',57169:'\u7B78',57170:'\u7B76',57171:'\u7B63',57172:'\u7CB2',57173:'\u7CB4',57174:'\u7CAF',57175:'\u7D88',57176:'\u7D86',57177:'\u7D80',57178:'\u7D8D',57179:'\u7D7F',57180:'\u7D85',57181:'\u7D7A',57182:'\u7D8E',57183:'\u7D7B',57184:'\u7D83',57185:'\u7D7C',57186:'\u7D8C',57187:'\u7D94',57188:'\u7D84',57189:'\u7D7D',57190:'\u7D92',57191:'\u7F6D',57192:'\u7F6B',57193:'\u7F67',57194:'\u7F68',57195:'\u7F6C',57196:'\u7FA6',57197:'\u7FA5',57198:'\u7FA7',57199:'\u7FDB',57200:'\u7FDC',57201:'\u8021',57202:'\u8164',57203:'\u8160',57204:'\u8177',57205:'\u815C',57206:'\u8169',57207:'\u815B',57208:'\u8162',57209:'\u8172',57210:'\u6721',57211:'\u815E',57212:'\u8176',57213:'\u8167',57214:'\u816F',57249:'\u8144',57250:'\u8161',57251:'\u821D',57252:'\u8249',57253:'\u8244',57254:'\u8240',57255:'\u8242',57256:'\u8245',57257:'\u84F1',57258:'\u843F',57259:'\u8456',57260:'\u8476',57261:'\u8479',57262:'\u848F',57263:'\u848D',57264:'\u8465',57265:'\u8451',57266:'\u8440',57267:'\u8486',57268:'\u8467',57269:'\u8430',57270:'\u844D',57271:'\u847D',57272:'\u845A',57273:'\u8459',57274:'\u8474',57275:'\u8473',57276:'\u845D',57277:'\u8507',57278:'\u845E',57279:'\u8437',57280:'\u843A',57281:'\u8434',57282:'\u847A',57283:'\u8443',57284:'\u8478',57285:'\u8432',57286:'\u8445',57287:'\u8429',57288:'\u83D9',57289:'\u844B',57290:'\u842F',57291:'\u8442',57292:'\u842D',57293:'\u845F',57294:'\u8470',57295:'\u8439',57296:'\u844E',57297:'\u844C',57298:'\u8452',57299:'\u846F',57300:'\u84C5',57301:'\u848E',57302:'\u843B',57303:'\u8447',57304:'\u8436',57305:'\u8433',57306:'\u8468',57307:'\u847E',57308:'\u8444',57309:'\u842B',57310:'\u8460',57311:'\u8454',57312:'\u846E',57313:'\u8450',57314:'\u870B',57315:'\u8704',57316:'\u86F7',57317:'\u870C',57318:'\u86FA',57319:'\u86D6',57320:'\u86F5',57321:'\u874D',57322:'\u86F8',57323:'\u870E',57324:'\u8709',57325:'\u8701',57326:'\u86F6',57327:'\u870D',57328:'\u8705',57329:'\u88D6',57330:'\u88CB',57331:'\u88CD',57332:'\u88CE',57333:'\u88DE',57334:'\u88DB',57335:'\u88DA',57336:'\u88CC',57337:'\u88D0',57338:'\u8985',57339:'\u899B',57340:'\u89DF',57341:'\u89E5',57342:'\u89E4',57408:'\u89E1',57409:'\u89E0',57410:'\u89E2',57411:'\u89DC',57412:'\u89E6',57413:'\u8A76',57414:'\u8A86',57415:'\u8A7F',57416:'\u8A61',57417:'\u8A3F',57418:'\u8A77',57419:'\u8A82',57420:'\u8A84',57421:'\u8A75',57422:'\u8A83',57423:'\u8A81',57424:'\u8A74',57425:'\u8A7A',57426:'\u8C3C',57427:'\u8C4B',57428:'\u8C4A',57429:'\u8C65',57430:'\u8C64',57431:'\u8C66',57432:'\u8C86',57433:'\u8C84',57434:'\u8C85',57435:'\u8CCC',57436:'\u8D68',57437:'\u8D69',57438:'\u8D91',57439:'\u8D8C',57440:'\u8D8E',57441:'\u8D8F',57442:'\u8D8D',57443:'\u8D93',57444:'\u8D94',57445:'\u8D90',57446:'\u8D92',57447:'\u8DF0',57448:'\u8DE0',57449:'\u8DEC',57450:'\u8DF1',57451:'\u8DEE',57452:'\u8DD0',57453:'\u8DE9',57454:'\u8DE3',57455:'\u8DE2',57456:'\u8DE7',57457:'\u8DF2',57458:'\u8DEB',57459:'\u8DF4',57460:'\u8F06',57461:'\u8EFF',57462:'\u8F01',57463:'\u8F00',57464:'\u8F05',57465:'\u8F07',57466:'\u8F08',57467:'\u8F02',57468:'\u8F0B',57469:'\u9052',57470:'\u903F',57505:'\u9044',57506:'\u9049',57507:'\u903D',57508:'\u9110',57509:'\u910D',57510:'\u910F',57511:'\u9111',57512:'\u9116',57513:'\u9114',57514:'\u910B',57515:'\u910E',57516:'\u916E',57517:'\u916F',57518:'\u9248',57519:'\u9252',57520:'\u9230',57521:'\u923A',57522:'\u9266',57523:'\u9233',57524:'\u9265',57525:'\u925E',57526:'\u9283',57527:'\u922E',57528:'\u924A',57529:'\u9246',57530:'\u926D',57531:'\u926C',57532:'\u924F',57533:'\u9260',57534:'\u9267',57535:'\u926F',57536:'\u9236',57537:'\u9261',57538:'\u9270',57539:'\u9231',57540:'\u9254',57541:'\u9263',57542:'\u9250',57543:'\u9272',57544:'\u924E',57545:'\u9253',57546:'\u924C',57547:'\u9256',57548:'\u9232',57549:'\u959F',57550:'\u959C',57551:'\u959E',57552:'\u959B',57553:'\u9692',57554:'\u9693',57555:'\u9691',57556:'\u9697',57557:'\u96CE',57558:'\u96FA',57559:'\u96FD',57560:'\u96F8',57561:'\u96F5',57562:'\u9773',57563:'\u9777',57564:'\u9778',57565:'\u9772',57566:'\u980F',57567:'\u980D',57568:'\u980E',57569:'\u98AC',57570:'\u98F6',57571:'\u98F9',57572:'\u99AF',57573:'\u99B2',57574:'\u99B0',57575:'\u99B5',57576:'\u9AAD',57577:'\u9AAB',57578:'\u9B5B',57579:'\u9CEA',57580:'\u9CED',57581:'\u9CE7',57582:'\u9E80',57583:'\u9EFD',57584:'\u50E6',57585:'\u50D4',57586:'\u50D7',57587:'\u50E8',57588:'\u50F3',57589:'\u50DB',57590:'\u50EA',57591:'\u50DD',57592:'\u50E4',57593:'\u50D3',57594:'\u50EC',57595:'\u50F0',57596:'\u50EF',57597:'\u50E3',57598:'\u50E0',57664:'\u51D8',57665:'\u5280',57666:'\u5281',57667:'\u52E9',57668:'\u52EB',57669:'\u5330',57670:'\u53AC',57671:'\u5627',57672:'\u5615',57673:'\u560C',57674:'\u5612',57675:'\u55FC',57676:'\u560F',57677:'\u561C',57678:'\u5601',57679:'\u5613',57680:'\u5602',57681:'\u55FA',57682:'\u561D',57683:'\u5604',57684:'\u55FF',57685:'\u55F9',57686:'\u5889',57687:'\u587C',57688:'\u5890',57689:'\u5898',57690:'\u5886',57691:'\u5881',57692:'\u587F',57693:'\u5874',57694:'\u588B',57695:'\u587A',57696:'\u5887',57697:'\u5891',57698:'\u588E',57699:'\u5876',57700:'\u5882',57701:'\u5888',57702:'\u587B',57703:'\u5894',57704:'\u588F',57705:'\u58FE',57706:'\u596B',57707:'\u5ADC',57708:'\u5AEE',57709:'\u5AE5',57710:'\u5AD5',57711:'\u5AEA',57712:'\u5ADA',57713:'\u5AED',57714:'\u5AEB',57715:'\u5AF3',57716:'\u5AE2',57717:'\u5AE0',57718:'\u5ADB',57719:'\u5AEC',57720:'\u5ADE',57721:'\u5ADD',57722:'\u5AD9',57723:'\u5AE8',57724:'\u5ADF',57725:'\u5B77',57726:'\u5BE0',57761:'\u5BE3',57762:'\u5C63',57763:'\u5D82',57764:'\u5D80',57765:'\u5D7D',57766:'\u5D86',57767:'\u5D7A',57768:'\u5D81',57769:'\u5D77',57770:'\u5D8A',57771:'\u5D89',57772:'\u5D88',57773:'\u5D7E',57774:'\u5D7C',57775:'\u5D8D',57776:'\u5D79',57777:'\u5D7F',57778:'\u5E58',57779:'\u5E59',57780:'\u5E53',57781:'\u5ED8',57782:'\u5ED1',57783:'\u5ED7',57784:'\u5ECE',57785:'\u5EDC',57786:'\u5ED5',57787:'\u5ED9',57788:'\u5ED2',57789:'\u5ED4',57790:'\u5F44',57791:'\u5F43',57792:'\u5F6F',57793:'\u5FB6',57794:'\u612C',57795:'\u6128',57796:'\u6141',57797:'\u615E',57798:'\u6171',57799:'\u6173',57800:'\u6152',57801:'\u6153',57802:'\u6172',57803:'\u616C',57804:'\u6180',57805:'\u6174',57806:'\u6154',57807:'\u617A',57808:'\u615B',57809:'\u6165',57810:'\u613B',57811:'\u616A',57812:'\u6161',57813:'\u6156',57814:'\u6229',57815:'\u6227',57816:'\u622B',57817:'\u642B',57818:'\u644D',57819:'\u645B',57820:'\u645D',57821:'\u6474',57822:'\u6476',57823:'\u6472',57824:'\u6473',57825:'\u647D',57826:'\u6475',57827:'\u6466',57828:'\u64A6',57829:'\u644E',57830:'\u6482',57831:'\u645E',57832:'\u645C',57833:'\u644B',57834:'\u6453',57835:'\u6460',57836:'\u6450',57837:'\u647F',57838:'\u643F',57839:'\u646C',57840:'\u646B',57841:'\u6459',57842:'\u6465',57843:'\u6477',57844:'\u6573',57845:'\u65A0',57846:'\u66A1',57847:'\u66A0',57848:'\u669F',57849:'\u6705',57850:'\u6704',57851:'\u6722',57852:'\u69B1',57853:'\u69B6',57854:'\u69C9',57920:'\u69A0',57921:'\u69CE',57922:'\u6996',57923:'\u69B0',57924:'\u69AC',57925:'\u69BC',57926:'\u6991',57927:'\u6999',57928:'\u698E',57929:'\u69A7',57930:'\u698D',57931:'\u69A9',57932:'\u69BE',57933:'\u69AF',57934:'\u69BF',57935:'\u69C4',57936:'\u69BD',57937:'\u69A4',57938:'\u69D4',57939:'\u69B9',57940:'\u69CA',57941:'\u699A',57942:'\u69CF',57943:'\u69B3',57944:'\u6993',57945:'\u69AA',57946:'\u69A1',57947:'\u699E',57948:'\u69D9',57949:'\u6997',57950:'\u6990',57951:'\u69C2',57952:'\u69B5',57953:'\u69A5',57954:'\u69C6',57955:'\u6B4A',57956:'\u6B4D',57957:'\u6B4B',57958:'\u6B9E',57959:'\u6B9F',57960:'\u6BA0',57961:'\u6BC3',57962:'\u6BC4',57963:'\u6BFE',57964:'\u6ECE',57965:'\u6EF5',57966:'\u6EF1',57967:'\u6F03',57968:'\u6F25',57969:'\u6EF8',57970:'\u6F37',57971:'\u6EFB',57972:'\u6F2E',57973:'\u6F09',57974:'\u6F4E',57975:'\u6F19',57976:'\u6F1A',57977:'\u6F27',57978:'\u6F18',57979:'\u6F3B',57980:'\u6F12',57981:'\u6EED',57982:'\u6F0A',58017:'\u6F36',58018:'\u6F73',58019:'\u6EF9',58020:'\u6EEE',58021:'\u6F2D',58022:'\u6F40',58023:'\u6F30',58024:'\u6F3C',58025:'\u6F35',58026:'\u6EEB',58027:'\u6F07',58028:'\u6F0E',58029:'\u6F43',58030:'\u6F05',58031:'\u6EFD',58032:'\u6EF6',58033:'\u6F39',58034:'\u6F1C',58035:'\u6EFC',58036:'\u6F3A',58037:'\u6F1F',58038:'\u6F0D',58039:'\u6F1E',58040:'\u6F08',58041:'\u6F21',58042:'\u7187',58043:'\u7190',58044:'\u7189',58045:'\u7180',58046:'\u7185',58047:'\u7182',58048:'\u718F',58049:'\u717B',58050:'\u7186',58051:'\u7181',58052:'\u7197',58053:'\u7244',58054:'\u7253',58055:'\u7297',58056:'\u7295',58057:'\u7293',58058:'\u7343',58059:'\u734D',58060:'\u7351',58061:'\u734C',58062:'\u7462',58063:'\u7473',58064:'\u7471',58065:'\u7475',58066:'\u7472',58067:'\u7467',58068:'\u746E',58069:'\u7500',58070:'\u7502',58071:'\u7503',58072:'\u757D',58073:'\u7590',58074:'\u7616',58075:'\u7608',58076:'\u760C',58077:'\u7615',58078:'\u7611',58079:'\u760A',58080:'\u7614',58081:'\u76B8',58082:'\u7781',58083:'\u777C',58084:'\u7785',58085:'\u7782',58086:'\u776E',58087:'\u7780',58088:'\u776F',58089:'\u777E',58090:'\u7783',58091:'\u78B2',58092:'\u78AA',58093:'\u78B4',58094:'\u78AD',58095:'\u78A8',58096:'\u787E',58097:'\u78AB',58098:'\u789E',58099:'\u78A5',58100:'\u78A0',58101:'\u78AC',58102:'\u78A2',58103:'\u78A4',58104:'\u7998',58105:'\u798A',58106:'\u798B',58107:'\u7996',58108:'\u7995',58109:'\u7994',58110:'\u7993',58176:'\u7997',58177:'\u7988',58178:'\u7992',58179:'\u7990',58180:'\u7A2B',58181:'\u7A4A',58182:'\u7A30',58183:'\u7A2F',58184:'\u7A28',58185:'\u7A26',58186:'\u7AA8',58187:'\u7AAB',58188:'\u7AAC',58189:'\u7AEE',58190:'\u7B88',58191:'\u7B9C',58192:'\u7B8A',58193:'\u7B91',58194:'\u7B90',58195:'\u7B96',58196:'\u7B8D',58197:'\u7B8C',58198:'\u7B9B',58199:'\u7B8E',58200:'\u7B85',58201:'\u7B98',58202:'\u5284',58203:'\u7B99',58204:'\u7BA4',58205:'\u7B82',58206:'\u7CBB',58207:'\u7CBF',58208:'\u7CBC',58209:'\u7CBA',58210:'\u7DA7',58211:'\u7DB7',58212:'\u7DC2',58213:'\u7DA3',58214:'\u7DAA',58215:'\u7DC1',58216:'\u7DC0',58217:'\u7DC5',58218:'\u7D9D',58219:'\u7DCE',58220:'\u7DC4',58221:'\u7DC6',58222:'\u7DCB',58223:'\u7DCC',58224:'\u7DAF',58225:'\u7DB9',58226:'\u7D96',58227:'\u7DBC',58228:'\u7D9F',58229:'\u7DA6',58230:'\u7DAE',58231:'\u7DA9',58232:'\u7DA1',58233:'\u7DC9',58234:'\u7F73',58235:'\u7FE2',58236:'\u7FE3',58237:'\u7FE5',58238:'\u7FDE',58273:'\u8024',58274:'\u805D',58275:'\u805C',58276:'\u8189',58277:'\u8186',58278:'\u8183',58279:'\u8187',58280:'\u818D',58281:'\u818C',58282:'\u818B',58283:'\u8215',58284:'\u8497',58285:'\u84A4',58286:'\u84A1',58287:'\u849F',58288:'\u84BA',58289:'\u84CE',58290:'\u84C2',58291:'\u84AC',58292:'\u84AE',58293:'\u84AB',58294:'\u84B9',58295:'\u84B4',58296:'\u84C1',58297:'\u84CD',58298:'\u84AA',58299:'\u849A',58300:'\u84B1',58301:'\u84D0',58302:'\u849D',58303:'\u84A7',58304:'\u84BB',58305:'\u84A2',58306:'\u8494',58307:'\u84C7',58308:'\u84CC',58309:'\u849B',58310:'\u84A9',58311:'\u84AF',58312:'\u84A8',58313:'\u84D6',58314:'\u8498',58315:'\u84B6',58316:'\u84CF',58317:'\u84A0',58318:'\u84D7',58319:'\u84D4',58320:'\u84D2',58321:'\u84DB',58322:'\u84B0',58323:'\u8491',58324:'\u8661',58325:'\u8733',58326:'\u8723',58327:'\u8728',58328:'\u876B',58329:'\u8740',58330:'\u872E',58331:'\u871E',58332:'\u8721',58333:'\u8719',58334:'\u871B',58335:'\u8743',58336:'\u872C',58337:'\u8741',58338:'\u873E',58339:'\u8746',58340:'\u8720',58341:'\u8732',58342:'\u872A',58343:'\u872D',58344:'\u873C',58345:'\u8712',58346:'\u873A',58347:'\u8731',58348:'\u8735',58349:'\u8742',58350:'\u8726',58351:'\u8727',58352:'\u8738',58353:'\u8724',58354:'\u871A',58355:'\u8730',58356:'\u8711',58357:'\u88F7',58358:'\u88E7',58359:'\u88F1',58360:'\u88F2',58361:'\u88FA',58362:'\u88FE',58363:'\u88EE',58364:'\u88FC',58365:'\u88F6',58366:'\u88FB',58432:'\u88F0',58433:'\u88EC',58434:'\u88EB',58435:'\u899D',58436:'\u89A1',58437:'\u899F',58438:'\u899E',58439:'\u89E9',58440:'\u89EB',58441:'\u89E8',58442:'\u8AAB',58443:'\u8A99',58444:'\u8A8B',58445:'\u8A92',58446:'\u8A8F',58447:'\u8A96',58448:'\u8C3D',58449:'\u8C68',58450:'\u8C69',58451:'\u8CD5',58452:'\u8CCF',58453:'\u8CD7',58454:'\u8D96',58455:'\u8E09',58456:'\u8E02',58457:'\u8DFF',58458:'\u8E0D',58459:'\u8DFD',58460:'\u8E0A',58461:'\u8E03',58462:'\u8E07',58463:'\u8E06',58464:'\u8E05',58465:'\u8DFE',58466:'\u8E00',58467:'\u8E04',58468:'\u8F10',58469:'\u8F11',58470:'\u8F0E',58471:'\u8F0D',58472:'\u9123',58473:'\u911C',58474:'\u9120',58475:'\u9122',58476:'\u911F',58477:'\u911D',58478:'\u911A',58479:'\u9124',58480:'\u9121',58481:'\u911B',58482:'\u917A',58483:'\u9172',58484:'\u9179',58485:'\u9173',58486:'\u92A5',58487:'\u92A4',58488:'\u9276',58489:'\u929B',58490:'\u927A',58491:'\u92A0',58492:'\u9294',58493:'\u92AA',58494:'\u928D',58529:'\u92A6',58530:'\u929A',58531:'\u92AB',58532:'\u9279',58533:'\u9297',58534:'\u927F',58535:'\u92A3',58536:'\u92EE',58537:'\u928E',58538:'\u9282',58539:'\u9295',58540:'\u92A2',58541:'\u927D',58542:'\u9288',58543:'\u92A1',58544:'\u928A',58545:'\u9286',58546:'\u928C',58547:'\u9299',58548:'\u92A7',58549:'\u927E',58550:'\u9287',58551:'\u92A9',58552:'\u929D',58553:'\u928B',58554:'\u922D',58555:'\u969E',58556:'\u96A1',58557:'\u96FF',58558:'\u9758',58559:'\u977D',58560:'\u977A',58561:'\u977E',58562:'\u9783',58563:'\u9780',58564:'\u9782',58565:'\u977B',58566:'\u9784',58567:'\u9781',58568:'\u977F',58569:'\u97CE',58570:'\u97CD',58571:'\u9816',58572:'\u98AD',58573:'\u98AE',58574:'\u9902',58575:'\u9900',58576:'\u9907',58577:'\u999D',58578:'\u999C',58579:'\u99C3',58580:'\u99B9',58581:'\u99BB',58582:'\u99BA',58583:'\u99C2',58584:'\u99BD',58585:'\u99C7',58586:'\u9AB1',58587:'\u9AE3',58588:'\u9AE7',58589:'\u9B3E',58590:'\u9B3F',58591:'\u9B60',58592:'\u9B61',58593:'\u9B5F',58594:'\u9CF1',58595:'\u9CF2',58596:'\u9CF5',58597:'\u9EA7',58598:'\u50FF',58599:'\u5103',58600:'\u5130',58601:'\u50F8',58602:'\u5106',58603:'\u5107',58604:'\u50F6',58605:'\u50FE',58606:'\u510B',58607:'\u510C',58608:'\u50FD',58609:'\u510A',58610:'\u528B',58611:'\u528C',58612:'\u52F1',58613:'\u52EF',58614:'\u5648',58615:'\u5642',58616:'\u564C',58617:'\u5635',58618:'\u5641',58619:'\u564A',58620:'\u5649',58621:'\u5646',58622:'\u5658',58688:'\u565A',58689:'\u5640',58690:'\u5633',58691:'\u563D',58692:'\u562C',58693:'\u563E',58694:'\u5638',58695:'\u562A',58696:'\u563A',58697:'\u571A',58698:'\u58AB',58699:'\u589D',58700:'\u58B1',58701:'\u58A0',58702:'\u58A3',58703:'\u58AF',58704:'\u58AC',58705:'\u58A5',58706:'\u58A1',58707:'\u58FF',58708:'\u5AFF',58709:'\u5AF4',58710:'\u5AFD',58711:'\u5AF7',58712:'\u5AF6',58713:'\u5B03',58714:'\u5AF8',58715:'\u5B02',58716:'\u5AF9',58717:'\u5B01',58718:'\u5B07',58719:'\u5B05',58720:'\u5B0F',58721:'\u5C67',58722:'\u5D99',58723:'\u5D97',58724:'\u5D9F',58725:'\u5D92',58726:'\u5DA2',58727:'\u5D93',58728:'\u5D95',58729:'\u5DA0',58730:'\u5D9C',58731:'\u5DA1',58732:'\u5D9A',58733:'\u5D9E',58734:'\u5E69',58735:'\u5E5D',58736:'\u5E60',58737:'\u5E5C',58738:'\u7DF3',58739:'\u5EDB',58740:'\u5EDE',58741:'\u5EE1',58742:'\u5F49',58743:'\u5FB2',58744:'\u618B',58745:'\u6183',58746:'\u6179',58747:'\u61B1',58748:'\u61B0',58749:'\u61A2',58750:'\u6189',58785:'\u619B',58786:'\u6193',58787:'\u61AF',58788:'\u61AD',58789:'\u619F',58790:'\u6192',58791:'\u61AA',58792:'\u61A1',58793:'\u618D',58794:'\u6166',58795:'\u61B3',58796:'\u622D',58797:'\u646E',58798:'\u6470',58799:'\u6496',58800:'\u64A0',58801:'\u6485',58802:'\u6497',58803:'\u649C',58804:'\u648F',58805:'\u648B',58806:'\u648A',58807:'\u648C',58808:'\u64A3',58809:'\u649F',58810:'\u6468',58811:'\u64B1',58812:'\u6498',58813:'\u6576',58814:'\u657A',58815:'\u6579',58816:'\u657B',58817:'\u65B2',58818:'\u65B3',58819:'\u66B5',58820:'\u66B0',58821:'\u66A9',58822:'\u66B2',58823:'\u66B7',58824:'\u66AA',58825:'\u66AF',58826:'\u6A00',58827:'\u6A06',58828:'\u6A17',58829:'\u69E5',58830:'\u69F8',58831:'\u6A15',58832:'\u69F1',58833:'\u69E4',58834:'\u6A20',58835:'\u69FF',58836:'\u69EC',58837:'\u69E2',58838:'\u6A1B',58839:'\u6A1D',58840:'\u69FE',58841:'\u6A27',58842:'\u69F2',58843:'\u69EE',58844:'\u6A14',58845:'\u69F7',58846:'\u69E7',58847:'\u6A40',58848:'\u6A08',58849:'\u69E6',58850:'\u69FB',58851:'\u6A0D',58852:'\u69FC',58853:'\u69EB',58854:'\u6A09',58855:'\u6A04',58856:'\u6A18',58857:'\u6A25',58858:'\u6A0F',58859:'\u69F6',58860:'\u6A26',58861:'\u6A07',58862:'\u69F4',58863:'\u6A16',58864:'\u6B51',58865:'\u6BA5',58866:'\u6BA3',58867:'\u6BA2',58868:'\u6BA6',58869:'\u6C01',58870:'\u6C00',58871:'\u6BFF',58872:'\u6C02',58873:'\u6F41',58874:'\u6F26',58875:'\u6F7E',58876:'\u6F87',58877:'\u6FC6',58878:'\u6F92',58944:'\u6F8D',58945:'\u6F89',58946:'\u6F8C',58947:'\u6F62',58948:'\u6F4F',58949:'\u6F85',58950:'\u6F5A',58951:'\u6F96',58952:'\u6F76',58953:'\u6F6C',58954:'\u6F82',58955:'\u6F55',58956:'\u6F72',58957:'\u6F52',58958:'\u6F50',58959:'\u6F57',58960:'\u6F94',58961:'\u6F93',58962:'\u6F5D',58963:'\u6F00',58964:'\u6F61',58965:'\u6F6B',58966:'\u6F7D',58967:'\u6F67',58968:'\u6F90',58969:'\u6F53',58970:'\u6F8B',58971:'\u6F69',58972:'\u6F7F',58973:'\u6F95',58974:'\u6F63',58975:'\u6F77',58976:'\u6F6A',58977:'\u6F7B',58978:'\u71B2',58979:'\u71AF',58980:'\u719B',58981:'\u71B0',58982:'\u71A0',58983:'\u719A',58984:'\u71A9',58985:'\u71B5',58986:'\u719D',58987:'\u71A5',58988:'\u719E',58989:'\u71A4',58990:'\u71A1',58991:'\u71AA',58992:'\u719C',58993:'\u71A7',58994:'\u71B3',58995:'\u7298',58996:'\u729A',58997:'\u7358',58998:'\u7352',58999:'\u735E',59000:'\u735F',59001:'\u7360',59002:'\u735D',59003:'\u735B',59004:'\u7361',59005:'\u735A',59006:'\u7359',59041:'\u7362',59042:'\u7487',59043:'\u7489',59044:'\u748A',59045:'\u7486',59046:'\u7481',59047:'\u747D',59048:'\u7485',59049:'\u7488',59050:'\u747C',59051:'\u7479',59052:'\u7508',59053:'\u7507',59054:'\u757E',59055:'\u7625',59056:'\u761E',59057:'\u7619',59058:'\u761D',59059:'\u761C',59060:'\u7623',59061:'\u761A',59062:'\u7628',59063:'\u761B',59064:'\u769C',59065:'\u769D',59066:'\u769E',59067:'\u769B',59068:'\u778D',59069:'\u778F',59070:'\u7789',59071:'\u7788',59072:'\u78CD',59073:'\u78BB',59074:'\u78CF',59075:'\u78CC',59076:'\u78D1',59077:'\u78CE',59078:'\u78D4',59079:'\u78C8',59080:'\u78C3',59081:'\u78C4',59082:'\u78C9',59083:'\u799A',59084:'\u79A1',59085:'\u79A0',59086:'\u799C',59087:'\u79A2',59088:'\u799B',59089:'\u6B76',59090:'\u7A39',59091:'\u7AB2',59092:'\u7AB4',59093:'\u7AB3',59094:'\u7BB7',59095:'\u7BCB',59096:'\u7BBE',59097:'\u7BAC',59098:'\u7BCE',59099:'\u7BAF',59100:'\u7BB9',59101:'\u7BCA',59102:'\u7BB5',59103:'\u7CC5',59104:'\u7CC8',59105:'\u7CCC',59106:'\u7CCB',59107:'\u7DF7',59108:'\u7DDB',59109:'\u7DEA',59110:'\u7DE7',59111:'\u7DD7',59112:'\u7DE1',59113:'\u7E03',59114:'\u7DFA',59115:'\u7DE6',59116:'\u7DF6',59117:'\u7DF1',59118:'\u7DF0',59119:'\u7DEE',59120:'\u7DDF',59121:'\u7F76',59122:'\u7FAC',59123:'\u7FB0',59124:'\u7FAD',59125:'\u7FED',59126:'\u7FEB',59127:'\u7FEA',59128:'\u7FEC',59129:'\u7FE6',59130:'\u7FE8',59131:'\u8064',59132:'\u8067',59133:'\u81A3',59134:'\u819F',59200:'\u819E',59201:'\u8195',59202:'\u81A2',59203:'\u8199',59204:'\u8197',59205:'\u8216',59206:'\u824F',59207:'\u8253',59208:'\u8252',59209:'\u8250',59210:'\u824E',59211:'\u8251',59212:'\u8524',59213:'\u853B',59214:'\u850F',59215:'\u8500',59216:'\u8529',59217:'\u850E',59218:'\u8509',59219:'\u850D',59220:'\u851F',59221:'\u850A',59222:'\u8527',59223:'\u851C',59224:'\u84FB',59225:'\u852B',59226:'\u84FA',59227:'\u8508',59228:'\u850C',59229:'\u84F4',59230:'\u852A',59231:'\u84F2',59232:'\u8515',59233:'\u84F7',59234:'\u84EB',59235:'\u84F3',59236:'\u84FC',59237:'\u8512',59238:'\u84EA',59239:'\u84E9',59240:'\u8516',59241:'\u84FE',59242:'\u8528',59243:'\u851D',59244:'\u852E',59245:'\u8502',59246:'\u84FD',59247:'\u851E',59248:'\u84F6',59249:'\u8531',59250:'\u8526',59251:'\u84E7',59252:'\u84E8',59253:'\u84F0',59254:'\u84EF',59255:'\u84F9',59256:'\u8518',59257:'\u8520',59258:'\u8530',59259:'\u850B',59260:'\u8519',59261:'\u852F',59262:'\u8662',59297:'\u8756',59298:'\u8763',59299:'\u8764',59300:'\u8777',59301:'\u87E1',59302:'\u8773',59303:'\u8758',59304:'\u8754',59305:'\u875B',59306:'\u8752',59307:'\u8761',59308:'\u875A',59309:'\u8751',59310:'\u875E',59311:'\u876D',59312:'\u876A',59313:'\u8750',59314:'\u874E',59315:'\u875F',59316:'\u875D',59317:'\u876F',59318:'\u876C',59319:'\u877A',59320:'\u876E',59321:'\u875C',59322:'\u8765',59323:'\u874F',59324:'\u877B',59325:'\u8775',59326:'\u8762',59327:'\u8767',59328:'\u8769',59329:'\u885A',59330:'\u8905',59331:'\u890C',59332:'\u8914',59333:'\u890B',59334:'\u8917',59335:'\u8918',59336:'\u8919',59337:'\u8906',59338:'\u8916',59339:'\u8911',59340:'\u890E',59341:'\u8909',59342:'\u89A2',59343:'\u89A4',59344:'\u89A3',59345:'\u89ED',59346:'\u89F0',59347:'\u89EC',59348:'\u8ACF',59349:'\u8AC6',59350:'\u8AB8',59351:'\u8AD3',59352:'\u8AD1',59353:'\u8AD4',59354:'\u8AD5',59355:'\u8ABB',59356:'\u8AD7',59357:'\u8ABE',59358:'\u8AC0',59359:'\u8AC5',59360:'\u8AD8',59361:'\u8AC3',59362:'\u8ABA',59363:'\u8ABD',59364:'\u8AD9',59365:'\u8C3E',59366:'\u8C4D',59367:'\u8C8F',59368:'\u8CE5',59369:'\u8CDF',59370:'\u8CD9',59371:'\u8CE8',59372:'\u8CDA',59373:'\u8CDD',59374:'\u8CE7',59375:'\u8DA0',59376:'\u8D9C',59377:'\u8DA1',59378:'\u8D9B',59379:'\u8E20',59380:'\u8E23',59381:'\u8E25',59382:'\u8E24',59383:'\u8E2E',59384:'\u8E15',59385:'\u8E1B',59386:'\u8E16',59387:'\u8E11',59388:'\u8E19',59389:'\u8E26',59390:'\u8E27',59456:'\u8E14',59457:'\u8E12',59458:'\u8E18',59459:'\u8E13',59460:'\u8E1C',59461:'\u8E17',59462:'\u8E1A',59463:'\u8F2C',59464:'\u8F24',59465:'\u8F18',59466:'\u8F1A',59467:'\u8F20',59468:'\u8F23',59469:'\u8F16',59470:'\u8F17',59471:'\u9073',59472:'\u9070',59473:'\u906F',59474:'\u9067',59475:'\u906B',59476:'\u912F',59477:'\u912B',59478:'\u9129',59479:'\u912A',59480:'\u9132',59481:'\u9126',59482:'\u912E',59483:'\u9185',59484:'\u9186',59485:'\u918A',59486:'\u9181',59487:'\u9182',59488:'\u9184',59489:'\u9180',59490:'\u92D0',59491:'\u92C3',59492:'\u92C4',59493:'\u92C0',59494:'\u92D9',59495:'\u92B6',59496:'\u92CF',59497:'\u92F1',59498:'\u92DF',59499:'\u92D8',59500:'\u92E9',59501:'\u92D7',59502:'\u92DD',59503:'\u92CC',59504:'\u92EF',59505:'\u92C2',59506:'\u92E8',59507:'\u92CA',59508:'\u92C8',59509:'\u92CE',59510:'\u92E6',59511:'\u92CD',59512:'\u92D5',59513:'\u92C9',59514:'\u92E0',59515:'\u92DE',59516:'\u92E7',59517:'\u92D1',59518:'\u92D3',59553:'\u92B5',59554:'\u92E1',59555:'\u92C6',59556:'\u92B4',59557:'\u957C',59558:'\u95AC',59559:'\u95AB',59560:'\u95AE',59561:'\u95B0',59562:'\u96A4',59563:'\u96A2',59564:'\u96D3',59565:'\u9705',59566:'\u9708',59567:'\u9702',59568:'\u975A',59569:'\u978A',59570:'\u978E',59571:'\u9788',59572:'\u97D0',59573:'\u97CF',59574:'\u981E',59575:'\u981D',59576:'\u9826',59577:'\u9829',59578:'\u9828',59579:'\u9820',59580:'\u981B',59581:'\u9827',59582:'\u98B2',59583:'\u9908',59584:'\u98FA',59585:'\u9911',59586:'\u9914',59587:'\u9916',59588:'\u9917',59589:'\u9915',59590:'\u99DC',59591:'\u99CD',59592:'\u99CF',59593:'\u99D3',59594:'\u99D4',59595:'\u99CE',59596:'\u99C9',59597:'\u99D6',59598:'\u99D8',59599:'\u99CB',59600:'\u99D7',59601:'\u99CC',59602:'\u9AB3',59603:'\u9AEC',59604:'\u9AEB',59605:'\u9AF3',59606:'\u9AF2',59607:'\u9AF1',59608:'\u9B46',59609:'\u9B43',59610:'\u9B67',59611:'\u9B74',59612:'\u9B71',59613:'\u9B66',59614:'\u9B76',59615:'\u9B75',59616:'\u9B70',59617:'\u9B68',59618:'\u9B64',59619:'\u9B6C',59620:'\u9CFC',59621:'\u9CFA',59622:'\u9CFD',59623:'\u9CFF',59624:'\u9CF7',59625:'\u9D07',59626:'\u9D00',59627:'\u9CF9',59628:'\u9CFB',59629:'\u9D08',59630:'\u9D05',59631:'\u9D04',59632:'\u9E83',59633:'\u9ED3',59634:'\u9F0F',59635:'\u9F10',59636:'\u511C',59637:'\u5113',59638:'\u5117',59639:'\u511A',59640:'\u5111',59641:'\u51DE',59642:'\u5334',59643:'\u53E1',59644:'\u5670',59645:'\u5660',59646:'\u566E',59712:'\u5673',59713:'\u5666',59714:'\u5663',59715:'\u566D',59716:'\u5672',59717:'\u565E',59718:'\u5677',59719:'\u571C',59720:'\u571B',59721:'\u58C8',59722:'\u58BD',59723:'\u58C9',59724:'\u58BF',59725:'\u58BA',59726:'\u58C2',59727:'\u58BC',59728:'\u58C6',59729:'\u5B17',59730:'\u5B19',59731:'\u5B1B',59732:'\u5B21',59733:'\u5B14',59734:'\u5B13',59735:'\u5B10',59736:'\u5B16',59737:'\u5B28',59738:'\u5B1A',59739:'\u5B20',59740:'\u5B1E',59741:'\u5BEF',59742:'\u5DAC',59743:'\u5DB1',59744:'\u5DA9',59745:'\u5DA7',59746:'\u5DB5',59747:'\u5DB0',59748:'\u5DAE',59749:'\u5DAA',59750:'\u5DA8',59751:'\u5DB2',59752:'\u5DAD',59753:'\u5DAF',59754:'\u5DB4',59755:'\u5E67',59756:'\u5E68',59757:'\u5E66',59758:'\u5E6F',59759:'\u5EE9',59760:'\u5EE7',59761:'\u5EE6',59762:'\u5EE8',59763:'\u5EE5',59764:'\u5F4B',59765:'\u5FBC',59766:'\u619D',59767:'\u61A8',59768:'\u6196',59769:'\u61C5',59770:'\u61B4',59771:'\u61C6',59772:'\u61C1',59773:'\u61CC',59774:'\u61BA',59809:'\u61BF',59810:'\u61B8',59811:'\u618C',59812:'\u64D7',59813:'\u64D6',59814:'\u64D0',59815:'\u64CF',59816:'\u64C9',59817:'\u64BD',59818:'\u6489',59819:'\u64C3',59820:'\u64DB',59821:'\u64F3',59822:'\u64D9',59823:'\u6533',59824:'\u657F',59825:'\u657C',59826:'\u65A2',59827:'\u66C8',59828:'\u66BE',59829:'\u66C0',59830:'\u66CA',59831:'\u66CB',59832:'\u66CF',59833:'\u66BD',59834:'\u66BB',59835:'\u66BA',59836:'\u66CC',59837:'\u6723',59838:'\u6A34',59839:'\u6A66',59840:'\u6A49',59841:'\u6A67',59842:'\u6A32',59843:'\u6A68',59844:'\u6A3E',59845:'\u6A5D',59846:'\u6A6D',59847:'\u6A76',59848:'\u6A5B',59849:'\u6A51',59850:'\u6A28',59851:'\u6A5A',59852:'\u6A3B',59853:'\u6A3F',59854:'\u6A41',59855:'\u6A6A',59856:'\u6A64',59857:'\u6A50',59858:'\u6A4F',59859:'\u6A54',59860:'\u6A6F',59861:'\u6A69',59862:'\u6A60',59863:'\u6A3C',59864:'\u6A5E',59865:'\u6A56',59866:'\u6A55',59867:'\u6A4D',59868:'\u6A4E',59869:'\u6A46',59870:'\u6B55',59871:'\u6B54',59872:'\u6B56',59873:'\u6BA7',59874:'\u6BAA',59875:'\u6BAB',59876:'\u6BC8',59877:'\u6BC7',59878:'\u6C04',59879:'\u6C03',59880:'\u6C06',59881:'\u6FAD',59882:'\u6FCB',59883:'\u6FA3',59884:'\u6FC7',59885:'\u6FBC',59886:'\u6FCE',59887:'\u6FC8',59888:'\u6F5E',59889:'\u6FC4',59890:'\u6FBD',59891:'\u6F9E',59892:'\u6FCA',59893:'\u6FA8',59894:'\u7004',59895:'\u6FA5',59896:'\u6FAE',59897:'\u6FBA',59898:'\u6FAC',59899:'\u6FAA',59900:'\u6FCF',59901:'\u6FBF',59902:'\u6FB8',59968:'\u6FA2',59969:'\u6FC9',59970:'\u6FAB',59971:'\u6FCD',59972:'\u6FAF',59973:'\u6FB2',59974:'\u6FB0',59975:'\u71C5',59976:'\u71C2',59977:'\u71BF',59978:'\u71B8',59979:'\u71D6',59980:'\u71C0',59981:'\u71C1',59982:'\u71CB',59983:'\u71D4',59984:'\u71CA',59985:'\u71C7',59986:'\u71CF',59987:'\u71BD',59988:'\u71D8',59989:'\u71BC',59990:'\u71C6',59991:'\u71DA',59992:'\u71DB',59993:'\u729D',59994:'\u729E',59995:'\u7369',59996:'\u7366',59997:'\u7367',59998:'\u736C',59999:'\u7365',60000:'\u736B',60001:'\u736A',60002:'\u747F',60003:'\u749A',60004:'\u74A0',60005:'\u7494',60006:'\u7492',60007:'\u7495',60008:'\u74A1',60009:'\u750B',60010:'\u7580',60011:'\u762F',60012:'\u762D',60013:'\u7631',60014:'\u763D',60015:'\u7633',60016:'\u763C',60017:'\u7635',60018:'\u7632',60019:'\u7630',60020:'\u76BB',60021:'\u76E6',60022:'\u779A',60023:'\u779D',60024:'\u77A1',60025:'\u779C',60026:'\u779B',60027:'\u77A2',60028:'\u77A3',60029:'\u7795',60030:'\u7799',60065:'\u7797',60066:'\u78DD',60067:'\u78E9',60068:'\u78E5',60069:'\u78EA',60070:'\u78DE',60071:'\u78E3',60072:'\u78DB',60073:'\u78E1',60074:'\u78E2',60075:'\u78ED',60076:'\u78DF',60077:'\u78E0',60078:'\u79A4',60079:'\u7A44',60080:'\u7A48',60081:'\u7A47',60082:'\u7AB6',60083:'\u7AB8',60084:'\u7AB5',60085:'\u7AB1',60086:'\u7AB7',60087:'\u7BDE',60088:'\u7BE3',60089:'\u7BE7',60090:'\u7BDD',60091:'\u7BD5',60092:'\u7BE5',60093:'\u7BDA',60094:'\u7BE8',60095:'\u7BF9',60096:'\u7BD4',60097:'\u7BEA',60098:'\u7BE2',60099:'\u7BDC',60100:'\u7BEB',60101:'\u7BD8',60102:'\u7BDF',60103:'\u7CD2',60104:'\u7CD4',60105:'\u7CD7',60106:'\u7CD0',60107:'\u7CD1',60108:'\u7E12',60109:'\u7E21',60110:'\u7E17',60111:'\u7E0C',60112:'\u7E1F',60113:'\u7E20',60114:'\u7E13',60115:'\u7E0E',60116:'\u7E1C',60117:'\u7E15',60118:'\u7E1A',60119:'\u7E22',60120:'\u7E0B',60121:'\u7E0F',60122:'\u7E16',60123:'\u7E0D',60124:'\u7E14',60125:'\u7E25',60126:'\u7E24',60127:'\u7F43',60128:'\u7F7B',60129:'\u7F7C',60130:'\u7F7A',60131:'\u7FB1',60132:'\u7FEF',60133:'\u802A',60134:'\u8029',60135:'\u806C',60136:'\u81B1',60137:'\u81A6',60138:'\u81AE',60139:'\u81B9',60140:'\u81B5',60141:'\u81AB',60142:'\u81B0',60143:'\u81AC',60144:'\u81B4',60145:'\u81B2',60146:'\u81B7',60147:'\u81A7',60148:'\u81F2',60149:'\u8255',60150:'\u8256',60151:'\u8257',60152:'\u8556',60153:'\u8545',60154:'\u856B',60155:'\u854D',60156:'\u8553',60157:'\u8561',60158:'\u8558',60224:'\u8540',60225:'\u8546',60226:'\u8564',60227:'\u8541',60228:'\u8562',60229:'\u8544',60230:'\u8551',60231:'\u8547',60232:'\u8563',60233:'\u853E',60234:'\u855B',60235:'\u8571',60236:'\u854E',60237:'\u856E',60238:'\u8575',60239:'\u8555',60240:'\u8567',60241:'\u8560',60242:'\u858C',60243:'\u8566',60244:'\u855D',60245:'\u8554',60246:'\u8565',60247:'\u856C',60248:'\u8663',60249:'\u8665',60250:'\u8664',60251:'\u879B',60252:'\u878F',60253:'\u8797',60254:'\u8793',60255:'\u8792',60256:'\u8788',60257:'\u8781',60258:'\u8796',60259:'\u8798',60260:'\u8779',60261:'\u8787',60262:'\u87A3',60263:'\u8785',60264:'\u8790',60265:'\u8791',60266:'\u879D',60267:'\u8784',60268:'\u8794',60269:'\u879C',60270:'\u879A',60271:'\u8789',60272:'\u891E',60273:'\u8926',60274:'\u8930',60275:'\u892D',60276:'\u892E',60277:'\u8927',60278:'\u8931',60279:'\u8922',60280:'\u8929',60281:'\u8923',60282:'\u892F',60283:'\u892C',60284:'\u891F',60285:'\u89F1',60286:'\u8AE0',60321:'\u8AE2',60322:'\u8AF2',60323:'\u8AF4',60324:'\u8AF5',60325:'\u8ADD',60326:'\u8B14',60327:'\u8AE4',60328:'\u8ADF',60329:'\u8AF0',60330:'\u8AC8',60331:'\u8ADE',60332:'\u8AE1',60333:'\u8AE8',60334:'\u8AFF',60335:'\u8AEF',60336:'\u8AFB',60337:'\u8C91',60338:'\u8C92',60339:'\u8C90',60340:'\u8CF5',60341:'\u8CEE',60342:'\u8CF1',60343:'\u8CF0',60344:'\u8CF3',60345:'\u8D6C',60346:'\u8D6E',60347:'\u8DA5',60348:'\u8DA7',60349:'\u8E33',60350:'\u8E3E',60351:'\u8E38',60352:'\u8E40',60353:'\u8E45',60354:'\u8E36',60355:'\u8E3C',60356:'\u8E3D',60357:'\u8E41',60358:'\u8E30',60359:'\u8E3F',60360:'\u8EBD',60361:'\u8F36',60362:'\u8F2E',60363:'\u8F35',60364:'\u8F32',60365:'\u8F39',60366:'\u8F37',60367:'\u8F34',60368:'\u9076',60369:'\u9079',60370:'\u907B',60371:'\u9086',60372:'\u90FA',60373:'\u9133',60374:'\u9135',60375:'\u9136',60376:'\u9193',60377:'\u9190',60378:'\u9191',60379:'\u918D',60380:'\u918F',60381:'\u9327',60382:'\u931E',60383:'\u9308',60384:'\u931F',60385:'\u9306',60386:'\u930F',60387:'\u937A',60388:'\u9338',60389:'\u933C',60390:'\u931B',60391:'\u9323',60392:'\u9312',60393:'\u9301',60394:'\u9346',60395:'\u932D',60396:'\u930E',60397:'\u930D',60398:'\u92CB',60399:'\u931D',60400:'\u92FA',60401:'\u9325',60402:'\u9313',60403:'\u92F9',60404:'\u92F7',60405:'\u9334',60406:'\u9302',60407:'\u9324',60408:'\u92FF',60409:'\u9329',60410:'\u9339',60411:'\u9335',60412:'\u932A',60413:'\u9314',60414:'\u930C',60480:'\u930B',60481:'\u92FE',60482:'\u9309',60483:'\u9300',60484:'\u92FB',60485:'\u9316',60486:'\u95BC',60487:'\u95CD',60488:'\u95BE',60489:'\u95B9',60490:'\u95BA',60491:'\u95B6',60492:'\u95BF',60493:'\u95B5',60494:'\u95BD',60495:'\u96A9',60496:'\u96D4',60497:'\u970B',60498:'\u9712',60499:'\u9710',60500:'\u9799',60501:'\u9797',60502:'\u9794',60503:'\u97F0',60504:'\u97F8',60505:'\u9835',60506:'\u982F',60507:'\u9832',60508:'\u9924',60509:'\u991F',60510:'\u9927',60511:'\u9929',60512:'\u999E',60513:'\u99EE',60514:'\u99EC',60515:'\u99E5',60516:'\u99E4',60517:'\u99F0',60518:'\u99E3',60519:'\u99EA',60520:'\u99E9',60521:'\u99E7',60522:'\u9AB9',60523:'\u9ABF',60524:'\u9AB4',60525:'\u9ABB',60526:'\u9AF6',60527:'\u9AFA',60528:'\u9AF9',60529:'\u9AF7',60530:'\u9B33',60531:'\u9B80',60532:'\u9B85',60533:'\u9B87',60534:'\u9B7C',60535:'\u9B7E',60536:'\u9B7B',60537:'\u9B82',60538:'\u9B93',60539:'\u9B92',60540:'\u9B90',60541:'\u9B7A',60542:'\u9B95',60577:'\u9B7D',60578:'\u9B88',60579:'\u9D25',60580:'\u9D17',60581:'\u9D20',60582:'\u9D1E',60583:'\u9D14',60584:'\u9D29',60585:'\u9D1D',60586:'\u9D18',60587:'\u9D22',60588:'\u9D10',60589:'\u9D19',60590:'\u9D1F',60591:'\u9E88',60592:'\u9E86',60593:'\u9E87',60594:'\u9EAE',60595:'\u9EAD',60596:'\u9ED5',60597:'\u9ED6',60598:'\u9EFA',60599:'\u9F12',60600:'\u9F3D',60601:'\u5126',60602:'\u5125',60603:'\u5122',60604:'\u5124',60605:'\u5120',60606:'\u5129',60607:'\u52F4',60608:'\u5693',60609:'\u568C',60610:'\u568D',60611:'\u5686',60612:'\u5684',60613:'\u5683',60614:'\u567E',60615:'\u5682',60616:'\u567F',60617:'\u5681',60618:'\u58D6',60619:'\u58D4',60620:'\u58CF',60621:'\u58D2',60622:'\u5B2D',60623:'\u5B25',60624:'\u5B32',60625:'\u5B23',60626:'\u5B2C',60627:'\u5B27',60628:'\u5B26',60629:'\u5B2F',60630:'\u5B2E',60631:'\u5B7B',60632:'\u5BF1',60633:'\u5BF2',60634:'\u5DB7',60635:'\u5E6C',60636:'\u5E6A',60637:'\u5FBE',60638:'\u5FBB',60639:'\u61C3',60640:'\u61B5',60641:'\u61BC',60642:'\u61E7',60643:'\u61E0',60644:'\u61E5',60645:'\u61E4',60646:'\u61E8',60647:'\u61DE',60648:'\u64EF',60649:'\u64E9',60650:'\u64E3',60651:'\u64EB',60652:'\u64E4',60653:'\u64E8',60654:'\u6581',60655:'\u6580',60656:'\u65B6',60657:'\u65DA',60658:'\u66D2',60659:'\u6A8D',60660:'\u6A96',60661:'\u6A81',60662:'\u6AA5',60663:'\u6A89',60664:'\u6A9F',60665:'\u6A9B',60666:'\u6AA1',60667:'\u6A9E',60668:'\u6A87',60669:'\u6A93',60670:'\u6A8E',60736:'\u6A95',60737:'\u6A83',60738:'\u6AA8',60739:'\u6AA4',60740:'\u6A91',60741:'\u6A7F',60742:'\u6AA6',60743:'\u6A9A',60744:'\u6A85',60745:'\u6A8C',60746:'\u6A92',60747:'\u6B5B',60748:'\u6BAD',60749:'\u6C09',60750:'\u6FCC',60751:'\u6FA9',60752:'\u6FF4',60753:'\u6FD4',60754:'\u6FE3',60755:'\u6FDC',60756:'\u6FED',60757:'\u6FE7',60758:'\u6FE6',60759:'\u6FDE',60760:'\u6FF2',60761:'\u6FDD',60762:'\u6FE2',60763:'\u6FE8',60764:'\u71E1',60765:'\u71F1',60766:'\u71E8',60767:'\u71F2',60768:'\u71E4',60769:'\u71F0',60770:'\u71E2',60771:'\u7373',60772:'\u736E',60773:'\u736F',60774:'\u7497',60775:'\u74B2',60776:'\u74AB',60777:'\u7490',60778:'\u74AA',60779:'\u74AD',60780:'\u74B1',60781:'\u74A5',60782:'\u74AF',60783:'\u7510',60784:'\u7511',60785:'\u7512',60786:'\u750F',60787:'\u7584',60788:'\u7643',60789:'\u7648',60790:'\u7649',60791:'\u7647',60792:'\u76A4',60793:'\u76E9',60794:'\u77B5',60795:'\u77AB',60796:'\u77B2',60797:'\u77B7',60798:'\u77B6',60833:'\u77B4',60834:'\u77B1',60835:'\u77A8',60836:'\u77F0',60837:'\u78F3',60838:'\u78FD',60839:'\u7902',60840:'\u78FB',60841:'\u78FC',60842:'\u78F2',60843:'\u7905',60844:'\u78F9',60845:'\u78FE',60846:'\u7904',60847:'\u79AB',60848:'\u79A8',60849:'\u7A5C',60850:'\u7A5B',60851:'\u7A56',60852:'\u7A58',60853:'\u7A54',60854:'\u7A5A',60855:'\u7ABE',60856:'\u7AC0',60857:'\u7AC1',60858:'\u7C05',60859:'\u7C0F',60860:'\u7BF2',60861:'\u7C00',60862:'\u7BFF',60863:'\u7BFB',60864:'\u7C0E',60865:'\u7BF4',60866:'\u7C0B',60867:'\u7BF3',60868:'\u7C02',60869:'\u7C09',60870:'\u7C03',60871:'\u7C01',60872:'\u7BF8',60873:'\u7BFD',60874:'\u7C06',60875:'\u7BF0',60876:'\u7BF1',60877:'\u7C10',60878:'\u7C0A',60879:'\u7CE8',60880:'\u7E2D',60881:'\u7E3C',60882:'\u7E42',60883:'\u7E33',60884:'\u9848',60885:'\u7E38',60886:'\u7E2A',60887:'\u7E49',60888:'\u7E40',60889:'\u7E47',60890:'\u7E29',60891:'\u7E4C',60892:'\u7E30',60893:'\u7E3B',60894:'\u7E36',60895:'\u7E44',60896:'\u7E3A',60897:'\u7F45',60898:'\u7F7F',60899:'\u7F7E',60900:'\u7F7D',60901:'\u7FF4',60902:'\u7FF2',60903:'\u802C',60904:'\u81BB',60905:'\u81C4',60906:'\u81CC',60907:'\u81CA',60908:'\u81C5',60909:'\u81C7',60910:'\u81BC',60911:'\u81E9',60912:'\u825B',60913:'\u825A',60914:'\u825C',60915:'\u8583',60916:'\u8580',60917:'\u858F',60918:'\u85A7',60919:'\u8595',60920:'\u85A0',60921:'\u858B',60922:'\u85A3',60923:'\u857B',60924:'\u85A4',60925:'\u859A',60926:'\u859E',60992:'\u8577',60993:'\u857C',60994:'\u8589',60995:'\u85A1',60996:'\u857A',60997:'\u8578',60998:'\u8557',60999:'\u858E',61000:'\u8596',61001:'\u8586',61002:'\u858D',61003:'\u8599',61004:'\u859D',61005:'\u8581',61006:'\u85A2',61007:'\u8582',61008:'\u8588',61009:'\u8585',61010:'\u8579',61011:'\u8576',61012:'\u8598',61013:'\u8590',61014:'\u859F',61015:'\u8668',61016:'\u87BE',61017:'\u87AA',61018:'\u87AD',61019:'\u87C5',61020:'\u87B0',61021:'\u87AC',61022:'\u87B9',61023:'\u87B5',61024:'\u87BC',61025:'\u87AE',61026:'\u87C9',61027:'\u87C3',61028:'\u87C2',61029:'\u87CC',61030:'\u87B7',61031:'\u87AF',61032:'\u87C4',61033:'\u87CA',61034:'\u87B4',61035:'\u87B6',61036:'\u87BF',61037:'\u87B8',61038:'\u87BD',61039:'\u87DE',61040:'\u87B2',61041:'\u8935',61042:'\u8933',61043:'\u893C',61044:'\u893E',61045:'\u8941',61046:'\u8952',61047:'\u8937',61048:'\u8942',61049:'\u89AD',61050:'\u89AF',61051:'\u89AE',61052:'\u89F2',61053:'\u89F3',61054:'\u8B1E',61089:'\u8B18',61090:'\u8B16',61091:'\u8B11',61092:'\u8B05',61093:'\u8B0B',61094:'\u8B22',61095:'\u8B0F',61096:'\u8B12',61097:'\u8B15',61098:'\u8B07',61099:'\u8B0D',61100:'\u8B08',61101:'\u8B06',61102:'\u8B1C',61103:'\u8B13',61104:'\u8B1A',61105:'\u8C4F',61106:'\u8C70',61107:'\u8C72',61108:'\u8C71',61109:'\u8C6F',61110:'\u8C95',61111:'\u8C94',61112:'\u8CF9',61113:'\u8D6F',61114:'\u8E4E',61115:'\u8E4D',61116:'\u8E53',61117:'\u8E50',61118:'\u8E4C',61119:'\u8E47',61120:'\u8F43',61121:'\u8F40',61122:'\u9085',61123:'\u907E',61124:'\u9138',61125:'\u919A',61126:'\u91A2',61127:'\u919B',61128:'\u9199',61129:'\u919F',61130:'\u91A1',61131:'\u919D',61132:'\u91A0',61133:'\u93A1',61134:'\u9383',61135:'\u93AF',61136:'\u9364',61137:'\u9356',61138:'\u9347',61139:'\u937C',61140:'\u9358',61141:'\u935C',61142:'\u9376',61143:'\u9349',61144:'\u9350',61145:'\u9351',61146:'\u9360',61147:'\u936D',61148:'\u938F',61149:'\u934C',61150:'\u936A',61151:'\u9379',61152:'\u9357',61153:'\u9355',61154:'\u9352',61155:'\u934F',61156:'\u9371',61157:'\u9377',61158:'\u937B',61159:'\u9361',61160:'\u935E',61161:'\u9363',61162:'\u9367',61163:'\u9380',61164:'\u934E',61165:'\u9359',61166:'\u95C7',61167:'\u95C0',61168:'\u95C9',61169:'\u95C3',61170:'\u95C5',61171:'\u95B7',61172:'\u96AE',61173:'\u96B0',61174:'\u96AC',61175:'\u9720',61176:'\u971F',61177:'\u9718',61178:'\u971D',61179:'\u9719',61180:'\u979A',61181:'\u97A1',61182:'\u979C',61248:'\u979E',61249:'\u979D',61250:'\u97D5',61251:'\u97D4',61252:'\u97F1',61253:'\u9841',61254:'\u9844',61255:'\u984A',61256:'\u9849',61257:'\u9845',61258:'\u9843',61259:'\u9925',61260:'\u992B',61261:'\u992C',61262:'\u992A',61263:'\u9933',61264:'\u9932',61265:'\u992F',61266:'\u992D',61267:'\u9931',61268:'\u9930',61269:'\u9998',61270:'\u99A3',61271:'\u99A1',61272:'\u9A02',61273:'\u99FA',61274:'\u99F4',61275:'\u99F7',61276:'\u99F9',61277:'\u99F8',61278:'\u99F6',61279:'\u99FB',61280:'\u99FD',61281:'\u99FE',61282:'\u99FC',61283:'\u9A03',61284:'\u9ABE',61285:'\u9AFE',61286:'\u9AFD',61287:'\u9B01',61288:'\u9AFC',61289:'\u9B48',61290:'\u9B9A',61291:'\u9BA8',61292:'\u9B9E',61293:'\u9B9B',61294:'\u9BA6',61295:'\u9BA1',61296:'\u9BA5',61297:'\u9BA4',61298:'\u9B86',61299:'\u9BA2',61300:'\u9BA0',61301:'\u9BAF',61302:'\u9D33',61303:'\u9D41',61304:'\u9D67',61305:'\u9D36',61306:'\u9D2E',61307:'\u9D2F',61308:'\u9D31',61309:'\u9D38',61310:'\u9D30',61345:'\u9D45',61346:'\u9D42',61347:'\u9D43',61348:'\u9D3E',61349:'\u9D37',61350:'\u9D40',61351:'\u9D3D',61352:'\u7FF5',61353:'\u9D2D',61354:'\u9E8A',61355:'\u9E89',61356:'\u9E8D',61357:'\u9EB0',61358:'\u9EC8',61359:'\u9EDA',61360:'\u9EFB',61361:'\u9EFF',61362:'\u9F24',61363:'\u9F23',61364:'\u9F22',61365:'\u9F54',61366:'\u9FA0',61367:'\u5131',61368:'\u512D',61369:'\u512E',61370:'\u5698',61371:'\u569C',61372:'\u5697',61373:'\u569A',61374:'\u569D',61375:'\u5699',61376:'\u5970',61377:'\u5B3C',61378:'\u5C69',61379:'\u5C6A',61380:'\u5DC0',61381:'\u5E6D',61382:'\u5E6E',61383:'\u61D8',61384:'\u61DF',61385:'\u61ED',61386:'\u61EE',61387:'\u61F1',61388:'\u61EA',61389:'\u61F0',61390:'\u61EB',61391:'\u61D6',61392:'\u61E9',61393:'\u64FF',61394:'\u6504',61395:'\u64FD',61396:'\u64F8',61397:'\u6501',61398:'\u6503',61399:'\u64FC',61400:'\u6594',61401:'\u65DB',61402:'\u66DA',61403:'\u66DB',61404:'\u66D8',61405:'\u6AC5',61406:'\u6AB9',61407:'\u6ABD',61408:'\u6AE1',61409:'\u6AC6',61410:'\u6ABA',61411:'\u6AB6',61412:'\u6AB7',61413:'\u6AC7',61414:'\u6AB4',61415:'\u6AAD',61416:'\u6B5E',61417:'\u6BC9',61418:'\u6C0B',61419:'\u7007',61420:'\u700C',61421:'\u700D',61422:'\u7001',61423:'\u7005',61424:'\u7014',61425:'\u700E',61426:'\u6FFF',61427:'\u7000',61428:'\u6FFB',61429:'\u7026',61430:'\u6FFC',61431:'\u6FF7',61432:'\u700A',61433:'\u7201',61434:'\u71FF',61435:'\u71F9',61436:'\u7203',61437:'\u71FD',61438:'\u7376',61504:'\u74B8',61505:'\u74C0',61506:'\u74B5',61507:'\u74C1',61508:'\u74BE',61509:'\u74B6',61510:'\u74BB',61511:'\u74C2',61512:'\u7514',61513:'\u7513',61514:'\u765C',61515:'\u7664',61516:'\u7659',61517:'\u7650',61518:'\u7653',61519:'\u7657',61520:'\u765A',61521:'\u76A6',61522:'\u76BD',61523:'\u76EC',61524:'\u77C2',61525:'\u77BA',61526:'\u78FF',61527:'\u790C',61528:'\u7913',61529:'\u7914',61530:'\u7909',61531:'\u7910',61532:'\u7912',61533:'\u7911',61534:'\u79AD',61535:'\u79AC',61536:'\u7A5F',61537:'\u7C1C',61538:'\u7C29',61539:'\u7C19',61540:'\u7C20',61541:'\u7C1F',61542:'\u7C2D',61543:'\u7C1D',61544:'\u7C26',61545:'\u7C28',61546:'\u7C22',61547:'\u7C25',61548:'\u7C30',61549:'\u7E5C',61550:'\u7E50',61551:'\u7E56',61552:'\u7E63',61553:'\u7E58',61554:'\u7E62',61555:'\u7E5F',61556:'\u7E51',61557:'\u7E60',61558:'\u7E57',61559:'\u7E53',61560:'\u7FB5',61561:'\u7FB3',61562:'\u7FF7',61563:'\u7FF8',61564:'\u8075',61565:'\u81D1',61566:'\u81D2',61601:'\u81D0',61602:'\u825F',61603:'\u825E',61604:'\u85B4',61605:'\u85C6',61606:'\u85C0',61607:'\u85C3',61608:'\u85C2',61609:'\u85B3',61610:'\u85B5',61611:'\u85BD',61612:'\u85C7',61613:'\u85C4',61614:'\u85BF',61615:'\u85CB',61616:'\u85CE',61617:'\u85C8',61618:'\u85C5',61619:'\u85B1',61620:'\u85B6',61621:'\u85D2',61622:'\u8624',61623:'\u85B8',61624:'\u85B7',61625:'\u85BE',61626:'\u8669',61627:'\u87E7',61628:'\u87E6',61629:'\u87E2',61630:'\u87DB',61631:'\u87EB',61632:'\u87EA',61633:'\u87E5',61634:'\u87DF',61635:'\u87F3',61636:'\u87E4',61637:'\u87D4',61638:'\u87DC',61639:'\u87D3',61640:'\u87ED',61641:'\u87D8',61642:'\u87E3',61643:'\u87A4',61644:'\u87D7',61645:'\u87D9',61646:'\u8801',61647:'\u87F4',61648:'\u87E8',61649:'\u87DD',61650:'\u8953',61651:'\u894B',61652:'\u894F',61653:'\u894C',61654:'\u8946',61655:'\u8950',61656:'\u8951',61657:'\u8949',61658:'\u8B2A',61659:'\u8B27',61660:'\u8B23',61661:'\u8B33',61662:'\u8B30',61663:'\u8B35',61664:'\u8B47',61665:'\u8B2F',61666:'\u8B3C',61667:'\u8B3E',61668:'\u8B31',61669:'\u8B25',61670:'\u8B37',61671:'\u8B26',61672:'\u8B36',61673:'\u8B2E',61674:'\u8B24',61675:'\u8B3B',61676:'\u8B3D',61677:'\u8B3A',61678:'\u8C42',61679:'\u8C75',61680:'\u8C99',61681:'\u8C98',61682:'\u8C97',61683:'\u8CFE',61684:'\u8D04',61685:'\u8D02',61686:'\u8D00',61687:'\u8E5C',61688:'\u8E62',61689:'\u8E60',61690:'\u8E57',61691:'\u8E56',61692:'\u8E5E',61693:'\u8E65',61694:'\u8E67',61760:'\u8E5B',61761:'\u8E5A',61762:'\u8E61',61763:'\u8E5D',61764:'\u8E69',61765:'\u8E54',61766:'\u8F46',61767:'\u8F47',61768:'\u8F48',61769:'\u8F4B',61770:'\u9128',61771:'\u913A',61772:'\u913B',61773:'\u913E',61774:'\u91A8',61775:'\u91A5',61776:'\u91A7',61777:'\u91AF',61778:'\u91AA',61779:'\u93B5',61780:'\u938C',61781:'\u9392',61782:'\u93B7',61783:'\u939B',61784:'\u939D',61785:'\u9389',61786:'\u93A7',61787:'\u938E',61788:'\u93AA',61789:'\u939E',61790:'\u93A6',61791:'\u9395',61792:'\u9388',61793:'\u9399',61794:'\u939F',61795:'\u938D',61796:'\u93B1',61797:'\u9391',61798:'\u93B2',61799:'\u93A4',61800:'\u93A8',61801:'\u93B4',61802:'\u93A3',61803:'\u93A5',61804:'\u95D2',61805:'\u95D3',61806:'\u95D1',61807:'\u96B3',61808:'\u96D7',61809:'\u96DA',61810:'\u5DC2',61811:'\u96DF',61812:'\u96D8',61813:'\u96DD',61814:'\u9723',61815:'\u9722',61816:'\u9725',61817:'\u97AC',61818:'\u97AE',61819:'\u97A8',61820:'\u97AB',61821:'\u97A4',61822:'\u97AA',61857:'\u97A2',61858:'\u97A5',61859:'\u97D7',61860:'\u97D9',61861:'\u97D6',61862:'\u97D8',61863:'\u97FA',61864:'\u9850',61865:'\u9851',61866:'\u9852',61867:'\u98B8',61868:'\u9941',61869:'\u993C',61870:'\u993A',61871:'\u9A0F',61872:'\u9A0B',61873:'\u9A09',61874:'\u9A0D',61875:'\u9A04',61876:'\u9A11',61877:'\u9A0A',61878:'\u9A05',61879:'\u9A07',61880:'\u9A06',61881:'\u9AC0',61882:'\u9ADC',61883:'\u9B08',61884:'\u9B04',61885:'\u9B05',61886:'\u9B29',61887:'\u9B35',61888:'\u9B4A',61889:'\u9B4C',61890:'\u9B4B',61891:'\u9BC7',61892:'\u9BC6',61893:'\u9BC3',61894:'\u9BBF',61895:'\u9BC1',61896:'\u9BB5',61897:'\u9BB8',61898:'\u9BD3',61899:'\u9BB6',61900:'\u9BC4',61901:'\u9BB9',61902:'\u9BBD',61903:'\u9D5C',61904:'\u9D53',61905:'\u9D4F',61906:'\u9D4A',61907:'\u9D5B',61908:'\u9D4B',61909:'\u9D59',61910:'\u9D56',61911:'\u9D4C',61912:'\u9D57',61913:'\u9D52',61914:'\u9D54',61915:'\u9D5F',61916:'\u9D58',61917:'\u9D5A',61918:'\u9E8E',61919:'\u9E8C',61920:'\u9EDF',61921:'\u9F01',61922:'\u9F00',61923:'\u9F16',61924:'\u9F25',61925:'\u9F2B',61926:'\u9F2A',61927:'\u9F29',61928:'\u9F28',61929:'\u9F4C',61930:'\u9F55',61931:'\u5134',61932:'\u5135',61933:'\u5296',61934:'\u52F7',61935:'\u53B4',61936:'\u56AB',61937:'\u56AD',61938:'\u56A6',61939:'\u56A7',61940:'\u56AA',61941:'\u56AC',61942:'\u58DA',61943:'\u58DD',61944:'\u58DB',61945:'\u5912',61946:'\u5B3D',61947:'\u5B3E',61948:'\u5B3F',61949:'\u5DC3',61950:'\u5E70',62016:'\u5FBF',62017:'\u61FB',62018:'\u6507',62019:'\u6510',62020:'\u650D',62021:'\u6509',62022:'\u650C',62023:'\u650E',62024:'\u6584',62025:'\u65DE',62026:'\u65DD',62027:'\u66DE',62028:'\u6AE7',62029:'\u6AE0',62030:'\u6ACC',62031:'\u6AD1',62032:'\u6AD9',62033:'\u6ACB',62034:'\u6ADF',62035:'\u6ADC',62036:'\u6AD0',62037:'\u6AEB',62038:'\u6ACF',62039:'\u6ACD',62040:'\u6ADE',62041:'\u6B60',62042:'\u6BB0',62043:'\u6C0C',62044:'\u7019',62045:'\u7027',62046:'\u7020',62047:'\u7016',62048:'\u702B',62049:'\u7021',62050:'\u7022',62051:'\u7023',62052:'\u7029',62053:'\u7017',62054:'\u7024',62055:'\u701C',62056:'\u702A',62057:'\u720C',62058:'\u720A',62059:'\u7207',62060:'\u7202',62061:'\u7205',62062:'\u72A5',62063:'\u72A6',62064:'\u72A4',62065:'\u72A3',62066:'\u72A1',62067:'\u74CB',62068:'\u74C5',62069:'\u74B7',62070:'\u74C3',62071:'\u7516',62072:'\u7660',62073:'\u77C9',62074:'\u77CA',62075:'\u77C4',62076:'\u77F1',62077:'\u791D',62078:'\u791B',62113:'\u7921',62114:'\u791C',62115:'\u7917',62116:'\u791E',62117:'\u79B0',62118:'\u7A67',62119:'\u7A68',62120:'\u7C33',62121:'\u7C3C',62122:'\u7C39',62123:'\u7C2C',62124:'\u7C3B',62125:'\u7CEC',62126:'\u7CEA',62127:'\u7E76',62128:'\u7E75',62129:'\u7E78',62130:'\u7E70',62131:'\u7E77',62132:'\u7E6F',62133:'\u7E7A',62134:'\u7E72',62135:'\u7E74',62136:'\u7E68',62137:'\u7F4B',62138:'\u7F4A',62139:'\u7F83',62140:'\u7F86',62141:'\u7FB7',62142:'\u7FFD',62143:'\u7FFE',62144:'\u8078',62145:'\u81D7',62146:'\u81D5',62147:'\u8264',62148:'\u8261',62149:'\u8263',62150:'\u85EB',62151:'\u85F1',62152:'\u85ED',62153:'\u85D9',62154:'\u85E1',62155:'\u85E8',62156:'\u85DA',62157:'\u85D7',62158:'\u85EC',62159:'\u85F2',62160:'\u85F8',62161:'\u85D8',62162:'\u85DF',62163:'\u85E3',62164:'\u85DC',62165:'\u85D1',62166:'\u85F0',62167:'\u85E6',62168:'\u85EF',62169:'\u85DE',62170:'\u85E2',62171:'\u8800',62172:'\u87FA',62173:'\u8803',62174:'\u87F6',62175:'\u87F7',62176:'\u8809',62177:'\u880C',62178:'\u880B',62179:'\u8806',62180:'\u87FC',62181:'\u8808',62182:'\u87FF',62183:'\u880A',62184:'\u8802',62185:'\u8962',62186:'\u895A',62187:'\u895B',62188:'\u8957',62189:'\u8961',62190:'\u895C',62191:'\u8958',62192:'\u895D',62193:'\u8959',62194:'\u8988',62195:'\u89B7',62196:'\u89B6',62197:'\u89F6',62198:'\u8B50',62199:'\u8B48',62200:'\u8B4A',62201:'\u8B40',62202:'\u8B53',62203:'\u8B56',62204:'\u8B54',62205:'\u8B4B',62206:'\u8B55',62272:'\u8B51',62273:'\u8B42',62274:'\u8B52',62275:'\u8B57',62276:'\u8C43',62277:'\u8C77',62278:'\u8C76',62279:'\u8C9A',62280:'\u8D06',62281:'\u8D07',62282:'\u8D09',62283:'\u8DAC',62284:'\u8DAA',62285:'\u8DAD',62286:'\u8DAB',62287:'\u8E6D',62288:'\u8E78',62289:'\u8E73',62290:'\u8E6A',62291:'\u8E6F',62292:'\u8E7B',62293:'\u8EC2',62294:'\u8F52',62295:'\u8F51',62296:'\u8F4F',62297:'\u8F50',62298:'\u8F53',62299:'\u8FB4',62300:'\u9140',62301:'\u913F',62302:'\u91B0',62303:'\u91AD',62304:'\u93DE',62305:'\u93C7',62306:'\u93CF',62307:'\u93C2',62308:'\u93DA',62309:'\u93D0',62310:'\u93F9',62311:'\u93EC',62312:'\u93CC',62313:'\u93D9',62314:'\u93A9',62315:'\u93E6',62316:'\u93CA',62317:'\u93D4',62318:'\u93EE',62319:'\u93E3',62320:'\u93D5',62321:'\u93C4',62322:'\u93CE',62323:'\u93C0',62324:'\u93D2',62325:'\u93E7',62326:'\u957D',62327:'\u95DA',62328:'\u95DB',62329:'\u96E1',62330:'\u9729',62331:'\u972B',62332:'\u972C',62333:'\u9728',62334:'\u9726',62369:'\u97B3',62370:'\u97B7',62371:'\u97B6',62372:'\u97DD',62373:'\u97DE',62374:'\u97DF',62375:'\u985C',62376:'\u9859',62377:'\u985D',62378:'\u9857',62379:'\u98BF',62380:'\u98BD',62381:'\u98BB',62382:'\u98BE',62383:'\u9948',62384:'\u9947',62385:'\u9943',62386:'\u99A6',62387:'\u99A7',62388:'\u9A1A',62389:'\u9A15',62390:'\u9A25',62391:'\u9A1D',62392:'\u9A24',62393:'\u9A1B',62394:'\u9A22',62395:'\u9A20',62396:'\u9A27',62397:'\u9A23',62398:'\u9A1E',62399:'\u9A1C',62400:'\u9A14',62401:'\u9AC2',62402:'\u9B0B',62403:'\u9B0A',62404:'\u9B0E',62405:'\u9B0C',62406:'\u9B37',62407:'\u9BEA',62408:'\u9BEB',62409:'\u9BE0',62410:'\u9BDE',62411:'\u9BE4',62412:'\u9BE6',62413:'\u9BE2',62414:'\u9BF0',62415:'\u9BD4',62416:'\u9BD7',62417:'\u9BEC',62418:'\u9BDC',62419:'\u9BD9',62420:'\u9BE5',62421:'\u9BD5',62422:'\u9BE1',62423:'\u9BDA',62424:'\u9D77',62425:'\u9D81',62426:'\u9D8A',62427:'\u9D84',62428:'\u9D88',62429:'\u9D71',62430:'\u9D80',62431:'\u9D78',62432:'\u9D86',62433:'\u9D8B',62434:'\u9D8C',62435:'\u9D7D',62436:'\u9D6B',62437:'\u9D74',62438:'\u9D75',62439:'\u9D70',62440:'\u9D69',62441:'\u9D85',62442:'\u9D73',62443:'\u9D7B',62444:'\u9D82',62445:'\u9D6F',62446:'\u9D79',62447:'\u9D7F',62448:'\u9D87',62449:'\u9D68',62450:'\u9E94',62451:'\u9E91',62452:'\u9EC0',62453:'\u9EFC',62454:'\u9F2D',62455:'\u9F40',62456:'\u9F41',62457:'\u9F4D',62458:'\u9F56',62459:'\u9F57',62460:'\u9F58',62461:'\u5337',62462:'\u56B2',62528:'\u56B5',62529:'\u56B3',62530:'\u58E3',62531:'\u5B45',62532:'\u5DC6',62533:'\u5DC7',62534:'\u5EEE',62535:'\u5EEF',62536:'\u5FC0',62537:'\u5FC1',62538:'\u61F9',62539:'\u6517',62540:'\u6516',62541:'\u6515',62542:'\u6513',62543:'\u65DF',62544:'\u66E8',62545:'\u66E3',62546:'\u66E4',62547:'\u6AF3',62548:'\u6AF0',62549:'\u6AEA',62550:'\u6AE8',62551:'\u6AF9',62552:'\u6AF1',62553:'\u6AEE',62554:'\u6AEF',62555:'\u703C',62556:'\u7035',62557:'\u702F',62558:'\u7037',62559:'\u7034',62560:'\u7031',62561:'\u7042',62562:'\u7038',62563:'\u703F',62564:'\u703A',62565:'\u7039',62566:'\u7040',62567:'\u703B',62568:'\u7033',62569:'\u7041',62570:'\u7213',62571:'\u7214',62572:'\u72A8',62573:'\u737D',62574:'\u737C',62575:'\u74BA',62576:'\u76AB',62577:'\u76AA',62578:'\u76BE',62579:'\u76ED',62580:'\u77CC',62581:'\u77CE',62582:'\u77CF',62583:'\u77CD',62584:'\u77F2',62585:'\u7925',62586:'\u7923',62587:'\u7927',62588:'\u7928',62589:'\u7924',62590:'\u7929',62625:'\u79B2',62626:'\u7A6E',62627:'\u7A6C',62628:'\u7A6D',62629:'\u7AF7',62630:'\u7C49',62631:'\u7C48',62632:'\u7C4A',62633:'\u7C47',62634:'\u7C45',62635:'\u7CEE',62636:'\u7E7B',62637:'\u7E7E',62638:'\u7E81',62639:'\u7E80',62640:'\u7FBA',62641:'\u7FFF',62642:'\u8079',62643:'\u81DB',62644:'\u81D9',62645:'\u820B',62646:'\u8268',62647:'\u8269',62648:'\u8622',62649:'\u85FF',62650:'\u8601',62651:'\u85FE',62652:'\u861B',62653:'\u8600',62654:'\u85F6',62655:'\u8604',62656:'\u8609',62657:'\u8605',62658:'\u860C',62659:'\u85FD',62660:'\u8819',62661:'\u8810',62662:'\u8811',62663:'\u8817',62664:'\u8813',62665:'\u8816',62666:'\u8963',62667:'\u8966',62668:'\u89B9',62669:'\u89F7',62670:'\u8B60',62671:'\u8B6A',62672:'\u8B5D',62673:'\u8B68',62674:'\u8B63',62675:'\u8B65',62676:'\u8B67',62677:'\u8B6D',62678:'\u8DAE',62679:'\u8E86',62680:'\u8E88',62681:'\u8E84',62682:'\u8F59',62683:'\u8F56',62684:'\u8F57',62685:'\u8F55',62686:'\u8F58',62687:'\u8F5A',62688:'\u908D',62689:'\u9143',62690:'\u9141',62691:'\u91B7',62692:'\u91B5',62693:'\u91B2',62694:'\u91B3',62695:'\u940B',62696:'\u9413',62697:'\u93FB',62698:'\u9420',62699:'\u940F',62700:'\u9414',62701:'\u93FE',62702:'\u9415',62703:'\u9410',62704:'\u9428',62705:'\u9419',62706:'\u940D',62707:'\u93F5',62708:'\u9400',62709:'\u93F7',62710:'\u9407',62711:'\u940E',62712:'\u9416',62713:'\u9412',62714:'\u93FA',62715:'\u9409',62716:'\u93F8',62717:'\u940A',62718:'\u93FF',62784:'\u93FC',62785:'\u940C',62786:'\u93F6',62787:'\u9411',62788:'\u9406',62789:'\u95DE',62790:'\u95E0',62791:'\u95DF',62792:'\u972E',62793:'\u972F',62794:'\u97B9',62795:'\u97BB',62796:'\u97FD',62797:'\u97FE',62798:'\u9860',62799:'\u9862',62800:'\u9863',62801:'\u985F',62802:'\u98C1',62803:'\u98C2',62804:'\u9950',62805:'\u994E',62806:'\u9959',62807:'\u994C',62808:'\u994B',62809:'\u9953',62810:'\u9A32',62811:'\u9A34',62812:'\u9A31',62813:'\u9A2C',62814:'\u9A2A',62815:'\u9A36',62816:'\u9A29',62817:'\u9A2E',62818:'\u9A38',62819:'\u9A2D',62820:'\u9AC7',62821:'\u9ACA',62822:'\u9AC6',62823:'\u9B10',62824:'\u9B12',62825:'\u9B11',62826:'\u9C0B',62827:'\u9C08',62828:'\u9BF7',62829:'\u9C05',62830:'\u9C12',62831:'\u9BF8',62832:'\u9C40',62833:'\u9C07',62834:'\u9C0E',62835:'\u9C06',62836:'\u9C17',62837:'\u9C14',62838:'\u9C09',62839:'\u9D9F',62840:'\u9D99',62841:'\u9DA4',62842:'\u9D9D',62843:'\u9D92',62844:'\u9D98',62845:'\u9D90',62846:'\u9D9B',62881:'\u9DA0',62882:'\u9D94',62883:'\u9D9C',62884:'\u9DAA',62885:'\u9D97',62886:'\u9DA1',62887:'\u9D9A',62888:'\u9DA2',62889:'\u9DA8',62890:'\u9D9E',62891:'\u9DA3',62892:'\u9DBF',62893:'\u9DA9',62894:'\u9D96',62895:'\u9DA6',62896:'\u9DA7',62897:'\u9E99',62898:'\u9E9B',62899:'\u9E9A',62900:'\u9EE5',62901:'\u9EE4',62902:'\u9EE7',62903:'\u9EE6',62904:'\u9F30',62905:'\u9F2E',62906:'\u9F5B',62907:'\u9F60',62908:'\u9F5E',62909:'\u9F5D',62910:'\u9F59',62911:'\u9F91',62912:'\u513A',62913:'\u5139',62914:'\u5298',62915:'\u5297',62916:'\u56C3',62917:'\u56BD',62918:'\u56BE',62919:'\u5B48',62920:'\u5B47',62921:'\u5DCB',62922:'\u5DCF',62923:'\u5EF1',62924:'\u61FD',62925:'\u651B',62926:'\u6B02',62927:'\u6AFC',62928:'\u6B03',62929:'\u6AF8',62930:'\u6B00',62931:'\u7043',62932:'\u7044',62933:'\u704A',62934:'\u7048',62935:'\u7049',62936:'\u7045',62937:'\u7046',62938:'\u721D',62939:'\u721A',62940:'\u7219',62941:'\u737E',62942:'\u7517',62943:'\u766A',62944:'\u77D0',62945:'\u792D',62946:'\u7931',62947:'\u792F',62948:'\u7C54',62949:'\u7C53',62950:'\u7CF2',62951:'\u7E8A',62952:'\u7E87',62953:'\u7E88',62954:'\u7E8B',62955:'\u7E86',62956:'\u7E8D',62957:'\u7F4D',62958:'\u7FBB',62959:'\u8030',62960:'\u81DD',62961:'\u8618',62962:'\u862A',62963:'\u8626',62964:'\u861F',62965:'\u8623',62966:'\u861C',62967:'\u8619',62968:'\u8627',62969:'\u862E',62970:'\u8621',62971:'\u8620',62972:'\u8629',62973:'\u861E',62974:'\u8625',63040:'\u8829',63041:'\u881D',63042:'\u881B',63043:'\u8820',63044:'\u8824',63045:'\u881C',63046:'\u882B',63047:'\u884A',63048:'\u896D',63049:'\u8969',63050:'\u896E',63051:'\u896B',63052:'\u89FA',63053:'\u8B79',63054:'\u8B78',63055:'\u8B45',63056:'\u8B7A',63057:'\u8B7B',63058:'\u8D10',63059:'\u8D14',63060:'\u8DAF',63061:'\u8E8E',63062:'\u8E8C',63063:'\u8F5E',63064:'\u8F5B',63065:'\u8F5D',63066:'\u9146',63067:'\u9144',63068:'\u9145',63069:'\u91B9',63070:'\u943F',63071:'\u943B',63072:'\u9436',63073:'\u9429',63074:'\u943D',63075:'\u943C',63076:'\u9430',63077:'\u9439',63078:'\u942A',63079:'\u9437',63080:'\u942C',63081:'\u9440',63082:'\u9431',63083:'\u95E5',63084:'\u95E4',63085:'\u95E3',63086:'\u9735',63087:'\u973A',63088:'\u97BF',63089:'\u97E1',63090:'\u9864',63091:'\u98C9',63092:'\u98C6',63093:'\u98C0',63094:'\u9958',63095:'\u9956',63096:'\u9A39',63097:'\u9A3D',63098:'\u9A46',63099:'\u9A44',63100:'\u9A42',63101:'\u9A41',63102:'\u9A3A',63137:'\u9A3F',63138:'\u9ACD',63139:'\u9B15',63140:'\u9B17',63141:'\u9B18',63142:'\u9B16',63143:'\u9B3A',63144:'\u9B52',63145:'\u9C2B',63146:'\u9C1D',63147:'\u9C1C',63148:'\u9C2C',63149:'\u9C23',63150:'\u9C28',63151:'\u9C29',63152:'\u9C24',63153:'\u9C21',63154:'\u9DB7',63155:'\u9DB6',63156:'\u9DBC',63157:'\u9DC1',63158:'\u9DC7',63159:'\u9DCA',63160:'\u9DCF',63161:'\u9DBE',63162:'\u9DC5',63163:'\u9DC3',63164:'\u9DBB',63165:'\u9DB5',63166:'\u9DCE',63167:'\u9DB9',63168:'\u9DBA',63169:'\u9DAC',63170:'\u9DC8',63171:'\u9DB1',63172:'\u9DAD',63173:'\u9DCC',63174:'\u9DB3',63175:'\u9DCD',63176:'\u9DB2',63177:'\u9E7A',63178:'\u9E9C',63179:'\u9EEB',63180:'\u9EEE',63181:'\u9EED',63182:'\u9F1B',63183:'\u9F18',63184:'\u9F1A',63185:'\u9F31',63186:'\u9F4E',63187:'\u9F65',63188:'\u9F64',63189:'\u9F92',63190:'\u4EB9',63191:'\u56C6',63192:'\u56C5',63193:'\u56CB',63194:'\u5971',63195:'\u5B4B',63196:'\u5B4C',63197:'\u5DD5',63198:'\u5DD1',63199:'\u5EF2',63200:'\u6521',63201:'\u6520',63202:'\u6526',63203:'\u6522',63204:'\u6B0B',63205:'\u6B08',63206:'\u6B09',63207:'\u6C0D',63208:'\u7055',63209:'\u7056',63210:'\u7057',63211:'\u7052',63212:'\u721E',63213:'\u721F',63214:'\u72A9',63215:'\u737F',63216:'\u74D8',63217:'\u74D5',63218:'\u74D9',63219:'\u74D7',63220:'\u766D',63221:'\u76AD',63222:'\u7935',63223:'\u79B4',63224:'\u7A70',63225:'\u7A71',63226:'\u7C57',63227:'\u7C5C',63228:'\u7C59',63229:'\u7C5B',63230:'\u7C5A',63296:'\u7CF4',63297:'\u7CF1',63298:'\u7E91',63299:'\u7F4F',63300:'\u7F87',63301:'\u81DE',63302:'\u826B',63303:'\u8634',63304:'\u8635',63305:'\u8633',63306:'\u862C',63307:'\u8632',63308:'\u8636',63309:'\u882C',63310:'\u8828',63311:'\u8826',63312:'\u882A',63313:'\u8825',63314:'\u8971',63315:'\u89BF',63316:'\u89BE',63317:'\u89FB',63318:'\u8B7E',63319:'\u8B84',63320:'\u8B82',63321:'\u8B86',63322:'\u8B85',63323:'\u8B7F',63324:'\u8D15',63325:'\u8E95',63326:'\u8E94',63327:'\u8E9A',63328:'\u8E92',63329:'\u8E90',63330:'\u8E96',63331:'\u8E97',63332:'\u8F60',63333:'\u8F62',63334:'\u9147',63335:'\u944C',63336:'\u9450',63337:'\u944A',63338:'\u944B',63339:'\u944F',63340:'\u9447',63341:'\u9445',63342:'\u9448',63343:'\u9449',63344:'\u9446',63345:'\u973F',63346:'\u97E3',63347:'\u986A',63348:'\u9869',63349:'\u98CB',63350:'\u9954',63351:'\u995B',63352:'\u9A4E',63353:'\u9A53',63354:'\u9A54',63355:'\u9A4C',63356:'\u9A4F',63357:'\u9A48',63358:'\u9A4A',63393:'\u9A49',63394:'\u9A52',63395:'\u9A50',63396:'\u9AD0',63397:'\u9B19',63398:'\u9B2B',63399:'\u9B3B',63400:'\u9B56',63401:'\u9B55',63402:'\u9C46',63403:'\u9C48',63404:'\u9C3F',63405:'\u9C44',63406:'\u9C39',63407:'\u9C33',63408:'\u9C41',63409:'\u9C3C',63410:'\u9C37',63411:'\u9C34',63412:'\u9C32',63413:'\u9C3D',63414:'\u9C36',63415:'\u9DDB',63416:'\u9DD2',63417:'\u9DDE',63418:'\u9DDA',63419:'\u9DCB',63420:'\u9DD0',63421:'\u9DDC',63422:'\u9DD1',63423:'\u9DDF',63424:'\u9DE9',63425:'\u9DD9',63426:'\u9DD8',63427:'\u9DD6',63428:'\u9DF5',63429:'\u9DD5',63430:'\u9DDD',63431:'\u9EB6',63432:'\u9EF0',63433:'\u9F35',63434:'\u9F33',63435:'\u9F32',63436:'\u9F42',63437:'\u9F6B',63438:'\u9F95',63439:'\u9FA2',63440:'\u513D',63441:'\u5299',63442:'\u58E8',63443:'\u58E7',63444:'\u5972',63445:'\u5B4D',63446:'\u5DD8',63447:'\u882F',63448:'\u5F4F',63449:'\u6201',63450:'\u6203',63451:'\u6204',63452:'\u6529',63453:'\u6525',63454:'\u6596',63455:'\u66EB',63456:'\u6B11',63457:'\u6B12',63458:'\u6B0F',63459:'\u6BCA',63460:'\u705B',63461:'\u705A',63462:'\u7222',63463:'\u7382',63464:'\u7381',63465:'\u7383',63466:'\u7670',63467:'\u77D4',63468:'\u7C67',63469:'\u7C66',63470:'\u7E95',63471:'\u826C',63472:'\u863A',63473:'\u8640',63474:'\u8639',63475:'\u863C',63476:'\u8631',63477:'\u863B',63478:'\u863E',63479:'\u8830',63480:'\u8832',63481:'\u882E',63482:'\u8833',63483:'\u8976',63484:'\u8974',63485:'\u8973',63486:'\u89FE',63552:'\u8B8C',63553:'\u8B8E',63554:'\u8B8B',63555:'\u8B88',63556:'\u8C45',63557:'\u8D19',63558:'\u8E98',63559:'\u8F64',63560:'\u8F63',63561:'\u91BC',63562:'\u9462',63563:'\u9455',63564:'\u945D',63565:'\u9457',63566:'\u945E',63567:'\u97C4',63568:'\u97C5',63569:'\u9800',63570:'\u9A56',63571:'\u9A59',63572:'\u9B1E',63573:'\u9B1F',63574:'\u9B20',63575:'\u9C52',63576:'\u9C58',63577:'\u9C50',63578:'\u9C4A',63579:'\u9C4D',63580:'\u9C4B',63581:'\u9C55',63582:'\u9C59',63583:'\u9C4C',63584:'\u9C4E',63585:'\u9DFB',63586:'\u9DF7',63587:'\u9DEF',63588:'\u9DE3',63589:'\u9DEB',63590:'\u9DF8',63591:'\u9DE4',63592:'\u9DF6',63593:'\u9DE1',63594:'\u9DEE',63595:'\u9DE6',63596:'\u9DF2',63597:'\u9DF0',63598:'\u9DE2',63599:'\u9DEC',63600:'\u9DF4',63601:'\u9DF3',63602:'\u9DE8',63603:'\u9DED',63604:'\u9EC2',63605:'\u9ED0',63606:'\u9EF2',63607:'\u9EF3',63608:'\u9F06',63609:'\u9F1C',63610:'\u9F38',63611:'\u9F37',63612:'\u9F36',63613:'\u9F43',63614:'\u9F4F',63649:'\u9F71',63650:'\u9F70',63651:'\u9F6E',63652:'\u9F6F',63653:'\u56D3',63654:'\u56CD',63655:'\u5B4E',63656:'\u5C6D',63657:'\u652D',63658:'\u66ED',63659:'\u66EE',63660:'\u6B13',63661:'\u705F',63662:'\u7061',63663:'\u705D',63664:'\u7060',63665:'\u7223',63666:'\u74DB',63667:'\u74E5',63668:'\u77D5',63669:'\u7938',63670:'\u79B7',63671:'\u79B6',63672:'\u7C6A',63673:'\u7E97',63674:'\u7F89',63675:'\u826D',63676:'\u8643',63677:'\u8838',63678:'\u8837',63679:'\u8835',63680:'\u884B',63681:'\u8B94',63682:'\u8B95',63683:'\u8E9E',63684:'\u8E9F',63685:'\u8EA0',63686:'\u8E9D',63687:'\u91BE',63688:'\u91BD',63689:'\u91C2',63690:'\u946B',63691:'\u9468',63692:'\u9469',63693:'\u96E5',63694:'\u9746',63695:'\u9743',63696:'\u9747',63697:'\u97C7',63698:'\u97E5',63699:'\u9A5E',63700:'\u9AD5',63701:'\u9B59',63702:'\u9C63',63703:'\u9C67',63704:'\u9C66',63705:'\u9C62',63706:'\u9C5E',63707:'\u9C60',63708:'\u9E02',63709:'\u9DFE',63710:'\u9E07',63711:'\u9E03',63712:'\u9E06',63713:'\u9E05',63714:'\u9E00',63715:'\u9E01',63716:'\u9E09',63717:'\u9DFF',63718:'\u9DFD',63719:'\u9E04',63720:'\u9EA0',63721:'\u9F1E',63722:'\u9F46',63723:'\u9F74',63724:'\u9F75',63725:'\u9F76',63726:'\u56D4',63727:'\u652E',63728:'\u65B8',63729:'\u6B18',63730:'\u6B19',63731:'\u6B17',63732:'\u6B1A',63733:'\u7062',63734:'\u7226',63735:'\u72AA',63736:'\u77D8',63737:'\u77D9',63738:'\u7939',63739:'\u7C69',63740:'\u7C6B',63741:'\u7CF6',63742:'\u7E9A',63808:'\u7E98',63809:'\u7E9B',63810:'\u7E99',63811:'\u81E0',63812:'\u81E1',63813:'\u8646',63814:'\u8647',63815:'\u8648',63816:'\u8979',63817:'\u897A',63818:'\u897C',63819:'\u897B',63820:'\u89FF',63821:'\u8B98',63822:'\u8B99',63823:'\u8EA5',63824:'\u8EA4',63825:'\u8EA3',63826:'\u946E',63827:'\u946D',63828:'\u946F',63829:'\u9471',63830:'\u9473',63831:'\u9749',63832:'\u9872',63833:'\u995F',63834:'\u9C68',63835:'\u9C6E',63836:'\u9C6D',63837:'\u9E0B',63838:'\u9E0D',63839:'\u9E10',63840:'\u9E0F',63841:'\u9E12',63842:'\u9E11',63843:'\u9EA1',63844:'\u9EF5',63845:'\u9F09',63846:'\u9F47',63847:'\u9F78',63848:'\u9F7B',63849:'\u9F7A',63850:'\u9F79',63851:'\u571E',63852:'\u7066',63853:'\u7C6F',63854:'\u883C',63855:'\u8DB2',63856:'\u8EA6',63857:'\u91C3',63858:'\u9474',63859:'\u9478',63860:'\u9476',63861:'\u9475',63862:'\u9A60',63863:'\u9C74',63864:'\u9C73',63865:'\u9C71',63866:'\u9C75',63867:'\u9E14',63868:'\u9E13',63869:'\u9EF6',63870:'\u9F0A',63905:'\u9FA4',63906:'\u7068',63907:'\u7065',63908:'\u7CF7',63909:'\u866A',63910:'\u883E',63911:'\u883D',63912:'\u883F',63913:'\u8B9E',63914:'\u8C9C',63915:'\u8EA9',63916:'\u8EC9',63917:'\u974B',63918:'\u9873',63919:'\u9874',63920:'\u98CC',63921:'\u9961',63922:'\u99AB',63923:'\u9A64',63924:'\u9A66',63925:'\u9A67',63926:'\u9B24',63927:'\u9E15',63928:'\u9E17',63929:'\u9F48',63930:'\u6207',63931:'\u6B1E',63932:'\u7227',63933:'\u864C',63934:'\u8EA8',63935:'\u9482',63936:'\u9480',63937:'\u9481',63938:'\u9A69',63939:'\u9A68',63940:'\u9B2E',63941:'\u9E19',63942:'\u7229',63943:'\u864B',63944:'\u8B9F',63945:'\u9483',63946:'\u9C79',63947:'\u9EB7',63948:'\u7675',63949:'\u9A6B',63950:'\u9C7A',63951:'\u9E1D',63952:'\u7069',63953:'\u706A',63954:'\u9EA4',63955:'\u9F7E',63956:'\u9F49',63957:'\u9F98',63958:'\u7881',63959:'\u92B9',63960:'\u88CF',63961:'\u58BB',63962:'\u6052',63963:'\u7CA7',63964:'\u5AFA',63965:'\u2554',63966:'\u2566',63967:'\u2557',63968:'\u2560',63969:'\u256C',63970:'\u2563',63971:'\u255A',63972:'\u2569',63973:'\u255D',63974:'\u2552',63975:'\u2564',63976:'\u2555',63977:'\u255E',63978:'\u256A',63979:'\u2561',63980:'\u2558',63981:'\u2567',63982:'\u255B',63983:'\u2553',63984:'\u2565',63985:'\u2556',63986:'\u255F',63987:'\u256B',63988:'\u2562',63989:'\u2559',63990:'\u2568',63991:'\u255C',63992:'\u2551',63993:'\u2550',63994:'\u256D',63995:'\u256E',63996:'\u2570',63997:'\u256F',63998:'\u2593',64064:'\uE000',64065:'\uE001',64066:'\uE002',64067:'\uE003',64068:'\uE004',64069:'\uE005',64070:'\uE006',64071:'\uE007',64072:'\uE008',64073:'\uE009',64074:'\uE00A',64075:'\uE00B',64076:'\uE00C',64077:'\uE00D',64078:'\uE00E',64079:'\uE00F',64080:'\uE010',64081:'\uE011',64082:'\uE012',64083:'\uE013',64084:'\uE014',64085:'\uE015',64086:'\uE016',64087:'\uE017',64088:'\uE018',64089:'\uE019',64090:'\uE01A',64091:'\uE01B',64092:'\uE01C',64093:'\uE01D',64094:'\uE01E',64095:'\uE01F',64096:'\uE020',64097:'\uE021',64098:'\uE022',64099:'\uE023',64100:'\uE024',64101:'\uE025',64102:'\uE026',64103:'\uE027',64104:'\uE028',64105:'\uE029',64106:'\uE02A',64107:'\uE02B',64108:'\uE02C',64109:'\uE02D',64110:'\uE02E',64111:'\uE02F',64112:'\uE030',64113:'\uE031',64114:'\uE032',64115:'\uE033',64116:'\uE034',64117:'\uE035',64118:'\uE036',64119:'\uE037',64120:'\uE038',64121:'\uE039',64122:'\uE03A',64123:'\uE03B',64124:'\uE03C',64125:'\uE03D',64126:'\uE03E',64161:'\uE03F',64162:'\uE040',64163:'\uE041',64164:'\uE042',64165:'\uE043',64166:'\uE044',64167:'\uE045',64168:'\uE046',64169:'\uE047',64170:'\uE048',64171:'\uE049',64172:'\uE04A',64173:'\uE04B',64174:'\uE04C',64175:'\uE04D',64176:'\uE04E',64177:'\uE04F',64178:'\uE050',64179:'\uE051',64180:'\uE052',64181:'\uE053',64182:'\uE054',64183:'\uE055',64184:'\uE056',64185:'\uE057',64186:'\uE058',64187:'\uE059',64188:'\uE05A',64189:'\uE05B',64190:'\uE05C',64191:'\uE05D',64192:'\uE05E',64193:'\uE05F',64194:'\uE060',64195:'\uE061',64196:'\uE062',64197:'\uE063',64198:'\uE064',64199:'\uE065',64200:'\uE066',64201:'\uE067',64202:'\uE068',64203:'\uE069',64204:'\uE06A',64205:'\uE06B',64206:'\uE06C',64207:'\uE06D',64208:'\uE06E',64209:'\uE06F',64210:'\uE070',64211:'\uE071',64212:'\uE072',64213:'\uE073',64214:'\uE074',64215:'\uE075',64216:'\uE076',64217:'\uE077',64218:'\uE078',64219:'\uE079',64220:'\uE07A',64221:'\uE07B',64222:'\uE07C',64223:'\uE07D',64224:'\uE07E',64225:'\uE07F',64226:'\uE080',64227:'\uE081',64228:'\uE082',64229:'\uE083',64230:'\uE084',64231:'\uE085',64232:'\uE086',64233:'\uE087',64234:'\uE088',64235:'\uE089',64236:'\uE08A',64237:'\uE08B',64238:'\uE08C',64239:'\uE08D',64240:'\uE08E',64241:'\uE08F',64242:'\uE090',64243:'\uE091',64244:'\uE092',64245:'\uE093',64246:'\uE094',64247:'\uE095',64248:'\uE096',64249:'\uE097',64250:'\uE098',64251:'\uE099',64252:'\uE09A',64253:'\uE09B',64254:'\uE09C',64320:'\uE09D',64321:'\uE09E',64322:'\uE09F',64323:'\uE0A0',64324:'\uE0A1',64325:'\uE0A2',64326:'\uE0A3',64327:'\uE0A4',64328:'\uE0A5',64329:'\uE0A6',64330:'\uE0A7',64331:'\uE0A8',64332:'\uE0A9',64333:'\uE0AA',64334:'\uE0AB',64335:'\uE0AC',64336:'\uE0AD',64337:'\uE0AE',64338:'\uE0AF',64339:'\uE0B0',64340:'\uE0B1',64341:'\uE0B2',64342:'\uE0B3',64343:'\uE0B4',64344:'\uE0B5',64345:'\uE0B6',64346:'\uE0B7',64347:'\uE0B8',64348:'\uE0B9',64349:'\uE0BA',64350:'\uE0BB',64351:'\uE0BC',64352:'\uE0BD',64353:'\uE0BE',64354:'\uE0BF',64355:'\uE0C0',64356:'\uE0C1',64357:'\uE0C2',64358:'\uE0C3',64359:'\uE0C4',64360:'\uE0C5',64361:'\uE0C6',64362:'\uE0C7',64363:'\uE0C8',64364:'\uE0C9',64365:'\uE0CA',64366:'\uE0CB',64367:'\uE0CC',64368:'\uE0CD',64369:'\uE0CE',64370:'\uE0CF',64371:'\uE0D0',64372:'\uE0D1',64373:'\uE0D2',64374:'\uE0D3',64375:'\uE0D4',64376:'\uE0D5',64377:'\uE0D6',64378:'\uE0D7',64379:'\uE0D8',64380:'\uE0D9',64381:'\uE0DA',64382:'\uE0DB',64417:'\uE0DC',64418:'\uE0DD',64419:'\uE0DE',64420:'\uE0DF',64421:'\uE0E0',64422:'\uE0E1',64423:'\uE0E2',64424:'\uE0E3',64425:'\uE0E4',64426:'\uE0E5',64427:'\uE0E6',64428:'\uE0E7',64429:'\uE0E8',64430:'\uE0E9',64431:'\uE0EA',64432:'\uE0EB',64433:'\uE0EC',64434:'\uE0ED',64435:'\uE0EE',64436:'\uE0EF',64437:'\uE0F0',64438:'\uE0F1',64439:'\uE0F2',64440:'\uE0F3',64441:'\uE0F4',64442:'\uE0F5',64443:'\uE0F6',64444:'\uE0F7',64445:'\uE0F8',64446:'\uE0F9',64447:'\uE0FA',64448:'\uE0FB',64449:'\uE0FC',64450:'\uE0FD',64451:'\uE0FE',64452:'\uE0FF',64453:'\uE100',64454:'\uE101',64455:'\uE102',64456:'\uE103',64457:'\uE104',64458:'\uE105',64459:'\uE106',64460:'\uE107',64461:'\uE108',64462:'\uE109',64463:'\uE10A',64464:'\uE10B',64465:'\uE10C',64466:'\uE10D',64467:'\uE10E',64468:'\uE10F',64469:'\uE110',64470:'\uE111',64471:'\uE112',64472:'\uE113',64473:'\uE114',64474:'\uE115',64475:'\uE116',64476:'\uE117',64477:'\uE118',64478:'\uE119',64479:'\uE11A',64480:'\uE11B',64481:'\uE11C',64482:'\uE11D',64483:'\uE11E',64484:'\uE11F',64485:'\uE120',64486:'\uE121',64487:'\uE122',64488:'\uE123',64489:'\uE124',64490:'\uE125',64491:'\uE126',64492:'\uE127',64493:'\uE128',64494:'\uE129',64495:'\uE12A',64496:'\uE12B',64497:'\uE12C',64498:'\uE12D',64499:'\uE12E',64500:'\uE12F',64501:'\uE130',64502:'\uE131',64503:'\uE132',64504:'\uE133',64505:'\uE134',64506:'\uE135',64507:'\uE136',64508:'\uE137',64509:'\uE138',64510:'\uE139',64576:'\uE13A',64577:'\uE13B',64578:'\uE13C',64579:'\uE13D',64580:'\uE13E',64581:'\uE13F',64582:'\uE140',64583:'\uE141',64584:'\uE142',64585:'\uE143',64586:'\uE144',64587:'\uE145',64588:'\uE146',64589:'\uE147',64590:'\uE148',64591:'\uE149',64592:'\uE14A',64593:'\uE14B',64594:'\uE14C',64595:'\uE14D',64596:'\uE14E',64597:'\uE14F',64598:'\uE150',64599:'\uE151',64600:'\uE152',64601:'\uE153',64602:'\uE154',64603:'\uE155',64604:'\uE156',64605:'\uE157',64606:'\uE158',64607:'\uE159',64608:'\uE15A',64609:'\uE15B',64610:'\uE15C',64611:'\uE15D',64612:'\uE15E',64613:'\uE15F',64614:'\uE160',64615:'\uE161',64616:'\uE162',64617:'\uE163',64618:'\uE164',64619:'\uE165',64620:'\uE166',64621:'\uE167',64622:'\uE168',64623:'\uE169',64624:'\uE16A',64625:'\uE16B',64626:'\uE16C',64627:'\uE16D',64628:'\uE16E',64629:'\uE16F',64630:'\uE170',64631:'\uE171',64632:'\uE172',64633:'\uE173',64634:'\uE174',64635:'\uE175',64636:'\uE176',64637:'\uE177',64638:'\uE178',64673:'\uE179',64674:'\uE17A',64675:'\uE17B',64676:'\uE17C',64677:'\uE17D',64678:'\uE17E',64679:'\uE17F',64680:'\uE180',64681:'\uE181',64682:'\uE182',64683:'\uE183',64684:'\uE184',64685:'\uE185',64686:'\uE186',64687:'\uE187',64688:'\uE188',64689:'\uE189',64690:'\uE18A',64691:'\uE18B',64692:'\uE18C',64693:'\uE18D',64694:'\uE18E',64695:'\uE18F',64696:'\uE190',64697:'\uE191',64698:'\uE192',64699:'\uE193',64700:'\uE194',64701:'\uE195',64702:'\uE196',64703:'\uE197',64704:'\uE198',64705:'\uE199',64706:'\uE19A',64707:'\uE19B',64708:'\uE19C',64709:'\uE19D',64710:'\uE19E',64711:'\uE19F',64712:'\uE1A0',64713:'\uE1A1',64714:'\uE1A2',64715:'\uE1A3',64716:'\uE1A4',64717:'\uE1A5',64718:'\uE1A6',64719:'\uE1A7',64720:'\uE1A8',64721:'\uE1A9',64722:'\uE1AA',64723:'\uE1AB',64724:'\uE1AC',64725:'\uE1AD',64726:'\uE1AE',64727:'\uE1AF',64728:'\uE1B0',64729:'\uE1B1',64730:'\uE1B2',64731:'\uE1B3',64732:'\uE1B4',64733:'\uE1B5',64734:'\uE1B6',64735:'\uE1B7',64736:'\uE1B8',64737:'\uE1B9',64738:'\uE1BA',64739:'\uE1BB',64740:'\uE1BC',64741:'\uE1BD',64742:'\uE1BE',64743:'\uE1BF',64744:'\uE1C0',64745:'\uE1C1',64746:'\uE1C2',64747:'\uE1C3',64748:'\uE1C4',64749:'\uE1C5',64750:'\uE1C6',64751:'\uE1C7',64752:'\uE1C8',64753:'\uE1C9',64754:'\uE1CA',64755:'\uE1CB',64756:'\uE1CC',64757:'\uE1CD',64758:'\uE1CE',64759:'\uE1CF',64760:'\uE1D0',64761:'\uE1D1',64762:'\uE1D2',64763:'\uE1D3',64764:'\uE1D4',64765:'\uE1D5',64766:'\uE1D6',64832:'\uE1D7',64833:'\uE1D8',64834:'\uE1D9',64835:'\uE1DA',64836:'\uE1DB',64837:'\uE1DC',64838:'\uE1DD',64839:'\uE1DE',64840:'\uE1DF',64841:'\uE1E0',64842:'\uE1E1',64843:'\uE1E2',64844:'\uE1E3',64845:'\uE1E4',64846:'\uE1E5',64847:'\uE1E6',64848:'\uE1E7',64849:'\uE1E8',64850:'\uE1E9',64851:'\uE1EA',64852:'\uE1EB',64853:'\uE1EC',64854:'\uE1ED',64855:'\uE1EE',64856:'\uE1EF',64857:'\uE1F0',64858:'\uE1F1',64859:'\uE1F2',64860:'\uE1F3',64861:'\uE1F4',64862:'\uE1F5',64863:'\uE1F6',64864:'\uE1F7',64865:'\uE1F8',64866:'\uE1F9',64867:'\uE1FA',64868:'\uE1FB',64869:'\uE1FC',64870:'\uE1FD',64871:'\uE1FE',64872:'\uE1FF',64873:'\uE200',64874:'\uE201',64875:'\uE202',64876:'\uE203',64877:'\uE204',64878:'\uE205',64879:'\uE206',64880:'\uE207',64881:'\uE208',64882:'\uE209',64883:'\uE20A',64884:'\uE20B',64885:'\uE20C',64886:'\uE20D',64887:'\uE20E',64888:'\uE20F',64889:'\uE210',64890:'\uE211',64891:'\uE212',64892:'\uE213',64893:'\uE214',64894:'\uE215',64929:'\uE216',64930:'\uE217',64931:'\uE218',64932:'\uE219',64933:'\uE21A',64934:'\uE21B',64935:'\uE21C',64936:'\uE21D',64937:'\uE21E',64938:'\uE21F',64939:'\uE220',64940:'\uE221',64941:'\uE222',64942:'\uE223',64943:'\uE224',64944:'\uE225',64945:'\uE226',64946:'\uE227',64947:'\uE228',64948:'\uE229',64949:'\uE22A',64950:'\uE22B',64951:'\uE22C',64952:'\uE22D',64953:'\uE22E',64954:'\uE22F',64955:'\uE230',64956:'\uE231',64957:'\uE232',64958:'\uE233',64959:'\uE234',64960:'\uE235',64961:'\uE236',64962:'\uE237',64963:'\uE238',64964:'\uE239',64965:'\uE23A',64966:'\uE23B',64967:'\uE23C',64968:'\uE23D',64969:'\uE23E',64970:'\uE23F',64971:'\uE240',64972:'\uE241',64973:'\uE242',64974:'\uE243',64975:'\uE244',64976:'\uE245',64977:'\uE246',64978:'\uE247',64979:'\uE248',64980:'\uE249',64981:'\uE24A',64982:'\uE24B',64983:'\uE24C',64984:'\uE24D',64985:'\uE24E',64986:'\uE24F',64987:'\uE250',64988:'\uE251',64989:'\uE252',64990:'\uE253',64991:'\uE254',64992:'\uE255',64993:'\uE256',64994:'\uE257',64995:'\uE258',64996:'\uE259',64997:'\uE25A',64998:'\uE25B',64999:'\uE25C',65000:'\uE25D',65001:'\uE25E',65002:'\uE25F',65003:'\uE260',65004:'\uE261',65005:'\uE262',65006:'\uE263',65007:'\uE264',65008:'\uE265',65009:'\uE266',65010:'\uE267',65011:'\uE268',65012:'\uE269',65013:'\uE26A',65014:'\uE26B',65015:'\uE26C',65016:'\uE26D',65017:'\uE26E',65018:'\uE26F',65019:'\uE270',65020:'\uE271',65021:'\uE272',65022:'\uE273',65088:'\uE274',65089:'\uE275',65090:'\uE276',65091:'\uE277',65092:'\uE278',65093:'\uE279',65094:'\uE27A',65095:'\uE27B',65096:'\uE27C',65097:'\uE27D',65098:'\uE27E',65099:'\uE27F',65100:'\uE280',65101:'\uE281',65102:'\uE282',65103:'\uE283',65104:'\uE284',65105:'\uE285',65106:'\uE286',65107:'\uE287',65108:'\uE288',65109:'\uE289',65110:'\uE28A',65111:'\uE28B',65112:'\uE28C',65113:'\uE28D',65114:'\uE28E',65115:'\uE28F',65116:'\uE290',65117:'\uE291',65118:'\uE292',65119:'\uE293',65120:'\uE294',65121:'\uE295',65122:'\uE296',65123:'\uE297',65124:'\uE298',65125:'\uE299',65126:'\uE29A',65127:'\uE29B',65128:'\uE29C',65129:'\uE29D',65130:'\uE29E',65131:'\uE29F',65132:'\uE2A0',65133:'\uE2A1',65134:'\uE2A2',65135:'\uE2A3',65136:'\uE2A4',65137:'\uE2A5',65138:'\uE2A6',65139:'\uE2A7',65140:'\uE2A8',65141:'\uE2A9',65142:'\uE2AA',65143:'\uE2AB',65144:'\uE2AC',65145:'\uE2AD',65146:'\uE2AE',65147:'\uE2AF',65148:'\uE2B0',65149:'\uE2B1',65150:'\uE2B2',65185:'\uE2B3',65186:'\uE2B4',65187:'\uE2B5',65188:'\uE2B6',65189:'\uE2B7',65190:'\uE2B8',65191:'\uE2B9',65192:'\uE2BA',65193:'\uE2BB',65194:'\uE2BC',65195:'\uE2BD',65196:'\uE2BE',65197:'\uE2BF',65198:'\uE2C0',65199:'\uE2C1',65200:'\uE2C2',65201:'\uE2C3',65202:'\uE2C4',65203:'\uE2C5',65204:'\uE2C6',65205:'\uE2C7',65206:'\uE2C8',65207:'\uE2C9',65208:'\uE2CA',65209:'\uE2CB',65210:'\uE2CC',65211:'\uE2CD',65212:'\uE2CE',65213:'\uE2CF',65214:'\uE2D0',65215:'\uE2D1',65216:'\uE2D2',65217:'\uE2D3',65218:'\uE2D4',65219:'\uE2D5',65220:'\uE2D6',65221:'\uE2D7',65222:'\uE2D8',65223:'\uE2D9',65224:'\uE2DA',65225:'\uE2DB',65226:'\uE2DC',65227:'\uE2DD',65228:'\uE2DE',65229:'\uE2DF',65230:'\uE2E0',65231:'\uE2E1',65232:'\uE2E2',65233:'\uE2E3',65234:'\uE2E4',65235:'\uE2E5',65236:'\uE2E6',65237:'\uE2E7',65238:'\uE2E8',65239:'\uE2E9',65240:'\uE2EA',65241:'\uE2EB',65242:'\uE2EC',65243:'\uE2ED',65244:'\uE2EE',65245:'\uE2EF',65246:'\uE2F0',65247:'\uE2F1',65248:'\uE2F2',65249:'\uE2F3',65250:'\uE2F4',65251:'\uE2F5',65252:'\uE2F6',65253:'\uE2F7',65254:'\uE2F8',65255:'\uE2F9',65256:'\uE2FA',65257:'\uE2FB',65258:'\uE2FC',65259:'\uE2FD',65260:'\uE2FE',65261:'\uE2FF',65262:'\uE300',65263:'\uE301',65264:'\uE302',65265:'\uE303',65266:'\uE304',65267:'\uE305',65268:'\uE306',65269:'\uE307',65270:'\uE308',65271:'\uE309',65272:'\uE30A',65273:'\uE30B',65274:'\uE30C',65275:'\uE30D',65276:'\uE30E',65277:'\uE30F',65278:'\uE310',129:None,130:None,131:None,132:None,133:None,134:None,135:None,136:None,137:None,138:None,139:None,140:None,141:None,142:None,143:None,144:None,145:None,146:None,147:None,148:None,149:None,150:None,151:None,152:None,153:None,154:None,155:None,156:None,157:None,158:None,159:None,160:None,161:None,162:None,163:None,164:None,165:None,166:None,167:None,168:None,169:None,170:None,171:None,172:None,173:None,174:None,175:None,176:None,177:None,178:None,179:None,180:None,181:None,182:None,183:None,184:None,185:None,186:None,187:None,188:None,189:None,190:None,191:None,192:None,193:None,194:None,195:None,196:None,197:None,198:None,199:None,200:None,201:None,202:None,203:None,204:None,205:None,206:None,207:None,208:None,209:None,210:None,211:None,212:None,213:None,214:None,215:None,216:None,217:None,218:None,219:None,220:None,221:None,222:None,223:None,224:None,225:None,226:None,227:None,228:None,229:None,230:None,231:None,232:None,233:None,234:None,235:None,236:None,237:None,238:None,239:None,240:None,241:None,242:None,243:None,244:None,245:None,246:None,247:None,248:None,249:None,250:None,251:None,252:None,253:None,254:None} \ No newline at end of file diff --git a/extract_msg/encoding/_win950_dec.py b/extract_msg/encoding/_win950_dec.py deleted file mode 100644 index bdd7725a..00000000 --- a/extract_msg/encoding/_win950_dec.py +++ /dev/null @@ -1,5 +0,0 @@ -__all__ = [ - 'decodingTable' -] - -decodingTable={0:'\u0000',1:'\u0001',2:'\u0002',3:'\u0003',4:'\u0004',5:'\u0005',6:'\u0006',7:'\u0007',8:'\u0008',9:'\u0009',10:'\u000A',11:'\u000B',12:'\u000C',13:'\u000D',14:'\u000E',15:'\u000F',16:'\u0010',17:'\u0011',18:'\u0012',19:'\u0013',20:'\u0014',21:'\u0015',22:'\u0016',23:'\u0017',24:'\u0018',25:'\u0019',26:'\u001A',27:'\u001B',28:'\u001C',29:'\u001D',30:'\u001E',31:'\u001F',32:'\u0020',33:'\u0021',34:'\u0022',35:'\u0023',36:'\u0024',37:'\u0025',38:'\u0026',39:'\u0027',40:'\u0028',41:'\u0029',42:'\u002A',43:'\u002B',44:'\u002C',45:'\u002D',46:'\u002E',47:'\u002F',48:'\u0030',49:'\u0031',50:'\u0032',51:'\u0033',52:'\u0034',53:'\u0035',54:'\u0036',55:'\u0037',56:'\u0038',57:'\u0039',58:'\u003A',59:'\u003B',60:'\u003C',61:'\u003D',62:'\u003E',63:'\u003F',64:'\u0040',65:'\u0041',66:'\u0042',67:'\u0043',68:'\u0044',69:'\u0045',70:'\u0046',71:'\u0047',72:'\u0048',73:'\u0049',74:'\u004A',75:'\u004B',76:'\u004C',77:'\u004D',78:'\u004E',79:'\u004F',80:'\u0050',81:'\u0051',82:'\u0052',83:'\u0053',84:'\u0054',85:'\u0055',86:'\u0056',87:'\u0057',88:'\u0058',89:'\u0059',90:'\u005A',91:'\u005B',92:'\u005C',93:'\u005D',94:'\u005E',95:'\u005F',96:'\u0060',97:'\u0061',98:'\u0062',99:'\u0063',100:'\u0064',101:'\u0065',102:'\u0066',103:'\u0067',104:'\u0068',105:'\u0069',106:'\u006A',107:'\u006B',108:'\u006C',109:'\u006D',110:'\u006E',111:'\u006F',112:'\u0070',113:'\u0071',114:'\u0072',115:'\u0073',116:'\u0074',117:'\u0075',118:'\u0076',119:'\u0077',120:'\u0078',121:'\u0079',122:'\u007A',123:'\u007B',124:'\u007C',125:'\u007D',126:'\u007E',127:'\u007F',128:'\u0080',255:'\uF8F8',33088:'\uEEB8',33089:'\uEEB9',33090:'\uEEBA',33091:'\uEEBB',33092:'\uEEBC',33093:'\uEEBD',33094:'\uEEBE',33095:'\uEEBF',33096:'\uEEC0',33097:'\uEEC1',33098:'\uEEC2',33099:'\uEEC3',33100:'\uEEC4',33101:'\uEEC5',33102:'\uEEC6',33103:'\uEEC7',33104:'\uEEC8',33105:'\uEEC9',33106:'\uEECA',33107:'\uEECB',33108:'\uEECC',33109:'\uEECD',33110:'\uEECE',33111:'\uEECF',33112:'\uEED0',33113:'\uEED1',33114:'\uEED2',33115:'\uEED3',33116:'\uEED4',33117:'\uEED5',33118:'\uEED6',33119:'\uEED7',33120:'\uEED8',33121:'\uEED9',33122:'\uEEDA',33123:'\uEEDB',33124:'\uEEDC',33125:'\uEEDD',33126:'\uEEDE',33127:'\uEEDF',33128:'\uEEE0',33129:'\uEEE1',33130:'\uEEE2',33131:'\uEEE3',33132:'\uEEE4',33133:'\uEEE5',33134:'\uEEE6',33135:'\uEEE7',33136:'\uEEE8',33137:'\uEEE9',33138:'\uEEEA',33139:'\uEEEB',33140:'\uEEEC',33141:'\uEEED',33142:'\uEEEE',33143:'\uEEEF',33144:'\uEEF0',33145:'\uEEF1',33146:'\uEEF2',33147:'\uEEF3',33148:'\uEEF4',33149:'\uEEF5',33150:'\uEEF6',33185:'\uEEF7',33186:'\uEEF8',33187:'\uEEF9',33188:'\uEEFA',33189:'\uEEFB',33190:'\uEEFC',33191:'\uEEFD',33192:'\uEEFE',33193:'\uEEFF',33194:'\uEF00',33195:'\uEF01',33196:'\uEF02',33197:'\uEF03',33198:'\uEF04',33199:'\uEF05',33200:'\uEF06',33201:'\uEF07',33202:'\uEF08',33203:'\uEF09',33204:'\uEF0A',33205:'\uEF0B',33206:'\uEF0C',33207:'\uEF0D',33208:'\uEF0E',33209:'\uEF0F',33210:'\uEF10',33211:'\uEF11',33212:'\uEF12',33213:'\uEF13',33214:'\uEF14',33215:'\uEF15',33216:'\uEF16',33217:'\uEF17',33218:'\uEF18',33219:'\uEF19',33220:'\uEF1A',33221:'\uEF1B',33222:'\uEF1C',33223:'\uEF1D',33224:'\uEF1E',33225:'\uEF1F',33226:'\uEF20',33227:'\uEF21',33228:'\uEF22',33229:'\uEF23',33230:'\uEF24',33231:'\uEF25',33232:'\uEF26',33233:'\uEF27',33234:'\uEF28',33235:'\uEF29',33236:'\uEF2A',33237:'\uEF2B',33238:'\uEF2C',33239:'\uEF2D',33240:'\uEF2E',33241:'\uEF2F',33242:'\uEF30',33243:'\uEF31',33244:'\uEF32',33245:'\uEF33',33246:'\uEF34',33247:'\uEF35',33248:'\uEF36',33249:'\uEF37',33250:'\uEF38',33251:'\uEF39',33252:'\uEF3A',33253:'\uEF3B',33254:'\uEF3C',33255:'\uEF3D',33256:'\uEF3E',33257:'\uEF3F',33258:'\uEF40',33259:'\uEF41',33260:'\uEF42',33261:'\uEF43',33262:'\uEF44',33263:'\uEF45',33264:'\uEF46',33265:'\uEF47',33266:'\uEF48',33267:'\uEF49',33268:'\uEF4A',33269:'\uEF4B',33270:'\uEF4C',33271:'\uEF4D',33272:'\uEF4E',33273:'\uEF4F',33274:'\uEF50',33275:'\uEF51',33276:'\uEF52',33277:'\uEF53',33278:'\uEF54',33344:'\uEF55',33345:'\uEF56',33346:'\uEF57',33347:'\uEF58',33348:'\uEF59',33349:'\uEF5A',33350:'\uEF5B',33351:'\uEF5C',33352:'\uEF5D',33353:'\uEF5E',33354:'\uEF5F',33355:'\uEF60',33356:'\uEF61',33357:'\uEF62',33358:'\uEF63',33359:'\uEF64',33360:'\uEF65',33361:'\uEF66',33362:'\uEF67',33363:'\uEF68',33364:'\uEF69',33365:'\uEF6A',33366:'\uEF6B',33367:'\uEF6C',33368:'\uEF6D',33369:'\uEF6E',33370:'\uEF6F',33371:'\uEF70',33372:'\uEF71',33373:'\uEF72',33374:'\uEF73',33375:'\uEF74',33376:'\uEF75',33377:'\uEF76',33378:'\uEF77',33379:'\uEF78',33380:'\uEF79',33381:'\uEF7A',33382:'\uEF7B',33383:'\uEF7C',33384:'\uEF7D',33385:'\uEF7E',33386:'\uEF7F',33387:'\uEF80',33388:'\uEF81',33389:'\uEF82',33390:'\uEF83',33391:'\uEF84',33392:'\uEF85',33393:'\uEF86',33394:'\uEF87',33395:'\uEF88',33396:'\uEF89',33397:'\uEF8A',33398:'\uEF8B',33399:'\uEF8C',33400:'\uEF8D',33401:'\uEF8E',33402:'\uEF8F',33403:'\uEF90',33404:'\uEF91',33405:'\uEF92',33406:'\uEF93',33441:'\uEF94',33442:'\uEF95',33443:'\uEF96',33444:'\uEF97',33445:'\uEF98',33446:'\uEF99',33447:'\uEF9A',33448:'\uEF9B',33449:'\uEF9C',33450:'\uEF9D',33451:'\uEF9E',33452:'\uEF9F',33453:'\uEFA0',33454:'\uEFA1',33455:'\uEFA2',33456:'\uEFA3',33457:'\uEFA4',33458:'\uEFA5',33459:'\uEFA6',33460:'\uEFA7',33461:'\uEFA8',33462:'\uEFA9',33463:'\uEFAA',33464:'\uEFAB',33465:'\uEFAC',33466:'\uEFAD',33467:'\uEFAE',33468:'\uEFAF',33469:'\uEFB0',33470:'\uEFB1',33471:'\uEFB2',33472:'\uEFB3',33473:'\uEFB4',33474:'\uEFB5',33475:'\uEFB6',33476:'\uEFB7',33477:'\uEFB8',33478:'\uEFB9',33479:'\uEFBA',33480:'\uEFBB',33481:'\uEFBC',33482:'\uEFBD',33483:'\uEFBE',33484:'\uEFBF',33485:'\uEFC0',33486:'\uEFC1',33487:'\uEFC2',33488:'\uEFC3',33489:'\uEFC4',33490:'\uEFC5',33491:'\uEFC6',33492:'\uEFC7',33493:'\uEFC8',33494:'\uEFC9',33495:'\uEFCA',33496:'\uEFCB',33497:'\uEFCC',33498:'\uEFCD',33499:'\uEFCE',33500:'\uEFCF',33501:'\uEFD0',33502:'\uEFD1',33503:'\uEFD2',33504:'\uEFD3',33505:'\uEFD4',33506:'\uEFD5',33507:'\uEFD6',33508:'\uEFD7',33509:'\uEFD8',33510:'\uEFD9',33511:'\uEFDA',33512:'\uEFDB',33513:'\uEFDC',33514:'\uEFDD',33515:'\uEFDE',33516:'\uEFDF',33517:'\uEFE0',33518:'\uEFE1',33519:'\uEFE2',33520:'\uEFE3',33521:'\uEFE4',33522:'\uEFE5',33523:'\uEFE6',33524:'\uEFE7',33525:'\uEFE8',33526:'\uEFE9',33527:'\uEFEA',33528:'\uEFEB',33529:'\uEFEC',33530:'\uEFED',33531:'\uEFEE',33532:'\uEFEF',33533:'\uEFF0',33534:'\uEFF1',33600:'\uEFF2',33601:'\uEFF3',33602:'\uEFF4',33603:'\uEFF5',33604:'\uEFF6',33605:'\uEFF7',33606:'\uEFF8',33607:'\uEFF9',33608:'\uEFFA',33609:'\uEFFB',33610:'\uEFFC',33611:'\uEFFD',33612:'\uEFFE',33613:'\uEFFF',33614:'\uF000',33615:'\uF001',33616:'\uF002',33617:'\uF003',33618:'\uF004',33619:'\uF005',33620:'\uF006',33621:'\uF007',33622:'\uF008',33623:'\uF009',33624:'\uF00A',33625:'\uF00B',33626:'\uF00C',33627:'\uF00D',33628:'\uF00E',33629:'\uF00F',33630:'\uF010',33631:'\uF011',33632:'\uF012',33633:'\uF013',33634:'\uF014',33635:'\uF015',33636:'\uF016',33637:'\uF017',33638:'\uF018',33639:'\uF019',33640:'\uF01A',33641:'\uF01B',33642:'\uF01C',33643:'\uF01D',33644:'\uF01E',33645:'\uF01F',33646:'\uF020',33647:'\uF021',33648:'\uF022',33649:'\uF023',33650:'\uF024',33651:'\uF025',33652:'\uF026',33653:'\uF027',33654:'\uF028',33655:'\uF029',33656:'\uF02A',33657:'\uF02B',33658:'\uF02C',33659:'\uF02D',33660:'\uF02E',33661:'\uF02F',33662:'\uF030',33697:'\uF031',33698:'\uF032',33699:'\uF033',33700:'\uF034',33701:'\uF035',33702:'\uF036',33703:'\uF037',33704:'\uF038',33705:'\uF039',33706:'\uF03A',33707:'\uF03B',33708:'\uF03C',33709:'\uF03D',33710:'\uF03E',33711:'\uF03F',33712:'\uF040',33713:'\uF041',33714:'\uF042',33715:'\uF043',33716:'\uF044',33717:'\uF045',33718:'\uF046',33719:'\uF047',33720:'\uF048',33721:'\uF049',33722:'\uF04A',33723:'\uF04B',33724:'\uF04C',33725:'\uF04D',33726:'\uF04E',33727:'\uF04F',33728:'\uF050',33729:'\uF051',33730:'\uF052',33731:'\uF053',33732:'\uF054',33733:'\uF055',33734:'\uF056',33735:'\uF057',33736:'\uF058',33737:'\uF059',33738:'\uF05A',33739:'\uF05B',33740:'\uF05C',33741:'\uF05D',33742:'\uF05E',33743:'\uF05F',33744:'\uF060',33745:'\uF061',33746:'\uF062',33747:'\uF063',33748:'\uF064',33749:'\uF065',33750:'\uF066',33751:'\uF067',33752:'\uF068',33753:'\uF069',33754:'\uF06A',33755:'\uF06B',33756:'\uF06C',33757:'\uF06D',33758:'\uF06E',33759:'\uF06F',33760:'\uF070',33761:'\uF071',33762:'\uF072',33763:'\uF073',33764:'\uF074',33765:'\uF075',33766:'\uF076',33767:'\uF077',33768:'\uF078',33769:'\uF079',33770:'\uF07A',33771:'\uF07B',33772:'\uF07C',33773:'\uF07D',33774:'\uF07E',33775:'\uF07F',33776:'\uF080',33777:'\uF081',33778:'\uF082',33779:'\uF083',33780:'\uF084',33781:'\uF085',33782:'\uF086',33783:'\uF087',33784:'\uF088',33785:'\uF089',33786:'\uF08A',33787:'\uF08B',33788:'\uF08C',33789:'\uF08D',33790:'\uF08E',33856:'\uF08F',33857:'\uF090',33858:'\uF091',33859:'\uF092',33860:'\uF093',33861:'\uF094',33862:'\uF095',33863:'\uF096',33864:'\uF097',33865:'\uF098',33866:'\uF099',33867:'\uF09A',33868:'\uF09B',33869:'\uF09C',33870:'\uF09D',33871:'\uF09E',33872:'\uF09F',33873:'\uF0A0',33874:'\uF0A1',33875:'\uF0A2',33876:'\uF0A3',33877:'\uF0A4',33878:'\uF0A5',33879:'\uF0A6',33880:'\uF0A7',33881:'\uF0A8',33882:'\uF0A9',33883:'\uF0AA',33884:'\uF0AB',33885:'\uF0AC',33886:'\uF0AD',33887:'\uF0AE',33888:'\uF0AF',33889:'\uF0B0',33890:'\uF0B1',33891:'\uF0B2',33892:'\uF0B3',33893:'\uF0B4',33894:'\uF0B5',33895:'\uF0B6',33896:'\uF0B7',33897:'\uF0B8',33898:'\uF0B9',33899:'\uF0BA',33900:'\uF0BB',33901:'\uF0BC',33902:'\uF0BD',33903:'\uF0BE',33904:'\uF0BF',33905:'\uF0C0',33906:'\uF0C1',33907:'\uF0C2',33908:'\uF0C3',33909:'\uF0C4',33910:'\uF0C5',33911:'\uF0C6',33912:'\uF0C7',33913:'\uF0C8',33914:'\uF0C9',33915:'\uF0CA',33916:'\uF0CB',33917:'\uF0CC',33918:'\uF0CD',33953:'\uF0CE',33954:'\uF0CF',33955:'\uF0D0',33956:'\uF0D1',33957:'\uF0D2',33958:'\uF0D3',33959:'\uF0D4',33960:'\uF0D5',33961:'\uF0D6',33962:'\uF0D7',33963:'\uF0D8',33964:'\uF0D9',33965:'\uF0DA',33966:'\uF0DB',33967:'\uF0DC',33968:'\uF0DD',33969:'\uF0DE',33970:'\uF0DF',33971:'\uF0E0',33972:'\uF0E1',33973:'\uF0E2',33974:'\uF0E3',33975:'\uF0E4',33976:'\uF0E5',33977:'\uF0E6',33978:'\uF0E7',33979:'\uF0E8',33980:'\uF0E9',33981:'\uF0EA',33982:'\uF0EB',33983:'\uF0EC',33984:'\uF0ED',33985:'\uF0EE',33986:'\uF0EF',33987:'\uF0F0',33988:'\uF0F1',33989:'\uF0F2',33990:'\uF0F3',33991:'\uF0F4',33992:'\uF0F5',33993:'\uF0F6',33994:'\uF0F7',33995:'\uF0F8',33996:'\uF0F9',33997:'\uF0FA',33998:'\uF0FB',33999:'\uF0FC',34000:'\uF0FD',34001:'\uF0FE',34002:'\uF0FF',34003:'\uF100',34004:'\uF101',34005:'\uF102',34006:'\uF103',34007:'\uF104',34008:'\uF105',34009:'\uF106',34010:'\uF107',34011:'\uF108',34012:'\uF109',34013:'\uF10A',34014:'\uF10B',34015:'\uF10C',34016:'\uF10D',34017:'\uF10E',34018:'\uF10F',34019:'\uF110',34020:'\uF111',34021:'\uF112',34022:'\uF113',34023:'\uF114',34024:'\uF115',34025:'\uF116',34026:'\uF117',34027:'\uF118',34028:'\uF119',34029:'\uF11A',34030:'\uF11B',34031:'\uF11C',34032:'\uF11D',34033:'\uF11E',34034:'\uF11F',34035:'\uF120',34036:'\uF121',34037:'\uF122',34038:'\uF123',34039:'\uF124',34040:'\uF125',34041:'\uF126',34042:'\uF127',34043:'\uF128',34044:'\uF129',34045:'\uF12A',34046:'\uF12B',34112:'\uF12C',34113:'\uF12D',34114:'\uF12E',34115:'\uF12F',34116:'\uF130',34117:'\uF131',34118:'\uF132',34119:'\uF133',34120:'\uF134',34121:'\uF135',34122:'\uF136',34123:'\uF137',34124:'\uF138',34125:'\uF139',34126:'\uF13A',34127:'\uF13B',34128:'\uF13C',34129:'\uF13D',34130:'\uF13E',34131:'\uF13F',34132:'\uF140',34133:'\uF141',34134:'\uF142',34135:'\uF143',34136:'\uF144',34137:'\uF145',34138:'\uF146',34139:'\uF147',34140:'\uF148',34141:'\uF149',34142:'\uF14A',34143:'\uF14B',34144:'\uF14C',34145:'\uF14D',34146:'\uF14E',34147:'\uF14F',34148:'\uF150',34149:'\uF151',34150:'\uF152',34151:'\uF153',34152:'\uF154',34153:'\uF155',34154:'\uF156',34155:'\uF157',34156:'\uF158',34157:'\uF159',34158:'\uF15A',34159:'\uF15B',34160:'\uF15C',34161:'\uF15D',34162:'\uF15E',34163:'\uF15F',34164:'\uF160',34165:'\uF161',34166:'\uF162',34167:'\uF163',34168:'\uF164',34169:'\uF165',34170:'\uF166',34171:'\uF167',34172:'\uF168',34173:'\uF169',34174:'\uF16A',34209:'\uF16B',34210:'\uF16C',34211:'\uF16D',34212:'\uF16E',34213:'\uF16F',34214:'\uF170',34215:'\uF171',34216:'\uF172',34217:'\uF173',34218:'\uF174',34219:'\uF175',34220:'\uF176',34221:'\uF177',34222:'\uF178',34223:'\uF179',34224:'\uF17A',34225:'\uF17B',34226:'\uF17C',34227:'\uF17D',34228:'\uF17E',34229:'\uF17F',34230:'\uF180',34231:'\uF181',34232:'\uF182',34233:'\uF183',34234:'\uF184',34235:'\uF185',34236:'\uF186',34237:'\uF187',34238:'\uF188',34239:'\uF189',34240:'\uF18A',34241:'\uF18B',34242:'\uF18C',34243:'\uF18D',34244:'\uF18E',34245:'\uF18F',34246:'\uF190',34247:'\uF191',34248:'\uF192',34249:'\uF193',34250:'\uF194',34251:'\uF195',34252:'\uF196',34253:'\uF197',34254:'\uF198',34255:'\uF199',34256:'\uF19A',34257:'\uF19B',34258:'\uF19C',34259:'\uF19D',34260:'\uF19E',34261:'\uF19F',34262:'\uF1A0',34263:'\uF1A1',34264:'\uF1A2',34265:'\uF1A3',34266:'\uF1A4',34267:'\uF1A5',34268:'\uF1A6',34269:'\uF1A7',34270:'\uF1A8',34271:'\uF1A9',34272:'\uF1AA',34273:'\uF1AB',34274:'\uF1AC',34275:'\uF1AD',34276:'\uF1AE',34277:'\uF1AF',34278:'\uF1B0',34279:'\uF1B1',34280:'\uF1B2',34281:'\uF1B3',34282:'\uF1B4',34283:'\uF1B5',34284:'\uF1B6',34285:'\uF1B7',34286:'\uF1B8',34287:'\uF1B9',34288:'\uF1BA',34289:'\uF1BB',34290:'\uF1BC',34291:'\uF1BD',34292:'\uF1BE',34293:'\uF1BF',34294:'\uF1C0',34295:'\uF1C1',34296:'\uF1C2',34297:'\uF1C3',34298:'\uF1C4',34299:'\uF1C5',34300:'\uF1C6',34301:'\uF1C7',34302:'\uF1C8',34368:'\uF1C9',34369:'\uF1CA',34370:'\uF1CB',34371:'\uF1CC',34372:'\uF1CD',34373:'\uF1CE',34374:'\uF1CF',34375:'\uF1D0',34376:'\uF1D1',34377:'\uF1D2',34378:'\uF1D3',34379:'\uF1D4',34380:'\uF1D5',34381:'\uF1D6',34382:'\uF1D7',34383:'\uF1D8',34384:'\uF1D9',34385:'\uF1DA',34386:'\uF1DB',34387:'\uF1DC',34388:'\uF1DD',34389:'\uF1DE',34390:'\uF1DF',34391:'\uF1E0',34392:'\uF1E1',34393:'\uF1E2',34394:'\uF1E3',34395:'\uF1E4',34396:'\uF1E5',34397:'\uF1E6',34398:'\uF1E7',34399:'\uF1E8',34400:'\uF1E9',34401:'\uF1EA',34402:'\uF1EB',34403:'\uF1EC',34404:'\uF1ED',34405:'\uF1EE',34406:'\uF1EF',34407:'\uF1F0',34408:'\uF1F1',34409:'\uF1F2',34410:'\uF1F3',34411:'\uF1F4',34412:'\uF1F5',34413:'\uF1F6',34414:'\uF1F7',34415:'\uF1F8',34416:'\uF1F9',34417:'\uF1FA',34418:'\uF1FB',34419:'\uF1FC',34420:'\uF1FD',34421:'\uF1FE',34422:'\uF1FF',34423:'\uF200',34424:'\uF201',34425:'\uF202',34426:'\uF203',34427:'\uF204',34428:'\uF205',34429:'\uF206',34430:'\uF207',34465:'\uF208',34466:'\uF209',34467:'\uF20A',34468:'\uF20B',34469:'\uF20C',34470:'\uF20D',34471:'\uF20E',34472:'\uF20F',34473:'\uF210',34474:'\uF211',34475:'\uF212',34476:'\uF213',34477:'\uF214',34478:'\uF215',34479:'\uF216',34480:'\uF217',34481:'\uF218',34482:'\uF219',34483:'\uF21A',34484:'\uF21B',34485:'\uF21C',34486:'\uF21D',34487:'\uF21E',34488:'\uF21F',34489:'\uF220',34490:'\uF221',34491:'\uF222',34492:'\uF223',34493:'\uF224',34494:'\uF225',34495:'\uF226',34496:'\uF227',34497:'\uF228',34498:'\uF229',34499:'\uF22A',34500:'\uF22B',34501:'\uF22C',34502:'\uF22D',34503:'\uF22E',34504:'\uF22F',34505:'\uF230',34506:'\uF231',34507:'\uF232',34508:'\uF233',34509:'\uF234',34510:'\uF235',34511:'\uF236',34512:'\uF237',34513:'\uF238',34514:'\uF239',34515:'\uF23A',34516:'\uF23B',34517:'\uF23C',34518:'\uF23D',34519:'\uF23E',34520:'\uF23F',34521:'\uF240',34522:'\uF241',34523:'\uF242',34524:'\uF243',34525:'\uF244',34526:'\uF245',34527:'\uF246',34528:'\uF247',34529:'\uF248',34530:'\uF249',34531:'\uF24A',34532:'\uF24B',34533:'\uF24C',34534:'\uF24D',34535:'\uF24E',34536:'\uF24F',34537:'\uF250',34538:'\uF251',34539:'\uF252',34540:'\uF253',34541:'\uF254',34542:'\uF255',34543:'\uF256',34544:'\uF257',34545:'\uF258',34546:'\uF259',34547:'\uF25A',34548:'\uF25B',34549:'\uF25C',34550:'\uF25D',34551:'\uF25E',34552:'\uF25F',34553:'\uF260',34554:'\uF261',34555:'\uF262',34556:'\uF263',34557:'\uF264',34558:'\uF265',34624:'\uF266',34625:'\uF267',34626:'\uF268',34627:'\uF269',34628:'\uF26A',34629:'\uF26B',34630:'\uF26C',34631:'\uF26D',34632:'\uF26E',34633:'\uF26F',34634:'\uF270',34635:'\uF271',34636:'\uF272',34637:'\uF273',34638:'\uF274',34639:'\uF275',34640:'\uF276',34641:'\uF277',34642:'\uF278',34643:'\uF279',34644:'\uF27A',34645:'\uF27B',34646:'\uF27C',34647:'\uF27D',34648:'\uF27E',34649:'\uF27F',34650:'\uF280',34651:'\uF281',34652:'\uF282',34653:'\uF283',34654:'\uF284',34655:'\uF285',34656:'\uF286',34657:'\uF287',34658:'\uF288',34659:'\uF289',34660:'\uF28A',34661:'\uF28B',34662:'\uF28C',34663:'\uF28D',34664:'\uF28E',34665:'\uF28F',34666:'\uF290',34667:'\uF291',34668:'\uF292',34669:'\uF293',34670:'\uF294',34671:'\uF295',34672:'\uF296',34673:'\uF297',34674:'\uF298',34675:'\uF299',34676:'\uF29A',34677:'\uF29B',34678:'\uF29C',34679:'\uF29D',34680:'\uF29E',34681:'\uF29F',34682:'\uF2A0',34683:'\uF2A1',34684:'\uF2A2',34685:'\uF2A3',34686:'\uF2A4',34721:'\uF2A5',34722:'\uF2A6',34723:'\uF2A7',34724:'\uF2A8',34725:'\uF2A9',34726:'\uF2AA',34727:'\uF2AB',34728:'\uF2AC',34729:'\uF2AD',34730:'\uF2AE',34731:'\uF2AF',34732:'\uF2B0',34733:'\uF2B1',34734:'\uF2B2',34735:'\uF2B3',34736:'\uF2B4',34737:'\uF2B5',34738:'\uF2B6',34739:'\uF2B7',34740:'\uF2B8',34741:'\uF2B9',34742:'\uF2BA',34743:'\uF2BB',34744:'\uF2BC',34745:'\uF2BD',34746:'\uF2BE',34747:'\uF2BF',34748:'\uF2C0',34749:'\uF2C1',34750:'\uF2C2',34751:'\uF2C3',34752:'\uF2C4',34753:'\uF2C5',34754:'\uF2C6',34755:'\uF2C7',34756:'\uF2C8',34757:'\uF2C9',34758:'\uF2CA',34759:'\uF2CB',34760:'\uF2CC',34761:'\uF2CD',34762:'\uF2CE',34763:'\uF2CF',34764:'\uF2D0',34765:'\uF2D1',34766:'\uF2D2',34767:'\uF2D3',34768:'\uF2D4',34769:'\uF2D5',34770:'\uF2D6',34771:'\uF2D7',34772:'\uF2D8',34773:'\uF2D9',34774:'\uF2DA',34775:'\uF2DB',34776:'\uF2DC',34777:'\uF2DD',34778:'\uF2DE',34779:'\uF2DF',34780:'\uF2E0',34781:'\uF2E1',34782:'\uF2E2',34783:'\uF2E3',34784:'\uF2E4',34785:'\uF2E5',34786:'\uF2E6',34787:'\uF2E7',34788:'\uF2E8',34789:'\uF2E9',34790:'\uF2EA',34791:'\uF2EB',34792:'\uF2EC',34793:'\uF2ED',34794:'\uF2EE',34795:'\uF2EF',34796:'\uF2F0',34797:'\uF2F1',34798:'\uF2F2',34799:'\uF2F3',34800:'\uF2F4',34801:'\uF2F5',34802:'\uF2F6',34803:'\uF2F7',34804:'\uF2F8',34805:'\uF2F9',34806:'\uF2FA',34807:'\uF2FB',34808:'\uF2FC',34809:'\uF2FD',34810:'\uF2FE',34811:'\uF2FF',34812:'\uF300',34813:'\uF301',34814:'\uF302',34880:'\uF303',34881:'\uF304',34882:'\uF305',34883:'\uF306',34884:'\uF307',34885:'\uF308',34886:'\uF309',34887:'\uF30A',34888:'\uF30B',34889:'\uF30C',34890:'\uF30D',34891:'\uF30E',34892:'\uF30F',34893:'\uF310',34894:'\uF311',34895:'\uF312',34896:'\uF313',34897:'\uF314',34898:'\uF315',34899:'\uF316',34900:'\uF317',34901:'\uF318',34902:'\uF319',34903:'\uF31A',34904:'\uF31B',34905:'\uF31C',34906:'\uF31D',34907:'\uF31E',34908:'\uF31F',34909:'\uF320',34910:'\uF321',34911:'\uF322',34912:'\uF323',34913:'\uF324',34914:'\uF325',34915:'\uF326',34916:'\uF327',34917:'\uF328',34918:'\uF329',34919:'\uF32A',34920:'\uF32B',34921:'\uF32C',34922:'\uF32D',34923:'\uF32E',34924:'\uF32F',34925:'\uF330',34926:'\uF331',34927:'\uF332',34928:'\uF333',34929:'\uF334',34930:'\uF335',34931:'\uF336',34932:'\uF337',34933:'\uF338',34934:'\uF339',34935:'\uF33A',34936:'\uF33B',34937:'\uF33C',34938:'\uF33D',34939:'\uF33E',34940:'\uF33F',34941:'\uF340',34942:'\uF341',34977:'\uF342',34978:'\uF343',34979:'\uF344',34980:'\uF345',34981:'\uF346',34982:'\uF347',34983:'\uF348',34984:'\uF349',34985:'\uF34A',34986:'\uF34B',34987:'\uF34C',34988:'\uF34D',34989:'\uF34E',34990:'\uF34F',34991:'\uF350',34992:'\uF351',34993:'\uF352',34994:'\uF353',34995:'\uF354',34996:'\uF355',34997:'\uF356',34998:'\uF357',34999:'\uF358',35000:'\uF359',35001:'\uF35A',35002:'\uF35B',35003:'\uF35C',35004:'\uF35D',35005:'\uF35E',35006:'\uF35F',35007:'\uF360',35008:'\uF361',35009:'\uF362',35010:'\uF363',35011:'\uF364',35012:'\uF365',35013:'\uF366',35014:'\uF367',35015:'\uF368',35016:'\uF369',35017:'\uF36A',35018:'\uF36B',35019:'\uF36C',35020:'\uF36D',35021:'\uF36E',35022:'\uF36F',35023:'\uF370',35024:'\uF371',35025:'\uF372',35026:'\uF373',35027:'\uF374',35028:'\uF375',35029:'\uF376',35030:'\uF377',35031:'\uF378',35032:'\uF379',35033:'\uF37A',35034:'\uF37B',35035:'\uF37C',35036:'\uF37D',35037:'\uF37E',35038:'\uF37F',35039:'\uF380',35040:'\uF381',35041:'\uF382',35042:'\uF383',35043:'\uF384',35044:'\uF385',35045:'\uF386',35046:'\uF387',35047:'\uF388',35048:'\uF389',35049:'\uF38A',35050:'\uF38B',35051:'\uF38C',35052:'\uF38D',35053:'\uF38E',35054:'\uF38F',35055:'\uF390',35056:'\uF391',35057:'\uF392',35058:'\uF393',35059:'\uF394',35060:'\uF395',35061:'\uF396',35062:'\uF397',35063:'\uF398',35064:'\uF399',35065:'\uF39A',35066:'\uF39B',35067:'\uF39C',35068:'\uF39D',35069:'\uF39E',35070:'\uF39F',35136:'\uF3A0',35137:'\uF3A1',35138:'\uF3A2',35139:'\uF3A3',35140:'\uF3A4',35141:'\uF3A5',35142:'\uF3A6',35143:'\uF3A7',35144:'\uF3A8',35145:'\uF3A9',35146:'\uF3AA',35147:'\uF3AB',35148:'\uF3AC',35149:'\uF3AD',35150:'\uF3AE',35151:'\uF3AF',35152:'\uF3B0',35153:'\uF3B1',35154:'\uF3B2',35155:'\uF3B3',35156:'\uF3B4',35157:'\uF3B5',35158:'\uF3B6',35159:'\uF3B7',35160:'\uF3B8',35161:'\uF3B9',35162:'\uF3BA',35163:'\uF3BB',35164:'\uF3BC',35165:'\uF3BD',35166:'\uF3BE',35167:'\uF3BF',35168:'\uF3C0',35169:'\uF3C1',35170:'\uF3C2',35171:'\uF3C3',35172:'\uF3C4',35173:'\uF3C5',35174:'\uF3C6',35175:'\uF3C7',35176:'\uF3C8',35177:'\uF3C9',35178:'\uF3CA',35179:'\uF3CB',35180:'\uF3CC',35181:'\uF3CD',35182:'\uF3CE',35183:'\uF3CF',35184:'\uF3D0',35185:'\uF3D1',35186:'\uF3D2',35187:'\uF3D3',35188:'\uF3D4',35189:'\uF3D5',35190:'\uF3D6',35191:'\uF3D7',35192:'\uF3D8',35193:'\uF3D9',35194:'\uF3DA',35195:'\uF3DB',35196:'\uF3DC',35197:'\uF3DD',35198:'\uF3DE',35233:'\uF3DF',35234:'\uF3E0',35235:'\uF3E1',35236:'\uF3E2',35237:'\uF3E3',35238:'\uF3E4',35239:'\uF3E5',35240:'\uF3E6',35241:'\uF3E7',35242:'\uF3E8',35243:'\uF3E9',35244:'\uF3EA',35245:'\uF3EB',35246:'\uF3EC',35247:'\uF3ED',35248:'\uF3EE',35249:'\uF3EF',35250:'\uF3F0',35251:'\uF3F1',35252:'\uF3F2',35253:'\uF3F3',35254:'\uF3F4',35255:'\uF3F5',35256:'\uF3F6',35257:'\uF3F7',35258:'\uF3F8',35259:'\uF3F9',35260:'\uF3FA',35261:'\uF3FB',35262:'\uF3FC',35263:'\uF3FD',35264:'\uF3FE',35265:'\uF3FF',35266:'\uF400',35267:'\uF401',35268:'\uF402',35269:'\uF403',35270:'\uF404',35271:'\uF405',35272:'\uF406',35273:'\uF407',35274:'\uF408',35275:'\uF409',35276:'\uF40A',35277:'\uF40B',35278:'\uF40C',35279:'\uF40D',35280:'\uF40E',35281:'\uF40F',35282:'\uF410',35283:'\uF411',35284:'\uF412',35285:'\uF413',35286:'\uF414',35287:'\uF415',35288:'\uF416',35289:'\uF417',35290:'\uF418',35291:'\uF419',35292:'\uF41A',35293:'\uF41B',35294:'\uF41C',35295:'\uF41D',35296:'\uF41E',35297:'\uF41F',35298:'\uF420',35299:'\uF421',35300:'\uF422',35301:'\uF423',35302:'\uF424',35303:'\uF425',35304:'\uF426',35305:'\uF427',35306:'\uF428',35307:'\uF429',35308:'\uF42A',35309:'\uF42B',35310:'\uF42C',35311:'\uF42D',35312:'\uF42E',35313:'\uF42F',35314:'\uF430',35315:'\uF431',35316:'\uF432',35317:'\uF433',35318:'\uF434',35319:'\uF435',35320:'\uF436',35321:'\uF437',35322:'\uF438',35323:'\uF439',35324:'\uF43A',35325:'\uF43B',35326:'\uF43C',35392:'\uF43D',35393:'\uF43E',35394:'\uF43F',35395:'\uF440',35396:'\uF441',35397:'\uF442',35398:'\uF443',35399:'\uF444',35400:'\uF445',35401:'\uF446',35402:'\uF447',35403:'\uF448',35404:'\uF449',35405:'\uF44A',35406:'\uF44B',35407:'\uF44C',35408:'\uF44D',35409:'\uF44E',35410:'\uF44F',35411:'\uF450',35412:'\uF451',35413:'\uF452',35414:'\uF453',35415:'\uF454',35416:'\uF455',35417:'\uF456',35418:'\uF457',35419:'\uF458',35420:'\uF459',35421:'\uF45A',35422:'\uF45B',35423:'\uF45C',35424:'\uF45D',35425:'\uF45E',35426:'\uF45F',35427:'\uF460',35428:'\uF461',35429:'\uF462',35430:'\uF463',35431:'\uF464',35432:'\uF465',35433:'\uF466',35434:'\uF467',35435:'\uF468',35436:'\uF469',35437:'\uF46A',35438:'\uF46B',35439:'\uF46C',35440:'\uF46D',35441:'\uF46E',35442:'\uF46F',35443:'\uF470',35444:'\uF471',35445:'\uF472',35446:'\uF473',35447:'\uF474',35448:'\uF475',35449:'\uF476',35450:'\uF477',35451:'\uF478',35452:'\uF479',35453:'\uF47A',35454:'\uF47B',35489:'\uF47C',35490:'\uF47D',35491:'\uF47E',35492:'\uF47F',35493:'\uF480',35494:'\uF481',35495:'\uF482',35496:'\uF483',35497:'\uF484',35498:'\uF485',35499:'\uF486',35500:'\uF487',35501:'\uF488',35502:'\uF489',35503:'\uF48A',35504:'\uF48B',35505:'\uF48C',35506:'\uF48D',35507:'\uF48E',35508:'\uF48F',35509:'\uF490',35510:'\uF491',35511:'\uF492',35512:'\uF493',35513:'\uF494',35514:'\uF495',35515:'\uF496',35516:'\uF497',35517:'\uF498',35518:'\uF499',35519:'\uF49A',35520:'\uF49B',35521:'\uF49C',35522:'\uF49D',35523:'\uF49E',35524:'\uF49F',35525:'\uF4A0',35526:'\uF4A1',35527:'\uF4A2',35528:'\uF4A3',35529:'\uF4A4',35530:'\uF4A5',35531:'\uF4A6',35532:'\uF4A7',35533:'\uF4A8',35534:'\uF4A9',35535:'\uF4AA',35536:'\uF4AB',35537:'\uF4AC',35538:'\uF4AD',35539:'\uF4AE',35540:'\uF4AF',35541:'\uF4B0',35542:'\uF4B1',35543:'\uF4B2',35544:'\uF4B3',35545:'\uF4B4',35546:'\uF4B5',35547:'\uF4B6',35548:'\uF4B7',35549:'\uF4B8',35550:'\uF4B9',35551:'\uF4BA',35552:'\uF4BB',35553:'\uF4BC',35554:'\uF4BD',35555:'\uF4BE',35556:'\uF4BF',35557:'\uF4C0',35558:'\uF4C1',35559:'\uF4C2',35560:'\uF4C3',35561:'\uF4C4',35562:'\uF4C5',35563:'\uF4C6',35564:'\uF4C7',35565:'\uF4C8',35566:'\uF4C9',35567:'\uF4CA',35568:'\uF4CB',35569:'\uF4CC',35570:'\uF4CD',35571:'\uF4CE',35572:'\uF4CF',35573:'\uF4D0',35574:'\uF4D1',35575:'\uF4D2',35576:'\uF4D3',35577:'\uF4D4',35578:'\uF4D5',35579:'\uF4D6',35580:'\uF4D7',35581:'\uF4D8',35582:'\uF4D9',35648:'\uF4DA',35649:'\uF4DB',35650:'\uF4DC',35651:'\uF4DD',35652:'\uF4DE',35653:'\uF4DF',35654:'\uF4E0',35655:'\uF4E1',35656:'\uF4E2',35657:'\uF4E3',35658:'\uF4E4',35659:'\uF4E5',35660:'\uF4E6',35661:'\uF4E7',35662:'\uF4E8',35663:'\uF4E9',35664:'\uF4EA',35665:'\uF4EB',35666:'\uF4EC',35667:'\uF4ED',35668:'\uF4EE',35669:'\uF4EF',35670:'\uF4F0',35671:'\uF4F1',35672:'\uF4F2',35673:'\uF4F3',35674:'\uF4F4',35675:'\uF4F5',35676:'\uF4F6',35677:'\uF4F7',35678:'\uF4F8',35679:'\uF4F9',35680:'\uF4FA',35681:'\uF4FB',35682:'\uF4FC',35683:'\uF4FD',35684:'\uF4FE',35685:'\uF4FF',35686:'\uF500',35687:'\uF501',35688:'\uF502',35689:'\uF503',35690:'\uF504',35691:'\uF505',35692:'\uF506',35693:'\uF507',35694:'\uF508',35695:'\uF509',35696:'\uF50A',35697:'\uF50B',35698:'\uF50C',35699:'\uF50D',35700:'\uF50E',35701:'\uF50F',35702:'\uF510',35703:'\uF511',35704:'\uF512',35705:'\uF513',35706:'\uF514',35707:'\uF515',35708:'\uF516',35709:'\uF517',35710:'\uF518',35745:'\uF519',35746:'\uF51A',35747:'\uF51B',35748:'\uF51C',35749:'\uF51D',35750:'\uF51E',35751:'\uF51F',35752:'\uF520',35753:'\uF521',35754:'\uF522',35755:'\uF523',35756:'\uF524',35757:'\uF525',35758:'\uF526',35759:'\uF527',35760:'\uF528',35761:'\uF529',35762:'\uF52A',35763:'\uF52B',35764:'\uF52C',35765:'\uF52D',35766:'\uF52E',35767:'\uF52F',35768:'\uF530',35769:'\uF531',35770:'\uF532',35771:'\uF533',35772:'\uF534',35773:'\uF535',35774:'\uF536',35775:'\uF537',35776:'\uF538',35777:'\uF539',35778:'\uF53A',35779:'\uF53B',35780:'\uF53C',35781:'\uF53D',35782:'\uF53E',35783:'\uF53F',35784:'\uF540',35785:'\uF541',35786:'\uF542',35787:'\uF543',35788:'\uF544',35789:'\uF545',35790:'\uF546',35791:'\uF547',35792:'\uF548',35793:'\uF549',35794:'\uF54A',35795:'\uF54B',35796:'\uF54C',35797:'\uF54D',35798:'\uF54E',35799:'\uF54F',35800:'\uF550',35801:'\uF551',35802:'\uF552',35803:'\uF553',35804:'\uF554',35805:'\uF555',35806:'\uF556',35807:'\uF557',35808:'\uF558',35809:'\uF559',35810:'\uF55A',35811:'\uF55B',35812:'\uF55C',35813:'\uF55D',35814:'\uF55E',35815:'\uF55F',35816:'\uF560',35817:'\uF561',35818:'\uF562',35819:'\uF563',35820:'\uF564',35821:'\uF565',35822:'\uF566',35823:'\uF567',35824:'\uF568',35825:'\uF569',35826:'\uF56A',35827:'\uF56B',35828:'\uF56C',35829:'\uF56D',35830:'\uF56E',35831:'\uF56F',35832:'\uF570',35833:'\uF571',35834:'\uF572',35835:'\uF573',35836:'\uF574',35837:'\uF575',35838:'\uF576',35904:'\uF577',35905:'\uF578',35906:'\uF579',35907:'\uF57A',35908:'\uF57B',35909:'\uF57C',35910:'\uF57D',35911:'\uF57E',35912:'\uF57F',35913:'\uF580',35914:'\uF581',35915:'\uF582',35916:'\uF583',35917:'\uF584',35918:'\uF585',35919:'\uF586',35920:'\uF587',35921:'\uF588',35922:'\uF589',35923:'\uF58A',35924:'\uF58B',35925:'\uF58C',35926:'\uF58D',35927:'\uF58E',35928:'\uF58F',35929:'\uF590',35930:'\uF591',35931:'\uF592',35932:'\uF593',35933:'\uF594',35934:'\uF595',35935:'\uF596',35936:'\uF597',35937:'\uF598',35938:'\uF599',35939:'\uF59A',35940:'\uF59B',35941:'\uF59C',35942:'\uF59D',35943:'\uF59E',35944:'\uF59F',35945:'\uF5A0',35946:'\uF5A1',35947:'\uF5A2',35948:'\uF5A3',35949:'\uF5A4',35950:'\uF5A5',35951:'\uF5A6',35952:'\uF5A7',35953:'\uF5A8',35954:'\uF5A9',35955:'\uF5AA',35956:'\uF5AB',35957:'\uF5AC',35958:'\uF5AD',35959:'\uF5AE',35960:'\uF5AF',35961:'\uF5B0',35962:'\uF5B1',35963:'\uF5B2',35964:'\uF5B3',35965:'\uF5B4',35966:'\uF5B5',36001:'\uF5B6',36002:'\uF5B7',36003:'\uF5B8',36004:'\uF5B9',36005:'\uF5BA',36006:'\uF5BB',36007:'\uF5BC',36008:'\uF5BD',36009:'\uF5BE',36010:'\uF5BF',36011:'\uF5C0',36012:'\uF5C1',36013:'\uF5C2',36014:'\uF5C3',36015:'\uF5C4',36016:'\uF5C5',36017:'\uF5C6',36018:'\uF5C7',36019:'\uF5C8',36020:'\uF5C9',36021:'\uF5CA',36022:'\uF5CB',36023:'\uF5CC',36024:'\uF5CD',36025:'\uF5CE',36026:'\uF5CF',36027:'\uF5D0',36028:'\uF5D1',36029:'\uF5D2',36030:'\uF5D3',36031:'\uF5D4',36032:'\uF5D5',36033:'\uF5D6',36034:'\uF5D7',36035:'\uF5D8',36036:'\uF5D9',36037:'\uF5DA',36038:'\uF5DB',36039:'\uF5DC',36040:'\uF5DD',36041:'\uF5DE',36042:'\uF5DF',36043:'\uF5E0',36044:'\uF5E1',36045:'\uF5E2',36046:'\uF5E3',36047:'\uF5E4',36048:'\uF5E5',36049:'\uF5E6',36050:'\uF5E7',36051:'\uF5E8',36052:'\uF5E9',36053:'\uF5EA',36054:'\uF5EB',36055:'\uF5EC',36056:'\uF5ED',36057:'\uF5EE',36058:'\uF5EF',36059:'\uF5F0',36060:'\uF5F1',36061:'\uF5F2',36062:'\uF5F3',36063:'\uF5F4',36064:'\uF5F5',36065:'\uF5F6',36066:'\uF5F7',36067:'\uF5F8',36068:'\uF5F9',36069:'\uF5FA',36070:'\uF5FB',36071:'\uF5FC',36072:'\uF5FD',36073:'\uF5FE',36074:'\uF5FF',36075:'\uF600',36076:'\uF601',36077:'\uF602',36078:'\uF603',36079:'\uF604',36080:'\uF605',36081:'\uF606',36082:'\uF607',36083:'\uF608',36084:'\uF609',36085:'\uF60A',36086:'\uF60B',36087:'\uF60C',36088:'\uF60D',36089:'\uF60E',36090:'\uF60F',36091:'\uF610',36092:'\uF611',36093:'\uF612',36094:'\uF613',36160:'\uF614',36161:'\uF615',36162:'\uF616',36163:'\uF617',36164:'\uF618',36165:'\uF619',36166:'\uF61A',36167:'\uF61B',36168:'\uF61C',36169:'\uF61D',36170:'\uF61E',36171:'\uF61F',36172:'\uF620',36173:'\uF621',36174:'\uF622',36175:'\uF623',36176:'\uF624',36177:'\uF625',36178:'\uF626',36179:'\uF627',36180:'\uF628',36181:'\uF629',36182:'\uF62A',36183:'\uF62B',36184:'\uF62C',36185:'\uF62D',36186:'\uF62E',36187:'\uF62F',36188:'\uF630',36189:'\uF631',36190:'\uF632',36191:'\uF633',36192:'\uF634',36193:'\uF635',36194:'\uF636',36195:'\uF637',36196:'\uF638',36197:'\uF639',36198:'\uF63A',36199:'\uF63B',36200:'\uF63C',36201:'\uF63D',36202:'\uF63E',36203:'\uF63F',36204:'\uF640',36205:'\uF641',36206:'\uF642',36207:'\uF643',36208:'\uF644',36209:'\uF645',36210:'\uF646',36211:'\uF647',36212:'\uF648',36213:'\uF649',36214:'\uF64A',36215:'\uF64B',36216:'\uF64C',36217:'\uF64D',36218:'\uF64E',36219:'\uF64F',36220:'\uF650',36221:'\uF651',36222:'\uF652',36257:'\uF653',36258:'\uF654',36259:'\uF655',36260:'\uF656',36261:'\uF657',36262:'\uF658',36263:'\uF659',36264:'\uF65A',36265:'\uF65B',36266:'\uF65C',36267:'\uF65D',36268:'\uF65E',36269:'\uF65F',36270:'\uF660',36271:'\uF661',36272:'\uF662',36273:'\uF663',36274:'\uF664',36275:'\uF665',36276:'\uF666',36277:'\uF667',36278:'\uF668',36279:'\uF669',36280:'\uF66A',36281:'\uF66B',36282:'\uF66C',36283:'\uF66D',36284:'\uF66E',36285:'\uF66F',36286:'\uF670',36287:'\uF671',36288:'\uF672',36289:'\uF673',36290:'\uF674',36291:'\uF675',36292:'\uF676',36293:'\uF677',36294:'\uF678',36295:'\uF679',36296:'\uF67A',36297:'\uF67B',36298:'\uF67C',36299:'\uF67D',36300:'\uF67E',36301:'\uF67F',36302:'\uF680',36303:'\uF681',36304:'\uF682',36305:'\uF683',36306:'\uF684',36307:'\uF685',36308:'\uF686',36309:'\uF687',36310:'\uF688',36311:'\uF689',36312:'\uF68A',36313:'\uF68B',36314:'\uF68C',36315:'\uF68D',36316:'\uF68E',36317:'\uF68F',36318:'\uF690',36319:'\uF691',36320:'\uF692',36321:'\uF693',36322:'\uF694',36323:'\uF695',36324:'\uF696',36325:'\uF697',36326:'\uF698',36327:'\uF699',36328:'\uF69A',36329:'\uF69B',36330:'\uF69C',36331:'\uF69D',36332:'\uF69E',36333:'\uF69F',36334:'\uF6A0',36335:'\uF6A1',36336:'\uF6A2',36337:'\uF6A3',36338:'\uF6A4',36339:'\uF6A5',36340:'\uF6A6',36341:'\uF6A7',36342:'\uF6A8',36343:'\uF6A9',36344:'\uF6AA',36345:'\uF6AB',36346:'\uF6AC',36347:'\uF6AD',36348:'\uF6AE',36349:'\uF6AF',36350:'\uF6B0',36416:'\uE311',36417:'\uE312',36418:'\uE313',36419:'\uE314',36420:'\uE315',36421:'\uE316',36422:'\uE317',36423:'\uE318',36424:'\uE319',36425:'\uE31A',36426:'\uE31B',36427:'\uE31C',36428:'\uE31D',36429:'\uE31E',36430:'\uE31F',36431:'\uE320',36432:'\uE321',36433:'\uE322',36434:'\uE323',36435:'\uE324',36436:'\uE325',36437:'\uE326',36438:'\uE327',36439:'\uE328',36440:'\uE329',36441:'\uE32A',36442:'\uE32B',36443:'\uE32C',36444:'\uE32D',36445:'\uE32E',36446:'\uE32F',36447:'\uE330',36448:'\uE331',36449:'\uE332',36450:'\uE333',36451:'\uE334',36452:'\uE335',36453:'\uE336',36454:'\uE337',36455:'\uE338',36456:'\uE339',36457:'\uE33A',36458:'\uE33B',36459:'\uE33C',36460:'\uE33D',36461:'\uE33E',36462:'\uE33F',36463:'\uE340',36464:'\uE341',36465:'\uE342',36466:'\uE343',36467:'\uE344',36468:'\uE345',36469:'\uE346',36470:'\uE347',36471:'\uE348',36472:'\uE349',36473:'\uE34A',36474:'\uE34B',36475:'\uE34C',36476:'\uE34D',36477:'\uE34E',36478:'\uE34F',36513:'\uE350',36514:'\uE351',36515:'\uE352',36516:'\uE353',36517:'\uE354',36518:'\uE355',36519:'\uE356',36520:'\uE357',36521:'\uE358',36522:'\uE359',36523:'\uE35A',36524:'\uE35B',36525:'\uE35C',36526:'\uE35D',36527:'\uE35E',36528:'\uE35F',36529:'\uE360',36530:'\uE361',36531:'\uE362',36532:'\uE363',36533:'\uE364',36534:'\uE365',36535:'\uE366',36536:'\uE367',36537:'\uE368',36538:'\uE369',36539:'\uE36A',36540:'\uE36B',36541:'\uE36C',36542:'\uE36D',36543:'\uE36E',36544:'\uE36F',36545:'\uE370',36546:'\uE371',36547:'\uE372',36548:'\uE373',36549:'\uE374',36550:'\uE375',36551:'\uE376',36552:'\uE377',36553:'\uE378',36554:'\uE379',36555:'\uE37A',36556:'\uE37B',36557:'\uE37C',36558:'\uE37D',36559:'\uE37E',36560:'\uE37F',36561:'\uE380',36562:'\uE381',36563:'\uE382',36564:'\uE383',36565:'\uE384',36566:'\uE385',36567:'\uE386',36568:'\uE387',36569:'\uE388',36570:'\uE389',36571:'\uE38A',36572:'\uE38B',36573:'\uE38C',36574:'\uE38D',36575:'\uE38E',36576:'\uE38F',36577:'\uE390',36578:'\uE391',36579:'\uE392',36580:'\uE393',36581:'\uE394',36582:'\uE395',36583:'\uE396',36584:'\uE397',36585:'\uE398',36586:'\uE399',36587:'\uE39A',36588:'\uE39B',36589:'\uE39C',36590:'\uE39D',36591:'\uE39E',36592:'\uE39F',36593:'\uE3A0',36594:'\uE3A1',36595:'\uE3A2',36596:'\uE3A3',36597:'\uE3A4',36598:'\uE3A5',36599:'\uE3A6',36600:'\uE3A7',36601:'\uE3A8',36602:'\uE3A9',36603:'\uE3AA',36604:'\uE3AB',36605:'\uE3AC',36606:'\uE3AD',36672:'\uE3AE',36673:'\uE3AF',36674:'\uE3B0',36675:'\uE3B1',36676:'\uE3B2',36677:'\uE3B3',36678:'\uE3B4',36679:'\uE3B5',36680:'\uE3B6',36681:'\uE3B7',36682:'\uE3B8',36683:'\uE3B9',36684:'\uE3BA',36685:'\uE3BB',36686:'\uE3BC',36687:'\uE3BD',36688:'\uE3BE',36689:'\uE3BF',36690:'\uE3C0',36691:'\uE3C1',36692:'\uE3C2',36693:'\uE3C3',36694:'\uE3C4',36695:'\uE3C5',36696:'\uE3C6',36697:'\uE3C7',36698:'\uE3C8',36699:'\uE3C9',36700:'\uE3CA',36701:'\uE3CB',36702:'\uE3CC',36703:'\uE3CD',36704:'\uE3CE',36705:'\uE3CF',36706:'\uE3D0',36707:'\uE3D1',36708:'\uE3D2',36709:'\uE3D3',36710:'\uE3D4',36711:'\uE3D5',36712:'\uE3D6',36713:'\uE3D7',36714:'\uE3D8',36715:'\uE3D9',36716:'\uE3DA',36717:'\uE3DB',36718:'\uE3DC',36719:'\uE3DD',36720:'\uE3DE',36721:'\uE3DF',36722:'\uE3E0',36723:'\uE3E1',36724:'\uE3E2',36725:'\uE3E3',36726:'\uE3E4',36727:'\uE3E5',36728:'\uE3E6',36729:'\uE3E7',36730:'\uE3E8',36731:'\uE3E9',36732:'\uE3EA',36733:'\uE3EB',36734:'\uE3EC',36769:'\uE3ED',36770:'\uE3EE',36771:'\uE3EF',36772:'\uE3F0',36773:'\uE3F1',36774:'\uE3F2',36775:'\uE3F3',36776:'\uE3F4',36777:'\uE3F5',36778:'\uE3F6',36779:'\uE3F7',36780:'\uE3F8',36781:'\uE3F9',36782:'\uE3FA',36783:'\uE3FB',36784:'\uE3FC',36785:'\uE3FD',36786:'\uE3FE',36787:'\uE3FF',36788:'\uE400',36789:'\uE401',36790:'\uE402',36791:'\uE403',36792:'\uE404',36793:'\uE405',36794:'\uE406',36795:'\uE407',36796:'\uE408',36797:'\uE409',36798:'\uE40A',36799:'\uE40B',36800:'\uE40C',36801:'\uE40D',36802:'\uE40E',36803:'\uE40F',36804:'\uE410',36805:'\uE411',36806:'\uE412',36807:'\uE413',36808:'\uE414',36809:'\uE415',36810:'\uE416',36811:'\uE417',36812:'\uE418',36813:'\uE419',36814:'\uE41A',36815:'\uE41B',36816:'\uE41C',36817:'\uE41D',36818:'\uE41E',36819:'\uE41F',36820:'\uE420',36821:'\uE421',36822:'\uE422',36823:'\uE423',36824:'\uE424',36825:'\uE425',36826:'\uE426',36827:'\uE427',36828:'\uE428',36829:'\uE429',36830:'\uE42A',36831:'\uE42B',36832:'\uE42C',36833:'\uE42D',36834:'\uE42E',36835:'\uE42F',36836:'\uE430',36837:'\uE431',36838:'\uE432',36839:'\uE433',36840:'\uE434',36841:'\uE435',36842:'\uE436',36843:'\uE437',36844:'\uE438',36845:'\uE439',36846:'\uE43A',36847:'\uE43B',36848:'\uE43C',36849:'\uE43D',36850:'\uE43E',36851:'\uE43F',36852:'\uE440',36853:'\uE441',36854:'\uE442',36855:'\uE443',36856:'\uE444',36857:'\uE445',36858:'\uE446',36859:'\uE447',36860:'\uE448',36861:'\uE449',36862:'\uE44A',36928:'\uE44B',36929:'\uE44C',36930:'\uE44D',36931:'\uE44E',36932:'\uE44F',36933:'\uE450',36934:'\uE451',36935:'\uE452',36936:'\uE453',36937:'\uE454',36938:'\uE455',36939:'\uE456',36940:'\uE457',36941:'\uE458',36942:'\uE459',36943:'\uE45A',36944:'\uE45B',36945:'\uE45C',36946:'\uE45D',36947:'\uE45E',36948:'\uE45F',36949:'\uE460',36950:'\uE461',36951:'\uE462',36952:'\uE463',36953:'\uE464',36954:'\uE465',36955:'\uE466',36956:'\uE467',36957:'\uE468',36958:'\uE469',36959:'\uE46A',36960:'\uE46B',36961:'\uE46C',36962:'\uE46D',36963:'\uE46E',36964:'\uE46F',36965:'\uE470',36966:'\uE471',36967:'\uE472',36968:'\uE473',36969:'\uE474',36970:'\uE475',36971:'\uE476',36972:'\uE477',36973:'\uE478',36974:'\uE479',36975:'\uE47A',36976:'\uE47B',36977:'\uE47C',36978:'\uE47D',36979:'\uE47E',36980:'\uE47F',36981:'\uE480',36982:'\uE481',36983:'\uE482',36984:'\uE483',36985:'\uE484',36986:'\uE485',36987:'\uE486',36988:'\uE487',36989:'\uE488',36990:'\uE489',37025:'\uE48A',37026:'\uE48B',37027:'\uE48C',37028:'\uE48D',37029:'\uE48E',37030:'\uE48F',37031:'\uE490',37032:'\uE491',37033:'\uE492',37034:'\uE493',37035:'\uE494',37036:'\uE495',37037:'\uE496',37038:'\uE497',37039:'\uE498',37040:'\uE499',37041:'\uE49A',37042:'\uE49B',37043:'\uE49C',37044:'\uE49D',37045:'\uE49E',37046:'\uE49F',37047:'\uE4A0',37048:'\uE4A1',37049:'\uE4A2',37050:'\uE4A3',37051:'\uE4A4',37052:'\uE4A5',37053:'\uE4A6',37054:'\uE4A7',37055:'\uE4A8',37056:'\uE4A9',37057:'\uE4AA',37058:'\uE4AB',37059:'\uE4AC',37060:'\uE4AD',37061:'\uE4AE',37062:'\uE4AF',37063:'\uE4B0',37064:'\uE4B1',37065:'\uE4B2',37066:'\uE4B3',37067:'\uE4B4',37068:'\uE4B5',37069:'\uE4B6',37070:'\uE4B7',37071:'\uE4B8',37072:'\uE4B9',37073:'\uE4BA',37074:'\uE4BB',37075:'\uE4BC',37076:'\uE4BD',37077:'\uE4BE',37078:'\uE4BF',37079:'\uE4C0',37080:'\uE4C1',37081:'\uE4C2',37082:'\uE4C3',37083:'\uE4C4',37084:'\uE4C5',37085:'\uE4C6',37086:'\uE4C7',37087:'\uE4C8',37088:'\uE4C9',37089:'\uE4CA',37090:'\uE4CB',37091:'\uE4CC',37092:'\uE4CD',37093:'\uE4CE',37094:'\uE4CF',37095:'\uE4D0',37096:'\uE4D1',37097:'\uE4D2',37098:'\uE4D3',37099:'\uE4D4',37100:'\uE4D5',37101:'\uE4D6',37102:'\uE4D7',37103:'\uE4D8',37104:'\uE4D9',37105:'\uE4DA',37106:'\uE4DB',37107:'\uE4DC',37108:'\uE4DD',37109:'\uE4DE',37110:'\uE4DF',37111:'\uE4E0',37112:'\uE4E1',37113:'\uE4E2',37114:'\uE4E3',37115:'\uE4E4',37116:'\uE4E5',37117:'\uE4E6',37118:'\uE4E7',37184:'\uE4E8',37185:'\uE4E9',37186:'\uE4EA',37187:'\uE4EB',37188:'\uE4EC',37189:'\uE4ED',37190:'\uE4EE',37191:'\uE4EF',37192:'\uE4F0',37193:'\uE4F1',37194:'\uE4F2',37195:'\uE4F3',37196:'\uE4F4',37197:'\uE4F5',37198:'\uE4F6',37199:'\uE4F7',37200:'\uE4F8',37201:'\uE4F9',37202:'\uE4FA',37203:'\uE4FB',37204:'\uE4FC',37205:'\uE4FD',37206:'\uE4FE',37207:'\uE4FF',37208:'\uE500',37209:'\uE501',37210:'\uE502',37211:'\uE503',37212:'\uE504',37213:'\uE505',37214:'\uE506',37215:'\uE507',37216:'\uE508',37217:'\uE509',37218:'\uE50A',37219:'\uE50B',37220:'\uE50C',37221:'\uE50D',37222:'\uE50E',37223:'\uE50F',37224:'\uE510',37225:'\uE511',37226:'\uE512',37227:'\uE513',37228:'\uE514',37229:'\uE515',37230:'\uE516',37231:'\uE517',37232:'\uE518',37233:'\uE519',37234:'\uE51A',37235:'\uE51B',37236:'\uE51C',37237:'\uE51D',37238:'\uE51E',37239:'\uE51F',37240:'\uE520',37241:'\uE521',37242:'\uE522',37243:'\uE523',37244:'\uE524',37245:'\uE525',37246:'\uE526',37281:'\uE527',37282:'\uE528',37283:'\uE529',37284:'\uE52A',37285:'\uE52B',37286:'\uE52C',37287:'\uE52D',37288:'\uE52E',37289:'\uE52F',37290:'\uE530',37291:'\uE531',37292:'\uE532',37293:'\uE533',37294:'\uE534',37295:'\uE535',37296:'\uE536',37297:'\uE537',37298:'\uE538',37299:'\uE539',37300:'\uE53A',37301:'\uE53B',37302:'\uE53C',37303:'\uE53D',37304:'\uE53E',37305:'\uE53F',37306:'\uE540',37307:'\uE541',37308:'\uE542',37309:'\uE543',37310:'\uE544',37311:'\uE545',37312:'\uE546',37313:'\uE547',37314:'\uE548',37315:'\uE549',37316:'\uE54A',37317:'\uE54B',37318:'\uE54C',37319:'\uE54D',37320:'\uE54E',37321:'\uE54F',37322:'\uE550',37323:'\uE551',37324:'\uE552',37325:'\uE553',37326:'\uE554',37327:'\uE555',37328:'\uE556',37329:'\uE557',37330:'\uE558',37331:'\uE559',37332:'\uE55A',37333:'\uE55B',37334:'\uE55C',37335:'\uE55D',37336:'\uE55E',37337:'\uE55F',37338:'\uE560',37339:'\uE561',37340:'\uE562',37341:'\uE563',37342:'\uE564',37343:'\uE565',37344:'\uE566',37345:'\uE567',37346:'\uE568',37347:'\uE569',37348:'\uE56A',37349:'\uE56B',37350:'\uE56C',37351:'\uE56D',37352:'\uE56E',37353:'\uE56F',37354:'\uE570',37355:'\uE571',37356:'\uE572',37357:'\uE573',37358:'\uE574',37359:'\uE575',37360:'\uE576',37361:'\uE577',37362:'\uE578',37363:'\uE579',37364:'\uE57A',37365:'\uE57B',37366:'\uE57C',37367:'\uE57D',37368:'\uE57E',37369:'\uE57F',37370:'\uE580',37371:'\uE581',37372:'\uE582',37373:'\uE583',37374:'\uE584',37440:'\uE585',37441:'\uE586',37442:'\uE587',37443:'\uE588',37444:'\uE589',37445:'\uE58A',37446:'\uE58B',37447:'\uE58C',37448:'\uE58D',37449:'\uE58E',37450:'\uE58F',37451:'\uE590',37452:'\uE591',37453:'\uE592',37454:'\uE593',37455:'\uE594',37456:'\uE595',37457:'\uE596',37458:'\uE597',37459:'\uE598',37460:'\uE599',37461:'\uE59A',37462:'\uE59B',37463:'\uE59C',37464:'\uE59D',37465:'\uE59E',37466:'\uE59F',37467:'\uE5A0',37468:'\uE5A1',37469:'\uE5A2',37470:'\uE5A3',37471:'\uE5A4',37472:'\uE5A5',37473:'\uE5A6',37474:'\uE5A7',37475:'\uE5A8',37476:'\uE5A9',37477:'\uE5AA',37478:'\uE5AB',37479:'\uE5AC',37480:'\uE5AD',37481:'\uE5AE',37482:'\uE5AF',37483:'\uE5B0',37484:'\uE5B1',37485:'\uE5B2',37486:'\uE5B3',37487:'\uE5B4',37488:'\uE5B5',37489:'\uE5B6',37490:'\uE5B7',37491:'\uE5B8',37492:'\uE5B9',37493:'\uE5BA',37494:'\uE5BB',37495:'\uE5BC',37496:'\uE5BD',37497:'\uE5BE',37498:'\uE5BF',37499:'\uE5C0',37500:'\uE5C1',37501:'\uE5C2',37502:'\uE5C3',37537:'\uE5C4',37538:'\uE5C5',37539:'\uE5C6',37540:'\uE5C7',37541:'\uE5C8',37542:'\uE5C9',37543:'\uE5CA',37544:'\uE5CB',37545:'\uE5CC',37546:'\uE5CD',37547:'\uE5CE',37548:'\uE5CF',37549:'\uE5D0',37550:'\uE5D1',37551:'\uE5D2',37552:'\uE5D3',37553:'\uE5D4',37554:'\uE5D5',37555:'\uE5D6',37556:'\uE5D7',37557:'\uE5D8',37558:'\uE5D9',37559:'\uE5DA',37560:'\uE5DB',37561:'\uE5DC',37562:'\uE5DD',37563:'\uE5DE',37564:'\uE5DF',37565:'\uE5E0',37566:'\uE5E1',37567:'\uE5E2',37568:'\uE5E3',37569:'\uE5E4',37570:'\uE5E5',37571:'\uE5E6',37572:'\uE5E7',37573:'\uE5E8',37574:'\uE5E9',37575:'\uE5EA',37576:'\uE5EB',37577:'\uE5EC',37578:'\uE5ED',37579:'\uE5EE',37580:'\uE5EF',37581:'\uE5F0',37582:'\uE5F1',37583:'\uE5F2',37584:'\uE5F3',37585:'\uE5F4',37586:'\uE5F5',37587:'\uE5F6',37588:'\uE5F7',37589:'\uE5F8',37590:'\uE5F9',37591:'\uE5FA',37592:'\uE5FB',37593:'\uE5FC',37594:'\uE5FD',37595:'\uE5FE',37596:'\uE5FF',37597:'\uE600',37598:'\uE601',37599:'\uE602',37600:'\uE603',37601:'\uE604',37602:'\uE605',37603:'\uE606',37604:'\uE607',37605:'\uE608',37606:'\uE609',37607:'\uE60A',37608:'\uE60B',37609:'\uE60C',37610:'\uE60D',37611:'\uE60E',37612:'\uE60F',37613:'\uE610',37614:'\uE611',37615:'\uE612',37616:'\uE613',37617:'\uE614',37618:'\uE615',37619:'\uE616',37620:'\uE617',37621:'\uE618',37622:'\uE619',37623:'\uE61A',37624:'\uE61B',37625:'\uE61C',37626:'\uE61D',37627:'\uE61E',37628:'\uE61F',37629:'\uE620',37630:'\uE621',37696:'\uE622',37697:'\uE623',37698:'\uE624',37699:'\uE625',37700:'\uE626',37701:'\uE627',37702:'\uE628',37703:'\uE629',37704:'\uE62A',37705:'\uE62B',37706:'\uE62C',37707:'\uE62D',37708:'\uE62E',37709:'\uE62F',37710:'\uE630',37711:'\uE631',37712:'\uE632',37713:'\uE633',37714:'\uE634',37715:'\uE635',37716:'\uE636',37717:'\uE637',37718:'\uE638',37719:'\uE639',37720:'\uE63A',37721:'\uE63B',37722:'\uE63C',37723:'\uE63D',37724:'\uE63E',37725:'\uE63F',37726:'\uE640',37727:'\uE641',37728:'\uE642',37729:'\uE643',37730:'\uE644',37731:'\uE645',37732:'\uE646',37733:'\uE647',37734:'\uE648',37735:'\uE649',37736:'\uE64A',37737:'\uE64B',37738:'\uE64C',37739:'\uE64D',37740:'\uE64E',37741:'\uE64F',37742:'\uE650',37743:'\uE651',37744:'\uE652',37745:'\uE653',37746:'\uE654',37747:'\uE655',37748:'\uE656',37749:'\uE657',37750:'\uE658',37751:'\uE659',37752:'\uE65A',37753:'\uE65B',37754:'\uE65C',37755:'\uE65D',37756:'\uE65E',37757:'\uE65F',37758:'\uE660',37793:'\uE661',37794:'\uE662',37795:'\uE663',37796:'\uE664',37797:'\uE665',37798:'\uE666',37799:'\uE667',37800:'\uE668',37801:'\uE669',37802:'\uE66A',37803:'\uE66B',37804:'\uE66C',37805:'\uE66D',37806:'\uE66E',37807:'\uE66F',37808:'\uE670',37809:'\uE671',37810:'\uE672',37811:'\uE673',37812:'\uE674',37813:'\uE675',37814:'\uE676',37815:'\uE677',37816:'\uE678',37817:'\uE679',37818:'\uE67A',37819:'\uE67B',37820:'\uE67C',37821:'\uE67D',37822:'\uE67E',37823:'\uE67F',37824:'\uE680',37825:'\uE681',37826:'\uE682',37827:'\uE683',37828:'\uE684',37829:'\uE685',37830:'\uE686',37831:'\uE687',37832:'\uE688',37833:'\uE689',37834:'\uE68A',37835:'\uE68B',37836:'\uE68C',37837:'\uE68D',37838:'\uE68E',37839:'\uE68F',37840:'\uE690',37841:'\uE691',37842:'\uE692',37843:'\uE693',37844:'\uE694',37845:'\uE695',37846:'\uE696',37847:'\uE697',37848:'\uE698',37849:'\uE699',37850:'\uE69A',37851:'\uE69B',37852:'\uE69C',37853:'\uE69D',37854:'\uE69E',37855:'\uE69F',37856:'\uE6A0',37857:'\uE6A1',37858:'\uE6A2',37859:'\uE6A3',37860:'\uE6A4',37861:'\uE6A5',37862:'\uE6A6',37863:'\uE6A7',37864:'\uE6A8',37865:'\uE6A9',37866:'\uE6AA',37867:'\uE6AB',37868:'\uE6AC',37869:'\uE6AD',37870:'\uE6AE',37871:'\uE6AF',37872:'\uE6B0',37873:'\uE6B1',37874:'\uE6B2',37875:'\uE6B3',37876:'\uE6B4',37877:'\uE6B5',37878:'\uE6B6',37879:'\uE6B7',37880:'\uE6B8',37881:'\uE6B9',37882:'\uE6BA',37883:'\uE6BB',37884:'\uE6BC',37885:'\uE6BD',37886:'\uE6BE',37952:'\uE6BF',37953:'\uE6C0',37954:'\uE6C1',37955:'\uE6C2',37956:'\uE6C3',37957:'\uE6C4',37958:'\uE6C5',37959:'\uE6C6',37960:'\uE6C7',37961:'\uE6C8',37962:'\uE6C9',37963:'\uE6CA',37964:'\uE6CB',37965:'\uE6CC',37966:'\uE6CD',37967:'\uE6CE',37968:'\uE6CF',37969:'\uE6D0',37970:'\uE6D1',37971:'\uE6D2',37972:'\uE6D3',37973:'\uE6D4',37974:'\uE6D5',37975:'\uE6D6',37976:'\uE6D7',37977:'\uE6D8',37978:'\uE6D9',37979:'\uE6DA',37980:'\uE6DB',37981:'\uE6DC',37982:'\uE6DD',37983:'\uE6DE',37984:'\uE6DF',37985:'\uE6E0',37986:'\uE6E1',37987:'\uE6E2',37988:'\uE6E3',37989:'\uE6E4',37990:'\uE6E5',37991:'\uE6E6',37992:'\uE6E7',37993:'\uE6E8',37994:'\uE6E9',37995:'\uE6EA',37996:'\uE6EB',37997:'\uE6EC',37998:'\uE6ED',37999:'\uE6EE',38000:'\uE6EF',38001:'\uE6F0',38002:'\uE6F1',38003:'\uE6F2',38004:'\uE6F3',38005:'\uE6F4',38006:'\uE6F5',38007:'\uE6F6',38008:'\uE6F7',38009:'\uE6F8',38010:'\uE6F9',38011:'\uE6FA',38012:'\uE6FB',38013:'\uE6FC',38014:'\uE6FD',38049:'\uE6FE',38050:'\uE6FF',38051:'\uE700',38052:'\uE701',38053:'\uE702',38054:'\uE703',38055:'\uE704',38056:'\uE705',38057:'\uE706',38058:'\uE707',38059:'\uE708',38060:'\uE709',38061:'\uE70A',38062:'\uE70B',38063:'\uE70C',38064:'\uE70D',38065:'\uE70E',38066:'\uE70F',38067:'\uE710',38068:'\uE711',38069:'\uE712',38070:'\uE713',38071:'\uE714',38072:'\uE715',38073:'\uE716',38074:'\uE717',38075:'\uE718',38076:'\uE719',38077:'\uE71A',38078:'\uE71B',38079:'\uE71C',38080:'\uE71D',38081:'\uE71E',38082:'\uE71F',38083:'\uE720',38084:'\uE721',38085:'\uE722',38086:'\uE723',38087:'\uE724',38088:'\uE725',38089:'\uE726',38090:'\uE727',38091:'\uE728',38092:'\uE729',38093:'\uE72A',38094:'\uE72B',38095:'\uE72C',38096:'\uE72D',38097:'\uE72E',38098:'\uE72F',38099:'\uE730',38100:'\uE731',38101:'\uE732',38102:'\uE733',38103:'\uE734',38104:'\uE735',38105:'\uE736',38106:'\uE737',38107:'\uE738',38108:'\uE739',38109:'\uE73A',38110:'\uE73B',38111:'\uE73C',38112:'\uE73D',38113:'\uE73E',38114:'\uE73F',38115:'\uE740',38116:'\uE741',38117:'\uE742',38118:'\uE743',38119:'\uE744',38120:'\uE745',38121:'\uE746',38122:'\uE747',38123:'\uE748',38124:'\uE749',38125:'\uE74A',38126:'\uE74B',38127:'\uE74C',38128:'\uE74D',38129:'\uE74E',38130:'\uE74F',38131:'\uE750',38132:'\uE751',38133:'\uE752',38134:'\uE753',38135:'\uE754',38136:'\uE755',38137:'\uE756',38138:'\uE757',38139:'\uE758',38140:'\uE759',38141:'\uE75A',38142:'\uE75B',38208:'\uE75C',38209:'\uE75D',38210:'\uE75E',38211:'\uE75F',38212:'\uE760',38213:'\uE761',38214:'\uE762',38215:'\uE763',38216:'\uE764',38217:'\uE765',38218:'\uE766',38219:'\uE767',38220:'\uE768',38221:'\uE769',38222:'\uE76A',38223:'\uE76B',38224:'\uE76C',38225:'\uE76D',38226:'\uE76E',38227:'\uE76F',38228:'\uE770',38229:'\uE771',38230:'\uE772',38231:'\uE773',38232:'\uE774',38233:'\uE775',38234:'\uE776',38235:'\uE777',38236:'\uE778',38237:'\uE779',38238:'\uE77A',38239:'\uE77B',38240:'\uE77C',38241:'\uE77D',38242:'\uE77E',38243:'\uE77F',38244:'\uE780',38245:'\uE781',38246:'\uE782',38247:'\uE783',38248:'\uE784',38249:'\uE785',38250:'\uE786',38251:'\uE787',38252:'\uE788',38253:'\uE789',38254:'\uE78A',38255:'\uE78B',38256:'\uE78C',38257:'\uE78D',38258:'\uE78E',38259:'\uE78F',38260:'\uE790',38261:'\uE791',38262:'\uE792',38263:'\uE793',38264:'\uE794',38265:'\uE795',38266:'\uE796',38267:'\uE797',38268:'\uE798',38269:'\uE799',38270:'\uE79A',38305:'\uE79B',38306:'\uE79C',38307:'\uE79D',38308:'\uE79E',38309:'\uE79F',38310:'\uE7A0',38311:'\uE7A1',38312:'\uE7A2',38313:'\uE7A3',38314:'\uE7A4',38315:'\uE7A5',38316:'\uE7A6',38317:'\uE7A7',38318:'\uE7A8',38319:'\uE7A9',38320:'\uE7AA',38321:'\uE7AB',38322:'\uE7AC',38323:'\uE7AD',38324:'\uE7AE',38325:'\uE7AF',38326:'\uE7B0',38327:'\uE7B1',38328:'\uE7B2',38329:'\uE7B3',38330:'\uE7B4',38331:'\uE7B5',38332:'\uE7B6',38333:'\uE7B7',38334:'\uE7B8',38335:'\uE7B9',38336:'\uE7BA',38337:'\uE7BB',38338:'\uE7BC',38339:'\uE7BD',38340:'\uE7BE',38341:'\uE7BF',38342:'\uE7C0',38343:'\uE7C1',38344:'\uE7C2',38345:'\uE7C3',38346:'\uE7C4',38347:'\uE7C5',38348:'\uE7C6',38349:'\uE7C7',38350:'\uE7C8',38351:'\uE7C9',38352:'\uE7CA',38353:'\uE7CB',38354:'\uE7CC',38355:'\uE7CD',38356:'\uE7CE',38357:'\uE7CF',38358:'\uE7D0',38359:'\uE7D1',38360:'\uE7D2',38361:'\uE7D3',38362:'\uE7D4',38363:'\uE7D5',38364:'\uE7D6',38365:'\uE7D7',38366:'\uE7D8',38367:'\uE7D9',38368:'\uE7DA',38369:'\uE7DB',38370:'\uE7DC',38371:'\uE7DD',38372:'\uE7DE',38373:'\uE7DF',38374:'\uE7E0',38375:'\uE7E1',38376:'\uE7E2',38377:'\uE7E3',38378:'\uE7E4',38379:'\uE7E5',38380:'\uE7E6',38381:'\uE7E7',38382:'\uE7E8',38383:'\uE7E9',38384:'\uE7EA',38385:'\uE7EB',38386:'\uE7EC',38387:'\uE7ED',38388:'\uE7EE',38389:'\uE7EF',38390:'\uE7F0',38391:'\uE7F1',38392:'\uE7F2',38393:'\uE7F3',38394:'\uE7F4',38395:'\uE7F5',38396:'\uE7F6',38397:'\uE7F7',38398:'\uE7F8',38464:'\uE7F9',38465:'\uE7FA',38466:'\uE7FB',38467:'\uE7FC',38468:'\uE7FD',38469:'\uE7FE',38470:'\uE7FF',38471:'\uE800',38472:'\uE801',38473:'\uE802',38474:'\uE803',38475:'\uE804',38476:'\uE805',38477:'\uE806',38478:'\uE807',38479:'\uE808',38480:'\uE809',38481:'\uE80A',38482:'\uE80B',38483:'\uE80C',38484:'\uE80D',38485:'\uE80E',38486:'\uE80F',38487:'\uE810',38488:'\uE811',38489:'\uE812',38490:'\uE813',38491:'\uE814',38492:'\uE815',38493:'\uE816',38494:'\uE817',38495:'\uE818',38496:'\uE819',38497:'\uE81A',38498:'\uE81B',38499:'\uE81C',38500:'\uE81D',38501:'\uE81E',38502:'\uE81F',38503:'\uE820',38504:'\uE821',38505:'\uE822',38506:'\uE823',38507:'\uE824',38508:'\uE825',38509:'\uE826',38510:'\uE827',38511:'\uE828',38512:'\uE829',38513:'\uE82A',38514:'\uE82B',38515:'\uE82C',38516:'\uE82D',38517:'\uE82E',38518:'\uE82F',38519:'\uE830',38520:'\uE831',38521:'\uE832',38522:'\uE833',38523:'\uE834',38524:'\uE835',38525:'\uE836',38526:'\uE837',38561:'\uE838',38562:'\uE839',38563:'\uE83A',38564:'\uE83B',38565:'\uE83C',38566:'\uE83D',38567:'\uE83E',38568:'\uE83F',38569:'\uE840',38570:'\uE841',38571:'\uE842',38572:'\uE843',38573:'\uE844',38574:'\uE845',38575:'\uE846',38576:'\uE847',38577:'\uE848',38578:'\uE849',38579:'\uE84A',38580:'\uE84B',38581:'\uE84C',38582:'\uE84D',38583:'\uE84E',38584:'\uE84F',38585:'\uE850',38586:'\uE851',38587:'\uE852',38588:'\uE853',38589:'\uE854',38590:'\uE855',38591:'\uE856',38592:'\uE857',38593:'\uE858',38594:'\uE859',38595:'\uE85A',38596:'\uE85B',38597:'\uE85C',38598:'\uE85D',38599:'\uE85E',38600:'\uE85F',38601:'\uE860',38602:'\uE861',38603:'\uE862',38604:'\uE863',38605:'\uE864',38606:'\uE865',38607:'\uE866',38608:'\uE867',38609:'\uE868',38610:'\uE869',38611:'\uE86A',38612:'\uE86B',38613:'\uE86C',38614:'\uE86D',38615:'\uE86E',38616:'\uE86F',38617:'\uE870',38618:'\uE871',38619:'\uE872',38620:'\uE873',38621:'\uE874',38622:'\uE875',38623:'\uE876',38624:'\uE877',38625:'\uE878',38626:'\uE879',38627:'\uE87A',38628:'\uE87B',38629:'\uE87C',38630:'\uE87D',38631:'\uE87E',38632:'\uE87F',38633:'\uE880',38634:'\uE881',38635:'\uE882',38636:'\uE883',38637:'\uE884',38638:'\uE885',38639:'\uE886',38640:'\uE887',38641:'\uE888',38642:'\uE889',38643:'\uE88A',38644:'\uE88B',38645:'\uE88C',38646:'\uE88D',38647:'\uE88E',38648:'\uE88F',38649:'\uE890',38650:'\uE891',38651:'\uE892',38652:'\uE893',38653:'\uE894',38654:'\uE895',38720:'\uE896',38721:'\uE897',38722:'\uE898',38723:'\uE899',38724:'\uE89A',38725:'\uE89B',38726:'\uE89C',38727:'\uE89D',38728:'\uE89E',38729:'\uE89F',38730:'\uE8A0',38731:'\uE8A1',38732:'\uE8A2',38733:'\uE8A3',38734:'\uE8A4',38735:'\uE8A5',38736:'\uE8A6',38737:'\uE8A7',38738:'\uE8A8',38739:'\uE8A9',38740:'\uE8AA',38741:'\uE8AB',38742:'\uE8AC',38743:'\uE8AD',38744:'\uE8AE',38745:'\uE8AF',38746:'\uE8B0',38747:'\uE8B1',38748:'\uE8B2',38749:'\uE8B3',38750:'\uE8B4',38751:'\uE8B5',38752:'\uE8B6',38753:'\uE8B7',38754:'\uE8B8',38755:'\uE8B9',38756:'\uE8BA',38757:'\uE8BB',38758:'\uE8BC',38759:'\uE8BD',38760:'\uE8BE',38761:'\uE8BF',38762:'\uE8C0',38763:'\uE8C1',38764:'\uE8C2',38765:'\uE8C3',38766:'\uE8C4',38767:'\uE8C5',38768:'\uE8C6',38769:'\uE8C7',38770:'\uE8C8',38771:'\uE8C9',38772:'\uE8CA',38773:'\uE8CB',38774:'\uE8CC',38775:'\uE8CD',38776:'\uE8CE',38777:'\uE8CF',38778:'\uE8D0',38779:'\uE8D1',38780:'\uE8D2',38781:'\uE8D3',38782:'\uE8D4',38817:'\uE8D5',38818:'\uE8D6',38819:'\uE8D7',38820:'\uE8D8',38821:'\uE8D9',38822:'\uE8DA',38823:'\uE8DB',38824:'\uE8DC',38825:'\uE8DD',38826:'\uE8DE',38827:'\uE8DF',38828:'\uE8E0',38829:'\uE8E1',38830:'\uE8E2',38831:'\uE8E3',38832:'\uE8E4',38833:'\uE8E5',38834:'\uE8E6',38835:'\uE8E7',38836:'\uE8E8',38837:'\uE8E9',38838:'\uE8EA',38839:'\uE8EB',38840:'\uE8EC',38841:'\uE8ED',38842:'\uE8EE',38843:'\uE8EF',38844:'\uE8F0',38845:'\uE8F1',38846:'\uE8F2',38847:'\uE8F3',38848:'\uE8F4',38849:'\uE8F5',38850:'\uE8F6',38851:'\uE8F7',38852:'\uE8F8',38853:'\uE8F9',38854:'\uE8FA',38855:'\uE8FB',38856:'\uE8FC',38857:'\uE8FD',38858:'\uE8FE',38859:'\uE8FF',38860:'\uE900',38861:'\uE901',38862:'\uE902',38863:'\uE903',38864:'\uE904',38865:'\uE905',38866:'\uE906',38867:'\uE907',38868:'\uE908',38869:'\uE909',38870:'\uE90A',38871:'\uE90B',38872:'\uE90C',38873:'\uE90D',38874:'\uE90E',38875:'\uE90F',38876:'\uE910',38877:'\uE911',38878:'\uE912',38879:'\uE913',38880:'\uE914',38881:'\uE915',38882:'\uE916',38883:'\uE917',38884:'\uE918',38885:'\uE919',38886:'\uE91A',38887:'\uE91B',38888:'\uE91C',38889:'\uE91D',38890:'\uE91E',38891:'\uE91F',38892:'\uE920',38893:'\uE921',38894:'\uE922',38895:'\uE923',38896:'\uE924',38897:'\uE925',38898:'\uE926',38899:'\uE927',38900:'\uE928',38901:'\uE929',38902:'\uE92A',38903:'\uE92B',38904:'\uE92C',38905:'\uE92D',38906:'\uE92E',38907:'\uE92F',38908:'\uE930',38909:'\uE931',38910:'\uE932',38976:'\uE933',38977:'\uE934',38978:'\uE935',38979:'\uE936',38980:'\uE937',38981:'\uE938',38982:'\uE939',38983:'\uE93A',38984:'\uE93B',38985:'\uE93C',38986:'\uE93D',38987:'\uE93E',38988:'\uE93F',38989:'\uE940',38990:'\uE941',38991:'\uE942',38992:'\uE943',38993:'\uE944',38994:'\uE945',38995:'\uE946',38996:'\uE947',38997:'\uE948',38998:'\uE949',38999:'\uE94A',39000:'\uE94B',39001:'\uE94C',39002:'\uE94D',39003:'\uE94E',39004:'\uE94F',39005:'\uE950',39006:'\uE951',39007:'\uE952',39008:'\uE953',39009:'\uE954',39010:'\uE955',39011:'\uE956',39012:'\uE957',39013:'\uE958',39014:'\uE959',39015:'\uE95A',39016:'\uE95B',39017:'\uE95C',39018:'\uE95D',39019:'\uE95E',39020:'\uE95F',39021:'\uE960',39022:'\uE961',39023:'\uE962',39024:'\uE963',39025:'\uE964',39026:'\uE965',39027:'\uE966',39028:'\uE967',39029:'\uE968',39030:'\uE969',39031:'\uE96A',39032:'\uE96B',39033:'\uE96C',39034:'\uE96D',39035:'\uE96E',39036:'\uE96F',39037:'\uE970',39038:'\uE971',39073:'\uE972',39074:'\uE973',39075:'\uE974',39076:'\uE975',39077:'\uE976',39078:'\uE977',39079:'\uE978',39080:'\uE979',39081:'\uE97A',39082:'\uE97B',39083:'\uE97C',39084:'\uE97D',39085:'\uE97E',39086:'\uE97F',39087:'\uE980',39088:'\uE981',39089:'\uE982',39090:'\uE983',39091:'\uE984',39092:'\uE985',39093:'\uE986',39094:'\uE987',39095:'\uE988',39096:'\uE989',39097:'\uE98A',39098:'\uE98B',39099:'\uE98C',39100:'\uE98D',39101:'\uE98E',39102:'\uE98F',39103:'\uE990',39104:'\uE991',39105:'\uE992',39106:'\uE993',39107:'\uE994',39108:'\uE995',39109:'\uE996',39110:'\uE997',39111:'\uE998',39112:'\uE999',39113:'\uE99A',39114:'\uE99B',39115:'\uE99C',39116:'\uE99D',39117:'\uE99E',39118:'\uE99F',39119:'\uE9A0',39120:'\uE9A1',39121:'\uE9A2',39122:'\uE9A3',39123:'\uE9A4',39124:'\uE9A5',39125:'\uE9A6',39126:'\uE9A7',39127:'\uE9A8',39128:'\uE9A9',39129:'\uE9AA',39130:'\uE9AB',39131:'\uE9AC',39132:'\uE9AD',39133:'\uE9AE',39134:'\uE9AF',39135:'\uE9B0',39136:'\uE9B1',39137:'\uE9B2',39138:'\uE9B3',39139:'\uE9B4',39140:'\uE9B5',39141:'\uE9B6',39142:'\uE9B7',39143:'\uE9B8',39144:'\uE9B9',39145:'\uE9BA',39146:'\uE9BB',39147:'\uE9BC',39148:'\uE9BD',39149:'\uE9BE',39150:'\uE9BF',39151:'\uE9C0',39152:'\uE9C1',39153:'\uE9C2',39154:'\uE9C3',39155:'\uE9C4',39156:'\uE9C5',39157:'\uE9C6',39158:'\uE9C7',39159:'\uE9C8',39160:'\uE9C9',39161:'\uE9CA',39162:'\uE9CB',39163:'\uE9CC',39164:'\uE9CD',39165:'\uE9CE',39166:'\uE9CF',39232:'\uE9D0',39233:'\uE9D1',39234:'\uE9D2',39235:'\uE9D3',39236:'\uE9D4',39237:'\uE9D5',39238:'\uE9D6',39239:'\uE9D7',39240:'\uE9D8',39241:'\uE9D9',39242:'\uE9DA',39243:'\uE9DB',39244:'\uE9DC',39245:'\uE9DD',39246:'\uE9DE',39247:'\uE9DF',39248:'\uE9E0',39249:'\uE9E1',39250:'\uE9E2',39251:'\uE9E3',39252:'\uE9E4',39253:'\uE9E5',39254:'\uE9E6',39255:'\uE9E7',39256:'\uE9E8',39257:'\uE9E9',39258:'\uE9EA',39259:'\uE9EB',39260:'\uE9EC',39261:'\uE9ED',39262:'\uE9EE',39263:'\uE9EF',39264:'\uE9F0',39265:'\uE9F1',39266:'\uE9F2',39267:'\uE9F3',39268:'\uE9F4',39269:'\uE9F5',39270:'\uE9F6',39271:'\uE9F7',39272:'\uE9F8',39273:'\uE9F9',39274:'\uE9FA',39275:'\uE9FB',39276:'\uE9FC',39277:'\uE9FD',39278:'\uE9FE',39279:'\uE9FF',39280:'\uEA00',39281:'\uEA01',39282:'\uEA02',39283:'\uEA03',39284:'\uEA04',39285:'\uEA05',39286:'\uEA06',39287:'\uEA07',39288:'\uEA08',39289:'\uEA09',39290:'\uEA0A',39291:'\uEA0B',39292:'\uEA0C',39293:'\uEA0D',39294:'\uEA0E',39329:'\uEA0F',39330:'\uEA10',39331:'\uEA11',39332:'\uEA12',39333:'\uEA13',39334:'\uEA14',39335:'\uEA15',39336:'\uEA16',39337:'\uEA17',39338:'\uEA18',39339:'\uEA19',39340:'\uEA1A',39341:'\uEA1B',39342:'\uEA1C',39343:'\uEA1D',39344:'\uEA1E',39345:'\uEA1F',39346:'\uEA20',39347:'\uEA21',39348:'\uEA22',39349:'\uEA23',39350:'\uEA24',39351:'\uEA25',39352:'\uEA26',39353:'\uEA27',39354:'\uEA28',39355:'\uEA29',39356:'\uEA2A',39357:'\uEA2B',39358:'\uEA2C',39359:'\uEA2D',39360:'\uEA2E',39361:'\uEA2F',39362:'\uEA30',39363:'\uEA31',39364:'\uEA32',39365:'\uEA33',39366:'\uEA34',39367:'\uEA35',39368:'\uEA36',39369:'\uEA37',39370:'\uEA38',39371:'\uEA39',39372:'\uEA3A',39373:'\uEA3B',39374:'\uEA3C',39375:'\uEA3D',39376:'\uEA3E',39377:'\uEA3F',39378:'\uEA40',39379:'\uEA41',39380:'\uEA42',39381:'\uEA43',39382:'\uEA44',39383:'\uEA45',39384:'\uEA46',39385:'\uEA47',39386:'\uEA48',39387:'\uEA49',39388:'\uEA4A',39389:'\uEA4B',39390:'\uEA4C',39391:'\uEA4D',39392:'\uEA4E',39393:'\uEA4F',39394:'\uEA50',39395:'\uEA51',39396:'\uEA52',39397:'\uEA53',39398:'\uEA54',39399:'\uEA55',39400:'\uEA56',39401:'\uEA57',39402:'\uEA58',39403:'\uEA59',39404:'\uEA5A',39405:'\uEA5B',39406:'\uEA5C',39407:'\uEA5D',39408:'\uEA5E',39409:'\uEA5F',39410:'\uEA60',39411:'\uEA61',39412:'\uEA62',39413:'\uEA63',39414:'\uEA64',39415:'\uEA65',39416:'\uEA66',39417:'\uEA67',39418:'\uEA68',39419:'\uEA69',39420:'\uEA6A',39421:'\uEA6B',39422:'\uEA6C',39488:'\uEA6D',39489:'\uEA6E',39490:'\uEA6F',39491:'\uEA70',39492:'\uEA71',39493:'\uEA72',39494:'\uEA73',39495:'\uEA74',39496:'\uEA75',39497:'\uEA76',39498:'\uEA77',39499:'\uEA78',39500:'\uEA79',39501:'\uEA7A',39502:'\uEA7B',39503:'\uEA7C',39504:'\uEA7D',39505:'\uEA7E',39506:'\uEA7F',39507:'\uEA80',39508:'\uEA81',39509:'\uEA82',39510:'\uEA83',39511:'\uEA84',39512:'\uEA85',39513:'\uEA86',39514:'\uEA87',39515:'\uEA88',39516:'\uEA89',39517:'\uEA8A',39518:'\uEA8B',39519:'\uEA8C',39520:'\uEA8D',39521:'\uEA8E',39522:'\uEA8F',39523:'\uEA90',39524:'\uEA91',39525:'\uEA92',39526:'\uEA93',39527:'\uEA94',39528:'\uEA95',39529:'\uEA96',39530:'\uEA97',39531:'\uEA98',39532:'\uEA99',39533:'\uEA9A',39534:'\uEA9B',39535:'\uEA9C',39536:'\uEA9D',39537:'\uEA9E',39538:'\uEA9F',39539:'\uEAA0',39540:'\uEAA1',39541:'\uEAA2',39542:'\uEAA3',39543:'\uEAA4',39544:'\uEAA5',39545:'\uEAA6',39546:'\uEAA7',39547:'\uEAA8',39548:'\uEAA9',39549:'\uEAAA',39550:'\uEAAB',39585:'\uEAAC',39586:'\uEAAD',39587:'\uEAAE',39588:'\uEAAF',39589:'\uEAB0',39590:'\uEAB1',39591:'\uEAB2',39592:'\uEAB3',39593:'\uEAB4',39594:'\uEAB5',39595:'\uEAB6',39596:'\uEAB7',39597:'\uEAB8',39598:'\uEAB9',39599:'\uEABA',39600:'\uEABB',39601:'\uEABC',39602:'\uEABD',39603:'\uEABE',39604:'\uEABF',39605:'\uEAC0',39606:'\uEAC1',39607:'\uEAC2',39608:'\uEAC3',39609:'\uEAC4',39610:'\uEAC5',39611:'\uEAC6',39612:'\uEAC7',39613:'\uEAC8',39614:'\uEAC9',39615:'\uEACA',39616:'\uEACB',39617:'\uEACC',39618:'\uEACD',39619:'\uEACE',39620:'\uEACF',39621:'\uEAD0',39622:'\uEAD1',39623:'\uEAD2',39624:'\uEAD3',39625:'\uEAD4',39626:'\uEAD5',39627:'\uEAD6',39628:'\uEAD7',39629:'\uEAD8',39630:'\uEAD9',39631:'\uEADA',39632:'\uEADB',39633:'\uEADC',39634:'\uEADD',39635:'\uEADE',39636:'\uEADF',39637:'\uEAE0',39638:'\uEAE1',39639:'\uEAE2',39640:'\uEAE3',39641:'\uEAE4',39642:'\uEAE5',39643:'\uEAE6',39644:'\uEAE7',39645:'\uEAE8',39646:'\uEAE9',39647:'\uEAEA',39648:'\uEAEB',39649:'\uEAEC',39650:'\uEAED',39651:'\uEAEE',39652:'\uEAEF',39653:'\uEAF0',39654:'\uEAF1',39655:'\uEAF2',39656:'\uEAF3',39657:'\uEAF4',39658:'\uEAF5',39659:'\uEAF6',39660:'\uEAF7',39661:'\uEAF8',39662:'\uEAF9',39663:'\uEAFA',39664:'\uEAFB',39665:'\uEAFC',39666:'\uEAFD',39667:'\uEAFE',39668:'\uEAFF',39669:'\uEB00',39670:'\uEB01',39671:'\uEB02',39672:'\uEB03',39673:'\uEB04',39674:'\uEB05',39675:'\uEB06',39676:'\uEB07',39677:'\uEB08',39678:'\uEB09',39744:'\uEB0A',39745:'\uEB0B',39746:'\uEB0C',39747:'\uEB0D',39748:'\uEB0E',39749:'\uEB0F',39750:'\uEB10',39751:'\uEB11',39752:'\uEB12',39753:'\uEB13',39754:'\uEB14',39755:'\uEB15',39756:'\uEB16',39757:'\uEB17',39758:'\uEB18',39759:'\uEB19',39760:'\uEB1A',39761:'\uEB1B',39762:'\uEB1C',39763:'\uEB1D',39764:'\uEB1E',39765:'\uEB1F',39766:'\uEB20',39767:'\uEB21',39768:'\uEB22',39769:'\uEB23',39770:'\uEB24',39771:'\uEB25',39772:'\uEB26',39773:'\uEB27',39774:'\uEB28',39775:'\uEB29',39776:'\uEB2A',39777:'\uEB2B',39778:'\uEB2C',39779:'\uEB2D',39780:'\uEB2E',39781:'\uEB2F',39782:'\uEB30',39783:'\uEB31',39784:'\uEB32',39785:'\uEB33',39786:'\uEB34',39787:'\uEB35',39788:'\uEB36',39789:'\uEB37',39790:'\uEB38',39791:'\uEB39',39792:'\uEB3A',39793:'\uEB3B',39794:'\uEB3C',39795:'\uEB3D',39796:'\uEB3E',39797:'\uEB3F',39798:'\uEB40',39799:'\uEB41',39800:'\uEB42',39801:'\uEB43',39802:'\uEB44',39803:'\uEB45',39804:'\uEB46',39805:'\uEB47',39806:'\uEB48',39841:'\uEB49',39842:'\uEB4A',39843:'\uEB4B',39844:'\uEB4C',39845:'\uEB4D',39846:'\uEB4E',39847:'\uEB4F',39848:'\uEB50',39849:'\uEB51',39850:'\uEB52',39851:'\uEB53',39852:'\uEB54',39853:'\uEB55',39854:'\uEB56',39855:'\uEB57',39856:'\uEB58',39857:'\uEB59',39858:'\uEB5A',39859:'\uEB5B',39860:'\uEB5C',39861:'\uEB5D',39862:'\uEB5E',39863:'\uEB5F',39864:'\uEB60',39865:'\uEB61',39866:'\uEB62',39867:'\uEB63',39868:'\uEB64',39869:'\uEB65',39870:'\uEB66',39871:'\uEB67',39872:'\uEB68',39873:'\uEB69',39874:'\uEB6A',39875:'\uEB6B',39876:'\uEB6C',39877:'\uEB6D',39878:'\uEB6E',39879:'\uEB6F',39880:'\uEB70',39881:'\uEB71',39882:'\uEB72',39883:'\uEB73',39884:'\uEB74',39885:'\uEB75',39886:'\uEB76',39887:'\uEB77',39888:'\uEB78',39889:'\uEB79',39890:'\uEB7A',39891:'\uEB7B',39892:'\uEB7C',39893:'\uEB7D',39894:'\uEB7E',39895:'\uEB7F',39896:'\uEB80',39897:'\uEB81',39898:'\uEB82',39899:'\uEB83',39900:'\uEB84',39901:'\uEB85',39902:'\uEB86',39903:'\uEB87',39904:'\uEB88',39905:'\uEB89',39906:'\uEB8A',39907:'\uEB8B',39908:'\uEB8C',39909:'\uEB8D',39910:'\uEB8E',39911:'\uEB8F',39912:'\uEB90',39913:'\uEB91',39914:'\uEB92',39915:'\uEB93',39916:'\uEB94',39917:'\uEB95',39918:'\uEB96',39919:'\uEB97',39920:'\uEB98',39921:'\uEB99',39922:'\uEB9A',39923:'\uEB9B',39924:'\uEB9C',39925:'\uEB9D',39926:'\uEB9E',39927:'\uEB9F',39928:'\uEBA0',39929:'\uEBA1',39930:'\uEBA2',39931:'\uEBA3',39932:'\uEBA4',39933:'\uEBA5',39934:'\uEBA6',40000:'\uEBA7',40001:'\uEBA8',40002:'\uEBA9',40003:'\uEBAA',40004:'\uEBAB',40005:'\uEBAC',40006:'\uEBAD',40007:'\uEBAE',40008:'\uEBAF',40009:'\uEBB0',40010:'\uEBB1',40011:'\uEBB2',40012:'\uEBB3',40013:'\uEBB4',40014:'\uEBB5',40015:'\uEBB6',40016:'\uEBB7',40017:'\uEBB8',40018:'\uEBB9',40019:'\uEBBA',40020:'\uEBBB',40021:'\uEBBC',40022:'\uEBBD',40023:'\uEBBE',40024:'\uEBBF',40025:'\uEBC0',40026:'\uEBC1',40027:'\uEBC2',40028:'\uEBC3',40029:'\uEBC4',40030:'\uEBC5',40031:'\uEBC6',40032:'\uEBC7',40033:'\uEBC8',40034:'\uEBC9',40035:'\uEBCA',40036:'\uEBCB',40037:'\uEBCC',40038:'\uEBCD',40039:'\uEBCE',40040:'\uEBCF',40041:'\uEBD0',40042:'\uEBD1',40043:'\uEBD2',40044:'\uEBD3',40045:'\uEBD4',40046:'\uEBD5',40047:'\uEBD6',40048:'\uEBD7',40049:'\uEBD8',40050:'\uEBD9',40051:'\uEBDA',40052:'\uEBDB',40053:'\uEBDC',40054:'\uEBDD',40055:'\uEBDE',40056:'\uEBDF',40057:'\uEBE0',40058:'\uEBE1',40059:'\uEBE2',40060:'\uEBE3',40061:'\uEBE4',40062:'\uEBE5',40097:'\uEBE6',40098:'\uEBE7',40099:'\uEBE8',40100:'\uEBE9',40101:'\uEBEA',40102:'\uEBEB',40103:'\uEBEC',40104:'\uEBED',40105:'\uEBEE',40106:'\uEBEF',40107:'\uEBF0',40108:'\uEBF1',40109:'\uEBF2',40110:'\uEBF3',40111:'\uEBF4',40112:'\uEBF5',40113:'\uEBF6',40114:'\uEBF7',40115:'\uEBF8',40116:'\uEBF9',40117:'\uEBFA',40118:'\uEBFB',40119:'\uEBFC',40120:'\uEBFD',40121:'\uEBFE',40122:'\uEBFF',40123:'\uEC00',40124:'\uEC01',40125:'\uEC02',40126:'\uEC03',40127:'\uEC04',40128:'\uEC05',40129:'\uEC06',40130:'\uEC07',40131:'\uEC08',40132:'\uEC09',40133:'\uEC0A',40134:'\uEC0B',40135:'\uEC0C',40136:'\uEC0D',40137:'\uEC0E',40138:'\uEC0F',40139:'\uEC10',40140:'\uEC11',40141:'\uEC12',40142:'\uEC13',40143:'\uEC14',40144:'\uEC15',40145:'\uEC16',40146:'\uEC17',40147:'\uEC18',40148:'\uEC19',40149:'\uEC1A',40150:'\uEC1B',40151:'\uEC1C',40152:'\uEC1D',40153:'\uEC1E',40154:'\uEC1F',40155:'\uEC20',40156:'\uEC21',40157:'\uEC22',40158:'\uEC23',40159:'\uEC24',40160:'\uEC25',40161:'\uEC26',40162:'\uEC27',40163:'\uEC28',40164:'\uEC29',40165:'\uEC2A',40166:'\uEC2B',40167:'\uEC2C',40168:'\uEC2D',40169:'\uEC2E',40170:'\uEC2F',40171:'\uEC30',40172:'\uEC31',40173:'\uEC32',40174:'\uEC33',40175:'\uEC34',40176:'\uEC35',40177:'\uEC36',40178:'\uEC37',40179:'\uEC38',40180:'\uEC39',40181:'\uEC3A',40182:'\uEC3B',40183:'\uEC3C',40184:'\uEC3D',40185:'\uEC3E',40186:'\uEC3F',40187:'\uEC40',40188:'\uEC41',40189:'\uEC42',40190:'\uEC43',40256:'\uEC44',40257:'\uEC45',40258:'\uEC46',40259:'\uEC47',40260:'\uEC48',40261:'\uEC49',40262:'\uEC4A',40263:'\uEC4B',40264:'\uEC4C',40265:'\uEC4D',40266:'\uEC4E',40267:'\uEC4F',40268:'\uEC50',40269:'\uEC51',40270:'\uEC52',40271:'\uEC53',40272:'\uEC54',40273:'\uEC55',40274:'\uEC56',40275:'\uEC57',40276:'\uEC58',40277:'\uEC59',40278:'\uEC5A',40279:'\uEC5B',40280:'\uEC5C',40281:'\uEC5D',40282:'\uEC5E',40283:'\uEC5F',40284:'\uEC60',40285:'\uEC61',40286:'\uEC62',40287:'\uEC63',40288:'\uEC64',40289:'\uEC65',40290:'\uEC66',40291:'\uEC67',40292:'\uEC68',40293:'\uEC69',40294:'\uEC6A',40295:'\uEC6B',40296:'\uEC6C',40297:'\uEC6D',40298:'\uEC6E',40299:'\uEC6F',40300:'\uEC70',40301:'\uEC71',40302:'\uEC72',40303:'\uEC73',40304:'\uEC74',40305:'\uEC75',40306:'\uEC76',40307:'\uEC77',40308:'\uEC78',40309:'\uEC79',40310:'\uEC7A',40311:'\uEC7B',40312:'\uEC7C',40313:'\uEC7D',40314:'\uEC7E',40315:'\uEC7F',40316:'\uEC80',40317:'\uEC81',40318:'\uEC82',40353:'\uEC83',40354:'\uEC84',40355:'\uEC85',40356:'\uEC86',40357:'\uEC87',40358:'\uEC88',40359:'\uEC89',40360:'\uEC8A',40361:'\uEC8B',40362:'\uEC8C',40363:'\uEC8D',40364:'\uEC8E',40365:'\uEC8F',40366:'\uEC90',40367:'\uEC91',40368:'\uEC92',40369:'\uEC93',40370:'\uEC94',40371:'\uEC95',40372:'\uEC96',40373:'\uEC97',40374:'\uEC98',40375:'\uEC99',40376:'\uEC9A',40377:'\uEC9B',40378:'\uEC9C',40379:'\uEC9D',40380:'\uEC9E',40381:'\uEC9F',40382:'\uECA0',40383:'\uECA1',40384:'\uECA2',40385:'\uECA3',40386:'\uECA4',40387:'\uECA5',40388:'\uECA6',40389:'\uECA7',40390:'\uECA8',40391:'\uECA9',40392:'\uECAA',40393:'\uECAB',40394:'\uECAC',40395:'\uECAD',40396:'\uECAE',40397:'\uECAF',40398:'\uECB0',40399:'\uECB1',40400:'\uECB2',40401:'\uECB3',40402:'\uECB4',40403:'\uECB5',40404:'\uECB6',40405:'\uECB7',40406:'\uECB8',40407:'\uECB9',40408:'\uECBA',40409:'\uECBB',40410:'\uECBC',40411:'\uECBD',40412:'\uECBE',40413:'\uECBF',40414:'\uECC0',40415:'\uECC1',40416:'\uECC2',40417:'\uECC3',40418:'\uECC4',40419:'\uECC5',40420:'\uECC6',40421:'\uECC7',40422:'\uECC8',40423:'\uECC9',40424:'\uECCA',40425:'\uECCB',40426:'\uECCC',40427:'\uECCD',40428:'\uECCE',40429:'\uECCF',40430:'\uECD0',40431:'\uECD1',40432:'\uECD2',40433:'\uECD3',40434:'\uECD4',40435:'\uECD5',40436:'\uECD6',40437:'\uECD7',40438:'\uECD8',40439:'\uECD9',40440:'\uECDA',40441:'\uECDB',40442:'\uECDC',40443:'\uECDD',40444:'\uECDE',40445:'\uECDF',40446:'\uECE0',40512:'\uECE1',40513:'\uECE2',40514:'\uECE3',40515:'\uECE4',40516:'\uECE5',40517:'\uECE6',40518:'\uECE7',40519:'\uECE8',40520:'\uECE9',40521:'\uECEA',40522:'\uECEB',40523:'\uECEC',40524:'\uECED',40525:'\uECEE',40526:'\uECEF',40527:'\uECF0',40528:'\uECF1',40529:'\uECF2',40530:'\uECF3',40531:'\uECF4',40532:'\uECF5',40533:'\uECF6',40534:'\uECF7',40535:'\uECF8',40536:'\uECF9',40537:'\uECFA',40538:'\uECFB',40539:'\uECFC',40540:'\uECFD',40541:'\uECFE',40542:'\uECFF',40543:'\uED00',40544:'\uED01',40545:'\uED02',40546:'\uED03',40547:'\uED04',40548:'\uED05',40549:'\uED06',40550:'\uED07',40551:'\uED08',40552:'\uED09',40553:'\uED0A',40554:'\uED0B',40555:'\uED0C',40556:'\uED0D',40557:'\uED0E',40558:'\uED0F',40559:'\uED10',40560:'\uED11',40561:'\uED12',40562:'\uED13',40563:'\uED14',40564:'\uED15',40565:'\uED16',40566:'\uED17',40567:'\uED18',40568:'\uED19',40569:'\uED1A',40570:'\uED1B',40571:'\uED1C',40572:'\uED1D',40573:'\uED1E',40574:'\uED1F',40609:'\uED20',40610:'\uED21',40611:'\uED22',40612:'\uED23',40613:'\uED24',40614:'\uED25',40615:'\uED26',40616:'\uED27',40617:'\uED28',40618:'\uED29',40619:'\uED2A',40620:'\uED2B',40621:'\uED2C',40622:'\uED2D',40623:'\uED2E',40624:'\uED2F',40625:'\uED30',40626:'\uED31',40627:'\uED32',40628:'\uED33',40629:'\uED34',40630:'\uED35',40631:'\uED36',40632:'\uED37',40633:'\uED38',40634:'\uED39',40635:'\uED3A',40636:'\uED3B',40637:'\uED3C',40638:'\uED3D',40639:'\uED3E',40640:'\uED3F',40641:'\uED40',40642:'\uED41',40643:'\uED42',40644:'\uED43',40645:'\uED44',40646:'\uED45',40647:'\uED46',40648:'\uED47',40649:'\uED48',40650:'\uED49',40651:'\uED4A',40652:'\uED4B',40653:'\uED4C',40654:'\uED4D',40655:'\uED4E',40656:'\uED4F',40657:'\uED50',40658:'\uED51',40659:'\uED52',40660:'\uED53',40661:'\uED54',40662:'\uED55',40663:'\uED56',40664:'\uED57',40665:'\uED58',40666:'\uED59',40667:'\uED5A',40668:'\uED5B',40669:'\uED5C',40670:'\uED5D',40671:'\uED5E',40672:'\uED5F',40673:'\uED60',40674:'\uED61',40675:'\uED62',40676:'\uED63',40677:'\uED64',40678:'\uED65',40679:'\uED66',40680:'\uED67',40681:'\uED68',40682:'\uED69',40683:'\uED6A',40684:'\uED6B',40685:'\uED6C',40686:'\uED6D',40687:'\uED6E',40688:'\uED6F',40689:'\uED70',40690:'\uED71',40691:'\uED72',40692:'\uED73',40693:'\uED74',40694:'\uED75',40695:'\uED76',40696:'\uED77',40697:'\uED78',40698:'\uED79',40699:'\uED7A',40700:'\uED7B',40701:'\uED7C',40702:'\uED7D',40768:'\uED7E',40769:'\uED7F',40770:'\uED80',40771:'\uED81',40772:'\uED82',40773:'\uED83',40774:'\uED84',40775:'\uED85',40776:'\uED86',40777:'\uED87',40778:'\uED88',40779:'\uED89',40780:'\uED8A',40781:'\uED8B',40782:'\uED8C',40783:'\uED8D',40784:'\uED8E',40785:'\uED8F',40786:'\uED90',40787:'\uED91',40788:'\uED92',40789:'\uED93',40790:'\uED94',40791:'\uED95',40792:'\uED96',40793:'\uED97',40794:'\uED98',40795:'\uED99',40796:'\uED9A',40797:'\uED9B',40798:'\uED9C',40799:'\uED9D',40800:'\uED9E',40801:'\uED9F',40802:'\uEDA0',40803:'\uEDA1',40804:'\uEDA2',40805:'\uEDA3',40806:'\uEDA4',40807:'\uEDA5',40808:'\uEDA6',40809:'\uEDA7',40810:'\uEDA8',40811:'\uEDA9',40812:'\uEDAA',40813:'\uEDAB',40814:'\uEDAC',40815:'\uEDAD',40816:'\uEDAE',40817:'\uEDAF',40818:'\uEDB0',40819:'\uEDB1',40820:'\uEDB2',40821:'\uEDB3',40822:'\uEDB4',40823:'\uEDB5',40824:'\uEDB6',40825:'\uEDB7',40826:'\uEDB8',40827:'\uEDB9',40828:'\uEDBA',40829:'\uEDBB',40830:'\uEDBC',40865:'\uEDBD',40866:'\uEDBE',40867:'\uEDBF',40868:'\uEDC0',40869:'\uEDC1',40870:'\uEDC2',40871:'\uEDC3',40872:'\uEDC4',40873:'\uEDC5',40874:'\uEDC6',40875:'\uEDC7',40876:'\uEDC8',40877:'\uEDC9',40878:'\uEDCA',40879:'\uEDCB',40880:'\uEDCC',40881:'\uEDCD',40882:'\uEDCE',40883:'\uEDCF',40884:'\uEDD0',40885:'\uEDD1',40886:'\uEDD2',40887:'\uEDD3',40888:'\uEDD4',40889:'\uEDD5',40890:'\uEDD6',40891:'\uEDD7',40892:'\uEDD8',40893:'\uEDD9',40894:'\uEDDA',40895:'\uEDDB',40896:'\uEDDC',40897:'\uEDDD',40898:'\uEDDE',40899:'\uEDDF',40900:'\uEDE0',40901:'\uEDE1',40902:'\uEDE2',40903:'\uEDE3',40904:'\uEDE4',40905:'\uEDE5',40906:'\uEDE6',40907:'\uEDE7',40908:'\uEDE8',40909:'\uEDE9',40910:'\uEDEA',40911:'\uEDEB',40912:'\uEDEC',40913:'\uEDED',40914:'\uEDEE',40915:'\uEDEF',40916:'\uEDF0',40917:'\uEDF1',40918:'\uEDF2',40919:'\uEDF3',40920:'\uEDF4',40921:'\uEDF5',40922:'\uEDF6',40923:'\uEDF7',40924:'\uEDF8',40925:'\uEDF9',40926:'\uEDFA',40927:'\uEDFB',40928:'\uEDFC',40929:'\uEDFD',40930:'\uEDFE',40931:'\uEDFF',40932:'\uEE00',40933:'\uEE01',40934:'\uEE02',40935:'\uEE03',40936:'\uEE04',40937:'\uEE05',40938:'\uEE06',40939:'\uEE07',40940:'\uEE08',40941:'\uEE09',40942:'\uEE0A',40943:'\uEE0B',40944:'\uEE0C',40945:'\uEE0D',40946:'\uEE0E',40947:'\uEE0F',40948:'\uEE10',40949:'\uEE11',40950:'\uEE12',40951:'\uEE13',40952:'\uEE14',40953:'\uEE15',40954:'\uEE16',40955:'\uEE17',40956:'\uEE18',40957:'\uEE19',40958:'\uEE1A',41024:'\uEE1B',41025:'\uEE1C',41026:'\uEE1D',41027:'\uEE1E',41028:'\uEE1F',41029:'\uEE20',41030:'\uEE21',41031:'\uEE22',41032:'\uEE23',41033:'\uEE24',41034:'\uEE25',41035:'\uEE26',41036:'\uEE27',41037:'\uEE28',41038:'\uEE29',41039:'\uEE2A',41040:'\uEE2B',41041:'\uEE2C',41042:'\uEE2D',41043:'\uEE2E',41044:'\uEE2F',41045:'\uEE30',41046:'\uEE31',41047:'\uEE32',41048:'\uEE33',41049:'\uEE34',41050:'\uEE35',41051:'\uEE36',41052:'\uEE37',41053:'\uEE38',41054:'\uEE39',41055:'\uEE3A',41056:'\uEE3B',41057:'\uEE3C',41058:'\uEE3D',41059:'\uEE3E',41060:'\uEE3F',41061:'\uEE40',41062:'\uEE41',41063:'\uEE42',41064:'\uEE43',41065:'\uEE44',41066:'\uEE45',41067:'\uEE46',41068:'\uEE47',41069:'\uEE48',41070:'\uEE49',41071:'\uEE4A',41072:'\uEE4B',41073:'\uEE4C',41074:'\uEE4D',41075:'\uEE4E',41076:'\uEE4F',41077:'\uEE50',41078:'\uEE51',41079:'\uEE52',41080:'\uEE53',41081:'\uEE54',41082:'\uEE55',41083:'\uEE56',41084:'\uEE57',41085:'\uEE58',41086:'\uEE59',41121:'\uEE5A',41122:'\uEE5B',41123:'\uEE5C',41124:'\uEE5D',41125:'\uEE5E',41126:'\uEE5F',41127:'\uEE60',41128:'\uEE61',41129:'\uEE62',41130:'\uEE63',41131:'\uEE64',41132:'\uEE65',41133:'\uEE66',41134:'\uEE67',41135:'\uEE68',41136:'\uEE69',41137:'\uEE6A',41138:'\uEE6B',41139:'\uEE6C',41140:'\uEE6D',41141:'\uEE6E',41142:'\uEE6F',41143:'\uEE70',41144:'\uEE71',41145:'\uEE72',41146:'\uEE73',41147:'\uEE74',41148:'\uEE75',41149:'\uEE76',41150:'\uEE77',41151:'\uEE78',41152:'\uEE79',41153:'\uEE7A',41154:'\uEE7B',41155:'\uEE7C',41156:'\uEE7D',41157:'\uEE7E',41158:'\uEE7F',41159:'\uEE80',41160:'\uEE81',41161:'\uEE82',41162:'\uEE83',41163:'\uEE84',41164:'\uEE85',41165:'\uEE86',41166:'\uEE87',41167:'\uEE88',41168:'\uEE89',41169:'\uEE8A',41170:'\uEE8B',41171:'\uEE8C',41172:'\uEE8D',41173:'\uEE8E',41174:'\uEE8F',41175:'\uEE90',41176:'\uEE91',41177:'\uEE92',41178:'\uEE93',41179:'\uEE94',41180:'\uEE95',41181:'\uEE96',41182:'\uEE97',41183:'\uEE98',41184:'\uEE99',41185:'\uEE9A',41186:'\uEE9B',41187:'\uEE9C',41188:'\uEE9D',41189:'\uEE9E',41190:'\uEE9F',41191:'\uEEA0',41192:'\uEEA1',41193:'\uEEA2',41194:'\uEEA3',41195:'\uEEA4',41196:'\uEEA5',41197:'\uEEA6',41198:'\uEEA7',41199:'\uEEA8',41200:'\uEEA9',41201:'\uEEAA',41202:'\uEEAB',41203:'\uEEAC',41204:'\uEEAD',41205:'\uEEAE',41206:'\uEEAF',41207:'\uEEB0',41208:'\uEEB1',41209:'\uEEB2',41210:'\uEEB3',41211:'\uEEB4',41212:'\uEEB5',41213:'\uEEB6',41214:'\uEEB7',41280:'\u3000',41281:'\uFF0C',41282:'\u3001',41283:'\u3002',41284:'\uFF0E',41285:'\u2027',41286:'\uFF1B',41287:'\uFF1A',41288:'\uFF1F',41289:'\uFF01',41290:'\uFE30',41291:'\u2026',41292:'\u2025',41293:'\uFE50',41294:'\uFE51',41295:'\uFE52',41296:'\u00B7',41297:'\uFE54',41298:'\uFE55',41299:'\uFE56',41300:'\uFE57',41301:'\uFF5C',41302:'\u2013',41303:'\uFE31',41304:'\u2014',41305:'\uFE33',41306:'\u2574',41307:'\uFE34',41308:'\uFE4F',41309:'\uFF08',41310:'\uFF09',41311:'\uFE35',41312:'\uFE36',41313:'\uFF5B',41314:'\uFF5D',41315:'\uFE37',41316:'\uFE38',41317:'\u3014',41318:'\u3015',41319:'\uFE39',41320:'\uFE3A',41321:'\u3010',41322:'\u3011',41323:'\uFE3B',41324:'\uFE3C',41325:'\u300A',41326:'\u300B',41327:'\uFE3D',41328:'\uFE3E',41329:'\u3008',41330:'\u3009',41331:'\uFE3F',41332:'\uFE40',41333:'\u300C',41334:'\u300D',41335:'\uFE41',41336:'\uFE42',41337:'\u300E',41338:'\u300F',41339:'\uFE43',41340:'\uFE44',41341:'\uFE59',41342:'\uFE5A',41377:'\uFE5B',41378:'\uFE5C',41379:'\uFE5D',41380:'\uFE5E',41381:'\u2018',41382:'\u2019',41383:'\u201C',41384:'\u201D',41385:'\u301D',41386:'\u301E',41387:'\u2035',41388:'\u2032',41389:'\uFF03',41390:'\uFF06',41391:'\uFF0A',41392:'\u203B',41393:'\u00A7',41394:'\u3003',41395:'\u25CB',41396:'\u25CF',41397:'\u25B3',41398:'\u25B2',41399:'\u25CE',41400:'\u2606',41401:'\u2605',41402:'\u25C7',41403:'\u25C6',41404:'\u25A1',41405:'\u25A0',41406:'\u25BD',41407:'\u25BC',41408:'\u32A3',41409:'\u2105',41410:'\u00AF',41411:'\uFFE3',41412:'\uFF3F',41413:'\u02CD',41414:'\uFE49',41415:'\uFE4A',41416:'\uFE4D',41417:'\uFE4E',41418:'\uFE4B',41419:'\uFE4C',41420:'\uFE5F',41421:'\uFE60',41422:'\uFE61',41423:'\uFF0B',41424:'\uFF0D',41425:'\u00D7',41426:'\u00F7',41427:'\u00B1',41428:'\u221A',41429:'\uFF1C',41430:'\uFF1E',41431:'\uFF1D',41432:'\u2266',41433:'\u2267',41434:'\u2260',41435:'\u221E',41436:'\u2252',41437:'\u2261',41438:'\uFE62',41439:'\uFE63',41440:'\uFE64',41441:'\uFE65',41442:'\uFE66',41443:'\uFF5E',41444:'\u2229',41445:'\u222A',41446:'\u22A5',41447:'\u2220',41448:'\u221F',41449:'\u22BF',41450:'\u33D2',41451:'\u33D1',41452:'\u222B',41453:'\u222E',41454:'\u2235',41455:'\u2234',41456:'\u2640',41457:'\u2642',41458:'\u2295',41459:'\u2299',41460:'\u2191',41461:'\u2193',41462:'\u2190',41463:'\u2192',41464:'\u2196',41465:'\u2197',41466:'\u2199',41467:'\u2198',41468:'\u2225',41469:'\u2223',41470:'\uFF0F',41536:'\uFF3C',41537:'\u2215',41538:'\uFE68',41539:'\uFF04',41540:'\uFFE5',41541:'\u3012',41542:'\uFFE0',41543:'\uFFE1',41544:'\uFF05',41545:'\uFF20',41546:'\u2103',41547:'\u2109',41548:'\uFE69',41549:'\uFE6A',41550:'\uFE6B',41551:'\u33D5',41552:'\u339C',41553:'\u339D',41554:'\u339E',41555:'\u33CE',41556:'\u33A1',41557:'\u338E',41558:'\u338F',41559:'\u33C4',41560:'\u00B0',41561:'\u5159',41562:'\u515B',41563:'\u515E',41564:'\u515D',41565:'\u5161',41566:'\u5163',41567:'\u55E7',41568:'\u74E9',41569:'\u7CCE',41570:'\u2581',41571:'\u2582',41572:'\u2583',41573:'\u2584',41574:'\u2585',41575:'\u2586',41576:'\u2587',41577:'\u2588',41578:'\u258F',41579:'\u258E',41580:'\u258D',41581:'\u258C',41582:'\u258B',41583:'\u258A',41584:'\u2589',41585:'\u253C',41586:'\u2534',41587:'\u252C',41588:'\u2524',41589:'\u251C',41590:'\u2594',41591:'\u2500',41592:'\u2502',41593:'\u2595',41594:'\u250C',41595:'\u2510',41596:'\u2514',41597:'\u2518',41598:'\u256D',41633:'\u256E',41634:'\u2570',41635:'\u256F',41636:'\u2550',41637:'\u255E',41638:'\u256A',41639:'\u2561',41640:'\u25E2',41641:'\u25E3',41642:'\u25E5',41643:'\u25E4',41644:'\u2571',41645:'\u2572',41646:'\u2573',41647:'\uFF10',41648:'\uFF11',41649:'\uFF12',41650:'\uFF13',41651:'\uFF14',41652:'\uFF15',41653:'\uFF16',41654:'\uFF17',41655:'\uFF18',41656:'\uFF19',41657:'\u2160',41658:'\u2161',41659:'\u2162',41660:'\u2163',41661:'\u2164',41662:'\u2165',41663:'\u2166',41664:'\u2167',41665:'\u2168',41666:'\u2169',41667:'\u3021',41668:'\u3022',41669:'\u3023',41670:'\u3024',41671:'\u3025',41672:'\u3026',41673:'\u3027',41674:'\u3028',41675:'\u3029',41676:'\u5341',41677:'\u5344',41678:'\u5345',41679:'\uFF21',41680:'\uFF22',41681:'\uFF23',41682:'\uFF24',41683:'\uFF25',41684:'\uFF26',41685:'\uFF27',41686:'\uFF28',41687:'\uFF29',41688:'\uFF2A',41689:'\uFF2B',41690:'\uFF2C',41691:'\uFF2D',41692:'\uFF2E',41693:'\uFF2F',41694:'\uFF30',41695:'\uFF31',41696:'\uFF32',41697:'\uFF33',41698:'\uFF34',41699:'\uFF35',41700:'\uFF36',41701:'\uFF37',41702:'\uFF38',41703:'\uFF39',41704:'\uFF3A',41705:'\uFF41',41706:'\uFF42',41707:'\uFF43',41708:'\uFF44',41709:'\uFF45',41710:'\uFF46',41711:'\uFF47',41712:'\uFF48',41713:'\uFF49',41714:'\uFF4A',41715:'\uFF4B',41716:'\uFF4C',41717:'\uFF4D',41718:'\uFF4E',41719:'\uFF4F',41720:'\uFF50',41721:'\uFF51',41722:'\uFF52',41723:'\uFF53',41724:'\uFF54',41725:'\uFF55',41726:'\uFF56',41792:'\uFF57',41793:'\uFF58',41794:'\uFF59',41795:'\uFF5A',41796:'\u0391',41797:'\u0392',41798:'\u0393',41799:'\u0394',41800:'\u0395',41801:'\u0396',41802:'\u0397',41803:'\u0398',41804:'\u0399',41805:'\u039A',41806:'\u039B',41807:'\u039C',41808:'\u039D',41809:'\u039E',41810:'\u039F',41811:'\u03A0',41812:'\u03A1',41813:'\u03A3',41814:'\u03A4',41815:'\u03A5',41816:'\u03A6',41817:'\u03A7',41818:'\u03A8',41819:'\u03A9',41820:'\u03B1',41821:'\u03B2',41822:'\u03B3',41823:'\u03B4',41824:'\u03B5',41825:'\u03B6',41826:'\u03B7',41827:'\u03B8',41828:'\u03B9',41829:'\u03BA',41830:'\u03BB',41831:'\u03BC',41832:'\u03BD',41833:'\u03BE',41834:'\u03BF',41835:'\u03C0',41836:'\u03C1',41837:'\u03C3',41838:'\u03C4',41839:'\u03C5',41840:'\u03C6',41841:'\u03C7',41842:'\u03C8',41843:'\u03C9',41844:'\u3105',41845:'\u3106',41846:'\u3107',41847:'\u3108',41848:'\u3109',41849:'\u310A',41850:'\u310B',41851:'\u310C',41852:'\u310D',41853:'\u310E',41854:'\u310F',41889:'\u3110',41890:'\u3111',41891:'\u3112',41892:'\u3113',41893:'\u3114',41894:'\u3115',41895:'\u3116',41896:'\u3117',41897:'\u3118',41898:'\u3119',41899:'\u311A',41900:'\u311B',41901:'\u311C',41902:'\u311D',41903:'\u311E',41904:'\u311F',41905:'\u3120',41906:'\u3121',41907:'\u3122',41908:'\u3123',41909:'\u3124',41910:'\u3125',41911:'\u3126',41912:'\u3127',41913:'\u3128',41914:'\u3129',41915:'\u02D9',41916:'\u02C9',41917:'\u02CA',41918:'\u02C7',41919:'\u02CB',41953:'\u20AC',42048:'\u4E00',42049:'\u4E59',42050:'\u4E01',42051:'\u4E03',42052:'\u4E43',42053:'\u4E5D',42054:'\u4E86',42055:'\u4E8C',42056:'\u4EBA',42057:'\u513F',42058:'\u5165',42059:'\u516B',42060:'\u51E0',42061:'\u5200',42062:'\u5201',42063:'\u529B',42064:'\u5315',42065:'\u5341',42066:'\u535C',42067:'\u53C8',42068:'\u4E09',42069:'\u4E0B',42070:'\u4E08',42071:'\u4E0A',42072:'\u4E2B',42073:'\u4E38',42074:'\u51E1',42075:'\u4E45',42076:'\u4E48',42077:'\u4E5F',42078:'\u4E5E',42079:'\u4E8E',42080:'\u4EA1',42081:'\u5140',42082:'\u5203',42083:'\u52FA',42084:'\u5343',42085:'\u53C9',42086:'\u53E3',42087:'\u571F',42088:'\u58EB',42089:'\u5915',42090:'\u5927',42091:'\u5973',42092:'\u5B50',42093:'\u5B51',42094:'\u5B53',42095:'\u5BF8',42096:'\u5C0F',42097:'\u5C22',42098:'\u5C38',42099:'\u5C71',42100:'\u5DDD',42101:'\u5DE5',42102:'\u5DF1',42103:'\u5DF2',42104:'\u5DF3',42105:'\u5DFE',42106:'\u5E72',42107:'\u5EFE',42108:'\u5F0B',42109:'\u5F13',42110:'\u624D',42145:'\u4E11',42146:'\u4E10',42147:'\u4E0D',42148:'\u4E2D',42149:'\u4E30',42150:'\u4E39',42151:'\u4E4B',42152:'\u5C39',42153:'\u4E88',42154:'\u4E91',42155:'\u4E95',42156:'\u4E92',42157:'\u4E94',42158:'\u4EA2',42159:'\u4EC1',42160:'\u4EC0',42161:'\u4EC3',42162:'\u4EC6',42163:'\u4EC7',42164:'\u4ECD',42165:'\u4ECA',42166:'\u4ECB',42167:'\u4EC4',42168:'\u5143',42169:'\u5141',42170:'\u5167',42171:'\u516D',42172:'\u516E',42173:'\u516C',42174:'\u5197',42175:'\u51F6',42176:'\u5206',42177:'\u5207',42178:'\u5208',42179:'\u52FB',42180:'\u52FE',42181:'\u52FF',42182:'\u5316',42183:'\u5339',42184:'\u5348',42185:'\u5347',42186:'\u5345',42187:'\u535E',42188:'\u5384',42189:'\u53CB',42190:'\u53CA',42191:'\u53CD',42192:'\u58EC',42193:'\u5929',42194:'\u592B',42195:'\u592A',42196:'\u592D',42197:'\u5B54',42198:'\u5C11',42199:'\u5C24',42200:'\u5C3A',42201:'\u5C6F',42202:'\u5DF4',42203:'\u5E7B',42204:'\u5EFF',42205:'\u5F14',42206:'\u5F15',42207:'\u5FC3',42208:'\u6208',42209:'\u6236',42210:'\u624B',42211:'\u624E',42212:'\u652F',42213:'\u6587',42214:'\u6597',42215:'\u65A4',42216:'\u65B9',42217:'\u65E5',42218:'\u66F0',42219:'\u6708',42220:'\u6728',42221:'\u6B20',42222:'\u6B62',42223:'\u6B79',42224:'\u6BCB',42225:'\u6BD4',42226:'\u6BDB',42227:'\u6C0F',42228:'\u6C34',42229:'\u706B',42230:'\u722A',42231:'\u7236',42232:'\u723B',42233:'\u7247',42234:'\u7259',42235:'\u725B',42236:'\u72AC',42237:'\u738B',42238:'\u4E19',42304:'\u4E16',42305:'\u4E15',42306:'\u4E14',42307:'\u4E18',42308:'\u4E3B',42309:'\u4E4D',42310:'\u4E4F',42311:'\u4E4E',42312:'\u4EE5',42313:'\u4ED8',42314:'\u4ED4',42315:'\u4ED5',42316:'\u4ED6',42317:'\u4ED7',42318:'\u4EE3',42319:'\u4EE4',42320:'\u4ED9',42321:'\u4EDE',42322:'\u5145',42323:'\u5144',42324:'\u5189',42325:'\u518A',42326:'\u51AC',42327:'\u51F9',42328:'\u51FA',42329:'\u51F8',42330:'\u520A',42331:'\u52A0',42332:'\u529F',42333:'\u5305',42334:'\u5306',42335:'\u5317',42336:'\u531D',42337:'\u4EDF',42338:'\u534A',42339:'\u5349',42340:'\u5361',42341:'\u5360',42342:'\u536F',42343:'\u536E',42344:'\u53BB',42345:'\u53EF',42346:'\u53E4',42347:'\u53F3',42348:'\u53EC',42349:'\u53EE',42350:'\u53E9',42351:'\u53E8',42352:'\u53FC',42353:'\u53F8',42354:'\u53F5',42355:'\u53EB',42356:'\u53E6',42357:'\u53EA',42358:'\u53F2',42359:'\u53F1',42360:'\u53F0',42361:'\u53E5',42362:'\u53ED',42363:'\u53FB',42364:'\u56DB',42365:'\u56DA',42366:'\u5916',42401:'\u592E',42402:'\u5931',42403:'\u5974',42404:'\u5976',42405:'\u5B55',42406:'\u5B83',42407:'\u5C3C',42408:'\u5DE8',42409:'\u5DE7',42410:'\u5DE6',42411:'\u5E02',42412:'\u5E03',42413:'\u5E73',42414:'\u5E7C',42415:'\u5F01',42416:'\u5F18',42417:'\u5F17',42418:'\u5FC5',42419:'\u620A',42420:'\u6253',42421:'\u6254',42422:'\u6252',42423:'\u6251',42424:'\u65A5',42425:'\u65E6',42426:'\u672E',42427:'\u672C',42428:'\u672A',42429:'\u672B',42430:'\u672D',42431:'\u6B63',42432:'\u6BCD',42433:'\u6C11',42434:'\u6C10',42435:'\u6C38',42436:'\u6C41',42437:'\u6C40',42438:'\u6C3E',42439:'\u72AF',42440:'\u7384',42441:'\u7389',42442:'\u74DC',42443:'\u74E6',42444:'\u7518',42445:'\u751F',42446:'\u7528',42447:'\u7529',42448:'\u7530',42449:'\u7531',42450:'\u7532',42451:'\u7533',42452:'\u758B',42453:'\u767D',42454:'\u76AE',42455:'\u76BF',42456:'\u76EE',42457:'\u77DB',42458:'\u77E2',42459:'\u77F3',42460:'\u793A',42461:'\u79BE',42462:'\u7A74',42463:'\u7ACB',42464:'\u4E1E',42465:'\u4E1F',42466:'\u4E52',42467:'\u4E53',42468:'\u4E69',42469:'\u4E99',42470:'\u4EA4',42471:'\u4EA6',42472:'\u4EA5',42473:'\u4EFF',42474:'\u4F09',42475:'\u4F19',42476:'\u4F0A',42477:'\u4F15',42478:'\u4F0D',42479:'\u4F10',42480:'\u4F11',42481:'\u4F0F',42482:'\u4EF2',42483:'\u4EF6',42484:'\u4EFB',42485:'\u4EF0',42486:'\u4EF3',42487:'\u4EFD',42488:'\u4F01',42489:'\u4F0B',42490:'\u5149',42491:'\u5147',42492:'\u5146',42493:'\u5148',42494:'\u5168',42560:'\u5171',42561:'\u518D',42562:'\u51B0',42563:'\u5217',42564:'\u5211',42565:'\u5212',42566:'\u520E',42567:'\u5216',42568:'\u52A3',42569:'\u5308',42570:'\u5321',42571:'\u5320',42572:'\u5370',42573:'\u5371',42574:'\u5409',42575:'\u540F',42576:'\u540C',42577:'\u540A',42578:'\u5410',42579:'\u5401',42580:'\u540B',42581:'\u5404',42582:'\u5411',42583:'\u540D',42584:'\u5408',42585:'\u5403',42586:'\u540E',42587:'\u5406',42588:'\u5412',42589:'\u56E0',42590:'\u56DE',42591:'\u56DD',42592:'\u5733',42593:'\u5730',42594:'\u5728',42595:'\u572D',42596:'\u572C',42597:'\u572F',42598:'\u5729',42599:'\u5919',42600:'\u591A',42601:'\u5937',42602:'\u5938',42603:'\u5984',42604:'\u5978',42605:'\u5983',42606:'\u597D',42607:'\u5979',42608:'\u5982',42609:'\u5981',42610:'\u5B57',42611:'\u5B58',42612:'\u5B87',42613:'\u5B88',42614:'\u5B85',42615:'\u5B89',42616:'\u5BFA',42617:'\u5C16',42618:'\u5C79',42619:'\u5DDE',42620:'\u5E06',42621:'\u5E76',42622:'\u5E74',42657:'\u5F0F',42658:'\u5F1B',42659:'\u5FD9',42660:'\u5FD6',42661:'\u620E',42662:'\u620C',42663:'\u620D',42664:'\u6210',42665:'\u6263',42666:'\u625B',42667:'\u6258',42668:'\u6536',42669:'\u65E9',42670:'\u65E8',42671:'\u65EC',42672:'\u65ED',42673:'\u66F2',42674:'\u66F3',42675:'\u6709',42676:'\u673D',42677:'\u6734',42678:'\u6731',42679:'\u6735',42680:'\u6B21',42681:'\u6B64',42682:'\u6B7B',42683:'\u6C16',42684:'\u6C5D',42685:'\u6C57',42686:'\u6C59',42687:'\u6C5F',42688:'\u6C60',42689:'\u6C50',42690:'\u6C55',42691:'\u6C61',42692:'\u6C5B',42693:'\u6C4D',42694:'\u6C4E',42695:'\u7070',42696:'\u725F',42697:'\u725D',42698:'\u767E',42699:'\u7AF9',42700:'\u7C73',42701:'\u7CF8',42702:'\u7F36',42703:'\u7F8A',42704:'\u7FBD',42705:'\u8001',42706:'\u8003',42707:'\u800C',42708:'\u8012',42709:'\u8033',42710:'\u807F',42711:'\u8089',42712:'\u808B',42713:'\u808C',42714:'\u81E3',42715:'\u81EA',42716:'\u81F3',42717:'\u81FC',42718:'\u820C',42719:'\u821B',42720:'\u821F',42721:'\u826E',42722:'\u8272',42723:'\u827E',42724:'\u866B',42725:'\u8840',42726:'\u884C',42727:'\u8863',42728:'\u897F',42729:'\u9621',42730:'\u4E32',42731:'\u4EA8',42732:'\u4F4D',42733:'\u4F4F',42734:'\u4F47',42735:'\u4F57',42736:'\u4F5E',42737:'\u4F34',42738:'\u4F5B',42739:'\u4F55',42740:'\u4F30',42741:'\u4F50',42742:'\u4F51',42743:'\u4F3D',42744:'\u4F3A',42745:'\u4F38',42746:'\u4F43',42747:'\u4F54',42748:'\u4F3C',42749:'\u4F46',42750:'\u4F63',42816:'\u4F5C',42817:'\u4F60',42818:'\u4F2F',42819:'\u4F4E',42820:'\u4F36',42821:'\u4F59',42822:'\u4F5D',42823:'\u4F48',42824:'\u4F5A',42825:'\u514C',42826:'\u514B',42827:'\u514D',42828:'\u5175',42829:'\u51B6',42830:'\u51B7',42831:'\u5225',42832:'\u5224',42833:'\u5229',42834:'\u522A',42835:'\u5228',42836:'\u52AB',42837:'\u52A9',42838:'\u52AA',42839:'\u52AC',42840:'\u5323',42841:'\u5373',42842:'\u5375',42843:'\u541D',42844:'\u542D',42845:'\u541E',42846:'\u543E',42847:'\u5426',42848:'\u544E',42849:'\u5427',42850:'\u5446',42851:'\u5443',42852:'\u5433',42853:'\u5448',42854:'\u5442',42855:'\u541B',42856:'\u5429',42857:'\u544A',42858:'\u5439',42859:'\u543B',42860:'\u5438',42861:'\u542E',42862:'\u5435',42863:'\u5436',42864:'\u5420',42865:'\u543C',42866:'\u5440',42867:'\u5431',42868:'\u542B',42869:'\u541F',42870:'\u542C',42871:'\u56EA',42872:'\u56F0',42873:'\u56E4',42874:'\u56EB',42875:'\u574A',42876:'\u5751',42877:'\u5740',42878:'\u574D',42913:'\u5747',42914:'\u574E',42915:'\u573E',42916:'\u5750',42917:'\u574F',42918:'\u573B',42919:'\u58EF',42920:'\u593E',42921:'\u599D',42922:'\u5992',42923:'\u59A8',42924:'\u599E',42925:'\u59A3',42926:'\u5999',42927:'\u5996',42928:'\u598D',42929:'\u59A4',42930:'\u5993',42931:'\u598A',42932:'\u59A5',42933:'\u5B5D',42934:'\u5B5C',42935:'\u5B5A',42936:'\u5B5B',42937:'\u5B8C',42938:'\u5B8B',42939:'\u5B8F',42940:'\u5C2C',42941:'\u5C40',42942:'\u5C41',42943:'\u5C3F',42944:'\u5C3E',42945:'\u5C90',42946:'\u5C91',42947:'\u5C94',42948:'\u5C8C',42949:'\u5DEB',42950:'\u5E0C',42951:'\u5E8F',42952:'\u5E87',42953:'\u5E8A',42954:'\u5EF7',42955:'\u5F04',42956:'\u5F1F',42957:'\u5F64',42958:'\u5F62',42959:'\u5F77',42960:'\u5F79',42961:'\u5FD8',42962:'\u5FCC',42963:'\u5FD7',42964:'\u5FCD',42965:'\u5FF1',42966:'\u5FEB',42967:'\u5FF8',42968:'\u5FEA',42969:'\u6212',42970:'\u6211',42971:'\u6284',42972:'\u6297',42973:'\u6296',42974:'\u6280',42975:'\u6276',42976:'\u6289',42977:'\u626D',42978:'\u628A',42979:'\u627C',42980:'\u627E',42981:'\u6279',42982:'\u6273',42983:'\u6292',42984:'\u626F',42985:'\u6298',42986:'\u626E',42987:'\u6295',42988:'\u6293',42989:'\u6291',42990:'\u6286',42991:'\u6539',42992:'\u653B',42993:'\u6538',42994:'\u65F1',42995:'\u66F4',42996:'\u675F',42997:'\u674E',42998:'\u674F',42999:'\u6750',43000:'\u6751',43001:'\u675C',43002:'\u6756',43003:'\u675E',43004:'\u6749',43005:'\u6746',43006:'\u6760',43072:'\u6753',43073:'\u6757',43074:'\u6B65',43075:'\u6BCF',43076:'\u6C42',43077:'\u6C5E',43078:'\u6C99',43079:'\u6C81',43080:'\u6C88',43081:'\u6C89',43082:'\u6C85',43083:'\u6C9B',43084:'\u6C6A',43085:'\u6C7A',43086:'\u6C90',43087:'\u6C70',43088:'\u6C8C',43089:'\u6C68',43090:'\u6C96',43091:'\u6C92',43092:'\u6C7D',43093:'\u6C83',43094:'\u6C72',43095:'\u6C7E',43096:'\u6C74',43097:'\u6C86',43098:'\u6C76',43099:'\u6C8D',43100:'\u6C94',43101:'\u6C98',43102:'\u6C82',43103:'\u7076',43104:'\u707C',43105:'\u707D',43106:'\u7078',43107:'\u7262',43108:'\u7261',43109:'\u7260',43110:'\u72C4',43111:'\u72C2',43112:'\u7396',43113:'\u752C',43114:'\u752B',43115:'\u7537',43116:'\u7538',43117:'\u7682',43118:'\u76EF',43119:'\u77E3',43120:'\u79C1',43121:'\u79C0',43122:'\u79BF',43123:'\u7A76',43124:'\u7CFB',43125:'\u7F55',43126:'\u8096',43127:'\u8093',43128:'\u809D',43129:'\u8098',43130:'\u809B',43131:'\u809A',43132:'\u80B2',43133:'\u826F',43134:'\u8292',43169:'\u828B',43170:'\u828D',43171:'\u898B',43172:'\u89D2',43173:'\u8A00',43174:'\u8C37',43175:'\u8C46',43176:'\u8C55',43177:'\u8C9D',43178:'\u8D64',43179:'\u8D70',43180:'\u8DB3',43181:'\u8EAB',43182:'\u8ECA',43183:'\u8F9B',43184:'\u8FB0',43185:'\u8FC2',43186:'\u8FC6',43187:'\u8FC5',43188:'\u8FC4',43189:'\u5DE1',43190:'\u9091',43191:'\u90A2',43192:'\u90AA',43193:'\u90A6',43194:'\u90A3',43195:'\u9149',43196:'\u91C6',43197:'\u91CC',43198:'\u9632',43199:'\u962E',43200:'\u9631',43201:'\u962A',43202:'\u962C',43203:'\u4E26',43204:'\u4E56',43205:'\u4E73',43206:'\u4E8B',43207:'\u4E9B',43208:'\u4E9E',43209:'\u4EAB',43210:'\u4EAC',43211:'\u4F6F',43212:'\u4F9D',43213:'\u4F8D',43214:'\u4F73',43215:'\u4F7F',43216:'\u4F6C',43217:'\u4F9B',43218:'\u4F8B',43219:'\u4F86',43220:'\u4F83',43221:'\u4F70',43222:'\u4F75',43223:'\u4F88',43224:'\u4F69',43225:'\u4F7B',43226:'\u4F96',43227:'\u4F7E',43228:'\u4F8F',43229:'\u4F91',43230:'\u4F7A',43231:'\u5154',43232:'\u5152',43233:'\u5155',43234:'\u5169',43235:'\u5177',43236:'\u5176',43237:'\u5178',43238:'\u51BD',43239:'\u51FD',43240:'\u523B',43241:'\u5238',43242:'\u5237',43243:'\u523A',43244:'\u5230',43245:'\u522E',43246:'\u5236',43247:'\u5241',43248:'\u52BE',43249:'\u52BB',43250:'\u5352',43251:'\u5354',43252:'\u5353',43253:'\u5351',43254:'\u5366',43255:'\u5377',43256:'\u5378',43257:'\u5379',43258:'\u53D6',43259:'\u53D4',43260:'\u53D7',43261:'\u5473',43262:'\u5475',43328:'\u5496',43329:'\u5478',43330:'\u5495',43331:'\u5480',43332:'\u547B',43333:'\u5477',43334:'\u5484',43335:'\u5492',43336:'\u5486',43337:'\u547C',43338:'\u5490',43339:'\u5471',43340:'\u5476',43341:'\u548C',43342:'\u549A',43343:'\u5462',43344:'\u5468',43345:'\u548B',43346:'\u547D',43347:'\u548E',43348:'\u56FA',43349:'\u5783',43350:'\u5777',43351:'\u576A',43352:'\u5769',43353:'\u5761',43354:'\u5766',43355:'\u5764',43356:'\u577C',43357:'\u591C',43358:'\u5949',43359:'\u5947',43360:'\u5948',43361:'\u5944',43362:'\u5954',43363:'\u59BE',43364:'\u59BB',43365:'\u59D4',43366:'\u59B9',43367:'\u59AE',43368:'\u59D1',43369:'\u59C6',43370:'\u59D0',43371:'\u59CD',43372:'\u59CB',43373:'\u59D3',43374:'\u59CA',43375:'\u59AF',43376:'\u59B3',43377:'\u59D2',43378:'\u59C5',43379:'\u5B5F',43380:'\u5B64',43381:'\u5B63',43382:'\u5B97',43383:'\u5B9A',43384:'\u5B98',43385:'\u5B9C',43386:'\u5B99',43387:'\u5B9B',43388:'\u5C1A',43389:'\u5C48',43390:'\u5C45',43425:'\u5C46',43426:'\u5CB7',43427:'\u5CA1',43428:'\u5CB8',43429:'\u5CA9',43430:'\u5CAB',43431:'\u5CB1',43432:'\u5CB3',43433:'\u5E18',43434:'\u5E1A',43435:'\u5E16',43436:'\u5E15',43437:'\u5E1B',43438:'\u5E11',43439:'\u5E78',43440:'\u5E9A',43441:'\u5E97',43442:'\u5E9C',43443:'\u5E95',43444:'\u5E96',43445:'\u5EF6',43446:'\u5F26',43447:'\u5F27',43448:'\u5F29',43449:'\u5F80',43450:'\u5F81',43451:'\u5F7F',43452:'\u5F7C',43453:'\u5FDD',43454:'\u5FE0',43455:'\u5FFD',43456:'\u5FF5',43457:'\u5FFF',43458:'\u600F',43459:'\u6014',43460:'\u602F',43461:'\u6035',43462:'\u6016',43463:'\u602A',43464:'\u6015',43465:'\u6021',43466:'\u6027',43467:'\u6029',43468:'\u602B',43469:'\u601B',43470:'\u6216',43471:'\u6215',43472:'\u623F',43473:'\u623E',43474:'\u6240',43475:'\u627F',43476:'\u62C9',43477:'\u62CC',43478:'\u62C4',43479:'\u62BF',43480:'\u62C2',43481:'\u62B9',43482:'\u62D2',43483:'\u62DB',43484:'\u62AB',43485:'\u62D3',43486:'\u62D4',43487:'\u62CB',43488:'\u62C8',43489:'\u62A8',43490:'\u62BD',43491:'\u62BC',43492:'\u62D0',43493:'\u62D9',43494:'\u62C7',43495:'\u62CD',43496:'\u62B5',43497:'\u62DA',43498:'\u62B1',43499:'\u62D8',43500:'\u62D6',43501:'\u62D7',43502:'\u62C6',43503:'\u62AC',43504:'\u62CE',43505:'\u653E',43506:'\u65A7',43507:'\u65BC',43508:'\u65FA',43509:'\u6614',43510:'\u6613',43511:'\u660C',43512:'\u6606',43513:'\u6602',43514:'\u660E',43515:'\u6600',43516:'\u660F',43517:'\u6615',43518:'\u660A',43584:'\u6607',43585:'\u670D',43586:'\u670B',43587:'\u676D',43588:'\u678B',43589:'\u6795',43590:'\u6771',43591:'\u679C',43592:'\u6773',43593:'\u6777',43594:'\u6787',43595:'\u679D',43596:'\u6797',43597:'\u676F',43598:'\u6770',43599:'\u677F',43600:'\u6789',43601:'\u677E',43602:'\u6790',43603:'\u6775',43604:'\u679A',43605:'\u6793',43606:'\u677C',43607:'\u676A',43608:'\u6772',43609:'\u6B23',43610:'\u6B66',43611:'\u6B67',43612:'\u6B7F',43613:'\u6C13',43614:'\u6C1B',43615:'\u6CE3',43616:'\u6CE8',43617:'\u6CF3',43618:'\u6CB1',43619:'\u6CCC',43620:'\u6CE5',43621:'\u6CB3',43622:'\u6CBD',43623:'\u6CBE',43624:'\u6CBC',43625:'\u6CE2',43626:'\u6CAB',43627:'\u6CD5',43628:'\u6CD3',43629:'\u6CB8',43630:'\u6CC4',43631:'\u6CB9',43632:'\u6CC1',43633:'\u6CAE',43634:'\u6CD7',43635:'\u6CC5',43636:'\u6CF1',43637:'\u6CBF',43638:'\u6CBB',43639:'\u6CE1',43640:'\u6CDB',43641:'\u6CCA',43642:'\u6CAC',43643:'\u6CEF',43644:'\u6CDC',43645:'\u6CD6',43646:'\u6CE0',43681:'\u7095',43682:'\u708E',43683:'\u7092',43684:'\u708A',43685:'\u7099',43686:'\u722C',43687:'\u722D',43688:'\u7238',43689:'\u7248',43690:'\u7267',43691:'\u7269',43692:'\u72C0',43693:'\u72CE',43694:'\u72D9',43695:'\u72D7',43696:'\u72D0',43697:'\u73A9',43698:'\u73A8',43699:'\u739F',43700:'\u73AB',43701:'\u73A5',43702:'\u753D',43703:'\u759D',43704:'\u7599',43705:'\u759A',43706:'\u7684',43707:'\u76C2',43708:'\u76F2',43709:'\u76F4',43710:'\u77E5',43711:'\u77FD',43712:'\u793E',43713:'\u7940',43714:'\u7941',43715:'\u79C9',43716:'\u79C8',43717:'\u7A7A',43718:'\u7A79',43719:'\u7AFA',43720:'\u7CFE',43721:'\u7F54',43722:'\u7F8C',43723:'\u7F8B',43724:'\u8005',43725:'\u80BA',43726:'\u80A5',43727:'\u80A2',43728:'\u80B1',43729:'\u80A1',43730:'\u80AB',43731:'\u80A9',43732:'\u80B4',43733:'\u80AA',43734:'\u80AF',43735:'\u81E5',43736:'\u81FE',43737:'\u820D',43738:'\u82B3',43739:'\u829D',43740:'\u8299',43741:'\u82AD',43742:'\u82BD',43743:'\u829F',43744:'\u82B9',43745:'\u82B1',43746:'\u82AC',43747:'\u82A5',43748:'\u82AF',43749:'\u82B8',43750:'\u82A3',43751:'\u82B0',43752:'\u82BE',43753:'\u82B7',43754:'\u864E',43755:'\u8671',43756:'\u521D',43757:'\u8868',43758:'\u8ECB',43759:'\u8FCE',43760:'\u8FD4',43761:'\u8FD1',43762:'\u90B5',43763:'\u90B8',43764:'\u90B1',43765:'\u90B6',43766:'\u91C7',43767:'\u91D1',43768:'\u9577',43769:'\u9580',43770:'\u961C',43771:'\u9640',43772:'\u963F',43773:'\u963B',43774:'\u9644',43840:'\u9642',43841:'\u96B9',43842:'\u96E8',43843:'\u9752',43844:'\u975E',43845:'\u4E9F',43846:'\u4EAD',43847:'\u4EAE',43848:'\u4FE1',43849:'\u4FB5',43850:'\u4FAF',43851:'\u4FBF',43852:'\u4FE0',43853:'\u4FD1',43854:'\u4FCF',43855:'\u4FDD',43856:'\u4FC3',43857:'\u4FB6',43858:'\u4FD8',43859:'\u4FDF',43860:'\u4FCA',43861:'\u4FD7',43862:'\u4FAE',43863:'\u4FD0',43864:'\u4FC4',43865:'\u4FC2',43866:'\u4FDA',43867:'\u4FCE',43868:'\u4FDE',43869:'\u4FB7',43870:'\u5157',43871:'\u5192',43872:'\u5191',43873:'\u51A0',43874:'\u524E',43875:'\u5243',43876:'\u524A',43877:'\u524D',43878:'\u524C',43879:'\u524B',43880:'\u5247',43881:'\u52C7',43882:'\u52C9',43883:'\u52C3',43884:'\u52C1',43885:'\u530D',43886:'\u5357',43887:'\u537B',43888:'\u539A',43889:'\u53DB',43890:'\u54AC',43891:'\u54C0',43892:'\u54A8',43893:'\u54CE',43894:'\u54C9',43895:'\u54B8',43896:'\u54A6',43897:'\u54B3',43898:'\u54C7',43899:'\u54C2',43900:'\u54BD',43901:'\u54AA',43902:'\u54C1',43937:'\u54C4',43938:'\u54C8',43939:'\u54AF',43940:'\u54AB',43941:'\u54B1',43942:'\u54BB',43943:'\u54A9',43944:'\u54A7',43945:'\u54BF',43946:'\u56FF',43947:'\u5782',43948:'\u578B',43949:'\u57A0',43950:'\u57A3',43951:'\u57A2',43952:'\u57CE',43953:'\u57AE',43954:'\u5793',43955:'\u5955',43956:'\u5951',43957:'\u594F',43958:'\u594E',43959:'\u5950',43960:'\u59DC',43961:'\u59D8',43962:'\u59FF',43963:'\u59E3',43964:'\u59E8',43965:'\u5A03',43966:'\u59E5',43967:'\u59EA',43968:'\u59DA',43969:'\u59E6',43970:'\u5A01',43971:'\u59FB',43972:'\u5B69',43973:'\u5BA3',43974:'\u5BA6',43975:'\u5BA4',43976:'\u5BA2',43977:'\u5BA5',43978:'\u5C01',43979:'\u5C4E',43980:'\u5C4F',43981:'\u5C4D',43982:'\u5C4B',43983:'\u5CD9',43984:'\u5CD2',43985:'\u5DF7',43986:'\u5E1D',43987:'\u5E25',43988:'\u5E1F',43989:'\u5E7D',43990:'\u5EA0',43991:'\u5EA6',43992:'\u5EFA',43993:'\u5F08',43994:'\u5F2D',43995:'\u5F65',43996:'\u5F88',43997:'\u5F85',43998:'\u5F8A',43999:'\u5F8B',44000:'\u5F87',44001:'\u5F8C',44002:'\u5F89',44003:'\u6012',44004:'\u601D',44005:'\u6020',44006:'\u6025',44007:'\u600E',44008:'\u6028',44009:'\u604D',44010:'\u6070',44011:'\u6068',44012:'\u6062',44013:'\u6046',44014:'\u6043',44015:'\u606C',44016:'\u606B',44017:'\u606A',44018:'\u6064',44019:'\u6241',44020:'\u62DC',44021:'\u6316',44022:'\u6309',44023:'\u62FC',44024:'\u62ED',44025:'\u6301',44026:'\u62EE',44027:'\u62FD',44028:'\u6307',44029:'\u62F1',44030:'\u62F7',44096:'\u62EF',44097:'\u62EC',44098:'\u62FE',44099:'\u62F4',44100:'\u6311',44101:'\u6302',44102:'\u653F',44103:'\u6545',44104:'\u65AB',44105:'\u65BD',44106:'\u65E2',44107:'\u6625',44108:'\u662D',44109:'\u6620',44110:'\u6627',44111:'\u662F',44112:'\u661F',44113:'\u6628',44114:'\u6631',44115:'\u6624',44116:'\u66F7',44117:'\u67FF',44118:'\u67D3',44119:'\u67F1',44120:'\u67D4',44121:'\u67D0',44122:'\u67EC',44123:'\u67B6',44124:'\u67AF',44125:'\u67F5',44126:'\u67E9',44127:'\u67EF',44128:'\u67C4',44129:'\u67D1',44130:'\u67B4',44131:'\u67DA',44132:'\u67E5',44133:'\u67B8',44134:'\u67CF',44135:'\u67DE',44136:'\u67F3',44137:'\u67B0',44138:'\u67D9',44139:'\u67E2',44140:'\u67DD',44141:'\u67D2',44142:'\u6B6A',44143:'\u6B83',44144:'\u6B86',44145:'\u6BB5',44146:'\u6BD2',44147:'\u6BD7',44148:'\u6C1F',44149:'\u6CC9',44150:'\u6D0B',44151:'\u6D32',44152:'\u6D2A',44153:'\u6D41',44154:'\u6D25',44155:'\u6D0C',44156:'\u6D31',44157:'\u6D1E',44158:'\u6D17',44193:'\u6D3B',44194:'\u6D3D',44195:'\u6D3E',44196:'\u6D36',44197:'\u6D1B',44198:'\u6CF5',44199:'\u6D39',44200:'\u6D27',44201:'\u6D38',44202:'\u6D29',44203:'\u6D2E',44204:'\u6D35',44205:'\u6D0E',44206:'\u6D2B',44207:'\u70AB',44208:'\u70BA',44209:'\u70B3',44210:'\u70AC',44211:'\u70AF',44212:'\u70AD',44213:'\u70B8',44214:'\u70AE',44215:'\u70A4',44216:'\u7230',44217:'\u7272',44218:'\u726F',44219:'\u7274',44220:'\u72E9',44221:'\u72E0',44222:'\u72E1',44223:'\u73B7',44224:'\u73CA',44225:'\u73BB',44226:'\u73B2',44227:'\u73CD',44228:'\u73C0',44229:'\u73B3',44230:'\u751A',44231:'\u752D',44232:'\u754F',44233:'\u754C',44234:'\u754E',44235:'\u754B',44236:'\u75AB',44237:'\u75A4',44238:'\u75A5',44239:'\u75A2',44240:'\u75A3',44241:'\u7678',44242:'\u7686',44243:'\u7687',44244:'\u7688',44245:'\u76C8',44246:'\u76C6',44247:'\u76C3',44248:'\u76C5',44249:'\u7701',44250:'\u76F9',44251:'\u76F8',44252:'\u7709',44253:'\u770B',44254:'\u76FE',44255:'\u76FC',44256:'\u7707',44257:'\u77DC',44258:'\u7802',44259:'\u7814',44260:'\u780C',44261:'\u780D',44262:'\u7946',44263:'\u7949',44264:'\u7948',44265:'\u7947',44266:'\u79B9',44267:'\u79BA',44268:'\u79D1',44269:'\u79D2',44270:'\u79CB',44271:'\u7A7F',44272:'\u7A81',44273:'\u7AFF',44274:'\u7AFD',44275:'\u7C7D',44276:'\u7D02',44277:'\u7D05',44278:'\u7D00',44279:'\u7D09',44280:'\u7D07',44281:'\u7D04',44282:'\u7D06',44283:'\u7F38',44284:'\u7F8E',44285:'\u7FBF',44286:'\u8004',44352:'\u8010',44353:'\u800D',44354:'\u8011',44355:'\u8036',44356:'\u80D6',44357:'\u80E5',44358:'\u80DA',44359:'\u80C3',44360:'\u80C4',44361:'\u80CC',44362:'\u80E1',44363:'\u80DB',44364:'\u80CE',44365:'\u80DE',44366:'\u80E4',44367:'\u80DD',44368:'\u81F4',44369:'\u8222',44370:'\u82E7',44371:'\u8303',44372:'\u8305',44373:'\u82E3',44374:'\u82DB',44375:'\u82E6',44376:'\u8304',44377:'\u82E5',44378:'\u8302',44379:'\u8309',44380:'\u82D2',44381:'\u82D7',44382:'\u82F1',44383:'\u8301',44384:'\u82DC',44385:'\u82D4',44386:'\u82D1',44387:'\u82DE',44388:'\u82D3',44389:'\u82DF',44390:'\u82EF',44391:'\u8306',44392:'\u8650',44393:'\u8679',44394:'\u867B',44395:'\u867A',44396:'\u884D',44397:'\u886B',44398:'\u8981',44399:'\u89D4',44400:'\u8A08',44401:'\u8A02',44402:'\u8A03',44403:'\u8C9E',44404:'\u8CA0',44405:'\u8D74',44406:'\u8D73',44407:'\u8DB4',44408:'\u8ECD',44409:'\u8ECC',44410:'\u8FF0',44411:'\u8FE6',44412:'\u8FE2',44413:'\u8FEA',44414:'\u8FE5',44449:'\u8FED',44450:'\u8FEB',44451:'\u8FE4',44452:'\u8FE8',44453:'\u90CA',44454:'\u90CE',44455:'\u90C1',44456:'\u90C3',44457:'\u914B',44458:'\u914A',44459:'\u91CD',44460:'\u9582',44461:'\u9650',44462:'\u964B',44463:'\u964C',44464:'\u964D',44465:'\u9762',44466:'\u9769',44467:'\u97CB',44468:'\u97ED',44469:'\u97F3',44470:'\u9801',44471:'\u98A8',44472:'\u98DB',44473:'\u98DF',44474:'\u9996',44475:'\u9999',44476:'\u4E58',44477:'\u4EB3',44478:'\u500C',44479:'\u500D',44480:'\u5023',44481:'\u4FEF',44482:'\u5026',44483:'\u5025',44484:'\u4FF8',44485:'\u5029',44486:'\u5016',44487:'\u5006',44488:'\u503C',44489:'\u501F',44490:'\u501A',44491:'\u5012',44492:'\u5011',44493:'\u4FFA',44494:'\u5000',44495:'\u5014',44496:'\u5028',44497:'\u4FF1',44498:'\u5021',44499:'\u500B',44500:'\u5019',44501:'\u5018',44502:'\u4FF3',44503:'\u4FEE',44504:'\u502D',44505:'\u502A',44506:'\u4FFE',44507:'\u502B',44508:'\u5009',44509:'\u517C',44510:'\u51A4',44511:'\u51A5',44512:'\u51A2',44513:'\u51CD',44514:'\u51CC',44515:'\u51C6',44516:'\u51CB',44517:'\u5256',44518:'\u525C',44519:'\u5254',44520:'\u525B',44521:'\u525D',44522:'\u532A',44523:'\u537F',44524:'\u539F',44525:'\u539D',44526:'\u53DF',44527:'\u54E8',44528:'\u5510',44529:'\u5501',44530:'\u5537',44531:'\u54FC',44532:'\u54E5',44533:'\u54F2',44534:'\u5506',44535:'\u54FA',44536:'\u5514',44537:'\u54E9',44538:'\u54ED',44539:'\u54E1',44540:'\u5509',44541:'\u54EE',44542:'\u54EA',44608:'\u54E6',44609:'\u5527',44610:'\u5507',44611:'\u54FD',44612:'\u550F',44613:'\u5703',44614:'\u5704',44615:'\u57C2',44616:'\u57D4',44617:'\u57CB',44618:'\u57C3',44619:'\u5809',44620:'\u590F',44621:'\u5957',44622:'\u5958',44623:'\u595A',44624:'\u5A11',44625:'\u5A18',44626:'\u5A1C',44627:'\u5A1F',44628:'\u5A1B',44629:'\u5A13',44630:'\u59EC',44631:'\u5A20',44632:'\u5A23',44633:'\u5A29',44634:'\u5A25',44635:'\u5A0C',44636:'\u5A09',44637:'\u5B6B',44638:'\u5C58',44639:'\u5BB0',44640:'\u5BB3',44641:'\u5BB6',44642:'\u5BB4',44643:'\u5BAE',44644:'\u5BB5',44645:'\u5BB9',44646:'\u5BB8',44647:'\u5C04',44648:'\u5C51',44649:'\u5C55',44650:'\u5C50',44651:'\u5CED',44652:'\u5CFD',44653:'\u5CFB',44654:'\u5CEA',44655:'\u5CE8',44656:'\u5CF0',44657:'\u5CF6',44658:'\u5D01',44659:'\u5CF4',44660:'\u5DEE',44661:'\u5E2D',44662:'\u5E2B',44663:'\u5EAB',44664:'\u5EAD',44665:'\u5EA7',44666:'\u5F31',44667:'\u5F92',44668:'\u5F91',44669:'\u5F90',44670:'\u6059',44705:'\u6063',44706:'\u6065',44707:'\u6050',44708:'\u6055',44709:'\u606D',44710:'\u6069',44711:'\u606F',44712:'\u6084',44713:'\u609F',44714:'\u609A',44715:'\u608D',44716:'\u6094',44717:'\u608C',44718:'\u6085',44719:'\u6096',44720:'\u6247',44721:'\u62F3',44722:'\u6308',44723:'\u62FF',44724:'\u634E',44725:'\u633E',44726:'\u632F',44727:'\u6355',44728:'\u6342',44729:'\u6346',44730:'\u634F',44731:'\u6349',44732:'\u633A',44733:'\u6350',44734:'\u633D',44735:'\u632A',44736:'\u632B',44737:'\u6328',44738:'\u634D',44739:'\u634C',44740:'\u6548',44741:'\u6549',44742:'\u6599',44743:'\u65C1',44744:'\u65C5',44745:'\u6642',44746:'\u6649',44747:'\u664F',44748:'\u6643',44749:'\u6652',44750:'\u664C',44751:'\u6645',44752:'\u6641',44753:'\u66F8',44754:'\u6714',44755:'\u6715',44756:'\u6717',44757:'\u6821',44758:'\u6838',44759:'\u6848',44760:'\u6846',44761:'\u6853',44762:'\u6839',44763:'\u6842',44764:'\u6854',44765:'\u6829',44766:'\u68B3',44767:'\u6817',44768:'\u684C',44769:'\u6851',44770:'\u683D',44771:'\u67F4',44772:'\u6850',44773:'\u6840',44774:'\u683C',44775:'\u6843',44776:'\u682A',44777:'\u6845',44778:'\u6813',44779:'\u6818',44780:'\u6841',44781:'\u6B8A',44782:'\u6B89',44783:'\u6BB7',44784:'\u6C23',44785:'\u6C27',44786:'\u6C28',44787:'\u6C26',44788:'\u6C24',44789:'\u6CF0',44790:'\u6D6A',44791:'\u6D95',44792:'\u6D88',44793:'\u6D87',44794:'\u6D66',44795:'\u6D78',44796:'\u6D77',44797:'\u6D59',44798:'\u6D93',44864:'\u6D6C',44865:'\u6D89',44866:'\u6D6E',44867:'\u6D5A',44868:'\u6D74',44869:'\u6D69',44870:'\u6D8C',44871:'\u6D8A',44872:'\u6D79',44873:'\u6D85',44874:'\u6D65',44875:'\u6D94',44876:'\u70CA',44877:'\u70D8',44878:'\u70E4',44879:'\u70D9',44880:'\u70C8',44881:'\u70CF',44882:'\u7239',44883:'\u7279',44884:'\u72FC',44885:'\u72F9',44886:'\u72FD',44887:'\u72F8',44888:'\u72F7',44889:'\u7386',44890:'\u73ED',44891:'\u7409',44892:'\u73EE',44893:'\u73E0',44894:'\u73EA',44895:'\u73DE',44896:'\u7554',44897:'\u755D',44898:'\u755C',44899:'\u755A',44900:'\u7559',44901:'\u75BE',44902:'\u75C5',44903:'\u75C7',44904:'\u75B2',44905:'\u75B3',44906:'\u75BD',44907:'\u75BC',44908:'\u75B9',44909:'\u75C2',44910:'\u75B8',44911:'\u768B',44912:'\u76B0',44913:'\u76CA',44914:'\u76CD',44915:'\u76CE',44916:'\u7729',44917:'\u771F',44918:'\u7720',44919:'\u7728',44920:'\u77E9',44921:'\u7830',44922:'\u7827',44923:'\u7838',44924:'\u781D',44925:'\u7834',44926:'\u7837',44961:'\u7825',44962:'\u782D',44963:'\u7820',44964:'\u781F',44965:'\u7832',44966:'\u7955',44967:'\u7950',44968:'\u7960',44969:'\u795F',44970:'\u7956',44971:'\u795E',44972:'\u795D',44973:'\u7957',44974:'\u795A',44975:'\u79E4',44976:'\u79E3',44977:'\u79E7',44978:'\u79DF',44979:'\u79E6',44980:'\u79E9',44981:'\u79D8',44982:'\u7A84',44983:'\u7A88',44984:'\u7AD9',44985:'\u7B06',44986:'\u7B11',44987:'\u7C89',44988:'\u7D21',44989:'\u7D17',44990:'\u7D0B',44991:'\u7D0A',44992:'\u7D20',44993:'\u7D22',44994:'\u7D14',44995:'\u7D10',44996:'\u7D15',44997:'\u7D1A',44998:'\u7D1C',44999:'\u7D0D',45000:'\u7D19',45001:'\u7D1B',45002:'\u7F3A',45003:'\u7F5F',45004:'\u7F94',45005:'\u7FC5',45006:'\u7FC1',45007:'\u8006',45008:'\u8018',45009:'\u8015',45010:'\u8019',45011:'\u8017',45012:'\u803D',45013:'\u803F',45014:'\u80F1',45015:'\u8102',45016:'\u80F0',45017:'\u8105',45018:'\u80ED',45019:'\u80F4',45020:'\u8106',45021:'\u80F8',45022:'\u80F3',45023:'\u8108',45024:'\u80FD',45025:'\u810A',45026:'\u80FC',45027:'\u80EF',45028:'\u81ED',45029:'\u81EC',45030:'\u8200',45031:'\u8210',45032:'\u822A',45033:'\u822B',45034:'\u8228',45035:'\u822C',45036:'\u82BB',45037:'\u832B',45038:'\u8352',45039:'\u8354',45040:'\u834A',45041:'\u8338',45042:'\u8350',45043:'\u8349',45044:'\u8335',45045:'\u8334',45046:'\u834F',45047:'\u8332',45048:'\u8339',45049:'\u8336',45050:'\u8317',45051:'\u8340',45052:'\u8331',45053:'\u8328',45054:'\u8343',45120:'\u8654',45121:'\u868A',45122:'\u86AA',45123:'\u8693',45124:'\u86A4',45125:'\u86A9',45126:'\u868C',45127:'\u86A3',45128:'\u869C',45129:'\u8870',45130:'\u8877',45131:'\u8881',45132:'\u8882',45133:'\u887D',45134:'\u8879',45135:'\u8A18',45136:'\u8A10',45137:'\u8A0E',45138:'\u8A0C',45139:'\u8A15',45140:'\u8A0A',45141:'\u8A17',45142:'\u8A13',45143:'\u8A16',45144:'\u8A0F',45145:'\u8A11',45146:'\u8C48',45147:'\u8C7A',45148:'\u8C79',45149:'\u8CA1',45150:'\u8CA2',45151:'\u8D77',45152:'\u8EAC',45153:'\u8ED2',45154:'\u8ED4',45155:'\u8ECF',45156:'\u8FB1',45157:'\u9001',45158:'\u9006',45159:'\u8FF7',45160:'\u9000',45161:'\u8FFA',45162:'\u8FF4',45163:'\u9003',45164:'\u8FFD',45165:'\u9005',45166:'\u8FF8',45167:'\u9095',45168:'\u90E1',45169:'\u90DD',45170:'\u90E2',45171:'\u9152',45172:'\u914D',45173:'\u914C',45174:'\u91D8',45175:'\u91DD',45176:'\u91D7',45177:'\u91DC',45178:'\u91D9',45179:'\u9583',45180:'\u9662',45181:'\u9663',45182:'\u9661',45217:'\u965B',45218:'\u965D',45219:'\u9664',45220:'\u9658',45221:'\u965E',45222:'\u96BB',45223:'\u98E2',45224:'\u99AC',45225:'\u9AA8',45226:'\u9AD8',45227:'\u9B25',45228:'\u9B32',45229:'\u9B3C',45230:'\u4E7E',45231:'\u507A',45232:'\u507D',45233:'\u505C',45234:'\u5047',45235:'\u5043',45236:'\u504C',45237:'\u505A',45238:'\u5049',45239:'\u5065',45240:'\u5076',45241:'\u504E',45242:'\u5055',45243:'\u5075',45244:'\u5074',45245:'\u5077',45246:'\u504F',45247:'\u500F',45248:'\u506F',45249:'\u506D',45250:'\u515C',45251:'\u5195',45252:'\u51F0',45253:'\u526A',45254:'\u526F',45255:'\u52D2',45256:'\u52D9',45257:'\u52D8',45258:'\u52D5',45259:'\u5310',45260:'\u530F',45261:'\u5319',45262:'\u533F',45263:'\u5340',45264:'\u533E',45265:'\u53C3',45266:'\u66FC',45267:'\u5546',45268:'\u556A',45269:'\u5566',45270:'\u5544',45271:'\u555E',45272:'\u5561',45273:'\u5543',45274:'\u554A',45275:'\u5531',45276:'\u5556',45277:'\u554F',45278:'\u5555',45279:'\u552F',45280:'\u5564',45281:'\u5538',45282:'\u552E',45283:'\u555C',45284:'\u552C',45285:'\u5563',45286:'\u5533',45287:'\u5541',45288:'\u5557',45289:'\u5708',45290:'\u570B',45291:'\u5709',45292:'\u57DF',45293:'\u5805',45294:'\u580A',45295:'\u5806',45296:'\u57E0',45297:'\u57E4',45298:'\u57FA',45299:'\u5802',45300:'\u5835',45301:'\u57F7',45302:'\u57F9',45303:'\u5920',45304:'\u5962',45305:'\u5A36',45306:'\u5A41',45307:'\u5A49',45308:'\u5A66',45309:'\u5A6A',45310:'\u5A40',45376:'\u5A3C',45377:'\u5A62',45378:'\u5A5A',45379:'\u5A46',45380:'\u5A4A',45381:'\u5B70',45382:'\u5BC7',45383:'\u5BC5',45384:'\u5BC4',45385:'\u5BC2',45386:'\u5BBF',45387:'\u5BC6',45388:'\u5C09',45389:'\u5C08',45390:'\u5C07',45391:'\u5C60',45392:'\u5C5C',45393:'\u5C5D',45394:'\u5D07',45395:'\u5D06',45396:'\u5D0E',45397:'\u5D1B',45398:'\u5D16',45399:'\u5D22',45400:'\u5D11',45401:'\u5D29',45402:'\u5D14',45403:'\u5D19',45404:'\u5D24',45405:'\u5D27',45406:'\u5D17',45407:'\u5DE2',45408:'\u5E38',45409:'\u5E36',45410:'\u5E33',45411:'\u5E37',45412:'\u5EB7',45413:'\u5EB8',45414:'\u5EB6',45415:'\u5EB5',45416:'\u5EBE',45417:'\u5F35',45418:'\u5F37',45419:'\u5F57',45420:'\u5F6C',45421:'\u5F69',45422:'\u5F6B',45423:'\u5F97',45424:'\u5F99',45425:'\u5F9E',45426:'\u5F98',45427:'\u5FA1',45428:'\u5FA0',45429:'\u5F9C',45430:'\u607F',45431:'\u60A3',45432:'\u6089',45433:'\u60A0',45434:'\u60A8',45435:'\u60CB',45436:'\u60B4',45437:'\u60E6',45438:'\u60BD',45473:'\u60C5',45474:'\u60BB',45475:'\u60B5',45476:'\u60DC',45477:'\u60BC',45478:'\u60D8',45479:'\u60D5',45480:'\u60C6',45481:'\u60DF',45482:'\u60B8',45483:'\u60DA',45484:'\u60C7',45485:'\u621A',45486:'\u621B',45487:'\u6248',45488:'\u63A0',45489:'\u63A7',45490:'\u6372',45491:'\u6396',45492:'\u63A2',45493:'\u63A5',45494:'\u6377',45495:'\u6367',45496:'\u6398',45497:'\u63AA',45498:'\u6371',45499:'\u63A9',45500:'\u6389',45501:'\u6383',45502:'\u639B',45503:'\u636B',45504:'\u63A8',45505:'\u6384',45506:'\u6388',45507:'\u6399',45508:'\u63A1',45509:'\u63AC',45510:'\u6392',45511:'\u638F',45512:'\u6380',45513:'\u637B',45514:'\u6369',45515:'\u6368',45516:'\u637A',45517:'\u655D',45518:'\u6556',45519:'\u6551',45520:'\u6559',45521:'\u6557',45522:'\u555F',45523:'\u654F',45524:'\u6558',45525:'\u6555',45526:'\u6554',45527:'\u659C',45528:'\u659B',45529:'\u65AC',45530:'\u65CF',45531:'\u65CB',45532:'\u65CC',45533:'\u65CE',45534:'\u665D',45535:'\u665A',45536:'\u6664',45537:'\u6668',45538:'\u6666',45539:'\u665E',45540:'\u66F9',45541:'\u52D7',45542:'\u671B',45543:'\u6881',45544:'\u68AF',45545:'\u68A2',45546:'\u6893',45547:'\u68B5',45548:'\u687F',45549:'\u6876',45550:'\u68B1',45551:'\u68A7',45552:'\u6897',45553:'\u68B0',45554:'\u6883',45555:'\u68C4',45556:'\u68AD',45557:'\u6886',45558:'\u6885',45559:'\u6894',45560:'\u689D',45561:'\u68A8',45562:'\u689F',45563:'\u68A1',45564:'\u6882',45565:'\u6B32',45566:'\u6BBA',45632:'\u6BEB',45633:'\u6BEC',45634:'\u6C2B',45635:'\u6D8E',45636:'\u6DBC',45637:'\u6DF3',45638:'\u6DD9',45639:'\u6DB2',45640:'\u6DE1',45641:'\u6DCC',45642:'\u6DE4',45643:'\u6DFB',45644:'\u6DFA',45645:'\u6E05',45646:'\u6DC7',45647:'\u6DCB',45648:'\u6DAF',45649:'\u6DD1',45650:'\u6DAE',45651:'\u6DDE',45652:'\u6DF9',45653:'\u6DB8',45654:'\u6DF7',45655:'\u6DF5',45656:'\u6DC5',45657:'\u6DD2',45658:'\u6E1A',45659:'\u6DB5',45660:'\u6DDA',45661:'\u6DEB',45662:'\u6DD8',45663:'\u6DEA',45664:'\u6DF1',45665:'\u6DEE',45666:'\u6DE8',45667:'\u6DC6',45668:'\u6DC4',45669:'\u6DAA',45670:'\u6DEC',45671:'\u6DBF',45672:'\u6DE6',45673:'\u70F9',45674:'\u7109',45675:'\u710A',45676:'\u70FD',45677:'\u70EF',45678:'\u723D',45679:'\u727D',45680:'\u7281',45681:'\u731C',45682:'\u731B',45683:'\u7316',45684:'\u7313',45685:'\u7319',45686:'\u7387',45687:'\u7405',45688:'\u740A',45689:'\u7403',45690:'\u7406',45691:'\u73FE',45692:'\u740D',45693:'\u74E0',45694:'\u74F6',45729:'\u74F7',45730:'\u751C',45731:'\u7522',45732:'\u7565',45733:'\u7566',45734:'\u7562',45735:'\u7570',45736:'\u758F',45737:'\u75D4',45738:'\u75D5',45739:'\u75B5',45740:'\u75CA',45741:'\u75CD',45742:'\u768E',45743:'\u76D4',45744:'\u76D2',45745:'\u76DB',45746:'\u7737',45747:'\u773E',45748:'\u773C',45749:'\u7736',45750:'\u7738',45751:'\u773A',45752:'\u786B',45753:'\u7843',45754:'\u784E',45755:'\u7965',45756:'\u7968',45757:'\u796D',45758:'\u79FB',45759:'\u7A92',45760:'\u7A95',45761:'\u7B20',45762:'\u7B28',45763:'\u7B1B',45764:'\u7B2C',45765:'\u7B26',45766:'\u7B19',45767:'\u7B1E',45768:'\u7B2E',45769:'\u7C92',45770:'\u7C97',45771:'\u7C95',45772:'\u7D46',45773:'\u7D43',45774:'\u7D71',45775:'\u7D2E',45776:'\u7D39',45777:'\u7D3C',45778:'\u7D40',45779:'\u7D30',45780:'\u7D33',45781:'\u7D44',45782:'\u7D2F',45783:'\u7D42',45784:'\u7D32',45785:'\u7D31',45786:'\u7F3D',45787:'\u7F9E',45788:'\u7F9A',45789:'\u7FCC',45790:'\u7FCE',45791:'\u7FD2',45792:'\u801C',45793:'\u804A',45794:'\u8046',45795:'\u812F',45796:'\u8116',45797:'\u8123',45798:'\u812B',45799:'\u8129',45800:'\u8130',45801:'\u8124',45802:'\u8202',45803:'\u8235',45804:'\u8237',45805:'\u8236',45806:'\u8239',45807:'\u838E',45808:'\u839E',45809:'\u8398',45810:'\u8378',45811:'\u83A2',45812:'\u8396',45813:'\u83BD',45814:'\u83AB',45815:'\u8392',45816:'\u838A',45817:'\u8393',45818:'\u8389',45819:'\u83A0',45820:'\u8377',45821:'\u837B',45822:'\u837C',45888:'\u8386',45889:'\u83A7',45890:'\u8655',45891:'\u5F6A',45892:'\u86C7',45893:'\u86C0',45894:'\u86B6',45895:'\u86C4',45896:'\u86B5',45897:'\u86C6',45898:'\u86CB',45899:'\u86B1',45900:'\u86AF',45901:'\u86C9',45902:'\u8853',45903:'\u889E',45904:'\u8888',45905:'\u88AB',45906:'\u8892',45907:'\u8896',45908:'\u888D',45909:'\u888B',45910:'\u8993',45911:'\u898F',45912:'\u8A2A',45913:'\u8A1D',45914:'\u8A23',45915:'\u8A25',45916:'\u8A31',45917:'\u8A2D',45918:'\u8A1F',45919:'\u8A1B',45920:'\u8A22',45921:'\u8C49',45922:'\u8C5A',45923:'\u8CA9',45924:'\u8CAC',45925:'\u8CAB',45926:'\u8CA8',45927:'\u8CAA',45928:'\u8CA7',45929:'\u8D67',45930:'\u8D66',45931:'\u8DBE',45932:'\u8DBA',45933:'\u8EDB',45934:'\u8EDF',45935:'\u9019',45936:'\u900D',45937:'\u901A',45938:'\u9017',45939:'\u9023',45940:'\u901F',45941:'\u901D',45942:'\u9010',45943:'\u9015',45944:'\u901E',45945:'\u9020',45946:'\u900F',45947:'\u9022',45948:'\u9016',45949:'\u901B',45950:'\u9014',45985:'\u90E8',45986:'\u90ED',45987:'\u90FD',45988:'\u9157',45989:'\u91CE',45990:'\u91F5',45991:'\u91E6',45992:'\u91E3',45993:'\u91E7',45994:'\u91ED',45995:'\u91E9',45996:'\u9589',45997:'\u966A',45998:'\u9675',45999:'\u9673',46000:'\u9678',46001:'\u9670',46002:'\u9674',46003:'\u9676',46004:'\u9677',46005:'\u966C',46006:'\u96C0',46007:'\u96EA',46008:'\u96E9',46009:'\u7AE0',46010:'\u7ADF',46011:'\u9802',46012:'\u9803',46013:'\u9B5A',46014:'\u9CE5',46015:'\u9E75',46016:'\u9E7F',46017:'\u9EA5',46018:'\u9EBB',46019:'\u50A2',46020:'\u508D',46021:'\u5085',46022:'\u5099',46023:'\u5091',46024:'\u5080',46025:'\u5096',46026:'\u5098',46027:'\u509A',46028:'\u6700',46029:'\u51F1',46030:'\u5272',46031:'\u5274',46032:'\u5275',46033:'\u5269',46034:'\u52DE',46035:'\u52DD',46036:'\u52DB',46037:'\u535A',46038:'\u53A5',46039:'\u557B',46040:'\u5580',46041:'\u55A7',46042:'\u557C',46043:'\u558A',46044:'\u559D',46045:'\u5598',46046:'\u5582',46047:'\u559C',46048:'\u55AA',46049:'\u5594',46050:'\u5587',46051:'\u558B',46052:'\u5583',46053:'\u55B3',46054:'\u55AE',46055:'\u559F',46056:'\u553E',46057:'\u55B2',46058:'\u559A',46059:'\u55BB',46060:'\u55AC',46061:'\u55B1',46062:'\u557E',46063:'\u5589',46064:'\u55AB',46065:'\u5599',46066:'\u570D',46067:'\u582F',46068:'\u582A',46069:'\u5834',46070:'\u5824',46071:'\u5830',46072:'\u5831',46073:'\u5821',46074:'\u581D',46075:'\u5820',46076:'\u58F9',46077:'\u58FA',46078:'\u5960',46144:'\u5A77',46145:'\u5A9A',46146:'\u5A7F',46147:'\u5A92',46148:'\u5A9B',46149:'\u5AA7',46150:'\u5B73',46151:'\u5B71',46152:'\u5BD2',46153:'\u5BCC',46154:'\u5BD3',46155:'\u5BD0',46156:'\u5C0A',46157:'\u5C0B',46158:'\u5C31',46159:'\u5D4C',46160:'\u5D50',46161:'\u5D34',46162:'\u5D47',46163:'\u5DFD',46164:'\u5E45',46165:'\u5E3D',46166:'\u5E40',46167:'\u5E43',46168:'\u5E7E',46169:'\u5ECA',46170:'\u5EC1',46171:'\u5EC2',46172:'\u5EC4',46173:'\u5F3C',46174:'\u5F6D',46175:'\u5FA9',46176:'\u5FAA',46177:'\u5FA8',46178:'\u60D1',46179:'\u60E1',46180:'\u60B2',46181:'\u60B6',46182:'\u60E0',46183:'\u611C',46184:'\u6123',46185:'\u60FA',46186:'\u6115',46187:'\u60F0',46188:'\u60FB',46189:'\u60F4',46190:'\u6168',46191:'\u60F1',46192:'\u610E',46193:'\u60F6',46194:'\u6109',46195:'\u6100',46196:'\u6112',46197:'\u621F',46198:'\u6249',46199:'\u63A3',46200:'\u638C',46201:'\u63CF',46202:'\u63C0',46203:'\u63E9',46204:'\u63C9',46205:'\u63C6',46206:'\u63CD',46241:'\u63D2',46242:'\u63E3',46243:'\u63D0',46244:'\u63E1',46245:'\u63D6',46246:'\u63ED',46247:'\u63EE',46248:'\u6376',46249:'\u63F4',46250:'\u63EA',46251:'\u63DB',46252:'\u6452',46253:'\u63DA',46254:'\u63F9',46255:'\u655E',46256:'\u6566',46257:'\u6562',46258:'\u6563',46259:'\u6591',46260:'\u6590',46261:'\u65AF',46262:'\u666E',46263:'\u6670',46264:'\u6674',46265:'\u6676',46266:'\u666F',46267:'\u6691',46268:'\u667A',46269:'\u667E',46270:'\u6677',46271:'\u66FE',46272:'\u66FF',46273:'\u671F',46274:'\u671D',46275:'\u68FA',46276:'\u68D5',46277:'\u68E0',46278:'\u68D8',46279:'\u68D7',46280:'\u6905',46281:'\u68DF',46282:'\u68F5',46283:'\u68EE',46284:'\u68E7',46285:'\u68F9',46286:'\u68D2',46287:'\u68F2',46288:'\u68E3',46289:'\u68CB',46290:'\u68CD',46291:'\u690D',46292:'\u6912',46293:'\u690E',46294:'\u68C9',46295:'\u68DA',46296:'\u696E',46297:'\u68FB',46298:'\u6B3E',46299:'\u6B3A',46300:'\u6B3D',46301:'\u6B98',46302:'\u6B96',46303:'\u6BBC',46304:'\u6BEF',46305:'\u6C2E',46306:'\u6C2F',46307:'\u6C2C',46308:'\u6E2F',46309:'\u6E38',46310:'\u6E54',46311:'\u6E21',46312:'\u6E32',46313:'\u6E67',46314:'\u6E4A',46315:'\u6E20',46316:'\u6E25',46317:'\u6E23',46318:'\u6E1B',46319:'\u6E5B',46320:'\u6E58',46321:'\u6E24',46322:'\u6E56',46323:'\u6E6E',46324:'\u6E2D',46325:'\u6E26',46326:'\u6E6F',46327:'\u6E34',46328:'\u6E4D',46329:'\u6E3A',46330:'\u6E2C',46331:'\u6E43',46332:'\u6E1D',46333:'\u6E3E',46334:'\u6ECB',46400:'\u6E89',46401:'\u6E19',46402:'\u6E4E',46403:'\u6E63',46404:'\u6E44',46405:'\u6E72',46406:'\u6E69',46407:'\u6E5F',46408:'\u7119',46409:'\u711A',46410:'\u7126',46411:'\u7130',46412:'\u7121',46413:'\u7136',46414:'\u716E',46415:'\u711C',46416:'\u724C',46417:'\u7284',46418:'\u7280',46419:'\u7336',46420:'\u7325',46421:'\u7334',46422:'\u7329',46423:'\u743A',46424:'\u742A',46425:'\u7433',46426:'\u7422',46427:'\u7425',46428:'\u7435',46429:'\u7436',46430:'\u7434',46431:'\u742F',46432:'\u741B',46433:'\u7426',46434:'\u7428',46435:'\u7525',46436:'\u7526',46437:'\u756B',46438:'\u756A',46439:'\u75E2',46440:'\u75DB',46441:'\u75E3',46442:'\u75D9',46443:'\u75D8',46444:'\u75DE',46445:'\u75E0',46446:'\u767B',46447:'\u767C',46448:'\u7696',46449:'\u7693',46450:'\u76B4',46451:'\u76DC',46452:'\u774F',46453:'\u77ED',46454:'\u785D',46455:'\u786C',46456:'\u786F',46457:'\u7A0D',46458:'\u7A08',46459:'\u7A0B',46460:'\u7A05',46461:'\u7A00',46462:'\u7A98',46497:'\u7A97',46498:'\u7A96',46499:'\u7AE5',46500:'\u7AE3',46501:'\u7B49',46502:'\u7B56',46503:'\u7B46',46504:'\u7B50',46505:'\u7B52',46506:'\u7B54',46507:'\u7B4D',46508:'\u7B4B',46509:'\u7B4F',46510:'\u7B51',46511:'\u7C9F',46512:'\u7CA5',46513:'\u7D5E',46514:'\u7D50',46515:'\u7D68',46516:'\u7D55',46517:'\u7D2B',46518:'\u7D6E',46519:'\u7D72',46520:'\u7D61',46521:'\u7D66',46522:'\u7D62',46523:'\u7D70',46524:'\u7D73',46525:'\u5584',46526:'\u7FD4',46527:'\u7FD5',46528:'\u800B',46529:'\u8052',46530:'\u8085',46531:'\u8155',46532:'\u8154',46533:'\u814B',46534:'\u8151',46535:'\u814E',46536:'\u8139',46537:'\u8146',46538:'\u813E',46539:'\u814C',46540:'\u8153',46541:'\u8174',46542:'\u8212',46543:'\u821C',46544:'\u83E9',46545:'\u8403',46546:'\u83F8',46547:'\u840D',46548:'\u83E0',46549:'\u83C5',46550:'\u840B',46551:'\u83C1',46552:'\u83EF',46553:'\u83F1',46554:'\u83F4',46555:'\u8457',46556:'\u840A',46557:'\u83F0',46558:'\u840C',46559:'\u83CC',46560:'\u83FD',46561:'\u83F2',46562:'\u83CA',46563:'\u8438',46564:'\u840E',46565:'\u8404',46566:'\u83DC',46567:'\u8407',46568:'\u83D4',46569:'\u83DF',46570:'\u865B',46571:'\u86DF',46572:'\u86D9',46573:'\u86ED',46574:'\u86D4',46575:'\u86DB',46576:'\u86E4',46577:'\u86D0',46578:'\u86DE',46579:'\u8857',46580:'\u88C1',46581:'\u88C2',46582:'\u88B1',46583:'\u8983',46584:'\u8996',46585:'\u8A3B',46586:'\u8A60',46587:'\u8A55',46588:'\u8A5E',46589:'\u8A3C',46590:'\u8A41',46656:'\u8A54',46657:'\u8A5B',46658:'\u8A50',46659:'\u8A46',46660:'\u8A34',46661:'\u8A3A',46662:'\u8A36',46663:'\u8A56',46664:'\u8C61',46665:'\u8C82',46666:'\u8CAF',46667:'\u8CBC',46668:'\u8CB3',46669:'\u8CBD',46670:'\u8CC1',46671:'\u8CBB',46672:'\u8CC0',46673:'\u8CB4',46674:'\u8CB7',46675:'\u8CB6',46676:'\u8CBF',46677:'\u8CB8',46678:'\u8D8A',46679:'\u8D85',46680:'\u8D81',46681:'\u8DCE',46682:'\u8DDD',46683:'\u8DCB',46684:'\u8DDA',46685:'\u8DD1',46686:'\u8DCC',46687:'\u8DDB',46688:'\u8DC6',46689:'\u8EFB',46690:'\u8EF8',46691:'\u8EFC',46692:'\u8F9C',46693:'\u902E',46694:'\u9035',46695:'\u9031',46696:'\u9038',46697:'\u9032',46698:'\u9036',46699:'\u9102',46700:'\u90F5',46701:'\u9109',46702:'\u90FE',46703:'\u9163',46704:'\u9165',46705:'\u91CF',46706:'\u9214',46707:'\u9215',46708:'\u9223',46709:'\u9209',46710:'\u921E',46711:'\u920D',46712:'\u9210',46713:'\u9207',46714:'\u9211',46715:'\u9594',46716:'\u958F',46717:'\u958B',46718:'\u9591',46753:'\u9593',46754:'\u9592',46755:'\u958E',46756:'\u968A',46757:'\u968E',46758:'\u968B',46759:'\u967D',46760:'\u9685',46761:'\u9686',46762:'\u968D',46763:'\u9672',46764:'\u9684',46765:'\u96C1',46766:'\u96C5',46767:'\u96C4',46768:'\u96C6',46769:'\u96C7',46770:'\u96EF',46771:'\u96F2',46772:'\u97CC',46773:'\u9805',46774:'\u9806',46775:'\u9808',46776:'\u98E7',46777:'\u98EA',46778:'\u98EF',46779:'\u98E9',46780:'\u98F2',46781:'\u98ED',46782:'\u99AE',46783:'\u99AD',46784:'\u9EC3',46785:'\u9ECD',46786:'\u9ED1',46787:'\u4E82',46788:'\u50AD',46789:'\u50B5',46790:'\u50B2',46791:'\u50B3',46792:'\u50C5',46793:'\u50BE',46794:'\u50AC',46795:'\u50B7',46796:'\u50BB',46797:'\u50AF',46798:'\u50C7',46799:'\u527F',46800:'\u5277',46801:'\u527D',46802:'\u52DF',46803:'\u52E6',46804:'\u52E4',46805:'\u52E2',46806:'\u52E3',46807:'\u532F',46808:'\u55DF',46809:'\u55E8',46810:'\u55D3',46811:'\u55E6',46812:'\u55CE',46813:'\u55DC',46814:'\u55C7',46815:'\u55D1',46816:'\u55E3',46817:'\u55E4',46818:'\u55EF',46819:'\u55DA',46820:'\u55E1',46821:'\u55C5',46822:'\u55C6',46823:'\u55E5',46824:'\u55C9',46825:'\u5712',46826:'\u5713',46827:'\u585E',46828:'\u5851',46829:'\u5858',46830:'\u5857',46831:'\u585A',46832:'\u5854',46833:'\u586B',46834:'\u584C',46835:'\u586D',46836:'\u584A',46837:'\u5862',46838:'\u5852',46839:'\u584B',46840:'\u5967',46841:'\u5AC1',46842:'\u5AC9',46843:'\u5ACC',46844:'\u5ABE',46845:'\u5ABD',46846:'\u5ABC',46912:'\u5AB3',46913:'\u5AC2',46914:'\u5AB2',46915:'\u5D69',46916:'\u5D6F',46917:'\u5E4C',46918:'\u5E79',46919:'\u5EC9',46920:'\u5EC8',46921:'\u5F12',46922:'\u5F59',46923:'\u5FAC',46924:'\u5FAE',46925:'\u611A',46926:'\u610F',46927:'\u6148',46928:'\u611F',46929:'\u60F3',46930:'\u611B',46931:'\u60F9',46932:'\u6101',46933:'\u6108',46934:'\u614E',46935:'\u614C',46936:'\u6144',46937:'\u614D',46938:'\u613E',46939:'\u6134',46940:'\u6127',46941:'\u610D',46942:'\u6106',46943:'\u6137',46944:'\u6221',46945:'\u6222',46946:'\u6413',46947:'\u643E',46948:'\u641E',46949:'\u642A',46950:'\u642D',46951:'\u643D',46952:'\u642C',46953:'\u640F',46954:'\u641C',46955:'\u6414',46956:'\u640D',46957:'\u6436',46958:'\u6416',46959:'\u6417',46960:'\u6406',46961:'\u656C',46962:'\u659F',46963:'\u65B0',46964:'\u6697',46965:'\u6689',46966:'\u6687',46967:'\u6688',46968:'\u6696',46969:'\u6684',46970:'\u6698',46971:'\u668D',46972:'\u6703',46973:'\u6994',46974:'\u696D',47009:'\u695A',47010:'\u6977',47011:'\u6960',47012:'\u6954',47013:'\u6975',47014:'\u6930',47015:'\u6982',47016:'\u694A',47017:'\u6968',47018:'\u696B',47019:'\u695E',47020:'\u6953',47021:'\u6979',47022:'\u6986',47023:'\u695D',47024:'\u6963',47025:'\u695B',47026:'\u6B47',47027:'\u6B72',47028:'\u6BC0',47029:'\u6BBF',47030:'\u6BD3',47031:'\u6BFD',47032:'\u6EA2',47033:'\u6EAF',47034:'\u6ED3',47035:'\u6EB6',47036:'\u6EC2',47037:'\u6E90',47038:'\u6E9D',47039:'\u6EC7',47040:'\u6EC5',47041:'\u6EA5',47042:'\u6E98',47043:'\u6EBC',47044:'\u6EBA',47045:'\u6EAB',47046:'\u6ED1',47047:'\u6E96',47048:'\u6E9C',47049:'\u6EC4',47050:'\u6ED4',47051:'\u6EAA',47052:'\u6EA7',47053:'\u6EB4',47054:'\u714E',47055:'\u7159',47056:'\u7169',47057:'\u7164',47058:'\u7149',47059:'\u7167',47060:'\u715C',47061:'\u716C',47062:'\u7166',47063:'\u714C',47064:'\u7165',47065:'\u715E',47066:'\u7146',47067:'\u7168',47068:'\u7156',47069:'\u723A',47070:'\u7252',47071:'\u7337',47072:'\u7345',47073:'\u733F',47074:'\u733E',47075:'\u746F',47076:'\u745A',47077:'\u7455',47078:'\u745F',47079:'\u745E',47080:'\u7441',47081:'\u743F',47082:'\u7459',47083:'\u745B',47084:'\u745C',47085:'\u7576',47086:'\u7578',47087:'\u7600',47088:'\u75F0',47089:'\u7601',47090:'\u75F2',47091:'\u75F1',47092:'\u75FA',47093:'\u75FF',47094:'\u75F4',47095:'\u75F3',47096:'\u76DE',47097:'\u76DF',47098:'\u775B',47099:'\u776B',47100:'\u7766',47101:'\u775E',47102:'\u7763',47168:'\u7779',47169:'\u776A',47170:'\u776C',47171:'\u775C',47172:'\u7765',47173:'\u7768',47174:'\u7762',47175:'\u77EE',47176:'\u788E',47177:'\u78B0',47178:'\u7897',47179:'\u7898',47180:'\u788C',47181:'\u7889',47182:'\u787C',47183:'\u7891',47184:'\u7893',47185:'\u787F',47186:'\u797A',47187:'\u797F',47188:'\u7981',47189:'\u842C',47190:'\u79BD',47191:'\u7A1C',47192:'\u7A1A',47193:'\u7A20',47194:'\u7A14',47195:'\u7A1F',47196:'\u7A1E',47197:'\u7A9F',47198:'\u7AA0',47199:'\u7B77',47200:'\u7BC0',47201:'\u7B60',47202:'\u7B6E',47203:'\u7B67',47204:'\u7CB1',47205:'\u7CB3',47206:'\u7CB5',47207:'\u7D93',47208:'\u7D79',47209:'\u7D91',47210:'\u7D81',47211:'\u7D8F',47212:'\u7D5B',47213:'\u7F6E',47214:'\u7F69',47215:'\u7F6A',47216:'\u7F72',47217:'\u7FA9',47218:'\u7FA8',47219:'\u7FA4',47220:'\u8056',47221:'\u8058',47222:'\u8086',47223:'\u8084',47224:'\u8171',47225:'\u8170',47226:'\u8178',47227:'\u8165',47228:'\u816E',47229:'\u8173',47230:'\u816B',47265:'\u8179',47266:'\u817A',47267:'\u8166',47268:'\u8205',47269:'\u8247',47270:'\u8482',47271:'\u8477',47272:'\u843D',47273:'\u8431',47274:'\u8475',47275:'\u8466',47276:'\u846B',47277:'\u8449',47278:'\u846C',47279:'\u845B',47280:'\u843C',47281:'\u8435',47282:'\u8461',47283:'\u8463',47284:'\u8469',47285:'\u846D',47286:'\u8446',47287:'\u865E',47288:'\u865C',47289:'\u865F',47290:'\u86F9',47291:'\u8713',47292:'\u8708',47293:'\u8707',47294:'\u8700',47295:'\u86FE',47296:'\u86FB',47297:'\u8702',47298:'\u8703',47299:'\u8706',47300:'\u870A',47301:'\u8859',47302:'\u88DF',47303:'\u88D4',47304:'\u88D9',47305:'\u88DC',47306:'\u88D8',47307:'\u88DD',47308:'\u88E1',47309:'\u88CA',47310:'\u88D5',47311:'\u88D2',47312:'\u899C',47313:'\u89E3',47314:'\u8A6B',47315:'\u8A72',47316:'\u8A73',47317:'\u8A66',47318:'\u8A69',47319:'\u8A70',47320:'\u8A87',47321:'\u8A7C',47322:'\u8A63',47323:'\u8AA0',47324:'\u8A71',47325:'\u8A85',47326:'\u8A6D',47327:'\u8A62',47328:'\u8A6E',47329:'\u8A6C',47330:'\u8A79',47331:'\u8A7B',47332:'\u8A3E',47333:'\u8A68',47334:'\u8C62',47335:'\u8C8A',47336:'\u8C89',47337:'\u8CCA',47338:'\u8CC7',47339:'\u8CC8',47340:'\u8CC4',47341:'\u8CB2',47342:'\u8CC3',47343:'\u8CC2',47344:'\u8CC5',47345:'\u8DE1',47346:'\u8DDF',47347:'\u8DE8',47348:'\u8DEF',47349:'\u8DF3',47350:'\u8DFA',47351:'\u8DEA',47352:'\u8DE4',47353:'\u8DE6',47354:'\u8EB2',47355:'\u8F03',47356:'\u8F09',47357:'\u8EFE',47358:'\u8F0A',47424:'\u8F9F',47425:'\u8FB2',47426:'\u904B',47427:'\u904A',47428:'\u9053',47429:'\u9042',47430:'\u9054',47431:'\u903C',47432:'\u9055',47433:'\u9050',47434:'\u9047',47435:'\u904F',47436:'\u904E',47437:'\u904D',47438:'\u9051',47439:'\u903E',47440:'\u9041',47441:'\u9112',47442:'\u9117',47443:'\u916C',47444:'\u916A',47445:'\u9169',47446:'\u91C9',47447:'\u9237',47448:'\u9257',47449:'\u9238',47450:'\u923D',47451:'\u9240',47452:'\u923E',47453:'\u925B',47454:'\u924B',47455:'\u9264',47456:'\u9251',47457:'\u9234',47458:'\u9249',47459:'\u924D',47460:'\u9245',47461:'\u9239',47462:'\u923F',47463:'\u925A',47464:'\u9598',47465:'\u9698',47466:'\u9694',47467:'\u9695',47468:'\u96CD',47469:'\u96CB',47470:'\u96C9',47471:'\u96CA',47472:'\u96F7',47473:'\u96FB',47474:'\u96F9',47475:'\u96F6',47476:'\u9756',47477:'\u9774',47478:'\u9776',47479:'\u9810',47480:'\u9811',47481:'\u9813',47482:'\u980A',47483:'\u9812',47484:'\u980C',47485:'\u98FC',47486:'\u98F4',47521:'\u98FD',47522:'\u98FE',47523:'\u99B3',47524:'\u99B1',47525:'\u99B4',47526:'\u9AE1',47527:'\u9CE9',47528:'\u9E82',47529:'\u9F0E',47530:'\u9F13',47531:'\u9F20',47532:'\u50E7',47533:'\u50EE',47534:'\u50E5',47535:'\u50D6',47536:'\u50ED',47537:'\u50DA',47538:'\u50D5',47539:'\u50CF',47540:'\u50D1',47541:'\u50F1',47542:'\u50CE',47543:'\u50E9',47544:'\u5162',47545:'\u51F3',47546:'\u5283',47547:'\u5282',47548:'\u5331',47549:'\u53AD',47550:'\u55FE',47551:'\u5600',47552:'\u561B',47553:'\u5617',47554:'\u55FD',47555:'\u5614',47556:'\u5606',47557:'\u5609',47558:'\u560D',47559:'\u560E',47560:'\u55F7',47561:'\u5616',47562:'\u561F',47563:'\u5608',47564:'\u5610',47565:'\u55F6',47566:'\u5718',47567:'\u5716',47568:'\u5875',47569:'\u587E',47570:'\u5883',47571:'\u5893',47572:'\u588A',47573:'\u5879',47574:'\u5885',47575:'\u587D',47576:'\u58FD',47577:'\u5925',47578:'\u5922',47579:'\u5924',47580:'\u596A',47581:'\u5969',47582:'\u5AE1',47583:'\u5AE6',47584:'\u5AE9',47585:'\u5AD7',47586:'\u5AD6',47587:'\u5AD8',47588:'\u5AE3',47589:'\u5B75',47590:'\u5BDE',47591:'\u5BE7',47592:'\u5BE1',47593:'\u5BE5',47594:'\u5BE6',47595:'\u5BE8',47596:'\u5BE2',47597:'\u5BE4',47598:'\u5BDF',47599:'\u5C0D',47600:'\u5C62',47601:'\u5D84',47602:'\u5D87',47603:'\u5E5B',47604:'\u5E63',47605:'\u5E55',47606:'\u5E57',47607:'\u5E54',47608:'\u5ED3',47609:'\u5ED6',47610:'\u5F0A',47611:'\u5F46',47612:'\u5F70',47613:'\u5FB9',47614:'\u6147',47680:'\u613F',47681:'\u614B',47682:'\u6177',47683:'\u6162',47684:'\u6163',47685:'\u615F',47686:'\u615A',47687:'\u6158',47688:'\u6175',47689:'\u622A',47690:'\u6487',47691:'\u6458',47692:'\u6454',47693:'\u64A4',47694:'\u6478',47695:'\u645F',47696:'\u647A',47697:'\u6451',47698:'\u6467',47699:'\u6434',47700:'\u646D',47701:'\u647B',47702:'\u6572',47703:'\u65A1',47704:'\u65D7',47705:'\u65D6',47706:'\u66A2',47707:'\u66A8',47708:'\u669D',47709:'\u699C',47710:'\u69A8',47711:'\u6995',47712:'\u69C1',47713:'\u69AE',47714:'\u69D3',47715:'\u69CB',47716:'\u699B',47717:'\u69B7',47718:'\u69BB',47719:'\u69AB',47720:'\u69B4',47721:'\u69D0',47722:'\u69CD',47723:'\u69AD',47724:'\u69CC',47725:'\u69A6',47726:'\u69C3',47727:'\u69A3',47728:'\u6B49',47729:'\u6B4C',47730:'\u6C33',47731:'\u6F33',47732:'\u6F14',47733:'\u6EFE',47734:'\u6F13',47735:'\u6EF4',47736:'\u6F29',47737:'\u6F3E',47738:'\u6F20',47739:'\u6F2C',47740:'\u6F0F',47741:'\u6F02',47742:'\u6F22',47777:'\u6EFF',47778:'\u6EEF',47779:'\u6F06',47780:'\u6F31',47781:'\u6F38',47782:'\u6F32',47783:'\u6F23',47784:'\u6F15',47785:'\u6F2B',47786:'\u6F2F',47787:'\u6F88',47788:'\u6F2A',47789:'\u6EEC',47790:'\u6F01',47791:'\u6EF2',47792:'\u6ECC',47793:'\u6EF7',47794:'\u7194',47795:'\u7199',47796:'\u717D',47797:'\u718A',47798:'\u7184',47799:'\u7192',47800:'\u723E',47801:'\u7292',47802:'\u7296',47803:'\u7344',47804:'\u7350',47805:'\u7464',47806:'\u7463',47807:'\u746A',47808:'\u7470',47809:'\u746D',47810:'\u7504',47811:'\u7591',47812:'\u7627',47813:'\u760D',47814:'\u760B',47815:'\u7609',47816:'\u7613',47817:'\u76E1',47818:'\u76E3',47819:'\u7784',47820:'\u777D',47821:'\u777F',47822:'\u7761',47823:'\u78C1',47824:'\u789F',47825:'\u78A7',47826:'\u78B3',47827:'\u78A9',47828:'\u78A3',47829:'\u798E',47830:'\u798F',47831:'\u798D',47832:'\u7A2E',47833:'\u7A31',47834:'\u7AAA',47835:'\u7AA9',47836:'\u7AED',47837:'\u7AEF',47838:'\u7BA1',47839:'\u7B95',47840:'\u7B8B',47841:'\u7B75',47842:'\u7B97',47843:'\u7B9D',47844:'\u7B94',47845:'\u7B8F',47846:'\u7BB8',47847:'\u7B87',47848:'\u7B84',47849:'\u7CB9',47850:'\u7CBD',47851:'\u7CBE',47852:'\u7DBB',47853:'\u7DB0',47854:'\u7D9C',47855:'\u7DBD',47856:'\u7DBE',47857:'\u7DA0',47858:'\u7DCA',47859:'\u7DB4',47860:'\u7DB2',47861:'\u7DB1',47862:'\u7DBA',47863:'\u7DA2',47864:'\u7DBF',47865:'\u7DB5',47866:'\u7DB8',47867:'\u7DAD',47868:'\u7DD2',47869:'\u7DC7',47870:'\u7DAC',47936:'\u7F70',47937:'\u7FE0',47938:'\u7FE1',47939:'\u7FDF',47940:'\u805E',47941:'\u805A',47942:'\u8087',47943:'\u8150',47944:'\u8180',47945:'\u818F',47946:'\u8188',47947:'\u818A',47948:'\u817F',47949:'\u8182',47950:'\u81E7',47951:'\u81FA',47952:'\u8207',47953:'\u8214',47954:'\u821E',47955:'\u824B',47956:'\u84C9',47957:'\u84BF',47958:'\u84C6',47959:'\u84C4',47960:'\u8499',47961:'\u849E',47962:'\u84B2',47963:'\u849C',47964:'\u84CB',47965:'\u84B8',47966:'\u84C0',47967:'\u84D3',47968:'\u8490',47969:'\u84BC',47970:'\u84D1',47971:'\u84CA',47972:'\u873F',47973:'\u871C',47974:'\u873B',47975:'\u8722',47976:'\u8725',47977:'\u8734',47978:'\u8718',47979:'\u8755',47980:'\u8737',47981:'\u8729',47982:'\u88F3',47983:'\u8902',47984:'\u88F4',47985:'\u88F9',47986:'\u88F8',47987:'\u88FD',47988:'\u88E8',47989:'\u891A',47990:'\u88EF',47991:'\u8AA6',47992:'\u8A8C',47993:'\u8A9E',47994:'\u8AA3',47995:'\u8A8D',47996:'\u8AA1',47997:'\u8A93',47998:'\u8AA4',48033:'\u8AAA',48034:'\u8AA5',48035:'\u8AA8',48036:'\u8A98',48037:'\u8A91',48038:'\u8A9A',48039:'\u8AA7',48040:'\u8C6A',48041:'\u8C8D',48042:'\u8C8C',48043:'\u8CD3',48044:'\u8CD1',48045:'\u8CD2',48046:'\u8D6B',48047:'\u8D99',48048:'\u8D95',48049:'\u8DFC',48050:'\u8F14',48051:'\u8F12',48052:'\u8F15',48053:'\u8F13',48054:'\u8FA3',48055:'\u9060',48056:'\u9058',48057:'\u905C',48058:'\u9063',48059:'\u9059',48060:'\u905E',48061:'\u9062',48062:'\u905D',48063:'\u905B',48064:'\u9119',48065:'\u9118',48066:'\u911E',48067:'\u9175',48068:'\u9178',48069:'\u9177',48070:'\u9174',48071:'\u9278',48072:'\u9280',48073:'\u9285',48074:'\u9298',48075:'\u9296',48076:'\u927B',48077:'\u9293',48078:'\u929C',48079:'\u92A8',48080:'\u927C',48081:'\u9291',48082:'\u95A1',48083:'\u95A8',48084:'\u95A9',48085:'\u95A3',48086:'\u95A5',48087:'\u95A4',48088:'\u9699',48089:'\u969C',48090:'\u969B',48091:'\u96CC',48092:'\u96D2',48093:'\u9700',48094:'\u977C',48095:'\u9785',48096:'\u97F6',48097:'\u9817',48098:'\u9818',48099:'\u98AF',48100:'\u98B1',48101:'\u9903',48102:'\u9905',48103:'\u990C',48104:'\u9909',48105:'\u99C1',48106:'\u9AAF',48107:'\u9AB0',48108:'\u9AE6',48109:'\u9B41',48110:'\u9B42',48111:'\u9CF4',48112:'\u9CF6',48113:'\u9CF3',48114:'\u9EBC',48115:'\u9F3B',48116:'\u9F4A',48117:'\u5104',48118:'\u5100',48119:'\u50FB',48120:'\u50F5',48121:'\u50F9',48122:'\u5102',48123:'\u5108',48124:'\u5109',48125:'\u5105',48126:'\u51DC',48192:'\u5287',48193:'\u5288',48194:'\u5289',48195:'\u528D',48196:'\u528A',48197:'\u52F0',48198:'\u53B2',48199:'\u562E',48200:'\u563B',48201:'\u5639',48202:'\u5632',48203:'\u563F',48204:'\u5634',48205:'\u5629',48206:'\u5653',48207:'\u564E',48208:'\u5657',48209:'\u5674',48210:'\u5636',48211:'\u562F',48212:'\u5630',48213:'\u5880',48214:'\u589F',48215:'\u589E',48216:'\u58B3',48217:'\u589C',48218:'\u58AE',48219:'\u58A9',48220:'\u58A6',48221:'\u596D',48222:'\u5B09',48223:'\u5AFB',48224:'\u5B0B',48225:'\u5AF5',48226:'\u5B0C',48227:'\u5B08',48228:'\u5BEE',48229:'\u5BEC',48230:'\u5BE9',48231:'\u5BEB',48232:'\u5C64',48233:'\u5C65',48234:'\u5D9D',48235:'\u5D94',48236:'\u5E62',48237:'\u5E5F',48238:'\u5E61',48239:'\u5EE2',48240:'\u5EDA',48241:'\u5EDF',48242:'\u5EDD',48243:'\u5EE3',48244:'\u5EE0',48245:'\u5F48',48246:'\u5F71',48247:'\u5FB7',48248:'\u5FB5',48249:'\u6176',48250:'\u6167',48251:'\u616E',48252:'\u615D',48253:'\u6155',48254:'\u6182',48289:'\u617C',48290:'\u6170',48291:'\u616B',48292:'\u617E',48293:'\u61A7',48294:'\u6190',48295:'\u61AB',48296:'\u618E',48297:'\u61AC',48298:'\u619A',48299:'\u61A4',48300:'\u6194',48301:'\u61AE',48302:'\u622E',48303:'\u6469',48304:'\u646F',48305:'\u6479',48306:'\u649E',48307:'\u64B2',48308:'\u6488',48309:'\u6490',48310:'\u64B0',48311:'\u64A5',48312:'\u6493',48313:'\u6495',48314:'\u64A9',48315:'\u6492',48316:'\u64AE',48317:'\u64AD',48318:'\u64AB',48319:'\u649A',48320:'\u64AC',48321:'\u6499',48322:'\u64A2',48323:'\u64B3',48324:'\u6575',48325:'\u6577',48326:'\u6578',48327:'\u66AE',48328:'\u66AB',48329:'\u66B4',48330:'\u66B1',48331:'\u6A23',48332:'\u6A1F',48333:'\u69E8',48334:'\u6A01',48335:'\u6A1E',48336:'\u6A19',48337:'\u69FD',48338:'\u6A21',48339:'\u6A13',48340:'\u6A0A',48341:'\u69F3',48342:'\u6A02',48343:'\u6A05',48344:'\u69ED',48345:'\u6A11',48346:'\u6B50',48347:'\u6B4E',48348:'\u6BA4',48349:'\u6BC5',48350:'\u6BC6',48351:'\u6F3F',48352:'\u6F7C',48353:'\u6F84',48354:'\u6F51',48355:'\u6F66',48356:'\u6F54',48357:'\u6F86',48358:'\u6F6D',48359:'\u6F5B',48360:'\u6F78',48361:'\u6F6E',48362:'\u6F8E',48363:'\u6F7A',48364:'\u6F70',48365:'\u6F64',48366:'\u6F97',48367:'\u6F58',48368:'\u6ED5',48369:'\u6F6F',48370:'\u6F60',48371:'\u6F5F',48372:'\u719F',48373:'\u71AC',48374:'\u71B1',48375:'\u71A8',48376:'\u7256',48377:'\u729B',48378:'\u734E',48379:'\u7357',48380:'\u7469',48381:'\u748B',48382:'\u7483',48448:'\u747E',48449:'\u7480',48450:'\u757F',48451:'\u7620',48452:'\u7629',48453:'\u761F',48454:'\u7624',48455:'\u7626',48456:'\u7621',48457:'\u7622',48458:'\u769A',48459:'\u76BA',48460:'\u76E4',48461:'\u778E',48462:'\u7787',48463:'\u778C',48464:'\u7791',48465:'\u778B',48466:'\u78CB',48467:'\u78C5',48468:'\u78BA',48469:'\u78CA',48470:'\u78BE',48471:'\u78D5',48472:'\u78BC',48473:'\u78D0',48474:'\u7A3F',48475:'\u7A3C',48476:'\u7A40',48477:'\u7A3D',48478:'\u7A37',48479:'\u7A3B',48480:'\u7AAF',48481:'\u7AAE',48482:'\u7BAD',48483:'\u7BB1',48484:'\u7BC4',48485:'\u7BB4',48486:'\u7BC6',48487:'\u7BC7',48488:'\u7BC1',48489:'\u7BA0',48490:'\u7BCC',48491:'\u7CCA',48492:'\u7DE0',48493:'\u7DF4',48494:'\u7DEF',48495:'\u7DFB',48496:'\u7DD8',48497:'\u7DEC',48498:'\u7DDD',48499:'\u7DE8',48500:'\u7DE3',48501:'\u7DDA',48502:'\u7DDE',48503:'\u7DE9',48504:'\u7D9E',48505:'\u7DD9',48506:'\u7DF2',48507:'\u7DF9',48508:'\u7F75',48509:'\u7F77',48510:'\u7FAF',48545:'\u7FE9',48546:'\u8026',48547:'\u819B',48548:'\u819C',48549:'\u819D',48550:'\u81A0',48551:'\u819A',48552:'\u8198',48553:'\u8517',48554:'\u853D',48555:'\u851A',48556:'\u84EE',48557:'\u852C',48558:'\u852D',48559:'\u8513',48560:'\u8511',48561:'\u8523',48562:'\u8521',48563:'\u8514',48564:'\u84EC',48565:'\u8525',48566:'\u84FF',48567:'\u8506',48568:'\u8782',48569:'\u8774',48570:'\u8776',48571:'\u8760',48572:'\u8766',48573:'\u8778',48574:'\u8768',48575:'\u8759',48576:'\u8757',48577:'\u874C',48578:'\u8753',48579:'\u885B',48580:'\u885D',48581:'\u8910',48582:'\u8907',48583:'\u8912',48584:'\u8913',48585:'\u8915',48586:'\u890A',48587:'\u8ABC',48588:'\u8AD2',48589:'\u8AC7',48590:'\u8AC4',48591:'\u8A95',48592:'\u8ACB',48593:'\u8AF8',48594:'\u8AB2',48595:'\u8AC9',48596:'\u8AC2',48597:'\u8ABF',48598:'\u8AB0',48599:'\u8AD6',48600:'\u8ACD',48601:'\u8AB6',48602:'\u8AB9',48603:'\u8ADB',48604:'\u8C4C',48605:'\u8C4E',48606:'\u8C6C',48607:'\u8CE0',48608:'\u8CDE',48609:'\u8CE6',48610:'\u8CE4',48611:'\u8CEC',48612:'\u8CED',48613:'\u8CE2',48614:'\u8CE3',48615:'\u8CDC',48616:'\u8CEA',48617:'\u8CE1',48618:'\u8D6D',48619:'\u8D9F',48620:'\u8DA3',48621:'\u8E2B',48622:'\u8E10',48623:'\u8E1D',48624:'\u8E22',48625:'\u8E0F',48626:'\u8E29',48627:'\u8E1F',48628:'\u8E21',48629:'\u8E1E',48630:'\u8EBA',48631:'\u8F1D',48632:'\u8F1B',48633:'\u8F1F',48634:'\u8F29',48635:'\u8F26',48636:'\u8F2A',48637:'\u8F1C',48638:'\u8F1E',48704:'\u8F25',48705:'\u9069',48706:'\u906E',48707:'\u9068',48708:'\u906D',48709:'\u9077',48710:'\u9130',48711:'\u912D',48712:'\u9127',48713:'\u9131',48714:'\u9187',48715:'\u9189',48716:'\u918B',48717:'\u9183',48718:'\u92C5',48719:'\u92BB',48720:'\u92B7',48721:'\u92EA',48722:'\u92AC',48723:'\u92E4',48724:'\u92C1',48725:'\u92B3',48726:'\u92BC',48727:'\u92D2',48728:'\u92C7',48729:'\u92F0',48730:'\u92B2',48731:'\u95AD',48732:'\u95B1',48733:'\u9704',48734:'\u9706',48735:'\u9707',48736:'\u9709',48737:'\u9760',48738:'\u978D',48739:'\u978B',48740:'\u978F',48741:'\u9821',48742:'\u982B',48743:'\u981C',48744:'\u98B3',48745:'\u990A',48746:'\u9913',48747:'\u9912',48748:'\u9918',48749:'\u99DD',48750:'\u99D0',48751:'\u99DF',48752:'\u99DB',48753:'\u99D1',48754:'\u99D5',48755:'\u99D2',48756:'\u99D9',48757:'\u9AB7',48758:'\u9AEE',48759:'\u9AEF',48760:'\u9B27',48761:'\u9B45',48762:'\u9B44',48763:'\u9B77',48764:'\u9B6F',48765:'\u9D06',48766:'\u9D09',48801:'\u9D03',48802:'\u9EA9',48803:'\u9EBE',48804:'\u9ECE',48805:'\u58A8',48806:'\u9F52',48807:'\u5112',48808:'\u5118',48809:'\u5114',48810:'\u5110',48811:'\u5115',48812:'\u5180',48813:'\u51AA',48814:'\u51DD',48815:'\u5291',48816:'\u5293',48817:'\u52F3',48818:'\u5659',48819:'\u566B',48820:'\u5679',48821:'\u5669',48822:'\u5664',48823:'\u5678',48824:'\u566A',48825:'\u5668',48826:'\u5665',48827:'\u5671',48828:'\u566F',48829:'\u566C',48830:'\u5662',48831:'\u5676',48832:'\u58C1',48833:'\u58BE',48834:'\u58C7',48835:'\u58C5',48836:'\u596E',48837:'\u5B1D',48838:'\u5B34',48839:'\u5B78',48840:'\u5BF0',48841:'\u5C0E',48842:'\u5F4A',48843:'\u61B2',48844:'\u6191',48845:'\u61A9',48846:'\u618A',48847:'\u61CD',48848:'\u61B6',48849:'\u61BE',48850:'\u61CA',48851:'\u61C8',48852:'\u6230',48853:'\u64C5',48854:'\u64C1',48855:'\u64CB',48856:'\u64BB',48857:'\u64BC',48858:'\u64DA',48859:'\u64C4',48860:'\u64C7',48861:'\u64C2',48862:'\u64CD',48863:'\u64BF',48864:'\u64D2',48865:'\u64D4',48866:'\u64BE',48867:'\u6574',48868:'\u66C6',48869:'\u66C9',48870:'\u66B9',48871:'\u66C4',48872:'\u66C7',48873:'\u66B8',48874:'\u6A3D',48875:'\u6A38',48876:'\u6A3A',48877:'\u6A59',48878:'\u6A6B',48879:'\u6A58',48880:'\u6A39',48881:'\u6A44',48882:'\u6A62',48883:'\u6A61',48884:'\u6A4B',48885:'\u6A47',48886:'\u6A35',48887:'\u6A5F',48888:'\u6A48',48889:'\u6B59',48890:'\u6B77',48891:'\u6C05',48892:'\u6FC2',48893:'\u6FB1',48894:'\u6FA1',48960:'\u6FC3',48961:'\u6FA4',48962:'\u6FC1',48963:'\u6FA7',48964:'\u6FB3',48965:'\u6FC0',48966:'\u6FB9',48967:'\u6FB6',48968:'\u6FA6',48969:'\u6FA0',48970:'\u6FB4',48971:'\u71BE',48972:'\u71C9',48973:'\u71D0',48974:'\u71D2',48975:'\u71C8',48976:'\u71D5',48977:'\u71B9',48978:'\u71CE',48979:'\u71D9',48980:'\u71DC',48981:'\u71C3',48982:'\u71C4',48983:'\u7368',48984:'\u749C',48985:'\u74A3',48986:'\u7498',48987:'\u749F',48988:'\u749E',48989:'\u74E2',48990:'\u750C',48991:'\u750D',48992:'\u7634',48993:'\u7638',48994:'\u763A',48995:'\u76E7',48996:'\u76E5',48997:'\u77A0',48998:'\u779E',48999:'\u779F',49000:'\u77A5',49001:'\u78E8',49002:'\u78DA',49003:'\u78EC',49004:'\u78E7',49005:'\u79A6',49006:'\u7A4D',49007:'\u7A4E',49008:'\u7A46',49009:'\u7A4C',49010:'\u7A4B',49011:'\u7ABA',49012:'\u7BD9',49013:'\u7C11',49014:'\u7BC9',49015:'\u7BE4',49016:'\u7BDB',49017:'\u7BE1',49018:'\u7BE9',49019:'\u7BE6',49020:'\u7CD5',49021:'\u7CD6',49022:'\u7E0A',49057:'\u7E11',49058:'\u7E08',49059:'\u7E1B',49060:'\u7E23',49061:'\u7E1E',49062:'\u7E1D',49063:'\u7E09',49064:'\u7E10',49065:'\u7F79',49066:'\u7FB2',49067:'\u7FF0',49068:'\u7FF1',49069:'\u7FEE',49070:'\u8028',49071:'\u81B3',49072:'\u81A9',49073:'\u81A8',49074:'\u81FB',49075:'\u8208',49076:'\u8258',49077:'\u8259',49078:'\u854A',49079:'\u8559',49080:'\u8548',49081:'\u8568',49082:'\u8569',49083:'\u8543',49084:'\u8549',49085:'\u856D',49086:'\u856A',49087:'\u855E',49088:'\u8783',49089:'\u879F',49090:'\u879E',49091:'\u87A2',49092:'\u878D',49093:'\u8861',49094:'\u892A',49095:'\u8932',49096:'\u8925',49097:'\u892B',49098:'\u8921',49099:'\u89AA',49100:'\u89A6',49101:'\u8AE6',49102:'\u8AFA',49103:'\u8AEB',49104:'\u8AF1',49105:'\u8B00',49106:'\u8ADC',49107:'\u8AE7',49108:'\u8AEE',49109:'\u8AFE',49110:'\u8B01',49111:'\u8B02',49112:'\u8AF7',49113:'\u8AED',49114:'\u8AF3',49115:'\u8AF6',49116:'\u8AFC',49117:'\u8C6B',49118:'\u8C6D',49119:'\u8C93',49120:'\u8CF4',49121:'\u8E44',49122:'\u8E31',49123:'\u8E34',49124:'\u8E42',49125:'\u8E39',49126:'\u8E35',49127:'\u8F3B',49128:'\u8F2F',49129:'\u8F38',49130:'\u8F33',49131:'\u8FA8',49132:'\u8FA6',49133:'\u9075',49134:'\u9074',49135:'\u9078',49136:'\u9072',49137:'\u907C',49138:'\u907A',49139:'\u9134',49140:'\u9192',49141:'\u9320',49142:'\u9336',49143:'\u92F8',49144:'\u9333',49145:'\u932F',49146:'\u9322',49147:'\u92FC',49148:'\u932B',49149:'\u9304',49150:'\u931A',49216:'\u9310',49217:'\u9326',49218:'\u9321',49219:'\u9315',49220:'\u932E',49221:'\u9319',49222:'\u95BB',49223:'\u96A7',49224:'\u96A8',49225:'\u96AA',49226:'\u96D5',49227:'\u970E',49228:'\u9711',49229:'\u9716',49230:'\u970D',49231:'\u9713',49232:'\u970F',49233:'\u975B',49234:'\u975C',49235:'\u9766',49236:'\u9798',49237:'\u9830',49238:'\u9838',49239:'\u983B',49240:'\u9837',49241:'\u982D',49242:'\u9839',49243:'\u9824',49244:'\u9910',49245:'\u9928',49246:'\u991E',49247:'\u991B',49248:'\u9921',49249:'\u991A',49250:'\u99ED',49251:'\u99E2',49252:'\u99F1',49253:'\u9AB8',49254:'\u9ABC',49255:'\u9AFB',49256:'\u9AED',49257:'\u9B28',49258:'\u9B91',49259:'\u9D15',49260:'\u9D23',49261:'\u9D26',49262:'\u9D28',49263:'\u9D12',49264:'\u9D1B',49265:'\u9ED8',49266:'\u9ED4',49267:'\u9F8D',49268:'\u9F9C',49269:'\u512A',49270:'\u511F',49271:'\u5121',49272:'\u5132',49273:'\u52F5',49274:'\u568E',49275:'\u5680',49276:'\u5690',49277:'\u5685',49278:'\u5687',49313:'\u568F',49314:'\u58D5',49315:'\u58D3',49316:'\u58D1',49317:'\u58CE',49318:'\u5B30',49319:'\u5B2A',49320:'\u5B24',49321:'\u5B7A',49322:'\u5C37',49323:'\u5C68',49324:'\u5DBC',49325:'\u5DBA',49326:'\u5DBD',49327:'\u5DB8',49328:'\u5E6B',49329:'\u5F4C',49330:'\u5FBD',49331:'\u61C9',49332:'\u61C2',49333:'\u61C7',49334:'\u61E6',49335:'\u61CB',49336:'\u6232',49337:'\u6234',49338:'\u64CE',49339:'\u64CA',49340:'\u64D8',49341:'\u64E0',49342:'\u64F0',49343:'\u64E6',49344:'\u64EC',49345:'\u64F1',49346:'\u64E2',49347:'\u64ED',49348:'\u6582',49349:'\u6583',49350:'\u66D9',49351:'\u66D6',49352:'\u6A80',49353:'\u6A94',49354:'\u6A84',49355:'\u6AA2',49356:'\u6A9C',49357:'\u6ADB',49358:'\u6AA3',49359:'\u6A7E',49360:'\u6A97',49361:'\u6A90',49362:'\u6AA0',49363:'\u6B5C',49364:'\u6BAE',49365:'\u6BDA',49366:'\u6C08',49367:'\u6FD8',49368:'\u6FF1',49369:'\u6FDF',49370:'\u6FE0',49371:'\u6FDB',49372:'\u6FE4',49373:'\u6FEB',49374:'\u6FEF',49375:'\u6F80',49376:'\u6FEC',49377:'\u6FE1',49378:'\u6FE9',49379:'\u6FD5',49380:'\u6FEE',49381:'\u6FF0',49382:'\u71E7',49383:'\u71DF',49384:'\u71EE',49385:'\u71E6',49386:'\u71E5',49387:'\u71ED',49388:'\u71EC',49389:'\u71F4',49390:'\u71E0',49391:'\u7235',49392:'\u7246',49393:'\u7370',49394:'\u7372',49395:'\u74A9',49396:'\u74B0',49397:'\u74A6',49398:'\u74A8',49399:'\u7646',49400:'\u7642',49401:'\u764C',49402:'\u76EA',49403:'\u77B3',49404:'\u77AA',49405:'\u77B0',49406:'\u77AC',49472:'\u77A7',49473:'\u77AD',49474:'\u77EF',49475:'\u78F7',49476:'\u78FA',49477:'\u78F4',49478:'\u78EF',49479:'\u7901',49480:'\u79A7',49481:'\u79AA',49482:'\u7A57',49483:'\u7ABF',49484:'\u7C07',49485:'\u7C0D',49486:'\u7BFE',49487:'\u7BF7',49488:'\u7C0C',49489:'\u7BE0',49490:'\u7CE0',49491:'\u7CDC',49492:'\u7CDE',49493:'\u7CE2',49494:'\u7CDF',49495:'\u7CD9',49496:'\u7CDD',49497:'\u7E2E',49498:'\u7E3E',49499:'\u7E46',49500:'\u7E37',49501:'\u7E32',49502:'\u7E43',49503:'\u7E2B',49504:'\u7E3D',49505:'\u7E31',49506:'\u7E45',49507:'\u7E41',49508:'\u7E34',49509:'\u7E39',49510:'\u7E48',49511:'\u7E35',49512:'\u7E3F',49513:'\u7E2F',49514:'\u7F44',49515:'\u7FF3',49516:'\u7FFC',49517:'\u8071',49518:'\u8072',49519:'\u8070',49520:'\u806F',49521:'\u8073',49522:'\u81C6',49523:'\u81C3',49524:'\u81BA',49525:'\u81C2',49526:'\u81C0',49527:'\u81BF',49528:'\u81BD',49529:'\u81C9',49530:'\u81BE',49531:'\u81E8',49532:'\u8209',49533:'\u8271',49534:'\u85AA',49569:'\u8584',49570:'\u857E',49571:'\u859C',49572:'\u8591',49573:'\u8594',49574:'\u85AF',49575:'\u859B',49576:'\u8587',49577:'\u85A8',49578:'\u858A',49579:'\u8667',49580:'\u87C0',49581:'\u87D1',49582:'\u87B3',49583:'\u87D2',49584:'\u87C6',49585:'\u87AB',49586:'\u87BB',49587:'\u87BA',49588:'\u87C8',49589:'\u87CB',49590:'\u893B',49591:'\u8936',49592:'\u8944',49593:'\u8938',49594:'\u893D',49595:'\u89AC',49596:'\u8B0E',49597:'\u8B17',49598:'\u8B19',49599:'\u8B1B',49600:'\u8B0A',49601:'\u8B20',49602:'\u8B1D',49603:'\u8B04',49604:'\u8B10',49605:'\u8C41',49606:'\u8C3F',49607:'\u8C73',49608:'\u8CFA',49609:'\u8CFD',49610:'\u8CFC',49611:'\u8CF8',49612:'\u8CFB',49613:'\u8DA8',49614:'\u8E49',49615:'\u8E4B',49616:'\u8E48',49617:'\u8E4A',49618:'\u8F44',49619:'\u8F3E',49620:'\u8F42',49621:'\u8F45',49622:'\u8F3F',49623:'\u907F',49624:'\u907D',49625:'\u9084',49626:'\u9081',49627:'\u9082',49628:'\u9080',49629:'\u9139',49630:'\u91A3',49631:'\u919E',49632:'\u919C',49633:'\u934D',49634:'\u9382',49635:'\u9328',49636:'\u9375',49637:'\u934A',49638:'\u9365',49639:'\u934B',49640:'\u9318',49641:'\u937E',49642:'\u936C',49643:'\u935B',49644:'\u9370',49645:'\u935A',49646:'\u9354',49647:'\u95CA',49648:'\u95CB',49649:'\u95CC',49650:'\u95C8',49651:'\u95C6',49652:'\u96B1',49653:'\u96B8',49654:'\u96D6',49655:'\u971C',49656:'\u971E',49657:'\u97A0',49658:'\u97D3',49659:'\u9846',49660:'\u98B6',49661:'\u9935',49662:'\u9A01',49728:'\u99FF',49729:'\u9BAE',49730:'\u9BAB',49731:'\u9BAA',49732:'\u9BAD',49733:'\u9D3B',49734:'\u9D3F',49735:'\u9E8B',49736:'\u9ECF',49737:'\u9EDE',49738:'\u9EDC',49739:'\u9EDD',49740:'\u9EDB',49741:'\u9F3E',49742:'\u9F4B',49743:'\u53E2',49744:'\u5695',49745:'\u56AE',49746:'\u58D9',49747:'\u58D8',49748:'\u5B38',49749:'\u5F5D',49750:'\u61E3',49751:'\u6233',49752:'\u64F4',49753:'\u64F2',49754:'\u64FE',49755:'\u6506',49756:'\u64FA',49757:'\u64FB',49758:'\u64F7',49759:'\u65B7',49760:'\u66DC',49761:'\u6726',49762:'\u6AB3',49763:'\u6AAC',49764:'\u6AC3',49765:'\u6ABB',49766:'\u6AB8',49767:'\u6AC2',49768:'\u6AAE',49769:'\u6AAF',49770:'\u6B5F',49771:'\u6B78',49772:'\u6BAF',49773:'\u7009',49774:'\u700B',49775:'\u6FFE',49776:'\u7006',49777:'\u6FFA',49778:'\u7011',49779:'\u700F',49780:'\u71FB',49781:'\u71FC',49782:'\u71FE',49783:'\u71F8',49784:'\u7377',49785:'\u7375',49786:'\u74A7',49787:'\u74BF',49788:'\u7515',49789:'\u7656',49790:'\u7658',49825:'\u7652',49826:'\u77BD',49827:'\u77BF',49828:'\u77BB',49829:'\u77BC',49830:'\u790E',49831:'\u79AE',49832:'\u7A61',49833:'\u7A62',49834:'\u7A60',49835:'\u7AC4',49836:'\u7AC5',49837:'\u7C2B',49838:'\u7C27',49839:'\u7C2A',49840:'\u7C1E',49841:'\u7C23',49842:'\u7C21',49843:'\u7CE7',49844:'\u7E54',49845:'\u7E55',49846:'\u7E5E',49847:'\u7E5A',49848:'\u7E61',49849:'\u7E52',49850:'\u7E59',49851:'\u7F48',49852:'\u7FF9',49853:'\u7FFB',49854:'\u8077',49855:'\u8076',49856:'\u81CD',49857:'\u81CF',49858:'\u820A',49859:'\u85CF',49860:'\u85A9',49861:'\u85CD',49862:'\u85D0',49863:'\u85C9',49864:'\u85B0',49865:'\u85BA',49866:'\u85B9',49867:'\u85A6',49868:'\u87EF',49869:'\u87EC',49870:'\u87F2',49871:'\u87E0',49872:'\u8986',49873:'\u89B2',49874:'\u89F4',49875:'\u8B28',49876:'\u8B39',49877:'\u8B2C',49878:'\u8B2B',49879:'\u8C50',49880:'\u8D05',49881:'\u8E59',49882:'\u8E63',49883:'\u8E66',49884:'\u8E64',49885:'\u8E5F',49886:'\u8E55',49887:'\u8EC0',49888:'\u8F49',49889:'\u8F4D',49890:'\u9087',49891:'\u9083',49892:'\u9088',49893:'\u91AB',49894:'\u91AC',49895:'\u91D0',49896:'\u9394',49897:'\u938A',49898:'\u9396',49899:'\u93A2',49900:'\u93B3',49901:'\u93AE',49902:'\u93AC',49903:'\u93B0',49904:'\u9398',49905:'\u939A',49906:'\u9397',49907:'\u95D4',49908:'\u95D6',49909:'\u95D0',49910:'\u95D5',49911:'\u96E2',49912:'\u96DC',49913:'\u96D9',49914:'\u96DB',49915:'\u96DE',49916:'\u9724',49917:'\u97A3',49918:'\u97A6',49984:'\u97AD',49985:'\u97F9',49986:'\u984D',49987:'\u984F',49988:'\u984C',49989:'\u984E',49990:'\u9853',49991:'\u98BA',49992:'\u993E',49993:'\u993F',49994:'\u993D',49995:'\u992E',49996:'\u99A5',49997:'\u9A0E',49998:'\u9AC1',49999:'\u9B03',50000:'\u9B06',50001:'\u9B4F',50002:'\u9B4E',50003:'\u9B4D',50004:'\u9BCA',50005:'\u9BC9',50006:'\u9BFD',50007:'\u9BC8',50008:'\u9BC0',50009:'\u9D51',50010:'\u9D5D',50011:'\u9D60',50012:'\u9EE0',50013:'\u9F15',50014:'\u9F2C',50015:'\u5133',50016:'\u56A5',50017:'\u58DE',50018:'\u58DF',50019:'\u58E2',50020:'\u5BF5',50021:'\u9F90',50022:'\u5EEC',50023:'\u61F2',50024:'\u61F7',50025:'\u61F6',50026:'\u61F5',50027:'\u6500',50028:'\u650F',50029:'\u66E0',50030:'\u66DD',50031:'\u6AE5',50032:'\u6ADD',50033:'\u6ADA',50034:'\u6AD3',50035:'\u701B',50036:'\u701F',50037:'\u7028',50038:'\u701A',50039:'\u701D',50040:'\u7015',50041:'\u7018',50042:'\u7206',50043:'\u720D',50044:'\u7258',50045:'\u72A2',50046:'\u7378',50081:'\u737A',50082:'\u74BD',50083:'\u74CA',50084:'\u74E3',50085:'\u7587',50086:'\u7586',50087:'\u765F',50088:'\u7661',50089:'\u77C7',50090:'\u7919',50091:'\u79B1',50092:'\u7A6B',50093:'\u7A69',50094:'\u7C3E',50095:'\u7C3F',50096:'\u7C38',50097:'\u7C3D',50098:'\u7C37',50099:'\u7C40',50100:'\u7E6B',50101:'\u7E6D',50102:'\u7E79',50103:'\u7E69',50104:'\u7E6A',50105:'\u7F85',50106:'\u7E73',50107:'\u7FB6',50108:'\u7FB9',50109:'\u7FB8',50110:'\u81D8',50111:'\u85E9',50112:'\u85DD',50113:'\u85EA',50114:'\u85D5',50115:'\u85E4',50116:'\u85E5',50117:'\u85F7',50118:'\u87FB',50119:'\u8805',50120:'\u880D',50121:'\u87F9',50122:'\u87FE',50123:'\u8960',50124:'\u895F',50125:'\u8956',50126:'\u895E',50127:'\u8B41',50128:'\u8B5C',50129:'\u8B58',50130:'\u8B49',50131:'\u8B5A',50132:'\u8B4E',50133:'\u8B4F',50134:'\u8B46',50135:'\u8B59',50136:'\u8D08',50137:'\u8D0A',50138:'\u8E7C',50139:'\u8E72',50140:'\u8E87',50141:'\u8E76',50142:'\u8E6C',50143:'\u8E7A',50144:'\u8E74',50145:'\u8F54',50146:'\u8F4E',50147:'\u8FAD',50148:'\u908A',50149:'\u908B',50150:'\u91B1',50151:'\u91AE',50152:'\u93E1',50153:'\u93D1',50154:'\u93DF',50155:'\u93C3',50156:'\u93C8',50157:'\u93DC',50158:'\u93DD',50159:'\u93D6',50160:'\u93E2',50161:'\u93CD',50162:'\u93D8',50163:'\u93E4',50164:'\u93D7',50165:'\u93E8',50166:'\u95DC',50167:'\u96B4',50168:'\u96E3',50169:'\u972A',50170:'\u9727',50171:'\u9761',50172:'\u97DC',50173:'\u97FB',50174:'\u985E',50240:'\u9858',50241:'\u985B',50242:'\u98BC',50243:'\u9945',50244:'\u9949',50245:'\u9A16',50246:'\u9A19',50247:'\u9B0D',50248:'\u9BE8',50249:'\u9BE7',50250:'\u9BD6',50251:'\u9BDB',50252:'\u9D89',50253:'\u9D61',50254:'\u9D72',50255:'\u9D6A',50256:'\u9D6C',50257:'\u9E92',50258:'\u9E97',50259:'\u9E93',50260:'\u9EB4',50261:'\u52F8',50262:'\u56A8',50263:'\u56B7',50264:'\u56B6',50265:'\u56B4',50266:'\u56BC',50267:'\u58E4',50268:'\u5B40',50269:'\u5B43',50270:'\u5B7D',50271:'\u5BF6',50272:'\u5DC9',50273:'\u61F8',50274:'\u61FA',50275:'\u6518',50276:'\u6514',50277:'\u6519',50278:'\u66E6',50279:'\u6727',50280:'\u6AEC',50281:'\u703E',50282:'\u7030',50283:'\u7032',50284:'\u7210',50285:'\u737B',50286:'\u74CF',50287:'\u7662',50288:'\u7665',50289:'\u7926',50290:'\u792A',50291:'\u792C',50292:'\u792B',50293:'\u7AC7',50294:'\u7AF6',50295:'\u7C4C',50296:'\u7C43',50297:'\u7C4D',50298:'\u7CEF',50299:'\u7CF0',50300:'\u8FAE',50301:'\u7E7D',50302:'\u7E7C',50337:'\u7E82',50338:'\u7F4C',50339:'\u8000',50340:'\u81DA',50341:'\u8266',50342:'\u85FB',50343:'\u85F9',50344:'\u8611',50345:'\u85FA',50346:'\u8606',50347:'\u860B',50348:'\u8607',50349:'\u860A',50350:'\u8814',50351:'\u8815',50352:'\u8964',50353:'\u89BA',50354:'\u89F8',50355:'\u8B70',50356:'\u8B6C',50357:'\u8B66',50358:'\u8B6F',50359:'\u8B5F',50360:'\u8B6B',50361:'\u8D0F',50362:'\u8D0D',50363:'\u8E89',50364:'\u8E81',50365:'\u8E85',50366:'\u8E82',50367:'\u91B4',50368:'\u91CB',50369:'\u9418',50370:'\u9403',50371:'\u93FD',50372:'\u95E1',50373:'\u9730',50374:'\u98C4',50375:'\u9952',50376:'\u9951',50377:'\u99A8',50378:'\u9A2B',50379:'\u9A30',50380:'\u9A37',50381:'\u9A35',50382:'\u9C13',50383:'\u9C0D',50384:'\u9E79',50385:'\u9EB5',50386:'\u9EE8',50387:'\u9F2F',50388:'\u9F5F',50389:'\u9F63',50390:'\u9F61',50391:'\u5137',50392:'\u5138',50393:'\u56C1',50394:'\u56C0',50395:'\u56C2',50396:'\u5914',50397:'\u5C6C',50398:'\u5DCD',50399:'\u61FC',50400:'\u61FE',50401:'\u651D',50402:'\u651C',50403:'\u6595',50404:'\u66E9',50405:'\u6AFB',50406:'\u6B04',50407:'\u6AFA',50408:'\u6BB2',50409:'\u704C',50410:'\u721B',50411:'\u72A7',50412:'\u74D6',50413:'\u74D4',50414:'\u7669',50415:'\u77D3',50416:'\u7C50',50417:'\u7E8F',50418:'\u7E8C',50419:'\u7FBC',50420:'\u8617',50421:'\u862D',50422:'\u861A',50423:'\u8823',50424:'\u8822',50425:'\u8821',50426:'\u881F',50427:'\u896A',50428:'\u896C',50429:'\u89BD',50430:'\u8B74',50496:'\u8B77',50497:'\u8B7D',50498:'\u8D13',50499:'\u8E8A',50500:'\u8E8D',50501:'\u8E8B',50502:'\u8F5F',50503:'\u8FAF',50504:'\u91BA',50505:'\u942E',50506:'\u9433',50507:'\u9435',50508:'\u943A',50509:'\u9438',50510:'\u9432',50511:'\u942B',50512:'\u95E2',50513:'\u9738',50514:'\u9739',50515:'\u9732',50516:'\u97FF',50517:'\u9867',50518:'\u9865',50519:'\u9957',50520:'\u9A45',50521:'\u9A43',50522:'\u9A40',50523:'\u9A3E',50524:'\u9ACF',50525:'\u9B54',50526:'\u9B51',50527:'\u9C2D',50528:'\u9C25',50529:'\u9DAF',50530:'\u9DB4',50531:'\u9DC2',50532:'\u9DB8',50533:'\u9E9D',50534:'\u9EEF',50535:'\u9F19',50536:'\u9F5C',50537:'\u9F66',50538:'\u9F67',50539:'\u513C',50540:'\u513B',50541:'\u56C8',50542:'\u56CA',50543:'\u56C9',50544:'\u5B7F',50545:'\u5DD4',50546:'\u5DD2',50547:'\u5F4E',50548:'\u61FF',50549:'\u6524',50550:'\u6B0A',50551:'\u6B61',50552:'\u7051',50553:'\u7058',50554:'\u7380',50555:'\u74E4',50556:'\u758A',50557:'\u766E',50558:'\u766C',50593:'\u79B3',50594:'\u7C60',50595:'\u7C5F',50596:'\u807E',50597:'\u807D',50598:'\u81DF',50599:'\u8972',50600:'\u896F',50601:'\u89FC',50602:'\u8B80',50603:'\u8D16',50604:'\u8D17',50605:'\u8E91',50606:'\u8E93',50607:'\u8F61',50608:'\u9148',50609:'\u9444',50610:'\u9451',50611:'\u9452',50612:'\u973D',50613:'\u973E',50614:'\u97C3',50615:'\u97C1',50616:'\u986B',50617:'\u9955',50618:'\u9A55',50619:'\u9A4D',50620:'\u9AD2',50621:'\u9B1A',50622:'\u9C49',50623:'\u9C31',50624:'\u9C3E',50625:'\u9C3B',50626:'\u9DD3',50627:'\u9DD7',50628:'\u9F34',50629:'\u9F6C',50630:'\u9F6A',50631:'\u9F94',50632:'\u56CC',50633:'\u5DD6',50634:'\u6200',50635:'\u6523',50636:'\u652B',50637:'\u652A',50638:'\u66EC',50639:'\u6B10',50640:'\u74DA',50641:'\u7ACA',50642:'\u7C64',50643:'\u7C63',50644:'\u7C65',50645:'\u7E93',50646:'\u7E96',50647:'\u7E94',50648:'\u81E2',50649:'\u8638',50650:'\u863F',50651:'\u8831',50652:'\u8B8A',50653:'\u9090',50654:'\u908F',50655:'\u9463',50656:'\u9460',50657:'\u9464',50658:'\u9768',50659:'\u986F',50660:'\u995C',50661:'\u9A5A',50662:'\u9A5B',50663:'\u9A57',50664:'\u9AD3',50665:'\u9AD4',50666:'\u9AD1',50667:'\u9C54',50668:'\u9C57',50669:'\u9C56',50670:'\u9DE5',50671:'\u9E9F',50672:'\u9EF4',50673:'\u56D1',50674:'\u58E9',50675:'\u652C',50676:'\u705E',50677:'\u7671',50678:'\u7672',50679:'\u77D7',50680:'\u7F50',50681:'\u7F88',50682:'\u8836',50683:'\u8839',50684:'\u8862',50685:'\u8B93',50686:'\u8B92',50752:'\u8B96',50753:'\u8277',50754:'\u8D1B',50755:'\u91C0',50756:'\u946A',50757:'\u9742',50758:'\u9748',50759:'\u9744',50760:'\u97C6',50761:'\u9870',50762:'\u9A5F',50763:'\u9B22',50764:'\u9B58',50765:'\u9C5F',50766:'\u9DF9',50767:'\u9DFA',50768:'\u9E7C',50769:'\u9E7D',50770:'\u9F07',50771:'\u9F77',50772:'\u9F72',50773:'\u5EF3',50774:'\u6B16',50775:'\u7063',50776:'\u7C6C',50777:'\u7C6E',50778:'\u883B',50779:'\u89C0',50780:'\u8EA1',50781:'\u91C1',50782:'\u9472',50783:'\u9470',50784:'\u9871',50785:'\u995E',50786:'\u9AD6',50787:'\u9B23',50788:'\u9ECC',50789:'\u7064',50790:'\u77DA',50791:'\u8B9A',50792:'\u9477',50793:'\u97C9',50794:'\u9A62',50795:'\u9A65',50796:'\u7E9C',50797:'\u8B9C',50798:'\u8EAA',50799:'\u91C5',50800:'\u947D',50801:'\u947E',50802:'\u947C',50803:'\u9C77',50804:'\u9C78',50805:'\u9EF7',50806:'\u8C54',50807:'\u947F',50808:'\u9E1A',50809:'\u7228',50810:'\u9A6A',50811:'\u9B31',50812:'\u9E1B',50813:'\u9E1E',50814:'\u7C72',50849:'\uF6B1',50850:'\uF6B2',50851:'\uF6B3',50852:'\uF6B4',50853:'\uF6B5',50854:'\uF6B6',50855:'\uF6B7',50856:'\uF6B8',50857:'\uF6B9',50858:'\uF6BA',50859:'\uF6BB',50860:'\uF6BC',50861:'\uF6BD',50862:'\uF6BE',50863:'\uF6BF',50864:'\uF6C0',50865:'\uF6C1',50866:'\uF6C2',50867:'\uF6C3',50868:'\uF6C4',50869:'\uF6C5',50870:'\uF6C6',50871:'\uF6C7',50872:'\uF6C8',50873:'\uF6C9',50874:'\uF6CA',50875:'\uF6CB',50876:'\uF6CC',50877:'\uF6CD',50878:'\uF6CE',50879:'\uF6CF',50880:'\uF6D0',50881:'\uF6D1',50882:'\uF6D2',50883:'\uF6D3',50884:'\uF6D4',50885:'\uF6D5',50886:'\uF6D6',50887:'\uF6D7',50888:'\uF6D8',50889:'\uF6D9',50890:'\uF6DA',50891:'\uF6DB',50892:'\uF6DC',50893:'\uF6DD',50894:'\uF6DE',50895:'\uF6DF',50896:'\uF6E0',50897:'\uF6E1',50898:'\uF6E2',50899:'\uF6E3',50900:'\uF6E4',50901:'\uF6E5',50902:'\uF6E6',50903:'\uF6E7',50904:'\uF6E8',50905:'\uF6E9',50906:'\uF6EA',50907:'\uF6EB',50908:'\uF6EC',50909:'\uF6ED',50910:'\uF6EE',50911:'\uF6EF',50912:'\uF6F0',50913:'\uF6F1',50914:'\uF6F2',50915:'\uF6F3',50916:'\uF6F4',50917:'\uF6F5',50918:'\uF6F6',50919:'\uF6F7',50920:'\uF6F8',50921:'\uF6F9',50922:'\uF6FA',50923:'\uF6FB',50924:'\uF6FC',50925:'\uF6FD',50926:'\uF6FE',50927:'\uF6FF',50928:'\uF700',50929:'\uF701',50930:'\uF702',50931:'\uF703',50932:'\uF704',50933:'\uF705',50934:'\uF706',50935:'\uF707',50936:'\uF708',50937:'\uF709',50938:'\uF70A',50939:'\uF70B',50940:'\uF70C',50941:'\uF70D',50942:'\uF70E',51008:'\uF70F',51009:'\uF710',51010:'\uF711',51011:'\uF712',51012:'\uF713',51013:'\uF714',51014:'\uF715',51015:'\uF716',51016:'\uF717',51017:'\uF718',51018:'\uF719',51019:'\uF71A',51020:'\uF71B',51021:'\uF71C',51022:'\uF71D',51023:'\uF71E',51024:'\uF71F',51025:'\uF720',51026:'\uF721',51027:'\uF722',51028:'\uF723',51029:'\uF724',51030:'\uF725',51031:'\uF726',51032:'\uF727',51033:'\uF728',51034:'\uF729',51035:'\uF72A',51036:'\uF72B',51037:'\uF72C',51038:'\uF72D',51039:'\uF72E',51040:'\uF72F',51041:'\uF730',51042:'\uF731',51043:'\uF732',51044:'\uF733',51045:'\uF734',51046:'\uF735',51047:'\uF736',51048:'\uF737',51049:'\uF738',51050:'\uF739',51051:'\uF73A',51052:'\uF73B',51053:'\uF73C',51054:'\uF73D',51055:'\uF73E',51056:'\uF73F',51057:'\uF740',51058:'\uF741',51059:'\uF742',51060:'\uF743',51061:'\uF744',51062:'\uF745',51063:'\uF746',51064:'\uF747',51065:'\uF748',51066:'\uF749',51067:'\uF74A',51068:'\uF74B',51069:'\uF74C',51070:'\uF74D',51105:'\uF74E',51106:'\uF74F',51107:'\uF750',51108:'\uF751',51109:'\uF752',51110:'\uF753',51111:'\uF754',51112:'\uF755',51113:'\uF756',51114:'\uF757',51115:'\uF758',51116:'\uF759',51117:'\uF75A',51118:'\uF75B',51119:'\uF75C',51120:'\uF75D',51121:'\uF75E',51122:'\uF75F',51123:'\uF760',51124:'\uF761',51125:'\uF762',51126:'\uF763',51127:'\uF764',51128:'\uF765',51129:'\uF766',51130:'\uF767',51131:'\uF768',51132:'\uF769',51133:'\uF76A',51134:'\uF76B',51135:'\uF76C',51136:'\uF76D',51137:'\uF76E',51138:'\uF76F',51139:'\uF770',51140:'\uF771',51141:'\uF772',51142:'\uF773',51143:'\uF774',51144:'\uF775',51145:'\uF776',51146:'\uF777',51147:'\uF778',51148:'\uF779',51149:'\uF77A',51150:'\uF77B',51151:'\uF77C',51152:'\uF77D',51153:'\uF77E',51154:'\uF77F',51155:'\uF780',51156:'\uF781',51157:'\uF782',51158:'\uF783',51159:'\uF784',51160:'\uF785',51161:'\uF786',51162:'\uF787',51163:'\uF788',51164:'\uF789',51165:'\uF78A',51166:'\uF78B',51167:'\uF78C',51168:'\uF78D',51169:'\uF78E',51170:'\uF78F',51171:'\uF790',51172:'\uF791',51173:'\uF792',51174:'\uF793',51175:'\uF794',51176:'\uF795',51177:'\uF796',51178:'\uF797',51179:'\uF798',51180:'\uF799',51181:'\uF79A',51182:'\uF79B',51183:'\uF79C',51184:'\uF79D',51185:'\uF79E',51186:'\uF79F',51187:'\uF7A0',51188:'\uF7A1',51189:'\uF7A2',51190:'\uF7A3',51191:'\uF7A4',51192:'\uF7A5',51193:'\uF7A6',51194:'\uF7A7',51195:'\uF7A8',51196:'\uF7A9',51197:'\uF7AA',51198:'\uF7AB',51264:'\uF7AC',51265:'\uF7AD',51266:'\uF7AE',51267:'\uF7AF',51268:'\uF7B0',51269:'\uF7B1',51270:'\uF7B2',51271:'\uF7B3',51272:'\uF7B4',51273:'\uF7B5',51274:'\uF7B6',51275:'\uF7B7',51276:'\uF7B8',51277:'\uF7B9',51278:'\uF7BA',51279:'\uF7BB',51280:'\uF7BC',51281:'\uF7BD',51282:'\uF7BE',51283:'\uF7BF',51284:'\uF7C0',51285:'\uF7C1',51286:'\uF7C2',51287:'\uF7C3',51288:'\uF7C4',51289:'\uF7C5',51290:'\uF7C6',51291:'\uF7C7',51292:'\uF7C8',51293:'\uF7C9',51294:'\uF7CA',51295:'\uF7CB',51296:'\uF7CC',51297:'\uF7CD',51298:'\uF7CE',51299:'\uF7CF',51300:'\uF7D0',51301:'\uF7D1',51302:'\uF7D2',51303:'\uF7D3',51304:'\uF7D4',51305:'\uF7D5',51306:'\uF7D6',51307:'\uF7D7',51308:'\uF7D8',51309:'\uF7D9',51310:'\uF7DA',51311:'\uF7DB',51312:'\uF7DC',51313:'\uF7DD',51314:'\uF7DE',51315:'\uF7DF',51316:'\uF7E0',51317:'\uF7E1',51318:'\uF7E2',51319:'\uF7E3',51320:'\uF7E4',51321:'\uF7E5',51322:'\uF7E6',51323:'\uF7E7',51324:'\uF7E8',51325:'\uF7E9',51326:'\uF7EA',51361:'\uF7EB',51362:'\uF7EC',51363:'\uF7ED',51364:'\uF7EE',51365:'\uF7EF',51366:'\uF7F0',51367:'\uF7F1',51368:'\uF7F2',51369:'\uF7F3',51370:'\uF7F4',51371:'\uF7F5',51372:'\uF7F6',51373:'\uF7F7',51374:'\uF7F8',51375:'\uF7F9',51376:'\uF7FA',51377:'\uF7FB',51378:'\uF7FC',51379:'\uF7FD',51380:'\uF7FE',51381:'\uF7FF',51382:'\uF800',51383:'\uF801',51384:'\uF802',51385:'\uF803',51386:'\uF804',51387:'\uF805',51388:'\uF806',51389:'\uF807',51390:'\uF808',51391:'\uF809',51392:'\uF80A',51393:'\uF80B',51394:'\uF80C',51395:'\uF80D',51396:'\uF80E',51397:'\uF80F',51398:'\uF810',51399:'\uF811',51400:'\uF812',51401:'\uF813',51402:'\uF814',51403:'\uF815',51404:'\uF816',51405:'\uF817',51406:'\uF818',51407:'\uF819',51408:'\uF81A',51409:'\uF81B',51410:'\uF81C',51411:'\uF81D',51412:'\uF81E',51413:'\uF81F',51414:'\uF820',51415:'\uF821',51416:'\uF822',51417:'\uF823',51418:'\uF824',51419:'\uF825',51420:'\uF826',51421:'\uF827',51422:'\uF828',51423:'\uF829',51424:'\uF82A',51425:'\uF82B',51426:'\uF82C',51427:'\uF82D',51428:'\uF82E',51429:'\uF82F',51430:'\uF830',51431:'\uF831',51432:'\uF832',51433:'\uF833',51434:'\uF834',51435:'\uF835',51436:'\uF836',51437:'\uF837',51438:'\uF838',51439:'\uF839',51440:'\uF83A',51441:'\uF83B',51442:'\uF83C',51443:'\uF83D',51444:'\uF83E',51445:'\uF83F',51446:'\uF840',51447:'\uF841',51448:'\uF842',51449:'\uF843',51450:'\uF844',51451:'\uF845',51452:'\uF846',51453:'\uF847',51454:'\uF848',51520:'\u4E42',51521:'\u4E5C',51522:'\u51F5',51523:'\u531A',51524:'\u5382',51525:'\u4E07',51526:'\u4E0C',51527:'\u4E47',51528:'\u4E8D',51529:'\u56D7',51530:'\uFA0C',51531:'\u5C6E',51532:'\u5F73',51533:'\u4E0F',51534:'\u5187',51535:'\u4E0E',51536:'\u4E2E',51537:'\u4E93',51538:'\u4EC2',51539:'\u4EC9',51540:'\u4EC8',51541:'\u5198',51542:'\u52FC',51543:'\u536C',51544:'\u53B9',51545:'\u5720',51546:'\u5903',51547:'\u592C',51548:'\u5C10',51549:'\u5DFF',51550:'\u65E1',51551:'\u6BB3',51552:'\u6BCC',51553:'\u6C14',51554:'\u723F',51555:'\u4E31',51556:'\u4E3C',51557:'\u4EE8',51558:'\u4EDC',51559:'\u4EE9',51560:'\u4EE1',51561:'\u4EDD',51562:'\u4EDA',51563:'\u520C',51564:'\u531C',51565:'\u534C',51566:'\u5722',51567:'\u5723',51568:'\u5917',51569:'\u592F',51570:'\u5B81',51571:'\u5B84',51572:'\u5C12',51573:'\u5C3B',51574:'\u5C74',51575:'\u5C73',51576:'\u5E04',51577:'\u5E80',51578:'\u5E82',51579:'\u5FC9',51580:'\u6209',51581:'\u6250',51582:'\u6C15',51617:'\u6C36',51618:'\u6C43',51619:'\u6C3F',51620:'\u6C3B',51621:'\u72AE',51622:'\u72B0',51623:'\u738A',51624:'\u79B8',51625:'\u808A',51626:'\u961E',51627:'\u4F0E',51628:'\u4F18',51629:'\u4F2C',51630:'\u4EF5',51631:'\u4F14',51632:'\u4EF1',51633:'\u4F00',51634:'\u4EF7',51635:'\u4F08',51636:'\u4F1D',51637:'\u4F02',51638:'\u4F05',51639:'\u4F22',51640:'\u4F13',51641:'\u4F04',51642:'\u4EF4',51643:'\u4F12',51644:'\u51B1',51645:'\u5213',51646:'\u5209',51647:'\u5210',51648:'\u52A6',51649:'\u5322',51650:'\u531F',51651:'\u534D',51652:'\u538A',51653:'\u5407',51654:'\u56E1',51655:'\u56DF',51656:'\u572E',51657:'\u572A',51658:'\u5734',51659:'\u593C',51660:'\u5980',51661:'\u597C',51662:'\u5985',51663:'\u597B',51664:'\u597E',51665:'\u5977',51666:'\u597F',51667:'\u5B56',51668:'\u5C15',51669:'\u5C25',51670:'\u5C7C',51671:'\u5C7A',51672:'\u5C7B',51673:'\u5C7E',51674:'\u5DDF',51675:'\u5E75',51676:'\u5E84',51677:'\u5F02',51678:'\u5F1A',51679:'\u5F74',51680:'\u5FD5',51681:'\u5FD4',51682:'\u5FCF',51683:'\u625C',51684:'\u625E',51685:'\u6264',51686:'\u6261',51687:'\u6266',51688:'\u6262',51689:'\u6259',51690:'\u6260',51691:'\u625A',51692:'\u6265',51693:'\u65EF',51694:'\u65EE',51695:'\u673E',51696:'\u6739',51697:'\u6738',51698:'\u673B',51699:'\u673A',51700:'\u673F',51701:'\u673C',51702:'\u6733',51703:'\u6C18',51704:'\u6C46',51705:'\u6C52',51706:'\u6C5C',51707:'\u6C4F',51708:'\u6C4A',51709:'\u6C54',51710:'\u6C4B',51776:'\u6C4C',51777:'\u7071',51778:'\u725E',51779:'\u72B4',51780:'\u72B5',51781:'\u738E',51782:'\u752A',51783:'\u767F',51784:'\u7A75',51785:'\u7F51',51786:'\u8278',51787:'\u827C',51788:'\u8280',51789:'\u827D',51790:'\u827F',51791:'\u864D',51792:'\u897E',51793:'\u9099',51794:'\u9097',51795:'\u9098',51796:'\u909B',51797:'\u9094',51798:'\u9622',51799:'\u9624',51800:'\u9620',51801:'\u9623',51802:'\u4F56',51803:'\u4F3B',51804:'\u4F62',51805:'\u4F49',51806:'\u4F53',51807:'\u4F64',51808:'\u4F3E',51809:'\u4F67',51810:'\u4F52',51811:'\u4F5F',51812:'\u4F41',51813:'\u4F58',51814:'\u4F2D',51815:'\u4F33',51816:'\u4F3F',51817:'\u4F61',51818:'\u518F',51819:'\u51B9',51820:'\u521C',51821:'\u521E',51822:'\u5221',51823:'\u52AD',51824:'\u52AE',51825:'\u5309',51826:'\u5363',51827:'\u5372',51828:'\u538E',51829:'\u538F',51830:'\u5430',51831:'\u5437',51832:'\u542A',51833:'\u5454',51834:'\u5445',51835:'\u5419',51836:'\u541C',51837:'\u5425',51838:'\u5418',51873:'\u543D',51874:'\u544F',51875:'\u5441',51876:'\u5428',51877:'\u5424',51878:'\u5447',51879:'\u56EE',51880:'\u56E7',51881:'\u56E5',51882:'\u5741',51883:'\u5745',51884:'\u574C',51885:'\u5749',51886:'\u574B',51887:'\u5752',51888:'\u5906',51889:'\u5940',51890:'\u59A6',51891:'\u5998',51892:'\u59A0',51893:'\u5997',51894:'\u598E',51895:'\u59A2',51896:'\u5990',51897:'\u598F',51898:'\u59A7',51899:'\u59A1',51900:'\u5B8E',51901:'\u5B92',51902:'\u5C28',51903:'\u5C2A',51904:'\u5C8D',51905:'\u5C8F',51906:'\u5C88',51907:'\u5C8B',51908:'\u5C89',51909:'\u5C92',51910:'\u5C8A',51911:'\u5C86',51912:'\u5C93',51913:'\u5C95',51914:'\u5DE0',51915:'\u5E0A',51916:'\u5E0E',51917:'\u5E8B',51918:'\u5E89',51919:'\u5E8C',51920:'\u5E88',51921:'\u5E8D',51922:'\u5F05',51923:'\u5F1D',51924:'\u5F78',51925:'\u5F76',51926:'\u5FD2',51927:'\u5FD1',51928:'\u5FD0',51929:'\u5FED',51930:'\u5FE8',51931:'\u5FEE',51932:'\u5FF3',51933:'\u5FE1',51934:'\u5FE4',51935:'\u5FE3',51936:'\u5FFA',51937:'\u5FEF',51938:'\u5FF7',51939:'\u5FFB',51940:'\u6000',51941:'\u5FF4',51942:'\u623A',51943:'\u6283',51944:'\u628C',51945:'\u628E',51946:'\u628F',51947:'\u6294',51948:'\u6287',51949:'\u6271',51950:'\u627B',51951:'\u627A',51952:'\u6270',51953:'\u6281',51954:'\u6288',51955:'\u6277',51956:'\u627D',51957:'\u6272',51958:'\u6274',51959:'\u6537',51960:'\u65F0',51961:'\u65F4',51962:'\u65F3',51963:'\u65F2',51964:'\u65F5',51965:'\u6745',51966:'\u6747',52032:'\u6759',52033:'\u6755',52034:'\u674C',52035:'\u6748',52036:'\u675D',52037:'\u674D',52038:'\u675A',52039:'\u674B',52040:'\u6BD0',52041:'\u6C19',52042:'\u6C1A',52043:'\u6C78',52044:'\u6C67',52045:'\u6C6B',52046:'\u6C84',52047:'\u6C8B',52048:'\u6C8F',52049:'\u6C71',52050:'\u6C6F',52051:'\u6C69',52052:'\u6C9A',52053:'\u6C6D',52054:'\u6C87',52055:'\u6C95',52056:'\u6C9C',52057:'\u6C66',52058:'\u6C73',52059:'\u6C65',52060:'\u6C7B',52061:'\u6C8E',52062:'\u7074',52063:'\u707A',52064:'\u7263',52065:'\u72BF',52066:'\u72BD',52067:'\u72C3',52068:'\u72C6',52069:'\u72C1',52070:'\u72BA',52071:'\u72C5',52072:'\u7395',52073:'\u7397',52074:'\u7393',52075:'\u7394',52076:'\u7392',52077:'\u753A',52078:'\u7539',52079:'\u7594',52080:'\u7595',52081:'\u7681',52082:'\u793D',52083:'\u8034',52084:'\u8095',52085:'\u8099',52086:'\u8090',52087:'\u8092',52088:'\u809C',52089:'\u8290',52090:'\u828F',52091:'\u8285',52092:'\u828E',52093:'\u8291',52094:'\u8293',52129:'\u828A',52130:'\u8283',52131:'\u8284',52132:'\u8C78',52133:'\u8FC9',52134:'\u8FBF',52135:'\u909F',52136:'\u90A1',52137:'\u90A5',52138:'\u909E',52139:'\u90A7',52140:'\u90A0',52141:'\u9630',52142:'\u9628',52143:'\u962F',52144:'\u962D',52145:'\u4E33',52146:'\u4F98',52147:'\u4F7C',52148:'\u4F85',52149:'\u4F7D',52150:'\u4F80',52151:'\u4F87',52152:'\u4F76',52153:'\u4F74',52154:'\u4F89',52155:'\u4F84',52156:'\u4F77',52157:'\u4F4C',52158:'\u4F97',52159:'\u4F6A',52160:'\u4F9A',52161:'\u4F79',52162:'\u4F81',52163:'\u4F78',52164:'\u4F90',52165:'\u4F9C',52166:'\u4F94',52167:'\u4F9E',52168:'\u4F92',52169:'\u4F82',52170:'\u4F95',52171:'\u4F6B',52172:'\u4F6E',52173:'\u519E',52174:'\u51BC',52175:'\u51BE',52176:'\u5235',52177:'\u5232',52178:'\u5233',52179:'\u5246',52180:'\u5231',52181:'\u52BC',52182:'\u530A',52183:'\u530B',52184:'\u533C',52185:'\u5392',52186:'\u5394',52187:'\u5487',52188:'\u547F',52189:'\u5481',52190:'\u5491',52191:'\u5482',52192:'\u5488',52193:'\u546B',52194:'\u547A',52195:'\u547E',52196:'\u5465',52197:'\u546C',52198:'\u5474',52199:'\u5466',52200:'\u548D',52201:'\u546F',52202:'\u5461',52203:'\u5460',52204:'\u5498',52205:'\u5463',52206:'\u5467',52207:'\u5464',52208:'\u56F7',52209:'\u56F9',52210:'\u576F',52211:'\u5772',52212:'\u576D',52213:'\u576B',52214:'\u5771',52215:'\u5770',52216:'\u5776',52217:'\u5780',52218:'\u5775',52219:'\u577B',52220:'\u5773',52221:'\u5774',52222:'\u5762',52288:'\u5768',52289:'\u577D',52290:'\u590C',52291:'\u5945',52292:'\u59B5',52293:'\u59BA',52294:'\u59CF',52295:'\u59CE',52296:'\u59B2',52297:'\u59CC',52298:'\u59C1',52299:'\u59B6',52300:'\u59BC',52301:'\u59C3',52302:'\u59D6',52303:'\u59B1',52304:'\u59BD',52305:'\u59C0',52306:'\u59C8',52307:'\u59B4',52308:'\u59C7',52309:'\u5B62',52310:'\u5B65',52311:'\u5B93',52312:'\u5B95',52313:'\u5C44',52314:'\u5C47',52315:'\u5CAE',52316:'\u5CA4',52317:'\u5CA0',52318:'\u5CB5',52319:'\u5CAF',52320:'\u5CA8',52321:'\u5CAC',52322:'\u5C9F',52323:'\u5CA3',52324:'\u5CAD',52325:'\u5CA2',52326:'\u5CAA',52327:'\u5CA7',52328:'\u5C9D',52329:'\u5CA5',52330:'\u5CB6',52331:'\u5CB0',52332:'\u5CA6',52333:'\u5E17',52334:'\u5E14',52335:'\u5E19',52336:'\u5F28',52337:'\u5F22',52338:'\u5F23',52339:'\u5F24',52340:'\u5F54',52341:'\u5F82',52342:'\u5F7E',52343:'\u5F7D',52344:'\u5FDE',52345:'\u5FE5',52346:'\u602D',52347:'\u6026',52348:'\u6019',52349:'\u6032',52350:'\u600B',52385:'\u6034',52386:'\u600A',52387:'\u6017',52388:'\u6033',52389:'\u601A',52390:'\u601E',52391:'\u602C',52392:'\u6022',52393:'\u600D',52394:'\u6010',52395:'\u602E',52396:'\u6013',52397:'\u6011',52398:'\u600C',52399:'\u6009',52400:'\u601C',52401:'\u6214',52402:'\u623D',52403:'\u62AD',52404:'\u62B4',52405:'\u62D1',52406:'\u62BE',52407:'\u62AA',52408:'\u62B6',52409:'\u62CA',52410:'\u62AE',52411:'\u62B3',52412:'\u62AF',52413:'\u62BB',52414:'\u62A9',52415:'\u62B0',52416:'\u62B8',52417:'\u653D',52418:'\u65A8',52419:'\u65BB',52420:'\u6609',52421:'\u65FC',52422:'\u6604',52423:'\u6612',52424:'\u6608',52425:'\u65FB',52426:'\u6603',52427:'\u660B',52428:'\u660D',52429:'\u6605',52430:'\u65FD',52431:'\u6611',52432:'\u6610',52433:'\u66F6',52434:'\u670A',52435:'\u6785',52436:'\u676C',52437:'\u678E',52438:'\u6792',52439:'\u6776',52440:'\u677B',52441:'\u6798',52442:'\u6786',52443:'\u6784',52444:'\u6774',52445:'\u678D',52446:'\u678C',52447:'\u677A',52448:'\u679F',52449:'\u6791',52450:'\u6799',52451:'\u6783',52452:'\u677D',52453:'\u6781',52454:'\u6778',52455:'\u6779',52456:'\u6794',52457:'\u6B25',52458:'\u6B80',52459:'\u6B7E',52460:'\u6BDE',52461:'\u6C1D',52462:'\u6C93',52463:'\u6CEC',52464:'\u6CEB',52465:'\u6CEE',52466:'\u6CD9',52467:'\u6CB6',52468:'\u6CD4',52469:'\u6CAD',52470:'\u6CE7',52471:'\u6CB7',52472:'\u6CD0',52473:'\u6CC2',52474:'\u6CBA',52475:'\u6CC3',52476:'\u6CC6',52477:'\u6CED',52478:'\u6CF2',52544:'\u6CD2',52545:'\u6CDD',52546:'\u6CB4',52547:'\u6C8A',52548:'\u6C9D',52549:'\u6C80',52550:'\u6CDE',52551:'\u6CC0',52552:'\u6D30',52553:'\u6CCD',52554:'\u6CC7',52555:'\u6CB0',52556:'\u6CF9',52557:'\u6CCF',52558:'\u6CE9',52559:'\u6CD1',52560:'\u7094',52561:'\u7098',52562:'\u7085',52563:'\u7093',52564:'\u7086',52565:'\u7084',52566:'\u7091',52567:'\u7096',52568:'\u7082',52569:'\u709A',52570:'\u7083',52571:'\u726A',52572:'\u72D6',52573:'\u72CB',52574:'\u72D8',52575:'\u72C9',52576:'\u72DC',52577:'\u72D2',52578:'\u72D4',52579:'\u72DA',52580:'\u72CC',52581:'\u72D1',52582:'\u73A4',52583:'\u73A1',52584:'\u73AD',52585:'\u73A6',52586:'\u73A2',52587:'\u73A0',52588:'\u73AC',52589:'\u739D',52590:'\u74DD',52591:'\u74E8',52592:'\u753F',52593:'\u7540',52594:'\u753E',52595:'\u758C',52596:'\u7598',52597:'\u76AF',52598:'\u76F3',52599:'\u76F1',52600:'\u76F0',52601:'\u76F5',52602:'\u77F8',52603:'\u77FC',52604:'\u77F9',52605:'\u77FB',52606:'\u77FA',52641:'\u77F7',52642:'\u7942',52643:'\u793F',52644:'\u79C5',52645:'\u7A78',52646:'\u7A7B',52647:'\u7AFB',52648:'\u7C75',52649:'\u7CFD',52650:'\u8035',52651:'\u808F',52652:'\u80AE',52653:'\u80A3',52654:'\u80B8',52655:'\u80B5',52656:'\u80AD',52657:'\u8220',52658:'\u82A0',52659:'\u82C0',52660:'\u82AB',52661:'\u829A',52662:'\u8298',52663:'\u829B',52664:'\u82B5',52665:'\u82A7',52666:'\u82AE',52667:'\u82BC',52668:'\u829E',52669:'\u82BA',52670:'\u82B4',52671:'\u82A8',52672:'\u82A1',52673:'\u82A9',52674:'\u82C2',52675:'\u82A4',52676:'\u82C3',52677:'\u82B6',52678:'\u82A2',52679:'\u8670',52680:'\u866F',52681:'\u866D',52682:'\u866E',52683:'\u8C56',52684:'\u8FD2',52685:'\u8FCB',52686:'\u8FD3',52687:'\u8FCD',52688:'\u8FD6',52689:'\u8FD5',52690:'\u8FD7',52691:'\u90B2',52692:'\u90B4',52693:'\u90AF',52694:'\u90B3',52695:'\u90B0',52696:'\u9639',52697:'\u963D',52698:'\u963C',52699:'\u963A',52700:'\u9643',52701:'\u4FCD',52702:'\u4FC5',52703:'\u4FD3',52704:'\u4FB2',52705:'\u4FC9',52706:'\u4FCB',52707:'\u4FC1',52708:'\u4FD4',52709:'\u4FDC',52710:'\u4FD9',52711:'\u4FBB',52712:'\u4FB3',52713:'\u4FDB',52714:'\u4FC7',52715:'\u4FD6',52716:'\u4FBA',52717:'\u4FC0',52718:'\u4FB9',52719:'\u4FEC',52720:'\u5244',52721:'\u5249',52722:'\u52C0',52723:'\u52C2',52724:'\u533D',52725:'\u537C',52726:'\u5397',52727:'\u5396',52728:'\u5399',52729:'\u5398',52730:'\u54BA',52731:'\u54A1',52732:'\u54AD',52733:'\u54A5',52734:'\u54CF',52800:'\u54C3',52801:'\u830D',52802:'\u54B7',52803:'\u54AE',52804:'\u54D6',52805:'\u54B6',52806:'\u54C5',52807:'\u54C6',52808:'\u54A0',52809:'\u5470',52810:'\u54BC',52811:'\u54A2',52812:'\u54BE',52813:'\u5472',52814:'\u54DE',52815:'\u54B0',52816:'\u57B5',52817:'\u579E',52818:'\u579F',52819:'\u57A4',52820:'\u578C',52821:'\u5797',52822:'\u579D',52823:'\u579B',52824:'\u5794',52825:'\u5798',52826:'\u578F',52827:'\u5799',52828:'\u57A5',52829:'\u579A',52830:'\u5795',52831:'\u58F4',52832:'\u590D',52833:'\u5953',52834:'\u59E1',52835:'\u59DE',52836:'\u59EE',52837:'\u5A00',52838:'\u59F1',52839:'\u59DD',52840:'\u59FA',52841:'\u59FD',52842:'\u59FC',52843:'\u59F6',52844:'\u59E4',52845:'\u59F2',52846:'\u59F7',52847:'\u59DB',52848:'\u59E9',52849:'\u59F3',52850:'\u59F5',52851:'\u59E0',52852:'\u59FE',52853:'\u59F4',52854:'\u59ED',52855:'\u5BA8',52856:'\u5C4C',52857:'\u5CD0',52858:'\u5CD8',52859:'\u5CCC',52860:'\u5CD7',52861:'\u5CCB',52862:'\u5CDB',52897:'\u5CDE',52898:'\u5CDA',52899:'\u5CC9',52900:'\u5CC7',52901:'\u5CCA',52902:'\u5CD6',52903:'\u5CD3',52904:'\u5CD4',52905:'\u5CCF',52906:'\u5CC8',52907:'\u5CC6',52908:'\u5CCE',52909:'\u5CDF',52910:'\u5CF8',52911:'\u5DF9',52912:'\u5E21',52913:'\u5E22',52914:'\u5E23',52915:'\u5E20',52916:'\u5E24',52917:'\u5EB0',52918:'\u5EA4',52919:'\u5EA2',52920:'\u5E9B',52921:'\u5EA3',52922:'\u5EA5',52923:'\u5F07',52924:'\u5F2E',52925:'\u5F56',52926:'\u5F86',52927:'\u6037',52928:'\u6039',52929:'\u6054',52930:'\u6072',52931:'\u605E',52932:'\u6045',52933:'\u6053',52934:'\u6047',52935:'\u6049',52936:'\u605B',52937:'\u604C',52938:'\u6040',52939:'\u6042',52940:'\u605F',52941:'\u6024',52942:'\u6044',52943:'\u6058',52944:'\u6066',52945:'\u606E',52946:'\u6242',52947:'\u6243',52948:'\u62CF',52949:'\u630D',52950:'\u630B',52951:'\u62F5',52952:'\u630E',52953:'\u6303',52954:'\u62EB',52955:'\u62F9',52956:'\u630F',52957:'\u630C',52958:'\u62F8',52959:'\u62F6',52960:'\u6300',52961:'\u6313',52962:'\u6314',52963:'\u62FA',52964:'\u6315',52965:'\u62FB',52966:'\u62F0',52967:'\u6541',52968:'\u6543',52969:'\u65AA',52970:'\u65BF',52971:'\u6636',52972:'\u6621',52973:'\u6632',52974:'\u6635',52975:'\u661C',52976:'\u6626',52977:'\u6622',52978:'\u6633',52979:'\u662B',52980:'\u663A',52981:'\u661D',52982:'\u6634',52983:'\u6639',52984:'\u662E',52985:'\u670F',52986:'\u6710',52987:'\u67C1',52988:'\u67F2',52989:'\u67C8',52990:'\u67BA',53056:'\u67DC',53057:'\u67BB',53058:'\u67F8',53059:'\u67D8',53060:'\u67C0',53061:'\u67B7',53062:'\u67C5',53063:'\u67EB',53064:'\u67E4',53065:'\u67DF',53066:'\u67B5',53067:'\u67CD',53068:'\u67B3',53069:'\u67F7',53070:'\u67F6',53071:'\u67EE',53072:'\u67E3',53073:'\u67C2',53074:'\u67B9',53075:'\u67CE',53076:'\u67E7',53077:'\u67F0',53078:'\u67B2',53079:'\u67FC',53080:'\u67C6',53081:'\u67ED',53082:'\u67CC',53083:'\u67AE',53084:'\u67E6',53085:'\u67DB',53086:'\u67FA',53087:'\u67C9',53088:'\u67CA',53089:'\u67C3',53090:'\u67EA',53091:'\u67CB',53092:'\u6B28',53093:'\u6B82',53094:'\u6B84',53095:'\u6BB6',53096:'\u6BD6',53097:'\u6BD8',53098:'\u6BE0',53099:'\u6C20',53100:'\u6C21',53101:'\u6D28',53102:'\u6D34',53103:'\u6D2D',53104:'\u6D1F',53105:'\u6D3C',53106:'\u6D3F',53107:'\u6D12',53108:'\u6D0A',53109:'\u6CDA',53110:'\u6D33',53111:'\u6D04',53112:'\u6D19',53113:'\u6D3A',53114:'\u6D1A',53115:'\u6D11',53116:'\u6D00',53117:'\u6D1D',53118:'\u6D42',53153:'\u6D01',53154:'\u6D18',53155:'\u6D37',53156:'\u6D03',53157:'\u6D0F',53158:'\u6D40',53159:'\u6D07',53160:'\u6D20',53161:'\u6D2C',53162:'\u6D08',53163:'\u6D22',53164:'\u6D09',53165:'\u6D10',53166:'\u70B7',53167:'\u709F',53168:'\u70BE',53169:'\u70B1',53170:'\u70B0',53171:'\u70A1',53172:'\u70B4',53173:'\u70B5',53174:'\u70A9',53175:'\u7241',53176:'\u7249',53177:'\u724A',53178:'\u726C',53179:'\u7270',53180:'\u7273',53181:'\u726E',53182:'\u72CA',53183:'\u72E4',53184:'\u72E8',53185:'\u72EB',53186:'\u72DF',53187:'\u72EA',53188:'\u72E6',53189:'\u72E3',53190:'\u7385',53191:'\u73CC',53192:'\u73C2',53193:'\u73C8',53194:'\u73C5',53195:'\u73B9',53196:'\u73B6',53197:'\u73B5',53198:'\u73B4',53199:'\u73EB',53200:'\u73BF',53201:'\u73C7',53202:'\u73BE',53203:'\u73C3',53204:'\u73C6',53205:'\u73B8',53206:'\u73CB',53207:'\u74EC',53208:'\u74EE',53209:'\u752E',53210:'\u7547',53211:'\u7548',53212:'\u75A7',53213:'\u75AA',53214:'\u7679',53215:'\u76C4',53216:'\u7708',53217:'\u7703',53218:'\u7704',53219:'\u7705',53220:'\u770A',53221:'\u76F7',53222:'\u76FB',53223:'\u76FA',53224:'\u77E7',53225:'\u77E8',53226:'\u7806',53227:'\u7811',53228:'\u7812',53229:'\u7805',53230:'\u7810',53231:'\u780F',53232:'\u780E',53233:'\u7809',53234:'\u7803',53235:'\u7813',53236:'\u794A',53237:'\u794C',53238:'\u794B',53239:'\u7945',53240:'\u7944',53241:'\u79D5',53242:'\u79CD',53243:'\u79CF',53244:'\u79D6',53245:'\u79CE',53246:'\u7A80',53312:'\u7A7E',53313:'\u7AD1',53314:'\u7B00',53315:'\u7B01',53316:'\u7C7A',53317:'\u7C78',53318:'\u7C79',53319:'\u7C7F',53320:'\u7C80',53321:'\u7C81',53322:'\u7D03',53323:'\u7D08',53324:'\u7D01',53325:'\u7F58',53326:'\u7F91',53327:'\u7F8D',53328:'\u7FBE',53329:'\u8007',53330:'\u800E',53331:'\u800F',53332:'\u8014',53333:'\u8037',53334:'\u80D8',53335:'\u80C7',53336:'\u80E0',53337:'\u80D1',53338:'\u80C8',53339:'\u80C2',53340:'\u80D0',53341:'\u80C5',53342:'\u80E3',53343:'\u80D9',53344:'\u80DC',53345:'\u80CA',53346:'\u80D5',53347:'\u80C9',53348:'\u80CF',53349:'\u80D7',53350:'\u80E6',53351:'\u80CD',53352:'\u81FF',53353:'\u8221',53354:'\u8294',53355:'\u82D9',53356:'\u82FE',53357:'\u82F9',53358:'\u8307',53359:'\u82E8',53360:'\u8300',53361:'\u82D5',53362:'\u833A',53363:'\u82EB',53364:'\u82D6',53365:'\u82F4',53366:'\u82EC',53367:'\u82E1',53368:'\u82F2',53369:'\u82F5',53370:'\u830C',53371:'\u82FB',53372:'\u82F6',53373:'\u82F0',53374:'\u82EA',53409:'\u82E4',53410:'\u82E0',53411:'\u82FA',53412:'\u82F3',53413:'\u82ED',53414:'\u8677',53415:'\u8674',53416:'\u867C',53417:'\u8673',53418:'\u8841',53419:'\u884E',53420:'\u8867',53421:'\u886A',53422:'\u8869',53423:'\u89D3',53424:'\u8A04',53425:'\u8A07',53426:'\u8D72',53427:'\u8FE3',53428:'\u8FE1',53429:'\u8FEE',53430:'\u8FE0',53431:'\u90F1',53432:'\u90BD',53433:'\u90BF',53434:'\u90D5',53435:'\u90C5',53436:'\u90BE',53437:'\u90C7',53438:'\u90CB',53439:'\u90C8',53440:'\u91D4',53441:'\u91D3',53442:'\u9654',53443:'\u964F',53444:'\u9651',53445:'\u9653',53446:'\u964A',53447:'\u964E',53448:'\u501E',53449:'\u5005',53450:'\u5007',53451:'\u5013',53452:'\u5022',53453:'\u5030',53454:'\u501B',53455:'\u4FF5',53456:'\u4FF4',53457:'\u5033',53458:'\u5037',53459:'\u502C',53460:'\u4FF6',53461:'\u4FF7',53462:'\u5017',53463:'\u501C',53464:'\u5020',53465:'\u5027',53466:'\u5035',53467:'\u502F',53468:'\u5031',53469:'\u500E',53470:'\u515A',53471:'\u5194',53472:'\u5193',53473:'\u51CA',53474:'\u51C4',53475:'\u51C5',53476:'\u51C8',53477:'\u51CE',53478:'\u5261',53479:'\u525A',53480:'\u5252',53481:'\u525E',53482:'\u525F',53483:'\u5255',53484:'\u5262',53485:'\u52CD',53486:'\u530E',53487:'\u539E',53488:'\u5526',53489:'\u54E2',53490:'\u5517',53491:'\u5512',53492:'\u54E7',53493:'\u54F3',53494:'\u54E4',53495:'\u551A',53496:'\u54FF',53497:'\u5504',53498:'\u5508',53499:'\u54EB',53500:'\u5511',53501:'\u5505',53502:'\u54F1',53568:'\u550A',53569:'\u54FB',53570:'\u54F7',53571:'\u54F8',53572:'\u54E0',53573:'\u550E',53574:'\u5503',53575:'\u550B',53576:'\u5701',53577:'\u5702',53578:'\u57CC',53579:'\u5832',53580:'\u57D5',53581:'\u57D2',53582:'\u57BA',53583:'\u57C6',53584:'\u57BD',53585:'\u57BC',53586:'\u57B8',53587:'\u57B6',53588:'\u57BF',53589:'\u57C7',53590:'\u57D0',53591:'\u57B9',53592:'\u57C1',53593:'\u590E',53594:'\u594A',53595:'\u5A19',53596:'\u5A16',53597:'\u5A2D',53598:'\u5A2E',53599:'\u5A15',53600:'\u5A0F',53601:'\u5A17',53602:'\u5A0A',53603:'\u5A1E',53604:'\u5A33',53605:'\u5B6C',53606:'\u5BA7',53607:'\u5BAD',53608:'\u5BAC',53609:'\u5C03',53610:'\u5C56',53611:'\u5C54',53612:'\u5CEC',53613:'\u5CFF',53614:'\u5CEE',53615:'\u5CF1',53616:'\u5CF7',53617:'\u5D00',53618:'\u5CF9',53619:'\u5E29',53620:'\u5E28',53621:'\u5EA8',53622:'\u5EAE',53623:'\u5EAA',53624:'\u5EAC',53625:'\u5F33',53626:'\u5F30',53627:'\u5F67',53628:'\u605D',53629:'\u605A',53630:'\u6067',53665:'\u6041',53666:'\u60A2',53667:'\u6088',53668:'\u6080',53669:'\u6092',53670:'\u6081',53671:'\u609D',53672:'\u6083',53673:'\u6095',53674:'\u609B',53675:'\u6097',53676:'\u6087',53677:'\u609C',53678:'\u608E',53679:'\u6219',53680:'\u6246',53681:'\u62F2',53682:'\u6310',53683:'\u6356',53684:'\u632C',53685:'\u6344',53686:'\u6345',53687:'\u6336',53688:'\u6343',53689:'\u63E4',53690:'\u6339',53691:'\u634B',53692:'\u634A',53693:'\u633C',53694:'\u6329',53695:'\u6341',53696:'\u6334',53697:'\u6358',53698:'\u6354',53699:'\u6359',53700:'\u632D',53701:'\u6347',53702:'\u6333',53703:'\u635A',53704:'\u6351',53705:'\u6338',53706:'\u6357',53707:'\u6340',53708:'\u6348',53709:'\u654A',53710:'\u6546',53711:'\u65C6',53712:'\u65C3',53713:'\u65C4',53714:'\u65C2',53715:'\u664A',53716:'\u665F',53717:'\u6647',53718:'\u6651',53719:'\u6712',53720:'\u6713',53721:'\u681F',53722:'\u681A',53723:'\u6849',53724:'\u6832',53725:'\u6833',53726:'\u683B',53727:'\u684B',53728:'\u684F',53729:'\u6816',53730:'\u6831',53731:'\u681C',53732:'\u6835',53733:'\u682B',53734:'\u682D',53735:'\u682F',53736:'\u684E',53737:'\u6844',53738:'\u6834',53739:'\u681D',53740:'\u6812',53741:'\u6814',53742:'\u6826',53743:'\u6828',53744:'\u682E',53745:'\u684D',53746:'\u683A',53747:'\u6825',53748:'\u6820',53749:'\u6B2C',53750:'\u6B2F',53751:'\u6B2D',53752:'\u6B31',53753:'\u6B34',53754:'\u6B6D',53755:'\u8082',53756:'\u6B88',53757:'\u6BE6',53758:'\u6BE4',53824:'\u6BE8',53825:'\u6BE3',53826:'\u6BE2',53827:'\u6BE7',53828:'\u6C25',53829:'\u6D7A',53830:'\u6D63',53831:'\u6D64',53832:'\u6D76',53833:'\u6D0D',53834:'\u6D61',53835:'\u6D92',53836:'\u6D58',53837:'\u6D62',53838:'\u6D6D',53839:'\u6D6F',53840:'\u6D91',53841:'\u6D8D',53842:'\u6DEF',53843:'\u6D7F',53844:'\u6D86',53845:'\u6D5E',53846:'\u6D67',53847:'\u6D60',53848:'\u6D97',53849:'\u6D70',53850:'\u6D7C',53851:'\u6D5F',53852:'\u6D82',53853:'\u6D98',53854:'\u6D2F',53855:'\u6D68',53856:'\u6D8B',53857:'\u6D7E',53858:'\u6D80',53859:'\u6D84',53860:'\u6D16',53861:'\u6D83',53862:'\u6D7B',53863:'\u6D7D',53864:'\u6D75',53865:'\u6D90',53866:'\u70DC',53867:'\u70D3',53868:'\u70D1',53869:'\u70DD',53870:'\u70CB',53871:'\u7F39',53872:'\u70E2',53873:'\u70D7',53874:'\u70D2',53875:'\u70DE',53876:'\u70E0',53877:'\u70D4',53878:'\u70CD',53879:'\u70C5',53880:'\u70C6',53881:'\u70C7',53882:'\u70DA',53883:'\u70CE',53884:'\u70E1',53885:'\u7242',53886:'\u7278',53921:'\u7277',53922:'\u7276',53923:'\u7300',53924:'\u72FA',53925:'\u72F4',53926:'\u72FE',53927:'\u72F6',53928:'\u72F3',53929:'\u72FB',53930:'\u7301',53931:'\u73D3',53932:'\u73D9',53933:'\u73E5',53934:'\u73D6',53935:'\u73BC',53936:'\u73E7',53937:'\u73E3',53938:'\u73E9',53939:'\u73DC',53940:'\u73D2',53941:'\u73DB',53942:'\u73D4',53943:'\u73DD',53944:'\u73DA',53945:'\u73D7',53946:'\u73D8',53947:'\u73E8',53948:'\u74DE',53949:'\u74DF',53950:'\u74F4',53951:'\u74F5',53952:'\u7521',53953:'\u755B',53954:'\u755F',53955:'\u75B0',53956:'\u75C1',53957:'\u75BB',53958:'\u75C4',53959:'\u75C0',53960:'\u75BF',53961:'\u75B6',53962:'\u75BA',53963:'\u768A',53964:'\u76C9',53965:'\u771D',53966:'\u771B',53967:'\u7710',53968:'\u7713',53969:'\u7712',53970:'\u7723',53971:'\u7711',53972:'\u7715',53973:'\u7719',53974:'\u771A',53975:'\u7722',53976:'\u7727',53977:'\u7823',53978:'\u782C',53979:'\u7822',53980:'\u7835',53981:'\u782F',53982:'\u7828',53983:'\u782E',53984:'\u782B',53985:'\u7821',53986:'\u7829',53987:'\u7833',53988:'\u782A',53989:'\u7831',53990:'\u7954',53991:'\u795B',53992:'\u794F',53993:'\u795C',53994:'\u7953',53995:'\u7952',53996:'\u7951',53997:'\u79EB',53998:'\u79EC',53999:'\u79E0',54000:'\u79EE',54001:'\u79ED',54002:'\u79EA',54003:'\u79DC',54004:'\u79DE',54005:'\u79DD',54006:'\u7A86',54007:'\u7A89',54008:'\u7A85',54009:'\u7A8B',54010:'\u7A8C',54011:'\u7A8A',54012:'\u7A87',54013:'\u7AD8',54014:'\u7B10',54080:'\u7B04',54081:'\u7B13',54082:'\u7B05',54083:'\u7B0F',54084:'\u7B08',54085:'\u7B0A',54086:'\u7B0E',54087:'\u7B09',54088:'\u7B12',54089:'\u7C84',54090:'\u7C91',54091:'\u7C8A',54092:'\u7C8C',54093:'\u7C88',54094:'\u7C8D',54095:'\u7C85',54096:'\u7D1E',54097:'\u7D1D',54098:'\u7D11',54099:'\u7D0E',54100:'\u7D18',54101:'\u7D16',54102:'\u7D13',54103:'\u7D1F',54104:'\u7D12',54105:'\u7D0F',54106:'\u7D0C',54107:'\u7F5C',54108:'\u7F61',54109:'\u7F5E',54110:'\u7F60',54111:'\u7F5D',54112:'\u7F5B',54113:'\u7F96',54114:'\u7F92',54115:'\u7FC3',54116:'\u7FC2',54117:'\u7FC0',54118:'\u8016',54119:'\u803E',54120:'\u8039',54121:'\u80FA',54122:'\u80F2',54123:'\u80F9',54124:'\u80F5',54125:'\u8101',54126:'\u80FB',54127:'\u8100',54128:'\u8201',54129:'\u822F',54130:'\u8225',54131:'\u8333',54132:'\u832D',54133:'\u8344',54134:'\u8319',54135:'\u8351',54136:'\u8325',54137:'\u8356',54138:'\u833F',54139:'\u8341',54140:'\u8326',54141:'\u831C',54142:'\u8322',54177:'\u8342',54178:'\u834E',54179:'\u831B',54180:'\u832A',54181:'\u8308',54182:'\u833C',54183:'\u834D',54184:'\u8316',54185:'\u8324',54186:'\u8320',54187:'\u8337',54188:'\u832F',54189:'\u8329',54190:'\u8347',54191:'\u8345',54192:'\u834C',54193:'\u8353',54194:'\u831E',54195:'\u832C',54196:'\u834B',54197:'\u8327',54198:'\u8348',54199:'\u8653',54200:'\u8652',54201:'\u86A2',54202:'\u86A8',54203:'\u8696',54204:'\u868D',54205:'\u8691',54206:'\u869E',54207:'\u8687',54208:'\u8697',54209:'\u8686',54210:'\u868B',54211:'\u869A',54212:'\u8685',54213:'\u86A5',54214:'\u8699',54215:'\u86A1',54216:'\u86A7',54217:'\u8695',54218:'\u8698',54219:'\u868E',54220:'\u869D',54221:'\u8690',54222:'\u8694',54223:'\u8843',54224:'\u8844',54225:'\u886D',54226:'\u8875',54227:'\u8876',54228:'\u8872',54229:'\u8880',54230:'\u8871',54231:'\u887F',54232:'\u886F',54233:'\u8883',54234:'\u887E',54235:'\u8874',54236:'\u887C',54237:'\u8A12',54238:'\u8C47',54239:'\u8C57',54240:'\u8C7B',54241:'\u8CA4',54242:'\u8CA3',54243:'\u8D76',54244:'\u8D78',54245:'\u8DB5',54246:'\u8DB7',54247:'\u8DB6',54248:'\u8ED1',54249:'\u8ED3',54250:'\u8FFE',54251:'\u8FF5',54252:'\u9002',54253:'\u8FFF',54254:'\u8FFB',54255:'\u9004',54256:'\u8FFC',54257:'\u8FF6',54258:'\u90D6',54259:'\u90E0',54260:'\u90D9',54261:'\u90DA',54262:'\u90E3',54263:'\u90DF',54264:'\u90E5',54265:'\u90D8',54266:'\u90DB',54267:'\u90D7',54268:'\u90DC',54269:'\u90E4',54270:'\u9150',54336:'\u914E',54337:'\u914F',54338:'\u91D5',54339:'\u91E2',54340:'\u91DA',54341:'\u965C',54342:'\u965F',54343:'\u96BC',54344:'\u98E3',54345:'\u9ADF',54346:'\u9B2F',54347:'\u4E7F',54348:'\u5070',54349:'\u506A',54350:'\u5061',54351:'\u505E',54352:'\u5060',54353:'\u5053',54354:'\u504B',54355:'\u505D',54356:'\u5072',54357:'\u5048',54358:'\u504D',54359:'\u5041',54360:'\u505B',54361:'\u504A',54362:'\u5062',54363:'\u5015',54364:'\u5045',54365:'\u505F',54366:'\u5069',54367:'\u506B',54368:'\u5063',54369:'\u5064',54370:'\u5046',54371:'\u5040',54372:'\u506E',54373:'\u5073',54374:'\u5057',54375:'\u5051',54376:'\u51D0',54377:'\u526B',54378:'\u526D',54379:'\u526C',54380:'\u526E',54381:'\u52D6',54382:'\u52D3',54383:'\u532D',54384:'\u539C',54385:'\u5575',54386:'\u5576',54387:'\u553C',54388:'\u554D',54389:'\u5550',54390:'\u5534',54391:'\u552A',54392:'\u5551',54393:'\u5562',54394:'\u5536',54395:'\u5535',54396:'\u5530',54397:'\u5552',54398:'\u5545',54433:'\u550C',54434:'\u5532',54435:'\u5565',54436:'\u554E',54437:'\u5539',54438:'\u5548',54439:'\u552D',54440:'\u553B',54441:'\u5540',54442:'\u554B',54443:'\u570A',54444:'\u5707',54445:'\u57FB',54446:'\u5814',54447:'\u57E2',54448:'\u57F6',54449:'\u57DC',54450:'\u57F4',54451:'\u5800',54452:'\u57ED',54453:'\u57FD',54454:'\u5808',54455:'\u57F8',54456:'\u580B',54457:'\u57F3',54458:'\u57CF',54459:'\u5807',54460:'\u57EE',54461:'\u57E3',54462:'\u57F2',54463:'\u57E5',54464:'\u57EC',54465:'\u57E1',54466:'\u580E',54467:'\u57FC',54468:'\u5810',54469:'\u57E7',54470:'\u5801',54471:'\u580C',54472:'\u57F1',54473:'\u57E9',54474:'\u57F0',54475:'\u580D',54476:'\u5804',54477:'\u595C',54478:'\u5A60',54479:'\u5A58',54480:'\u5A55',54481:'\u5A67',54482:'\u5A5E',54483:'\u5A38',54484:'\u5A35',54485:'\u5A6D',54486:'\u5A50',54487:'\u5A5F',54488:'\u5A65',54489:'\u5A6C',54490:'\u5A53',54491:'\u5A64',54492:'\u5A57',54493:'\u5A43',54494:'\u5A5D',54495:'\u5A52',54496:'\u5A44',54497:'\u5A5B',54498:'\u5A48',54499:'\u5A8E',54500:'\u5A3E',54501:'\u5A4D',54502:'\u5A39',54503:'\u5A4C',54504:'\u5A70',54505:'\u5A69',54506:'\u5A47',54507:'\u5A51',54508:'\u5A56',54509:'\u5A42',54510:'\u5A5C',54511:'\u5B72',54512:'\u5B6E',54513:'\u5BC1',54514:'\u5BC0',54515:'\u5C59',54516:'\u5D1E',54517:'\u5D0B',54518:'\u5D1D',54519:'\u5D1A',54520:'\u5D20',54521:'\u5D0C',54522:'\u5D28',54523:'\u5D0D',54524:'\u5D26',54525:'\u5D25',54526:'\u5D0F',54592:'\u5D30',54593:'\u5D12',54594:'\u5D23',54595:'\u5D1F',54596:'\u5D2E',54597:'\u5E3E',54598:'\u5E34',54599:'\u5EB1',54600:'\u5EB4',54601:'\u5EB9',54602:'\u5EB2',54603:'\u5EB3',54604:'\u5F36',54605:'\u5F38',54606:'\u5F9B',54607:'\u5F96',54608:'\u5F9F',54609:'\u608A',54610:'\u6090',54611:'\u6086',54612:'\u60BE',54613:'\u60B0',54614:'\u60BA',54615:'\u60D3',54616:'\u60D4',54617:'\u60CF',54618:'\u60E4',54619:'\u60D9',54620:'\u60DD',54621:'\u60C8',54622:'\u60B1',54623:'\u60DB',54624:'\u60B7',54625:'\u60CA',54626:'\u60BF',54627:'\u60C3',54628:'\u60CD',54629:'\u60C0',54630:'\u6332',54631:'\u6365',54632:'\u638A',54633:'\u6382',54634:'\u637D',54635:'\u63BD',54636:'\u639E',54637:'\u63AD',54638:'\u639D',54639:'\u6397',54640:'\u63AB',54641:'\u638E',54642:'\u636F',54643:'\u6387',54644:'\u6390',54645:'\u636E',54646:'\u63AF',54647:'\u6375',54648:'\u639C',54649:'\u636D',54650:'\u63AE',54651:'\u637C',54652:'\u63A4',54653:'\u633B',54654:'\u639F',54689:'\u6378',54690:'\u6385',54691:'\u6381',54692:'\u6391',54693:'\u638D',54694:'\u6370',54695:'\u6553',54696:'\u65CD',54697:'\u6665',54698:'\u6661',54699:'\u665B',54700:'\u6659',54701:'\u665C',54702:'\u6662',54703:'\u6718',54704:'\u6879',54705:'\u6887',54706:'\u6890',54707:'\u689C',54708:'\u686D',54709:'\u686E',54710:'\u68AE',54711:'\u68AB',54712:'\u6956',54713:'\u686F',54714:'\u68A3',54715:'\u68AC',54716:'\u68A9',54717:'\u6875',54718:'\u6874',54719:'\u68B2',54720:'\u688F',54721:'\u6877',54722:'\u6892',54723:'\u687C',54724:'\u686B',54725:'\u6872',54726:'\u68AA',54727:'\u6880',54728:'\u6871',54729:'\u687E',54730:'\u689B',54731:'\u6896',54732:'\u688B',54733:'\u68A0',54734:'\u6889',54735:'\u68A4',54736:'\u6878',54737:'\u687B',54738:'\u6891',54739:'\u688C',54740:'\u688A',54741:'\u687D',54742:'\u6B36',54743:'\u6B33',54744:'\u6B37',54745:'\u6B38',54746:'\u6B91',54747:'\u6B8F',54748:'\u6B8D',54749:'\u6B8E',54750:'\u6B8C',54751:'\u6C2A',54752:'\u6DC0',54753:'\u6DAB',54754:'\u6DB4',54755:'\u6DB3',54756:'\u6E74',54757:'\u6DAC',54758:'\u6DE9',54759:'\u6DE2',54760:'\u6DB7',54761:'\u6DF6',54762:'\u6DD4',54763:'\u6E00',54764:'\u6DC8',54765:'\u6DE0',54766:'\u6DDF',54767:'\u6DD6',54768:'\u6DBE',54769:'\u6DE5',54770:'\u6DDC',54771:'\u6DDD',54772:'\u6DDB',54773:'\u6DF4',54774:'\u6DCA',54775:'\u6DBD',54776:'\u6DED',54777:'\u6DF0',54778:'\u6DBA',54779:'\u6DD5',54780:'\u6DC2',54781:'\u6DCF',54782:'\u6DC9',54848:'\u6DD0',54849:'\u6DF2',54850:'\u6DD3',54851:'\u6DFD',54852:'\u6DD7',54853:'\u6DCD',54854:'\u6DE3',54855:'\u6DBB',54856:'\u70FA',54857:'\u710D',54858:'\u70F7',54859:'\u7117',54860:'\u70F4',54861:'\u710C',54862:'\u70F0',54863:'\u7104',54864:'\u70F3',54865:'\u7110',54866:'\u70FC',54867:'\u70FF',54868:'\u7106',54869:'\u7113',54870:'\u7100',54871:'\u70F8',54872:'\u70F6',54873:'\u710B',54874:'\u7102',54875:'\u710E',54876:'\u727E',54877:'\u727B',54878:'\u727C',54879:'\u727F',54880:'\u731D',54881:'\u7317',54882:'\u7307',54883:'\u7311',54884:'\u7318',54885:'\u730A',54886:'\u7308',54887:'\u72FF',54888:'\u730F',54889:'\u731E',54890:'\u7388',54891:'\u73F6',54892:'\u73F8',54893:'\u73F5',54894:'\u7404',54895:'\u7401',54896:'\u73FD',54897:'\u7407',54898:'\u7400',54899:'\u73FA',54900:'\u73FC',54901:'\u73FF',54902:'\u740C',54903:'\u740B',54904:'\u73F4',54905:'\u7408',54906:'\u7564',54907:'\u7563',54908:'\u75CE',54909:'\u75D2',54910:'\u75CF',54945:'\u75CB',54946:'\u75CC',54947:'\u75D1',54948:'\u75D0',54949:'\u768F',54950:'\u7689',54951:'\u76D3',54952:'\u7739',54953:'\u772F',54954:'\u772D',54955:'\u7731',54956:'\u7732',54957:'\u7734',54958:'\u7733',54959:'\u773D',54960:'\u7725',54961:'\u773B',54962:'\u7735',54963:'\u7848',54964:'\u7852',54965:'\u7849',54966:'\u784D',54967:'\u784A',54968:'\u784C',54969:'\u7826',54970:'\u7845',54971:'\u7850',54972:'\u7964',54973:'\u7967',54974:'\u7969',54975:'\u796A',54976:'\u7963',54977:'\u796B',54978:'\u7961',54979:'\u79BB',54980:'\u79FA',54981:'\u79F8',54982:'\u79F6',54983:'\u79F7',54984:'\u7A8F',54985:'\u7A94',54986:'\u7A90',54987:'\u7B35',54988:'\u7B47',54989:'\u7B34',54990:'\u7B25',54991:'\u7B30',54992:'\u7B22',54993:'\u7B24',54994:'\u7B33',54995:'\u7B18',54996:'\u7B2A',54997:'\u7B1D',54998:'\u7B31',54999:'\u7B2B',55000:'\u7B2D',55001:'\u7B2F',55002:'\u7B32',55003:'\u7B38',55004:'\u7B1A',55005:'\u7B23',55006:'\u7C94',55007:'\u7C98',55008:'\u7C96',55009:'\u7CA3',55010:'\u7D35',55011:'\u7D3D',55012:'\u7D38',55013:'\u7D36',55014:'\u7D3A',55015:'\u7D45',55016:'\u7D2C',55017:'\u7D29',55018:'\u7D41',55019:'\u7D47',55020:'\u7D3E',55021:'\u7D3F',55022:'\u7D4A',55023:'\u7D3B',55024:'\u7D28',55025:'\u7F63',55026:'\u7F95',55027:'\u7F9C',55028:'\u7F9D',55029:'\u7F9B',55030:'\u7FCA',55031:'\u7FCB',55032:'\u7FCD',55033:'\u7FD0',55034:'\u7FD1',55035:'\u7FC7',55036:'\u7FCF',55037:'\u7FC9',55038:'\u801F',55104:'\u801E',55105:'\u801B',55106:'\u8047',55107:'\u8043',55108:'\u8048',55109:'\u8118',55110:'\u8125',55111:'\u8119',55112:'\u811B',55113:'\u812D',55114:'\u811F',55115:'\u812C',55116:'\u811E',55117:'\u8121',55118:'\u8115',55119:'\u8127',55120:'\u811D',55121:'\u8122',55122:'\u8211',55123:'\u8238',55124:'\u8233',55125:'\u823A',55126:'\u8234',55127:'\u8232',55128:'\u8274',55129:'\u8390',55130:'\u83A3',55131:'\u83A8',55132:'\u838D',55133:'\u837A',55134:'\u8373',55135:'\u83A4',55136:'\u8374',55137:'\u838F',55138:'\u8381',55139:'\u8395',55140:'\u8399',55141:'\u8375',55142:'\u8394',55143:'\u83A9',55144:'\u837D',55145:'\u8383',55146:'\u838C',55147:'\u839D',55148:'\u839B',55149:'\u83AA',55150:'\u838B',55151:'\u837E',55152:'\u83A5',55153:'\u83AF',55154:'\u8388',55155:'\u8397',55156:'\u83B0',55157:'\u837F',55158:'\u83A6',55159:'\u8387',55160:'\u83AE',55161:'\u8376',55162:'\u839A',55163:'\u8659',55164:'\u8656',55165:'\u86BF',55166:'\u86B7',55201:'\u86C2',55202:'\u86C1',55203:'\u86C5',55204:'\u86BA',55205:'\u86B0',55206:'\u86C8',55207:'\u86B9',55208:'\u86B3',55209:'\u86B8',55210:'\u86CC',55211:'\u86B4',55212:'\u86BB',55213:'\u86BC',55214:'\u86C3',55215:'\u86BD',55216:'\u86BE',55217:'\u8852',55218:'\u8889',55219:'\u8895',55220:'\u88A8',55221:'\u88A2',55222:'\u88AA',55223:'\u889A',55224:'\u8891',55225:'\u88A1',55226:'\u889F',55227:'\u8898',55228:'\u88A7',55229:'\u8899',55230:'\u889B',55231:'\u8897',55232:'\u88A4',55233:'\u88AC',55234:'\u888C',55235:'\u8893',55236:'\u888E',55237:'\u8982',55238:'\u89D6',55239:'\u89D9',55240:'\u89D5',55241:'\u8A30',55242:'\u8A27',55243:'\u8A2C',55244:'\u8A1E',55245:'\u8C39',55246:'\u8C3B',55247:'\u8C5C',55248:'\u8C5D',55249:'\u8C7D',55250:'\u8CA5',55251:'\u8D7D',55252:'\u8D7B',55253:'\u8D79',55254:'\u8DBC',55255:'\u8DC2',55256:'\u8DB9',55257:'\u8DBF',55258:'\u8DC1',55259:'\u8ED8',55260:'\u8EDE',55261:'\u8EDD',55262:'\u8EDC',55263:'\u8ED7',55264:'\u8EE0',55265:'\u8EE1',55266:'\u9024',55267:'\u900B',55268:'\u9011',55269:'\u901C',55270:'\u900C',55271:'\u9021',55272:'\u90EF',55273:'\u90EA',55274:'\u90F0',55275:'\u90F4',55276:'\u90F2',55277:'\u90F3',55278:'\u90D4',55279:'\u90EB',55280:'\u90EC',55281:'\u90E9',55282:'\u9156',55283:'\u9158',55284:'\u915A',55285:'\u9153',55286:'\u9155',55287:'\u91EC',55288:'\u91F4',55289:'\u91F1',55290:'\u91F3',55291:'\u91F8',55292:'\u91E4',55293:'\u91F9',55294:'\u91EA',55360:'\u91EB',55361:'\u91F7',55362:'\u91E8',55363:'\u91EE',55364:'\u957A',55365:'\u9586',55366:'\u9588',55367:'\u967C',55368:'\u966D',55369:'\u966B',55370:'\u9671',55371:'\u966F',55372:'\u96BF',55373:'\u976A',55374:'\u9804',55375:'\u98E5',55376:'\u9997',55377:'\u509B',55378:'\u5095',55379:'\u5094',55380:'\u509E',55381:'\u508B',55382:'\u50A3',55383:'\u5083',55384:'\u508C',55385:'\u508E',55386:'\u509D',55387:'\u5068',55388:'\u509C',55389:'\u5092',55390:'\u5082',55391:'\u5087',55392:'\u515F',55393:'\u51D4',55394:'\u5312',55395:'\u5311',55396:'\u53A4',55397:'\u53A7',55398:'\u5591',55399:'\u55A8',55400:'\u55A5',55401:'\u55AD',55402:'\u5577',55403:'\u5645',55404:'\u55A2',55405:'\u5593',55406:'\u5588',55407:'\u558F',55408:'\u55B5',55409:'\u5581',55410:'\u55A3',55411:'\u5592',55412:'\u55A4',55413:'\u557D',55414:'\u558C',55415:'\u55A6',55416:'\u557F',55417:'\u5595',55418:'\u55A1',55419:'\u558E',55420:'\u570C',55421:'\u5829',55422:'\u5837',55457:'\u5819',55458:'\u581E',55459:'\u5827',55460:'\u5823',55461:'\u5828',55462:'\u57F5',55463:'\u5848',55464:'\u5825',55465:'\u581C',55466:'\u581B',55467:'\u5833',55468:'\u583F',55469:'\u5836',55470:'\u582E',55471:'\u5839',55472:'\u5838',55473:'\u582D',55474:'\u582C',55475:'\u583B',55476:'\u5961',55477:'\u5AAF',55478:'\u5A94',55479:'\u5A9F',55480:'\u5A7A',55481:'\u5AA2',55482:'\u5A9E',55483:'\u5A78',55484:'\u5AA6',55485:'\u5A7C',55486:'\u5AA5',55487:'\u5AAC',55488:'\u5A95',55489:'\u5AAE',55490:'\u5A37',55491:'\u5A84',55492:'\u5A8A',55493:'\u5A97',55494:'\u5A83',55495:'\u5A8B',55496:'\u5AA9',55497:'\u5A7B',55498:'\u5A7D',55499:'\u5A8C',55500:'\u5A9C',55501:'\u5A8F',55502:'\u5A93',55503:'\u5A9D',55504:'\u5BEA',55505:'\u5BCD',55506:'\u5BCB',55507:'\u5BD4',55508:'\u5BD1',55509:'\u5BCA',55510:'\u5BCE',55511:'\u5C0C',55512:'\u5C30',55513:'\u5D37',55514:'\u5D43',55515:'\u5D6B',55516:'\u5D41',55517:'\u5D4B',55518:'\u5D3F',55519:'\u5D35',55520:'\u5D51',55521:'\u5D4E',55522:'\u5D55',55523:'\u5D33',55524:'\u5D3A',55525:'\u5D52',55526:'\u5D3D',55527:'\u5D31',55528:'\u5D59',55529:'\u5D42',55530:'\u5D39',55531:'\u5D49',55532:'\u5D38',55533:'\u5D3C',55534:'\u5D32',55535:'\u5D36',55536:'\u5D40',55537:'\u5D45',55538:'\u5E44',55539:'\u5E41',55540:'\u5F58',55541:'\u5FA6',55542:'\u5FA5',55543:'\u5FAB',55544:'\u60C9',55545:'\u60B9',55546:'\u60CC',55547:'\u60E2',55548:'\u60CE',55549:'\u60C4',55550:'\u6114',55616:'\u60F2',55617:'\u610A',55618:'\u6116',55619:'\u6105',55620:'\u60F5',55621:'\u6113',55622:'\u60F8',55623:'\u60FC',55624:'\u60FE',55625:'\u60C1',55626:'\u6103',55627:'\u6118',55628:'\u611D',55629:'\u6110',55630:'\u60FF',55631:'\u6104',55632:'\u610B',55633:'\u624A',55634:'\u6394',55635:'\u63B1',55636:'\u63B0',55637:'\u63CE',55638:'\u63E5',55639:'\u63E8',55640:'\u63EF',55641:'\u63C3',55642:'\u649D',55643:'\u63F3',55644:'\u63CA',55645:'\u63E0',55646:'\u63F6',55647:'\u63D5',55648:'\u63F2',55649:'\u63F5',55650:'\u6461',55651:'\u63DF',55652:'\u63BE',55653:'\u63DD',55654:'\u63DC',55655:'\u63C4',55656:'\u63D8',55657:'\u63D3',55658:'\u63C2',55659:'\u63C7',55660:'\u63CC',55661:'\u63CB',55662:'\u63C8',55663:'\u63F0',55664:'\u63D7',55665:'\u63D9',55666:'\u6532',55667:'\u6567',55668:'\u656A',55669:'\u6564',55670:'\u655C',55671:'\u6568',55672:'\u6565',55673:'\u658C',55674:'\u659D',55675:'\u659E',55676:'\u65AE',55677:'\u65D0',55678:'\u65D2',55713:'\u667C',55714:'\u666C',55715:'\u667B',55716:'\u6680',55717:'\u6671',55718:'\u6679',55719:'\u666A',55720:'\u6672',55721:'\u6701',55722:'\u690C',55723:'\u68D3',55724:'\u6904',55725:'\u68DC',55726:'\u692A',55727:'\u68EC',55728:'\u68EA',55729:'\u68F1',55730:'\u690F',55731:'\u68D6',55732:'\u68F7',55733:'\u68EB',55734:'\u68E4',55735:'\u68F6',55736:'\u6913',55737:'\u6910',55738:'\u68F3',55739:'\u68E1',55740:'\u6907',55741:'\u68CC',55742:'\u6908',55743:'\u6970',55744:'\u68B4',55745:'\u6911',55746:'\u68EF',55747:'\u68C6',55748:'\u6914',55749:'\u68F8',55750:'\u68D0',55751:'\u68FD',55752:'\u68FC',55753:'\u68E8',55754:'\u690B',55755:'\u690A',55756:'\u6917',55757:'\u68CE',55758:'\u68C8',55759:'\u68DD',55760:'\u68DE',55761:'\u68E6',55762:'\u68F4',55763:'\u68D1',55764:'\u6906',55765:'\u68D4',55766:'\u68E9',55767:'\u6915',55768:'\u6925',55769:'\u68C7',55770:'\u6B39',55771:'\u6B3B',55772:'\u6B3F',55773:'\u6B3C',55774:'\u6B94',55775:'\u6B97',55776:'\u6B99',55777:'\u6B95',55778:'\u6BBD',55779:'\u6BF0',55780:'\u6BF2',55781:'\u6BF3',55782:'\u6C30',55783:'\u6DFC',55784:'\u6E46',55785:'\u6E47',55786:'\u6E1F',55787:'\u6E49',55788:'\u6E88',55789:'\u6E3C',55790:'\u6E3D',55791:'\u6E45',55792:'\u6E62',55793:'\u6E2B',55794:'\u6E3F',55795:'\u6E41',55796:'\u6E5D',55797:'\u6E73',55798:'\u6E1C',55799:'\u6E33',55800:'\u6E4B',55801:'\u6E40',55802:'\u6E51',55803:'\u6E3B',55804:'\u6E03',55805:'\u6E2E',55806:'\u6E5E',55872:'\u6E68',55873:'\u6E5C',55874:'\u6E61',55875:'\u6E31',55876:'\u6E28',55877:'\u6E60',55878:'\u6E71',55879:'\u6E6B',55880:'\u6E39',55881:'\u6E22',55882:'\u6E30',55883:'\u6E53',55884:'\u6E65',55885:'\u6E27',55886:'\u6E78',55887:'\u6E64',55888:'\u6E77',55889:'\u6E55',55890:'\u6E79',55891:'\u6E52',55892:'\u6E66',55893:'\u6E35',55894:'\u6E36',55895:'\u6E5A',55896:'\u7120',55897:'\u711E',55898:'\u712F',55899:'\u70FB',55900:'\u712E',55901:'\u7131',55902:'\u7123',55903:'\u7125',55904:'\u7122',55905:'\u7132',55906:'\u711F',55907:'\u7128',55908:'\u713A',55909:'\u711B',55910:'\u724B',55911:'\u725A',55912:'\u7288',55913:'\u7289',55914:'\u7286',55915:'\u7285',55916:'\u728B',55917:'\u7312',55918:'\u730B',55919:'\u7330',55920:'\u7322',55921:'\u7331',55922:'\u7333',55923:'\u7327',55924:'\u7332',55925:'\u732D',55926:'\u7326',55927:'\u7323',55928:'\u7335',55929:'\u730C',55930:'\u742E',55931:'\u742C',55932:'\u7430',55933:'\u742B',55934:'\u7416',55969:'\u741A',55970:'\u7421',55971:'\u742D',55972:'\u7431',55973:'\u7424',55974:'\u7423',55975:'\u741D',55976:'\u7429',55977:'\u7420',55978:'\u7432',55979:'\u74FB',55980:'\u752F',55981:'\u756F',55982:'\u756C',55983:'\u75E7',55984:'\u75DA',55985:'\u75E1',55986:'\u75E6',55987:'\u75DD',55988:'\u75DF',55989:'\u75E4',55990:'\u75D7',55991:'\u7695',55992:'\u7692',55993:'\u76DA',55994:'\u7746',55995:'\u7747',55996:'\u7744',55997:'\u774D',55998:'\u7745',55999:'\u774A',56000:'\u774E',56001:'\u774B',56002:'\u774C',56003:'\u77DE',56004:'\u77EC',56005:'\u7860',56006:'\u7864',56007:'\u7865',56008:'\u785C',56009:'\u786D',56010:'\u7871',56011:'\u786A',56012:'\u786E',56013:'\u7870',56014:'\u7869',56015:'\u7868',56016:'\u785E',56017:'\u7862',56018:'\u7974',56019:'\u7973',56020:'\u7972',56021:'\u7970',56022:'\u7A02',56023:'\u7A0A',56024:'\u7A03',56025:'\u7A0C',56026:'\u7A04',56027:'\u7A99',56028:'\u7AE6',56029:'\u7AE4',56030:'\u7B4A',56031:'\u7B3B',56032:'\u7B44',56033:'\u7B48',56034:'\u7B4C',56035:'\u7B4E',56036:'\u7B40',56037:'\u7B58',56038:'\u7B45',56039:'\u7CA2',56040:'\u7C9E',56041:'\u7CA8',56042:'\u7CA1',56043:'\u7D58',56044:'\u7D6F',56045:'\u7D63',56046:'\u7D53',56047:'\u7D56',56048:'\u7D67',56049:'\u7D6A',56050:'\u7D4F',56051:'\u7D6D',56052:'\u7D5C',56053:'\u7D6B',56054:'\u7D52',56055:'\u7D54',56056:'\u7D69',56057:'\u7D51',56058:'\u7D5F',56059:'\u7D4E',56060:'\u7F3E',56061:'\u7F3F',56062:'\u7F65',56128:'\u7F66',56129:'\u7FA2',56130:'\u7FA0',56131:'\u7FA1',56132:'\u7FD7',56133:'\u8051',56134:'\u804F',56135:'\u8050',56136:'\u80FE',56137:'\u80D4',56138:'\u8143',56139:'\u814A',56140:'\u8152',56141:'\u814F',56142:'\u8147',56143:'\u813D',56144:'\u814D',56145:'\u813A',56146:'\u81E6',56147:'\u81EE',56148:'\u81F7',56149:'\u81F8',56150:'\u81F9',56151:'\u8204',56152:'\u823C',56153:'\u823D',56154:'\u823F',56155:'\u8275',56156:'\u833B',56157:'\u83CF',56158:'\u83F9',56159:'\u8423',56160:'\u83C0',56161:'\u83E8',56162:'\u8412',56163:'\u83E7',56164:'\u83E4',56165:'\u83FC',56166:'\u83F6',56167:'\u8410',56168:'\u83C6',56169:'\u83C8',56170:'\u83EB',56171:'\u83E3',56172:'\u83BF',56173:'\u8401',56174:'\u83DD',56175:'\u83E5',56176:'\u83D8',56177:'\u83FF',56178:'\u83E1',56179:'\u83CB',56180:'\u83CE',56181:'\u83D6',56182:'\u83F5',56183:'\u83C9',56184:'\u8409',56185:'\u840F',56186:'\u83DE',56187:'\u8411',56188:'\u8406',56189:'\u83C2',56190:'\u83F3',56225:'\u83D5',56226:'\u83FA',56227:'\u83C7',56228:'\u83D1',56229:'\u83EA',56230:'\u8413',56231:'\u83C3',56232:'\u83EC',56233:'\u83EE',56234:'\u83C4',56235:'\u83FB',56236:'\u83D7',56237:'\u83E2',56238:'\u841B',56239:'\u83DB',56240:'\u83FE',56241:'\u86D8',56242:'\u86E2',56243:'\u86E6',56244:'\u86D3',56245:'\u86E3',56246:'\u86DA',56247:'\u86EA',56248:'\u86DD',56249:'\u86EB',56250:'\u86DC',56251:'\u86EC',56252:'\u86E9',56253:'\u86D7',56254:'\u86E8',56255:'\u86D1',56256:'\u8848',56257:'\u8856',56258:'\u8855',56259:'\u88BA',56260:'\u88D7',56261:'\u88B9',56262:'\u88B8',56263:'\u88C0',56264:'\u88BE',56265:'\u88B6',56266:'\u88BC',56267:'\u88B7',56268:'\u88BD',56269:'\u88B2',56270:'\u8901',56271:'\u88C9',56272:'\u8995',56273:'\u8998',56274:'\u8997',56275:'\u89DD',56276:'\u89DA',56277:'\u89DB',56278:'\u8A4E',56279:'\u8A4D',56280:'\u8A39',56281:'\u8A59',56282:'\u8A40',56283:'\u8A57',56284:'\u8A58',56285:'\u8A44',56286:'\u8A45',56287:'\u8A52',56288:'\u8A48',56289:'\u8A51',56290:'\u8A4A',56291:'\u8A4C',56292:'\u8A4F',56293:'\u8C5F',56294:'\u8C81',56295:'\u8C80',56296:'\u8CBA',56297:'\u8CBE',56298:'\u8CB0',56299:'\u8CB9',56300:'\u8CB5',56301:'\u8D84',56302:'\u8D80',56303:'\u8D89',56304:'\u8DD8',56305:'\u8DD3',56306:'\u8DCD',56307:'\u8DC7',56308:'\u8DD6',56309:'\u8DDC',56310:'\u8DCF',56311:'\u8DD5',56312:'\u8DD9',56313:'\u8DC8',56314:'\u8DD7',56315:'\u8DC5',56316:'\u8EEF',56317:'\u8EF7',56318:'\u8EFA',56384:'\u8EF9',56385:'\u8EE6',56386:'\u8EEE',56387:'\u8EE5',56388:'\u8EF5',56389:'\u8EE7',56390:'\u8EE8',56391:'\u8EF6',56392:'\u8EEB',56393:'\u8EF1',56394:'\u8EEC',56395:'\u8EF4',56396:'\u8EE9',56397:'\u902D',56398:'\u9034',56399:'\u902F',56400:'\u9106',56401:'\u912C',56402:'\u9104',56403:'\u90FF',56404:'\u90FC',56405:'\u9108',56406:'\u90F9',56407:'\u90FB',56408:'\u9101',56409:'\u9100',56410:'\u9107',56411:'\u9105',56412:'\u9103',56413:'\u9161',56414:'\u9164',56415:'\u915F',56416:'\u9162',56417:'\u9160',56418:'\u9201',56419:'\u920A',56420:'\u9225',56421:'\u9203',56422:'\u921A',56423:'\u9226',56424:'\u920F',56425:'\u920C',56426:'\u9200',56427:'\u9212',56428:'\u91FF',56429:'\u91FD',56430:'\u9206',56431:'\u9204',56432:'\u9227',56433:'\u9202',56434:'\u921C',56435:'\u9224',56436:'\u9219',56437:'\u9217',56438:'\u9205',56439:'\u9216',56440:'\u957B',56441:'\u958D',56442:'\u958C',56443:'\u9590',56444:'\u9687',56445:'\u967E',56446:'\u9688',56481:'\u9689',56482:'\u9683',56483:'\u9680',56484:'\u96C2',56485:'\u96C8',56486:'\u96C3',56487:'\u96F1',56488:'\u96F0',56489:'\u976C',56490:'\u9770',56491:'\u976E',56492:'\u9807',56493:'\u98A9',56494:'\u98EB',56495:'\u9CE6',56496:'\u9EF9',56497:'\u4E83',56498:'\u4E84',56499:'\u4EB6',56500:'\u50BD',56501:'\u50BF',56502:'\u50C6',56503:'\u50AE',56504:'\u50C4',56505:'\u50CA',56506:'\u50B4',56507:'\u50C8',56508:'\u50C2',56509:'\u50B0',56510:'\u50C1',56511:'\u50BA',56512:'\u50B1',56513:'\u50CB',56514:'\u50C9',56515:'\u50B6',56516:'\u50B8',56517:'\u51D7',56518:'\u527A',56519:'\u5278',56520:'\u527B',56521:'\u527C',56522:'\u55C3',56523:'\u55DB',56524:'\u55CC',56525:'\u55D0',56526:'\u55CB',56527:'\u55CA',56528:'\u55DD',56529:'\u55C0',56530:'\u55D4',56531:'\u55C4',56532:'\u55E9',56533:'\u55BF',56534:'\u55D2',56535:'\u558D',56536:'\u55CF',56537:'\u55D5',56538:'\u55E2',56539:'\u55D6',56540:'\u55C8',56541:'\u55F2',56542:'\u55CD',56543:'\u55D9',56544:'\u55C2',56545:'\u5714',56546:'\u5853',56547:'\u5868',56548:'\u5864',56549:'\u584F',56550:'\u584D',56551:'\u5849',56552:'\u586F',56553:'\u5855',56554:'\u584E',56555:'\u585D',56556:'\u5859',56557:'\u5865',56558:'\u585B',56559:'\u583D',56560:'\u5863',56561:'\u5871',56562:'\u58FC',56563:'\u5AC7',56564:'\u5AC4',56565:'\u5ACB',56566:'\u5ABA',56567:'\u5AB8',56568:'\u5AB1',56569:'\u5AB5',56570:'\u5AB0',56571:'\u5ABF',56572:'\u5AC8',56573:'\u5ABB',56574:'\u5AC6',56640:'\u5AB7',56641:'\u5AC0',56642:'\u5ACA',56643:'\u5AB4',56644:'\u5AB6',56645:'\u5ACD',56646:'\u5AB9',56647:'\u5A90',56648:'\u5BD6',56649:'\u5BD8',56650:'\u5BD9',56651:'\u5C1F',56652:'\u5C33',56653:'\u5D71',56654:'\u5D63',56655:'\u5D4A',56656:'\u5D65',56657:'\u5D72',56658:'\u5D6C',56659:'\u5D5E',56660:'\u5D68',56661:'\u5D67',56662:'\u5D62',56663:'\u5DF0',56664:'\u5E4F',56665:'\u5E4E',56666:'\u5E4A',56667:'\u5E4D',56668:'\u5E4B',56669:'\u5EC5',56670:'\u5ECC',56671:'\u5EC6',56672:'\u5ECB',56673:'\u5EC7',56674:'\u5F40',56675:'\u5FAF',56676:'\u5FAD',56677:'\u60F7',56678:'\u6149',56679:'\u614A',56680:'\u612B',56681:'\u6145',56682:'\u6136',56683:'\u6132',56684:'\u612E',56685:'\u6146',56686:'\u612F',56687:'\u614F',56688:'\u6129',56689:'\u6140',56690:'\u6220',56691:'\u9168',56692:'\u6223',56693:'\u6225',56694:'\u6224',56695:'\u63C5',56696:'\u63F1',56697:'\u63EB',56698:'\u6410',56699:'\u6412',56700:'\u6409',56701:'\u6420',56702:'\u6424',56737:'\u6433',56738:'\u6443',56739:'\u641F',56740:'\u6415',56741:'\u6418',56742:'\u6439',56743:'\u6437',56744:'\u6422',56745:'\u6423',56746:'\u640C',56747:'\u6426',56748:'\u6430',56749:'\u6428',56750:'\u6441',56751:'\u6435',56752:'\u642F',56753:'\u640A',56754:'\u641A',56755:'\u6440',56756:'\u6425',56757:'\u6427',56758:'\u640B',56759:'\u63E7',56760:'\u641B',56761:'\u642E',56762:'\u6421',56763:'\u640E',56764:'\u656F',56765:'\u6592',56766:'\u65D3',56767:'\u6686',56768:'\u668C',56769:'\u6695',56770:'\u6690',56771:'\u668B',56772:'\u668A',56773:'\u6699',56774:'\u6694',56775:'\u6678',56776:'\u6720',56777:'\u6966',56778:'\u695F',56779:'\u6938',56780:'\u694E',56781:'\u6962',56782:'\u6971',56783:'\u693F',56784:'\u6945',56785:'\u696A',56786:'\u6939',56787:'\u6942',56788:'\u6957',56789:'\u6959',56790:'\u697A',56791:'\u6948',56792:'\u6949',56793:'\u6935',56794:'\u696C',56795:'\u6933',56796:'\u693D',56797:'\u6965',56798:'\u68F0',56799:'\u6978',56800:'\u6934',56801:'\u6969',56802:'\u6940',56803:'\u696F',56804:'\u6944',56805:'\u6976',56806:'\u6958',56807:'\u6941',56808:'\u6974',56809:'\u694C',56810:'\u693B',56811:'\u694B',56812:'\u6937',56813:'\u695C',56814:'\u694F',56815:'\u6951',56816:'\u6932',56817:'\u6952',56818:'\u692F',56819:'\u697B',56820:'\u693C',56821:'\u6B46',56822:'\u6B45',56823:'\u6B43',56824:'\u6B42',56825:'\u6B48',56826:'\u6B41',56827:'\u6B9B',56828:'\uFA0D',56829:'\u6BFB',56830:'\u6BFC',56896:'\u6BF9',56897:'\u6BF7',56898:'\u6BF8',56899:'\u6E9B',56900:'\u6ED6',56901:'\u6EC8',56902:'\u6E8F',56903:'\u6EC0',56904:'\u6E9F',56905:'\u6E93',56906:'\u6E94',56907:'\u6EA0',56908:'\u6EB1',56909:'\u6EB9',56910:'\u6EC6',56911:'\u6ED2',56912:'\u6EBD',56913:'\u6EC1',56914:'\u6E9E',56915:'\u6EC9',56916:'\u6EB7',56917:'\u6EB0',56918:'\u6ECD',56919:'\u6EA6',56920:'\u6ECF',56921:'\u6EB2',56922:'\u6EBE',56923:'\u6EC3',56924:'\u6EDC',56925:'\u6ED8',56926:'\u6E99',56927:'\u6E92',56928:'\u6E8E',56929:'\u6E8D',56930:'\u6EA4',56931:'\u6EA1',56932:'\u6EBF',56933:'\u6EB3',56934:'\u6ED0',56935:'\u6ECA',56936:'\u6E97',56937:'\u6EAE',56938:'\u6EA3',56939:'\u7147',56940:'\u7154',56941:'\u7152',56942:'\u7163',56943:'\u7160',56944:'\u7141',56945:'\u715D',56946:'\u7162',56947:'\u7172',56948:'\u7178',56949:'\u716A',56950:'\u7161',56951:'\u7142',56952:'\u7158',56953:'\u7143',56954:'\u714B',56955:'\u7170',56956:'\u715F',56957:'\u7150',56958:'\u7153',56993:'\u7144',56994:'\u714D',56995:'\u715A',56996:'\u724F',56997:'\u728D',56998:'\u728C',56999:'\u7291',57000:'\u7290',57001:'\u728E',57002:'\u733C',57003:'\u7342',57004:'\u733B',57005:'\u733A',57006:'\u7340',57007:'\u734A',57008:'\u7349',57009:'\u7444',57010:'\u744A',57011:'\u744B',57012:'\u7452',57013:'\u7451',57014:'\u7457',57015:'\u7440',57016:'\u744F',57017:'\u7450',57018:'\u744E',57019:'\u7442',57020:'\u7446',57021:'\u744D',57022:'\u7454',57023:'\u74E1',57024:'\u74FF',57025:'\u74FE',57026:'\u74FD',57027:'\u751D',57028:'\u7579',57029:'\u7577',57030:'\u6983',57031:'\u75EF',57032:'\u760F',57033:'\u7603',57034:'\u75F7',57035:'\u75FE',57036:'\u75FC',57037:'\u75F9',57038:'\u75F8',57039:'\u7610',57040:'\u75FB',57041:'\u75F6',57042:'\u75ED',57043:'\u75F5',57044:'\u75FD',57045:'\u7699',57046:'\u76B5',57047:'\u76DD',57048:'\u7755',57049:'\u775F',57050:'\u7760',57051:'\u7752',57052:'\u7756',57053:'\u775A',57054:'\u7769',57055:'\u7767',57056:'\u7754',57057:'\u7759',57058:'\u776D',57059:'\u77E0',57060:'\u7887',57061:'\u789A',57062:'\u7894',57063:'\u788F',57064:'\u7884',57065:'\u7895',57066:'\u7885',57067:'\u7886',57068:'\u78A1',57069:'\u7883',57070:'\u7879',57071:'\u7899',57072:'\u7880',57073:'\u7896',57074:'\u787B',57075:'\u797C',57076:'\u7982',57077:'\u797D',57078:'\u7979',57079:'\u7A11',57080:'\u7A18',57081:'\u7A19',57082:'\u7A12',57083:'\u7A17',57084:'\u7A15',57085:'\u7A22',57086:'\u7A13',57152:'\u7A1B',57153:'\u7A10',57154:'\u7AA3',57155:'\u7AA2',57156:'\u7A9E',57157:'\u7AEB',57158:'\u7B66',57159:'\u7B64',57160:'\u7B6D',57161:'\u7B74',57162:'\u7B69',57163:'\u7B72',57164:'\u7B65',57165:'\u7B73',57166:'\u7B71',57167:'\u7B70',57168:'\u7B61',57169:'\u7B78',57170:'\u7B76',57171:'\u7B63',57172:'\u7CB2',57173:'\u7CB4',57174:'\u7CAF',57175:'\u7D88',57176:'\u7D86',57177:'\u7D80',57178:'\u7D8D',57179:'\u7D7F',57180:'\u7D85',57181:'\u7D7A',57182:'\u7D8E',57183:'\u7D7B',57184:'\u7D83',57185:'\u7D7C',57186:'\u7D8C',57187:'\u7D94',57188:'\u7D84',57189:'\u7D7D',57190:'\u7D92',57191:'\u7F6D',57192:'\u7F6B',57193:'\u7F67',57194:'\u7F68',57195:'\u7F6C',57196:'\u7FA6',57197:'\u7FA5',57198:'\u7FA7',57199:'\u7FDB',57200:'\u7FDC',57201:'\u8021',57202:'\u8164',57203:'\u8160',57204:'\u8177',57205:'\u815C',57206:'\u8169',57207:'\u815B',57208:'\u8162',57209:'\u8172',57210:'\u6721',57211:'\u815E',57212:'\u8176',57213:'\u8167',57214:'\u816F',57249:'\u8144',57250:'\u8161',57251:'\u821D',57252:'\u8249',57253:'\u8244',57254:'\u8240',57255:'\u8242',57256:'\u8245',57257:'\u84F1',57258:'\u843F',57259:'\u8456',57260:'\u8476',57261:'\u8479',57262:'\u848F',57263:'\u848D',57264:'\u8465',57265:'\u8451',57266:'\u8440',57267:'\u8486',57268:'\u8467',57269:'\u8430',57270:'\u844D',57271:'\u847D',57272:'\u845A',57273:'\u8459',57274:'\u8474',57275:'\u8473',57276:'\u845D',57277:'\u8507',57278:'\u845E',57279:'\u8437',57280:'\u843A',57281:'\u8434',57282:'\u847A',57283:'\u8443',57284:'\u8478',57285:'\u8432',57286:'\u8445',57287:'\u8429',57288:'\u83D9',57289:'\u844B',57290:'\u842F',57291:'\u8442',57292:'\u842D',57293:'\u845F',57294:'\u8470',57295:'\u8439',57296:'\u844E',57297:'\u844C',57298:'\u8452',57299:'\u846F',57300:'\u84C5',57301:'\u848E',57302:'\u843B',57303:'\u8447',57304:'\u8436',57305:'\u8433',57306:'\u8468',57307:'\u847E',57308:'\u8444',57309:'\u842B',57310:'\u8460',57311:'\u8454',57312:'\u846E',57313:'\u8450',57314:'\u870B',57315:'\u8704',57316:'\u86F7',57317:'\u870C',57318:'\u86FA',57319:'\u86D6',57320:'\u86F5',57321:'\u874D',57322:'\u86F8',57323:'\u870E',57324:'\u8709',57325:'\u8701',57326:'\u86F6',57327:'\u870D',57328:'\u8705',57329:'\u88D6',57330:'\u88CB',57331:'\u88CD',57332:'\u88CE',57333:'\u88DE',57334:'\u88DB',57335:'\u88DA',57336:'\u88CC',57337:'\u88D0',57338:'\u8985',57339:'\u899B',57340:'\u89DF',57341:'\u89E5',57342:'\u89E4',57408:'\u89E1',57409:'\u89E0',57410:'\u89E2',57411:'\u89DC',57412:'\u89E6',57413:'\u8A76',57414:'\u8A86',57415:'\u8A7F',57416:'\u8A61',57417:'\u8A3F',57418:'\u8A77',57419:'\u8A82',57420:'\u8A84',57421:'\u8A75',57422:'\u8A83',57423:'\u8A81',57424:'\u8A74',57425:'\u8A7A',57426:'\u8C3C',57427:'\u8C4B',57428:'\u8C4A',57429:'\u8C65',57430:'\u8C64',57431:'\u8C66',57432:'\u8C86',57433:'\u8C84',57434:'\u8C85',57435:'\u8CCC',57436:'\u8D68',57437:'\u8D69',57438:'\u8D91',57439:'\u8D8C',57440:'\u8D8E',57441:'\u8D8F',57442:'\u8D8D',57443:'\u8D93',57444:'\u8D94',57445:'\u8D90',57446:'\u8D92',57447:'\u8DF0',57448:'\u8DE0',57449:'\u8DEC',57450:'\u8DF1',57451:'\u8DEE',57452:'\u8DD0',57453:'\u8DE9',57454:'\u8DE3',57455:'\u8DE2',57456:'\u8DE7',57457:'\u8DF2',57458:'\u8DEB',57459:'\u8DF4',57460:'\u8F06',57461:'\u8EFF',57462:'\u8F01',57463:'\u8F00',57464:'\u8F05',57465:'\u8F07',57466:'\u8F08',57467:'\u8F02',57468:'\u8F0B',57469:'\u9052',57470:'\u903F',57505:'\u9044',57506:'\u9049',57507:'\u903D',57508:'\u9110',57509:'\u910D',57510:'\u910F',57511:'\u9111',57512:'\u9116',57513:'\u9114',57514:'\u910B',57515:'\u910E',57516:'\u916E',57517:'\u916F',57518:'\u9248',57519:'\u9252',57520:'\u9230',57521:'\u923A',57522:'\u9266',57523:'\u9233',57524:'\u9265',57525:'\u925E',57526:'\u9283',57527:'\u922E',57528:'\u924A',57529:'\u9246',57530:'\u926D',57531:'\u926C',57532:'\u924F',57533:'\u9260',57534:'\u9267',57535:'\u926F',57536:'\u9236',57537:'\u9261',57538:'\u9270',57539:'\u9231',57540:'\u9254',57541:'\u9263',57542:'\u9250',57543:'\u9272',57544:'\u924E',57545:'\u9253',57546:'\u924C',57547:'\u9256',57548:'\u9232',57549:'\u959F',57550:'\u959C',57551:'\u959E',57552:'\u959B',57553:'\u9692',57554:'\u9693',57555:'\u9691',57556:'\u9697',57557:'\u96CE',57558:'\u96FA',57559:'\u96FD',57560:'\u96F8',57561:'\u96F5',57562:'\u9773',57563:'\u9777',57564:'\u9778',57565:'\u9772',57566:'\u980F',57567:'\u980D',57568:'\u980E',57569:'\u98AC',57570:'\u98F6',57571:'\u98F9',57572:'\u99AF',57573:'\u99B2',57574:'\u99B0',57575:'\u99B5',57576:'\u9AAD',57577:'\u9AAB',57578:'\u9B5B',57579:'\u9CEA',57580:'\u9CED',57581:'\u9CE7',57582:'\u9E80',57583:'\u9EFD',57584:'\u50E6',57585:'\u50D4',57586:'\u50D7',57587:'\u50E8',57588:'\u50F3',57589:'\u50DB',57590:'\u50EA',57591:'\u50DD',57592:'\u50E4',57593:'\u50D3',57594:'\u50EC',57595:'\u50F0',57596:'\u50EF',57597:'\u50E3',57598:'\u50E0',57664:'\u51D8',57665:'\u5280',57666:'\u5281',57667:'\u52E9',57668:'\u52EB',57669:'\u5330',57670:'\u53AC',57671:'\u5627',57672:'\u5615',57673:'\u560C',57674:'\u5612',57675:'\u55FC',57676:'\u560F',57677:'\u561C',57678:'\u5601',57679:'\u5613',57680:'\u5602',57681:'\u55FA',57682:'\u561D',57683:'\u5604',57684:'\u55FF',57685:'\u55F9',57686:'\u5889',57687:'\u587C',57688:'\u5890',57689:'\u5898',57690:'\u5886',57691:'\u5881',57692:'\u587F',57693:'\u5874',57694:'\u588B',57695:'\u587A',57696:'\u5887',57697:'\u5891',57698:'\u588E',57699:'\u5876',57700:'\u5882',57701:'\u5888',57702:'\u587B',57703:'\u5894',57704:'\u588F',57705:'\u58FE',57706:'\u596B',57707:'\u5ADC',57708:'\u5AEE',57709:'\u5AE5',57710:'\u5AD5',57711:'\u5AEA',57712:'\u5ADA',57713:'\u5AED',57714:'\u5AEB',57715:'\u5AF3',57716:'\u5AE2',57717:'\u5AE0',57718:'\u5ADB',57719:'\u5AEC',57720:'\u5ADE',57721:'\u5ADD',57722:'\u5AD9',57723:'\u5AE8',57724:'\u5ADF',57725:'\u5B77',57726:'\u5BE0',57761:'\u5BE3',57762:'\u5C63',57763:'\u5D82',57764:'\u5D80',57765:'\u5D7D',57766:'\u5D86',57767:'\u5D7A',57768:'\u5D81',57769:'\u5D77',57770:'\u5D8A',57771:'\u5D89',57772:'\u5D88',57773:'\u5D7E',57774:'\u5D7C',57775:'\u5D8D',57776:'\u5D79',57777:'\u5D7F',57778:'\u5E58',57779:'\u5E59',57780:'\u5E53',57781:'\u5ED8',57782:'\u5ED1',57783:'\u5ED7',57784:'\u5ECE',57785:'\u5EDC',57786:'\u5ED5',57787:'\u5ED9',57788:'\u5ED2',57789:'\u5ED4',57790:'\u5F44',57791:'\u5F43',57792:'\u5F6F',57793:'\u5FB6',57794:'\u612C',57795:'\u6128',57796:'\u6141',57797:'\u615E',57798:'\u6171',57799:'\u6173',57800:'\u6152',57801:'\u6153',57802:'\u6172',57803:'\u616C',57804:'\u6180',57805:'\u6174',57806:'\u6154',57807:'\u617A',57808:'\u615B',57809:'\u6165',57810:'\u613B',57811:'\u616A',57812:'\u6161',57813:'\u6156',57814:'\u6229',57815:'\u6227',57816:'\u622B',57817:'\u642B',57818:'\u644D',57819:'\u645B',57820:'\u645D',57821:'\u6474',57822:'\u6476',57823:'\u6472',57824:'\u6473',57825:'\u647D',57826:'\u6475',57827:'\u6466',57828:'\u64A6',57829:'\u644E',57830:'\u6482',57831:'\u645E',57832:'\u645C',57833:'\u644B',57834:'\u6453',57835:'\u6460',57836:'\u6450',57837:'\u647F',57838:'\u643F',57839:'\u646C',57840:'\u646B',57841:'\u6459',57842:'\u6465',57843:'\u6477',57844:'\u6573',57845:'\u65A0',57846:'\u66A1',57847:'\u66A0',57848:'\u669F',57849:'\u6705',57850:'\u6704',57851:'\u6722',57852:'\u69B1',57853:'\u69B6',57854:'\u69C9',57920:'\u69A0',57921:'\u69CE',57922:'\u6996',57923:'\u69B0',57924:'\u69AC',57925:'\u69BC',57926:'\u6991',57927:'\u6999',57928:'\u698E',57929:'\u69A7',57930:'\u698D',57931:'\u69A9',57932:'\u69BE',57933:'\u69AF',57934:'\u69BF',57935:'\u69C4',57936:'\u69BD',57937:'\u69A4',57938:'\u69D4',57939:'\u69B9',57940:'\u69CA',57941:'\u699A',57942:'\u69CF',57943:'\u69B3',57944:'\u6993',57945:'\u69AA',57946:'\u69A1',57947:'\u699E',57948:'\u69D9',57949:'\u6997',57950:'\u6990',57951:'\u69C2',57952:'\u69B5',57953:'\u69A5',57954:'\u69C6',57955:'\u6B4A',57956:'\u6B4D',57957:'\u6B4B',57958:'\u6B9E',57959:'\u6B9F',57960:'\u6BA0',57961:'\u6BC3',57962:'\u6BC4',57963:'\u6BFE',57964:'\u6ECE',57965:'\u6EF5',57966:'\u6EF1',57967:'\u6F03',57968:'\u6F25',57969:'\u6EF8',57970:'\u6F37',57971:'\u6EFB',57972:'\u6F2E',57973:'\u6F09',57974:'\u6F4E',57975:'\u6F19',57976:'\u6F1A',57977:'\u6F27',57978:'\u6F18',57979:'\u6F3B',57980:'\u6F12',57981:'\u6EED',57982:'\u6F0A',58017:'\u6F36',58018:'\u6F73',58019:'\u6EF9',58020:'\u6EEE',58021:'\u6F2D',58022:'\u6F40',58023:'\u6F30',58024:'\u6F3C',58025:'\u6F35',58026:'\u6EEB',58027:'\u6F07',58028:'\u6F0E',58029:'\u6F43',58030:'\u6F05',58031:'\u6EFD',58032:'\u6EF6',58033:'\u6F39',58034:'\u6F1C',58035:'\u6EFC',58036:'\u6F3A',58037:'\u6F1F',58038:'\u6F0D',58039:'\u6F1E',58040:'\u6F08',58041:'\u6F21',58042:'\u7187',58043:'\u7190',58044:'\u7189',58045:'\u7180',58046:'\u7185',58047:'\u7182',58048:'\u718F',58049:'\u717B',58050:'\u7186',58051:'\u7181',58052:'\u7197',58053:'\u7244',58054:'\u7253',58055:'\u7297',58056:'\u7295',58057:'\u7293',58058:'\u7343',58059:'\u734D',58060:'\u7351',58061:'\u734C',58062:'\u7462',58063:'\u7473',58064:'\u7471',58065:'\u7475',58066:'\u7472',58067:'\u7467',58068:'\u746E',58069:'\u7500',58070:'\u7502',58071:'\u7503',58072:'\u757D',58073:'\u7590',58074:'\u7616',58075:'\u7608',58076:'\u760C',58077:'\u7615',58078:'\u7611',58079:'\u760A',58080:'\u7614',58081:'\u76B8',58082:'\u7781',58083:'\u777C',58084:'\u7785',58085:'\u7782',58086:'\u776E',58087:'\u7780',58088:'\u776F',58089:'\u777E',58090:'\u7783',58091:'\u78B2',58092:'\u78AA',58093:'\u78B4',58094:'\u78AD',58095:'\u78A8',58096:'\u787E',58097:'\u78AB',58098:'\u789E',58099:'\u78A5',58100:'\u78A0',58101:'\u78AC',58102:'\u78A2',58103:'\u78A4',58104:'\u7998',58105:'\u798A',58106:'\u798B',58107:'\u7996',58108:'\u7995',58109:'\u7994',58110:'\u7993',58176:'\u7997',58177:'\u7988',58178:'\u7992',58179:'\u7990',58180:'\u7A2B',58181:'\u7A4A',58182:'\u7A30',58183:'\u7A2F',58184:'\u7A28',58185:'\u7A26',58186:'\u7AA8',58187:'\u7AAB',58188:'\u7AAC',58189:'\u7AEE',58190:'\u7B88',58191:'\u7B9C',58192:'\u7B8A',58193:'\u7B91',58194:'\u7B90',58195:'\u7B96',58196:'\u7B8D',58197:'\u7B8C',58198:'\u7B9B',58199:'\u7B8E',58200:'\u7B85',58201:'\u7B98',58202:'\u5284',58203:'\u7B99',58204:'\u7BA4',58205:'\u7B82',58206:'\u7CBB',58207:'\u7CBF',58208:'\u7CBC',58209:'\u7CBA',58210:'\u7DA7',58211:'\u7DB7',58212:'\u7DC2',58213:'\u7DA3',58214:'\u7DAA',58215:'\u7DC1',58216:'\u7DC0',58217:'\u7DC5',58218:'\u7D9D',58219:'\u7DCE',58220:'\u7DC4',58221:'\u7DC6',58222:'\u7DCB',58223:'\u7DCC',58224:'\u7DAF',58225:'\u7DB9',58226:'\u7D96',58227:'\u7DBC',58228:'\u7D9F',58229:'\u7DA6',58230:'\u7DAE',58231:'\u7DA9',58232:'\u7DA1',58233:'\u7DC9',58234:'\u7F73',58235:'\u7FE2',58236:'\u7FE3',58237:'\u7FE5',58238:'\u7FDE',58273:'\u8024',58274:'\u805D',58275:'\u805C',58276:'\u8189',58277:'\u8186',58278:'\u8183',58279:'\u8187',58280:'\u818D',58281:'\u818C',58282:'\u818B',58283:'\u8215',58284:'\u8497',58285:'\u84A4',58286:'\u84A1',58287:'\u849F',58288:'\u84BA',58289:'\u84CE',58290:'\u84C2',58291:'\u84AC',58292:'\u84AE',58293:'\u84AB',58294:'\u84B9',58295:'\u84B4',58296:'\u84C1',58297:'\u84CD',58298:'\u84AA',58299:'\u849A',58300:'\u84B1',58301:'\u84D0',58302:'\u849D',58303:'\u84A7',58304:'\u84BB',58305:'\u84A2',58306:'\u8494',58307:'\u84C7',58308:'\u84CC',58309:'\u849B',58310:'\u84A9',58311:'\u84AF',58312:'\u84A8',58313:'\u84D6',58314:'\u8498',58315:'\u84B6',58316:'\u84CF',58317:'\u84A0',58318:'\u84D7',58319:'\u84D4',58320:'\u84D2',58321:'\u84DB',58322:'\u84B0',58323:'\u8491',58324:'\u8661',58325:'\u8733',58326:'\u8723',58327:'\u8728',58328:'\u876B',58329:'\u8740',58330:'\u872E',58331:'\u871E',58332:'\u8721',58333:'\u8719',58334:'\u871B',58335:'\u8743',58336:'\u872C',58337:'\u8741',58338:'\u873E',58339:'\u8746',58340:'\u8720',58341:'\u8732',58342:'\u872A',58343:'\u872D',58344:'\u873C',58345:'\u8712',58346:'\u873A',58347:'\u8731',58348:'\u8735',58349:'\u8742',58350:'\u8726',58351:'\u8727',58352:'\u8738',58353:'\u8724',58354:'\u871A',58355:'\u8730',58356:'\u8711',58357:'\u88F7',58358:'\u88E7',58359:'\u88F1',58360:'\u88F2',58361:'\u88FA',58362:'\u88FE',58363:'\u88EE',58364:'\u88FC',58365:'\u88F6',58366:'\u88FB',58432:'\u88F0',58433:'\u88EC',58434:'\u88EB',58435:'\u899D',58436:'\u89A1',58437:'\u899F',58438:'\u899E',58439:'\u89E9',58440:'\u89EB',58441:'\u89E8',58442:'\u8AAB',58443:'\u8A99',58444:'\u8A8B',58445:'\u8A92',58446:'\u8A8F',58447:'\u8A96',58448:'\u8C3D',58449:'\u8C68',58450:'\u8C69',58451:'\u8CD5',58452:'\u8CCF',58453:'\u8CD7',58454:'\u8D96',58455:'\u8E09',58456:'\u8E02',58457:'\u8DFF',58458:'\u8E0D',58459:'\u8DFD',58460:'\u8E0A',58461:'\u8E03',58462:'\u8E07',58463:'\u8E06',58464:'\u8E05',58465:'\u8DFE',58466:'\u8E00',58467:'\u8E04',58468:'\u8F10',58469:'\u8F11',58470:'\u8F0E',58471:'\u8F0D',58472:'\u9123',58473:'\u911C',58474:'\u9120',58475:'\u9122',58476:'\u911F',58477:'\u911D',58478:'\u911A',58479:'\u9124',58480:'\u9121',58481:'\u911B',58482:'\u917A',58483:'\u9172',58484:'\u9179',58485:'\u9173',58486:'\u92A5',58487:'\u92A4',58488:'\u9276',58489:'\u929B',58490:'\u927A',58491:'\u92A0',58492:'\u9294',58493:'\u92AA',58494:'\u928D',58529:'\u92A6',58530:'\u929A',58531:'\u92AB',58532:'\u9279',58533:'\u9297',58534:'\u927F',58535:'\u92A3',58536:'\u92EE',58537:'\u928E',58538:'\u9282',58539:'\u9295',58540:'\u92A2',58541:'\u927D',58542:'\u9288',58543:'\u92A1',58544:'\u928A',58545:'\u9286',58546:'\u928C',58547:'\u9299',58548:'\u92A7',58549:'\u927E',58550:'\u9287',58551:'\u92A9',58552:'\u929D',58553:'\u928B',58554:'\u922D',58555:'\u969E',58556:'\u96A1',58557:'\u96FF',58558:'\u9758',58559:'\u977D',58560:'\u977A',58561:'\u977E',58562:'\u9783',58563:'\u9780',58564:'\u9782',58565:'\u977B',58566:'\u9784',58567:'\u9781',58568:'\u977F',58569:'\u97CE',58570:'\u97CD',58571:'\u9816',58572:'\u98AD',58573:'\u98AE',58574:'\u9902',58575:'\u9900',58576:'\u9907',58577:'\u999D',58578:'\u999C',58579:'\u99C3',58580:'\u99B9',58581:'\u99BB',58582:'\u99BA',58583:'\u99C2',58584:'\u99BD',58585:'\u99C7',58586:'\u9AB1',58587:'\u9AE3',58588:'\u9AE7',58589:'\u9B3E',58590:'\u9B3F',58591:'\u9B60',58592:'\u9B61',58593:'\u9B5F',58594:'\u9CF1',58595:'\u9CF2',58596:'\u9CF5',58597:'\u9EA7',58598:'\u50FF',58599:'\u5103',58600:'\u5130',58601:'\u50F8',58602:'\u5106',58603:'\u5107',58604:'\u50F6',58605:'\u50FE',58606:'\u510B',58607:'\u510C',58608:'\u50FD',58609:'\u510A',58610:'\u528B',58611:'\u528C',58612:'\u52F1',58613:'\u52EF',58614:'\u5648',58615:'\u5642',58616:'\u564C',58617:'\u5635',58618:'\u5641',58619:'\u564A',58620:'\u5649',58621:'\u5646',58622:'\u5658',58688:'\u565A',58689:'\u5640',58690:'\u5633',58691:'\u563D',58692:'\u562C',58693:'\u563E',58694:'\u5638',58695:'\u562A',58696:'\u563A',58697:'\u571A',58698:'\u58AB',58699:'\u589D',58700:'\u58B1',58701:'\u58A0',58702:'\u58A3',58703:'\u58AF',58704:'\u58AC',58705:'\u58A5',58706:'\u58A1',58707:'\u58FF',58708:'\u5AFF',58709:'\u5AF4',58710:'\u5AFD',58711:'\u5AF7',58712:'\u5AF6',58713:'\u5B03',58714:'\u5AF8',58715:'\u5B02',58716:'\u5AF9',58717:'\u5B01',58718:'\u5B07',58719:'\u5B05',58720:'\u5B0F',58721:'\u5C67',58722:'\u5D99',58723:'\u5D97',58724:'\u5D9F',58725:'\u5D92',58726:'\u5DA2',58727:'\u5D93',58728:'\u5D95',58729:'\u5DA0',58730:'\u5D9C',58731:'\u5DA1',58732:'\u5D9A',58733:'\u5D9E',58734:'\u5E69',58735:'\u5E5D',58736:'\u5E60',58737:'\u5E5C',58738:'\u7DF3',58739:'\u5EDB',58740:'\u5EDE',58741:'\u5EE1',58742:'\u5F49',58743:'\u5FB2',58744:'\u618B',58745:'\u6183',58746:'\u6179',58747:'\u61B1',58748:'\u61B0',58749:'\u61A2',58750:'\u6189',58785:'\u619B',58786:'\u6193',58787:'\u61AF',58788:'\u61AD',58789:'\u619F',58790:'\u6192',58791:'\u61AA',58792:'\u61A1',58793:'\u618D',58794:'\u6166',58795:'\u61B3',58796:'\u622D',58797:'\u646E',58798:'\u6470',58799:'\u6496',58800:'\u64A0',58801:'\u6485',58802:'\u6497',58803:'\u649C',58804:'\u648F',58805:'\u648B',58806:'\u648A',58807:'\u648C',58808:'\u64A3',58809:'\u649F',58810:'\u6468',58811:'\u64B1',58812:'\u6498',58813:'\u6576',58814:'\u657A',58815:'\u6579',58816:'\u657B',58817:'\u65B2',58818:'\u65B3',58819:'\u66B5',58820:'\u66B0',58821:'\u66A9',58822:'\u66B2',58823:'\u66B7',58824:'\u66AA',58825:'\u66AF',58826:'\u6A00',58827:'\u6A06',58828:'\u6A17',58829:'\u69E5',58830:'\u69F8',58831:'\u6A15',58832:'\u69F1',58833:'\u69E4',58834:'\u6A20',58835:'\u69FF',58836:'\u69EC',58837:'\u69E2',58838:'\u6A1B',58839:'\u6A1D',58840:'\u69FE',58841:'\u6A27',58842:'\u69F2',58843:'\u69EE',58844:'\u6A14',58845:'\u69F7',58846:'\u69E7',58847:'\u6A40',58848:'\u6A08',58849:'\u69E6',58850:'\u69FB',58851:'\u6A0D',58852:'\u69FC',58853:'\u69EB',58854:'\u6A09',58855:'\u6A04',58856:'\u6A18',58857:'\u6A25',58858:'\u6A0F',58859:'\u69F6',58860:'\u6A26',58861:'\u6A07',58862:'\u69F4',58863:'\u6A16',58864:'\u6B51',58865:'\u6BA5',58866:'\u6BA3',58867:'\u6BA2',58868:'\u6BA6',58869:'\u6C01',58870:'\u6C00',58871:'\u6BFF',58872:'\u6C02',58873:'\u6F41',58874:'\u6F26',58875:'\u6F7E',58876:'\u6F87',58877:'\u6FC6',58878:'\u6F92',58944:'\u6F8D',58945:'\u6F89',58946:'\u6F8C',58947:'\u6F62',58948:'\u6F4F',58949:'\u6F85',58950:'\u6F5A',58951:'\u6F96',58952:'\u6F76',58953:'\u6F6C',58954:'\u6F82',58955:'\u6F55',58956:'\u6F72',58957:'\u6F52',58958:'\u6F50',58959:'\u6F57',58960:'\u6F94',58961:'\u6F93',58962:'\u6F5D',58963:'\u6F00',58964:'\u6F61',58965:'\u6F6B',58966:'\u6F7D',58967:'\u6F67',58968:'\u6F90',58969:'\u6F53',58970:'\u6F8B',58971:'\u6F69',58972:'\u6F7F',58973:'\u6F95',58974:'\u6F63',58975:'\u6F77',58976:'\u6F6A',58977:'\u6F7B',58978:'\u71B2',58979:'\u71AF',58980:'\u719B',58981:'\u71B0',58982:'\u71A0',58983:'\u719A',58984:'\u71A9',58985:'\u71B5',58986:'\u719D',58987:'\u71A5',58988:'\u719E',58989:'\u71A4',58990:'\u71A1',58991:'\u71AA',58992:'\u719C',58993:'\u71A7',58994:'\u71B3',58995:'\u7298',58996:'\u729A',58997:'\u7358',58998:'\u7352',58999:'\u735E',59000:'\u735F',59001:'\u7360',59002:'\u735D',59003:'\u735B',59004:'\u7361',59005:'\u735A',59006:'\u7359',59041:'\u7362',59042:'\u7487',59043:'\u7489',59044:'\u748A',59045:'\u7486',59046:'\u7481',59047:'\u747D',59048:'\u7485',59049:'\u7488',59050:'\u747C',59051:'\u7479',59052:'\u7508',59053:'\u7507',59054:'\u757E',59055:'\u7625',59056:'\u761E',59057:'\u7619',59058:'\u761D',59059:'\u761C',59060:'\u7623',59061:'\u761A',59062:'\u7628',59063:'\u761B',59064:'\u769C',59065:'\u769D',59066:'\u769E',59067:'\u769B',59068:'\u778D',59069:'\u778F',59070:'\u7789',59071:'\u7788',59072:'\u78CD',59073:'\u78BB',59074:'\u78CF',59075:'\u78CC',59076:'\u78D1',59077:'\u78CE',59078:'\u78D4',59079:'\u78C8',59080:'\u78C3',59081:'\u78C4',59082:'\u78C9',59083:'\u799A',59084:'\u79A1',59085:'\u79A0',59086:'\u799C',59087:'\u79A2',59088:'\u799B',59089:'\u6B76',59090:'\u7A39',59091:'\u7AB2',59092:'\u7AB4',59093:'\u7AB3',59094:'\u7BB7',59095:'\u7BCB',59096:'\u7BBE',59097:'\u7BAC',59098:'\u7BCE',59099:'\u7BAF',59100:'\u7BB9',59101:'\u7BCA',59102:'\u7BB5',59103:'\u7CC5',59104:'\u7CC8',59105:'\u7CCC',59106:'\u7CCB',59107:'\u7DF7',59108:'\u7DDB',59109:'\u7DEA',59110:'\u7DE7',59111:'\u7DD7',59112:'\u7DE1',59113:'\u7E03',59114:'\u7DFA',59115:'\u7DE6',59116:'\u7DF6',59117:'\u7DF1',59118:'\u7DF0',59119:'\u7DEE',59120:'\u7DDF',59121:'\u7F76',59122:'\u7FAC',59123:'\u7FB0',59124:'\u7FAD',59125:'\u7FED',59126:'\u7FEB',59127:'\u7FEA',59128:'\u7FEC',59129:'\u7FE6',59130:'\u7FE8',59131:'\u8064',59132:'\u8067',59133:'\u81A3',59134:'\u819F',59200:'\u819E',59201:'\u8195',59202:'\u81A2',59203:'\u8199',59204:'\u8197',59205:'\u8216',59206:'\u824F',59207:'\u8253',59208:'\u8252',59209:'\u8250',59210:'\u824E',59211:'\u8251',59212:'\u8524',59213:'\u853B',59214:'\u850F',59215:'\u8500',59216:'\u8529',59217:'\u850E',59218:'\u8509',59219:'\u850D',59220:'\u851F',59221:'\u850A',59222:'\u8527',59223:'\u851C',59224:'\u84FB',59225:'\u852B',59226:'\u84FA',59227:'\u8508',59228:'\u850C',59229:'\u84F4',59230:'\u852A',59231:'\u84F2',59232:'\u8515',59233:'\u84F7',59234:'\u84EB',59235:'\u84F3',59236:'\u84FC',59237:'\u8512',59238:'\u84EA',59239:'\u84E9',59240:'\u8516',59241:'\u84FE',59242:'\u8528',59243:'\u851D',59244:'\u852E',59245:'\u8502',59246:'\u84FD',59247:'\u851E',59248:'\u84F6',59249:'\u8531',59250:'\u8526',59251:'\u84E7',59252:'\u84E8',59253:'\u84F0',59254:'\u84EF',59255:'\u84F9',59256:'\u8518',59257:'\u8520',59258:'\u8530',59259:'\u850B',59260:'\u8519',59261:'\u852F',59262:'\u8662',59297:'\u8756',59298:'\u8763',59299:'\u8764',59300:'\u8777',59301:'\u87E1',59302:'\u8773',59303:'\u8758',59304:'\u8754',59305:'\u875B',59306:'\u8752',59307:'\u8761',59308:'\u875A',59309:'\u8751',59310:'\u875E',59311:'\u876D',59312:'\u876A',59313:'\u8750',59314:'\u874E',59315:'\u875F',59316:'\u875D',59317:'\u876F',59318:'\u876C',59319:'\u877A',59320:'\u876E',59321:'\u875C',59322:'\u8765',59323:'\u874F',59324:'\u877B',59325:'\u8775',59326:'\u8762',59327:'\u8767',59328:'\u8769',59329:'\u885A',59330:'\u8905',59331:'\u890C',59332:'\u8914',59333:'\u890B',59334:'\u8917',59335:'\u8918',59336:'\u8919',59337:'\u8906',59338:'\u8916',59339:'\u8911',59340:'\u890E',59341:'\u8909',59342:'\u89A2',59343:'\u89A4',59344:'\u89A3',59345:'\u89ED',59346:'\u89F0',59347:'\u89EC',59348:'\u8ACF',59349:'\u8AC6',59350:'\u8AB8',59351:'\u8AD3',59352:'\u8AD1',59353:'\u8AD4',59354:'\u8AD5',59355:'\u8ABB',59356:'\u8AD7',59357:'\u8ABE',59358:'\u8AC0',59359:'\u8AC5',59360:'\u8AD8',59361:'\u8AC3',59362:'\u8ABA',59363:'\u8ABD',59364:'\u8AD9',59365:'\u8C3E',59366:'\u8C4D',59367:'\u8C8F',59368:'\u8CE5',59369:'\u8CDF',59370:'\u8CD9',59371:'\u8CE8',59372:'\u8CDA',59373:'\u8CDD',59374:'\u8CE7',59375:'\u8DA0',59376:'\u8D9C',59377:'\u8DA1',59378:'\u8D9B',59379:'\u8E20',59380:'\u8E23',59381:'\u8E25',59382:'\u8E24',59383:'\u8E2E',59384:'\u8E15',59385:'\u8E1B',59386:'\u8E16',59387:'\u8E11',59388:'\u8E19',59389:'\u8E26',59390:'\u8E27',59456:'\u8E14',59457:'\u8E12',59458:'\u8E18',59459:'\u8E13',59460:'\u8E1C',59461:'\u8E17',59462:'\u8E1A',59463:'\u8F2C',59464:'\u8F24',59465:'\u8F18',59466:'\u8F1A',59467:'\u8F20',59468:'\u8F23',59469:'\u8F16',59470:'\u8F17',59471:'\u9073',59472:'\u9070',59473:'\u906F',59474:'\u9067',59475:'\u906B',59476:'\u912F',59477:'\u912B',59478:'\u9129',59479:'\u912A',59480:'\u9132',59481:'\u9126',59482:'\u912E',59483:'\u9185',59484:'\u9186',59485:'\u918A',59486:'\u9181',59487:'\u9182',59488:'\u9184',59489:'\u9180',59490:'\u92D0',59491:'\u92C3',59492:'\u92C4',59493:'\u92C0',59494:'\u92D9',59495:'\u92B6',59496:'\u92CF',59497:'\u92F1',59498:'\u92DF',59499:'\u92D8',59500:'\u92E9',59501:'\u92D7',59502:'\u92DD',59503:'\u92CC',59504:'\u92EF',59505:'\u92C2',59506:'\u92E8',59507:'\u92CA',59508:'\u92C8',59509:'\u92CE',59510:'\u92E6',59511:'\u92CD',59512:'\u92D5',59513:'\u92C9',59514:'\u92E0',59515:'\u92DE',59516:'\u92E7',59517:'\u92D1',59518:'\u92D3',59553:'\u92B5',59554:'\u92E1',59555:'\u92C6',59556:'\u92B4',59557:'\u957C',59558:'\u95AC',59559:'\u95AB',59560:'\u95AE',59561:'\u95B0',59562:'\u96A4',59563:'\u96A2',59564:'\u96D3',59565:'\u9705',59566:'\u9708',59567:'\u9702',59568:'\u975A',59569:'\u978A',59570:'\u978E',59571:'\u9788',59572:'\u97D0',59573:'\u97CF',59574:'\u981E',59575:'\u981D',59576:'\u9826',59577:'\u9829',59578:'\u9828',59579:'\u9820',59580:'\u981B',59581:'\u9827',59582:'\u98B2',59583:'\u9908',59584:'\u98FA',59585:'\u9911',59586:'\u9914',59587:'\u9916',59588:'\u9917',59589:'\u9915',59590:'\u99DC',59591:'\u99CD',59592:'\u99CF',59593:'\u99D3',59594:'\u99D4',59595:'\u99CE',59596:'\u99C9',59597:'\u99D6',59598:'\u99D8',59599:'\u99CB',59600:'\u99D7',59601:'\u99CC',59602:'\u9AB3',59603:'\u9AEC',59604:'\u9AEB',59605:'\u9AF3',59606:'\u9AF2',59607:'\u9AF1',59608:'\u9B46',59609:'\u9B43',59610:'\u9B67',59611:'\u9B74',59612:'\u9B71',59613:'\u9B66',59614:'\u9B76',59615:'\u9B75',59616:'\u9B70',59617:'\u9B68',59618:'\u9B64',59619:'\u9B6C',59620:'\u9CFC',59621:'\u9CFA',59622:'\u9CFD',59623:'\u9CFF',59624:'\u9CF7',59625:'\u9D07',59626:'\u9D00',59627:'\u9CF9',59628:'\u9CFB',59629:'\u9D08',59630:'\u9D05',59631:'\u9D04',59632:'\u9E83',59633:'\u9ED3',59634:'\u9F0F',59635:'\u9F10',59636:'\u511C',59637:'\u5113',59638:'\u5117',59639:'\u511A',59640:'\u5111',59641:'\u51DE',59642:'\u5334',59643:'\u53E1',59644:'\u5670',59645:'\u5660',59646:'\u566E',59712:'\u5673',59713:'\u5666',59714:'\u5663',59715:'\u566D',59716:'\u5672',59717:'\u565E',59718:'\u5677',59719:'\u571C',59720:'\u571B',59721:'\u58C8',59722:'\u58BD',59723:'\u58C9',59724:'\u58BF',59725:'\u58BA',59726:'\u58C2',59727:'\u58BC',59728:'\u58C6',59729:'\u5B17',59730:'\u5B19',59731:'\u5B1B',59732:'\u5B21',59733:'\u5B14',59734:'\u5B13',59735:'\u5B10',59736:'\u5B16',59737:'\u5B28',59738:'\u5B1A',59739:'\u5B20',59740:'\u5B1E',59741:'\u5BEF',59742:'\u5DAC',59743:'\u5DB1',59744:'\u5DA9',59745:'\u5DA7',59746:'\u5DB5',59747:'\u5DB0',59748:'\u5DAE',59749:'\u5DAA',59750:'\u5DA8',59751:'\u5DB2',59752:'\u5DAD',59753:'\u5DAF',59754:'\u5DB4',59755:'\u5E67',59756:'\u5E68',59757:'\u5E66',59758:'\u5E6F',59759:'\u5EE9',59760:'\u5EE7',59761:'\u5EE6',59762:'\u5EE8',59763:'\u5EE5',59764:'\u5F4B',59765:'\u5FBC',59766:'\u619D',59767:'\u61A8',59768:'\u6196',59769:'\u61C5',59770:'\u61B4',59771:'\u61C6',59772:'\u61C1',59773:'\u61CC',59774:'\u61BA',59809:'\u61BF',59810:'\u61B8',59811:'\u618C',59812:'\u64D7',59813:'\u64D6',59814:'\u64D0',59815:'\u64CF',59816:'\u64C9',59817:'\u64BD',59818:'\u6489',59819:'\u64C3',59820:'\u64DB',59821:'\u64F3',59822:'\u64D9',59823:'\u6533',59824:'\u657F',59825:'\u657C',59826:'\u65A2',59827:'\u66C8',59828:'\u66BE',59829:'\u66C0',59830:'\u66CA',59831:'\u66CB',59832:'\u66CF',59833:'\u66BD',59834:'\u66BB',59835:'\u66BA',59836:'\u66CC',59837:'\u6723',59838:'\u6A34',59839:'\u6A66',59840:'\u6A49',59841:'\u6A67',59842:'\u6A32',59843:'\u6A68',59844:'\u6A3E',59845:'\u6A5D',59846:'\u6A6D',59847:'\u6A76',59848:'\u6A5B',59849:'\u6A51',59850:'\u6A28',59851:'\u6A5A',59852:'\u6A3B',59853:'\u6A3F',59854:'\u6A41',59855:'\u6A6A',59856:'\u6A64',59857:'\u6A50',59858:'\u6A4F',59859:'\u6A54',59860:'\u6A6F',59861:'\u6A69',59862:'\u6A60',59863:'\u6A3C',59864:'\u6A5E',59865:'\u6A56',59866:'\u6A55',59867:'\u6A4D',59868:'\u6A4E',59869:'\u6A46',59870:'\u6B55',59871:'\u6B54',59872:'\u6B56',59873:'\u6BA7',59874:'\u6BAA',59875:'\u6BAB',59876:'\u6BC8',59877:'\u6BC7',59878:'\u6C04',59879:'\u6C03',59880:'\u6C06',59881:'\u6FAD',59882:'\u6FCB',59883:'\u6FA3',59884:'\u6FC7',59885:'\u6FBC',59886:'\u6FCE',59887:'\u6FC8',59888:'\u6F5E',59889:'\u6FC4',59890:'\u6FBD',59891:'\u6F9E',59892:'\u6FCA',59893:'\u6FA8',59894:'\u7004',59895:'\u6FA5',59896:'\u6FAE',59897:'\u6FBA',59898:'\u6FAC',59899:'\u6FAA',59900:'\u6FCF',59901:'\u6FBF',59902:'\u6FB8',59968:'\u6FA2',59969:'\u6FC9',59970:'\u6FAB',59971:'\u6FCD',59972:'\u6FAF',59973:'\u6FB2',59974:'\u6FB0',59975:'\u71C5',59976:'\u71C2',59977:'\u71BF',59978:'\u71B8',59979:'\u71D6',59980:'\u71C0',59981:'\u71C1',59982:'\u71CB',59983:'\u71D4',59984:'\u71CA',59985:'\u71C7',59986:'\u71CF',59987:'\u71BD',59988:'\u71D8',59989:'\u71BC',59990:'\u71C6',59991:'\u71DA',59992:'\u71DB',59993:'\u729D',59994:'\u729E',59995:'\u7369',59996:'\u7366',59997:'\u7367',59998:'\u736C',59999:'\u7365',60000:'\u736B',60001:'\u736A',60002:'\u747F',60003:'\u749A',60004:'\u74A0',60005:'\u7494',60006:'\u7492',60007:'\u7495',60008:'\u74A1',60009:'\u750B',60010:'\u7580',60011:'\u762F',60012:'\u762D',60013:'\u7631',60014:'\u763D',60015:'\u7633',60016:'\u763C',60017:'\u7635',60018:'\u7632',60019:'\u7630',60020:'\u76BB',60021:'\u76E6',60022:'\u779A',60023:'\u779D',60024:'\u77A1',60025:'\u779C',60026:'\u779B',60027:'\u77A2',60028:'\u77A3',60029:'\u7795',60030:'\u7799',60065:'\u7797',60066:'\u78DD',60067:'\u78E9',60068:'\u78E5',60069:'\u78EA',60070:'\u78DE',60071:'\u78E3',60072:'\u78DB',60073:'\u78E1',60074:'\u78E2',60075:'\u78ED',60076:'\u78DF',60077:'\u78E0',60078:'\u79A4',60079:'\u7A44',60080:'\u7A48',60081:'\u7A47',60082:'\u7AB6',60083:'\u7AB8',60084:'\u7AB5',60085:'\u7AB1',60086:'\u7AB7',60087:'\u7BDE',60088:'\u7BE3',60089:'\u7BE7',60090:'\u7BDD',60091:'\u7BD5',60092:'\u7BE5',60093:'\u7BDA',60094:'\u7BE8',60095:'\u7BF9',60096:'\u7BD4',60097:'\u7BEA',60098:'\u7BE2',60099:'\u7BDC',60100:'\u7BEB',60101:'\u7BD8',60102:'\u7BDF',60103:'\u7CD2',60104:'\u7CD4',60105:'\u7CD7',60106:'\u7CD0',60107:'\u7CD1',60108:'\u7E12',60109:'\u7E21',60110:'\u7E17',60111:'\u7E0C',60112:'\u7E1F',60113:'\u7E20',60114:'\u7E13',60115:'\u7E0E',60116:'\u7E1C',60117:'\u7E15',60118:'\u7E1A',60119:'\u7E22',60120:'\u7E0B',60121:'\u7E0F',60122:'\u7E16',60123:'\u7E0D',60124:'\u7E14',60125:'\u7E25',60126:'\u7E24',60127:'\u7F43',60128:'\u7F7B',60129:'\u7F7C',60130:'\u7F7A',60131:'\u7FB1',60132:'\u7FEF',60133:'\u802A',60134:'\u8029',60135:'\u806C',60136:'\u81B1',60137:'\u81A6',60138:'\u81AE',60139:'\u81B9',60140:'\u81B5',60141:'\u81AB',60142:'\u81B0',60143:'\u81AC',60144:'\u81B4',60145:'\u81B2',60146:'\u81B7',60147:'\u81A7',60148:'\u81F2',60149:'\u8255',60150:'\u8256',60151:'\u8257',60152:'\u8556',60153:'\u8545',60154:'\u856B',60155:'\u854D',60156:'\u8553',60157:'\u8561',60158:'\u8558',60224:'\u8540',60225:'\u8546',60226:'\u8564',60227:'\u8541',60228:'\u8562',60229:'\u8544',60230:'\u8551',60231:'\u8547',60232:'\u8563',60233:'\u853E',60234:'\u855B',60235:'\u8571',60236:'\u854E',60237:'\u856E',60238:'\u8575',60239:'\u8555',60240:'\u8567',60241:'\u8560',60242:'\u858C',60243:'\u8566',60244:'\u855D',60245:'\u8554',60246:'\u8565',60247:'\u856C',60248:'\u8663',60249:'\u8665',60250:'\u8664',60251:'\u879B',60252:'\u878F',60253:'\u8797',60254:'\u8793',60255:'\u8792',60256:'\u8788',60257:'\u8781',60258:'\u8796',60259:'\u8798',60260:'\u8779',60261:'\u8787',60262:'\u87A3',60263:'\u8785',60264:'\u8790',60265:'\u8791',60266:'\u879D',60267:'\u8784',60268:'\u8794',60269:'\u879C',60270:'\u879A',60271:'\u8789',60272:'\u891E',60273:'\u8926',60274:'\u8930',60275:'\u892D',60276:'\u892E',60277:'\u8927',60278:'\u8931',60279:'\u8922',60280:'\u8929',60281:'\u8923',60282:'\u892F',60283:'\u892C',60284:'\u891F',60285:'\u89F1',60286:'\u8AE0',60321:'\u8AE2',60322:'\u8AF2',60323:'\u8AF4',60324:'\u8AF5',60325:'\u8ADD',60326:'\u8B14',60327:'\u8AE4',60328:'\u8ADF',60329:'\u8AF0',60330:'\u8AC8',60331:'\u8ADE',60332:'\u8AE1',60333:'\u8AE8',60334:'\u8AFF',60335:'\u8AEF',60336:'\u8AFB',60337:'\u8C91',60338:'\u8C92',60339:'\u8C90',60340:'\u8CF5',60341:'\u8CEE',60342:'\u8CF1',60343:'\u8CF0',60344:'\u8CF3',60345:'\u8D6C',60346:'\u8D6E',60347:'\u8DA5',60348:'\u8DA7',60349:'\u8E33',60350:'\u8E3E',60351:'\u8E38',60352:'\u8E40',60353:'\u8E45',60354:'\u8E36',60355:'\u8E3C',60356:'\u8E3D',60357:'\u8E41',60358:'\u8E30',60359:'\u8E3F',60360:'\u8EBD',60361:'\u8F36',60362:'\u8F2E',60363:'\u8F35',60364:'\u8F32',60365:'\u8F39',60366:'\u8F37',60367:'\u8F34',60368:'\u9076',60369:'\u9079',60370:'\u907B',60371:'\u9086',60372:'\u90FA',60373:'\u9133',60374:'\u9135',60375:'\u9136',60376:'\u9193',60377:'\u9190',60378:'\u9191',60379:'\u918D',60380:'\u918F',60381:'\u9327',60382:'\u931E',60383:'\u9308',60384:'\u931F',60385:'\u9306',60386:'\u930F',60387:'\u937A',60388:'\u9338',60389:'\u933C',60390:'\u931B',60391:'\u9323',60392:'\u9312',60393:'\u9301',60394:'\u9346',60395:'\u932D',60396:'\u930E',60397:'\u930D',60398:'\u92CB',60399:'\u931D',60400:'\u92FA',60401:'\u9325',60402:'\u9313',60403:'\u92F9',60404:'\u92F7',60405:'\u9334',60406:'\u9302',60407:'\u9324',60408:'\u92FF',60409:'\u9329',60410:'\u9339',60411:'\u9335',60412:'\u932A',60413:'\u9314',60414:'\u930C',60480:'\u930B',60481:'\u92FE',60482:'\u9309',60483:'\u9300',60484:'\u92FB',60485:'\u9316',60486:'\u95BC',60487:'\u95CD',60488:'\u95BE',60489:'\u95B9',60490:'\u95BA',60491:'\u95B6',60492:'\u95BF',60493:'\u95B5',60494:'\u95BD',60495:'\u96A9',60496:'\u96D4',60497:'\u970B',60498:'\u9712',60499:'\u9710',60500:'\u9799',60501:'\u9797',60502:'\u9794',60503:'\u97F0',60504:'\u97F8',60505:'\u9835',60506:'\u982F',60507:'\u9832',60508:'\u9924',60509:'\u991F',60510:'\u9927',60511:'\u9929',60512:'\u999E',60513:'\u99EE',60514:'\u99EC',60515:'\u99E5',60516:'\u99E4',60517:'\u99F0',60518:'\u99E3',60519:'\u99EA',60520:'\u99E9',60521:'\u99E7',60522:'\u9AB9',60523:'\u9ABF',60524:'\u9AB4',60525:'\u9ABB',60526:'\u9AF6',60527:'\u9AFA',60528:'\u9AF9',60529:'\u9AF7',60530:'\u9B33',60531:'\u9B80',60532:'\u9B85',60533:'\u9B87',60534:'\u9B7C',60535:'\u9B7E',60536:'\u9B7B',60537:'\u9B82',60538:'\u9B93',60539:'\u9B92',60540:'\u9B90',60541:'\u9B7A',60542:'\u9B95',60577:'\u9B7D',60578:'\u9B88',60579:'\u9D25',60580:'\u9D17',60581:'\u9D20',60582:'\u9D1E',60583:'\u9D14',60584:'\u9D29',60585:'\u9D1D',60586:'\u9D18',60587:'\u9D22',60588:'\u9D10',60589:'\u9D19',60590:'\u9D1F',60591:'\u9E88',60592:'\u9E86',60593:'\u9E87',60594:'\u9EAE',60595:'\u9EAD',60596:'\u9ED5',60597:'\u9ED6',60598:'\u9EFA',60599:'\u9F12',60600:'\u9F3D',60601:'\u5126',60602:'\u5125',60603:'\u5122',60604:'\u5124',60605:'\u5120',60606:'\u5129',60607:'\u52F4',60608:'\u5693',60609:'\u568C',60610:'\u568D',60611:'\u5686',60612:'\u5684',60613:'\u5683',60614:'\u567E',60615:'\u5682',60616:'\u567F',60617:'\u5681',60618:'\u58D6',60619:'\u58D4',60620:'\u58CF',60621:'\u58D2',60622:'\u5B2D',60623:'\u5B25',60624:'\u5B32',60625:'\u5B23',60626:'\u5B2C',60627:'\u5B27',60628:'\u5B26',60629:'\u5B2F',60630:'\u5B2E',60631:'\u5B7B',60632:'\u5BF1',60633:'\u5BF2',60634:'\u5DB7',60635:'\u5E6C',60636:'\u5E6A',60637:'\u5FBE',60638:'\u5FBB',60639:'\u61C3',60640:'\u61B5',60641:'\u61BC',60642:'\u61E7',60643:'\u61E0',60644:'\u61E5',60645:'\u61E4',60646:'\u61E8',60647:'\u61DE',60648:'\u64EF',60649:'\u64E9',60650:'\u64E3',60651:'\u64EB',60652:'\u64E4',60653:'\u64E8',60654:'\u6581',60655:'\u6580',60656:'\u65B6',60657:'\u65DA',60658:'\u66D2',60659:'\u6A8D',60660:'\u6A96',60661:'\u6A81',60662:'\u6AA5',60663:'\u6A89',60664:'\u6A9F',60665:'\u6A9B',60666:'\u6AA1',60667:'\u6A9E',60668:'\u6A87',60669:'\u6A93',60670:'\u6A8E',60736:'\u6A95',60737:'\u6A83',60738:'\u6AA8',60739:'\u6AA4',60740:'\u6A91',60741:'\u6A7F',60742:'\u6AA6',60743:'\u6A9A',60744:'\u6A85',60745:'\u6A8C',60746:'\u6A92',60747:'\u6B5B',60748:'\u6BAD',60749:'\u6C09',60750:'\u6FCC',60751:'\u6FA9',60752:'\u6FF4',60753:'\u6FD4',60754:'\u6FE3',60755:'\u6FDC',60756:'\u6FED',60757:'\u6FE7',60758:'\u6FE6',60759:'\u6FDE',60760:'\u6FF2',60761:'\u6FDD',60762:'\u6FE2',60763:'\u6FE8',60764:'\u71E1',60765:'\u71F1',60766:'\u71E8',60767:'\u71F2',60768:'\u71E4',60769:'\u71F0',60770:'\u71E2',60771:'\u7373',60772:'\u736E',60773:'\u736F',60774:'\u7497',60775:'\u74B2',60776:'\u74AB',60777:'\u7490',60778:'\u74AA',60779:'\u74AD',60780:'\u74B1',60781:'\u74A5',60782:'\u74AF',60783:'\u7510',60784:'\u7511',60785:'\u7512',60786:'\u750F',60787:'\u7584',60788:'\u7643',60789:'\u7648',60790:'\u7649',60791:'\u7647',60792:'\u76A4',60793:'\u76E9',60794:'\u77B5',60795:'\u77AB',60796:'\u77B2',60797:'\u77B7',60798:'\u77B6',60833:'\u77B4',60834:'\u77B1',60835:'\u77A8',60836:'\u77F0',60837:'\u78F3',60838:'\u78FD',60839:'\u7902',60840:'\u78FB',60841:'\u78FC',60842:'\u78F2',60843:'\u7905',60844:'\u78F9',60845:'\u78FE',60846:'\u7904',60847:'\u79AB',60848:'\u79A8',60849:'\u7A5C',60850:'\u7A5B',60851:'\u7A56',60852:'\u7A58',60853:'\u7A54',60854:'\u7A5A',60855:'\u7ABE',60856:'\u7AC0',60857:'\u7AC1',60858:'\u7C05',60859:'\u7C0F',60860:'\u7BF2',60861:'\u7C00',60862:'\u7BFF',60863:'\u7BFB',60864:'\u7C0E',60865:'\u7BF4',60866:'\u7C0B',60867:'\u7BF3',60868:'\u7C02',60869:'\u7C09',60870:'\u7C03',60871:'\u7C01',60872:'\u7BF8',60873:'\u7BFD',60874:'\u7C06',60875:'\u7BF0',60876:'\u7BF1',60877:'\u7C10',60878:'\u7C0A',60879:'\u7CE8',60880:'\u7E2D',60881:'\u7E3C',60882:'\u7E42',60883:'\u7E33',60884:'\u9848',60885:'\u7E38',60886:'\u7E2A',60887:'\u7E49',60888:'\u7E40',60889:'\u7E47',60890:'\u7E29',60891:'\u7E4C',60892:'\u7E30',60893:'\u7E3B',60894:'\u7E36',60895:'\u7E44',60896:'\u7E3A',60897:'\u7F45',60898:'\u7F7F',60899:'\u7F7E',60900:'\u7F7D',60901:'\u7FF4',60902:'\u7FF2',60903:'\u802C',60904:'\u81BB',60905:'\u81C4',60906:'\u81CC',60907:'\u81CA',60908:'\u81C5',60909:'\u81C7',60910:'\u81BC',60911:'\u81E9',60912:'\u825B',60913:'\u825A',60914:'\u825C',60915:'\u8583',60916:'\u8580',60917:'\u858F',60918:'\u85A7',60919:'\u8595',60920:'\u85A0',60921:'\u858B',60922:'\u85A3',60923:'\u857B',60924:'\u85A4',60925:'\u859A',60926:'\u859E',60992:'\u8577',60993:'\u857C',60994:'\u8589',60995:'\u85A1',60996:'\u857A',60997:'\u8578',60998:'\u8557',60999:'\u858E',61000:'\u8596',61001:'\u8586',61002:'\u858D',61003:'\u8599',61004:'\u859D',61005:'\u8581',61006:'\u85A2',61007:'\u8582',61008:'\u8588',61009:'\u8585',61010:'\u8579',61011:'\u8576',61012:'\u8598',61013:'\u8590',61014:'\u859F',61015:'\u8668',61016:'\u87BE',61017:'\u87AA',61018:'\u87AD',61019:'\u87C5',61020:'\u87B0',61021:'\u87AC',61022:'\u87B9',61023:'\u87B5',61024:'\u87BC',61025:'\u87AE',61026:'\u87C9',61027:'\u87C3',61028:'\u87C2',61029:'\u87CC',61030:'\u87B7',61031:'\u87AF',61032:'\u87C4',61033:'\u87CA',61034:'\u87B4',61035:'\u87B6',61036:'\u87BF',61037:'\u87B8',61038:'\u87BD',61039:'\u87DE',61040:'\u87B2',61041:'\u8935',61042:'\u8933',61043:'\u893C',61044:'\u893E',61045:'\u8941',61046:'\u8952',61047:'\u8937',61048:'\u8942',61049:'\u89AD',61050:'\u89AF',61051:'\u89AE',61052:'\u89F2',61053:'\u89F3',61054:'\u8B1E',61089:'\u8B18',61090:'\u8B16',61091:'\u8B11',61092:'\u8B05',61093:'\u8B0B',61094:'\u8B22',61095:'\u8B0F',61096:'\u8B12',61097:'\u8B15',61098:'\u8B07',61099:'\u8B0D',61100:'\u8B08',61101:'\u8B06',61102:'\u8B1C',61103:'\u8B13',61104:'\u8B1A',61105:'\u8C4F',61106:'\u8C70',61107:'\u8C72',61108:'\u8C71',61109:'\u8C6F',61110:'\u8C95',61111:'\u8C94',61112:'\u8CF9',61113:'\u8D6F',61114:'\u8E4E',61115:'\u8E4D',61116:'\u8E53',61117:'\u8E50',61118:'\u8E4C',61119:'\u8E47',61120:'\u8F43',61121:'\u8F40',61122:'\u9085',61123:'\u907E',61124:'\u9138',61125:'\u919A',61126:'\u91A2',61127:'\u919B',61128:'\u9199',61129:'\u919F',61130:'\u91A1',61131:'\u919D',61132:'\u91A0',61133:'\u93A1',61134:'\u9383',61135:'\u93AF',61136:'\u9364',61137:'\u9356',61138:'\u9347',61139:'\u937C',61140:'\u9358',61141:'\u935C',61142:'\u9376',61143:'\u9349',61144:'\u9350',61145:'\u9351',61146:'\u9360',61147:'\u936D',61148:'\u938F',61149:'\u934C',61150:'\u936A',61151:'\u9379',61152:'\u9357',61153:'\u9355',61154:'\u9352',61155:'\u934F',61156:'\u9371',61157:'\u9377',61158:'\u937B',61159:'\u9361',61160:'\u935E',61161:'\u9363',61162:'\u9367',61163:'\u9380',61164:'\u934E',61165:'\u9359',61166:'\u95C7',61167:'\u95C0',61168:'\u95C9',61169:'\u95C3',61170:'\u95C5',61171:'\u95B7',61172:'\u96AE',61173:'\u96B0',61174:'\u96AC',61175:'\u9720',61176:'\u971F',61177:'\u9718',61178:'\u971D',61179:'\u9719',61180:'\u979A',61181:'\u97A1',61182:'\u979C',61248:'\u979E',61249:'\u979D',61250:'\u97D5',61251:'\u97D4',61252:'\u97F1',61253:'\u9841',61254:'\u9844',61255:'\u984A',61256:'\u9849',61257:'\u9845',61258:'\u9843',61259:'\u9925',61260:'\u992B',61261:'\u992C',61262:'\u992A',61263:'\u9933',61264:'\u9932',61265:'\u992F',61266:'\u992D',61267:'\u9931',61268:'\u9930',61269:'\u9998',61270:'\u99A3',61271:'\u99A1',61272:'\u9A02',61273:'\u99FA',61274:'\u99F4',61275:'\u99F7',61276:'\u99F9',61277:'\u99F8',61278:'\u99F6',61279:'\u99FB',61280:'\u99FD',61281:'\u99FE',61282:'\u99FC',61283:'\u9A03',61284:'\u9ABE',61285:'\u9AFE',61286:'\u9AFD',61287:'\u9B01',61288:'\u9AFC',61289:'\u9B48',61290:'\u9B9A',61291:'\u9BA8',61292:'\u9B9E',61293:'\u9B9B',61294:'\u9BA6',61295:'\u9BA1',61296:'\u9BA5',61297:'\u9BA4',61298:'\u9B86',61299:'\u9BA2',61300:'\u9BA0',61301:'\u9BAF',61302:'\u9D33',61303:'\u9D41',61304:'\u9D67',61305:'\u9D36',61306:'\u9D2E',61307:'\u9D2F',61308:'\u9D31',61309:'\u9D38',61310:'\u9D30',61345:'\u9D45',61346:'\u9D42',61347:'\u9D43',61348:'\u9D3E',61349:'\u9D37',61350:'\u9D40',61351:'\u9D3D',61352:'\u7FF5',61353:'\u9D2D',61354:'\u9E8A',61355:'\u9E89',61356:'\u9E8D',61357:'\u9EB0',61358:'\u9EC8',61359:'\u9EDA',61360:'\u9EFB',61361:'\u9EFF',61362:'\u9F24',61363:'\u9F23',61364:'\u9F22',61365:'\u9F54',61366:'\u9FA0',61367:'\u5131',61368:'\u512D',61369:'\u512E',61370:'\u5698',61371:'\u569C',61372:'\u5697',61373:'\u569A',61374:'\u569D',61375:'\u5699',61376:'\u5970',61377:'\u5B3C',61378:'\u5C69',61379:'\u5C6A',61380:'\u5DC0',61381:'\u5E6D',61382:'\u5E6E',61383:'\u61D8',61384:'\u61DF',61385:'\u61ED',61386:'\u61EE',61387:'\u61F1',61388:'\u61EA',61389:'\u61F0',61390:'\u61EB',61391:'\u61D6',61392:'\u61E9',61393:'\u64FF',61394:'\u6504',61395:'\u64FD',61396:'\u64F8',61397:'\u6501',61398:'\u6503',61399:'\u64FC',61400:'\u6594',61401:'\u65DB',61402:'\u66DA',61403:'\u66DB',61404:'\u66D8',61405:'\u6AC5',61406:'\u6AB9',61407:'\u6ABD',61408:'\u6AE1',61409:'\u6AC6',61410:'\u6ABA',61411:'\u6AB6',61412:'\u6AB7',61413:'\u6AC7',61414:'\u6AB4',61415:'\u6AAD',61416:'\u6B5E',61417:'\u6BC9',61418:'\u6C0B',61419:'\u7007',61420:'\u700C',61421:'\u700D',61422:'\u7001',61423:'\u7005',61424:'\u7014',61425:'\u700E',61426:'\u6FFF',61427:'\u7000',61428:'\u6FFB',61429:'\u7026',61430:'\u6FFC',61431:'\u6FF7',61432:'\u700A',61433:'\u7201',61434:'\u71FF',61435:'\u71F9',61436:'\u7203',61437:'\u71FD',61438:'\u7376',61504:'\u74B8',61505:'\u74C0',61506:'\u74B5',61507:'\u74C1',61508:'\u74BE',61509:'\u74B6',61510:'\u74BB',61511:'\u74C2',61512:'\u7514',61513:'\u7513',61514:'\u765C',61515:'\u7664',61516:'\u7659',61517:'\u7650',61518:'\u7653',61519:'\u7657',61520:'\u765A',61521:'\u76A6',61522:'\u76BD',61523:'\u76EC',61524:'\u77C2',61525:'\u77BA',61526:'\u78FF',61527:'\u790C',61528:'\u7913',61529:'\u7914',61530:'\u7909',61531:'\u7910',61532:'\u7912',61533:'\u7911',61534:'\u79AD',61535:'\u79AC',61536:'\u7A5F',61537:'\u7C1C',61538:'\u7C29',61539:'\u7C19',61540:'\u7C20',61541:'\u7C1F',61542:'\u7C2D',61543:'\u7C1D',61544:'\u7C26',61545:'\u7C28',61546:'\u7C22',61547:'\u7C25',61548:'\u7C30',61549:'\u7E5C',61550:'\u7E50',61551:'\u7E56',61552:'\u7E63',61553:'\u7E58',61554:'\u7E62',61555:'\u7E5F',61556:'\u7E51',61557:'\u7E60',61558:'\u7E57',61559:'\u7E53',61560:'\u7FB5',61561:'\u7FB3',61562:'\u7FF7',61563:'\u7FF8',61564:'\u8075',61565:'\u81D1',61566:'\u81D2',61601:'\u81D0',61602:'\u825F',61603:'\u825E',61604:'\u85B4',61605:'\u85C6',61606:'\u85C0',61607:'\u85C3',61608:'\u85C2',61609:'\u85B3',61610:'\u85B5',61611:'\u85BD',61612:'\u85C7',61613:'\u85C4',61614:'\u85BF',61615:'\u85CB',61616:'\u85CE',61617:'\u85C8',61618:'\u85C5',61619:'\u85B1',61620:'\u85B6',61621:'\u85D2',61622:'\u8624',61623:'\u85B8',61624:'\u85B7',61625:'\u85BE',61626:'\u8669',61627:'\u87E7',61628:'\u87E6',61629:'\u87E2',61630:'\u87DB',61631:'\u87EB',61632:'\u87EA',61633:'\u87E5',61634:'\u87DF',61635:'\u87F3',61636:'\u87E4',61637:'\u87D4',61638:'\u87DC',61639:'\u87D3',61640:'\u87ED',61641:'\u87D8',61642:'\u87E3',61643:'\u87A4',61644:'\u87D7',61645:'\u87D9',61646:'\u8801',61647:'\u87F4',61648:'\u87E8',61649:'\u87DD',61650:'\u8953',61651:'\u894B',61652:'\u894F',61653:'\u894C',61654:'\u8946',61655:'\u8950',61656:'\u8951',61657:'\u8949',61658:'\u8B2A',61659:'\u8B27',61660:'\u8B23',61661:'\u8B33',61662:'\u8B30',61663:'\u8B35',61664:'\u8B47',61665:'\u8B2F',61666:'\u8B3C',61667:'\u8B3E',61668:'\u8B31',61669:'\u8B25',61670:'\u8B37',61671:'\u8B26',61672:'\u8B36',61673:'\u8B2E',61674:'\u8B24',61675:'\u8B3B',61676:'\u8B3D',61677:'\u8B3A',61678:'\u8C42',61679:'\u8C75',61680:'\u8C99',61681:'\u8C98',61682:'\u8C97',61683:'\u8CFE',61684:'\u8D04',61685:'\u8D02',61686:'\u8D00',61687:'\u8E5C',61688:'\u8E62',61689:'\u8E60',61690:'\u8E57',61691:'\u8E56',61692:'\u8E5E',61693:'\u8E65',61694:'\u8E67',61760:'\u8E5B',61761:'\u8E5A',61762:'\u8E61',61763:'\u8E5D',61764:'\u8E69',61765:'\u8E54',61766:'\u8F46',61767:'\u8F47',61768:'\u8F48',61769:'\u8F4B',61770:'\u9128',61771:'\u913A',61772:'\u913B',61773:'\u913E',61774:'\u91A8',61775:'\u91A5',61776:'\u91A7',61777:'\u91AF',61778:'\u91AA',61779:'\u93B5',61780:'\u938C',61781:'\u9392',61782:'\u93B7',61783:'\u939B',61784:'\u939D',61785:'\u9389',61786:'\u93A7',61787:'\u938E',61788:'\u93AA',61789:'\u939E',61790:'\u93A6',61791:'\u9395',61792:'\u9388',61793:'\u9399',61794:'\u939F',61795:'\u938D',61796:'\u93B1',61797:'\u9391',61798:'\u93B2',61799:'\u93A4',61800:'\u93A8',61801:'\u93B4',61802:'\u93A3',61803:'\u93A5',61804:'\u95D2',61805:'\u95D3',61806:'\u95D1',61807:'\u96B3',61808:'\u96D7',61809:'\u96DA',61810:'\u5DC2',61811:'\u96DF',61812:'\u96D8',61813:'\u96DD',61814:'\u9723',61815:'\u9722',61816:'\u9725',61817:'\u97AC',61818:'\u97AE',61819:'\u97A8',61820:'\u97AB',61821:'\u97A4',61822:'\u97AA',61857:'\u97A2',61858:'\u97A5',61859:'\u97D7',61860:'\u97D9',61861:'\u97D6',61862:'\u97D8',61863:'\u97FA',61864:'\u9850',61865:'\u9851',61866:'\u9852',61867:'\u98B8',61868:'\u9941',61869:'\u993C',61870:'\u993A',61871:'\u9A0F',61872:'\u9A0B',61873:'\u9A09',61874:'\u9A0D',61875:'\u9A04',61876:'\u9A11',61877:'\u9A0A',61878:'\u9A05',61879:'\u9A07',61880:'\u9A06',61881:'\u9AC0',61882:'\u9ADC',61883:'\u9B08',61884:'\u9B04',61885:'\u9B05',61886:'\u9B29',61887:'\u9B35',61888:'\u9B4A',61889:'\u9B4C',61890:'\u9B4B',61891:'\u9BC7',61892:'\u9BC6',61893:'\u9BC3',61894:'\u9BBF',61895:'\u9BC1',61896:'\u9BB5',61897:'\u9BB8',61898:'\u9BD3',61899:'\u9BB6',61900:'\u9BC4',61901:'\u9BB9',61902:'\u9BBD',61903:'\u9D5C',61904:'\u9D53',61905:'\u9D4F',61906:'\u9D4A',61907:'\u9D5B',61908:'\u9D4B',61909:'\u9D59',61910:'\u9D56',61911:'\u9D4C',61912:'\u9D57',61913:'\u9D52',61914:'\u9D54',61915:'\u9D5F',61916:'\u9D58',61917:'\u9D5A',61918:'\u9E8E',61919:'\u9E8C',61920:'\u9EDF',61921:'\u9F01',61922:'\u9F00',61923:'\u9F16',61924:'\u9F25',61925:'\u9F2B',61926:'\u9F2A',61927:'\u9F29',61928:'\u9F28',61929:'\u9F4C',61930:'\u9F55',61931:'\u5134',61932:'\u5135',61933:'\u5296',61934:'\u52F7',61935:'\u53B4',61936:'\u56AB',61937:'\u56AD',61938:'\u56A6',61939:'\u56A7',61940:'\u56AA',61941:'\u56AC',61942:'\u58DA',61943:'\u58DD',61944:'\u58DB',61945:'\u5912',61946:'\u5B3D',61947:'\u5B3E',61948:'\u5B3F',61949:'\u5DC3',61950:'\u5E70',62016:'\u5FBF',62017:'\u61FB',62018:'\u6507',62019:'\u6510',62020:'\u650D',62021:'\u6509',62022:'\u650C',62023:'\u650E',62024:'\u6584',62025:'\u65DE',62026:'\u65DD',62027:'\u66DE',62028:'\u6AE7',62029:'\u6AE0',62030:'\u6ACC',62031:'\u6AD1',62032:'\u6AD9',62033:'\u6ACB',62034:'\u6ADF',62035:'\u6ADC',62036:'\u6AD0',62037:'\u6AEB',62038:'\u6ACF',62039:'\u6ACD',62040:'\u6ADE',62041:'\u6B60',62042:'\u6BB0',62043:'\u6C0C',62044:'\u7019',62045:'\u7027',62046:'\u7020',62047:'\u7016',62048:'\u702B',62049:'\u7021',62050:'\u7022',62051:'\u7023',62052:'\u7029',62053:'\u7017',62054:'\u7024',62055:'\u701C',62056:'\u702A',62057:'\u720C',62058:'\u720A',62059:'\u7207',62060:'\u7202',62061:'\u7205',62062:'\u72A5',62063:'\u72A6',62064:'\u72A4',62065:'\u72A3',62066:'\u72A1',62067:'\u74CB',62068:'\u74C5',62069:'\u74B7',62070:'\u74C3',62071:'\u7516',62072:'\u7660',62073:'\u77C9',62074:'\u77CA',62075:'\u77C4',62076:'\u77F1',62077:'\u791D',62078:'\u791B',62113:'\u7921',62114:'\u791C',62115:'\u7917',62116:'\u791E',62117:'\u79B0',62118:'\u7A67',62119:'\u7A68',62120:'\u7C33',62121:'\u7C3C',62122:'\u7C39',62123:'\u7C2C',62124:'\u7C3B',62125:'\u7CEC',62126:'\u7CEA',62127:'\u7E76',62128:'\u7E75',62129:'\u7E78',62130:'\u7E70',62131:'\u7E77',62132:'\u7E6F',62133:'\u7E7A',62134:'\u7E72',62135:'\u7E74',62136:'\u7E68',62137:'\u7F4B',62138:'\u7F4A',62139:'\u7F83',62140:'\u7F86',62141:'\u7FB7',62142:'\u7FFD',62143:'\u7FFE',62144:'\u8078',62145:'\u81D7',62146:'\u81D5',62147:'\u8264',62148:'\u8261',62149:'\u8263',62150:'\u85EB',62151:'\u85F1',62152:'\u85ED',62153:'\u85D9',62154:'\u85E1',62155:'\u85E8',62156:'\u85DA',62157:'\u85D7',62158:'\u85EC',62159:'\u85F2',62160:'\u85F8',62161:'\u85D8',62162:'\u85DF',62163:'\u85E3',62164:'\u85DC',62165:'\u85D1',62166:'\u85F0',62167:'\u85E6',62168:'\u85EF',62169:'\u85DE',62170:'\u85E2',62171:'\u8800',62172:'\u87FA',62173:'\u8803',62174:'\u87F6',62175:'\u87F7',62176:'\u8809',62177:'\u880C',62178:'\u880B',62179:'\u8806',62180:'\u87FC',62181:'\u8808',62182:'\u87FF',62183:'\u880A',62184:'\u8802',62185:'\u8962',62186:'\u895A',62187:'\u895B',62188:'\u8957',62189:'\u8961',62190:'\u895C',62191:'\u8958',62192:'\u895D',62193:'\u8959',62194:'\u8988',62195:'\u89B7',62196:'\u89B6',62197:'\u89F6',62198:'\u8B50',62199:'\u8B48',62200:'\u8B4A',62201:'\u8B40',62202:'\u8B53',62203:'\u8B56',62204:'\u8B54',62205:'\u8B4B',62206:'\u8B55',62272:'\u8B51',62273:'\u8B42',62274:'\u8B52',62275:'\u8B57',62276:'\u8C43',62277:'\u8C77',62278:'\u8C76',62279:'\u8C9A',62280:'\u8D06',62281:'\u8D07',62282:'\u8D09',62283:'\u8DAC',62284:'\u8DAA',62285:'\u8DAD',62286:'\u8DAB',62287:'\u8E6D',62288:'\u8E78',62289:'\u8E73',62290:'\u8E6A',62291:'\u8E6F',62292:'\u8E7B',62293:'\u8EC2',62294:'\u8F52',62295:'\u8F51',62296:'\u8F4F',62297:'\u8F50',62298:'\u8F53',62299:'\u8FB4',62300:'\u9140',62301:'\u913F',62302:'\u91B0',62303:'\u91AD',62304:'\u93DE',62305:'\u93C7',62306:'\u93CF',62307:'\u93C2',62308:'\u93DA',62309:'\u93D0',62310:'\u93F9',62311:'\u93EC',62312:'\u93CC',62313:'\u93D9',62314:'\u93A9',62315:'\u93E6',62316:'\u93CA',62317:'\u93D4',62318:'\u93EE',62319:'\u93E3',62320:'\u93D5',62321:'\u93C4',62322:'\u93CE',62323:'\u93C0',62324:'\u93D2',62325:'\u93E7',62326:'\u957D',62327:'\u95DA',62328:'\u95DB',62329:'\u96E1',62330:'\u9729',62331:'\u972B',62332:'\u972C',62333:'\u9728',62334:'\u9726',62369:'\u97B3',62370:'\u97B7',62371:'\u97B6',62372:'\u97DD',62373:'\u97DE',62374:'\u97DF',62375:'\u985C',62376:'\u9859',62377:'\u985D',62378:'\u9857',62379:'\u98BF',62380:'\u98BD',62381:'\u98BB',62382:'\u98BE',62383:'\u9948',62384:'\u9947',62385:'\u9943',62386:'\u99A6',62387:'\u99A7',62388:'\u9A1A',62389:'\u9A15',62390:'\u9A25',62391:'\u9A1D',62392:'\u9A24',62393:'\u9A1B',62394:'\u9A22',62395:'\u9A20',62396:'\u9A27',62397:'\u9A23',62398:'\u9A1E',62399:'\u9A1C',62400:'\u9A14',62401:'\u9AC2',62402:'\u9B0B',62403:'\u9B0A',62404:'\u9B0E',62405:'\u9B0C',62406:'\u9B37',62407:'\u9BEA',62408:'\u9BEB',62409:'\u9BE0',62410:'\u9BDE',62411:'\u9BE4',62412:'\u9BE6',62413:'\u9BE2',62414:'\u9BF0',62415:'\u9BD4',62416:'\u9BD7',62417:'\u9BEC',62418:'\u9BDC',62419:'\u9BD9',62420:'\u9BE5',62421:'\u9BD5',62422:'\u9BE1',62423:'\u9BDA',62424:'\u9D77',62425:'\u9D81',62426:'\u9D8A',62427:'\u9D84',62428:'\u9D88',62429:'\u9D71',62430:'\u9D80',62431:'\u9D78',62432:'\u9D86',62433:'\u9D8B',62434:'\u9D8C',62435:'\u9D7D',62436:'\u9D6B',62437:'\u9D74',62438:'\u9D75',62439:'\u9D70',62440:'\u9D69',62441:'\u9D85',62442:'\u9D73',62443:'\u9D7B',62444:'\u9D82',62445:'\u9D6F',62446:'\u9D79',62447:'\u9D7F',62448:'\u9D87',62449:'\u9D68',62450:'\u9E94',62451:'\u9E91',62452:'\u9EC0',62453:'\u9EFC',62454:'\u9F2D',62455:'\u9F40',62456:'\u9F41',62457:'\u9F4D',62458:'\u9F56',62459:'\u9F57',62460:'\u9F58',62461:'\u5337',62462:'\u56B2',62528:'\u56B5',62529:'\u56B3',62530:'\u58E3',62531:'\u5B45',62532:'\u5DC6',62533:'\u5DC7',62534:'\u5EEE',62535:'\u5EEF',62536:'\u5FC0',62537:'\u5FC1',62538:'\u61F9',62539:'\u6517',62540:'\u6516',62541:'\u6515',62542:'\u6513',62543:'\u65DF',62544:'\u66E8',62545:'\u66E3',62546:'\u66E4',62547:'\u6AF3',62548:'\u6AF0',62549:'\u6AEA',62550:'\u6AE8',62551:'\u6AF9',62552:'\u6AF1',62553:'\u6AEE',62554:'\u6AEF',62555:'\u703C',62556:'\u7035',62557:'\u702F',62558:'\u7037',62559:'\u7034',62560:'\u7031',62561:'\u7042',62562:'\u7038',62563:'\u703F',62564:'\u703A',62565:'\u7039',62566:'\u7040',62567:'\u703B',62568:'\u7033',62569:'\u7041',62570:'\u7213',62571:'\u7214',62572:'\u72A8',62573:'\u737D',62574:'\u737C',62575:'\u74BA',62576:'\u76AB',62577:'\u76AA',62578:'\u76BE',62579:'\u76ED',62580:'\u77CC',62581:'\u77CE',62582:'\u77CF',62583:'\u77CD',62584:'\u77F2',62585:'\u7925',62586:'\u7923',62587:'\u7927',62588:'\u7928',62589:'\u7924',62590:'\u7929',62625:'\u79B2',62626:'\u7A6E',62627:'\u7A6C',62628:'\u7A6D',62629:'\u7AF7',62630:'\u7C49',62631:'\u7C48',62632:'\u7C4A',62633:'\u7C47',62634:'\u7C45',62635:'\u7CEE',62636:'\u7E7B',62637:'\u7E7E',62638:'\u7E81',62639:'\u7E80',62640:'\u7FBA',62641:'\u7FFF',62642:'\u8079',62643:'\u81DB',62644:'\u81D9',62645:'\u820B',62646:'\u8268',62647:'\u8269',62648:'\u8622',62649:'\u85FF',62650:'\u8601',62651:'\u85FE',62652:'\u861B',62653:'\u8600',62654:'\u85F6',62655:'\u8604',62656:'\u8609',62657:'\u8605',62658:'\u860C',62659:'\u85FD',62660:'\u8819',62661:'\u8810',62662:'\u8811',62663:'\u8817',62664:'\u8813',62665:'\u8816',62666:'\u8963',62667:'\u8966',62668:'\u89B9',62669:'\u89F7',62670:'\u8B60',62671:'\u8B6A',62672:'\u8B5D',62673:'\u8B68',62674:'\u8B63',62675:'\u8B65',62676:'\u8B67',62677:'\u8B6D',62678:'\u8DAE',62679:'\u8E86',62680:'\u8E88',62681:'\u8E84',62682:'\u8F59',62683:'\u8F56',62684:'\u8F57',62685:'\u8F55',62686:'\u8F58',62687:'\u8F5A',62688:'\u908D',62689:'\u9143',62690:'\u9141',62691:'\u91B7',62692:'\u91B5',62693:'\u91B2',62694:'\u91B3',62695:'\u940B',62696:'\u9413',62697:'\u93FB',62698:'\u9420',62699:'\u940F',62700:'\u9414',62701:'\u93FE',62702:'\u9415',62703:'\u9410',62704:'\u9428',62705:'\u9419',62706:'\u940D',62707:'\u93F5',62708:'\u9400',62709:'\u93F7',62710:'\u9407',62711:'\u940E',62712:'\u9416',62713:'\u9412',62714:'\u93FA',62715:'\u9409',62716:'\u93F8',62717:'\u940A',62718:'\u93FF',62784:'\u93FC',62785:'\u940C',62786:'\u93F6',62787:'\u9411',62788:'\u9406',62789:'\u95DE',62790:'\u95E0',62791:'\u95DF',62792:'\u972E',62793:'\u972F',62794:'\u97B9',62795:'\u97BB',62796:'\u97FD',62797:'\u97FE',62798:'\u9860',62799:'\u9862',62800:'\u9863',62801:'\u985F',62802:'\u98C1',62803:'\u98C2',62804:'\u9950',62805:'\u994E',62806:'\u9959',62807:'\u994C',62808:'\u994B',62809:'\u9953',62810:'\u9A32',62811:'\u9A34',62812:'\u9A31',62813:'\u9A2C',62814:'\u9A2A',62815:'\u9A36',62816:'\u9A29',62817:'\u9A2E',62818:'\u9A38',62819:'\u9A2D',62820:'\u9AC7',62821:'\u9ACA',62822:'\u9AC6',62823:'\u9B10',62824:'\u9B12',62825:'\u9B11',62826:'\u9C0B',62827:'\u9C08',62828:'\u9BF7',62829:'\u9C05',62830:'\u9C12',62831:'\u9BF8',62832:'\u9C40',62833:'\u9C07',62834:'\u9C0E',62835:'\u9C06',62836:'\u9C17',62837:'\u9C14',62838:'\u9C09',62839:'\u9D9F',62840:'\u9D99',62841:'\u9DA4',62842:'\u9D9D',62843:'\u9D92',62844:'\u9D98',62845:'\u9D90',62846:'\u9D9B',62881:'\u9DA0',62882:'\u9D94',62883:'\u9D9C',62884:'\u9DAA',62885:'\u9D97',62886:'\u9DA1',62887:'\u9D9A',62888:'\u9DA2',62889:'\u9DA8',62890:'\u9D9E',62891:'\u9DA3',62892:'\u9DBF',62893:'\u9DA9',62894:'\u9D96',62895:'\u9DA6',62896:'\u9DA7',62897:'\u9E99',62898:'\u9E9B',62899:'\u9E9A',62900:'\u9EE5',62901:'\u9EE4',62902:'\u9EE7',62903:'\u9EE6',62904:'\u9F30',62905:'\u9F2E',62906:'\u9F5B',62907:'\u9F60',62908:'\u9F5E',62909:'\u9F5D',62910:'\u9F59',62911:'\u9F91',62912:'\u513A',62913:'\u5139',62914:'\u5298',62915:'\u5297',62916:'\u56C3',62917:'\u56BD',62918:'\u56BE',62919:'\u5B48',62920:'\u5B47',62921:'\u5DCB',62922:'\u5DCF',62923:'\u5EF1',62924:'\u61FD',62925:'\u651B',62926:'\u6B02',62927:'\u6AFC',62928:'\u6B03',62929:'\u6AF8',62930:'\u6B00',62931:'\u7043',62932:'\u7044',62933:'\u704A',62934:'\u7048',62935:'\u7049',62936:'\u7045',62937:'\u7046',62938:'\u721D',62939:'\u721A',62940:'\u7219',62941:'\u737E',62942:'\u7517',62943:'\u766A',62944:'\u77D0',62945:'\u792D',62946:'\u7931',62947:'\u792F',62948:'\u7C54',62949:'\u7C53',62950:'\u7CF2',62951:'\u7E8A',62952:'\u7E87',62953:'\u7E88',62954:'\u7E8B',62955:'\u7E86',62956:'\u7E8D',62957:'\u7F4D',62958:'\u7FBB',62959:'\u8030',62960:'\u81DD',62961:'\u8618',62962:'\u862A',62963:'\u8626',62964:'\u861F',62965:'\u8623',62966:'\u861C',62967:'\u8619',62968:'\u8627',62969:'\u862E',62970:'\u8621',62971:'\u8620',62972:'\u8629',62973:'\u861E',62974:'\u8625',63040:'\u8829',63041:'\u881D',63042:'\u881B',63043:'\u8820',63044:'\u8824',63045:'\u881C',63046:'\u882B',63047:'\u884A',63048:'\u896D',63049:'\u8969',63050:'\u896E',63051:'\u896B',63052:'\u89FA',63053:'\u8B79',63054:'\u8B78',63055:'\u8B45',63056:'\u8B7A',63057:'\u8B7B',63058:'\u8D10',63059:'\u8D14',63060:'\u8DAF',63061:'\u8E8E',63062:'\u8E8C',63063:'\u8F5E',63064:'\u8F5B',63065:'\u8F5D',63066:'\u9146',63067:'\u9144',63068:'\u9145',63069:'\u91B9',63070:'\u943F',63071:'\u943B',63072:'\u9436',63073:'\u9429',63074:'\u943D',63075:'\u943C',63076:'\u9430',63077:'\u9439',63078:'\u942A',63079:'\u9437',63080:'\u942C',63081:'\u9440',63082:'\u9431',63083:'\u95E5',63084:'\u95E4',63085:'\u95E3',63086:'\u9735',63087:'\u973A',63088:'\u97BF',63089:'\u97E1',63090:'\u9864',63091:'\u98C9',63092:'\u98C6',63093:'\u98C0',63094:'\u9958',63095:'\u9956',63096:'\u9A39',63097:'\u9A3D',63098:'\u9A46',63099:'\u9A44',63100:'\u9A42',63101:'\u9A41',63102:'\u9A3A',63137:'\u9A3F',63138:'\u9ACD',63139:'\u9B15',63140:'\u9B17',63141:'\u9B18',63142:'\u9B16',63143:'\u9B3A',63144:'\u9B52',63145:'\u9C2B',63146:'\u9C1D',63147:'\u9C1C',63148:'\u9C2C',63149:'\u9C23',63150:'\u9C28',63151:'\u9C29',63152:'\u9C24',63153:'\u9C21',63154:'\u9DB7',63155:'\u9DB6',63156:'\u9DBC',63157:'\u9DC1',63158:'\u9DC7',63159:'\u9DCA',63160:'\u9DCF',63161:'\u9DBE',63162:'\u9DC5',63163:'\u9DC3',63164:'\u9DBB',63165:'\u9DB5',63166:'\u9DCE',63167:'\u9DB9',63168:'\u9DBA',63169:'\u9DAC',63170:'\u9DC8',63171:'\u9DB1',63172:'\u9DAD',63173:'\u9DCC',63174:'\u9DB3',63175:'\u9DCD',63176:'\u9DB2',63177:'\u9E7A',63178:'\u9E9C',63179:'\u9EEB',63180:'\u9EEE',63181:'\u9EED',63182:'\u9F1B',63183:'\u9F18',63184:'\u9F1A',63185:'\u9F31',63186:'\u9F4E',63187:'\u9F65',63188:'\u9F64',63189:'\u9F92',63190:'\u4EB9',63191:'\u56C6',63192:'\u56C5',63193:'\u56CB',63194:'\u5971',63195:'\u5B4B',63196:'\u5B4C',63197:'\u5DD5',63198:'\u5DD1',63199:'\u5EF2',63200:'\u6521',63201:'\u6520',63202:'\u6526',63203:'\u6522',63204:'\u6B0B',63205:'\u6B08',63206:'\u6B09',63207:'\u6C0D',63208:'\u7055',63209:'\u7056',63210:'\u7057',63211:'\u7052',63212:'\u721E',63213:'\u721F',63214:'\u72A9',63215:'\u737F',63216:'\u74D8',63217:'\u74D5',63218:'\u74D9',63219:'\u74D7',63220:'\u766D',63221:'\u76AD',63222:'\u7935',63223:'\u79B4',63224:'\u7A70',63225:'\u7A71',63226:'\u7C57',63227:'\u7C5C',63228:'\u7C59',63229:'\u7C5B',63230:'\u7C5A',63296:'\u7CF4',63297:'\u7CF1',63298:'\u7E91',63299:'\u7F4F',63300:'\u7F87',63301:'\u81DE',63302:'\u826B',63303:'\u8634',63304:'\u8635',63305:'\u8633',63306:'\u862C',63307:'\u8632',63308:'\u8636',63309:'\u882C',63310:'\u8828',63311:'\u8826',63312:'\u882A',63313:'\u8825',63314:'\u8971',63315:'\u89BF',63316:'\u89BE',63317:'\u89FB',63318:'\u8B7E',63319:'\u8B84',63320:'\u8B82',63321:'\u8B86',63322:'\u8B85',63323:'\u8B7F',63324:'\u8D15',63325:'\u8E95',63326:'\u8E94',63327:'\u8E9A',63328:'\u8E92',63329:'\u8E90',63330:'\u8E96',63331:'\u8E97',63332:'\u8F60',63333:'\u8F62',63334:'\u9147',63335:'\u944C',63336:'\u9450',63337:'\u944A',63338:'\u944B',63339:'\u944F',63340:'\u9447',63341:'\u9445',63342:'\u9448',63343:'\u9449',63344:'\u9446',63345:'\u973F',63346:'\u97E3',63347:'\u986A',63348:'\u9869',63349:'\u98CB',63350:'\u9954',63351:'\u995B',63352:'\u9A4E',63353:'\u9A53',63354:'\u9A54',63355:'\u9A4C',63356:'\u9A4F',63357:'\u9A48',63358:'\u9A4A',63393:'\u9A49',63394:'\u9A52',63395:'\u9A50',63396:'\u9AD0',63397:'\u9B19',63398:'\u9B2B',63399:'\u9B3B',63400:'\u9B56',63401:'\u9B55',63402:'\u9C46',63403:'\u9C48',63404:'\u9C3F',63405:'\u9C44',63406:'\u9C39',63407:'\u9C33',63408:'\u9C41',63409:'\u9C3C',63410:'\u9C37',63411:'\u9C34',63412:'\u9C32',63413:'\u9C3D',63414:'\u9C36',63415:'\u9DDB',63416:'\u9DD2',63417:'\u9DDE',63418:'\u9DDA',63419:'\u9DCB',63420:'\u9DD0',63421:'\u9DDC',63422:'\u9DD1',63423:'\u9DDF',63424:'\u9DE9',63425:'\u9DD9',63426:'\u9DD8',63427:'\u9DD6',63428:'\u9DF5',63429:'\u9DD5',63430:'\u9DDD',63431:'\u9EB6',63432:'\u9EF0',63433:'\u9F35',63434:'\u9F33',63435:'\u9F32',63436:'\u9F42',63437:'\u9F6B',63438:'\u9F95',63439:'\u9FA2',63440:'\u513D',63441:'\u5299',63442:'\u58E8',63443:'\u58E7',63444:'\u5972',63445:'\u5B4D',63446:'\u5DD8',63447:'\u882F',63448:'\u5F4F',63449:'\u6201',63450:'\u6203',63451:'\u6204',63452:'\u6529',63453:'\u6525',63454:'\u6596',63455:'\u66EB',63456:'\u6B11',63457:'\u6B12',63458:'\u6B0F',63459:'\u6BCA',63460:'\u705B',63461:'\u705A',63462:'\u7222',63463:'\u7382',63464:'\u7381',63465:'\u7383',63466:'\u7670',63467:'\u77D4',63468:'\u7C67',63469:'\u7C66',63470:'\u7E95',63471:'\u826C',63472:'\u863A',63473:'\u8640',63474:'\u8639',63475:'\u863C',63476:'\u8631',63477:'\u863B',63478:'\u863E',63479:'\u8830',63480:'\u8832',63481:'\u882E',63482:'\u8833',63483:'\u8976',63484:'\u8974',63485:'\u8973',63486:'\u89FE',63552:'\u8B8C',63553:'\u8B8E',63554:'\u8B8B',63555:'\u8B88',63556:'\u8C45',63557:'\u8D19',63558:'\u8E98',63559:'\u8F64',63560:'\u8F63',63561:'\u91BC',63562:'\u9462',63563:'\u9455',63564:'\u945D',63565:'\u9457',63566:'\u945E',63567:'\u97C4',63568:'\u97C5',63569:'\u9800',63570:'\u9A56',63571:'\u9A59',63572:'\u9B1E',63573:'\u9B1F',63574:'\u9B20',63575:'\u9C52',63576:'\u9C58',63577:'\u9C50',63578:'\u9C4A',63579:'\u9C4D',63580:'\u9C4B',63581:'\u9C55',63582:'\u9C59',63583:'\u9C4C',63584:'\u9C4E',63585:'\u9DFB',63586:'\u9DF7',63587:'\u9DEF',63588:'\u9DE3',63589:'\u9DEB',63590:'\u9DF8',63591:'\u9DE4',63592:'\u9DF6',63593:'\u9DE1',63594:'\u9DEE',63595:'\u9DE6',63596:'\u9DF2',63597:'\u9DF0',63598:'\u9DE2',63599:'\u9DEC',63600:'\u9DF4',63601:'\u9DF3',63602:'\u9DE8',63603:'\u9DED',63604:'\u9EC2',63605:'\u9ED0',63606:'\u9EF2',63607:'\u9EF3',63608:'\u9F06',63609:'\u9F1C',63610:'\u9F38',63611:'\u9F37',63612:'\u9F36',63613:'\u9F43',63614:'\u9F4F',63649:'\u9F71',63650:'\u9F70',63651:'\u9F6E',63652:'\u9F6F',63653:'\u56D3',63654:'\u56CD',63655:'\u5B4E',63656:'\u5C6D',63657:'\u652D',63658:'\u66ED',63659:'\u66EE',63660:'\u6B13',63661:'\u705F',63662:'\u7061',63663:'\u705D',63664:'\u7060',63665:'\u7223',63666:'\u74DB',63667:'\u74E5',63668:'\u77D5',63669:'\u7938',63670:'\u79B7',63671:'\u79B6',63672:'\u7C6A',63673:'\u7E97',63674:'\u7F89',63675:'\u826D',63676:'\u8643',63677:'\u8838',63678:'\u8837',63679:'\u8835',63680:'\u884B',63681:'\u8B94',63682:'\u8B95',63683:'\u8E9E',63684:'\u8E9F',63685:'\u8EA0',63686:'\u8E9D',63687:'\u91BE',63688:'\u91BD',63689:'\u91C2',63690:'\u946B',63691:'\u9468',63692:'\u9469',63693:'\u96E5',63694:'\u9746',63695:'\u9743',63696:'\u9747',63697:'\u97C7',63698:'\u97E5',63699:'\u9A5E',63700:'\u9AD5',63701:'\u9B59',63702:'\u9C63',63703:'\u9C67',63704:'\u9C66',63705:'\u9C62',63706:'\u9C5E',63707:'\u9C60',63708:'\u9E02',63709:'\u9DFE',63710:'\u9E07',63711:'\u9E03',63712:'\u9E06',63713:'\u9E05',63714:'\u9E00',63715:'\u9E01',63716:'\u9E09',63717:'\u9DFF',63718:'\u9DFD',63719:'\u9E04',63720:'\u9EA0',63721:'\u9F1E',63722:'\u9F46',63723:'\u9F74',63724:'\u9F75',63725:'\u9F76',63726:'\u56D4',63727:'\u652E',63728:'\u65B8',63729:'\u6B18',63730:'\u6B19',63731:'\u6B17',63732:'\u6B1A',63733:'\u7062',63734:'\u7226',63735:'\u72AA',63736:'\u77D8',63737:'\u77D9',63738:'\u7939',63739:'\u7C69',63740:'\u7C6B',63741:'\u7CF6',63742:'\u7E9A',63808:'\u7E98',63809:'\u7E9B',63810:'\u7E99',63811:'\u81E0',63812:'\u81E1',63813:'\u8646',63814:'\u8647',63815:'\u8648',63816:'\u8979',63817:'\u897A',63818:'\u897C',63819:'\u897B',63820:'\u89FF',63821:'\u8B98',63822:'\u8B99',63823:'\u8EA5',63824:'\u8EA4',63825:'\u8EA3',63826:'\u946E',63827:'\u946D',63828:'\u946F',63829:'\u9471',63830:'\u9473',63831:'\u9749',63832:'\u9872',63833:'\u995F',63834:'\u9C68',63835:'\u9C6E',63836:'\u9C6D',63837:'\u9E0B',63838:'\u9E0D',63839:'\u9E10',63840:'\u9E0F',63841:'\u9E12',63842:'\u9E11',63843:'\u9EA1',63844:'\u9EF5',63845:'\u9F09',63846:'\u9F47',63847:'\u9F78',63848:'\u9F7B',63849:'\u9F7A',63850:'\u9F79',63851:'\u571E',63852:'\u7066',63853:'\u7C6F',63854:'\u883C',63855:'\u8DB2',63856:'\u8EA6',63857:'\u91C3',63858:'\u9474',63859:'\u9478',63860:'\u9476',63861:'\u9475',63862:'\u9A60',63863:'\u9C74',63864:'\u9C73',63865:'\u9C71',63866:'\u9C75',63867:'\u9E14',63868:'\u9E13',63869:'\u9EF6',63870:'\u9F0A',63905:'\u9FA4',63906:'\u7068',63907:'\u7065',63908:'\u7CF7',63909:'\u866A',63910:'\u883E',63911:'\u883D',63912:'\u883F',63913:'\u8B9E',63914:'\u8C9C',63915:'\u8EA9',63916:'\u8EC9',63917:'\u974B',63918:'\u9873',63919:'\u9874',63920:'\u98CC',63921:'\u9961',63922:'\u99AB',63923:'\u9A64',63924:'\u9A66',63925:'\u9A67',63926:'\u9B24',63927:'\u9E15',63928:'\u9E17',63929:'\u9F48',63930:'\u6207',63931:'\u6B1E',63932:'\u7227',63933:'\u864C',63934:'\u8EA8',63935:'\u9482',63936:'\u9480',63937:'\u9481',63938:'\u9A69',63939:'\u9A68',63940:'\u9B2E',63941:'\u9E19',63942:'\u7229',63943:'\u864B',63944:'\u8B9F',63945:'\u9483',63946:'\u9C79',63947:'\u9EB7',63948:'\u7675',63949:'\u9A6B',63950:'\u9C7A',63951:'\u9E1D',63952:'\u7069',63953:'\u706A',63954:'\u9EA4',63955:'\u9F7E',63956:'\u9F49',63957:'\u9F98',63958:'\u7881',63959:'\u92B9',63960:'\u88CF',63961:'\u58BB',63962:'\u6052',63963:'\u7CA7',63964:'\u5AFA',63965:'\u2554',63966:'\u2566',63967:'\u2557',63968:'\u2560',63969:'\u256C',63970:'\u2563',63971:'\u255A',63972:'\u2569',63973:'\u255D',63974:'\u2552',63975:'\u2564',63976:'\u2555',63977:'\u255E',63978:'\u256A',63979:'\u2561',63980:'\u2558',63981:'\u2567',63982:'\u255B',63983:'\u2553',63984:'\u2565',63985:'\u2556',63986:'\u255F',63987:'\u256B',63988:'\u2562',63989:'\u2559',63990:'\u2568',63991:'\u255C',63992:'\u2551',63993:'\u2550',63994:'\u256D',63995:'\u256E',63996:'\u2570',63997:'\u256F',63998:'\u2593',64064:'\uE000',64065:'\uE001',64066:'\uE002',64067:'\uE003',64068:'\uE004',64069:'\uE005',64070:'\uE006',64071:'\uE007',64072:'\uE008',64073:'\uE009',64074:'\uE00A',64075:'\uE00B',64076:'\uE00C',64077:'\uE00D',64078:'\uE00E',64079:'\uE00F',64080:'\uE010',64081:'\uE011',64082:'\uE012',64083:'\uE013',64084:'\uE014',64085:'\uE015',64086:'\uE016',64087:'\uE017',64088:'\uE018',64089:'\uE019',64090:'\uE01A',64091:'\uE01B',64092:'\uE01C',64093:'\uE01D',64094:'\uE01E',64095:'\uE01F',64096:'\uE020',64097:'\uE021',64098:'\uE022',64099:'\uE023',64100:'\uE024',64101:'\uE025',64102:'\uE026',64103:'\uE027',64104:'\uE028',64105:'\uE029',64106:'\uE02A',64107:'\uE02B',64108:'\uE02C',64109:'\uE02D',64110:'\uE02E',64111:'\uE02F',64112:'\uE030',64113:'\uE031',64114:'\uE032',64115:'\uE033',64116:'\uE034',64117:'\uE035',64118:'\uE036',64119:'\uE037',64120:'\uE038',64121:'\uE039',64122:'\uE03A',64123:'\uE03B',64124:'\uE03C',64125:'\uE03D',64126:'\uE03E',64161:'\uE03F',64162:'\uE040',64163:'\uE041',64164:'\uE042',64165:'\uE043',64166:'\uE044',64167:'\uE045',64168:'\uE046',64169:'\uE047',64170:'\uE048',64171:'\uE049',64172:'\uE04A',64173:'\uE04B',64174:'\uE04C',64175:'\uE04D',64176:'\uE04E',64177:'\uE04F',64178:'\uE050',64179:'\uE051',64180:'\uE052',64181:'\uE053',64182:'\uE054',64183:'\uE055',64184:'\uE056',64185:'\uE057',64186:'\uE058',64187:'\uE059',64188:'\uE05A',64189:'\uE05B',64190:'\uE05C',64191:'\uE05D',64192:'\uE05E',64193:'\uE05F',64194:'\uE060',64195:'\uE061',64196:'\uE062',64197:'\uE063',64198:'\uE064',64199:'\uE065',64200:'\uE066',64201:'\uE067',64202:'\uE068',64203:'\uE069',64204:'\uE06A',64205:'\uE06B',64206:'\uE06C',64207:'\uE06D',64208:'\uE06E',64209:'\uE06F',64210:'\uE070',64211:'\uE071',64212:'\uE072',64213:'\uE073',64214:'\uE074',64215:'\uE075',64216:'\uE076',64217:'\uE077',64218:'\uE078',64219:'\uE079',64220:'\uE07A',64221:'\uE07B',64222:'\uE07C',64223:'\uE07D',64224:'\uE07E',64225:'\uE07F',64226:'\uE080',64227:'\uE081',64228:'\uE082',64229:'\uE083',64230:'\uE084',64231:'\uE085',64232:'\uE086',64233:'\uE087',64234:'\uE088',64235:'\uE089',64236:'\uE08A',64237:'\uE08B',64238:'\uE08C',64239:'\uE08D',64240:'\uE08E',64241:'\uE08F',64242:'\uE090',64243:'\uE091',64244:'\uE092',64245:'\uE093',64246:'\uE094',64247:'\uE095',64248:'\uE096',64249:'\uE097',64250:'\uE098',64251:'\uE099',64252:'\uE09A',64253:'\uE09B',64254:'\uE09C',64320:'\uE09D',64321:'\uE09E',64322:'\uE09F',64323:'\uE0A0',64324:'\uE0A1',64325:'\uE0A2',64326:'\uE0A3',64327:'\uE0A4',64328:'\uE0A5',64329:'\uE0A6',64330:'\uE0A7',64331:'\uE0A8',64332:'\uE0A9',64333:'\uE0AA',64334:'\uE0AB',64335:'\uE0AC',64336:'\uE0AD',64337:'\uE0AE',64338:'\uE0AF',64339:'\uE0B0',64340:'\uE0B1',64341:'\uE0B2',64342:'\uE0B3',64343:'\uE0B4',64344:'\uE0B5',64345:'\uE0B6',64346:'\uE0B7',64347:'\uE0B8',64348:'\uE0B9',64349:'\uE0BA',64350:'\uE0BB',64351:'\uE0BC',64352:'\uE0BD',64353:'\uE0BE',64354:'\uE0BF',64355:'\uE0C0',64356:'\uE0C1',64357:'\uE0C2',64358:'\uE0C3',64359:'\uE0C4',64360:'\uE0C5',64361:'\uE0C6',64362:'\uE0C7',64363:'\uE0C8',64364:'\uE0C9',64365:'\uE0CA',64366:'\uE0CB',64367:'\uE0CC',64368:'\uE0CD',64369:'\uE0CE',64370:'\uE0CF',64371:'\uE0D0',64372:'\uE0D1',64373:'\uE0D2',64374:'\uE0D3',64375:'\uE0D4',64376:'\uE0D5',64377:'\uE0D6',64378:'\uE0D7',64379:'\uE0D8',64380:'\uE0D9',64381:'\uE0DA',64382:'\uE0DB',64417:'\uE0DC',64418:'\uE0DD',64419:'\uE0DE',64420:'\uE0DF',64421:'\uE0E0',64422:'\uE0E1',64423:'\uE0E2',64424:'\uE0E3',64425:'\uE0E4',64426:'\uE0E5',64427:'\uE0E6',64428:'\uE0E7',64429:'\uE0E8',64430:'\uE0E9',64431:'\uE0EA',64432:'\uE0EB',64433:'\uE0EC',64434:'\uE0ED',64435:'\uE0EE',64436:'\uE0EF',64437:'\uE0F0',64438:'\uE0F1',64439:'\uE0F2',64440:'\uE0F3',64441:'\uE0F4',64442:'\uE0F5',64443:'\uE0F6',64444:'\uE0F7',64445:'\uE0F8',64446:'\uE0F9',64447:'\uE0FA',64448:'\uE0FB',64449:'\uE0FC',64450:'\uE0FD',64451:'\uE0FE',64452:'\uE0FF',64453:'\uE100',64454:'\uE101',64455:'\uE102',64456:'\uE103',64457:'\uE104',64458:'\uE105',64459:'\uE106',64460:'\uE107',64461:'\uE108',64462:'\uE109',64463:'\uE10A',64464:'\uE10B',64465:'\uE10C',64466:'\uE10D',64467:'\uE10E',64468:'\uE10F',64469:'\uE110',64470:'\uE111',64471:'\uE112',64472:'\uE113',64473:'\uE114',64474:'\uE115',64475:'\uE116',64476:'\uE117',64477:'\uE118',64478:'\uE119',64479:'\uE11A',64480:'\uE11B',64481:'\uE11C',64482:'\uE11D',64483:'\uE11E',64484:'\uE11F',64485:'\uE120',64486:'\uE121',64487:'\uE122',64488:'\uE123',64489:'\uE124',64490:'\uE125',64491:'\uE126',64492:'\uE127',64493:'\uE128',64494:'\uE129',64495:'\uE12A',64496:'\uE12B',64497:'\uE12C',64498:'\uE12D',64499:'\uE12E',64500:'\uE12F',64501:'\uE130',64502:'\uE131',64503:'\uE132',64504:'\uE133',64505:'\uE134',64506:'\uE135',64507:'\uE136',64508:'\uE137',64509:'\uE138',64510:'\uE139',64576:'\uE13A',64577:'\uE13B',64578:'\uE13C',64579:'\uE13D',64580:'\uE13E',64581:'\uE13F',64582:'\uE140',64583:'\uE141',64584:'\uE142',64585:'\uE143',64586:'\uE144',64587:'\uE145',64588:'\uE146',64589:'\uE147',64590:'\uE148',64591:'\uE149',64592:'\uE14A',64593:'\uE14B',64594:'\uE14C',64595:'\uE14D',64596:'\uE14E',64597:'\uE14F',64598:'\uE150',64599:'\uE151',64600:'\uE152',64601:'\uE153',64602:'\uE154',64603:'\uE155',64604:'\uE156',64605:'\uE157',64606:'\uE158',64607:'\uE159',64608:'\uE15A',64609:'\uE15B',64610:'\uE15C',64611:'\uE15D',64612:'\uE15E',64613:'\uE15F',64614:'\uE160',64615:'\uE161',64616:'\uE162',64617:'\uE163',64618:'\uE164',64619:'\uE165',64620:'\uE166',64621:'\uE167',64622:'\uE168',64623:'\uE169',64624:'\uE16A',64625:'\uE16B',64626:'\uE16C',64627:'\uE16D',64628:'\uE16E',64629:'\uE16F',64630:'\uE170',64631:'\uE171',64632:'\uE172',64633:'\uE173',64634:'\uE174',64635:'\uE175',64636:'\uE176',64637:'\uE177',64638:'\uE178',64673:'\uE179',64674:'\uE17A',64675:'\uE17B',64676:'\uE17C',64677:'\uE17D',64678:'\uE17E',64679:'\uE17F',64680:'\uE180',64681:'\uE181',64682:'\uE182',64683:'\uE183',64684:'\uE184',64685:'\uE185',64686:'\uE186',64687:'\uE187',64688:'\uE188',64689:'\uE189',64690:'\uE18A',64691:'\uE18B',64692:'\uE18C',64693:'\uE18D',64694:'\uE18E',64695:'\uE18F',64696:'\uE190',64697:'\uE191',64698:'\uE192',64699:'\uE193',64700:'\uE194',64701:'\uE195',64702:'\uE196',64703:'\uE197',64704:'\uE198',64705:'\uE199',64706:'\uE19A',64707:'\uE19B',64708:'\uE19C',64709:'\uE19D',64710:'\uE19E',64711:'\uE19F',64712:'\uE1A0',64713:'\uE1A1',64714:'\uE1A2',64715:'\uE1A3',64716:'\uE1A4',64717:'\uE1A5',64718:'\uE1A6',64719:'\uE1A7',64720:'\uE1A8',64721:'\uE1A9',64722:'\uE1AA',64723:'\uE1AB',64724:'\uE1AC',64725:'\uE1AD',64726:'\uE1AE',64727:'\uE1AF',64728:'\uE1B0',64729:'\uE1B1',64730:'\uE1B2',64731:'\uE1B3',64732:'\uE1B4',64733:'\uE1B5',64734:'\uE1B6',64735:'\uE1B7',64736:'\uE1B8',64737:'\uE1B9',64738:'\uE1BA',64739:'\uE1BB',64740:'\uE1BC',64741:'\uE1BD',64742:'\uE1BE',64743:'\uE1BF',64744:'\uE1C0',64745:'\uE1C1',64746:'\uE1C2',64747:'\uE1C3',64748:'\uE1C4',64749:'\uE1C5',64750:'\uE1C6',64751:'\uE1C7',64752:'\uE1C8',64753:'\uE1C9',64754:'\uE1CA',64755:'\uE1CB',64756:'\uE1CC',64757:'\uE1CD',64758:'\uE1CE',64759:'\uE1CF',64760:'\uE1D0',64761:'\uE1D1',64762:'\uE1D2',64763:'\uE1D3',64764:'\uE1D4',64765:'\uE1D5',64766:'\uE1D6',64832:'\uE1D7',64833:'\uE1D8',64834:'\uE1D9',64835:'\uE1DA',64836:'\uE1DB',64837:'\uE1DC',64838:'\uE1DD',64839:'\uE1DE',64840:'\uE1DF',64841:'\uE1E0',64842:'\uE1E1',64843:'\uE1E2',64844:'\uE1E3',64845:'\uE1E4',64846:'\uE1E5',64847:'\uE1E6',64848:'\uE1E7',64849:'\uE1E8',64850:'\uE1E9',64851:'\uE1EA',64852:'\uE1EB',64853:'\uE1EC',64854:'\uE1ED',64855:'\uE1EE',64856:'\uE1EF',64857:'\uE1F0',64858:'\uE1F1',64859:'\uE1F2',64860:'\uE1F3',64861:'\uE1F4',64862:'\uE1F5',64863:'\uE1F6',64864:'\uE1F7',64865:'\uE1F8',64866:'\uE1F9',64867:'\uE1FA',64868:'\uE1FB',64869:'\uE1FC',64870:'\uE1FD',64871:'\uE1FE',64872:'\uE1FF',64873:'\uE200',64874:'\uE201',64875:'\uE202',64876:'\uE203',64877:'\uE204',64878:'\uE205',64879:'\uE206',64880:'\uE207',64881:'\uE208',64882:'\uE209',64883:'\uE20A',64884:'\uE20B',64885:'\uE20C',64886:'\uE20D',64887:'\uE20E',64888:'\uE20F',64889:'\uE210',64890:'\uE211',64891:'\uE212',64892:'\uE213',64893:'\uE214',64894:'\uE215',64929:'\uE216',64930:'\uE217',64931:'\uE218',64932:'\uE219',64933:'\uE21A',64934:'\uE21B',64935:'\uE21C',64936:'\uE21D',64937:'\uE21E',64938:'\uE21F',64939:'\uE220',64940:'\uE221',64941:'\uE222',64942:'\uE223',64943:'\uE224',64944:'\uE225',64945:'\uE226',64946:'\uE227',64947:'\uE228',64948:'\uE229',64949:'\uE22A',64950:'\uE22B',64951:'\uE22C',64952:'\uE22D',64953:'\uE22E',64954:'\uE22F',64955:'\uE230',64956:'\uE231',64957:'\uE232',64958:'\uE233',64959:'\uE234',64960:'\uE235',64961:'\uE236',64962:'\uE237',64963:'\uE238',64964:'\uE239',64965:'\uE23A',64966:'\uE23B',64967:'\uE23C',64968:'\uE23D',64969:'\uE23E',64970:'\uE23F',64971:'\uE240',64972:'\uE241',64973:'\uE242',64974:'\uE243',64975:'\uE244',64976:'\uE245',64977:'\uE246',64978:'\uE247',64979:'\uE248',64980:'\uE249',64981:'\uE24A',64982:'\uE24B',64983:'\uE24C',64984:'\uE24D',64985:'\uE24E',64986:'\uE24F',64987:'\uE250',64988:'\uE251',64989:'\uE252',64990:'\uE253',64991:'\uE254',64992:'\uE255',64993:'\uE256',64994:'\uE257',64995:'\uE258',64996:'\uE259',64997:'\uE25A',64998:'\uE25B',64999:'\uE25C',65000:'\uE25D',65001:'\uE25E',65002:'\uE25F',65003:'\uE260',65004:'\uE261',65005:'\uE262',65006:'\uE263',65007:'\uE264',65008:'\uE265',65009:'\uE266',65010:'\uE267',65011:'\uE268',65012:'\uE269',65013:'\uE26A',65014:'\uE26B',65015:'\uE26C',65016:'\uE26D',65017:'\uE26E',65018:'\uE26F',65019:'\uE270',65020:'\uE271',65021:'\uE272',65022:'\uE273',65088:'\uE274',65089:'\uE275',65090:'\uE276',65091:'\uE277',65092:'\uE278',65093:'\uE279',65094:'\uE27A',65095:'\uE27B',65096:'\uE27C',65097:'\uE27D',65098:'\uE27E',65099:'\uE27F',65100:'\uE280',65101:'\uE281',65102:'\uE282',65103:'\uE283',65104:'\uE284',65105:'\uE285',65106:'\uE286',65107:'\uE287',65108:'\uE288',65109:'\uE289',65110:'\uE28A',65111:'\uE28B',65112:'\uE28C',65113:'\uE28D',65114:'\uE28E',65115:'\uE28F',65116:'\uE290',65117:'\uE291',65118:'\uE292',65119:'\uE293',65120:'\uE294',65121:'\uE295',65122:'\uE296',65123:'\uE297',65124:'\uE298',65125:'\uE299',65126:'\uE29A',65127:'\uE29B',65128:'\uE29C',65129:'\uE29D',65130:'\uE29E',65131:'\uE29F',65132:'\uE2A0',65133:'\uE2A1',65134:'\uE2A2',65135:'\uE2A3',65136:'\uE2A4',65137:'\uE2A5',65138:'\uE2A6',65139:'\uE2A7',65140:'\uE2A8',65141:'\uE2A9',65142:'\uE2AA',65143:'\uE2AB',65144:'\uE2AC',65145:'\uE2AD',65146:'\uE2AE',65147:'\uE2AF',65148:'\uE2B0',65149:'\uE2B1',65150:'\uE2B2',65185:'\uE2B3',65186:'\uE2B4',65187:'\uE2B5',65188:'\uE2B6',65189:'\uE2B7',65190:'\uE2B8',65191:'\uE2B9',65192:'\uE2BA',65193:'\uE2BB',65194:'\uE2BC',65195:'\uE2BD',65196:'\uE2BE',65197:'\uE2BF',65198:'\uE2C0',65199:'\uE2C1',65200:'\uE2C2',65201:'\uE2C3',65202:'\uE2C4',65203:'\uE2C5',65204:'\uE2C6',65205:'\uE2C7',65206:'\uE2C8',65207:'\uE2C9',65208:'\uE2CA',65209:'\uE2CB',65210:'\uE2CC',65211:'\uE2CD',65212:'\uE2CE',65213:'\uE2CF',65214:'\uE2D0',65215:'\uE2D1',65216:'\uE2D2',65217:'\uE2D3',65218:'\uE2D4',65219:'\uE2D5',65220:'\uE2D6',65221:'\uE2D7',65222:'\uE2D8',65223:'\uE2D9',65224:'\uE2DA',65225:'\uE2DB',65226:'\uE2DC',65227:'\uE2DD',65228:'\uE2DE',65229:'\uE2DF',65230:'\uE2E0',65231:'\uE2E1',65232:'\uE2E2',65233:'\uE2E3',65234:'\uE2E4',65235:'\uE2E5',65236:'\uE2E6',65237:'\uE2E7',65238:'\uE2E8',65239:'\uE2E9',65240:'\uE2EA',65241:'\uE2EB',65242:'\uE2EC',65243:'\uE2ED',65244:'\uE2EE',65245:'\uE2EF',65246:'\uE2F0',65247:'\uE2F1',65248:'\uE2F2',65249:'\uE2F3',65250:'\uE2F4',65251:'\uE2F5',65252:'\uE2F6',65253:'\uE2F7',65254:'\uE2F8',65255:'\uE2F9',65256:'\uE2FA',65257:'\uE2FB',65258:'\uE2FC',65259:'\uE2FD',65260:'\uE2FE',65261:'\uE2FF',65262:'\uE300',65263:'\uE301',65264:'\uE302',65265:'\uE303',65266:'\uE304',65267:'\uE305',65268:'\uE306',65269:'\uE307',65270:'\uE308',65271:'\uE309',65272:'\uE30A',65273:'\uE30B',65274:'\uE30C',65275:'\uE30D',65276:'\uE30E',65277:'\uE30F',65278:'\uE310',129:None,130:None,131:None,132:None,133:None,134:None,135:None,136:None,137:None,138:None,139:None,140:None,141:None,142:None,143:None,144:None,145:None,146:None,147:None,148:None,149:None,150:None,151:None,152:None,153:None,154:None,155:None,156:None,157:None,158:None,159:None,160:None,161:None,162:None,163:None,164:None,165:None,166:None,167:None,168:None,169:None,170:None,171:None,172:None,173:None,174:None,175:None,176:None,177:None,178:None,179:None,180:None,181:None,182:None,183:None,184:None,185:None,186:None,187:None,188:None,189:None,190:None,191:None,192:None,193:None,194:None,195:None,196:None,197:None,198:None,199:None,200:None,201:None,202:None,203:None,204:None,205:None,206:None,207:None,208:None,209:None,210:None,211:None,212:None,213:None,214:None,215:None,216:None,217:None,218:None,219:None,220:None,221:None,222:None,223:None,224:None,225:None,226:None,227:None,228:None,229:None,230:None,231:None,232:None,233:None,234:None,235:None,236:None,237:None,238:None,239:None,240:None,241:None,242:None,243:None,244:None,245:None,246:None,247:None,248:None,249:None,250:None,251:None,252:None,253:None,254:None} \ No newline at end of file diff --git a/extract_msg/encoding/utils.py b/extract_msg/encoding/utils.py index 918a04ae..8aa60ca0 100644 --- a/extract_msg/encoding/utils.py +++ b/extract_msg/encoding/utils.py @@ -13,9 +13,192 @@ from typing import Dict, Tuple +def createVBEncoding(codecName : str, decodingTable : Dict[int, str]) -> codecs.CodecInfo: + """ + Creates the classes for a variable byte encoding, returning the CodecInfo + instance associated with it. Currently only supports encodings with up to 2 + bytes per character. + + :param codecName: The name of the codec being created. + :param decodingTable: The table to use for decoding data. Will be used to + create the encodingTable. + """ + # Create the encoding table. If there are duplicate keys, they will use the + # last one introduced. Iterating in reverse means the lowest possible value + # for a character will be the one used. + encodingTable = { + value : bytes((key,)) if key < 256 else bytes((key >> 8, key & 0xFF)) + for key, value in reversed(decodingTable.items()) if value is not None + } + + # Create the classes. + class Codec(codecs.Codec): + def encode(self, text, errors='strict'): + return variableByteEncode(codecName, text, errors, encodingTable) + + def decode(self, data, errors='strict'): + return variableByteDecode(codecName, data, errors, decodingTable) + + class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, text, final=False): + return variableByteEncode(codecName, text, self.errors, encodingTable)[0] + + class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, data, final=False): + return variableByteDecode(codecName, data, self.errors, decodingTable)[0] + + class StreamWriter(Codec, codecs.StreamWriter): + pass + + class StreamReader(Codec, codecs.StreamReader): + pass + + # Return the CodecInfo instance. + return codecs.CodecInfo( + name=codecName, + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) + + +def createSBEncoding(codecName : str, decodingTable : Dict[int, str]) -> codecs.CodecInfo: + """ + Creates the classes for a single byte encoding, returning the CodecInfo + instance associated with it. Currently only supports encodings with up to 2 + bytes per character. + + :param codecName: The name of the codec being created. + :param decodingTable: The table to use for decoding data. Will be used to + create the encodingTable. + """ + # Create the encoding table. If there are duplicate keys, they will use the + # last one introduced. Iterating in reverse means the lowest possible value + # for a character will be the one used. + encodingTable = { + value : bytes((key,)) + for key, value in reversed(decodingTable.items()) if value is not None + } + + # Create the classes. + class Codec(codecs.Codec): + def encode(self, text, errors='strict'): + return singleByteEncode(codecName, text, errors, encodingTable) + + def decode(self, data, errors='strict'): + return singleByteDecode(codecName, data, errors, decodingTable) + + class IncrementalEncoder(codecs.IncrementalEncoder): + def encode(self, text, final=False): + return singleByteEncode(codecName, text, self.errors, encodingTable)[0] + + class IncrementalDecoder(codecs.IncrementalDecoder): + def decode(self, data, final=False): + return singleByteDecode(codecName, data, self.errors, decodingTable)[0] + + class StreamWriter(Codec, codecs.StreamWriter): + pass + + class StreamReader(Codec, codecs.StreamReader): + pass + + # Return the CodecInfo instance. + return codecs.CodecInfo( + name=codecName, + encode=Codec().encode, + decode=Codec().decode, + incrementalencoder=IncrementalEncoder, + incrementaldecoder=IncrementalDecoder, + streamwriter=StreamWriter, + streamreader=StreamReader, + ) + + +def singleByteDecode(codecName : str, data, errors : str, decodeTable : Dict[int, str]) -> Tuple[str, int]: + """ + Function for decoding single-byte codecs. + + :param codecName: The name of the codec, used for error messages. + :param data: A bytes-like object to decode. + :param errors: The error behavior to use. + :param decodeTable: The mapping of values to use. Continuation bytes MUST be + defined in the table, but SHOULD be set to None. This allows for the + function to detect what bytes are valid for continuation. + """ + if len(data) == 0: + return ('', 0) + + errorHandler = codecs.lookup_error(errors) + output = '' + + iterator = enumerate(data) + start = 0 + + for start, byte in iterator: + if byte in decodeTable: + output += decodeTable[byte] + else: + err = UnicodeDecodeError(codecName, + data, + start, + start + 1, + 'character maps to ', + ) + rep = errorHandler(err) + output += rep[0] + for _ in range(rep[1] - start - 1): + try: + next(iterator) + except StopIteration: + break + + return (output, len(output)) + + +def singleByteEncode(codecName : str, data, errors : str, encodeTable : Dict[str, bytes]) -> Tuple[bytes, int]: + """ + Function for encoding variable-byte codecs that use one or two bytes per + character. + + :param codecName: The name of the codec, used for error messages. + :param data: A bytes-like object to decode. + :param errors: The error behavior to use. + :param encodeTable: The mapping of values to use. + """ + if len(data) == 0: + return + + errorHandler = codecs.lookup_error(errors) + output = b'' + iterator = enumerate(data) + start = 0 + for start, char in iterator: + if char in encodeTable: + output += encodeTable[char] + else: + err = UnicodeEncodeError(codecName, + data, + start, + start + 1, + 'illegal multibyte sequence', + ) + rep = errorHandler(err) + output += rep[0] + # Skip the specified number of characters. + for _ in range(rep[1] - start - 1): + try: + next(iterator) + except StopIteration: + break + + + def variableByteDecode(codecName : str, data, errors : str, decodeTable : Dict[int, str]) -> Tuple[str, int]: """ - Function for decoding variable-byte codecs. + Function for decoding variable-byte codecs that use one or two bytes per character. Checks if a character is less than 0x80, mapping it directly if so. Otherwise, it reads the next byte and combines the two before looking up the @@ -35,6 +218,8 @@ def variableByteDecode(codecName : str, data, errors : str, decodeTable : Dict[i output = '' iterator = enumerate(data) + start = 0 + for start, byte in iterator: # Variable byte should be an integer here. if byte < 0x80: @@ -45,29 +230,35 @@ def variableByteDecode(codecName : str, data, errors : str, decodeTable : Dict[i data, start, start + 1, - 'character maps to ' + 'character maps to ', ) rep = errorHandler(err) output += rep[0] # Skip the specified number of characters. for _ in range(rep[1] - start - 1): - iterator.__next__() + try: + next(iterator) + except StopIteration: + break elif byte not in decodeTable: err = UnicodeDecodeError(codecName, data, start, start + 1, - 'invalid start byte' + 'invalid start byte', ) rep = errorHandler(err) output += rep[0] # Skip the specified number of characters. for _ in range(rep[1] - start - 1): - iterator.__next__() + try: + next(iterator) + except StopIteration: + break else: try: - byte = (byte << 8) | iterator.__next__()[1] + byte = (byte << 8) | next(iterator)[1] if byte in decodeTable: output += decodeTable[byte] else: @@ -75,19 +266,19 @@ def variableByteDecode(codecName : str, data, errors : str, decodeTable : Dict[i data, start, start + 2, - 'character maps to ' + 'character maps to ', ) rep = errorHandler(err) output += rep[0] # Skip the specified number of characters. for _ in range(rep[1] - start - 1): - iterator.__next__() + next(iterator) except StopIteration: err = UnicodeDecodeError(codecName, data, start, start + 1, - 'unexpected end of data' + 'unexpected end of data', ) rep = errorHandler(err) output += rep[0] @@ -96,9 +287,10 @@ def variableByteDecode(codecName : str, data, errors : str, decodeTable : Dict[i return (output, start) -def variableByteEncode(codecName : str, data, errors : str, encodeTable : Dict[str, int]) -> Tuple[bytes, int]: +def variableByteEncode(codecName : str, data, errors : str, encodeTable : Dict[str, bytes]) -> Tuple[bytes, int]: """ - Function for decoding variable-byte codecs. + Function for encoding variable-byte codecs that use one or two bytes per + character. :param codecName: The name of the codec, used for error messages. :param data: A bytes-like object to decode. @@ -111,19 +303,25 @@ def variableByteEncode(codecName : str, data, errors : str, encodeTable : Dict[s errorHandler = codecs.lookup_error(errors) output = b'' iterator = enumerate(data) + start = 0 + for start, char in iterator: - if char not in encodeTable: + if char in encodeTable: + data += encodeTable[char] + else: err = UnicodeEncodeError(codecName, data, start, start + 1, - 'illegal multibyte sequence') + 'illegal multibyte sequence', + ) rep = errorHandler(err) output += rep[0] # Skip the specified number of characters. for _ in range(rep[1] - start - 1): - iterator.__next__() - else: - data += encodeTable[char] + try: + next(iterator) + except StopIteration: + break - return output + return (output, start + 1) diff --git a/extract_msg/encoding/win950.py b/extract_msg/encoding/win950.py deleted file mode 100644 index aeb1bee2..00000000 --- a/extract_msg/encoding/win950.py +++ /dev/null @@ -1,59 +0,0 @@ -""" -Support for Microsoft's implementation of CP950 (core python has bad support -for it). -""" - -__all__ = [ - 'getregentry', -] - - -# We use a similar format to what I've seen in core Python encoding files. -import codecs - -from .utils import variableByteDecode, variableByteEncode -from ._win950_dec import decodingTable - -### Codec APIs - -class Codec(codecs.Codec): - def encode(self, text, errors='strict'): - return variableByteEncode('windows-950', text, errors, encodingTable) - - def decode(self, data, errors='strict'): - return variableByteDecode('windows-950', data, errors, decodingTable) - -class IncrementalEncoder(codecs.IncrementalEncoder): - def encode(self, text, final=False): - return variableByteEncode('windows-950', text, self.errors, encodingTable)[0] - -class IncrementalDecoder(codecs.IncrementalDecoder): - def decode(self, data, final=False): - return variableByteDecode('windows-950', data, self.errors, decodingTable)[0] - -class StreamWriter(Codec, codecs.StreamWriter): - pass - -class StreamReader(Codec, codecs.StreamReader): - pass - -### encodings module API - -def getregentry(): - return codecs.CodecInfo( - name='windows-950', - encode=Codec().encode, - decode=Codec().decode, - incrementalencoder=IncrementalEncoder, - incrementaldecoder=IncrementalDecoder, - streamwriter=StreamWriter, - streamreader=StreamReader, - ) - - -### Encoding table -encodingTable = {value : bytes((key,)) if key < 256 - else bytes((key >> 8, key & 0xFF)) - for key, value in decodingTable.items() - if value is not None - } \ No newline at end of file From 467c1068bb61ad578493ca90cfbb6c6078bd23a0 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Fri, 7 Jul 2023 21:29:47 -0700 Subject: [PATCH 84/89] Updated comments and changelog --- CHANGELOG.md | 4 ++-- extract_msg/encoding/__init__.py | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 421e6bed..9ae70ebf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,8 @@ * [[TeamMsgExtractor #372](https://github.com/TeamMsgExtractor/msg-extractor/issues/372)] Changed the way that the save functions return a value. This makes the return value from all save functions much more informative, allowing a user to separate if a fole or folder (or if more than one) was saved from the function. It also guarentees that all classes from this module will return the relevent path(s) if data is actually saved. * [[TeamMsgExtractor #288](https://github.com/TeamMsgExtractor/msg-extractor/issues/288)] Added feature to allow attachment save functions to simply overwrite existing files of the same name. This can be done with the `overwriteExisting` keyword argument from code or the `--overwrite-existing` option from the command line. * [[TeamMsgExtractor #40](https://github.com/TeamMsgExtractor/msg-extractor/issues/40)] Added new submodule `custom_attachments`. This submodule provides an extendable way to handle custom attachment types, attachment types whose structure and formatting are not defined in the Microsoft documentation for MSG files. This includes a handler to at least partially cover support for Outlook images. -* [[TeamMsgExtractor #373](https://github.com/TeamMsgExtractor/msg-extractor/issues/373)] Added the `encoding` submodule for encoding tasks, including proper support for Microsoft's implementation of cp950. This gets added to the codecs list as "windows-950". +* [[TeamMsgExtractor #373](https://github.com/TeamMsgExtractor/msg-extractor/issues/373)] Added the `encoding` submodule for encoding tasks, including proper support for Microsoft's implementation of CP950. This gets added to the codecs list as "windows-950". + * Added support for the windows-874 encoding. This includes infrastructure to more easily support new single-byte encodings, only needing a decoding table to make them work. * Fixed an issue in the save functions that left the possibility for the zip files to not end up closing if the save function created it and then had an exception. * Added new property `AttachmentBase.clsid` which returns the listed CLSID value of the data stream/storage of the attachment. * Changed internal behavior of `MSGFile.attachments`. This should not cause any noticeable changes to the output. @@ -45,7 +46,6 @@ * Fixed sender not being properly decoded in some circumstances. * Changed behavior of `MSGFile` to have olefile raise defects of type `DEFECT_INCORRECT` and above instead of just `DEFECT_FATAL`. Uncaught issues of `DEFECT_INCORRECT` can often cause the module to have parsing issues that may be misleading, this just ensures the issue is clarified. This behavior can be reverted back to the previous with `ErrorBehavior.OLE_DEFECT_INCORRECT`. * Fixed potential issues that may have made is possible for certain attachments to ignore filename conflict resolution code. -* Added support for the windows-874 encoding. This includes infrastructure to more easily support new single-byte encodings, only needing a decoding table to make them work. **v0.41.5** * Fixed an issue from version `0.41.3` where the header being present but missing the `From` field would cause an exception. diff --git a/extract_msg/encoding/__init__.py b/extract_msg/encoding/__init__.py index a1470818..75b99045 100644 --- a/extract_msg/encoding/__init__.py +++ b/extract_msg/encoding/__init__.py @@ -56,7 +56,6 @@ 866: 'cp866', # OEM Russian; Cyrillic (DOS) 869: 'ibm869', # OEM Modern Greek; Greek, Modern (DOS) 870: 'cp870', # IBM870 # IBM EBCDIC Multilingual/ROECE (Latin 2); IBM EBCDIC Multilingual Latin 2 - # UNSUPPORTED. 874: 'windows-874', # ANSI/OEM Thai (ISO 8859-11); Thai (Windows) 875: 'cp875', # IBM EBCDIC Greek Modern 932: 'shift_jis', # ANSI/OEM Japanese; Japanese (Shift-JIS) @@ -77,8 +76,8 @@ 1147: 'cp1147', # IBM EBCDIC France (20297 + Euro symbol); IBM EBCDIC (France-Euro) 1148: 'cp1148ms', # IBM EBCDIC International (500 + Euro symbol); IBM EBCDIC (International-Euro) 1149: 'cp1149', # IBM EBCDIC Icelandic (20871 + Euro symbol); IBM EBCDIC (Icelandic-Euro) - 1200: 'utf-16-le', # Unicode UTF-16, little endian byte order (BMP of ISO 10646); available only to managed applications - 1201: 'utf-16-be', # Unicode UTF-16, big endian byte order; available only to managed applications + 1200: 'utf-16-le', # Unicode UTF-16, little endian byte order (BMP of ISO 10646); + 1201: 'utf-16-be', # Unicode UTF-16, big endian byte order; 1250: 'windows-1250', # ANSI Central European; Central European (Windows) 1251: 'windows-1251', # ANSI Cyrillic; Cyrillic (Windows) 1252: 'windows-1252', # ANSI Latin 1; Western European (Windows) From 061558eab1a2c48db39a00f813180e8229fd0d55 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Sat, 8 Jul 2023 18:55:54 -0700 Subject: [PATCH 85/89] Bit of organization --- extract_msg/encoding/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/extract_msg/encoding/__init__.py b/extract_msg/encoding/__init__.py index 75b99045..f562755f 100644 --- a/extract_msg/encoding/__init__.py +++ b/extract_msg/encoding/__init__.py @@ -243,6 +243,7 @@ 65001: 'utf-8', # Unicode (UTF-8) } +# Register new encodings. def lookupCodePage(id_ : int) -> str: """ From 36843cf5277c1f1a5e6cbe4cdb07b40b308680ae Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Sat, 8 Jul 2023 19:47:59 -0700 Subject: [PATCH 86/89] Add new encoding, add utility, update changelog --- CHANGELOG.md | 5 ++- extract_msg/encoding/__init__.py | 13 +++++--- extract_msg/encoding/_dt/_mac_cyrillic.py | 8 +++++ extract_msg/encoding/_dt/_win874_dec.py | 2 ++ helper-scripts/produce-dec-table.py | 39 +++++++++++++++++++++++ 5 files changed, 61 insertions(+), 6 deletions(-) create mode 100644 extract_msg/encoding/_dt/_mac_cyrillic.py create mode 100644 helper-scripts/produce-dec-table.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ae70ebf..30bef6ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,10 @@ * [[TeamMsgExtractor #288](https://github.com/TeamMsgExtractor/msg-extractor/issues/288)] Added feature to allow attachment save functions to simply overwrite existing files of the same name. This can be done with the `overwriteExisting` keyword argument from code or the `--overwrite-existing` option from the command line. * [[TeamMsgExtractor #40](https://github.com/TeamMsgExtractor/msg-extractor/issues/40)] Added new submodule `custom_attachments`. This submodule provides an extendable way to handle custom attachment types, attachment types whose structure and formatting are not defined in the Microsoft documentation for MSG files. This includes a handler to at least partially cover support for Outlook images. * [[TeamMsgExtractor #373](https://github.com/TeamMsgExtractor/msg-extractor/issues/373)] Added the `encoding` submodule for encoding tasks, including proper support for Microsoft's implementation of CP950. This gets added to the codecs list as "windows-950". - * Added support for the windows-874 encoding. This includes infrastructure to more easily support new single-byte encodings, only needing a decoding table to make them work. + * Added infrastructure to make it easy to add variable-byte (up to two bytes) encodings and single-byte encodings. + * Added the following encodings: + * windows-874 + * x-mac-cyrillic * Fixed an issue in the save functions that left the possibility for the zip files to not end up closing if the save function created it and then had an exception. * Added new property `AttachmentBase.clsid` which returns the listed CLSID value of the data stream/storage of the attachment. * Changed internal behavior of `MSGFile.attachments`. This should not cause any noticeable changes to the output. diff --git a/extract_msg/encoding/__init__.py b/extract_msg/encoding/__init__.py index f562755f..a5fb911f 100644 --- a/extract_msg/encoding/__init__.py +++ b/extract_msg/encoding/__init__.py @@ -12,7 +12,6 @@ import codecs from ..exceptions import UnknownCodepageError, UnsupportedEncodingError -from .utils import createSBEncoding, createVBEncoding # This is a dictionary matching the code page number to it's encoding name. @@ -99,7 +98,6 @@ 10005: 'x-mac-hebrew', # Hebrew (Mac) # UNSUPPORTED. 10006: 'x-mac-greek', # Greek (Mac) - # UNSUPPORTED. 10007: 'x-mac-cyrillic', # Cyrillic (Mac) # UNSUPPORTED. 10008: 'x-mac-chinesesimp', # MAC Simplified Chinese (GB 2312); Chinese Simplified (Mac) @@ -264,10 +262,15 @@ def lookupCodePage(id_ : int) -> str: def _lookupEncoding(name): return _codecsInfo.get(name) -from ._dt import _win874_dec, _win950_dec +from .utils import createSBEncoding as _sb, createVBEncoding as _vb +from ._dt import ( + _mac_cyrillic, _win874_dec, _win950_dec + ) + _codecsInfo = { - 'windows_950': createVBEncoding('windows-950', _win950_dec.decodingTable), - 'windows_874': createSBEncoding('windows-874', _win874_dec.decodingTable), + 'x_mac_cyrillic': _sb('x-mac-cyrillic', _mac_cyrillic.decodingTable), + 'windows_950': _vb('windows-950', _win950_dec.decodingTable), + 'windows_874': _sb('windows-874', _win874_dec.decodingTable), } codecs.register(_lookupEncoding) \ No newline at end of file diff --git a/extract_msg/encoding/_dt/_mac_cyrillic.py b/extract_msg/encoding/_dt/_mac_cyrillic.py new file mode 100644 index 00000000..125d4e63 --- /dev/null +++ b/extract_msg/encoding/_dt/_mac_cyrillic.py @@ -0,0 +1,8 @@ +# Based on https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/MAC/CYRILLIC.TXT + +__all__ = [ + 'decodingTable', +] + + +decodingTable={0:'\x00',1:'\x01',2:'\x02',3:'\x03',4:'\x04',5:'\x05',6:'\x06',7:'\x07',8:'\x08',9:'\t',10:'\n',11:'\x0b',12:'\x0c',13:'\r',14:'\x0e',15:'\x0f',16:'\x10',17:'\x11',18:'\x12',19:'\x13',20:'\x14',21:'\x15',22:'\x16',23:'\x17',24:'\x18',25:'\x19',26:'\x1a',27:'\x1b',28:'\x1c',29:'\x1d',30:'\x1e',31:'\x1f',32:' ',33:'!',34:'"',35:'#',36:'$',37:'%',38:'&',39:"'",40:'(',41:')',42:'*',43:'+',44:',',45:'-',46:'.',47:'/',48:'0',49:'1',50:'2',51:'3',52:'4',53:'5',54:'6',55:'7',56:'8',57:'9',58:':',59:';',60:'<',61:'=',62:'>',63:'?',64:'@',65:'A',66:'B',67:'C',68:'D',69:'E',70:'F',71:'G',72:'H',73:'I',74:'J',75:'K',76:'L',77:'M',78:'N',79:'O',80:'P',81:'Q',82:'R',83:'S',84:'T',85:'U',86:'V',87:'W',88:'X',89:'Y',90:'Z',91:'[',92:'\\',93:']',94:'^',95:'_',96:'`',97:'a',98:'b',99:'c',100:'d',101:'e',102:'f',103:'g',104:'h',105:'i',106:'j',107:'k',108:'l',109:'m',110:'n',111:'o',112:'p',113:'q',114:'r',115:'s',116:'t',117:'u',118:'v',119:'w',120:'x',121:'y',122:'z',123:'{',124:'|',125:'}',126:'~',127:'\x7f',128:'\u0410',129:'\u0411',130:'\u0412',131:'\u0413',132:'\u0414',133:'\u0415',134:'\u0416',135:'\u0417',136:'\u0418',137:'\u0419',138:'\u041A',139:'\u041B',140:'\u041C',141:'\u041D',142:'\u041E',143:'\u041F',144:'\u0420',145:'\u0421',146:'\u0422',147:'\u0423',148:'\u0424',149:'\u0425',150:'\u0426',151:'\u0427',152:'\u0428',153:'\u0429',154:'\u042A',155:'\u042B',156:'\u042C',157:'\u042D',158:'\u042E',159:'\u042F',160:'\u2020',161:'\xB0',162:'\xA2',163:'\xA3',164:'\xA7',165:'\u2022',166:'\xB6',167:'\u0406',168:'\xAE',169:'\xA9',170:'\u2122',171:'\u0402',172:'\u0452',173:'\u2260',174:'\u0403',175:'\u0453',176:'\u221E',177:'\xB1',178:'\u2264',179:'\u2265',180:'\u0456',181:'\xB5',182:'\u2202',183:'\u0408',184:'\u0404',185:'\u0454',186:'\u0407',187:'\u0457',188:'\u0409',189:'\u0459',190:'\u040A',191:'\u045A',192:'\u0458',193:'\u0405',194:'\xAC',195:'\u221A',196:'\u0192',197:'\u2248',198:'\u2206',199:'\xAB',200:'\xBB',201:'\u2026',202:'\xA0',203:'\u040B',204:'\u045B',205:'\u040C',206:'\u045C',207:'\u0455',208:'\u2013',209:'\u2014',210:'\u201C',211:'\u201D',212:'\u2018',213:'\u2019',214:'\xF7',215:'\u201E',216:'\u040E',217:'\u045E',218:'\u040F',219:'\u045F',220:'\u2116',221:'\u0401',222:'\u0451',223:'\u044F',224:'\u0430',225:'\u0431',226:'\u0432',227:'\u0433',228:'\u0434',229:'\u0435',230:'\u0436',231:'\u0437',232:'\u0438',233:'\u0439',234:'\u043A',235:'\u043B',236:'\u043C',237:'\u043D',238:'\u043E',239:'\u043F',240:'\u0440',241:'\u0441',242:'\u0442',243:'\u0443',244:'\u0444',245:'\u0445',246:'\u0446',247:'\u0447',248:'\u0448',249:'\u0449',250:'\u044A',251:'\u044B',252:'\u044C',253:'\u044D',254:'\u044E',255:'\xA4'} \ No newline at end of file diff --git a/extract_msg/encoding/_dt/_win874_dec.py b/extract_msg/encoding/_dt/_win874_dec.py index c80429fd..406f833f 100644 --- a/extract_msg/encoding/_dt/_win874_dec.py +++ b/extract_msg/encoding/_dt/_win874_dec.py @@ -1,3 +1,5 @@ +# Based on https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP874.TXT + __all__ = [ 'decodingTable', ] diff --git a/helper-scripts/produce-dec-table.py b/helper-scripts/produce-dec-table.py new file mode 100644 index 00000000..f983bec0 --- /dev/null +++ b/helper-scripts/produce-dec-table.py @@ -0,0 +1,39 @@ +""" +Basic script to convert a document for a single-byte encoding into a decoding +table for use by the module. +""" + + +import sys + + +conversionDict = {0:"'\\x00'",1:"'\\x01'",2:"'\\x02'",3:"'\\x03'",4:"'\\x04'",5:"'\\x05'",6:"'\\x06'",7:"'\\x07'",8:"'\\x08'",9:"'\\t'",10:"'\\n'",11:"'\\x0b'",12:"'\\x0c'",13:"'\\r'",14:"'\\x0e'",15:"'\\x0f'",16:"'\\x10'",17:"'\\x11'",18:"'\\x12'",19:"'\\x13'",20:"'\\x14'",21:"'\\x15'",22:"'\\x16'",23:"'\\x17'",24:"'\\x18'",25:"'\\x19'",26:"'\\x1a'",27:"'\\x1b'",28:"'\\x1c'",29:"'\\x1d'",30:"'\\x1e'",31:"'\\x1f'",32:"' '",33:"'!'",34:'\'"\'',35:"'#'",36:"'$'",37:"'%'",38:"'&'",39:'"\'"',40:"'('",41:"')'",42:"'*'",43:"'+'",44:"','",45:"'-'",46:"'.'",47:"'/'",48:"'0'",49:"'1'",50:"'2'",51:"'3'",52:"'4'",53:"'5'",54:"'6'",55:"'7'",56:"'8'",57:"'9'",58:"':'",59:"';'",60:"'<'",61:"'='",62:"'>'",63:"'?'",64:"'@'",65:"'A'",66:"'B'",67:"'C'",68:"'D'",69:"'E'",70:"'F'",71:"'G'",72:"'H'",73:"'I'",74:"'J'",75:"'K'",76:"'L'",77:"'M'",78:"'N'",79:"'O'",80:"'P'",81:"'Q'",82:"'R'",83:"'S'",84:"'T'",85:"'U'",86:"'V'",87:"'W'",88:"'X'",89:"'Y'",90:"'Z'",91:"'['",92:"'\\\\'",93:"']'",94:"'^'",95:"'_'",96:"'`'",97:"'a'",98:"'b'",99:"'c'",100:"'d'",101:"'e'",102:"'f'",103:"'g'",104:"'h'",105:"'i'",106:"'j'",107:"'k'",108:"'l'",109:"'m'",110:"'n'",111:"'o'",112:"'p'",113:"'q'",114:"'r'",115:"'s'",116:"'t'",117:"'u'",118:"'v'",119:"'w'",120:"'x'",121:"'y'",122:"'z'",123:"'{'",124:"'|'",125:"'}'",126:"'~'",127:"'\\x7f'",128:"'\\x80'",129:"'\\x81'",130:"'\\x82'",131:"'\\x83'",132:"'\\x84'",133:"'\\x85'",134:"'\\x86'",135:"'\\x87'",136:"'\\x88'",137:"'\\x89'",138:"'\\x8A'",139:"'\\x8B'",140:"'\\x8C'",141:"'\\x8D'",142:"'\\x8E'",143:"'\\x8F'",144:"'\\x90'",145:"'\\x91'",146:"'\\x92'",147:"'\\x93'",148:"'\\x94'",149:"'\\x95'",150:"'\\x96'",151:"'\\x97'",152:"'\\x98'",153:"'\\x99'",154:"'\\x9A'",155:"'\\x9B'",156:"'\\x9C'",157:"'\\x9D'",158:"'\\x9E'",159:"'\\x9F'",160:"'\\xA0'",161:"'\\xA1'",162:"'\\xA2'",163:"'\\xA3'",164:"'\\xA4'",165:"'\\xA5'",166:"'\\xA6'",167:"'\\xA7'",168:"'\\xA8'",169:"'\\xA9'",170:"'\\xAA'",171:"'\\xAB'",172:"'\\xAC'",173:"'\\xAD'",174:"'\\xAE'",175:"'\\xAF'",176:"'\\xB0'",177:"'\\xB1'",178:"'\\xB2'",179:"'\\xB3'",180:"'\\xB4'",181:"'\\xB5'",182:"'\\xB6'",183:"'\\xB7'",184:"'\\xB8'",185:"'\\xB9'",186:"'\\xBA'",187:"'\\xBB'",188:"'\\xBC'",189:"'\\xBD'",190:"'\\xBE'",191:"'\\xBF'",192:"'\\xC0'",193:"'\\xC1'",194:"'\\xC2'",195:"'\\xC3'",196:"'\\xC4'",197:"'\\xC5'",198:"'\\xC6'",199:"'\\xC7'",200:"'\\xC8'",201:"'\\xC9'",202:"'\\xCA'",203:"'\\xCB'",204:"'\\xCC'",205:"'\\xCD'",206:"'\\xCE'",207:"'\\xCF'",208:"'\\xD0'",209:"'\\xD1'",210:"'\\xD2'",211:"'\\xD3'",212:"'\\xD4'",213:"'\\xD5'",214:"'\\xD6'",215:"'\\xD7'",216:"'\\xD8'",217:"'\\xD9'",218:"'\\xDA'",219:"'\\xDB'",220:"'\\xDC'",221:"'\\xDD'",222:"'\\xDE'",223:"'\\xDF'",224:"'\\xE0'",225:"'\\xE1'",226:"'\\xE2'",227:"'\\xE3'",228:"'\\xE4'",229:"'\\xE5'",230:"'\\xE6'",231:"'\\xE7'",232:"'\\xE8'",233:"'\\xE9'",234:"'\\xEA'",235:"'\\xEB'",236:"'\\xEC'",237:"'\\xED'",238:"'\\xEE'",239:"'\\xEF'",240:"'\\xF0'",241:"'\\xF1'",242:"'\\xF2'",243:"'\\xF3'",244:"'\\xF4'",245:"'\\xF5'",246:"'\\xF6'",247:"'\\xF7'",248:"'\\xF8'",249:"'\\xF9'",250:"'\\xFA'",251:"'\\xFB'",252:"'\\xFC'",253:"'\\xFD'",254:"'\\xFE'",255:"'\\xFF'"} + +def symbolToEntry(input : int, output : int) -> str: + if output < 256: + return f'{input}:{conversionDict[output]}' + elif output < 0x10000: + return f'{input}:\'\\u{output:04X}\'' + else: + return f'{input}:\'\\U{output:08X}\'' + + +if __name__ == "__main__": + table = {} + if len(sys.argv) != 2: + print('Invalid number of arguments (requires exactly one file name)!') + exit(-1) + + with open(sys.argv[1], 'r') as f: + for line in f: + # Skip comment lines. + if not line.strip().startswith('#'): + items = line.split('\t') + if len(items) != 1: + table[int(items[0], 16)] = int(items[1], 16) + + with open('.'.join(sys.argv[1].split('.')[:-1] + ['py']), 'w') as f: + # Write the top of the file. + f.write('__all__ = [\n \'decodingTable\',\n]\n\n\ndecodingTable={') + f.write(','.join(symbolToEntry(x, table[x]) for x in table)) + f.write('}') \ No newline at end of file From 32d445d0c618ef40886a1426fb35b286739c3a18 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Sat, 8 Jul 2023 19:54:21 -0700 Subject: [PATCH 87/89] Fix bug in new utility --- helper-scripts/produce-dec-table.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/helper-scripts/produce-dec-table.py b/helper-scripts/produce-dec-table.py index f983bec0..3e699f49 100644 --- a/helper-scripts/produce-dec-table.py +++ b/helper-scripts/produce-dec-table.py @@ -29,7 +29,7 @@ def symbolToEntry(input : int, output : int) -> str: # Skip comment lines. if not line.strip().startswith('#'): items = line.split('\t') - if len(items) != 1: + if len(items) != 1 and items[1]: table[int(items[0], 16)] = int(items[1], 16) with open('.'.join(sys.argv[1].split('.')[:-1] + ['py']), 'w') as f: From 9e0c7ffb38eafa7d07bfe99a5ed4c1d98306f380 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Sat, 8 Jul 2023 20:53:54 -0700 Subject: [PATCH 88/89] Added a few more encodings --- CHANGELOG.md | 4 ++++ extract_msg/encoding/__init__.py | 11 ++++++----- extract_msg/encoding/_dt/_mac_ce.py | 8 ++++++++ extract_msg/encoding/_dt/_mac_greek.py | 8 ++++++++ extract_msg/encoding/_dt/_mac_iceland.py | 8 ++++++++ extract_msg/encoding/_dt/_mac_turkish.py | 8 ++++++++ 6 files changed, 42 insertions(+), 5 deletions(-) create mode 100644 extract_msg/encoding/_dt/_mac_ce.py create mode 100644 extract_msg/encoding/_dt/_mac_greek.py create mode 100644 extract_msg/encoding/_dt/_mac_iceland.py create mode 100644 extract_msg/encoding/_dt/_mac_turkish.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 30bef6ae..358eca51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,11 @@ * Added infrastructure to make it easy to add variable-byte (up to two bytes) encodings and single-byte encodings. * Added the following encodings: * windows-874 + * x-mac-ce * x-mac-cyrillic + * x-mac-greek + * x-mac-icelandic + * x-mac-turkish * Fixed an issue in the save functions that left the possibility for the zip files to not end up closing if the save function created it and then had an exception. * Added new property `AttachmentBase.clsid` which returns the listed CLSID value of the data stream/storage of the attachment. * Changed internal behavior of `MSGFile.attachments`. This should not cause any noticeable changes to the output. diff --git a/extract_msg/encoding/__init__.py b/extract_msg/encoding/__init__.py index a5fb911f..19b04d07 100644 --- a/extract_msg/encoding/__init__.py +++ b/extract_msg/encoding/__init__.py @@ -96,7 +96,6 @@ 10004: 'x-mac-arabic', # Arabic (Mac) # UNSUPPORTED. 10005: 'x-mac-hebrew', # Hebrew (Mac) - # UNSUPPORTED. 10006: 'x-mac-greek', # Greek (Mac) 10007: 'x-mac-cyrillic', # Cyrillic (Mac) # UNSUPPORTED. @@ -107,11 +106,8 @@ 10017: 'x-mac-ukrainian', # Ukrainian (Mac) # UNSUPPORTED. 10021: 'x-mac-thai', # Thai (Mac) - # UNSUPPORTED. 10029: 'x-mac-ce', # MAC Latin 2; Central European (Mac) - # UNSUPPORTED. 10079: 'x-mac-icelandic', # Icelandic (Mac) - # UNSUPPORTED. 10081: 'x-mac-turkish', # Turkish (Mac) # UNSUPPORTED. 10082: 'x-mac-croatian', # Croatian (Mac) @@ -264,11 +260,16 @@ def _lookupEncoding(name): from .utils import createSBEncoding as _sb, createVBEncoding as _vb from ._dt import ( - _mac_cyrillic, _win874_dec, _win950_dec + _mac_ce, _mac_cyrillic, _mac_greek, _mac_iceland, _mac_turkish, + _win874_dec, _win950_dec ) _codecsInfo = { + 'x_mac_ce': _sb('x-mac-ce', _mac_ce.decodingTable), 'x_mac_cyrillic': _sb('x-mac-cyrillic', _mac_cyrillic.decodingTable), + 'x_mac_greek': _sb('x-mac-greek', _mac_greek.decodingTable), + 'x_mac_icelandic': _sb('x-mac-icelandic', _mac_iceland.decodingTable), + 'x_mac_turkish': _sb('x-mac-turkish', _mac_turkish.decodingTable), 'windows_950': _vb('windows-950', _win950_dec.decodingTable), 'windows_874': _sb('windows-874', _win874_dec.decodingTable), } diff --git a/extract_msg/encoding/_dt/_mac_ce.py b/extract_msg/encoding/_dt/_mac_ce.py new file mode 100644 index 00000000..a23e582c --- /dev/null +++ b/extract_msg/encoding/_dt/_mac_ce.py @@ -0,0 +1,8 @@ +# Based on https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/MAC/LATIN2.TXT + +__all__ = [ + 'decodingTable', +] + + +decodingTable={0:'\x00',1:'\x01',2:'\x02',3:'\x03',4:'\x04',5:'\x05',6:'\x06',7:'\x07',8:'\x08',9:'\t',10:'\n',11:'\x0b',12:'\x0c',13:'\r',14:'\x0e',15:'\x0f',16:'\x10',17:'\x11',18:'\x12',19:'\x13',20:'\x14',21:'\x15',22:'\x16',23:'\x17',24:'\x18',25:'\x19',26:'\x1a',27:'\x1b',28:'\x1c',29:'\x1d',30:'\x1e',31:'\x1f',32:' ',33:'!',34:'"',35:'#',36:'$',37:'%',38:'&',39:"'",40:'(',41:')',42:'*',43:'+',44:',',45:'-',46:'.',47:'/',48:'0',49:'1',50:'2',51:'3',52:'4',53:'5',54:'6',55:'7',56:'8',57:'9',58:':',59:';',60:'<',61:'=',62:'>',63:'?',64:'@',65:'A',66:'B',67:'C',68:'D',69:'E',70:'F',71:'G',72:'H',73:'I',74:'J',75:'K',76:'L',77:'M',78:'N',79:'O',80:'P',81:'Q',82:'R',83:'S',84:'T',85:'U',86:'V',87:'W',88:'X',89:'Y',90:'Z',91:'[',92:'\\',93:']',94:'^',95:'_',96:'`',97:'a',98:'b',99:'c',100:'d',101:'e',102:'f',103:'g',104:'h',105:'i',106:'j',107:'k',108:'l',109:'m',110:'n',111:'o',112:'p',113:'q',114:'r',115:'s',116:'t',117:'u',118:'v',119:'w',120:'x',121:'y',122:'z',123:'{',124:'|',125:'}',126:'~',127:'\x7f',128:'\xC4',129:'\u0100',130:'\u0101',131:'\xC9',132:'\u0104',133:'\xD6',134:'\xDC',135:'\xE1',136:'\u0105',137:'\u010C',138:'\xE4',139:'\u010D',140:'\u0106',141:'\u0107',142:'\xE9',143:'\u0179',144:'\u017A',145:'\u010E',146:'\xED',147:'\u010F',148:'\u0112',149:'\u0113',150:'\u0116',151:'\xF3',152:'\u0117',153:'\xF4',154:'\xF6',155:'\xF5',156:'\xFA',157:'\u011A',158:'\u011B',159:'\xFC',160:'\u2020',161:'\xB0',162:'\u0118',163:'\xA3',164:'\xA7',165:'\u2022',166:'\xB6',167:'\xDF',168:'\xAE',169:'\xA9',170:'\u2122',171:'\u0119',172:'\xA8',173:'\u2260',174:'\u0123',175:'\u012E',176:'\u012F',177:'\u012A',178:'\u2264',179:'\u2265',180:'\u012B',181:'\u0136',182:'\u2202',183:'\u2211',184:'\u0142',185:'\u013B',186:'\u013C',187:'\u013D',188:'\u013E',189:'\u0139',190:'\u013A',191:'\u0145',192:'\u0146',193:'\u0143',194:'\xAC',195:'\u221A',196:'\u0144',197:'\u0147',198:'\u2206',199:'\xAB',200:'\xBB',201:'\u2026',202:'\xA0',203:'\u0148',204:'\u0150',205:'\xD5',206:'\u0151',207:'\u014C',208:'\u2013',209:'\u2014',210:'\u201C',211:'\u201D',212:'\u2018',213:'\u2019',214:'\xF7',215:'\u25CA',216:'\u014D',217:'\u0154',218:'\u0155',219:'\u0158',220:'\u2039',221:'\u203A',222:'\u0159',223:'\u0156',224:'\u0157',225:'\u0160',226:'\u201A',227:'\u201E',228:'\u0161',229:'\u015A',230:'\u015B',231:'\xC1',232:'\u0164',233:'\u0165',234:'\xCD',235:'\u017D',236:'\u017E',237:'\u016A',238:'\xD3',239:'\xD4',240:'\u016B',241:'\u016E',242:'\xDA',243:'\u016F',244:'\u0170',245:'\u0171',246:'\u0172',247:'\u0173',248:'\xDD',249:'\xFD',250:'\u0137',251:'\u017B',252:'\u0141',253:'\u017C',254:'\u0122',255:'\u02C7'} \ No newline at end of file diff --git a/extract_msg/encoding/_dt/_mac_greek.py b/extract_msg/encoding/_dt/_mac_greek.py new file mode 100644 index 00000000..41985a13 --- /dev/null +++ b/extract_msg/encoding/_dt/_mac_greek.py @@ -0,0 +1,8 @@ +# Based on https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/MAC/GREEK.TXT + +__all__ = [ + 'decodingTable', +] + + +decodingTable={0:'\x00',1:'\x01',2:'\x02',3:'\x03',4:'\x04',5:'\x05',6:'\x06',7:'\x07',8:'\x08',9:'\t',10:'\n',11:'\x0b',12:'\x0c',13:'\r',14:'\x0e',15:'\x0f',16:'\x10',17:'\x11',18:'\x12',19:'\x13',20:'\x14',21:'\x15',22:'\x16',23:'\x17',24:'\x18',25:'\x19',26:'\x1a',27:'\x1b',28:'\x1c',29:'\x1d',30:'\x1e',31:'\x1f',32:' ',33:'!',34:'"',35:'#',36:'$',37:'%',38:'&',39:"'",40:'(',41:')',42:'*',43:'+',44:',',45:'-',46:'.',47:'/',48:'0',49:'1',50:'2',51:'3',52:'4',53:'5',54:'6',55:'7',56:'8',57:'9',58:':',59:';',60:'<',61:'=',62:'>',63:'?',64:'@',65:'A',66:'B',67:'C',68:'D',69:'E',70:'F',71:'G',72:'H',73:'I',74:'J',75:'K',76:'L',77:'M',78:'N',79:'O',80:'P',81:'Q',82:'R',83:'S',84:'T',85:'U',86:'V',87:'W',88:'X',89:'Y',90:'Z',91:'[',92:'\\',93:']',94:'^',95:'_',96:'`',97:'a',98:'b',99:'c',100:'d',101:'e',102:'f',103:'g',104:'h',105:'i',106:'j',107:'k',108:'l',109:'m',110:'n',111:'o',112:'p',113:'q',114:'r',115:'s',116:'t',117:'u',118:'v',119:'w',120:'x',121:'y',122:'z',123:'{',124:'|',125:'}',126:'~',127:'\x7f',128:'\xC4',129:'\xB9',130:'\xB2',131:'\xC9',132:'\xB3',133:'\xD6',134:'\xDC',135:'\u0385',136:'\xE0',137:'\xE2',138:'\xE4',139:'\u0384',140:'\xA8',141:'\xE7',142:'\xE9',143:'\xE8',144:'\xEA',145:'\xEB',146:'\xA3',147:'\u2122',148:'\xEE',149:'\xEF',150:'\u2022',151:'\xBD',152:'\u2030',153:'\xF4',154:'\xF6',155:'\xA6',156:'\xAD',157:'\xF9',158:'\xFB',159:'\xFC',160:'\u2020',161:'\u0393',162:'\u0394',163:'\u0398',164:'\u039B',165:'\u039E',166:'\u03A0',167:'\xDF',168:'\xAE',169:'\xA9',170:'\u03A3',171:'\u03AA',172:'\xA7',173:'\u2260',174:'\xB0',175:'\u0387',176:'\u0391',177:'\xB1',178:'\u2264',179:'\u2265',180:'\xA5',181:'\u0392',182:'\u0395',183:'\u0396',184:'\u0397',185:'\u0399',186:'\u039A',187:'\u039C',188:'\u03A6',189:'\u03AB',190:'\u03A8',191:'\u03A9',192:'\u03AC',193:'\u039D',194:'\xAC',195:'\u039F',196:'\u03A1',197:'\u2248',198:'\u03A4',199:'\xAB',200:'\xBB',201:'\u2026',202:'\xA0',203:'\u03A5',204:'\u03A7',205:'\u0386',206:'\u0388',207:'\u0153',208:'\u2013',209:'\u2015',210:'\u201C',211:'\u201D',212:'\u2018',213:'\u2019',214:'\xF7',215:'\u0389',216:'\u038A',217:'\u038C',218:'\u038E',219:'\u03AD',220:'\u03AE',221:'\u03AF',222:'\u03CC',223:'\u038F',224:'\u03CD',225:'\u03B1',226:'\u03B2',227:'\u03C8',228:'\u03B4',229:'\u03B5',230:'\u03C6',231:'\u03B3',232:'\u03B7',233:'\u03B9',234:'\u03BE',235:'\u03BA',236:'\u03BB',237:'\u03BC',238:'\u03BD',239:'\u03BF',240:'\u03C0',241:'\u03CE',242:'\u03C1',243:'\u03C3',244:'\u03C4',245:'\u03B8',246:'\u03C9',247:'\u03C2',248:'\u03C7',249:'\u03C5',250:'\u03B6',251:'\u03CA',252:'\u03CB',253:'\u0390',254:'\u03B0'} \ No newline at end of file diff --git a/extract_msg/encoding/_dt/_mac_iceland.py b/extract_msg/encoding/_dt/_mac_iceland.py new file mode 100644 index 00000000..2fb210bd --- /dev/null +++ b/extract_msg/encoding/_dt/_mac_iceland.py @@ -0,0 +1,8 @@ +# Based on https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/MAC/ICELAND.TXT + +__all__ = [ + 'decodingTable', +] + + +decodingTable={0:'\x00',1:'\x01',2:'\x02',3:'\x03',4:'\x04',5:'\x05',6:'\x06',7:'\x07',8:'\x08',9:'\t',10:'\n',11:'\x0b',12:'\x0c',13:'\r',14:'\x0e',15:'\x0f',16:'\x10',17:'\x11',18:'\x12',19:'\x13',20:'\x14',21:'\x15',22:'\x16',23:'\x17',24:'\x18',25:'\x19',26:'\x1a',27:'\x1b',28:'\x1c',29:'\x1d',30:'\x1e',31:'\x1f',32:' ',33:'!',34:'"',35:'#',36:'$',37:'%',38:'&',39:"'",40:'(',41:')',42:'*',43:'+',44:',',45:'-',46:'.',47:'/',48:'0',49:'1',50:'2',51:'3',52:'4',53:'5',54:'6',55:'7',56:'8',57:'9',58:':',59:';',60:'<',61:'=',62:'>',63:'?',64:'@',65:'A',66:'B',67:'C',68:'D',69:'E',70:'F',71:'G',72:'H',73:'I',74:'J',75:'K',76:'L',77:'M',78:'N',79:'O',80:'P',81:'Q',82:'R',83:'S',84:'T',85:'U',86:'V',87:'W',88:'X',89:'Y',90:'Z',91:'[',92:'\\',93:']',94:'^',95:'_',96:'`',97:'a',98:'b',99:'c',100:'d',101:'e',102:'f',103:'g',104:'h',105:'i',106:'j',107:'k',108:'l',109:'m',110:'n',111:'o',112:'p',113:'q',114:'r',115:'s',116:'t',117:'u',118:'v',119:'w',120:'x',121:'y',122:'z',123:'{',124:'|',125:'}',126:'~',127:'\x7f',128:'\xC4',129:'\xC5',130:'\xC7',131:'\xC9',132:'\xD1',133:'\xD6',134:'\xDC',135:'\xE1',136:'\xE0',137:'\xE2',138:'\xE4',139:'\xE3',140:'\xE5',141:'\xE7',142:'\xE9',143:'\xE8',144:'\xEA',145:'\xEB',146:'\xED',147:'\xEC',148:'\xEE',149:'\xEF',150:'\xF1',151:'\xF3',152:'\xF2',153:'\xF4',154:'\xF6',155:'\xF5',156:'\xFA',157:'\xF9',158:'\xFB',159:'\xFC',160:'\xDD',161:'\xB0',162:'\xA2',163:'\xA3',164:'\xA7',165:'\u2022',166:'\xB6',167:'\xDF',168:'\xAE',169:'\xA9',170:'\u2122',171:'\xB4',172:'\xA8',173:'\u2260',174:'\xC6',175:'\xD8',176:'\u221E',177:'\xB1',178:'\u2264',179:'\u2265',180:'\xA5',181:'\xB5',182:'\u2202',183:'\u2211',184:'\u220F',185:'\u03C0',186:'\u222B',187:'\xAA',188:'\xBA',189:'\u2126',190:'\xE6',191:'\xF8',192:'\xBF',193:'\xA1',194:'\xAC',195:'\u221A',196:'\u0192',197:'\u2248',198:'\u2206',199:'\xAB',200:'\xBB',201:'\u2026',202:'\xA0',203:'\xC0',204:'\xC3',205:'\xD5',206:'\u0152',207:'\u0153',208:'\u2013',209:'\u2014',210:'\u201C',211:'\u201D',212:'\u2018',213:'\u2019',214:'\xF7',215:'\u25CA',216:'\xFF',217:'\u0178',218:'\u2044',219:'\xA4',220:'\xD0',221:'\xF0',222:'\xDE',223:'\xFE',224:'\xFD',225:'\xB7',226:'\u201A',227:'\u201E',228:'\u2030',229:'\xC2',230:'\xCA',231:'\xC1',232:'\xCB',233:'\xC8',234:'\xCD',235:'\xCE',236:'\xCF',237:'\xCC',238:'\xD3',239:'\xD4',241:'\xD2',242:'\xDA',243:'\xDB',244:'\xD9',245:'\u0131',246:'\u02C6',247:'\u02DC',248:'\xAF',249:'\u02D8',250:'\u02D9',251:'\u02DA',252:'\xB8',253:'\u02DD',254:'\u02DB',255:'\u02C7'} \ No newline at end of file diff --git a/extract_msg/encoding/_dt/_mac_turkish.py b/extract_msg/encoding/_dt/_mac_turkish.py new file mode 100644 index 00000000..67678731 --- /dev/null +++ b/extract_msg/encoding/_dt/_mac_turkish.py @@ -0,0 +1,8 @@ +# Based on https://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/MAC/TURKISH.TXT + +__all__ = [ + 'decodingTable', +] + + +decodingTable={0:'\x00',1:'\x01',2:'\x02',3:'\x03',4:'\x04',5:'\x05',6:'\x06',7:'\x07',8:'\x08',9:'\t',10:'\n',11:'\x0b',12:'\x0c',13:'\r',14:'\x0e',15:'\x0f',16:'\x10',17:'\x11',18:'\x12',19:'\x13',20:'\x14',21:'\x15',22:'\x16',23:'\x17',24:'\x18',25:'\x19',26:'\x1a',27:'\x1b',28:'\x1c',29:'\x1d',30:'\x1e',31:'\x1f',32:' ',33:'!',34:'"',35:'#',36:'$',37:'%',38:'&',39:"'",40:'(',41:')',42:'*',43:'+',44:',',45:'-',46:'.',47:'/',48:'0',49:'1',50:'2',51:'3',52:'4',53:'5',54:'6',55:'7',56:'8',57:'9',58:':',59:';',60:'<',61:'=',62:'>',63:'?',64:'@',65:'A',66:'B',67:'C',68:'D',69:'E',70:'F',71:'G',72:'H',73:'I',74:'J',75:'K',76:'L',77:'M',78:'N',79:'O',80:'P',81:'Q',82:'R',83:'S',84:'T',85:'U',86:'V',87:'W',88:'X',89:'Y',90:'Z',91:'[',92:'\\',93:']',94:'^',95:'_',96:'`',97:'a',98:'b',99:'c',100:'d',101:'e',102:'f',103:'g',104:'h',105:'i',106:'j',107:'k',108:'l',109:'m',110:'n',111:'o',112:'p',113:'q',114:'r',115:'s',116:'t',117:'u',118:'v',119:'w',120:'x',121:'y',122:'z',123:'{',124:'|',125:'}',126:'~',127:'\x7f',128:'\xC4',129:'\xC5',130:'\xC7',131:'\xC9',132:'\xD1',133:'\xD6',134:'\xDC',135:'\xE1',136:'\xE0',137:'\xE2',138:'\xE4',139:'\xE3',140:'\xE5',141:'\xE7',142:'\xE9',143:'\xE8',144:'\xEA',145:'\xEB',146:'\xED',147:'\xEC',148:'\xEE',149:'\xEF',150:'\xF1',151:'\xF3',152:'\xF2',153:'\xF4',154:'\xF6',155:'\xF5',156:'\xFA',157:'\xF9',158:'\xFB',159:'\xFC',160:'\u2020',161:'\xB0',162:'\xA2',163:'\xA3',164:'\xA7',165:'\u2022',166:'\xB6',167:'\xDF',168:'\xAE',169:'\xA9',170:'\u2122',171:'\xB4',172:'\xA8',173:'\u2260',174:'\xC6',175:'\xD8',176:'\u221E',177:'\xB1',178:'\u2264',179:'\u2265',180:'\xA5',181:'\xB5',182:'\u2202',183:'\u2211',184:'\u220F',185:'\u03C0',186:'\u222B',187:'\xAA',188:'\xBA',189:'\u2126',190:'\xE6',191:'\xF8',192:'\xBF',193:'\xA1',194:'\xAC',195:'\u221A',196:'\u0192',197:'\u2248',198:'\u2206',199:'\xAB',200:'\xBB',201:'\u2026',202:'\xA0',203:'\xC0',204:'\xC3',205:'\xD5',206:'\u0152',207:'\u0153',208:'\u2013',209:'\u2014',210:'\u201C',211:'\u201D',212:'\u2018',213:'\u2019',214:'\xF7',215:'\u25CA',216:'\xFF',217:'\u0178',218:'\u011E',219:'\u011F',220:'\u0130',221:'\u0131',222:'\u015E',223:'\u015F',224:'\u2021',225:'\xB7',226:'\u201A',227:'\u201E',228:'\u2030',229:'\xC2',230:'\xCA',231:'\xC1',232:'\xCB',233:'\xC8',234:'\xCD',235:'\xCE',236:'\xCF',237:'\xCC',238:'\xD3',239:'\xD4',241:'\xD2',242:'\xDA',243:'\xDB',244:'\xD9',246:'\u02C6',247:'\u02DC',248:'\xAF',249:'\u02D8',250:'\u02D9',251:'\u02DA',252:'\xB8',253:'\u02DD',254:'\u02DB',255:'\u02C7'} \ No newline at end of file From bea3ea85ddce5cfabbf44aa70e21ec3992f5db32 Mon Sep 17 00:00:00 2001 From: TheElementalOfDestruction Date: Sat, 29 Jul 2023 16:00:26 -0700 Subject: [PATCH 89/89] Update __init__,py for new release. --- extract_msg/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extract_msg/__init__.py b/extract_msg/__init__.py index 56376918..3b964b71 100644 --- a/extract_msg/__init__.py +++ b/extract_msg/__init__.py @@ -27,7 +27,7 @@ # along with this program. If not, see . __author__ = 'Destiny Peterson & Matthew Walker' -__date__ = '2023-07-04' +__date__ = '2023-07-29' __version__ = '0.42.0' __all__ = [